#clojure log - Mar 01 2011

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

2:21 kilo__: (re-matches #"[a-zA-Z]* " "test")

3:46 bartj: if I have a list of vectors of size 2, eg: [1 2] [3 4]

3:47 to convert it into a hash-map I do: (zipmap (map first above_list) (map second above_list))

3:47 is there a better way ?

3:47 I think the map entries are vectors themselves, so I think there should be a function for this, to get back the original map?

3:49 grr, (into {} above_list)

4:07 TobiasRaeder: morning

4:07 is there a way to have methods with the same name and varying number of args or varargs in protocols?

4:08 pyr: hi

4:08 TobiasRaeder: hi :)

4:10 Chousuke: TobiasRaeder: I don't think protocols support varargs but you can do (defprotocol Foo (method [arg] [arg arg2])) for example.

4:12 TobiasRaeder: @Chousuke alright, sadly i kinda need something like (method-a [arg1]) and (method-a [arg1 arg2]) for convinience guess ill just have to name the 2. method-a method-b

4:15 pyr: ok, probably stupid question

4:15 but I can't get to go from a symbol to evaluating a function that has the same name

4:15 i.e, given :foo, calling (foo)

4:17 i meant keyword

4:17 not symbol, obviously

4:18 Chousuke: TobiasRaeder: convenience? what do you mean?

4:18 TobiasRaeder: I am kinda unhappy with the current wrappers around java.io.File (ie. i haven't found a function that wraps the File(String, String) constructor

4:18 Chousuke: TobiasRaeder: that syntax is only used when you define the protocol, when you implement it you write a (method [...] ...) block for each arg count

4:19 TobiasRaeder: my goal was something along the lines of (as-file "web") and (as-file "web" "WEB-INF") for example

4:19 oh, maybe i missunderstood you initially

4:19 think i did :)

4:19 Chousuke: probably

4:21 so what you want is (defprotocol FileOps (as-file [this] [this whatever]) and then implement those two for String

4:21 +)

4:22 a multimethod might be more flexible though. Protocols are faster but only polymorphic on the first argument.

4:22 protocol methods*

4:22 TobiasRaeder: yeah which is enough for me

4:22 but thanks that was exactly what i was looking for

4:27 @Chousuke mind looking at https://gist.github.com/848878 ? the first one doesnt work (throws Wrong number of args (1) passed to: user$eval2530$fn) for (as-file "filename")

4:27 @Chousuk the one i just wrote down (Foo and FooRecord work flawlessly)

4:33 Chousuke: TobiasRaeder: your extend-type syntax is wrong.

4:33 at least according to my docs :P

4:33 TobiasRaeder: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/extend-type

4:34 extend uses a map but extend-type seems fine

4:34 and it works for (as-file "web" "WEB-INF")

4:34 but the one param one throws the exception

4:34 Chousuke: huh

4:34 but it says there (baz ([x] ...) ([x y & zs] ...))

4:35 TobiasRaeder: oh wow missed that

4:35 obviously - its the important part in this case

4:35 Chousuke: what probably happened is your latter two-argument definition overrode the one-argument definition

4:36 they're both valid fn tails for a single arity so there would be no error I suppose.

4:36 TobiasRaeder: whats weird is that the foo example worked but now it's working

4:37 thanks for pointing that out :)

4:37 Chousuke: TobiasRaeder: defrecord uses a different syntax for some reason :/

4:37 TobiasRaeder: @Chousuke yeah mixing two different thing and not thining about them enough ... thanks :D

4:38 Chousuke: you've got extra apostrophes in your doc strings btw :P

4:39 TobiasRaeder: thx :p

5:02 khaliG: is there a nicer/easier way to persist some settings than slurping to file?

5:04 Fossi: java properties maybe

5:04 khaliG: hm, but doesn't still require reading writing files yourself?

5:05 Fossi: there's some to file or such

5:06 khaliG: i just want to avoid file io if i want to say some user setting

5:06 but i guess there isn't any convenience feature like that :(

5:07 *save

5:12 AWizzArd_: khaliG: you can store the user settings in a map and simply spit it on disk

5:12 When you want that data back then slurp it and read-string it.

5:13 khaliG: AWizzArd_, yup doing that for other stuff atm, that's cool at least its a clojure form and all. i just want to avoid dealing with files directly, if possible

5:17 Fossi: khaliG: the good thing about the property stuff is that it will go to $HOME$/.java-properties or such so you don't need any pathhandling

5:17 bad thing is it's not a nice format

5:18 khaliG: fair enough. I think i'm just going to sit down and write a Registry thing and use that throughout

5:29 Cozey: how to access resources in classpath from clojure?

5:33 khaliG: Cozey, same way as java

5:33 Cozey: so i need to just go through RT/baseLoader?

5:35 khaliG: Cozey, yep

5:36 clgv: seems thread local binding via "binding" is extremely expensive. is that true in general? is there anyway elegant way around it?

5:37 example: ##(time

5:37 (binding [*value* 1]

5:37 (doall

5:37 (map #(+ % *value*) (range N)))))

5:37 &(time

5:37 (binding [*value* 1]

5:37 (doall

5:37 (map #(+ % *value*) (range N)))))

5:40 khaliG: Cozey, hm check out clojure.lang.RT/baseLoader

5:41 Cozey: khaliG: there's no contrib package to support (. baseLoader getResources)? it returns some CompoundEnumeration, which is not easy to access (not sure how except completely using java interop)

5:43 hmm. is there a standard way to iterate over something with hasMoreElements/nextElement?

5:45 Chousuke: Cozey: you can use let to bind the value to a local if you want to close over it.

5:46 Cozey: mhm

5:46 Chousuke: Cozey: is that a java interface?

5:46 Cozey: none :-( http://download.oracle.com/javase/1.5.0/docs/api/javax/naming/CompoundName.html

5:46 what if i wanted to list directory in classpath?

5:47 Chousuke: file-seq?

5:47 Cozey: do i have to go through baseLoader/getResources, and forget about all clojure.contrib.io goodness ?

5:47 Chousuke: core has a couple iterator/enumerator/whatever seq constructors

5:48 Cozey: ok, got it! (file-seq (file (baseLoader/getResource ... ))

6:01 khaliG: if you overwrite some function in clojure.core is there a way to undo that?

6:02 raek: khaliG: overwrite as in (def conj ...) in your namespace, or (alter-var-root #'clojure.core/conj ...)?

6:03 khaliG: raek, i used defprotocol with methods called set and get

6:03 Chousuke: that shouldn't overwrite anything :/

6:04 khaliG: it did :/

6:04 raek: ok. then clojure.core/get is still intact, but your namespace contains a get -> your-ns/get mapping, instead of get -> clojure.core/get

6:04 khaliG: raek, correct

6:04 Chousuke: shouldn't Clojure throw an error in a case like that?

6:04 khaliG: it gave warnings

6:04 raek: khaliG: you can remove the var with (ns-unmap 'your-ns 'the-var) and then (refer-clojure) to put back the old one

6:05 Chousuke: hmm

6:05 raek: I think it gives a warning nowadays instead of an error to not break old programs

6:05 Chousuke: I dunno if you should unmap the thing from your namespace

6:06 wouldn't that render it inaccessible?

6:06 raek: Chousuke: for protocol functions or in general?

6:06 Chousuke: the functions

6:06 or hm, I guess in general

6:06 khaliG: raek, that did the trick, thank you

6:07 raek: ah, my interpretation of the question was that he wanted to call it something else but undo the mistake

6:07 khaliG: yep, i'll change the name to something else now

6:07 xkb: is it possible to stop one specific agent?

6:07 besides adding a control bool

6:08 raek: xkb: no

6:08 xkb: ok

6:08 I created a small tank simulation, where each moving element is an agent, including bullets

6:08 and that creates quite alot of threads sometimes :P

6:08 raek: if you use a thread pool manually (very similar to sending to an agent) you can call future-cancel on the future

6:09 Chousuke: xkb: so you didn't go the all-bullets-in-one-structure route? :)

6:09 xkb: Chousuke: tried that at first, eventually decided to try this anyway.

6:09 raek: but thread interruption only works directly for certain blocking calls. in general, you have to poll the current thread's interrupted status in your code

6:10 xkb: Chousuke: maybe I will convert it back.. as this solution slows the system downquite often

6:10 Chousuke: shouldn't the number of agent threads be limited anyway? :/

6:10 raek: which is in the end very similar to check a bool value

6:10 xkb: I now cary the state of :hit or :shot in each tank and bullet

6:10 and those flags act as control bools

6:11 it's not really elegant

6:11 khaliG: how does the all-bullets-in-one structure work? :s

6:11 raek: khaliG: note that it is possible to have a var called 'get' in your ns and still access the clojure one

6:11 Chousuke: khaliG: easily. just update the state of all bullets in one go.

6:11 khaliG: oh, i see

6:11 xkb: keep one ref with all bullets

6:11 khaliG: raek, understood

6:11 xkb: or at least that's what I did

6:12 Chousuke: you could even have all tanks AND bullets in one structure, really.

6:12 xkb: and I fixed the number of bullets

6:12 khaliG: so you update everything in ticks?

6:12 xkb: yes, actually 2 ticks

6:12 Chousuke: it should be easier to keep synchronised too

6:12 xkb: something I have to work on

6:12 Chousuke: if you have a bunch of agents it'll be hell to figure out what is going on at any single moment

6:13 xkb: I now have 2 freq. one for bullets, and one for tanks

6:13 Chousuke: so how are you going to draw the UI? :D

6:13 xkb: Chousuke: in a separate agent

6:13 acting on the grid of the world

6:13 and the world cells contain stuff

6:13 Chousuke: xkb: so do the other agents send it drawing commands?

6:13 xkb: like the ants demo

6:13 Chousuke: nope, the other agents now update "the world"

6:14 Chousuke: ah.

6:14 xkb: exactly like the ants demo

6:14 with the food etc.

6:14 it's kind of a strange mental model though

6:15 as the state of a tank is partially in the agent (position) and in "the world" (grid content)

6:15 Chousuke: I've been thinking that if you need efficient drawing in a functional program you'd probably have to construct a sequence of "drawing commands" from whatever happens when the world is updated.

6:15 because if you update the world data structure and then draw it, you'll have to redraw everything :/

6:16 xkb: hmm kinde lik FRP

6:16 like*

6:16 Functional Reactive Programming

6:17 Chousuke: I suppose. You could even construct a seq of update commands and then just send it to two receivers, the one that updates the world data structure, and the renderer. :)

6:17 xkb: Hmm might be fun to try

6:17 this needs to be finished before comming weekend :P

6:17 Chousuke: yeah, so maybe not :P

6:17 but it would let you keep the rendering logic neatly separate from the game logic

6:18 xkb: I'm going to do a presentation on Clojure parallelism/concurrency and use this as a case

6:18 Chousuke: designing "clean" functional programs seems to get tricky whenever UIs are involved :P

6:19 xkb: I must say, It was quite hard to escape from a more OOish design

6:19 Chousuke: I mean, haskell folks go arrows arrows and everyone else is just "er, hm, just write some imperative code"

6:19 :P

6:19 xkb: hehe indeed

6:19 or they put it in a Monad anyway

6:20 Chousuke: arrows are a generalisation of monads I think

6:20 xkb: even though I very much like Haskell :)

6:20 ye

6:20 Chousuke: or a related concept anyway

6:20 AWizzArd_: Chousuke: I did not follow the discussion. Was it explained above what you mean by "arrows arrows"? If not, could you please tell more about it?

6:21 xkb: AWizzArd_: it's a haskell concept: http://www.haskell.org/arrows/

6:21 Chousuke: AWizzArd_: I didn't mean much about it; all I know that haskell people have taken some pretty interesting approaches to UI programming and they use arrows :P

6:21 xkb: or actually it's more of an abstraction over computation

6:21 Chousuke: there was a really neat demonstration in some paper

6:22 they wrote a pong UI and then a mirror UI transformer

6:22 xkb: cool :)

6:22 Chousuke: then they combined the pong UI with the mirror UI thingy and got a mirrored pong UI

6:22 xkb: Still I always feel I have to dig up my cat. math. book to really understand it

6:22 Chousuke: and it was synchronised with the non-mirrored UI

6:22 both getting the same inputs

6:22 just rendering differently

6:22 really cool stuff

6:23 xkb: hmm think I'll google for the paper

6:23 sounds interesting indeed

6:24 Chousuke: I unfortunately don't remember the name of the library they used /:

6:25 the arrows page probably links to it

6:30 xkb: ah found it

6:30 http://conal.net/papers/genuinely-functional-guis.pdf

6:31 Chousuke: hmm, looks like my memory is not very reliable.

6:31 oh well, still cool stuff.

6:34 AWizzArd_: I see, thanks.

7:10 shafire: hi

7:11 G0SUB: shafire

7:11 shafire: why do I write the keys like :key value and not key: value? which reason behind this?

7:12 and why def?

7:14 companion_cube: because :key is a special kind of datatype

7:14 ,:hello

7:14 clojurebot: :hello

7:15 kilo_: ,'(does the comma invoke the bot ?)

7:15 clojurebot: (does the comma invoke the bot ?)

7:15 kilo_: yep it does !

7:15 xkb: ,(class :key)

7:15 clojurebot: clojure.lang.Keyword

7:16 xkb: ,(class something)

7:16 clojurebot: java.lang.Exception: Unable to resolve symbol: something in this context

7:16 companion_cube: ,(= :hello :hello)

7:16 kilo_: ,( + 1 2)

7:16 clojurebot: true

7:16 3

7:16 Chousuke: shafire: Clojure has pretty minimal syntax. Map syntax for example is nothing but {} and key value pairs

7:16 thorwil: where a value can be a key

7:17 Chousuke: shafire: so the following are valid maps: {:key 'val} {'key :val} {1 2} {"key" {:another 'map}} and even {{:a :map} 'val}

7:17 shafire: so, why not key: value - looks better?

7:18 Chousuke: shafire: what would key: be?

7:18 companion_cube: for the sake of uniformity

7:18 xkb: as far as I know a key can be anything implementing hascode/equals right?

7:18 Chousuke: shafire: and IMO it doesn't really look any better. :P

7:18 the : is just superfluous. why should it be there?

7:19 thorwil: shachaf: because the : has nothing to do with the following item, but only marks a key symbol as such

7:19 shafire: okay, and why def and not function or so?

7:20 Chousuke: def is for defining bindings to anything, not just functions

7:20 and since "fn" is the clojure term for a function, the define-function macro is called defn :P

7:21 shafire: :-)

7:21 today, it's my first day with clojure

7:21 Chousuke: defn is just a shortcut for (def foo (fn foo ...)) plus some other stuff :)

7:24 xkb: shafire: so do you like it? :)

7:24 Chousuke: if Clojure syntax seems weird to you, keep in mind that most of it is not actually defined in terms of text, but in terms of data structures

7:24 shafire: yeah, i like it, but it's complicated

7:25 but i have the feeling, the code is shorter

7:25 Chousuke: the data structures have a literal textual representation, but the syntax of things like defn or defmacro or defprotocol is defined by the data structures, not the text.

7:25 xkb: :)

7:26 shafire: (* 99999999999999999999999999999999999999 99999999999999999999999999999)

7:26 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.NumberFormatException: For input string: "99999999999999999999999999999999999999">

7:27 xkb: :P

7:27 clgv: performance question: does an algorithm written with iterate have significant duration overhead compared to a loop-recur one?

7:27 shafire: (* 99999999999999999999999 999999999999999999999999)

7:27 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.NumberFormatException: For input string: "99999999999999999999999">

7:27 shafire: mhm

7:27 how long?

7:27 Chousuke: for example, in (defn foo [params] body) there's no "paren, defn, string, bracket..." but "list:defn-symbol, name-symbol, vector of symbols, body"

7:29 though I guess this is not so important in the beginning. I just think it's good to keep in mind if you think clojure has weird syntax.

7:29 shafire: do you use intellij? good enough?

7:30 i like weird syntax :D

7:30 xkb: I use vim, but that's an exception in clojure-land

7:30 most use emacs I think

7:30 clgv: I use eclipse which seem to be rare too ;)

7:30 Chousuke: emacs with paredit and slime is just too good with lisp :)

7:31 xkb: vim has something similar nowadays

7:31 Chousuke: though I suppose some of the IDEs have comparable features already.

7:31 xkb: though the emacs version is far superior

7:31 however, my mind is wired in vim

7:31 Chousuke: vim is not very suited to working with external programs :/

7:31 clgv: <joke>I already had an operating system installed - so why should I install emacs too? </joke> ;)

7:32 Chousuke: it's got a nice editing model IMO but the implementation is bad.

7:33 it's great as a simple editor but when you need to extend and integrate it with other tools it shows its weakness :/

7:34 kilo_: hi, newbie here, how do i invoke the clojurebot

7:34 companion_cube: ,(+ 1 1)

7:34 xkb: use , as prefix

7:34 clojurebot: 2

7:34 kilo_: ,(* 99999999999999999999999 999999999999999999999999)

7:34 clojurebot: java.lang.ExceptionInInitializerError

7:34 Chousuke: numbers too large :P

7:34 kilo_: interesting. this works on my clojure box

7:34 Fossi: kilo_: if you just want a quick repl you can also message it in private

7:34 xkb: what's up with the bignums

7:35 Chousuke: ,(* 99999999999999999999M 99999999999999999999999M)

7:35 clojurebot: 9999999999999999999899900000000000000000001M

7:35 kilo_: M !!

7:35 Chousuke: ,*clojure-version*

7:35 clojurebot: {:major 1, :minor 2, :incremental 0, :qualifier ""}

7:35 khaliG: ugh protocols are confusing, shall i persevere or just use interfaces for now :/

7:35 clgv: whats up with sexpbot today?

7:35 xkb: persevere I'd say

7:35 kilo_: Fossi, tx, already have clojure version, was showing off to a (C++) friend

7:36 i meant clojurebox

7:36 Fossi: kilo_: well, i meant people tend to use it in here after asking that question and we all get spammed to death ;)

