#clojure log - Apr 18 2011

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

2:06 Havvy: How can you test "String can be converted into integer"?

2:15 mec: ,(map #(try (bigint %) (catch NumberFormatException e :nope)) ["5" "5.0" "1/3" "high"]) ;p

2:15 clojurebot: mec: Pardon?

2:15 amalloy: mec: catch is a no-no for bots

2:15 mec: aw

2:16 Havvy: So no other choice than using try/catch... :(

2:17 mec: I suck at regex but something like #"^-?[0-9]*" should do

2:17 Havvy: Oh, duh...

2:23 mec: ,(map #(re-seq #"^\-?[0-9]*$" %) ["5" "5.0" "1/3" "high"])

2:23 clojurebot: (("5") nil nil nil)

2:43 markoman: is there some general function to check if some value is "empty" ?

2:43 "" [] {} {{}{}} nil for example

2:44 shachaf: markoman: {{}{}} isn't empty.

2:46 markoman: shachaf: by which function call you can check it?

2:47 shachaf: No idea. Seems like an odd operation.

2:49 amalloy: if you give up on identifying {{}{}} as empty, you can use empty?

2:49 &(map empty? ["" [] {} {{}{}} nil])

2:49 sexpbot: ⟹ (true true true false true)

2:49 shachaf: Ah, there you go.

2:49 * shachaf isn't sure why he's in this channel, really.

2:49 amalloy: empty? is basically (complement seq)

2:52 markoman: i see, i though empty? is just for strings. if i want to check {{}{}} i need to make nested check. is there some way to use map for nested things like {{}{}} or [[][]]

2:52 amalloy: markoman: it is a terrible idea

2:52 mec: &(map (comp empty? flatten) ["" [] {} {{}{}} nil])

2:52 sexpbot: ⟹ (true true true true true)

2:53 amalloy: mec: when someone walks into your store crying, asking for a pistol, don't sell them one. what people think they want is often pretty far off from what is good for them

2:54 mec: but those are the people willing to pay extra :D

2:54 amalloy: also that doesn't really work: ##((comp empty? flatten) [""])

2:54 sexpbot: ⟹ false

2:55 mec: anywho, I added a findarg to sexpbot but I have no idea how to test the whole thing to see if it works

2:55 amalloy: mec: where's your fork?

2:56 mec: https://github.com/mecdemort/sexpbot

2:57 markoman: so I think I need to make sure data structure doesnt contain empty nested maps. this is good for now

2:57 amalloy: mec: doesn't compile

2:57 i'll have a look

2:57 mec: bah, the find-arg works fine on its own, I just kind of shoved it in there tho

2:59 amalloy: mec: kinda-sorta works with a little tweak. needs better syntax

2:59 :findarg map '% [1 2 3] [2 3 4]

3:00 buttered-toast: [clojure.core/unchecked-inc clojure.core/inc]

3:00 amalloy: very neat though

3:00 mec: what was the tweak needed?

3:00 amalloy: you just used the wrong name

3:00 for a symbol

3:00 the tweak i think it still needs is some way to not need to quote %

3:01 mec: ooo right, forgot to rename that

3:01 amalloy: :part #clojure

3:01 buttered-toast: Bai!

3:01 amalloy: man. that part message needs to die

3:02 mec: I was having the same problem with findfn, but if you make it a macro so you dont have to quote, then other things break

3:07 amalloy: mec: fixed

3:08 as long as nobody wants to use % for something else :P

3:09 mec: since its the normal aphorism for #() i dont think its too common to use it elsewhere

3:09 r/aphorism/anaphora/

3:10 amalloy: $findfn #(inc %) [1] [2]

3:10 sexpbot: [clojure.core/map clojure.core/pmap clojure.core/keep]

3:10 amalloy: i think my fix breaks that behavior

3:11 wow, it doesn't. three cheers for clojure's reader

3:13 mec: anyway, thanks. that'll be added next time sexpbot gets reloaded

3:13 mec: cool

3:42 Derander: $findfn 1 2

3:42 sexpbot: [clojure.core/unchecked-inc clojure.core/inc]

3:42 Derander: bad ass

3:42 $findfn [1 2 3 4] [[1 2] [3 4]]

3:42 sexpbot: []

3:43 Derander: $findfn 2 2 [1 2 3 4] ((1 2]) (3 4))

3:43 sexpbot: []

3:43 Derander: $findfn 2 1 [1 2 3 4] ((1 2]) (3 4))

3:43 sexpbot: []

3:43 Derander: $findfn 2 2 [1 2 3 4] ((1 2)) (3 4))

3:43 sexpbot: java.security.PrivilegedActionException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

3:43 amalloy: :findarg 2 [1 2 3 4] [[1 2] [3 4]]

3:43 buttered-toast: []

3:43 amalloy: gr

3:43 Derander: $findfn 2 2 [1 2 3 4] ((1 2) (3 4))

3:43 sexpbot: java.security.PrivilegedActionException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)

3:43 Derander: I fail

3:43 giving up now

3:44 amalloy: $findfn 2 [1 2 3 4] [[1 2] [3 4]]

3:44 sexpbot: [clojure.core/split-at clojure.core/partition-all clojure.core/partition]

3:44 amalloy: Derander: ^

3:45 Derander: doesn't partition take two integer args optionally?

3:46 amalloy: Derander: yes. but you never gave it a wellformed thing to test against :P

3:46 Derander: nooooooo

3:46 amalloy: $findfn 2 2 [1 2 3 4] [[1 2] [3 4]]

3:46 sexpbot: [clojure.core/partition-all clojure.core/partition]

3:46 Derander: hahahahahah

3:46 god damnit.

3:46 I need paredit for irc

3:46 amalloy: Derander: funny you should mention that!

3:46 &(let [x 1) (inc x))

3:46 sexpbot: ⟹ 2 ; Adjusted to (let [x 1] (inc x))

3:47 Derander: I do not understand

3:47 oh

3:47 impressive

3:48 amalloy: it only works in contexts where he knows the rest of the line is an input. eg, ##(let [x 1) (inc x)) won't work, because he tries to (read) what comes after ## to see if it's a command

