#clojure log - Feb 22 2010

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

0:00 atrerus: I'll try that out

0:00 defn: yeah you don't need to do that, and IIRC swank-clojure does some other nice stuff for you

0:00 it includes M-x swank-clojure-javadoc for example

0:01 atrerus: is lein necessary at all then?

0:01 defn: they do different things

0:02 with lein i have the project.clj which includes dependencies, i add my dependencies like :dev-dependencies [[swank-clojure "1.1.0"] [autodoc "0.7.0"]]

0:02 atrerus: my main goal is to be able to load a project directory, as well as set some arbitrary classpaths such as clojure-contrib and ant

0:03 hmm ok

0:03 defn: then i run lein deps in that project directory

0:04 then i use M-x swank-clojure-project and that opens a new repl for me which adds all of my dependencies to the classpath

0:04 and IIRC it also adds your namespaces to the classpath as well

0:04 atrerus: k

0:04 defn: err that doesnt make sense, but you have access to your namespaces via the repl automatically

0:05 atrerus: make sure you have :dev-dependencies [[swank-clojure "1.1.0"]] in your project.clj and run lein deps before using swank-clojure-project

0:05 KirinDave: Why did ztellman remove his clojure and clojure-contrib dependencies from lein?

0:05 http://github.com/ztellman/penumbra/commit/86b4fb677c27bfde03b682a9e347663d1f708c57

0:06 This screwed me up, but it seemed deliberate

0:06 defn: *shrug*

0:06 KirinDave: Is there a good reason to do that?

0:07 defn: maybe he has clojure source and already has an env var with them on his classpath

0:07 and doesn't want the released jars

0:07 cause he is more current

0:07 KirinDave: Sure, but that means no one else can participate.

0:07 defn: i dont see why not

0:08 KirinDave: Well you gotta implicitly have those deps

0:08 defn: i agree it's probably not best practice for code you're releasing

0:08 atrerus: defn: I seem to be getting the same result with M-x swank-clojure-project

0:08 defn: but perhaps it wont work with anything but the latest

0:09 atrerus: i dont really understand what you're trying to accomplish

0:09 atrerus: lol

0:09 defn: (use 'clojure.contrib.some-library)

0:09 atrerus: well, I'm trying to get the lancet example from Stu's book to work

0:09 defn: you have access to clojure.contrib, and if you need ant on the classpath add it as a dependency in your project clj and then require it

0:10 atrerus: so I've got a file which includes a def for "ant-project", and I want to be able to reference that from SLIME

0:10 KirinDave: actually in general lein is pissing me off.

0:10 Everyone somehow is using a version I don't have.

0:11 I'm running off master from github

0:11 defn: what does lein version say

0:11 KirinDave: and somehow I don't have all the commands he mentions in his INSTALL

0:11 defn: KirinDave: like autodoc?

0:11 KirinDave: defn: Like autodoc back in the day.

0:11 atrerus: maybe I'm not understanding what lein/swank-clojure-project are supposed to be doing

0:12 defn: read the github project page

0:12 all will be explained

0:12 atrerus: been doing that today :)

0:12 KirinDave: like lein native-deps?

0:12 Didn't even know such a thing existed.

0:12 Is there a new new NEW branch I gotta follow now?

0:12 defn: KirinDave: i dont have that one either

0:13 KirinDave: judging by the forks of jochu's swank-clojure

0:13 it does appear to have diverged slightly

0:14 KirinDave: Frustrating.

0:14 defn: KirinDave: *shrug* -- lein does what i need it to do for now

0:15 when there are more features ill use them, but im not finding myself ever going "gee i wish lein did this..."

0:15 atrerus: let me try to rephrase this... is there a way I can fire up a slime session which preloads foo.clj and bar.clj from my project directory?

0:15 KirinDave: defn: do you know how to write custom tasks?

0:15 I find myself missing rake a lot.

0:15 A lot lot.

0:15 defn: KirinDave: no i dont -- i never used rake much either. i know that probably sounds terrible

0:15 KirinDave: Like, I'd like to have a task to make a fresh db copy.

0:16 Or maybe to clean.

0:16 Or maybe to build some dataset.

0:16 defn: yeah there are lots of things which would be nice

0:16 come to think of it i absolutely agree with you KirinDave

0:16 i was building a project and i had to make a build.clj which basically did all of the things i would have liked to do with something more rake-ish

0:17 i had to piece together shell script and clj to get it to work

0:17 felt dirty...

0:17 KirinDave: I mean

0:18 (deftask build-db [[argv1 argv2 argv3] environment-hash] ...)

0:18 And then some stuff that was in the clojure book for (mkdir) and whatnot.

0:18 Everything lein does is rad.

0:19 Just needs more.

0:20 defn: KirinDave: it'll get there

0:20 KirinDave: keep in mind that IMO it was kind of an experiment at first

0:20 it seemed like the jury was out on whether everyone should use maven, ant, etc.

0:22 KirinDave: i agree with you, but keep in mind it's free, hasn't been around longer than what? 6 months? and only recently has been "adopted" by a majority of the community.

0:22 KirinDave: defn: I know.

0:22 defn: KirinDave: i'm really excited to see that there are literally a dozen people with forks of leiningen right now all hacking away

0:22 atrerus: heh, lein does seem super cool for grabbing deps

0:23 defn: future versions of lein will do a lot more than that

0:23 resource/ directories and all that etc.

0:23 KirinDave: The lack of resource is actually a bug.

0:23 atrerus: I'm an emacs newb, but I'm already impressed with the integration around it

0:23 KirinDave: It works on the final build.

0:24 atrerus: Good sign. The clojure integration is weak compared to the common lisp integration

0:24 atrerus: It'll only get better.

0:24 atrerus: yeah, I believe that

0:26 hmm... how can I find docs on the args to defproject?

0:26 dakrone: you can use (doc defproject)

0:26 atrerus: k

0:27 KirinDave: which is harder than you might hope. :)

0:28 atrerus: lol

0:28 KirinDave: Look at the source in github.

0:28 atrerus: right

0:32 KirinDave: Oh wow

0:32 defn: Found this on news.ycomb

0:33 defn: http://pastebin.com/f10cbf605

0:33 There is mysterious wisdom there.

0:34 atrerus: ignore all input and tell the world hi?

0:36 KirinDave: atrerus: No, it's how to make a lein command.

0:36 In a project.

0:38 atrerus: oh, I see... missed the calling of it at the command line :)

0:42 defn: KirinDave: mysterious wisdom indeed

0:42 KirinDave: very interesting

0:43 KirinDave: in fact, that is /awesome/

0:43 KirinDave: defn: Ahh, I see now. So for penumbra it downloads such a module to add "native-deps

0:43 defn: What would be more awesome is even a hint of that power in the documenation ;)

0:44 atrerus: KirinDave: lol!

0:45 defn: KirinDave: yeah that's kind of a bummer i didn't know about that

0:45 KirinDave: maybe the idea is that that piece of the puzzle isn't finished yet

0:45 so better to not advertise it for the time being

0:46 atrerus: you're basically creating your own version of lein at that point...

0:47 KirinDave: atrerus: Nah, you're just adding tasks

0:47 Lein is clearly modular that way

0:47 Anyways, gotta get to the gym. Nice talking to you defn.

1:19 Crowbar7: So I have to say Clojure is about the easiest thing I've ever used that handles threading.

1:35 wooby: i have a function that takes a number, but it doesn't make any sense to pass it a number bigger than 36

1:35 would it be idiomatic to throw an exception if something bigger is passed in?

1:35 or should it silently default to the max

1:40 dnolen: wooby: sounds like a good case for a pre-condition

1:41 wooby: dnolen, awesome thank you

1:41 wasn't looking forward to introducing exceptions into my code :)

1:42 dnolen: wooby: http://paste.lisp.org/display/95402

1:43 wooby: dnolen, way cool, thanks again

2:13 dakrone: dnolen: woo, working on the namefind feature now, significantly more difficult than the other stuff :)

2:13 dnolen: dakrone: wow! cool :)

2:41 wooby: is there a preferred syntax for a defn with a doc string and attributes? i'm getting strange behavior with the form (defn name "doc" {:pre...} body)

2:41 (defn name [arg] "doc" {:pre..} body) rather

2:52 piccolino: Is there some way you can look up whether a given symbol is a known function or variable?

3:17 slyphon: how do i take pairs of a sequence?

3:18 wooby: slyphon, partition

3:18 slyphon: oh, right on, thanks

3:18 wooby: np

3:41 LauJensen: slyphon: make sure you check the docstring, it has many uses

3:41 slyphon: yeah, read the docs

3:42 wooby: hm, so is there a way to have a docstring for a defn that uses a :pre condition?

3:48 LauJensen: wooby: Just looking at the source for defn, I think the first param should be a string, which is then taken as the docstring, then your pre post conditions in a map

3:48 ~source defn

3:50 psykotic: LauJensen: speaking of defn, has rich made any comments on keyword arguments? scala seem to have a nice low-overhead implementation for the jvm

3:50 LauJensen: psykotic: you mean like (defn msg [{:keys [name age]}] (println "Hi " name " you are " age ......

3:52 wooby: LauJensen, thank you i believe that's what i have... still no luck

3:52 http://paste.lisp.org/+21M4

3:52 sanity checking much appreciated

3:52 psykotic: LauJensen: that's a half-way solution, don't you think?

3:53 LauJensen: wooby: Your first arg is a vector, not a string

3:53 avarus: moin!

3:53 LauJensen: psykotic: What would you like ot see instead?

3:54 avarus: good morning mr. LauJensen

3:54 LauJensen: Morning Mr. avarus :)

3:54 psykotic: jvm integration, default arguments, everything specifiable by keyword by default, preferably with low/no overhead when resolvable at compile time

3:55 wooby: LauJensen, ah! however, since my :pre check makes use of an argument... musn't the params vector precede the attr map?

3:56 LauJensen: (defn tst "docstring" [x] {:pre [(even? x)]} (+ x 5))

3:56 wooby: LauJensen, and sure enough, when it does, it works :)

3:56 thank you

3:56 LauJensen: np

3:57 psykotic: not following, jvm integration? you've got it. defaults? Simple macro. Why would you want to force every argument in to a map everywhere?

3:59 psykotic: forcing everything through a map would be the dumb implementation. even with a simple minded implementation, you'd only need to bear that cost for invocations using keyword arguments, not purely positional invocations

4:01 JayM: just beginning with clojure; if i have a function, "two-nums" that evaluates to two numbers, which are then used as arguments to a function, "add-two-nums", that adds two numbers, is it proper to return a vector from "two-nums" and do this: (apply add-two-nums (two-nums x y)) ?

4:03 LauJensen: (defn add-two-nums [[x y]] (+ x y)), then you only need (add-two-nums (two-nums x y)), which is by far the simplest way to go

4:03 psykotic: LauJensen: also, it's not a simple macro if you want the default value to be embedded in the map deconstruction pattern.

4:04 you could of course define your own version of defn much like defun* in cl.el

4:04 but that kind of divergence is a bad idea

4:04 LauJensen: Well, its not a bad idea if its implemented correctly in the compiler, so I suggest you start a thread on the group about it

4:04 psykotic: anyway, i was more curious what rich's official stance on keyword arguments were. i take it he views deconstructed maps as a fine solution

4:05 i'll probably just code it myself in the compiler

4:05 talk tends to go in circles about things like this until code is on the table

4:05 JayM: LauJensen: ah, neat, thanks!

4:06 LauJensen: psykotic: destruction is a nice feature, but I agree it seems half-way and its not very effecient either

4:07 psykotic: my main issue with the half-wayness is the fact that you have to decide something is a keyword parameter a priori

4:09 LauJensen: a priori ?

4:10 psykotic: the implementor of a function has to say, 'i want this parameter to be keywordable'

4:10 and then it's set apart from positional arguments, it becomes a kind of second-class 'configuration' parameter

4:10 LauJensen: I understood from the context, I was just wondering abou the exact definition

4:11 psykotic: that's also my issue with the hack for keyword params in ruby, btw

