#clojure log - Dec 14 2012

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

0:02 Raynes: Stencil is also much faster, IIRC.

0:08 dabd: if i call (do (clojure.java.shell/sh some-external-command) (foo result-from-external-command)) how can I assure foo will not be called before the external command terminated?

0:09 lucian: dabd: afaik .../sh will block until the command finishes

0:16 dabd: lucian: thanks, I will try it

0:45 vsync: TimMc: nice meeting you sir

0:54 Raynes: You don't know him well enough.

2:13 devn: hello fellow clojurians

2:13 Raynes: good day, sir

2:14 Raynes: devn: Heyo

2:14 devn: rbranson: Richard Branson? Do Clojurians get a discount Virgin Air rate?

2:15 Raynes: whatcha working on?

2:15 Raynes: devn: A new html transformation library.

2:15 devn: cool!

2:15 Raynes: It even has a cool name, laser.

2:15 devn: oh man, i love lasers

2:15 im going to use this library of yours

2:16 Raynes: lol

2:16 devn: speaking of which, there's this logging tool that has a great line on their homepage

2:16 http://graylog2.org/

2:16 "Manage your logs in the dark and have lasers going and make it look like you're from space."

2:16 best tagline ever

2:20 Raynes: Nice.

2:23 devn: https://github.com/Raynes/laser

2:25 benedikt: Is there a simpler way to write small programs with cljoure than lein? Something that doesn't require a "project"?

2:27 Raynes: You usually want a project.

2:28 benedikt: Not me. I think that's more of a personal preference then a technical dependency.

2:28 Raynes: https://github.com/mtyaka/lein-oneoff but it hasn't been updated in quite a while.

2:28 Well, not really.

2:29 All of the tools in Clojure's eco system are based around projects.

2:29 So from a technical standpoint, you usually want a project.

2:29 benedikt: Not if i want to write a simple single-purpose program

2:29 Raynes: You're missing the point. :p

2:29 I'm just saying that you might find it hard to do things without a project.

2:30 Your reason for doing it may be perfectly valid.

2:30 Clojure isn't really suited to one-off scripts like that.

2:30 benedikt: Ah

2:30 But if lein manages dependencies system-wide, then whats from stopping me using a clojure process that knows where lein stores its stuff?

2:30 Raynes: The JVM has a large startup time, and that's the biggest problem for shell scripty things.

2:32 Oneoff is probably what you want, but it hasn't een updated to work with lein 2. :(

2:32 benedikt: Yes, and nobody uses Java for scripting.

2:35 Raynes: devn: I'll give you a cookie if you actually do use laser.

2:38 benedikt: Raynes: so you mean that the way clojure (and implicitly java/jvm) makes clojure sub-optimal for those "quick and dirty" things anywaysÐ

2:38 s/Ð/?

2:39 Raynes: If you need it to start up fast, Clojure isn't the right tool for that job.

2:39 Which is why I hope Clojure implementations on other platforms mature.

2:39 There is a very immature Ruby implementation with decent startup speed.

2:39 There is also a Python one, but it is pretty slow to.

2:39 benedikt: I was more thinking like if i were to solve a project euler problem or something of the likes

2:40 There is a python implementation of clojure?

2:40 Raynes: too*

2:40 $google clojurepy

2:40 lazybot: [halgari/clojure-py · GitHub] https://github.com/halgari/clojure-py

2:40 benedikt: wat

2:40 Raynes: Indeed.

2:40 Not sure if it is still active.

2:40 Hah

2:40 Looks like yes

2:40 Last update 4 hours ago

2:40 benedikt: does this mean that it has Python interlope and not Java interlope?

2:41 Raynes: Yes.

2:41 benedikt: Curious

2:42 (Sidenote: why are java programs faster to start than clojure? Is it because clojure has to be loaded to a jvm every single time?)

2:42 ivan: you just need a fast-starting client to interact with a running JVM

2:42 Raynes: Java programs don't start much faster.

2:42 benedikt: I havent used Java in a while..

2:42 amalloy: Raynes: java programs start a lot faster

2:43 Raynes: amalloy: Any benchmarks?

2:43 It doesn't surprise me, but I'd be curious to see the numbers.

2:44 benedikt: I wonder if this is a lexer+parser+tac generator

2:44 amalloy: Raynes: i wrote a demo in java that spins up ten threads that do a thousand additions each - ie, basically nothing. `time java Threaded`: 0.053s

2:44 akhudek: You can massively improve the startup time of a large clojure program by AOT compiling the entire thing.

2:44 benedikt: probably not tac, but python as intermediate language

2:44 amalloy: `time lein repl < /dev/null`: 8.051s

2:44 Raynes: lein repl is a horrible command for checking startup time, amalloy.

2:44 amalloy: yeah yeah

2:44 Raynes: It spins up like 20 java processes.

2:45 Use lein version for that sort of thing.

2:45 amalloy: 2.67s

2:45 java is still fifty times faster

2:45 Raynes: Well, life sucks.

2:46 ivan: Drip-like things are nice but not really a panacea.

2:46 What'd be great is to not have to do hacks.

2:46 benedikt: `time clojure < /dev/null` 2.2s

2:49 ivan: Raynes: multitenant JVM, assuming it is smart enough to share the JITed code

2:50 akhudek: amalloy: wait, how is that possible, just running the java binary with no program takes longer than 0.053s

2:51 amalloy: akhudek: for me, that takes 0.09s. presumably it loads some classes that do i/o or whatever to decide on the version/help output, which aren't loaded for my simple program

2:51 echo-area: Doesn't setting up Clojure runtime require at least ~2 secs?

2:51 akhudek: huh, amazing. I had no idea Java could start up an actual program that quickly.

2:52 echo-area: At least it requires here.

2:52 ivan: you can make Clojure start faster by turning off bytecode verification

2:52 Raynes: amalloy: Why do people complain about slow jvm startup time then?

2:52 ivan: and giving Intel more money

2:52 akhudek: Raynes: oh yes

2:52 Raynes: If it is that fast, it looks like the problem is Clojure startup time.

2:54 akhudek: I'm assuming that amalloy's example was fast because it didn't load the majority of the java library

2:54 Raynes: We should just never load anything ever then.

2:54 Just write programs that can only do (+ 1 1) and we should be fine.

2:55 amalloy: Raynes: 0.05s for a fork is pretty slow, even if we assume all programs start up that quickly. `cat < /dev/null` takes just 0.002s

2:55 benedikt: If you time "lein version", how are you then timing the perforance of clojure itself? And doesnt the high timings for "lein repl" indicate that it is way too bloated?

2:56 Raynes: Well, this is how people start Clojure in most situations.

2:56 That 'clojure' script you've got doesn't have anything to do with Clojure (Clojure doesn't ship with a command-line interface like it or lein).

2:57 Whoever made whatever package you got that from put it in there. That's why everybody tells newbies to not bother with Clojure in their package managers and just get lein instead.

2:57 benedikt: I know. But i think it might be a indicator that "lein repl" needs to be looked at, it might be too bloated.

2:57 Raynes: But it is true that since lein does other things there is some overhead, but `lein version` doesn't have much.

2:57 benedikt: The "clojure" command, comes from the clojure package for ubuntu

2:57 Raynes: The reason lein repl is slow is because it starts up subprocesses.

2:58 Yeah, those packages are generally useless.

2:59 I wish Clojure packages would just install Leiningen instead and get it over with. :P

2:59 It's the end result anyways.

3:00 benedikt: lein needs to be packaged for debian/ubuntu/fedora

3:00 Raynes: cemerick: You seriously cannot be up this early.

3:00 It does indeed.

3:00 benedikt: It somehow outside of the linux ecosystem, which is a very very very bad thing for ti

3:00 it*

3:00 Raynes: It's hard to package it, but there are some people working on it IIRC.

3:01 cemerick: Raynes: Just got home from Boston.

3:01 Raynes: I thought you lived in Boston?

3:01 You do have a home, right?

3:02 cemerick: I live ~2 hours from Boston

3:02 * cemerick is a nomadic Clojure gypsy

3:03 Raynes: cemerick: I did this https://github.com/Raynes/laser

3:03 benedikt: But i'm rather new at this whole clojure thing so there are probably (good) reasons for all this weirdness

3:06 cemerick: Raynes: will look; stumbling towards bed

3:06 Raynes: lol

3:07 Obviously too old for that stuff, cemerick.

3:07 cemerick: hah

3:07 whatever man, I close parties ;-P

3:40 dabd: how do i clean the cache of a core.memoized function?

3:50 bbloom: dabd: (source memoized) suggests that you can't

3:58 ivan: dabd: perhaps something on (meta your-memoed-func)

3:59 source suggests it's :unk on the metadata

4:22 echo-area: So it seems that priority-map can be used as either a priority-queue or a linked-hash-map

4:24 Is it then not necessary to implement such data structures as PersistentLinkedHashMap in Java?

4:28 mindbender1: Are there any examples out there or projects that demonstrate strong usage of PersistentQueues

4:31 echo-area: mindbender1: I recently implemented a task manager, managing tasks as persistent queues. It is not public though. I find a persistent linked hash map or similar is necessary to describe it functionally

4:34 mindbender1: echo-area: I really need to see something that was done with queues.. any other directions since yours is not public domain

5:27 fredyr: `Clojure is not a good language for using frameworks`

5:27 what's the reasoning behind this?

5:28 it's from the first comment on HN for Moving away from Noir

5:28 http://news.ycombinator.com/item?id=4918720

5:32 p_l: maybe the author experienced soemthign similar to what CL programmers often feel :D

5:32 fredyr: hah

5:32 from the way he wrote it seemed to me it was some kind of general knowledge in the clojure community

5:33 ejackson: fredyr: yes its that. The idea is to use small composable abstractions, rather than monolithic frameworks

5:33 so something like Rails is not what Clojure aims for, rather its a bunch of small libraries that do one thing well, and that can be combined

5:34 AFAIK, anyway.

5:34 fredyr: right, i see the difference

5:34 thanks for the explanation

5:35 clgv: fredyr: the summarized point is "built clojure libraries not frameworks". I wish I could quote the place where I read that one.

5:36 borkdude: make libraries, not frameworks (love, not war)

5:36 ejackson: fredyr: exactly as clgz says, I recall RH saying the same thing.

5:36 clgv: fredyr: libraries can be composed in ways the single library authors did not anticipate nor they needed to anticipate ut

5:36 Raynes: Libraries are composable. Frameworks are ot.

5:36 not*

5:36 fredyr: yeah

5:36 ejackson: the problem is the 'cold start' issue, for guys getting going, having a framework makes life easier.... for a while.

5:37 clgv: frameworks are only extendable limited by what the authors thought one needed to expand ;)