7:36 shafire: why do you like clojure?

7:36 kilo_: I understand.

7:36 Fossi: shafire: why wouldn't you?

7:36 xkb: elegant, terse syntax. no bloat

7:37 khaliG: xkb, ok i shall!

7:37 Fossi: lisp + jvm + nice datastructures = win

7:37 xkb: khaliG: good luck :)

7:37 hehe nice one

7:37 clgv: &(+ 1 2)

7:42 shafire: Fossi: win win:)

7:43 just one i don't like

7:43 nobody is commeting his code....

7:43 nobody has commented his code

7:43 https://github.com/richhickey/clojure-contrib/blob/master/clojurescript/src/clojure/contrib/clojurescript.clj

7:45 clgv: shafire: you are right. I hate the lack of commets, too. it makes a lot of things hard to understand

7:46 xkb: quite often in functional programming, functions are very short and therefore easy to understand without comments

7:47 but I agree, in contrib it's very hard to understand sometimes

7:47 clgv: then have a look in clojure core xkb - I pick a random definition and you explain it adhoc ;)

7:47 xkb: hehe hence the second sentence :)

7:48 core and contrib are very hard to read sometimes indeed

7:48 esp. with nested let bindings and stuff

7:49 clgv: it took me a while to get the details of the "defn" definition in there ;)

7:50 kilo_: hey, what does .....

7:50 ,(doc defn)

7:50 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any do...

7:50 kilo_: not too readable.... hmm

7:51 clgv: kilo_: I didn't mean the doc. I meant the implementation of "defn" ;)

7:52 xkb: for documentation you can also check http://clojuredocs.org/clojure_core/clojure.core/defn-

7:52 shafire: why are all clojure def so short? that is really amazing...

7:53 khaliG: shafire, compared to?

7:53 kilo_: clgv, true

7:53 that was easier to understand

7:54 shafire: khaliG: java

7:54 Dranik: java is designed to be understendable for brain-damaged people

7:55 kilo_: sorry clgv, i misunderstand . when you said 'in there' .....

7:55 clgv: kilo_: np

7:55 shafire: Dranik: you are so funny :D

7:56 and the clojure community is more active than the scala community

7:56 khaliG: shafire, i'm not sure.. i've got an almost complete program in about 500 lines of clojure and when i mocked it up in netbeans/matisse the generated code itself was about 1000 lines just for an older version

7:57 shafire: mh

7:57 Fossi: actually i like the code of core quite a bit

7:57 sometimes it's easier to just read the code than the random doc

7:57 esp for things like defn

7:59 clgv: I think e.g. the defn code would be easier to understand if there were some comments explaining the sub steps ;)

8:07 shafire: commenting clojure is a major step worth

8:10 see you later

8:10 bye

8:14 _fogus: amalloy_: Ping

8:24 semperos: _fogus: pretty sure he's a west coaster

8:24 _fogus: It was worth a shot.

8:24 semperos: :)

8:27 cemerick: _fogus: BTW, Ruby? :-O

8:27 ;-)

8:28 _fogus: OOP is the wave of the future!

8:29 cemerick: So I've heard.

8:29 Bizarrely, I've been tinkering with perl lately.

8:29 _fogus: Orgiastic mutation FTW

8:29 cemerick: I guess that's more deserving of a :-O

8:29 clgv: _fogus: whats that supposed to mean?

8:30 _fogus: Perl6?

8:30 clgv: What is what supposed to mean?

8:30 clgv: (14:19:54) _fogus: OOP is the wave of the future!

8:30 cemerick: Honestly, I'm not over the WTF stage enough to make any reasonable distinction between perl 5 or 6 yet.

8:32 _fogus: clgv: Haven't you heard the news? Object-oriented programming is the "way that the world works"

8:32 cemerick: clgv: I think writing a Clojure book makes one dread functional programming.

8:33 clgv: ah ok. :P

8:33 * _fogus reading http://groups.google.com/group/qilang/browse_thread/thread/84fb7adc8c45268e/c2d51658e9313453?hl=en=c2d51658e9313453

8:33 clgv: is that book finished now?

8:33 _fogus: clgv: I'm just playing... but I'm also not hardlined against OOP

8:34 cemerick: clgv: the above has a huge ;-) of course

8:34 * cemerick is clearly doesn't have the constitution to pull off a straight-man position

8:34 clgv: cemerick: yeah read it like that ;)

8:35 fliebel: cemerick: http://rubini.us/2011/02/25/why-use-rubinius/#wur-academic

8:35 "Despite vast odds, somehow programs are written that actually run."

8:36 _fogus: fliebel: Nice quote

8:36 cemerick: Everything is always despite vast odds.

8:36 s/somehow.*/somehow we moved out of the caves

8:36 etc

8:37 _fogus: Getting out of bed this morning was pretty tough too

8:38 cemerick: "Oh shit, I need to screw with dates today. GD ISO 8601"

8:39 _fogus: cemerick: I liked your tweet about the Scala levels.

8:39 fliebel: _fogus: Link?

8:39 _fogus: fliebel: To the original?

8:40 fliebel: _fogus: Noh, just curious what cemerick said.

8:40 cemerick: _fogus: It's bat-nuts crazy IMO. I have cynical theories as to why such a concept was surfaced.

8:40 Thankfully, I do keep my trap shut sometimes.

8:41 _fogus: http://twitter.com/#!/cemerick/status/40416922378051584

8:41 * fliebel just read Clojure is like Yoda

8:41 clgv: if I have a transient vector can I still change position "i" or is the "only" effect that conj!-ing is much faster?

8:42 _fogus: cemerick: That post is a perfect microcosm of the Scala community in general.

8:42 cemerick: clgv: nah, there's assoc! and dissoc! too

8:42 clgv: cemerick: thanks. thats what I wanted to hear ;)

8:42 cemerick: and pop! and disj!

8:43 disj! only for sets, of course

8:43 fliebel: And some more with some copy-pasting fom clojure.core :)

8:43 e.g. update-in!

8:44 cemerick: _fogus: I figured. Doesn't seem out of line with the crazy I was seeing before I left.

8:44 Eh, that's ungenerous of me.

8:45 I suppose it works for some. Just not my cup of tea.

8:45 _fogus: Scala's type system is so powerful that it also types the programmers themselves.

8:46 fliebel: _fogus: Nice one :)

8:46 _fogus: object Fogus extends A3 with L1

8:46 cemerick: hah

8:47 * cemerick 's hair catches on fire

8:47 * fliebel wraps cemerick in parens to extinguish him

8:47 cemerick: The haskell and F# folk don't seem to have such artifice though. Perhaps it's the "java.next" sword that hangs over the scala community's head that prompts such things.

8:47 _fogus: Scala's levels are too coarse... I can't properly mix them into myself!

8:48 fliebel: cemerick: Han, in Haskell, you'd just say Pepijn -> Pepijn and be done with it.

8:54 * _fogus is blown away by Haskell on a daily basis

8:55 * dnolen thinks that for non-FP and non-Lispers, Clojure must also seem like it has levels.

8:56 _fogus: dnolen: Can the same be said about any language?

8:57 clgv: if clojure had levels, the good thing would be that we could level up ;)

9:00 * _fogus reading hate-mail

9:00 lucian: clgv: imagine: "you're typing away, you just wrote a highly-concurrent web-server using the STM and your text editor goes: "DING! LEVEL 4!""

9:01 jkdufair: I think I need a guide like that for life itself. i.e. A1: respiration, defecation, A2... Z999: zen master

9:01 cemerick: lucian: now we just need unlockable achievements…

9:02 …and that's when I become a carpenter.

9:02 clgv: lucian: hilarious thought :D

9:02 fliebel: dnolen: I gave up the number stuff for a while. I tried to reason about it for a while, change a few things, but no luck.

9:02 octe: hehe, speaking of achievements and programming

9:02 http://blog.whiletrue.com/2011/01/what-if-visual-studio-had-achievements/

9:03 jkdufair: M-x swank-level-up

9:03 fliebel: octe, lik the new ms word, I read?

9:03 octe: octe, huh?

9:03 lucian: octe: that list's somewhat funny

9:03 octe: fliebel, huh?*

9:04 jkdufair: octe: literally LOL

9:04 _fogus: "You must go to El Dorado and talk with Chouser before you can reach the next level"

9:04 fliebel: octe: I read ms is planning to add achievements to word as a sort of 'game' to learn Word.

9:04 octe: oh

9:04 haha

9:04 that'd be funny

9:06 jkdufair: I tried to use PLT Scheme for a project. Amongst other things, the levels made me a bit nuts.

9:07 lucian: fliebel: reading that rubinius thing, it confirms my suspicion that Ruby programmers don't really know other languages

