#clojure log - Jun 10 2011

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

0:22 amalloy: mattb[]: the amount of code generated bymacros is stupendous

0:24 for example, see ##(macroexpand-all '(for [x xs y ys] [x y]))

0:24 sexpbot: ⟹ (let* [iter__4063__auto__ (fn* iter__10212 ([s__10213] (new clojure.lang.LazySeq (fn* [] (loop* [s__10213 s__10213] (if (clojure.core/seq s__10213) (do (let* [x (clojure.core/first s__10213)] (let* [iterys__4059__auto__ (fn* iter__10214 ([s__10215] (new clojure.lang... http://gist.github.com/1018221

0:24 mattb[]: haha wtf

0:25 dnolen: mattb[]: pshaw! https://gist.github.com/1018223

0:26 mattb[]: wtf...

0:26 brehaut: dnolen: win

0:27 mattb[]: macros ~= writing a little bit of the compiler yourself

0:27 amalloy: mattb[]: the point is, it's nice to be able to build language features like this yourself instead of having them baked into eg gcc where you can't even understand them

0:27 mattb[]: sure

0:28 where are they located?

0:28 amalloy: mattb[]: well, for is a builtin in clojure.core

0:28 ~source for

0:28 dnolen's is nonsense of his own imagining

0:28 mattb[]: haha

0:29 dnolen: hey!

0:29 mattb[]: how much of clojure is written in clojure?

0:29 dnolen: mattb[]: not much at the moment, but work is being done to have most of it done in itself. thus deftype/record

0:30 mattb[]: and there's a performance benefit to that?

0:30 amalloy: dnolen: i think "not much" isn't accurate. clojure.core isn't as large as clojure.lang, but there's a lot of it

0:31 mattb[]: hah "and" is a macro

0:31 dnolen: mattb[]: no perf benefits, portability benefit.

0:31 mattb[]: ah

0:32 dnolen: in fact most certainly Clojure ports will be much slower than Clojure on the JVM for a very long time.

0:35 mattb[]: so a ref p is essentially a pointer, and alter changes the pointer rather than the pointee, correct?

0:38 amalloy: errr?

0:38 mattb[]: lol

0:39 amalloy: but i think that's reasonably accurate

0:39 mattb[]: in reference to (again with the defunct demo) "(alter p assoc :ant a)"

0:39 dnolen: mattb[]: Clojure reference types aren't just pointers, they all have state management semantics. refs are designed to work with the STM, you can't change a ref outside of a transaction.

0:39 mattb[]: aye dnolen

0:40 but you never actually change the pointee, right?

0:40 you change the pointer in a transaction

0:40 dnolen: mattb[]: done properly there's no such thing as changing the pointee either, immutable data structures and all that.

0:40 mattb[]: aye

0:41 amalloy: &(let [r (ref 1) v1 @r] (dosync (alter r inc) [v1 @r])))

0:41 sexpbot: ⟹ [1 2]

0:41 amalloy: mattb[]: ^?

0:42 mattb[]: so @r is immutable still

0:42 amalloy: yep

0:43 mattb[]: so if I ran this 1000 times would I have 1000 separate memory locations for variations of @r?

0:43 dnolen: mattb[]: not necessarily from what I understand.

0:43 amalloy: uhhhh, if you actually collected the results, i think so? otherwise they'd be eligible for gc and migght disappear or be reused

0:44 mattb[]: I see

0:44 are there unboxed value types?

0:44 dnolen: mattb[]: 64bit primitives.

0:44 long & double

0:44 mattb[]: no unboxed integer?

0:44 dnolen: mattb[]: no.

0:45 mattb[]: heh

0:45 dnolen: mattb[]: well yes, but not fast path for it.

0:45 mattb[]: I don't know much about the JVM GC

0:45 but I hope it's good :)

0:45 brehaut: its very good for a lot of uses cases (in particular if you tune it)

0:46 dnolen: mattb[]: it's very good, part of the reason Clojure is possible. but it's certainly true that Clojure is memory hungry.

0:48 mattb[]: http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=clojure&lang2=java

0:49 looks like clojure is 3-5x as memory intensive as plain java

0:52 dnolen: mattb[]: yup, tho those could probably be improved, only one person really works on those benchmarks. I think most of those could get whittled down to 1.5X-2X of Java and mostly on par w/ memory usage.

0:59 mattb[]: here's a weird question for you... how do you *read* lisp?

1:00 when you look at something like (< r (+ (slices i) sum)), how does it vocalize in your head? do you actually see it as "r is less than (slices i plus sum)"

1:01 dnolen: (-> (slices i) (+ sum) (< r)) if you don't like looking at nested code.

1:01 amalloy: mattb[]: i don't usually vocalize when i'm reading, programming or otherwise

1:02 dnolen: ,(-> 5 (+ 10) (< 20))

1:02 clojurebot: true

1:02 mattb[]: I feel like it's worthwhile to try not translating from prefix notation and back again

1:03 I guess I've only been looking at it for like two days though, not surprised it feels totally unnatural

1:03 amalloy: mattb[]: i still have trouble with (< x y). is x less than y, or y less than x?

1:04 brehaut: amalloy: its (< x y z) that really messes with me

1:04 dnolen: ,(< 1 2 3)

1:04 clojurebot: true

1:04 mattb[]: I can't look at it without looking at "less than.. x.. is less than.. y"

1:05 eyes bouncing inside the parenthesis like a bingo ball

1:05 brehaut: i think reading < as monotonically increasing is easier than 'less than'

1:05 makes (< 1) make sense too

1:05 mattb[]: huh

1:05 that makes way more sense lol

1:05 amalloy: brehaut: funny. i read (< x y z) with no problems

1:06 mattb[]: well brehaut just solved all my problems

1:06 now I can't look at (< x y z) without seeing "increasing to the right"

1:07 amalloy: mattb[]: careful. when brehaut solves all your problems you find yourself with another set of problems

1:07 mattb[]: haha

1:07 brehaut: haha

1:07 its true!

1:07 mattb[]: hopefully vastly more interesting problems

1:07 brehaut: mostly just regexp + monad soup

1:08 mattb[]: oh god

1:08 brehaut: i like to call it a parser

1:08 mattb[]: what have I stumbled into

1:08 where am I

1:08 I quit perl two years ago

1:08 brehaut: perl has a monads lib?

1:09 technomancy: elisp does

1:09 mattb[]: I wrote a small novel worth of regexp a while back

1:09 I believe I have multiple sclerosis now

1:09 technomancy: http://dorophone.blogspot.com/2011/04/deep-emacs-part-1.html

1:09 brehaut: technomancy: i am frightened

1:10 dynamic scopes ftw i guess?

1:11 http://ubuntuone.com/p/vtn/ even though i understand bind, that doesnt make much sense to me

1:21 oh i think i got terms wrong. < is strictly increasing, <= is monotonically increasing

1:23 mattb[]: erm I believe you were right

1:24 monotonically just means not decreasing

1:24 not only strictly increasing

1:24 brehaut: exactly

1:24 mattb[]: < is not decreasing

1:24 er no

1:24 you were right the second time :)

1:24 brehaut: thats what i mean

1:25 mattb[]: haha

1:25 it's late

1:25 brehaut: communication fails; clearly its friday evening

1:25 (down here in the future anyway)

1:25 mattb[]: let me know if anything bad happens in the future so I can prepare

1:26 brehaut: its raining pretty heavily so dont go out without an umbrella

1:32 mattb[]: aha

1:33 first class functions make me happy

1:35 amalloy: $findfn 4 5 6 15

1:35 sexpbot: [clojure.core/+]

1:35 amalloy: mattb[]: ^ is available for you, btw

1:36 mattb[]: ^ is what?

1:37 amalloy: a pointer upwards to the previous message

1:37 i guess i need to stop including it in sentences

1:38 mattb[]: OH lol I didn't realize you had said something before

1:51 so in (import '(java.awt Color Graphics Dimension)), how would it try to interpret that without the apostrophe?

1:51 hiredman: import may be a macro these days

1:51 brehaut: bad example, import doesnt need a '

1:51 hiredman: (meta #'import)

1:52 ,(meta #'import)

1:52 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name import, :file "clojure/core.clj", :line 2617, :arglists ([& import-symbols-or-lists]), :added "1.0", :doc "import-list => (package-symbol class-name-symbols*)\n\n For each name in class-name-symbols, adds a mapping from name to the\n class named by package.name to the current namespace. Use :import in the ns\n macro in preference to calling thi...

1:52 mattb[]: fair enough

1:52 hiredman: it used to need a quote, in the before time

1:52 mattb[]: this sample is really old

1:52 brehaut: extremely

1:52 * hiredman still quotes everything

1:52 brehaut: i first read it back in 08

1:52 its pre clojure 1.0

1:52 mattb[]: oh crap, it IS from 08

1:53 brehaut: back when rhickey would occasionally release a datestamp snapshot or you followed SVN

1:53 mattb[]: is the book worth reading?

1:53 brehaut: what book?

1:53 mattb[]: the joy of clojure I believe

1:53 brehaut: depends how familiar you are with one of Java or Lisp

1:54 (or failing that, some other dynamic or functional languages)

1:54 * mattb[] has never lisped

1:54 brehaut: Java?

1:54 clojurebot:

1:54 brehaut: thanks clojurebot

1:54 mattb[]: I'm most comfortable with C#/java

1:54 lol

1:54 brehaut: its a very good book

1:54 but its not a beginner book

1:55 being comfortable with the java ecosystem or a lisp is advisable

1:55 doesnt need to be both though

1:55 its very much the 'why' book rather than the 'how' book

1:55 mattb[]: it doesn't presume lisp knowledge though?

1:55 brehaut: no

1:55 mattb[]: good

1:55 brehaut: but its introduction is lightening fast

1:56 i think its called 'drinking from the firehose'

1:56 mattb[]: haha

2:03 amalloy: my favorite thing about that book is that there's a chapter called "being lazy and set in your ways", about laziness and immutability

2:04 mattb[]: haha

2:40 void_: good morning everyone ;)

2:58 Dranik: hi all!

2:58 is there a way to get the current name space except *ns* ?

2:59 opqdonut: why would you want another way?

3:00 Dranik: I want just a pure name space string in order to use it as a symbol.

3:00 but *ns* generates something like #<Namespace user> -- I have to parse that

3:01 opqdonut: well you shouldn't parse it

3:01 but use, for example (.getName *ns*)

3:02 the value of *ns* isn't a string "#<Namespace user>", it's a Namespace object

3:03 Dranik: opqdonut: thanks!

3:11 void_: Dranik: next time just say (type *ns*) and then find docs for that type

3:14 opqdonut: solid advice

3:15 void_: that's so great about clojure - you have repl all the time, you can inspect everything

3:23 Dranik: void_: thanks, but actually I didn't found that .getName() method while going your way (with (type *ns*) and find-doc)

3:25 void_: yeah you're right

3:26 my point was, when you have the type you can find out more about it

3:26 opqdonut: unfortunately the Java interfaces of clojure things are badly documented

3:26 void_: &(.getMethods (type *ns*))

3:26 sexpbot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Namespace is bad!

3:26 Dranik: btw, is there an easy way to get all the methods of the current object?

3:26 void_: Dranik: .getMethods

3:26 opqdonut: it would be neat if (doc) could access javadoc

3:26 void_: &(.getMethods *ns*)

3:26 sexpbot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Namespace is bad!

3:26 Dranik: let me try..

3:27 opqdonut: ah, repl-utils has (javadoc class)

3:27 void_: oh

3:50 Dranik: Ok, repl-utils solved most of my problems, thanks :-)

4:59 how to join two vectors?

4:59 opqdonut: ,(into [1 2 3] [4 5 6])

4:59 clojurebot: [1 2 3 4 5 6]

5:00 Dranik: thanks!

5:00 opqdonut: though that kinda works "by accident"

5:00 since what into does is repeated conjs, and the conj for vector appends

5:00 ,(vector (concat [1 2 3] [4 5 6]))

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

5:00 opqdonut: err

5:00 ,(vec (concat [1 2 3] [4 5 6]))

5:00 clojurebot: [1 2 3 4 5 6]

5:00 opqdonut: :)

5:01 Dranik: :-)

5:19 Fossi: ,(into '(1 2 3) [4 5 6])

5:19 clojurebot: (6 5 4 1 2 3)

5:19 Fossi: so, yeah ;)

5:20 opqdonut: and ##(into [1 2 3] '(4 5 6))

5:20 sexpbot: ⟹ [1 2 3 4 5 6]

5:20 opqdonut: vec could take multiple arguments like str

7:51 void_: &(.getInstance java.utilCalendar.)

7:51 sexpbot: java.lang.ClassNotFoundException: java.utilCalendar.

7:51 void_: (.getInstance java.util.Calendar.)

7:51 &(.getInstance java.util.Calendar.)

7:51 sexpbot: java.lang.ClassNotFoundException: java.util.Calendar.

7:51 void_: &(.getInstance java.util.Calendar)

7:51 sexpbot: java.lang.IllegalArgumentException: No matching field found: getInstance for class java.lang.Class

7:52 void_: Why doesn't this work?

7:52 I used (import '[java.util Calendar]) in my code

7:53 terom: I think getInstance is a static method. Try Calendar/getInstance

7:54 &(java.util.Calendar/getInstance)

7:54 sexpbot: ⟹ #<GregorianCalendar java.util.GregorianCalendar[time=1307706793147,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="US/Pacific",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZ... http://gist.github.com/1018696

7:54 clgv: &*clojure-version*

7:54 sexpbot: ⟹ {:major 1, :minor 2, :incremental 0, :qualifier ""}

8:00 void_: so you can't call static methods with (.method object) ?

8:01 &(let [cal (java.util.Calendar/getInstance)])

8:01 sexpbot: ⟹ nil

8:01 void_: &(let [cal (java.util.Calendar/getInstance)] (println cal))

8:01 sexpbot: ⟹ #<GregorianCalendar java.util.GregorianCalendar[time=1307707232071,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="US/Pacific",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZ... http://gist.github.com/1018703

8:01 manutter: ,(macroexpand-1 '(.method object))

8:01 clojurebot: (. object method)

8:01 rostayob: What's the best resource to learn clojure if I'm a haskell programmer? possibly something that I can read nicely on a kindle

8:02 considering that clojure would be my first lisp

8:02 void_: thanks guys

8:02 manutter: rostayob: I really liked the Clojure In Action book from manning press

8:03 Not sure if it's available in a kindle format yet

8:03 Dranik: Practical Clojure was best for me

8:03 rostayob: manutter: the problem is that the three books that seem to be most reccomended (the joy of clojure, clojure programming and the one you mentioned) seem so be available only in paper

8:03 Dranik: and The Joy of Clojure after it

8:03 manutter: Land of Lisp is also a good lisp intro

8:03 rostayob: Dranik: practical clojure is available for kindle mhm

8:04 Dranik: rostayob: no, all the books about clojure have their digital versions

8:04 manutter: also just as a general resource, the 4clojure.org web site has about a hundred exercises from elementary to advanced, great resource for practicing and getting hand-son

8:04 rostayob: Dranik: digital as in ebook? because pdf is not nice

8:05 manutter: *hands-on

8:05 void_: pdf is nice on iPad :)

8:05 rostayob: void_: no ipad for me eheh

8:05 Dranik: you are right, programming clojure is available in some ebook format

8:05 mobi

8:06 Dranik: rostayob: well, I meant pdfs of course

8:06 rostayob: Dranik: no but they have it in mobi, so it's good

8:06 manutter: rostayob: http://www.manning.com/rathore/

8:07 o wait, August release date

8:07 I read it thru the MEAP program, but I think the MEAP is pdf's

8:08 void_: Q: What are my options with MEAP?

8:08 A: With MEAP books, you get Early Access to electronic chapters for no extra charge. You choose the format of the final product: PDF ebook only, or you can also receive the paper book when it ships.

8:08 so it's only PDF

8:11 rostayob: ok, I think I'll go for practical clojure

8:11 Fossi: that's so sane

8:11 ebook formats stink so much

8:11 well, pdf does as well

8:12 void_: yeah practical clojure looks nice

8:12 terom: Joy of Clojure is a good book (even I've not yet completely read it yet). You'll get ebook for free if you buy paperback version. Or at least I did.

8:13 Dranik: can't wait for Clojure Programming

8:14 void_: why?

8:14 clojurebot: why not?

8:14 Dranik: it looks like a very practical book focused on some every-day tasks

8:14 not just on language usage

8:14 void_: that sounds nice

8:14 I'm thinking of pre-ordering that

8:14 http://www.bookdepository.com/Clojure-Programming-Chas-Emerick/9781449394707

8:15 manutter: I got the rough cuts version from O'Reilly, it's looking good

8:15 void_: huh

8:15 Dranik: yep that's what I'm talking about

8:16 manutter: could you please share you rouhg cuts to have a first glance at a book?

8:16 void_: &(. Integer valueOf "42")

8:16 sexpbot: ⟹ 42

8:16 void_: &(. Calendar getInstance)

8:16 sexpbot: java.lang.Exception: Unable to resolve symbol: Calendar in this context

8:16 void_: &(. java.util.Calendar getInstance)

8:16 sexpbot: ⟹ #<GregorianCalendar java.util.GregorianCalendar[time=1307708155283,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="US/Pacific",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZ... http://gist.github.com/1018726

8:17 void_: &(.getInstance java.util.Calendar)

8:17 sexpbot: java.lang.IllegalArgumentException: No matching field found: getInstance for class java.lang.Class

8:17 void_: why

8:17 manutter: wow, that's surprising

8:17 ,(macroexpand-1 '(.getInstance java.util.Calendar))

8:17 clojurebot: (. (clojure.core/identity java.util.Calendar) getInstance)

8:18 clgv: void: static methods are callled like that: ##(java.util.Calendar/getInstance))

8:18 sexpbot: ⟹ #<GregorianCalendar java.util.GregorianCalendar[time=1307708218870,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="US/Pacific",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZ... http://gist.github.com/1018728

8:18 manutter: o

8:18 void_: clgv: yes, it just doesn't make much sense to me right now! :)

8:19 clgv: void: in this case (.getInstance java.util.Calendar) Calender resolves to a Class object and the class Class has not .getInstance method

8:19 manutter: void_: check out the macroexpand--something funky is happening with the reference to the java class

8:19 clgv: &(type java.util.Calendar)

8:19 sexpbot: ⟹ java.lang.Class

8:19 void_: oh

8:19 clgv: &(type java.util.Calendar/getInstance)

8:19 sexpbot: java.lang.Exception: Unable to find static field: getInstance in class java.util.Calendar

8:19 void_: so speaking OOP, java.util.Calendar in this case is an instance of java.lang.Class

8:20 manutter: ,(.getInstance (java.util.Calendar.))

8:20 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.util.Calendar

8:20 manutter: heh, so much for being clever

8:20 clgv: void: the symbol "java.util.Calendar" you specify is resolved to an object of type java.lang.Class

8:21 void_: ok thanks ;)

8:21 for now I'll just remember to call static methods with /

8:21 clgv: right ;)

8:21 it is the same syntax as if you only required a clojure namespace where you have to provide the namespace of the function as well

8:22 void_: I really like this way of learning: for each topic: read something, hack, read something. Reading with having that experience of hacking is much different.

8:23 most people just read, and then hack.

8:23 clgv: void: but I suggest to read one of the introductory books for a start. that'll get you started much faster

8:24 void_: clgv: I'm reading Joy of Clojure, I'm at around half, and I feel the need to try the simple things before reading about complicated. (threading and stuff)

8:25 clgv: void_: trying the examples that seem not so clear at first glance is always a good idea ^^

9:40 void_: in compojure, where should I put my db connection code?

9:43 manutter: I'd put it in its own namespace

9:43 then call/require it from the same code that launches your app

9:43 I'm trying to remember how I did it, but I *think* it auto-connects just from pulling in the require

9:45 void_: ok so this is my handler

9:45 :ring {:handler theboots.core/app}

9:46 Dranik: void_: isn't compojure just a routing framework?

9:46 void_: Dranik: yeah I guess

9:46 but to me compojure = rails

9:46 so when I say "how do I do it in compojure" I mean "what is the best practise for web development in clojure" :)

9:47 Dranik: void_: I have implemented a rails-like blogging engine with posts, comments and simple authentication

9:47 would you like to have a look?

9:47 void_: of course

9:48 is it open-source?

9:48 Dranik: id havn't published it yet

9:48 I can send you via e-mail

9:48 redinger: Dranik: What framework did you use?

9:49 Dranik: ring/compojure, clojure-soy, clojure-sql

9:50 I like rails very much too so I've tried to emulate the rails-style in my application

9:50 redinger: clj-soy?

9:50 Dranik: yep

9:50 void_: Dranik: that's exactly what I would like to do

9:50 Dranik: but its a very hard work for a single person. that's why I have stopped my experiment

9:51 redinger: I'm very curious how people are doing this in the wild, I'd love to take a look if you don't mind. :)

9:51 Dranik: I can show you a couple of snippets

9:51 redinger: As a recovering Rails-ist, current Clojurian.

9:51 Dranik: I haven't published it, so just send my your email

9:53 void_: redinger: do you use clojure to build web applications too?

9:53 redinger: Yes

10:01 void_: Dranik: it's very nice code

10:01 Dranik: thanks! :-)

10:03 timvisher: hey all

10:04 i just started getting weird errors with slime. for example https://gist.github.com/1018881

10:06 I can do basic things like (+ 1 1)

10:06 nickik: @Dranik I want to implment a a blogging engine to would you mind sending it to me too?

10:06 timvisher: and i can C-c C-k on the namespace and switch to it

10:06 but the moment I try to use any of the functions, it starts throwing errors

10:06 Dranik: nickik: no problem, just send me your mail

10:07 manutter: timvisher: maybe you need a lein clean ; lein deps ?

10:09 timvisher: actually, i take that back. i can use in memory functions. it's when I reference my library ref that it seems to screw up. https://gist.github.com/1018890

10:09 manutter: haven't tried lein clean...

10:09 Dranik: also I have documented the project on my blog (my-clojure.blogspot.com) but it's in russian. if interested -- try translate.google.com, it reads my articles fine

10:12 timvisher: manutter: `lein clean` changed the error message at least. seems to be the same sort of issue though. https://gist.github.com/1018899

10:13 redinger: Dranik: Between the code base and the blog post, you are building a good tutorial. I hope you release the code publicly.

10:13 Dranik: redinger: you mean the blog or the code itself?

10:14 redinger: The code

10:14 Dranik: do you really think it looks fine as a tutorial?

10:15 if so, I can comment it and publish on github

10:15 Vinzent: Dranik, hey, maybe we should restore the #clojure-ru channel?

10:15 Dranik: Vinzent: no way, I don't wanna talk apart from clojure/core guys! :-)

10:20 Vinzent: Dranik, well, I just have readed your comment (about frameworks) and want to talk to you, but I think russian would be more convenient

10:20 redinger: Dranik: yes, I think it would be useful for the Rails people googling for how to do that

10:21 Dranik: Vinzent: my encoding is utf8. what's yours?

10:21 timvisher: i can run my tests and such via `lein test`

10:21 so it seems to be something with slime, not with lein

10:22 Vinzent: Dranik, latin/unicode

10:22 Dranik: redinger: Ok then, I'll publish the code with a tutorial. Probably anyone will help me to finish the project as a small framework

10:22 timvisher: and the project runs fine

10:23 it's just that i can't work on it in slime at the repl

10:33 Cozey: Hi! What's the recommented form / validation library for Compojure?

10:34 Vinzent: Cozey, checkout https://github.com/dnaumov/jaco/blob/master/test/jaco/test/core/actions.clj

10:34 Cozey: what about validation-clj, clj-decline etc?

10:35 Vinzent: what the heck is that?

10:38 Vinzent: Cozey, web-framework built on top of compojure. I see you didn't like it

10:39 Cozey: no - not at all

10:39 but i'm trying to aunderstand something that looks to me like prolog

10:39 why wouldn't i like it? I just woder how could i validate an e-mail form field with that

10:46 timvisher: anyone know why slime might throw an error like this? https://gist.github.com/1018899

10:47 Vinzent: Cozey, oh, my english is very bad, probably I've misunderstood you. To validate e-mail, you can write somethig like this: https://gist.github.com/1018974

10:47 pdk: ,(name :test)

10:47 clojurebot: "test"

10:47 pdk: ,(keyword "test")

10:47 clojurebot: :test

10:47 Vinzent: Many common predicates can be found in pretzel: https://github.com/joodie/pretzel

10:50 Cozey: Vinzent: mhmm . thanks, I will look into that

10:53 cemerick: curious mention of "jigsaw + clojure" here: http://openjdk.java.net/projects/mlvm/jvmlangsummit/agenda.html

10:57 Vinzent: timvisher, jpeg, strange... Same thing for new projects?

10:57 timvisher: Vinzent: you mean can I create a new project and reference the thing I'm trying to reference in the current project?

11:01 Vinzent: or are you talking about the use of the jpeg extension?

11:05 Vinzent: timvisher, i thought slime throwing this error for all projects

11:05 timvisher: i can only trigger it through the project that is referencing the library ref

11:05 which right now is only 1

11:05 it was working up until about an hour ago.

11:05 but I can see anything wrong with the seq in the file that i'm loading it from

11:06 and clojure's using it fine

11:06 it seems to be when slime tries to print it to the repl

11:08 i can also run all my tests from within slime (via clojure-test)

11:08 it's only when I try to utilize library from the repl

11:10 and hurray!

11:10 it magically started working again

11:11 and i immediately eat my own words

11:14 i can indeed use that reference. it's when i try to print the entire thing that it barfs

11:19 gfrlog: anybody know anything about clojure & Jenkins?

11:29 cemerick: gfrlog: such as?

11:31 gfrlog: cemerick: well googling tells me that there is not a "leiningen plugin for jenkins"

11:31 cemerick: yeah, that's correct, last I knew

11:32 gfrlog: I'm not familiar with jenkins though, and reading through things is starting to make me think that it can probably do arbitrary things

11:32 cemerick: Someone tried to ante up a bounty for one, I think.

11:32 gfrlog: I was just hoping that I can get it to run my tests without having to learn maven :)

11:32 cemerick: yeah, you can set up a job to run arbitrary scripts

11:32 gfrlog: that's the realization I was coming to. Good to hear it confirmed. Thanks.

11:33 cemerick: The real pain will be that you're going to need to drop down into a console in order to do certain things that you'd be able to do from the UI if you were using ant or maven, etc.

11:33 gfrlog: cemerick: what sort of things?

11:35 cemerick: installing/upgrading lein, using different JVMs, probably things like repository deployment

11:36 gfrlog: okay. I can live with that.

11:36 cemerick: yeah, there are definitely people using lein with hudson/jenkins

11:37 gfrlog: cool

11:37 timvisher: anyone know why slime would do something like this? https://gist.github.com/1018899

11:40 cemerick: gfrlog: hell, there are people using hudson with custom shell script builds :-P

11:42 gfrlog: "If you can not able solve it with few than 10 Apache rewrite rule, is probable not worth solve."

11:42 pjstadig: maybe no surprise, but we use hudson/jenkins with lein at Sonian

11:42 setup a build with to run a shell script

12:00 technomancy: somebody's working on a leiningen plugin for hudson too so you don't have to shell out

12:01 not sure how much that actually buys you though

12:01 deployment is easy to configure from project.clj and/or ~/.lein/init.clj

12:02 * offby1 notices the double meaning of "shell out"

12:02 technomancy: offby1: triple meaning if you count Ninja Turtles

12:02 cemerick: technomancy: clicky-clicky is always more pleasant than testing shell invocations via hudson :-)

12:03 technomancy: cemerick: depends... I just set up all our ci jobs via chef, so it all had to be based around config files anyway

12:03 it's more work up front, but it's way more repeatable

12:04 it's a cultural thing I guess

12:05 cemerick: I've never quite grokked the use of automation tools for hudson envs, actually. I don't start up new hudsons more than once every ~5 years, it seems.

12:05 technomancy: cemerick: we're probably going to be investing in a master/slave scenario down the road

12:06 because our recipes need testing too, and different environments are mutually exclusive for a given host

12:07 gfrlog: your automated-test-running-scripts need to be automatically tested?

12:07 cemerick: That makes more sense to me; but, there's a plugin already for build slaves, no?

12:07 technomancy: cemerick: right, but the build slaves will need to be torn down and rebuilt from scratch, otherwise the recipes aren't actually being tested.

12:08 gfrlog: STACK OVERFLOW

12:08 nickik: does jenkins/hudson work with leiningen? (never used any think like CI)

12:08 gfrlog: :)

12:08 technomancy: nickik: you can call out to any command from jenkins. as long as it returns a sensible exit code it will work.

12:09 gfrlog: man programmers never stop building their tower of abstractions

12:09 hiredman: ~problem

12:09 clojurebot: People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....

12:09 hiredman: ~problem

12:09 clojurebot: People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....

12:09 hiredman: clojurebot: you jerk

12:09 clojurebot: It's greek to me.

12:09 hiredman: ~abstractions

12:10 clojurebot: Huh?

12:10 gfrlog: someday it will take 15 experts to describe everything between the transistor and the website

12:10 hiredman: someday?

12:10 gfrlog: 45?

12:10 how high do I need to go?

12:10 TimMc: I think I can already pretty much explain it.

12:10 gfrlog: It depends on the level of detail that is required.

12:11 gfrlog: If I had piles of money I would commision a cool animated educational video outlining it

12:11 it would be bookended by a grandma clicking "Add friend" on facebook or something like that

12:11 hiredman: TimMc: I doubt you can explain the various optimizations the jvm does, or the inner workings of a recent intel chip

12:11 nickik: how many will it take until a noob can start from nothing build his computer and make it a webserver?

12:11 gfrlog: "good" and "caches"

12:12 technomancy: cemerick: do you use any of the fancy test output tracking in hudson?

12:12 TimMc: hiredman: That's what I mean by detail.

12:12 cemerick: gfrlog: like those nifty videos of protein synthesis that floated around a while back

12:12 gfrlog: cemerick: I know not of what you speak, but I wish I did.

12:12 cemerick: technomancy: Nope. It's all broken/notbroken for me.

12:13 technomancy: apparently clojure.test can output junit xml, which hudson can consume... I'm curious as to what it does with the data.

12:13 gfrlog: technomancy: digests it?

12:13 cemerick: So I've heard. I've never gone very deeply into test tooling tho.

12:13 gfrlog: extracts proteins and minerals?

12:14 hiredman: technomancy: graphs

12:14 cemerick: I think that's technically expectoration, not digestion.

12:14 gfrlog: :)

12:16 I wish there was a conference dedicated to broadening your computing knowledge base. I would go to an hour-long talk about how file systems work.

12:16 technomancy: hiredman: so it comes down to whether it's easier to tweak clojure.test to emit junit output or graph the output yourself =)

12:16 gfrlog: technomancy: so it CAN output the xml, but not without tweaking?

12:18 technomancy: gfrlog: well... actually it looks like only "lein test" would need tweaking

12:19 gfrlog: technomancy: ah ha. Well if I end up needing it, I'll dive in and take a look then.

12:19 technomancy: gfrlog: the problem is we already monkeypatch the hell out of clojure.test, likely in a number of ways that are likely to not be orthogonal to clojure.test.junit

12:20 gfrlog: oh dear

12:20 technomancy: I should probably come up with some patches to just make clojure.test more flexible

12:21 cemerick: gfrlog: not quite the one I remembered, but not bad, either: http://www.youtube.com/watch?v=41_Ne5mS2ls&feature=related

12:21 More "pop" than "science", but…

12:21 gfrlog: does "monkeypatching" refer to something other than rebinding vars pre-1.3-style?

12:22 technomancy: gfrlog: mostly robert.hooke

12:22 gfrlog: cemerick: this is the best thing that has happened to me today.

12:22 technomancy: though Emacs clojure-test-mode just redefines clojure.test/report after saving it off into another var since it was written long before hooke

12:23 hooke is slightly more composable than redef/binding

12:23 gfrlog: I apparently am woefully underinformed about the capabilities of robert.hooke.

12:24 technomancy: it's basically a functional implementation of elisp's defadvice

12:24 gfrlog: I always wonder how a DNA-reader knows which strand to read

12:24 technomancy: it probably has a PushbackReader

12:25 gfrlog: it's like if you had two binary files where one was the bitwise-complement of the other

12:30 cemerick: gfrlog: Here's a more complete one; the first segment (on replication) was the most interesting IMO http://www.youtube.com/watch?v=4PKjF7OumYo

12:31 gfrlog: cemerick: cool, thanks

12:34 timvisher: anyone know why slime would do something like this? https://gist.github.com/1018899

12:40 technomancy: cemerick: so are you turning fogus and chouser's attribute-your-book-to-the-other-coauthors policy into a tradition? =)

12:41 cemerick: technomancy: it seems way too gentlemanly to do otherwise!

12:41 technomancy: congrats

12:41 cemerick: Christophe and Brian aren't big twitterers though, so people may just think I'm a stalker or something.

12:41 thanks

12:41 long time coming

12:42 I really just want to get what we have done *now* out there. I botched things a bit, so what's there is stale. That'll be fixed pronto, tho.

12:43 technomancy: planning on timing it with the next release like stu did?

12:44 cemerick: Hardly a plan, but it's worked out well. I really didn't want to walk the 1.2/1.3 line like chouser and fogus had to (at least to some extent)

12:44 The real objective is to have it in print for the Conj.

12:44 clojurebot: Roger.

12:45 cemerick: clojurebot: you'll pass the Turing test yet.

12:45 clojurebot: ,(let [testar (fn [x y] (if (= (reduce + (filter odd? (range 0 x))) y) (str y " is an")) )] (testar 10 25))

12:52 timvisher: anyone know why slime would do something like this? https://gist.github.com/1018899

13:00 manutter: timvisher: Sorry, I got called away

13:00 So it looks like something is interrupting the network connection between swank server and your slime repl

13:02 This started happening when you changed your lib?

13:02 [mattb]: (doto (JFrame.) (.add (JLabel. "Hello")) .pack .show) <-- is the period in the function names part of the name? why would )) pack show) be invalid?

13:02 manutter: Have you got conflicting jar files in your local repo perhaps?

13:02 mattb: the leading period means you're calling a Java method

13:03 [mattb]: is that a macro to the (. xxx) form?

13:03 manutter: right

13:03 [mattb]: gotcha

13:03 manutter: ,(macroexpand-1 '(.method object))

13:03 clojurebot: (. object method)

13:03 [mattb]: heh, cool

13:04 manutter: timvisher: see if you have multiple copies of your lib in the .m2 directory in your home directory

13:05 timvisher: what OS are you on, btw?

13:56 redinger: cemerick: Having it in print for the Conj is an awesome goal!

13:56 Everyone should strive to have more stuff ready for the Conj

13:56 Raynes: redinger: Unfortunately, my book's soft deadline *is* November, so there isn't really any chance of it being in print by then.

13:57 cemerick: redinger: it's either that or have it in print three weeks _after_ the conj (or whatever), so we'll just get it done before. ;-)

13:58 redinger: Raynes: Print your own early release copy? :)

13:58 cemerick: redinger: Good point.

13:58 Raynes: The book will probably be finished by the Conj though, so yes, I could probably do something.

13:58 And since I'm actually free to do whatever I want with my own version of the book, I could actually do that.

13:59 cemerick: Raynes: Nifty; I'll roll you into my authors roundtable proposal then (unless you're not interested).

13:59 Raynes: Go for it. :)

14:02 cemerick: What is that proposal?

14:03 cemerick: Raynes: I thought it'd be fun to have an author's roundtable at the Conj. Get all the authors "up there", be asked questions from attendees, debate random topics, whatever.

14:03 Might be a good thing for the end of the day, start passing around the drinks, etc.

14:03 Raynes: Sounds like a fun idea.

14:04 cemerick: Stu set that precedent last time, so I'm expecting a sidebar in the conference room this time around. ;-)

14:10 gfrlog: question for author's panel: which clojure book is the best?

14:11 gko: Mannings?

14:11 newer

14:12 bartj: is there a diff b/w Sequential and ISeq ?

14:12 ,(doc seq?)

14:12 clojurebot: "([x]); Return true if x implements ISeq"

14:12 bartj: ,(doc sequential?)

14:12 clojurebot: "([coll]); Returns true if coll implements Sequential"

14:12 * technomancy kinda wishes those interfaces were documented

14:12 gfrlog: ,(seq? #{})

14:12 clojurebot: false

14:13 gfrlog: ,(seq? [])

14:13 clojurebot: false

14:13 gfrlog: ,(sequential? [])

14:13 clojurebot: true

14:13 bartj: for eg: (sequential? [1 2]) returns true

14:13 but, (seq? [1 2]) returns false

14:13 amalloy: &(map (juxt seq? sequential?) [[] () {} #{}])

14:13 sexpbot: ⟹ ([false true] [true true] [false false] [false false])

14:13 bartj: gfrlog, you type fast

14:13 hiredman: right a vector is not a seq

14:13 gfrlog: seqable? would return a third set of things

14:14 hiredman: but it is a sequential datastructure

14:14 but maps are not

14:14 technomancy: sequential means seqable and ordered, I think

14:14 gfrlog: so seq /subset sequential /subset seqable

14:14 is that fair?

14:14 hiredman: technomancy: just ordered, I believe

14:14 notation is not clear

14:15 technomancy: I guess everything ordered is seqable, so maybe that's not a real distinction

14:15 Raynes: gfrlog: Well shit, I'll answer that one: The Joy of Clojure.

14:15 My plan is perfect: I'm not trying to beat The Joy of Clojure, but agument it.

14:16 Or compliment it. Whichever is appropriate.

14:16 gfrlog: I just realized I don't know who the target audiences of the various books are

14:16 Raynes: meetclj.raynes.me

14:16 That wall of text might be helpful.

14:16 cgay_: Raynes I think you mean complement.

14:17 Raynes: cgay_: So do i.

14:17 I*

14:17 cgay_: Although complimenting it would be nice too.

14:17 gfrlog: compl[ie]ment?

14:18 Raynes: what are the beginning and end of clojure?

14:20 manutter: ,((juxt first last) "clojure")

14:20 clojurebot: [\c \e]

14:20 gfrlog: C is for clojure, that's good enough for me; OH, ...

14:21 ,((juxt first last) "cookie")

14:21 clojurebot: [\c \e]

14:21 Raynes: gfrlog: Well, the book begins with an overview and then an introduction to functional programming and ends with actual development and interactive development techniques, if that's helpful.

14:22 fliebel: cat /usr/share/dict/words | grep ^c.*e$

14:23 gfrlog: fliebel: :)

14:25 fliebel: Quite a few interesting words that are the same as Clojure, start [and] end.

14:26 This is where it gets interesting, for finding project names: cat /usr/share/dict/words | grep ^c.*j.*e$

14:26 gfrlog: I did not know that cloture is a word

14:26 manutter: gfrlog: not into politics eh? :)

14:27 gfrlog: fliebel: or ^c.*ure$

14:27 manutter: Not that level of detail I guess

14:27 gko: ,(repeat 6 " ")

14:27 clojurebot: (" " " " " " " " " " " ")

14:27 gko: ,(str (repeat 6 " "))

14:27 clojurebot: "clojure.lang.LazySeq@6d534741"

14:27 Raynes: &(apply str (repeat 6 " "))

14:27 sexpbot: ⟹ " "

14:27 gfrlog: ,(pr-str (repeat 6 " "))

14:27 clojurebot: "(\" \" \" \" \" \" \" \" \" \" \" \")"

14:27 fliebel: &(doc prstr)

14:27 sexpbot: java.lang.Exception: Unable to resolve var: prstr in this context

14:27 fliebel: hm

14:28 manutter: "Cloture: when a group of politicians gets together and votes on whether or not the govt would run more smoothly if it used functional programming techniques."

14:28 pjstadig: please. for the love of your fellow man, do not name anymore projects with a clojure pun.

14:28 i beg you

14:28 it must stop

14:28 gfrlog: pjure?

14:28 Raynes: pjstadig: People still do that?

14:28 gfrlog: erujolc?

14:29 fliebel: &(pr-str (repeat 6 " "))

14:29 sexpbot: ⟹ "(\" \" \" \" \" \" \" \" \" \" \" \")"

14:29 gfrlog: manutter: or not that level of vocabulary at least

14:30 On a completely unrelated note, is there an elegant way to generate a finite list with iterate?

14:30 ,(iterate #(if (neg? %) (inc %)) -10)

14:30 clojurebot: (-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 ...)

14:30 fliebel: pjstadig: Hm, I agree the *jure thing is silly, but more far-fetched things like cajole are okay by me.

14:31 gfrlog: ,(iterate #(if (neg? %) (inc %)) -3)

14:31 clojurebot: java.lang.NullPointerException

14:31 gfrlog: I wonder how rare the cloJure consonant is in english

14:32 ,(take-while identity (iterate #(if (neg? %) (inc %)) -3))

14:32 clojurebot: (-3 -2 -1 0)

14:32 gfrlog: that's what I end up with and that feels awkward

14:33 redinger: We joked around with the Cloture name for the clj-soy stuff, to see how many times we reference the homophones

14:33 or rather, could reference

14:34 manutter: ,(into [] (iterate #(if (neg? %) (inc %)) 3)

14:34 clojurebot: EOF while reading

14:35 manutter: ,(into [] (iterate #(if (neg? %) (inc %)) 3))

14:35 clojurebot: java.lang.RuntimeException: java.lang.NullPointerException

14:35 gfrlog: manutter: use -3?

14:35 manutter: silly me, can't type

14:35 ,(into [] (iterate #(if (neg? %) (inc %)) -3))

14:35 clojurebot: java.lang.RuntimeException: java.lang.NullPointerException

14:35 manutter: well, that's obviously not it

14:35 gfrlog: yeah, (into []) is going to consume as far as it can

14:36 manutter: There was some function I was just using that accumulated only the non-nil values into a seq

14:36 gfrlog: I feel like even (take-while identity) might fail sometimes? At least it still feels shakey to have an underlying dangerous seq

14:36 manutter: oh, keep

14:36 gfrlog: yeah, keep is (filter identity (map f coll)) right?

14:36 manutter: ,(keep (iterate #(if (neg? %) (inc %)) -3))

14:36 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$keep

14:36 gfrlog: if the underlying seq is still dangerous, most seq functions won't help

14:37 manutter: burf, what was it then

14:37 gfrlog: manutter: it needs a map fn as well, so I'm not sure it applies here

14:38 manutter: yeah, it wasn't keep I was thinking of

14:38 I'm sure I just used it tho, whatever it was

14:38 gfrlog: I'd be surprised if it exists, since it'd just be sugar for (filter identity ...)

14:39 at least in core

14:39 manutter: ,(doc some)

14:39 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

14:40 technomancy: there's talk of a one-arity version of filter that uses identity as its predicate

14:40 seems like a pretty clear win to me

14:40 gfrlog: technomancy: I love it

14:41 technomancy: gfrlog: http://dev.clojure.org/jira/browse/CLJ-450

14:42 gfrlog: hmm. I like every? as well.

14:42 manutter: ,(keep (fn [x] (iterate #(if (neg? %) (inc %))) -3)

14:42 clojurebot: EOF while reading

14:42 manutter: ,(keep (fn [x] (iterate #(if (neg? %) (inc %))) -3))

14:42 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$keep

14:43 manutter: ,(keep (fn [x] (iterate #(if (neg? %) (inc %)))) -3)

14:43 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

14:43 gfrlog: manutter: I don't think that's how keep works. you gotta give it a seq as 2nd arg

14:43 like I said, I don't think you can bend keep to be applicable here :)

14:43 amalloy: &(take-while #(< % 10) (iterate inc 1))

14:43 sexpbot: ⟹ (1 2 3 4 5 6 7 8 9)

14:44 amalloy: keep and filter ain't ever gonna work for you

14:44 manutter: yeah, trying to work in 2 windows at once, not really concentrating on either, I gotta get back to work...

14:45 gfrlog: amalloy: the original question deals with using iterate when the fn will eventually return nil

14:45 joegallo: http://clojure-log.n01se.net/date/2008-12-02.html

14:45 gfrlog: and calling (f nil) will break

14:45 joegallo: oops, wrong channel, ignore me

14:45 amalloy: so, take-while (complement nil?)

14:45 gfrlog: amalloy: right, that's how I do it. 1) it seems awkward, and 2) it seems dangerous

14:46 since the underlying lazy-seq is only not exploding because of laziness

14:46 i.e., can I be 100% sure that it won't try to compute one extra value?

14:46 amalloy: uhh…when you write a for loop in java, it only stops at the end because you tell it to

14:47 gfrlog: yes.

14:51 bartj: gfrlog, I thought keep was (remove nil? (map f coll))

14:51 amalloy: it is

14:52 gfrlog: bartj: what'd I say? filter identity? almost the same thing :)

15:19 Moominpapa: '(+ 1 1)

15:19 ,(+ 1 1)

15:19 clojurebot: 2

15:28 amalloy: Moominpapa: (inc 1) is much more efficient

15:29 fliebel: $source inc

15:29 sexpbot: inc is http://is.gd/7yWaho

15:32 [mattb]: what's the most idiomatic way to get the keys of all elements of a hashmap where the value is greater than x? so far I have:

15:32 (map first (filter #(> (last %) 1) {"foo" 1 "bar" 2 "baz" 4}))

15:33 seems like excessive mapping though

15:33 fliebel: amalloy: Care to explain why inc is faster?

15:33 amalloy: [mattb]: looks good to me. i'd write second instead of last

15:33 fliebel: it's not afaik. i assumed that my suggestion of a way to optimize 1+1 would be taken as a joke

15:34 or you could be a little clearer, and use key/val instead of first/second

15:34 fliebel: amalloy: Hm, I was thinking it might be doing something more close to the metal, since it's not written in Clojure.

15:35 amalloy: fliebel: sure, it might be

15:36 like i said, i don't really know anything here. it just seemed like a good opportunity for some poorly-considered optimization

15:37 [mattb]: actually what i like least about your example is the use of strings instead of keywords as map keys

15:38 [mattb]: oh?

15:38 amalloy: i mean, if your map happens to have strings for some reason, sure whatever

15:38 but if you're building a map yourself or for an example, {:foo 1 :bar 2 :baz 4} is nicer

15:38 [mattb]: prefer :foo :bar?

15:38 gotcha

15:39 amalloy: [mattb]: the thing keywords get used for most often is map keys

15:39 [mattb]: ahh

15:39 amalloy: and they're very efficient at it, as well as being convenient for some other reasons

15:40 but, lunchtime. more self-important nonsense about keywords when we return

15:40 [mattb]: :p

15:44 gfrlog: mattb: did you just make a pun with a colon?

15:49 [mattb]: haha

15:49 why would (.in System) be invalid?

15:49 e.g. (Scanner. (.in System)) compared to (Scanner. System/in)

15:51 gfrlog: mattb: (System/in) I think

15:51 or rather w/o the parens

15:51 oh wait

15:51 [mattb]: yeah System/in is correct, but not sure why .in System is wrong

15:52 gfrlog: clearly I only read the left half of your statement :)

15:52 [mattb]: haha

15:52 gfrlog: .in is for methods I believe

15:52 System/in is a public field

15:52 [mattb]: k

15:52 access vs message sending

15:52 gfrlog: more or less

15:52 if you're used to ruby it's a new distinction

15:54 [mattb]: print apparently doesn't flush while println does, hmph

15:54 stuartsierra: The System/in form is preferred for static fields.

15:55 TimMc: ,(. System in)

15:55 clojurebot: #<BufferedInputStream java.io.BufferedInputStream@bdc6a3>

15:55 gfrlog: ,(class (. System in))

15:55 clojurebot: java.io.BufferedInputStream

15:55 TimMc: ,(.in System)

15:55 clojurebot: java.lang.IllegalArgumentException: No matching field found: in for class java.lang.Class

15:55 gfrlog: ,(class (.in System))

15:55 clojurebot: java.lang.IllegalArgumentException: No matching field found: in for class java.lang.Class

15:56 TimMc: Fascinating.

15:56 Doesn't the invalid form macroexpand to the valid form? :-/

15:56 gfrlog: always something else to know...

15:57 kephale: hrm… #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: >

15:57 gfrlog: .in is a macro? can't be a normal macro I guess...maybe it could be called a "macro schema"

15:57 TimMc: ,(macroexpand-1 '(.foo Bar))

15:57 clojurebot: (. Bar foo)

15:58 gfrlog: (defmacro #".(\S+)" ...)

15:58 TimMc: No, . is a macro-y thing.

15:58 haha

16:00 Chousuke: ,(macroexpand '[(System/in) (.in System)])

16:00 hm

16:00 no reaction :(

16:00 &(macroexpand '[(System/in) (.in System)])

16:00 sexpbot: ⟹ [(System/in) (.in System)]

16:00 clojurebot: [(System/in) (.in System)]

16:00 Chousuke: wow

16:00 lag

16:00 gfrlog: clojurebot's roommate is using bittorrent?

16:02 ohpauleez: haha

16:07 [mattb]: is there a better way to repeat an argument for mapping than (cycle [:x])?

16:08 gfrlog: ,(take 20 (repeat :x))

16:08 clojurebot: (:x :x :x :x :x :x :x :x :x :x ...)

16:08 [mattb]: repeat, thanks

16:08 gfrlog: no probalo

16:08 TimMc: ,(find-doc #"repeat")

16:08 clojurebot: -------------------------

16:08 clojure.contrib.seq/fill-queue

16:08 ([filler-func & optseq])

16:08 filler-func will be called in another thread with a single arg

16:08 'fill'. filler-func may call fill repeatedly with one arg each

16:08 time which will be pushed onto a queue, blocking if needed until

16:08 this is possible. fill-queue will return a lazy seq of the values

16:08 TimMc: oh shit

16:08 clojurebot: filler-func has pushed onto the queue, blocking i...

16:08 [mattb]: haha

16:08 TimMc: Good, it has a line limit.

16:08 [mattb]: should probably make that pm

16:09 TimMc: yeah

16:09 I forgot how verbose find-doc tends to be.

16:25 tufflax: How do I use an Enum in a Java class? VertexBuffer.Type is the enum, and I will have to pass VertexBuffer.Type.Position for example to a method

16:25 [mattb]: how can I have map ignore nil values? e.g. (map match-val all-vals (repeat val)), where match-val returns nil if it doesn't match

16:26 gfrlog: mattb: if I understand correctly, you'll have to wrap that in (remove nil? ...)

16:27 [mattb]: no better way to do it? I figure map may not be the best way to apply a comparator to a collection

16:27 gfrlog: mattb: but there's probably a cleaner way to do what you're doing anyhow

16:27 [mattb]: yeah

16:27 gfrlog: are you trying to transform AND filter your collection, or just filter it?

16:28 [mattb]: FILTER

16:28 that's the name of the function :D

16:28 still not remembering my functional idioms

16:28 gfrlog: :)

16:29 stuartsierra: `keep` removes nils too

16:29 gfrlog: yeah, if you're going to transform as well, then keep is a good shortcut

16:29 lostpass: is it possible to view the grpah of issues until 1.3 in jira?

16:29 [mattb]: Usage: (filter pred coll) <-- how can I curry pred so it calls it with an argument?

16:29 gfrlog: mattb: ##(doc partial)

16:29 sexpbot: ⟹ "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

16:30 [mattb]: sweet thanks

16:30 lostpass: nvm i found it

16:30 gfrlog: if you need to partially apply some argument other than the first one[s], then you'll probably just have to make a fn-literal

16:31 Moominpapa: Stupid question, if you create a lazy-sequence and evaluate the first element, does "rest" remain unevaluated or can chunking evaluation occur?

16:32 [mattb]: filter + partial worked beautifully

16:32 stuartsierra: Moominpapa: chunks will get evaluated as chunks.

16:33 e.g. (first (map foo (range))) evaluates foo 32 times.

16:34 tufflax: did anyone know the answer to my question? :)

16:34 Moominpapa: ok, so I need to be careful putting blocking io into a sequence...

16:34 stuartsierra: tufflax: enums are normal Java classes.

16:35 Nested classes are represented by their binary names, OuterClass$InnerClass

16:36 Moominpapa: Sequences you create yourself with lazy-seq and cons are not chunked, but map/range/filter etc. all do chunking by default.

16:36 technomancy: I thought map was orthogonal to chunking

16:37 Moominpapa: Looking at the code...

16:38 Looks like map respects chunks if they're there, but doesn't chunk something unchunked.

16:41 gfrlog: I wonder what makes chunking faster for things like (range)

16:41 Moominpapa: Actually, this appears to be generally true: you don't need to worry about chunking if you don't do something likely to create a chunk.

16:41 [mattb]: oh fark

16:43 alright, I'm trying to filter a hashmap for keys that match some match function, return only those that do, then modify those values in the original hashmap

16:44 gfrlog: tracking so far

16:44 [mattb]: so far I'm using (filter (partial match-fun search-val) thehashmap), where match-fun returns the item that matches the search-val

16:45 but filter/partial passes the entire hash map to the match-fun

16:45 rather than mapping the function to it

16:45 gfrlog: mattb: I would expect it would pass key-val-pairs to the match-fn

16:46 [mattb]: it apparently passes a list of them

16:46 gfrlog: a list of pairs?

16:46 [mattb]: yeah

16:46 gfrlog: that don't sound right

16:47 ,(filter (comp pos? first) {0 3 -4 5 12 4 484 832})

16:47 clojurebot: ([12 4] [484 832])

16:47 [mattb]: http://pastebin.com/WuC5uvYr

16:48 I would expect match-ant to receive [ant key-val-pair], match ant to the key, and return the key if equal

16:48 but it returns the entire key value pair

16:49 gfrlog: you're never separating the key-val-pair

16:49 item will be bound to the pair

16:49 oh wait

16:49 yes you are :-|

16:49 [mattb]: :p

16:49 gfrlog: okay anyhow

16:50 the part you've left out is your all-ants object

16:50 [mattb]: (def all-ants {:ppyy 1 :pygp 2})

16:51 gfrlog: I don't see any problem with it. Maybe your repl has stale functions lying around?

16:52 [mattb]: user=> (find-ant :ppyy)

16:52 ([:ppyy 1])

16:52 gfrlog: that there is what I would expect

16:52 [mattb]: hrmph

16:53 gfrlog: but you wouldn't?

16:53 I think I know what you're misunderstanding

16:53 [mattb]: (when (= (first item) ant)

16:53 (first item))) <-- I thought this would return only the :ppyy

16:53 gfrlog: it does

16:53 but filter does not give you the result of match-ant

16:53 it gives you the original value

16:53 [mattb]: ............

16:53 OH.

16:53 hahaha crap

16:53 gfrlog: :)

16:54 [mattb]: duh, the doc for filter just says "return true"

16:54 brilliant

16:54 so all of that aside, is the a more concise way to do what my original statement was?

16:54 gfrlog: yes

16:54 your code has a few fun refactoring opportunities

16:55 first of all, it looks like you don't care about the values of all-ants, right?

16:55 for that matter, it seems like (find-ant :foo) is either going to return :foo or return nil, is that correct?

16:55 [mattb]: I do; after I find matching keys (which will match a more elaborate pattern than just =), I need to modify their values

16:55 and maintain the rest of all-ants

16:58 gfrlog: mattb: so if you have a key and you're just interested in whether the all-ants map has the key, you can use ##(doc contains?)

16:58 sexpbot: ⟹ "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or... http://gist.github.com/1019761

16:58 gfrlog: you can do that without looping through the whole hashmap-seq

16:59 I think that's what the code you have boils down to

17:02 raek: [mattb]: another approach to update some of the entries of a map: (into (empty m) (for [[k v] m] (if (pred? k) [k (update v)] [k v])))

17:04 gfrlog: raek: do you think reduce might be more efficient? particularly if the to-be-updated values are sparse?

17:05 [mattb]: gfrlog: mattb: so if you have a key and you're just interested in whether the all-ants map has the key, you can use ##(doc contains?) <-- the key is actually a pattern, and there could be multiple keys that match it

17:05 sexpbot: ⟹ "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or... http://gist.github.com/1019774

17:06 [mattb]: shutup sexpbot

17:06 raek: gfrlog: reduce instead of what? into is just reduce with conj...

17:07 gfrlog: mattb: okay; in that case (filter) is good, but I think filtering over the keys would be simpler than the pairs, if you don't need the values to do the filtering

17:07 [mattb]: you can do that? :(

17:07 gfrlog: mattb: (filter pred (keys all-ants))

17:07 [mattb]: haha

17:08 geeze that's too easy

17:08 gfrlog: sometimes it is

17:09 raek: I mean from the perspective of memory allocation

17:09 using (into {}) will reassemble the map from a seq

17:09 raek: gfrlog: ah, you mean to only assoc when the thing is to be changed?

17:10 zakwilson: I've been using Compojure for a couple projects, but I'm starting to get the feeling I'm missing out on something by using that instead of Moustache. Can someone with experience using both comment?

17:10 gfrlog: exactly

17:10 raek: yeah, the number of allocations will definitely be fewer

17:10 gfrlog: not something to bother a beginner about of course, so I don't know why I brought it up :-/

17:19 amalloy: [mattb]: if you didn't want sexpbot to eval the doc form, don't put ## in front of it :P

17:19 [mattb]: lol

17:19 gfrlog: amalloy: he was quoting me

17:19 ##(println "Shutup self")

17:19 sexpbot: ⟹ Shutup self nil

17:22 gfrlog: in my terminal client, all of sexpbot's responses begin with "M-W"

17:23 [mattb]: best way to check if a string contains a character?

17:23 hiredman: http://www.thelastcitadel.com/images/rhickey.png ripe for tshirting

17:23 [mattb]: I only see contains? for maps

17:24 gfrlog: ,(contains? (set "hooha") \h)

17:24 clojurebot: true

17:24 hiredman: ~jdoc String

17:24 clojurebot: Cool story bro.

17:25 gfrlog: another option would involve one of the substring functions

17:25 hiredman: clojurebot: you suck

17:25 clojurebot: I don't understand.

17:25 hiredman: http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html

17:25 ^- please read

17:25 gfrlog: clojurebot: I think you make valuable contributions

17:25 clojurebot: No entiendo

17:25 [mattb]: and for a keyword, (set (str :hooha))?

17:26 gfrlog: you can use name instead of str to omit the leading colon

17:26 but otherwise yeah

17:26 we should also say that if you're testing a keyword for containing a character, you're doing weird stuff :)

17:26 [mattb]: haha

17:26 wildcard matching keys

17:27 arohner: I have some code that walks a tree, and sometimes adds metadata to nodes. It works perfectly if I use clojure.walk/postwalk, but I get no metadata if I use clojure.walk/prewalk. Anyone know why?

17:27 [mattb]: e.g. p?yy should match ppyy and pgyy

17:27 :ppyy :pgyy rather

17:27 Cozey: Good evening. is there a smarter way to write: (map #(do [%1 %2]) (range 1 (count lst)) lst)

17:27 [mattb]: probably still a way better way to do this

17:27 hiredman: arohner: walk sucks, I think, but that is not really a useful answer

17:27 Cozey: or in general to iterate over a seq with a variable bound to current index ?

17:28 raek: [mattb]: then strings and regexes might be a plausible alternative

17:28 gfrlog: mattb: I think if you're keeping that much info in your keywords, you should use a different data structure that more naturally represents the data

17:28 [mattb]: it's just a search function

17:28 arohner: hiredman: why does walk suck?

17:28 raek: keys don't have to be keywords. they can be of any type

17:28 [mattb]: aye

17:28 technomancy: arohner: it's been publicly disowned by its author

17:28 gfrlog: mattb: yes, but normally keywords are used like enums -- human-meaningful values

17:29 [mattb]: ah

17:29 amalloy: Cozey: (map-indexed vector lst)?

17:29 hiredman: arohner: it is slow and not really maintained and has bugs

17:29 gfrlog: mattb: if you explain what your keywords mean, we might be able to suggest something simpler

17:29 Cozey: amalloy: thank You!

17:31 [mattb]: I'm mapping a four letter code to a scalar; the user types the four letter code, substituting ? for any unknown letters, and then specifies the scalar to update the collection with

17:31 if the wildcarded code matches more than one key then it lists which ones match

17:32 raek: I would use strings as keys here

17:32 gfrlog: yeah. If you have to work with the codes like that, strings make sense to me

17:32 [mattb]: k

17:32 raek: and keywords for named values that only programmers see

17:32 [mattb]: I figured as well, but someone said to prefer keywords :(

17:32 gfrlog: hiredman: you were suggesting String#indexOf?

17:33 amalloy: String.contains

17:33 gfrlog: mattb: yeah, that's the initial advice

17:33 oh right

17:33 I got sidetracked thinking he had a Character

17:34 but indexOf isn't any better in that case anyhow

17:34 raek: [mattb]: if the keys are just named values without meaningful internal structure (which seems to be the most common case), then keywords are preferred

17:48 tufflax: I have made an array of Vector3fs, and printing that array in the repl shows that it is an Object array. But I'm trying to pass it to a method that takes a Vector3f array, and I get an error. Can the type be the problem? How do I cast/hint that it is actually a Vector3f array?

17:49 amalloy: (into-array Vector3f (…some seq of vectors))

17:49 tufflax: ok, thanks

17:49 amalloy: eg, ##(into-array ["test" "thing"])

17:49 sexpbot: ⟹ #<String[] [Ljava.lang.String;@38d6bc>

17:52 [mattb]: user=> (find-ant "py?p")

17:52 ("pygp") <-- win

17:52 thanks for the help gfrlog

17:52 clojure is awesome!

17:58 technomancy: it is true

17:58 amalloy: &(= '(clojure awesome))

17:58 sexpbot: ⟹ true

17:58 [mattb]: haha

17:58 seancorfield: Q about duck-stream/slurp*

17:59 it looks like the only difference between that and core/slurp is the former uses a BufferedReader?

17:59 amalloy: my understanding is that duck-streams are about as old as cobol. is that accurate?

17:59 seancorfield: lol... yeah, looks that way

17:59 amalloy: probably best to stay away then

17:59 seancorfield: so is there a modern equivalent to slurp* ?

17:59 hiredman: I have a "Teach Yourself COBOL in 21 DAYS" book holding up my monitor

18:00 amalloy: seancorfield: what's wrong with core/slurp?

18:00 hiredman: ,(doc slurp)

18:00 clojurebot: "([f & opts]); Reads the file named by f using the encoding enc into a string and returns it."

18:00 seancorfield: i found contrib.io/slurp* as well which seems identical to contrib.duck-streams/slurp*

18:01 is there any specific reason to not use core/slurp when this code (congomongo) specifically uses slurp* ?

18:02 basically i'm trying to get congomongo running on clojure 1.3.0 so i'm modernizing the code...

18:02 raek: seancorfield: strange... duck-streams/slurp* uses a buffered reader too...

18:02 seancorfield: raek: yeah, duck-streams/slurp* and io/slurp* seem identical

18:02 raek: maybe the docstring reflects what used to be the case before clojure.java.io was introduced

18:03 * technomancy recalls opening an issue to fix slurp's docstring

18:03 raek: seancorfield: clojure.java.io replaces both clojure.contrib.duck-streams and clojure.contrib.io

18:03 technomancy: actually I think that one even got applied

18:03 anyway, it's misleading in 1.2.0, which is what clojurebot is running

18:04 raek: I think clojure.core/slurp was improved when clojure.java.io was added

18:04 seancorfield: hmm, let me look at clojure.java.io then...

18:04 amalloy: clojure.java.io is pretty sweet

18:06 raek: seancorfield: clojure.core/slurp passes its argument to clojure.java.io/reader, so the options that are specified in the docs for the io namespace can be used for slurp too

18:07 seancorfield: ah...

18:07 raek: (so you can pass it anything "streamish", and library authors can extend the IOFactory to other types too)

18:08 seancorfield: looks like the default is a BufferedReader anyway which is what the congomongo test needs...

18:08 or at least what slurp* actually used to do :)

18:08 raek: someone said something about "when clojure.java.io was introduced slurp got superpowers" :-)

18:08 seancorfield: ok, congomongo no longer depends on contrib 1.2.0 - yay!

18:09 tests still pass too which is encouraging...

18:09 raek: cool!

18:16 amalloy: seancorfield: nice

18:16 seancorfield: and it runs on clojure 1.3.0 now... sweet!

18:17 awesomeness... now i can get back to work and actually _use_ the blasted library!

18:20 hmm, still some 1.3.0 incompatibilities in the unit tests :( my work is apparently not yet done

18:20 raek: what is a typical usage for a document-oriented database (like MongoDB, if I understood this correctly)?

18:26 seancorfield: raek: well, we plan to use it for storing events (event sourcing), member profiles and probably logging

18:27 those three types of data in our system have rather 'flexible' schemas, to say the least so it's a pita to use rbdms with them

18:45 it seems clojure 1.3.0 pays much more attention to arglists metadata than 1.2.x!

18:45 congomongo had ^{:arglists '(arg1 arg2)} which is fine on 1.2.x but needs to be ^{:arglists '([arg1 arg2])} on 1.3.0

18:46 Somelauw: Hi, is there any way to add a docstring to a var without metatags. So something like (def "this var handles shizzle" handle 5)?

18:47 Right now it is (def #^{:doc "my documentation} varname value)

18:47 which looks a bit verbose

18:49 seancorfield: in 1.3.0 you can just do (def "docstring" varname value)

18:50 Somelauw: ,(def "bye" v 5)(doc v)

18:50 clojurebot: DENIED

18:51 raek: I thought it was (def name "docstring" value)

18:52 Somelauw: another alternative is to use defvar from contrib (http://clojuredocs.org/clojure_contrib/clojure.contrib.def)

18:54 Somelauw: It seems like I am using 1.2.0. I am using cake.

18:57 But maybe I can tell cake to upgrade to 1.3 or something.

18:59 raek: Somelauw: if you work in a project, you set that in your project.clj

19:00 Somelauw: control over the versions and libraries to be used is the reason you eventually need to develop in a project

19:01 Somelauw: I am working in a project. I will try what you said. Preferably I want it to always take the latest clojure version whenever I start a new project.

19:02 raek: 1.3.0 is still under development

19:03 the most recent release is 1.2.1

19:03 Somelauw: Ah, I see they are alpha releases.

19:03 pdk: what exactly has 1.2.1 changed while we're at it

19:04 Somelauw: Okay, thanks. I think I will stick to 1.2.1 and use the metadata method for now.

19:05 raek: pdk: https://github.com/clojure/clojure/blob/1.2.x/changes.txt

23:58 technomancy: ever wish you could destructure in catch? https://github.com/technomancy/data-conveying-exception

Logging service provided by n01se.net