2013-05-24 2 views
0

Я пытаюсь реализовать эту логику в Clojure (просто пример):Последовательные вычисления в Clojure

a = 1 + 5 
b = a + 3 
c = a + 4 
d = c + a 
return f(a, b, c, d) 

Лучший код, который я успел написать до сих пор выглядит следующим образом:

(let [a (+ 1 5) b (+ a 3) c (+ a 4) d (+ c a)] (f a b c d)) 

Это выглядит довольно громоздко, главным образом потому, что в моем реальном случае эти операции «добавить» намного сложнее и могут занимать несколько строк кода. Я предпочитаю писать его как (стиль Лиспа):

(set a (+ 1 5)) 
(set b (+ a 3)) 
(set c (+ a 4)) 
(set d (+ c a)) 
(f a b c d) 

Возможно ли это в Clojure?

+8

Не будет ли перемещение пар внутри 'let' в отдельные строки, чтобы он выглядел так же ясно, как бит Lisp? – toniedzwiedz

+0

** О ** как ясно ... – yegor256

+0

Честно говоря, я нахожу синтаксис Clojure лучше (повторное набор снова и снова кажется бессмысленным). Мое мнение может быть предвзятым, поскольку я видел только упрощенный пример, который вы предоставили. – toniedzwiedz

ответ

4

Нет, и это по намерениям, так как звонки, которые вы описываете, подразумевают использование изменяемого состояния в том, как это делают языки, такие как Java и C#. Это то, что Clojure активно избегает, чтобы управлять состоянием более разумным способом, что действительно становится важным в параллелизме. Для получения дополнительной информации я отсылаю вас к the Clojure website.

Кроме того, let формы не является громоздкой, он является полезным инструментом обзорным: В вашем примере a, b, c и d все местные, чтобы позволить. Это означает, что после того, как указатель инструкции выходит из let, все эти привязки забываются.

Напротив, даже если ваш (set...) пример должен был работать, вы бы загрязнили свое пространство имен всеми этими эфемерными именами.

4

На самом деле, вы почти нашли лучшее решение возможных в Clojure:

(let [a (+ 1 5) 
     b (+ a 3) 
     c (+ a 4) 
     d (+ c a)] 
    (f a b c d)) 

Вы не можете написать Clojure кода в императивном стиле, потому что это функциональный язык. Вы также не можете свободно использовать defs, потому что все переменные в Clojure неизменяемы. Таким образом, те, которые определены, не могут быть изменены. Итак, если вы хотите временно привязать некоторые переменные, вы должны использовать let.

3

set function В Clojure создается набор данных из другого контейнера для сбора данных, а не для изменения значений переменных. Тем не менее, вы можете сделать следующее:

(def a (+ 1 5)) 
(def b (+ a 3)) 
(def c (+ a 4)) 
(def d (+ c a)) 
(f a b c d) 

Оператор пусть позволяет делать то же самое, но не «загрязнять» ваш верхнего уровня пространства имен с a, b, c и d значения. Тем не менее, если вы хотите, чтобы иметь возможность держаться и ссылаться на a, b, c и d, def сделал бы трюк.

Смежные вопросы