5:37 *extend

5:37 Raynes: https://groups.google.com/d/msg/clj-noir/AbAvQuikjGk/xTorXq83WT0J

5:37 borkdude: maybe a transition guide from noir to compojure + whatever else you need to do the same would be nice for people now left behind with Noir heritage

5:37 nightfly_: Noir feels like it's got a good job tough. I love lisps for the raw control and power, but noir really fits when you don't quite need it but want a slick site with a well understood upper bound in development that you know it fits in.

5:37 fredyr: you mean a web transition framework?

5:37 :D

5:37 Raynes: Looks like the whole deprecation thing might not last long. Already have someone who apparently wants to take Noir on. Nothing official yet though. Kinda would rather not, but *shrug*. It's open source.

5:38 nightfly_: s/tough/though/

5:38 Raynes: As long as I don't have to bother with it, I guess.

6:20 I heard ejackson lost the ability to say anything other than the word 'cheerio'.

6:20 ejackson: whato, whato !

6:20 echo-area: Is it common to use *compile-files* to mimic eval-when-compile?

6:21 Or, is it idiomatic?

6:22 ejackson: Raynes: I'm not a substitute cemerick to pick fights with :p

6:24 clgv: echo-area: I only used it on the repl when I wanted to investigate the bytecode...

6:26 echo-area: clgv: I'm having an issue with our build system, which is not under my control. I'm loading ssh identities with clj-ssh, but somehow the build fails in the system. So I want to disable the evaluation of some top-level code.

6:26 clgv: BTW, by investigating the bytecode, what do you mean?

6:27 clgv: echo-area: decompiler oder bytecode viewer

6:27 *or

6:27 echo-area: *compile-files* set to true will compile all evaluated forms to class files

6:27 echo-area: How do you do that?

6:28 clgv: echo-area: jd-gui and "dr. garbage bytecode visualizer"

6:28 echo-area: clgv: Yes, I see when leiningen compiles projects it invokes `compile', which sets it to true. And I need this trick to make compilation work for the build system I'm using.

6:29 clgv: Okay, will look into those tools, thanks.

6:29 clgv: clgv: the second is an eclipse plugin

6:30 echo-area: Hah, okay

6:31 I guess using *compile-files* for this purpose won't hurt though

6:33 clgv: echo-area: since clojure.core/compile does the same thing it should work. can't you use clojure.core/compile yourself?

6:34 echo-area: clgv: I'm afraid not, it is part of lein jar

6:34 clgv: echo-area: no. I explicitely talked of clojure.core/compile

6:35 thats part of the clojure.jar ^^

6:35 echo-area: I know, you mean I do clojure.core/compile manually instead of doing lein jar?

6:36 clgv: erm what? what exactly is the workflow you want to accomplish? which dependencies are (not) allowed?

6:38 echo-area: The system invokes a script provided by me, and I do `lein jar' in it. Originally, when compiling, some top-level form trying to load ssh identities fails to pass compilation.

6:39 clgv: echo-area: sounds like a programming error when you load those ssh-identities top-level

6:40 echo-area: What is the suggested way to fix it?

6:40 The ssh identity files on the building host seems incorrect

6:42 In fact I didn't do nothing, only calling JSch's declared methods

6:42 Indirectly through clj-ssh of course

6:54 clgv: echo-area: why is there any ssh programmlogic executed on compilation?

6:54 echo-area: probably you have global variables which would be there error here

6:56 echo-area: clgv: Yes, I have a Var there, and I add identities into it at the top-level. My intention is to add identities when the class loads. Is there any better option than top-level forms?

6:58 clgv: echo-area: if you really need it global, define the var and create an init function that is used before any ssh-operation is done

6:58 echo-area: But that needs to be only done once. I.e. I need a static semantic.

6:59 clgv: though I really wonder why the code is executed on compile time....

6:59 echo-area: Similar to a static block in Java

6:59 clgv: Because these are top-level forms?

7:00 clgv: yeah but that static block seems to be the problem. since the namespace gets loaded and thus the static block executed

7:00 mynamespace$init or such^^

7:00 echo-area: Oh I see.

7:01 clgv: echo-area: If I were you I would fix the initilization so that it happens once at runtime and not create a non-standard obscure build process ;)

7:02 echo-area: clgv: I see. I'll make such a fix, thanks. Anyway got to go, see you later.

8:01 tomoj: is it a user error if f returns a map in (r/mapcat f)?

8:04 joegallo: tomoj: i suppose that depends on what you want back from mapcat. if you want a lazy-seq of map entries then that would perfectly fine.

8:04 if you want a map, well, then that won't work out very well for you...

8:07 tomoj: I mean clojure.core.reducers/mapcat

8:07 so I want a reducer

8:08 joegallo: oh, my bad. i have no idea.

8:14 tgoossens: I've always found the word "business logic" a bit vague. How would you describe it?

8:17 borkdude: "A customer can have only one account", "A client can never buy anything if his credits are 0 or below", etc

8:21 I'm going to attempt converting my noir site to compojure

8:22 p_l: tgoossens: business logic is the top-level stuff that you're actually trying to accomplish :)

8:22 borkdude: when running the server I get this: https://www.refheap.com/paste/7582

8:23 vijaykiran: borkdude: do you have lein ring plugin installed in profiles or project.clj ?

8:24 borkdude: vijaykiran this is my project.clj (I still have to sort out if all of these libs are compatible..) https://www.refheap.com/paste/7583

8:25 vijaykiran shouldn't I specify somewhere that it's supposed to run on jetty?

8:27 tgoossens: p_l: so you mean that. you want to separate your data from the actions you can do on them (something that OOP combines into one construct: a class) ?

8:27 Joreji: Hello everybody. I have a clojure library that depends on some native libraries, so I figured I'd make a library with the native .so files and deploy it to clojars. But the transfer fails, both over ssh & http. Does anyone know whether there is a there a file size limit for uploads to clojars (the jar is 28mb large)?

8:27 p_l: tgoossens: Classes are, frankly speaking, orthogonal to OOP ;P

8:27 vijaykiran: borkdude: hmm - I just pasted your project.clj, and it worked fine for me

8:28 borkdude: AFAIK, lein ring server is going to jetty

8:28 p_l: tgoossens: but in general, business logic means "what the program is going to accomplish + and rules it has to follow", an abstract design

8:28 vijaykiran: borkdude: could be some missing/messed up maven downloads

8:29 tgoossens: p_l: can you expand on the orthogonal part ?

8:30 you probably mean that OOP is about working with actual objects rather than classes

8:31 p_l: tgoossens: OOP can be done with normal functions and still be OOP

8:31 though actually the original OOP concepts involved Actors, not classes

8:32 borkdude: vijaykiran this is the output of lein deps :tree, I see no jetty jar https://www.refheap.com/paste/7584

8:33 tgoossens: if that all is true, then i got taught OOP in a completely wrong way

8:33 vijaykiran: borkdude: I think the jetty dep comes from the plugin, not from the project deps

8:33 borkdude: vijaykiran ah right

8:34 vijaykiran: borkdude: may be a lein clean and lein ring server again might help ?

8:35 borkdude: vijaykiran yeah that helped

8:35 tgoossens: p_l: i was taught that OOP was all about classes, inheritance, mutating etc. Can you give me some references so I can investigate your statements?

8:38 borkdude: where do you host your website. Where i currently host my websites they don't support for clojure, java

8:38 borkdude: tgoossens I used Heroku for some experimentation and now have a VPS at directvps.nl

8:38 p_l: tgoossens: read about Alan Kay's Smalltalk. Kay was one of the coiners of the term "Object Oriented"

8:39 borkdude: tgoossens Heroku is really easy, but it takes some time to get up on first use (free account)

8:39 tgoossens: p_l: thanks

8:39 borkdude: tgoossens I mean deploying is easy

8:39 p_l: tgoossens: and yes, you were taught a certain, narrow-minded school of programming that calls itself OOP :P

8:40 tgoossens: p_l: so what i'm taught is a subset of what OOP is about then?

8:40 p_l: tgoossens: funny thing, Object Management Group so far managed to testify CLOS (Common Lisp Object System) as the one that actually fit all their requirements... or so I recall