3:48 Derander: understand

3:48 understood*

3:48 damn, writing ability goes way down after midnight apparently

3:48 strangely though I'm dominating at words for friends

4:32 markoman: hmh.. i have a function that returns a sequence, but I'd like return value be a map

4:32 ejackson: markoman: try (into {} )

4:32 you'll have to get the key/val orders correct

4:34 amalloy: &(into {} (map vec (partition 2 (range 10))))

4:34 sexpbot: ⟹ {0 1, 2 3, 4 5, 6 7, 8 9}

4:34 ejackson: ,(into {} [[:a 1] [:b 2] [:c 3]])

4:34 clojurebot: {:a 1, :b 2, :c 3}

4:36 markoman: its a deep nested map inside, but basically goes like: ({:key "val"} {:key "val"}) -> [{:key "val"} {:key "val"}]

4:36 and sorry, its not a map on return but a list

4:37 ejackson: markoman: try merge in that case

4:38 markoman: im giving this to the function: [{:key "val"} {:key "val"}] and expect [{:key "val2"} {:key "val2"}] but instead getting ({:key "val2"} {:key "val2"})

4:38 ejackson: ,(apply merge [{:a 1} {:b 2} {:c 3}])

4:38 clojurebot: {:c 3, :b 2, :a 1}

4:39 ejackson: so you want a vector, but its giving you a list ?

4:39 ,(into [] '({:k1 :v1} {:k2 :v2}))

4:39 clojurebot: [{:k1 :v1} {:k2 :v2}]

4:40 markoman: im still bad with terms, but id say i want [] but get sequence () probably because of for loop i have there inside the function

4:40 ok, i think i need to try into

4:41 amalloy: markoman, ejackson: (vec foo) is better than (into [] foo) most of the time

4:41 ejackson: markoman: by design everything accepts and returns seqs, and you then plonk that into whatever concrete structure you want after processing.

4:41 amalloy: why's that ?

4:42 amalloy: ejackson: it's clearer in intent, i think. and shorter, not that that matters much

4:43 ejackson: OK. I always use into when 'casting' as its clearer to me that way. Funny.

4:44 amalloy: ejackson: well, into is overloaded a bit

4:44 &(into [1 2 3] [4 5])

4:44 sexpbot: ⟹ [1 2 3 4 5]

4:44 amalloy: ie, it's not always for putting something into an empty collection

4:45 ejackson: that's true, its got a bit conj hustle going on as well.

4:45 i see you point amalloy

4:45 amalloy: but (into {}) is super-useful

4:45 vec is probably faster too, since it gets you into java-land

4:46 &(time (dotimes [_ 1e4] (vec (range 1000))))

4:46 sexpbot: ⟹ "Elapsed time: 4604.595346 msecs" nil

4:46 amalloy: &(time (dotimes [_ 1e4] (into [] (range 1000))))

4:46 sexpbot: ⟹ "Elapsed time: 3153.579926 msecs" nil

4:46 amalloy: haha

4:46 ejackson: :D

4:46 amalloy: ejackson: you win this round, but i'll be back!

4:46 ejackson: ,botstnack

4:46 clojurebot: java.lang.Exception: Unable to resolve symbol: botstnack in this context

4:46 ejackson: ,botsnack

4:46 clojurebot: java.lang.Exception: Unable to resolve symbol: botsnack in this context

4:47 ejackson: hehehe, i hate it when that happens

4:47 amalloy: $botsnack

4:47 sexpbot: amalloy: Thanks! Om nom nom!!

4:47 amalloy: (since i was using sexpbot anyway)

4:47 ejackson: oh yeah, you're using sexpbot.

4:47 amalloy: ~botsnack

4:47 clojurebot: thanks; that was delicious. (nom nom nom)

4:47 amalloy: to talk to clojurebot

4:47 ejackson: its like perl in here with these bots...

4:48 amalloy: > 1

4:48 hsbot: 1

4:48 ejackson: thanks amalloy, i'll try to remember (again)

4:48 hsbot !

4:48 who's that ?

4:48 amalloy: i know, i noticed him yesterday

4:48 he's someone's haskell bot

4:48 > [1,4..15]

4:48 hsbot: [1,4,7,10,13]

4:48 ejackson: hmmmmm

5:01 markoman: so its into :)

5:08 ejackson: alrighty.

6:34 fliebel: Where would I look for creating cool interfaces on Mac? Like ones that really go swoosh and poof, and not simply look like Mac widgets.

6:37 ejackson: fliebel: tried apache pivot ?

6:38 dunno about its coefficient of poof, however.

6:39 fliebel: ejackson: No I did not. Googling now.

6:39 ejackson: i always end up using Swing though

6:40 fliebel: ejackson: Can you make Swing apps that look and feel good on Mac?

6:40 ejackson: good enough for me...

6:41 perhaps there's some grating nastiness that I'm not sensitive enough to notice

6:41 mrBliss``: fliebel: http://code.google.com/p/macwidgets/

6:41 fliebel: mrBliss``: Is that with wx?

6:42 mrBliss``: fliebel: nope, just swing but requires some jars

6:42 fliebel: looks nice...

6:43 mrBliss``: fliebel: http://www.devdaily.com/apple/mac/java-mac-native-look/java-on-mac.shtml

6:43 ejackson: mrBliss``: cool

6:47 fliebel: exit pivot. Even worse than Swing so far.

7:52 markoman: im still struggling with changing sequence to list/vector

7:57 two for loops iterates and returns ( ( {'a 'b} ) ( {'c 'd} ) ) but what i want is simpler form [{'a 'b} {'c 'd}]

