Повышаем уровень - 1. Чтение документации
Перевод. Оригинал здесь
Человек, который не хочет читать, подобен человеку, не умеющему читать. (Марк Твен)
Это 12-я статья из серии Введение в PicoLisp. Мы рассмотрели базовые концепции, синтаксис, наиболее важные функции и то, как объединить их в исполняемую программу. Поздравляем всех, кто прошёл этот нелёгкий путь!
Наверняка у вас более масштабные планы, чем просто написать программу "Hello, World!" Вам понадобится больше информации о функциях. Может быть, вы даже найдёте в работе интерпретатора ошибку...
В этой статье пойдёт речь о некоторых инструментах, которые помогут вам в решении этих проблем. Сегодня мы обсудим:
- Как читать документацию.
- Как пользоваться функциями
doc
иhelp
. - Как получить доступ к исходному коду программы с помощью встроенного
редактора
vip
. - Как редактировать функции с помощью команды
v
.
Одна из вещей, которая вам точно понадобится во время работы - это документация. Есть два способа просматривать её: через браузер или с помощью REPL.
Вы можете ознакомиться с документацией по адресу https://software-lab.de/doc/index.html. Как видите, окно браузера разбито на несколько частей:
- Верхняя левая часть: меню навигации.
- Нижняя левая часть: строка поиска функций.
- Верхняя правая часть: справочник функций.
- Нижняя правая часть: справочник PicoLisp.
Если вам нужны функции определённого типа, удобно держать в верхней части окна список функций, отсортированный по категориям. При нажатии на имя функции её описание будет открываться в нижней части окна. Другой вариант поиска функции - ввести её имя в строку поиска.
Если вам не понятны сокращения, которые применяются в описании функций, то их можно найти в верхней части окна, прокрутив вверх до соответствующего раздела.
Давайте попрактикуемся в чтении документации на примере простой функции
if
. Мы знаем её основное назначение. Посмотрим, что говорится о ней в
документации.
Первой строкой идёт синтаксис функции. Далее следует короткое словесное описание. Ниже приведено несколько примеров использования. Примеры в большинстве случаев очень простые и из них легко понять, что делает функция. Во многих случаях одних только примеров достаточно, чтобы понять, как функция работает.
Давайте посмотрим на строку с описанием синтаксиса функции. Мы не будем погружаться в эту тему глубоко, лишь отметим важные моменты.
-> (if 'any1 any2 . prg) -> any
- Первым аргументом функция
if
принимает аргумент'any1
. Одинарная кавычка'
показывает, что аргумент вычисляется в процессе выполнения функции. Например,(> 3 4)
вычисляется вNIL
, а(setq A 3)
вычисляется в3
, что не равноNIL
. - Далее мы видим второй аргумент,
any2
и третий,prg
, разделенные точкой. В зависимости от результата вычисления'any1
будет выполняться либоany2
, либоprg
. if
возвращаетany
, которое может быть любым типом данных (список, число, символ), в зависимости от того, что вычисляется вany2
илиprg
.
Какая разница между any2
и prg
? any2
должно быть выражением,
которое вычисляется в единственное значение, в то время как prg
может
быть списком из идущих друг за другом выражений. Таким образом, если
после условия 'any1
идёт несколько аргументов, то интерпретатор
"знает", что первый из них нужно вычислять в случае, если условие
вычисляется в NIL
, а все остальные - если в не-NIL
.
Пример:
(if (> 4 3) (print 1) (print 2) (print 3) (print 4)) печатает 1
.(if (> 3 4) (print 1) (print 2) (print 3) (print 4)) пнчатает 234
.
Примечание: структура (A . B)
является точечной парой, о которых
уже говорилось в предыдущих статьях. К более подробному обсуждению этого
вида ячеек мы вернёмся позднее, когда будем детально обсуждать структуру
функций в PicoLisp. Пока что просто запомните, что any2
- обязательно
одиночное выражение, а prg
может быть списком выражений.
В качестве второго примера давайте взглянем на функцию apply
, которая
применяет функцию к списку.
(apply 'fun 'lst ['any ..]) -> any
Мы видим аргументы 'fun
и 'lst
, оба они вычисляются.
- Как вы могли догадаться,
'fun
означает функция. Функция определяется по её имени, либо может быть анонимной (см. статью определение собственных функций). 'lst
означает список.'any
взят в квадратные скобки. Это означает, что аргумент необязательный.
Что будет, если мы передадим 'any
? То, что описано в тексте:
Функция будет применена к нему, как если бы он стоял в начале списка.
Третий пример из документации показывает, что это значит:
: (apply println (3 4) 1 2)
1 2 3 4
-> 4
В целом, мы советуем смотреть примеры кода, если описание остаётся неясным. Скопируйте код в REPL и попробуйте поработать с ним. Часто метод придти ошибок более продуктивен, чем чтение многих страниц документации.
Для чтения документации вовсе не обязательно держать открытым браузер.
Часто удобнее открыть документацию прямо из окна REPL. Для этих целей
используется браузер w3m
. Если он не установлен, вам сначала
понадобится его установить.
$ sudo apt-get install w3m
После этого вы сможете открывать документацию командой (doc 'fun)
прямо в REPL. Пример:
: (doc 'println)
Команда показывает текст с документацией.
Вы можете перемещаться по тексту с помощью клавиши tab
, стрелок вправо
и влево -> <- и выходить с помощью q
. Больше клавиатурных команд вы
можете найти в документации к браузеру
w3m.
Если вы не хотите переходить в документацию с помощью текстового
браузера, вы можете вывести её прямо в REPL. Команда (help 'fun)
выведет синтаксис и описание. (help 'fun T)
дополнительно выведет
примеры кода.
Может оказаться, что вам нужна не документация, а исходный код той или иной функции. Например, если вы хотите понять, как именно функция работает, или ищете вдохновения для написания собственных функций.
С этой целью в REPL предусмотрена возможность просмотра исходного кода
функций. На текущий момент поддерживается просмотр только с помощью
встроенного редактора vip
, варианта редактора vi
.
Чтобы открыть исходный код функции, введите команду (vi 'fun)
. Давайте
взглянем для примера на код функции align
:
: (vi 'align)
Откроется редактор vip
и вы сможете увидеть исходный код функции:
У редактора vip большое количество различных функций, будут рассмотрены только самые основные, об остальных вы можете прочитать здесь. В общих чертах команды редактора vip почти не отличаются от команд стандартного vim. Если вы не работали с ним раньше, можете ознакомиться с основами работы в нём здесь.
i
- переход в режим вставки <-->ESC
- переход в обычный (командный) режим.h
- курсор влево (командный режим)l
- курсор вправо (командный режим)j
- курсор вниз (командный режим)k
- курсор вверх (командный режим):q
- выйти:w ``<filename>
{=html} - сохранить в файл:x
- сохранить и выйти
Одна из самых полезных функций - это возможность переходить по коду от
функции к функции. Например, если мы хотим исследовать функцию pack
на
первой строке функции align
, мы можем навести курсор на слово pack с
помощью клавиш h, j, k, l
и нажать сочетание Shift-K
(либо Ctrl-]
,
как в стандартном vim).
Shift-K
илиCtrl-]
- перейти к следующей ссылке, вперёд.Shift-Q
илиCtrl-T
- переход к предыдущей ссылке, назад.
Очевидно, исходные коды функций не должны редактироваться, за
исключением тех случаев, когда вы точно знаете, что делаете. Тем не
менее, выполнив команду (vi '(fun1 fun2 fun3))
или её сокращённый
аналог (v fun1 fun2 fun3)
вы можете открыть код во временном файле,
отредактировать и сохранить его на диск с помощью
:w ``<filename>
{=html} без опаски повредить критически важные данные.
: (v align uniq) # то же самое, что и (vi '(align uniq))
Примечание: более ранние версии PicoLisp (до pil21) не имеют
встроенного редактора vip, однако у них есть поддержка просмотра
исходных кодов в vi и emacs с помощью команд (vi 'fun)
и (em 'fun)
соответственно. Для того, чтобы эти функции работали, вам нужно будет
установить vim, либо emacs.
На этом всё! В следующей статье будет рассмотрена работа с отладчиком.