8:40 tgoossens: or an extension

8:40 it intersects with it, definitely :)

8:40 tgoossens: :)

8:40 I never heard of the Object Management Group before

8:41 vijaykiran: OMG :)

8:41 p_l: for example, I prefer to use protocols/interfaces/types/whatever-it's-called-in-this-language instead of inheritance, especially if I'm forced into single-inheritance and thus can't compose objects (which is wtf-worthy)

8:42 vijaykiran: OMG - who brought us CORBA too :)

8:43 borkdude: Gradually upgrading to compojure: Caused by: java.lang.RuntimeException: Unable to resolve symbol: defpartial in this context :-D

8:44 I guess the best way to get rid of defpartial or to just use defn?

8:46 vijaykiran: borkdude: I'm guessing defpartial is from noir ?

8:46 tgoossens: p_l: but i still can't imagine me going to my professor and saying, "hey that thing you are teaching my isn't OOP actually". Isn't it possible that the meaning of OOP has just evolved to what i'm thought?

8:46 p_l: tgoossens: more like was compromised and taken over ;)

8:46 borkdude: vijaykiran yes, I think it's just defn under the hoods

8:47 vijaykiran: borkdude: oh, yeah https://github.com/noir-clojure/noir/blob/master/src/noir/core.clj#L103

8:47 tgoossens: p_l: if we continue on that. Then aren't my previous statements true?

8:47 vijaykiran: borkdude: looks like you can just copy the macro to your project :)

8:47 borkdude: lol

8:50 p_l: tgoossens: depends on whether you accept that state :)

8:54 borkdude: is it really recommended to use lib-noir, or just go for other ways of session storage after noir?

8:54 I will first remove every reference to noir and see where I get

8:58 hmm, I do I comment out a giant block of code in Eclipse CCW? I run into all kinds of intteresting questions today =)

9:00 josteink: hm

9:00 http://blog.raynes.me/blog/2012/12/13/moving-away-from-noir/

9:00 well I'll be damned

9:00 Raynes: so long and thanks for all the fish, I guess ;)

9:02 borkdude: josteink this is just a way to create more consultancy work in clojure world - I'm now trying to become an expert on porting noir to compojure and then hopefully get a paid job :P

9:02 josteink: heh

9:35 TimMc: cemerick: Thanks for the book! I can see I'm going to get some good stuff out of it.

9:36 cemerick: ...but it just occurred to me: Wouldn't the person in the room who knows the *least* Clojure trivia get the most out of a free book? :-P

9:36 solussd: is it possible to add metadata to an object that isnt copied when new versions of that object are created (e.g. a map with metadata where an assoc operation yields a new map without the metadata)?

9:37 cemerick: TimMc: Perhaps, perhaps. That's why the first Q I asked was not Clojure-related!

9:37 I suppose I should start building up a repertoire of appropriate trivial questions for when I'm giving away books :-)

9:45 ambrosebs: I've put a brief rationale in Typed Clojure's readme (under Rationale). Any comments? https://github.com/frenchy64/typed-clojure

9:50 It's meant to bring ppl who've never heard of Typed Clojure & gradual typing up to speed.

9:50 ..without reading a dissertation :P

9:51 Joreji: Does typed clojure add type hints?

9:53 ambrosebs: No. There's currently no way to interface with the compiler.

9:53 It can *infer* type hints, sure.

9:54 Joreji: Too bad :-(

9:55 ambrosebs: Yes, but I'll be pushing for something to allow that in the coming months. Some cool stuff going on with CLJS compiler.

9:56 Probably a long time before we'll see the benefits in Clojure though.

9:56 Joreji: Ah, that's nice to hear!

9:56 ambrosebs: Perhaps wait for Clojure 2.0

9:56 ;)

9:56 Joreji: Will do :-)

9:56 borkdude: how do I redirect in compojure?

9:56 Joreji: For now, if I want typing, I'll go to scala ^^

9:57 ambrosebs: A valid choice :)

9:59 vijaykiran: borkdude: isn't its ring/utils redirect ?

9:59 ambrosebs: If you're curious about what TC *could* be, boot up Dr Racket and try some Typed Racket.

9:59 incredible stuff.

10:00 borkdude: vijaykiran ah, tnx

10:10 mpenet: ambrosebs: some would argue that it helps in the design phase, starting from type definitions, signatures, data driven development I think?

10:11 ambrosebs: maybe it's not the right term in the clojure context

10:13 ambrosebs: mpenet: sure. I guess I was after more objective truths. Clojure ppl have done fine without types so far.

10:13 Certainly TC allows you to design with types.

10:16 It'll be interesting to see if people actually do.

10:18 mpenet: I think clojure folks are more after the compile time checks and maybe later optimisations (at least for now), but it is already huge imho. I can't count the hours I wasted on stupid bugs that could have been caught by static typing.

10:20 and the effort is minimal compared to writing tests (not that it replaces it)

10:22 ambrosebs: Ya. Clojure runtime errors suck.

10:22 *type errors

10:26 cemerick: ohpauleez, lynaghk: what a tool; disregard the second Q in my email, I didn't look at the subject of the event :-P

10:28 ohpauleez: To all - anyone have questions for lynaghk (Kevin Lynagh), myself (Paul deGrandis) or cemerick (Chas "Clojure Godfather" Emerick) -- Mostly Lazy podcast

10:28 anything except when vs if

10:28 cemerick: lol

10:28 ejackson: How bout <SPC><SPC> vs <TAB> :)

10:29 ohpauleez: haha :)

10:29 ambrosebs: bbloom: where does cljs-cps fit in with the compilation pipleline?

10:29 when is the AST transformed?

10:29 and where does it go?

10:30 ohpauleez: ambrosebs: I believe the idea is to introduce a new optimization phase after the initial AST is produced. I'm not sure if that's the case with bbloom's cps transformer or not

10:32 ambrosebs: I didn't think there was a way to make such phases.

10:32 Could it integrate with normal compilation?

10:33 ohpauleez: you mean in the same pass?

10:34 ambrosebs: I mean, how much can compilation be customised currently?

10:35 ohpauleez: no idea - but we're hitting a few areas where optimizations could be applied. Making the compilation size even smaller, cps, etc

10:35 and I expect more to come

10:36 ambrosebs: right. AFAICT these are just the optimisation phases, without being integrated into compiler?

10:36 Which is basically what Typed Clojure is currently.

10:37 ohpauleez: ah, I understand what you're saying now

10:38 creese: I'm wondering about the Right Way to handle AJAX calls in clojure.

10:38 ohpauleez: I don't know the implementation details of each specific approach, I'm just reporting on the discussion I've witnessed so far.

10:38 crease: on the server or within CLJS?

10:38 creese: on the server

10:40 ambrosebs: I'm waiting to find out how all these optimisations phases work together.

10:40 mpenet: creese: you need to be more specific

10:40 ohpauleez: crease: Expose a RESTful interface to the resources you need to continually update in the AJAX call. If you have CLJS on client-side, use EDN as data representation and perform the AJAX call as a Remote

10:44 borkdude: to work with a ring session in compojure, I have to do this? (GET "/mypage" {session :session} (…))

10:47 cemerick: borkdude: as long as you have the session middleware in place, yes

10:47 borkdude: cemerick yeah have that. I saw somewhere the same thing, but then with [ {session :session} ], so brackets around it… syntax change over time?

10:49 creese: ohpauleez: why EDN and not JSON?

10:49 cemerick: borkdude: Hrm, I don't think that would work

10:50 borkdude: yeah, I don't think that'd be valid, https://github.com/weavejester/compojure/wiki/Destructuring-Syntax

10:51 ohpauleez: creese: You can capture more kinds of things (richer expression), but it's also extensible into your problem domain, so it's easy to capture domain-specific data too

10:52 no need to double parse out special meaning from a JSON structure

10:52 and allows you to program Clojure the whole way through

10:52 bordatoue: in clojure is do we have any thing to convert a number to binary strings similar to bin()in python

10:53 cemerick: borkdude: you mean, base 2?

10:53 bordatoue: yeah

10:53 cemerick: ,(Long/toString 5 2)

10:53 clojurebot: "101"

10:54 bordatoue: cemerick: cool, thanks

10:54 creese: ohpauleez: can you elaborate on the first half of your answer "Expose a RESTful interface..." or point me to tutorial?

10:54 cemerick: oh, sorry, bordatoue, not bork :-)

10:55 ohpauleez: better just call it HTTP lest the RESTifarians schedule a sit-in at your place. :-P

10:55 bordatoue: cemerick: you are fogiven :-)

10:55 ohpauleez: cemerick: :)

10:56 creese: ohpauleez: are we talking about a route?

10:56 ohpauleez: creese: You just need to expose a URL on your server side, that will take args for a given resource, and return you the snapshot of data you need

10:57 it should play nicely with the HTTP 1.1 methods: POST GET PUT DELETE

10:57 bordatoue: can anyone suggest what would be the best way to implement a client that connects to multiple tcp sockets with different port numbers

10:57 ip address remains the same

10:57 ohpauleez: if you go the other way (exposing remote calls over http to CLJS), then you can define your resource and API in a Clojure file, and just expose the whole API to CLJS

11:11 mindbender1: is it possible to change the working dir where a repl started

11:13 S11001001: mindbender1: depends on what you mean by "working dir"

11:13 if you mean the OS one, JVM doesn't give you this option

11:14 mindbender1: there is a system prop, I forget what, with a *copy* of the cwd in it; setting that prop does nothing but affect other users of that prop

