-
-
Save cassiel/978270 to your computer and use it in GitHub Desktop.
; Our legacy Java OSC library: | |
(def transmitter (net.loadbang.osc.comms.UDPTransmitter. (java.net.InetAddress/getByName "localhost") 10332)) | |
; Seriously non-idiomatic code. I'm only 20% of the way through the Joy of Clojure book... | |
(defn xmit [enc buffer] | |
"Transmit to encoder number enc, buffer is a sequence of integers." | |
(let [m (doto (net.loadbang.osc.data.Message. "/example/ring/map") (.addInteger enc))] | |
(doseq [n buffer] (.addInteger m n)) | |
(.transmit transmitter m) | |
)) | |
; There must be a better way to do this bit! | |
(def buf (map (fn [_] 5) (vec (range 64)))) | |
(xmit 1 buf) |
The trick, I guess, is to isolate calls to imperative legacy code behind Clojure's Agent machinery. That'll be the next step.
The only head-scratching moment was trying to figure out why it didn't work with "for", until I tried "doseq". Lazy evaluation, I'm guessing?
Absolutely - lazy evaluation can be a killer if you're relying on an explicit evaluation of all the iterations. I've been bitten by this quite a few times - particularly using map. You can often fix it by using a doall which will force evaluation.
It's all starting to make sense. The namespace machinery is still pretty unfamiliar, and I'm not sure how some of the macros operate (the "#()" function form is confusing me), but otherwise it's not too dissimilar from generic functional programming.
If you're happy with (fn [foo] (baz foo))
, then you can just see #()
as a less explicit (in terms of argument definition) shortcut form: #(baz %)
where %
stands for the argument.
If you need more arguments:
(fn [a b c] (baz a b c)) ;=equivalent to=> #(baz %1 %2 %3)
However, using the anonymous #()
with more than one argument is usually non-idiomatic.
So just see #()
as a shortcut for (fn [] ...)
Oh - right - it's doing([...])
as an evaluation. My Lisp is still a bit shaky...
Mine was completely non-existent before Clojure :-)
And yep, that one got me too. If you're looking for a fn that returns its argument take a look at identity
.
Oh, and as for GitHub's code markup in gist comments - can't get that to work at all. Obviously.
:-) It seems to be Markdown which means you can either surround your code with backticks for inline code such as this
or you can indent by over four spaces
for something
that spans multiple
lines
The Markdown seems to be seriously on the blink...
Here's how I formatted my previous comment:
:-) It seems to be Markdown which means you can either surround your code with backticks for inline code `such as this`
or you can indent by over four spaces
for something
that spans multiple
lines
It might be imperative code, but that's because you're using an imperative library :-) I think one of the coolest parts of Clojure is that you can do this if you need to.
BTW, creating a seq of 64 5s can be achieved with the following:
(repeat 64 5)
You'll gradually pick these cool little functions up as you go along :-)