#clojure log - Jan 29 2012

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

0:01 jweiss: jeremyheiler: just out of curiosity, how would that work? if you don't know the names you want to bind in advance, what names would you use inside your function?

0:02 muhoo: what is a "promise" in clojure?

0:03 i mean, i did ##(doc promise) but i don't understand it

0:03 lazybot: ⇒ ------------------------- clojure.core/promise ([]) Alpha - subject to change. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block, unless the variant of deref with timeout is... https://refheap.com/paste/468

0:03 jweiss: muhoo: it's a way of connecting two unrelated pieces of code, possibly in different threads, so that one can deliver a value to the other

0:03 muhoo: jweiss: cool, thanks

0:04 kind of like a slot/signal in gui toolkits?

0:05 jweiss: muhoo: i use in in my test-running harness - when the test starts, it creates a promise object in a result map. the reporting derefs the promise, which waits forthe test to complete before it reads the result

0:05 the reporting mechanism doesn't need to know anything about how orwhen the test is run

0:05 it just gets the result when it's available

0:06 muhoo: async communications? nice.

0:06 jweiss: passing a promise to a piece of code is saying "here, eventually this will contain what you need, call deref when you're ready for it"

0:07 muhoo: when you're ready for it, or when it is ready for you?

0:07 what if the data isn't ready yet?

0:07 and you call deref on the promise?

0:07 napping: blocks

0:08 as mentioned in the pasted docs

0:08 muhoo: oh, yes it does, thanks.

0:08 napping: (and the deref-with-timeout)

0:09 muhoo: oh cool, realized? is how you check to see if there's data

0:09 it's like select/read/filedescriptor stuff

0:10 but instead of file descriptors, it's vars. nifty.

0:37 jeremyheiler: oh yeah https://refheap.com/paste/469

0:40 muhoo: jeremyheiler: it is ALIIIIVE!

0:43 jeremyheiler: haha

0:45 Now I have to think about important things, like consistancy. For example, should the command functions include the terminating \r\n, or should that be automatically appended by issue-command. The issue-message command does append the terminating sequence, but it's more complicated.

0:47 muhoo: yep also api consistency

0:48 jeremyheiler: definitely

0:48 muhoo: not that there's anything wrong without wrapping smtp thinly and lettting the user do what they want with it

0:49 but it' be nice to have stuff like (send-mail from to subject message) , etc

0:49 jeremyheiler: i know ;-) the interesting part will be actually creating the high level functions.

0:50 and controlling the flow of the conversation between the client and server

0:50 muhoo: sounds like a good project

0:50 jeremyheiler: and also being considerate of any possible smtp extension

0:50 (which is what the low level api is mostly for i suppose)

0:51 yeah, im already having fun

1:06 yoklov: how do you get around immutability of, maps for instance, in clojure if you want to make cyclic data

1:06 dnolen: you can emit pretty darn efficient JavaScript w/ ClojureScript ...

1:08 yoklov: you could use a reference type, but it's generally frowned upon from what I can tell.

1:08 Twey: yoklov: You can use laziness.

1:08 yoklov: how can i use laziness?

1:09 Twey: Oh, beg your pardon, apparently not.

1:09 yoklov: haha, thats okay

1:09 Twey: In Haskell you can do something like: let m = Map.fromList [(0, m)] in m

1:10 Er, not that that would typecheck, but in general you can do that sort of thing

1:10 yoklov: right

1:10 Twey: StackOverflow seems to indicate that the equivalent is not valid in Clojure

1:11 And that there is no nice way to do it

1:11 yoklov: damn, that sucks.

1:11 Twey: http://stackoverflow.com/questions/4580865/how-can-one-create-cyclic-and-immutable-data-structures-in-clojure-without-ext

1:51 muhoo: meaning, a ring buffer?

1:51 how about a vector then?

2:24 nodename: Hi, problem in ClojureScript One project: "lein repl" gives NoSuchMethodError: clojure.lang.KeywordLookupSite.<init>(ILclojure/lang/Keyword;)V ... clues anyone?

2:25 muhoo: i have not yet been able to get clojurescript one working

2:26 regular clojurescript, yes, but not the one variety

2:26 nodename: muhoo: same kind of problem?

2:27 muhoo: /me checks

2:27 actually, i got FileNotFoundException Could not locate cljs/closure__init.class or cljs/closure.clj on classpath: clojure.lang.RT.load (RT.java:430)

2:30 nodename: I think this is the answer to my question: http://clojure-play-framework.blogspot.com/2012/01/re-new-version-of-clojurescript-one.html

2:31 muhoo: seems to me you just need to set your classpath correctly (or is lein supposed to take care of that?)

2:33 muhoo: i dunno

2:33 i shoudl note that lein boostrap fails too

2:35 https://refheap.com/paste/470

2:38 git fuckup?

2:38 error: The requested URL returned error: 403

2:39 ah, https: does NOT work for me with git. i need to use git://

3:00 nodename: i got it, it works!

3:08 this was required: https://refheap.com/paste/471

3:15 i should ask when more people aare here, but, would it be of any value to have a bot that posts a notice here when a new message comes in on the mailing list, or a bug gets posted, or some such thing?

3:19 _ulises: morning folk

3:28 muhoo: it strikes me now that the rich-client user interfface problem that cljs is trying to solve, was originally intended to be solved by... java applets!

3:28 back in like 1998 or so