11:14 mindbender1: What I need is to be able to change what (System/getProperty("user.dir") returns

11:15 S11001001: mindbender1: you can do that, but that's all you'll change.

11:16 mindbender1: Won't it affect where load will start searching

11:16 S11001001: no.

11:16 mindbender1: Is the only option restarting the repl in the proper dir

11:16 S11001001: if you want to affect *that*, give up on cwd and look at classloaders

11:17 mindbender1: how do we work with classloaders from clojure

11:18 S11001001: mindbender1: with clojure's java interop features

11:18 mindbender1: I've written classloaders in clojure; it's as approachable as the classloader api allows

11:18 cemerick: mindbender1: what are you actually trying to do?

11:18 ChongLi: change the cwd of the repl

11:19 S11001001: ChongLi: I think that was the solution looking for the problem

11:19 ChongLi: in ghci you can do this with :cd

11:19 mindbender1: just to have more control of where .repl is located or something

11:20 it integrates nicely with emacs ecb

11:20 ChongLi: are you saying cwd will work

11:21 hw do I execute cwd from the repl for instance

11:21 S11001001: ghci is a haskell interpreter entirely separate from clojure & jvm, mindbender1

11:21 mindbender1: oh ok

11:21 I thouhgt therre was hope

11:22 S11001001: are you using lein, mindbender1?

11:22 mindbender1: yes of course, with nrepl mixed in

11:23 S11001001: are you using C-c C-l to load files?

11:23 mindbender1: there has to be a way to do this

11:24 didn't try that.. just (load ...)

11:24 S11001001: in a clj file, you can press C-c C-l and it will load/reload it, no typing load commands at all

11:24 mindbender1: S11001001: ok will try that soon enough

11:25 gfredericks: So I am doing config via a "config.clj" file on the classpath, with environments managed by just putting a different config file in /resources at deploy-time

11:25 now I'm trying to setup automated testing, where I'll want a special test config

11:25 cemerick: mindbender1: .repl?

11:25 gfredericks: this means I want a test-resources directory?

11:25 lein doesn't seem to pick that up by default. Do I need a test profile?

11:26 mindbender1: cemerick: yes I believe that controls the working dir

11:26 or the one it starts in initially

11:27 I think that used to be the file where repl save its work

11:28 or am I getting it wrong

11:29 cemerick: mindbender1: I've never heard of .repl; it's a file?

11:31 mindbender1: I remember seeing it sometime and thought that repl used it for history

11:31 cemerick: I'm not aware of it. `lein repl` doesn't seem to create it, either

11:31 mindbender1: though it doesn't show up now.. I wa assuming

11:32 cemerick: ok think I mistook it

11:33 cemerick: any thought on the cwd thing

11:35 gfredericks: does the leiningen :resources-paths vector not specify things in the order they will be searched?

11:35 I'm trying to make my test-resources/config.clj shadow my resources/config.clj

11:35 and it doesn't seem to be

11:36 oh wait

11:36 :resource-paths instead

11:36 cemerick: ha-ha dynamic typing ;-P

11:37 * gfredericks switches to haskell where his project.clj just works

11:38 gfredericks: oh nice the test task picks up the test profile automatically

12:21 solussd: anyone using emacs-live w/ clojure and either clojure-jack-in or nrepl-jack-in experience the repl printing dozens of newlines before returning the result of a function call?

12:31 firesofmay: Hi, If I have a huge map with lot of nesting, and I only want to understand the key structure of it. And I dont want to go through the values, what is the best way to do it?

12:32 tgoossens: anyone here experience with heroku? I'm playing around with it and I'm currently unable to push (permission denied). I'm reading through the documentation. But if anyone knows already what might be wrong that would be helpful

12:32 technomancy: tgoossens: hey

12:32 tgoossens: technomancy: hi!

12:32 technomancy: can I pm you about it?

12:32 tgoossens: sure thing!

12:36 TimMc: firesofmay: So you want to throw away some, but not all of the values in a nested map?

12:36 firesofmay: TimMc, I dont want the values. I just want to understand what are the keys and its structure.

12:37 TimMc: Except some of the values in the top-level map are also maps you want to inspect, right?

12:37 firesofmay: TimMc, I can go through it manually, But I was wondering if there is a better way.

12:37 TimMc, Yeah Its a nested map.

12:37 technomancy: firesofmay: tree-seq could get you all the keys, but you'd lose the shape of the map

12:37 firesofmay: technomancy, I see.

12:38 technomancy, no way to retain the structure?

12:38 TimMc: firesofmay: If it's just a map of maps... (into {} (for [[k v] my-map] [k (keys v)]))

12:38 technomancy: firesofmay: well, not with tree-seq; sure there are ways to do it

12:38 firesofmay: TimMc, okay.

12:38 technomancy, okay.

12:39 TimMc: &(into {} (for [[k v] {:a {} :b {:c 1 :d 2}}] [k (keys v)]))

12:39 lazybot: ⇒ {:a nil, :b (:c :d)}

12:42 firesofmay: TimMc, will this work for clojure.lang.PersistentArrayMap?

12:42 TimMc: Sure, why not?

12:42 firesofmay: TimMc, Getting "Don't know how to create ISeq from: java.lang.Integer" Error.

12:42 TimMc: SOunds like an argument order error.

12:43 Are you calling nth anywhere?

12:43 firesofmay: TimMc, No, I just have a full map, and I replaced it with my-map in the function you gave.

12:43 TimMc: &(keys 4)

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

12:44 firesofmay: TimMc, (into {} (for [[k v] req-sites] [k (keys v)]))

12:44 TimMc: firesofmay: My code only works if it's a map of maps.

12:44 firesofmay: TimMc, What if it has a vector too?

12:44 TimMc: It sounds like at least one of your vals is a number.

12:44 ohpauleez: cemerick: I'm amped

12:44 cemerick: \m/

12:44 ohpauleez: oh, what for? :-P

12:45 firesofmay: TimMc, some keys have a number as a val.

12:45 TimMc: firesofmay: Add a :when clause: ##(into {} (for [[k v] {:a {} :some-number 5 :b {:c 1 :d 2}} :when (map? v)] [k (keys v)]))

12:45 lazybot: ⇒ {:a nil, :b (:c :d)}

12:45 ohpauleez: cemerick: Mostly Lazy!

12:46 cemerick: "Dedicated to discussing security issues affecting those building applications with Clojure and its variants." https://groups.google.com/group/clojure-sec

12:47 sgeo: I _think_ I'd rather have light-weight co-operative threads than heavy-weight pre-emptive threads, although light-weight pre-emptive threads would be best

12:47 I'm not sure though

12:48 TimMc: cemerick: Nice, I hope that draws some folks.

12:48 technomancy: cemerick: can I join and just bitch endlessly about how awful Bouncy Castle is?

12:48 sgeo: Bouncy Castle?

12:48 technomancy: sgeo: a suite of crypto implementations for the JVM

12:49 cemerick: technomancy: only if you bone up and produce a clean-room impl in Clojure.

12:49 technomancy: cemerick: pass

12:49 cemerick: so close

12:50 firesofmay: TimMc, technomancy thanks.

12:50 cemerick: TimMc: Me too. It'd be nice if I knew something about security stuff.

13:17 mindbender1: I have not done cljs for a while. Is cljsbuild still preferred for cljs. The repo seem kinda quiet

13:18 dnolen: mindbender1: it is still the preferred way. quiet is good :)

13:18 duck1123: nothing has been broken that needs fixed

13:20 mindbender1: ok

13:27 seangrove: Is there any negative to wrapping js api's like this: https://www.refheap.com/paste/7592

13:28 As far as I can tell, this should work fine with the minifier without any any externs, it won't get munged, and allows me to use the ns like a normal cljs ns from the rest of my program

13:31 dnolen: seangrove: so "extension" just holds plain functions - not methods?

13:32 seangrove: Well, singleton-style methods, I believe

13:32 You'd never instantiate "extension"

13:33 dnolen: seangrove: it would be a problem if the implementations of those methods use "this"

13:33 seangrove: if they don't than that's ok. using rest args + apply is a perf hit but from the looks of this API I don't think that's much of a concern.

13:34 seangrove: Well, this is used in fairly tight loops - best to map the args directly?

13:34 dnolen: seangrove: yes

13:34 seangrove: Great, thank you

13:37 cemerick: last chance for questions/topics for ohpauleez, lynaghk, and myself on Mostly Lazy

13:38 borkdude: cemerick are you on air right now?

13:38 cemerick: yup

13:40 borkdude: cemerick I mean, so we can listen? or just recording and publishing afterwards? either way, just saying I like your podcast very much and enjoy it while running

13:40 cemerick: yeah, no live broadcasting thing

