#clojure log - Oct 06 2011

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

0:00 duck1123: there's 2 parts to it. The clojure server, and the emacs client in elisp. I believe there's something for VIM as well

0:01 trptcolin: ah, looks like there's some fanciness going on, deprecated Thread.stop method and all

0:02 alandipert: trptcolin: goodnight & godspeed, that would be a cool repl addition!

0:02 trptcolin: thanks man

0:02 and thanks duck1123 and amalloy too

0:03 naptime for me as well

0:12 tomoj: suppose you have [[0 "foo"] [1 "bar"] [5 "baz"] [6 "bang"] [8 "bing"]] and want [["foo" "bar"] ["baz" "bang"] ["bing"]]. or you have [["foo" :x] ["bar" :y] ["baz" :y] ["bang" :z] ["bing" :z]] and want [["foo"] ["bar" "baz"] ["bang" "bing"]]

0:12 is there some slightly more general partitioning hof that can handle this kind of thing?

0:14 hmm, actually

0:16 amalloy: tomoj: (partition-all 2 (map second foo)) for the first one?

0:17 i mean, it's not entirely clear how your inputs and outputs are related

0:17 tomoj: yeah..

0:18 in the first, partitions are runs where 'first' of each value increases by 1

0:19 in the second, it's just partition-by second I think?

0:19 amalloy: tomoj: i wrote a more-general partitioning scheme you might like. let me find it

0:19 https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L180

0:20 tomoj: https://gist.github.com/56dc10b22a3d8fdc26c4 duh

0:20 oh, cool

0:21 I was trying to do something like that with (->> .. (partition 2 1) (partition-by ..))

0:21 but it wasn't working

0:21 amalloy: yeah, partition-by is a special case of partition-between

0:29 tomoj: hmm https://gist.github.com/9c059ff9d231b61c6bb7

0:29 I don't like either of those

0:31 but they work, thanks

0:31 amalloy: tomoj: the first one looks more like (partition-between (fn [[[x] [y]]] (not= y (inc x))

0:32 tomoj: that's better

3:25 Blkt: good morning everyone

3:25 cark: good morning sir

4:24 michaelr525: hello

4:30 kzar: What causes null pointer exceptions generally? Any ideas how to get more information about why one happened?

4:31 clgv: kzar: strange compiler errors often do in clojure 1.2

4:31 kzar: clgv: I'm using 1.3

4:31 clgv: kzar: I can't say often then - maybe they improved a bit over there

4:32 kzar: do you get NPEs when compiling?

4:32 kzar: clgv: What's a NPE?

4:32 oh

4:32 sorry

4:33 clgv: Hmm well all clojure's compiled right? I get the error when evaling some code in the buffer, also when same code is run from within one of my tests with `lein test`

4:33 clgv: kzar: you get no hint where in the source it happens?

4:34 raek: some functions indicate "failure" with NPEs

4:34 ,(let [[a b c] [1 2]] c)

4:34 clojurebot: nil

4:34 raek: *with nils

4:34 clgv: raek: but then you get the source line in most cases

4:35 raek: ah

4:35 kzar: you don't get a source line?

4:35 kzar: raek: Actually I do, sorry I didn't realise it was anything useful until you mentioned it

4:35 raek: That gives me a hint, thanks

4:36 raek: So much crap gets printed it's hard to pick out the one useful tid-bit eh?

4:36 clgv: kzar: use clojure.stacktrace and have a look for your files in there

4:37 is there a shortcut function to combine two map entries in a map similar to update-in

4:38 the 1.2 cheat sheet doesnt tell me any

4:39 cark: ,(update-in {:a {:b 1}} [:a] merge {:c 2})

4:39 clojurebot: {:a {:c 2, :b 1}}

4:39 cark: ?

4:40 maybe not a shortcut, but short enough, if that's what you mean

4:40 raek: clgv: can you give an example of a desired output for a certain input?

4:40 clgv: I thought of something like: {:a 1 :b 3} [:a :b] + :c -> {:c 4}

4:40 I skipped other keys of the map

4:41 cark: ok i was way off =P

4:42 raek: so :a and :b should be dissoced, and :c should be assoced with the result

4:42 cark: i can't think of a one-liner for this one

4:42 clgv: yeah. thats what the intention was

4:43 thorwil: a job for select-keys and vals, i guess

4:43 clgv: it seems to be a basic use case for a map, so I thought there might be something

4:43 thorwill: yeah that might do to implement it

4:44 raek: (defn combine-vals [m keys f key] (assoc (apply dissoc keys) key (apply f (map m keys))))

4:46 thorwil: oh

4:46 raek: it has three sub-expressions: 1) make a map without 'keys', 2) make a new value by applying 'f' to the values for 'keys' in the original map, 3) assoc 'key' with that value in the map from 1)

4:47 thorwil: clgv: keys in the map that are not in the list should be in the result

4:47 ?

4:47 raek: probably looks more readable if you bind 1) and 2) in a let

4:47 clgv: raeks approach looks fine

4:48 thorwil: raeks approaches tend to do that :) i assumed other key-vals should be dropped, not kept

4:50 raek: the argument order [m key f keys] feels more natural to me (this is very subjective and a different order may feel more natural for you in the context of your program)

4:53 but [m keys f key] is more consistent with update-in, though

4:53 *shrug*

4:54 clgv: yeah, I used the latter

5:12 zakwilson: Maybe I'm tired, but I haven't been able to find it. What do I put in my project.clj to get all of contrib 1.3?

5:14 Or has contrib gone away and been replaced by libraries directly under org.clojure?

5:15 Blafasel: Yes.

5:16 thorwil: zakwilson: see http://dev.clojure.org/display/doc/Clojure+Contrib

5:17 zakwilson: thorwil: yeah, I found that just before you linked it. Looks like a bunch of stuff has moved though. This is going to require changes to my code, I think.

5:17 raek: and http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

5:18 thorwil: zakwilson: you might want to put ":repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}" into your project.clj

5:28 zakwilson: Hmm... append-spit seems to be gone. Is there a new name for it?

5:28 raek: zakwilson: spit now takes an :append option

5:28 zakwilson: Ahh.

5:28 raek: http://clojuredocs.org/clojure_core/clojure.java.io/iofactory

5:29 it sends all its arguments to clojure.java.io/writer

5:29 and therefore gains the superpowers of clojure.java.io

5:30 (works on Files, URLs, strings (becomes file or url), byte arrays, sockets, &c)

5:31 zakwilson: Ok, this actually looks like it might be working with pretty minor changes then.

5:32 Is there a replacement for read-lines?

5:32 raek: line-seq

5:33 but it does not close the stream like read-lines

5:34 most file operations are often used together with 'with-open'

5:35 but watch out so that you don't return the lazy line-seq out of with-open

5:36 clgv: is there a min function that uses compare automatically?

5:36 raek: either process it inside with-open or wrap the line-seq call in a doall call

5:37 zakwilson: Got it. Thanks.

5:44 ejackson: morning all

6:23 kzar: raek: It's this line that's giving a null pointer exception, but I can't see why! https://github.com/kzar/ring-hmac-check/blob/master/src/ring/middleware/hmac_check.clj#L29

6:23 raek: When called from here https://github.com/kzar/ring-hmac-check/blob/master/test/ring/middleware/hmac_check_test.clj#L24

6:29 raek: kzar: it's hard for me to tell too (I don't spot anything obvious) without the stacktrace

6:30 kzar: raek: http://paste.lisp.org/display/125118

6:47 raek: kzar: I think the "or" form should be a map and not a vector

6:48 pred becomes nil because the :or didn't work

6:48 it was probably treated as {0 forbidden-handler, 1 (fn [req] ...), 2 ..., 3 ...}

6:49 since vectors can be seen as maps from indices to values

6:49 but it would be good if the compiler could complain when you try to do this

6:55 kzar: maybe you could open a ticket in Jira regarding that the :or form is silently ignored if it's of the wrong kind (a vector in the case of map destructuring)

7:42 michaelr525: i'm falling asleep here

7:54 kzar: raek: Thanks! I've got it working, new version pushed also I opened that ticket http://dev.clojure.org/jira/browse/CLJ-848

8:21 fdaoud: Rest in peace, Steve Jobs

9:06 bhenry: if you use and require inside a do, is it only available inside the do?

9:09 raek: bhenry: no

9:10 "use" and "require :as" mutate the current namespace when they add aliases

9:23 thoefer: Is there any particular reason why the and macro uses stack consuming recursion instead of recur?

9:23 I´m quite new to clojure so excuse me if I don´t see a obviouse point

9:23 joegallo: macros only work with the code that's sitting there in front of you

9:24 i would be pretty surprised if somebody wrote a big enough and for it to blow the stack

9:24 clgv: thoefer: it is a macro hence it consumes no stack but is expanded on compile time

9:25 &(-> '(and a b c d) macroexpand-1 pprint)

9:25 lazybot: java.lang.Exception: Unable to resolve symbol: pprint in this context

9:25 clgv: &(-> '(and a b c d) macroexpand-1)

9:25 lazybot: ⇒ (clojure.core/let [and__3468__auto__ a] (if and__3468__auto__ (clojure.core/and b c d) and__3468__auto__))

9:25 clgv: &(-> '(and a b c d) macroexpand-1 macroexpand-1)

9:25 lazybot: ⇒ (let* [and__3468__auto__ a] (if and__3468__auto__ (clojure.core/and b c d) and__3468__auto__))

9:25 clgv: &(-> '(and a b c d) macroexpand-1 macroexpand-1 macroexpand-1)

9:25 lazybot: ⇒ (let* [and__3468__auto__ a] (if and__3468__auto__ (clojure.core/and b c d) and__3468__auto__))

9:26 clgv: humm I would have like macroexpand to expand the inner as well for demonstration ;)

9:26 chouser: clgv: this is a common desire

9:26 thoefer: thanks guys I think I see your points!

9:27 chouser: clgv: there are bits of code that simulate that, but it a form with inner macros expanded never actually exists in memory while the Clojure compiler is running, so such an expansion is a bit of a lie

9:29 clgv: chouser: huh? the compiler has hidden magic ways of dealing with macros?

9:29 chouser: well, they're not magic, and they're no more hidden than everything else the complier does... but other than that, yeah. :-)

9:31 clgv: I never checked the jvm source of macro handling... ;)

9:31 chouser: the compiler transforms the forms you give it into a new tree of data that has a lot more information about each form. The shape of this analysis tree is roughly the same as what was read, but each node looks very different.

9:32 clgv: ok, so macroexpands aim is to have a user friendly look at macroexpansion?

9:32 chouser: macroexpansion happens as nearly the first step of analyzing a form, and only after the analysis for that form is complete are the children macroexpanded as needed.

9:32 clgv: ok

9:33 chouser: well, the macroexpand you can call is the same one the compiler uses. the very one.

9:33 but then more work is done on it before the kids are expanded.

9:33 So there's never an expanded outer form with expanded inner forms all put together at once.

9:33 thoefer: how would you guys implement a basic binary search tree in clojure? I tried but the absence of state, even with atoms, refs etc. is quite new to me. Just a basic outline of the implementation would help enormously...

9:34 clgv: thoefer: I would use a sorted set that should be very similar ;)

9:34 chouser: thoefer: you're doing this as a learning experience? if not, just use a sorted map or set

9:34 sorted-map and sorted-set are red/black binary trees inside.

9:35 thoefer: do I have to rebuild the tree everytime I add a new node? It´s some kind of evaluation for a smaller university project :)

9:35 chouser: evaluation of you or the language?

