Бесплатный курс по Racket. Зарегистрируйтесь для отслеживания прогресса →

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. Выполните форматирование кода так, чтобы он легче воспринимался (код можно разбить по-разному).

Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

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


Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе