Регистры и кавычки
Всегда чему-то учусь!
Так называется статья - “Registers and quoting in PicoLisp“. Кстати, полезный ресурс для изучения системы, на сайте около трех десятков статей на тему PicoLisp. Регистрами автор статьи называет CAR и CDR. К ним мы ещё вернемся, а здесь, ещё раз акцентируется quote, которая возвращает все как есть, не оценивая. “Reader распознает одинарную кавычку char ' как макрос для этой функции“. Отдельный пост, акцентирующий “квотинг“ (цитирование) или возможность - не оцентвать выражение, смотрите здесь - quote и о её необходимости. Но без примеров.
(set '*Greeting '("Hello" "how" "are" "you" "doing?"))
(prin (car *Greeting))
set 'var — это просто сокращение setq var.
' — это сокращение для quote.
Все, что заключено в кавычки, воспринимается буквально. Имена переменных внутри заключенного в кавычки списка, конечно, не будут расширяться до своих значений — за исключением случаев, когда они вычисляются или передаются в семейство специальных функций, mapcar является одной из них.
Когда вы думаете о цитировании, это помогает … думать о машине Тьюринга, которая принимает инструкции в форме этих длинных бумажных полосок, которые вы в нее вставляете. С другой стороны, вы получаете результат вычисления. Когда вы скармливаете машине переменную, она, конечно, расширится до содержащейся в ней полосы. Однако, когда вы цитируете, вы просто скармливаете машине необработанную/буквальную полоску, говоря ей, чтобы она обращалась с ней как с таковой.
Есть целая категория функций, которые принимают литерал функции (список в кавычках) и используют эту функцию в другом списке. Давайте рассмотрим простой пример:
(de getSomething (Lst R)
(mapcar '((Element) (R Element)) Lst) )
(setq *Fruits
'(("green" "apple" "guava" "avocado")
("red" "cherry" "apple")))
(prin (getSomething *Fruits 'car))
В этом случае мы извлечем все ключи, по сути, та же функциональность, что и у функции PHP array_keys. Если вы сделаете 'cdr, то вместо этого получите значения, которые соответствуют array_values(). А что, если вы хотите получить первый фрукт в каждом подсписке? Да, вы угадали, просто передайте вместо этого 'cadr. Довольно динамично, не правда ли? Если вернуться к аналогии с машиной Тьюринга, это будет означать использование заполнителя на необработанной полосе, которая получит свое значение, когда придет время выполнить полосу/список.
Здесь происходит следующее: функция mapcar принимает функциональный литерал в качестве первого параметра, второй параметр — это список, с которым будет работать функциональный литерал, на самом деле mapcar может принимать несколько списков и использовать их содержимое в функциональном литерале, однако в этом случае мы просто упрощаем его. Элементом будет каждый элемент в списке, в нашем случае два подсписка. Результатом будет новый список, элементы которого являются результатами каждой операции, выполняемой нашим функциональным литералом. Вот почему мы получаем список с «зеленым» и «красным» в нем, если передаем 'car в getSomething.
Обратите внимание, что нет ключевого слова return, в Pico Lisp (как во всех Lisp) все выражения что-то возвращают, поэтому нет необходимости в ключевом слове return. А ключевое слово (de… — это то же самое, что и function в PHP, мы просто определяем новую функцию, которая будет использоваться позже.