Получение более полезных предупреждений при компиляции Clojure

В функции ниже, я использовал cond в месте case, Мне потребовалось много времени, чтобы выделить эту функцию. Я изучаю clojure, поэтому ошибка не была очевидна для меня. Когда я попытался запустить код до map функция (используя отладчик cursive / Intellij), Intellij жаловался: There is no executable code at core.clj:144, Если компилятор clojure знает об этом, есть ли возможность получить предупреждение во время компиляции? Существуют ли другие проверки, которые компилятор (или пух) может сделать в моем коде?

(defn uri-gen [uri fields line]
  (let [remo "[//\\:*?()<>|.%'\"&]"]
    (cond (count fields)
      0 (correct-uri ...)
      1 (let ...)
      (correct-empty
        uri
        (apply str
          (map (fn [it] ...)))))))

2 ответа

Решение

К сожалению, предупреждения и сообщения об ошибках в Clojure часто краткие, бессмысленные или просто отсутствуют.

Я не уверен, поможет ли это в этом случае, но вы можете попробовать eastwood Инструмент Clojure Lint (см. Другие на панели инструментов Clojure). Я также широко использую Plumatic Schema, которая помогла мне избежать многих простых ошибок типа.

Это не проблема компилятора.

С точки зрения компилятора, то, что вы написали, имеет смысл. У вас есть s-выражение, состоящее из s-выражения, за которым следуют дополнительные s-выражения - в чем проблема? Лисп, такой как Clojure, вычеркнул небольшой "синтаксис", о котором "знает" компилятор. Например, ему не нужно беспокоиться о глупых вещах, таких как приоритет операторов и операторы "если" и "пока" и "до", а также о множестве других вещей, которые компиляторы для других языков колеблются. Он не знает, что cond а также case а также and а также whatever делать - он просто знает, что, поскольку они являются первым значением в форме без кавычек, они должны быть функцией; компилятор может в некотором смысле "найти" эту функцию, поэтому он может создать код для вызова функции; и за ним следует множество других допустимых выражений, которые необходимо передать в функцию. (И, конечно, эти другие выражения могут состоять из большего количества s-выражений, представляющих больше функций, которые должны быть вызваны, и мы идем вниз по Лисп-дыре!). KEWL! Это функция, которая должна иметь некоторый смысл передаваемых аргументов и делать то, что должна делать функция. Компилятор ничего об этом не знает - в очень упрощенном смысле он просто читает s-выражения и генерирует код для вызова функций.

Если вы настаиваете на прохождении caseаргументы condкомпилятору все равно. Он будет весело делать то, что вы просили. Дело в том, что cond будет (вероятно) прервать все эти аргументы - это не то, что компилятор должен решать , а проблема программиста. Lisp/Clojure возлагает ответственность за то, чтобы все было правильно, прямо на плечи программиста, которому он принадлежит.

Lisp - это своего рода сверхдержава для программистов. В правильных руках это ценный инструмент на службе человечества. В чужих руках это рецепт катастрофы. Старайтесь не быть Затянутым - используйте свои силы с умом.:-)

Другие вопросы по тегам