Racket: Скобки
Скобки настолько пугают новичков, что весь интернет завален вопросами "почему в лиспе так много скобок?". Такие вопросы возникают не просто так: при обычном способе редактирования текста Lisp-программы с трудом поддаются модификации. Забытая скобка может стать причиной долгой отладки. Посмотрите на этот код:
(define (GET/hash #:rconn [rconn (current-redis-connection)] key
#:map-key [fkey identity]
#:map-val [fval identity])
(let loop ([lst (HGETALL #:rconn rconn key)] [h (hash)])
(if (null? lst) h
(loop (cddr lst) (hash-set h (fkey (car lst)) (fval (cadr lst)))))))
В самом конце очень много скобок. Представьте, что будет, если придётся обернуть какую-то часть кода в новый список или удалить ненужный список? Похожие проблемы возникают при редактировании HTML-файлов, когда нужно удалить как открывающий, так и закрывающий тег (либо наоборот — добавить).
Очевидно, что обычный способ работы в редакторе не слишком подходит для модификации Lisp-программ. Поэтому в этом мире приняты другие подходы, о которых начинающие Lisp-программисты узнают случайно.
Секрет приятной работы с Lisp-кодом состоит в изменении точки зрения на этот код. В то время как в обычных языках мы модифицируем текст, в Lisp мы оперируем деревом. Для удобной работы с этим деревом нам понадобятся операции, которые помогают легко вставлять и удалять узлы, объединять их и разъединять. А еще неплохо было бы никогда не нарушать "баланс скобок".
Такой способ работы с кодом существует и называется "структурное редактирование". Исторически сложилось так, что расширения для редакторов принято называть "Paredit". Попробуйте загуглить: "<имя редактора> paredit lisp". Скажем, для продуктов компании JetBrains разработано специальное расширение Cursive. В документации этого расширения наглядно показаны возможности Paredit. Обязательно посмотрите эти гифки, они помогут понять принципы управления Lisp-кодом. У Paredit есть альтернатива Parinfer.
При правильном подходе в какой-то момент вы вдруг обнаружите, что структурное редактирование эффективнее обычного. Скобки перестанут быть проблемой, а при возврате в обычные языки вы начнёте испытывать неудобства.
Другой важный аспект — правильное форматирование. Длинные операции принято разбивать так, что операнды оказываются друг под другом:
(+ 234
88
123423)
Более сложный пример:
(- 100
(+ 4 100)
(- 1000
50))
Такая запись тоже требует привыкания, но взамен вы сможете с лёгкостью ориентироваться в аккуратно оформленном коде.
Задание
Выведите на экран значение выражения: 4 + 2 - 3 * 5 - 8 / 7
. Выполните форматирование кода так, чтобы он легче воспринимался (код можно разбить по-разному).