apply is designed for calling a function with a variable argument list. Conceptually, you can write any function call of the form (f a b c) as (apply f (list a b c)). Its arguments are a function, any number of arguments, and a list at the end. For instance, suppose we have (apply f x y z (list a b c)). This is the same as writing (f x y z a b c).
In your example, you have (apply + '(a b) '((c d) (e f))); apply splices in the closing list, doing the same thing as (+ '(a b) '(c d) '(e f)); it should be clear why this returns '(a b c d e f).
That was not the clearest explanation in the world, so if you still have questions, please ask.
Also, a formatting tip: indent your code with two spaces and surround it by blank lines to have it formatted as code.
Thanks. The behaviour of apply seems to be consistent with last-args-as-varargs.
arc> (apply + "a" '("b" "c"))
"abc"
I was originally thrown by a line in w/uniq in arc.arc -
(apply + nil (map1 (fn (n) (list n '(uniq))) names))
This line is constructing an argument list for "with". It looks like the nil is necessary in case map1 returns an empty list, otherwise + would return 0, which is not a valid argument list.
The reason that w/uniq has the nil is so that + thinks it's adding lists, not numbers. Of course, pg could have just used join there, which would (a) eliminate the typing problem, and (b) in the nil case, produce (join), which is nil.
Also, if you want to reply directly to a person, click on the reply link below their post; it makes following the conversation a little bit smoother :)
I think apply is typically supposed to take only 2
args:
arc> (apply + '((a b) ((c d) (e f))))
(a b (c d) (e f))
There's some special code that interprets apply with
3+ args differently. I don't know why apply with 3+
args is even allowed. Search ac.scm for ar-apply-args
and there's a comment about it. It seems to have
something to do with the arc/scheme boundary, but I
don't really understand the comment.
No, apply can take any number of args. The last arg is interpreted as a varargs parameter. This is in fact the entire reason 'apply exists at all, so it can expand the final list into individual args.
Not quite. All that the comment is talking about is that Arc lists are different from Scheme lists. In Arc, they end with the symbol 'nil (e.g., '(1 2 3) is the same as '(1 2 3 . nil)); in Scheme, they end with '() (e.g., '(1 2 3) is the same as '(1 2 3 . ())).
apply is perfectly well-defined for n arguments: (apply f x xs) is the same as (apply f (cons x xs)). In other words, if we think about apply as providing the contents of a list as arguments to a function, this is only relevant to the last argument. The rest are passed to the function normally. This is a nicety, allowing us to write things like (apply map + list-of-lists).