8:14 kephale: , (apply vector '(1 2 3))

8:14 clojurebot: [1 2 3]

8:14 kephale: , (apply vector (flatten (list '( 1 2 3) (3 4 5)))

8:14 clojurebot: EOF while reading

8:14 kephale: err

8:15 , (apply vector (flatten (list '( 1 2 3) (3 4 5))))

8:15 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

8:15 kephale: gagh

8:15 oh

8:15 (apply vector (flatten (list '( 1 2 3) '(3 4 5))))

8:15 , (apply vector (flatten (list '( 1 2 3) '(3 4 5))))

8:15 clojurebot: [1 2 3 3 4 5]

8:15 kephale: dunno if you need the flatten though

8:16 markoman: i need to test

8:16 kephale: it looks like you might though

8:18 markoman: its also in recursive loop. im using into [] at the moment, but problem is, i get too many nests, it may well be, that flatten works when wrapped over for loops

8:19 opqdonut_: markoman: are you aware that you can do (for [thing some-things element-of-thing thing] ...) ?

8:20 ,(let [vs [[1 2 3] [4 5 6]]] (for [v vs el v] {:a el}))

8:20 clojurebot: ({:a 1} {:a 2} {:a 3} {:a 4} {:a 5} {:a 6})

8:24 markoman: hmh... probably not useful in this case, but good to know. it looks similar to let [a b c (d a)]

8:24 opqdonut_: yeah but you kinda get the flatten for free

8:30 markoman: oh yes. well the problem is two for loops returns sequence, which i want to be a vector, its kinda backward

8:32 let me test, if its still confusing, i need to put a pastebin

8:32 kephale: mmm, yeah, i'm not sure why a concat wont work

9:53 scottj: moving webapp from just jetty to jetty in dev and tomcat in production, I was using an environment variable to tell app whether it's test/dev/production, any recommendations for how best to do that with wars? set an environment variable on tomcat itself?

10:00 joegallo: jndi works well for that sort of thing

11:54 amalloy: kephale: flatten is dreadful for "general use". it will always mash every level of nesting all the way down; usually you want something that mashes a predefined level of nesting

11:54 KirinDave: Please to enjoy being confused by this: https://github.com/ryan-allen/lispy

11:54 Completely inscrutable.

11:55 It's like, 'Yes, smalltalkers did indeed do this. Not sure where lisp comes in."

11:55 amalloy: eg here he probly wants (into [] (mapcat whatever-function-you-were-using-map-with the-collection))

13:04 ilyak: hi *

13:05 What's the best way to express the following idiom in Clojure: reading file by one line and being able to read "current" line and advance to the next one

13:05 We should forget "current" line when we advanced, but we would need to read the "current" line multiple times

13:06 manutter: Are you familiar with line-seq?

13:07 pjstadig: ,(doc line-seq)

13:07 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

13:07 ilyak: So the first operation would be (first) and the second operation would be (rest)?

13:07 pjstadig: most often used inside of a with-open, but you just have to make sure the lazy seq doesn't escape the with-open, or bad things will happen

13:08 ilyak: Would it handle calling (first) more than once and would it properly discard old lines when (rest) is called?

13:09 pjstadig: you could do (with-open [f (reader "somefile")] (doseq [current (line-seq f)] do-something))

13:09 pyr: what about read-lines ?

13:09 (doseq [line (read-lines "/some/file")] (do-something-with line))

13:09 manutter: Why do you need to read the first line more than once? Could you just put the current line into a variable and re-use that as needed?

13:10 technomancy: read-lines is deprecated as it was a common source of resource leaks

13:10 because it doesn't work with with-open

13:13 raek: ilyak: when you use a lazy sequence like line-seq, you can hold on to a certain subsequence, go forward in the sequence, discover that you need to try someting in another way and jump back to the old subsequence

13:13 ilyak: calling first multiple times on the same object will yield the same value

13:13 ilyak: raek: okay, it's cool

13:17 If I (map ... lazy-seq), would I get another lazy-seq with those magical properties?

13:17 raek: ilyak: yes, you would :)

13:18 amalloy: heh, magic. funny because it's true

13:20 raek: ilyak: you can also use reader from the clojure.java.io namespace to get a suitable object to pass to line-seq

13:29 TimMc: OK, I just want to map across the vals of a map. Anything better than (fn [[k v]] ...) ?

13:29 (more terse)

13:29 ataggart: (map f (vals m))

13:30 TimMc: Yeah, but I want the whole map back. :-(

13:30 Like, (map-vals inc {:a 0, :b 1}) -> {:a 1, :b 2}

13:31 $findfn inc {:a 0, :b 1} {:a 1, :b 2}

13:31 sexpbot: []

13:31 ataggart: seems like there should be, but I can't think of one

13:31 fliebel: TimMc: fmap in generic.functor or whatever.

13:32 TimMc: Not that keys and vals for the same map are guaranteed to have the same order, so you can map over vals and reunite them.

13:32 *note

13:32 raek: (into {} (for [[k v] m] [(f k) (g v)])) is one option

13:32 ataggart: (reduce (fn [[k v]] [k (f v)]) m) is about it for core

13:33 throw a {} in the above

13:33 fliebel: http://clojuredocs.org/clojure_contrib/clojure.contrib.generic.functor/fmap

13:33 raek: (zipmap (map f (keys m)) (map g (vals m))) is another

13:33 ataggart: skinning cats is fun

13:35 TimMc: raek: Yeah, zipmap is probably what I'll go with -- the map already has a name, so it's easy to refer to it twice.

13:48 (apply zipmap (juxt keys (comp (partial map boolean) vals)))

13:51 bulters: gday all

13:52 anyone here familiar with efforts of "interfacing" with git from clojure?

13:53 hiredman: http://eclipse.org/jgit/

13:54 bulters: *facepalm*

13:54 (stuck in ruby mindset of looking for gems)

13:55 * webar7 knows some elisp ... knows no java ... :-| would clojure be away I could learn about the underbelly of java web application programming like .war's, ant, deployment, various application server setups tomcat etc (what's "jetty?" hehe) while having fun with LISP'ish things ... I want/need to know how java apps are wired together (for sysadmin purposes) but not how to program in java

13:56 amalloy: webar7: probably. a lot of the grosser java "wiring-together" has been replaced with clojure-specific wiring for many projects, though, so you might not see as much of that as you'd like

13:57 webar7: oh hmmm i'm from python/zope/fabric/django beackground as far as any coding goes ... those are all very different of course so even though "in python" ... hmm

13:57 amalloy, ok I grok

13:58 then I get levels of abstraction via leinegen (sp?) etc etc

13:58 amalloy: leiningen

13:59 webar7: amalloy, thanks ... I will fiddle a bit with it and see what I learn

13:59 amalloy: webar7: check out Ring - it's clojure's super-simple modular web server

14:00 webar7: ok ... I think it got installed in the project by adding it to the project.clj and running leiningen ... anyway it's fun to do lisp in a web environment but the error messages from the JVM are freaky!!

14:00 bulters: amalloy: only thing left is the deployment on a server...

14:00 amalloy: luckily I'm not there yet ;-)

14:02 webar7: I think what I want now is to wire things up with routes etc. and then have some pages just be handled statically but with clojure code execed before rendering

14:02 so I will look at ring and related tools

14:04 by the time I know what i'm doing maybe appengine will support clojure :) ?

14:04 oh wait ...

14:04 mids: webar7: check out 'appengine-magic'

14:04 webar7: woah

14:05 ok then maybe by the time I know what I'm doing google will have bought java from Oracle and relicensed it :)

14:05 amalloy: webar7: appengine doesn't have to support clojure. it supports java, which is kinda the point :)

14:09 webar7: amalloy, :)

14:11 amalloy, I've been working with BSD based systems mostly (usually very small or for dedicated stuff like email or proxying) so have avoided java ... if only to avoid the hassle of installing it :-\

14:13 maybe Oracle trying too/so hard monetize as much as possible and ASAP means they really think java has "jumped the shark" :)

14:14 does clojure run on dalvik :)

14:15 amalloy: webar7: slowly

14:15 webar7: WOW!

14:15 impressed by the fact it runs at all

14:15 nice

14:15 amalloy: it's all "just java" underneath

14:16 webar7: gotta love LISP ... invented before computers ... in use "after" computers ;-)

14:16 amalloy: heh. no doubt PCs were viewed as "after" computers back in the mainframe days

14:17 webar7: so clojure could run on other "open" jvm's or stack/register vm's that can "pretend" to be java

14:18 * webar7 heard LISP was in use on paper and chalkboards before the machines existed to make it run :)

14:18 TimMc: webar7: Clojure can be run anywhere JVM bytecode can be run.

14:18 webar7: hmm that's very broad :)

14:20 it seems like one could write something using lisp that simultaneously creates a dedicated "client" to run with a java "GUI" and web based UI (CSS etc)

14:21 amalloy: that such tasks are possible does not make them easy

14:23 bulters: if every small task whas easy, then large tasks are easy as well

14:23 where** (damn)

14:23 *DAMNIT*

14:23 you get the point

14:25 fmw: I'm trying to send a form submission using clj-http, but there seems to be something wrong with the request: http://paste.pocoo.org/show/374016/ (screenshot of a tshark capture of the request/response: http://vix.io/post_request_capture.png)

14:25 does anyone know what I'm doing wrong?

14:25 I've compared my post requests with post requests made by curl/chrome and my request looks OK

14:26 amalloy: fmw: your boundary has ---- once, and ----- once

14:27 fmw: amalloy: I copied that from Chrome

14:27 afaik its correct?

14:28 amalloy: *shrug* maybe so. seems a bit loony to copy a bunch of output from chrome instead of just posting edit_week=test or whatever

14:28 i mean, i'm not an expert at form encoding, but chrome looks like it's including a lot of overhead just in case it wants to do multi-part mime-encoded forms, when the minimal data needed to POST something is much simpler

14:29 raek: for it to work you should have boundary=<some string> in the content type and then delimit the sections with --<some string> .... --<some string> .... --<some string--

14:30 fmw: it looks like you are one - short in the two form-data lines

14:30 oh sorry, you're not

14:31 I made a mistake when I counted them.... :)

