On Mon, Dec 22, 2008 at 10:23 AM, Piotr 'Qertoip' Włodarek <qert...@gmail.com> wrote: > > Being new to Clojure, to Lisp and to functional programming in > general, I have some trouble wraping my head around it.
Looks to me like you're doing pretty well. > I came that far: > > (defn multiplication-row [n k] > (map (partial * k) (range 1 (inc n)))) > > (defn multiplication-table [n] > (map (partial multiplication-row n) (range 1 (inc n)))) > > (println (multiplication-table 3)) ; => ((1 2 3) (2 4 6) (3 6 9)) Nothing wrong there, though the #() reader macro is handy for building map functions: (defn multiplication-table [n] (let [r (range 1 (inc n))] (map (fn [x] (map #(* x %) r)) r))) When to get to nesting small functions, 'for' can be a nice alternative: (defn multiplication-table [n] (let [r (range 1 (inc n))] (for [x r] (for [y r] (* x y))))) So many fun ways to do this! But anyway, what you had is fine. > Now, how to pretty print this? > > This does not work - prints nothing - why?: > (defn pretty-print-row [row] > (map print row)) Because 'map' is lazy, and won't evaluate 'print' on any of the items sequence unless necessary. For functions with side-effects (like 'print') you'll generally need 'doseq', loop/recur, or 'dorun'. > This also does not work - throws > java.lang.UnsupportedOperationException: Can only recur from tail > position (hello_world.clj:47) - why?: > > (defn pretty-print-row [row] > (if (first row) > ((print (first row)) > (recur (rest row))))) > > Once I remove print expression, exception is not thrown (what the > heck?) You probably mean: (defn pretty-print-row [row] (if (first row) (do (print (first row)) (recur (rest row))))) Without the 'do', you had (foo bar) where foo is the return value of 'print' and bar is the return value of 'recur'. Using the "return value of recur" in any way other than as your own functions return value is not allowed, hence the exception. But even if that hadn't complained, 'print' returns nil and trying to call nil as a function would also throw an exception. Another approach would be to build the whole table as a string, then print just once: (defn multiplication-table-string [n] (apply str (for [row (multiplication-table n)] (apply str (concat (for [i row] (format "% 3d" i)) ["\n"]))))) user=> (print (multiplication-table-string 9)) 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 nil I'm not sure building the nested seqs separately is much of a win. This combines the entire operation into a single function: (defn multiplication-table-string [n] (let [r (range 1 (inc n))] (apply str (for [y r] (apply str (concat (for [x r] (format "% 3d" (* x y))) ["\n"])))))) --Chouser --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---