Jest coś, czego nie mogę pominąć w makro wątku w Clojure.Nieparzysta różnica między nazwanymi i anonimowymi funkcjami podczas korzystania z makra gwintowania.
Mam mapę z wartościami, które są również mapami, i chciałbym sprawdzić w wyniku innego wyszukiwania. Niech mapa będzie prosta: {:a {:b 2}}
- najpierw chcę wyszukać klucz :a
, który da mu {:b 2}
, a następnie przejdzie w górę b
, wynikiem jest 2
. Klucz do drugiego wyszukiwania musi być wynikiem funkcji.
((fn [x] (get x :b)) ({:a {:b 2} } :a))
=> 2
Ok, zróbmy to bardziej czytelnym dzięki makrze do gwintowania.
(-> {:a {:b 2} } :a (fn [x] (get x :b)))
tj. Zastosuj :a
jako funkcję na mapie, a następnie zastosuj inną funkcję. Cóż, to nie działa: CompilerException java.lang.IllegalArgumentException: Parameter declaration :a should be a vector
Co dziwne, jeśli funkcja anonimowa ekstrahuje się do wyznaczonego jednego, to działa dobrze:
(defn f [x] (get x :b))
(-> {:a {:b 2} } :a f)
=> 2
lub nawet:
(def f (fn [x] (get x :b)))
(-> {:a {:b 2} } :a f)
=> 2
Dlaczego istnieje różnica między działaniem nazwanych i anonimowych funkcji?
Hmm, ciekawe, dzięki. Muszę opanować makra - oczywiście "pierwszy argument do każdego podformularza" nie oznacza "pierwszego argumentu anonimowej funkcji" - tak początkowo myślałem. –
tak, makra są bardzo dosłowne, więc widzi i zmienia nie 'fn', ale wywołanie' fn'. – noisesmith