14:31 fmw: raek: aye, I had that wrong a few times, myself, but at least that part seems fixed now

14:33 amalloy: I agree with you there, but for now the Chrome version is known to work, so felt safer to just copy & paste

14:33 clizzin: is lein-javac still useful, or has leiningen swallowed up that functionality with one of its options? if so, which option?

14:35 raek: clizzin: it is in leiningen now.

14:36 fmw: raek: any chance the request is correct but PHP expects some additional headers to be present to process it?

14:36 clizzin: raek: what option is it equivalent to? just set :java-source-path, and it just works?

14:37 raek: you might be able to just put the java source files in src/ too, but you can use :java-source-path like this: https://github.com/raek/map-exception/blob/master/project.clj

14:37 Nikelandjelo: Is there standard function for comparing 2 collections (nested collections too). E.g. compare [[1 2] [3 4]] '((1 2) (3 4)) are equal

14:37 clizzin: raek: excellent, thank you!

14:37 hiredman: ,(= [[1 2] [3 4]] '((1 2) (3 4)))

14:37 clojurebot: true

14:37 raek: clizzin: I think so

14:38 Nikelandjelo: hiredman: Oh :) Thanks. I am ashamed

14:39 amalloy: it's okay, you're used to languages that enjoy making things hard. you'll get the hang of clojure's ease-of-use

14:40 clizzin: hahaha

14:40 fmw: amalloy, raek: thanks, I've got it working. dropped multipart/form-data and went with appplication/x-www-form-urlencoded instead, using a simple foo=bar string as a body

14:41 amalloy: hooray

14:47 fmw: btw, is it worth it switching from vim to emacs for because of Clojure? I've been drewling at all the nice Emacs goodness for Lisp since I picked up Clojure, but although I used it as my first editor over 10 years ago I hardly remember how emacs works

14:47 also, I quite like Vim and have invested a lot of time into learning it over the last couple of years

14:47 amalloy: fmw: there are vim users who write clojure. some of them are even smart people, so there must be something to it

14:48 technomancy: fmw: we make people use Emacs at work. we have hired 3 vim users, and 1 of them still uses vim outside work.

14:48 as a data point.

14:48 fmw: amalloy: aye, I remember that Paul Graham is using vim too

14:49 technomancy: you *make* people use emacs? because of some in-house emacs plugins or something?

14:49 technomancy: fmw: for pair programming.

14:49 amalloy: fmw: because emacs is the best

14:49 fmw: technomancy: hmm, valid point

14:50 rak85: hi, guys!