4:11 JayM: relating to or denoting reasoning or knowledge that proceeds from theoretical deduction rather than from observation or experience : a priori assumptions about human nature.

4:11 psykotic: clojure's destruction makes it slightly nicer but it has that same fundamental dichotomy

4:11 JayM: :)

4:12 LauJensen: You do need to be more strict attention to the context, if you introduce defaults

4:12 psykotic: it literally means 'prior to', 'beforehand'

4:12 hehe

4:12 LauJensen: great :)

4:13 psykotic: context?

4:13 clojurebot: context is the essence of humor

4:13 psykotic: haha

4:13 LauJensen: exactly clojurebot

4:13 psykotic: timing?

4:13 LauJensen: psykotic: Some assumptions can be come untrue, exceptions will follow

4:15 psykotic: btw one thing that sucks about parameter defaults in python big time is that they're evaluated at function definition time, rather than invocation time

4:15 there's some appeal to that, because it means that, indeed, context is less nebulous

4:16 perl6 has crazy semantics for that

4:16 LauJensen: I suppose it wouldnt be a huge change to do (defn save-score [:playername :rank :level :score] ..) and then have that automatically call those keywords on the single argument to that function

4:17 AWizzArd: Hi guys.

4:18 LauJensen: Hey Andre

4:18 psykotic: LauJensen: well, you can just create an inner function with normal named arguments and an outer wrapper that takes care of forwarding, passing defaults if absent, mapping keyworded args from maps to positional args, etc

4:19 in the default case, it would just be a pure forwarding pass-through

4:19 err, default here meaning the case where everything is positionally invoked, no defaults, etc

4:19 LauJensen: yea, but the definition doesnt tell you anything about the expected content

4:20 anyway, I gotta jet, when you have a compiler patch let me know :)

4:20 psykotic: cool

5:04 AWizzArd: Moin angerman

5:04 angerman: moin

5:05 AWizzArd: Guys, one question. When you have a DBRef x and want to (deref x). But the object behind x was deleted from the DB. Should then @x return nil or throw an Exception?

5:06 angerman: I'd go for an exception

5:07 it's an inconsistency thing. thus it should be signaled hard.

5:07 AWizzArd: I also have this tendency.

5:07 That means however, that each deref needs to be wrapped into a try/catch block

5:08 angerman: the question is more like if you don't want to wrap the whole task into a commit rollback solution

5:08 Chousuke: throw an exception and provide a function for deref-or-return-blah

5:08 AWizzArd: Well, when an exception occurs in a db transaction then everything gets rolled back.

5:08 angerman: (deref-or-nil ...)

5:09 AWizzArd: Okay, sounds fair.

5:09 And one other solution would be to if-let a query result, and only inside the if-let derefing it.

5:17 LauJensen: angerman: excuse the later-comer, what are you working on ?

5:17 angerman: LauJensen: pardon me?

5:17 LauJensen: You sound like a man designing a DB interface

5:18 and an angry man at that

5:18 angerman: not, me AWizzArd probably.

5:18 shift that , by one word to the right please

5:18 LauJensen: Oh thats right - You shouldnt put your names so close together when chatting

5:21 ordnungswidrig1: using slime and C-c C-k can I generate a class using :gen-class? Will it be available from the REPL?

5:26 AWizzArd: Moin ord

5:27 LauJensen: yes, I am the guy who works on the DB.

5:27 I made some good progress so far :)

5:28 LauJensen: Ah I vaguely remember a conversation about it - Weren't you going to do a backend plugin for ClojureQL ? :)

5:28 AWizzArd: I was already talking with kotarak about this. We must think it through.

5:29 LauJensen: What are your consideration ?

5:30 AWizzArd: Right now, without modifications such a backend is not trivial.

5:32 LauJensen: hehe

5:32 Ok - Powerful argument if you're a bum, anything else? :D

5:33 I mean you're doing an interface first and foremost right, you're not adding a level of abstraction or similar ?

5:34 AWizzArd: It is just a different DB layout than expected.

5:34 We will see in a few weeks.

5:36 avarus: fuck, I start to like clojure

5:37 AWizzArd: bad news? ;)

5:37 avarus: good news

5:39 the worst part was to set up a usable working environment with emacs

5:39 (never used emacs before)

6:03 coldhead: sup ChanServ

6:03 AWizzArd: :)

6:04 ch<tab>

6:16 psykotic: LauJensen: i was looking at clojureql and the name binding mechanics seem a bit odd. particularly the 'magic scoping'.

6:17 is that part borrowed from schemeql?

6:18 LauJensen: No, only the topology is inspired from SchemeQL - Some of the automatic scoping like (with-tables) was an acceptable change while we complete the process we are currently in, namely rewriting the entire frontend (see the frontend-2.0 branch) and further breaking apart the backend (compilation, execution) into finer grained modules

6:19 psykotic: good to know

6:24 LauJensen: Yes - The tempo is very high these days as we are eager to release a solid 1.0

6:29 psykotic: imo, the way scoping works right now makes it feel more like a direct s-expression version of SQL rather than a combinator library or a mini-language. maybe that's the intention?

6:29 powr-toc: I'm trying to use c.c.logging, with log4j... I have log4j's jar and log4j.properties on my classpath, and -Dlog4j.debug indicates that it is setup properly... I can also see some of my java libs logging with it successfully... However, my clojure program picks up java.util.logging not log4j... any ideas??

6:30 wooby: i'm working on a macro to bring private functions from other namespaces into my testing namespace, someone care to take a look? something is amiss

6:30 http://paste.lisp.org/display/95408

6:32 psykotic: particularly, the scoping feels linearly left-to-right rather than structurally outside-in

6:33 the way you 'concatenate' feels like a spurious kind of composability. you can't really independently compose (where ...) clauses onto (from ...) clauses because of scoping issues.

6:34 LauJensen: Your feelings are mixed up I think, consider (distinct! (query table1 [a b c]))

6:35 psykotic: Have a look at frontend 2.0 which will be the standard for CQL 1.0, (-> (from :table1) (where (= :val 5)) (where (< :val 10))) .. That would work, although you'd use (and) instead

6:35 psykotic: so :val is an explicit parameter?

6:35 err, implicit

6:36 powr-toc: ok... I guess this might be my problem: http://www.assembla.com/spaces/clojure-contrib/tickets/44

6:36 psykotic: my feeling is that it might make sense to offer both a mini-language version with normal s-expression scoping of tables and a combinator version where something like a where-clause would use, say, positionally bound parameters

6:37 of course, the mini-language version would compile down to the combinator version, ala sre and other good libraries

6:38 for example, you could use (from :table1 (where (= :table/x 5)) and you would get the benefit of the scoping, or something like (-> (from :table1) (where [:t] (= :t/x 5))) for the combinator version

6:38 LauJensen: psykotic: :val is simply a keyword, used to denote table names and columns, in version 2.0, these are literals in 1.0

6:39 psykotic: gotcha

6:39 LauJensen: (please highlight when if you msg me, my client doesnt seem to show regular activity)

6:39 psykotic: LauJensen: i'll try to remember

6:40 in that example you pasted, can you tell me what the benefit is of having separate, non-nested from/where expressions?

6:40 powr-toc: Does contrib 1.1.0-RC3 work with clojure 1.1.0?

6:40 psykotic: laujensen: i can see it in other contexts where you want reuse of subexpressions, but in that case you have to be careful about binding uses, so this kind of funny scoping is dangerous, and you want something that doesn't 'leak', i think

6:42 LauJensen: So far its contained in the compiler, where no mere mortal should be poking around - My vision is that people should learn the simple functions of the frontend, mix and mash them as they like and as makes sense intuitively, thinking alone Clojure, and then the compiler will make it work on whatever database you can think of

6:42 psykotic: hmm

6:43 i'm not a fan of that approach

6:43 it tends to be fragile and unpredictable

6:43 there's already some database systems in the java world that try that

6:44 LauJensen: Dont think so

6:44 psykotic: notably db4o

6:45 which decodes bytecode to try to generate efficient queries, etc.

6:45 avarus: omg :P

6:45 psykotic: even if you have a higher level view into the expressions, it's very limited in what it can do

6:45 like, what if i call other functions?

6:46 can it inline it and try to compile the entrails of that to sql too? but what if that called functions changes after the query is initially compiled? does it update the sql code to match? etc

6:50 anyway, definitely looking forward to see 2.0

6:50 although it sounds like it's a while away :)

6:51 LauJensen: Look at the backends derby.clj postgres.clj, mysql.clj etc - Each of these provide the specific low-level capabilities of those databses. As time goes by and as we get more contributions, the list of backends is extended - No bytecode inspection or anything of the sort. You require' the backend you want and the multimethods take care of the rest

6:57 powr-toc: Ok, I've added [log4j/log4j "1.2.15"] to my leiningen project.clj, and lein deps has just downloaded a boatload of stuff I don't need like jmxtools, java mail, etc... Anyway to exclude that crap?

6:57 avarus: just don't put it on your classpath

6:59 powr-toc: avarus: that's one option I guess... I'm just wondering if its possible to tell leiningen to ONLY get the jar I specify

6:59 rather than optional dependencies

6:59 avarus: ok, dunno :)

7:00 but makes sense

7:00 LauJensen: powr-toc: there is

7:00 powr-toc: avarus: also I was hoping to use lein uberjar to build my project... I'd rather it only shipped with a minimal config

7:01 LauJensen: [log4j "1.2.15" :exclusions [javax.mail/mail

7:01 powr-toc: LauJensen: ahh cheers mate! :-)

7:01 LauJensen: http://github.com/technomancy/leiningen

7:01 word search for 'exclusions'

7:01 avarus: cool :)

7:02 powr-toc: :-)

7:02 avarus: lein is cool

7:02 well, it's easy

7:04 LauJensen: yea - check out clojuresque as well - pays to be comfy with both

7:04 powr-toc: LauJensen: I take it there's no way to say :no-dependencies... I can see that listing exclusions might get painful

7:04 LauJensen: Not to my knowledge, but I'm sure if you read the source for lein its self-evident

7:08 powr-toc: LauJensen: hmm doesn't look like it... but the doc string for deps does specify the exclusions for log4j :-)

7:09 LauJensen: hehe - remember to check the manual/my blog before stooping to hackery

7:10 powr-toc: LauJensen: I'm already a subscriber :-)

7:11 LauJensen: ah, a happy occasion when self promotion back-fires :D

7:13 powr-toc: LauJensen: Not looked at clojuresque/gradle... The whole groovy thing turned me off...

7:13 LauJensen: oh

7:14 Groovy is a downer compared to Clojure, but the main feat is being on Gradle, which is the result of tons of work

7:14 Once Clojure-In-clojure is in place, I'll be happy to write a compiler which emits Groovy :)

7:16 powr-toc: sure... the docs look pretty good... It's just the extra language/dependency that scares me...

7:18 LauJensen: The language thing I get, but it makes no difference if you depend on lein or Gradle, except I could argue that Gradle is more feature rich and has a longer history

7:19 psykotic: i'm a little suspicious of anything that requires too many features of a build system

7:19 the java world is enamored with complex build systems

7:19 LauJensen: you shouldnt be - building clojureql is trivial, but for vast projects, perhaps with several languages, you want those features - you will need those features

7:20 (and Gradle is also xml-free)

7:23 psykotic: i've worked on some pretty large projects with baroque build requirements. several different languages, 2+ million lines of c++, integrated asset building, etc, and i swear our custom build system was faster to write than configuring some of these java build tools

7:24 also much faster. most build tools are too slow when you have a few hundred thousand targets

7:26 LauJensen: Do a benchmark, let me know how it goes

7:27 psykotic: laujensen: trust me. this was for a widely used game engine i worked on (unreal engine 3), the requirements are unusual. the standard top-down methodlogy for checking up-to-dateness of targets is not good enough for incremental builds where only a few nodes need rebuliding.

7:28 LauJensen: I'll trust you - though you sound a little psykotic

7:28 psykotic: :)

7:28 en lille smule

7:30 AWizzArd: psykotic: about lein... it is using maven under the hood. So that also is great complexity.