9:08 fliebel: lucian: How so?

9:08 lucian: the article treats bad and good languages just as badly, likely just because they're not ruby

9:08 fliebel: there's a dig at python, even comparing it to PHP to some extent. that's just nasty

9:09 also an "eww" directed at Groovy, which isn't really that bad

9:09 cemerick: No one can ever claim that Groovy is elegant, but it sure can get a job done.

9:09 reading that rubinius thing talking about "making ruby fast" reminds me of those hordes of really smart people working on making javascript fast, all due to one unfortunate historical accident

9:11 _fogus: cemerick: Which event? It's release?

9:11 lucian: cemerick: meh, ruby isn't nowhere near as crappy as js

9:11 i see ruby as almost as nice as python

9:11 hoeck: cemerick: which event, the inclusion in every browser?

9:11 fliebel: cemerick: As they put it in this book I have here, Ruby is made for fast writing, not fast execution.

9:13 cemerick: The accident being: the original 10-day spike, followed by its updake, distribution, and then shoehorning into a standard. Everything is predicated on that one break.

9:14 TimMc: lucian: My first encounter with Groovy was Grails, where I stared at the scaffolding code for about 20 minutes before I understood that they were trying to make a DSL using catchall methods. Then I burned my computer and ran away screaming.

9:14 cemerick: lucian: It's the "let's work on making language X fast" objective that made me think of the js connection, not anything related to the languages themselves.

9:15 _fogus: fliebel: I think that is perfectly valid in the abstract. I can't say that I find Ruby particularly speedy at composing, but that's probably just me

9:15 cemerick: It seems like once you're contemplating writing yet another VM, something's gone haywire.

9:15 lucian: cemerick: i see. well, i see it as a nice goal. languages shouldn't be designed first and foremost to be easy to write a fast implementation for

9:16 octe: The Joy Of Clojure is interesting enough that i'd actually want a dead tree variant

9:16 cemerick: lucian: oh, it's a fine goal. See, this is what happens when I expose my stream-of-consciousness. :-P

9:16 octe: i've never actually wanted to read a programming book before

9:16 lucian: cemerick: well, which vm to use? for many purposes the jvm isn unacceptable

9:17 and parrot isn't yet mature enough

9:17 fliebel: lucian: Rubinus, PyPy, Parrot, etc...

9:17 dnolen: _fogus: Clojure has far more levels than JavaScript, IMO

9:17 sacho: I don't see why javascript is "horrible" and makes programs written in it "slow"

9:17 cemerick: lucian: LLVM, parrot, mono

9:17 lucian: cemerick: well, they're using llvm

9:17 companion_cube: what do you call "levels" ?

9:18 TimMc: sacho: JS is great, IMO.

9:18 lucian: mono has dubious licensing issues

9:18 dnolen: fliebel: where you unable to implement the number stuff from TRS at all?

9:18 locks: rubinius

9:18 lucian: fliebel: and PyPy is awesome, but it's still writing a new VM

9:18 sacho: TimMc: sure, minus a few backward-compatibility inherited bumps.

9:18 lucian: fliebel: and you're forgetting that Ruby people hate Python (even though Python people rather like Ruby)

9:18 cemerick: lucian: all I know about it, I read on wikipedia :-P

9:18 locks: lucian: psh, those pesky whitespaces ;P

9:18 sacho: are people who use both python and ruby rythonists or pybyists?

9:19 fliebel: dnolen: I got the addition exactly as in the book and the minikanren source, but it has duplicated results.

9:19 lucian: sacho: that's a dreadful name

9:19 locks: is there a red snake?

9:19 sacho: why not. Rython, Python that compiles to ruby code!

9:19 _fogus: dnolen: I would agree with that. But there's more to js than meets the eye. I'm not sure many people understand that

9:19 lucian: cemerick: i see. they don't use llvm that much because llvm sucks for anything but compiling static code

9:19 dnolen: fliebel: hmm, is your all your work pushed to your fork?

9:19 lucian: sacho: there's unholy, which does the reverse

9:20 cemerick: pypy and parrot get a pass, since they were through the gate first. Seriously, if someone said they were starting a new VM project, they should get a lot of strange looks.

9:20 fliebel: sacho: There is a Python implementaion for Rubynus.

9:20 locks: I'm reading 'js the good parts' and falling in love with it :P

9:20 lucian: cemerick: i mostly agree, but i think that in this case it's partly justified

9:21 locks: try CoffeeScript and you'll love it even more :)

9:21 fliebel: dnolen: Yes, except that I flattened one all into the parent exist, which should not matter.

9:21 locks: lucian: it's because of CS that I wanted to learn JS properly ;)

9:21 the C-syntax really tricks you into thinking of js wrong

9:21 lucian: cemerick: for the record, i'm a pypy user and i plan to implement python on parrot

9:21 _fogus: dnolen: Although I might say that Clojure's required knowledge is less transferrable from other languages. In order to get experience in the types of things that Clojure advocates you need to have exposed yourself to many different languages.

9:21 dnolen: fliebel: I'll check it out later today.

9:21 _fogus: lucian: Until you need to debug i5t

9:22 cemerick: lucian: yeah, the perceived value is directly corollated with one's interest in ruby :-)

9:22 * cemerick knows basically nothing about ruby, FWIW

9:22 fliebel: dnolen: Only thing I did not do yet is computing the result by hand.

9:22 companion_cube: just, what do you call "levels" in the context of a language ?

9:22 lucian: _fogus: ?

9:23 dnolen: companion_cube: reference to this, http://www.scala-lang.org/node/8610

9:23 lucian: cemerick: they considered PyPy to be too python-y (stupid) and parrot immature (mostly correct)

9:23 companion_cube: uh, ok

9:23 and clojure has more levels?

9:24 * lucian is extremely skeptical of scala

9:24 pyr: clojure just made my day

9:24 https://gist.github.com/849172

9:24 cemerick: lucian: I have irrational faith in the parrot folks.

9:24 dnolen: companion_cube: ehhh, no, just that Clojure has many levels as well. Even more so for those unfamiliar with FP or Lisp.

9:24 lucian: cemerick: they do have awesome goals, don't they? join i.p.o#parrot

9:24 cemerick: companion_cube: I don't think anyone is going to be so daft as to attempt to codify "levels" for Clojure.

9:25 companion_cube: oh, yeah, i suppose it takes time to begin playing with some features like meta

9:25 lucian: the levels thing is stupid

9:25 octe: has anyone noticed that require'ing swank.swank increases compilation time a lot?

9:25 _fogus: I think Tony Morris's response to the Scala levels was apt. Vintage Morris.

9:25 locks: lol @ levels

9:26 makes me think of maturity levels *shivers*

9:26 cemerick: locks: I don't think the vernacular was accidental.

9:26 locks: _fogus: link?

9:26 Adamant: complexity is hard, let's go shopping

9:26 locks: complex is better than complicated

9:27 _fogus: locks: http://blog.tmorris.net/critique-of-oderskys-scala-levels/

9:27 locks: thanks

9:27 fliebel: Hm, dos Clojure have a PEP 20?

9:28 cemerick: fliebel: style guide, you mean?

9:28 fliebel: cemerick: 8 is style guide, 20 is zen.

9:28 lucian: cemerick: that's PEP 8

9:28 fliebel: (locks quoted it)

9:29 * cemerick has forgotten his PEP numbers. He's no longer even notationally a python programmer.

9:29 lucian: cemerick: try python -m "this"

9:30 * locks pats cemerick

9:30 * lucian pukes at that rubinius article yet again

9:30 * locks smacks lucian

9:30 locks: what's the rpoblem with it?

9:30 _fogus: We had a "style guide" in JoC up until the final editing phase, but threw it out

9:31 locks: haha

9:31 fliebel: _fogus: Why?

9:31 _fogus: fliebel: page count mostly, but also because it's really something that should be a living document rather than in a book

9:31 lucian: locks: it boasts a lot of features that rubinius doesn't actually have (yet, anyway)

9:31 _fogus: we will probably put it up on the site one day

9:32 fliebel: _fogus: (is it done nearly? I've only got 1.7 programming books left)

9:32 locks: lucian: it's blogpost-driven development :)

9:33 Fossi: yeah, that's quite a great comment to the level thing

9:33 fliebel: Man, #clojure is full of good quotes today :)

9:33 lucian: locks: not only that, but CRuby (or is it called MRI?) has those exact features

9:33 _fogus: fliebel: The delay of JoC is a very sore point for me... but yes, it's 1-2 days away from being sent to the printer.

9:34 fliebel: yay!

9:34 * dnolen finds the cover for The Little MLer hilarious ... Lisp and ML making a truce.

9:34 TimMc: _fogus: Congratulations!

9:35 eckroth`: _fogus: what delayed JoC? I too have been waiting a while but it didn't seem to me like it has been "delayed"

9:35 _fogus: If I ever consider writing another book again someone PLEASE shoot me

9:35 TimMc: aw

9:35 zoldar: _fogus, will this release have some substantial differences in comparison to the "final" MEAP release?

9:35 lucian: dnolen: heh

9:35 Fossi: i guess you have to be an author to get why every author says that

9:36 _fogus: zoldar: The final MEAP has yet to be released. But it will be mostly the same structure as the last MEAP update with less grammar errors and misspellings. :-O

9:36 eckroth`: Fossi: probably; maybe the authors always have personal deadlines that are not met; it's best we (not the authors of JoC) can just pleasently bide our time :)

9:37 pjstadig: JoC is stalled?

9:37 :-p

9:37 locks: lucian: I think it's MRI now, who cares as long as we understand each other :P

9:37 _fogus: eckroth`: I'll tell you over a drink one day... not in a public forum. Sorry

9:38 octe: interesting

9:38 eckroth`: _fogus: oh ok; thought it was just a silly thing like buggy copyediting software or whatever; no problem; glad it's soon on its way!

9:38 octe: the long compile times when requiring swank seems related to leiningen

9:38 takes 1m6s to compile a hello world which requires swank with leiningen

9:38 and 16s with cake, with no jvm running

9:39 fliebel: Okay, anyone in for spewing Clojure commandments?

9:39 "Namespaces are one honking great idea -- Clojure does more of those" ;)

9:39 _fogus: pjstadig: zing!

9:40 pjstadig: sorry...

9:40 i was totally joking

9:40 fliebel: "When faced with repetition, refuse the temptation to write a macro"

9:40 Fossi: yeah, c&p instead

9:40 fliebel: -.-

9:41 Dranik: fliebel, where did you read that?

9:41 fliebel: Dranik: I'm making it up right now.

9:42 "Functions are better than macroes" "Although macroes are better than mutability"

9:43 "fliebel may not be obvious at first unless you're Dutch."

9:43 Dranik: fliebel, that one about macro was really confusing