14:50 fmw: I might just dive into emacs again, soon

14:50 org-mode and the email client seem nice benefits too

14:51 amalloy: fmw: after a couple weeks of pain you'll be as productive as you were with vim, and then it keeps going upwards

14:51 rak85: i have a list and want to iterate over its items in order to make side effects; actually save in a database...what's the best approach you would consider for this?

14:51 amalloy: doseq

14:51 technomancy: in my book the best part is having paredit available for IRC

14:51 fmw: right now I'm using mutt with vim as an external editor, but the integration could be better

14:51 amalloy: &(doseq [x (range 5)] (prn x))

14:51 sexpbot: ⟹ 0 1 2 3 4 nil

14:51 fmw: oh yes, I forgot that emacs is an OS ;)

14:51 IRC client too! :)

14:52 rak85: &(println "teste")

14:52 sexpbot: ⟹ teste nil

14:52 fmw: amalloy: why do you think I'll be more productive writing Clojure in Emacs?

14:52 amalloy: fmw: and shell! web browser! chess board! do whatever you want without ever closing emacs :P

14:52 paredit. slime

14:52 rak85: ammaloy: thanks!

14:52 amalloy: also the massive customizability of .emacs

14:53 scottj: fmw: if you're super good at vim I don't think switching makes sense

14:53 fmw: and as an editor? it seems nice as an OS, but I'm still quite fond of modal editing etc

14:54 scottj: I would say I'm super good at it, but quite experienced at least

14:54 s/would/wouldn't

14:54 sexpbot: <fmw> scottj: I wouldn't say I'm super good at it, but quite experienced at least

14:54 amalloy: fmw: you could try...what is it, viper, for making emacs keybindings more like the vim ones?

14:55 or vimpulse? i think i've heard of both of those things

14:55 fmw: amalloy: aye, I've read about that plugin

14:55 vimpulse yes

14:56 amalloy: but i dunno. i fumbled along with vim for years, never really attained proficiency, and then tried emacs when i started common lisp

14:56 fmw: oth, when I'll lose modal editing I guess I can just as well bite the bullet and grow that extra finger so I can press control all the time

14:56 amalloy: so i'm not really an ideal "switch from vim to emacs" consultant

14:56 scottj: fmw: emacs is good, but I think an advanced vim user would find things lacking that they'd have to add and might find the keybindings not quite as nice

14:57 amalloy: fmw: heh, so true. map caps-lock to an extra ctl key if you do; hugely more comfortable

14:57 leifw: +1 amalloy

14:57 scottj: fmw: for example, emacs doesn't have two move forward/backward by beginning/end of word.

14:57 fmw: hmm

14:57 technomancy: fmw: foot pedal

14:57 pjstadig: technomancy: hooooly crap i want one!

14:57 amalloy: technomancy: that sounds hardcore and awesome

14:58 dnolen: technomancy: I had one.

14:58 fmw: heh, might be a good investment :)

14:58 amalloy: need one for meta too though

14:58 leifw: technomancy: I always wanted a foot pedal

14:58 technomancy: well it doesn't work with a standing desk unfortunately =\

14:58 pjstadig: i play the drums, so a couple of foot pedals would be nice

14:58 lancepantz: na, the kinesis gives you 6 buttons per thumb, they might as well brand it as an emacs keyboard

14:58 amalloy: technomancy: pressure sensitive. lean forward if you want meta

14:59 scottj: like dance dance emacs?

14:59 amalloy: scottj: or that

15:00 leifw: lancepantz: <3 kinesis

15:00 lancepantz: :D

15:00 it's also fantastic for rsi

15:00 pjstadig: lancepantz: as in causing it or curing it?

15:00 lancepantz: curing :)

15:00 i used to have to wear wrist braces at night

15:00 leifw: haha emacs is fantastic for causing it :-P

15:01 lancepantz: now i don't even think about it

15:01 technomancy: man... I really do not buy the "use doall+map-indexed instead of doseq+indexed" argument at all.

15:01 lancepantz: to be fair thats when i was a vim user!

15:01 technomancy: doall is ugly; sometimes you're i/o bound and don't care about the extra consing. =\

15:02 indexed is way more composable

15:02 amalloy: technomancy: dorun+map-indexed?

15:02 $source indexed

15:02 sexpbot: Source not found.

15:02 amalloy: where is this indexed nonsense

15:03 leifw: $source map-indexed

15:03 sexpbot: map-indexed is http://is.gd/VNs4dX

15:03 technomancy: amalloy: indexed didn't get promoted from c.c.seq because it's a lot slower than map-indexed

15:03 but sometimes you just want a seq without mapping and you're not penny-pinching GC cycles. =\

15:04 http://groups.google.com/group/clojure-dev/msg/d8e342f54ea3db3b

15:06 amalloy: technomancy: i don't understand what you would use indexed for. just (map-indexed vector my-coll) if that's what you want, no?

15:06 technomancy: yeah, I was about to say (def indexed (partial map-indexed list))

15:06 I just prefer the more composable version over the faster one.

15:09 plus there are times when for is clearer than map

15:10 amalloy: technomancy: indeed there are a lot of such times

15:11 fliebel: I am with technomancy on this one. I frequently do (map-indexed vector some-list) to use it for something else.

15:12 Now we have map-indexed, reduce-indexed, but not filter-indexed, reductions-indexed, etc. (I'm not saying we should!)

15:12 technomancy: well, there is keep-indexed

15:13 webar7: wow ... clojure REPL emacs eshell and SLIME

15:13 nice :-P

15:16 there must be a few different approaches to writing "Active Clojure Pages" (hehe) i.e. html-ish pages that I can keep in ./resources/public/ or ./resources/clojure_pages and which get eval'ed (?) with stuff added by the client and my app's main handler ...

15:16 but what are they called ?

15:16 there's been a clojure explojion in my brain ... I feel like someone who has been using perl for 20 years but just discovered CPAN or something

15:17 pjstadig: and ugh for using dorun+map for side effects seems like doseq+indexed would be a better use

15:17 mids: take a look at hiccup and enlive

15:17 * webar7 wants to reserve the word "explojion" for furture use ;-)