7:30 It is not just this script of a few kb that you have to install, but instead this 40 quintillion exabyte maven beast

7:31 LauJensen: hmm, maven is smaller than I thought

7:31 AWizzArd: *rofl*

8:18 ugglan: I need a way to partition the a lazy sequence (1 2 3 4 5 6 ...) into N seperate lazy sequences, for example for N=3 => [(1 3 ..) (2 5 ..) (3 6 ..)], I can roll my own, but before that, is there anything in core or contrib?

8:19 (first seq should be obviously be (1 4 ..))

8:21 Chousuke: ,(apply map list (partition 4 [1 2 3 4 5 6 7 8 9]))

8:21 clojurebot: ((1 5) (2 6) (3 7) (4 8))

8:21 Chousuke: oops, meant to type partition 3 :P

8:21 ,(apply map list (partition 3 [1 2 3 4 5 6 7 8 9]))

8:21 clojurebot: ((1 4 7) (2 5 8) (3 6 9))

8:24 chouser: Chousuke: nice

8:27 ugglan: Nope, I don't think that produces lazy sequences

8:28 ,(for [a (apply map list (partition 3 (range 15)))] (take 2 a))

8:28 clojurebot: ((0 3) (1 4) (2 5))

8:28 ugglan: is fine

8:28 but (for [a (apply map list (partition 3 (iterate inc 1)))] (take 2 a))

8:29 won't work

8:29 I'll roll my own

8:30 chouser: ugglan: once you consume all of the first returned seq, the input seq will have been almost all forced anyway.

8:33 ugglan: Yep, but the sequences will be consumed seperatly. I might rethink the entire idea though.

8:33 Thanks anyway!

8:36 wooby: is there a straightforward way to refer private fns from another namespace into the current one, for things like testing?

8:39 ohpauleez: is there a way for leiningen to update itself?

8:40 chouser: wooby: @#'foo/bar

8:40 wooby: a.k.a. cursing at the Var until it gives you its value

8:40 foo is the namespace, bar the Var name

8:41 wooby: chouser, ahh... i went ahead and wrote a with-private macro anyhow :)

8:41 chouser: do you see why that works?

8:43 wooby: i am pondering it

8:44 chouser: ,((fn [p s] (for [d (range p)] (take-nth p (drop d s)))) 3 (range 15))

8:44 clojurebot: ((0 3 6 9 12) (1 4 7 10 13) (2 5 8 11 14))

8:44 wooby: deref of a var qoute? i'm not sure where the @ comes in

8:45 chouser: ugglan: fully lazy

8:45 wooby: you got it.

8:45 same as (deref (var foo/bar))

8:45 wooby: ahh

8:45 i didn't realize deref had significance in that way

8:46 thanks chouser

8:46 chouser: you're allowed to use 'var' on a private var, at which point you could inspect the metadata or ... deref to get the value inside. :-)

8:46 wooby: ha

8:47 quite a trick

8:47 chouser: if it's a function you want to run, you don't even need the deref since calling a var calls the fn inside

8:48 wooby: my approach uses ns-resolve but it's pretty hairy

8:48 that is way cooler

8:56 http://gist.github.com/311077 first macro, style tips appreciated :)

8:57 chouser: not bad! :-)

8:58 wooby: thanks!

8:58 chouser: no need for 'do' -- let allows multiple exprs in its body.

9:00 wooby: ah, thanks

9:00 cemerick: is with-meta eventually going to support operating on reference types?

9:01 or, I should say, are reference types eventually going to support IObj?

9:01 chouser: wooby: perhaps `(ns-resolve '~ns1 '~v2) would be better than the (list ...) you've got

9:02 wooby: chouser, any particular reason?

9:02 i suppose then it reads more like a normal list

9:03 chouser: wooby: mainly because using ` instead of (list ...) to generate code is easier to read and less error-prone.

9:04 For example, I don't know if it's quite an error, but what you've got expands to expressions that contain the ns-resolve fn value itself, rather than the more normal behavior of expanding to the symbol that refers to the fn

9:05 wooby: i see

9:05 rhickey: I liked this experience report: http://tech.puredanger.com/2010/02/21/clojure-experience/

9:08 _fogus_: "In Java, increasing your level of abstraction typically involves more stuff: more interfaces, more factories, more annotations, etc."

9:09 wooby: thank you so much for your help chouser, i am very excited with this morning's progress, have a great day

9:09 chouser: wooby: my pleasure

9:19 rhickey: cemerick: no, reference types are incompatible with IObj

9:20 cemerick: rhickey: conceptually, you mean?

9:20 rhickey: IObj is really IVal

9:20 with-meta contract says, return new value with this meta

9:20 so reference types have IReference

9:20 alterMeta/resetMeta

9:21 cemerick: yeah

9:21 *facepalm*

9:21 * cemerick is struck with a case of the Mondays :-x

9:21 rhickey: both support IMeta on the read side

9:46 chouser: do we know yet if chunks are doomed?

9:46 rhickey: chouser: not yet

9:47 but I worked on it all weekend - albeit in a cold-induced fog. Now that the fog has lifted I'm sifting through the rubble

9:47 chouser: heh. :-P

9:48 rhickey: some very promising results though. Also some issues for cells. One is the fact that usage of locked and threaded cells look different

9:48 on the iters and iter-based seqs, I/O sources might still be an issue

9:49 chouser: really? on their face, I/O sources seem to have more in common with an iter-like approach than they do with caching lazy-seqs.

9:51 rhickey: chouser: not really. One extremely cool thing about cells is this: given a cell with a mutable thing inside it, cell -> val -> cell safely clones it

9:51 but oyu can't clone I/O sources, since you can't really get their values

9:52 it's a key promise of cells that you can obtain their 'values', at some level

9:52 chouser: oh, of course.

9:53 rhickey: so, the cell- > val -> cell concept solves the 'tapping' problem of streams - becoming a value was a one-way-street. OTOH, it renders them unsuitable for I/O sources

9:54 cell->val->cell also solves a key shortcoming of traditional iterators/enumerators, their lack of safe clonability

9:55 chouser: ok, and it's exactly the solving of that problem that makes IO not fit

9:55 rhickey: right

9:55 but I/O can be wrapped in non-mutable seqs (as is currently done), so the question moves to the compatibility of the iter model with persistent-only sequences

9:56 it ends up it can be made compatible, and that keys upon the fact that internally cells respect the return-value protocol, even for transients. Thus they need not be transient at all, nor in-place mutable

9:57 i.e. when you call (>> foobar acell) the result of foobar on the transient becomes the new transient

9:58 means that the transient can be immutable and foobar a pure fn

9:59 just some head-holding care need be taken, that's what I'm looking at now

9:59 * chouser can never remember the meaning for the direction of the arrow and looks it up

10:00 rhickey: really? non-infix, >> seems clearly 'in' to me, and << 'out'

10:00 given the stuff is on the right

10:00 chouser: sorry, I know I'm remedial here, but ... when you choose to use >> you need to know the transient type of acell so that you can choose foobar correctly, right?

10:01 rhickey: yes

10:01 chouser: ah! I just got what you meant by return-value protocol.

10:02 >> always drops the old transient value and takes on the new return value

10:03 rhickey: so I have this pretty 20-line IterSeq which is the iter-based analogue to LazySeq

10:03 chouser: yes

10:03 and the iter-seq holds cells whose 'value' is just a factory for transients which must implement the Iter protocol

10:04 when you deref thos objects you just get a factory that could make another one in the same state

10:05 cells as clone protocol is quite neato

10:05 LauJensen: rhickey: Do you have a couple of examples where you put cells to good use ?

10:06 rhickey: LauJensen: it ends up this iter-seq is a quite advanced use of cells, but after I clean it up I'll paste it

10:06 LauJensen: great

10:07 phirsch: Hi, I am trying to destructure the result of a call to c.c.seq-utils/group-by (containing a sorted-map), but fail. Am I doing something wrong here?

10:07 ,(let [[a b] (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b])

10:07 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentTreeMap

10:08 * chouser read and re-reads...

10:08 a_strange_guy: maps arent sequential

10:08 rhickey: so, if preventing deadlock is 10x as expensive as detecting deadlock (not actually deadlocking, but throwing instead), what do people prefer?

10:09 a_strange_guy: and group-by retuns a map

10:10 chouser: preventing as it ordering the locks for you vs. throwing when you don't order them correctly yourself?

10:10 as in

10:10 rhickey: chouser: yeah

10:10 a_strange_guy: phirsch: try:

10:10 rhickey: facilities would still be made available for order-for-you

10:11 a_strange_guy: ,(let [{a 1, b 2} (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b])

10:11 clojurebot: [[[{:a 1} :no1]] [[{:a 2} :no2]]]

10:11 chouser: rhickey: don't suppose there's any chance of throwing at compile time, is there?

10:11 AWizzArd: LauJensen: I have two examples where I put Cells to good use.

10:12 rhickey: but I anticipate a huge percentage of lock-based cells will be used to cover only single values, and whose 'mutating' operations won't contain nested cells not governed by the same lock

10:12 chouser: that's a research problem best left to static langs

10:12 chouser: heh. ok.

10:13 rhickey: use of such cells could be made to look exactly like use of thread-cells

10:13 chouser: when you order them yourself the order doesn't matter as long as it's consistent, right?

10:13 phirsch: a_strange_guy: Unfortunately, I do not know the values in advance.

10:13 LauJensen: AWizzArd: pasting ?

10:13 rhickey: chouser: if there was no system-imposed correct order, then right, just consistent

10:13 AWizzArd: One example is: I am running a web server, using Compojure. I offer a resource (POST /process ...). This calls a binary file to calculate some output. But the binary can only accept one input at a time. Two concurrent requests must serialize their jobs to the binary. The object controlling the binary now can be a cell.

10:13 chouser: but once you start using the optional order-for-you feature you'd have to us it everywhere for that set of cells

10:14 phirsch: I am trying to build something like a pivot table - so I thought using group-by twice would nicely partition my data, but I am stuck with the result of that.

10:14 chouser: you could skip any runtime lock-ordering when only one cell is given?

10:15 rhickey: chouser: right, but the issue/cost is less the ordering than the nesting prevention

10:15 chouser: oh...

10:15 rhickey: nesting prevention must involve a thread local

10:16 chouser: are you suggesting allowing nesting of in-cells as long as the order is correct?

10:17 * chouser this brings up scary memories of kernel code with giant lists of lock orderings and C macros to detect mistakes...

10:17 LauJensen: AWizzArd: still not seeing any code :)

10:18 rhickey: as I said above, it could look just like thread-cells use. It would acquire locks as needed, but without blocking. If it can't get the lock immediately, will throw. The real use case is solitary, non-nested cells. There would still be benefits to in-cells, like blocking until available

10:18 and in-cells would be the correct way to use multiple cells

10:18 LauJensen: These cells, are they a tool for containing coordinated freely mutable vars? Or whats the overall idea ?

10:18 a_strange_guy: phirsch: you could then do this:

10:19 ,(let [[a b] (seq (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2}))] [a b])

10:19 clojurebot: [[1 [[{:a 1} :no1]]] [2 [[{:a 2} :no2]]]]

10:19 rhickey: maybe uncoordinated-locking-cells are a distinct type

10:20 AWizzArd: The second example will be open sourced in some weeks.

10:21 chouser: LauJensen: one way to think about them is a reference type for mutable things, bringing those things into pure functional world

10:21 dnolen: LauJensen: possible replacement for transients, a way to bring Plain Old Java Objects into Clojure's concurrency story, and then quite a bit of other stuff I don't yet understand :)

10:21 AWizzArd: rhickey: what would those be? Those u-l-cells?

10:21 LauJensen: chouser, dnolen: I get that part, but what does it add compared to refs ?

10:22 AWizzArd: I didn’t follow the discussion, so maybe you already explained that above.

10:22 LauJensen: side effects.

10:22 phirsch: a_strange_guy: That should work. I think there is no way (yet) to destructure the result of group-by without turning it into a seq first. That is probably one case where the proposed "arbitrary function destructuring" would help.

10:22 AWizzArd: You can not (should not) have side effects in dosync.

