#clojure log - Nov 29 2011

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

0:06 hhutch: dnolen, or anybody else that knows: is the clojurescript/nodejs repl source public ?

0:08 dnolen: hhutch: https://github.com/swannodette/clojurescript

0:11 hhutch: dnolen: thanks, i appreciate it

0:11 dnolen: i've been working on these http://hhutch.github.com/cljs-closure-demos/

0:12 any help making them more idiomatic / "best practices" would be greatly appreciated

0:13 dnolen: hhutch: neat!

0:16 hhutch: those look good to me - interop-y, but about what you'd expect from integrating w/ gclosure.

0:19 hhutch: dnolen: thanks. I don't know what the general community plans are, but with all that i'm learning from this, i'll probably help with any effort to write a wrapper library

0:20 there's a lot of stuff in the goog namespace to exploit

0:21 dnolen: hhutch: no gclosure community plans that I'm aware of. but yes it would be nice to have a cleaner interface to all the stuff that's there.

0:25 hhutch: dnolen: is there any new stuff since the conj with d3 ?

0:27 dnolen: hhutch: not sure, I haven't followed the d3 stuff closely.

0:27 ibdknox: new stuff in terms of what?

0:34 hhutch: ibdknox: just wondering if anybody has released anything using d3/clojurescript since the conj

0:34 ibdknox: I wrote a basic d3 in CLJS

0:35 hhutch: cljs-d3 ?

0:35 ibdknox: no

0:35 pinot has a visualization ns: http://github.com/ibdknox/pinot

0:36 hhutch: oh yes, i saw that before, i've been meaning to give it a shot

0:40 scottj: hhutch: maybe linked to github source page from demos page

0:48 hhutch: scottj: done. the demos page will be better as i get more time

0:58 ibdknox: http://news.ycombinator.com/item?id=3289261

1:04 duck1123: good post

1:06 I played with using the term "controller" with ciste, but it just didn't fit and ended up going with "actions" as the core of the app

1:14 devn: ibdknox: you know, someone brought this up in IRC the other night which I believe prompted him to ask on the list (not sure on that)

1:15 My initial reaction was to agree it was worth bringing up (having a feeling you'd put some serious thought into it)

1:15 alexbaranosky: amalloy, I will write it as a regular macro probably if there's no interest in a reader macro. Figured I might as well ask, and am enjoying the exercise of making changes to the clojure project, since I haven't done that before.

1:15 amalloy: alexbaranosky: no good as a regular macro

1:16 actually you could probably reuse most of the code from my "real multi-line comments" patch

1:16 devn: ibdknox: When I just re-read your response on the ML I realized that when I've mucked around with compojure, ring, etc. I found myself ending up with...basically...noir.

1:16 alexbaranosky: amalloy, you think it can't be done as a regular macro?

1:16 amalloy: certainly not. (heredoc The following text should be a bunch of close parens ))))))))))

1:16 devn: ibdknox: noir seems like a predictable stable state for a web app

1:17 ibdknox: devn: I think so too, Noir was extracted from apps I wrote

1:18 devn: ibdknox: i found myself going through this feeling of uncertainty over and over where I'd think: "Where's the controller? Am I just making a mess?"

1:18 ibdknox: lol

1:18 devn: the truth is, adding more namespaces would have been a mess

1:19 alexbaranosky: amalloy: I'd also like to see a non-regex-only way to write strings that don't need escaping - that and heredocs are things I use all the time when I have the option available, and they make manipulating strings that much less of a pain in the rear

1:19 ibdknox: amalloy: I really wish it *could* be done as a regular macro though

1:20 I'd love a way to have a set of characters magically turn into a string without having to write it as a string, but that's mostly just because it's more aesthetically pleasing for certain scenarios

1:21 devn: ibdknox: i think the other thing is that with clojure the same "lines" between various aspects of the app melted away a bit. At exactly which point could you say it had exited the view and entered the controller's domain?

1:21 alexbaranosky: amalloy, ibdknox I guess it can be done - in powered down form, where it obvioulsy doesn't accept right o parens as legal values

1:21 amalloy: alexbaranosky: that's how the " reader macro already works - it doesn't accept " as a legal value

1:21 ibdknox: devn: yeah, I don't think those boundaries make sense. You're better off modeling your domain directly

1:21 alexbaranosky: that said: its inability to be written as a regular macro seems to give it legit reasons for existing as a reader macro

1:22 amalloy: and there are a zillion other problems with using it as a plain macro: the string you're heredoc-ing has to be syntactically valid

1:22 eg, (heredoc [[[[[[) isn't possible without a reader macro

1:22 ibdknox: yeah :(

1:22 alexbaranosky: amalloy, sometimes though, you really don't care about ")", you might just want to write the equivalent: 'The Sarah said to Bob, "Hello"', without dealing with escaping

1:22 devn: (heredoc ~@'`[[[[[)

1:23 terom: controllers aside, how do you organize your "models" and "views"? i ended up with namespaces like app.model.entity and app.view.entity and it's sometimes confusing (for example both would be in a file called entity.clj, although in different directories)

1:23 amalloy: alexbaranosky: if you need to write that it should probably be in a config file, which you can write unescaped and slurp whenever you want

1:24 devn: alexbaranosky: What sorts of things are heredocs useful for?

1:24 amalloy: i mean, having heredocs wouldn't be a disaster, but it hardly seems worthwhile when we have so many other ways to quote and/or escape

1:24 alexbaranosky: amalloy, you're making a lot of sense over there. Soooo why the heck is this not great reason to make this sucker a reader macro built-in?

1:24 :)

1:24 amalloy: huh?

1:24 ibdknox: lol

1:24 someone is confused

1:24 it might be me

1:24 amalloy: i think there are at least three of us in that club

1:25 alexbaranosky: ha

1:25 devn: Why not just use ""? I'm not trying to dash any hopes or dreams. I'm just trying to understand why it's a valuable feature. Using "'s with escapes seems to work fine?

1:26 The annoying formatting of docstrings is proof that multiline strings in "s work just like I'd imagine a heredoc would, no?

1:26 alexbaranosky: devn: why not? I don't understand why we want to avoid adding a language feature that almost all modern languages have?

1:26 devn: alexbaranosky: because we don't want to end up like Ada

1:27 alexbaranosky: what the heck is Ada? :)

1:27 devn: http://en.wikipedia.org/wiki/Ada_(programming_language)

1:27 duck1123: It's nice having the parsing kept simple

1:28 ibdknox: lo;

1:28 lol*

1:28 what's ada :p

1:28 alexbaranosky: It's not like these kinds of additions would make the parser crazy complex - like amalloy said they're pretty straightforward

1:29 ibdknox: you do pay in cognitive load

1:30 alexbaranosky: guess it depends how many of us are going to be reading the parser regularly, right?

1:30 amalloy: fwiw this is exactly the response i got for my #| multi-line comment |# patch. it was so obvious to me that we should have this feature

1:30 devn: alexbaranosky: I would agree with amalloy that it wouldn't be the end of the world if there were heredocs in clojure, but the chances of this rising to the top of the queue and being debated seems pretty unlikely given there are a number of issues being addressed in the next release.

1:30 alexbaranosky: well, honestly I figured the interest wasn't there for it, hence asking on the dev list

1:30 amalloy: but nobody really wanted it

1:32 ibdknox: when I said cognitive load, I meant for consumers of code not the people reading the parser :p

1:32 alexbaranosky: devn: I mean, if I wrote it it wouldn't need to be near the top of their queue would it?

1:32 anyway, moot point :)

1:32 goodnight folks

1:33 ibdknox, I guess you're right, it would keep the syntax simpler, less squiggles, ticks and hash signs :)

1:35 devn: im still wondering with all honesty if there's a difference between a heredoc and using the current behavior of "

1:35 I've always avoided them.

2:12 accel_: okay; everything I like

2:12 except lein startup time

2:12 too slow

2:13 it needs to go from 5 seconds

2:13 to somethign lower

2:13 like 0.05 seconds

2:13 how can we make this happen?

2:13 amalloy: accel_: never going to happen on the jvm

2:14 accel_: i have disk and memory to spare

2:14 why can't I have a "preloaded jvm"

2:14 where all it deos is mmap a file into memory

2:14 and viola, it's a running JVM ?

2:14 Chousuke: you can run a persistent jvm instance

2:14 amalloy: cake and jark do something like that

2:14 accel_: that soudns good

2:14 can lein use persistent jvms?

2:15 devn: ibdknox: still around?

2:15 amalloy: but the jvm will never let you mmap a file into a running jvm - they couldn't guarantee bytecode integrity, etc

2:15 it's something being planned as a possible optional feature for lein, now that it's merging with cake

2:15 accel_: wait wait

2:15 cake and lein are merging?

2:16 amalloy: as of the conj

2:16 devn: cake's team is joining the lein project

2:16 Guest61397: ¹

2:16 accel_: http://stackoverflow.com/questions/3906276/whats-the-difference-between-cake-and-leiningen looks good

2:16 cake uses persistent jvm

2:16 why is it not lein joining cake ?

2:16 i like persistent jvm

2:17 devn: cake has done a better job from a usability standpoint. i hope that gets into the water.

2:17 amalloy: because everyone uses lein? lein has way fewer bugs? it doesn't matter who's "joining" who?

2:18 devn: accel_: amalloy is right. lein enjoys pretty widespread adoption

2:18 amalloy: i mean, i use cake, i work on cake. it has some cool features. but i start up the jvm so rarely that lein is fine

2:19 and i end up doing enough "just in case" `cake kill` that i don't get much of a boost from the persistent jvm

2:19 devn: well, a lot of the time I want to kill my persistent JVM so I can open up a new swank

2:19 after a lein deps

2:19 accel_: don't you have to startup the jvm every time you want to test your clojure app?

2:19 devn: accel_: no, I work in the REPL

2:19 amalloy: swank, slime, emacs. never kill your jvm again

2:19 accel_: you write actual code in the repl?

2:19 how do you save it to disk?

2:19 devn: you paste it into your source file :)

2:20 amalloy: accel_: the way hiredman was telling you earlier (that was you, right?)

2:20 devn: accel_: it's really a great way to work.

2:20 accel_: amalloy: that was me

2:20 but I wasn't listening

2:20 amalloy: i write it in a source file, and swank sends it to the repl for me

2:20 accel_: how does this way work?

2:20 so you write files on disk

2:20 amalloy: you can do it the other way if you want, and i guess devn does

2:20 accel_: then load them into the repl?

2:20 and the repl basically never dies?

2:20 amalloy: in broad strokes, yes

2:20 devn: i do both, depends on when I'm experimenting or building

2:20 some of the architecture gets done up top, but then i monkey with subexpressions, threading, etc. in the REPL

2:21 sort of like madlibs :X

2:21 (that's a really scary analogy)

2:22 (and reflective of clojure's strengths at the same time)

2:22 amalloy: if you ever find yourself terrified of a madlibs-based analogy, i have to wonder how you came to live in such an otherwise low-stress life

2:22 devn: verb, noun, verb the noun, (-> noun, verb)

2:23 (verb (adjective noun))

2:26 amalloy: you did a syntax highlighting update recently, yeah? What do you think about highlighting the left and right hand sides of a (foo/bar) differently?

2:27 amalloy: that was brehaut

2:27 i guess mine is the one on github

2:27 devn: amalloy: either way, do you think that would work?

2:27 amalloy: devn: it's certainly possible? i'm unclear on "would work"

2:27 brehaut: im not sure i follow

2:28 devn: amalloy: it's sort of a readability concern

2:28 parsing the namespace every single time could be reduced with some different highlighting

2:28 brehaut: do you mean the namespace and name of symbols and keywords?

2:29 devn: brehaut: yeah: (ns foo.core (:require [hello.core :as world])) (world/people)

2:30 brehaut: devn: the brush doesnt know about namespace globals specifically atm.

2:30 it does rudimentary local tracking

2:30 devn: brehaut: i'll pose the same question to you as I did to amalloy, do you think it is useful for readability?

2:31 brehaut: devn: ive put a bit of thought into it and im not sure

2:32 at the moment things like head of form highlighting and local analysis provide a decent balance between useful highlighting and the occasional incorrect highlighting (or absence of highlighting)

2:32 determing whether something is a function, static method, method, class or constructor is mostly just guess work

2:33 devn: brehaut: yeah, i suppose there's a balance, but I'm not sure where / would be abused in a way that could confuse the highlighter

2:33 neotyk: Good morning everyone!

2:33 brehaut: devn: the problem is, when it gets it wrong (which it does sometimes) to exacerbates the problem

2:34 neotyk: devn: you mentioned ws-cljs, did you have any luck with it?

2:34 brehaut: the more highlighting rules, the more it implies that the brush is sure of the meaning of something

2:34 devn: neotyk: i have to admit that i wound up on a related problem for the same project, but it's still open in my browser and I've read a bit of source

2:35 brehaut: yeah, i can see the balance there

2:35 brehaut: devn: the other point is that theres already a lexographic marker for the namespace, name split

2:36 i leaned away from doing 'clever' tricks to highlight reader static seperate to the things they cling to

2:37 devn: if i do swing back around to thinking highlighting namespaces seperately is a good idea, it'll definately be as a secondary class

2:37 devn: so that consumers of the brush can control what the highlighting is with CSS

2:37 (the way meta and quoting currently are)

2:38 (because far out the default style sheet is a mess)

2:38 neotyk: devn: to run it you need to build against closure-library head

2:38 devn: neotyk: thanks for the tip. added a note in org-mode.

2:38 neotyk: devn: but even then you might have problems cause by ws protocol versions

2:39 devn: neotyk: that's fine -- I can hack around with it, was just curious if anything was already out there to peek at

2:41 neotyk: aleph I built against depends on netty with some other version of ws: than version 10

2:42 and that one is not backward compatible with older ones

2:42 so keep also that in mind when hacking it

2:42 all is all I guess it is very early for websocket applications

2:55 georgek: hi, can anyone tell me what are the Sphinx-like doc tools typically used in Java/Clojure projects?

2:56 devn: neotyk: they're becoming pretty commonplace IMO

2:56 neotyk: there has been a slow transition, but I think we're close

2:57 neotyk: once draft 10 is easily available on server, yes. as most browsers work with v10 only

2:58 devn: I war writing it in a time where chrome was just pushing draft 10, so my app just stopped working, now it should be better, I hope

3:19 patchwork: man, suddenly > lein deps is taking forever to run

3:19 and pegging my cpu at 99%

3:19 what could cause that?

3:31 tomoj: I see it taking forever sometimes

3:31 didn't think to check cpu

3:32 I do `lein clean` and try again, usually works, but I'm not sure the clean actually helps at all

3:32 in other words I have no clue what could cause that..

3:32 intermittent network issues?

3:35 patchwork: tomoj: hmmm… interesting. I'll try that

3:39 amalloy: i like to imagine that he's interested in trying out "intermittent network issues"

3:40 tomoj: unplug the cord?

3:41 amalloy: or a ping -f of localhost scheduled as a cron job, i dunno man, but it sounds exciting

3:41 hiredman: flex your cat5 until you get some wire fatigue

3:56 patchwork: Yeah I can simulate the issue if I shake a magnet above the ethernet cord really fast

3:59 and I mean approaching relativistic speeds fast

3:59 ejackson: patchwork: you must drink a lot of coffee

4:01 patchwork: I drink an amount of coffee approaching the mass of the universe

4:01 though time has almost stopped entirely

4:31 Bahman: Hi all!

4:33 tufflax: Hi

4:34 Is the reference on clojure.org is up to date with 1.3?

4:52 changbeer: if clojure async story tied completely to threads, e.g. send and send-off. what if you building a web crawler, using send-off will result in many threads as the threads block waiting for io completion.

4:56 send-off seems to be what is suggested meaning the thread pool will grow as large as the number of actions concurrently running even though most of them will be in an io wait state

5:21 rrc7cz: is there any way to rebind (like binding for vars) something that was lexically scoped? for example (let [x 1] (defn foo [] x)) then do something like (binding [x 2] (foo))?

5:24 tufflax: I would guess not, the binding created with let is not something the rest of the program should know about, so it doesnt make much sense for another part of the program to change it

5:28 ejackson: ~tryit

5:28 clojurebot: Excuse me?

7:47 neotyk: devn: just updated my ws-cljs, new aleph works with chrome

8:07 fliebel: &(instance? Object nil)

8:07 lazybot: ⇒ false

8:18 clgv: :O

8:25 cemerick: fliebel: is that surprising?

8:26 fliebel: cemerick: Not sure, I just hadn't thought of it. I had the "everything is an object" mantra in my mind.

8:26 clgv: nil/null is a special value. there are language concepts where each type has its own null-value...

8:26 cemerick: primitives aren't objects either

8:27 fliebel: cemerick: I know, but ##(instance? Object 1) does work(I hope), because it wraps stuff, right?

8:27 lazybot: ⇒ true

8:27 cemerick: right, you're benefitting from autoboxing there

8:27 "benefitting"

8:27 That's equivalent to ##(instance? Object (Integer. 1))

8:27 lazybot: ⇒ true

8:28 fliebel: Right, so why isn't there a Null box?

8:28 clgv: fliebel: what for?

8:29 fliebel: $source seque

8:29 lazybot: seque is http://is.gd/aZK2oD

8:29 cemerick: you're looking for a sentinel?

8:30 fliebel: cemerick: No, I extended Object to my protocol, and then it bombed out, but seque is one example where a primitive nil is a problem.

8:31 cemerick: You can extend nil to a protocol.

8:31 fliebel: cemerick: I know, I just hadn't anticipated the need to do that.

8:31 cemerick: ah

8:31 fliebel: the correct url is https://github.com/clojure/clojure/blob/1.3.x/src/clj/clojure/core.clj#L4721

8:32 cemerick: There's a lot of strong opinions re: nullability as a general concept, esp. in ML and adjacent worlds IIRC.

8:32 clgv: lazybot needs an update^^

8:33 fliebel: cemerick: I suppose a non-primitive null would set the world on fire, but it'd be useful... sometimes.

8:34 xdanypx: hi

8:34 !list

8:35 cemerick: fliebel: you mean, so that a protocol extension to Object will handle nil cases too?

8:35 fliebel: cemerick: yea, and so that you can insert nil into queues and such.

8:36 xdanypx: http://itunes.apple.com/us/app/textual-irc-client/id403012667?mt=12

8:36 cemerick: That's a serious conflation of concepts.

8:37 Object and nil are diametrically opposed notions. Making the latter fit into a hierarchy headed by the former would be insanity.

8:37 fliebel: cemerick: I'm not saying it's a good idea, just that it's convenient... sometimes.

8:40 cemerick: wow, app store spam in irc

8:40 clgv: ~guards

8:40 clojurebot: SEIZE HIM!

8:40 cemerick: hey, that worked! :-P

8:42 ejackson: ~botsnack

8:42 clojurebot: thanks; that was delicious. (nom nom nom)

8:43 ejackson: ~cemericksnack

8:43 clojurebot: Gabh mo leithscéal?

8:43 ejackson: it was worth a try...

8:43 :P

8:45 cemerick: ejackson: it's appreciated in any case :-)

8:45 * cemerick will work for irc snacks

8:45 ejackson: :)

8:47 fliebel: ejackson: Maybe he has another prefix

8:48 raek: ☃cemericksnack

8:50 fdaoud: cemerick: your book release date got pushed back again :_(

8:51 so in the meantime I'm reading clojure in action.. and doing review for programming clojure 2nd edition

9:12 cemerick: fdaoud: huh, so it has :-/

9:17 fdaoud: cemerick: are you guys all done with it? it is just up to o'reilly now?

9:34 fliebel: What does the Eclipse Public License say, in human language?

9:40 clgv: fliebel: "use me" ;)

9:41 fliebel: clgv: Ok, as long as it does not say "abuse me"

9:41 * clgv votes for licenses written in plain predicate logic

9:41 fliebel: clgv: Or in one sylable words :P

9:42 Fossi: toki pona?

9:43 oh, that's two :[

9:43 * clgv thinks that licenses are only written that way to keep lawyers in business^^

9:44 clgv: Fossi: does toki pona reach the information theoretic bound? ;)

9:45 fliebel: Fossi: Loyban rather, totally unambiguous.

9:46 At least you should be able to make a statement, run the interpreter and get an output. IllegalException ;)

9:48 Fossi: clgv: nobody knows i guess

9:49 clgv: Fossi: the wikipedia entry read as if they wanted to maximize information per character ...

9:49 clojurebot: Excuse me?

9:50 Fossi: hmm, not really

9:51 it only has 123 words, so it's highly context sensitive

9:51 clgv: "Kisa designed Toki Pona to express maximal meaning with minimal complexity."

9:51 oh dont get me wrong I didnt mean soley on single characters

9:52 Fossi: since i don't know any experiment to create a big enough vocabulary, it's kinda hard to say whether it would be too ambiguous/limite to

9:52 talk about things like licensing

9:53 but most words are very short ;)

9:57 anyway, it's totally worth checking it out ;)

10:24 noidi: fliebel, afaik, the EPL is pretty much the same as LGPL. i.e. do whatever you want with the code, as long as you make it (and your modifications to it) available under the EPL

10:24 cemerick: EPL does not mandate the open-sourcing of changes

10:25 noidi: cemerick, http://www.eclipse.org/legal/eplfaq.php#MODDIST

10:26 cemerick: ah, I thought you were saying open-sourcing was mandated even if used internally

10:27 noidi: heh, I don't think even the GPL goes that far :)

10:28 jweiss: that would be pretty difficult to enforce

10:28 cemerick: I've always avoided the LGPL because of various rumblings from the FSF about what constitutes a "derivative work"

10:29 ejackson: what's the licensing story for services ? I build an webapp based on some GPL/EPL/LGPL. What sort of obligations do I have ?

10:29 cemerick: i.e. Is an uberjar that contains LGPL'd classfiles a derivative work?

10:29 ejackson: None AFAIK, as long as you avoid insanity like affero

10:30 ejackson: never even heard of that... crikey

10:32 cemerick: AFAICT, it's mostly a foil for companies that want to do the "open core" thing.

10:33 Similar (but more extreme) to what MySQL AB did with the GPL.

10:33 jweiss: i was under the impression that you can generally build any service off open source, and keep your own code secret, as long as you don't distribute

10:33 pjstadig: right

10:34 but the Affero license was intended to close that "loophole"

10:34 ejackson: yeah, that's an historical artifact though. How many of you ever actually distribute your code ?

10:34 pjstadig: it considers a service a "distribution"

10:34 cemerick: ejackson: PDFTextStream is still my cash cow. :-)

10:34 jweiss: yeah, that is an ever growing loophole which licences will eventually have to address

10:35 pjstadig: the EPL allows you to combine EPL'ed code with proprietary code and distribute it as a binary without having to release the proprietary source

10:35 only changes to the EPL'ed code must be distributed

10:36 cemerick: jweiss: except distribution and uptake are the scarce "resources", not contributions. All other things being equal, a project that has a liberal license will generally outpace one with a restrictive license.

10:38 jweiss: cemerick: good point

10:39 gtrak: pdftextstream looks pretty hot, how long did it take you to make that?

10:40 cemerick: "hot"? :-D

10:40 I might use that as a quote.

10:40 gtrak: No way to answer that at this point. First released late 2003 IIRC.

10:41 gtrak: i want a cash cow, too, but i have so many interests bouncing around in the head

10:41 cemerick: Probably has a couple of man-years baked into it, plus however many years of live-fire testing in absolutely absurd conditions. :-)