9:43 tscheibl: ,(let [x [:test]] (contains? x :test)

9:43 clojurebot: EOF while reading

9:43 tscheibl: ,(let [x [:test]] (contains? x :test))

9:43 clojurebot: false

9:43 tscheibl: shoud that worry me?

9:43 l

9:43 clgv: ,(doc contains?)

9:43 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric k...

9:44 fliebel: Dranik: It was. you have better suggestions?

9:44 tscheibl: ,(let [x '(:test)] (contains? x :test))

9:44 clojurebot: false

9:44 tscheibl: same

9:44 * dnolen finds the Zen of Python generally offensive and overly simplistic.

9:45 Fossi: it's fun to read

9:45 * fliebel finds the zen of Python fun

9:45 TimMc: Is there ever a case in Clojure where (identical? l (next (cons :foo l))) is false?

9:45 _fogus: tscheibl: contains? looks for keys only. It's not a function to look up values in a sequence

9:45 tscheibl: _fogus: ahh ok..

9:45 fliebel: tscheibl: I think some does that.

9:45 TimMc: That is, do the persistent data structures ever get swapped out for size-based optimization?

9:46 clgv: ,(let [x [:test]] (contains? 0 :test))

9:46 clojurebot: false

9:46 _fogus: ,(some #{:test} '(foo bar :test))

9:46 clojurebot: :test

9:46 clgv: ups lol mixed it

9:46 _fogus: ,(let [x [:test]] (contains? 0 x))

9:46 clojurebot: false

9:46 clgv: ,(let [x [:test]] (contains? x 0))

9:46 clojurebot: true

9:46 _fogus: (let [x [:test]] (contains? x 0))

9:47 I'm too slow!

9:47 clgv: and doing the same mistakes ;)

9:47 _fogus: :-(

9:47 * clgv has to refill coffee

9:52 clgv: hmm I have a bad feeling with this: I have an algorithm that is creating vectors with double and then calculating partial sums. Now I got the idea that the it could be a significant overhead to create all these vectors all the time in comparison to simply create one double array at the begin of the algorithm and reuse it every time. is that worth a shot or simply a bad idea?

9:53 raek: ,(let [x #{:test}] (contains? x :test))

9:53 clojurebot: true

9:53 clgv: these vectors with doubles are really one main part of the algorithm - approx. half of the time is spent there

9:54 dnolen: clgv: yeah doesn't sound like you should be using vectors here.

9:55 clgv: dnolen: so the reused double-array would be the way to go?

9:55 raek: clgv: do you need to pour the data into vectors, or could you manage with using lazy sequences directly?

9:55 dnolen: clgv: if performance is the most important thing yes.

9:57 clgv: raek: I need could exchange the vectors with a sequence but I guess the question woul remain the same

9:57 raek: for example, in (reductions f (vec (map g some-coll))), the vec is superflous

9:57 ...but this might not be the issue here

9:57 clgv: raek: it's a probability distribution that is calculated and then I draw a single element from it

9:58 dnolen: even so w/ vector or sequences you face the overhead of boxing, unboxing numbers.

9:58 * _fogus is shocked by the reaction to a little criticism of SO/Quora

9:58 raek: so you need to do look-up with an index?

10:01 clgv: raek: its concept is: (1) calculate probability for each element (2) calculate commulative distribution function (partial sums) (3) draw random value (4) get element related to random value

10:06 TimMc: Ah, so you don't know which element you'll be using ahead of time.

10:07 Unless... could you pick the random value ahead of time and only do the calculations necessary for that value?

10:07 TobiasRaeder: anyone knows an easy way to launch something (ie shellscript) and then pipe all output to stdout?

10:07 clgv: TimMc: yes, I don't know which element it'll be. I want to pick it at random with a certain probability distribution

10:08 TimMc: clgv: Is "draw random value" a random index into the vector or a random value *from* the vector?

10:09 * _fogus needs a version of range that takes a fn that uses previous values to generate the next value

10:09 octe: any opinions on berkeley db? (for java)

10:09 TimMc: _fogus: Like iterate?

10:09 clgv: TimMc: when I calculate the partial-sums the last one is total-sum. then I do (rand total-sum)

10:10 _fogus: TimMc: kinda yes

10:10 TimMc: With take?

10:11 clgv: I'm not sure I understnd the partial-sums stuff, unfortunately.

10:12 _fogus: TimMc: But I need the last n results to calculate the next value

10:12 TimMc: _fogus: Oh! Interesting.

10:13 _fogus: I'm sure someone has written it before.

10:14 TimMc: What's the use case?

10:14 clgv: TimMc: concept: (let [probs (map calc-probability element-list), partial-sums (reductions + 0.0 probs), rnd (rand (last partial-sums))] (select-element-index partial-sums rnd)

10:14 thats the idea

10:15 _fogus: TimMc: Curve fitting

10:15 TimMc: _fogus: hmmok

10:16 _fogus: ,(doc hmmok)

10:16 clojurebot: Gabh mo leithscéal?

10:16 _fogus: :p

10:18 TimMc: clgv: select-element-index grabs an element from the partial sums of the probabilities based on rnd?

10:18 Or does it give you the index?

10:18 It reminds of wrand.

10:19 clgv: only an index

10:19 whats wrand?

10:19 ,(doc wrand)

10:19 clojurebot: Excuse me?

10:19 TimMc: where did I see this...

10:20 pffft, never mind

10:20 It's something defined in ants.clj.

10:20 clgv: yeah thats what google said too ;)

10:21 TimMc: Is that basically what you are doing with the probs, though?

10:22 clgv: seems so at first glance. it looks similar to my first approach

10:23 I am trying the double array approach now.

10:26 it's just getting pretty ugly in comparison to the first elegant version

10:27 TimMc: clgv: Benchmark the two. Is the ugliness worth the gains?

10:27 clgv: I'll do

10:28 I am encapsulating it in a deftype

10:28 so it's hidden from the main algorithm

10:30 dnolen: clgv: are you using amap/areduce?

10:32 clgv: dnolen: no. loop-recur right now

10:40 with the new handling of java primitives in 1.3 will a transient vector of doubles be almost equivalent to a double array in terms of performance?

10:45 dnolen: clgv: no

10:45 clgv: from what I understand transient gvecs are going to happen until after Pods.

10:46 s/are/aren't

10:46 jcromartie: does it make sense to have a "lazy set"

10:46 ?

10:46 I guess not

10:47 clgv: dnolen: what is "Pods"? sexpbot seems to be on holidays...

10:48 dnolen: clgv: rhickey's new reference type for dealing POJOs as well as unsafe mutable code w/o having to manually deal with locks.

10:49 jcromartie: Pods ~ Beans?

10:49 dnolen: clgv: ultimately, map + gvec of prims should be as fast amap/areduce. transients will become implementation detail.

10:49 clgv: dnolen: ok. I hope there is going to be a lot of docu on new features when 1.3 is released

10:51 ah gvec = generic vector

10:51 dnolen: clgv: none of what I described is slated for 1.3 as far I know.

10:52 clgv: dnolen: oh ok. so it's "planned" for later?

10:53 dnolen: clgv: something like that.

10:55 ttmrichter: What's the current best package for "install and have a REPL" to introduce a new Clojure user to the technology?

10:56 TimMc: ttmrichter: leiningen is a build tool, but I think it's a pretty fast way to get a REPL

10:57 ttmrichter: I'm targetting a Windows user here: someone who's going to want an installer and a clicky-icon.

10:57 TimMc: heh

10:58 Are you sure you want someone writing programs who can't handle running a self-install script? :-P

11:00 zoldar: ttmrichter, http://www.try-clojure.org/ could be of some use to some extent

11:00 for the basics at least

11:02 ttmrichter: Is "Clojure Box" any good?

11:02 It seems to fit the bill here.

11:03 Hmmm... The Emacs thing might be a tough sell.

11:10 clgv: ttmrichter: you might try eclipse counterclockwise

11:11 ttmrichter: I was just about to ask about Counterclockwise and Enclojure.

11:11 clgv: ttmrichter: if you have eclipse setup you just need to add the update site and install CCW and then create a clojure project

11:11 ttmrichter: I'm not sure if my target uses Eclipse or Netbeans (probably Eclipse).

11:12 Are these plugins any good?

11:12 As in do they provide a REPL, build suites, etc.?

11:13 jkdufair: I have to say, Clojure Box is very very nice

11:13 works out of the... well, box

11:13 clgv: CCW has a repl. but the one in the stable version feels a bit odd when using ;)

11:13 jkdufair: Emacs is not hard to learn

11:14 And Emacs can be pretty clicky and guified these days if that's what they prefer

11:14 ttmrichter: jkdufair: Given that I can't stand emacs myself, I rather doubt I'm in a position to tell someone else to use it.

11:15 jkdufair: Alas

11:16 * ttmrichter is a bit auld-skool: a window with an editor (ABE), a window with a REPL, a window for the command line.

11:17 jkdufair: That's exactly how I work in Emacs

11:17 ttmrichter: When I say "window" I mean "a window with a shell".

11:17 Not a window plied to the gills with bucky-bits and wrist-torture. ;)

11:18 jkdufair: M-x shell

11:18 there's a window with a shell :-)

11:18 ttmrichter: And the window with the ABE editor?

11:18 (ABE stands for "Anything But EMACS".:)

11:18 jkdufair: Oh. I don't have that.

11:19 ttmrichter: I do. It's called xterm (or something equivalent like gnome_terminal or the like). :D

11:19 jkdufair: paredit mode is the real juice. it lets the developer THINK in s-expressions and not in text

11:21 my brain is too small to think at a character level

11:22 Chousuke: I don't think I think in either characters or s-exprs, but since you're manipulating s-expressions anyway there's no reason not to use something like paredit

11:23 jkdufair: Yeah, I don't suppose I think in s-exprs, per se, but I think about manipulating them

11:35 TimMc: ttmrichter: I finally went over to the dark side and learned Emacs: http://www.brainonfire.net/blog/emacs-n00b-start/

11:35 zoldar: I'm a vim user who recently switched to emacs - with viper-mode it's really fine experience

11:36 the only pain I have recently, is working with mixed html/js content - this one really sucks :(

11:37 there's nxhtml for emacs but it doesn't play too well with newer versions

11:38 TimMc: zoldar: I try to avoid embedding CSS and JS in HTML beyond trivialities; remembering to escape < and > as SGML hurts my brain.

11:39 zoldar: TimMc, I also try to reduce it to the minimum, but even then, it's a bit of a bumpy ride

11:40 ttmrichter: TimMc: I've learnt emacs. I just don't like it. :)

11:40 TimMc: heh

11:40 It took me three tries over the course of 2 years.

11:41 Paredit mode is fantastic, and that's the only reason I use the thing.

11:41 Nothing else compares in that regard.

11:42 clgv: so well I have the changed version running now and it's actually a bit slower... :(

11:42 no reflection-warnings though

11:42 TimMc: clgv: >_<

11:43 clgv: yeah well, the question is only: can I improve it or do I just delete that branch and go on somewhere else ;)

11:46 the strange thing is that most of the time is spent in calculating the single probabilities which was done almost the same before.

11:53 hv: ,(let [c Integer] (class c "10"))

11:53 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$class

11:53 hv: oops

11:53 ,(let [c Integer] (new c "10"))

11:53 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: c

11:55 TimMc: Yeah, classes aren't exactly first-class. :-/

11:55 zoldar: ,(let [c Integer] (clojure.lang.Reflector/invokeConstructor c (object-array [4])))

11:55 clojurebot: 4

11:56 raek: there are class objects (as c above), but new is a special form and does not evaluate its first argument

11:56 TimMc: Why would it not?

11:57 raek: the compiler wants to decide which constructor to use at compile time

11:58 the byte code for instantiating a class is just an instruction or two

11:59 hv: raek: in my situation I need to decide at runtime, so is there another fn or macro that helps here?

12:00 zoldar: hv: you can use reflection, but bear in mind that it can be a significant performance hit

12:00 raek: hv: if you need it at run time, reflection is a good option (and the Reflector class presents a fairly simple API to do it)

12:01 hv: in some cases, you can solve the problem with macros

12:02 (assuming that you can make the decision at macro expand time)

12:03 hv: zoldar, raek: thanks, I guess I go with invokeConstructor.

12:04 TimMc: ,(new Integer (identity "15"))

12:04 clojurebot: 15

12:05 TimMc: raek: In the above example, I'm sure the compiler did not know what constructor to use statically.

12:06 raek: IIRC, the compiler emits code that uses reflection when the class is known, but the exact constructor is not

12:06 hv: Perhaps there is a reflective-new somewhere? like: (defn reflective-new [c & args] (clojure.lang.Reflector/invokeConstructor c (object-array args)))

12:07 TimMc: Ah, OK.

12:07 raek: hv: where from do you get the class?

12:07 zoldar: hv: there's none (in 1.2 at least) - I have this very function in my personal toolbox

12:08 hv: zoldar: hmm, what do you call it?

12:08 zoldar: make-instance

12:10 hv: however, if you gave more context about what you want to do, folks here could suggest some better solution

12:11 raek: hv: sometimes you can get away with something like (defmacro instantiate-class-by-name [name & args] (let [c (name->class c)] `(new ~c ~@args)))

12:11 in case you know the class, but have the name in some other form

12:12 zoldar: reak, are you sure that this macro will work?

12:12 raek, argh, sorry

12:12 hv: raek: what is name->class

12:12 ,name->class

12:12 clojurebot: java.lang.Exception: Unable to resolve symbol: name->class in this context

12:13 raek: lets assume that you have the class name in string form, then name->class would be the clojure function 'symbol'

12:13 amalloy: i find myself using (juxt identity more-functions) a lot. i want to write myself a little function wrapping that up, but i can't decide if it should be like (def annotate (partial juxt identity)) or (defn decorate [obj & fns] ((apply juxt identity fns) obj))

12:14 ie, both names make sense, and it could plausibly either return a function or immediately apply itself to a value

12:14 raek: hv: the point is, as long as you can make some clojure code that can construct the class name as a symbol, and then invoke that code in the macro, you can do all this at compile time

12:15 hv: raek: thanks, I have to think about it. Right now I am not sure if I can know the class name at compile time.

12:16 raek: the exreme case of runtime would be if the class name is something that the user enters into a dialog box in the middle of program execution

12:17 in that case you would need reflection

12:17 in a case where you want to read the class name from a file at application start up, you can use macros

12:18 so maybe "startup time" and "in-the-middle-of-execution-time" would be better terms :-)

12:18 hv: raek: I see, thanks.

12:19 amalloy: raek: it sounds pretty hard to read at startup time if the user is using an aot jar file though, right?

12:20 raek: hrm. good point.

12:21 amalloy: but if they have an actual clojure compiler, then yes, it can be pretty cool to have the compile cycle involve reading config from disk :)

12:26 TimMc: amalloy: That's almost as good as popping up a modal dialog from the macro to ask the user!

12:26 Someday I will hold a Macro Abuse Competition.

12:28 amalloy: TimMc: you will have to work pretty hard to beat even the iocc, and they barely have macros available

12:29 TimMc: I'm not restricting the concept to obfuscation.

12:34 Adamant: put fear in the hearts of the unbelievers

12:35 (I joke, of course)

12:38 Bennyl: Hi I am trying to debug some code that I am writing I use swank with debug enabled and I can di breakpoint but cannot step into/ out etc, can it be done?

12:41 rhickey: the latest push makes it so that fns only get code to support metadata if they have metadata when defined

12:41 metadata support was a significant part of the code for small fns, and rarely used

12:43 fliebel: rhickey: Does this mean one cannot attach metadata to a fn later?

12:43 amalloy: fliebel: you already can't, because fns are immutable, right?

12:44 rhickey: fliebel: right, not unless it has metadata when defined

12:44 amalloy: I presume he meant with-meta semantics

12:44 fliebel: right

12:44 TimMc: Is it a memory consideration?

12:45 amalloy: hm. so (with-meta (fn [] 10) {::whatever "value"}) won't be legal either?

12:46 TimMc: Or (defn annotate [f] (with-meta f {...}))

12:46 fliebel: IMO, unless there is a huge gain, I don't think it outweighs the inconsistency and possible troubles in existing code.

12:47 rhickey: LISP programmers know the value of everything and the cost of nothing. - Alan Perlis

12:48 amalloy: actually the only time i've put meta on functions i did it with (with-meta (memoize (fn [x] ...)) {:key value})

12:48 and it sounds like i won't be able to do this anymore?

12:49 rhickey: TimMc: memory, time spent in validation

12:49 TimMc: ah

12:50 rhickey: but one could easily make a fn wrapper that had metadata and forwarded to a wrapped fn

12:51 fliebel: rhickey: Is there any way to get etadata on an existing function now, except for wraping it in another function? ah, you're faster.

12:51 amalloy: rhickey: oh, like (defn {} meta-able [f] (fn [& args] (apply f args)))?

12:51 rhickey: user=> (meta ^{::whatever "value"} (fn [] 10))

12:51 {:user/whatever "value"}

12:52 just put the metadata on the fn form

12:52 amalloy: i see

12:52 i confess i'm not very comfortable with the ^ reader macro

12:53 as in, unfamiliar, not "it disturbs me"

12:54 TimMc: What's this double-colon nonsense?

12:54 drewr: ,[:foo ::foo]

12:54 clojurebot: [:foo :sandbox/foo]

12:54 drewr: TimMc: ^^ 'sandbox is *ns*

12:55 TimMc: Namespaced keywords? Or just a way to get keywords that start with *ns*/ ?

12:55 fliebel: rhickey: Maybe a bad idea, don't know, but would it work to make with-meta wrap the function itself? (defn with-meta [bla bla] (fn? bla (fn [] (apply ^meta bla bla)))

12:57 TobiasRaeder: anyone here tried using lancet to integrate external ant tasks into leiningen?

12:57 rhickey: fliebel: that might be possible

12:58 at some cost in perf vs direct support

12:58 direct support is still provided if you have metadata at definition

12:59 technomancy: TobiasRaeder: yeah, the lein-tar plugin does that

13:02 TobiasRaeder: @technomanct alright, thanks a ton i will look into it :)

13:04 TimMc: holy crap I *just* got the joke behind Leiningen's name

13:04 I am an idiot.

13:09 _fogus: TimMc: The later. ::foo ---> :my-cool-ns/foo, but nothing prevents you from just doing :my-cool-ns/foo at any time

13:09 TimMc: Interesting.

13:12 rhickey: fliebel: ok - https://github.com/clojure/clojure/commit/2b16fee78a0517bc83dd5735ab01d3d5813b1f72

13:14 so, now the change is just an efficiency difference, not (much) of a capability difference

13:15 TimMc: "Keywords are like symbols, except [... t]hey cannot contain '.' or name classes."

13:15 amalloy: $source vary-meta

13:15 sexpbot: vary-meta is http://is.gd/50kMdS

13:15 rhickey: actually no capability difference, the wrapper can't do arity chewcking but the wrappee will

13:15 TimMc: How does ##:Integer not name a class?

13:16 ,:Integer ; rather

13:16 clojurebot: :Integer

13:16 amalloy: TimMc: the same way that "Integer" doesn't name a class: only ##(Class/forName "Integer") does

13:16 sexpbot: java.lang.ClassNotFoundException: Integer

13:17 amalloy: rhickey: so (meta (fn [])) will return {}, right?

13:18 rhickey: amalloy: nil

13:18 amalloy: rhickey: then vary-meta needs updating

13:18 doesn't it?

13:18 TimMc: amalloy: That seems vacuously true; keywords aren't classes therefore they can't name them. Or do I not understand the word "name" here?

13:19 amalloy: TimMc: i tend to agree; perhaps what is meant is that keywords can't be interned in your namespace to resolve to classnames

13:19 rhickey: amalloy: no

13:20 TimMc: amalloy: In short, keywords only evaluate to themselves?

13:20 dnm: Does dmiller hang out here?

13:21 rhickey: amalloy:

13:21 user=> (meta (vary-meta (fn []) assoc :a 1))

13:21 {:a 1}

13:21 ahihi: is there a strict variant of map that doesn't collect results? (for side effects)

13:21 amalloy: rhickey: ##(vary-meta (fn[]) conj [:a 1])

13:21 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IPersistentMap

13:21 amalloy: hrm

13:22 ahihi: check out dorun and/or doseq

13:22 rhickey: amalloy: expecting conj to work on something that might not have metadata is broken

13:22 amalloy: okay

13:22 LauJensen_: Morning :)

13:23 ahihi: well, I guess I'm just looking for a predefined name for (comp dorun map) :)

13:23 amalloy: i assumed it was working before and broken after, but if it's broken before i don't mind - it is a bad idea, as you say

13:23 ahihi: doseq's for-style syntax seems a bit verbose since you have to introduce a variable

13:23 amalloy: ahihi: depends what you're using it for

13:24 if you don't *really* have to use map in the first place, then dorun/map is more verbose than doseq

13:24 ahihi: basically just (dorun (map f xs))

13:24 amalloy: ahihi: sure, if f already exists

13:24 ahihi: it does

13:25 amalloy: but compare (dorun (map #(do stuff to %) args)) to (doseq [a args] (do stuff to a))

13:25 ahihi: sorry, the verbosity remark was only about this case, not in general

13:25 amalloy: anyway whatever, use whichever makes more sense

13:25 yeah, i'm sorta defending doseq for no particular reason

13:26 ahihi: :)

13:26 well, thanks for the pointers

13:27 amalloy: ahihi: no problem. here's another: 0x4ba330f8

13:28 chouser: rhickey: I'm curious what prompted the fn metadata change.

13:29 rhickey: chouser: I built just the Java bits of Clojure the other day, by hand, with javac - 5 secs, 500k, made me sad

13:29 :)

13:30 drewr: cinc is nigh?

13:30 rhickey: chouser: but given the latest changes the ony change is less waste compiling, loading, verifying code for metadata support that no one will use

13:30 chouser: i.e. with wrapper gen, no loss of metadata for fns

13:30 just no per-fn code to support it

13:33 chouser: in general I was looking for ways to slim donw CLojure and improve startup time, as more people look to use it as a library, on Android etc

13:34 we need a way to strip out all the interactive stuff when delivering as a runtime library

13:36 fliebel: rhickey: Great, so you implemented my auto-wrapper idea?

13:36 rhickey: yup, done

13:36 cemerick: rhickey: which is more common than not outside of "real" development -- updating a production webapp and such via a REPL is cute, but impractical most of the time.

13:37 rhickey: cemerick: well, not so much losing the repl as losing, e.g. doc and arglist metadata, but yeah, could strip compiler and ASM too

13:38 I implemented lazy fn loading, helps with startup time somewhat

13:38 but no big wins anywhere - we suffer from class-per-fn and verification of same

13:39 fliebel: rhickey: Wait, aren't functions defined with meta already? user=> (meta (defn a [] 3))

13:39 {:ns #<Namespace user>, :name a, :file "NO_SOURCE_PATH", :line 3, :arglists ([])}

13:39 amalloy: fliebel: ##(meta (fn[]))

13:39 sexpbot: ⟹ nil

13:40 rhickey: fliebel: that's the metadata of the var

13:40 fliebel: Ah, of course....

13:42 ataggart: Regarding android space/time trade-off, the switch bytecode emitted from case can currently have up to 8k entries since it always uses table instead of lookup. Might not be significant.

13:45 rhickey: ataggart: thanks for that patch! I hope to get some time to look at it soon

13:46 ataggart: rhickey: the code is much longer than I anticipated when first embarking on it.

13:46 __name__: is the clojure book from pragmatic programmers still valuable for 1.2?

13:49 ataggart: rhickey: have you had a chance to look at the compiler/reflector patch on CLJ-445?

13:50 technomancy: __name__: sure

13:51 __name__: Is it any good? The example chapters were a bit short to judge, but I liked what I saw

13:52 khaliG: is putting a form at the top level of a clj file a good way to ensure it's evaluated, and only once?

13:52 technomancy: __name__: I liked it a lot. it's short, but to the point.

13:54 khaliG: or shall i use an init atom?

13:55 amalloy: khaliG: that ensures it's evaluated exactly once, but you may want to be careful if you ever AOT-compile

13:55 because it will be evaluated at compile time as well as runtime

13:55 khaliG: ooh, i see. ok thanks.

13:56 amalloy: (disclaimer: the above is probably an unintentional oversimplification but it's been correct enough for me in the past)

13:57 khaliG: well tell me if there is a better way to do this.. but hte first time i call get-registry, it should open up a file and read some data into a map. Subsequent calls to get-registry ought to return that map.

13:58 amalloy: khaliG: memoize

13:58 khaliG: amalloy, sounds good!

13:58 amalloy: (def get-registry (memoize (fn [] (do expensive stuff))))

14:15 konr: Is there a doseq-like function that collects the results of every interaction?

14:16 TimMc: konr: You can force a for.

14:17 (dorun (map ...)) or (dorun (for ...))

14:17 konr: oh, I got it! Thanks, TimMc

14:17 TimMc: konr: Wait!

14:17 amalloy: TimMc: that doesn't collect the results

14:17 TimMc: yeah

14:17 amalloy: doall

14:17 TimMc: That's the one.

14:18 konr: http://clojuredocs.org/clojure_core/clojure.core/doall <-- good site for finding related functions

14:18 amalloy: $findfn [1 2 3 4] [1 2 3 4]

14:18 sexpbot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/list* clojure.core/time clojure.core/dosync clojure.core/distinct clojure.core/lazy-cat clojure.core/sequence clojure.core/with-loading-context clojure.core/vec clojure.core/concat clojur... http://gist.github.com/849677

14:18 amalloy: hm. not as useful as i'd hoped

14:18 but doall is in there!

14:25 redinger: Clojure Conj 2011 information has been posted: http://clojure-conj.org

14:27 swart: so I've more or less got my clojure/emacs env set up (modulo firewall issues), but now I'm a bit confused about the dev process itself

14:28 I have a repl, I have a buffer with a file in it, and I have various packages I can manage with lein. but how do I load packages into the repl and interactively update my code based on changes I make there?

14:29 amalloy: swart: do you have a swank server running?

14:29 swart: yes

14:29 amalloy: C-c C-k will feed the contents of the current buffer to the repl

14:29 swart: ah ok

14:30 I saw C-c C-k and I confused it with C-c C-j to compile the buffer

14:30 amalloy: see also the many handy things under the SLIME toolbar like C-c C-d C-d to see docstring for var at point

14:31 swart: ok. I'm running emacs -nw due to the firewall problems but I think I'll have a look

14:31 clearly I need to read more docs :)

14:32 amalloy: swart: ah. there's a way to get at the toolbar in -nw, and while overall i approve of -nw i don't use it that often in practice

14:33 swart: M-` does the trick

14:33 amalloy: sweet

14:33 lpetit: rhickey: hello. can you explain more what is behind "lazy fn loading" ? Does it mean that not all fn code will be JIT compiled and/or loaded in memory until it is first evaluated (in a callable or argument position) ?

14:33 amalloy: lpetit: he left

14:33 lpetit: amalloy: oh ok, thx

14:33 amalloy: do you understand what's behind "lazy fn loading" ?

14:34 amalloy: your guess is about the same as my guess was

14:34 hiredman: lpetit: my guess is a change to how the code for namespaces is generated

14:34 lpetit: Currently if there's an area where we pay for what we don't necessarily use, it's the fact that by means of transitive deps, all code of all fns constituting one's application is loaded on startup time.

14:35 hiredman: hmm, is your guess even more precise than that ?

14:36 hiredman: defns maybe hold a reference to a instance of FnThunkLoader instead of the instance of the function

14:36 lpetit: e.g. : unless the Android underlying framework uses lazy loading heavily itself and an Android app benefits from it out of the box (presumably via wrapper java classes), then if the android app has 20 screens, and the user only uses one, chances are the code for the 20 screens is loaded on startup, everytime

14:37 hiredman: FnThunkLoader loads the fn it puts to via something like Class/forName and caches it

14:37 points

14:37 amalloy: hiredman: both devious and useful

14:37 hiredman: lpetit: *shrug* until android gets a real gc, I doubt it is viable anyway

14:38 that is a guess, I just scanned the diff

14:38 lpetit: hiredman: of course, I know you can generalize from my example. Same problem for ccw with OSGi, for example.

14:39 hiredman: the latest version of Android still not ok wrt to this problem?

14:39 hiredman: lpetit: don't follow it too closely, but I don't imagine it is a priority for google

14:41 lpetit: hiredman: granted

14:41 hiredman: oh, and then fnthunkloader sets the value of the var root to the instance of the class

14:44 lpetit: so, somehow, requiring a namespace would now just create vars full of "lazy thunks" of fn ready to load (compile?) bytecode (from disk) ?

14:47 _fogus-away: Whoa! http://clojure-conj.org

14:48 konr: What's the clojuresque way of dealing with queues, dequeuing and multiple threads? (dosync (let [new @foo] (alter foo rest) (first new)))?

14:50 brehaut: konr: if you want a queue then clojure.lang.PersistentQueue might be what you are after

14:54 hiredman: pq doesn't block

14:55 ataggart: cemerick: http://dev.clojure.org/jira/browse/CLJ-426

14:58 brehaut: hiredman: would the java.util.concurrent.BlockingQueue be a better choice then?

14:59 hiredman: depends if you want to block (I almost always do)

14:59 brehaut: hiredman: i have no idea on his usecase

14:59 ataggart: how about seque?

15:00 Dranik: is anyone from Belarus here?

15:04 OlegYch: me

15:06 cemerick: ataggart: looks like a sizable job :-)

15:07 ataggart: it was, but the performance gains were worth it.

15:07 plus being able to use enums will be nice

15:08 I found your blog post when I was embarking on it. your and cgrand's comments pointed me in the right direction.

15:09 cemerick: ataggart: looks like you're evaluating e.g. static fields and such?

15:10 er, maybe not

15:10 ataggart: evaling the symbol ns to see if it's an enum class

15:10 then evaling the whole thing to see if it's also the same enum class

15:10 I wanted to avoid inadvertently screwing something up, hence the ns eval first

15:11 cemerick: sure

15:11 ataggart: did you take a shot at static final fields, or is that out of scope?

15:12 ataggart: ah, no I had forgotten. It should be perfectly doable so long as the values are themselves consistently hashed.

15:12 I'll get on it now.

15:13 cemerick: ataggart: I suppose requiring the fields to be final is a little too persnickety.

15:13 ataggart: I can reflectively find out

15:13 though it would be eaiser if the clojure.reflect ns was available

15:13 instead, I can probably just make calls to clojure.lang.Reflector

15:13 (the new one)

15:14 cemerick: True, but that restriction will cause frustration; a lot of Java constants are declared static, but not final.

15:14 ataggart: not much of a constant then

15:14 examples?

15:14 clojurebot: examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

15:16 cemerick: ataggart: perhaps "a lot" was an exaggeration ;-)

15:17 ataggart: cemerick: there is the concern that someone will want to switch on the actual symbols.

15:19 a usecase that might occur when writing macros conditionally calling java fields/methods

15:20 cemerick: ataggart: Sneaky. I'd say 'Absurd/Coincidence would be reasonable in such cases.

15:20 cdddr: $findfn [1 nil 2 3 nil] [1 2 3]

15:20 sexpbot: []

15:21 amalloy: &(keep identity [1 nil 2 3 nil])

15:21 sexpbot: ⟹ (1 2 3)

15:22 cdddr: I was thinking (remove nil? [list]) :)

15:22 More explicit.

15:23 amalloy: cdddr: meh. are you producing this seq from a (map)?

15:24 cdddr: Yes. I keep thinking there was probably a better way.

15:24 amalloy: &(keep :initials [{:name "amalloy" :initials "akm"} {:name "cdddr" :interests "caaadr"}])

15:24 sexpbot: ⟹ ("akm")

15:25 ataggart: cemerick: The current doc for case notes that nothing need be quoted, so there's a backwards compatability issue with requiring symbols-as-symbols to be quoted. Of course that's also the case with the new enum functionality. Hmm...

15:25 amalloy: ie, keep folds together the map and the remove

15:25 cdddr: Aaaah.

15:26 Yeah, this is definitely better.

15:26 __name__: $source keep

15:26 sexpbot: keep is http://is.gd/2Dlrr4

15:27 cemerick: ataggart: Once things get resolved, symbols become second-class. I think that's a reasonable tradeoff, given the prevalence of enums, static fields, etc.

15:27 __name__: this code is scary :(

15:27 cemerick: ataggart: If "constant" vars are in play as well, then that's doubly true IMO.

15:28 ataggart: cemerick: fair point.

15:29 amalloy: __name__: clojure.core is optimized for speed rather than legibility

15:29 if you were writing keep yourself, you would do like (defn keep [f coll] (remove nil? (map f coll))) and that would be it

15:30 __name__: $source remove

15:30 sexpbot: remove is http://is.gd/ttw47S

15:30 amalloy: or if brehaut had his way, (def keep (comp (partial remove nil?) map))

15:30 ataggart: cemerick: so strings, numbers, quoted symbols, evaluated constants, enums, and clojure collections of the foregoing.

15:30 __name__: :)

15:30 brehaut: amalloy: when did i become the champion of point free :P

15:31 amalloy: brehaut: i just like to blame my crazy ideas on the haskell community

15:31 brehaut: haha

15:31 __name__: amalloy: the standard functions just keep scaring me

15:31 amalloy: nobody ever wants to stand up for them

15:31 brehaut: amalloy i think the haskell community would be offended if they thought i was a spokesperson for them here :P

15:31 amalloy: heh

15:32 cemerick: ataggart: seems entirely reasonable to me. "Constant" is a fungible term, of course. "Values as evaluated at compilation time" perhaps.

15:33 amalloy: __name__: try implementing them yourself from reading the docstrings. it will probably be more enlightening than trying to follow the source

15:33 ataggart: cemerick: agreed, though it should probably go in as a separate enhancement. There's enough shoved into that ticket already.

15:35 cemerick: In any case, I'll get started on a separate patch with those changes, and see what Rich, et al. have to say.

15:35 cemerick: ataggart: Sounds good, let me know if you need help (FWIW). Thanks for taking that on. :-)

15:36 ataggart: cemerick: heh, np. Gave me a chance to delve into jvm bytecode.

15:40 Despite: What is the definition of "point" in "pointfree"?

15:41 amalloy: Despite: i think the rough answer is "named bindings"

15:41 Despite: great, thanks

15:41 brehaut: Despite, amalloy: short hand for http://en.wikipedia.org/wiki/Least_fixed_point i think

15:42 kencausey: http://www.haskell.org/haskellwiki/Pointfree See point 1

15:45 brehaut: kencausey: hah jeremy gibbons (mentioned in 2) is completely insane with the point free :)

