Kontynuując moje "naukowe" aktywności zakończyłem lekturę "The Joy of Clojure: Thinking the Clojure Way", którą podsumowałem recenzją The "Why" of Clojure - mind-bending for enlightenment with idiomatic Clojure code w serwisie Amazon.com (nakłaniam do oddaniu głosu) i zabrałem się za kolejną książkę Clojure – Grundlagen, Concurrent Programming, Java. Tym razem będzie po niemiecku, a przez to zdecydowanie trudniej (dawno to było, kiedy władałem tym językiem w stopniu zadowalającym).
Jakby celem utrudnienia i tak już niełatwego zadania nauki Clojure po niemiecku, dostałem od Manning Clojure in Action, co przyprawiło mnie o niemały ból głowy - brnąć w przypominanie sobie niemieckiego (jedno z postanowień noworocznych), czy odłożyć to i zabrać się za drugą książkę, która pisana była z myślą o tym "Jak to zrobić w Clojure". Na razie Clojure z niemieckim przeważa.
Przeglądając reakcję czytelników po ostatnim wpisie Clojure finansowo uzasadniłem moje wewnętrzne przekonanie, że należy kontynuować temat programowania funkcyjnego z Clojure.
I właśnie w tym momencie zorientowałem się, że w prezentowanej aplikacji najbardziej zabrakło idiomatycznego Clojure, o którym tak wiele pisano w "The Joy of Clojure".
Było tak:
; zakładam 366 dni w roku 2012 i kapitalizację w dni wolne (niesprawdzone) (defn interest-rate-per-day [interest-rate-per-year] (/ (* interest-rate-per-year 0.01) 366)) ; funkcja pomocnicza do wyliczenia zysku (niewykorzystywana) (defn interest [present-value interest-rate] (- (* present-value (inc interest-rate)) present-value)) (defn future-value [present-value interest-rate periods] (* present-value (Math/pow (inc (interest-rate-per-day interest-rate)) periods))) (defn max-present-value [limit interest-rate periods] (/ limit (Math/pow (inc (interest-rate-per-day interest-rate)) periods))) (max-present-value 10000 8.1 31)Powinno być jednak tak (miejsca oznaczone przez ",,," w pierwszej funkcji służą *jedynie* wskazaniu, gdzie argument zostanie przekazany przez makro -> - usuń je, a zobaczysz zmianę, a raczej jej brak!):
; zakładam 366 dni w roku 2012 i kapitalizację w dni wolne (niesprawdzone) (defn interest-rate-per-day [interest-rate-per-year] (-> interest-rate-per-year (* ,,, 0.01) (/ ,,, 366))) (defn future-value [present-value interest-rate periods] (-> interest-rate interest-rate-per-day inc (Math/pow periods) (* present-value))) ; teraz dopiero zauważyłem, że future-value jest skopiowane w części do max-present-value :( (defn max-present-value [limit interest-rate periods] (let [v (-> interest-rate interest-rate-per-day inc (Math/pow periods))] (/ limit v))) (max-present-value 10000 8.1 31)Od razu ładniej, nieprawdaż?
Mówią, że po ilości idiomatyczych konstrukcji poznaje się poziom zaawansowania w danej dziedzinie i nie inaczej jest w programowaniu - czy to w Javie, czy Clojure, czy innym języku, nawet takim jak angielski, niemiecki, itp.
A jak to jest u Ciebie z idiomatycznymi konstrukcjami? Znasz jakieś w Javie? Ciekawym również Scali (pewnie _ jest swego rodzaju idiomem) czy JRuby.
Chyba coś Ci się pomyliło w drugiej implementacji max-present-value. Pierwsze wersja bez makra -> daje mi wynik 9931... a druga z makrem -> 1.0068834796647728E-4
OdpowiedzUsuńW końcu! (muszę jednak uważać z tymi wpisami z błędami, bo jeszcze wejdzie w krew) Wiesz dlaczego zwraca błędny wynik? (podpowiedź: kolejność)
OdpowiedzUsuńA co do uzycia samego makra ->. Jego użycia zaciemnilo mi troche obraz tego co tam napisane.
OdpowiedzUsuńOfftopic: daloby rade umieszczac komentarz tylko z nick/email/url a nie z tymi wszystkimi profilami?
Poprawiłem. Inaczej sformatowałem kod. Nie jestem z niego do końca zadowolony, ale niech zostanie dla potomności, jakie to potworki tworzyłem w okresie niemowlęctwa clojure'owego :)
OdpowiedzUsuń