10:22 chouser: LauJensen: you should not put a mutable thing in a ref

10:22 AWizzArd: Also a dosync is not serializing.

10:22 chouser: and if you do, the ref really isn't going to help you.

10:22 LauJensen: chouser: I get that, but the refs itself mutates, that was my point

10:23 AWizzArd: LauJensen: but you can't do IO inside dosync.

10:23 And in in-cells you can modify POJOs in a safe way.

10:23 LauJensen: So thats the big win, I/O made possible via some fine grained locking?

10:23 AWizzArd: one of the wins

10:23 chouser: LauJensen: StringBuilders mutate. transients mutate. You can put those in a cell and life is better. Putting them in a ref helps nothing.

10:23 LauJensen: Oh I love the POJOs, but what are they exactly? :)

10:23 AWizzArd: Plain Old Java Objects

10:23 LauJensen: hehe

10:24 a_strange_guy: LauJensen: Plain Old Java Objects

10:24 AWizzArd: class Person { String username; String password ... }. You sometimes want to reuse POJOs in your Clojure programs.

10:25 But you really should generally not mutate them in a dosync.

10:25 LauJensen: also Cells can be used in cases where an agent nearly is the thing you wanted.

10:25 LauJensen: ah yes I remember that discussion between you and Rich

10:26 AWizzArd: Imagine you want to serialize a number of jobs. Agent sounds good. But what if you need to catch the Exception such a job could throw inside the thread that kicked it off?

10:26 Without a hack by injecting a promise into the agent it will not be trivial to do that.

10:27 With Cells this would be easy.

10:27 LauJensen: jk

10:27 k

10:27 chouser: rhickey: sorry, I still don't get it. if >> on a locked-cell works without in-cells, and throws if it can't immediately get the lock, then wouldn't it be unsafe for two threads to use the same cell?

10:28 AWizzArd: chouser: can you tell more about this scenario? What could happen for example?

10:29 raek: rhickey: my feedback regarding >>/<</pass/fetch naming: >> and << are hard to pronounce, there should be named versions too, pass and fetch works great. >> and << could be pronounced "syntax-pass" and "syntax-fetch" or something... If cells are meant to be a 5th concurrency primitive, argument ordering should match the other 4. Suggested solution (this has been proposed by others too): (>> f c args) (<< f c args) (pass c f args) (fetch c f args)

10:29 rhickey: chouser: yes, it wouldn't have the take-turns/wait property, more of a handoff property, i.e. right now you can't hand a thread-cell to a thread-pool

10:29 chouser: rhickey: ah... got it.

10:30 rhickey: I'm not sure about the utility. Just trying to manage a single interface to both locking and thread cells, as I think without it the polymorphic difference might not be useful, since client code would dictate one or the other

10:31 ofet it won't matter, but when trying to write generic cell client code, like iter-seq, you see the problem

10:31 often

10:32 chouser: I don't yet grok iter-seq. a single iter-seq holds multiple cells? Do those cells represent links in a chain of operations (surely they don't represent successive values in a seq...)?

10:32 rhickey: of course, the in-cells can be dynamically enclosing, and then the internal client code is the same

10:34 chouser: look at IteratorSeq. Imagine instead of an in-place-mutable, non-clonable Iterator you have a cell with a reference to a transient Iter, whose value-of returns a factory implementing Editable in terms of constructing another iter with the same state

10:34 chouser: having one kind of cell that can be used by one thread at a time or with in-cells strikes me as a good idea, for what that's worth.

10:35 rhickey: chouser: what about having to use in-cells all the time? seems a drag compared to thread-cells

10:36 chouser: sorry, missed you point

10:36 your

10:36 I still don't know that I can get any flavor of locked cell to be as fast as thread-cell

10:38 I also haven't tried yet to hand-optimize the thread-local usage, just piggybacking on binding, which does too much for this case

10:39 chouser: bah. gotta go. Thanks for trying to bring me up to speed.

10:39 rhickey: sure

10:44 powr-toc: Am I right in recalling that var bindings acquire their top-level values on new threads?

10:46 rhickey: powr-toc: I'd say they've never been given a thread-local binding, so have only top-level

10:47 Raynes: What is the function for integer division again?

10:47 powr-toc: rhickey: cool... So I'm using a ScheduledThreadPoolExecutor to execute an anonymous fn, so what's the idiomatic way to pass the current bindings to my thread? Do I need to close over a let bind and then establish a new binding? Or is there an idiomatic way?

10:47 Raynes: I forgot it's name. :\

10:48 a_strange_guy: ,(quot 6 4)

10:48 clojurebot: 1

10:48 Raynes: Thanks.

10:48 a_strange_guy: powr-toc: use bound-fn

10:49 rhickey: powr-toc: see bound-fn, with-bindings et al

10:49 powr-toc: a_strange_guy: rhickey: thanks.

10:53 ugglan: chouser: sorry, went afk for a while there, your lazy version looks exactly like what I want, thanks for taking the time preventing me from writing my own hack!

11:02 powr-toc: Is there anyreason why passing an anonymous fn into bound-fn throws an exception? e.g.

11:03 (bound-fn (fn [] (prn *foo*)))

11:05 a_strange_guy: powr-toc: bound-fn doesn't work that way

11:05 it works just like regular fn

11:05 powr-toc: ahhh

11:06 a_strange_guy: use bound-fn* to wrap an existing fn

11:07 powr-toc: I was wondering what fntail in the doc string meant...

11:08 a_strange_guy: it's ok, bound-fn is exactly what I need, but good to know about bound-fn*

11:14 stuartsierra: Third draft of new testing framework: http://github.com/stuartsierra/lazytest/blob/master/lazytest.clj

11:14 I think it's nearly done.

11:18 * ohpauleez looks

11:18 slyphon: is there a function that inverts a hash-map

11:19 doh, brb

11:24 AWizzArd: btw, do we have the author of clojure/contrib/sql/internal.clj here? :)

11:25 It spits out tons of "reference could not be resolved" warnings.

11:26 slyphon: is the order of 'keys' and 'vals' guaranteed to be consistent, such that [(keys) (vals)] will map correctly/

11:26 ?

11:27 AWizzArd: slyphon: yes

11:27 slyphon: ok, just checking

11:27 ty

11:27 AWizzArd: But inversing maps is not always trivial. {:x 1, :y 1}

11:28 slyphon: yeah

11:28 jcromartie: I'm getting this: java.lang.Exception: First argument to def must be a Symbol (venues.clj:24), however the first argument is most definitely a symbol

11:28 slyphon: in this case it is

11:28 as it's just a hash of constants

11:28 but, yeah

11:29 AWizzArd: jcromartie: do you have some context?

