Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arguments var missing in ki functions #25

Open
orlin opened this issue Mar 15, 2015 · 4 comments
Open

arguments var missing in ki functions #25

orlin opened this issue Mar 15, 2015 · 4 comments

Comments

@orlin
Copy link
Contributor

orlin commented Mar 15, 2015

Sometimes it's useful to have the arguments var available, just like js functions offer. Some cases can't quite be covered with variadic arity / multimethod functions. For example variable args with last arg a callback, or whatever other edge-case scenario. In any case, people could write their functions in ki without missing javascript's arguments or falling back to javascript for that reason. Otherwise useful just for the sake of matching-up the host language.

@lantiga
Copy link
Owner

lantiga commented Mar 18, 2015

This one is tricky. ki uses a lot of intermediate immediate function invocations to achieve proper lexical scoping and at the same time the JavaScript arguments object only contains the arguments provided to the enclosing function.

What we could do is store the content of the arguments object in a ki-specific args (or whatever) object which gets overwritten only when a ki fn is invoked. Then we'll have to make sure the previous value of args is put back when the function returns.

I'm wondering whether this is the right thing to do as opposed to trying to cover the edge cases directly. Any thoughts? Also, can you provide an example of edge case with code? Thanks!

@lantiga
Copy link
Owner

lantiga commented Mar 19, 2015

Actually, it's easier than I thought.

Let's start from the current state of things: arguments is correct and available right after entering the function body, e.g.

ki require core
ki (do
     (defn f [] (prn arguments))
     (f 1 2 3))

prints { '0': 1, '1': 2, '2': 3 }, since there's no intermediate immediate functions in the way at that point.
However, the only way to have arguments survive the rest of the scope is to assign it to a variable. However, using let wouldn't work, because the assignment happens within an immediate function (for lexical scoping reasons), which is passed no arguments. In fact,

ki require core
ki (do
     (defn f [] (let [args arguments] (prn arguments)))
     (f 1 2 3))

prints {}.

However, we can get to it with the help of a macro

ki require core
ki macro (defargs $args) (js var $args = arguments)
ki (do
     (defn f [] (defargs args) (let [foo 1 bar 2] (prn args)))
     (f 1 2 3))

prints { '0': 1, '1': 2, '2': 3 }.

Feel free to let me know your thoughts.

@noncom
Copy link

noncom commented Jan 3, 2016

Much better than nothing! This is a working solution. And considering that the args variable is not used often, making this obvious call is even better, which will also remove the unnecessary overhead where args is never used.. So maybe putting (defargs ..) and some argumentless form of it like (use-args) into the core would be good.

@lantiga
Copy link
Owner

lantiga commented Jan 4, 2016

Thanks for the feedback.

Another couple of (not necessarily better) options

(letargs arg_binding ...)

ki require core
ki macro (defargs $args) (js var $args = arguments)
ki (do
     (defn f [] (letargs args (let [foo 1 bar 2] (prn args))))
     (f 1 2 3))

(defnargs [arg1 arg2 ...] ...)

ki require core
ki macro (defargs $args) (js var $args = arguments)
ki (do
     (defnargs f [] args (let [foo 1 bar 2] (prn args)))
     (f 1 2 3))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants