Clojure: несколько задач, если - PullRequest
0 голосов
/ 21 сентября 2018

Как я узнал, форма if - это (if [condition] [true] [false]).Аналогично, cond равно (cond [condition] [true] ... [condition] [true] [false]).Кажется, что каждый истинный и ложный сегмент принимает только одно действие.Если я хочу представить следующую логику:

if (i > 0)
{
    a += 5;
    b += 10;
}

Я думаю, что я должен сделать:

(if (> i 0) (def a (+ a 5)))
(if (> i 0) (def b (+ b 10)))

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

ps. Я также подозреваю, что переопределение a и b каждый раз не лучший способ увеличения, но также и убежище.не видел другой способ сделать это.Мне пришлось также переопределить списки при использовании Con.

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Другой ответ охватывал явный вопрос о наличии более одного выражения в ветви if (с использованием do или с использованием when, если нет ветви else в качестве when обертокего вложенные выражения неявные do).

Однако существует другая проблема в вопросе с использованием состояния, которое обычно является локальным для функции.Я не думаю, что atom, хранящийся в глобальной переменной, является лучшим способом справиться с этим, и поскольку программы Clojure стремятся минимизировать глобальное состояние, обычно лучше сохранять состояние локальным.

Мы используем let чтобы определить локальное состояние и сузить его область (примечание, он также поддерживает деструктурирование ):

(let [i 0
      a 5
      b 10]
  (println i)
  (println a)
  (println b))

let присваивает значение локальной переменной, и оно не может быть переопределено.Если нам нужно обновить локальное состояние, мы можем использовать рекурсию, вызывая recur непосредственно для функции или используя loop и recur.

Например:

(defn plus [a b]
  (if (> b 0)
    (do
      (println "Recurring...")
      (recur (inc a) (dec b)))
    (do
      (println "Returning result")
      a)))

Или:

(defn plus [a b]
  (loop [a a
         b b]
    (if (> b 0)
      (do
        (println "Recurring...")
        (recur (inc a) (dec b)))
      (do
        (println "Returning result")
        a))))
0 голосов
/ 25 сентября 2018

Вы смотрите не в тот конец телескопа.Помните, что

  • У Clojure нет локальных переменных.
  • У Clojure нет действий (обычно называемых операторами), только выражения, возвращающие значение.

Существует нет эквивалента Clojure оператора a += 5;.

Однако выражения могут иметь побочные эффекты: print и т.п. ничего другого не достигают.Форма do позволяет выполнить ряд побочных эффектов перед возвратом окончательного значения.Например,

(do (print a) (print b) (+ a b))
  • печатает a,
  • печатает b,
  • возвращает их сумму.

Вот почему, когда вы пишете форму if ...

Кажется, что каждый сегмент истинного и ложного допускает только одно действие.

Что имеет Clojure, так это

  • локальные привязки имен с формой let и
  • производной версией let под названием loop, которая реализует примитивную форму рекурсии, которая может заменить простое использованиециклы в таких языках, как C или Java.

Между ними let и его потомки loop позволяют писать самые простые управляющие структуры.чтобы определить, относится ли это к фрагменту вашей программы ...

if (i > 0)
{
    a += 5;
    b += 10;
}

... нам нужно увидеть контекст.

Однако вот самая большая общая функция делителей в C (непроверенная)

long gcd (long i, long j)
{
  long m = i, n = j;
  while (n != 0)
  {
    long t = n;
    n = m % n;
    m = t;
  }
}

и в Clojure

(defn gcd [i j]
  (loop [m i, n j]
    (if (zero? n)
      m
      (recur n (mod m n)))))

Обе они могут быть сокращены.

0 голосов
/ 21 сентября 2018

Самая прямая транзакция, использующая атомы вместо переменных (def), будет

;; assuming something like (def a (atom 0)) (def b (atom 0))
(if (> i 0)
  (do
    (swap! a + 5)
    (swap! b + 10)))

или

(when (> i 0)
  (swap! a + 5)
  (swap! b + 10))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...