15:46 Despite: i like that style

15:46 I wonder how far you can take it

15:46 brehaut: Despite: you can write entire programs without mentioning the arguments to anything with the right operators

15:47 TimMc: Just like you can write entire programs with only lambdas.

15:48 shachaf: Despite: http://en.wikipedia.org/wiki/SKI_combinator_calculus

15:50 amalloy: yeah, you can take it arbitrarily far

15:50 brehaut: its better as a sometimes thing though

15:51 _fogus: https://github.com/fogus/skiing

15:51 brehaut: in particular, if naming the variables would add clarity, then you should. if the function is general enough that the name is completely laking information then point free can be a win

15:53 Despite: Hrmm, guess i need to read a book. I get lost when combinators come up.

15:55 brehaut: Despite: start experimenting in a repl

15:56 shachaf: Despite: When combinators come up? But those are the simplest types of functions! :-)

15:57 A Factor programmer I know has said that pseudo-"point-free style" can be carried much farther in Factor without losing clarity.

15:59 brehaut: shachaf: father than in what?

15:59 shachaf: brehaut: Haskell in that context.

15:59 brehaut: thats quite an astounding statement

15:59 shachaf: brehaut: Why?

16:00 brehaut: because haskell is extremely good at point free

16:00 shachaf: The normal way of expressing things in a concatenative language is in terms of stack manipulation, with no names unless you explicitly want them.