3:28 then when that didn't work out, by xul, some years later.

4:18 vimja: is there a good cryptography library (looking for SHA-256) for Clojure or should I just use one of the Java libraries?

4:22 amalloy: i hope nobody writes a crypto library in clojure for a long time. it's a dangerous wheel to reinvent

4:22 vimja: well, true

4:23 i would expect it to be a lispy wrapper around the java libs

4:24 amalloy: meh. just use apache commons or one o' them things. a wrapper would surely be so thin as to be pretty uninteresting

4:25 guns: Wrappers are friendly to recent converts anyway (who never thought they would be looking at Java class documentation)

4:25 vimja: i have for a long time avoided java

4:26 in fact, clojure being based on the jvm was reason enough to not use clojure

4:26 for a while at least

4:29 guns: I'm with you vimja; could be worse though. Rich could have stayed with .NET and tempted us all back to Windows.

4:30 vimja: guns: I would still be in CL then ^_^

4:51 raek: vimja: the most common algorithms are implemented in classes that come with the JVM

4:53 (def data (.getBytes "hello world, åäö" "UTF-8"))

4:53 (import 'java.security.MessageDigest)

4:53 (def md (MessageDigest/getInstance "SHA-256"))

4:54 (.update md data)

4:54 (def data-hash (.digest md))

4:58 vimja: raek: thanks, I'll have to read up on java interop

5:03 guns: Has anyone attempted to port clojure to the GHC?

5:04 Just watched a presentation by Simon Peyton Jones, and it has me all pumped on Haskell

5:05 notostraca: guns, not that I am aware of -- seems like you wouldn't get much library-wise

5:05 guns: notostraca: lack of libraries can be exciting for a programmer looking to make a name for himself

5:06 but, that's too bad

5:06 notostraca: the F# people were talking about porting to LLVM if M$ fails to keep maintaining the language

5:06 guns: That's interesting!

5:06 notostraca: haskell might be better

5:06 guns: That kind of project is beyond my ken ATM unfortunately

5:07 notostraca: guns, Falcon VM could probably handle Clojure features (or the language) without much difficulty once the new engine is finalized in the next few months

5:07 #falcon here on freenode

5:08 Falcon is, like Clojure, a multiparadigm dynamically-typed language

5:08 AimHere: Lets port Clojure to the Infocom Zmachine

5:08 guns: notostraca: never heard of it, but I will definitely check it out.

5:09 notostraca: but Falcon doesn't support concurrency internally, instead meaning to be embedded in multi-threaded C++ apps, which no other full-featured scripting languages are very good at

5:09 Lua is C, Python doesn't like multithreading, Ruby doesn't like embedding...

5:10 Falcon 1.0 would be a great target for clojure... better interop with C++ is important for lots of apps

5:10 also, about as fast as Lua

5:10 guns: interop with C++!

5:10 Calling C++ methods sounds like a headache wrt GC

5:11 notostraca: yeah, clojure concurrency primitives would be hard to port, but clojure macros would work

5:11 unlike ClojureScript

5:11 (as far as I remember)

5:12 guns: notostraca: Are you an author of Falcon?

5:12 notostraca: guns, yeah Falcon is still in early stages I would say, despite being around for years

5:12 and no

5:12 the author is Giancarlo Niccolai, jonnymind here

5:13 vimja: notostraca: python was around for years before taking off too

5:14 notostraca: Falcon VM has a really neat structure, it evaluates a syntax tree directly rather than doing the standard way of execution, and gains lots of metaprogramming features as a result

5:14 (at least, it WILL have this structure once released, now it is nearing the end of development)

5:14 guns: do you mean its also homoiconic? or just easy to reconstruct the AST

5:14 notostraca: yes, homoiconic

5:14 statements and keywords are manipulatable values

5:15 it is a pretty maximalist language, the opposite of Lua

5:15 www.falconpl.org IIRC

5:15 guns: Looks like there is alot of attention paid to embedded work

5:16 notostraca: the site is awful though

5:16 guns: that's pretty cool

5:16 AimHere: The maker of Falcon obviously named his language with an eye to getting a thick O Reilly book out of it.

5:16 notostraca: they don't have a web designer related to the author, like clojure does haha

5:16 guns: lol

5:16 notostraca: AimHere, it is named after a judge in Italy killed by the mob

5:16 in honor of his sacrifice

5:17 something Falcone

5:17 AimHere: Python is named after Monty Python, but they still put snakes on the cover

5:17 notostraca: yes

5:17 it will probably be a bird of prey :-)

5:18 it will be a little while before it will be really ready for major use, but when it is, porting other languages could be awesome

5:18 although honestly you wouldn't get many features in clojure that falcon doesn't have

5:19 amcnamara: anyone familiar with aleph/lamina (specifically wrt TCP)?

5:19 notostraca: both have similar FP and metaprogramming

5:19 amcnamara, whoosh over my head

5:19 guns: The site really does need a nice demo page. Coffeescript is the high mark on PL websites IMO

5:19 notostraca: guns, yeah

5:19 you can use www.ideone.com

5:20 they should embed it'

5:20 guns: very cool

5:20 notostraca: yeah, if you need C++ rather than JVM, CLR, or JS, it will be a good option

5:21 I have been watching the progress for about a year on the new engine

5:21 it has gotten so many features added...

5:22 i think it has portable serialized data, like clojure for the most part, but functions can be serialized too (I guess you can do that with macros?)

