local ...

Sergey ShishkinSergey Shishkin
3 min read

Функция, которая часто используется в библиотечных файлах наряду с symbols. Уже акцентировалась в рамках “лексического анализа“. Благодаря поиску кода ее определения, наконец, разобрался в “либах“ проекта. Во-первых, есть папка с таким именем в src, где лежит только один файл llvm.l Странно, но это ещё не самая большая нагрузка на менталитет, как впрочем, и с файлами, обозначенными как lib, но с разными расширениями, хотя тоже путает. Главная проблема в том, что с именем lib две папки, то есть кроме той, которая в src, есть ещё папка прямо в pil21. По аналогии с предыдущими функциями, ссылки на код определения для которых я искал в map, с local “этот номер не прошел” и я обратился к Chat GPT за помощью, планируя потом получить от него комментарии кода. Он предоставил некий код и послал в lib/lib.l , но после того как я обратил его внимания на то, что такого файла там нет, он уточнил, что файл лежит прямо в директории pil21/lib.l. И только там уже я, действительно, обнаружил код, но другой.

“В версии pil21 определение local изменено. Вот актуальный код из lib.l:”

(de local ()
   (symbols (list (car (symbols)))
      (read) ) )

В этой реализации local больше не принимает явно список символов, как раньше. Вместо этого она:

  1. Использует (symbols) — для получения списка символов в текущей лексической области.

  2. Берёт только первый символ: (list (car (symbols))).

  3. Затем read считывает одно выражение, которое выполняется в лексической области, где этот символ временно локализован.

Пример использования:

: (setq A 123)
→ 123
: (local (A) (setq A 999) A)
→ 999
: A
→ 123  ;; значение восстановлено

По этой новой реализации, вызов должен быть без аргументов, а символ передаётся неявно через окружение. Это позволяет использовать local в контексте макрорасширений или REPL-интерфейса.

Почему так?

Версия pil21 — это минималистичный и экспериментальный PicoLisp, сильно урезанный по сравнению с классическим (picoLisp 3.x). Здесь упор на компактность и чистоту. В частности:

  • local упростили и адаптировали под односимвольное локальное связывание.

  • Многое реализуется в духе Forth и homoiconic-style.

Файл lib.l — это основной библиотечный модуль, написанный на самом PicoLisp. Он содержит:

  • определения макросов (de),

  • часто используемые утилиты, не встроенные в интерпретатор.

Так что DeepSeek скорее всего не фантазировал, а приводил “старую версию“ symbols … все надо уточнять. Конечно, я не удержался и спросил Chat GPT о местонахождении и symbols

“В текстовых файлах *.l нет её определения — это низкоуровневая примитивная функция, встроенная прямо в ядро PicoLisp.symbols является частью реализации среды — она взаимодействует напрямую с таблицами символов, которая реализована на … (Chat GPT пока ещё не знает про реализацию на LLVM и ссылается на С), а не на PicoLisp.” Естетственно, что он аккуратно и подробно прокомментировал код, который без комментариев есть в посте symbols.

А уже в рамках этого исследования я полез в pil21/src/dec.l , где обнаружил вот такое любопытное обращение к local

### Primitives ###
(local) (caar cadr cdar cddr int cnt sign sym name memq member length boxNum box64 eval run)

...

Кстати, файл интересный во всех отношениях и там много чего можно увидеть, чтобы лучше понять архитектуру системы.

0
Subscribe to my newsletter

Read articles from Sergey Shishkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sergey Shishkin
Sergey Shishkin

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