Arc Forumnew | comments | leaders | submitlogin
Function that takes any amount of arguments?
2 points by globalrev 5825 days ago | 5 comments
how do i write a function that takes any amount of arguments?

and how do i refer later to those arguments?

lets say i want a function that takes any amount of integer arguments, squares them and puts them into a list (def sqnl(a, b, c...)



4 points by tokipin 5825 days ago | link

you can use the . as meaning "rest"

  (def sqnl (a b . c) ...)
this is a function that takes a mininum of 2 arguments. when called, the extra arguments are combined into a list and bound to c

for full variadic functions, you can just leave off the parens:

  (def sqnl args
      (map [* _ _] args))
a really nifty thing is that the arguments are automatically destructured (dunno if that's the term.) for example, say you are using lists of two elements to represent points on a coordinate plane:

  (= p1 (list 30 50)
     p2 (list 20 80))
and say you want to make a function that multiplies the points by a scalar. you can do it like this:

  (def scale (point s)
       (list (* s (car point))
             (* s (cadr point))))
so you're explicitly accessing the first (car) and second (cadr) parts of the list. but you can have the work done for you like so:

  (def scale ((x y) s)
       (list (* s x)
             (* s y)))

-----

4 points by wfarr 5825 days ago | link

In arc, this is denoted with the "." just like in Scheme.

For example, an argument list for '+ might look like so:

  (a b . rest)
'rest would take the value of everything after '(a b).

-----

3 points by cchooper 5825 days ago | link

Just to add: if you want your function to take any number (including zero) arguments, then just use a symbol instead of an argument list, and all the arguments will be bound to that symbol.

  (def return-all-args x x)

  (return-all-args 1 2 3)
  => (1 2 3)

-----

1 point by krg 5821 days ago | link

globalrev, this stuff confused me at first too.

So if you have (def foo (a b . c) ...stuff...) and you call (foo 1 2 3 4 5), a is bound to 1, b is bound to 2, and c is bound to the list (3 4 5).

And (def foo a ...stuff...) is just shorthand for (def foo ( . a) ...stuff...). So calling (foo 1 2 3) in this case means a is bound to the list (1 2 3).

-----

3 points by almkglor 5821 days ago | link

> And (def foo a ...stuff...) is just shorthand for (def foo ( . a) ...stuff...).

Technically wrong: ( . a) is invalid syntax. However it does help to think of it that way.

-----