5:22 tables of functions are neat

5:22 vimja: notostraca: the internationalisation stuff looks cool

5:23 notostraca: message passing, again like clojure

5:23 vimja, yes

5:23 the web page has an annoying refresh to see a new sample thing

5:23 but one of the samples is a nice for-loop thing

5:23 you can create blocks that only execute on specific iterations of a loop

5:23 like

5:24 ifI have an array that is words in a sentence

5:24 forstart: capitalize, formiddle: add a ", ", forlast: add "."

5:25 or add " and " + text + "."

5:26 also classes can have states as part of a state machine syntax

5:26 err, classes AND objects

5:26 guns: notostraca: classes can have states? I admit I don't know what that means

5:26 notostraca: guns, like

5:26 a bird in a game

5:27 vimja: ants in an ant colony

5:27 notostraca: could have a state called "hungry" where the "act" function is more likely to have it feed and less likely to run

5:27 and a state called "scared" where the opposite is true

5:27 when it runs, it changes state

5:28 guns: And this dynamically affects all instances of that class?

5:28 notostraca: scared reverts to hungry after an amount of time without feeding, etc.

5:28 it can, or it can be per object

5:28 I think

5:28 I know it works for objects

5:28 not sure if it can be static for a class

5:29 also they make a big deal about first-class functions as well as first-class methods

5:29 guns: you aren't kidding about multi-paradigm then

5:29 notostraca: which I think is because you can assign a first-class method to a different class than you had before and it can act correctly

5:29 guns, indeed

5:30 it is good when you can only embed one language

5:30 but you need lots of features from multiple paradigms

5:30 or when you don't KNOW what the requirements will be

5:30 it is definitely a more advanced scripting language than something like Python, harder to learn but more powerful

5:31 (at a language level, not a library level)

5:31 guns: I guess that's a possible scenario. Seems like Unix + open source PLs is the modern multi-paradigm solution

5:31 Though admittedly that's a rickety scaffold

5:32 notostraca: I do like clojure's data structure support better than Falcon's though

5:32 hard to top how easy it is to manipulate data in clojure

5:33 though they each have strengths and weaknesses i suppose

5:34 guns: It's a freaking miracle, Clojure. Seems like anyhow; I haven't written anything very large in it yet.

5:35 notostraca: guns, same here, nothing too large. small stuff is wonderful so far

5:35 guns: But it's a breath of fresh air coming from the madness of a large Ruby project

5:35 notostraca: Joreji, Joreji_, Joreji__, Joreji___: hello?

5:36 guns, haha oh yes

11:00 TimMc: I felt like such a badass for having my code work basically the first time I ran it, then I realized one of my tests didn't fail when I messed with it. :-(

11:00 the-kenny: TimMc: You need unit tests for yout unit tests.

11:00 AimHere: Write a test suite for your test suite

11:00 the-kenny: *your

11:01 AimHere: Actually testing is a binary relationship. The way to test your tests is to write the thing you were going to test

11:02 TimMc: the-kenny: I use the saboteur approach to check my tests.

11:02 frob some conditionals or constants in the code under test and ensure the tests fail.

11:03 That can be automated, of course.

11:17 Raynes: jeremyheiler: Looking good.

11:17 jeremyheiler: Raynes: gracias

11:23 Vinzent: Hi. What's the best way to preserve type information when inserting in mongodb?

11:24 (with congomongo)

11:32 clgv: TimMc: someone wanted to port the unit test test engine that automatically removes stuff from test and checks if they still pass. did they finish that already?

11:33 sorry to be that unspecific. it was just something I heard here.

11:36 TimMc: clgv: I don't even know what it was called.

11:37 clgv: TimMc: I dont remember the language. must have been python or ruby

11:37 TimMc: There's some ruby lib that I saw...

11:37 clgv: oh ok. two votes for ruby then ;)

11:38 TimMc: heckle

11:39 http://ruby.sadi.st/Heckle.html

11:39 clgv: right that wa sit

11:41 jeremyheiler: That site is kind of creepy, but i seems like a neat idea as an alternative to line/branch coverage you see wtih java.

11:41 probably more efficient at ensuring things are tested, too

11:42 clgv: oh I found the old log. technomancy was talking about it

11:42 jeremyheiler: i wonder how that would work in clojure? if at all.

11:43 clgv: according to the log the author converted ruby into s-expressions to be able to implement heckle

11:43 jeremyheiler: nice

11:45 I was thinking that it would be difficult to know what to "change" in a clojure program that wouldn't break things in a way that show you weak points. I mean, heckle changes literal values, control statemets, and operators.

11:46 i suppose you could do similar trhings liek change (if ...) to (not (if ...))

11:46 *shrugs*

11:47 sorry... (if (not ...))

11:49 TimMc: clgv: s-expressions? Or an AST?

11:49 clgv: TimMc: http://clojure-log.n01se.net/date/2011-11-10.html

11:51 TimMc: Hearsay and speculation!

11:51 I'm convinced. :-)

11:51 clgv: lol. technomancy sounded convinced ;)

11:53 ah btw. did the clojure conj 2011 talks make it to public available videos already?

11:56 jeremyheiler: Speaking of testing... does anybody worry about testing for ArityException to ensure fixed argument lists a preserved?

11:56 TimMc: What do you mean? If it's thrown, you know there's an error.

11:56 Raynes: clgv: No. I expect they will at some point in the next 30 years though.

