#clojure logs

2010-02-22

00:00atrerusI'll try that out
00:00defnyeah you don't need to do that, and IIRC swank-clojure does some other nice stuff for you
00:00defnit includes M-x swank-clojure-javadoc for example
00:01atrerusis lein necessary at all then?
00:01defnthey do different things
00:02defnwith 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"]]
00:02atrerusmy main goal is to be able to load a project directory, as well as set some arbitrary classpaths such as clojure-contrib and ant
00:03atrerushmm ok
00:03defnthen i run lein deps in that project directory
00:04defnthen i use M-x swank-clojure-project and that opens a new repl for me which adds all of my dependencies to the classpath
00:04defnand IIRC it also adds your namespaces to the classpath as well
00:04atrerusk
00:04defnerr that doesnt make sense, but you have access to your namespaces via the repl automatically
00:05defnatrerus: make sure you have :dev-dependencies [[swank-clojure "1.1.0"]] in your project.clj and run lein deps before using swank-clojure-project
00:05KirinDaveWhy did ztellman remove his clojure and clojure-contrib dependencies from lein?
00:05KirinDavehttp://github.com/ztellman/penumbra/commit/86b4fb677c27bfde03b682a9e347663d1f708c57
00:06KirinDaveThis screwed me up, but it seemed deliberate
00:06defn*shrug*
00:06KirinDaveIs there a good reason to do that?
00:07defnmaybe he has clojure source and already has an env var with them on his classpath
00:07defnand doesn't want the released jars
00:07defncause he is more current
00:07KirinDaveSure, but that means no one else can participate.
00:07defni dont see why not
00:08KirinDaveWell you gotta implicitly have those deps
00:08defni agree it's probably not best practice for code you're releasing
00:08atrerusdefn: I seem to be getting the same result with M-x swank-clojure-project
00:08defnbut perhaps it wont work with anything but the latest
00:09defnatrerus: i dont really understand what you're trying to accomplish
00:09atreruslol
00:09defn(use 'clojure.contrib.some-library)
00:09atreruswell, I'm trying to get the lancet example from Stu's book to work
00:09defnyou 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
00:10atrerusso I've got a file which includes a def for "ant-project", and I want to be able to reference that from SLIME
00:10KirinDaveactually in general lein is pissing me off.
00:10KirinDaveEveryone somehow is using a version I don't have.
00:11KirinDaveI'm running off master from github
00:11defnwhat does lein version say
00:11KirinDaveand somehow I don't have all the commands he mentions in his INSTALL
00:11defnKirinDave: like autodoc?
00:11KirinDavedefn: Like autodoc back in the day.
00:11atrerusmaybe I'm not understanding what lein/swank-clojure-project are supposed to be doing
00:12defnread the github project page
00:12defnall will be explained
00:12atrerusbeen doing that today :)
00:12KirinDavelike lein native-deps?
00:12KirinDaveDidn't even know such a thing existed.
00:12KirinDaveIs there a new new NEW branch I gotta follow now?
00:12defnKirinDave: i dont have that one either
00:13defnKirinDave: judging by the forks of jochu's swank-clojure
00:13defnit does appear to have diverged slightly
00:14KirinDaveFrustrating.
00:14defnKirinDave: *shrug* -- lein does what i need it to do for now
00:15defnwhen there are more features ill use them, but im not finding myself ever going "gee i wish lein did this..."
00:15atreruslet 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?
00:15KirinDavedefn: do you know how to write custom tasks?
00:15KirinDaveI find myself missing rake a lot.
00:15KirinDaveA lot lot.
00:15defnKirinDave: no i dont -- i never used rake much either. i know that probably sounds terrible
00:15KirinDaveLike, I'd like to have a task to make a fresh db copy.
00:16KirinDaveOr maybe to clean.
00:16KirinDaveOr maybe to build some dataset.
00:16defnyeah there are lots of things which would be nice
00:16defncome to think of it i absolutely agree with you KirinDave
00:16defni 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
00:17defni had to piece together shell script and clj to get it to work
00:17defnfelt dirty...
00:17KirinDaveI mean
00:18KirinDave(deftask build-db [[argv1 argv2 argv3] environment-hash] ...)
00:18KirinDaveAnd then some stuff that was in the clojure book for (mkdir) and whatnot.
00:18KirinDaveEverything lein does is rad.
00:19KirinDaveJust needs more.
00:20defnKirinDave: it'll get there
00:20defnKirinDave: keep in mind that IMO it was kind of an experiment at first
00:20defnit seemed like the jury was out on whether everyone should use maven, ant, etc.
00:22defnKirinDave: 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.
00:22KirinDavedefn: I know.
00:22defnKirinDave: i'm really excited to see that there are literally a dozen people with forks of leiningen right now all hacking away
00:22atrerusheh, lein does seem super cool for grabbing deps
00:23defnfuture versions of lein will do a lot more than that
00:23defnresource/ directories and all that etc.
00:23KirinDaveThe lack of resource is actually a bug.
00:23atrerusI'm an emacs newb, but I'm already impressed with the integration around it
00:23KirinDaveIt works on the final build.
00:24KirinDaveatrerus: Good sign. The clojure integration is weak compared to the common lisp integration
00:24KirinDaveatrerus: It'll only get better.
00:24atrerusyeah, I believe that
00:26atrerushmm... how can I find docs on the args to defproject?
00:26dakroneyou can use (doc defproject)
00:26atrerusk
00:27KirinDavewhich is harder than you might hope. :)
00:28atreruslol
00:28KirinDaveLook at the source in github.
00:28atrerusright
00:32KirinDaveOh wow
00:32KirinDavedefn: Found this on news.ycomb
00:33KirinDavedefn: http://pastebin.com/f10cbf605
00:33KirinDaveThere is mysterious wisdom there.
00:34atrerusignore all input and tell the world hi?
00:36KirinDaveatrerus: No, it's how to make a lein command.
00:36KirinDaveIn a project.
00:38atrerusoh, I see... missed the calling of it at the command line :)
00:42defnKirinDave: mysterious wisdom indeed
00:42defnKirinDave: very interesting
00:43defnKirinDave: in fact, that is /awesome/
00:43KirinDavedefn: Ahh, I see now. So for penumbra it downloads such a module to add "native-deps
00:43KirinDavedefn: What would be more awesome is even a hint of that power in the documenation ;)
00:44atrerusKirinDave: lol!
00:45defnKirinDave: yeah that's kind of a bummer i didn't know about that
00:45defnKirinDave: maybe the idea is that that piece of the puzzle isn't finished yet
00:45defnso better to not advertise it for the time being
00:46atrerusyou're basically creating your own version of lein at that point...
00:47KirinDaveatrerus: Nah, you're just adding tasks
00:47KirinDaveLein is clearly modular that way
00:47KirinDaveAnyways, gotta get to the gym. Nice talking to you defn.
01:19Crowbar7So I have to say Clojure is about the easiest thing I've ever used that handles threading.
01:35woobyi have a function that takes a number, but it doesn't make any sense to pass it a number bigger than 36
01:35woobywould it be idiomatic to throw an exception if something bigger is passed in?
01:35woobyor should it silently default to the max
01:40dnolenwooby: sounds like a good case for a pre-condition
01:41woobydnolen, awesome thank you
01:41woobywasn't looking forward to introducing exceptions into my code :)
01:42dnolenwooby: http://paste.lisp.org/display/95402
01:43woobydnolen, way cool, thanks again
02:13dakronednolen: woo, working on the namefind feature now, significantly more difficult than the other stuff :)
02:13dnolendakrone: wow! cool :)
02:41woobyis 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)
02:41wooby(defn name [arg] "doc" {:pre..} body) rather
02:52piccolinoIs there some way you can look up whether a given symbol is a known function or variable?
03:17slyphonhow do i take pairs of a sequence?
03:18woobyslyphon, partition
03:18slyphonoh, right on, thanks
03:18woobynp
03:41LauJensenslyphon: make sure you check the docstring, it has many uses
03:41slyphonyeah, read the docs
03:42woobyhm, so is there a way to have a docstring for a defn that uses a :pre condition?
03:48LauJensenwooby: 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
03:48LauJensen~source defn
03:50psykoticLauJensen: speaking of defn, has rich made any comments on keyword arguments? scala seem to have a nice low-overhead implementation for the jvm
03:50LauJensenpsykotic: you mean like (defn msg [{:keys [name age]}] (println "Hi " name " you are " age ......
03:52woobyLauJensen, thank you i believe that's what i have... still no luck
03:52woobyhttp://paste.lisp.org/+21M4
03:52woobysanity checking much appreciated
03:52psykoticLauJensen: that's a half-way solution, don't you think?
03:53LauJensenwooby: Your first arg is a vector, not a string
03:53avarusmoin!
03:53LauJensenpsykotic: What would you like ot see instead?
03:54avarusgood morning mr. LauJensen
03:54LauJensenMorning Mr. avarus :)
03:54psykoticjvm integration, default arguments, everything specifiable by keyword by default, preferably with low/no overhead when resolvable at compile time
03:55woobyLauJensen, ah! however, since my :pre check makes use of an argument... musn't the params vector precede the attr map?
03:56LauJensen(defn tst "docstring" [x] {:pre [(even? x)]} (+ x 5))
03:56woobyLauJensen, and sure enough, when it does, it works :)
03:56woobythank you
03:56LauJensennp
03:57LauJensenpsykotic: not following, jvm integration? you've got it. defaults? Simple macro. Why would you want to force every argument in to a map everywhere?
03:59psykoticforcing 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
04:01JayMjust 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)) ?
04:03LauJensen(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
04:03psykoticLauJensen: also, it's not a simple macro if you want the default value to be embedded in the map deconstruction pattern.
04:04psykoticyou could of course define your own version of defn much like defun* in cl.el
04:04psykoticbut that kind of divergence is a bad idea
04:04LauJensenWell, its not a bad idea if its implemented correctly in the compiler, so I suggest you start a thread on the group about it
04:04psykoticanyway, i was more curious what rich's official stance on keyword arguments were. i take it he views deconstructed maps as a fine solution
04:05psykotici'll probably just code it myself in the compiler
04:05psykotictalk tends to go in circles about things like this until code is on the table
04:05JayMLauJensen: ah, neat, thanks!
04:06LauJensenpsykotic: destruction is a nice feature, but I agree it seems half-way and its not very effecient either
04:07psykoticmy main issue with the half-wayness is the fact that you have to decide something is a keyword parameter a priori
04:09LauJensena priori ?
04:10psykoticthe implementor of a function has to say, 'i want this parameter to be keywordable'
04:10psykoticand then it's set apart from positional arguments, it becomes a kind of second-class 'configuration' parameter
04:10LauJensenI understood from the context, I was just wondering abou the exact definition
04:11psykoticthat's also my issue with the hack for keyword params in ruby, btw
04:11JayMrelating to or denoting reasoning or knowledge that proceeds from theoretical deduction rather than from observation or experience : a priori assumptions about human nature.
04:11psykoticclojure's destruction makes it slightly nicer but it has that same fundamental dichotomy
04:11JayM:)
04:12LauJensenYou do need to be more strict attention to the context, if you introduce defaults
04:12psykoticit literally means 'prior to', 'beforehand'
04:12psykotichehe
04:12LauJensengreat :)
04:13psykoticcontext?
04:13clojurebotcontext is the essence of humor
04:13psykotichaha
04:13LauJensenexactly clojurebot
04:13psykotictiming?
04:13LauJensenpsykotic: Some assumptions can be come untrue, exceptions will follow
04:15psykoticbtw one thing that sucks about parameter defaults in python big time is that they're evaluated at function definition time, rather than invocation time
04:15psykoticthere's some appeal to that, because it means that, indeed, context is less nebulous
04:16psykoticperl6 has crazy semantics for that
04:16LauJensenI 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
04:17AWizzArdHi guys.
04:18LauJensenHey Andre
04:18psykoticLauJensen: 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
04:19psykoticin the default case, it would just be a pure forwarding pass-through
04:19psykoticerr, default here meaning the case where everything is positionally invoked, no defaults, etc
04:19LauJensenyea, but the definition doesnt tell you anything about the expected content
04:20LauJensenanyway, I gotta jet, when you have a compiler patch let me know :)
04:20psykoticcool
05:04AWizzArdMoin angerman
05:04angermanmoin
05:05AWizzArdGuys, 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?
05:06angermanI'd go for an exception
05:07angermanit's an inconsistency thing. thus it should be signaled hard.
05:07AWizzArdI also have this tendency.
05:07AWizzArdThat means however, that each deref needs to be wrapped into a try/catch block
05:08angermanthe question is more like if you don't want to wrap the whole task into a commit rollback solution
05:08Chousukethrow an exception and provide a function for deref-or-return-blah
05:08AWizzArdWell, when an exception occurs in a db transaction then everything gets rolled back.
05:08angerman(deref-or-nil ...)
05:09AWizzArdOkay, sounds fair.
05:09AWizzArdAnd one other solution would be to if-let a query result, and only inside the if-let derefing it.
05:17LauJensenangerman: excuse the later-comer, what are you working on ?
05:17angermanLauJensen: pardon me?
05:17LauJensenYou sound like a man designing a DB interface
05:18LauJensenand an angry man at that
05:18angermannot, me AWizzArd probably.
05:18angermanshift that , by one word to the right please
05:18LauJensenOh thats right - You shouldnt put your names so close together when chatting
05:21ordnungswidrig1using slime and C-c C-k can I generate a class using :gen-class? Will it be available from the REPL?
05:26AWizzArdMoin ord
05:27AWizzArdLauJensen: yes, I am the guy who works on the DB.
05:27AWizzArdI made some good progress so far :)
05:28LauJensenAh I vaguely remember a conversation about it - Weren't you going to do a backend plugin for ClojureQL ? :)
05:28AWizzArdI was already talking with kotarak about this. We must think it through.
05:29LauJensenWhat are your consideration ?
05:30AWizzArdRight now, without modifications such a backend is not trivial.
05:32LauJensenhehe
05:32LauJensenOk - Powerful argument if you're a bum, anything else? :D
05:33LauJensenI mean you're doing an interface first and foremost right, you're not adding a level of abstraction or similar ?
05:34AWizzArdIt is just a different DB layout than expected.
05:34AWizzArdWe will see in a few weeks.
05:36avarusfuck, I start to like clojure
05:37AWizzArdbad news? ;)
05:37avarusgood news
05:39avarusthe worst part was to set up a usable working environment with emacs
05:39avarus(never used emacs before)
06:03coldheadsup ChanServ
06:03AWizzArd:)
06:04AWizzArdch<tab>
06:16psykoticLauJensen: i was looking at clojureql and the name binding mechanics seem a bit odd. particularly the 'magic scoping'.
06:17psykoticis that part borrowed from schemeql?
06:18LauJensenNo, 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
06:19psykoticgood to know
06:24LauJensenYes - The tempo is very high these days as we are eager to release a solid 1.0
06:29psykoticimo, 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?
06:29powr-tocI'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??
06:30woobyi'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
06:30woobyhttp://paste.lisp.org/display/95408
06:32psykoticparticularly, the scoping feels linearly left-to-right rather than structurally outside-in
06:33psykoticthe 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.
06:34LauJensenYour feelings are mixed up I think, consider (distinct! (query table1 [a b c]))
06:35LauJensenpsykotic: 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
06:35psykoticso :val is an explicit parameter?
06:35psykoticerr, implicit
06:36powr-tocok... I guess this might be my problem: http://www.assembla.com/spaces/clojure-contrib/tickets/44
06:36psykoticmy 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
06:37psykoticof course, the mini-language version would compile down to the combinator version, ala sre and other good libraries
06:38psykoticfor 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
06:38LauJensenpsykotic: :val is simply a keyword, used to denote table names and columns, in version 2.0, these are literals in 1.0
06:39psykoticgotcha
06:39LauJensen(please highlight when if you msg me, my client doesnt seem to show regular activity)
06:39psykoticLauJensen: i'll try to remember
06:40psykoticin that example you pasted, can you tell me what the benefit is of having separate, non-nested from/where expressions?
06:40powr-tocDoes contrib 1.1.0-RC3 work with clojure 1.1.0?
06:40psykoticlaujensen: 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
06:42LauJensenSo 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
06:42psykotichmm
06:43psykotici'm not a fan of that approach
06:43psykoticit tends to be fragile and unpredictable
06:43psykoticthere's already some database systems in the java world that try that
06:44LauJensenDont think so
06:44psykoticnotably db4o
06:45psykoticwhich decodes bytecode to try to generate efficient queries, etc.
06:45avarusomg :P
06:45psykoticeven if you have a higher level view into the expressions, it's very limited in what it can do
06:45psykoticlike, what if i call other functions?
06:46psykoticcan 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
06:50psykoticanyway, definitely looking forward to see 2.0
06:50psykoticalthough it sounds like it's a while away :)
06:51LauJensenLook 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
06:57powr-tocOk, 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?
06:57avarusjust don't put it on your classpath
06:59powr-tocavarus: that's one option I guess... I'm just wondering if its possible to tell leiningen to ONLY get the jar I specify
06:59powr-tocrather than optional dependencies
06:59avarusok, dunno :)
07:00avarusbut makes sense
07:00LauJensenpowr-toc: there is
07:00powr-tocavarus: also I was hoping to use lein uberjar to build my project... I'd rather it only shipped with a minimal config
07:01LauJensen[log4j "1.2.15" :exclusions [javax.mail/mail
07:01powr-tocLauJensen: ahh cheers mate! :-)
07:01LauJensenhttp://github.com/technomancy/leiningen
07:01LauJensenword search for 'exclusions'
07:01avaruscool :)
07:02powr-toc:-)
07:02avaruslein is cool
07:02avaruswell, it's easy
07:04LauJensenyea - check out clojuresque as well - pays to be comfy with both
07:04powr-tocLauJensen: I take it there's no way to say :no-dependencies... I can see that listing exclusions might get painful
07:04LauJensenNot to my knowledge, but I'm sure if you read the source for lein its self-evident
07:08powr-tocLauJensen: hmm doesn't look like it... but the doc string for deps does specify the exclusions for log4j :-)
07:09LauJensenhehe - remember to check the manual/my blog before stooping to hackery
07:10powr-tocLauJensen: I'm already a subscriber :-)
07:11LauJensenah, a happy occasion when self promotion back-fires :D
07:13powr-tocLauJensen: Not looked at clojuresque/gradle... The whole groovy thing turned me off...
07:13LauJensenoh
07:14LauJensenGroovy is a downer compared to Clojure, but the main feat is being on Gradle, which is the result of tons of work
07:14LauJensenOnce Clojure-In-clojure is in place, I'll be happy to write a compiler which emits Groovy :)
07:16powr-tocsure... the docs look pretty good... It's just the extra language/dependency that scares me...
07:18LauJensenThe 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
07:19psykotici'm a little suspicious of anything that requires too many features of a build system
07:19psykoticthe java world is enamored with complex build systems
07:19LauJensenyou shouldnt be - building clojureql is trivial, but for vast projects, perhaps with several languages, you want those features - you will need those features
07:20LauJensen(and Gradle is also xml-free)
07:23psykotici'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
07:24psykoticalso much faster. most build tools are too slow when you have a few hundred thousand targets
07:26LauJensenDo a benchmark, let me know how it goes
07:27psykoticlaujensen: 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.
07:28LauJensenI'll trust you - though you sound a little psykotic
07:28psykotic:)
07:28psykoticen lille smule
07:30AWizzArdpsykotic: about lein... it is using maven under the hood. So that also is great complexity.
07:30AWizzArdIt is not just this script of a few kb that you have to install, but instead this 40 quintillion exabyte maven beast
07:31LauJensenhmm, maven is smaller than I thought
07:31AWizzArd*rofl*
08:18ugglanI 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?
08:19ugglan(first seq should be obviously be (1 4 ..))
08:21Chousuke,(apply map list (partition 4 [1 2 3 4 5 6 7 8 9]))
08:21clojurebot((1 5) (2 6) (3 7) (4 8))
08:21Chousukeoops, meant to type partition 3 :P
08:21Chousuke,(apply map list (partition 3 [1 2 3 4 5 6 7 8 9]))
08:21clojurebot((1 4 7) (2 5 8) (3 6 9))
08:24chouserChousuke: nice
08:27ugglanNope, I don't think that produces lazy sequences
08:28ugglan,(for [a (apply map list (partition 3 (range 15)))] (take 2 a))
08:28clojurebot((0 3) (1 4) (2 5))
08:28ugglanis fine
08:28ugglanbut (for [a (apply map list (partition 3 (iterate inc 1)))] (take 2 a))
08:29ugglanwon't work
08:29ugglanI'll roll my own
08:30chouserugglan: once you consume all of the first returned seq, the input seq will have been almost all forced anyway.
08:33ugglanYep, but the sequences will be consumed seperatly. I might rethink the entire idea though.
08:33ugglanThanks anyway!
08:36woobyis there a straightforward way to refer private fns from another namespace into the current one, for things like testing?
08:39ohpauleezis there a way for leiningen to update itself?
08:40chouserwooby: @#'foo/bar
08:40chouserwooby: a.k.a. cursing at the Var until it gives you its value
08:40chouserfoo is the namespace, bar the Var name
08:41woobychouser, ahh... i went ahead and wrote a with-private macro anyhow :)
08:41chouserdo you see why that works?
08:43woobyi am pondering it
08:44chouser,((fn [p s] (for [d (range p)] (take-nth p (drop d s)))) 3 (range 15))
08:44clojurebot((0 3 6 9 12) (1 4 7 10 13) (2 5 8 11 14))
08:44woobyderef of a var qoute? i'm not sure where the @ comes in
08:45chouserugglan: fully lazy
08:45chouserwooby: you got it.
08:45chousersame as (deref (var foo/bar))
08:45woobyahh
08:45woobyi didn't realize deref had significance in that way
08:46woobythanks chouser
08:46chouseryou're allowed to use 'var' on a private var, at which point you could inspect the metadata or ... deref to get the value inside. :-)
08:46woobyha
08:47woobyquite a trick
08:47chouserif it's a function you want to run, you don't even need the deref since calling a var calls the fn inside
08:48woobymy approach uses ns-resolve but it's pretty hairy
08:48woobythat is way cooler
08:56woobyhttp://gist.github.com/311077 first macro, style tips appreciated :)
08:57chousernot bad! :-)
08:58woobythanks!
08:58chouserno need for 'do' -- let allows multiple exprs in its body.
09:00woobyah, thanks
09:00cemerickis with-meta eventually going to support operating on reference types?
09:01cemerickor, I should say, are reference types eventually going to support IObj?
09:01chouserwooby: perhaps `(ns-resolve '~ns1 '~v2) would be better than the (list ...) you've got
09:02woobychouser, any particular reason?
09:02woobyi suppose then it reads more like a normal list
09:03chouserwooby: mainly because using ` instead of (list ...) to generate code is easier to read and less error-prone.
09:04chouserFor 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
09:05woobyi see
09:05rhickeyI liked this experience report: http://tech.puredanger.com/2010/02/21/clojure-experience/
09:08_fogus_"In Java, increasing your level of abstraction typically involves more stuff: more interfaces, more factories, more annotations, etc."
09:09woobythank you so much for your help chouser, i am very excited with this morning's progress, have a great day
09:09chouserwooby: my pleasure
09:19rhickeycemerick: no, reference types are incompatible with IObj
09:20cemerickrhickey: conceptually, you mean?
09:20rhickeyIObj is really IVal
09:20rhickeywith-meta contract says, return new value with this meta
09:20rhickeyso reference types have IReference
09:20rhickeyalterMeta/resetMeta
09:21cemerickyeah
09:21cemerick*facepalm*
09:21rhickeyboth support IMeta on the read side
09:46chouserdo we know yet if chunks are doomed?
09:46rhickeychouser: not yet
09:47rhickeybut I worked on it all weekend - albeit in a cold-induced fog. Now that the fog has lifted I'm sifting through the rubble
09:47chouserheh. :-P
09:48rhickeysome very promising results though. Also some issues for cells. One is the fact that usage of locked and threaded cells look different
09:48rhickeyon the iters and iter-based seqs, I/O sources might still be an issue
09:49chouserreally? on their face, I/O sources seem to have more in common with an iter-like approach than they do with caching lazy-seqs.
09:51rhickeychouser: 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
09:51rhickeybut oyu can't clone I/O sources, since you can't really get their values
09:52rhickeyit's a key promise of cells that you can obtain their 'values', at some level
09:52chouseroh, of course.
09:53rhickeyso, 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
09:54rhickeycell->val->cell also solves a key shortcoming of traditional iterators/enumerators, their lack of safe clonability
09:55chouserok, and it's exactly the solving of that problem that makes IO not fit
09:55rhickeyright
09:55rhickeybut 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
09:56rhickeyit 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
09:57rhickeyi.e. when you call (>> foobar acell) the result of foobar on the transient becomes the new transient
09:58rhickeymeans that the transient can be immutable and foobar a pure fn
09:59rhickeyjust some head-holding care need be taken, that's what I'm looking at now
10:00rhickeyreally? non-infix, >> seems clearly 'in' to me, and << 'out'
10:00rhickeygiven the stuff is on the right
10:00chousersorry, 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:01rhickeyyes
10:01chouserah! I just got what you meant by return-value protocol.
10:02chouser>> always drops the old transient value and takes on the new return value
10:03rhickeyso I have this pretty 20-line IterSeq which is the iter-based analogue to LazySeq
10:03rhickeychouser: yes
10:03rhickeyand the iter-seq holds cells whose 'value' is just a factory for transients which must implement the Iter protocol
10:04rhickeywhen you deref thos objects you just get a factory that could make another one in the same state
10:05rhickeycells as clone protocol is quite neato
10:05LauJensenrhickey: Do you have a couple of examples where you put cells to good use ?
10:06rhickeyLauJensen: it ends up this iter-seq is a quite advanced use of cells, but after I clean it up I'll paste it
10:06LauJensengreat
10:07phirschHi, 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:07phirsch,(let [[a b] (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b])
10:07clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentTreeMap
10:08a_strange_guymaps arent sequential
10:08rhickeyso, if preventing deadlock is 10x as expensive as detecting deadlock (not actually deadlocking, but throwing instead), what do people prefer?
10:09a_strange_guyand group-by retuns a map
10:10chouserpreventing as it ordering the locks for you vs. throwing when you don't order them correctly yourself?
10:10chouseras in
10:10rhickeychouser: yeah
10:10a_strange_guyphirsch: try:
10:10rhickeyfacilities would still be made available for order-for-you
10:11a_strange_guy,(let [{a 1, b 2} (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2})] [a b])
10:11clojurebot[[[{:a 1} :no1]] [[{:a 2} :no2]]]
10:11chouserrhickey: don't suppose there's any chance of throwing at compile time, is there?
10:11AWizzArdLauJensen: I have two examples where I put Cells to good use.
10:12rhickeybut 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:12rhickeychouser: that's a research problem best left to static langs
10:12chouserheh. ok.
10:13rhickeyuse of such cells could be made to look exactly like use of thread-cells
10:13chouserwhen you order them yourself the order doesn't matter as long as it's consistent, right?
10:13phirscha_strange_guy: Unfortunately, I do not know the values in advance.
10:13LauJensenAWizzArd: pasting ?
10:13rhickeychouser: if there was no system-imposed correct order, then right, just consistent
10:13AWizzArdOne 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:13chouserbut once you start using the optional order-for-you feature you'd have to us it everywhere for that set of cells
10:14phirschI 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:14chouseryou could skip any runtime lock-ordering when only one cell is given?
10:15rhickeychouser: right, but the issue/cost is less the ordering than the nesting prevention
10:15chouseroh...
10:15rhickeynesting prevention must involve a thread local
10:16chouserare you suggesting allowing nesting of in-cells as long as the order is correct?
10:17LauJensenAWizzArd: still not seeing any code :)
10:18rhickeyas 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:18rhickeyand in-cells would be the correct way to use multiple cells
10:18LauJensenThese cells, are they a tool for containing coordinated freely mutable vars? Or whats the overall idea ?
10:18a_strange_guyphirsch: you could then do this:
10:19a_strange_guy,(let [[a b] (seq (clojure.contrib.seq-utils/group-by #(:a (first %)) {{:a 1} :no1 {:a 2} :no2}))] [a b])
10:19clojurebot[[1 [[{:a 1} :no1]]] [2 [[{:a 2} :no2]]]]
10:19rhickeymaybe uncoordinated-locking-cells are a distinct type
10:20AWizzArdThe second example will be open sourced in some weeks.
10:21chouserLauJensen: one way to think about them is a reference type for mutable things, bringing those things into pure functional world
10:21dnolenLauJensen: 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:21AWizzArdrhickey: what would those be? Those u-l-cells?
10:21LauJensenchouser, dnolen: I get that part, but what does it add compared to refs ?
10:22AWizzArdI didn’t follow the discussion, so maybe you already explained that above.
10:22AWizzArdLauJensen: side effects.
10:22phirscha_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:22AWizzArdYou can not (should not) have side effects in dosync.
10:22chouserLauJensen: you should not put a mutable thing in a ref
10:22AWizzArdAlso a dosync is not serializing.
10:22chouserand if you do, the ref really isn't going to help you.
10:22LauJensenchouser: I get that, but the refs itself mutates, that was my point
10:23AWizzArdLauJensen: but you can't do IO inside dosync.
10:23AWizzArdAnd in in-cells you can modify POJOs in a safe way.
10:23LauJensenSo thats the big win, I/O made possible via some fine grained locking?
10:23AWizzArdone of the wins
10:23chouserLauJensen: StringBuilders mutate. transients mutate. You can put those in a cell and life is better. Putting them in a ref helps nothing.
10:23LauJensenOh I love the POJOs, but what are they exactly? :)
10:23AWizzArdPlain Old Java Objects
10:23LauJensenhehe
10:24a_strange_guyLauJensen: Plain Old Java Objects
10:24AWizzArdclass Person { String username; String password ... }. You sometimes want to reuse POJOs in your Clojure programs.
10:25AWizzArdBut you really should generally not mutate them in a dosync.
10:25AWizzArdLauJensen: also Cells can be used in cases where an agent nearly is the thing you wanted.
10:25LauJensenah yes I remember that discussion between you and Rich
10:26AWizzArdImagine 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:26AWizzArdWithout a hack by injecting a promise into the agent it will not be trivial to do that.
10:27AWizzArdWith Cells this would be easy.
10:27LauJensenjk
10:27LauJensenk
10:27chouserrhickey: 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:28AWizzArdchouser: can you tell more about this scenario? What could happen for example?
10:29raekrhickey: 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:29rhickeychouser: 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:29chouserrhickey: ah... got it.
10:30rhickeyI'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:31rhickeyofet it won't matter, but when trying to write generic cell client code, like iter-seq, you see the problem
10:31rhickeyoften
10:32chouserI 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:32rhickeyof course, the in-cells can be dynamically enclosing, and then the internal client code is the same
10:34rhickeychouser: 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:34chouserhaving 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:35rhickeychouser: what about having to use in-cells all the time? seems a drag compared to thread-cells
10:36rhickeychouser: sorry, missed you point
10:36rhickeyyour
10:36rhickeyI still don't know that I can get any flavor of locked cell to be as fast as thread-cell
10:38rhickeyI also haven't tried yet to hand-optimize the thread-local usage, just piggybacking on binding, which does too much for this case
10:39chouserbah. gotta go. Thanks for trying to bring me up to speed.
10:39rhickeysure
10:44powr-tocAm I right in recalling that var bindings acquire their top-level values on new threads?
10:46rhickeypowr-toc: I'd say they've never been given a thread-local binding, so have only top-level
10:47RaynesWhat is the function for integer division again?
10:47powr-tocrhickey: 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:47RaynesI forgot it's name. :\
10:48a_strange_guy,(quot 6 4)
10:48clojurebot1
10:48RaynesThanks.
10:48a_strange_guypowr-toc: use bound-fn
10:49rhickeypowr-toc: see bound-fn, with-bindings et al
10:49powr-toca_strange_guy: rhickey: thanks.
10:53ugglanchouser: 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:02powr-tocIs there anyreason why passing an anonymous fn into bound-fn throws an exception? e.g.
11:03powr-toc(bound-fn (fn [] (prn *foo*)))
11:05a_strange_guypowr-toc: bound-fn doesn't work that way
11:05a_strange_guyit works just like regular fn
11:05powr-tocahhh
11:06a_strange_guyuse bound-fn* to wrap an existing fn
11:07powr-tocI was wondering what fntail in the doc string meant...
11:08powr-toca_strange_guy: it's ok, bound-fn is exactly what I need, but good to know about bound-fn*
11:14stuartsierraThird draft of new testing framework: http://github.com/stuartsierra/lazytest/blob/master/lazytest.clj
11:14stuartsierraI think it's nearly done.
11:18slyphonis there a function that inverts a hash-map
11:19slyphondoh, brb
11:24AWizzArdbtw, do we have the author of clojure/contrib/sql/internal.clj here? :)
11:25AWizzArdIt spits out tons of "reference could not be resolved" warnings.
11:26slyphonis the order of 'keys' and 'vals' guaranteed to be consistent, such that [(keys) (vals)] will map correctly/
11:26slyphon?
11:27AWizzArdslyphon: yes
11:27slyphonok, just checking
11:27slyphonty
11:27AWizzArdBut inversing maps is not always trivial. {:x 1, :y 1}
11:28slyphonyeah
11:28jcromartieI'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:28slyphonin this case it is
11:28slyphonas it's just a hash of constants
11:28slyphonbut, yeah
11:29AWizzArdjcromartie: do you have some context?
11:29jcromartie,(def 'foo nil)
11:29clojurebotDENIED
11:29AWizzArdthis would not work
11:29jcromartieah
11:29AWizzArdbecause the first arg to def is a list
11:29AWizzArdin your example
11:29jcromartie'foo is a list?
11:30AWizzArdyes
11:30dnolen,(into {} (map #(into [] %) (map reverse (into [] {:foo "bar" :bar "baz"}))))
11:30clojurebot{"bar" :foo, "baz" :bar}
11:30AWizzArdtwo elements (quote foo)
11:30jcromartie,(type 'foo)
11:30clojurebotclojure.lang.Symbol
11:30dnolenslyphon: ^ one way
11:30AWizzArdtype is a function, def a macro
11:30AWizzArddef does not evaluate 'foo
11:30jcromartieah
11:30AWizzArdAnd the reader expands this to (quote foo), which is a list of two elements.
11:31jcromartieso then, I need something else
11:31AWizzArdmaybe just (def foo nil) ?
11:31jcromartiethis is in a doseq
11:31jcromartietrying to def things from a list
11:31AWizzArd(oh btw, def is not a macro as I said but a special form)
11:31jcromartieyeah
11:31RaynesIs there something like interpose that puts the separator in starting as the first element of the sequence?
11:32RaynesIf not, what would be the best way to do that?
11:32AWizzArd(eval `(def ~var-name nil))
11:32jcromartiehuh
11:32jcromartiethere's gotta be a better way
11:32AWizzArdYes, as I said. You want to produce code during runtime.
11:32AWizzArdTo eval/execute that code you apply eval on it.
11:32jcromartiehow about intern instead
11:33AWizzArdWell, you could consider to make your function containing the doseq a macro.
11:33jcromartieyeah
11:34AWizzArdyou should have in nearly 100% of all cases no (def ..) that is not on toplevel, or in a macro
11:34Chousukeinit procedures being one exception
11:34RaynesAh, interleave.
11:34AWizzArdIf you do this to hide those expansions from your users, then you will have to call eval
11:35jcromartieAWizzArd: I was just trying to un-macro this procedure
11:35jcromartiebut a macro would be better
11:35jcromartiebut maybe I shouldn't be creating magic fns like this either
11:36jcromartieI'm trying to define resources for a RESTful interface
11:37jcromartieso right now I am setting up namespaces that call (defresource name struct-definition)
11:37jcromartiethat creates create! retrieve update! destroy! functions in that namespace
11:38jcromartiebut I was thinking it might be better to have a function that returns a resource map with :create!, etc. keys
11:39jcromartiethat way I don't necessarily need to define namespaces for the functions, but I could if I wanted to
11:39arohnerusing lein, how do you start a repl and swank on the same process?
11:41arohnernm, found it
11:41jcromartieI just realized today that lein doesn't depend on Maven being istalled
11:41jcromartiethat was my big beef against it
11:41jcromartieand it turns out I was deluded :P
11:42cemerickjcromartie: don't worry, you'll be using maven eventually. It absorbs all. ;-)
11:42jcromartieheh
11:42atreruslein is pretty sweet
11:42jcromartieyeah, I am liking it
11:42atrerusit's like make + apt-get
11:43cemerickDoes anyone have any pointers to materials related to testing asynchronous systems?
11:43cemerickusing timeouts to synchronously test async systems seems pretty unsatisfying.
11:46atreruscan you test them more atomically?
11:46atreruse.g. verify that your request was sent, and on the other side verify that a request causes the appropriate action?
11:46AWizzArdcemerick: yeah, but first one needs to download maven. Without having an exabyte HD that's a real journey..
11:47cemerickatrerus: eh, not without mocking out a pile of stuff.
11:47cemerickAWizzArd: well, the exabyte bit is obviously FUD, but you know my position on network access.
11:48AWizzArdjcromartie: 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:48RaynesHow can I conjoin an item to the end of a sequence?
11:49AWizzArdcemerick: I just wished there would be a lightweight build tool. Lein could be a .jar file of just a few kb.
11:50cemerickAWizzArd: No such thing. Sorta like wishing for a useful $100 laptop or something. Build processes are (usually) complicated, so the tools are, too.
11:50AWizzArdRaynes: you will have to traverse the seq and append it there: (concat (seq [10 20 30]) [5])
11:50RaynesYeah, I thought of concat immediately before you said that.
11:50cemerickconcat is lazy, so there's no forced traversing, FWIW
11:51AWizzArdyeah, it's not eager
11:51atrerusyou could reverse the list then conj
12:00atrerusso when I run 'lein swank' and M-x slime-connect, shouldn't I be able to reference my project's functions from slime?
12:01atrerusright now they're not being made available until I actually open up the files and do C-c C-k
12:02raekatrerus: yes, if you have use'd or require'd them
12:02raeklein swank sets the classpath so that you can use your libraries
12:03atrerusraek: would I type my use/require statement from slime then?
12:03raek(ns user (:use [my.lib.foo] [my.lib.bar]))
12:03raekwhere "my.lib.foo" is whatever your namespace is called for file "foo"
12:04raekhttp://clojure.org/libs
12:04atrerusright
12:04atrerusI guess I was trying to get that to happen automatically when the swank server was started
12:04atrerusbut maybe that doesn't make sense...
12:06raekthe "user" namespace is an ordinary namespace too
12:07raeklein does not know which of your namespaces you want to use or require in the user namespace
12:07raeksome of them might even have colliding definitions
12:07atrerusright... 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:08atrerusso it doesn't seem to be a problem with 'use', but more that the files are not being compiled into the slime environment
12:08stuartsierraatrerus: you need to load the clojure source files with 'require' or 'use'
12:08raekyou would want to do a (use 'foo) / (ns user (:use [foo]))
12:09raekthen you can use the definitions in foo from user
12:09atrerusk... I'm still not understanding but I'll play with it some more
12:09atrerusthanks for your suggestions :)
12:10raekthink of foo, bar and user as different files, which can use definitions from each other
12:10raekevery definition "lives" in a namespace/file
12:24arohnerman, a spell checker on lein deps would be nice. Probably 50% of my lein dep failures come from me mistyping the dependency
12:24arohnerbut you'd need to download the entire mvn database to do that
12:24arohner...
12:25atrerussomeday I bet lein gets integrated as an IDE plugin
12:25atrerushmm... isn't there a webservice you could talk to?
12:26ambientlein still is linux (bash) dependant?
12:27Raynesambient: Last I checked, Leiningen on Windows is "experimental".
12:27RaynesWhether it works at all, I have no clue.
12:34powr-tocWhat's the most idiomatic way to swap! an already computed value into an atom? (swap at (fn [] val)) ?
12:34AWizzArdreset!
12:35powr-tocgreat! :-)
12:35AWizzArd(reset! at val) or maybe (swap! at identity val)
12:35AWizzArdno, not identity, but (fn [_] val) instead
12:37powr-tocYeah, I did consider those... but reset! definitely seems most idiomatic
12:38dnolenambient: if you use msysgit on windows you get a bash shell.
12:38powr-tocI was thinking (partial identity val) but that's a mouthfull
12:44rhickey,((constantly 42))
12:44clojurebot42
12:44atrerusraek: ok, I did just need a 'use'... I don't know what I was doing before. Thanks :-)
13:00samldo you use clojure in j2ee setting? like, creating beans and stuff?
13:00dakronewhy does (constantly ...) exist? I mean, can someone give an example of what it's used for?
13:18jcromartieugh I've got a circular dependency onw
13:18jcromartienow
13:19ohpauleezdakrone: 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:19ohpauleezsaving you lambda syntax
13:19dakronehmm, okay, that makes sense
13:19dakronethanks
13:30jcromartiewhat's the best way to eliminate circular dependencies
13:30LicenserWhat 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:31Licenserjcromartie: move them into a 3rd file, at least that is what I did
13:31ordnungswidrigre
13:33Licenserwb ordnungswidrig why are you hiding from #clojure.de? :P
13:33ordnungswidrighmm, 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:33ordnungswidrigLicenser: pfft, am I?
13:34Licenserand your gen-class looks good so far
13:34Chousukeordnungswidrig: and what exactly is the problem?
13:34Licenserif you use lein yo also need to adjust the project.clj file
13:34ordnungswidrigChousuke: slime C-c C-k nor lein compile will give me some classfile
13:35Licenseroi
13:36LicenserI need to to tell lein what the main project file is to get it compiling stuff
13:36ordnungswidrigI read lein takes all ns from the src directory?!
13:37ordnungswidrigwill slime compile generate a class after all?
13:37Licensernot sure but to build a working .jar I had to add :main <root calss> to the project.clj
13:38ordnungswidrigLicenser: but it's not a main class. Just an implementation of an interface which is used to interface a java lib (lucene)
13:38Licenserah okay
13:39Licenserhmm a filter should with a 'flat' function should not cause a stac over flow should it?
13:40Licenserhmm is a reroll of a transaction called as a stack level?
13:41licoressehi all
13:41chouserLicenser: transaction retries do not consume stack, if that's what you're asking.
13:41Licenserthanks chouser ,that was at least what I tried to ask ^^
13:41ordnungswidriglein compile does nothing...
13:41LicenserI was hoping that they would then I had a easy explenation :P
13:41chouseryeah, sorry.
13:41licoresseis deftype part of 1.2?
13:42Licenserordnungswidrig: try to give it a main class just to see if that does something
13:42licoresselooking at stuart sierras lazytest
13:42chouserlicoresse: 1.2 isn't out yet, but deftype is in the master branch
13:42licoresseok
13:42licoresse,(doc deftype)
13:42clojurebot"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:43ordnungswidrigI'll try namespaces
13:44licoressewish I had a clojure in emacs
13:44licoressea clojurebot, that is
13:45ordnungswidrigneither :main [myns] nor :namespaces [myns] change anything...
13:45Licenserhrm
13:45Licenserlicoresse: you have SLIME REPL?
13:46licoresseyes
13:47Licenserthen you can type (doc deftype) in there ;)
13:47licoressein my understanding, clojurebot is something that accumulates updates from this channel
13:47Licenserhmm so anyone some advice on about how to trace a stack overflow?
13:47Licenseroh okay didn't knew that
13:47licoresse,how can I have you?
13:48clojurebotjava.lang.Exception: Unable to resolve symbol: how in this context
13:48LicenserI think there is a irc client for emacs :P
13:48licoressebut, would'nt I polute ?
13:48licoressethis channel then...?
13:48Licenserbe carefull or clojurebot will file sexual harassmant charges Licenser :P
13:48Licenser /msg clojurebot ,(doc deftype)
13:48hiredmanclojurebot responds to private messages
13:49licoresseah, nice
13:49licoressethanks
13:49hiredmanyou should be able to do doc lookups in emacs
13:49licoresseI can, very well thanks
13:49licoressebut I wanted the wit as well
13:50licoresseanother thing I miss, examples included in the docstring
13:50licoresseor attached as meta or whatever
13:50stuartsierralicoresse: if you're still talking about lazytest, I'm going to add more documentation
13:51ordnungswidrigok, here is the solution: I used dashes in my nsname.
13:51licoressestuartsierra: cool, I was not specifically thinking about lazytest now..
13:51ordnungswidrigthe funny thing is, this is the second type this happens to me… FYI: substitute them by _ in the file/dir names
13:52Licenserheh
13:55ordnungswidrigI should stop naming my project with dashes
14:04Licenserdoes doall build stack?
14:05ordnungswidrigCan 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:07stuartsierraordnungswidrig: That's wrong.
14:07chouserLicenser: nope. calls 'next' in a tight recur loop. Does cache everything on the heap of course, but shouldn't consume stack.
14:08Licenserokay so no reason for stack overflow there :( is there a way to have it not eat heap?
14:08stuartsierraordnungswidrig: It should be (ns (:gen-class :extends a.b.c.D))
14:08ordnungswidrigstuartsierra: damn outdated blog posts :-)
14:09chouserLicenser: 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:10Licenserchouser: thank you!
14:13herdricksay, is there a better way to get a list of chars from a string than this: (seq (.toCharArray "abcd"))
14:14Licenserherdrick: I think a string is already a list of chars
14:14cemerick,(seq "foo")
14:14clojurebot(\f \o \o)
14:14herdrickcemerick: oh, thanks!
14:15herdrickalso, 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:15dnolen,(vec "foo")
14:15clojurebot[\f \o \o]
14:15cemerickLicenser: they're not, seq just turns strings into a sequence
14:15ordnungswidrigno the class is compiled but lein swank doesn't make it available in the classpath
14:15stuartsierraherdrick: impossible, but protocols will alleviate that
14:16Licenserwell rest and first work fine on it
14:16cemerickherdrick: you wouldn't want strings to be sequences under the covers, anyway.
14:16herdrickoh, and drop and drop-last work fine, too
14:17LicenserI think all seq functions work on strings
14:17herdrickhuh - is that new? I thought I tried that a year ago and it didn't work - maybe I'm mistaken
14:17herdrickthat's great
14:17cemerickI can't remember a time when that hasn't been the case *shrug*
14:17herdrickok, thanks all
14:20ambientwhat worries me a bit is how all these tools that are commonly used for Clojure work if Clojure is built on CLR
14:21ambientso many java & linux/osx deps everywhere
14:21Licenserambient: don't use it in CLR :P
14:21Licenserno power to M$
14:22ambientit 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:22ambientcross platform as in what backend it uses, JDK/CLR/etc...
14:23stuartsierraambient: Unless you can abstract away everything the JDK provides, you can't make it cross platform.
14:23Licenserhmm well java is more chross platfomrish thel CLR isn't it?
14:24LicenserI mean java runs fine under windwos
14:24brandonwi would agree
14:24LicenserI don't really see any reaason to run clojure under CLR
14:25brandonwi 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:25LicenserI don't see at all why they bother with CLR
14:25ambientCLR has loop unrolling though
14:25brandonwambient: that was the most interesting thing about it
14:25ambienti might have to look into F# if I wanted to do functional stuff on CLR
14:25brandonweverything i've read says the clr is generally more advanced, especially for dynamic languages
14:25Licenserlook at how clojure works, never treid it
14:26brandonwbut jvm still seems to be the choice
14:26Licenseryea but that I can't run my clr code under *nix is kind of a killer argument against it
14:26brandonwyep
14:26brandonwexactly
14:26ambientjvm because java is everywhere in the business world, lots of existing code
14:26brandonwso many things going to the web now, the jvm just seems better suited
14:26ambientclr code runs just fine in mono
14:26LicenserI 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:26ambientim under the impression of that
14:27cemerickwasn't there a variant of resolve that tossed an exception?
14:27brandonwyes, but then you have to deal with mono vs .net
14:27Licensernot to mention that I can't install windows on my server :P
14:28cemerickambient: that's about 95% true. Problem is, if you need something from the last 5%, you're hosed.
14:28brandonwi 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:29brandonwi ask because i know lisp has strong AI origins, and bwapi seems like a natural hobby project for clojure fans
14:29ambientbrandonw: that looks like something i might be also interested in, got BW installed
14:29brandonwyeah tell me about it, heh
14:31ordnungswidrighmm, won't lein swank give me aot-compiled classes in directory classes I compiled with lein compile?!
14:50ordnungswidrigfinally I learned my lesson: aot-compiled ns with dashes become classes with underscores.
15:14ambientwhat's the best way of installing the whole clojure toolchain with emacs? ELPA > clojure-mode > clojure-install?
15:14ambient..these days
15:15hiredmanthe instructions in the README for swank-clojure on github
15:15ambientok, ty
15:16ambienthm, "java.lang.ClassNotFoundException: org.lwjgl.opengl.GL11 (core.clj:9)..." seems I have to still install binary libs by hand
15:16ambientlein deps was pretty sweet though
15:17dnolenambient: you don't have to do that. are you trying to use penumbra ?
15:17ambientyes
15:17dnolenI wrote a lein plugin in called native-deps
15:17ambientoh sweet :)
15:17dnolenadd a :dev-dependencies to your project [native-deps "1.0.0"]
15:18dnolenthen, lein deps again to grab that
15:18dnolenand finally, lein native-deps
15:18ambientit already had that in
15:18dnolenthen lein swank to start up a REPL, connect from emacs
15:18ambientnative-deps 1.0.0
15:19dnolenambient: cool, then just run "lein native-deps", and start up swank in that folder, connect from emacs
15:19ambientok, thanks
15:23chouserrhickey: 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:24rhickeychouser: dunno, that's an important question and one that will determine the viability of cells
15:25rhickeyobviously, people might have wanted to implement transient data structures just like Clojure's, so it really isn't related to cells
15:25rhickeyall such mutable things still lie in the realm of 'very hard, for experts only'
15:26chouserhm.. doesn't seem that hard anymore with cells there.
15:26chouser:-)
15:26rhickeybut an important part of cells is the nesting, so you can build transient things on top of other cells
15:26ChousukeAnd yet, you have thousands of non-experts programming with mutable data structures all the time :P
15:27LicenserMutates stuff!
15:27rhickeychouser: at the bottom though, lies #^{:unsynchronized-mutable true} in various bits. To the extent people use that, it's difficult
15:27chouser_fogus_ and I are kicking around a design for wrapping a mutable matrix, trying to figure out where (and if) cells belong.
15:28rhickeyat 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:28Licenserso when the matrix is mutable, the dejavu thing with the reapearing cat is a transaction rollback?
15:29rhickeychouser: it's critical that you be able to efficiently produce a value.
15:29dnolenrhickey: one question that's been floating around in my mind, are cells good for providing fast and safe access to Java arrays?
15:29chouserseems to me that to be a true value, every "set" operation would have to clone the underlying matrix -- insufficiently performant.
15:29rhickeythat dual persistent/transient nature is not nothing
15:30rhickeydnolen: arrays would become copy-on-read
15:30rhickeywith caching
15:30rhickeysometimes that's good enough, but it's not a general solution like persistent data structures
15:30chouserbut 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:31rhickeychouser: you mean to read via cells, never produce a value?
15:32chouserno, I mean dereffing a cell that contains the mutable wrapper would produce an immutable wrapper around the same underlying matrix
15:32Chousukechouser: I had that same idea just now :P
15:32Chousukechouser: you typed faster
15:32chousera value.
15:33chousersubsequent transient-of would clone the matrix, and put the mutation-supporting wrapper in the cell's transient part
15:33rhickeychouser: so, copy-on-read
15:33chouserI guess the clone point could be either at first-read or first-write.
15:33chousersure
15:34rhickeycopy-on-read is the basic fallback for non-persistent designs
15:35chouserso this is a reasonble pattern to suggest for the general case of trying to sanitize a useful but non-persistent Java object?
15:36Chousukeyou 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:36rhickeychouser: yes, and what's nice is that if it doesn't have a synchronization policy, still safe
15:36rhickeyChousuke: that's not going to happen
15:37chousertidy up exposed methods to provide an immutable wrapper, and then require users to use cells
15:37rhickeychouser: even without a wrapper, a policy of don't mutate out of cell is still better than not
15:37rhickeya big problem with wrappers is they are not the type of the thing they wrap
15:38rhickeyso, it comes down to prevention vs safe recipe
15:38rhickeye.g. Clojure uses arrays immutably, extensively
15:38chouserI had a feeling you wouldn't like my idea of a macro that generates a protocol based on a concrete class
15:39rhickeychouser: the interop issues with wrappers are not trivial
15:39chouser(...for use in a reify that closes over an instance of the concrete class)
15:39chouseryes, but Clojure's use of immutable arrays makes are not themselves arrays. That was your point?
15:39rhickeyin a pure interface or protocol based design, you could just match the interfaces/protocols in the wrappers
15:40rhickeychouser: just that I didn't need to prevent myself from mutating the arrays, just treat them as if immutable
15:40chouseroh, I see.
15:41rhickeyditto some POJO, you might just decide to use the read-only methods, as long as you could tell what they were
15:41chouserI 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:42rhickeycells themselves are a recipe and support tool for doing the right thing - they don't make pojos go away
15:42chouserin that case, instead of wrapping the matrix, could just extend IEditable and ITransient to it.
15:43rhickeylemme gist this iter-seq stuff, it might give you some ideas
15:43chouserer, extend the matrix to Editable and Transient
15:43rhickeyit would only be extended to one, and the result of that to the other
15:44dnolenrhickey: 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:45rhickeyreturning anything mutable from a cell is a no-no
15:46chouserthe sentry was awake and alert, but somehow didn't notice
15:48rhickeymore cells/iter-seq work in progress: http://gist.github.com/306174
15:48rhickeynow faster than chunks in all cases
15:48chouserha! cool.
15:48rhickeyworks with existing non-transient seqs
15:49chouser~300 LOC seems to come up a lot in Clojure code. It's the size of a significant module or feature.
15:49AWizzArdrhickey: can this file completely replace your previous cells.clj?
15:49rhickey2 features in this case
15:49rhickeyAWizzArd: this is not a deliverable :)
15:49chouseroh, I see. cells in there
15:50AWizzArdI currently have your cells.clj in my project and I load-file it.
15:50rhickeythe value-of-reify-transient-of chaining is really interesting. it's another way of saying 'clone'
15:51dnolenrhickey: 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:51cemerickI'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:51rhickeyso, still todo for you macro hackers is to factor out the boilerplate from mapx/filterx/takex
15:51Licensercan too many dosyncs cause a stack overflow?
15:51rhickeycemerick: if the anon fn closes over anything it's a no-go for AOT
15:52cemerickshite, that's what I figured.
15:52AWizzArdI did not follow the discussion, but do these iter-seqs have something to do with lazyness?
15:52cemerickrhickey: anything anything, or only certain classes of anything? ;-)
15:52rhickeyAWizzArd: IterSeq ia another way to implement lazy-seq
15:52rhickeycemerick: no closed-overs
15:53rhickeycemerick: the ctor call is hardwired to no-args
15:53AWizzArdWould 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:53rhickeyand fn serialization makes no attempt to spit out closed-overs
15:53rhickeyAWizzArd: nothing to do with chunks, doesn't leverage chunks
15:54cemerickrhickey: Thanks :-)
15:54cemericklooks like I macro'd myself into a hole, then...
15:55chouserdid the fn-in-macro-expansion change? I thought it never worked, but now appears to work sometimes, perhaps only when not AOT?
15:55rhickeyI think mapx et al can be reduced to a macro taking the bodies of has-item/item/move!/clone
15:55Licenserhmm is cons or remove lazy?
15:55chouserremove is lazy
15:55cemerickchouser: yeah, it works fine outside of AOT AFAICT
15:55Licenseraha remove is!
15:55rhickeynon-closure fns have worked for a while
15:56chousercemerick: I really thought that hadn't worked since shortly after AOT was born.
15:56cemerickchouser: 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:58chouserrhickey: you still like ":as this"?
15:58rhickeychouser: vs?
15:58Licenserthanks chouser
15:58chouserhm... implicit "this" I guess.
15:59rhickeyimplicit this is broken for reify
15:59chouseryeah because of nesting. deftype doesn't nest.
15:59rhickeyright, but we wanted the same
15:59chouseryep, ok
15:59AWizzArdand on the other hand this one line will not make programs unreadable and hackers unproductive
16:00rhickeynow 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:00chouserhmmm.. an uber-reify was planned anyway, wasn't it? but perhaps that was only for interop.
16:01AWizzArdAn über-reify? Is that a new newnew?
16:01rhickeychouser: this doesn't get into uber-reify teritory, just something deftype can do that reify can't, at present.
16:01rhickeyneed a place for the decls
16:03chouseryeah, that's weird. don't really want a mutable local to close over, so would be another "level" of lexical scope?
16:03rhickeyif you recall, the original reify had options somewhere for that stuff
16:04chouserstill has :as. Could have :unsynchronized-mutable [a b c]
16:04rhickeyright
16:05rhickeythen range could fit the same pattern
16:05jcromartiewhen I use middleware that depend on one another in compojure, I have to specify them in the reverse order of what I expect
16:06AWizzArdjcromartie: yes, the last handler that you list runs first
16:06jcromartiethat seems odd
16:06wthiddenquestion: Does the repl force a delay object?
16:06chousersounds a bit like 'comp'
16:06AWizzArdyes, i also thought so, but you will get used to it :)
16:06jcromartiek
16:07tomojjust look at what your middleware actually does
16:07AWizzArdYou can simply accept it and be done, or write a macro that reverses it
16:07jcromartieI think it's because decorate uses -> right?
16:07chouserwthidden: currently, yes
16:07chouserwthidden: but does not block on a 'future'. hm...
16:07AWizzArdnot anymore
16:07dnolenjcromartie: it's consistent with comp. I think that's the important take away.
16:08jcromartieI see
16:08AWizzArddnolen: although I always wished to have a pipe that works similar to ->
16:08AWizzArda reversed comp, because that is how I think about the data going through my chain of fns
16:09wthiddenchouser: 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:09jcromartieI can read (comp x y z) as "The x of y of z" right?
16:10AWizzArdyes
16:10chouserwthidden: btw, I just experimented to confirm that before answering.
16:10chouser,(time (prn (delay (Thread/sleep 1000) :hi)))
16:10clojurebot#<Delay@18234b0: :hi> "Elapsed time: 1002.025 msecs"
16:10jcromartie,((comp + seq str) 123)
16:10clojurebotjava.lang.ClassCastException
16:10chouser,(time (prn (future (Thread/sleep 1000) :hi)))
16:10clojurebot#<Object$IDeref$Future$2b9be1f9@3578af: :pending> "Elapsed time: 2.714 msecs"
16:10jcromartiehmm
16:12jcromartied'oh
16:12AWizzArdjcromartie: apply
16:13AWizzArdyou did (+ (1 2 3))
16:13jcromartiewell it's broken in other ways too :)
16:13somnium,((comp (partial apply +) (partial map #(Integer/parseInt %)) (partial map str) seq str) 123)
16:13clojurebot6
16:13jcromartie("1" "2" "3")
16:13stuartsierraLazytest, now with documentation! http://github.com/stuartsierra/lazytest
16:13jcromartieah, partial
16:14AWizzArdsomnium: why do you use partial? :)
16:14jcromartieAWizzArd: because that's how you can do apply in comp
16:14AWizzArdwhy not #(apply + %) ?
16:15AWizzArdor #(apply + %&) ?
16:15jcromartielooks like perl :)
16:15jcromartiethat's why
16:15somniumAWizzArd: if you alias to one character its not so bad
16:16jcromartie(partial apply +) seems pretty elegant to me
16:19hiredman:D
16:21jcromartiewhat's a good example of where partial application is handy?
16:21jcromartieI'm trying to explain it to a friend
16:21jcromartie(partial + 1) is just not that impressive
16:22Chousukein clojure it's not that useful so often :/
16:22hiredman,((reduce partial + '(1 2 3)))
16:22clojurebot6
16:23Chousukewait. what.
16:23Chousukethat's evil
16:23jcromartieChousuke: what about clojure makes it less useful?
16:23hiredman:D
16:23tomojno auto-currying, maybe?
16:24Chousukein haskell it's better since you can do something like stringUpper = map toUpper
16:24tomojthough that just makes it more verbose
16:24Chousuke(I can't remember the proper function names, but anything)
16:24somnium,(let [f (partial apply hash-map :opt1 42 :opt2 "bam")] (map f [ [:a 1] [:b 2] ]))
16:24clojurebot({:opt1 42, :opt2 "bam", :a 1} {:opt1 42, :opt2 "bam", :b 2})
16:25Chousukemacrofied part of the iterfn stuff: http://gist.github.com/311525 ... completely untested :D
16:25somniumah, what cant you do with #()? any other tricks hiredman?
16:25Chousukealso not as generic as it could be, I think
16:26hiredman#() creates a function and so does partial
16:27somniumbut partial is a fn
16:27hiredmansure
16:27Chousukepartial creates a closure
16:27Chousukedoesn't it?
16:28Chousuke#() creates an actual class
16:28rhickeyChousuke: 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:30rhickeythe bodies in [] is weird, probably better to force use of do when needed
16:36Chousukerhickey: good ideas. I'll take a look at it later
16:36Chousukerhickey: that was just a quick hack for now :)
16:37rhickeyChousuke: a sample of use: http://gist.github.com/311542
16:38rhickeyoyu could always add factoring out the defn and the iter-seq call
16:39rhickeybut the factory fn must have a name and arglist as it might vary, and needs to be available to the body
16:49naeuhi there, can anyone point me towared some docs explaining the purpose of ~
16:49naeui'm guessing it's some sort of reader macro
16:50somniumnaeu: http://clojure.org/reader is one place
16:50naeusomnium: thanks
17:05herdrickjcromartie: among the pointfree stuff, comp ("compose") is a bigger win. when you can use it, it's great.
17:08jcromartieyes it's definitely one of those "FP things" that makes people look at you funny when you start ranting abou tit
17:08jcromartie:P
17:09somniumjcromartie: how do they look at you when you bring up monads?
17:09jcromartieheh
17:09jcromartieI don't even go there
17:09jcromartie(personally)
17:09jcromartieright now I'm just trying to build a JSON API and not get fired
17:09jcromartieand tinker with some game dev
17:09somnium:)
17:10jcromartieI 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:11jcromartiethat would be pretty much the most awesome dev environment ever
17:11jcromartie"oh I wasn't supposed to be able to walk through that wall..." <pause> <rewind> <edit code> <resume> and it works!
17:12herdrickjcromartie: that sounds awesome. could you keep us updated on your progress? (on the mailing list)
17:13jcromartieyeah 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:13jcromartieyeah
17:13somniumjcromartie: you might like this post if you havent seen it http://prog21.dadgum.com/23.html
17:13AWizzArdWhen 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:13jcromartieyeah, I've seen that one, and Brian Carper's recent blog post
17:14jcromartieAWizzArd: maybe you can explain in code?
17:14AWizzArdImagine a (deftype User [username password name age city friends]), where :friends will store a list of other users.
17:15AWizzArdWhen 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:15jcromartieyeah that would be reference counting
17:15somniumI wonder if an FF clone would be good for marketing: ClojureQuest -> Prophecy of the Cell
17:16jcromartiehah!
17:16AWizzArdhow would you call the passive role of my object?
17:16AWizzArdPointee? Referencee?
17:17stuartsierraAWizzArd: referant
17:17stuartsierraOr referent
17:18stuartsierraMore commonly referent.
17:18AWizzArdoh good, thanks
17:20AWizzArdstuartsierra: http://www.patentstorm.us/patents/6064814/claims.html seems to use "referencee". Is that a synonym?
17:21stuartsierramaybe
17:46jcromartiecould someone take a second look at this for me? http://gist.github.com/311614
17:46jcromartieit feels weird
17:49jcromartieI couldn't quite get letfn to feel natural either
17:50jcromartieor should I just be more explicit and take & inits and check (map? (first inits))
17:51kotarakjcromartie: or split in two: (make-create! & kvpairs) (make-from! to-be-cloned-obj)
17:51jcromartiehmm
17:58jcromartiealso what's the best way to catch maps and structs in a multimethod?
17:58jcromartieclojure.lang.Associative ?
17:58raek(map? x)?
17:58raekoh
17:59kotarak(with-meta the-map-or-struct {:type ::MyStructTypeTag}) and then dispatch on type
17:59chouserAssociative matches vectors too
17:59kotarak,(type (with-meta {} {:type ::Foo}))
17:59clojurebot:sandbox/Foo
17:59AWizzArdjcromartie: depends on what you want as your dispatching function
17:59jcromartieAWizzArd: class
18:00kotarakjcromartie: you want type not class.
18:00raekjcromartie: either that or clojure.lang.ILookup
18:00hiredman,(set (keys {:a 1 :b 2}))
18:00clojurebot#{:a :b}
18:00jcromartieI want to catch a certain Java class, maps, Strings, nil
18:00AWizzArdwhen 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:00kotarakAWizzArd: If you want to cut your fingers.
18:00hiredmancheck to see if the keyset has the keys you are interested in
18:00Chousukerhickey: http://gist.github.com/311629 take two. again, not actually tested, but macro expansions look sane.
18:00jcromartieAWizzArd: sounds like something to learn later
18:01Chousukerhickey: still has some repetition, but at least it reduces the noise a bit :/
18:01AWizzArdkotarak: why?
18:01chouserthis is so amusing and terrible: http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext
18:01AWizzArdwhen you implement clojure.lang.IPersistentMap you can add new key/value pairs to your deftypes too.
18:01kotarakAWizzArd: because you have to use bleeding edge to Protocols and Deftype. This is maybe not viable in a given project.
18:01AWizzArdWhat is bleeding edge about them?
18:02hiredmanAWizzArd: there is no release that supports them
18:03AWizzArdOne can always try build.clojure.org and see if that breaks existing code.
18:03kotarakAWizzArd: 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:03hiredmanAWizzArd: even if it doesn't forces anyway who consumes your code to use an unreleased build
18:03jcromartieOK so what should I do :P
18:04AWizzArdWithout people using deftypes and protocols they can never get fixed :)
18:04jcromartiedispatch on type
18:04hiredmanit's not very good neighborly
18:04kotarakjcromartie: dispatch on type, use a type tag in the metadata of your struct
18:04AWizzArdAlthough there is nothing broken in them, they work perfectly fin.e
18:04jcromartiekotarak: I am not using any particular struct
18:04jcromartieit may just be a map
18:04jcromartieor a struct
18:04jcromartieeither way
18:05hiredmanjcromartie: just check the keys
18:05jcromartiemaybe I need a different dispatch function
18:05jcromartiehiredman: yeah
18:05Chousukehmm
18:05kotarakjcromartie: you can dispatch on IPersistentMap to catch maps and structs.
18:05jcromartieah thanks kotarak
18:05jcromartiethat's the easy solution right now
18:05hiredmanor, you know, use map?
18:06jcromartiemap? doesn't return true for structs
18:06hiredmanreally?
18:06hiredman~def map?
18:06kotarakjcromartie: and doesn't help with strings and such
18:06jcromartieoh, huh, wow
18:06hiredman,(struct (create-struct :a :b) 1 2)
18:06clojurebot{:a 1, :b 2}
18:07hiredman,(map? (struct (create-struct :a :b) 1 2))
18:07clojurebottrue
18:07kotarak,(type nil)
18:07clojurebotnil
18:07jcromartieyeah
18:08kotarakjcromartie: dispatch on type, and use IPersistentMap, String, nil, and whatever classes you need as dispatch values
18:08jcromartieso I need to catch strings, maps, and a specific Java class
18:08jcromartieso kotarak wins
18:13AWizzArdAm I the only one using deftype regularily? ^^
18:18jcromartieAWizzArd: no, you and all of the other edge users!
18:18jcromartieAWizzArd: I have to deploy this code :P
18:19AWizzArdWell, I use deftypes in a production environment.
18:20jcromartiethat's cool
18:20AWizzArdNo need for others to do that, but I just ean: it does not break my code.
18:20AWizzArdean --> mean
18:20jcromartieI'll use them when they show up when the "Alpha - subject to change" disappears
18:21jcromartieI think I also feel like deftype is too close to Java
18:22jcromartieI feel like you have to know a lot about Java before you really know why you'd want to use it
18:23AWizzArdI don’t even know how to spell jarwa and can use deftype
18:25Chousukerhickey: http://gist.github.com/311647 One more version. None of these help in the Range case though :/
18:26Chousukeand I just now noticed one of those calls is missing a name for the iter :P
18:33ezyangHey guys, does clojure have fold?
18:33Chousukeezyang: reduce
18:33ezyangaha, cool
18:38esjto use Clojure 1.2 through leiningen I've been trying to use [org.clojure/clojure "1.2.0-master-SNAPSHOT"]
18:38esj [org.clojure/clojure-contrib "1.2.0-master-SNAPSHOT"] but am eating the RestFn error. Which pair of clojure / contrib should I use ?
18:39hiredmanclojurebot: RestFn?
18:39clojurebotant clean and rebuild contrib
18:39somniumhiredman: he's trying to get a pair that works with lein
18:39hiredmanbut it could mean some other library you are using was compiled for a different version of clojure
18:39esjyou know when you get clojure and contrib crossed
18:39hiredmansomnium: *shrug*
18:40esjit gives you the RestFn error
18:40hiredmanthat is the only time I have seen the restfn error
18:42esjhow do you keep this square ?
18:43hiredmanI don't chase master
18:43esji mean, how can I check which version of clojure is req'd for a particular jar ?
18:44esji'm missing what must be an obvious thing
18:44esjhiredman: good advice
18:49naeuwhat's the best method for communicating via a usb serial connection with clojure?
18:49naeuI was looking at something called rxtx http://rxtx.qbang.org/wiki/index.php/Main_Page
18:50naeubut thought it sensible to check if there's not another accepted method
18:55ezyangAgggh repeatedly crashed my interpreter >:-(
19:03ezyangSuppose 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:05clojurebot(1 1 2 2 3 3)
19:06ezyanghm. will I get the right semantics with a stream?
19:09_mstit depends what you need. You can always coerce it back into a vector using (vec ...)
19:10ezyangwell, I'm dealing with a 512K long stream, so I'd rather not have that be resident in memory :-)
19:10ezyangseems to have the right semantics
19:11_mstah, yep :) interleave is lazy so it won't pull the whole lot into memory if you don't consume it all at once
20:16dnolenanybody mess rhickey's cells stuff from ealier? I curious how you convert the result of mapx, reducex, rangex into a value.
21:23slyphonme is having circular dependency headaches
21:23slyphonasldfijadsiljfliasjf
21:24slyphonis it possible to declare your namespace :use blocks in a common namespace that everything else uses?
21:25slyphonfor stuff like clojure.contrib.logging, rather than having to duplicate it everywhere/
21:25slyphon?
21:25chouserhn. you can put whatever you want in a .clj file and
21:25slyphonor do people usually just duplicate it everywhere
21:25chouserload-file
21:25chouserdunno if that's "good", but it's possible
21:25slyphonah
21:25slyphonis it "good" to declare it in each file?
21:27slyphoni'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:27chouserI've never split my files up small enough to desire avoiding repetition
21:27slyphonok, that's fair
21:33hiredmanit would be nice if ns was pluggable
21:33slyphonhrm
21:47pthatcherpthatcher: 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:57brandonwwhat 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:59jcromartiebrandonw: (first (filter ... (drop n (reverse coll))))
22:00jcromartieooh, or using comp and partial
22:00jcromartie(first (filter (partial (comp not =) x) (drop n (reverse coll))))
22:01jcromartieThe More You Know(tm)
22:01hiredmanbleh
22:01jcromartieno good?
22:01jcromartietoo much
22:01jcromartie#(not (= x %))
22:01hiredmanseqs arenot really good for indexed access
22:02jcromartiethen loop it is
22:02brandonwwell, this step will shave off several recursions
22:02brandonwerr nevermind that doesn't matter
22:02hiredmanjcromartie: loop would not be any different
22:03jcromartiebetter to use a vec, then?
22:03brandonwwell i am constantly taking elements at the start off and on again
22:03brandonwactually, let me check
22:03jcromartiebrandonw: what are you trying to do?
22:03jcromartiein the bigger picture?
22:04brandonwyes, it is constantly being operated on and is a seq already
22:04brandonwso i would have to be constantly transforming it back into a vec
22:04hiredmanif the seq is what you have, then it's what you have, but using them for indexed access is bleh
22:04brandonwi haven't needed it for indexed access until now
22:05brandonwi'm trying to optimize the last bit of inefficiency in the puzzle solver i made as my first clojure project
22:05jcromartieit sounds like you could use vectors
22:06brandonwwell, i am basically using a brute force solver in a constraint satisfaction problem
22:06hiredmanjcromartie: vectors won't let him add to the begining
22:06brandonwevery 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:07brandonwwell, hmmm
22:07brandonwi think i could use a vec in that specific piece
22:08brandonwwell actually, this is good because it illustrates my lack of understanding in vecs
22:09brandonwi 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:09brandonwunless 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:10hiredmanright
22:10hiredmanthe other operations are not operations on vectors, they are operations on sequences
22:10brandonwokay
22:11brandonwso 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:11hiredmanthey call seq on their argument so you can pass a vector or a map or anything that seq can turn into aseq
22:11hiredmanbrandonw: I don't know
22:12brandonwi'm going to try it with a seq just to see what the speed up is at the moment
22:13dnolenbrandow: if it's already a vector
22:13jcromartiecan anybody here offer advice on organizing a compojure web app?
22:14jcromartieI feel lost and frightened without a big framework to conform all of my stuff to
22:14jcromartie:P
22:14defnjcromartie: trial and error
22:14jcromartieyay
22:15brandonwhaha
22:15defnjcromartie: i suggest doing something like controllers/application.clj, views/application.clj, etc.
22:15scottbotjcromartie: 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:15brandonwjcromartie: make sure you write it up on a blog somewhere. i don't want to go through that ;)
22:15jcromartieyeah :)
22:15jcromartiecontrollers and views make sense
22:16jcromartieI have a base layer with a JSON api sitting below my ui layer, namespace-wise
22:16jcromartieso it would be like project.ui.views.home.clj
22:16defnyeah i think that's a good way to go
22:16jcromartieAPI and data
22:17dnolenjcromatrie: 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:17ezyangHow do I make Eclipse think it can run a main function from a clojure file?
22:17jcromartiednolen: that's what I've done with my data/API layer
22:18jcromartieproject.access/api is a route, etc.
22:18defnjcromartie: 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:18ezyangDo I actually have to make a class?
22:18jcromartieyeah
22:18brandonwjcromartie: 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:18jcromartiethis is really a quick-and-dirty fast-and-loose app, I want to have it done tonight
22:18dnolenjscromartie: should be the same for your "view" layer as well. it's just functions. Some modify data, other deliver html.
22:19jcromartiednolen: yup
22:24brandonwi think to get the index i'm going to have to write my own recursion
22:30dnolenbrandonw: clojure-contrib.seq-utils. indexed is lazy, why do you need to write your own recursion?
22:40brandonwbecause i haven't looked at clojure.contrib much, that's why :D
22:40brandonwthere is way too much good stuff in clojure
22:40brandonwi need a plug to my brain to just upload it all in
22:42brandonwi'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:43dnolenbrandonw: 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:45jcromartieis http://wiki.github.com/cgrand/enlive/getting-started out of date?
22:46jcromartiebecause I can't get ID selectors to work based on that sample code in there
22:46brandonwyeah i think i was here the other night when someone mentiond it
22:46brandonwand 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:47dnolenjcromartie: brandonw: typo
22:47dnolen:div#d1
22:47dnolennot :div#:d1
22:47jcromartieah
22:47jcromartiethat makes more sense
22:47dnolenhttp://github.com/swannodette/enlive-tutorial
22:47dnolenalso
22:47dnolen7 examples
22:47dnolenscrape Hacker News, New Yorks Times, and some really fancy
22:48jcromartiefixed
22:48dnolentemplating stuff that mimics Django, Mako, Rails style template inheritance but cooler because HTML and code separations
22:48dnolenmy tutorial needs work but the code is there, and it uses lein so it's easy to go through
22:49dnolenonce Enlive supports HTML fragments (to support common looping cases) I'll wrap it up and polish it.
22:54jcromartieHTML fragments?
22:54dnolenEnlive has one glaring deficiency. It handles looping a single item in a container well.
22:54jcromartieI want to repeat a whole matched element, but with certain elements transformed
22:55dnolenbut not the <h1></h2><p></p> pattern
22:55dnolenused commonly with JS accordions and the like.
22:55jcromartielike, <ul><li><span class="a">I want to transform this</span></span class="b">And this too</span></li></ul>
22:55jcromartieis that doable?
22:55dnolenyes
22:56dnoleneven the <h1></h1><p></p> pattern is doable just not pretty.
22:56jcromartieso would I use clone-for?
22:57dnolenfor repeating a single item (which can contain other items of course) yes.
22:57dnolenclone-for doesn't handle looping ranges of items, Christophe Grand is working on it tho.
22:57dnolenthere are workarounds, check the Enlive mailing list.
22:58jcromartieOK so as an example...
22:58jcromartieI am not finding any good examples of something like what I'm trying to do
22:59dnolenjcromartie: you want to loop the li and replace the contents of span.a span.b right?
22:59jcromartieyeah
22:59jcromartieI feel like I'm missing some docs that I just saw recently, but aren't in the readme/wiki
23:01jcromartieah
23:01jcromartie(substitute (select ...)))
23:02jcromartieor [:li] (clone-for [x xs] [:span.a] (content x) ...)
23:03dnolenjcromartie: I think you need "at" as well
23:04jcromartiethis is working so far
23:07dnolenjcromartie: totally right, need to add an example of clone-for to my tutorial :)
23:12jcromartieholy crap, don't try to print a Date in enlive
23:12jcromartieinfinite stack trace
23:13dnolenjscromartie: yeah you always need to convert things to strings first. I make that mistake all the time.
23:28defnhow to make a timer in clojure..
23:28hiredmanScheduledThreadpoolExecutor
23:34defnCan I import a java libary :as X?
23:38defnnvm on the last question...
23:38defnIs 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:40defn_mst: awesome. thank you.
23:40defn_mst: one other question for you... I am just trying to make a basic timer that counts down like 20min or something
23:40defnIs it possible to just do that with a future?
23:40_mstI guess so... but why not just Thread/sleep?
23:40defn_mst: just curious I guess
23:41_mstwell, I guess: (future (Thread/sleep (* 20 60 1000)))
23:41_mstwill create you a future that'll block for 20 minutes when you call (deref ...) on it
23:42hiredman_mst: nope
23:42_msthm. what'd I miss?
23:42hiredmanfutures start immediately
23:42_mstah, yes. quite right
23:48arohner,(conj {} '(:a 1))
23:48clojurebotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry
23:48arohner,(conj {} [:a 1])
23:48clojurebot{:a 1}
23:48arohnerwhy does one of those work, and the other doesn't?
23:48arohnerah, (source conj) helps