9:35 fdaoud: :D

9:35 thoefer: both :)

9:36 Blafasel: is there a way to have something like (fn [&varargs] ..) in the #() form? Is there a magic % way?

9:36 chouser: Blafasel: %&

9:37 Blafasel: ,(#(println %&) [1 2 3] [4 5 6])

9:37 chouser: thoefer: so I still don't understand if you want to write your own code to do binary tree stuff, or if you're wanting to understand sorted-map better.

9:37 clgv: black magic O.O

9:37 clojurebot: ([1 2 3] [4 5 6])

9:37 Blafasel: Ah..

9:40 thoefer: chouser: I want to implement my own binary search tree, maybe my problem can be reduced to the question if I have to rebuild the entire tree when I add a new node?!

9:42 chouser: thoefer: ah, yes you'll need to recreate all the nodes in the path from the root to the node you're adding.

9:42 thoefer: chouser: that sounds really expensive... anyway thanks!

9:42 clojurebot: chouser: it's tougher with guards (arbitrary tests), where grouping is less clear. I need to work that out still.

9:43 kzar: Can you def a variable in another namespace? like (def some-other.namespace/*whatever* 42)

9:43 chouser: this is why the most commonly used collections in Clojure are not binary

9:43 thoefer: they have up to 32 children per node so that trees are very shallow and not so many nodes need to be recreated for changes

9:44 thoefer: also transients allow batches of changes to be made without creating new intermediate nodes

9:44 thoefer: ok, that´s a reasonable optimization

9:45 chouser: thoefer: but yes, it is both less fast and more complicated than a mutable tree. But the benefits in code simplicity and clarity are almost always more than worth it.

9:45 thoefer: will need to read more about transients :)

9:45 chouser: kzar: no, not without actually switching to that namespace. why do you think you want to?

9:45 :-)

9:46 kzar: chouser: Why do you think I think I want to?

9:46 heh

9:46 I'm using noir and I want to save the mode like :dev / :prod in another namespace so I can check it later

9:47 thoefer: chouser: thanks a lot for your help! making a coffee break now... :)

9:47 bhenry: kzar def an atom in that namespace and use it in the one that defines :dev / :prod

9:48 maybe?

10:05 pandeiro: is there any example online of using ClojureScript's clojure.browser.net xhr wrapper? I'm new to Clojure and don't get what I am supposed to do with the IConnection protocol to use it

10:43 chrido: hi, i have a simple problem: i have a set which i get from the database in this form ({:id "someid", :classification 2} {:id "2ndid", :classification 3})

10:44 for usage in my rest of clojure i want to map it to ({:id "someid", :classification "urgent"} {:id "2ndid", :classification "very urgent"})

10:45 so map 2=> "urgent" and 3 => "very urgent"

10:46 there must be something short to do this without if/else...

10:46 clgv: chrido: use a self-written function urgency on those maps via (update-in m [:classification] urgency) and urgency can be implemented via case

10:46 or you can use a map insteady of that function

10:47 a map like: (update-in m [:classification] {2 "urgent", 3 "very urgent"})

10:47 raek: (def classifications {2 "urgent", 3 "very urgent"}) (defn convert-entry [entry] (update-in entry [:classification] classifications)) (defn convert-entries [entries] (map convert-entry entries))

10:48 chrido: raek, clgv: thanks a lot! wasn't aware of update-in

10:48 cark: ,(let [values {2 :urgent 3 :very}] (map #(update-in % [:classification] values) [{:classification 2} {:classification 3}]))

10:48 clojurebot: ({:classification :urgent} {:classification :very})

10:49 raek: clgv: you beat me to it ;)

10:50 chrido: can it be done shorter? ;)

10:50 cark: thanks!

10:50 clgv: chrido: yeah, you can store it in the database ;)

10:51 raek: (for [m entries] (update-in m [:classification] {2 "urgent", 3 "very urgent"}))

10:51 I prefer 'for' in this case

10:51 chrido: clgv: or create a view :D

10:51 cark: raek : why ?

10:52 raek: you get less of a gap between m and entries in the code

10:52 Blafasel: java.lang.OutOfMemoryError: Java heap space

10:52 oops :)

10:52 raek: at least it looks better for bodies larger than one line

10:53 cark: raek: i don't know, map is so pervasive, it should be very readable

10:58 clgv: cark: define a function or macro that expands to the map

10:58 but I dont think it gets more readable then

11:47 Blafasel: ... 1025 lines of stacktrace? Seriously? For a 20 line file?

11:49 stuarthalloway: What's the correlation between file size and stack trace size? Aren't they orthogonal?

11:49 Blafasel: Sure.. I guess I would find 1025 excessive in any case.

11:51 stuarthalloway: What's excessive: Existence, or reporting?

11:52 1.3 repl reports 1st 10 lines, while providing access to the rest if you care

11:57 Blafasel: I just ran a couple of (probably stupid) things via java <putOptionsHere> my.clj which outputs everything. I didn't use the repl for this to check if I can get line numbers in error messages.

12:26 PPPaul: how do i kill a long running function in clojure?

12:26 via slime emacs

12:35 robermann_: C-c C-c

12:38 bye

12:55 Blafasel: Can someone help me understand what exactly happens if I declare something as (fn [[& as]] ..) vs. (fn [& as] ..) ?

12:57 joegallo: ,((fn [& xs] (prn xs)) 1 2 3)

12:57 clojurebot: (1 2 3)

12:57 joegallo: ,((fn [[& xs]] (prn xs)) [1 2 3])

12:57 clojurebot: (1 2 3)

12:58 joegallo: the first will take many arguments and turn them into a seq, called xs

12:58 pcavs: Blafasel: The first [[& as]] is destructuring the first argument as a rest argument. The second is actually taking only a rest argument.

12:58 ,((fn [&as] as) (range 10))

12:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: as in this context, compiling:(NO_SOURCE_PATH:0)>

12:59 joegallo: ,((fn [xs] (prn xs)) [1 2 3])

12:59 clojurebot: [1 2 3]

12:59 pcavs: ,((fn [&as] as) (range 10)))

12:59 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: as in this context, compiling:(NO_SOURCE_PATH:0)>

12:59 pcavs: ,((fn [& as] as) (range 10)))

12:59 clojurebot: ((0 1 2 3 4 ...))

13:00 pcavs: ,((fn [[& as]] as) (range 10)))

13:00 clojurebot: (0 1 2 3 4 ...)

13:01 Blafasel: pcavs: joegallo: Thanks.

13:12 srid: in clojurescript, (.foo o) compiles to o.foo; but foo is a function (prototype method), and I had to write (.foo o nil) to force compile it to o.foo(); is this a bug?

13:13 chouser: srid: it is not a bug.

13:13 srid: (.bar o 234) works, and .bar always takes that one argument.

13:14 chouser: On th JVM, o.foo can only be an method or field. You can't get the method as a "value"

13:14 so there's no ambiguity. This isn't true in javascript, so you have to resolve the amibuity for Clojure.

13:15 Clojure has an older interop syntax that helps out here.

13:15 (. o bar) for fields, (. o bar (arg1 arg2)) for a method call, and just (.o bar ()) for a method call with no args

13:15 srid: I also see this syntax (. o (bar)) which does o.bar()

13:16 chouser: (.bar o null) is actually doing o.bar(null), which is *almost* always the same as o.bar()

13:16 but if bar were to check its arguments.length, it could tell you passed a null arg, so (. o bar ()) is safer.

13:17 ibdknox: I find (. o (bar arg1 arg2)) clearer, but I think that's just personal preference

13:17 duck1123: a

13:18 chouser: oh, am I mistaken? maybe my examples were wrong.

13:18 srid: ibdknox: does -> work with that form? eg: (-> o (foo arg1) (bar arg2 arg3))

13:18 ibdknox: no

13:18 srid: shame

13:18 ibdknox: doto will, though... I think

13:18 srid: but i want to call bar on the object returned o.foo

13:19 ibdknox: ..

13:19 chouser: heh.

13:19 ibdknox: (.. o (foo arg1) (bar arg2 arg3))

13:19 ,(doc ..)

13:19 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

13:20 ibdknox: chouser: are you sure that (. foo bar ()) doesn't pass an empty list as the first arg?

13:20 zippy314: Hi, can anybody point to instructions (or tell me) on how, in my lein project.clj, to refer to my own fork of github project that's a dependency normally on clojars? I feel like the answer should be really straight-forward, but haven't been able to figure it out. Thanks.

13:21 chouser: srid, ibdknox: I think I was wrong in my examples.

13:21 should be (. o (bar arg1 arg2)) and (. o (bar))

13:21 ibdknox: k

13:21 srid: ibdknox: .. is exactly what I need.

13:21 ibdknox: I know those word

13:21 work*

13:21 without caveat

13:21 chouser: I always disliked that syntax as was happy we got (.foo bar) and (Foo/bar)

13:21 alas

13:22 ibdknox: haha

13:22 back again!

13:22 srid: chouser: me too

13:22 technomancy: zippy314: look in the readme for the section on "checkout dependencies"

13:22 srid: ((.foo bar))?

13:22 ibdknox: don't do that

13:22 chouser: yeah, that's something else again

13:22 bar will see a "this" of null

13:22 srid: javascript, oh my!

13:25 PPPaul: if i spin up an infinite amount of futures (one a second or something) will i run into any problems? (i'm waiting for each one to finish before i start a new one, i know it's not really a good use of a future)

13:25 technomancy: PPPaul: it's fine as long as you have infinite hardware

13:25 PPPaul: oh

13:26 should i be reusing a future or something?

13:26 hiredman: it's fine

13:26 technomancy: I'm just messing with you

13:26 PPPaul: :P

13:26 technomancy: they'll use a thread pool

13:26 zippy314: technomancy: I don't quite understand. You mean if I clone my fork, and symlink that clone into myproject/checkouts then lein will include the files from that directory as if I had named them as a dependency?

13:26 hiredman: futures will be garbage collected when you are done with them

13:26 technomancy: zippy314: right

13:26 hiredman: technomancy: I don't think checkout deps are what he wants

13:26 PPPaul: cool, that's what i was hoping for. just wondering if i had to do any cleanup

13:27 zippy314: technomancy: sweet! Thanks!

13:27 technomancy: zippy314: but if you want it to be usable by others you should consider a clojars-hosted fork

13:27 as hiredman alludes to

13:27 chouser: PPPaul: you'll have to shutdown the agent pools to exit cleanly, but that's all. see (shutdown-agents)

13:27 technomancy: org.clojars.zippy312/mylib

13:28 PPPaul: i'm not really sure what that means

13:28 zippy314: technomancy: Nah, this is only because the main fork hasn't pulled a feature I need yet. Have you considered adding a way in lein just to be able to point directly to a git repo?

13:29 technomancy: zippy314: checkout deps should work with submodules

13:29 PPPaul: i want my program to run forever, making futures forever... so i don't think i'll be calling shutdown agents

13:30 technomancy: zippy314: without using submodules you should think through the fact that no one else working on the project will have the checkout deps set up for them

13:30 so it should be able to work from the clojars version as well to play nicely with others

13:32 zippy314: technomancy: No, I was thinking just in general that it would be nice simply to be able to put in a the url of a git repo of a project (instead of a repository hosted name) and have lein pull down that repo, build it right in the checkouts directory.

13:38 arohner: did to-byte-array make it into new-contrib?

13:44 cemerick: Google Closure seems to insist on defining some top-level functions even if the code it's optimizing is entirely contained within a single closure. Has anyone noticed this / needed to get around this?

13:45 * cemerick should probably go look at the gclosure javadoc

13:45 chouser: cemerick: haven't noticed, no.

13:46 cemerick: a friend of mine (and until recently a co-worker) is actively looking at ClojureScript for CouchDB as well

13:46 cemerick: I've got views and such working just fine

13:47 chouser: ok, so you may be ahead of where he is.

13:47 cemerick: They're tightening up what's acceptable in a view function definition in 1.2 though — must be a single expression

13:47 I can wrap what cljs produces with (function () { … })(), but gclosure puts a bunch of top-level `function B () { …}` sorts of definitions when it optimizes.

13:48 hiredman: λ lifting I imagine

13:48 cemerick: The bottom line being, it works, will work even in couch 1.2 with simple optimizations, but that a *lot* of code in a view fn. :-P

13:49 hiredman: right; there may be an option for controlling that in gclosure's API, but I haven't gone spelunking yet.

13:50 It has a functionally top-level scope already though, so I don't see the utility of defining those fns outside of it.

13:50 (since you're supposed to give the compiler all the js you're optimizing anyway)

13:50 hiredman: good point

13:50 huh

13:51 cemerick: I'll dink around. Got to get the deck ready for tonight. I'll probably msg the dev list with my set of demands^H^H^H^H^H issues next week.

13:52 jodaro: quick lein question: is there project metadata available, i.e. does the project's version get stashed into a var somehwere?

13:53 my use case is to have the project version as part of the user-agent string in a restful api client

13:53 and not have to remember to update it in > 1 place

13:55 actually i'm not even sure how that would work

13:55 but

14:01 gfredericks: jodaro: my limited knowledge doubts it

14:01 technomancy: jodaro: it's set as a system property

14:01 (System/getProperty "myproject.version")

14:02 * gfredericks can't think of anything funny to say

14:02 jodaro: ahh

14:02 that makes sense

14:03 gfredericks: does anybody know what an unbound fn is? I'm trying to call a clojure function from java via RT.var(...)

14:03 and getting an exception after casting to IFn

14:03 well I mean the casting works fine, the exception comes from fn.call()

14:04 hiredman: the namespace the var is in isn't loaded

14:04 (the var hasn't been initialized)

14:04 gfredericks: hiredman: ah ha

14:04 hiredman: so I gotta require it somehow

14:04 * gfredericks hopes there's an RT.require method

14:10 gfredericks: alright, does anybody know how to load a namespace from RT? Do a gotta load a "(require ...)" string?

14:14 cemerick: gfredericks: RT.var("clojure.core", "require").invoke(…)

14:15 Java Swing method names and Clojure internals, these are the things I remember. :-P

14:15 gfredericks: cemerick: not sure why I didn't think of that. Quite thanks.

14:17 I'm curious why Var#invoke exists. I assume it's some kind of optimization, but not sure what for.

14:18 hiredman: the opposite, it just makes things easier

14:19 gfredericks: my intuition fails me again!

14:21 (Symbol/create "foo")

14:21 whoops not my repl

14:27 devth: when i use a (future) it makes it very hard to debug anything since exceptions inside the future call aren't relayed back to the repl. is there a way to peer inside and see if there are exceptions?

14:29 hiredman: (try … (catch Throwable t (.printStacktrace t)))

14:29 or use clojure.tools.logging

14:30 devth: hiredman: thanks, i'll try that.

14:50 dafra: hi there

14:50 how to require some clojurecode from clojurescript ?

14:52 zerokarmaleft: what does RT stand for in clojure.lang.RT? reader types?

14:52 technomancy: runtime

15:01 dafra: anybody knows how to require or use clojure code from clojurescript ?

15:01 ibdknox: add :require or :use to your ns decl

15:02 dafra: i didnt manage to :require nor :use *.clj from *.cljs

15:02 i have to duplicate the file

15:02 ibdknox: ah sorry

15:02 misread

15:02 you can't yet

15:02 dafra: i hope its planned

15:03 ibdknox: it's on the list

15:04 dafra: wher's that list ?

15:06 ibdknox: I don't believe there's a physical list. I meant more metaphorically that it's on the minds of those working on it

15:07 Raynes: It's in my sock drawer, underneath my internets.

15:07 dafra: just looked at the clojurescript jira, and no ticket there

15:07 ibdknox: Raynes, good place for it really

15:08 dafra, feel free to add one, but its been discussed a fair amount both here and on the clojure-dev mailing list

15:08 how exactly it should be done hasn't been decided

15:08 dafra: ibdknox: googling for clojurescript clojure require is of little help

15:09 ibdknox: google still barely aware of clojurescript

15:12 gfredericks: since duck-streams is deprecated, is there an append-spit anywhere, or do I have to make my own?

15:13 ibdknox: gfredericks, I don't think it made it anywhere

15:13 gfredericks: ibdknox: :/ oh well

15:14 * gfredericks copies it out of duck-streams

15:15 amalloy: ibdknox: really, it's planned? i thought rich's whole thing was that you can't easily "reuse" clj code in cljs and so you shouldn't try

15:16 ibdknox: amalloy: I can't remember which thread brought it back up, but rich didn't comment on it

15:16 Dnolen and I have been going back and forth on how to do it some

15:16 I see no reason why we can't share algorithmic code

15:17 gfredericks: dnolen made his match library work for both, right?

15:17 ibdknox: yes

15:17 dafra: you usually duplicate some controls in server and client

15:17 dnolen: amalloy: rhickey was not against the idea of reuse between Clojure/ClojureScript. There's a ticket assigned to him. I don't expect rapid movement on it though since a solutions needs to be carefully considered as it will change Clojure.

15:18 ibdknox: dnolen, I'm still not convinced it *has* to change Clojure. What's the forcing function there?

15:18 dnolen: macro-centric stuff (which is a lot of what I do) of course is easy to port. library stuff much more challenging.

15:18 dafra: dnolen: jsut parse clj file as cljs

15:19 we can have a polyglot subset

15:19 ibdknox: well, you'd want meta-data saying it should be parsed as such, but yes

15:19 gfredericks: foo_bar.clj[s]

15:19 ibdknox: lol

15:20 dafra: ibdknox: why is this metadata needed ?

15:20 ibdknox: simple functions work the same in both languages

15:20 ibdknox: dafra, why parse a bunch of files that are guaranteed not to work?

15:21 dafra, it should be an explicit choice

15:21 dnolen: there subtle issues around the fact that types don't map cleanly, nor interfaces, nor protocols.

15:21 dafra: ibdknox: maybe *.clp for polyglot files

15:21 ibdknox: supporting both cljs and clj from a single file will require deliberate care

15:21 cemerick: This seems like not-a-problem, fundamentally.

15:22 ibdknox: cemerick, doing it? or needing it?

15:22 cemerick: worrying about portability

15:22 People that need it (library authors) can take care when possible.

15:23 Especially at this early stage, thinking about how to maximize portability seems like a waste.

15:23 gfredericks: cemerick: you don't think it'd be common in app code? e.g., user data validation?

15:23 ibdknox: I agree, I just want it to work :)

15:24 dafra: same here

15:24 ibdknox: really it's probably a couple line change in the cljs compiler to enable such a thing

15:24 pick up *.clj files, if their ns decl doesn't have :cljs-compat or something in it, move on

15:24 cemerick: gfredericks: common? Probably not. You need to have *zero* interop. That takes a lot of code off the table.

15:25 dafra: dnolen: how are protocol different ?

15:25 ibdknox: cemerick, I have a number of things that I would definitely factor into code to be used in both places

15:25 dnolen: dafra: ClojureScript has protocols early on, Clojure relies on a lot of interfaces.

15:25 cemerick: ibdknox: you're a library author ;-)

15:25 ibdknox: cemerick, touche

15:25 lol

15:25 dafra: dnolen: for new code we can use protocols for both

15:26 ibdknox: cemerick, templates are a good example, outside of lib code though

15:26 cemerick: I'm just saying, it's a rat's nest of little details. There's nothing to gain from anyone working on the problem too hard (or doing anything 'simple' and thereby guaranteeing a constant stream of "it doesn't work" messages on the list).

15:26 ibdknox: cemerick, with my impl of hiccup in pinot, they can be used transparently from client or server

15:26 cemerick: clojure : cljs :: clojure : ClojureCLR, IMO

15:27 dnolen: cemerick: I'm skeptical, as people beging to realize that ClojureScript is NOT "Clojure Light" - they'll want some level of interoperability.

15:27 cemerick: ibdknox: symlink to .cljs?

15:28 ibdknox: hah, now I feel dumb

15:28 gfredericks: dnolen: that makes more sense with s/beging/begin/ than with s/beging/begging/ :)

15:28 kzar: ibdknox: Is there a way to filter a route variable and store the result of running the filtering function? Say if I want to query the database to see if a post exists before I decide if the route's valid, but I want to save the result in the case that it is, so I can display it.

15:28 cemerick: dnolen: ClojureCLR is certainly not 'clojure light'; all the same issues apply

15:28 dnolen: cemerick: what about a common graphics library that can target Java surfaces and the browser

15:28 ibdknox: kzar, just do that in the body using a when-let

15:29 * cemerick winces

15:29 dnolen: cemerick: not even remotely the same. JS is the most widely deployed language in the entire world except for C.

15:29 ClojureCLR has a low adoption ceiling, ClojureScript not so much.

15:29 cemerick: That doesn't speak to the portability challenges.

15:29 ibdknox: kzar, if the handler returns nil, it's the same as it not being valid

15:29 hiredman: working on backend data processing is great, I don't have to care about any of this

15:29 cemerick: hiredman: seconded

15:29 kzar: ibdknox: Ah, cool thanks

15:30 cemerick: says the fool talking about clojurescript views in couch

15:30 ibdknox: cemerick, :p

15:31 dnolen: cemerick: macro-centric stuff has shown me how small the differences really. But all my workarounds are very ad-hoc.

15:31 cemerick: dnolen: to clarify, I think portability would be great, I just don't think anyone really knows how to do it right yet. And cljs will almost surely be the first target for whatever solutions are devised.

15:31 dnolen: cemerick: not disagreeing there's no reason to rush into a solution.

15:31 gfredericks: dnolen: doing macros kind of sidesteps any runtime differences, doesn't it?

15:31 cemerick: Then let's just get a drink.

15:32 gfredericks: not sidesteps, but doesn't come into contact with

15:32 cemerick: dnolen: have you twiddled with gclosure's compiler options any?

15:32 dnolen: gfredericks: not entirely. for example try/catch in Clojure / ClojureScript not the same.

15:32 gfredericks: ah ha

15:32 dnolen: cemerick: no not much.

15:32 hiredman: and macros themselves are different

15:32 you have to load macros differently in clojurescript

15:33 dafra: dnolen: how is try/catch different ?

15:34 dnolen: dafra: in JS you just catch the error and bind it to a name, in Java you have to specify the exception type.

15:35 dafra: dnolen: i've read about some plan to replace exceptions with default handlers, dont know if its done alreasy

15:36 already, certainly not easy

15:36 dnolen: cemerick: any other early ClojureScript impressions?

15:37 wink: what? no catch Throwable e? ;)

15:37 dnolen: dafra: yeah I'm not sure where the Clojure exception stuff is headed.

15:43 TimMc: It would be nice to have an alternate catch (with no specification of exception type) in Clojure so that code could be compatible.

15:43 gfredericks: (inc TimMc)

15:43 lazybot: ⟹ 3

15:43 * TimMc makes yet another note to send in that damn CA

15:48 srid: is there a primitive to iterate items in *serious* of collections that may have overlapping items? I can't use (seq (conj coll1 coll2 ...)) here because when conj'ing a map, i'll lose duplicate elements

15:48 *series*

15:49 hiredman: serious?

15:49 brehaut: javascripts try/catch doesn't just have to bind a name; the catch clause can have a guard expression too

15:49 hiredman: well, conj won't give you a series of collections anyway

15:49 amalloy: mapcat?

15:49 or just concat? it's not clear what you want

15:51 srid: amalloy: concat works. trying to solve conj

15:51 s/conj/http://www.4clojure.com/problem/69/

16:03 PPPaul: how do i use (binding []) to have a threat print to the slime console?

16:05 leafw: hi. Where can one find the jar for the monads library that used to be in clojure-contrib.jar ?

16:06 or, what does one write in the project.clj from lein?

16:08 brehaut: leafw: the new algo.monads is [org.clojure/algo.monads "0.1.1-SNAPSHOT"] and you need to also add :repositories {"sonatype-snapshots" "https://oss.sonatype.org/content/repositories/snapshots/&quot;} to your project.clj to get leon to search the snapshots repo

16:10 leafw: thanks brehaut, that helped lots. Is there any webpage where this is explained, or one has just to find out here?

16:10 brehaut: leafw: no idea actually; i figured it out by watching IRC for a few days and piecing things together

16:11 leafw: remember to switch your use or require stuff to clojure.algo.monads too

16:11 leafw: indeed, thanks

16:11 zerokarmaleft: leafw: for the library itself? https://github.com/clojure/algo.monads has tutorial links

16:11 leafw: thanks zerokarmaleft

16:12 zerokarmaleft: i imagine they were written pre-1.3, though

16:12 brehaut: leafw: out of curiosity, what are you using it for?

16:12 srid: amalloy: through #128 I discovered that maps can take a 2nd argument.

16:12 zerokarmaleft: brehaut: how'd you figure out where the jar was hosted since it's not on clojars?

16:13 leafw: a file text parser, with (def parser-m (state-t maybe-m)) and then defining my own domain language for the parsing.

16:13 brehaut: zerokarmaleft: watching IRC; i think hiredman mentioned something about the snapshot repo

16:13 zerokarmaleft: fair enough

16:13 brehaut: leafw: cool :) before you get to far, you know about fnparse right?

16:13 hiredman: I don mention stuff about things sometimes

16:14 leafw: the github.com/clojure/algo.monads could explain what brehaut knows about lein and the jar ... would help more people than just me

16:14 brehaut: no, didn't know about fnparse

16:14 brehaut: I am just adapting existing code to 1.3.0, and the clojure-contrib disappeared.

16:14 hiredman: there are a number of different parsing libraries for clojure

16:14 brehaut: leafw: there also a variety of clj-parsec ports too, but fnparse is the most used parser combinator lib for clj at the moment

16:15 leafw: will definitely checkout fnparse, thanks for the tip

16:15 brehaut: cgrand's parsley sounds interesting too

16:17 leafw: ok, found the jar, back to work. See you all later and thanks for the help.

16:19 quit

16:22 PPPaul: i want to bind a var used in a future, that is declared outside of the future... i'm trying (binding [varName 0]...) but it's not working in the future

16:22 hiredman: PPPaul: declared?

16:23 I suspect var does not mean what you think it does

16:23 cemerick: I guess I need to understand gclosure better: it will 'optimize' "a.someRealName" into "a.L" or whatever. Shouldn't that not happen?

16:24 bpr: cemerick: iirc that won't occur if you "export" the name

16:24 PPPaul: (def varName 100)

16:24 (binding [varName 0] function)

16:25 when the function isn't a future, it works, but in the future it doesn't work

16:25 cemerick: bpr: in that example, `a` is a function argument…

16:25 bpr: oh

16:25 hiredman: PPPaul: what version of clojure?

16:25 cemerick: I suppose that doesn't matter. (aget a "someRealName") is a bummer, tho.

16:25 PPPaul: 1.2

16:25 will this be different in 1.3?

16:26 hiredman: vars are not dynamic by default in 1.3

16:26 and how are you binding it in the future?

16:26 PPPaul: i'm binding it before calling the future

16:27 technomancy: cemerick: a bit late on the discussion, but this seems relevant re: sharing code across runtimes: http://blog.ianbicking.org/2011/03/30/js-on-server-and-client-is-not-a-big-deal/

16:27 PPPaul: (binding [varName 0] (future ...))

16:27 amalloy: bindings are thread-local

16:27 hiredman: that is not in the future

16:27 technomancy: I think templates are probably one of the few places it makes a lot of sense for app code

16:27 PPPaul: oh

16:27 dnolen: brehaut: good point, though still, different than Java

16:27 PPPaul: how would i force the var to be different in the future, from outside the future?

16:28 amalloy: just...(future (binding ...))

16:28 PPPaul: or is that impossible?

16:28 oh

16:28 what if that future makes more futures?

16:28 amalloy: as of 1.3 they're a little bit less thread-local so your original version would probably work, but this is clearer

16:28 cemerick: technomancy: yeah, and honest-to-goodness algorithmic stuff e.g. core.logic

16:28 amalloy: PPPaul: then you're probably abusing futures :P

16:28 PPPaul: ^_^

16:29 i'll try 1.3 first

16:31 oh, my -main doesn't work anymore in clojure 1.3

16:32 oh shit, my deps don't work in clojure 1.3

16:32 :(

16:33 amalloy: PPPaul: this is god telling you not to abuse futures and bindings

16:34 Bronsa: what if PPPaul is atheist :P

16:34 gtrak: anybody think about using clojurescript with XUL or something for desktop apps yet?

16:35 arkh: gtrak: I've thought about it ; ) I was looking at prism, tho

16:35 rbranson: make clojurescript generate actionscript, use adobe air #winning

16:37 gtrak: looks neat

16:37 rbranson, there is las3r

16:38 i know some flex already, actually clojure there would be pretty sweet

16:40 what about haxe?

16:52 dabd: I'd like to use a Java lib that defines an interface that I need to implement. what is the best way? reify?

16:59 amalloy: yes

16:59 i mean, defrecord or deftype may be best in some circumstances, but reify is a generally-useful tool for this

16:59 arohner: dabd: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

17:00 dabd: arohner:ty

17:02 I don't want to define a new type I just need to implement an interface so I am not sure if reify or proxy should be used. I'd like to implement this interface http://commons.apache.org/math/apidocs/org/apache/commons/math/analysis/UnivariateRealFunction.html

17:11 PPPaul: when i do (future (binding [var val] f)) i get a thread error

17:12 hiredman: "thread error"

17:14 PPPaul: oh shit, it's working now

17:14 :(

17:28 would someone be able to help me with my binding problem?

17:29 amalloy: dabd: you do want to define a type, because you need to implement an interface, which java requires types for

17:29 but proxy should be used only when reify isn't enough

17:30 dabd: amalloy: yeah it looks like I need proxy

17:30 amalloy: wth, why?

17:30 you definitely do not need proxy to implement some interface

17:30 dabd: amalloy: bc I need to pass an instance of the implemented class

17:31 amalloy: &(.size (reify java.util.Collection (size [this] 10)))

17:31 lazybot: ⇒ 10

17:31 amalloy: dabd: reify gives you an instance, that's the whole point

17:32 dabd: amalloy: ok then reify should do it

17:33 dnolen: PPPaul: if you don't get an answer here, you can always ask on the mailing list as well.

17:35 cemerick: dnolen: you asked before, but I didn't answer: my bottom line impression of clojurescript right now is, it's fabulous as long as you know where the potholes are. The biggest potholes being around interop.

17:35 i.e. the map / object / array strangeness has tagged me many, many times so far.

17:36 melipone: how do I convert a string to a keyword? for example "D" to :d ?

17:37 dabd: amalloy: with proxy I don't get any errors but with reify this: (reify org.apache.commons.math.analysis.UnivariateRealFunction (value [x] x)) gives me an error: Can't define method not in interfaces: value

17:37 amalloy: (value [this x] x)

17:37 cemerick: ,(-> "D" .toLowerCase keyword)

17:37 clojurebot: :d

17:37 cemerick: melipone: ^

17:37 melipone: thnaks!

17:37 dabd: amalloy: the method value is in the interface http://commons.apache.org/math/api-2.0/index.html

17:37 srid: is there a primitive that does negation of a function? #(not (p %))

17:37 cemerick: srid: complement

17:38 dnolen: cemerick: yeah the map / object / array thing didn't bother me much since I was expecting that.

17:38 pjstadig: ,(doc complement)

17:38 clojurebot: "([f]); Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value."

17:38 amalloy: dabd: see my previous answer

17:38 dnolen: cemerick: I've found interop less of an issue but I'm not trying to use it for CouchDB views either.

17:38 dabd: amalloy: ok I need the 'this'

17:39 cemerick: There's nothing couchdb-specific about it, I don't think.

17:39 dnolen: cemerick: excepts that views are meant to be small snippets of JS. And Clojure brings along a huge API.

17:39 amalloy: proxy is an older construct; since then all the "type-oriented" functions require an explicit this parameter

17:39 cemerick: e.g. I needed to call a fn with a javascript array. Figuring out (apply array [1 2 3]) took 60 seconds, but it's unfortunate that that's the case.

17:40 dnolen: That's an implementation detail. ;-)

17:40 dnolen: cemerick: what's the alternative? (array example)

17:41 cemerick: Perhaps. Not sure how to get around it tho, calling seq pulls in a lot of code.

17:41 and by a lot of code - not for scripting or browser stuff - just CouchDB views.

17:42 cemerick: re: arrays, there may not be an alternative. I've not looked at core.cljs in any seriousness yet.

17:43 The fact that e.g. cljs vectors are js objects just makes for a confusing state at first — at least, compared to the jvm, where having a wrong type usually fails faster.

17:43 My overfamiliarity with Java stuff probably accentuates that issue for me, though.

17:44 dnolen: "lots of code" isn't really a serious problem for couch views. spidermonkey slurps it all in and keeps chugging away.

17:45 I can imagine hitting some implementation-specific limit on code size somewhere (esp. in nonstandard couch builds perhaps), but it hasn't happened yet.

17:45 dnolen: cemerick: well, glad you're digging in, curious to see where this stuff goes.

18:19 prokii: I am trying to embed a repl in my gui so I can interact with the running program. But I am having trouble..

18:21 I have an agent in one of the namespaces which my gui watches.. but when I use send to update the agent it returns the agent w/o the update.

18:27 amalloy: that's what agents do. they are asynchronous - the change you send can happen anytime on another thread

18:27 prokii: but the gui never updates..

18:28 it works when I send to the agent through a slime conection

18:41 jli: no one should talk about jline anymore

18:42 so I stop getting false alerts

18:45 hiredman: .win 11

18:49 srid: i seem to be able to access functions a in cljs file even without declaring them with ^:export. what is the point of export, then?

18:51 dnolen: srid: are you compiling w/ advanced optimizations?

19:09 sritchie: ,(flatten {:1 2 :3 4})

19:09 clojurebot: ()

19:10 sritchie: is that the expected behaviour?

19:10 hiredman: ,:1

19:10 clojurebot: :1

19:11 sritchie: that's in 1.3.0

19:11 hiredman: ,(doc flatten)

19:11 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

19:11 hiredman: ^- "...sequential things..."

19:12 sritchie: ,(for [[k v] {:1 2 :3 4}] k)

19:12 clojurebot: (:1 :3)

19:12 hiredman: maps are not sequential

19:13 ,(flatten (seq {1 2 3 4}))

19:13 clojurebot: (1 2 3 4)

19:13 sritchie: true, good point

19:13 ,(flatten #{1 2 3})

19:13 clojurebot: ()

19:13 hiredman: also not sequential

19:13 sritchie: yeah, just clarifying for myself

19:13 I was just surprised that it returned an empty sequence

19:15 no_mind: What is the best way to run compile on a namespace ? I want to do this during build time.

19:15 hiredman: lein compile

19:15 (go read the docs)

19:15 no_mind: will this not compile all namespaces ?

19:16 hiredman: ^-

19:16 khaliG: hiredman, except the array-map? :P

19:21 sritchie: ,(sequential? (array-map :1 2 :3 4))

19:21 clojurebot: false

19:22 hiredman: 58.259 hiredman maps are not sequential

19:23 technomancy: no_mind: looks like the docstring fails to mention you can do lein compile :all

19:23 khaliG: wrap it in seq

19:23 sritchie: apply concat's fine for me

19:23 ,(apply concat {:1 2 :3 4})

19:23 clojurebot: (:1 2 :3 4)

19:34 eanxgeek: ping clojure trying to build a package w/ lein on Mac OS X lion and am getting java.lang.IllegalArgumentException: Duplicate key: clojars (NO_SOURCE_FILE:0)

19:34 _khaliG: ,(sequential? (seq (array-map :1 2 :3 4)))

19:34 clojurebot: true

19:34 eanxgeek: I am new to clojure and this is my first attempt at doing this on Mac

19:35 technomancy: eanxgeek: probably something wrong with the :repositories key in project.clj

19:37 eanxgeek: technomancy: this project.clj someone else wrote but looks good, :repositories {"clojars" {:url "http://clojars.org/repo" :snapshots {:update :always}}}

19:38 technomancy: eanxgeek: that's going to conflict with the defaults

19:39 either remove it or add :omit-default-repositories and add central to your list

19:40 eanxgeek: technomancy: ok I commented out the lines with ;;

19:40 and now get a java.lang.Exception: EOF

19:41 technomancy: comment out the whole map

19:45 * gfredericks just learned about treaps

19:46 eanxgeek: technomancy: ok as I mentioned I'm very new to this, if I wanted to go the other route, so as to do minimal damage to the project.clj how would I specify the :omit-default-repositories and add central?

19:47 I tried doing :omit-default-repositories under :repositories

19:47 but not sure how or where to specify central

19:48 gary_poster: Hi. I don't understand something. I can give a type hint in defrecord for float (and other things) but not keyword. Why not? This is 1.3.0. Here's my example in the REPL:

19:48 technomancy: something like this http://p.hagelb.org/project.clj.html

19:49 eanxgeek: technomancy: cool I did get the comments to work too

19:49 thanks!

19:49 gary_poster: user> (defrecord Test [^float value])

19:49 user.Test

19:49 user> (defrecord Test [^keyword value])

19:49 ; Evaluation aborted.

19:49 Unable to resolve classname: keyword

19:49 [Thrown class java.lang.IllegalArgumentException]

19:49 technomancy: eanxgeek: no problem

19:50 gfredericks: gary_poster: use a pastie next time

19:50 hiredman: gary_poster: why do you need to type hint a keyword?

19:50 gary_poster: yeah sorry gfredericks, I thought it was just under the limit. I'll adjust smaller

19:50 hiredman: (short answer: you don't, so don't)

19:50 gary_poster: hiredman, I was doing it for documentation

19:50 hiredman: it's not documentation

19:50 gary_poster: why not?

19:51 hiredman: doncumentation starts with ;;

19:51 gary_poster: It is advertised somewhere or other as a reasonable way to document stuff

19:51 citation eeded I know

19:51 hiredman: so?

19:51 gary_poster: but it seemed reasonable

19:51 hiredman: I don't really care what a blog says somewhere

19:51 gfredericks: gary_poster: irrespective of whether it's a good idea, my guess is that you would have to use ^clojure.lang.Keyword

19:52 gary_poster: so...I liked it...and it seems like it ought to work...and it doesn't. No, this is either Joy of Clojure or Programming Clojure.

19:52 hiredman: and?

19:52 (none of that changes the fact that it is not documentation)

19:53 for documentation you have comments and doc strings

19:53 gary_poster: hiredman, you seem unnecessarily peeved by me question! I'm learning clojure and using some standard well known books to do so. The advice comes from them

19:53 hiredman: the advice is incorrect

19:53 gary_poster: s/me/my/

19:53 lazybot: <gary_poster> hiredman, you seem unnecessarily peeved by my question! I'm learning clojure and using somy standard well known books to do so. The advice comys from them

19:53 gary_poster: oh bah

19:53 to lazybot

19:54 hiredman: http://dev.clojure.org/display/design/Library+Coding+Standards

19:56 gary_poster: ack hiredman, thanks

19:56 hiredman: I peeved because it annoys me to give sound advice to people who are learning the language and then have them say "well, this book/blog post/motivational speaker says to do it like X"

19:58 gfredericks: hiredman: somebody who's learning the language probably doesn't have a good way to compare the merits of you vs a blogger

19:59 hiredman: gfredericks: fine, then why are they so attached to the bad advice they get?

19:59 devn: Is there a way to get the cheat sheet fns that can be called, on, a seq?

19:59 (in clojure.repl or something)

20:01 pjstadig: https://github.com/technomancy/corkscrew

20:02 technomancy: pjstadig: aw man, why you gotta go digging through my closet?

20:02 gfredericks: hiredman: my guess is he's hoping to write code that's in line with what's accepted by the community. Maybe by countering he was testing your confidence. You could have been also a beginner who tends to sound oversure, and upon hearing that JoC says the opposite, backed down.

20:02 _khaliG: where does JoC say that?

20:02 hiredman: ugh, I really hope it's not the JoC

20:02 pjstadig: technomancy: it's all up on github

20:02 hiredman: (but I will admit I never finished my copy of JoC so it could be)

20:03 technomancy: pjstadig: I'd delete it, but there's the small matter of the language highscore board

20:03 gfredericks: _khaliG: no idea, I think gary_poster just mentioned it

20:03 _khaliG: JoC is a horrible book in any case, but i dont remember reading it there :/

20:03 devn: really? you think that?

20:03 I completely disagree.

20:04 JoC is a great book.

20:04 pjstadig: technomancy: hehe you and your gaming of github

20:04 technomancy: pjstadig: we gotta make a comeback after coffeescript passed clojure

20:04 devn: JoC has so much extra knowledge in it that you don't get out of most books.

20:04 technomancy: are you doing your part?

20:04 _khaliG: devn, not on my book shelf :)

20:05 devn: It's a cultural document and a great general programming book, and a great Clojure book.

20:05 * devn shrugs

20:05 pjstadig: i forked die-roboter

20:05 devn: _khaliG: different strokes I suppose. I really enjoyed it.

20:05 technomancy: pjstadig: you got Big Plans?

20:05 gfredericks: hiredman: in any case, my impression is that documentation is an abstract term, distinct from comments and docstrings. type hints are totally capable of documenting the expected types of arguments. Whether or not you think it's a _good_ way to document expected types is more up for discussion, IMO

20:05 pjstadig: looking for projects at capclug

20:06 devn: gfredericks: I tend to agree that there isn't a concrete reason to choose not to use type hints, but I think they can be overused and are sometimes completely inappropriate.

20:06 hiredman: gfredericks: type hints communicate information to the compiler for generating faster code, they are not designed for communicating information to people, documentation is

20:07 _khaliG: devn, i've got SICP, PAIP etc down as great books. I found JoY really hard to understand - i still dont think i've learnt anything out from it. The other book Practical Clojure is excellent though.

20:07 gfredericks: hiredman: they may not be designed to do that, but they certainly can

20:07 devn: gfredericks: I think it is more idiomatic (w/r/t to 3rd party libs and so on), to talk about what you expect and return in the actual :doc meta on the function

20:07 gfredericks: hiredman: I just think "type hints are not documentation" is too strong

20:07 devn: I don't disagree

20:07 devn: but I don't disagree with people using type hints if that's a key area you want to highlight

20:07 hiredman: type hints are bad style, clojure 1.3 requires less type hints to get good performance for a reason

20:07 that reason is we don't want them

20:07 gfredericks: hiredman: no disagreement there

20:07 devn: in general though I do not believe in using type hints, but I sometimes use them when I "concretize" some function

20:08 I will say and represent that something is "stable" or "hard" in the program by using a type hint to represent how strict it is

20:08 but I rarely use them in practice. I generally opt for the docstring

20:08 You can say way more there.

20:09 type java.lang.String or something in your docstring instead of in the binding form or something, y'know?

20:09 gfredericks: yep

20:09 devn: at the same time I don't think anyone *must* do it a certain way, I just tend to think the community feels the style is more in line with what I'm prescribing

20:09 hiredman: be kind, use CharSequence (but I guess that ship has sailed)

20:10 devn: :D

20:10 gfredericks: :)

20:10 devn: just wrap all of your types! (+ (int x) (int y))!

20:10 That's the key to performance!

20:11 :)

20:11 ,(time (int (int (int (int (int (int 32)))))))

20:11 clojurebot: "Elapsed time: 0.07 msecs"

20:11 32

20:11 hiredman: actually the key is the compiler inlines (+ x y) into (clojure.lang.Numbers/add x y), and in some cases can inline the call to clojure.lang.Numbers/add as an iadd

20:12 devn: ,(time (int 32))

20:12 clojurebot: "Elapsed time: 0.068 msecs"

20:12 32

20:12 devn: hiredman: that's interesting

20:12 I didn't know that.

20:12 gfredericks: hiredman: how can it do that? because 1.3 doesn't let + be dynamic?

20:12 devn: methinks that sounds like a totally reasonable answer

20:12 gfredericks: can't the root binding still be changed?

20:12 devn: gfredericks: ewww

20:13 gfredericks: devn: ??

20:13 lazybot: gfredericks: What are you, crazy? Of course not!

20:13 devn: (alter-var-root fail)

20:13 hiredman: no, actually the compiler has inlined the 2 arity version of + into clojure.lang.Numbers/add since 1.2 at least

20:13 gfredericks: devn: I'm not saying it's fun to change var roots, I'm wondering why the compiler is allowed to inline it semantically

20:13 hiredman: ,(doc definline)

20:13 clojurebot: "([name & decl]); Experimental - like defmacro, except defines a named function whose body is the expansion, calls to which may be expanded inline as if it were a macro. Cannot be used with variadic (&) args."

20:13 hiredman: it more or less uses the definline mechanism

20:14 gfredericks: hiredman: so is this an exception to the normal behavior of vars?

20:14 or do I not know how vars work?

20:14 hiredman: yes, that is how definline works, it adds some metadate to the var which the compiler uses for inlining

20:15 turning clojure.lang.Number/add into an iadd is a late addition to 1.3

20:15 https://github.com/clojure/clojure/commit/e92978783e1ba7ac0e2617fdabfed576209d7fa4

20:16 it's semantically allowed to do it because it makes math fast

20:16 gfredericks: hiredman: what happens if you alter the root of an inlined var?

20:16 hiredman: don't

20:17 gfredericks: weird to have forbidden parts of the language

20:17 hiredman: you'll get different behaviour based on if the compiler determines it can inline or not

20:17 gfredericks: do the other lisps use vars?

20:17 hiredman: similar to alter-var-rooting macros and similar

20:18 vars are sort of like dynamic vars from common lisp

20:18 (less so in 1.3)

20:20 gfredericks: vars have always seemed weird to me. They're often discussed as a way to achieve thread-local (dynamic-scoped?) values, but at the same time they're so much more mundane than refs/agents/atoms

20:21 and then in 1.3 we change it so by default they _don't_ give you thread-local state anymore

20:21 gtrak``: gfredericks feels bad for the vars

20:21 gfredericks: it feels like there's two concepts being complected together, which I'm not used to in clojure

20:22 hiredman: they give you indirect linking

20:22 technomancy: vars have to be reference types or you couldn't update functions interactively

20:22 hiredman: right

20:22 gfredericks: yeah :/

20:22 technomancy: in ml-descendants IIRC redefinitions don't apply retroactively

20:22 hiredman: so they are very useful, but the same time you do pay a cost for them

20:23 so there are ways to avoid that cost, definline, defstatic, etc

20:24 gfredericks: hmmm

20:24 hiredman: vars are also useful as serializable function pointers

20:25 ,(prn-str #'group-by)

20:25 clojurebot: "#'clojure.core/group-by\n"

20:25 hiredman: ,(read-string (pr-str #'group-by))

20:25 clojurebot: (var clojure.core/group-by)

20:25 gfredericks: hiredman: that is quite an interesting way to look at it

20:26 hiredman: if I ever write a book, the implmentation and design decisions around vars get a chapter

20:27 gfredericks: hiredman: if you ever write a book [about clojure], I will read it.

20:27 hiredman: IIX. Vars: WTF?

20:29 gfredericks: IIX -- :D

20:29 hiredman: I want every chapter to be numbered by fake roman numerals

20:29 hiredman: how do roman numerals work again?

20:29 right, the other way

20:29 duck1123: Chapter #'IIX

20:29 gfredericks: lol

20:30 duck1123: I like vars because they allow me to write multimethods that dispatch on the function

20:30 gary_poster: _khaliG, gfredericks, hiredman, FWIW I found where I read about using type hints for documentation. In the current beta of Programming Clojure (Bedra and Holloway, clojure/core AFAIK) it says "These type hints serve three purposes: [o]ptimizing critical performance paths[, d]ocumenting the required type[, and e]nforcing the required type at runtime."

20:31 That's not to contradict hiredman or the obviously authoritative page to which he pointed, but sharing where I got it.

20:31 I haven't reviewed JoC; I've been reading the PC beta more recently.

20:31 * gary_poster goes back to RL for a bit.

20:31 gary_poster: It might or might not be in JoC, I mean

20:31 gfredericks: well now we can all sleep soundly

20:32 gtrak``: there's no downside to too many hints I guess, unless they're wrong?

20:32 hiredman: they make the code harder to read and less general

20:33 gfredericks: can you type hint with a protocol?

20:33 technomancy: gtrak``: they're wrong more often than you think

20:33 hiredman: protocols are not types

20:33 technomancy: because the code will still work if they're incorrect, so it's easy to change the code without changing the hints

20:33 (in that respect they're just like comments)

20:34 gtrak``: i don't use them except to silence the compiler

20:34 hiredman: they do generate an interface you could type hint with, but you can breaks things

20:34 gfredericks: technomancy: isn't there some context in which a type hint changes the behavior?

20:34 duck1123: I think that'll get better with 1.3 now that they're checked more

20:34 hiredman: because not everything that satisfies the protocol will implement the interface

20:34 gfredericks: hiredman: specifically things that are extend-type'ed?

20:34 hiredman: sure

20:35 gfredericks: I swear I remember being surprised at some point when I found out that a type hint could change a program's behavior

20:35 duck1123: gfredericks: if you have 2 classes that have the same method name, but you type hint the wrong way, you get odd errors

20:36 gtrak``: i've seen some rumors about optional static typing being not out of the question

20:36 technomancy: gfredericks: a wrong type hint will result in reflection

20:36 afaik

20:36 hiredman: depends how wrong it is

20:36 gfredericks: technomancy: I mean beyond those sorts of performance implications

20:36 technomancy: hiredman: oh?

20:36 gfredericks: in some case, contradicting the type hint would cause it to break

20:36 hiredman: like what duck1123 said

20:37 technomancy: aha

20:37 hiredman: if the type hint apears correct in that way, the compiler will generate a cast+method call

20:37 so the error will be a classcastexception

20:38 dnolen: type hints are not and never will be idiomatic beyond performance and interop, http://clojure-log.n01se.net/date/2008-09-21.html#16:56

20:38 devn: but no need to point that out

20:38 I think you just arrive at that conclusion on your own

20:39 It takes very little mental agility to realize they're just adding noise.

20:40 hiredman: well halloway is apparently saying they are good for documentation

20:40 the idea of arguing with him about it is just exhausting

20:40 devn: It's like being explicit for the sake of it. Why? It's like adding metadata to everything you build about their birthday or something.

20:41 I don't see any problem with that either.

20:41 gfredericks: hiredman: it might just be left over from the first version

20:41 it's certainly there in the first version

20:41 dnolen: it's left over from the first version

20:41 and it's wrong

20:41 hiredman: maybe, I never finished that book either

20:41 devn: wrong...to a point

20:42 dnolen: only the first point is relevant. there's no enforcment, and useless as a general form of documentation

20:42 devn: I can conceive of a scenario where an explicit type hint might be a nice way of documenting a particularly hairy area of "typestuff".

20:42 but again I'll say what I did earlier -- you rarely need this, but you *could* use it for some light documentation in a dark corner here or there.

20:42 It might just make *sense* to use it there.

20:43 gfredericks: devn: you can document with docstrings and comments though

20:43 devn: The majority of cases do not require it, nor do they even suggest it as a possibility.

20:43 gfredericks: I think I said that earlier.

20:43 gfredericks: devn: probably :)

20:43 devn: I'm surprised you guys are still talking about it. :)

20:43 hiredman: types tend to be simple carriers of stuff, most complex clojure stuff is nested maps and vectors

20:43 devn: It's such...minutae.

20:43 Might as well build something instead...

20:44 gfredericks: Maybe it means the language is well designed, since we _could_ be sitting here griping about why our language doesn't have closures or integers.

20:44 devn: lol

20:44 Yeah, I think that's a fair statement.

20:44 Although, beware the dogma stick. People don't like assholes.

20:44 Even if they're right.

20:46 gfredericks: devn: in saying so you're both right _and_ not an asshole!

20:46 devn: Sorry, didn't mean to say that to you specifically gfredericks-- I just am being wary of it.

20:47 I see this in dysfunctional communities: "You don't like type systems so *fuck you*." "You can't possibly appreciate how expressive my language is so *get lost*.", etc.

20:48 duck1123: I think too many people here are also Haskell fans

20:49 devn: Strong opinions rule. We just need to be careful about being dickish about them. I think the type hints as documentation thing is minor. There is absolutely no reason for "calling out" people or being like "HOW DARE YOU!" over it.

20:49 dnolen: duck1123: cuz we know they're are evil and up to no good.

20:50 devn: dnolen: haha

20:50 btw, dnolen, i have this sinking suspicion you can give me some insight on this...

20:50 dnolen: are chunked sequences at all related to haskell "iteratees"

20:51 dnolen: devn: I don't know anything about iteratees

20:51 hiredman: there is a lot of poorly written clojure code out there, it irks me

20:51 devn: damn!

20:51 hiredman: they are not

20:51 devn: hiredman: pull requests, brother!

20:51 I've converted a haskeller or two's libraries to a more idiomatic clojure style. They were accomodating.

20:52 Just find a way to replace regex and spaceshipish function names and you're off to the races!

20:52 err replace via regex camelCase

20:53 hiredman: chunked seqs and iteratees have some similarities, stream fusionish stuff

20:53 devn: (defn <|fooThingToBuyBread|> [argumentTheFirst argumentTheSecond] stuff)

20:54 hiredman: i thought i might be nuts in thinking that. i see some "similar" features, but I just don't know them well enough to know *how* close they are.

20:55 ,(symbol "<-_->")

20:55 clojurebot: <-_->

20:55 devn: I think that should replace -main

20:59 gfredericks: devn: they really make function names like <|this|> ? or is that an exaggeration?

21:00 I don't know enough haskell to tell

21:00 devn: gfredericks: a library I idiomaticized had some interesting naming involved

21:00 it was related to parser combinators so some of them make sense

21:01 gfredericks: ah ha

21:01 devn: but even still it just made things look a bit...messy

21:01 gfredericks: I wonder if scala refugees are worse

21:01 devn: (defn <|> [])

21:01 etc.

21:01 dum dee dum: (<|> ...)

21:02 duck1123: it would be fun to name a bunch of clojure functions to look like html elements just to troll people

21:02 devn: it just reads weird. maybe I'm being emotional about it, but my experience is that those naming styles are just weird

21:02 i like having freedom in clojure to use UTF-8 craziness

21:02 but don't let the freedom lead you astray and so on

21:02 with great power comes great responsibility and so on

21:03 ,(defn æ [])

21:03 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

21:03 devn: awww

21:04 ,(defn <-Ã->¸ [])

21:04 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

21:04 gfredericks: ,(let [defn list] (defn æ []))

21:04 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

21:04 gfredericks: haha

21:04 devn: hiredman thought of everything, unfortunately

21:04 ;)

21:04 gfredericks: but that one was harmless

21:04 &(let [defn list] (defn æ []))

21:04 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

21:04 gfredericks: ack

21:05 duck1123: better safe than sorry

21:05 devn: whitelist, dont blacklist

21:05 that's the rule of rules

21:05 or it seems to be anyway

21:05 so gfredericks duck1123 i dont know you guys

21:05 hi!

21:05 gfredericks: hi devn!

21:06 duck1123: hello

21:06 devn: what are you guys getting into? should i know you already? you guys work in clojure or just hobbying?

21:07 gfredericks: I do webbish development for a medical university, and use clojure a good portion of the time. I'm currently agonizing over whether I'd be happier doing more development for the rest of my life or trying to be academic.

21:07 devn: learning it for fun, for profit, for job security, because your friend won't shut up about how awesome it is?

21:07 duck1123: I'm working on an OStatus-compatible microblog. (similar to identi.ca)

21:07 gfredericks: I also use it for nearly all my personal projects

21:07 devn: gfredericks: very cool

21:07 duck1123: equally awesome

21:08 duck1123: I'm so glad I'm finally able to use Clojure for my projects at work

21:08 devn: yeah that's great to hear

21:08 it seems like work in that area is heating up

21:08 duck1123: up to this point we've been using Ruby

21:08 gfredericks: I was first introduced to clojure at work, two years ago

21:08 devn: Yeah I work at a Ruby shop primarily. We've done bits of clojure work here and there, and I think I'm slowly converting-- but it takes time to show people the why

21:08 gfredericks: six months after I was first introduced to ruby/erlang, which was the first I had heard of functional programming

21:09 technomancy: devn: where is that?

21:09 devn: gfredericks: whoever introduced you must be pretty awesome

21:09 technomancy: bendyworks

21:10 gfredericks: devn: he definitely stood out

21:10 devn: i feel like an old fuddy duddy saying this because there is so much more happening now than there was then

21:10 gfredericks: based on bendyworks.com I'd say it's a typography shop

21:10 devn: but seeing this place grow out of a crack in the cement has been so incredibly fun to watch

21:11 gfredericks: it's a shop that hired a designer ;)

21:11 gfredericks: devn: that right there is so far out of my range of experience...

21:11 it's a pretty slick front page though

21:12 I've never seen such a scrolling effect before

21:12 devn: the scrolling effect thing is sort of glitchy but we've just been really busy on other projects

21:12 gfredericks: devn: you're one of the eight faces?

21:12 looked fine to me. I didn't try to break it though.

21:12 devn: i am. i'm the hipster-ish photo

21:12 gfredericks: you mean the yellow one? :)

21:12 devn: haha! precisely!

21:13 i think I'm leading our crew in terms of hipsterdom

21:13 gfredericks: so that's where "devn" comes from

21:13 devn: err, I'm one of the top 3 anyways

21:13 gfredericks: correct. I used to be defn, which once upon a time was for def n ... end, as in ruby

21:13 i found clojure and then started to feel sort of like a putzy fanboy what with (defn) and all

21:13 gfredericks: haha

21:13 devn: so I converted to devn :)

21:14 duck1123: ok, so you're defn

21:14 gfredericks: devn: better than people calling you "girl frog"

21:14 devn: hahahaha

21:14 duck1123: you must have gotten sick of people highlighting you all the time

21:14 devn: duck1123: you have no idea

21:14 as soon as i started idling in here I'd get back to my highlight buffer and be like WTF

21:14 gfredericks: (devn foo [x y] (+ x y))

21:14 devn: but it was sort of informative

21:15 if you want to learn about a language just make yourself a constructor-ish nickname

21:15 and watch your buffer fill with examples

21:15 * gfredericks wonders where he can get one of these "highlight buffers"

21:15 devn: irssi

21:15 by nerds, for nerds.

21:15 gfredericks: gosh dangit I stopped using irssi when everybody said "use emacs and erc"

21:15 devn: i like erc and all, but I never got into it

21:15 duck1123: they were right

21:15 devn: mainly because irc in my code buffer = major fucking distraction

21:16 gfredericks: I started using erc but never started using emacs for anything else. Now I use erc and vim.

21:16 * technomancy keeps em in separate instances

21:16 devn: technomancy: fair enough, im just not as disciplined

21:16 I wish I had paren matching though :X

21:16 technomancy: devn: well it's mostly because emacs is useless at concurrency

21:16 but yeah, paren matching in irc is awesome

21:16 * technomancy came pretty close to turning on paredit too

21:16 devn: technomancy: i suppose i could run erc in a remote emacs instance

21:16 technomancy: devn: it's easier than running a bouncer

21:17 devn: i run the nextstep GUI emacs on OSX primarily

21:17 i run irssi in screen on a remote box

21:17 so it's not insane to use erc in a remote emacs

21:17 but it always feels sort of bulky

21:17 irssi is so light

21:17 duck1123: I just switched back to using stumpwm today

21:17 technomancy: devn: yeah, it's basically the same except you get to extend it with elisp instead of perl

21:17 devn: technomancy: SOLD!

21:17 ;)

21:17 technomancy: heh; and you get ido for switching, M-/ and stuff. =)

21:17 * devn loses his mind

21:18 gfredericks: I think I only switched to erc because I was trying to integrate IRC and IM, which I now realize I never did

21:18 devn: how did I justify using irssi for so long?

21:18 technomancy: secret fondness for perl?

21:18 devn: hippie-expand FTW

21:18 technomancy: sorry, that was uncalled-for =)

21:18 devn: I think I just like other languages for the sake of them

21:18 if computers and programming didn't mean jobs

21:18 I would just be a linguist I think

21:19 * gfredericks followed devn's profile to elitekeyboards.com

21:19 technomancy: devn: how obscure have you gone?

21:19 devn: technomancy: in terms of what? programming languages?

21:19 technomancy: yeah

21:19 hipster challenge!

21:19 devn: hahahaha

21:19 idk, I tried out APL, J, K recently -- that was interesting

21:19 I'm not on fogus' level

21:20 I tried to install a working eiffel setup for like 4 days and gave up

21:20 technomancy: nice

21:20 I've written a bit of ocaml and played around briefly with factor

21:20 devn: Yeah, factor still has me interested

21:20 although I found forth

21:20 technomancy: I tried to get into smalltalk via opencobalt, but I couldn't get it to launch, and the stack trace mentioned SOAP, so I fled.

21:20 devn: that looks really interesting

21:20 technomancy: oo! want a brainfsck?

21:21 install inferno-os and run it on OSX

21:21 technomancy: joegallo is your man for that

21:21 oh, not the language?

21:21 devn: write LIMBO on infero-os

21:21 and tell me your brain doesn't implode

21:21 inferno*

21:21 technomancy: heh. closest I've gotten to that is running wmii

21:21 but I've got mad respect for plan9

21:22 devn: i did google summer of code in 2007 for the inferno project

21:22 i was so underqualified

21:22 that is a jungle of ideas

21:22 so much to learn. rob pike is a hero due to that adventure.

21:23 and caerwyn jones. that guy. read his inferno programmer's notebook.

21:23 it's brilliant stuff.

21:23 technomancy: what have you been toying with?

21:23 technomancy: devn: mostly just ocaml

21:24 wondering how much work it would be to get ocsigen running unofficially on heroku =)

21:24 devn: technomancy: I don't expect a rational answer, but...why?

21:24 oh! right! :)

21:24 i love that heroku is embracing clojure

21:24 gfredericks: and php?

21:24 technomancy: devn: actually my original ocaml interest was because I need something that launches quickly without a VM

21:24 and I don't care about concurrency because for long-running processes clojure has that covered

21:25 devn: ocaml is um, fast.

21:25 widefinder 2, for instance.

21:25 technomancy: ocaml has a quirky standard library, but it at least has enough to make quick lil guis

21:25 devn: yeah it's like the functional equivalent of tcl/tk

21:25 it's weird like that.

21:26 technomancy: devn: http://technomancy.us/152 <= thoughts and rationale for ocaml

21:26 devn: technomancy: will read.

21:26 TheBusby: any issue with the type system? When I took a look at it I thought ocaml required a different function for each type to support something like "map"

21:26 technomancy: oh, I guess mirah is pretty obscure too

21:26 I think I was like user #8 for mirah

21:26 devn: fuckkkkk. not another type system chit chat...

21:27 TheBusby: im sorry, not trying to be a jerk to you at all -- it's just...damnit...this issue of type systems

21:27 technomancy: TheBusby: my program was only 40 lines, so the type system never got a chance to get in the way

21:27 devn: it seems to come up ALL THE TIME, and some people cannot see the forest for the trees

21:27 _khaliG: technomancy, what about now - how do you deal with the quick start VM issue w/ clojure?

21:27 TheBusby: just curious about personal experience, not debating details

21:27 gfredericks: devn: I think your profile on the site has a typo.

21:27 devn: i spoke to erik meijer briefly after his talk at strange loop and he was talking about "little erik"

21:27 gfredericks: likely

21:27 technomancy: _khaliG: I learned ocaml so I would have a better way to write programs that have to start fast.

21:28 devn: erik was talking about he was like "HELL YEAH FUNCTIONAL PROGRAMMING!"

21:28 and then "HELL YEAH TYPE SYSTEMS!

21:28 and now he sort of only kind of believes in either of them

21:28 technomancy: _khaliG: I wouldn't hold my breath for quick-launch clojure

21:28 but it would be nice!

21:28 devn: use clojurescript and node!

21:28 TheBusby: technomancy: great blog post. Exactly the type of info I was looking for, thank you!

21:28 _khaliG: technomancy, that makes too much sense :P what about railgun nailgun or whatver it is? reason i ask if i've got a clojure app i want people to use and the slow VM thing will need a solution for me

21:29 technomancy: _khaliG: a daemon works for a certain class of problem

21:29 it's not a good general-use solution though

21:29 devn: technomancy: agreed

21:29 technomancy: _khaliG: jark looks promising on the daemon side

21:29 hiredman: really?

21:29 all my stuff runs as daemons

21:30 dnolen: devn: +1. Learning OCaml or SML not a bad either.

21:30 devn: imagine if a narrator was narrayting IRC: He'd say "a malloy is now a malloy underscore"

21:30 dnolen: bad idea either.

21:30 technomancy: hiredman: you have a lot more patience to set that kind of stuff up than most people

21:30 devn: narrating*

21:31 technomancy: familiarity vs ease, though. ;)

21:31 hiredman: patience is a useful quality to cultivate

21:31 technomancy: hiredman: but not to require of your usesr =)

21:31 *users

21:32 hiredman: but daemons start when they open their laptop and are always there

21:32 like magic

21:32 devn: actually, no wink on that -- I did not want to wink. I truly believe all of this nonsense about "BUT IT TAKES 3 HOURS TO MAKE IT PERFECT FOR ME" are completely well founded, but they're also completely irrational. It cannot be a perfect environment when you start it, because you are unique, and no it should not takes 10 years to configure it.

21:32 technomancy: hiredman: like memory-hungry magic =)

21:32 hiredman: I have 8gigs

21:32 _khaliG: ooh jark does look nice - i hope it succeeds

21:32 devn: pft I scoff at your 8 gigs

21:33 I have 512 gigs of RAM.

21:33 hiredman: the most my macbook will hold

21:33 devn: That's how I roll, hiredman.

21:33 gfredericks: devn: you lie!

21:33 technomancy: hiredman: that's why I qualified it with general-purpose

21:33 devn: I can't run on a machine that isn't made by Azul.

21:34 hiredman: the run scripts lein generates are very useful

21:34 TheBusby: the problem with 512GB of ram though, is that the JVM will use all 512GB of ram to read a small text file ;)

21:34 devn: bahahaha

21:35 so incidental complexity at the language layer: check.

21:35 incidental complexity at the tooling layer: hmmm

21:35 let me just pass 12 args to my java command!

21:35 * devn pukes blood

21:36 hiredman: again, I fail to see the problem, launchd launchs the daemons and they are just there to use

21:37 devn: hiredman: there's no problem, there's just a lack of familiarity

21:38 TheBusby: hmm, I wonder what 'wc -l' would look like as a daemon though...

21:38 technomancy: what I want is a sexp-aware git merge strategy

21:39 devn: technomancy: i think such a thing exists

21:39 hiredman: remember dinner?

21:39 hiredman: TheBusby: wc is a command executed by the "shell" daemon

21:39 devn: hiredman: what was that?

21:39 technomancy: devn: from what I could find a year or two ago, most of the research was on XML

21:39 devn: hiredman: alan was talking about it IIRC.

21:40 hiredman: yeah, uh, alan said he thought the scheme guys had solved it

21:40 devn: There is a way to do what you're suggesting technomancy.

21:40 TheBusby: hiredman: I was thinking in refernce to nailgun/etc

21:40 technomancy: devn: that's just an example of something the JVM's going to do a crappy job of

21:40 devn: hiredman: yeah I can't remember the details

21:40 technomancy: we talk about abstractions.

21:40 technomancy: we can do better.

21:41 gfredericks: AJVM

21:42 hiredman: it's not like we spin up a whole new process to deliver a website (unless your rails) so why should we constantly spin up new processes locally?

21:42 technomancy: because unix?

21:42 hiredman: just about all the apps I use I never close

21:43 firefox, fluid apps, iterm, and emacs

21:43 devn: httpd?

21:43 hiredman: quicksilver

21:43 my twitter client

21:43 devn: and a partridge in a pear tree

21:43 hiredman: the all just run

21:43 TheBusby: cat, sed, awk, wc?

21:43 devn: and a partridge in a pear tree

21:43 gfredericks: five golden pings!

21:43 hiredman: the processes are in fact still an expensive abstraction

21:44 technomancy: what about it?

21:44 devn: gfredericks: a friend of mine has proposed that the squart root of 1225 is the square root of christmas

21:44 as in march 5th is the square root of christmas

21:44 hiredman: you seem to be under the impression that unix is X rather than unix is a vague idea in a bunch of people's heads that changes over time

21:45 devn: The 10-day interval between the Square Root of Christmas and Pi Day shall be known as Nerdigras.

21:45 On the twelth day of nerdigras I sent my ISP...

21:45 ❧ 12 fracking fractals

21:45 ❧ 11 puns so stunning

21:45 ❧ 10 bits a twiddling

21:45 ❧ 7 pointers dangling

21:45 ❧ 6 trees a splaying

21:45 ❧ Fiiiive RFID rings

21:45 ❧ 4 calling stacks

21:45 ❧ 3 unmatched parens

21:45 hiredman: the google go guy had a rant recently about how he dislikes modern unix

21:45 devn: ❧ 2 Power Gloves (all together now!)

21:45 ❧ ... and a hash map in a B-treeeee!

21:46 sorry for the nastiness, but I couldn't resist.

21:46 hiredman: which certainly would not be the case if unix was a perfect ideal

21:46 TheBusby: hiredman: link?

21:46 devn: hiredman: you're talking about pike. I think pike is peeved because some of the great ideas behind plan9 never made it to Linux.

21:46 hiredman: the reason "unix" is sucessful is the ability to change

21:46 technomancy: devn: yeah, he was complaining because modern systems aren't process/file-oriented enough

21:47 which is the opposite

21:47 hiredman: devn: oh, no doubt

21:47 devn: he wants "everything is a file"

21:47 I don't know if I agree, honestly

21:47 gfredericks: what things could be files? processes?

21:47 devn: gfredericks: everything.

21:47 plan9

21:47 inferno-os

21:47 inferno-os could have beaten Java

21:47 gfredericks: devn: mice?

21:47 integers?

21:48 devn: inferno-os was better than java. you can boot up a fast instance in 1M of RAM

21:48 acme was an insanely interesting editor and continues to be

21:48 hiredman: but want I mean is, if you read his comment, he seems to feel that the plan9 ideal is really the inheritor of the "unix" mantle and modern unixes have some how betrayed their lineage

21:48 devn: hiredman: why wouldn't the creator of that alternative path reassert his passion for his own ideals?

21:49 rhetorical. of course he wants that.

21:49 he invented it.

21:49 hiredman: devn: he had an idea of what the true "unix" is, as does technomancy

21:49 and they are different

21:49 devn: Yeah I don't disagree with you I guess

21:49 hiredman: so just going around saying "because unix" is noise

21:50 devn: I'm just pointing out some obvious bias

21:50 hiredman: ugh

21:50 devn: ?

21:50 hiredman: I did not say he was right about anything, or agree with him about anything, or anything

21:50 devn: hiredman: sorry -- I think I follow, you're just suggesting that unix is not a static thing -- it changes. is that right?

21:50 hiredman: nothing to do with the factual content of what he said regardless of bias

21:51 I am suggesting "because unix" is as useful a thing to say about something as "because it's awesome"

21:51 there is no information there

21:52 devn: hiredman: so that's interesting because what I got out of Pike's comment is that, while he is not enthused it didn't go his way, he is ultimately happier with the """""""UNIX"""""""" philosophy that currently exists, moreso than alternative philosophies.

21:52 s/that/than

21:52 lazybot: <devn> hiredman: so than's interesting because what I got out of Pike's comment is than, while he is not enthused it didn't go his way, he is ultimately happier with the """""""UNIX"""""""" philosophy than currently exists, moreso than alternative philosophies.

21:52 devn: ./kick lazybot

21:53 man I can't type.

21:53 I hope you can pick up on the gist of that incoherent rant.

21:53 gfredericks: (dec lazybot)

21:53 lazybot: ⟹ -1

21:53 devn: (dec lazybot)

21:53 lazybot: ⟹ -2

21:53 hiredman: *shrug*

21:54 devn: hiredman: I'm just saying. It could be a lot worse. It could also be a lot better.

21:54 That leaves us here, now.

21:54 No mystery there.

21:54 hiredman: not saying this to you specifically, again just ranting

21:55 hiredman: I really don't understand what you are talking about, you seem to be trying to talking about what pike said

21:55 I am not

21:56 devn: hiredman: I'm missing you then. Why bring up his comment if you don't wish to discuss its content?

21:56 hiredman: I am saying this and only this: saying something "is unix" is empty of content

21:56 technomancy: I'm just saying "everything must be a daemon or slow to respond" is a crappy requirement.

21:56 hiredman: sure

21:56 and that is a statement that conveys meaning

21:56 er, content

21:57 technomancy: unix traditionally is composed of lots of small processes that interact over pipes

21:57 hiredman: technomancy: sendmail, bind, etc?

21:57 * devn coughs

21:57 devn: composability

21:57 * devn coughs some more

21:58 hiredman: devn: I brought his content only to point out there are differences of opinion over what unix is and what it's strengths are

21:58 comment

21:58 its

21:58 technomancy: sendmail runs both as a daemon and as a quick-launching process afaik

21:58 devn: hiredman: sorry to branch the hell out of that statement. I must have taken your statement wrong.

21:58 * devn is not infallible.

21:59 hiredman: technomancy: so? does that not suggest a broader view then "lots of samll processes that interact over pipes"?

21:59 than

21:59 small

21:59 devn: Doug McIlroy

22:00 technomancy: hiredman: the only reason it runs as a daemon is to accept incoming network connections

22:00 hiredman: many of your small processes are shell builtins

22:00 (or realisticly in your case elisp functions)

22:00 technomancy: I'm not saying "unix means no daemons", just "make things daemons that have good reason to be daemons"

22:02 devn: "good reason"

22:02 so intuitive and obvious!

22:02 hiredman: is omnipresence not a good reason?

22:02 * devn evil smile

22:02 hiredman: quicksilver is great like, always running, never there unless I need it

22:03 devn: except when its indexing when you dont want it to

22:03 it's*

22:03 hiredman: I dunno, does it do that?

22:03 devn: depends on your config

22:03 depends on whether you do enough in the right places to make it annoying

22:03 depends on whether that CPU time matters to you

22:04 depends on whether that disk access matters to you

22:04 * devn shrugs

22:05 hiredman: my emacs uptime is only 19 days :/

22:11 devn: lol

22:11 i don't even know how to respond to that

22:13 hiredman: weep, sometime 19 days ago I lost where I was in most likely around 40 open buffers

22:13 devn: Sounds like my browser

22:13 I keep my editor clean

22:13 hiredman: ah, firefox restores everything when I open and close it

22:13 devn: I treat it like a temple

22:14 hiredman: no that's what I'm saying -- I make a mess of my browser for that very reason. I trim my editor like bonsai.

22:14 hiredman: I've been digging through infinispan's source recently, it is some what twisty so I have lots of buffers for various java files

22:15 devn: ah, gotcha

22:15 this is where i try to use eclipse and then just get a shit-ton of buffers going

22:16 technomancy: is it hard to get a tags file for something like that?

22:16 * technomancy never really mastered tags

22:16 devn: maybe?

22:16 hiredman: dunno, me neither

22:16 devn: I haven't either.

22:16 hiredman: rgrep

22:16 duck1123: I love emacs because you don't even notice it and have 119 buffers open

22:16 * devn high fives

22:16 devn: duck1123: im militant about buffers!

22:16 hiredman: yeah 40 was a conservative guess, I have 80 open right now

22:16 devn: more militant than an angry librarian!

22:17 hiredman: (81)

22:17 hugod: emacs with 900 open buffers uses about the same as safari with a couple of tabs

22:17 devn: (81) "Poop Hatch" http://www.youtube.com/watch?v=KKZSf3WHrKI

22:17 ^hiredman

22:17 hiredman: hugod: good to know

22:18 hugod: same memory that is

22:18 duck1123: I close buffers all the time, but sometimes you don't even notice

22:18 devn: I will force this upon all of you: http://www.youtube.com/watch?v=KKZSf3WHrKI

23:24 ivan__: Any thoughts on which book is better? 'The joy or clojure' or 'Clojure in action' ?

23:25 ataggart: probably whichever is newer

23:25 ivan__: of*

23:25 well Clojure in action is newer, but the joy of clojure is only march 2011 :)

23:28 amalloy: i would recommend JoC personally

23:28 technomancy: I wasn't impressed by the sample I read from clojure in action

23:28 amalloy: but i haven't actually read CiA

23:28 technomancy: it was a while ago though

23:28 JoC is pretty much universally-acclaimed

23:29 ivan__: i was leaning towards it based on what i had seen

23:31 gtrak``: ivan__, JoC is core language stuff only, but it has a lot of examples and rationale which is fun to read. it makes you think about what's going on

23:32 _khaliG: ivan__, practical clojure is really good

23:33 ivan__: gtrak``: yes, i only really want language stuff, which is why i was leaning towards it

23:33 _khaliG: manning published books only :)

23:33 _khaliG: ivan__, ah k, i wouldn't bother then :P

23:34 joy is unreadable imho

23:34 gtrak``: _khaliG, that's not true at all, in fact it is a joy to read

23:34 ivan__: i probably wont actaully read it <.< but hopefully will be ok language reference

23:34 _khaliG: i'd say PC is a joy to read

23:35 gtrak``: reviews: http://www.amazon.com/Joy-Clojure-Thinking-Way/product-reviews/1935182641/ref=sr_1_1_cm_cr_acr_txt?ie=UTF8&showViewpoints=1

23:36 _khaliG: gtrak``, thanks, let met give it a 1 star to balance things out :)

23:36 gtrak``: no skin off my back :-)

23:36 I'll give it a 5 if you give it a 1

23:36 amalloy: PC is like super-old, right? the number of people who've come in here sad that they don't know how to get clojure.contrib.duck-streams to work in clojure-1.3...

23:37 _khaliG: amalloy, I meant practical clojure, not programming clojure (which is pretty crap)

23:37 duck1123: Practical or Programming?

23:37 amalloy: i don't actually know which is which; i just associate PC with "out of date"

23:37 ivan__: the only book ive ever bought since my first year of uni is land of lisp, and that was only cos of the video

23:38 duck1123: Programming Clojure was the first, so of course it's the most out of date

23:38 _khaliG: amalloy, yeah programming was the first one, it's fairly old, i think from 2009, practical is new (2010ish)

23:38 ivan__: i have the interwebs

23:38 amalloy: i'm a pretty good book reviewer as long as you don't care whether my review is correlated with the book i claim to be reviewing

23:38 ivan__: haha

23:38 _khaliG: amalloy, lol

23:39 gtrak``: after reading this book, the hardest thing in clojure for me was learning emacs

23:39 but i haven't tried macros yet

23:41 ivan__: gtrak``: forget learning emacs, i cant even get all the clojure stuff installed for emacs lol

23:41 gtrak``: ha, yea, it's more overwhelming than the language itself

23:41 but the emacs starter kit is a good starting point

23:42 i still haven't figured out how to debug, but it's not as necessary when you have pure functions

23:43 alandipert: i'm like emacs a lot now, but i wish i knew that you don't need swank and stuff to get started

23:43 gtrak``: i guess you can use inferior-lisp, but it's not as good of an experience

23:43 I'm doing that right now with clojurescript

Logging service provided by n01se.net