11:57 clgv: Raynes: hmm whats the problem. before the conj it sounded like that was planned

11:57 Raynes: clgv: It is planned, but I think they managed to pick the slowest people in the world to actually produce the videos.

11:58 They seem to be focused on ever Ruby conference in the past infinity.

11:58 clgv: Raynes: so post-production is stalling the whole thing?

11:58 Raynes: every*

11:58 I don't know exactly what is stalling things on their end.

11:58 jeremyheiler: TimMc: For the cases when you test for a single arg function, and then you add optional varargs to it and forget to test, i was thinking it would be nice to see the test fail.

12:08 TimMc: hrm

12:08 That's a code coverage question, really.

12:09 jeremyheiler: Are there any code coverage tools for clojure?

12:09 bpr: in cljs, (map? nil) => false, but (assoc nil :foo :bar) => {:foo :bar}

12:09 is this a bug or by design?

12:10 jeremyheiler: (that would certainly help me convince the boss to let me use clojure at work :-P)

12:10 dnolen: hmm type hints in ClojureScript might not be such a bad idea

12:10 bpr: same behavior as Clojure

12:10 bpr: dnolen: ok, thanks

12:10 TimMc: bpr: You can't examine a value and tell what abstraction it is participating in.

12:11 nil participates in many

12:13 bpr: i think i'm confused then. b/c {:foo :bar} is a value, yet (map? {:foo :bar}) => true

12:14 TimMc: map? only checks the type -- it can't tell you what other functions will *accept*

12:14 bpr: ok

12:14 TimMc: It's confusing.

12:15 bpr: sounds like it has to do with protocols

12:15 TimMc: With regards to collections, nil represents an empty sequence.

12:15 This was probably chosen so that (if (seq ...) ... ...) would work. :-/

12:16 assoc is converting it into an empty map, {}

12:16 Special-casing, in other words.

12:16 bpr: ok

12:19 thanks, TimMc

12:21 TimMc: &(class (conj nil 7))

12:21 lazybot: ⇒ clojure.lang.PersistentList

12:22 dnolen: TimMc: bpr: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L261

12:23 TimMc: oh, nice

12:23 bpr: ty, dnolen

12:23 TimMc: dnolen: I take CLJS is serving as a place to explore reimplementations of core functionality?

12:30 clgv: pretty crowded here for a sunday. I hate to have to work today....

12:46 phil: what was the name of the mac tool that showed a password with big letters on your screen so some other person could type them in?

12:47 cant seem to find anything on google

12:56 TimMc: Hells yes, I have a working transitive closure.

12:56 the-kenny: phil: a password?

12:58 phil: the-kenny: yea i mean for example when you wanna show a wifi password to somebody

12:58 the-kenny: phil: So just to display some password in big letters as an overlay? I think quicksilver can do this

12:59 phil: the-kenny: yea thats what i mean... thanks a lot!

12:59 the-kenny: phil: However, Quicksilver is most likely too big to use it just for this purpose :) If you find a simpler tool, let me know

13:00 phil: the-kenny: yea i was desperately googling for over 10 minutes, only think i found are password "recovery" tools and such

13:00 thing*

13:00 clgv: phil: how about copying that wlan password via usb stick? secure wifi passwords are too long to type ;)

13:01 TimMc: I doubt that.

13:02 phil: clgv: yea also a possibility :) in the end i just copy and pasted it in some editor with a 72pt font :)

13:02 clgv: I would hate to type around 60 characters^^

13:02 phil: mine is around 25 or so

13:02 secure enough id say

13:02 TimMc: clgv: it gets hashed

13:02 clgv: mine has full length and is from a prng ;)

13:03 phil: mine is also from a password generator ofc but 60 chars is overkill :)

13:04 clgv: TimMc: getting hashed does not prevent bruteforce attacks ;)

13:04 TimMc: clgv: No, what I mean is, there's a limit to how uesful a long password can be.

13:04 since it is hashed *before* comparison

13:05 what I'm having trouble finding out is the size of WPA2 passwords

13:06 clgv: are you sure? that sounds odd. usually cryptographic procedure expand passwords of say N bits to a state of M>N bits to complicate algebraic attacks

13:07 TimMc: I would never credit the designers of WiFi with having considered something like that.

13:08 clgv: well they have definitely put some effort in WPA2 since WEP was an epic fail

13:08 TimMc: Hmm.

13:08 I think it basically uses the same key design, though.

13:09 clgv: I am pretty sure it uses the full size of the given PSK

13:34 dnolen: ibdknox: ping

13:59 entel: why can't i do this?: (let (vec (list 'foo 123)))

13:59 dnolen: entel: what is that supposed to do?

13:59 entel: make a vector that looks like [foo 123] and pass it to let

14:00 gfredericks: ah! :D

14:00 TimMc: entel: let needs a bindings clause.

14:00 gfredericks: let is a macro

14:01 or a special form

14:01 but in any case not a function

14:01 TimMc: entel: What do you imagine that would do?

14:01 gfredericks: the bindings cannot be something that evaluates to a vector, it has to actually be a vector literal