10:41 gtrak: sounds like a good way to do it

10:43 cemerick, so are you at a point where you pretty much get to do what you want from that?

10:44 cemerick: gtrak: I wouldn't say that, though I'm not entirely clear on what you mean either. :-)

10:45 gtrak: well, you know, I'd love to be able to quit a job at any point and not worry about it, climb everest, that kind of thing :-)

10:46 though i'd probably still work

10:47 cemerick: ah

10:47 I'm hardly retired. :-P

10:49 jheander: good morning!

10:50 mdeboard: hi

10:53 jheander: hi!

10:53 mdeboard: hey !

10:53 ok i'm done

10:53 jheander: anyone here using midje for tests and mocking?

10:55 Raynes: ~anyone

10:55 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

10:56 jheander: thanks clojurebot :)

10:56 Raynes: :p

10:56 fdaoud: haha

10:56 does anyone know the best way to get some help?

10:59 jheander: alright then: would like to mock a function called with some levels of nesting from my function-under-test, but since the FUT is defined in a separate file and namespace it always seems to resolve the original function first and ignore the mock. How can you get around this problem?

10:59 The documentation and examples on midjes home page all have the function and the tests in the same file and namespace. Nice for documentation and clarity, but rare in practice?

11:19 algal: Suppose I wanted to modify the Clojure reader to default to interpreting numbers as Integers rather than Longs. Is that very tricky? or is there a simpler way to produce the same effect?

11:19 gtrak: algal, i don't think there's any performance benefit for that

11:19 algal: gtrak: I'm not doing it for perf.

11:20 gtrak: for interop?

11:20 algal: gtrak: yeah.

11:20 the long story is… :

11:21 gtrak: the 'long' story :-P

11:21 algal: I've written clojure code to wrap a Java library. So I have a representation of certain java objects as clojure maps. I'd like to be able to print/read them. The java objects use Integers. Those integers will get printed to numbers and read back in as Longs.

11:21 So if take my java object, convert it to clojure. print it, read it, convert back to java, the object is now different -- all its Integers have been turned into Longs.

