Skip to main content

Command Palette

Search for a command to run...

Регистры и кавычки

Updated
3 min read
S

Всегда чему-то учусь!

Так называется статья - “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, мы просто определяем новую функцию, которая будет использоваться позже.

P.S. Даже маленькие детали имеют значение!

More from this blog

Нетривиальный Repl

Это плавный переход от eval к loop к циклам и где уместно вспомнить, что эта тема уже затрагивалась в контексте самой часто употребляемой функции for и рекурсии. Repl как функция не анонсирована в документации, но есть авторская классификация в файла...

Jul 15, 20257 min read
A

abrakadabra

195 posts

Метамоделирование как интеграция философии, лингвистики и математики на базе информатики. Анализ теорий и практик программирования. Прецеденты оптимизации.