2017-02-16 13 views

ответ

2

Пакет threading обеспечивает ~>> как макрос, который вставляет предыдущие выражения в последующих выражениях. Когда он видит образец так:

#lang racket 
(require threading) 
(~>> a 
    (f b _)) 

Это находит _ в течение второго суб-формы, и вставляет a в то место в форме, (f b a).

Что еще более сбивает с толку, так это то, что есть стенография. Если _ находится в конце подформы в ~>>, вы можете опустить его. Когда он видит что-то вроде (f b), где нет _, он вставляет его в конец, и это как если бы вы написали (f b _). Это то, что происходит в случае лямбда, оно интерпретировало ваш синтаксис как эквивалент (lambda (x) x _).

В результате после установки 1 был (lambda (x) x 1). Это было не то, что вы ожидали.

Что вы хотите

вашего использования функций лямбда и ваши ожидания, кажется, что вам не нужно это сложное поведение макросов; вы просто хотите, чтобы они применяли их как функции. Нужная форма для потоковой обработки просто применит более поздние выражения к результатам предыдущих, преобразуя (~> a (f b)) в ((f b) a). Эта более простая версия предоставляется пакетом point-free как ~>.

#lang racket 
(require point-free) 
(~> 1 
    (lambda (x) x)) 
;=> 1 
(~> 1 
    (lambda (x) (+ x 10)) 
    (lambda (x) (expt x 4)) 
    number->string 
    (lambda (x) (printf "~a seconds" x))) 
;=outputs> 14641 seconds 

Вы можете совместить это проще ~> с пакетом сокращенная-лямбда, такие как fancy-app сделать такие выражения, как это выглядит лучше.

(require fancy-app) 
(~> 1 
    (+ _ 10) 
    (expt _ 4) 
    number->string 
    (printf "~a seconds" _)) 
;=outputs> 14641 seconds 
+0

Такая распространенная путаница заставляет меня беспокоиться о том, что 'threading' является неправильной, особенно потому, что Racket допускает такую ​​гибкость, как« причудливое приложение ». Как вы думаете, стоит ли добавить отказ в документацию 'threading'? –

+0

Я думаю, что документация может быть намного понятнее. В первом примере это выглядит как transfrorms '(~> 1 add1 sqrt)' in '(sqrt (add1 1))', а затем следующий пример с 'bytes-ref' не имеет большого объяснения. Я не уверен, как вы должны представить концепцию, что она рассматривает выражения с круглыми скобками по-разному? –

+0

Ну, весь последующий раздел (раздел 1.2) объясняет пример с помощью 'bytes-ref'. Возможно, это нужно сделать более ясным? И хотя это кратко сказано, может быть, точка, что 'f' эквивалентна' (f) ', нужно сделать более заметной? –