15:18 Raynes: I don't think there is anything precisely like rhtml in Clojure.

15:18 Enlive is probably the closest.

15:19 webar7: hmm ok ... I'm thinking functional web programming a very different thing

15:19 I will loook at those

15:19 redinger: Enlive is pretty awesome

15:20 ataggart: enlive is pretty slick, see this tutorial: https://github.com/swannodette/enlive-tutorial

15:20 webar7: but I will first observe my own patterns of use for a few more days ... I just noticed I am thinking differently about HTTP :) this is very nice brain tickling

15:20 cool thanks

15:20 ataggart: I'm just hoping someone comes up with a more REST-y lib for ring so I don't have to write one.

15:21 fliebel: Does anyone have experience using JNA from Clojure?

15:21 webar7: ataggart, I love REST

15:22 KirinDave: Enlive is like... visionary.

15:22 I dunno what prior art exists for it

15:23 ataggart: fliebel: iirc someone wrote something to work with JNI. Not the same, but might point in the right direction.

15:23 KirinDave: But it's pretty much the only sensible way to develop software that is going to have nontrivial templating.

15:23 ataggart: KirinDave: after living through two years of an XSL-based website, I agree.

15:24 webar7: ataggart, and rest too for that matter ... :)

15:24 fliebel: ataggart: JNI still requires C code. JNA works in pure Java using interfaces, so I was thinking… defprotocol.

15:24 KirinDave: ataggart: Every time I see someone use sexps to generate nontrivial html, I get very very irritated.

15:24 It's like, "Yes. Toys exist. Stop playing with them when we're talking about grownup stuff."

15:25 ataggart: fliebel: if you get something together, I'd be interested. right now I'm punting on some pgp work by just making shell calls.

15:25 webar7: crikey! in a parallel universe connected by my own personal wormhole I just discovered fossil can pull and push and do git-ful things so I can use repos of clojure stuff pulled from git or various googlecode sorts of repos in my project which I then control my own parts of with fossil-scm

15:25 opqdonut_: KirinDave: /me worked on a project that generated everything using cl-who

15:25 fliebel: KirinDave: The difference between man and boy is the price of their toys. But then, this is all opens ource. Time for a new theory…

15:25 webar7: is that the "normal" way or does one use a clojure specific tool that updates the project classes one is using?

15:26 technomancy: KirinDave: the problem is it's so obvious and easy to implement that people are going to do it no matter what. ("wait a minute; these are trees, and these are trees... what happens if we...!!!")

15:26 KirinDave: technomancy: I try hard to be nice.

15:26 technomancy: But I am sort of tired of people who are just getting the basic idea now.

15:27 Part of that anger is directed at schools whos teaching is easily 20 years out of date now, in many cases.

15:27 technomancy: For example, my cousin is going to college right now. They're using Python to teach him.

15:27 Good start, I guess

15:27 ataggart: Now that MIT has bailed on it, does any school still teach using a lisp?

15:28 fliebel: Wait a moment… Why can't interfaces in Clojure extend another interface?

15:28 ataggart: fliebel: interfaces can, protocols can't

15:28 KirinDave: technomancy: He writes to me that he's angry he didn't get an A for this: http://pastebin.com/t7NtXnut

15:28 fliebel: $doc definterface

15:28 amalloy: ataggart: iirc there's no syntax *in clojure* to define an interface that extends another

15:28 ataggart: amalloy: ah fair enough

15:29 amalloy: ataggart: berkley uses scheme, i think

15:29 KirinDave: technomancy: Now I get he's a 1st year student and that code is common...

15:29 fliebel: amalloy: Oh, there goes all hope to implement JNA cleanly.

15:29 KirinDave: technomancy: But shiiit. I'd be hesitant to give that code a C outside of an introductory class.

15:30 ataggart: amalloy: I guess the argument now that we have protocols would be: "don't do that"

15:30 fliebel: How would I write this example in Clojure? http://en.wikipedia.org/wiki/Java_Native_Access

15:31 KirinDave: technomancy: When he was asking me to do his work for him I kinda replied in true bastard fashion: https://gist.github.com/10c6c81fbb98536fd8d8

15:31 webar7: If I do "lein new blahblahproject" ... then describe stuff in project file can I then run lein <something> to pull required jars into ./lib ? python/ruby have tools for this but since I know no java and the lisp is "higher up" not sure if I should use dvcs or some java tool?

15:32 ataggart, MIT seems to have no sense of history :) kerberos X lisp why bail?

15:32 raek: webar7: "lein deps" will pull the required jars into lib/

15:33 technomancy: KirinDave: heh. "Problem?"

15:33 KirinDave: technomancy: He was pretty unhappy with me.

15:34 webar7: raek, thanks

15:35 KirinDave: technomancy: And yet, why couldn't a first year student be using haskell? Is there really anything THAT complex? It's just alien. Same with clojure.

15:35 webar7: I just discover lein deps 10 seconds later :) but ... can't figure out how it works (I guess I need a bit of java dev env for browsing around jars and seeing how they connect)

15:36 technomancy: KirinDave: depends on the school. for trade schools it just doesn't address the target market. and most schools are trade schools.

15:36 webar7: raek, is it pulling .jars and java libs from vcs'es all over the place or is there a java (errm I mean clojure) collection of all the required stuff ?

15:36 KirinDave: technomancy: Another sentiment I don't entirely understand, but that's a different conversation :)

15:36 technomancy: KirinDave: not condoning it, just making an observation.

15:37 KirinDave: To me, that kind of thinking would have graduated no automotive engineers because the horse and buggy market was target.

15:37 webar7: raek, it seems like lein dep does a CPAN like scan of dependencies but ... where? :)

15:37 fliebel: chouser: Oh, thanks for sorting out all the nasty details for me! https://github.com/Chouser/clojure-jna

15:37 technomancy: webar7: "lein help tutorial" ought to sort you out

15:37 raek: webar7: it uses the maven dependency resolution system and some repos (clojars.org, the clojure build server, maven central, iirc)

15:38 webar7: technomancy, :)

15:38 raek, ahah! ok thanks just wanted to look around there without using lein

15:38 cheers