16:06 _fogus: brehaut: This series of posts was an outstanding look into that approach http://www.codecommit.com/blog/cat/the-joy-of-concatenative-languages-part-2

16:06 brehaut: _fogus: cheers

16:08 TobiasRaeder: @technomancy i checked out lein-tar but i guess i didn't make myself too awefully clear :/

16:08 @technomany what i was really for was integrating some "ant-macro" (not sure about the term)

16:09 @technomancy it's supposed to be imported via import task but i wasn't straight away to get the import task to work with lancet

16:10 dnolen: how do stack-oriented PLs deal w/ concurrency?

16:13 shachaf: dnolen: What does that mean?

16:14 dnolen: How does any language deal with concurrency?

16:17 dnolen: shachaf: thread, green threads, locks, data structures, STM, thread pools, co-routines, explicit/implicit data parallelism, etc. does the stack oriented paradigm make these more tedious? I see these kinds of things addressed in FP literature, but I haven't seen anything like that for stack-oriented PLs. Just curious.

16:19 shachaf: dnolen: I don't think it's really a property of the fact that a language is a stack language.

16:21 dnolen: shachaf: not saying that, just curious about the lack of literature, or existence of features in the stack PLs I've (admittedly in a surface way) perused.

16:27 bartj: Regarding namespace variables

16:27 one can access them using: imported-namespace/variable

16:27 but, when one does it via an (eval (symbol namespace variable)) it fails!

16:28 can anyone please have a look at the code in this paste:

16:28 http://pastie.org/1622241

16:28 which shows the above problem of accessing namespace variables

16:28 using (eval (symbol ....))

16:34 anyone ?

16:35 hiredman: bartj: you are missing the difference between vars and symbols

16:35 amalloy: yes, and also (symbol us "president") doesn't work. us isn't defined; it has nothing to do with eval

16:36 bartj: sorry that was a typo

16:37 amalloy, I have corrected the paste: http://pastie.org/1622241

16:39 hiredman, can you please tell me what I am missing ?

16:40 hiredman: there is no local binding for us and no var

16:40 raek: bartj: without using eval: (-> (symbol country f) resolve deref)

16:40 amalloy: i don't think the issue is symbols vs vars, it's more about eval being in a null lexical context, isn't it?

16:41 raek: bartj: but the most important question is: why do you use namespaces and vars, instead of, say, a map?

16:41 bartj: you mean something like: {def president {:us "obama" :uk "cameron"}) ?

16:41 raek: yes

16:41 bartj: because there are more than 20 different variables

16:42 in each country

16:42 hiredman: amalloy: no, he assumes that when he sees the symbol 'us' there must be a var backing it

16:42 so he can refer to in an expression like (symbol us ...)

16:42 amalloy: hiredman: that was my objection to; he updated the gist to be using "us"

16:43 and claims to still be having trouble

16:43 bartj: strangely, it works on the REPL !

16:43 hiredman: no it doesn't

16:44 raek: I think amalloy's observation explains it pretty well. the form sent to eval is not evaluated in the lexical context where the eval call is

16:44 bartj: raek, may I ask, why not?

16:45 raek: (let [x 1] (eval 'x)) ; <-- x is not available in the scope where the form is evaled

16:46 bartj: oh no! I thought it should be, because it is defined right before in the let

16:46 amalloy: bartj: there are a lot of reasons eval is not the right tool to use for many jobs

16:46 this is one of them

16:48 dnolen: nice, lisp 50 years ago, http://funcall.blogspot.com/2011/03/fifty-years-ago.html

16:49 raek: I think this is a result of how closures are implemented

16:50 when the compiler sees (eval ...), it cannot know which variables it closes over

16:50 jkrueger: i stumbled over this as well a while back. i tried to write a backend for couchdb and wanted to evaluate functions from the db dynamically in a certain context. what would be the proper way to do this then ?

16:52 HK_: I am a long time C# developer (since 2002 when it came out) who has discovered Clojure (and Lisp for that matter). I absolutely love the (almost non-existent) syntax, it's so elegant and it's unbelievable how many "frameworks" are all of the sudden unnecessary to achieve something.

16:53 I think Rich has done a very good job designing and implementing Clojure, but one think I don't understand is why the keywords have to be so cryptic. Why "defn", "fn" and all the other ugly keywoards? Why not just use "function" and if that is too long just "F". F would stand out and be very short.

16:53 swart: fn works for me

16:54 ohpauleez: HK_: defn is a macro for making a function (using fn) and def'ing it using (def)

16:54 swart: besides you can change the syntax to suit yourself

16:54 ohpauleez: more or less

16:54 ssideris: HK_: but the nice thing is that the language is flexible enough to replace the keywords!

16:54 swart: angle brackets ftw!

16:54 HK_: would replacing the keywords make the code slower?

16:55 ssideris: HK_: no, you can make it happen at compile time with macros

16:55 ohpauleez: HK_: nope, not necessarily

16:55 lucian: HK_: i find fn very nice

16:55 bartj: jkrueger, I am extremely clueless as well

16:55 lucian: much better than function

16:55 HK_: ok, good to know, thanks. so i guess the cryptic keywords are just legacy from other lisps?

16:55 lucian: HK_: partly

16:56 technomancy: "function" is such a long word that I have to use Emacs render-time magit to make JS bearable.

16:56 *magic

16:56 dang

16:56 swart: at least it uses first and rest instead of car and cdr

16:56 ohpauleez: As stated, macros expand at compile time, and any code you really need to perform better than clojure enables (which I think you'd be hard pressed to find), you can write in java and then wrap in clojure as you need

16:56 jkrueger: bartj: one thing about ruby i liked was the ability to completely control the environment in which a block of code gets executed

16:56 swart: mostly I think the postfix notation is confusing to new developers

16:56 lucian: technomancy: i really like CoffeeScript's ->

16:57 jkrueger: it allowed from some pretty nifty stunts

16:58 HK_: @swart: this is what i meant. he used first and rest instead of car and cdr, but i wished he had done the same for the other keywords

16:58 technomancy: lucian: my JS use predates coffeescript, but I'm totally going for that next time I need to do web work.

16:58 ohpauleez: jkrueger: You can use binding forms to achieve the same thing in clojure, no?

16:58 technomancy: quite sane

16:58 jkrueger: swart: who could forget good old cddadr :)

16:59 lucian: HK_: others than fn?

16:59 swart: yeah car and cdr have their appeal

16:59 jkrueger: ohpauleez: apparantly not when you are using eval

17:00 HK_: i am still a total newbie, i don't know most clojure keywords. partly because they are hard to remember because they are so cryptic

17:00 lucian: swart: noooooooooo

17:00 swart: :)

17:00 lucian: HK_: could you give examples? i'm not much of a lisper either

17:00 swart: I like the symmetry is all

17:01 ohpauleez: jkrueger: ahh sorry, I was missing the context. I ran into a similar issue when I started working on net-ns (which I had since dropped) and realized it seemed more of a characteristic of bad design than of a real need for the project

17:01 swart: they told me in uni that they stood for "contents of address register" and "contents of data register" but I think that's incorrect. at least according to something I read online somewhere

17:02 jkrueger: HK_: I agree with you that some things are short and that may seem strange. Functions like split-at or drop-while have full names. But you tend to use "fn" so much, that it just deserves a shorthand. The same goes for a few other functions/special forms.

17:02 swart: you can always use a lambda character. unicode is ubiquitous now

17:02 jkrueger: HK_: independent of lisp folklore

17:03 HK_: i guess, it's just personal taste

17:03 swart: not entirely. language idioms are important for sharing code

17:03 HK_: i come from the imperative OO world where everything is very descriptive

17:03 swart: that's why I can't handle C#. too many ways to doe the same thing

17:03 lucian: HK_: so do i. what exactly bothers you in clojure's keywords?

17:03 swart: meh, that's now why i dislike it

17:03 bartj: raek, (-> (symbol country f) resolve) gives a NullPointerException ?

17:04 lucian: i do like it more than i like java

17:04 jkrueger: swart: i hope you never had to write a c++ program

17:04 HK_: what i said earlier. i find the naming not consistent, so being a beginner i find it harder to remember

17:04 lucian: jkrueger: that's got to be the world's worst langauge

17:04 swart: I learned c++ a couple of years ago, but I've been a smalltalker for 20 odd years

17:04 lucian: HK_: i know, i was curious what names in particular

17:04 technomancy: lucian: except for the ones that are bad on purpose

17:04 lucian: technomancy: i'm not even convinced of that

17:05 brainfuck has an elegant uniformity

17:05 swart: c++ turned out to be less horrible than I thought, but apparently it gets worse the better you understand it :)

