Mapping every second item

utilities — cgrand, 17 April 2009 @ 10 h 58 min

I wanted to apply a function to every second item in a coll. I was considering writing something using interleave, take-nth and map or a combination of mapcat and partition when I thought of this:

(map #(%1 %2) (cycle [f identity]) coll)

I really love clojure’s map parallel processing. (I should ask if every? and some could be allowed to take several colls.)

mapsplice

utilities — cgrand, 25 March 2009 @ 22 h 11 min

I needed to update a seq as follows: apply a given function to items at specified indices and insert the result (a seq) in place.
My first laborious attempt involved extracting subseqs of untouched items, mapping the function on the remaining items then joining everything back. Bleh! (Really, I don’t like indices but this time I haven’t found a way to work around.)
I was sad when, suddenly, I found this shortest solution:

(defn mapsplice [f coll indices]
  (let [need-splice (map (set indices) (iterate inc 0))]
    (mapcat #(if %2 (f %1) [%1]) coll need-splice)))
;; (mapsplice #(repeat % %) (range 10) [7 3])
;; (0 1 2 3 3 3 4 5 6 7 7 7 7 7 7 7 8 9)

Simple variations on state machines in Clojure

unsorted — cgrand, 3 March 2009 @ 15 h 00 min

Given a transition function that takes the current state and an input value as arguments then (reduce transition-fn initial-state input) returns the final state.

If you are interested in intermediate states, you can use clojure.contrib.seq-utils/reductions instead of reduce.

If you want an asynchronous state machine, you can use an agent:

(def agt (agent initial-state))
;then each time you get an input-value:
(send agt transition-fn input-value)

If you add a watch to the agent, you can react to state transitions.

rest vs drop

unsorted — cgrand, 23 February 2009 @ 18 h 20 min

Now that fully lazy sequences are in the trunk, (rest a-seq) and (drop 1 a-seq) aren’t equivalent anymore:

user=> (def s (map #(do (println %) %) (range 10)))
#'user/s
user=> (def d (drop 1 s))
#'user/d
user=> (def r (rest s))
0
#'user/r

As one can see rest needs to realize the first element of s while drop doesn’t. The corollary is that (drop n s) holds on the whole seq (including the nth first elements) while rest computes the first element and then discards it.

Shadowing global names

unsorted — cgrand, 31 January 2009 @ 10 h 45 min

A nice article on Clojure that gives one wrong tip: to use #'var-name to access a shadowed global.
Don’t do that! You’d better use namespace-where-defined-or-alias/var-name.
There are several reasons not to use #'var-name:

  • it doesn’t work if the value of your var is not invokable,
  • it evaluates to something different: it returns the var an not its value. It happens that vars proxy function calls to their values but a var can be rebound:
    (def a (map str (range 10)))
    (def b (map #'str (range 10)))
    (take 5 a)
    <i>("0" "1" "2" "3" "4")</i>
    (take 5 b)
    <i>("0" "1" "2" "3" "4")</i>
    (binding [str identity] (doall a))
    <i>("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")</i>
    (binding [str identity] (doall b))
    <i>("0" "1" "2" "3" "4" <strong>5 6 7 8 9</strong>)</i>

NB: @#'var-name is better than #'var-name but, really, just use the namespaced symbol.

Living on the bleeding edge

utilities — cgrand, 27 January 2009 @ 19 h 34 min

You can try clojure libs straight from the cloud:

(add-classpath "http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/src/") ; sourceforge
(add-classpath "http://github.com/Lau-of-DK/clojureql/raw/master/src/"); github
(require '[clojure.contrib.duck-streams :as duck])
(require '[dk.bestinclass.clojureql :as ql])

Disclaimer:

  • add-classpath is not meant to be used anywhere but at the repl,
  • you’d better trust what you download,
  • if you are unlucky you can get an inconsistent snapshot,
  • use at your own risk!

Bindings and send

utilities — cgrand, 20 January 2009 @ 19 h 50 min

This morning on #clojure erohtar asked:

what is the best way to bind vars to a value when sending to an agent?

I don’t know if it’s the best way but it’s mine:

(defmacro capture-and-send
 "Capture the current value of the specified vars and rebind 
  them on the agent thread before executing the action."
 [vars agent action & args]
  (let [locals (map #(gensym (name %)) vars)]
    `(let [~@(interleave locals vars)
           action# (fn [& args#]
                     (binding [~@(interleave vars locals)]
                       (apply ~action args#)))]
       (send ~agent action# ~@args))))
;; usage:
(capture-and-send [*out*] a f b c)

I post it here because erohtar needed it, I needed it once so others may need it.

Enlive: yet another HTML templating library

unsorted — cgrand, 19 January 2009 @ 16 h 04 min
[UPDATE] I have rewritten Enlive, this posts doesn’t work with the actual Enlive.

Enlive is a selector based templating library.
Its main design goal is to decouple html and presentation code, that’s why Enlive templates are plain old html files (it will ease roundtripping with designers).
In code, you have to declare where (using CSS-like selectors) and how (using clojure code) to alter the html template.
The resulting templating functions are compiled (the html tree isn’t transformed at runtime) and yields a seq of strings.

Here is an example:

(deftemplate microblog-template "net/cgrand/enlive_html/example.html" [title posts]
  [:title] title
  [:h1] title
  [:div.no-msg] (when-not (seq posts) ~(html/show))
  [:div.post] (for [{:keys [title body]} posts]
           ~(at
              [:h2] title
              [:p] body)))

;; at the repl:
net.cgrand.enlive-html.examples=> (apply str (microblog-template "Hello user!"
             [{:title "post #1"
               :body "hello with dangerous chars: <>&"}
              {:title "post #2"
               :body "dolor ipsum"}]))

<em>"&lt;html>&lt;head>&lt;title>Hello user!&lt;/title>&lt;/head>
&lt;body>&lt;h1>Hello user!&lt;/h1>
&lt;div class=\"post\">&lt;h2>post #1&lt;/h2>
&lt;p>hello with dangerous chars: &amp;lt;&amp;gt;&amp;amp;&lt;/p>&lt;/div>
&lt;div class=\"post\">&lt;h2>post #2&lt;/h2>
&lt;p>dolor ipsum&lt;/p>&lt;/div>&lt;/body>&lt;/html>"</em>

(NB: manually edited to add linebreaks.)

(Disclaimer: original idea by Ozzilee)

Functionally growing a tree

mistakes — cgrand, 11 January 2009 @ 19 h 32 min

I was trying to write a restartable parser in Clojure when it occured to me that I was doing it wrong by not using clojure.zip to build the parse tree.
Update: follow-up

try-or, or-try, try-else or else-try?

utilities — cgrand, 8 January 2009 @ 18 h 26 min

I can’t decide which name is best for this macro:

(defmacro try-or
 "Evaluates exprs one at a time, from left to right. If a form returns a 
  value, this value is returned. If a form throws an exception, the next 
  form is evaluated. 
  If the last form throws an exception, the exception isn't caught."
 ([] nil)
 ([form] form)
 ([form & forms]
   `(try
      ~form
      (catch Exception e#
        (try-or ~@forms)))))
« Previous PageNext Page »
(c) 2012 Clojure and me | powered by WordPress with Barecity