15:39 digash: ,(map #(do [% %]) [1 2 3])

15:39 clojurebot: ([1 1] [2 2] [3 3])

15:39 digash: ,(System/exit 1)

15:39 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.1)

15:40 webar7: ataggart, I think lisp is taught where ever AI is taught ... once upon a time it seemed compsci specific

15:40 ataggart, but now it seems more interesting to non compsci audience

15:42 jlf: ataggart: http://webcast.berkeley.edu/course_details_new.php?seriesid=2011-B-26281&semesterid=2011-B

15:43 webar7: but I guess people doing stuff like writing "lisp interpreters" in ruby are compsci majors :)

15:46 rak85: (println "teste")

15:46 ,(println "teste")

15:46 clojurebot: teste

15:47 rak85: -(println "teste")

15:47 why & and , ?

15:49 TimMc: rak85: & and , are just bot-specific triggers

15:49 webar7: PhilG's 10th rule hmm

15:50 what is that

15:50 oh ... "Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."

15:50 hehe

15:50 * webar7 goes off to play with clojure

15:50 webar7: thanks for pointers

15:53 rak85: thanks TimMc

16:01 fliebel: $mail chouser Thanks for clojure-jna. I think it could use some Maven love though. Is there a reason it doesn't have a pom.xml or project.clj?

16:01 sexpbot: Message saved.

16:07 lancepantz: Any sufficiently complicated irc bot contains an ad hoc, informally-specified, bug-ridden, slow implmentation of half of an operating system?

16:07 KirinDave: Ha

16:07 lancepantz: lance's corallary

16:11 fliebel: lancepantz: But large applications already contain an ad hoc, informally-specified, bug-ridden, slow implementation of half Clojure, so you're already halfway there.

16:11 lancepantz: hehe

16:11 the best was the nosql one technomancy tweeted

16:11 fliebel: ?

16:12 lancepantz: Any sufficiently complicated NoSQL program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of SQL.

16:12 fliebel: Yea, you can pretty much define a nosql db in one line of clojure: (ref {})

16:12 lancepantz: source: http://twitter.com/#!/kellan/status/10504462699331584

16:13 fliebel: lancepantz: But that would mean Clojure is a half ad hoc, informally-specified, bug-ridden, slow implementation of SQL.

16:15 lancepantz: but is SQL a half ad hoc informally-specified, bug-ridden, slow implementation of Common Lisp?

16:17 i hope this channel log gets a high pagerank for "ad hoc informally-specified, bug-ridden, slow

16:17 implementation"

16:17 fliebel: lancepantz: SQL is at least specified.

16:18 lancepantz: fliebel: very true

16:18 fliebel: That would do Clojure no good, not at all being ad hoc informally-specified, bug-ridden and slow.

16:18 lancepantz: yep :)

16:47 devn: hmmm, this context.io thing is cool

17:05 lancepantz: devn: link?

17:11 TimMc: I'm pretty sure Clojure is informally specified, though.

17:22 devn: lancepantz: http://context.io

17:22 now i just need to figure out how to use clj-oauth :X

17:24 * devn needs some https

17:24 lancepantz: that is pretty sweet

17:25 devn: lancepantz: wanna help me figure out how the hell to use clj-oauth with it? :)

17:25 lancepantz: not right now, ninjudd would kill me :P

17:25 devn: haha

17:38 mec: when/why can you use ^:static? its a hard thing to search about

17:39 brehaut: mec: i might be waaay off track here, but i thought :static vars as an option was discarded in favour of :dynamic as an option

17:40 mec: no idea, im not very familiar with 1.3 changes

17:41 dnolen: mec: ^:static was a temporary idea on the way to the current state of 1.3

17:44 mec: its still looks pretty common in core.clj

17:44 dnolen: mec: it's a no-op now. doesn't do anything.

17:45 mec: default is static, no need to specify ^:static anymore.

17:45 mec: ah ok

17:47 hiredman: not true

17:47 the default is not :Static

17:47 dnolen: hiredman: ?

17:47 hiredman: :static

17:47 the default is just less dynamic

17:48 I wish people would stop saying that

17:48 dnolen: hiredman: ^:static had other connotations yes, doesn't really matter much now anyhow.

17:48 hiredman: I specificly asked rickhickey about it durring the q&a at the conj so he would say they are not the same in the hope that people would stop saying they were

17:51 mec: so what are they?

17:51 dnolen: hiredman: hmm, oh yeah ^:static was only about fns, dynamic is about vars.

17:51 mec: really it's not worth thinking about too much, main point is ^:static is irrelevant.

17:51 hiredman: :static did away with indirection through vars completely

17:52 dnolen: mec: in general ^:static wasn't that cool, had issues w/ protocols and redefinition.

17:56 seancorfield: dnolen: are you saying that in 1.3.0-alpha6 you don't have to mark a fn ^:static in order for it to be compiled to a java static (and use primitive arguments)?

17:57 or are you just saying it's irrelevant for vars?

17:57 dnolen: seancorfield: ^:static is just irrelevant now. fn's have direct support for primitive arg & return.

17:57 hiredman: seancorfield: :static has nothing to do with java static

18:00 devn: is it just me or is there nothing already built to handle https?

18:02 technomancy: ,(clojure.java.shell/sh "gnutls-cli" [...])

18:02 clojurebot: java.lang.Exception: Unable to resolve symbol: ... in this context

18:02 technomancy: bugger.

18:03 hiredman: devn: it's you

18:05 seancorfield: dnolen: lots of clojure.core still has ^:static annotations... is that just leftover from when it mattered?

18:05 dnolen: seancorfield: yeah.

18:09 seancorfield: some context here, http://clojure-log.n01se.net/date/2010-10-18.html

18:10 seancorfield: context for the old way (^:static) here, http://clojure-log.n01se.net/date/2010-06-07.html

18:12 devn: hiredman: any pointers?

18:13 seancorfield: thanx for the links dnolen - it's hard to keep up, sometimes!

18:17 dnolen: devn: seems to me like the good Clojure http clients have some sort of https support. clj-http, clj-apache-http

18:18 pyr: 0/clear

18:22 Raynes: devn: 'Course not! That'd be productive. Can't have that. ;)