17:05 no_mind: is there a framework in clojure that will let routes registered programatically ? Lets say a module registers the routes it want to handle...

17:05 technomancy: lucian: perhaps if you measure "most harmful" rather than "worst"

17:05 hiredman: HK_: consistent with what?

17:05 lucian: swart: try metaprogramming with templates

17:05 technomancy: i guess

17:05 jkrueger: swart: i can confirm that

17:05 lucian: swart: it's plain evil

17:05 HK_: they should have been either just initials for keywords, e.g. F for funktion, M for macro, MM for multimethod, D for define, which could then be combined to D-F for define function

17:05 or they could be just abbreviations like func, sync, mac

17:06 hiredman: HK_: how is that more consistent?

17:06 raek: bartj: resolve returns nil if the symbol does not corresond to any var

17:06 ,(resolve 'conj)

17:06 clojurebot: #'clojure.core/conj

17:06 raek: ,(resolve 'foo)

17:06 lucian: HK_: F, M, MM and D seem worse to me than fn, macro , etc

17:06 clojurebot: nil

17:06 raek: ,(resolve (symbol "clojure.core" "conj"))

17:06 clojurebot: #'clojure.core/conj

17:06 HK_: @lucian, i can see that

17:07 amalloy: tend to agree. uppercase is evil anyway

17:07 lucian: amalloy: yeah! CL is stupid that way

17:07 HK_: they stand out htough

17:07 swart: and - nicer than _

17:07 lucian: HK_: so do keywords in a decent editor

17:07 swart: camelcase cramps my fingers

17:07 amalloy: HK_: so does caadr

17:07 bartj: can anyone please point to some material re: difference b/w vars and symbols ?

17:07 amalloy: but that doesn't make it a good idea

17:07 lucian: swart: meh, i find _ ok

17:08 bartj: vars = variables

17:08 hiredman: HK_: you still have not explained your use of the word consistent

17:08 technomancy: bartj: vars are storage locations; symbols are just names

17:08 bartj: symbols are attached to vars ?

17:08 HK_: ok, guys, you're right, it was just the first thing i noticed when i started looking at clojure, now looking at some code, i noticed there aren't that many keywords anyway so it's not that bad

17:08 swart: no a symbol is a literal

17:08 bartj: and they are attached to a var ?

17:08 swart: not necessarily

17:08 HK_: @hiredman: right, sorry, i will now

17:09 swart: they are a value

17:09 technomancy: ,(class (name #'reduce))

17:09 clojurebot: java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.Named

17:09 technomancy: ...

17:09 speaking of consistency...

17:09 bartj: what use are symbols if they are just names ?

17:09 swart: like a string, but unique

17:09 bartj: blahblah is a name but doesn't reference anything :)

17:10 swart: beats using numbers for everything

17:10 can be used for looking things up in maps for example

17:10 HK_: it's inconsistent because "fn" stands for function, where it used the first (f) and last letter (n) of the word, but in the case of "def" for define, it uses the first 3 letters. "defn" for define function uses the first three letters of the first word and the initial of the second word

17:10 hiredman: or look up vars in namespaces

17:10 raek: bartj: you don't use them very often as data in programs. they are used for representing names in source code though.

17:10 lucian: HK_: so you'd prefer func and defunc?

17:11 HK_: i'd prefer func and def-func

17:11 bartj: raek, could you provide a tiny example, please ?

17:11 hiredman: HK_: how do you come to the conclusion that the 'f' in fn is the first letter of the word 'function' and the 'n' is the last?

17:11 spewn_: HK_: I would argue that "fn" comes from FuNction, not FunctioN.

17:12 raek: the code of the expression (inc 1) is represented as a clojure list of the symbol inc followed by the integer 1

17:12 jkrueger: i always liked "fun"

17:12 it's just fun to write a fun

17:12 raek: "clojure programmers have more fn"

17:13 dnolen: HK_: don't bring too many OO naming convention assumptions w/ you. Clojure is simply built on a different legacy - Scheme, CL, Standard ML, Haskell. Clojure naming conventions draw a lot from those languages.

17:13 HK_: because the 3 most common ways to abbreviate something are: 1) use initals of two words, like "ns" for namespace 2) use first and last letter 3) use first X letters

17:13 lucian: HK_: 4) use random Y letters

17:14 HK_: i was just interested, thanks for the discussion, i like the vibe you guys have

17:14 amalloy: HK_: i'm dubious. things ending in "ion" are special cases; mathematicians often use defn (superscript n) for definition

17:16 and you see fn used for function all over: "The domain of the function fn"..."Let Fn be the Fibonacci sequence"...

17:16 HK_: so it's just convention then

17:16 amalloy: oh, i think that last one is supposed to be F<sub>n, but it's not clear

17:17 *shrug* i think it's an arbitrary compromise between brevity and legibility

17:17 ohpauleez: amalloy: Yes, F sub n

17:18 amalloy: ohpauleez: in the context i found it, it looked like Fn, and since they didn't say "the nth element" it didn't click for me right away

17:18 ohpauleez: ahh cool

17:18 HK_: i don't mind "fn" that much anyway, it makes sense to me because i just thought they took the first and last letter of 'function"

17:18 something like : would have been cool for define

17:18 or := what is used in math

17:18 amalloy: HK_: we need our : for other stuff :P

17:19 HK_: i'm curious where you see so many first-last abbreviations. i can't think of anything off the top of my head

17:19 HK_: GMail for Google Mail

17:19 amalloy: that's not first and last at all

17:19 lucian: it's not GL

17:19 HK_: oh sorry

17:20 amalloy: that's first and first

17:20 HK_: i misread it

17:23 the word Doctor is an example

17:23 usually writen as dr

17:29 signalseeker: cake users: how do you set the classpath for cake repl?

17:30 It doesn't seem to honor my $CLASSPATH

17:30 HK_: say thanks to rich from me, he is a genious, bye bye

17:36 amalloy: signalseeker: if you're in a cake project the repl there will include the project's dependencies

17:36 signalseeker: amalloy: I am not in a cake project

17:37 I am using the global project I guess

17:37 amalloy: then you can futz with the settings in ~/.cake/project.clj, but you're better off not trying to manage classpath entries yourself

17:37 what do you need a custom classpath outside of a project for?

17:38 signalseeker: I don't need a custom classpath, I just want my default $CLASSPATH to be available

17:38 For whatever reason, I can't import my jars in cake repl although I can access them directly through java

17:39 bartj: If I have (ns blah1.blah2.blah3 :as us)

17:39 (ns-resolve 'blah1.blah2.blah3 (symbol x)) resolves properly

17:39 but, (ns-resolve (symbol us x) doesn't

17:41 ieure: What the fuck. http://stackoverflow.com/questions/5161164/python-in-memory-object-database-which-supports-indexing

17:41 amalloy: signalseeker: the point i'm getting at that if there are jars you want to import, the "proper" way to do it is specify them as dependencies wherever your code is, so that the tools can manage the fiddly low-level classpath details

17:41 bartj: ns-resolve wants two args

17:43 ,(resolve 'clojure.core/first)

17:43 signalseeker: amalloy: Agree, thats a better soln. But I just want to explore some java APIs using clojure, I don't have a need of a full-fledged project yet. It seems like too much trouble to have to create a project for this purpose

17:43 clojurebot: #'clojure.core/first

17:43 bartj: amalloy, oops, I mean (resolve (symbol us x))

17:43 amalloy: HK_: aha! like soln above :)

17:44 signalseeker: you could ask in #cake.clj

17:44 signalseeker: I did, there is no one there right now it seems :)

17:44 amalloy: that's often the case :P

17:45 signalseeker: maybe its not a cake thing, I am new to clojure. So I could be using the wrong syntax

17:45 amalloy: lein and cake both honor some kind of java env vars, i'm just not sure what they are

17:45 $google leiningen sample project.clj

17:45 sexpbot: First out of 451 results is: sample.project.clj at master from technomancy's leiningen - GitHub

17:45 https://github.com/technomancy/leiningen/blob/master/sample.project.clj

17:46 HK_: how do i direct someone in this chat?

17:46 signalseeker: (import 'foo.c) ;; I have boo.jar with the package foo in my $CLASSPATH

17:48 HK_: amalloy: i don't know what soln is

17:48 shafire: hi

17:49 amalloy: solution

17:49 HK_: /msg amalloy dude you are so wrong

17:50 my point was that he said "agree that's a better soln", meaning solution. evidence for my fn claim has arrived already! :)

17:50 HK_: see, that's why i didn't get it

17:51 soln isn't a great abbreviation

17:51 amalloy: $google soln set

17:51 sexpbot: First out of 30900 results is: 1.5 Solution Sets Ax = 0 and Ax = b Definition. The rank of a ...

17:51 http://www.math.northwestern.edu/~clark/285/handouts/soln-set.pdf

18:16 konr: The java library I'm using keeps spilling NoClassDefFoundErrors and asking for classes not available on its jar file. Is this behavior expected, or something else is going on?

18:17 ohpauleez: konr, what classes?

18:17 is it because you're not including Clojure or other project dep jars on your classpath?

18:19 konr: ohpauleez: org.cyberneko.html/HTMLConfiguration, for example. All my jars are in the lib/ directory, used by lein, but note that this class is not available on any jar

18:19 ohpauleez: I wonder if the .jar wasn't built properly

18:20 ohpauleez: konr: That could be it, i'd check the manifest

18:20 seems very weird to me

18:20 konr: s/\//./s

18:20 ohpauleez: especially if you're managing the deps with lein/mvn-dep

19:11 cdddr: Is there a clojure builtin that swaps argument order?

19:13 ohpauleez: cdddr: can you give an example?

19:13 amalloy: cdddr: sadly i don't know of one

19:13 -> and ->> are kinda-sorta related

19:14 ohpauleez: i think he's looking for (fn [f] (fn [a b] (f b a)))

19:14 cdddr: amalloy: Yup.

19:14 ohpauleez: ahh ok

19:14 amalloy: i've wanted that a number of times, but it's a little hard to envision how it works for non-binary functions

19:16 cdddr: Granted, but it would be useful enough for binary ones. Or it could just be "reverse-args", though that's probably not very useful for non-binary stuff.

19:16 amalloy: maybe (fn reorder [f order] (fn [& args] (apply f (map order args)))), called like (reorder fnil {0 1, 1 0})

19:16 er except that's totally absurd as an implementation

19:16 as a description it kinda explains what i was getting at, i think :P

19:16 cdddr: Yeah, it does. :>

19:20 amalloy: cdddr: i'll sketch something out later this afternoon if you're interested in a more general solution

19:23 cdddr: Sure, if I'll still be around.

19:40 $findfn 1 inc dec [2 0]

19:40 sexpbot: []

19:42 __name__: good night

19:42 $source findfn

19:42 sexpbot: Source not found.

19:42 brehaut: findfn is a sexpbot command

19:42 __name__: eh, i should just go to sleep :)

19:43 brehaut: yes i figured

19:43 $findfn 2 1

19:43 sexpbot: [clojure.core/unchecked-dec clojure.core/dec]

19:43 __name__: neat

19:43 Despite: heh, reddit is hilarious. somebody posts a year old blog about building a game in clojure from an admited newbie, and the comments are full of arguments about how immutability is inefficient