13:40 skybound: I would appreciate any hints on transforming a flat list into a tree (e.g. input like '("a" :push "b" :pop "c") ); got a somewhat working solution - but it ain't pretty :-(

13:40 cemerick: we can barely get skype to work :-P

13:41 borkdude: on what topics do you expect questions right now?

13:41 cemerick: whatever. We're just riffing for an hour.

13:53 ChongLi: mostly lazy?

13:53 oh I see

13:53 nice

13:53 cemerick: ChongLi: mostlylazy.com

13:55 ticking_: isn't it super frusttrating that there is no clojurish image library?

13:56 every tie I set out to find one I end up holding myself back to not write one

13:56 technomancy: maybe that's the problem

13:56 give into your urge =)

13:56 solussd: Is it possible to add metadata to just an instance of an object that isn't copied when operations are performed on the object? E.g. If I have a record and I perform an assoc on it, the new record has the same metadata. Is it possible to make that no so? :)

13:56 jkkramer: shave that yak

13:58 ticking_: yeah ^^but the time the time

13:58 jkkramer: the only image stuff I've needed is read, write, and resize, which I wrote some simple clojure wrappers to handle

14:00 ticking_: jkkramer: hm, not on your github^^

14:00 jkkramer: ticking_: https://gist.github.com/3959731

14:00 need to bundle it into a library sometime...

14:01 was waiting until I needed it in more than one project

14:01 seangrove: cemerick: State of cljs, the ASt, bbloom's cps-transform project, lots of interesting stuff to riff about ;)

14:01 ticking_: jkkramer: hrhr yeah I thought of using scalr too ^^

14:02 jkkramer: but the stuff I do to the image still requires a bit more functionality, like contrast, grayscaling, binarization

14:03 jkkramer: ticking_: I believe Scalr supports custom image operations, but I didn't dig into it much

14:04 ticking_: jkkramer: yeah but thats kinda the point, the stuff is there (like imagej) but it's not pretty (like imagej which loads 90% of AWT UI elements)

14:06 jkkramer: I punted and shelled out to graphics magick for a scala project

14:07 ticking_: hrhr

14:07 dnolen: tbaldridge: btw, I liked the bytecode core.logic video - can you explain a little more what you're trying to do - the advantage w/ the approach you're taking?

14:08 tbaldridge: on a call, give me a few min

14:27 @dnolen: the goal with my project is to explore how to rewrite the clojure-py bytecode assembler using core.logic.

14:28 dnolen: tbaldridge: yes I understand that - but what's the benefit? or you're just having fun w/ core.logic? :)

14:29 tbaldridge: The problem with many of the existing designs is that they are basically a hairball of imperative code. For instance, source mappings are basically consist of pairs of two bytes, (delta in bytecode, delta in sourcecode). Writing this sort of thing ends up with code like this:

14:29 http://code.google.com/p/byteplay/source/browse/trunk/byteplay.py?r=19

14:30 Thus far I've found it much easier to express as sets of constraints, then actual actually walking step by step through every bytecode.

14:33 dnolen: tbaldridge: I see, I guess I'd be concerned about performance for this kind of task - but perhaps you haven't found it to be an issue? (related I've been starting to ponder how tom make defne & conde's, etc more efficient if we have ground values)

14:34 tbaldridge: One more example is jump calculation. In an if branch, we can't write the number of bytes to jump, until we emit each branch of the if. so the result starts looking like this: https://gist.github.com/4287938

14:35 Yeah, I have no clue about performance yet, so far it's pretty fast, but we'll see. That being said, these functions are normally rather small, 40-200 bytecodes, so we'll see how the performance shakes out.

14:36 What also triggered this for me was when Joe Armstrong mentioned that he's been involved in working on some super-secret Erlang on crack language. Apparently it uses gecode internally. Ever since hearing that I've been thinking how I could use core.logic more in clojure-py

14:37 dnolen: tbaldridge: gotcha, well cool stuff - looking forward to some in depth write-ups.

14:37 tbaldridge: yes he mentioned he was doing things w/ GeCode at TechMesh, I should have picked his brain some more about that.

14:38 tbaldridge: related - support for optional binding into more high performance constraints solvers (GeCode, JaCoP) is definitely worth pursuing.

14:41 tbaldridge: agreed.

14:42 ticking_: jkkramer: btw I would slap apache sanselan on there for importing and exporting it can read most image formats

14:42 tbaldridge: I found Joe's talk on the subject: http://www.infoq.com/presentations/Building-Highly-Available-Systems-in-Erlang he's working on making a Erlang VM run specialized hardware. So GeCode is probably being used for FPGA layout or something of that nature.

14:43 ticking_: jkkramer: you should seriously do that and then release it, I'll certainly contribute as I continue to use it and maybee even add more advanced functionality ^^

14:43 dnolen: tbaldridge: thx for the link

14:45 jkkramer: ticking_: cool, good to know. I'm bundling up the gist as a lib at the moment. will make note to integrate sanselan at some point

14:59 ticking_: https://github.com/jkk/purty

15:00 ticking_: jkkramer: awesome ^^, I'll send a pull request for sanselan :D

15:01 jkkramer: ticking_: excellent

15:10 ravster: hello everyone

15:14 TimMc: Quick, off the top of your head -- is 36r5e2 > 100?

15:15 (This is a question about Clojure numeric literal syntax.)

15:17 * sgeo guesses yes?

15:17 ticking_: jkkramer: I wonder if we could use some stuff from rinzelight

15:17 * sgeo tries it

15:17 ticking_: jkkramer: it doesn't have an api as nice as purty but it has some functionality

15:17 amalloy: TimMc: seems like yes?

15:17 ravster: is anyone else having nrepl.el issues where it doesn't evaluate code into the correct namespace?

15:18 amalloy: assuming that it's actually a valid number literal; i don't know what is

15:18 technomancy: ravster: yeah, the heuristic it uses is very broken =(

15:19 TimMc: amalloy: It's not obvious to me what happend when you combine e-notation with higher radices.

15:20 dnolen: ravster: yep

15:20 TimMc: although yes, radix notation precludes e-notation.

15:20 technomancy: ravster: I tried to talk him out of it and get it to use the same heuristic as slime but it currently doesn't do that

15:21 maybe opening an issue will help get it fixed =)

15:23 jkkramer: ticking_: could be. rinzelight looks pretty elaborate; more than I would ever need. might be nice to have effects like blur, sharpen. and being able to view an image

15:24 ticking: jkkramer: well, viewing images brings us back to including the entire gui framework ;D

15:24 but yeah

15:25 jkkramer: was thinking of viewing as a dev-only, runtime thing

15:26 ticking: jkkramer: hrhr sure ^^

15:30 zerokarmaleft: TimMc: man, you can really confuse the reader with literals like that

15:42 ravster: Could someone point me to a resource that explains how to organize a clojure project in different files?

15:49 TimMc: ravster: I just start coding, and pull stuff out into additional namespaces as modularity becomes clear.

15:58 stuartsierra: ravster: http://stuartsierra.com/2011/08/08/clojure-namespaces

15:59 craigbro: heyo

15:59 got a quick lein2 question

15:59 i hate uer profiles

15:59 user...

15:59 and want those plugins defined in my project

15:59 specifically immutant

16:00 I added the immutant plugin to my project.clj, but it's not available as a lein2 command

16:00 what stupid mistake did I make?

16:03 gfredericks: Is there any way to do a DROP DATABASE with clojure.java.jdbc?

16:03 do-commands sets up a transaction and postgres won't let you drop DB from a transaction

16:03 tcrawley: craigbro: how did you add it to your project.clj?

16:06 craigbro: tcrawley: in the :plugins var

16:06 :plugins [[lein-cljsbuild "0.2.9"

16:06 lein-immutant "0.14.1"]]

16:06 :hooks [leiningen.cljsbuild]

16:06 gfredericks: ah ha

16:07 craigbro: in general, I despise the lein2 user profile for plugins

16:07 i want everything in my project

16:07 gfredericks: cljsbuild and immutatnt are two different plugins

16:07 craigbro: I understand that

16:07 gfredericks: so they need to be in two different vectors

16:07 craigbro: oh, that I didn't 8)

16:07 thanks for headcheck

16:07 gfredericks: [[lcljs ""] [len-imm ""]]

16:07 that sorta thing

16:07 tcrawley: gfredericks: good catch

16:07 jsabeaudry: Any idea how I can configure the jetty connector when using noir? (I'd like to change the responseBufferSize )

16:08 craigbro: gfredericks: makes total sense when I have my brain on

16:09 all good, thanks. I knew lein2 would not force me to put that stuff in user profiles

16:09 jsabeaudry: you can pass in a configurator func

16:10 borkdude: finished porting my noir app to compojure now… no use of lib-noir

16:10 clojurebot: Why are you asking *him*

16:10 Raynes: No no lib noir?

16:10 jsabeaudry: craigbro, hmmm I guess I'll look at the code

16:10 Raynes: borkdude: Something wrong

16:10 ?

16:10 borkdude: Raynes I didn't know why I needed it =)

16:11 Raynes: borkdude: Oh, I assumed coming from Noir you already used some of its libraries.

16:11 lib-noir has the session, cookie, response, etc stuff.

16:11 borkdude: Raynes I hesitated to use the session stuff from lib-noir, but I went with ring session directly now

16:12 craigbro: jsabeaudry: http://practice-blog.herokuapp.com/posts/ring-with-ssl-only

16:12 Raynes: The session stuff in lib-noir is exactly the same as in noir itself.

16:12 craigbro: jsabeaudry: that is an example of a configurator that I use to set up ssl

16:12 Raynes: But nothing wrong with using ring session directly.

16:12 In fact, cemerick would probably plant a nice sloppy kiss on you for it.

16:12 cemerick: heh

16:13 jsabeaudry: craigbro, Great, that should be simple enough wiht your example! thanks!

16:13 ivan: stuartsierra: "At the time, Prismatic had not yet released Graph as open-source." still isn't released, no?

16:13 stuartsierra: ivan: don't know

16:13 ivan: ah, thanks

16:13 not on their github, anyway

16:13 cemerick: There needs to be a helper fn to make updating the session easier, but it's definitely my preferred route.

16:14 update-session! or whatever is *ick* and hard to test and think about

16:14 Raynes: I think that's ridiculous, but you already know that.

16:14 borkdude: cemerick Raynes I don't get why ring session stuff is considered more "functional", the session store is still a mutable thing right

16:15 cemerick: borkdude: past the boundary of the session middleware, ring sessions are purely functional

16:15 Raynes: Yes. But cemerick has a box of excuses for that one too. ;)

