2016-05-14 4 views
4

Это пример кода из книги Programming Clojure (2nd edition), который вычисляет основные значения.Соответствующие параметры с let/fn в Clojure

(def primes 
    (concat 
    [2 3 5 7] 
    (lazy-seq 
    (let [primes-from 
      (fn primes-from [n [f & r]] 
      (if (some #(zero? (rem n %)) 
         (take-while #(<= (* % %) n) primes)) 
       (recur (+ n f) r) 
       (lazy-seq (cons n (primes-from (+ n f) r))))) 
      wheel (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6 4 2 
         6 4 6 8 4 2 4 2 4 8 6 4 6 2 4 6 
         2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])] 
     (primes-from 11 wheel))))) 

код имеет структуру, которая определяет локальную функцию primes-from использовать, что в форме, пусть.

(def primes 
    (concat 
    [2 3 5 7] 
    (lazy-seq 
    (let [primes-from (fn primes-from [n [f & r]] ... ] 
     (primes-from 11 wheel))))) 

Однако, я не уверен, как первый параметр 11 и второй параметр wheel матчей к [primes-from (fn primes-from [n [f & r]] ... ] структуре.

Кроме того, я не вижу, как параметр primes-from при определении анонимной функции (fn primes-from [n [f & r]].

Любые объяснения по поводу этого кода?

ответ

4

let определяет primes-from для обозначения функции, определенной с помощью fn.

Когда primes-from был вызван, 11 совпадений n и wheel соответствует [f & r]. wheel относится к последовательности, а [f & r] ожидает последовательность - это то, что означают скобки. f («первый») будет соответствовать первому элементу в последовательности, который будет первым в первый раз. Значение & означает, что параметр после него r («отдых») соответствует всем остальным последовательностям (который начинается с 4 в первый раз).

(cycle определяет последовательность ленивым, так что то, что соответствует r не полностью расширен.)

И «простые числа-с» в (let [primes-from ... и «простые числа-с» в (fn primes-from ... нужны. Первый экземпляр - это то, что позволяет начать вызов функции в последней строке определения primes. Второй экземпляр - это то, что позволяет рекурсивный вызов функции по имени в середине определения fn. Этот последний экземпляр «primes-from» также дает функции внутреннее свойство имени, которое может быть полезно при отладке.

(Обратите внимание, что есть два рекурсивных вызовов в пределах fn определения. Первый использует recur, а второй использует primes-from. Оба могли использовать primes-from, но это как правило, лучше использовать recur, когда это возможно, потому что он не использует стек и, следовательно, более эффективен и позволяет избежать нехватки памяти. recur может использоваться только в положении хвоста, т. е. когда дальнейшая обработка не должна выполняться с возвращаемым значением внутри функции. Во втором случае невозможно использовать recur , так как возвращаемое значение будет подаваться на cons и lazy-seq.)

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