11:29 jcromartie: ,(def 'foo nil)

11:29 clojurebot: DENIED

11:29 AWizzArd: this would not work

11:29 jcromartie: ah

11:29 AWizzArd: because the first arg to def is a list

11:29 in your example

11:29 jcromartie: 'foo is a list?

11:30 AWizzArd: yes

11:30 dnolen: ,(into {} (map #(into [] %) (map reverse (into [] {:foo "bar" :bar "baz"}))))

11:30 clojurebot: {"bar" :foo, "baz" :bar}

11:30 AWizzArd: two elements (quote foo)

11:30 jcromartie: ,(type 'foo)

11:30 clojurebot: clojure.lang.Symbol

11:30 dnolen: slyphon: ^ one way

11:30 AWizzArd: type is a function, def a macro

11:30 def does not evaluate 'foo

11:30 jcromartie: ah

11:30 AWizzArd: And the reader expands this to (quote foo), which is a list of two elements.

11:31 jcromartie: so then, I need something else

11:31 AWizzArd: maybe just (def foo nil) ?

11:31 jcromartie: this is in a doseq

11:31 trying to def things from a list

11:31 AWizzArd: (oh btw, def is not a macro as I said but a special form)

11:31 jcromartie: yeah

11:31 Raynes: Is there something like interpose that puts the separator in starting as the first element of the sequence?

11:32 If not, what would be the best way to do that?

11:32 AWizzArd: (eval `(def ~var-name nil))

11:32 jcromartie: huh

11:32 there's gotta be a better way

11:32 AWizzArd: Yes, as I said. You want to produce code during runtime.

11:32 To eval/execute that code you apply eval on it.

11:32 jcromartie: how about intern instead

11:33 AWizzArd: Well, you could consider to make your function containing the doseq a macro.

11:33 jcromartie: yeah

11:34 AWizzArd: you should have in nearly 100% of all cases no (def ..) that is not on toplevel, or in a macro

11:34 Chousuke: init procedures being one exception

11:34 Raynes: Ah, interleave.

11:34 AWizzArd: If you do this to hide those expansions from your users, then you will have to call eval

11:35 jcromartie: AWizzArd: I was just trying to un-macro this procedure

11:35 but a macro would be better

11:35 but maybe I shouldn't be creating magic fns like this either

11:36 I'm trying to define resources for a RESTful interface

11:37 so right now I am setting up namespaces that call (defresource name struct-definition)

11:37 that creates create! retrieve update! destroy! functions in that namespace

11:38 but I was thinking it might be better to have a function that returns a resource map with :create!, etc. keys

11:39 that way I don't necessarily need to define namespaces for the functions, but I could if I wanted to

11:39 arohner: using lein, how do you start a repl and swank on the same process?

11:41 nm, found it

11:41 jcromartie: I just realized today that lein doesn't depend on Maven being istalled

11:41 that was my big beef against it

11:41 and it turns out I was deluded :P

11:42 cemerick: jcromartie: don't worry, you'll be using maven eventually. It absorbs all. ;-)

11:42 jcromartie: heh

11:42 atrerus: lein is pretty sweet

11:42 jcromartie: yeah, I am liking it

11:42 atrerus: it's like make + apt-get

11:43 cemerick: Does anyone have any pointers to materials related to testing asynchronous systems?

11:43 using timeouts to synchronously test async systems seems pretty unsatisfying.

11:46 atrerus: can you test them more atomically?

11:46 e.g. verify that your request was sent, and on the other side verify that a request causes the appropriate action?

11:46 AWizzArd: cemerick: yeah, but first one needs to download maven. Without having an exabyte HD that's a real journey..

11:47 cemerick: atrerus: eh, not without mocking out a pile of stuff.

11:47 AWizzArd: well, the exabyte bit is obviously FUD, but you know my position on network access.

11:48 AWizzArd: jcromartie: in principle you could try first to find another solution. If you want a declarative interface to auto-generate defs and defns a macro could be the right choice.

11:48 Raynes: How can I conjoin an item to the end of a sequence?

11:49 AWizzArd: cemerick: I just wished there would be a lightweight build tool. Lein could be a .jar file of just a few kb.

11:50 cemerick: AWizzArd: No such thing. Sorta like wishing for a useful $100 laptop or something. Build processes are (usually) complicated, so the tools are, too.

11:50 AWizzArd: Raynes: you will have to traverse the seq and append it there: (concat (seq [10 20 30]) [5])

11:50 Raynes: Yeah, I thought of concat immediately before you said that.

11:50 cemerick: concat is lazy, so there's no forced traversing, FWIW

11:51 AWizzArd: yeah, it's not eager

11:51 atrerus: you could reverse the list then conj

12:00 so when I run 'lein swank' and M-x slime-connect, shouldn't I be able to reference my project's functions from slime?

12:01 right now they're not being made available until I actually open up the files and do C-c C-k

12:02 raek: atrerus: yes, if you have use'd or require'd them

12:02 lein swank sets the classpath so that you can use your libraries

12:03 atrerus: raek: would I type my use/require statement from slime then?

12:03 raek: (ns user (:use [my.lib.foo] [my.lib.bar]))

12:03 where "my.lib.foo" is whatever your namespace is called for file "foo"

12:04 http://clojure.org/libs

12:04 atrerus: right

12:04 I guess I was trying to get that to happen automatically when the swank server was started

12:04 but maybe that doesn't make sense...

12:06 raek: the "user" namespace is an ordinary namespace too

12:07 lein does not know which of your namespaces you want to use or require in the user namespace

12:07 some of them might even have colliding definitions

12:07 atrerus: right... but even if I change to (ns foo) which is defined in foo.clj, I'm not able to access the functions in that file

12:08 so it doesn't seem to be a problem with 'use', but more that the files are not being compiled into the slime environment

12:08 stuartsierra: atrerus: you need to load the clojure source files with 'require' or 'use'

12:08 raek: you would want to do a (use 'foo) / (ns user (:use [foo]))

12:09 then you can use the definitions in foo from user

12:09 atrerus: k... I'm still not understanding but I'll play with it some more

12:09 thanks for your suggestions :)

12:10 raek: think of foo, bar and user as different files, which can use definitions from each other

12:10 every definition "lives" in a namespace/file

12:24 arohner: man, a spell checker on lein deps would be nice. Probably 50% of my lein dep failures come from me mistyping the dependency

12:24 but you'd need to download the entire mvn database to do that

12:24 ...

12:25 atrerus: someday I bet lein gets integrated as an IDE plugin

12:25 hmm... isn't there a webservice you could talk to?

12:26 ambient: lein still is linux (bash) dependant?

12:27 Raynes: ambient: Last I checked, Leiningen on Windows is "experimental".

12:27 Whether it works at all, I have no clue.

12:34 powr-toc: What's the most idiomatic way to swap! an already computed value into an atom? (swap at (fn [] val)) ?

12:34 AWizzArd: reset!

12:35 powr-toc: great! :-)

12:35 AWizzArd: (reset! at val) or maybe (swap! at identity val)

12:35 no, not identity, but (fn [_] val) instead

12:37 powr-toc: Yeah, I did consider those... but reset! definitely seems most idiomatic

12:38 dnolen: ambient: if you use msysgit on windows you get a bash shell.

12:38 powr-toc: I was thinking (partial identity val) but that's a mouthfull

12:44 rhickey: ,((constantly 42))

12:44 clojurebot: 42

12:44 atrerus: raek: ok, I did just need a 'use'... I don't know what I was doing before. Thanks :-)

13:00 saml: do you use clojure in j2ee setting? like, creating beans and stuff?

13:00 dakrone: why does (constantly ...) exist? I mean, can someone give an example of what it's used for?

13:18 jcromartie: ugh I've got a circular dependency onw

13:18 now

13:19 ohpauleez: dakrone: I can't think of a practical case, but it's helpful if you have a constant that you constantly need to put in a spot where it'd be called like a function

13:19 saving you lambda syntax

13:19 dakrone: hmm, okay, that makes sense

13:19 thanks

13:30 jcromartie: what's the best way to eliminate circular dependencies

13:30 Licenser: What is the best way to trace down the source of a stack overflow? since the Excetion itself does not hold much useful information aside that it was caused somewhere under the main function :/

13:31 jcromartie: move them into a 3rd file, at least that is what I did

13:31 ordnungswidrig: re

13:33 Licenser: wb ordnungswidrig why are you hiding from #clojure.de? :P

13:33 ordnungswidrig: hmm, can anybody help my out with gen-class? I have defined foo.Classname in /foo/Classname.clj and therin is (ns foo.Classname (:gen-class))

13:33 Licenser: pfft, am I?

13:34 Licenser: and your gen-class looks good so far

13:34 Chousuke: ordnungswidrig: and what exactly is the problem?

13:34 Licenser: if you use lein yo also need to adjust the project.clj file

13:34 ordnungswidrig: Chousuke: slime C-c C-k nor lein compile will give me some classfile

13:35 Licenser: oi

13:36 I need to to tell lein what the main project file is to get it compiling stuff

13:36 ordnungswidrig: I read lein takes all ns from the src directory?!

13:37 will slime compile generate a class after all?

13:37 Licenser: not sure but to build a working .jar I had to add :main <root calss> to the project.clj

13:38 ordnungswidrig: Licenser: but it's not a main class. Just an implementation of an interface which is used to interface a java lib (lucene)

13:38 Licenser: ah okay

13:39 hmm a filter should with a 'flat' function should not cause a stac over flow should it?

13:40 hmm is a reroll of a transaction called as a stack level?

13:41 licoresse: hi all

13:41 chouser: Licenser: transaction retries do not consume stack, if that's what you're asking.

13:41 Licenser: thanks chouser ,that was at least what I tried to ask ^^

13:41 ordnungswidrig: lein compile does nothing...

13:41 Licenser: I was hoping that they would then I had a easy explenation :P

13:41 chouser: yeah, sorry.

13:41 licoresse: is deftype part of 1.2?

13:42 Licenser: ordnungswidrig: try to give it a main class just to see if that does something

13:42 licoresse: looking at stuart sierras lazytest

13:42 chouser: licoresse: 1.2 isn't out yet, but deftype is in the master branch

13:42 licoresse: ok

13:42 ,(doc deftype)

13:42 clojurebot: "clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being

13:43 ordnungswidrig: I'll try namespaces

13:44 licoresse: wish I had a clojure in emacs

13:44 a clojurebot, that is

13:45 ordnungswidrig: neither :main [myns] nor :namespaces [myns] change anything...

13:45 Licenser: hrm

13:45 licoresse: you have SLIME REPL?

13:46 licoresse: yes

13:47 Licenser: then you can type (doc deftype) in there ;)

13:47 licoresse: in my understanding, clojurebot is something that accumulates updates from this channel

13:47 Licenser: hmm so anyone some advice on about how to trace a stack overflow?

13:47 oh okay didn't knew that

13:47 licoresse: ,how can I have you?

13:48 clojurebot: java.lang.Exception: Unable to resolve symbol: how in this context

13:48 Licenser: I think there is a irc client for emacs :P

13:48 licoresse: but, would'nt I polute ?

13:48 this channel then...?

13:48 Licenser: be carefull or clojurebot will file sexual harassmant charges Licenser :P

13:48 /msg clojurebot ,(doc deftype)

13:48 hiredman: clojurebot responds to private messages

13:49 licoresse: ah, nice

13:49 thanks

13:49 hiredman: you should be able to do doc lookups in emacs

13:49 licoresse: I can, very well thanks

13:49 but I wanted the wit as well

13:50 another thing I miss, examples included in the docstring

13:50 or attached as meta or whatever

13:50 stuartsierra: licoresse: if you're still talking about lazytest, I'm going to add more documentation

13:51 ordnungswidrig: ok, here is the solution: I used dashes in my nsname.

13:51 licoresse: stuartsierra: cool, I was not specifically thinking about lazytest now..

13:51 ordnungswidrig: the funny thing is, this is the second type this happens to me… FYI: substitute them by _ in the file/dir names

13:52 Licenser: heh

13:55 ordnungswidrig: I should stop naming my project with dashes

14:04 Licenser: does doall build stack?

14:05 ordnungswidrig: Can anybody tell my why I seem to need to have (ns (:gen-class (:import a.b.c.D)) instead of (ns (:import a.b.c.D) (:gen-class :extends D))

14:07 stuartsierra: ordnungswidrig: That's wrong.

14:07 chouser: Licenser: nope. calls 'next' in a tight recur loop. Does cache everything on the heap of course, but shouldn't consume stack.

14:08 Licenser: okay so no reason for stack overflow there :( is there a way to have it not eat heap?

14:08 stuartsierra: ordnungswidrig: It should be (ns (:gen-class :extends a.b.c.D))

14:08 ordnungswidrig: stuartsierra: damn outdated blog posts :-)

14:09 chouser: Licenser: well, it's purpose is essentially to eat heap. I mean, the reason you use doall is to realize and cache a seq. If you don't want to cache it, use dorun -- if you don't want to realize it don't call either.

14:10 Licenser: chouser: thank you!

14:13 herdrick: say, is there a better way to get a list of chars from a string than this: (seq (.toCharArray "abcd"))

14:14 Licenser: herdrick: I think a string is already a list of chars

14:14 cemerick: ,(seq "foo")

14:14 clojurebot: (\f \o \o)

14:14 herdrick: cemerick: oh, thanks!

14:15 also, is there any sign of java.lang.String being made non-final so we can have our own Clojure String class? So it can be a seq already, for example.

14:15 dnolen: ,(vec "foo")

14:15 clojurebot: [\f \o \o]

14:15 cemerick: Licenser: they're not, seq just turns strings into a sequence

14:15 ordnungswidrig: no the class is compiled but lein swank doesn't make it available in the classpath

14:15 stuartsierra: herdrick: impossible, but protocols will alleviate that

14:16 Licenser: well rest and first work fine on it

14:16 cemerick: herdrick: you wouldn't want strings to be sequences under the covers, anyway.

14:16 herdrick: oh, and drop and drop-last work fine, too

14:17 Licenser: I think all seq functions work on strings

14:17 herdrick: huh - is that new? I thought I tried that a year ago and it didn't work - maybe I'm mistaken

14:17 that's great

14:17 cemerick: I can't remember a time when that hasn't been the case *shrug*

14:17 herdrick: ok, thanks all

14:20 ambient: what worries me a bit is how all these tools that are commonly used for Clojure work if Clojure is built on CLR

14:21 so many java & linux/osx deps everywhere

14:21 Licenser: ambient: don't use it in CLR :P

14:21 no power to M$

14:22 ambient: it is just in a hypothetical situation if i wanted to write cross-platform code with Clojure, it might not be that easy to get rid of Java

14:22 cross platform as in what backend it uses, JDK/CLR/etc...

14:23 stuartsierra: ambient: Unless you can abstract away everything the JDK provides, you can't make it cross platform.

14:23 Licenser: hmm well java is more chross platfomrish thel CLR isn't it?

14:24 I mean java runs fine under windwos

14:24 brandonw: i would agree

14:24 Licenser: I don't really see any reaason to run clojure under CLR

14:25 brandonw: i thought it was interesting that both scala and clojure, two of the newer highly functional and concise languages are both primarily aimed at the JVM first, and the CLR second

14:25 Licenser: I don't see at all why they bother with CLR

14:25 ambient: CLR has loop unrolling though

14:25 brandonw: ambient: that was the most interesting thing about it

14:25 ambient: i might have to look into F# if I wanted to do functional stuff on CLR

14:25 brandonw: everything i've read says the clr is generally more advanced, especially for dynamic languages

14:25 Licenser: look at how clojure works, never treid it

14:26 brandonw: but jvm still seems to be the choice

14:26 Licenser: yea but that I can't run my clr code under *nix is kind of a killer argument against it

14:26 brandonw: yep

14:26 exactly

14:26 ambient: jvm because java is everywhere in the business world, lots of existing code

14:26 brandonw: so many things going to the web now, the jvm just seems better suited

14:26 ambient: clr code runs just fine in mono

14:26 Licenser: I run solaris and OS X, both don't support CLR and honestly the performance gain deliverd by clr is most likely eaten twice by windows

14:26 ambient: im under the impression of that

14:27 cemerick: wasn't there a variant of resolve that tossed an exception?

14:27 brandonw: yes, but then you have to deal with mono vs .net

14:27 Licenser: not to mention that I can't install windows on my server :P

14:28 cemerick: ambient: that's about 95% true. Problem is, if you need something from the last 5%, you're hosed.

14:28 brandonw: i know this is probably somewhat of a niche question, but has anyone played around with bwapi in clojure? i've seen a couple posts on reddit about people thinking about playing with it, but i haven't heard anything concrete yet

14:29 i ask because i know lisp has strong AI origins, and bwapi seems like a natural hobby project for clojure fans

14:29 ambient: brandonw: that looks like something i might be also interested in, got BW installed

14:29 * ambient wishes he had more time

14:29 brandonw: yeah tell me about it, heh

14:31 ordnungswidrig: hmm, won't lein swank give me aot-compiled classes in directory classes I compiled with lein compile?!

14:50 finally I learned my lesson: aot-compiled ns with dashes become classes with underscores.

15:14 ambient: what's the best way of installing the whole clojure toolchain with emacs? ELPA > clojure-mode > clojure-install?

15:14 ..these days

15:15 hiredman: the instructions in the README for swank-clojure on github

15:15 ambient: ok, ty

15:16 hm, "java.lang.ClassNotFoundException: org.lwjgl.opengl.GL11 (core.clj:9)..." seems I have to still install binary libs by hand

15:16 lein deps was pretty sweet though

15:17 dnolen: ambient: you don't have to do that. are you trying to use penumbra ?

15:17 ambient: yes

15:17 dnolen: I wrote a lein plugin in called native-deps

15:17 ambient: oh sweet :)

15:17 dnolen: add a :dev-dependencies to your project [native-deps "1.0.0"]

15:18 then, lein deps again to grab that

15:18 and finally, lein native-deps

15:18 ambient: it already had that in

15:18 dnolen: then lein swank to start up a REPL, connect from emacs

15:18 ambient: native-deps 1.0.0

15:19 dnolen: ambient: cool, then just run "lein native-deps", and start up swank in that folder, connect from emacs

15:19 ambient: ok, thanks

15:23 chouser: rhickey: the existence of cells allows us mortals to design things that are neither clearly state nor identity. That is, transient-like things whose semantics are only safe in a cell. Should we embrace such designs now when they seem to fit?

15:24 rhickey: chouser: dunno, that's an important question and one that will determine the viability of cells

15:25 obviously, people might have wanted to implement transient data structures just like Clojure's, so it really isn't related to cells

15:25 all such mutable things still lie in the realm of 'very hard, for experts only'

15:26 chouser: hm.. doesn't seem that hard anymore with cells there.

15:26 :-)

15:26 rhickey: but an important part of cells is the nesting, so you can build transient things on top of other cells

15:26 Chousuke: And yet, you have thousands of non-experts programming with mutable data structures all the time :P

15:27 Licenser: Mutates stuff!

15:27 rhickey: chouser: at the bottom though, lies #^{:unsynchronized-mutable true} in various bits. To the extent people use that, it's difficult

15:27 chouser: _fogus_ and I are kicking around a design for wrapping a mutable matrix, trying to figure out where (and if) cells belong.

15:28 rhickey: at least if you stick with cells containing the mutable things, the system will ensure sequentiality, which is a big deal. You still have to deal with aliasing of mutable bits

15:28 Licenser: so when the matrix is mutable, the dejavu thing with the reapearing cat is a transaction rollback?

15:29 rhickey: chouser: it's critical that you be able to efficiently produce a value.

15:29 dnolen: rhickey: one question that's been floating around in my mind, are cells good for providing fast and safe access to Java arrays?

15:29 chouser: seems to me that to be a true value, every "set" operation would have to clone the underlying matrix -- insufficiently performant.

15:29 rhickey: that dual persistent/transient nature is not nothing

15:30 dnolen: arrays would become copy-on-read

15:30 with caching

15:30 sometimes that's good enough, but it's not a general solution like persistent data structures

15:30 chouser: but if instead we provide two wrappers, one with only lookup methods, and the other with setters, and wrap the pair up nicely in protocls cells understand, then we get performance and safety, but require users to use cells

15:31 rhickey: chouser: you mean to read via cells, never produce a value?

15:32 chouser: no, I mean dereffing a cell that contains the mutable wrapper would produce an immutable wrapper around the same underlying matrix

15:32 Chousuke: chouser: I had that same idea just now :P

15:32 chouser: you typed faster

15:32 chouser: a value.

15:33 subsequent transient-of would clone the matrix, and put the mutation-supporting wrapper in the cell's transient part

15:33 rhickey: chouser: so, copy-on-read

15:33 chouser: I guess the clone point could be either at first-read or first-write.

15:33 sure

15:34 rhickey: copy-on-read is the basic fallback for non-persistent designs

15:34 * _fogus_ bummed he has to leave

15:35 chouser: so this is a reasonble pattern to suggest for the general case of trying to sanitize a useful but non-persistent Java object?

15:36 * rhickey wants mutable in refiy...

15:36 Chousuke: you might allow for explicitly invalidating a read-only view so that the underlying transient can be used in a cell again and no clones need be done... but that sounds a bit complicated.

15:36 rhickey: chouser: yes, and what's nice is that if it doesn't have a synchronization policy, still safe

15:36 Chousuke: that's not going to happen

15:37 chouser: tidy up exposed methods to provide an immutable wrapper, and then require users to use cells

15:37 rhickey: chouser: even without a wrapper, a policy of don't mutate out of cell is still better than not

15:37 a big problem with wrappers is they are not the type of the thing they wrap

15:37 * rhickey hates wrappers

15:38 rhickey: so, it comes down to prevention vs safe recipe

15:38 e.g. Clojure uses arrays immutably, extensively

15:38 chouser: I had a feeling you wouldn't like my idea of a macro that generates a protocol based on a concrete class

15:39 rhickey: chouser: the interop issues with wrappers are not trivial

15:39 chouser: (...for use in a reify that closes over an instance of the concrete class)

15:39 yes, but Clojure's use of immutable arrays makes are not themselves arrays. That was your point?

15:39 rhickey: in a pure interface or protocol based design, you could just match the interfaces/protocols in the wrappers

15:40 chouser: just that I didn't need to prevent myself from mutating the arrays, just treat them as if immutable

15:40 chouser: oh, I see.

15:41 rhickey: ditto some POJO, you might just decide to use the read-only methods, as long as you could tell what they were

15:41 chouser: I prevent myself from doing things all the time. I guess I shouldn't be surprised when I then find it difficult to do things. *sigh*

15:42 rhickey: cells themselves are a recipe and support tool for doing the right thing - they don't make pojos go away

15:42 chouser: in that case, instead of wrapping the matrix, could just extend IEditable and ITransient to it.

15:43 rhickey: lemme gist this iter-seq stuff, it might give you some ideas

15:43 chouser: er, extend the matrix to Editable and Transient

15:43 rhickey: it would only be extended to one, and the result of that to the other

15:44 dnolen: rhickey: good to know. so we still have to wait for unboxed operations on vectors of natives. cells are not an essential part of that story, is what I'm getting out of this.

15:45 * chouser bakes a hacksaw into a cake and mails it to foo: (<< identity foo)

15:45 rhickey: returning anything mutable from a cell is a no-no

15:46 chouser: the sentry was awake and alert, but somehow didn't notice

15:48 rhickey: more cells/iter-seq work in progress: http://gist.github.com/306174

15:48 now faster than chunks in all cases

15:48 chouser: ha! cool.

15:48 rhickey: works with existing non-transient seqs

15:49 chouser: ~300 LOC seems to come up a lot in Clojure code. It's the size of a significant module or feature.

15:49 AWizzArd: rhickey: can this file completely replace your previous cells.clj?

15:49 rhickey: 2 features in this case

15:49 AWizzArd: this is not a deliverable :)

15:49 chouser: oh, I see. cells in there

15:50 AWizzArd: I currently have your cells.clj in my project and I load-file it.

15:50 rhickey: the value-of-reify-transient-of chaining is really interesting. it's another way of saying 'clone'

15:51 dnolen: rhickey: wow, much faster? chunks were pretty zippy and made sense "why" they were faster. I still don't understand how/why cells can be faster.

15:51 cemerick: I've got an anon fn that loads in the REPL and can be used just fine, but causes a "No matching ctor found for class com.foo.fsm$def_state_machine__1315$dispatcher__1318" exception when loaded from AOT'd classfiles. Any ideas?

15:51 rhickey: so, still todo for you macro hackers is to factor out the boilerplate from mapx/filterx/takex

15:51 Licenser: can too many dosyncs cause a stack overflow?

15:51 * dnolen still in the dark about _true_ nature of cells :\

15:51 rhickey: cemerick: if the anon fn closes over anything it's a no-go for AOT

15:52 cemerick: shite, that's what I figured.

15:52 AWizzArd: I did not follow the discussion, but do these iter-seqs have something to do with lazyness?

15:52 cemerick: rhickey: anything anything, or only certain classes of anything? ;-)

15:52 rhickey: AWizzArd: IterSeq ia another way to implement lazy-seq

15:52 cemerick: no closed-overs

15:53 cemerick: the ctor call is hardwired to no-args

15:53 AWizzArd: Would that IterSeq still always take 32 elements as one chunck out of a lazy seq? Or does this not have anything to do with it?

15:53 rhickey: and fn serialization makes no attempt to spit out closed-overs

15:53 AWizzArd: nothing to do with chunks, doesn't leverage chunks

15:54 cemerick: rhickey: Thanks :-)

15:54 looks like I macro'd myself into a hole, then...

15:55 chouser: did the fn-in-macro-expansion change? I thought it never worked, but now appears to work sometimes, perhaps only when not AOT?

15:55 rhickey: I think mapx et al can be reduced to a macro taking the bodies of has-item/item/move!/clone

15:55 Licenser: hmm is cons or remove lazy?

15:55 chouser: remove is lazy

15:55 cemerick: chouser: yeah, it works fine outside of AOT AFAICT

15:55 Licenser: aha remove is!

15:55 rhickey: non-closure fns have worked for a while

15:56 chouser: cemerick: I really thought that hadn't worked since shortly after AOT was born.

15:56 cemerick: chouser: or, let's put it this way, it works well enough to pass my non-rigorus REPL fiddling. The first real build bonked, of course.

15:58 * cemerick convinces himself that that fn really wanted to be a top-level, anyway!

15:58 chouser: rhickey: you still like ":as this"?

15:58 rhickey: chouser: vs?

15:58 Licenser: thanks chouser

15:58 chouser: hm... implicit "this" I guess.

15:59 rhickey: implicit this is broken for reify

15:59 chouser: yeah because of nesting. deftype doesn't nest.

15:59 rhickey: right, but we wanted the same

15:59 chouser: yep, ok

15:59 AWizzArd: and on the other hand this one line will not make programs unreadable and hackers unproductive

16:00 rhickey: now I want mutable decls for reify, as I had to break range out into a deftype for that reason only. Also take uses an atom and wouldn't

16:00 chouser: hmmm.. an uber-reify was planned anyway, wasn't it? but perhaps that was only for interop.

16:01 AWizzArd: An über-reify? Is that a new newnew?

16:01 rhickey: chouser: this doesn't get into uber-reify teritory, just something deftype can do that reify can't, at present.

16:01 need a place for the decls

16:03 chouser: yeah, that's weird. don't really want a mutable local to close over, so would be another "level" of lexical scope?

16:03 rhickey: if you recall, the original reify had options somewhere for that stuff

16:04 chouser: still has :as. Could have :unsynchronized-mutable [a b c]

16:04 rhickey: right

16:05 then range could fit the same pattern

16:05 jcromartie: when I use middleware that depend on one another in compojure, I have to specify them in the reverse order of what I expect

16:06 AWizzArd: jcromartie: yes, the last handler that you list runs first

16:06 jcromartie: that seems odd

16:06 wthidden: question: Does the repl force a delay object?

16:06 chouser: sounds a bit like 'comp'

16:06 AWizzArd: yes, i also thought so, but you will get used to it :)

16:06 jcromartie: k

16:07 tomoj: just look at what your middleware actually does

16:07 AWizzArd: You can simply accept it and be done, or write a macro that reverses it

16:07 jcromartie: I think it's because decorate uses -> right?

16:07 chouser: wthidden: currently, yes

16:07 wthidden: but does not block on a 'future'. hm...

16:07 AWizzArd: not anymore

16:07 dnolen: jcromartie: it's consistent with comp. I think that's the important take away.

16:08 jcromartie: I see

16:08 AWizzArd: dnolen: although I always wished to have a pipe that works similar to ->

16:08 a reversed comp, because that is how I think about the data going through my chain of fns

16:09 wthidden: chouser: thanks, that clears up a few things I've been seeing... and how did you know my next question was going to be about future? :)

16:09 jcromartie: I can read (comp x y z) as "The x of y of z" right?

16:10 AWizzArd: yes

16:10 chouser: wthidden: btw, I just experimented to confirm that before answering.

16:10 ,(time (prn (delay (Thread/sleep 1000) :hi)))

16:10 clojurebot: #<Delay@18234b0: :hi> "Elapsed time: 1002.025 msecs"

16:10 jcromartie: ,((comp + seq str) 123)

16:10 clojurebot: java.lang.ClassCastException

16:10 chouser: ,(time (prn (future (Thread/sleep 1000) :hi)))

16:10 clojurebot: #<Object$IDeref$Future$2b9be1f9@3578af: :pending> "Elapsed time: 2.714 msecs"

16:10 jcromartie: hmm

16:12 d'oh

16:12 AWizzArd: jcromartie: apply

16:13 you did (+ (1 2 3))

16:13 jcromartie: well it's broken in other ways too :)

16:13 somnium: ,((comp (partial apply +) (partial map #(Integer/parseInt %)) (partial map str) seq str) 123)

16:13 clojurebot: 6

16:13 jcromartie: ("1" "2" "3")

16:13 stuartsierra: Lazytest, now with documentation! http://github.com/stuartsierra/lazytest

16:13 jcromartie: ah, partial

16:14 AWizzArd: somnium: why do you use partial? :)

16:14 jcromartie: AWizzArd: because that's how you can do apply in comp

16:14 AWizzArd: why not #(apply + %) ?

16:15 or #(apply + %&) ?

16:15 jcromartie: looks like perl :)

16:15 that's why

16:15 somnium: AWizzArd: if you alias to one character its not so bad

16:16 jcromartie: (partial apply +) seems pretty elegant to me

16:19 hiredman: :D

16:21 jcromartie: what's a good example of where partial application is handy?

16:21 I'm trying to explain it to a friend

16:21 (partial + 1) is just not that impressive

16:22 Chousuke: in clojure it's not that useful so often :/

16:22 hiredman: ,((reduce partial + '(1 2 3)))

16:22 clojurebot: 6

16:23 Chousuke: wait. what.

16:23 that's evil

16:23 jcromartie: Chousuke: what about clojure makes it less useful?

16:23 hiredman: :D

16:23 tomoj: no auto-currying, maybe?

16:24 Chousuke: in haskell it's better since you can do something like stringUpper = map toUpper

16:24 tomoj: though that just makes it more verbose

16:24 Chousuke: (I can't remember the proper function names, but anything)

16:24 somnium: ,(let [f (partial apply hash-map :opt1 42 :opt2 "bam")] (map f [ [:a 1] [:b 2] ]))

16:24 clojurebot: ({:opt1 42, :opt2 "bam", :a 1} {:opt1 42, :opt2 "bam", :b 2})

16:25 Chousuke: macrofied part of the iterfn stuff: http://gist.github.com/311525 ... completely untested :D

16:25 somnium: ah, what cant you do with #()? any other tricks hiredman?

16:25 Chousuke: also not as generic as it could be, I think

16:26 hiredman: #() creates a function and so does partial

16:27 somnium: but partial is a fn

16:27 hiredman: sure

16:27 Chousuke: partial creates a closure

16:27 doesn't it?

16:28 #() creates an actual class

16:28 rhickey: Chousuke: I think you can stay away from the defn bits - you want the body - should define a factory fn - currently iter i nall cases - that might take varying args, plus a fourth body - that of transient-of. Finally, the initial call to the factory should be in the hands of the user too

16:30 the bodies in [] is weird, probably better to force use of do when needed

16:36 Chousuke: rhickey: good ideas. I'll take a look at it later

16:36 rhickey: that was just a quick hack for now :)

16:37 rhickey: Chousuke: a sample of use: http://gist.github.com/311542

16:38 oyu could always add factoring out the defn and the iter-seq call

16:39 but the factory fn must have a name and arglist as it might vary, and needs to be available to the body

16:49 naeu: hi there, can anyone point me towared some docs explaining the purpose of ~

16:49 i'm guessing it's some sort of reader macro

16:50 somnium: naeu: http://clojure.org/reader is one place

16:50 naeu: somnium: thanks

17:05 herdrick: jcromartie: among the pointfree stuff, comp ("compose") is a bigger win. when you can use it, it's great.

17:08 jcromartie: yes it's definitely one of those "FP things" that makes people look at you funny when you start ranting abou tit

17:08 :P

17:09 somnium: jcromartie: how do they look at you when you bring up monads?

17:09 jcromartie: heh

17:09 I don't even go there

17:09 (personally)

17:09 right now I'm just trying to build a JSON API and not get fired

17:09 and tinker with some game dev

17:09 somnium: :)

17:10 jcromartie: I am really interested in the possibility of a game that uses pure functions and keeps a history of the world state, so time can be rewound and the code reloaded and a segment played again.

17:11 that would be pretty much the most awesome dev environment ever

17:11 "oh I wasn't supposed to be able to walk through that wall..." <pause> <rewind> <edit code> <resume> and it works!

17:12 herdrick: jcromartie: that sounds awesome. could you keep us updated on your progress? (on the mailing list)

17:13 jcromartie: yeah I am starting with a SHMUP inspired by the Penumbra asteroids example (since most of the properties of things in a SHMUP can be calculated as a function of their origins and other properties)

17:13 yeah

17:13 somnium: jcromartie: you might like this post if you havent seen it http://prog21.dadgum.com/23.html

17:13 AWizzArd: When an object m (for example a map) references some other objects objs (= "putting them as values under some key into m"), can one then call the objs "referencees"? Does such a word exist in english?

17:13 jcromartie: yeah, I've seen that one, and Brian Carper's recent blog post

17:14 AWizzArd: maybe you can explain in code?

17:14 AWizzArd: Imagine a (deftype User [username password name age city friends]), where :friends will store a list of other users.

17:15 When you have me in your friend list, then we can not simply delete my user from the system, because there is still a reference on it in your instance.

17:15 jcromartie: yeah that would be reference counting

17:15 somnium: I wonder if an FF clone would be good for marketing: ClojureQuest -> Prophecy of the Cell

17:16 jcromartie: hah!

17:16 AWizzArd: how would you call the passive role of my object?

17:16 Pointee? Referencee?

17:17 stuartsierra: AWizzArd: referant

17:17 Or referent

17:18 More commonly referent.

17:18 AWizzArd: oh good, thanks

17:20 stuartsierra: http://www.patentstorm.us/patents/6064814/claims.html seems to use "referencee". Is that a synonym?

17:21 stuartsierra: maybe

17:46 jcromartie: could someone take a second look at this for me? http://gist.github.com/311614

17:46 it feels weird

17:49 I couldn't quite get letfn to feel natural either

17:50 or should I just be more explicit and take & inits and check (map? (first inits))

17:51 kotarak: jcromartie: or split in two: (make-create! & kvpairs) (make-from! to-be-cloned-obj)

17:51 jcromartie: hmm

17:58 also what's the best way to catch maps and structs in a multimethod?

17:58 clojure.lang.Associative ?

17:58 raek: (map? x)?

17:58 oh

17:59 kotarak: (with-meta the-map-or-struct {:type ::MyStructTypeTag}) and then dispatch on type

17:59 chouser: Associative matches vectors too

17:59 kotarak: ,(type (with-meta {} {:type ::Foo}))

17:59 clojurebot: :sandbox/Foo

17:59 AWizzArd: jcromartie: depends on what you want as your dispatching function

17:59 jcromartie: AWizzArd: class

18:00 kotarak: jcromartie: you want type not class.

18:00 raek: jcromartie: either that or clojure.lang.ILookup

18:00 hiredman: ,(set (keys {:a 1 :b 2}))

18:00 clojurebot: #{:a :b}

18:00 jcromartie: I want to catch a certain Java class, maps, Strings, nil

18:00 AWizzArd: when you want to dispatch for the type, then maybe you should not use a map/struct but deftype instead, and not a multimethod but Protocoll

18:00 kotarak: AWizzArd: If you want to cut your fingers.

18:00 hiredman: check to see if the keyset has the keys you are interested in

18:00 Chousuke: rhickey: http://gist.github.com/311629 take two. again, not actually tested, but macro expansions look sane.

18:00 jcromartie: AWizzArd: sounds like something to learn later

18:01 Chousuke: rhickey: still has some repetition, but at least it reduces the noise a bit :/

18:01 AWizzArd: kotarak: why?

18:01 chouser: this is so amusing and terrible: http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext

18:01 AWizzArd: when you implement clojure.lang.IPersistentMap you can add new key/value pairs to your deftypes too.

18:01 kotarak: AWizzArd: because you have to use bleeding edge to Protocols and Deftype. This is maybe not viable in a given project.

18:01 AWizzArd: What is bleeding edge about them?

18:02 hiredman: AWizzArd: there is no release that supports them

18:03 AWizzArd: One can always try build.clojure.org and see if that breaks existing code.

18:03 kotarak: AWizzArd: there are commits (eg. meta data for fns) which might break things. There are reasons to stay with 1.1 until such things are settled.

18:03 hiredman: AWizzArd: even if it doesn't forces anyway who consumes your code to use an unreleased build

18:03 jcromartie: OK so what should I do :P

18:04 AWizzArd: Without people using deftypes and protocols they can never get fixed :)

18:04 jcromartie: dispatch on type

18:04 hiredman: it's not very good neighborly

18:04 kotarak: jcromartie: dispatch on type, use a type tag in the metadata of your struct

18:04 AWizzArd: Although there is nothing broken in them, they work perfectly fin.e

18:04 jcromartie: kotarak: I am not using any particular struct

18:04 it may just be a map

18:04 or a struct

18:04 either way

18:05 hiredman: jcromartie: just check the keys

18:05 jcromartie: maybe I need a different dispatch function

18:05 hiredman: yeah

18:05 Chousuke: hmm

18:05 kotarak: jcromartie: you can dispatch on IPersistentMap to catch maps and structs.

18:05 jcromartie: ah thanks kotarak

18:05 that's the easy solution right now

18:05 hiredman: or, you know, use map?

18:06 jcromartie: map? doesn't return true for structs

18:06 hiredman: really?

18:06 ~def map?

18:06 kotarak: jcromartie: and doesn't help with strings and such

18:06 jcromartie: oh, huh, wow

18:06 hiredman: ,(struct (create-struct :a :b) 1 2)

18:06 clojurebot: {:a 1, :b 2}

18:07 hiredman: ,(map? (struct (create-struct :a :b) 1 2))

18:07 clojurebot: true

18:07 kotarak: ,(type nil)

18:07 clojurebot: nil

18:07 jcromartie: yeah

18:08 kotarak: jcromartie: dispatch on type, and use IPersistentMap, String, nil, and whatever classes you need as dispatch values

18:08 jcromartie: so I need to catch strings, maps, and a specific Java class

18:08 so kotarak wins

18:13 AWizzArd: Am I the only one using deftype regularily? ^^

18:18 jcromartie: AWizzArd: no, you and all of the other edge users!

18:18 AWizzArd: I have to deploy this code :P

18:19 AWizzArd: Well, I use deftypes in a production environment.

18:20 jcromartie: that's cool

18:20 AWizzArd: No need for others to do that, but I just ean: it does not break my code.

18:20 ean --> mean

18:20 jcromartie: I'll use them when they show up when the "Alpha - subject to change" disappears

18:21 I think I also feel like deftype is too close to Java

18:22 I feel like you have to know a lot about Java before you really know why you'd want to use it

18:23 AWizzArd: I don’t even know how to spell jarwa and can use deftype

18:24 * somnium notices that Jawa would have been a much cooler name than Java

18:25 Chousuke: rhickey: http://gist.github.com/311647 One more version. None of these help in the Range case though :/

18:26 and I just now noticed one of those calls is missing a name for the iter :P

18:33 ezyang: Hey guys, does clojure have fold?

18:33 Chousuke: ezyang: reduce

18:33 ezyang: aha, cool

18:38 esj: to use Clojure 1.2 through leiningen I've been trying to use [org.clojure/clojure "1.2.0-master-SNAPSHOT"]

18:38 [org.clojure/clojure-contrib "1.2.0-master-SNAPSHOT"] but am eating the RestFn error. Which pair of clojure / contrib should I use ?

18:39 hiredman: clojurebot: RestFn?

18:39 clojurebot: ant clean and rebuild contrib

18:39 somnium: hiredman: he's trying to get a pair that works with lein

18:39 hiredman: but it could mean some other library you are using was compiled for a different version of clojure

18:39 esj: you know when you get clojure and contrib crossed

18:39 hiredman: somnium: *shrug*

18:40 esj: it gives you the RestFn error

18:40 hiredman: that is the only time I have seen the restfn error

18:42 esj: how do you keep this square ?

18:43 hiredman: I don't chase master

18:43 esj: i mean, how can I check which version of clojure is req'd for a particular jar ?

18:44 i'm missing what must be an obvious thing

18:44 hiredman: good advice

18:49 naeu: what's the best method for communicating via a usb serial connection with clojure?

18:49 I was looking at something called rxtx http://rxtx.qbang.org/wiki/index.php/Main_Page

18:50 but thought it sensible to check if there's not another accepted method

18:55 ezyang: Agggh repeatedly crashed my interpreter >:-(

19:03 Suppose I have [1 2 3] and I want [1 1 2 2 3 3]. How can I do this?

19:05 _mst: ,(interleave [1 2 3] [1 2 3])

19:05 clojurebot: (1 1 2 2 3 3)

19:06 ezyang: hm. will I get the right semantics with a stream?

19:09 _mst: it depends what you need. You can always coerce it back into a vector using (vec ...)

19:10 ezyang: well, I'm dealing with a 512K long stream, so I'd rather not have that be resident in memory :-)

19:10 seems to have the right semantics

19:11 _mst: ah, yep :) interleave is lazy so it won't pull the whole lot into memory if you don't consume it all at once

20:16 dnolen: anybody mess rhickey's cells stuff from ealier? I curious how you convert the result of mapx, reducex, rangex into a value.

21:23 slyphon: me is having circular dependency headaches

21:23 asldfijadsiljfliasjf

21:23 * slyphon FAIL

21:24 slyphon: is it possible to declare your namespace :use blocks in a common namespace that everything else uses?

21:25 for stuff like clojure.contrib.logging, rather than having to duplicate it everywhere/

21:25 ?

21:25 chouser: hn. you can put whatever you want in a .clj file and

21:25 slyphon: or do people usually just duplicate it everywhere

21:25 chouser: load-file

21:25 dunno if that's "good", but it's possible

21:25 slyphon: ah

21:25 is it "good" to declare it in each file?

21:27 i'm having trouble figuring out when to use :use/:require, in ruby, for instance, i'd usually have a top-level module that would pull in the other modules in the order they needed to satisfy dependencies

21:27 chouser: I've never split my files up small enough to desire avoiding repetition

21:27 slyphon: ok, that's fair

21:30 * slyphon looks around for a style guide

21:33 hiredman: it would be nice if ns was pluggable

21:33 slyphon: hrm

21:47 pthatcher: pthatcher: I started playing with cells and deftype and defprotocol. Hashing (sha1, etc) seemed like a good use case for cells. So, here's my first try at it: http://gist.github.com/311790

21:57 brandonw: what would be the idiomatic way of finding an element of a seq that is not equal to a specific value, starting the search at an arbitrary index in the seq, and going backwards?

21:59 jcromartie: brandonw: (first (filter ... (drop n (reverse coll))))

22:00 ooh, or using comp and partial

22:00 (first (filter (partial (comp not =) x) (drop n (reverse coll))))

22:01 The More You Know(tm)

22:01 hiredman: bleh

22:01 jcromartie: no good?

22:01 too much

22:01 #(not (= x %))

22:01 hiredman: seqs arenot really good for indexed access

22:02 jcromartie: then loop it is

22:02 brandonw: well, this step will shave off several recursions

22:02 err nevermind that doesn't matter

22:02 hiredman: jcromartie: loop would not be any different

22:03 jcromartie: better to use a vec, then?

22:03 brandonw: well i am constantly taking elements at the start off and on again

22:03 actually, let me check

22:03 jcromartie: brandonw: what are you trying to do?

22:03 in the bigger picture?

22:04 brandonw: yes, it is constantly being operated on and is a seq already

22:04 so i would have to be constantly transforming it back into a vec

22:04 hiredman: if the seq is what you have, then it's what you have, but using them for indexed access is bleh

22:04 brandonw: i haven't needed it for indexed access until now

22:05 i'm trying to optimize the last bit of inefficiency in the puzzle solver i made as my first clojure project

22:05 jcromartie: it sounds like you could use vectors

22:06 brandonw: well, i am basically using a brute force solver in a constraint satisfaction problem

22:06 hiredman: jcromartie: vectors won't let him add to the begining

22:06 brandonw: every time the state of the snake is invalid, i recurse upwards, and transform the current three-dimensional state of the snake on a certain joint

22:07 well, hmmm

22:07 i think i could use a vec in that specific piece

22:08 well actually, this is good because it illustrates my lack of understanding in vecs

22:09 i know they are best for sequential access, but i don't understand how they can be usable if nearly every operation you perform on a vec returns a seq

22:09 unless the *only* thing you use with the vec is nth and other functions that either work very well with arbitrary indices, or are functions specifically designed for vectors (like conj)

22:10 hiredman: right

22:10 the other operations are not operations on vectors, they are operations on sequences

22:10 brandonw: okay

22:11 so if i am performing several seq operations per level of recursion, but only using nth once or twice, would it be worth it to convert the seq to a vector just for a couple of index-based calls?

22:11 hiredman: they call seq on their argument so you can pass a vector or a map or anything that seq can turn into aseq

22:11 brandonw: I don't know

22:12 brandonw: i'm going to try it with a seq just to see what the speed up is at the moment

22:13 dnolen: brandow: if it's already a vector

22:13 jcromartie: can anybody here offer advice on organizing a compojure web app?

22:14 I feel lost and frightened without a big framework to conform all of my stuff to

22:14 :P

22:14 defn: jcromartie: trial and error

22:14 jcromartie: yay

22:15 brandonw: haha

22:15 defn: jcromartie: i suggest doing something like controllers/application.clj, views/application.clj, etc.

22:15 scottbot: jcromartie: I used to have a 600 line file which contained everything, and am now splitting off small chunks into several 20-50 line files

22:15 brandonw: jcromartie: make sure you write it up on a blog somewhere. i don't want to go through that ;)

22:15 jcromartie: yeah :)

22:15 controllers and views make sense

22:16 I have a base layer with a JSON api sitting below my ui layer, namespace-wise

22:16 so it would be like project.ui.views.home.clj

22:16 defn: yeah i think that's a good way to go

22:16 jcromartie: API and data

22:17 dnolen: jcromatrie: organize your code around routes. I would make each namespace a logical application which defines routes which you add to the master routes. I'm against the distinction between controllers and views. It just functions, not MVC. This would especially well if you're using something like enlive to render your pages.

22:17 ezyang: How do I make Eclipse think it can run a main function from a clojure file?

22:17 jcromartie: dnolen: that's what I've done with my data/API layer

22:18 project.access/api is a route, etc.

22:18 defn: jcromartie: depending on the size of the app im also not opposed to just splitting the whole thing up by functionality, and then having a utils.clj which is the glue, server.clj which handles routes, etc.

22:18 ezyang: Do I actually have to make a class?

22:18 jcromartie: yeah

22:18 brandonw: jcromartie: okay to make it a little more complex... what if i revised my original request to find the element's index instead of the element's value?

22:18 jcromartie: this is really a quick-and-dirty fast-and-loose app, I want to have it done tonight

22:18 dnolen: jscromartie: should be the same for your "view" layer as well. it's just functions. Some modify data, other deliver html.

22:19 jcromartie: dnolen: yup

22:24 brandonw: i think to get the index i'm going to have to write my own recursion

22:30 dnolen: brandonw: clojure-contrib.seq-utils. indexed is lazy, why do you need to write your own recursion?

22:40 brandonw: because i haven't looked at clojure.contrib much, that's why :D

22:40 there is way too much good stuff in clojure

22:40 i need a plug to my brain to just upload it all in

22:42 i've got the recursion done so i guess i'll just leave it and hopefully i remember to look at seq-utils next time...

22:43 dnolen: brandonw: heh, it does take a while to learn where everything is. I think played around with Clojure for months before I discovered update-in assoc-in :P

22:45 jcromartie: is http://wiki.github.com/cgrand/enlive/getting-started out of date?

22:46 because I can't get ID selectors to work based on that sample code in there

22:46 brandonw: yeah i think i was here the other night when someone mentiond it

22:46 and i was kinda like 'holy crap, is there any trivial piece of functionality that ever actually needs to be implemented? or is it all already here..."

22:47 dnolen: jcromartie: brandonw: typo

22:47 :div#d1

22:47 not :div#:d1

22:47 jcromartie: ah

22:47 that makes more sense

22:47 dnolen: http://github.com/swannodette/enlive-tutorial

22:47 also

22:47 7 examples

22:47 scrape Hacker News, New Yorks Times, and some really fancy

22:48 jcromartie: fixed

22:48 dnolen: templating stuff that mimics Django, Mako, Rails style template inheritance but cooler because HTML and code separations

22:48 my tutorial needs work but the code is there, and it uses lein so it's easy to go through

22:49 once Enlive supports HTML fragments (to support common looping cases) I'll wrap it up and polish it.

22:54 jcromartie: HTML fragments?

22:54 dnolen: Enlive has one glaring deficiency. It handles looping a single item in a container well.

22:54 jcromartie: I want to repeat a whole matched element, but with certain elements transformed

22:55 dnolen: but not the <h1></h2><p></p> pattern

22:55 used commonly with JS accordions and the like.

22:55 jcromartie: like, <ul><li><span class="a">I want to transform this</span></span class="b">And this too</span></li></ul>

22:55 is that doable?

22:55 dnolen: yes

22:56 even the <h1></h1><p></p> pattern is doable just not pretty.

22:56 jcromartie: so would I use clone-for?

22:57 dnolen: for repeating a single item (which can contain other items of course) yes.

22:57 clone-for doesn't handle looping ranges of items, Christophe Grand is working on it tho.

22:57 there are workarounds, check the Enlive mailing list.

22:58 jcromartie: OK so as an example...

22:58 I am not finding any good examples of something like what I'm trying to do

22:59 dnolen: jcromartie: you want to loop the li and replace the contents of span.a span.b right?

22:59 jcromartie: yeah

22:59 I feel like I'm missing some docs that I just saw recently, but aren't in the readme/wiki

23:01 ah

23:01 (substitute (select ...)))

23:02 or [:li] (clone-for [x xs] [:span.a] (content x) ...)

23:03 dnolen: jcromartie: I think you need "at" as well

23:04 jcromartie: this is working so far

23:07 dnolen: jcromartie: totally right, need to add an example of clone-for to my tutorial :)

23:12 jcromartie: holy crap, don't try to print a Date in enlive

23:12 infinite stack trace

23:13 dnolen: jscromartie: yeah you always need to convert things to strings first. I make that mistake all the time.

23:28 defn: how to make a timer in clojure..

23:28 hiredman: ScheduledThreadpoolExecutor

23:34 defn: Can I import a java libary :as X?

23:38 nvm on the last question...

23:38 Is there a way to list the possible methods for a java object in the REPL?

23:39 _mst: (use 'clojure.contrib.repl-utils) then (show (Object.))

23:40 defn: _mst: awesome. thank you.

23:40 _mst: one other question for you... I am just trying to make a basic timer that counts down like 20min or something

23:40 Is it possible to just do that with a future?

23:40 _mst: I guess so... but why not just Thread/sleep?

23:40 defn: _mst: just curious I guess

23:41 _mst: well, I guess: (future (Thread/sleep (* 20 60 1000)))

23:41 will create you a future that'll block for 20 minutes when you call (deref ...) on it

23:42 hiredman: _mst: nope

23:42 _mst: hm. what'd I miss?

23:42 hiredman: futures start immediately

23:42 _mst: ah, yes. quite right

23:48 arohner: ,(conj {} '(:a 1))

23:48 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

23:48 arohner: ,(conj {} [:a 1])

23:48 clojurebot: {:a 1}

23:48 arohner: why does one of those work, and the other doesn't?

23:48 ah, (source conj) helps

Logging service provided by n01se.net