16:16 cemerick: The point is to try and push the frontier of unrestricted mutability outward as far as possible

16:16 Raynes: I'm surprised you don't use Haskell.

16:17 sgeo: I wish that there was some language+environment combination that I really liked

16:17 cemerick: page 81 in the book, FWIW: http://twitpic.com/blz6uk

16:18 sgeo: I like Smalltalk and Factor environments (well, not Factor's lack of ecosystem), a bit iffy on the languages. I love Haskell as a language except for icky macros, but it's not so nice for modifying a running program, and debugging can be tricky

16:18 borkdude: cemerick it is considered functional because the session map is always an updated version of the previous session map, or smth?

16:18 cemerick: Raynes: In another life, perhaps.

16:18 Gradual typing is more my speed.

16:19 Plus, no tools AFAICT. If I'm paying the static-typing tax all the time, I want killer tools.

16:19 borkdude: because handler functions are referentially transparent. Their results depend solely on their arguments, and they produce no side effects.

16:20 swap!'ing an atom is a side effect, and something you need to compensate for/mock/whatever when composing a fn performing such an action with another in a new way, or testing, etc

16:20 Raynes: Oh God, shut up.

16:20 :P

16:20 Go write a book or something.

16:21 cemerick: Zipped. :-|

16:21 Raynes: Oh wait.

16:21 You did write a book.

16:21 dsantiago: I require your assistance in telling me whether or not I'm an idiot.

16:21 Whenever you get a chance.

16:22 dsantiago: Raynes, I am responding to your issue right now.

16:22 TimMc: cemerick: Whoa, what's the bird?

16:22 Raynes: Good timing mate.

16:22 cemerick: TimMc: bird?

16:22 TimMc: Um... 91 days ago. OK.

16:22 Raynes: cemerick: I'm just kidding, love. We just like to do things differently and my way is better than yours. No biggies. Happens all the time with me.

16:22 TimMc: cemerick: http://twitpic.com/aui76e

16:23 ticking: TimMc: is that a dead falcon?

16:23 cemerick: oh, that. A sharp-shinned hawk that committed suicide against my living-room window this summer.

16:23 TimMc: ah

16:23 cemerick: Very sad. :-(

16:23 ticking: how did it taste?

16:23 Raynes: Hahahaha

16:23 ticking: Sounds like you're from the south.

16:23 ticking: you can't tell me that you wasted a perfectly good hawk

16:24 TimMc: I can't imagine raptors taste that great, being predators and all.

16:24 ticking: Raynes: germany to be exact but my grandparents are from louisiana ;D

16:24 Raynes: Had to get that from somewhere.

16:24 tmciver: It's funny to see a pic of cemerick's laughing face next to a dead bird.

16:25 TimMc: "MUAH HAHAHA

16:25 " <- sorry!

16:25 ticking: indeed

16:25 Raynes: cemerick: Is that picture meant to look like a trollface?

16:25 tmciver: TimMc: #clojure needs paredit!

16:25 ticking: tmciver: agreed

16:26 gfredericks: I tried to turn it on and it showed me a smiley and said it was an unmatched bracket or quote

16:26 borkdude: the only overhead I have now with ring sessions is: destructuring it in the compojure route and exposing it in the response map with the updated values, compared to (session/put! …) and (session/get …) right?

16:26 Raynes: cemerick: http://dc399.4shared.com/img/8w1Rixbl/s3/Asian-Troll-Face.jpg I you invert this picture...

16:27 cemerick: borkdude: You need to make sure you carry the session from the request (if it exists) into your response if you're going to update it.

16:27 dsantiago: There you go, Raynes.

16:27 ticking: cemerick: friend of mine picked one out of the wall in his office poor thing had gotten in there through the roof somehow, but he managed to nurse him back to health

16:28 borkdude: cemerick that carrying is done by (GET "/foo" {session :session}) right?

16:28 cemerick: e.g. (assoc-in ring-response [:session :your-key] "foo") won't work out well if the request session had :your-other-key in it

16:28 no, that's just *accessing* the session

16:28 borkdude: cemerick I use wrap-session

16:28 Raynes: dsantiago: Got it. Yeah, I was just experimenting. It didn't occur to me until the end that "Oh wait, some people might actually want it to be unescaped."

16:29 TimMc: ticking: Touchy business, that -- even authorized wildlife rehabilitators have to get special certification to possess raptors.

16:29 ivan: is anyone here capable of vetting http://dev.clojure.org/jira/browse/CLJ-1076 ? would be nice if 1.5 could build on Windows

16:29 cemerick: borkdude: yeah, that's fine. My only point is that, if you're updating the session, you need to carry forward the session from the request

16:29 e.g. (assoc ring-response :session (assoc (:session ring-request) :your-key "foo"))

16:29 ticking: TimMc: yeah luckily all he needed was some water and rest took him just a few hours to take of again

16:30 TimMc: Ah, OK.

16:30 cemerick: ticking: that's a bit nuts. I'd worry about getting my eyes ripped out.

16:30 i.e. if I had to handle it

16:31 borkdude: cemerick yes, that's what I did, thanks

16:31 ticking: cemerick: wan't a hawk the largest city born predator we have is that dude

16:31 http://en.wikipedia.org/wiki/Common_Kestrel

16:31 cemerick: borkdude: ok, you're good then

16:32 I used Ring sessions wrong for a solid year before being set right by weavejester

16:32 borkdude: cemerick so it didn't work for a year?

16:32 ticking: TimMc: and yeah I know I fished a raven chick out of my universities pond and nursed him over 2 days until giving him to the local wildlive rescue

16:32 cemerick: borkdude: I never noticed any issues because I was often only storing e.g. one key

16:32 ticking: TimMc: they didn't have open during the weekend and the vet said he gave him a lower than 50% chance and euthanized him but I could try ^^

16:33 cemerick: the middleware doesn't touch the stored session if the response map's :session entry is missing, or just {}

16:33 borkdude: cemerick it only kills the session when the :session value is nil right?

16:34 cemerick but using an empty session map would cause all session values to be wiped also I guess

16:34 cemerick: right, right

16:35 see, I still get it wrong :-P

16:35 A couple of helper fns in ring.util.response are needed.

16:36 ticking: TimMc: I give the healing credit to startrek ;D that bird loved enterpreise http://cl.ly/image/3h470k1c2V3A http://cl.ly/image/3g0A2j0l1w1l

16:36 borkdude: cemerick whadda you mean?

16:37 technomancy: Kestrel is another name for the K combinator IIRC

16:37 roughly analogous to clojure.core/constantly

16:37 hiredman: technomancy: identity

16:37 Raynes: dsantiago: Sounds like a great solution. Most people probably want unescaped

16:38 dsantiago: Raynes: Yes, I think so.

16:38 technomancy: hiredman: eh... depends how you map combinators to clojure fns

16:38 or do you mean Kestrel is I rather than K?

16:39 hiredman: technomancy: oh, no I am mistaken

16:39 borkdude: One thing I'm still struggling with is, should I store a "consumer" from clj-oauth object in session, because I need on two pages, or is that considered bad practice?

16:40 a "consumer" object from clj-oauth (wrong order), https://github.com/mattrepl/clj-oauth/blob/master/src/oauth/client.clj

16:41 TimMc: ticking: hah!

16:59 Raynes: Well, this is horrific: http://danielchoi.com/software/vmail.html

17:00 technomancy: Raynes: ouch; it complects reading, sending, and fetching, *and* recommends using rvm.

17:01 Raynes: technomancy: And it is a Vim plugin.

17:01 technomancy: and passwords in plaintext

17:01 Raynes: Kill it with fire.

17:01 technomancy: Also, Ruby + Vim + OS X = BROKE

17:01 It isn't much better on Linux.

17:02 TimMc: technomancy: But it supports contacts autocomplection!

17:02 oh wait, autocompletion.

17:02 Raynes: I spent way more time that I'm willing to admit on trying to fix broken Ruby vim support.

17:02 I gave up recently and just did the damned thing in Python.

17:02 bbloom: rvm is an atrocity.

17:02 Raynes: bbloom: rbenv users unite!

17:04 bbloom: as long as you don't load rbenv into your shell, and do the "graybeard" setup instructions, you're cool with me

17:04 the idea that you need a shell function to configure your environment is insane

17:04 TimMc: technomancy: The first thing that should horrify you is that it's a mail reader in vim.

17:04 bbloom: talk about non-composable

17:05 technomancy: TimMc: true; all vim users should already be using mutt

17:05 TimMc: I mean, if you want vmail, just use emacs.

17:06 Raynes: TimMc: I don't even want it in Emacs, bro.

17:06 bbloom: yeah, i don't really understand the draw of an email client in your editor

17:06 an editor in your email client maybe

17:06 but the other way around?

17:06 Raynes: I like postbox.

17:06 bbloom: at least with emacs it makes sense because you have an editor in your email client in your elisp os :-)

17:06 Raynes: It gives me mail, I press buttan to send mail. Easy. Don't need elisp.

17:07 technomancy: bbloom: well mutt lets you read in mutt and compose in vim; that makes way more sense

17:08 <textarea> is disgraceful for anything longer than a tweet

17:09 bbloom: technomancy: i don't really like composing prose in vim

17:09 i LOVE THE SHIT out of vim

17:09 * technomancy doubts your sincerity

17:09 bbloom: and i tried all sorts of word wrap and reformat and all the standard shit

17:09 but i hate writing prose

17:10 my brain is just wired to working with lines

17:10 (when i'm in vim)

17:10 technomancy: at least for HTML newlines don't affect the output

17:10 (not that I am condoning use of HTML email)

17:10 just that I find most non-mail prose is HTML our ends up as HTML these days

17:11 bbloom: i can't recall the last time i wrote HTML directly :-P

17:11 html is object code.

17:11 technomancy: yeah but markdown is the same way

17:11 bbloom: if i ever write prose with the goal of rendering HTML, i write markdown

17:11 technomancy: put all the newlines in you want; it won't affect the output

17:11 bbloom: fair enough, it's just that i find it awkward to write *paragraphs*

17:12 readmes and stuff are usually fine

17:12 and i write them in vim out of laziness to go else where and copy paste

17:12 but if i need to write a bunch of "realish" paragraphs, i'll open up text edit or something

17:12 technomancy: sure, and I doubt your commitment to sparklemotion^Wvim

17:12 =)

17:14 bbloom: eh, maybe i just don't do it often enough to hvae mastered the word wrap nonsense

17:15 n_b: bbloom: Have you tried the markdown.vim plugin

17:16 it's kind of funky with wrapping and occasionally I have to do grab a paragraph and do a gq, but on the whole it's sufficient for writing

17:16 much better than Word, at least

17:18 bbloom: n_b: yeah i use that plugin

17:18 ivan: value vs. place problem: the city thinks the tree in our front yard belongs to them and should be trimmed, because some other tree was in the same place 10 years ago

17:27 TimMc: ivan: Send them this article, and explain that the tree is the wrong Color: http://ansuz.sooke.bc.ca/entry/23

17:28 mpenet: I found a small difference between jvm/cljs re-* function handling: in cljs: (re-find #"foo" nil) -> nil - on the jvm NPE. There's probably a bug to be reported on one side or another?

17:29 I guess cljs is wrong to allow that, it doesn't make much sense

17:29 or is it considered platform specific behavior and remains like that

17:30 dnolen: ping

17:30 dnolen: mpenet: behavior of regexes are platform specific

17:31 mpenet: alright

17:31 dnolen: mpenet: though that doesn't mean there's isn't a bug here.

17:31 mpenet: ah

17:33 dnolen: mpenet: or not, this may just be undefined behavior for CLJS & CLJ

17:33 stuartsierra: mpenet: The JVM is stricter about nils than JS. I think it's platform-specific behavior.

17:33 mpenet: yeah it's a bit tricky

17:34 p_l: mpenet: JVM code probably does something different than JS one

17:34 mpenet: it's something that could be handled in the future by typed clojure hopefully

17:34 dnolen: mpenet: yes, re-find shouldn't take nil

17:35 mpenet: so should I create a ticket (and maybe send a patch) or do we just leave it like that

17:36 djwonk: `lein new app an_app` followed by `lein repl`raises an exception. I'm thinking there may be an underscore / hyphen confusion

17:37 dnolen: mpenet: a ticket for what? unnecessary runtime validation is not looked highly upon.

17:37 mpenet: dnolen: fine with me

17:37 p_l: IMO it should return that there were no results..

17:38 djwonk: according to http://stackoverflow.com/a/2223369/109618 "you musn't use the underscore in namespace names or the hyphen in filenames and wherever you use a hyphen in a namespace name, you must use an underscore in the filename"

17:39 dnolen: mpenet: there are quite a few annoying differences between CLJ & CLJS regexes - hopefully feature expressions can alleviate the differences for shared code bases.

17:40 hyPiRion: djwonk: There is a pull request fixing this on lein newnew

17:40 djwonk: hyPiRion : thanks. I just saw https://github.com/technomancy/leiningen/issues/865

17:40 hyPiRion: https://github.com/Raynes/lein-newnew/pull/55

17:41 djwonk: that's a catchy name

17:42 technomancy: newnew was the original name of clojure.core/reify

17:42 #historicalfact

17:42 mpenet: dnolen: Yeah I know, it is not a major annoyance anyway

17:42 technomancy: lemme take a look at that pull

17:42 hyPiRion: it's the new new.

17:42 djwonk: will it be the newnormal?

17:43 hyPiRion: then newnew turns stable, I guess.

17:43 duck1123: "just pushed a new newnew. Please replace your old nenew with the new newnew"

17:43 technomancy: head asplode

17:43 Raynes: anything else that should go into newnew 0.3.6?

17:46 bbloom: dnolen: mpenet: i wonder if for static patterns, a subset of the features could be compiled to platform specific regexes

17:47 amalloy: technomancy: wait, was reify really called newnew?

17:47 technomancy: amalloy: yeah, before it was implemented

17:48 dnolen: \me remembers

17:49 oops

17:49 http://clojure-log.n01se.net/date/2009-07-30.html#13:09a

17:50 glad that one didn't survive

17:51 bbloom: reify is just a damn good word in general

17:52 if nothing else, clojure has added improved my vocabulary with reify, complect, and simple vs easy

17:53 AimHere: Also, clojure hogs all the good function names for keywords, forcing you to use your vocabulary when writing code

17:54 technomancy: keywords?

17:54 clojurebot: http://clojure.org/data_structures#toc8

17:54 bbloom: AimHere: namespaces, one honking good idea!

17:54 technomancy: thanks clojurebot

17:55 AimHere: I meant in the sense the word is used in, say, K&R to mean reserved words that the language uses for itself

17:55 dnolen: AimHere: the number of names you can't override is quite small.

17:55 AimHere: See, that's an example right there

17:55 amalloy: AimHere: wat. clojure has a very small set of "keywords"

17:55 mthvedt: think he's talking about syms in clojure.core

17:55 AimHere: Yep

17:55 dnolen: mthvedt: syms?

17:56 mthvedt: def'd

17:56 AimHere: Names of functions in the core language

17:56 amalloy: that's totally different. the standard library is not keywords

17:56 mthvedt: technical term escapes me

17:56 interned?

17:56 technomancy: AimHere: :refer-clojure :exclude [whatever]

17:56 dnolen: AimHere: mthvedt: yes this is wrong. You can use your own names.

17:56 Sgeo: technomancy, doesn't work for special form names

17:56 dnolen: Sgeo: we already said that twice above.

17:56 mthvedt: dnolen: i know, just trying to be helpful and/or pedantic

17:56 technomancy: so what, like six words?

17:56 Sgeo: dnolen, oops

17:57 mthvedt: preferably both

17:57 technomancy: most of which have a * on them

17:58 bbloom: dnolen: i think that any name you can't override is a bug…. the clojure design wiki mentions namespacing special forms. that's a good idea we should do

17:58 S11001001: the other is /

17:58 special forms & / that is

17:58 amalloy: ,(let [let +] (let 2 3))

17:58 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:>

17:58 AimHere: Well I think it would be pretty bad style to reimplement 'car' and 'cdr' just because you want to use 'first' and 'rest' in your own program

17:58 bbloom: S11001001: the symbol foo// is fixed in clj 1.5

17:58 amalloy: aw, really?

17:58 AimHere: *rename the functions as

17:59 dnolen: bbloom: it's not something I care about much.

17:59 S11001001: bbloom: cool, when 1.5 is released I'll forget about it :)

17:59 djwonk: clojurebot wants to jump in on this convo

17:59 bbloom: dnolen: it's not a big deal, but it's a bit annoying in cljs/core.clj

18:00 dnolen: when i was exploring some AST changes, i wanted to see what happened if i overrode 'do and it just kinda blew up :-P

18:19 tomoj: what trouble would come from extending IDeref and IPending to everything, where the default deref is the identity and the default realized? is (constantly true)

18:20 other than breaking some uses of satisfies? out there

18:20 Bronsa: print-method wouldn't be happy

18:20 technomancy: it's sloppy and would shadow genuine mistakes

18:20 dnolen: tomoj: extend Object/default always needs a whopping good rationale.

18:20 tomoj: yeah, so you deref when you don't mean it and never notice

18:21 hiredman: deref is half of a monad

18:22 dnolen: tomoj: it's telling that in CLJS the only case of extend default is IHash & IEquiv

18:22 hiredman: the bind operation is basically a protocol for binding names to values

18:22 dnolen: it used to be the case for ICounted & IIndexed and that was painful.

18:23 tomoj: yeah, I wouldn't really consider extending IDeref/IPending to default, just trying to understand better why it would be bad

18:23 tpope: Is there a reasonably simple way to get a list of java classes for tab completion?

18:24 tomoj: my rationale is silly - I have many functions which may take either an IDeref or a value, and I don't want to write (if (satisfies? IDeref x) ...) in every one

18:24 technomancy: tpope: the clojure-complete library handles that

18:24 tpope: technomancy: can I count on that being available?

18:24 dnolen: tomoj: then you never know if you have a real IDeref or not, and you always have to call realized?, this sounds like the madness of not knowing wether you have a real list in Scheme.

18:25 technomancy: tpope: no, but it's completely reasonable to make completion a no-op when it's not

18:25 tpope: hmm ok

18:28 tomoj: actually, I can get away without satisfies? if I just extend IDeref to nil. :(

18:29 or just check for nil :)

18:37 aperiodic: but if you extend it, then you can get nil satisfaction

18:39 tomoj: (satisfies? ISeq nil)

18:39 but (not (satisfies? ASeq nil))

18:40 ..nor (satisfies? ISeqable nil)

18:40 (in cljs)

18:46 dnolen: tomoj: now that's probably an oversight. extending to nil happens on line 381-442 core.cljs

18:47 tomoj: which is an oversight, that (satisfies? ISeq nil) is true or that one or both of the others are false?

18:47 dnolen: tomoj: or maybe not

18:48 tomoj: I have to say extending to nil is a bit of convenience - not sure it's about semantics. In generally for perf reasons we should probably check for nil in the actually fns. this requires some hammock time from someone.

18:49 check for nil in the actual fns I mean. like checking for nil in first, and not extending nil to ISeq.

18:49 tomoj: you're suggesting checking for nil would be faster than extending to nil?

18:49 or that we extend to nil now for performance reasons?

18:50 dnolen: tomoj: nil check is cheap, what we're doing now is bound to be slower in the nil case.

18:51 would probably be cleaner for nil to be extending to nothing - same as in Java

18:51 this also makes sense from Typed Clojure perspective

18:51 nil is not a part of anything

18:51 it's just unioned w/ the various types that fns accepts

18:53 tomoj: seems seq and first already do check for nil

18:53 dnolen: yep

18:54 big perf benefit there.

18:54 when you hit the end of a seq

18:54 so probably would take a patch that made nil not participate in all those protocols.

18:55 and the required nil checking.

18:55 of course would still want to check that doesn't mess things up somehow or slow things down in some way I don't see at the moment.

18:56 but I suspect it'll be fine - that's basically how RT.java works.

19:02 tomoj: what's the seq typehint for?

19:03 oh, I see

19:05 I was thinking I wanted a typehint for "not boolean"

19:16 TEttinger: anyone have an idea how to implement nested commands a la supybot for lazybot?

19:17 `seen amalloy

19:37 amalloy: i don't understand the question

19:40 TEttinger: ^

19:40 TEttinger: amalloy: supybot allows you to do things like (assuming prepend $ )

19:41 $seen [decide amalloy,TEttinger]

19:41 lazybot: I have never seen [decide.

19:41 TEttinger: and it would call decide, take what it WOULD print to the channel and use it as the args to $seen

19:41 amalloy: i predict this would require a substantial rewrite of lazybot's plugin system

19:42 TEttinger: I think it would be as simple as a binding thing... if I could figure out binding...

19:42 ah

19:42 I was going to use a new plugin, preprend twice

19:42 like $$

19:43 do you know how I could rebind irclj's output like you do for *out* ?

19:46 amalloy: if you wanted to add it as a special plugin, rather than making it work for existing plugins, it's a much smaller effort

19:46 but i don't know anything about irclj

19:53 TEttinger: heh, ok.

20:16 tomoj: hmm.. it seems if your Executor for send-via runs the action in the calling thread, you get an error

20:16 'pop without matching push'

20:17 of thread bindings

20:18 wonder if that's a bug, or if using a synchronous Executor is a user error

20:18 Executor docs say "Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation."

20:19 hiredman: tomoj: sounds like a bug in the binding conveyence code

20:23 tomoj: yes, ((binding-conveyor-fn println)) gives the same error

20:29 don't understand why that would happen

20:30 seems like binding-conveyor-fn should be a noop when its return value is called right away

20:31 hiredman: :(

20:31 tomoj: it just gets the ThreadLocal<Frame> dvals when binding-conveyor-fn is called, then sets dvals to the same Frame when its return value is called

20:31 hiredman: nasty and unsafe

20:31 very yetch, just makes me hate binding conveyence all the more

20:32 bindig-conveyor-fn makes no effort to reset the frame back to whatever it was

20:32 tomoj: fwiw bound-fn is not broken in this respect, and binding-conveyor-fn is private

20:33 hiredman: and cloneThreadBindingFrame doesn't just clone bindings, it truncates the frame, if I recall

20:33 tomoj: ah

20:33 right, Frame clone only copies bindings, not prev

20:34 hiredman: *yetch*

20:37 tomoj: so a threadpool executor with callerruns might break agents?

20:38 hiredman: any one running agent actions on a thread that may actually have bindings you want to keep is in for a bad time

21:31 gfredericks: does core.logic run in parallel now?

21:33 dnolen: gfredericks: nope, but jamii is giving that another go as well as opt-in fair conjunction

21:33 gfredericks: it makes all 4 of my cores light up

21:33 I guess that's just...other stuffs :)

21:36 * gfredericks is trying to do project-euler 185

21:48 Foxboron: gfredericks, problem number 165 is "fun" in the sense it tok 8 hours to solve :P

21:51 gfredericks: to code or to run the code?

21:53 hyPiRion: 185 or 165?

22:02 * gfredericks certainly meant 185

22:10 Foxboron: too run.

23:23 TEttinger: ok, 4 hours later... still at the problem. I am trying to have a lazybot plugin call another lazybot plugin, get the output of the second one as a string, and pass it to the original plugin.

23:23 the main problem seems to be with the IRC stuff

23:23 Raynes: Yeah, you can't really do that.

23:23 TEttinger: I am not sure how to... capture the output

23:23 technomancy: if only plugins were implemented as functions

23:23 Raynes: technomancy: They are functions.

23:23 TEttinger: I have achieved some success though

23:24 technomancy: in a composable way

23:24 =

23:24 TEttinger: they are, yeah there's an :fn internally

23:24 Raynes: technomancy: They're just stored in complicated ways.

23:24 technomancy: )

23:24 Raynes: technomancy: You're welcome to fork it and fix my terrible design.

23:24 technomancy: actually I have been intrigued by http://tools.suckless.org/ii/

23:24 remarkable piece of soft ware

23:24 TEttinger: Raynes: I reassigned something in the :com , in case you want to see my terrible code

23:25 Raynes: technomancy: This composable magic of yours doesn't really work in an IRC context. You output to IRC. You don't just return strings.

23:26 You can return some data structure telling the plugin system how to output what you want, but then you lose flexibility that some plugins require.

23:26 technomancy: you can't just return a map of targets to output?

23:26 Raynes: No.

23:26 technomancy: oh. that's a shame. =\

23:26 Raynes: It is.

23:27 TEttinger3: http://ideone.com/sagF9a

23:27 Raynes: Some plugins required timed releases of output, no output at all, different kinds of output, output in a thread async. Plugins can be super complex.

23:27 TEttinger3: the problem has to do with it behaving weirdly regarding [:com :connection :sockout]

23:28 ohhh...

23:28 technomancy: you could do a lazy seq with a sleep in it

23:28 TEttinger3: I don't know when it will return

23:28 technomancy: but that might muck up the control thread

23:30 Raynes: technomancy: Also, I'm currently running Windows. I should download leiningen and just scream at you.

23:30 TEttinger3: heh, what?

23:31 Raynes: TEttinger: Could you summarize what you're trying to do with @com and what isn't working?

23:31 TEttinger3: Raynes, sure.

23:32 ...I admit I am not really sure what :com is or how it works

23:32 * technomancy hides under the desk

23:32 Raynes: TEttinger: I never thought anyone would actually mess with it. :p

23:32 TEttinger3: my version of lazybot has a TODO: document this for defplugin :-)

23:32 technomancy: Raynes: praying for your safe recovery

23:33 Raynes: @com is all the information from irclj. It holds everything irclj mutates and such.

23:33 technomancy: Just for video games, thankfully.

23:33 TEttinger3: but I am trying to get the output from irclj into a StringWriter

23:33 which could be trouble

23:33 Raynes: There is about a -4% chance of that working.

23:33 There can be 100 things writing to those streams at a time.

23:35 TEttinger3: Raynes: ...so is "piping" one plugin's printed messages into another plugin impossible with lazybot?

23:35 Raynes: It probably is, sadly.

23:35 TEttinger3: ah. worth a shot...

23:36 Raynes: technomancy has a point in that it could potentially be rewritten to be more composable, but I think it would be at the cost of flexibility in plugins. Might be an interesting thing to try sometime though.

23:37 technomancy: Raynes: return a per-channel vector where strings are emitted and numerics represent a pause?

23:37 Raynes: That was just an example.

23:37 technomancy: probably a handler/middleware approach a la ring and nrepl

23:38 or something

23:38 Raynes: Ugh

23:38 technomancy: well probably more like aleph

23:38 since it's async

23:38 Raynes: The primary issue would be plugins that do things like notify async. The Github commit plugin, for example.

23:38 It screams "GIVE ME A QUEUE!" but a queue wont help for composability.

23:39 Regular commands on the other hand might be possible.

23:39 To do what you say, I mean.

23:39 technomancy: irclj 2.0.0

23:39 Raynes: Things that do threads are typically hooks which you wouldn't want to grab anyways.

23:39 This isn't an irclj thing.

23:39 technomancy: (says the guy who hasn't released version 2.0.0 of his project)

23:39 Raynes: Irclj is entirely composable enough.

23:39 technomancy: oh right

23:40 Raynes: Lazybot is written by me when I was like 14.

23:40 technomancy: excellent point

23:40 Raynes: I've rewritten parts of it over time but have never given it a real shakedown.

Logging service provided by n01se.net