19:44 and FP'ers "live under a rock"

19:44 cdddr: Arrgh, what was that function that worked like (fn [f1 f2] (fn [x] [(f1 x) (f2 x)])) ?

19:44 brehaut: juxt

19:44 cdddr: Oh, thanks.

19:46 Adamant: reddit is crud.

19:46 at this point.

19:47 cdddr: Arguably, reddit has been crud for ong time now.

19:47 brehaut: i am hoping that alex payne's bloomfilter is successful

19:47 Despite: yeah, i read /r/programming only, but threads like that chase me away

19:47 Adamant: cdddr: I'd agree with that argument

19:47 Despite: But I don't have much other programming stuff to read, so I start jonesing.

19:47 Adamant: i'm not huge on Hacker News, but it's way better overall

19:48 brehaut: real programmers read lambda the ultimate. sadly im not smart enough to be a real programmer

19:48 Adamant: quality-wise, no argument, as long as you don't mind a deluge of startup stuff

19:49 I read LtU for a while. it's good to do so, but it's very academic style. everyone needs some of that, not everyone needs it forever.

19:58 cdddr: Adamant: True that.

19:59 And to be fair, HN is actually the one tech site that doesn't make me irritated within a few minutes of visiting. ;)

20:00 TimMc: /r/programming is long overdue for fragmentation.

20:00 I mod /r/scheme and /r/PLT (Prog Lang Theory), which are super low traffic. :-(

20:01 The larger subreddits are basically useless.

20:01 Adamant: cdddr: I don't agree with the the views of many Ars residents, but Ars Technica is pretty good overall

20:03 cdddr: It's been a while since I visited Ars last, and I don't remember being royally pissed, so I guess I'll give it a shot. :>

20:04 Ahh, the joy of replacing 40 lines of code with 8.

20:05 * TimMc golf claps

20:15 * locks likes TimMc

20:29 loquaciously: i think i found a spelling error in the source; do i need to do the contributors agreement, or can i just tell someone?

20:47 TimMc: Maybe we'll never know.

21:10 tomoj: no self-joins in clojureql 1.0.1, it seems?

21:12 pdk: tell me wise sages

21:12 for folks who've read the preview of joy of clojure

21:12 would it still be worth it next to a copy of practical clojure

21:12 tempting since with this gift card i could preorder for $1

21:15 technomancy: pdk: yes, definitely

21:16 TimMc: What is the target audience?

21:16 _fogus: Will there be updated PDFs over time if I buy JoC?

21:17 I'm rather fond of that approach.

21:25 amalloy: cdddr: still around?

21:25 cdddr: amalloy: Yup.

21:25 amalloy: https://gist.github.com/70f5bf52417ccdef5938

21:27 forces args into a vector, so won't work if you want to (apply (reorder f {0 1 1 0}) (range))

21:28 cdddr: is what you were looking for, yeah?

21:29 pdk: yes, JoC is sweet

21:29 cdddr: Yeah, it is. Thank!

21:29 amalloy: i haven't read practical clojure but assert anyway with 100% confidence that JoC is better :)

21:29 cdddr: cool. had it almost done two hours ago then a coworker showed up to pair-program :)

21:30 it's a neat idea i played with a while ago but didn't write until someone else made me. maybe i'll start using it

21:30 cdddr: Always an annoyance at work. ;)

21:30 amalloy: ugh, what is wrong with me. so many smilies today

21:30 gonna go home. ta-ta

21:30 cdddr: toodle-oo!

22:33 amalloy: cdddr: i was thinking about the needless repetition of {0 1, 1 0} in reorder. i could redefine it as "swaps", but not sure how i would handle something that my current scheme would express as {0 1, 1 2, 2 0}. any thoughts?

22:34 TimMc: amalloy: You're looking for a better way to express a permutation?

22:34 amalloy: TimMc: yes, i suppose i am

22:34 you caught my gist to cdddr earlier, right?

22:34 TimMc: Yes, but I didn't know the context.

22:35 Arbitrary permutation?

22:35 amalloy: he was looking for a HOF that wraps some other function by reording the args it takes

22:36 TimMc: HOF?

22:36 amalloy: my example allowed ((reorder map {0 1, 1 0}) [1 2] inc) => [2 3]

22:36 higher order function

22:36 TimMc: k

22:37 It does seem verbose.

22:38 amalloy: right. and i could make it accept just {0 1}, but then what if the user wants to reorder args in a more interesting way

22:38 TimMc: I suppose yours allows some arguments to be left alone, too.

22:38 amalloy: right

22:39 and conceivably you could write {0 1, 1 1} to mean "pass original arg 1 as new arg0 and arg1"

22:39 TimMc: I imagine the functionality could be extended such that given a vector it would use the values as a cycle.

22:40 amalloy: hm

22:40 what do you mean?

22:40 TimMc: (reorder map [1 2 3 0]) would be (reorder map {0 1, 1 2, 2 3, 3 0})

22:41 (Unless I have key:value backwards.)

22:44 amalloy: rotations like that would be better expressed as integers anyway

22:45 (reorder map 1) or (reorder map -1), depending on whether i have key:value backwards myself

22:45 TimMc: True.

22:46 Oh! And that would allow for rotations of arbitrary arity.

22:46 amalloy: but not infinite

22:47 TimMc: I can't see using something like [1 0 3 2] anyway.

22:47 True...

22:47 amalloy: well infinite is already impossible

22:47 TimMc: I wasn't aware you could apply...

22:47 Yeah.

22:47 amalloy: hard to see making it ever possible, or even useful

22:49 probly best to only allow swaps (maps) and rotations (ints)

22:49 TimMc: I'm imagining allowing seqs for &args.

22:49 apply would have to know about the arity of the target function, etc.

22:49 amalloy: so? as long &args is finite, it's already handled

22:49 you just (count args) before you rotate

22:50 which you have to do anyway

22:50 TimMc: Oh, I was still thinking of the infinite case for functions.

22:50 It's silly, though -- jut take a seq as an arg.

22:51 Next up: Functions with uncountably infinite arity!

22:52 * amalloy declines to include the axiom of choice in his new utility function

22:52 TimMc: :-D

22:53 I should go to sleep before I try to come up with anything more absurd.

22:53 night all

22:55 Thamster_: i'm sorry for the following noob question

22:56 Could not locate clojure/contrib/monads__init.class or clojure/contrib/monads.clj on classpath: (NO_SOURCE_FILE:0)

22:56 so i add the jar's location to the .closure file in my home directory?

22:59 amalloy: Thamster_: the answer is likely to depend on how you are running clojure. leiningen, cake, cljr, or something else?

23:00 Thamster_: clj in osx terminal after installing via macports

23:00 ?!

23:01 amalloy: mmm. not a mac user here; i know the macports version of leiningen is hopelessly out of date, but i've no idea what the state of clj is

23:02 Thamster_: so its that complicated in general to add a jar to the classpath in clojure?

23:03 amalloy: no, not at all

23:03 cause nobody uses clj :P

23:03 Thamster_: i see

23:03 is there another interactive shell i could try?

23:03 amalloy: if you use leiningen or cake (as most do), you just add a line to project.clj, and it goes and downloads the jar from maven then puts it on the classpath

23:03 Thamster_: thanks for the tips btw

23:03 amalloy: $google raynes get started with clojure

23:03 sexpbot: First out of 254 results is: An indirect guide to getting started with Clojure » I Don't Blog

23:03 http://blog.raynes.me/%3Fp%3D48

23:04 amalloy: wtf sexpbot, that link sucks

23:04 Thamster_: haha

23:04 amalloy: http://blog.raynes.me/?p=48

23:06 Thamster_: he skips right by cljr

23:08 amalloy: that's not an accident. cake and lein give you all the cljr features and loads more, and are barely any more complicated to install, if at all

23:08 Thamster_: they are command line too?

23:08 interactive shells?

23:08 amalloy: they include shells

23:08 Thamster_: ok cool

23:09 amalloy: $ cake repl

23:09 user=> (inc 1)

23:09 2

23:09 Thamster_: While Leiningen does have a command for starting an REPL outside of a project (a la cake, cljr), it does not currently have a way for you to manage dependencies for that “outside-of-a-project REPL” like cljr and cake does. If yo

23:09 … is that right?

23:09 i just want to do a quick tutorial on monads

23:10 i don't want an ide or anything

23:10 amalloy: it probably is no longer right, but technomancy is the one to ask

23:10 cake and lein really genuinely are command-line only tools. you don't have to worry about accidentally installing eclipse

23:10 they both integrate with several IDEs, including eclipse, emacs, vim, and textmate

23:13 Thamster_: sudo gem install cake; cake repl

23:13 that wasn't too painful

23:13 amalloy: hurrah!

23:13 Thamster_: drew!

23:14 amalloy: now you can just add [clojure-contrib "1.2.0"] to the :dependencies in ~/.cake/project.clj (if it's not there already), and you'll have that jar on the classpath when you launch a repl

23:14 Thamster_: hey thanks amalloy , that seems to have worked and managed the dependencies automagically

23:15 amalloy: that's the idea!

23:15 Thamster_: hmm

23:16 java.lang.IllegalStateException: m-bind already refers to: #'clojure.contrib.monads/m-bind in namespace: user (NO_SOURCE_FILE:2)

23:16 maybe i should delete my .clojure file

23:20 tomoj: I swear I remember finding the "outside-a-project" stuff in leiningen and being surprised

23:21 but now I don't see it

23:31 Thamster_: this is pretty nice

23:32 amalloy: cdddr: (reorder (partial reduce foo) {0 1}) vs (partial (reorder reduce {0 1}) [1 2 3]) is a funny distinction. swap the argument order for reduce, and decide which argument to partialize

23:33 i think i'll play around with ways to make reorder more convenient then push something to clojars if you're interested

23:40 technomancy: tomoj: you can install leiningen plugins that work outside a project

23:40 and you can set up a bare swank repl that's standalone

23:40 I haven't heard a coherent use case for actual dependencies outside a project, so I've left that to cljr for the time being.

23:41 IMO incanter should ship with shell-wrappers like swank does for standalone incanter hackery

23:45 ohpauleez: Raynes: fixed a bug in clj-github, pushed to master already. Can you up the version, push, and release to clojars?

23:47 amalloy: ohpauleez: probly best to tell him in #sexpbot; i think he's afk and might miss the scrollback in a noisy room like #clojure

23:47 cemerick: technomancy: My next push on ccw will probably include a way to start a REPL unassociated with any project, and allow one to add dependencies to that session dynamically. I've found myself wanting a REPL with deps X, Y, and Z of late, without the bother of setting up a project.

23:47 ohpauleez: amalloy: Thanks man, good thinking. Also I don't know if I told you, but I really loved your post the other day

23:47 amalloy: oh i'm glad

23:47 cemerick: Nothing special, but it seems useful enough (handy for beginners, too).

23:48 amalloy: i feel like the title was at once too pretentious and too hard to search for, so i tried to make up for it with content :P

23:48 ohpauleez: amalloy: haha. Well I sent it around the office, we all enjoyed it.

23:48 amalloy: great

23:49 ohpauleez: I'm working on a longer post right now (re-starting up the blog)

23:49 amalloy: ohpauleez: yeah, my blog had been silent for a month or so

23:49 not counting a post about emacs/vim vs notepad that nobody really noticed

23:50 ohpauleez: I've been polling clojars and github (soon bitbucket), to grab clojure projects, scan their project.clj if they have one, and make a heat map of dependencies per version of artifact

23:50 to help answer the question, "Which package should I be using?"

23:50 amalloy: ohpauleez: which version, or which package?

23:51 ohpauleez: version of artifact (you could sum all versions if you wanted)

23:51 amalloy: $findfn 1 [1 2 3] [3 1 2]

23:51 sexpbot: []

23:51 amalloy: $findfn [1 2 3] 1 [3 1 2]

23:51 sexpbot: []

23:51 ohpauleez: {"aleph" {"1.01" 10 "1.02" 15}}

23:51 amalloy: man, seriously? we don't have a rotate?

23:52 ohpauleez: amalloy: we have rotate, I'm almost certain of it

23:53 amalloy: ohpauleez: i can't find it on the clojure cheatsheet, and sexpbot is usually better at it than i am

23:54 likewise (find-doc "rotate") returns nothing

23:55 ohpauleez: amalloy: is there some weird thing you can do with cycle, if it's a seq

23:55 I'm scouring my code, I could have sworn I've done a rotate before

23:55 and I can't believe we have shuffle and not rotate

23:55 amalloy: i suppose so. it seems easier to do it by hand than hack it into a cycle op

23:55 tomoj: rotations should be free

23:56 s/free/almost free/

23:56 amalloy: sexpbot: botsnack

23:56 sexpbot: amalloy: Thanks! Om nom nom!!

23:56 tomoj: of vectors anyway

23:56 amalloy: tomoj: yes

23:56 ohpauleez: sure

23:56 amalloy: but you have to write the code

23:57 technomancy: I don't really see the utility of adding dependencies to something that isn't a project

23:57 it's not like you could make it any more streamlined than editing :dependencies in a new project

23:58 amalloy: technomancy: suppose that i like to have c.c.condition available in all my repls or some such

23:58 or com.amalloy.rlyawesome

23:58 tomoj: the number of interfaces it seems you'd have to implement for free rotation is discouraging

Logging service provided by n01se.net