18:23 TimMc: I've been experiencing a number of frustrating debugging sessions where I end up chasing down bad values that propagate through my function calls before triggering some irrelevant error message.

18:24 What's the best way to add some early bogon detection to my code?

18:24 technomancy: preconditions?

18:24 TimMc: (I've had misnamed :keywords in maps, the wrong data structure being passed in, etc.)

18:26 dnolen: TimMc: I agree w/ technomancy, pre/postconditions are useful.

18:26 TimMc: Preconditions... those would be ugly if I'm checking the validity of maps.

18:26 Are defrecords recommended for ensuring that all the right slots are filled in a data structure?

18:27 dnolen: TimMc: preconditions can be any old function. I usually define validators somewhere.

18:28 alelos: hey guys, whats my best bet for creating matrices and maybe doing some matrix operations? incanter?

18:28 dnolen: TimMc: defrecord generally need a ctor fn, that ctor will need to do some kind of validation.

18:28 TimMc: dnolen: And then check that each argument is the appropriate record type? (I guess type hints will help with that.)

18:29 dnolen: TimMc: type hints don't guarantee anything.

18:29 TimMc: https://gist.github.com/926381 is something I've done before in my own code.

18:29 TimMc: I know. But they'll sure as hell throw the right kind of fuss when the cast goes wrong.

18:30 technomancy: not really

18:31 TimMc: technomancy: Expand?

18:31 technomancy: pretty sure if the type hint is wrong it will just fall back to reflection.

18:32 TimMc: I recall it throwing.

18:32 brehaut: TimMc: i think you are being tricked by the interop

18:32 ,((fn [^String foo] foo) [1 2 3])

18:32 clojurebot: [1 2 3]

18:33 brehaut: ,((fn [^String foo] (.replace foo "a" "b")) [1 2 3])

18:33 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.String

18:33 dnolen: TimMc: type-hints are only about controlling reflection, not much else.

18:33 brehaut: the exception comes from .replace, not the type hint

18:33 TimMc: Sure, but I would be calling .methods on these things anyway.

18:34 Anywho, preconditions would work.

18:34 Thanks for the tips.

18:36 hiredman: https://gist.github.com/26d6a42bde8944290501

18:42 TimMc: (It doesn't help that I keep getting my damn unit tests wrong.)

18:48 hiredman: Was that for me?

18:48 dnolen: hiredman: very interesting, tho quite a bit slower than just using destructuring + :pre at least for the kinds of examples you've shown.

18:50 hiredman: dnolen: I don't recall making any claims of performance

19:16 * devn concocts an insane mixture of juxt, comp, and partial

21:01 mec: Are there any other generators of chunked seqs besides range?

21:02 brehaut: mec: vector

21:10 mec: was there some way to temporarily disable chunks or am I remembering wrong?

21:11 amalloy: mec: iirc the best way is currently to create a new manual lazy-seq around them

21:11 there's an example of that in JoC

21:11 mec: Ya I saw that, I just swear i remember something like *chunked-seqs* that could temporarily turn them off

21:50 tufflax: Welcome to Critique my fn! http://pastebin.com/agxEYdVm :P It doesn't feel quite right to have ps grow like that, hm...

21:54 mec: tufflax: if you just want primes one already exists, otherwise without looking in depth yet you should put lazy-seq elsewhere: https://gist.github.com/926654

21:56 Otherwise it will find the next prime before you actually want it

21:57 amalloy: mec: worse than that. i don't think it returns anything lazily: the cons is inside the lazy-seq

21:58 well, i guess that's not true. feh

21:58 mec: ya i think it'll just run until it hits the lazy-seq, doing the computation before hand

21:58 amalloy: i was thinking the recursive base case never gets hit, but lazy-seq does intervene

21:59 it's just harder to visualize for me, when the cons is inside the lazy-seq

21:59 tufflax: hmm, so you're saying it generates one more element than it needs to?

22:00 mec: no it just does the computation for the next element, so: 2 calc 3, 3 calc 4, 4 calc 5. instead of full lazy: 2, calc3 3, calc4 4, calc5 5

22:00 tufflax: amalloy isn't the cons supposed to be inside? i don't understand

22:01 amalloy: tufflax: if you're rolling your own, the general pattern is like (cons foo (lazy-seq ...))

22:01 this gets you the element you've computed immediately, and attaches the remainder of the computation lazily

22:02 but i think i'm oversimplifying in ways that make what i say unuseful

22:03 tufflax: hm, well mec's is also inside https://gist.github.com/926654

22:03 amalloy: tufflax: kinda-sorta. this is the simplification i referred to. it's *very deep* inside, so that it's very much like the cons is wrapping the lazy-seq generated by the *next* invocation of primes

22:04 mec: if you unroll mine the call to (primes [2] 3), the first statement is lazy-seq so you get: (cons 2 (lazy-seq ...))

22:05 tufflax: https://gist.github.com/926654

22:08 tufflax: oh yeah... but mine just does one calc ahead ro

22:08 right

22:10 mec: actually you can simplify away the if-let + when, check the gist again

22:11 tufflax: got disced after your <mec> tufflax: https://gist.github.com/926654

22:12 mec: I just said you can simplify away the if-let + when

22:14 tufflax: so as I was saying: mine just does one calc "too much" right?

22:14 mec: ya if you (take 10 primes) it will calculate for 11

22:15 also, since you have to hold onto the head anyway, you can completely get rid of ps

22:16 tufflax: refresh the gist for that change

22:23 * tufflax checks the log

22:27 tufflax: interesting... :)

22:32 thanks mec, amalloy_ i knew i would learn something by asking for critique :)

22:33 mec: tufflax: np, i love tweaking code ;p

22:35 tufflax: clojure is so much more fun than java, i never wanna touch java again :p

23:01 TimMc: ,(type (#()))

23:01 clojurebot: clojure.lang.PersistentList$EmptyList

23:01 TimMc: That's amusing.

23:02 mec: thats weird

23:03 TimMc: (#()) -> ()

23:03 mec: ,'#()

23:03 clojurebot: (fn* [] ())

Logging service provided by n01se.net