2012-01-11 4 views
8

Я учусь Guile Scheme на данный момент, и в документации я вдруг наткнулся на следующую конструкцию:Когда использовать определение лямбда с «голым» формальным параметром?

((lambda args (display args)) 42) 
=> (42) 

Это бросил меня за цикл; до этого момента я не предполагал, формальные параметры всегда были заключены в списке:

((lambda (args) (display args)) 42) 
=> 42 

Интересно, когда использовать этот вариант, и как это отличается от точечной нотации для переменного числа аргументов. В частности, в чем разница между этими двумя следующими вариантами:

((lambda args (display args)) 1 2 3)  => (1 2 3) 
((lambda (. args) (display args)) 1 2 3) => (1 2 3) 

Есть ли разница - возможно, для более сложных примеров - что мне нужно, чтобы быть в курсе и нет никаких оснований предпочесть один над другим?

+3

В качестве бонуса определение 'list' is '(define list (lambda xx))'. – erjiang

ответ

6

Разница заключается в том, что эта версия получает один параметр, называемый args, полезный для тех случаев, когда вы точно знаете, число фактических аргументов, ожидаемых для lambda формы:

(lambda (args) (display args)) 

И эта версия получает (возможно, пусто) списка параметров, называемый args, полезно, когда вы ожидаете переменное число аргументов для lambda формы:

(lambda args (display args)) 

Там не должно быть никакой разницы между следующими двумя версиями, но не все переводчики будут принимать второй, так как он отсутствует часть перед точкой (поэтому его следует избегать):

(lambda args (display args)) 
(lambda (. args) (display args)) 

Следующая версия полезно, если вы хотите указать, что форма lambda имеет один или несколько обязательных параметров (символы слева от точки) и список нулевых или более необязательных параметров (один символ справа от точки):

(lambda (mandadory1 mandatory2 . optional) (display mandatory1)) 
+3

'(. Args)' недопустим синтаксис чтения схемы. Тем не менее, Guile, кажется, расширил свой читатель, чтобы читать его как «args». Это определенно не переносится, и, как вы говорите, лучше всего избегать. –

+1

Отлично, спасибо. Я думал, что все наоборот; предположил, что точка-единственная форма была полностью стандартной, а «голая» форма была немного странной. Я думаю, что точка-точка более естественна из других форм для моих новичков. – Janne

1

Это бросило меня за OOP; до этого момента я полагал, формальные параметры всегда были заключены в списке:

Обратите внимание, что такие вещи, как (a . args) и (a b . args) не действительно перечисляет либо. (a . args) - это пара, где car является символом a, а cdr является символом args. (a b . args) - это пара, где car является символом a, а cdr (пара, где car является символом b, а cdr - это символ args). Он выглядит как список на некоторое время, с a и b, и это, но поскольку оно не заканчивается в null/пустом списке, это не совсем правильный список. Подобные структуры часто называют неправильными списками. Если вы хотите, вы можете прочитать немного о пунктирных парах нотации here, или где-нибудь еще ...

С (. args) я бы, возможно, что-то вроде «это пара, где cdr символа args».Или, может быть, это получилось как «пара, где car есть и cdr - args». В любом случае это не будет иметь большого смысла, и, как сказал Крис Шестер-Янг, это действительно не схема.

So. Такие вещи, как (a b . args), являются просто регулярными пунктирными обозначениями для размещения вещей, которые не равны нулю в последних cdr. Если формальные параметры-вещи в Схеме могут быть одним из тех неправильных списков или надлежащим списком или просто символом, то определение формальных параметров-вещей должно быть примерно таким: формальные параметры-вещи должны быть нулевыми, символами, или пара, где car является символом, а cdr является формальным параметром.

(Которая, по моему мнению, является довольно классной штукой, которая делает довольно элегантный способ привязки аргументов к параметрам. Например, вы смотрите на формальные параметры-вещи, и если это символ, вы связываете список аргументов с что, и если это пара, вы связываете аргументы car с аргументами формальных параметров и возвращаете по cdr формальных параметров-вещей/аргументов (ах, а если это нулевое значение, то вы сделались или что-то еще). ударяет меня как немного красивее, чем обычный Lisp-способ ", и если символ в car равен &rest, вы связываете остальные аргументы с символом после этого".)

+0

Пунктирная пара - я никогда не делал связи. Подумал, что это была конкретная нотация для формальной спецификации параметра. Благодаря; Я отредактирую свой вопрос, когда у меня появится такая возможность. – Janne

Смежные вопросы