14:01 dnolen: ,(let [v '[foo 123]] v)

14:01 clojurebot: [foo 123]

14:01 entel: hrm

14:01 TimMc: Oh, hah! I see.

14:01 gfredericks: entel: it has to do with the difference between compile time and runtime

14:01 dnolen: entel: ^ is probably what you want, right?

14:02 gfredericks: dnolen: I think he was treating the bindings form like it was an argument to the function let

14:02 TimMc: No, I think entel wants a macro.

14:02 gfredericks: entel: yeah, you can do this sort of thing at compile time by writing a macro

14:02 TimMc: entel: What's the larger picture here?

14:02 I have the feeling you're way off in the weeds.

14:03 amalloy: heh

14:03 entel: trying to do something like this..

14:03 (let (vec (interleave '[str trailing] (split str #" :" 2))) ;; prefix, str

14:04 amalloy: you just want (let [[str trailing] (split ...)] ...)

14:04 entel: oh that works?

14:04 hmm

14:04 gfredericks: amalloy: nice; woulda taken me minutes to figure out what he was trying to do

14:05 I need to stop mentioning macros no matter how relevant they are to the question as stated.

14:05 mrb_bk: any overtone users here?

14:09 danieljames: I've been googling this all evening, but earlier I was able to do (show x) at the repl, and now after restarts etc (use 'clojure.contrib.repl-utils) gives me an IllegalStateException "source already refers to"

14:10 any ideas

14:10 ?

14:10 dnolen: danieljames: contrib is dead. you should use clojure.repl instead

14:11 amalloy: clojure.reflect

14:11 entel: also does anyone know of a builtin that does this?: (defmacro append [x seq] (reverse (cons x (reverse seq))))

14:11 amalloy: repl has no substitute for show, but reflect/reflect is one

14:11 danieljames: The mystery is, how did I get it to work earlier!!

14:12 dnolen: danieljames: a contrib must have been on your classpath. perhaps using lein blew it away?

14:13 danieljames: I'm an absolute noob, I'm using eclipse and counterclockwise and it was literally one of the first things I did, defrecord a couple of pr's and (show MyRecord)

14:17 the-kenny-w: entel: Try conj

14:19 gfredericks: entel: A) conj will work if you're using a vector; B) in any case that could be a function, not a macro

14:21 danieljames: ah. no clojure.reflect either

14:25 entel: gfredericks: why should that be a function and not a macro?

14:26 jeremyheiler: danieljames: you need to (require 'clojure.reflect) in order to use clojure.reflect/reflect

14:26 danieljames: could not locate clojure/reflect__init

14:27 jeremyheiler: You you using 1.2 or 1.3?

14:27 danieljames: 1.2

14:27 jeremyheiler: Ah, then you need to upgrade to 1.3 in order to use the libs that replaced contrib.

14:27 solussd: what is going on here? : `(~'~v)

14:27 ,`(~'~v)

14:28 clojurebot: ((clojure.core/unquote v))

14:28 danieljames: I will go away and investigate how to get the latest version into eclipse. The annoying thing is that I definitely had (show MyRecordType) working earlier

14:30 amalloy: &(let [v 'test] `(~'~v))

14:30 lazybot: ⇒ ((clojure.core/unquote v))

14:30 danieljames: it was even coming up as a suggestion with Ctrl+Space

14:31 solussd: why isn't it ('test) ?

14:31 amalloy: &(let [v 'test] `('~v))

14:31 lazybot: ⇒ ((quote test))

14:31 jeremyheiler: danieljames: Did you reload something? It's possible contrib got lost somehwere.

14:32 danieljames: I've restarted the REPL a couple of times. I'm pretty sure I either executed something like (require or (use but I'm not sure what

14:33 solussd: &(let [v 'test] ``(~'~v))

14:33 lazybot: ⇒ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote test))))

14:33 danieljames: I didn't do require :as or anything like that

14:33 solussd: so confused.

14:35 TimMc: entel: If you have to ask why not to use a macro for that... don't use a macro for that.

14:35 danieljames: eugh. I did (use ... :only [show])

14:48 gfredericks: entel: any kind of data-processing (e.g., adding something to a collection in some particular way) can be implemented with a regular function. Just about anything you can imagine doing easily in a non-lisp can be done with functions and existing macros.

14:50 entel: my theory was it would avoid an extra function call overhead.. i dont really have a good understanding of when to use macros and when not to

14:50 whats a good rule of thumb there?

14:50 TimMc: entel: Don't worry about performance yet, you don't have enough experience. And profiling is a prerequisite anyway.

14:50 gfredericks: it's hard to resist just saying "don't use macros", but I know that's a frustrating answer

14:51 TimMc: entel: Also, macros *can't* do things like conjing values together, since they operate on syntax, not data.

14:51 gfredericks: at least 95% of the macros I've written are for syntactic sugar, not any kind of performance.

14:52 the only kind of performance-oriented macros I can imagine are maybe for hiccup and match

14:52 TimMc: Right, compiler macros.

14:52 really quite rare

14:52 dnolen: using macros for inlining is ridiculous in Clojure >= 1.3.

14:53 entel: hmm

14:53 ok that helps

14:53 dnolen: entel: functions are very fast in Clojure.

14:53 gfredericks: entel: one thing that took me a while to understand is that, because macros run at compile time, they don't have access to the values that you're passing in. Over and over again I tried to figure out how to take the list that I was "passing to my macro" and inspect it somehow; but that's impossible because the list doesn't exist until runtime.

14:54 entel: well im sure it will become more obvious with more experience

14:55 hopefully

14:55 gfredericks: it's all related to the code-is-data thing

15:12 ckirkendall: arkh: pong

15:23 raek: gfredericks: but you can access preciously def'ed vars from macros. (def foo "abc") (defmacro [] (... foo ...))

15:23 it's just the parameters that gets passed as uninterpreted code

15:31 gfredericks: raek: and also you can run macros at runtime too :)

15:36 chouser: but only with eval

15:40 gfredericks: chouser: really? Can't you get the underlying fn and pass it stuff?

15:43 TimMc: gfredericks: Sure, you can expand stuff.

15:44 &(macroexpand-1 `(let [x 5] x))

15:44 lazybot: ⇒ (let* [clojure.core/x 5] clojure.core/x)

15:44 TimMc: Heh, that wasn't very exciting.

16:11 gfredericks: &(@#'and nil nil 'foo 'bar)

16:11 lazybot: ⇒ (clojure.core/let [and__3546__auto__ foo] (if and__3546__auto__ (clojure.core/and bar) and__3546__auto__))

16:11 danieljames: does anyone have a link for how to change counterclockwise to point at 1.3?

17:04 ddollar: i'm trying to build my first clojure app.. after running lein install, lein help shows me this: https://gist.github.com/ef014ebe2ddb6fb5e02a

17:05 technomancy: ddollar: hmm; what does project.clj look like?

17:05 ddollar: https://gist.github.com/1a04db3d51167cfab2b3

17:06 technomancy: ddollar: nothing odd there... did you get leiningen from homebrew or by hand?

17:06 ddollar: homebrew

17:06 technomancy: anything in ~/.lein apart from self-installs?

17:06 ddollar: no

17:07 technomancy: it looks like there's a plugin somehow getting picked up that was written for a really old version of Clojure

17:08 can you see if you can repro using the manual install?

17:08 ddollar: https://gist.github.com/5bd6d49ccb3f2b6a2843

17:08 sure

17:10 so i downloaded the lein script and put it in my path, ran lein self-install again

17:10 same error

17:10 but only if i run inside the app dir.. lein help works fine from my homedir

17:11 technomancy: and the app was generated using "lein new hello-world"?

17:12 ddollar: i didn't use lein new, just made a directory myself

17:12 technomancy: oh, so what's the project tree look like?

17:14 ddollar: https://gist.github.com/5a197b97a626d51c236c

17:15 technomancy: can you go ahead and gist web.clj?

17:16 ddollar: https://gist.github.com/cc03dea04c1dba56de17

17:17 TimMc: whoaaaa

17:17 I just discovered that my transitive closure test was written backwards, but it still worked.

17:18 So, the algorithm is supposed to take a DAG of relationships like 0->1 and 1->2 and compute the missing transitive relationships, like 0->2

17:19 It turns out that if you run the inverse data through, the results are inverted too. I had no idea.

17:19 technomancy: there must be something else going on here

17:20 ddollar: where would a plugin live if it existed?

17:20 i think i tried clojure a long time ago, maybe something is left around

17:20 technomancy: it would either be in lib/dev or ~/.lein/plugins

17:21 actually if you do "DEBUG=y lein version" will list all the locations it's checking

17:21 ddollar: aha

17:21 some stuff in ~/.m2/repository

17:22 TimMc: Heh. When in doubt, rm -rf ~/.m2/repository

17:22 technomancy: nothing in ~/.m2 should affect the leiningen process itself

17:23 ddollar: so i nuked ~/.m2 and redid lein self install, still same error

17:23 https://gist.github.com/d26da5284f37d8722222

17:23 technomancy: ddollar: can you place this in src/leiningen/check.clj inside your project: (ns leiningen.check (:use [leiningen.util.ns :only [namespaces-matching]])) (defn check [project] (prn (namespaces-matching "leiningen")))

17:23 and then run "lein check"

17:24 don't worry about formatting or newlines; should work fine

17:24 TimMc: ddollar: Whoa, that lein is old as hell.

17:24 1.1.0

17:24 technomancy: oh yeah, that would do it

17:24 amalloy: three cheers for homebrew

17:24 technomancy: wow

17:24 ddollar: how do i update?

17:25 TimMc: ddollar: I think most people just use lein's self-installer.

17:26 technomancy: yeah, I don't know homebrew, but if you just curl https://raw.github.com/technomancy/leiningen/stable/bin/lein to somewhere on your $PATH and chmod it you should be good to go

17:27 Raynes: jeremyheiler: Thanks for pasting this: https://refheap.com/paste/469

17:27 jeremyheiler: It showed me how terrible pygments was highlighting Clojure, so I finally got motivation to fix it.

17:27 jeremyheiler: haha, glad I can help!

17:28 Raynes: https://refheap.com/paste/4f25c8ade4b06242c99e712e

17:28 Yay for highlighting that doesn't suck.

17:28 (notice the use line isn't completely screwed anymore)

17:28 jeremyheiler: Yeah, that's definitely nicer. Good work.

17:29 Raynes: I had… I had to look at regexen. :(

17:29 And Python.

17:29 ~python

17:29 clojurebot: python is defmulti doc

17:29 technomancy: should have tipped me off that it was warning about the meta syntax; that warning has been gone for ~ a year and a half

17:29 Raynes: Not the one I was looking for.

17:29 ~python

17:29 clojurebot: python is ugly

17:29 Raynes: There we go.

17:29 ddollar: technomancy: hmm, that's what i did (and uninstalled the homebrew version)

17:29 jeremyheiler: Grows characters

17:29 character*

17:29 ugh

17:30 TimMc: technomancy: I thought homebrew was entirely out of date, so I was surprised when you said that was OK.

17:30 ddollar: ah, i got an old one from github i think

17:30 Raynes: jeremyheiler: So, how is the refheap experience? Do you like it?

17:30 Will you be a return customer. :p

17:31 customer?*

17:32 jeremyheiler: I am a big fan so far. I wish the input box for pasting was bigger (like maybe autosize it so it fills the rest of the screen?) but otherwise it's simple and to the point, so you win my vote.

17:33 Raynes: jeremyheiler: You have a large monitor?

17:34 jeremyheiler: yes

17:34 Raynes: Yeah, I've been concerned about that.

17:34 I'll make an issue and talk to Alex about what we can do about not having maximum sizes.

17:35 jeremyheiler: Honestly, I think it would be ideal to have the site appear to be a "full screen" and resizes with the window (of course with a minmum size) and then the viewing area will just be as big as your screen, with its own scroll bar.

17:36 ddollar: im running now, thanks for the help

17:38 Raynes: jeremyheiler: Yeah, I don't see why we can't do that. I think Alex said it'd look like ass on high resolutions. *shrug*

17:40 jeremyheiler: What is your github username?

17:40 jeremyheiler: You know it

17:41 Raynes: jeremyheiler?

17:41 jeremyheiler: lol yeah

17:41 Raynes: Surpising.

17:41 jeremyheiler: effectively so

17:47 alexbaranosky: is there a simple way to run lein repl in 1.3 ?

17:47 Raynes: alexbaranosky: `lein repl`

17:47 alexbaranosky: Can you be more specific? :p

17:49 alexbaranosky: Raynes, I thought it was always 1.2.1... maybe it doesn't play well with a project.clj that has multiple versions of clojure stpecified alla: org.clojure/clojure "[1.2.0],[1.2.1],[1.3.0]"

17:50 Raynes: alexbaranosky: If you use clojure 1.3.0 in your project, it'll use that with lein repl. I don't even know what that does. Really, people should just give up on version ranges and stuff.

17:50 alexbaranosky: Raynes, yeah, changing to juse one version works

17:50 I'll look into getting rid of it.

17:50 * Raynes writes a new dependency management solution.

17:51 * Raynes dons a banana suit and starts dancing.

18:04 xcthulhu: This is a noob question, but according to Halloway (2009), (class (* 1000 1000 1000 1000 1000 1000 1000 1000)) => java.math.BigInteger

18:05 Raynes: alexbaranosky: You should write a dependency management solution with me. We could call it. Clojure boxes or something.

18:05 &(class (* 1000 1000 1000 1000 1000 1000 1000 1000))

18:05 lazybot: java.lang.ArithmeticException: integer overflow

18:06 Raynes: Heh.

18:06 Anyways, it'd be a clojure.lang.BigInt these days. I believe this changed in Clojure 1.3.

18:06 lucian: bah. why switch to non-arbitrarily large numbers?

18:08 edw: With hiccup, why does this explode: (html5 [:p (str "hi")]) ?

18:09 technomancy: ddollar: so it turned out a manual install from a while ago was shadowing the homebrew version on your $PATH?

18:09 ddollar: yeah

18:09 technomancy: tricky

18:09 xcthulhu: Raynes: Okay, I have 1.3.0

18:09 ddollar: will lein self-install be enough to keep me up to date going forward?

18:10 xcthulhu: Raynes: But I get (class (* 1000 1000 1000 1000 1000 1000 1000 1000)) => ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)

18:10 technomancy: ddollar: self-install is for getting the jar file that corresponds to the given shell script, but "lein upgrade" would have done the trick

18:11 Raynes: Yeah, the Clojure math situation in 1.3 is vague for me.

18:11 edw: Oh wait, that works but (html5 [:body [:p (str "foo")]]) sowa.

18:11 technomancy: provided "lein upgrade" existed back then; it may have been added in 1.2

18:11 edw: s/sowa/does/g

18:12 dnolen: ,(* 1000 1000 1000 1000 1000 1000 1000 1000)

18:12 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

18:12 dnolen: ,(*' 1000 1000 1000 1000 1000 1000 1000 1000)a

18:12 clojurebot: 1000000000000000000000000N

18:13 ihavequestions_: So I'm trying to get the lwjgl to work, and I am getting a class not found exception. So far as I can tell, lein has gotten all the deps though... anyone have a thought on what I might be doing wrong?

18:14 the-kenny: ihavequestions_: Which class is in question?

18:14 ihavequestions_: org.lwjgl.opengl.Display

18:47 clj_newb: I don't like conds / nested ifs; is there something like a (return) in clojure? which basically says "okay, this function execution is now done." ?

18:47 jeremyheiler: (throw (RuntimeException.)) *hides*

18:48 clj_newb: great; all I need is to wratp defMyFn around with a try/catch

18:48 awesome, thanks :-)

18:48 alexbaranosky: lol

18:48 clj_newb: for any arguments I want to return, I just need to derive it from the Exception class right?

18:49 lucian: clj_newb: i think jeremyheiler was joking :)

18:49 but yeah, derive from RuntimeException

18:49 ihavequestions_: I think clj_newb was too

18:49 * lucian is stupid

18:49 jeremyheiler: If you want. It's not really performant to throw an exception for control flow, and probably not the best idea in clojure.

18:50 clj_newb: givne clojure doesn't ahve tail call; I bet it doesnt' ahve continuations either? :-)

18:51 lucian: it has trampolines

19:01 clj_newb: in clojure; am I allowed to define functions starginw with _, or is that generally bad practice and should be reserfed only for core/system functions? [I'm guessing not, since everything is stuck inside of namespaces], but want to double check

19:03 jeremyheiler: There's nothing wrong with that. It seems more common to add a * at the end of a function name. Though, it depends on what your reasoning for putting a _ is.

19:03 clj_newb: it's a set of weird, "unsafe functions" that temporarily violates invariatnts on a data structure

19:03 so I have a set of "safe" functions that always keep the datastructure satisfying certain invariants; they are built with a set of unsafe intermediate helper functions

19:04 jeremyheiler: unsafe functions (in terms of stm) usually have a bang (!) at the end of them.

19:05 clj_newb: both the "safe" and "unsafe" functions change local _bindings_, i.e. the dynamic thread local vars; however, the "safe" ones does so in a way where certain invariants are observed; the unsafe ones violates the invariants; so it seems like ! is not an appropriate distingction here

19:05 jeremyheiler: ok

19:07 If you really want to be sure the distinction is understood, you could just name all your functions *-unsafe

19:07 all your unsafe functions*

19:22 benares_98: what's the reason for choosing the letter M for explicit typing of big decimal numbers?

19:25 Raynes: It looks better than W.

19:25 amalloy: right. you want mario in your data structures, not wario

19:25 ihavequestions_: that depends on your point of view

19:25 Raynes: Yeah, if you don't want Mario, your point of view is backwards.

19:25 benares_98: Shouldn't Long be L then for Luigi?

19:26 ihavequestions_: no, I mean by your logic, if you're upside down, wouldn't W look better than M?

19:26 Raynes: I like the cut of your jib.

19:26 ihavequestions_: thanks!

19:36 I'll just ask again before I leave, anybody have any idea why I'd get an error like: Unknown location: error: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.lwjgl.opengl.Display or how I might go about fixing it?

19:37 jeremyheiler: That class needs to be on the classpath. How you put there depends on what you doing to build your program.

19:38 you're*

19:39 ihavequestions_: ah, ok - so even though I have the dependencies, I don't know where they are, so to speak

19:40 I'll see what I can do with that - thank you

19:40 jeremyheiler: np. are you using lein?

19:40 ihavequestions_: yes

19:40 jeremyheiler: did you do: lein deps ?

19:41 (assuming you put the dep in your project.clj)

19:41 ihavequestions_: yeah, I have the dep in my project.clj, and got it via lein deps

19:42 for what it's worth, the lwjgl has native dependencies, but it seems like those all got pulled down too

19:42 jeremyheiler: is it possible that the Display class isn't in that version?

19:43 ihavequestions_: well, I was looking at the jar, and it seems like that path exists

19:43 jeremyheiler: hmm

19:47 ihavequestions_: well, I gotta go for now . thank you for trying to help me out

19:49 edw: Anyone here deploying to Heroku? Is there a way to speed up deploys? 'lein deps' is making incremental development deeply painful.

21:55 drewr: ,(re-matches #"(?m)f(.*)r" "foo\n\n\nbar")

21:55 clojurebot: nil

21:56 drewr: anybody know how to get MULTILINE working there?

21:56 ,(re-matches #"(?m)f(.*?)r" "foo\n\n\nbar")

21:56 clojurebot: nil

21:58 amalloy: i think you have to compile it with the right mode

21:58 $javadoc java.util.regex.Pattern compile

21:58 lazybot: http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#compile(java.lang.String)

21:58 drewr: that's what the (?m) is supposed to do

21:59 (I've also tried it with a manually compiled Pattern)

21:59 amalloy: you want the (String, int) compile

21:59 drewr: right, tried that

22:00 even tried (bit-or MULTILINE UNIX_LINES)

22:00 amalloy: you want DOTALL

22:00 drewr: orly

22:01 cemerick: ,(re-matches #"(?s)f(.*)r" "foo\n\n\nbar")

22:01 clojurebot: ["foo\n\n\nbar" "oo\n\n\nba"]

22:01 drewr: curses!

22:01 cemerick: amalloy: quick draw ;-)

22:01 drewr: what's MULTILINE for then

22:01 amalloy: changes where $ and ^ match

22:01 cemerick: having ^ and $ match \A and \Z, IIRC

22:01 drewr: gah, ok

22:02 amalloy: \A, \Z?

22:02 cemerick: beginning and end of input

22:21 aphyr: Has anyone used Parsley for parsing recursive infix syntaces? e.g. "foo and bar and baz or xyzzy"?

22:21 It's been somewhat difficult to google, and I'm having some trouble unwinding its internals

23:57 Aha! Parsley implements alternation using sets, but order matters for LR parsers!

23:57 So I need an APersistentSet that *preserves* fixed order somehow

23:58 Any idea how to make one?

23:58 jeremyheiler: ,(doc sorted-set)

23:58 clojurebot: "([& keys]); Returns a new sorted set with supplied keys."

23:59 aphyr: jeremyheiler: no, that doesn't preserve order.

23:59 (sorted-set 3 1 2)

23:59 #{1 2 3}

23:59 jeremyheiler: oh, insertion order. figured you meant your own ordering scheme

Logging service provided by n01se.net