Brian Candler <b.candler / pobox.com> writes:

> Mike Gold wrote:
>> Brian Candler wrote:
>>> (2) to understand Mike's assertion 
>>> that Ruby lambdas are not first-class functions (i.e. "The difference 
>>> between lambda { } and a real first-class function is quite profound").
>> 
>> Ruby:
>> 
>>   mean = lambda { |*args|
>>     (args.inject(0) { |acc, x| acc + x })/args.size.to_f
>>   }
>>   data = [[1,2,3], [4,5,6,7]]
>> 
>>   data.map(&mean) # fail
>>   data.map(&:mean) # fail
>>   data.map { |*numbers| mean.call(*numbers) } # fail
>>   data.map { |numbers| mean.call(*numbers) } # phew, found it
>
> OK, I think I see what you're getting at. You've written a lambda with a 
> splat (i.e. which takes a variable number of arguments), but needed a 
> splat at the caller side too. Otherwise the lambda receives a single 
> argument, which is an Array object.
>
> You could have written the lambda to take a single Array argument:
>
>   mean = lambda { |arg|  arg.inject(0) ...etc }
>
> I don't know enough about Lisp to say how Lisp resolves the same 
> dichotomy, but surely it must exist. That is, there must be a difference 
> between calling a function foo with a (list of) n arguments, and calling 
> a function foo with 1 argument which is itself a list?

At the function definition site, it's the same, you can decide whether
you'll take a single argument of type list, or several arguments that
will be treated like a list:

(defun unary-function (arguments)
   (process arguments))

(defun variadic-function (&rest arguments)
   (process arguments))

At the call site:

If  you have a list:                               several arguments:
        list-of-args                                    1 2 3

(unary-function list-of-args)                      (unary-function (list 1 2 3))  
                                                      [x]
(apply (function variadic-function) list-of-args)  (variadic-function 1 2 3)
  [y]                          


x: you can always build a list with the variadic function LIST.

y: there's a maximal number of arguments (implementation defined) that
   can be passed to a function, therefore a limit on the length of the list
   that can be passed with APPLY.



Moreover, Common Lisp as much richer parameter specifications.
You can specify of course mandatory parameters, but in addition:
- optional parameters,
- keyword parameters,
- rest parameters as above.

For both optional parameters and keyword parameters (which are also
optional), you can specify a default value.

For example:

(defun example (mandatory-1 mandatory-2
                 &optional optional-1
                           (optional-2 'default-value optional-2-present)
                 &rest remaining-arguments-\(including-keys\)
                 &key key-1
                      (key-2 'default-value-2 key-2-present)
                      ((:actual-key key-3) 'default-value-3 key-3-present)
                 &allow-other-keys)

   (print mandatory-1)
   (print mandatory-2)
   (when optional-1          (print optional-1))
   (when optional-2-present  (print optional-2))
   (print remaining-arguments-\(including-keys\))
   (print key-1)
   (when key-2-present (print key-2))
   (when key-3-present (print key-3))
   (values))

C/USER[20]> (example 'm1 'm2 'o1 'o2 :actual-key 'ak :key-1 'k1 :whatever 'you-want)

M1 
M2 
O1 
O2 
(:ACTUAL-KEY AK :KEY-1 K1 :WHATEVER YOU-WANT) 
K1 
AK 
                 


(In the case of macros, you can even specify recursive lists, to
deconstruct any syntax).


-- 
__Pascal Bourguignon__