11:22 This is bad because the Java library actually expects them to be Integers (they're keys).

11:22 gtrak: algal, well you should be using a constructor to create the java object, or setters and getters, no? is it a pojo?

11:23 algal: I could go through all my code and force Long->Integer conversions. but if I could just do a dynamic binding that modified the reader for the duration of certain functions that would suffice.

11:23 gtrak: they've got getters and setters but they're quite messy beasts and they are hard to construct accurately.

11:23 gtrak: i just don't understand why the object can be created with a Long instead of an Integer if it has a Integer field?

11:23 algal: It has an Object field.

11:24 This is the object: https://vaadin.com/api/com/vaadin/data/util/HierarchicalContainer.html

11:24 gtrak: so, the lib expects an Integer in an Object field, and can't deal with a Long, odd :-)

11:24 algal: In particular. the addItem(Object itemId) method is the one that needs to be fed Integers instead of Longs.

11:25 gtrak: oh i see, it's some kind of rendering component

11:25 algal: gtrak: it can deal with a Long, but it will generate Integers on its own in the future and treat them as distinct from the Longs. And then when I print/read, I'll get a collision.

11:25 gtrak: actually a data container backing a rendering component, but you get the idea.

11:25 gtrak: a collision? you mean with hashcode/equals problems?

11:25 algal: collision with (Integer 5) == (Long 5).

11:26 gtrak: right

11:26 algal: The Java object behaves as if (Integer5) is a distinct key from (Long 5)

11:26 But once I print/read, clojure's reader will clobber that by turning those two distinct items into two items with both having a key of Long 5

11:26 Wild_Cat: ,(= (.hashCode (Integer. 5)) (.hashCode (Long. 5)))

11:27 clojurebot: true

11:27 gtrak: (.equals (Integer. 5) (Long. 5))

11:27 ,(.equals (Integer. 5) (Long. 5))

11:27 clojurebot: false

11:27 algal: yeah, the Java object is relying on equals() to define equality of key objects. This is my problem.

11:28 value identity vs object identity strikes again….

11:28 gtrak: well, i think it's just as easy to funnel your maps through a post-processor, i doubt you'll have a performance bottle-neck, and it would be more clear than reader magic (which you can't even do)

11:29 sharms: I have a (for loop over a directory walker which will return a sequence of all the directories that match a regex -- how do I not add nil values? In other languages I would use next or continue (it looks like maybe I should use recur?)

11:29 algal: gtrak: ah. well if redefining the reader is not a practicable option, then I guess it's moot!

11:30 gtrak: bummer. that would have allowed a single point of change.

11:30 gtrak: algal, rather, I think it would be unclear if you could, AFAIK you need a custom build for that right now

11:30 Wild_Cat: it's interesting. I'd have expected Integer(5).equals(Long(5)) to be true. Probably not ==, but .equals, sure.

11:30 gtrak: Wild_Cat, too bad, sucka

11:30 sharms: I made a paste bin -- I just want to eliminate the nil's from being returned

11:30 http://pastebin.com/TqUHBs4G

11:30 Wild_Cat: that really is backwards.

11:31 sharms: also I have only used clojure today, so if you see anything there which doesn't make sense let me know

11:31 gtrak: Wild_Cat, I'm sure if they fixed it, it would break code elsewhere :-)

11:31 algal: gtrak: custom build? No thanks. I'm already too far off the reservation.

11:31 Wild_Cat: gtrak: oh, sure. Yay for legacy ;)

11:31 Java's equality semantics have always been a mess, really.

11:32 (which I mostly blame on primitive types not being part of the object hierarchy)

11:32 leafw: what can possibly cause this: Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: clojure/lang/AFunction

11:32 I am doing:

11:32 ,(eval (read-string "[255 255 255]"))

11:32 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

11:33 leafw: ok clojurebot doesn't what that ... but it works as standalone, and fails when the string comes from a function that, I've tested, gives exactly that string

11:33 algal: Wild_Cat: why weren't primitives weren't in the object system? Seems so braindead, but they must have been thinking something..

11:33 gtrak: algal, performance parity with C++

11:33 Wild_Cat: algal: I suspect what they thought was "C++ did it"

11:34 algal: But that doesn't explain it. You can keep the primitives in the object system and handle the treatment of them under the hood, no?

11:34 Wild_Cat: (of course, using C++ in the context of a discussion regarding a braindead language feature is barely a step above PHP)

11:34 algal: yeah, but when you do that, you sacrifice some performance. Java did it with autoboxing in 1.5

11:34 sharms: so if I have a loop that returns values, is there no way to eliminate returning a nil, and I have to use map to remove it later?

11:34 Wild_Cat: Python has had it since the beginning, and it's noticeably slower than Java for number-crunching ops

11:34 gtrak: algal, well, python needs numpy for fast numbers, that's a C extension

11:35 Wild_Cat: (and the boxing/unboxing cost is mostly to blame)

11:35 algal: I may be confused, but my understanding is that in-vs-out-of-the-object system is a separate issue from uses-boxing-or-unboxing.

11:35 Wild_Cat: however, I have no objections to sacrificing some performance in the name of retaining language semantics that make sense.

11:36 algal: For instance, I believe Common Lisp allows unboxed mathematical operations and the numbers are still in the object system. Could be I'm wrong.

11:36 clgv: sharms: if you 'map something and get nil values in the result you kann switch to 'keep and it's done

11:36 gtrak: within clojure, you get good semantics, the further lower-level you go, the worse it gets

11:36 leafw: is (eval (read-string ...)) somehow thread-context dependent?

11:36 Wild_Cat: algal: it's linked -- see, if you want numbers to be part of your object system, you can't simply map them to underlying C types, you need to construct proper classes

11:36 Chousuke: there are ways around it

11:37 jheander: sharms: you could change walk-directory into a lazy-seq. That would be more idiomatic and solve your problem

11:37 Wild_Cat: but yeah, Java got around that with autoboxing in 1.5. Now you can call methods on ints and all, but if/when you do you incur a performance penalty.

11:37 algal: Wild_Cat: Are you quite sure about that? I know that's what's said about Java's choices, btu I remember reading somewhere that Java's choices here were actually being dictated by earlier errors int he language design.

11:37 Chousuke: Wild_Cat: not like that, that's just a compiler hack

11:37 Wild_Cat: ...and it doesn't solve the fact that equality semantics are still moronic, because of the need to retain backwards compatibility

11:38 Chousuke: Wild_Cat: I mean you can have ~primitive numbers that have object semantics, but it requires trickery

11:38 Wild_Cat: Chousuke: oh. I am disappoint.

11:38 algal: chousuke: "trickery"?

11:38 Wild_Cat: in fact, Java sacrificed *all* its operators on the altar of slight-performance-improvement.

11:38 Chousuke: algal: tagged pointers :P

11:38 clgv: sharms: that would be a clojure solution: (defn walk-directory [dirpath pattern] (map #(.getPath %)  (filter #(re-matches pattern (.getName %)) (-> dirpath File. file-seq))))

11:39 sharms: ok so there is basically no way to say 'dont return anything this iteration' in clojure, and that is intended because it's functional?

11:40 gtrak: i don't know why people expect java not to suck :-), it's fast, we have clojure, there are warts

11:40 algal: Chousuke: hmm.. I must read more on this someday. Maybe it's in the Quienniac book.

11:40 Chousuke: sharms: use filter :P

11:40 clgv: you can use 'for with :let and :when

11:40 Wild_Cat: gtrak: I stopped expecting Java not to suck after coding in it professionally for 2 years.

11:40 jheander: sharms: yes, you only iterate if you really *need* side-effects. For generating lists it is more efficient to use lazy sequences

11:41 Wild_Cat: (I was, however, surprised when I discovered C++ and realized that compared to it, Java was the epitome of non-suckiness)

11:41 dnolen: algal: Common Lisp does this (maybe some Schemes), but that's a goal. tagging means you have less bits for the number itself.

11:41 algal: gtrak: I'm just curious what lead to that particular bit of it sucking. I'm not expecting otherwise.

11:41 gtrak: Wild_Cat, indeed :-) I did C++ first, came into java biased against it, warmed up to it, now I hate it for different reasons than before

11:41 Wild_Cat: haha

11:42 algal: dnolen: thx. I thought I remembered that CL did this. Didn't realise how. Still leaves open the question of why the guys didn't use the same trickery for Java. I realise this is really a historical curiosity...

11:42 gtrak: I mean... but I don't actually care, because clojure makes the difference

11:43 and honestly, if i were running a company that needed warm bodies, I'd pick java

11:43 Wild_Cat: Java's history is tortuous and full of bizarre things. Remember that it was initially conceived as a language for embedded hardware with very weak hardware.

11:44 ejackson: Wild_Cat: yup, and I have used it there.

11:45 Wild_Cat: ejackson: you mean Android? :p

11:45 ejackson: hehe

11:47 sharms: so I can google this, what is the verbose written name of the '->' function

11:48 ejackson: its the thread macro

11:49 sharms: Fogus' piece is good http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/

11:49 duck1123: minus_gt is a good name for it

11:49 gtrak: thrush

11:49 TimMc: I prefer to call it a "stitching macro".

11:49 algal: btw, anyone know if there is or will be video available of the Strange Loop 2011 talks?

11:49 gtrak: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

11:50 ejackson: gtrak: careful, its not actually,

11:50 gtrak: ya

11:50 zerokarmaleft: algal: they're being posted at infoq.com

11:50 ejackson: but you know that :)

11:50 dnolen: algal: because Java folks were competing w/ C++. What do they need tagged numbers for?

11:50 gtrak: that blog post was most enlightening

11:51 algal: zerokarmaleft: th

11:51 zerokarmaleft: thx.

11:51 gtrak: the thrush discussion shows the intent of -> and its shortcomings

11:51 algal: zerokarmaleft: Do you happen to know if they're all going up eventually?

11:52 zerokarmaleft: algal: i'm not sure

11:53 algal: Been wondering if dnolen's talk on the mapping dilemma is going to go online anywhere… :)

11:54 gtrak: algal, https://thestrangeloop.com/news/strange-loop-2011-video-schedule

11:54 zerokarmaleft: if it's anything like http://www2.parc.com/csl/groups/sda/projects/oi/towards-talk/transcript.html, i hope so too

11:55 algal: gtrak: awesome, thanks!

11:56 leafw: hi all

11:57 when one runs an eval or a load-string and gets this error: "Caused by: java.lang.ClassNotFoundException: clojure.lang.AFunction" -- what does it mean?

11:57 I've been banging my head for half an hour

11:57 it cannot find the namespace? Well (str (in-ns 'tmp) (use 'clojure.core) "[255 255 255]") also fails

11:58 what is eval expecting in the string?

11:58 or the clojure.lang.Compiler, for that matter

11:59 gtrak: AFunction is a core clojure class

11:59 leafw: gtrak: indeed, and how come the compiler cannot find it?

11:59 gtrak: maybe the classloaders are messed up somehow

12:00 that stuff's a can of worms

12:00 leafw: hum

12:00 joly: you're running this from a repl?

12:00 leafw: no

12:00 after pushing ok on a dialog

12:00 parsing three values for a color in an array

12:00 or vector, rather

12:01 funny part is that it run before, when there was only one click to a button. With two dialogs--two clicks--it does not run

12:01 it's all the EDT anyway

12:02 clgv: leafw: the (in-ns 'tmp) could be very evil if it 'tmp does not exist it does not automatically refer-clojure

12:02 leafw: clgv: it was just a test. Without it fails anyway

12:04 clgv: leafw: you are definitely doing something weird with your clojure environment - or can you give a reproducible example for a plain clojure repl?

12:05 leafw: clgv: I've been trying to reproduce it, but as I said, it involves GUIs and clicking on a button, then on an ok button of a dialog. Then it fails.

12:05 clgv: leafw: your project is clojure-only? or are you using clojure from java?

12:06 leafw: no, clojure only with imported swing classes

12:06 clgv: can you come up with a minimal example to post in a gist?

12:07 leafw: clgv: will try

12:27 clgv: https://gist.github.com/1405585

12:28 the gist shows a minimal non-working eval that throws Caused by: java.lang.ClassNotFoundException: clojure.lang.AFunction

12:28 push the button to run it.

12:29 clgv: leaf: clojure 1.2 or 1.3?

12:29 leafw: 1.3

12:29 there must be something about eval that I do not know about yet.

12:30 raek: that's a weird exception...

12:31 leafw: raek: it indicates an error perhaps in the class loader, as clgv suggested

12:31 clgv: leaf: so I put that code in the file "test.clj" (renamed the namespace) and fired up a 1.3 repl where I did (use 'test). I got the window and when hitting the button there was no exception

12:31 leafw: clgv: so did you get a print of the [255 255 255] vector?

12:31 clgv: yes

12:32 leafw: well that means the error is in my setup

12:32 good to know

12:32 clgv: it looks like it.

12:32 leafw: using clojure 1.3.x 1f55cc0a9df8e98c79973a1f563bb68baab7bccd

12:33 clgv: I have the release 1.3.0 from clojars

12:34 leafw: clgv: thanks for the help. Will find out what is up.

12:35 raek: leafw: are you using a pre-release version?

12:35 leafw: from git

12:35 the hash is above

12:36 raek: then I guess you haven't heard about Leiningen :-)

12:36 leafw: raek: I did, I am just used to Fiji and its Script Editor for one-off scripts.

12:36 fiji.sc

12:37 raek: hrm, 1f55cc... should be the release

12:44 leafw: see you all later

13:37 gfredericks: I'm using lein-difftest, which is nice and colorful but the colors turn into puke when I pipe to less. Is there a linux-tactic I'm missing? Is there a simple way to disable the difftest colors?

13:40 TimMc: gfredericks: There's an option to less to *keep* the colors.

13:41 gfredericks: use less -R

13:48 ibdknox: technomancy_: ping?

13:49 technomancy: ibdknox: heya

13:49 just wanted to touch base re: your plans for korma

13:49 you mentioned at one point you were considering migrations and/or schema declarations. have you taken a look at lobos?

13:49 Raynes: technomancy: Since you're here and in need of someone to bother you, do you have any clue what this guy is talking about: https://github.com/Raynes/tryclojure/tree/master/src/tryclojure/views

13:50 ibdknox: technomancy: yeah, I'd prefer not to do it myself

13:50 technomancy: migrations/creation-y things are scary

13:50 they cannot be wrong

13:50 period

13:50 technomancy: Raynes: what guy?

13:51 ibdknox: technomancy: he meant this one: https://github.com/technomancy/leiningen/issues/339

13:51 Raynes: Oh. Wow.

13:51 My clipboard doesn't change to reflect my thoughts, does it?

13:51 mdeboard: lol

13:52 technomancy: Raynes: yeah... I dunno. I can see the reasoning, but I don't think it's a problem in newnew and don't know that it's worth fixing in 1.x.

13:52 mdeboard: And thank god

13:52 Raynes: technomancy: I'm just not sure what he is even talking about.

13:52 gfredericks: TimMc: cool, thanks!

13:52 Raynes: cat doesn't care if my file has newlines.

13:52 technomancy: Raynes: if you cat a file that doesn't end in a newline, your prompt ends up in a funny place I guess.

13:52 Raynes: Yeah... I don't care.

13:52 :p

13:53 technomancy: there are certain cases where it's absolutely crucial

13:53 like crontabs--cron will just ignore the last line if it doesn't end in a newline

13:53 which is its own brand of insanity

13:53 ibdknox: lol

13:53 mdeboard: Orite, that has actually bitten me before

13:53 technomancy: so anyway, it's good hygiene to get in the habit

13:54 Raynes: I guess I'll add the damn newlines then.

13:54 amalloy: gfredericks: better yet, set an env var so that less always keeps the colors

13:54 mdeboard: Raynes: Dude don't give in. Just rewrite cron so it doesn't do that

13:54 ibdknox: +!

13:54 +1*

13:54 amalloy: export LESS="-R"

13:56 TimMc: Surprisingly, there's no common GNU command that strips ANSI control sequences from stdin.

13:58 yazirian: you don't have an awk 1-liner for that memorized? tsk

13:59 amalloy: Raynes: man, just set emacs up to put newlines at the ends of files when you save. they don't do any harm, and they make some programs/users happy

13:59 Raynes: I don't like making emacs do things to my files when I save them. I think I can manage on my own.

13:59 yazirian: anything you have to do yourself more than twice, the computer should be doing for you

14:00 ibdknox: yazirian: sweet, it can code for me?

14:00 gfredericks: amalloy: That is indeed "better yet". I'm on it!

14:00 yazirian: only on ipad

14:00 technomancy: I don't like hooks that modify the buffer automatically, but I make an exception for require-final-newline because it's a single byte

14:00 duck1123: I need to alias something so that curl always puts a newline at the end. I hate my prmpt getting messed up

14:00 amalloy: duck1123: just make your prompt start with a newline

14:01 yazirian: i wonder if you could construct a prompt that ... yeah, that

14:01 only smart enough not to make your terminal double-spaced

14:01 amalloy: fixes that issue, and makes things look less cramped when there *is* a trailing newline

14:01 duck1123: amalloy: will that put extra spaces in the terminal, I was thinking of piping curl to sed

14:02 amalloy: it will. i don't really understand why everyone thinks that's such an issue, though

14:02 duck1123: simply that I don't like it double spaced

14:03 amalloy: well, i guess that's good enough reason then

14:03 gtrak: avout!

14:03 yazirian: alias cat to pipe real cat's output to autodetect the final newline and insert one if it's not there

14:03 technomancy: gtrak: it's avout time, amirite?

14:04 gtrak: yea, that's what I was hoping to exist for a while, simple and clean client code for distributed state

14:04 duck1123: yazirian: you would probably do that with a regular expression and sed

14:05 yazirian: realistically you could probably get away with just always echoing the extra newline, since it would only ever happen on cat anyway. but that doesn't have the same nerd cred

14:05 Raynes: technomancy: Aren't Leiningen committers meant to get stickers? You should get more stickers.

14:06 technomancy: Raynes: I still have a few of the first run. send me a sase.

14:06 duck1123: I've been feeling it more with curl. Hiccup doesn't put a newline, so it screws up my prompt whenever I hit a url

14:06 Raynes: technomancy: PM me your address.

14:17 y3di: hey guys, im taking an AI course spring term. I was wondering if learning clojure would be appropriate for it?

14:18 I have some experience with scheme so i'm not completely new to functional languages

14:19 amalloy: i don't see why not

14:22 technomancy: isn't that a question for the instructors?

14:23 mdeboard: technomancy: How do you know we're not instructors for his course

14:23 ibdknox: I'm teaching it

14:23 technomancy: dun dun dun!

14:23 mdeboard: OMG me too!!

14:23 ibdknox: DUDE

14:23 mdeboard: y3di: just kidding buddy :)

14:24 kephale1: clojure is used in a number of the ai courses i've been involved in recently

14:24 duck1123: If the instructor were in this channel, I'd say the chances would be pretty good

14:24 y3di: ive been meaning to learn clojure some time, but i wanna know whether this course is a good excuse to learn it sooner rather than later

14:24 TimMc: The instructor could answer whether it is allowed, but we might be better at saying whether it is useful (if the instructor hasn't used it.)

14:25 y3di: I used it for a computer graphics class, so why not? And Lisp is classically an AI language.

14:25 mdeboard: y3di: Sounds like a great excuse.

14:25 duck1123: I still want to see an AIML processor done in clojure (the language for chat bots)

14:26 There's program D for java, but it's really old now

14:27 ibdknox: Clojure works nicely for AI stuff

14:28 y3di: cool

14:28 amalloy: i bet even a clojure bot would tell you clojure is good for ai, right???

14:28 lazybot: amalloy: How could that be wrong?

14:28 y3di: anyone know of any AI tutorials dealing specifically with clojure?

14:28 ibdknox: amalloy: he needs better yes responses :p

14:29 amalloy: ibdknox: plz fork

14:29 i wrote those in like two minutes, would love some more variety and/or better-ness

14:36 TimMc: amalloy: How did you decide on the mapping of {2 :no 3 :yes}? Coin flip?

14:36 amalloy: TimMc: partly based on my delusional beliefs about how fsbot in #emacs works

14:36 TimMc: or did you consider the most likely number of question marks for each?

14:36 ah

14:37 amalloy: I had decided that it as because truth is stranger than fiction. :-P

14:37 *was because

14:37 amalloy: *chuckle*

14:40 TimMc: y3di: ohpauleez mentioned that his company uses Clojure for some ML stuff.

14:46 gfredericks: I always assumed the map was based on ##(map count ["no" "yes"])

14:46 lazybot: ⇒ (2 3)

14:50 TimMc: heh

14:50 gfredericks: presumably amalloy would actually implement it as ##((comp (partial into {}) (partial map (juxt count identity))) ["yes" "no"])

14:50 lazybot: ⇒ {3 "yes", 2 "no"}

14:51 amalloy: i'm not a totaly HOF-nut, i'm just nuts for juxt

14:51 Raynes: Man.

14:51 TimMc: (juxt count identity) is (comp reverse (annotate count))

14:51 * Raynes is never giving a talk again.

14:52 gfredericks: amalloy: "nuts for juxt" is a phonetic gem.

14:52 ibdknox: Raynes: ?

14:52 Raynes: One line up. :p

14:52 Context is always a backlog away.

14:53 amalloy: ibdknox: he called me nuts for juxt in his talk. i'm just pleased as punch, but he seems to regret it

14:53 ibdknox: lol

14:53 Raynes: Heh

14:53 gfredericks: oh so Raynes is the original author

14:54 $inc Raynes ; then

14:54 $dec lazybot

14:54 I quit.

14:54 Raynes: $kill

14:54 lazybot: KILL IT WITH FIRE!

14:56 mdeboard: ,(inc Raynes)

14:56 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: Raynes in this context, compiling:(NO_SOURCE_PATH:0)>

14:56 mdeboard: balls

14:56 ,"balls"

14:56 clojurebot: "balls"

14:57 TimMc: (inc Raynes)

14:57 &(inc Raynes)

14:57 lazybot: java.lang.RuntimeException: Unable to resolve symbol: Raynes in this context

14:57 Raynes: Guys.

14:57 TimMc: Yep, the bots hate you.

14:57 Raynes: It's broken. Move on.

14:57 mdeboard: lol

14:57 ibdknox: ~guards

14:57 clojurebot: SEIZE HIM!

14:57 mdeboard: I'LL NEVER LET YOU GO

14:57 TimMc: hrmph, I thought you fixed it

14:57 Raynes: I did.

14:57 Dunno what's causing this.

14:57 mdeboard: $reload

14:57 lazybot: mdeboard: It is not the case that you don't not unhave insufficient privileges to do this.

14:57 mdeboard: :(

14:58 TimMc: Raynes: Pssh, where are your regression tests? :-P

15:00 Raynes: TimMc: Your mom has them.

15:00 TimMc: no, those are regression *testes*

15:03 Raynes: (dec TimMc) ; for implying that his mother has testes.

15:03 lazybot: ⇒ 2

15:03 TimMc: So, version numbers. Where did I recently hear something about someone trying to rework the notion of version number comparison in a distributed-development world?

15:04 technomancy: TimMc: rich talked through some of his ideas about that at the '10 emerging langs conference

15:05 nothing recent has happened afaik though

15:07 TimMc: OK, must have been oneof the videos I watched recently.

15:08 I was just thinking about that stuff today -- what we really care about is major and minor versions, a revision number, and the "publisher".

15:08 plus maybe some qualifier like SNAPSHOT

15:09 technomancy: part of the idea is you need another repository to host the DAG for the entire family of forks, plus a way of correlating a given mvn artifact to a point in that tree

15:09 TimMc: Do we really care about the DAG?

15:09 technomancy: then a way of specifying how you'd like to resolve conflicts

15:10 you need a way of determining which is the newer of two revisions

15:10 TimMc: Isn't it good enough to say, "this is the publisher we trust"?

15:10 technomancy: not for transitive dependencies

15:11 TimMc: Pick one? :-/

15:11 duck1123: what's the best way to stream a tailed log file over a ring request. I know that if I return a lazy seq, that seq will be streamed, but if I use with-open, the stream will be closed. Anyone have any tips that won't leave a bunch of files open?

15:11 technomancy: you need the whole DAG if you're going to be able to implement "pick the newest" as a conflict resolution strategy.

15:11 other strategies may need other things

15:12 _ulises: not just that, if A depends on B and C, and in turn B depends on Dv1 and C on Dv2 you need to resolve that and sometimes "newest" is not enough

15:12 * _ulises jumps in uninvited :)

15:12 technomancy: it's a messy problem

15:13 amalloy: duck1123: so you anticipate that the whole lazy-seq will be realized eventually, and you want to close the filehandle exactly when that happens?

15:13 * technomancy heads off for lunch

15:14 duck1123: amalloy: I assume that the browser page would be closed before that happened really. these files are constantally being written to

15:14 I'm thinking of just actually calling tail as this app is pretty closely tied to linux servers anyway

15:15 danlarkin: technomancy: heads off for lunch! http://www.gogmsite.net/_Media/1769_marie_antoinette_by_jo.jpg

15:15 hiredman: duck1123: tail the log into some kind of broadcast queue, and have lazy-seqs and just consume from the broadcast queue

15:15 clojurebot: eg, https://github.com/clojure/tools.logging is the new version of clojure.contrib.logging

15:16 duck1123: hiredman: yeah, that's probably what I'll do. I'm already using lamina and aleph, but I'm not using aleph for the server just yet

15:17 TimMc: _ulises: Maybe I'm thinking too much of package management. E.g. on my Ubuntu installation, I want the ubuntu-modified versions of packages, not the originals.

15:18 _ulises: TimMc: dependency management is a big faff and definitely not a trivial task

15:18 TimMc: more often than not, I think "well, just get the newest" but that's not the right answer sometimes

15:18 e.g. package C depends on Dv1 because Dv2 changed API

15:19 chouser: technomancy: in case you haven't caught my earlier comments, I'm now using a lot more of your work than I used to (emacs starter kit, clojure slime/swank, and more lein than ever) -- it's all fantastic, thanks!

15:25 _ulises: ,(doc juxt)

15:25 clojurebot: "([f] [f g] [f g h] [f g h & fs]); Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"

15:30 triyo: My app has a leiningen :main entry point. I have a few -main functions in other modules of my project I wish to run as separate java processes. Is there a way to say: lein run <which-main-module>

15:30 And if I don't specify <which-main-module>, run :main defined in project.clj

15:31 hiredman: you can pass lein run a namespace to run

15:34 triyo: hiredman: thanks, thanks great. However I got -> Exception in thread "main" clojure.lang.ArityException: Wrong number of args (1) passed to: core$-main

15:34 Hmm, that sounds like its firing :main in porject.clj file with one arg :-)

15:34 I'm certain

15:35 That use to be a `run` lein plugin that used to work that way..

15:36 Is the built in `run` command the same?

15:37 lein help -> "run Run a -main function with optional command-line arguments."

15:39 TimMc: What if there's no :main?

15:41 Hmm, that doesn't do it either.

15:41 triyo: -> :main namespace specified in project.clj

15:41 *no :main namespace specified in project.clj

15:41 that after running -> lein run mypkg.core

15:42 that has the -main fn

15:42 This is what I used to use https://github.com/sids/lein-run and it seems to have been merged in to lein

15:43 TimMc: Phil is at lunch at the moment.

15:43 triyo: since 1.4. I'm running 1.4.2

15:44 TimMc: lein 1.4? that's old

15:44 amalloy: like really old. i felt bad for having 1.5.2

15:44 TimMc: lein upgrade

15:45 * triyo *blush*

15:46 TimMc: triyo: "USAGE: lein run -m NAMESPACE[/MAIN_FUNCTION] [ARGS...]"

15:46 so it needs both namespace and main's name.

15:46 triyo: Ok great will test

15:46 hopefully this upgrade is backward compatible.

15:46 amalloy: TimMc: [] is optional

15:46 TimMc: oops, misread

15:48 oc_: can i write this any shorter (fewer chars): (filter #(= 0(mod % 3))(map #(* 2 %)(take 1000(iterate inc 1))))

15:49 amalloy: yes, but why?

15:50 TimMc: oc_: Doing 4clojure stuff?

15:50 oc_: nah competing with a haskell friend :p

15:51 = much more important

15:51 Raynes: Competing for the most insane solution?

15:51 amalloy: (range 1 1001), for starters

15:51 and taking out your whitespace is just absurd

15:51 TimMc: &(filter #(zero? (mod % 3)) (range 1 1001 2))

15:51 lazybot: ⇒ (3 9 15 21 27 33 39 45 51 57 63 69 75 81 87 93 99 105 111 117 123 129 135 141 147 153 159 165 171 177 183 189 195 201 207 213 219 225 231 237 243 249 255 261 267 273 279 285 291 297 303 309 315 321 327 333 339 345 351 357 363 369 375 381 387 393 399 405 411 417 423... https://gist.github.com/1406410

15:51 oc_: ah range takes a step

15:51 sweet

15:52 TimMc: actually...

15:52 &(range 3 1001 6)

15:52 amalloy: hah

15:52 lazybot: ⇒ (3 9 15 21 27 33 39 45 51 57 63 69 75 81 87 93 99 105 111 117 123 129 135 141 147 153 159 165 171 177 183 189 195 201 207 213 219 225 231 237 243 249 255 261 267 273 279 285 291 297 303 309 315 321 327 333 339 345 351 357 363 369 375 381 387 393 399 405 411 417 423... https://gist.github.com/1406415

15:52 Raynes: TimMc: = 0 is less characters than zero?

15:52 TimMc: Raynes: so what, I like zero?

15:53 Raynes: He was going for short.

15:53 TimMc: That's his problem. :-)

15:53 oc_: it's all about short, i initially used zero? and spaces ;)

15:53 Raynes: :P

15:54 TimMc: oc_: Actually, it looks like (range 6 1001 6) is what you want.

15:54 oc_: hehe thats perfect

15:54 now he shut up :D

15:54 thanks

15:54 amalloy: no, he'll win

15:54 if he does the same algo in haskell it's fewer characters

15:54 TimMc: oc_: Wait until he asks in #haskell.

15:55 amalloy: [6,12..1001]

15:55 TimMc: nice

15:55 amalloy: $he [6,12..1001]

15:55 lazybot: ⇒ [6,12,18,24,30,36,42,48,54,60,66,72,78,84,90,96,102,108,114,120,126,132,138,144,150,156,162,168,174,180,186,192,198,204,210,216,222,228,234,240,246,252,258,264,270,276,282,288,294,300,306,312,318,324,330,336,342,348,354,360,366,372,378,384,390,396,402,408,414,420,426,432,438,444,450,456,462,468,474,480,486,492,498,504,510,516,522,528,534,540,546,552,558,564,570,576,582,588,594,600,606,612,618,624,630,636,642,648,654,660,666,672,678,684,690,696,702,

15:55 amalloy: hm. not a very good gister

15:56 gtrak: how does it know it's not x*3-6?

15:56 amalloy: wut

15:56 oc_: hehe (range 6 2002 6) btw

15:56 gtrak: 6, 12, 30, 84?

15:57 amalloy: gtrak: that bears no resemblance at all to 3x-6

15:58 gtrak: hmm, let me put it another way, is the [6,12...1001] necessarily additive by a constant?

15:58 amalloy: yes

15:58 always arithmetic series

15:58 oc_: range is somewhat optimized tho, as I need to know the 1000 first chars to use it, thats why i iniitially didnt

15:58 TimMc: It's not a generic pattenr-guesser like Seek-Whence.

15:58 ,(doc range)

15:58 antares_: hey guys. I have a Clojure project (that uses Leiningen) that has Java bits in it. I am trying to build a jar I can distribute but it fails to find classes to AOT. lein javac works fine, lein javac + lein test also work. What I may be missing?

15:58 clojurebot: "([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity."

15:59 TimMc: &(take 400 (range 6 Double/POSITIVE_INFINITY 6))

15:59 lazybot: ⇒ (6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96 102 108 114 120 126 132 138 144 150 156 162 168 174 180 186 192 198 204 210 216 222 228 234 240 246 252 258 264 270 276 282 288 294 300 306 312 318 324 330 336 342 348 354 360 366 372 378 384 390 396 402 408 414 420 4... https://gist.github.com/1406447

15:59 TimMc: (there's no [start step] form)

16:01 oc_: should be some sugar for infinity

16:01 gtrak: $he[2,4,8..1001]

16:01 $he [2,4,8..1001]

16:01 lazybot: ⇒ <no location info>: parse error on input `..'

16:01 TimMc: three dots

16:01 amalloy: no

16:01 gtrak: $he [2,4,8...1001]

16:01 lazybot: ⇒ Not in scope: `...'

16:02 amalloy: two dots, no 8

16:02 TimMc: Ah, it doesn't like the third number.

16:02 oc_: perhaps ∞ should = Double/POSITIVE_INFINITY ;)

16:02 gtrak: just fail :-)

16:02 gotta learn haskell

16:02 oc_: ups, guess irssi don't support 'all' utf8 chars

16:02 TimMc: &(let [∞ Double/POSITIVE_INFINITY] (range 6 ∞ 6))

16:02 antares_: technomancy: do you have a minute?

16:03 lazybot: java.lang.OutOfMemoryError: Java heap space

16:03 oc_: :D

16:03 gtrak: TimMc, don't realize the seq

16:03 amalloy: gtrak: there's some pretty cool stuff in haskell, but i can't bear to deal with the uncool stuff

16:03 oc_: you crashed lazybot ;)

16:03 &(+ 1 1)

16:03 lazybot: ⇒ 2

16:03 oc_: nop

16:03 gtrak: &(let [∞ Double/POSITIVE_INFINITY] (take 5 (range 6 ∞ 6)))

16:03 lazybot: ⇒ (6 12 18 24 30)

16:04 TimMc: Oh, I thought lazybot wouldn't try to realize the whole thing.

16:04 amalloy: lazybot: the unkillable

16:04 gtrak: the problem with that seq is it'll stop incrementing

16:04 TimMc: there's some dynamic var for that, yeah?

16:04 gtrak: right?

16:04 clojurebot: flatten |is| rarely the right answer. What if your "base type" is a list

16:04 amalloy: TimMc: there is, but eh. if the output is so long he can't gist it, you probably asked a dumb question

16:04 TimMc: :-)

16:05 amalloy: ,(range 10)

16:05 clojurebot: (0 1 2 3 4 ...)

16:05 amalloy: and nobody wants THAT behavior

16:05 TimMc: heh

16:05 gtrak: &(last (take 100000 (range 6 Double/POSITIVE_INFINITY 6)))

16:05 lazybot: ⇒ 600000

16:05 gtrak: &(last (take 1000000 (range 6 Double/POSITIVE_INFINITY 6)))

16:05 lazybot: ⇒ 6000000

16:05 gtrak: &(last (take 1000000000 (range 6 Double/POSITIVE_INFINITY 6)))

16:06 amalloy: &(doc nth) ; gtrak

16:06 lazybot: ⇒ "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

16:06 Execution Timed Out!

16:06 gtrak: &(nth 1000000000 (range 6 Double/POSITIVE_INFINITY 6)))

16:06 lazybot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number

16:06 * gtrak facepalm

16:06 gtrak: &(nth (range 6 Double/POSITIVE_INFINITY 6) 1000000000))

16:06 lazybot: Execution Timed Out!

16:08 mefesto: anyone know of a good clojure/java markdown parser lib? google shows a posting by Brian Carper. Looking for alternatives

16:08 TimMc: gtrak: Depends on how the incrementing is done...

16:10 gtrak: TimMc, I'll let you know in a couple weeks when it's done

16:10 TimMc: yeah

16:10 oc_: markdownj perhaps?

16:10 gtrak: pegdown

16:10 TimMc: gtrak: Start higher. :-)

16:10 discount

16:10 mefesto: oc_: thanks. looking at clj-markdown atm

16:10 i'll check it out tho

16:10 TimMc: wait, that's in Python

16:12 gtrak: &(type 10000000000000000000000000000000000000000)

16:12 lazybot: ⇒ clojure.lang.BigInt

16:12 TimMc: &(take 4 (range Long/MAX_VALUE Double/POSITIVE_INFINITY 2))

16:12 lazybot: java.lang.ArithmeticException: integer overflow

16:12 TimMc: ha, works in 1.2

16:12 (9223372036854775807 9223372036854775809 9223372036854775811 9223372036854775813)

16:12 gtrak: yea, how do you make it promote there?

16:13 I know there's a +' but it doesn't apply

16:13 TimMc: $source range

16:13 lazybot: range is http://is.gd/QPzkqk

16:13 gtrak: range uses +

16:13 TimMc: well, that's the 1.2.x version at least

16:14 gtrak: 1.3 also uses +

16:14 oc_: see, a trivial lazy question, and a 1.3 bug is found

16:14 :D

16:14 mefesto: gtrak: thanks for mentioning pegdown. i think that's the one

16:14 TimMc: oc_: Not exactly a bug... maybe a wart.

16:15 gtrak: you can make a range' if you like

16:16 hell, you could make a macro to do it for you right? just replace any + with +'

16:16 TimMc: Tricky to do that correctly.

16:16 gtrak: &( +' Long/MAX_VALUE 1)

16:16 lazybot: ⇒ 9223372036854775808N

16:17 gtrak: &(type (+' Long/MAX_VALUE 1))

16:17 lazybot: ⇒ clojure.lang.BigInt

16:17 gtrak: TimMc, why tricky?

16:17 oc_: &(doc +')

16:17 lazybot: ⇒ "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Supports arbitrary precision. See also: +"

16:17 oc_: &(doc +)

16:17 lazybot: ⇒ "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"

16:18 gtrak: something like (promoting (range 10))

16:19 amalloy: that doesn't really work

16:19 oc_: &(doc addP)

16:19 lazybot: java.lang.RuntimeException: Unable to resolve var: addP in this context

16:19 gtrak: haven't really learned macros yet, but why?

16:19 jacortinas: &(doc promoting)

16:19 lazybot: java.lang.RuntimeException: Unable to resolve var: promoting in this context

16:19 jacortinas: ,(doc promoting)

16:20 bah

16:20 clojurebot: Gabh mo leithscéal?

16:20 oc_: is the inlined source / natives documented (outside the source)?

16:20 gtrak: jacortinas, it doesn't exist

16:20 just an idea

16:20 * jacortinas just got here

16:20 oc_: {:inline (nary-inline 'addP) ...

16:20 amalloy: because it...doesn't make sense. macros only transform the source they can see, not source somehow inside of other functions

16:20 duck1123: it seems that clojuredocs isn't indexing clojure.core anymore

16:21 amalloy: if there were some bindable variable the macro could affect, then it would be possible. but i think *unchecked-arithmetic* is a compile-time flag and range was compiled without it

16:22 gtrak: ah I see, you'd have to read the source into the macro

16:23 probably no way to make that not terrible, it makes an assumption that you can call the source

16:24 oc_: interesting: https://github.com/clojure/clojure/blob/aa7d26336faff6ccc65e4405e28e471221f35fc4/src/jvm/clojure/lang/Numbers.java#L500

16:25 think i need to spend some time in the clojure source

16:27 TimMc: again with the complete lack of javadoc

16:27 gtrak: yea, srsrly

16:27 oc_: don't need javadoc for that clean source

16:28 imo

16:28 could have some doc on stuff like ops, though it's pretty obvious once you navigate to it

16:28 brehaut: i am amused by the implication that 'clean source' could be defined as 'code without all that messy documentation'

16:30 gtrak: i don't really understand this: if ((ret ^ lx) < 0 && (ret ^ ly) < 0)

16:30 in addP

16:30 i guess that's just an overflow check?

16:31 TimMc: oc_: Source does not convey intent.

16:32 oc_: gtrak: yup

16:37 gtrak: it basically just checks that xor ret % is larger than x and y, otherwise it has overflowed.. i.e. -1 xor 1 < 0 (-2)

16:37 umm negate that

16:37 :)

16:40 technomancy: antares_: what's up?

16:45 chouser: technomancy: you rock, btw.

16:45 technomancy: chouser: haha; thanks

16:46 TimMc: antares_'s question was at 15:49, where now == 16:36

16:46 technomancy: are you using version 2 of the starter kit?

16:46 antares_: technomancy: I figured it out but still curious

16:46 technomancy: I have a project that has Java bits and I wanted to create a jar to release

16:47 technomancy: as long as I had :aot in my project.clj, lein jar or lein javac, jar failed saying that .class file could not be found

16:47 technomancy: removing :aot helped. Is this expected?

16:47 chouser: technomancy: 2.0.3 I think

16:48 technomancy: antares_: so it was clearing out classes/ in between javac and compile?

16:49 on the latest leiningen?

16:49 chouser: how's your team taking to it?

16:50 chouser: technomancy: One or two are resisting yet, but otherwise it's going swimingly.

16:50 evil helps a ton

16:50 technomancy: cool

16:51 chouser: one thing I've been doing lately is adding project.clj stubs to other projects I have checked out so that they will work as symlink targets from my checkouts dir

16:51 technomancy: chouser: yeah, some kind of lossy roundtrip functionality would be nice for poms

16:52 antares_: technomancy: possibly

16:52 chouser: I'm far from knowing if this is even possible, but what would you think of allowing metadata on my own project.clj's dep vectors to specify the various paths to local projects, thus not needing a checkouts dir at all.

16:52 antares_: technomancy: but in the end with :aot in project definition I could not build a .jar

16:53 jweiss: if i want to serialize a closure, how do I get the value of the surrounding fn's arrguments? eg, (defn makeclosure [x] (serialized/fn [] (+ x 1))) - technomancy's serializable.fn doesn't seem to be able to do this - throws NPE

16:53 technomancy: chouser: paths to directories of .class files or what?

16:53 chouser: yeah, :source-path, :compile-path, :resources-path

16:54 trying to write code to understand pom.xml, build.xml, etc. seems hard and fragile, but specifying those manually in my own project.clj would be nicer in a couple ways than putting symlinks in a dir

16:55 for one, you'd look in one place to find what version of a thing you're actually asking for

16:55 technomancy: chouser: maybe. I tend to shy away from placing arbitrary classpath entries in project.clj, and this isn't the first place I've seen a use for pom->project.clj conversion.

16:56 doesn't work with ant, but do people still actually use ant?

16:56 TimMc: Not directly, I hope.

16:56 chouser: as with checkouts, this would be strictly for development. Would be wise to have a git hook that disallows pushing such a project.clj, for example.

16:57 Rich still builds clojure with ant, I think, though I guess there's a valid pom.xml in there now too,

16:57 hiredman: mvn package

16:57 TimMc: desnailed

16:58 chouser: I suppose I should figure out how to make that the default

16:58 TimMc: now you are no longer an annotation.

16:58 chouser: don't deref me, man!

16:58 TimMc: s/man/bro/

16:58 chouser: bro!

16:59 sorry, my hip cultural references aren't very hip.

16:59 I suppose hip itself probably isn't hip.

16:59 amalloy: chouser needs a hip replacement?

16:59 chouser: hey now

16:59 patchwork: your ironic use of quasi-hip terms could be considered pre-hip

16:59 TimMc: That's what my s/// was.

17:00 algal: In gen-class, when defining methods with :methods, is there a special syntax for specifying Java array types?

17:00 technomancy: antares_: if you can narrow it down to a repro case it would be great to see an issue created for that

17:00 amalloy: algal: you have to use their real java classnames, like ^"[B" for an array of bytes

17:01 algal: amalloy: Woah. Don't think I've ever learned about how to construct the real Java classnames. Can I interrogate them from the repl?

17:01 antares_: technomancy: I will try, the repo is open source and all it takes is a small change in project.clj. Tomorrow.

17:01 TimMc: ,(type (bytes []))

17:01 technomancy: thanks

17:01 amalloy: sure

17:01 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to [B>

17:01 amalloy: &(class (byte-array 0))

17:01 lazybot: ⇒ [B

17:02 TimMc: My way worked too. :-P

17:02 amalloy: &(class (make-array Integer 0))

17:02 lazybot: ⇒ [Ljava.lang.Integer;

17:03 TimMc: &(class (make-array (class (make-array Long 0)) 0))

17:03 lazybot: ⇒ [[Ljava.lang.Long;

17:04 amalloy: TimMc: ##(class (make-array Long [0 0])), i think

17:04 lazybot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Character

17:04 TimMc: wut

17:04 amalloy: &(class (make-array Long 0 0)), i guess

17:04 lazybot: ⇒ [[Ljava.lang.Long;

17:04 algal: amalloy: Hmm. interesting. thanks. I notice make-array keeps type information, unlike to-array.

17:05 hiredman: ,(to-array Long [1 2 3])

17:05 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$to-array>

17:05 algal: &(class (make-array java.util.HashMap (java.uil.HashMap.)))

17:05 lazybot: java.lang.ClassNotFoundException: java.uil.HashMap

17:05 hiredman: Oh, well

17:05 TimMc: ,(doc to-array)

17:05 clojurebot: "([coll]); Returns an array of Objects containing the contents of coll, which can be any Collection. Maps to java.util.Collection.toArray()."

17:05 amalloy: hiredman: into-array? i've never had a reason to use to-array, myself

17:05 hiredman: amalloy: thats the one

17:05 yeah

17:06 TimMc: amalloy: I don't understand that error message you got at 16:55 EST.

17:07 amalloy: i don't either

17:08 $javadoc Array newInstance

17:08 i hate you, lazybot

17:08 TimMc: &(int [0 0])

17:08 lazybot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Character

17:08 TimMc: welp

17:08 hiredman: someone here (ok, lots of someones here) had a bean generating macro

17:09 TimMc: hiredman: gfredericks

17:09 amalloy: TimMc: okay, the reason you get that error message is c.l.RT/intCast

17:10 it checks for Integer, then Number, and falls back on Character

17:10 i love that for Numbers, it does intCast(longCast(x))

17:10 TimMc: hiredman: https://github.com/fredericksgary/lib-2367

17:11 hiredman: https://gist.github.com/34229 even I did I guess

17:13 devth: trying to figure out macros / syntax quoting. can someone tell me why this expands to nil? https://gist.github.com/1406759 i was hoping it'd expand into 10 (println 1)s

17:13 hiredman: devth: what does doseq return?

17:14 devth: nil.

17:14 hiredman: so when you use doseq and you get nil back should you be surprised?

17:14 devth: but i'm trying to expand the macro, not eval a fn

17:14 trying to write code that writes code and all that :)

17:16 brehaut: devth: i think hiredman is suggesting that your macro _executes_ a doseq, it doesnt quote it

17:17 devth: the body of a macro isnt magically quoted for you; its 'just like' any other function other than it is run at eval time

17:17 devth: hmm. basically i'm trying to write a macro that just write the statement (println 1) 10 times to help me understand the nature of macros and syntax quoting.

17:18 brehaut: right. i don't want the macro to write a doseq expr. only a println

17:18 brehaut: devth: you wont achieve that through side effecting then

17:18 amalloy: devth: macros return code, remember, rather than (say) printing it to stdout

17:18 algal: does the REPL offer any shorthands for the lsat expression evaluated, the second-to-last expression, a la *, **, *** in CL?

17:19 chouser: algal: *1

17:19 amalloy: if you want to return ten copies of a list, you need to construct another list that contains it ten times

17:19 algal: chouser: thx

17:19 brehaut: ,(list* 'do (map (constantly '(println 1)) (range 10))) ; devth

17:19 clojurebot: (do (println 1) (println 1) (println 1) (println 1) ...)

17:19 amalloy: haha brehaut, you couldn't think of a more foul way to do that?

17:19 brehaut: amalloy: im sure i could :P

17:20 amalloy: but i couldnt think of a simpler way to emphasis the point

17:20 TimMc: ,(doc list*)

17:20 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

17:20 TimMc: aha

17:20 amalloy: brehaut: well, you want cons and for, instead of list*, map, and constantly :P

17:20 brehaut: fine

17:21 or

17:21 repeat

17:21 amalloy: but i suppose i can get behind mentioning list* in here, because there always seems to be someone who's excited to hear about it

17:21 oh, sure

17:21 brehaut: ,(cons 'do (repeat 2 '(println 1)))

17:21 clojurebot: (do (println 1) (println 1))

17:21 devth: ok, i think i follow...

17:22 brehaut: list* is also generally quite useful for macros, to avoid someone doing (cons foo (cons bar (cons baz …

17:22 amalloy: really? i've used it a fair number of times but usually not in macros

17:22 brehaut: amalloy: depends if you want to syntax quote or not i guess

17:23 amalloy: i was using it to manipulate key-sequences for update-in: "if the first element is :meta, replace it with the two elements :my-obj :meta"

17:25 brehaut: huh cool

17:46 TimMc: so list* is like a multicons.

17:47 gtrak: how is it different from list?

17:47 brehaut: ,(list 1 2 3 [:a :b :c])

17:47 amalloy: &((juxt list list*) 1 2 3 [4 5 6])

17:47 lazybot: ⇒ [(1 2 3 [4 5 6]) (1 2 3 4 5 6)]

17:47 clojurebot: (1 2 3 [:a :b :c])

17:48 brehaut: amalloy wins

17:48 amalloy: brehaut: juxt always wins

17:48 brehaut: i should have known

17:48 TimMc: lazybot is so much faster...

17:48 gtrak: oh, so I would have expected list to do what list* does

17:48 amalloy: gtrak: i doubt it

17:49 gtrak: &(doc list)

17:49 lazybot: ⇒ "([& items]); Creates a new list containing the items."

17:49 TimMc: gtrak: (list 1 2 3) is '(1 2 3)

17:49 amalloy: you would expect (list 1 2) to throw an exception because 2 isn't a lsit?

17:49 TimMc: &(list* 1 2)

17:49 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

17:49 TimMc: &(list* ())

17:49 lazybot: ⇒ nil

17:49 gtrak: &(doc list*)

17:49 lazybot: ⇒ "([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

17:50 gtrak: ah

17:51 amalloy: if you prefer, you can think of list* as (partial apply list)

17:51 gtrak: yea, I was just trying to come up with that

17:53 slyrus_: so it's been a long time, but I'm trying to run lein again and I get: "Exception in thread "main" java.io.FileNotFoundException: -m (No such file or directory)"

17:59 well, using 1.6.2 and a lein self-install seems to fix the problem

17:59 TimMc: slyrus_: yeah, `lein upgrade` fixes a lot of things

18:00 amalloy: i run lein upgade when my car runs out of gas, just in case

18:02 slyrus_: hmm... "The upgrade task is not meant to be run from a checkout."

18:03 amalloy: if you're using lein from source, you want to git pull

18:03 upgrade is for stable versions

18:04 technomancy: if you pull, be sure to use the 1.x branch

18:04 master is in turmoil for 2.0

18:05 amalloy: "in turmoil". i need to start describing my projects this way

18:07 slyrus_: yeah, I figured that out and switched to 1.6.2. I guess I should use the 1.x branch instead of the 1.6.2 tag though.

18:09 jodaro: heh

18:09 1.2.3-chaos4

18:14 slyrus_: now onto my next problem... how do folks who use both CL and clojure go about using slime these days?

18:14 technomancy: it's ... not a pretty picture

18:15 slyrus_: bummer. I was hoping things would have improved in my absence.

18:15 technomancy: nobody really uses CL anymore

18:15 * slyrus_ is a nobody, apparently

18:15 hiredman: so did all the other absent cl people

18:17 devth: how would I check if something is a java.util.regex.Pattern?

18:17 algal: slyrus_: I gave up on trying to use them together in one emacs installation.

18:18 slyrus_: I keep Quicklisp-maintained current version of slime in aqua emacs, and it keeps working fine.

18:18 Then I installed all of technomancy's toolchain into plain vanilla emacs, and I use that for clojure.

18:18 slyrus_: and then there's an ugly conditional in my init.el.

18:19 slyrus_: I was using mrBliss's fork of swank-clojure, but it requires you to use a frozel old version of SLIME, and I'd rather stay on the Quicklisp reservation, so I gave up on that.

18:19 slyrus_: technomancy: the swank-clojure README says "...Common Lisp, which has a distinction between interpreted code and compiled code". I would say that the distinction is between loading code and compiling code.

18:20 blakesmith: devth: Can't you introspect the class using the 'class' method?

18:20 hiredman: (doc instance?)

18:20 clojurebot: "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

18:21 devth: hiredman: thanks. wasn't having any luck googling.

18:21 technomancy: slyrus_: because slime's "load" commands don't always imply interpreted code?

18:21 hiredman: fuh

18:21 devth: blakesmith: yep, instance? was what i was looking for.

18:21 hiredman: dunno what that "Evaluates x" is there for

18:21 all functions evaluate their arguments

18:21 well, all functions have their arguments evaluated for them

18:21 technomancy: slyrus_: if you don't have any slime-contribs set up, you might be able to get along OK with M-x clojure-jack-in since that bootstraps the clojure-compatible slime

18:24 slyrus_: technomancy: yes, it's true that load doesn't necessarily imply interpreted code -- that's an implementation detail. I'm trying to understand why CL's notion of compilation/load relates to the overloaded reload-all.

18:25 technomancy: slyrus_: clojure just has "compile", so originally the load commands just did the same thing as the compile commands

18:25 but slime doesn't expose reload commands, so I repurposed the "load" varians

18:25 variants

18:26 slyrus_: OK

18:33 jacortinas: anyone have experience getting vimclojure and nailgun working?

18:59 schaefer: i'm writing a webapp with the webapp written in clojurescript. i'd like to share code between the client and the server (things like input validators). does anyone have any suggestions for best practices? how to organize the code, build tips, etc

19:01 * stuartsierra enters, with a flourish of trumpets

19:01 adamesterline: java4lf

19:02 alexbaranosky: how do I make myself enter so magnanimously?

19:02 the trumpets and all

19:02 stuartsierra: alexbaranosky: Type /me followed by whatever you want.

19:03 alexbaranosky: thanks

19:03 cemerick: Usually the guards show up when I enter.

19:04 * alexbaranosky enters, with a slurry of whimpering bent brass instruments

19:04 alexbaranosky: nice

19:04 * slyrus_ just gets dirty looks from the locals, suspicious of the shifty looking dude from the wrong side of the lisp tracks

19:04 stuartsierra: Lisp has no wrong sides!

19:05 cemerick: newlisp might be the wrong side of the lisp tracks.

19:05 slyrus_: stuartsierra: I was informed earlier that "nobody uses CL anymore"

19:06 cemerick: I kid, I kid.

19:06 technomancy: cemerick: hehe

19:06 slyrus_: cemerick: heh!

19:06 ah, common ground :)

19:06 * cemerick is all-inclusive.

19:06 technomancy: slyrus_: I meant no one in this channel

19:06 * stuartsierra is an equal-opportunity curmudgeon

19:06 cemerick: slyrus_: dying breed, dying language as far as anyone can tell

19:08 I wonder what the attrition rate of CLers to some flavor of scheme are (vs. other language X).

19:08 slyrus_: low, I'd guess, but, clearly I'm biased

19:08 he not busy born is busy dying

19:09 It's alright ma, i'm only consing

19:09 next y'all are going to tell me that nobody listens to Bob Dylan anymore either

19:10 cemerick: slyrus_: that's my uneducated impression too, but I can't imagine why

19:10 peteriserins: what's wrong with this minikanren -> logic translation http://pastebin.com/UMNMZNd2?

19:11 cemerick: That is, I can imagine a CLer not finding Clojure hospitable (the JVM is a big pill to swallow if it doesn't align with your needs), but there's a number of killer schemes.

19:11 technomancy: CL is the last holdout of people who don't consider lisp-2 a mistake

19:11 slyrus_: I can handle the JVM. It's the slime/swank/bifurcation/incompatibilities that seem to cause the most headache for me

19:12 technomancy: may explain why they're not keen on switching to schemes

19:12 cemerick: technomancy: you think that's really a driving factor?

19:12 lisp-1 is so *obviously* better :-P

19:13 technomancy: I dunno, it's all I've got by way of explanation

19:13 elisp folks at least are embarrassed about it. =)

19:13 cemerick: Yeah. Who can't love a language with a symbol called FUNCALL?

19:13 stuartsierra: cemerick: But haven't you ever wanted to write (list list (list list)) ? :)

19:13 hiredman: well, you can

19:14 ,(list list (list list))

19:14 clojurebot: (#< clojure.lang.PersistentList$1@82226f> (#< clojure.lang.PersistentList$1@82226f>))

19:15 cemerick: stuartsierra: you should write an interpreter for a novelty language that supports only `list` symbols and lists; call it Buffalo.

19:15 stuartsierra: heh

19:16 I wrote a CL->Perl FFI, some considered that a novelty language. :)

19:16 cemerick: That's downright baroque!

19:18 technomancy: slyrus_: all that stuff would be simple if the slime devs would just agree to cut stable releases

19:18 but I've complained enough about CVS Cowboy release management in here already

19:19 brehaut: technomancy: do you need a time machine to work on clojure-swank ?

19:20 technomancy: if I needed a time machine it wouldn't be so bad; but for it to be required for all the users too is a problem =)

19:20 stuartsierra: How long 'till we fork SLIME?

19:20 brehaut: far out, i have cvs installed

19:20 technomancy: stuartsierra: waiting for a volunteer

19:20 I certainly am not going to do it

19:20 * stuartsierra steps back

19:21 hiredman: stuartsierra: it more or less has already happened

19:21 the symbols just haven't been renamed yet

19:21 * cemerick still recalls winCVS fondly

19:21 cemerick: That's like having good memories of MacGyver.

19:22 airolson: except that MacGyver was still enjoyable

19:23 cemerick: That doesn't seem possible. :-)

19:23 Man, all that emacs-fu lying about, and no one wants to take on a local poster child for worse-is-better?

19:24 brehaut: cemerick: im confused, isnt that unix?

19:25 cemerick: brehaut: we need crazy, but not *that* crazy

19:25 brehaut: but but everyone loves writing parsers!

19:25 dont they?

19:26 cemerick: parsers?

19:26 hiredman: if you love writing parsers why would you use lisp?

19:26 it is the simplest thing to parse

19:27 brehaut: lets pretend i never said a thing

19:41 amalloy: aw, is clojure.reflect new in 1.3?

19:41 hiredman: yes

19:47 stuartsierra: Hey check this out: https://github.com/stuartsierra/clojure/tree/clj322

19:47 New solution to transitive compilation

19:47 Set *compile-files* to :interop to emit files only for interop forms (gen-class, deftype, etc)

19:48 cemerick: stuartsierra: queued

19:48 stuartsierra: :)

19:48 cemerick: i.e. it's in a browser tab :-P

19:48 * cemerick 's tabs are his TODO list

19:49 amalloy: so if anyone has an urgent request for cemerick, please send him a browser virus and then ask him very nicely

19:49 cemerick: I respond only to groveling and patronage.

20:00 stuartsierra: I'll buy you a beer.

20:38 jweiss: is there any way to get at the "closed over" values of a closure? with reflection I can see the package private field on the object, I think there's some reflection tricks to bypass the security, but was hoping for a more direct way

20:39 amalloy: no

20:40 reflection tricks are unlikely to make you very happy either, since they will have munged or made-up names

20:42 jweiss: amalloy: damn. is there a way to grab that value sometime before the object is created? (let's say I can call an alternate fn macro)

20:42 amalloy: yes

20:42 with an alternate fn macro it's easy-peasy

20:42 $google technomancy serializable fn seajure

20:42 lazybot: [Seajure's Profile - GitHub] https://github.com/Seajure

20:43 jweiss: amalloy: i've been there, it does not work on closures. it calls .init on the closed over localbinding, which returns null

20:43 throws NPE

20:44 amalloy: it was designed to work for closures, and has worked for numerous people in the past. possibly it's broken in 1.3, i dunno

20:44 jweiss: oh hm, that is a forked version, let me see if it's different

20:45 no, it also uses .init. it didn't work with 1.2, i can try again now with 1.3

20:46 amalloy: at least with 1.2, it works with (let ...) locals but not closures

20:46 amalloy: those are the same thing. what is a specific use case that works and one that doesn't?

20:50 jweiss: amalloy: (defn blah [x] (serializable.fn/fn [] (+ x 3))) (pr (blah 5))

20:50 that does not work ^

20:51 (let [x 5] (pr (serializable.fn/fn [] (+ x 3))))

20:51 that works ^

20:52 they both create LocalBindings, but the former, when you call .init, returns nil for some reason

20:52 amalloy: well, there's no init form

20:52 because it happens at macro time. seems to me like phil could have done this at runtime instead, but maybe not

20:53 hiredman: jweiss: x isn't closed over unless it is a local

20:53 amalloy: hiredman: i either disagree or don't understand. inside that fn scope, x is closed over

20:54 jweiss: amalloy: seems to be closed over based on inspecting the object created with reflection

20:54 hiredman: amalloy: oh, I am misreading it

20:54 amalloy: the issue is that serializable/fn is checking the bindings at compile-time instead of runtime

20:55 hiredman: right, but the bindings don't exist at runtime

20:55 clojure doesn't have reified environments

20:55 amalloy: hiredman: they don't have to. (serializable.fn/fn [] (+ x 1)) could expand to (with-meta (fn [] (+ x 1)) {:locals {'x 1}})

20:56 er, {:locals {'x x}}

20:56 hiredman: fair point

20:57 brehaut: hiredman: ive heard you mention 'reified enviroments' before; what does that mean?

20:57 amalloy: technomancy: when you have a sec: is there a reason you didn't do it this way, or just some oversight?

20:58 hiredman: brehaut: it means you have some construct that represents the execution environment available for inspection at runtime

20:58 allowing for things like eval getting access to locals

20:59 brehaut: interesting; is there an obvious example of a langauge that does have them?

21:00 hiredman: well, it depends if you make the distinction between the languages runtime having access to such a thing and the language have access to it

21:01 jweiss: amalloy: how does storing {:locals ...} help? seems like at compile time the value of x isn't known, and by the time you look at the closure object, it's too late to get it

21:01 brehaut: hiredman: so many things ive never considered before; i have n idea if i would make that decision

21:01 hiredman: scheme's eval has access to the locals because the language's runtime has such a bookkeeping structure

21:02 interpreters almost always have such a thing (I am not really sure how you'd design one with it)

21:02 jweiss: amalloy: oh wait i think i see, the expansion contains the symbol x which at runtime will get the right value

21:04 brehaut: hiredman: i think i follow; thanks

21:05 amalloy: brehaut: javascript has it, sorta

21:05 and scheme does for reals

21:05 jweiss: right

21:06 brehaut: amalloy: ive not experimented much with javascripts eval

21:06 amalloy: brehaut: it's pretty shocking. i probed it a bit last time this came up, and was puzzled by how it behaved

21:07 jweiss: amalloy: so the print-method will also need updating, the current one doesn't distinguish one instance of a closure from another

21:07 brehaut: amalloy: its full of great evil – along with – thus i have avoided it

21:07 amalloy: like, the interpreter seemed to only save references to locals that it could prove you might need, but i forget how it knew that

21:08 (function(s){ var x = 1; return eval(s);})("x") // returns 1

21:09 brehaut: yikes

21:09 amalloy: oh, i remember how i confused it now. one sec

21:09 (function(f, s){ var x = 1; return f(s);})(eval, "x") // ReferenceError: x is not defined

21:10 brehaut: worse (function(s){ var x = 1; eval(s); return y})("var y = 2"); // returns 2

21:10 amalloy: so i guess that probably eval is not a "constant" function - every time you enter it as a literal you get a fresh copy of eval with bindings for your current set of locals

21:12 anyway, my understanding is that in scheme you have to pass eval two arguments: an expression, and the environment in which to evaluate it

21:12 and somehow or other there's a way to manipulate environments, or get a snapshot of your current env, etc

21:13 hiredman: oh, actually I guess at least for racket eval is non-lexical as well

21:14 brehaut: the more i learn, the more i have to learn

21:25 alexbaranosky: brehaut, it really does snowball

21:26 technomancy: amalloy: with-meta and :locals just wouldn't work

21:26 it wouldn't allow for round-tripping

21:27 jweiss: I'm up for changing serializable-fn for whatever it takes to get closures to work; what's committed now is kind of a half-hearted effort

21:27 I was just poking around and if I knew the right methods to call it could surely be made to do what you want

21:27 but none of that stuff is documented

21:29 amalloy: i don't understand how that doesn't allow for round-tripping? when you pr-str it you include the source and the locals, and you make sure to bind *print-meta* to true. then when you read it, you pull the meta out, wrap a let of the locals around the source, and eval that

21:33 developernotes: Can anyone explain why conj adds to the front of lists but to the back of vectors - seems odd to me.

21:34 amalloy: i guess your point is you want to be able to (eval (read-string (pr-str ...))), so you couldn't actually store it in a separate locals map

21:34 but you can still do the same thing of making the locals be evaled at runtime instead of compile-time, which is the main point i was making

21:45 TimMc: developernotes: conj puts the new element at the "most natural place" in the collection. For lists this is clearly the front. For random-access data structures like vectors, the obvious choice is the end, since that preserves indices.

21:45 (good question, by the way)

21:46 developernotes: TimMc: thanks for the answer!

21:48 mdeboard: TimMc: Why is the front "clearly" the most natural place in a list?

21:48 brehaut: mdeboard: because thats where its cheap

21:49 mdeboard: because lists are singly linked

21:49 mdeboard: Because it doesn't have to traverse the whole list or what

21:49 ah

21:49 brehaut: yeah

22:01 cgray: a clojure list is a bit more sophisticated than a singly-linked list, though

22:01 brehaut: its still not free to add at the end rather than start

22:02 cgray: it might make more sense to say that conj puts the new element at the front because the list could be infinite

22:02 i haven't looked at the clojure implementation, but i have a feeling that it might be pretty close to free

22:02 amalloy: cgray: incorrect, lists cannot be infinite. you mean seqs

22:02 cgray: (as long as the list is realized)

22:02 brehaut: a list cant be infinite

22:02 a seq can be infinit

22:02 e

22:03 cgray: i stand corrected :)

22:03 hiredman: cgray: clojure lists are just linked lists

22:03 amalloy: lazybot needs a $ninja'd brehaut command. but i'm not sure what it would do

22:03 brehaut: amalloy: i dont understand

22:04 amalloy: brehaut: i got in there right before you. it would be fun to be able to say $ninja'd brehaut and have him say something clever

22:04 brehaut: amalloy: ah right

22:04 cgray: when is there a benefit to using a list rather than a seq?

22:04 brehaut: im slow today it seems

22:05 cgray: you usually don't want a list unless you are writing a macro

22:05 hiredman: cgray: lists have constant time counting

22:05 amalloy: cgray: lists are (mostly) just counted seqs

22:07 cgray: so is it fair to say that lists are seqs without the possibility of being infinite?

22:08 amalloy: i think so

22:09 brehaut: cgray: at a mechanical level, being a seq is (just?) implementing clojure.lang.ISeq which list does

22:09 cgray: brehaut: oh true, and vectors and maps do to right?

22:10 s/to/too/

22:10 brehaut: cgray: nope

22:10 ,(map seq? [() [] {} #{}])

22:10 clojurebot: (true false false false)

22:10 brehaut: they are clojure.lang.Seqable though

22:11 cgray: meaning that you can turn them into seqs?

22:11 brehaut: ,(map (partial instance? clojure.lang.Seqable) [() [] {} #{}])

22:11 clojurebot: (true true true true)

22:11 brehaut: yes

22:12 however, not everything that is seqable implements clojure.lang.Seqable

22:12 ,((juxt seq (partial instance? clojure.lang.Seqable)) "abc")

22:12 clojurebot: [(\a \b \c) false]

22:12 cgray: ok... it's an interesting distinction (between seqs and lists)... i guess i still don't quite understand why it exists

22:13 but it's supper time here, so i will find out later :)

22:15 brehaut: cgray: abstraction vs concrete implementation

22:17 jweiss: how do you evaluate something first (whose value is a symbol) and *then* quote it?

22:18 (let [s 'x] (something s)) -> 'x

22:19 amalloy: (def something (partial list 'quote))

22:20 but in a macro it's easier

22:20 (or rather, in a syntax-quoted form)

22:20 &(let [s 'x] `(do '~s))

22:20 lazybot: ⇒ (do (quote x))

22:21 jweiss: this is a fn called by macro, so this isn't inside syntax quote... although it could be

22:21 amalloy: you're still looking at serializable.fn, right?

22:21 jweiss: amalloy: yeah, i've almost got it

22:21 amalloy: oh good, that means i don't have to

22:22 jweiss: just trying to do the {:locals {'x x}} part

22:22 amalloy: jweiss: technomancy is right though, you don't want a separate map, you want it shoved into the enclosing let form

22:24 jweiss: amalloy: damn, i missed that part. that should simplify things a bit though

22:26 amalloy: was he right that it doesn't allow for round-tripping? seems like it would

22:26 assuming i modified the print-method to replace the symbol with the value

22:26 amalloy: i think it depends on what he means by round-tripping. if you want to be able to (eval (read-string (pr the-fn))), then you have to put all the necessary info into the ::source meta

22:27 jweiss: amalloy: i don't think so

22:27 not if you specify a print-method that combines the locals and the source

22:28 amalloy: well, sure. but then you just delay the work of mashing it together into a single let - it happens in print-method instead of in the macro

22:28 jweiss: eg, ::source (fn [] (+ x 1)), ::locals {'x 4} -> (fn [] (+ 4 1))

22:28 amalloy: ew ew ew

22:28 do not do that

22:28 jweiss: ok ok i wasn't sure which way was best

22:28 amalloy: (fn [] (let [x 10] (+ x 1)))

22:29 jcrossley3: amalloy: i just finished reading this: http://amalloy.hubpages.com/hub/Dont-use-XML-JSON-for-Clojure-only-persistence-messaging

22:29 jweiss: ugh so if there are compile time locals AND runtime locals we'll get something like (let [x 5] (fn [] (let [y 10] (+ x y)))) ?

22:30 jcrossley3: amalloy: it was very helpful, but it left me wondering, why isn't there a defmethod for java.util.Date?

22:30 amalloy: uhhh, i don't think there is such a thing as runtime vs compile-time locals

22:31 brehaut: jcrossley3: that presupposes youd want to do anything with java.util.Date :S

22:31 jweiss: amalloy: (let [x 5] (defn blah [y] (fn [] (+ x y 10))))

22:31 x is compile time, y is runtime

22:31 brehaut: (well, aside from take it behind the barn and put it down humanely)

22:31 amalloy: jcrossley3: why isn't there a print-method for java.io.File? or java.lang.Package? or java.lang.StringBuffer?

22:32 jweiss: that distinction makes no sense. you just mean that one of them is closed over and one isn't

22:32 jweiss: amalloy: one will be able to call .init and .eval, the other won't

22:32 i guess i'm not using the right terms

22:33 amalloy: if you call .eval in your implementation i think you're guaranteed to have the same problems you do with technomancy's impl

22:33 jweiss: amalloy: i am only calling .eval when .init is non-nil

22:33 amalloy: doesn't matter

22:34 jweiss: hm, it seems to be working - the meta has the right stuff in t

22:34 amalloy: you haven't found the breaking cases yet, is atll

22:34 jcrossley3: amalloy: i think an argument could be made for *any* Serializable java object to be serializable without requiring the user to define a method to do so. unreasonable?

22:34 jweiss: ok, can you think of one?

22:34 amalloy: (let [x 10, y (inc x)] (fn [] y)) might be one

22:35 jweiss: ok i'll try that

22:35 amalloy: and if that works, then try ((fn [x] (let [y (inc x)] (fn [] y))) 10)

22:36 jweiss: amalloy: ok you were right :) Can't call public method of non-public class: public java.lang.Object clojure.lang.Compiler$StaticMethodExpr.eval()


22:36 amalloy: you want all the evaluation to be done in the expanded scope, not at macro time

22:38 jweiss: amalloy: technomancy's impl puts the let outside the (fn ...) - any suggestion whether it should be outside or inside?

22:39 amalloy: needs to be outside

22:39 jweiss: ok

22:39 amalloy: jcrossley3: meh. doesn't seem like much of a win to me, but i dunno

22:40 for example you have to deal with encoding bytes into a character stream and getting them back into bytes - what encoding do you use?

22:41 jweiss: one sec, i'll push up a fork with a proposed change

22:42 jweiss, technomancy: https://github.com/amalloy/serializable-fn/commit/8c83ca07a965ea084f0be525f5ba8e23938cddef

22:43 jcrossley3: amalloy: doesn't java's automatic serialiazation have to deal with the encoding issues, too? configurable somehow?

22:43 amalloy: hm, that doesn't actually work yet. i was testing the wrong thing

22:43 jweiss: amalloy: that's sort of what mine looks like: https://gist.github.com/1407876

22:44 amalloy: *nod* that should basically work, assuming you got the quoting more-right than i did :P

22:44 jweiss: oops, 1 too many levels of quoting in mine

22:45 amalloy: ugh, maybe not. needs more work

22:47 jcrossley3: amalloy: and even without some general purpose marshaling scheme, Date seems as commonly used as some of the other datatypes for which print-dup is defined.

22:48 plus it seems the most common example of a print-dup returned by google. :)

22:49 devn: Am I late to the party? Have we already exhausted conversation about heredocs this evening?

22:50 alexbaranosky: hellllllllllll, no

22:50 amalloy: jweiss: okay, what about https://github.com/amalloy/serializable-fn/commit/472f8c85249fdcb30ca9948401cd0e8d5e2f9094?

22:50 alexbaranosky: ;)

22:50 amalloy: (pr-str (let [x 10 y (inc x)] (fn [] y))) ;=> "(clojure.core/let [y 11 x 10] ^{:line 1} (fn [] y))"

22:50 devn: heh, alexbaranosky: You're tenacious, man.

22:50 alexbaranosky: we've moved on to triple-quotes though I think

22:50 devn: I really dislike that :X

22:50 alexbaranosky: :|

22:50 devn: Not triple quotes, the idea of having moved on.

22:51 alexbaranosky: dev: ahhh... I read it as tenacious

22:51 amalloy: devn, the language-feature stalker, just can't move on

22:51 devn: That post arrived as a "Well, Python does it with triple quotes" and then people started talking about triple quotes.

22:51 I don't think we're there yet. However, I do have some questions which I will post to the list, but I wanted to discuss briefly.

22:52 jweiss: amalloy: nice!

22:52 alexbaranosky: devn: it does't have to be heredocs... I'm not really married to heredocs over triple-quotes

22:52 amalloy: jweiss: it seems to still have some rough patches though :P

22:52 alexbaranosky: devn: I'd liek to hear your alternate views

22:52 devn: If we enumerate a half-dozen proposals for heredcos, do we always end up with the same tradeoffs?

22:52 brehaut: i just hope that whatever occurs doesnt encourage people to tunnel data into strings

22:53 devn: * How about string interpolation. String interpolation is related. Should we be having a discussion about some solution which combines both string interpolation and heredocs? Too far?

22:53 * Might there be any benefits or problems for clojurescript as a result of changes made during the process of adding heredocs?

22:53 ** Does that matter? How much?

22:53 alexbaranosky: dev: I think we should... I put a spot for it on the wiki page

22:54 jweiss: amalloy: only problem i see is calling .sym twice, i can try dropping this version in place of the old one, run it through tomorrow and see if there's any breakage

22:54 devn: * Could docstrings be changed to heredocs without breaking old docstrings?

22:54 alexbaranosky: devn: I mean to say I think it could be discussed, since it's in the same realm... but I don't necessarily think we need interpolation

22:54 amalloy: meh, .sym is free, and happens at macro time anyway

22:54 jweiss: ah

22:54 amalloy: i mean actual breakages in my code

22:55 eg, (fn [x] (let [y (inc x)] (fn [] y))) fails to compile at all

22:55 alexbaranosky: ~nuclear

22:55 clojurebot: Pardon?

22:55 gfredericks: can anybody familiar with clojure.core.match confirm that I'm doing this right? Getting a compile error.

22:55 alexbaranosky: ~sandwich

22:55 devn: alexbaranosky: They are very related. It should at least be considered even if it's rejected out of hand. To date I haven't seen anyone mention interpolation on the ML.

22:55 clojurebot: Pardon?

22:55 gfredericks: https://gist.github.com/1407915

22:55 nuclearsandwich: heey that's me!

22:55 jweiss: amalloy: stack overflow, nice

22:56 alexbaranosky: devn: are you thinking of adding your thoughts to the thread /wiki page?

22:56 devn: alexbaranosky: I haven't read your wiki page yet, but aside from C. Granger's example (which I did find rather compelling) I haven't been able to muster any person examples beyond docstring usage examples which involve strings as input or output.

22:56 amalloy: jweiss: yeah, i'm building the metadata wrong somewhere

22:57 devn: personal*

22:57 alexbaranosky: I don't know yet. I'm feeling like I might just sideline for a bit and see where the discussion travels. I need to condense some thoughts before I put out some half-baked opinions.

22:57 alexbaranosky: I've only really got docstrings, test of xml/json/sql

22:58 but it does seem like more people than just myself, think they make some sense at least on some level

22:59 devn: They do...on some level, but I have this nagging feeling that for long strings you'll do a little bit of typing to escape double quotes, and for longer things you probably should be reading from a file, but that's just an immediate reaction, not a fact.

22:59 gfredericks: well it seems to work okay for the latest snapshot release :/

23:00 alexbaranosky: tests are a great use case where seeing the text in front of you is valuable

23:01 devn: alexbaranosky: by the same token they may minimize the issue. If we cherry pick particularly hairy examples of escaping, does that actually confirm that this is a real problem worth solving, or does it confirm that we know how to find hairy examples?

23:01 I could present to you examples where a heredoc could be helpful if I'm golfing, but would not provide any significant benefit, for example.

23:02 alexbaranosky: devn: its tough to say

23:02 devn: I need some time to let my excitement die down so I can see the issue a little more clearly

23:03 because write now I'd say that I think they make sense... I can only think of one modern language that doesn't have some form of super-string

23:03 devn: Data helps. You could pull down a bunch of clojure toolbox projects and document escaped characters and do a little math to see how common the problem is with mainstream libraries.

23:03 alexbaranosky: devn: darn good idea

23:04 let me write that one down to do another time

23:04 devn: I mean, it's going to be a gradient. Granger's example is on one end clearly. There are many, many other examples on the other side of that gradient.

23:05 jweiss: amalloy: does the fn symbol in the meta need to be explicitly changed to clojure.core/fn ?

23:05 clojurebot: clojurebot is not very good at indicating the difference between a return value and an exception

23:05 devn: To assess the value it would be helpful to see how many escapes are common in certain contexts or situations.

23:05 jweiss: that's the only way i can see getting stack overflow - if it expands infinitely

23:05 amalloy: i don't think so, because it should be quoted, not evaluated

23:05 alexbaranosky: these kinds of strings are not useful most of the time. Does something have to be useful a lot of the time to be added to Clojure? or, just really nice to have when you run into certain issues?

23:05 amalloy: sure, it's clearly expanding infinitely

23:06 devn: alexbaranosky: Edge cases are edge cases.

23:06 jweiss: amalloy: how can the values get set in the let, if it's not being evaluated

23:07 devn: That's not saying they aren't worth considering. But they're *edge* cases, so my suggestion is to get a handle on the value by showing common contexts where heredocs would be useful.

23:07 amalloy: the let part needs to get evaluated, but not the body

23:07 alexbaranosky: yeah, that's a great idea, which I will do

23:08 on another note, programming is so much fun. I'm working on making midje's tabular tests not need to use variables that start with '?' -- tabular actually works, but something sneaky is causing stackoverflows in other constexts

23:09 devn: alexbaranosky: cool. objectivity wins in this community, even if it doesn't. by that I mean, if you spend a bunch of time and realize the number of people who actually need heredoc is incredibly low, then you lost, but you also are passing on some valuable knowledge to the rest of the community. no shame in being wrong, and all of that.

23:10 alexbaranosky: devn: I love that about Clojure. Its probably my favorite thing, the way people in general are really trying to do what is best... and sometimes it happens that your ideas weren't the best, no big deal

23:10 devn: it was posted on the ML, but this is not the first conversation about heredocs, so try and get that conversation to some sort of conclusion, whether it means no heredocs or it means heredocs everywhere.

23:10 that's my opinion anyway...

23:12 alexbaranosky: same here, i routinely think "don't lose your head, be lazy, defer evaluation, think." ;)

23:12 not sure I would have gotten on that process train without this community.

23:13 alexbaranosky: I mean Clojure has to be willing to reject ideas... the alternative would be much worse

23:13 devn: it's a good one. it keeps people honest. honesty makes society work. honesty keeps things moving in the right direction. pure functions are truth. truth matters. </rant>

23:14 anyway, you'

23:14 alexbaranosky: "pure functions are truth. truth matters." that's deep

23:16 devn: anyway, you're getting shit done, or not. just do what's right and think hard about it, make graphs and present data. everyone's programming language will be better for it.

23:17 and yeah, I'm feeling philosophical, but mainly I'm just the village idiot in this community. :D

23:18 alexbaranosky: devn: I'm not sure what that make me in this community

23:19 ambrosebs, thanks for the pointers on twitter

23:19 ambrosebs, I'm inching closer to getting the tabular variables working correctly without the '?'s

23:19 amalloy: ugh, this is just like having nested backticks, except one of them is invisible because you're printing to a string and then eval-ing it

23:20 so hard to keep straight

23:20 ambrosebs: alexbaranoksy, could you give me a link to what you're trying to do?

23:20 alexbaranosky: yes sure

23:20 ambrosebs, issue is here: https://github.com/marick/Midje/issues/70

23:20 devn: alexbaranosky: "eager" is probably fitting. it's cool to see you in IRC and on the ML post-conj. It's encouraging. Stay thirsty my friend.

23:21 alexbaranosky: I was never an IRC guy

23:21 for no particular reason.. just wasn't

23:21 ambrosebs: Does it make sense to call ClojureScript functions from Clojure?\

23:21 I want to play around with ClojureScript from the comfort of Clojure

23:21 alexbaranosky: ambrosebs, also, the branch I've pushed has one commit: https://github.com/marick/Midje/commits/no-q-tabular

23:21 ambrosebs: specifically the clojurescript compiler

23:22 zackmaril: What's the keyword for binding the parameters of function all together?

23:22 devn: ambrosebs: to what end? My immediate feeling is no, but I suppose it's just a different entry point.

23:22 zackmaril: Something like (defn [ a b :as args] blah)

23:22 devn: ambrosebs: if you want to play with the compiler it's probably not a bad idea, but you may as well have both sides up so you can watch what happens when you change things.

23:22 ambrosebs: devn: feed clojure code into the cljs analyzer and play with the map it returns

23:23 alexbaranosky: devn: thanks for the encouragement, btw

23:23 devn: alexbaranosky: :) know when to hold em, know when to fold em, and all that jazz -- I'm the Jack Handy of IRC

23:23 adamesterline: Anybody seen an exception like this: "java.lang.IllegalStateException: Attempting to call unbound fn". It occurs when invoking a this servlet from jetty (https://gist.github.com/1407977). Interesting enough... this same thing works when using gen-class. Any ideas?

23:24 devn: ambrosebs: that doesn't seem crazy to me. why the paranoia? just feels wrong or unfamilliar or something?

23:24 amalloy: jweiss: https://gist.github.com/1407984

23:24 ambrosebs: devn: I haven't touched ClojureScript :)

23:24 devn: ambrosebs: read core.cljs

23:25 ambrosebs: devn: I've done some reading, but I want to set up a leiningen-like project and start some prototyping

23:25 devn: how? :P

23:25 spoon16: any great libraries for making HTTP requests from clojure?

23:26 devn: ambrosebs: seriously. it's really interesting. read it all the way through. then step up and start looking at the compiler. read the google closure o'reilly book.

23:26 "You know, the one with the bird on the cover.

23:26 "

23:27 spoon16: https://github.com/mmcgrana/clj-http

23:27 spoon16: devn: thanks

23:27 amalloy: zackmaril: you can only use :as if they were already a list to begin with - the args to a function never were

23:28 you could write (fn [& [a b :as args]]), but then you lose checking/dispatching on argument count

23:28 devn: spoon16: there are others. do you know about clojars? the search isn't grep but http should be easy to search

23:29 spoon16: devn: yeah, I know about it, but I haven't trained myself to use it for search yet… good idea

23:29 devn: spoon16: http://clojars.org/search?q=http

23:30 ambrosebs: devn: from what I've seen from the Compiler, ClojureScript is genius

23:30 zackmaril: amalloy: figured that I might be asking for a bit much. Already worked around just hoping it could save time in the future. Thanks

23:30 ambrosebs: devn: but right now I'm mostly interested in utilizing the analysis phase for type checking

23:31 devn: ambrosebs: clojurescript is still pretty young. if you want a really fun ride start at the first commit on github and just walk through.

23:31 it's a really fun journey to the announcement

23:32 drewr: spoon16: this is the maintained version https://github.com/dakrone/clj-http

23:32 ambrosebs: devn: In Clojure, I'd just create a leiningen project. What should I do with ClojureScript?

23:32 devn: drewr: thanks.

23:32 ambrosebs: devn: :) will do

23:35 devn: ambrosebs: I have a bit of a weird setup. For a long time I was just using the cloned source and doing things by hand.

23:35 Today I'm using the cloned source and doing everything by hand, but with a browser repl. ;)

23:35 ambrosebs: right, I've got a cloned source. what commands do I need to know?

23:36 devn: ambrosebs: honestly I can't say with any amount of certainty that what I'm doing is efficient or "correct" because I've seen some fancy setups

23:36 ambrosebs: devn: I don't care for fancy right now

23:36 devn: ambrosebs: if you follow the getting started docs it should be enough to get you rolling

23:36 ambrosebs: devn: sweet

23:37 devn: ambrosebs: if you have any issues ping me though. if you use emacs check out the inferior lisp docs.

23:39 ambrosebs: I was planning to use inferior lisp (usually I'm a vimmer) .. is this what I want? https://github.com/clojure/clojurescript/wiki/Emacs-%26-inferior-lisp-mode

23:39 devn: the docs on the wiki are a little different from what i do: M-x set-variable [RET] M-x set-inferior-lisp-program [RET] (type the following with quotes) "path/to/my/repljs" [RET] M-x inferior-lisp

23:39 ambrosebs: devn: sweet, I'll give it a shot

23:40 devn: ambrosebs: happy clojuring :)

23:40 g'night

23:40 ambrosebs: devn: cya

23:54 dnolen: ambrosebs: using the ClojureScript compiler to analyze Clojure definitely sounds like a good idea - cgrand was talking about doing something along these lines

23:56 ambrosebs: dnolen: please tell me if I'm being dense, but I just want to add the CLJS compiler as a dependency from Clojure and just call the compiler. How do I do this :/

23:57 dnolen: ambrosebs: not following. why do you need to call the ClojureScript compiler?

23:57 don't you just want to deal w/ the analyzer?

23:58 ambrosebs: right, basically I like my Clojure setup, do I have to change my entire environment to play with analyzer, or can I play from the comfort of Clojure?

23:59 dnolen: ambrosebs: you could use the CLJS analyzer on CLJ, but of course anything JVM related will be missing.

23:59 ambrosebs: dnolen: I just want to experiment with what the meat of a type checker might look like

Logging service provided by n01se.net