#clojure logs

2010-11-22

00:36LauJensenMorning
00:53DeranderLauJensen: good morning
06:35noidiis it possible to use zippers for maps?
06:35noidithe docs say that "All it takes is a 4-5 line function to support other data structures."
06:36noidimaybe someone has already written the function for supporting maps? :)
06:53fbru02can i tell lein "use this pom , from this url " ?
07:00fbru02or how can i tell him to use this pom ? http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/mahout/mahout/0.4/mahout-0.4.pom because [org.apache.mahout/mahout "0.4"] will go to mahout/0.4/mahout instead of what i need
08:10noidiIn my program I have a tree made up of nested maps. Now I need to add references from nodes to their parents. In a language with mutable state I'd just do something like `node.parent = self` in the recursive function constructing the nodes.
08:12noidiBut with maps I obviously can't do this, because both the parent and the child would need to be created first so the other could refer to it.
08:12noidiHow can I solve this problem in Clojure? Do I need to scrap my map-tree approach and replace it with zippers?
08:13pdkcreate the parent with the field you want to reserve for the child blank then assoc it to a new map with the reference to the parent?
08:15noidipdk, hmm. yes, that should work. unlike zippers, it will lose data when traversed upwards, but that's fine for my use case.
08:15noidipdk, thanks!
08:20noidiAh, nope. Now that I think about my use case a bit more, I will need to be able to walk the tree back to the child.
08:21noidiSo I guess I'll need to look into zippers after all.
08:53chousernoidi: probably the best way to handle cyclic directed graphs like that is to give each node a 'name', and then they can refer to each other by that name
08:54chouser{:the-parent {:parent nil, :child :the-kid}, :the-kid {:parent :the-parent, :child nil}} ... or whatever
08:57noidichouser, thanks, I'll think about that
08:58chouserso I'm trying to use congomongo via maven, and apparently there's a binary version incompatibility
08:58chouserNoSuchMethodError clojure.core$meta.invokeStatic(Ljava/lang/Object;)Ljava/lang/Object; clojure.contrib.def/defmacro- (def.clj:39)
08:59chouserwhat are my options for resolving this?
09:00jweiss_anyone have any pointers on how to add java annotations to a clojure fn (to be used with gen-class)? the only way i can get it to work is by adding it to the gen-class :methods list, not the metadata of the fn itself
09:01chouserjweiss_: I think that's the only way that's supported.
09:01dnolenchouser: can you't just do a source checkout of congomongo and run 'maven install' from the source dir ?
09:01chouserthe fn's themselves aren't examined while doing the static class generation.
09:01jweiss_chouser: it's not supported in the ns form either? i tried that and it didn't work
09:02chouserjweiss_: oh, it should work in the ns form
09:02jweiss_hm, ok i'll play around w that some more. thakns
09:02chouserdnolen: I'll try that
09:03chouserthough that sounds a lot like failure to me. :-)
09:04mister_robotochouser: usually you have to find the correct version to list as your dependency when there is such a change in the API between versions. don't you have another version to try from the repo?
09:06mister_robotochouser: resorting to build from source is a very un-Maven solution :)
09:06chousermister_roboto: I believe I'm using the latest release of congomongo, contrib standalone, and clojure.
09:07chouseroh, the latest congomongo is listing 1.2-SNAPSHOT deps for clojure and contrib. :-P
09:07mister_robotochouser: is it possible you're trying to use an API method that no longer exists in the new version and, therefore, would have to list an older version to get your code to work?
09:08mister_robotoahhh, well there you go :)
09:09chouserso the current "solution" would be to use out-dated clojure, until such time as clojure libs stop binary compiling themselves by default.
09:11mister_robotochouser: you could always build the jar and put it in your local repo cache, keeping the build exactly the same. except for putting your own version that you "install"ed locally
09:12chouserthat's what I'm pursuing now
09:13dnolenchouser: heh - I thought the convention to package up non-compiled jars was well-established by now.
09:13chouserthis is not easier than resolving dependencies myself and building a classpath by hand.
09:13mister_robotoit's kind of like using programs from your linux distro repository: if you wanna stick with the standard packaging for your system, you use what is available in the repo. otherwise you have to mutate your local system away from the standard repo to be on the bleeding edge :)
09:16mister_robotodnolen: even if they weren't compiling the jars, if the repo only has the older version of the dependency, it's not going to work
09:16mister_robotothe new method would still be missing
09:16chouseryes. I can ask apt-get to fetch and install all dev deps for a source package, and fetch and prepare the source package itself, so I all i have to do is make my changes and install.
09:17chouserI wonder if maven supports that workflow.
09:17mister_robotochouser: i don't know but that would make it infinitely harder to support the transitive dependencies, i would imagine
09:18mister_robotoor not, if you're only changing the leaf node on the dependency list...
09:19mister_robotodev deps are what SNAPSHOTs are suppsoed to be
09:19chousergrr
09:20fliebelmorning
09:22chouserthe jar is empty
09:22chouserof course, because the pom created by lein can't be used to build the jar
09:22jweiss_is there a way to reload a gen-class'd class at the repl?
09:23jweiss_it doesn't seem to pick up the new version by importing it again
09:23chouserjweiss_: I don't think so. gen-class itself is unfortunately very static in nature
09:24chouseryou can load in new method definition fns, but the gen-class itself has to be re-AOT-compiled and a new JVM started up
09:25jweiss_chouser: ok thanks, that should save me some time futilly (is that a word) trying to get it to work :)
09:26mister_robotohttp://new.clojars.org/repo/congomongo/congomongo/0.1.3-SNAPSHOT/
09:26mister_robotocan't you just use that chouser?
09:26chousermister_roboto: well ... it just started working
09:26chouserI'm not sure why.
09:27cemerickwhat's this *new*.clojars.org?
09:27mister_robotohmmm that's usually not a good thing!
09:27mister_robotocemerick i have no idea, i just google'd congomongo maven jar to find a repo with maybe some newer artifacts
09:27chouserI noticed one of the several snapshot jars in my .m2 had only .clj files, no .classes, and I thought, "well, that should have been working all along"
09:28chouserso I cleaned all the congomongo stuff from my .m2, re-ran mvn clojure:repl in my own project, and new I no longer get the original exception.
09:29chouseroh, I know why. I'm no longer specifying a 1.3 contrib.
09:29chouserso this is clojure 1.3a3 and contrib 1.2
09:29chouserI bet. Though I don't know how to find oue.
09:29chouserout
09:33cemerickchouser: `mvn dependency:tree` is nifty
09:34cemerickHaving a decent maven-capable environment gives you a nice interactive UI for the same data rather than the asciiart, but whatever. :-P
09:36chouserI'm not yet willing to admit that dep management is the primary focus of my time in front of the computer. I still like to pretend I'm mostly about writing code.
09:37cemerickchouser: Well done, sir! :-D
09:37chouserheh
09:37chouserbut I'm probably just lying to myself
09:38LauJensen"cemerick - of indian root, means He that does not tire nor give up" :)
09:40cemerickLauJensen: and secondarily, He that gives succor to the poor and disenfranchised fellow traveler. ;-)
09:40LauJensenI want to buy your vocabulary, but until its available online I'll google 'succor'
09:40cemerickAnd lord knows, maven users need succor. :-P
09:41LauJensenoh I see. Well, let me put it this way: You do good screencasts :)
09:43mister_robotocemerick: if you're using a lot of java libs on a large project, letting maven manage all those transitive deps is easier than doing it manually! don't you think?
09:43edwI'm trying to use xml/parse to ... parse some xml, and I'm having trouble parsing a string. How do I create a StringInputStream in Clojure? (java.io.StringInputStream. "foo") gives me a "class not found" error.
09:44chousermister_roboto: that's the wrong fight or with the wrong cemerick, that is.
09:44mister_robotonot fighting, just asking :)
09:44chousermister_roboto: he's on your side
09:44tonylmorning
09:45LauJensenmister_roboto: cemerick never writes clojure code directly himself, he's made a maven task for that as well
09:45mister_robotolol
09:45cemerickthe people that run freenode are really missing opportunities -- they should "embrace and extend" irc to support profiles, message history, global and channel-specific logging, etc.
09:45LauJensenHe has a 4 year CS education, majoring in XML
09:45cemerickLauJensen: Dude, I dropped out. :-P
09:45LauJensencemerick: funny you mention that, I was just thinking about writing that server myself the other day
09:46dnolenedw: http://www.mayerdan.com/2005/04/java_string_to_inputstream.php
09:46cemerickLauJensen: well, it'd not get any traction unless you own a big network -- and I presume freenode's the largest
09:46LauJensencemerick: I have a Maven task that does a hostile takeover on freenode, so no worries
09:46cemerickThat they're still all non-profit, taking donations, just scraping by, etc. is almost criminal.
09:46LauJensen<attack>freenode</attack>
09:47dnolenedw: there's also w/ with-in-str in core
09:47dnolen,(doc with-in-str)
09:47clojurebot"([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s."
09:47cemerickmister_roboto: no one's linked to my shot across the bow (as it were), so: http://cemerick.com/2010/03/25/why-using-maven-for-clojure-builds-is-a-no-brainer/
09:47edwdnolen: Thank you!
09:48edwI'm also looking at clojure-contrib's io, which has `input-stream'
09:48edw.
09:50edwShould (with-in-str "<a>42</a>" (parse *in*)) work?
09:50LauJensencemerick: my only concern is, you start out saying "its this simple" then demo a 40 line XML script, doesnt look too bad, but before the cast its over its grown to something like 140 lines?
09:51tonyledw: why not just (parse "<a>42</a>") ?
09:51tonylunless parse messes with *in* implicitly in its body
09:51edwBecause parse interprets that as a filename.
09:51cemerickLauJensen: 140 is certainly exaggerating, but if you're focused on LOC, you're missing the forest for the trees.
09:52tonylok, but *in* is not a file name either
09:52LauJensencemerick: You've read my blog right?
09:52tonylwhat parse fn are you reffering?
09:53dnolenedw: oops, with-in-str binding *in* to a string reader not an input stream.
09:53cemerickLauJensen: Indeed. Any time you mention LOC, you lose me. :-)
09:53edwdnolen: D'oh...
09:54cemerickSometimes it matters, very often it doesn't.
09:54dnolencemerick: ha, might as well write Java then.
09:54cemerickFor stuff like builds, it *really* doesn't IMO.
09:54cemerickdnolen: well, if LOC matters, then I should write everything in ML, right?
09:54LauJensencemerick: ClojureQL is only 700 LOC vs Arel (Ruby) which is 4600+ :) Thats counts for something right?
09:54cemerickscrew this verbose Clojure thing.
09:55jetienneq. core devs are paid to work on clojure ?
09:55mister_robotocemerick: as a long-time maven user, with our own artifactory server and CI server, and using Eclipse (all this for java, btw), it sounds like the clojure plugin for maven is a lot simpler than trying to use cake/lein/whatever and trying to work that back into the existing infrastructure
09:55dnolencemerick: Clojure is about as terse as ML.
09:56tonyledw: maybe using (parse (java.io.StringReader. "<a>my text</a>"))
09:56LauJensencemerick: You should really learn J
09:56LauJensenWould provide a good counter weight to Maven
09:56chouserjetienne: yes, but not full time.
09:57chouserafaik, generally just Fridays
09:57jetiennechouser: oh ok. thanks them for their dedication then
09:57edwtonyl: parse doesn't accept readers.
10:00tonylfacepalm
10:01tonylwhat about this (ByteArrayInputStream. (.getBytes "<a>text here</a>" "UTF-8"))
10:02cemerickdnolen: It's not even close, AFAICT…but then, I'm absolutely no ML/haskell/ocaml expert.
10:02cemerickmister_roboto: well, that's what I've used for some time now. I entirely agree.
10:03tonyledw: or maybe clojure.java.io there seems to be some fn's that would help
10:04edwtonyl: Thanks.
10:10edwtonyl: Problem solved (stream (http-agent URL)) returns an input stream.
10:11tonylnice
10:15dnolencemerick: I'd say it's pretty close, in fact directly inspired. With macros it's even terser.
10:25cmiles74I read an article about literate programming over the weekend and hacked a little script together to generate the most simplistic sort of documentation you can get. https://github.com/cmiles74/lit-doc Does anyone do "literate programming" in real life? I'm mostly just curious.
10:29insomniaSalti happen to have my .emacs configuration organized in org-mode files, if that counts :-)
10:29insomniaSalt"real life"
10:31cmiles74I think org-mode with babel-mode definitely counts. :)
10:46Lajla&(docs fn)
10:46Lajla&(docs +)
10:46chouser(doc fn)
10:46clojurebot"([& sigs]); (fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+) params => positional-params* , or positional-params* & next-param positional-param => binding-form next-param => binding-form name => symbol Defines a function"
10:46LajlaNo sexpbot
10:46LajlaChousuke, thanks
10:46tonyl&(doc fn)
10:46tonylapparently not :(
10:47Lajlaclojurebot ignores me because I'm a douche
10:47LajlaBut ehh
10:47Lajlaso doc is a special form and not a function?
10:47LajlaHow does the evaluation model work that it can also accept special forms?
10:47tonyldoc is a macro
10:47LajlaIt just does a symbol comparison?
10:47tonyluh, i am trying to learn that too
10:47tonyllooking at the code...
10:48LajlaI wonder how it gets out fn
10:48LajlaI mean, fn doesn't evaluate to anything, right, it's a speical form
10:48Lajlatonyl, could you evaluate the symbol fn for me.
10:48Lajlabecause clojurebot ignores me, because I'm a total douche who worships His Shadow too much
10:49tonylI think fn internally is a macro
10:49tonyllet me find it
10:50tonylhttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L42
10:50tonylwhat I am trying to find out is where fn* is declared
10:51LajlaHmm
10:51LajlaMaybe fn*
10:51Lajlasecretly uses a list
10:51Lajlaand not a vector
10:51Lajlafor arguments
10:55paulrosaniafn* is a special form
10:55Lajlapaulrosania, but a primitive?
10:55paulrosaniait's implemented on the JVM
10:55paulrosaniahttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L3369
10:55LajlaAnd what is its definition?
10:57LajlaHow much difference is ther between Java Clojure and .NET Clojure anyway?
11:07fliebelWoohoo, my Clojure quiz is done :) https://github.com/pepijndevos/clojure-quiz
11:09fliebelIt might be fun to add it to tryclojure or sexpbot later.
11:10tonylyeah fliebel, I'll take a look
11:45fliebeltonyl: Still looking? ;)
11:46tonylyeah, in between some stuff i need to do
11:46tonylno bugs so far, in the code that is. there is some bugs in my clojure knowledge
11:46tonyl:P
11:50fliebeltonyl: Yea, especially those things for setting vars and agents nd such
12:24jaleyhi guys, is there a better way to do this? (:y (bean (:x (bean java-object))))
12:25Raynes(-> java-object bean :x bean :y)
12:25amalloyjaley: (-> java-object (.getX) (.getY))?
12:25Raynesamalloy: Those parens are redundant.
12:26amalloyyeah they are
12:26amalloyi was thinking in the wrong context
12:26jaleyamalloy: Raynes: cool thanks guys
12:26amalloyjaley: mine will certainly be faster, and arguably clearer if you just want to get that one sub-bean. if you might want multiple chunks of some object, consider Raynes's
12:26tonylfliebel: now i can't run the quiz script, it run fine the first time. but i'm pretty sure it is me trying to load it with a bash script
12:28fliebeltonyl: So it's no bug on my part? Why the bash script?
12:29tonylyeah it's not the code, I am placing it wrong in the command.
12:29tonylI don't use anything like lein or cake
12:29tonyljust a bash script that runs java with the necessary flags
12:29tonylit runs something like this java -cp /usr/share/java/jline.jar:/home/tonyl/.opt/jars/clojure-1.2.0.jar:/home/tonyl/.opt/jars/clojure-contrib-1.2.0.jar:/home/tonyl/Projects/clojure-learn/pepijndevos-clojure-quiz/src/clojure_quiz/core.clj jline.ConsoleRunner clojure.main -r
12:30tonylI am guessing the clojure_quiz/core.clj file doesn't go in the -cp parameter
12:31fliebeltonyl: Maybe just ad the dir, and not the file?
12:32tonylmaybe, i'll see
12:32mattmitchell_I'm getting a "Can't take value of a macro: #'clojure.core/let" error
12:32mattmitchell_how do I assign the value of a macro result to a let binding?
12:32fliebelmattmitchell_: You can't use a macro as a function.
12:33tonylfliebel: it worked :)
12:33mattmitchell_fliebel: so for example [let my-num (- 10 1)]
12:34fliebelmattmitchell_: Don't call it let, and you're out of trouble.
12:34tonyl(let [my-num (- 10 1)] ...)
12:34tonylsomething like that
12:35mattmitchell_oh duh my mistake sorry. i had [let not (let
12:43mattmitchell_i asked this question a few days ago and got a few good answers, but i'm still trying to find the right solution. and seriously can't figure this out: https://gist.github.com/708130
12:48fliebelI'm averaging on a 3/1 ratio on my quiz for (name-quiz)
12:49tonylmattmitchell_: maybe using merge-with
12:49tonylfliebel: name-quiz is the hardest
12:49fliebeltonyl: It totally is. What is your score?
12:50amalloymattmitchell_: yeah, merge-with looks applicable. also clojure.set/index might be relevant? it's a little awkward because you have a map rather than a set, but i think it can still work
12:50mattmitchell_tonyl: merge-with and concat into the :f vector?
12:50amalloyfliebel, tonyl: what is this "quiz" thing. i must take
12:50fliebelamalloy: https://github.com/pepijndevos/clojure-quiz
12:51tonylfliebel: I started it, but got a 2 out of 10 so I stopped on that one
12:51amalloyfliebel: neat. i see you went a different direction than you were originally going
12:51tonylI am at doc-quiz, but I am starting name-quiz-easy now :P
12:51mattmitchell_amalloy: so you think i should use a set instead of a map?
12:51tonylmattmichell_: that could work
12:51fliebelamalloy: Yea, the other thing required to much effort for to little fun.
12:53fliebelamalloy: I'm thinking of adding something like this to tryclojure or sexpbot, for much learning fun and multiplayer Clojure quizzing.
12:54amalloyfliebel: ratio? surely % is more useful
12:54tonylfliebel: how do you stop a quiz?
12:55fliebeltonyl: just kill it.
12:55tonyllol ok
12:55amalloyomg doc-quiz is so hilarious. i assume you're just picking three functions at random, getting their docstrings, and randomly choosing one for me to identify?
12:56fliebelamalloy: Yea, the top function just spits out a map of a set number of names and doc strings, and you select what you want to question for.
13:01fliebelHow do I commit the evil act of changing a var's value?
13:02tonylwith (binding
13:02fliebelwell, I'll use binding for less evilness
13:02fliebelah, thanks
13:03tonylevil would be def i guess
13:03fliebelamalloy_: Try this: (binding [number 5] (doc-quiz))
13:04fliebelOr even this: (binding [number 5 target 'clojure.set] (doc-quiz))
13:06fliebelSo you can quiz about contrib, or some specific lib as well :)
13:09jonaskoelker(alive? 'channel)
13:09tonylthere is people here
13:10jonaskoelkertrue
13:10cemerick$max
13:10sexpbotThe most users ever in #clojure is 317
13:10tonylfliebel: that is a nice touch with the binding of those vars
13:10jonaskoelkersexpbot is one small typo away from sounding very dirty... :D
13:11cemerickA nice bot feature would be to report on a moving average of active users
13:11jonaskoelkeryou mean like halve-and-add every $interval?
13:11Raynescemerick: Duly noted.
13:13jonaskoelkerI've had a lot of false starts with various lisps (some CL, elisp, mzscheme). Anyone got a recommendation on how to stick to it?
13:13cemerickjonaskoelker: you'd probably want to retain sample data so you can change the window, etc.
13:13jonaskoelkercemerick: good point
13:13jonaskoelkerI think I see the value of lisp---that is, its unique strengths and when/how/why they will come in handy
13:14jonaskoelkerBut for some strange reason, lisp just never stuck
13:14cemerickjonaskoelker: make sure you are working on a problem where a lisp would offer particularly compelling advantages.
13:14jonaskoelkermeh, do I _have_ to write a compiler? </caricature> :-P
13:15jonaskoelkerseriously though, that's a good point and one well taken
13:15LajlaHow is fn* defined?
13:15LajlaHow is it usd.
13:15Lajla&(doc fn*)
13:15sexpbotjava.lang.Exception: Unable to resolve var: fn* in this context
13:15LajlaHmm
13:15Lajla&(doc fn)
13:15sexpbot⟹ "Special Form: Please see http://clojure.org/special_forms#fn&quot;
13:15cemerickMany (rightly, IMO) believe that a lisp (Clojure in particular, at least in comparison to others, again IMO) provides compelling advantages regardless of the problem.
13:15cemerickLajla: don't use fn*
13:16jonaskoelkerI'm with you on the clojure vs. other lisps
13:16cemerickjonaskoelker: But if the question is, how to stick with learning it -- make sure the wow-factor is so high that you absolutely can't let up. :-)
13:17jonaskoelker:)
13:17jonaskoelkerIt seems to me like clojure has the right kind of abstractions when it comes to things "in/out of the box"
13:17Lajlacemerick, I want to know what it is.
13:18LajlaApparently fn is defined in terms of it as a macro.
13:18jonaskoelkeri.e. lazy sequences being "compatible" with plain ol' lists; IOW, there's interfaces and things that "implements" them
13:18cemerickLajla: fn* is the form that ties into the compiler's implementation of fn
13:24Lajlacemerick, but how does it work.
13:24LajlaHow would you use it.
13:24amalloyLajla: you don't use it. why would you want to?
13:25cemerickLajla: Like I said, you shouldn't use it -- it's entirely an implementation detail.
13:25LajlaI don't want to use it
13:25LajlaI want to know how it works
13:25LajlaAnd why fn itself can't serve that role
13:25amalloyLajla: look in the jvm source
13:25amalloyer, the java source for clojure
13:26amalloyin Compiler.java
13:26LajlaYeah, but I want to know how fn expands to fn* as a macro.
13:26LajlaI heard it does
13:26amalloy$source fn
13:26sexpbotfn is http://is.gd/hBfAf
13:26amalloylike so
13:29Lajla&(expand '(fn bla [I Worship His Shadow] (+ I His)))
13:29sexpbotjava.lang.Exception: Unable to resolve symbol: expand in this context
13:29LajlaHow do you expand macros?
13:30amalloymacroexpand
13:32Lajla&(macroexpand '(fn bla [I Worship His Shadow] (+ I His)))
13:32sexpbot⟹ (fn* bla ([I Worship His Shadow] (+ I His)))
13:33LajlaHmm
13:33Lajla&(macroexpand '(fn bla ([I Worship His Shadow] (+ I His)) ([I Worship His Divine Shadow] (+ I His Divine))))
13:33sexpbot⟹ (fn* bla ([I Worship His Shadow] (+ I His)) ([I Worship His Divine Shadow] (+ I His Divine)))
13:34Lajla&((fn* [x y] x) 3)
13:34sexpbotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox4394$eval6128$fn
13:34Lajla&((fn* [x y] x) 3 4)
13:34sexpbot⟹ 3
13:34LajlaHow is fn* different from fn?
13:34amalloyLajla: /msg sexpbot if you're going to ask him a lot of questions that you don't need to show other people. it clutters up #clojure
13:35LajlaI do need to show it to others? I'm asking quaestions about the results which I don't understand at al..
13:36amalloy&(fn* add "adds some stuff" ([x y] (+ x y)))
13:36sexpbotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.ISeq
13:36amalloy&(fn add "adds some stuff" ([x y] (+ x y)))
13:36sexpbotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character
13:37amalloy&(fn add {:doc "adds some stuff"} ([x y] (+ x y)))
13:37sexpbotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
13:37amalloybah
13:37amalloyanyway fn* won't handle the optional arguments like docstrings
13:37amalloyi suspect
13:38LajlaAhhh
13:38LajlaIt won't handle docstrings.
13:38hiredmanamalloy: fn doesn't take a docstring
13:39LajlaIf that's all.
13:39LajlaThen I see no real reason to not use fn*
13:39LajlaEspeially for function literals
13:39LajlaWhich often lack it.
13:39amalloyLajla: preconditions
13:40amalloyand there's...no reason to use fn* at all? you want to add two keystrokes to each function definition, in order to save a microsecond at compile time?
13:41Lajlaamalloy, maybe, but that doesn't warrant a 'you shouldn't ever use fn*, it's an implementation detail' statement
13:42LajlaUnless of course fn* has no real spefication and it's just a thing that only this clojure uses as an intermediate step.
13:42amalloyLajla: it is. someday maybe it will do something different, and the fn macro will change to work properly
13:42LajlaBut as far as I know, clojure has no specs, maybe?
13:42LajlaSo fn* is undocumented and unsupported?
13:43hiredmanhow does fn not work properly?
13:43amalloyhiredman: if fn* changes in the future, fn will need to change in order to work properly
13:43LajlaI never said it didn't, I was just wondering why fn expanded to fn* (answered) and then why fn* "should" not be used. (answered)
13:44amalloybut that will happen without us needing to know. if Lajla decides to rely on fn*, s/he will be hurting when that day comes cause nobody will rewrite that code
13:44Lajlaamalloy, so fn* is unsupported and undocumented at this point?
13:45amalloyi'm not exactly a language authority, but yes. * suffixes often mean that, and it seems to here
13:47LajlaAhhh
13:48LajlaSomewhat unhygenic and it could pose a security risk, but I'm cool with that I guess.
13:48amalloy...?!
13:48kiemdodercan any one suggest an open source project or something that is a good example of well written clojure code?
13:49kiemdodermaybe they're all good but I'm just asking
13:49chouserit's the lack of docs that indicate fn* is not supported for direct use, not the *
13:50Lajlaamalloy, well, if there are no docs, then someone could be unaware of its existence. Say someone wants to check input, and then check if the list provided doesn't start with fn, and then feels safe, however, the hacker makes it start with fn* to inject possibily malicious input and influence the runtime
13:55dnolensweet WebSockets works on iPad 4.2, Clojure+Aleph just got that much tastier, http://a6.video3.blip.tv/0210004346955/Dnolen-WebSocketSupportInIPad42656.MOV
13:55dnoleniOS 4.2 rather
13:55bobo_dnolen: awesome :-)
13:59kiemdoder"rest" and "next" seems to yield the same result
13:59kiemdoderwhat is the difference?
13:59kiemdoderif any
13:59fliebelkiemdoder: next return nil for an empt seq, but does realize the first item to do se.
14:03kiemdoderfliebel: tx, is see now that (next [1]) returns nil and (rest [1]) returns ()
14:04kiemdoderI see
14:05KirinDaveSo I see http://www.acunetix.com/blog/web-security-zone/articles/http-post-denial-service/
14:05KirinDaveAnd it makes me think that increasingly laziness may be a security feature.
14:21Lajla&(symbol? '&)
14:21sexpbot⟹ true
14:22LajlaIf & is a symbol, then why can't I bind to it/
14:22LajlaI assume it makes bindings assume a rest arg?
14:22Lajla&(let [& 3] (+ & 1))
14:22sexpbot⟹ 4
14:22LajlaAhh
14:22Lajlathat does work
14:23Lajla&((fn [& r] &) 1 2)
14:23sexpbotjava.lang.Exception: Unable to resolve symbol: & in this context
14:23LajlaHmm
14:23Chousukehm
14:23Lajla&(macroexpand '(let [& 3] (+ & 1)))
14:23sexpbot⟹ (let* [& 3] (+ & 1))
14:23tonylin a function args it is used for the rest binding
14:23kotarakLajla: binding works for me. fn obviously can't because & has special meaning there
14:23Lajla&(macroepand (let* [& 3] (+ & 1)))
14:23sexpbotjava.lang.Exception: Unable to resolve symbol: macroepand in this context
14:23tonyl& is a special form
14:23sexpbotjava.lang.Exception: Unable to resolve symbol: is in this context
14:23Lajla&(macroexpand (let* [& 3] (+ & 1)))
14:23sexpbot⟹ 4
14:23Lajla&(macroexpand '(let* [& 3] (+ & 1)))
14:23sexpbot⟹ (let* [& 3] (+ & 1))
14:23LajlaDamit
14:24LajlaHmm
14:24LajlaLet is a primitive/
14:24pjstadigis there any plan to release 1.2.1 or get 1.3 out the door to fix issues like this http://dev.clojure.org/jira/browse/CLJ-444 ?
14:24Lajlalet* I mean
14:24pjstadigcomes up fairly often
14:24ChousukeLajla: let* is an implementation detail
14:24LajlaAnd a primitive
14:24Chousukeyeah
14:24LajlaI would have expected that let be defined in terms of fn.
14:24cemericktonyl: it's not a special form, & is just part of destructuring syntax.
14:24ChousukeLajla: that's not efficient
14:25LajlaYou don't say.
14:25LajlaHmm.
14:25LajlaWhy do all other lisps do it then?
14:25LajlaIs it because of the sequential binding?
14:25Chousukethey don't?
14:25LajlaThey do.
14:25ChousukeCL doesn't as far as I know
14:25kotarakLajla: I know at least one Scheme which doesn't.
14:25LajlaI'm pretty sure that most if not all CL implementations define let as a macro on lambda
14:25LajlaR5RS also lists let as 'library syntax'
14:25LajlaNot sure what the CL specs says about it.
14:25ChousukeLajla: that's inefficient though.
14:26LajlaChousuke, in what way can let be optimized when you don't work like this then?
14:26LajlaOhh wait.
14:26Chousukeat least unless the compiler is smart enough to figure out it doesn't actually need to create an anonymous function
14:26LajlaPardon me
14:26LajlaI forgot that clojure has no TCO.
14:26LajlaCarry on carry on. :')
14:27LajlaWell, in clojure, functions are functions right?
14:27LajlaAs in, Java functions?
14:27LajlaIn most lisp implementions I guess that lambdas are lambda abstractions, which are much simpler things than java or C functions
14:27tonylthey are objects
14:28Chousukejava doesn't have functions :/
14:28tonylthey implement IFn
14:28cemerickLajla: Java doesn't have function primitives < java 7
14:28tonyljava 7 has them?
14:28LajlaWell, let me rephrase.
14:28hiredmanI don't think so
14:28LajlaThey are more complex than 'lambda abstractions'
14:28ChousukeLajla: they are more complex than that in any real-world language :P
14:29jarpiainCL allows any special form to be implemented as a macro
14:29Lajlajarpiain, not 'primitives' though
14:29LajlaDepending on what you call your primitive.
14:29LajlaChousuke, nahhh, a lot of languages explicitly reduce them for optimization's sake.
14:29cemericktonyl: Either 7 or 8, ostensibly. I haven't yet internalized how they got split.
14:30tonylthanks cemerick
14:30cemerickpjstadig: one of the various 1.3 alphas doesn't suit your needs?
14:30LajlaBasically, what you only need in the purest sense for such a thing is: an expression, which can be like any expression, formal paramatres, and a pointer to the environment in which it was created.
14:30LajlaReturn locations and all that can be hacked away by just passing them as arguments to them.
14:31ChousukeTheory is interesting but you should sometimes consider reality as well
14:32cemerickChousuke: wait, what? Where's my sufficiently smart compiler? :-P
14:32pjstadigcemerick: well for legacy (production) code bases is it a good idea to move to 1.3 (which is alpha)?
14:32pjstadigi know there are lots of changes, but i guess nothing breaking
14:32ChousukeDoesn't sound like a good idea :P
14:32ChousukeAt least test first. :D
14:32pjstadigis the numerics stuff in there?
14:32hiredmanyes
14:33cemerickpjstadig: Depends on how badly you want the change, etc. If it's just a single patch you're after, I'd just backport that and run your own build, if it's important enough.
14:33LajlaChousuke, well, this is theory of optimization
14:33cemerickI'd be pretty surprised if a 1.2.1 or somesuch made an appearance.
14:33pjstadigtrue, but if it's trivial we could get a 1.2.1 out the door
14:33LajlaThe reason some languages are 'purely functional' is largely an optimization idea, if you have very little side effects, you can better make it none, and then give the compiler a huge assumption it can always make to optimize
14:34pjstadigcemerick: weren't you the one complaining about people living on snapshots... now you're suggesting i move to an alpha release? :)
14:35kotarakwell, at least not a snapshot. ;P
14:35cemerickpjstadig: hrm, doesn't sound like me. I was probably pooh-poohing anyone that complained about breakage while following SNAPSHOT.
14:36pjstadigyeah so did we
14:37Lajla&(macroexpand '(-> 4 (a (1 4 4))))
14:37sexpbot⟹ (a 4 (1 4 4))
14:37cemerickThe discussion about patch releases always goes the same. If it's a trivial set of bugfixes, then it's suggested that one build a local patch release, and use it. If it's not a trivial set of fixes, then the question is who is going to shepard the release.
14:37LajlaWhy doesn't that insert the 4 after the (1 4 4)?
14:38cemerickAnd that's not even touching the question of who decides the working set to begin with.
14:38kotarakLajla: because that's what ->> is for
14:38LajlaAhhh
14:38LajlaI gues
14:39pjstadigcemerick: sure, i don't know the answer, i guess i was wondering if anyone else is seeing issues like this that might be useful to backport to 1.2
14:44cemerickpjstadig: No one has, at least AFAIK. By all means, open up a thread on clojure-dev and see if there's a plurality around some key issues people are running into.
14:45mroesslerIs it possible to pull the first four numbers out of a vector of integers? (def numbers [20101122 20101121]). I want just the 2010. With a string I use: (subs (str 20101122) 0 4). I'm uncertain how to apply to the vector.
14:46arohnermroessler: 2010 isn't in the vector. 20101122 and 20101121 are
14:46pjstadig(/ 20101122 10000)
14:46clojurebot*suffusion of yellow*
14:46arohnermroessler: you'll have to convert the number to a string, then string manipulate it
14:47arohneror pjstadig's answer
14:47pjstadigclojurebot!!!!!111
14:48pjstadig(int (/ 20101122 10000))
14:48pjstadigmeh
14:49mroesslerarohner: thanks. Can I convert each integer in the vector to a string? If I convert the whole vector, I'd get only the first 4 numbers of the entire vector, whereas I'm after the first four numbers in each integer within the vector.
14:50amalloymroessler: ##(map str [12 34])
14:50sexpbot⟹ ("12" "34")
14:51tonylusing pjstadig ##(map #(int (/ % 10000)) [20101122 20101123 20101122])
14:51sexpbot⟹ (2010 2010 2010)
14:51mroesslerThanks everyone!
14:51amalloytonyl: only works if every number is equally long
14:51tonyltrue
14:51amalloymroessler: ##(map (comp #(take 4) str) [12231414 346531])
14:51pjstadig,(map #(Integer/parseInt (subs (str %) 0 4)) [20101122 20101121])
14:51sexpbotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox4394$eval6324$fn
14:51clojurebot(2010 2010)
14:52amalloymroessler: ##(map (comp #(take 4 %) str) [12231414 346531])
14:52sexpbot⟹ ((\1 \2 \2 \3) (\3 \4 \6 \5))
14:52tonyl&(map #(subs (str %) 0 4) [20101122 20101123 20101122])
14:52sexpbot⟹ ("2010" "2010" "2010")
14:53pjstadig,(map (comp (partial apply str) (partial take 4) str) [20101122 20101121])
14:53clojurebot("2010" "2010")
14:53pjstadigerr something like that
14:54mroesslerThanks all. I'll look at the various suggestions.
14:58amalloymroessler: note that all of the (subs) implementations will fail if the string has fewer than four characters. see clojure.contrib.string/take, which will give you the first up-to-four characters, neatly packaged as a string (unlike the seq of chars core/take gets you)
14:59mroessleramalloy: Excellent point. Looking now.
14:59Lajlamroessler, http://codepad.org/nv7STxR7 would this also work?
14:59LajlaI don't know, I'm fucked at clojure, but it seemed cleaner to me to make a 'digits'function
14:59LajlaIt should take in a number and a base, and return a list of the digits that number has in that base
14:59clojurebotchouser: Some high-tech profiling with Activity monitor and println shows that I'm doing 100% of one core and not so much IO, though the number of files being read is huge(I estimate 5 per second).
15:01mroesslerLajla: looks suspiciously "anti-functional". I'll look at it.
15:01Lajlamroessler, why would it be anti functional?
15:01LajlaIt's just a function that takes in a natural and a base and returns a list of numbers
15:02mroesslerLajla: Hmm. the loop, if, let, I suppose. But I'm not taking issue with you - I'm grateful for the response!
15:02Lajlamroessler, clojure loops are not loops like in C.
15:03LajlaThey return a value actually.
15:03LajlaAs are ifs
15:03pjstadig~loop
15:03LajlaIfs are expressions, not statements
15:03clojurebotPardon?
15:03pjstadig~for
15:03clojurebotfor is not used enough
15:03LajlaWell, a bit of both I guess
15:03Lajlamroessler, basically, loop sets a recursion point
15:04LajlaThe function does not feature any mutable state as far as I can see.
15:04mroesslerLajla: no, no mutable state.
15:56KirinDaveLet's take votes for our most used clojure core functions.
15:56KirinDaveI vote constantly
15:56KirinDaveI use that shit like 800 times a day
15:57tonyli use map a lot
15:59aamarreally? constantly? j/k?
16:00amalloyKirinDave: map has to be high on the list
16:00KirinDaveaamar: You want to swap an atom or ref to a value
16:01chouserfor atom use 'reset!'
16:01chouserfor ref, use 'ret-set'
16:01chouser'ref-set'
16:02amalloyKirinDave: (reset!)?
16:02KirinDaveamalloy: Oh, because it's a value passed in
16:02KirinDaveIt isn't always constant
16:02KirinDaveSo I just pass in constantly in my interfaces.
16:02nickikdoes anybody how i can read a file and preserve the äöü?
16:02KirinDaveLike, for examnple...
16:02amalloythough i must say, if you ever find yourself doing this to an atom, it's very rarely right. i'm curious what you're doing that you do this 800 times a day
16:02KirinDaveamalloy: Oh, not atoms 800 times a day
16:02hiredman~google file.encoding
16:02clojurebotFirst, out of 3100000 results is:
16:02clojurebotHow can I determine the encoding of a file
16:02clojurebothttp://developers.sun.com/global/technology/standards/reference/faqs/determining-file-encoding.html
16:02hiredmanuseless
16:02hiredman~google java file.encoding
16:02KirinDaveCLothesline services need functions which are often constants in practice
16:02clojurebotFirst, out of 128000 results is:
16:02clojurebotjGuru: How do I set a default character encoding for file I/O ...
16:02clojurebothttp://www.jguru.com/faq/view.jsp?EID=78088
16:03KirinDaveCome on gist. :\
16:04KirinDaveamalloy: An example of why I am always using constantly: https://gist.github.com/f8579d7df3ebb2aaaed6
16:04fogus`I use syntax-symbol-anchor at least 138 times a month
16:04KirinDavefogus`: You Might Be A Clojure Badass If.
16:05amalloyKirinDave: okay, i see the idea. you might make clients' lives easier by checking the type of the value and behaving sensibly
16:05KirinDaveamalloy: Sure, but sometimes it can be tricky to do so
16:05KirinDaveamalloy: E.g., if something is a map it's an fn too, so...
16:06KirinDaveI guess I don't know how to uniquely isolate FNs.
16:06KirinDaveIs there a trivial way I don't know about that wouldn't also include things like maps or sets?
16:06amalloy&(doc fn?)
16:06sexpbot⟹ "([x]); Returns true if x implements Fn, i.e. is an object created via fn."
16:06amalloy&(doc ifn?)
16:06sexpbot⟹ "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"
16:07amalloyKirinDave: i hope this is trivial enough :)
16:07KirinDaveHuh
16:07fogus`You know, Rich should have named it konstantly. :p
16:08KirinDaveFor some reason I always assumed fn did what ifn did.
16:08KirinDaveamalloy: There is one other little problem.
16:08KirinDaveamalloy: Maybe you can solve all my problems like President Commacho in just 10 minutes.
16:08KirinDaveamalloy: i want to make it so that it plays nice with java.
16:08KirinDaveSpecifically
16:09KirinDaveFor scala and java and others, what can they pass in to these maps that would be fair game for a function?
16:09amalloy&(supers Fn)
16:09sexpbotjava.lang.Exception: Unable to resolve symbol: Fn in this context
16:09Raynesfogus`: Mortal Klojure
16:09KirinDave java.util.concurrent.Callable
16:09amalloy&(supers (class (fn [])))
16:09sexpbot⟹ #{clojure.lang.IObj clojure.lang.Fn java.lang.Runnable clojure.lang.AFunction clojure.lang.IMeta java.util.concurrent.Callable java.lang.Object clojure.lang.AFn java.io.Serializable clojure.lang.IFn java.util.Comparator}
16:09KirinDaveRunnable is not appropriate.
16:09amalloyyeah, that's kinda a pain. callable or runnable
16:10KirinDaveRunnable does't return a value
16:10KirinDaveCallable seems right, but uh
16:10hiredmancallable returns a value but doesn't take one
16:11KirinDaveRight.
16:11cemerickClojure functions are IFns; the other implemented interfaces are there for interop convenience.
16:11KirinDave:)
16:34nickikI have a problem if i read in a file the äüö are showed as a ?. Did anybody else have that problem?
16:34tonylyou would have to use file encoding that uses those characters
16:41hoecknickik: encoding problem?
16:42cemericknickik: all clojure source files must be in UTF-8
16:42nickikits not a sourcefile its a dic
16:42cemerickthen you need to use the same encoding to read the file as was used to write it
16:46mabesdoes contrib share the same jira project as clojure itself?
16:48nickikcemerick: do you know how i convert the file?
16:52KirinDaveI dunno what debugger-god I pissed off, but cdt-emacs just aint gonna work for me.
16:54LOPPnickik use a text editor
16:55LOPPfor instance Notepad++
16:55nickikusing linux :)
16:55RaynesKirinDave: You pissed off the Debugods.
16:56tonylnickik: I think you could open the file as a stream and get the bytes by UTF-8
16:57nickikthanks all wort with gedit
17:19ohpauleezdnolen: Awesome video
17:20chouserring is hurting me
17:20chousermake it stop
17:20hiredmanwhat are you doing?
17:20ohpauleezwhat's going on?
17:21chouserjust trying to use wrap-params, but the resulting req still has no :params
17:21hiredmanhave you considered writing a macro?
17:21chouserooh!
17:22hiredmanare you sure it has no :params?
17:22hiredmanyou may want to combine wrap-keyword-prams and wrap-params
17:22chouseryes, I'm sure.
17:23hiredmanclojurebot: works on my machine
17:23clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
17:23chouser(def app (-> handle-dump wrap-params wrap-keyword-params my-thing))
17:24chouserin my-thing I return a :body that includes prn-str of the req
17:24chouserit has a bunch of stuff in it, including a :query-string, but no :params
17:25chouserI'm sure I'm doing something stupid, I just don't see what yet.
17:25amalloychouser: welcome to programming
17:25chouserbackwards.
17:26hiredmanright
17:26kotarakchouser: the order of functions?
17:27chouserman. ok.
17:27chouserfor some reason I was thinking -> was comp there for a while.
17:27drewralso, you don't call those functions on app
17:27drewryou call the fn those fns return on app
17:27drewrs/app/req/
17:27sexpbot<drewr> you call the fn those fns return on req
17:27drewrsexpbot: shut your hole
17:28Lajlakotarak, which scheme doesn't by the way?
17:29LajlaI think I read a paper once of someone showing that quote was not a primitive.
17:29LajlaBut I think he made a mistake.
17:29LajlaBecause in his version (quote (bla balalblbalba)) I think also gets macroexpanded
17:29LajlaLike, if you do (quote (and ...)) or something, it expands, instead of getting a list which starts with a symbol and
17:36kotarakLajla: guile doesn't seem to do create function to handle let.
17:37Lajlakotarak, guile is an interpreter and not a compiler right?
17:38kotarakLajla: Ah. Now we start being more and more precise.
17:38Lajlaalso, guile is a marvel of ridiculously badly written technology as to be expected from the masters who have us undocumented and inefficient outdated shat that for some reason has become a staple of C compilers.
17:38Lajlakotarak, praecision is my middle name.
17:39Lajlagave us*
17:40AdamantLajla: what's next, a mortuiri salutant?
17:40LajlaAdamant, I have no idea what that means.
17:41Adamantprobably bad Latin for "we who are about to die, salute you"
17:41LajlaThis is because I am ignorant, beardless, and do not use gNewSEnse
17:41LajlaAll unlike Richard Stallman
17:41LajlaAhhh
17:41LajlaThat is incorrect actually.
17:41AdamantI figured praecision was Latin
17:41LajlaIt means 'those who are about to died salute you'
17:42Lajlathird person
17:42Adamantprobably, I would totally get Pythoned in Latin class
17:42AdamantMonty
17:42AdamantI never had one, just picked up shit here and there
17:42LajlaI find it amazing that I said I didn't know what it means when I could read it.
17:42LajlaJust shows how lazy I am.
17:42LajlaUnlike Dr. Richard Stallman
17:43Adamantthe good Doktor
17:43LajlaThough his belly might evidence otherwise.
17:43Adamantnot for a programmer
17:43LajlaThat is true
17:43LajlaI heard he's actually pretty bad and basically hacks his shit together into unreadable garbage
17:43Adamantdoubtful
17:43Adamanthe is from another, braver era though
17:44LajlaA rumour it may be, but what if it's on wikipedia?
17:44Adamantthen it's just stupid
17:44LajlaYeah, the era people hacked shit together due to performance problems and because Dijkstra hadn't yet risen to being the leader of the illuminati.
17:44mroesslerI see a lot of examples in Clojure books/sites about comparing quantities: (> 10 5) true. But I am missing how to I combine comparisons, such as greater than 5 AND less than 7?
17:44Adamantno, they assumed everyone was a wizard and if you weren't, tough shit
17:44Lajlamroessler, use and
17:44Adamantalso, documentation was for the weak
17:45LajlaOr like (< 3 x 7)
17:45amalloymroessler: ##(> 5 6 7)
17:45sexpbot⟹ false
17:45amalloymroessler: ##(< 5 6 7)
17:45sexpbot⟹ true
17:45Lajlaamalloy, other way around
17:45Lajlamroessler, but if you want it more complex, you can use and
17:45LajlaLike (and (> 3 x) (<= x 9))
17:46LajlaSo
17:46Lajlawhat I get from this ## notation
17:46LajlaIs that every thing I type
17:46mroesslerLajla: thanks!
17:46LajlaIs parsed by sexpbot?
17:46LajlaIs that right ##sexpbot?
17:46LajlaAh
17:46LajlaNo, it is not
17:46LajlaOr maybe it is
17:46tonylit has to be a form, i think
17:46LajlaIs that right ##()
17:46sexpbot⟹ ()
17:46LajlaBut a symbol is a form
17:47tonylmaybe not then
17:47tonyljust what ever is between ##( and )
17:47sexpbot⟹ true
17:47tonyllol
17:47Lajlamroessler, take note
17:47LajlaThis is a manly lisp
17:47LajlaHere operations are variadic
17:47LajlaSo like (+) is 0
17:47LajlaAnd (and) is true
17:47LajlaAnd (or) is false
17:48LajlaAnd ##(and 3 2 4 7)
17:48sexpbot⟹ 7
17:48LajlaAnd ##(or false nil 3 7)
17:48sexpbot⟹ 3
17:49msilverman2(+ 3 4)
17:49clojurebot*suffusion of yellow*
17:50msilverman2##(+ 3 4)
17:50sexpbot⟹ 7
17:50tonylwhat's up with clojurebot replying with that :P
17:51hiredmanlegacy feature
17:51amalloytonyl: 0.5% of the time (iirc), he randomly pretends the previous statement was addressed to him
17:51msilverman2##(car (cdr '(1 2 3)))
17:51sexpbotjava.lang.Exception: Unable to resolve symbol: car in this context
17:51hiredmanno, math expressions are always interpreted
17:51msilverman2##(first (last '(1 2 3)))
17:51sexpbotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
17:52hiredmanfrom the days when clojurebot was a single gist
17:52tonyl##(first (rest '(1 2 3)))
17:52sexpbot⟹ 2
17:52msilverman2##(first (rest '(1 2 3)))
17:52sexpbot⟹ 2
17:52mroesslerDouble "pound" or "hash" is to get the clojurebot to execute an IRC line? Sorry for the ignorance.
17:52hiredmanno
17:52amalloymroessler: there are a lot of ways to get the bots in here to talk
17:52amalloy,"clojurebot"
17:52clojurebot"clojurebot"
17:52amalloy&"sexpbot"
17:52sexpbot⟹ "sexpbot"
17:52Lajlamroessler, watch this:
17:52Lajla,"Clojurebot"
17:52clojurebotLajla: Cool story bro.
17:52mroessler##(> 5 7)
17:52amalloymid-sentence with ##"magic"
17:52sexpbot⟹ false
17:52Lajla,"Clojurebot"
17:52clojurebotLajla: Titim gan éirí ort.
17:52LajlaCool eh?
17:53LajlaI am such a douche, they made the bot ignore me.
17:53AdamantI don't think speaking Irish is ignoring
17:54Adamantthey're just still upset about the Hadrian's Wall thing
17:54msilverman2car and cdr is too old school, I guess: http://en.wikipedia.org/wiki/CAR_and_CDR
17:54amalloymsilverman2: yes, we're aware of what car and cdr are :)
17:54amalloyfirst and rest replace them, although most of the time you're better off with destructuring
17:55hiredmanAdamant: hadrian's wall was scotland
17:55amalloy&(let [[x & nums] [1 2 3 4]] [x nums])
17:55sexpbot⟹ [1 (2 3 4)]
17:55Adamanthiredman: a Celt is a Celt
17:55msilverman2new to clojure and haven't touched lisp in about 20 years. It's all coming back to me...
17:55Adamantto a Roman, anyway
17:58Lajlamsilverman2, I think it's more that that clojure does not have cons cells.
17:58LajlaA list is a list.
17:58LajlaThe rest is implementation abstracted
17:58Lajlapair? or consp does not exist
17:58LajlaI like car and cdr though, because you can cdadar.
17:59LajlaIf you have a binary tree
18:00msilverman2lajla: agree on cdadar coolness.
18:00joshua__Hey guys. I was wondering how I'm suppose to go about converting the params map given in compojure so that it uses :keys rather than "strings".
18:01joshua__Right not I'm trying to wrap the handler with a ring middleware called wrap-keyword-params and it isn't working.
18:02pjstadig,(ffirst '(foo (bar baz)))
18:02clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
18:02pjstadig,(ffirst '((foo bar) baz))
18:02clojurebotfoo
18:02hiredmanjoshua__: you have to use wrap-params first
18:02pjstadig,(frest '(foo (bar baz)))
18:02clojurebotjava.lang.Exception: Unable to resolve symbol: frest in this context
18:02hiredman,fnext
18:02clojurebot#<core$fnext clojure.core$fnext@1134c4b>
18:02pjstadigright
18:03pjstadig,(fnext '(foo (bar baz)))
18:03clojurebot(bar baz)
18:05eyerisIs there ever any reason to use a ref instead of an atom in a single-threaded program?
18:05hiredmanis there a reason to use an atom?
18:05amalloy&(let [[a [[b]]] [[1 [2 [3 4]]]]] [a b])
18:05sexpbot⟹ [[1 [2 [3 4]]] nil]
18:05KirinDaveMan, fuck AOT compilation.
18:05eyerisTo avoid rebinding vars
18:06KirinDaveI spend 30m because some compiled module doesn't get a new copy of the function when I reload the module via emacs
18:06hiredmanKirinDave: family friendly
18:06eyerisWhen I tried to do set! I was continually confused by the distinction between root bindings and thread-local bindings
18:06KirinDavehiredman: I'm speaking from the heart here.
18:06hiredmansure
18:07hiredmaneyeris: why use set!?
18:07eyerisnot the distiction between what they are, but it was hard to keep track of which global defs I rebound with (binding) just to satisfy the runtime
18:07eyerishiredman: isn't set! the way you change a var?
18:07hiredmaneyeris: why change a var?
18:07KirinDaveeyeris: It's a bit unusual to change a var permanently that way. It's relatively unsafe.
18:08KirinDaveeyeris: It's preferred to reset an atom.
18:08hiredmanuntrue
18:09hiredmanit's preferable not to mutate anything and program with values and functions
18:09eyerishiredman: well I'm making what amounts to a poor-mans message broker. clients can make an HTTP request to establish a new queue. I keep those queues in a map. (def queues {}). In order to add a queue to the map, I need to call assoc and then rebind the queues var to the result of assoc.
18:10hiredmaneyeris: that definitely should be an atom
18:10eyerisOkay. Good. That's what I used.
18:10technomancythe only reason vars can be changed is to support interactive programming
18:11technomancy*the only reason var roots can be changed
18:11eyerisSo what I was asking was whether there was any advantage at all to using a ref in a single-threaded app like this.
18:12KirinDaveeyeris: Oh, in a single thread? If you can really guarantee that, then there is none.
18:12eyerisI was basically looking to reinforce whether or not I made the proper decision.
18:12KirinDaveeyeris: For that, you could set! a thread local binding to ensure it. It's just... threading has a way of creeping into coding in places you don't expect.
18:12amalloyeyeris: i'm not sure single-threadedness is relevant. i've had an instance where, with only one thread, doing what i wanted was much easier with a ref
18:13eyerisWhat were you doing?
18:13amalloyeyeris: trying to mutate something, unless the new value would break some postcondition; in which case leave it alone and note a failure
18:14amalloyhard to do with swap!, because the only thing you return from an atom is the atom's new value
18:14eyerisI see. In that case you found a use for the post-set hooks that come with refs.
18:15amalloyeyeris: no, easier than that
18:15technomancycouldn't you use a postcondition on the function you pass to swap!?
18:15hiredmanatoms come with watchers too
18:15amalloytechnomancy: that would assert, not "leave it alone and note a failure"
18:16hiredmanamalloy: the ref mutation functions also only return the value of the ref
18:16amalloy(dosync (let [newval (whatever @ref)] (when (condition newval) (set ref to newval))))
18:17amalloyhiredman: but dosync returns whatever you did last
18:17amalloyand lets you test the ref before you mutate it, without breaking atomicity
18:18hiredmanso would any other function you twiddle the atom in
18:18eyerisIs there anything in clojure.test that is akin to the OO unit test framework's setUp() methods, letting me create some state to test against? All of my tests need to create a queue and then, after the test, destroy it.
18:20amalloyhiredman: i think it's harder than you're suggesting, but i'd love to be proven wrong. try swapping n with n^2, unless n^2 > 1000; in the code calling the swap, handle the swapped/ignored cases differently
18:21KirinDaveamalloy: For bonus points, error-kit in there.
18:21hiredman(fn [a] (let [x (swap! x som-fn)] (when (some-test x) (do-other-stuff-to a)))
18:21KirinDaveAnd yes, I know error-kit is unpopular now. :\
18:22jweiss_is the "clojure protocols explained" talk from the conj online anywhere? (video or slides)
18:23amalloyhiredman: now you've swapped in a value that is illegal for a. i specified leave the atom's value unchanged if changing it would break a rule
18:23hiredmanamalloy: no I haven't
18:23nickikhow to get at post data in compojure?
18:24nickikjweiss: the videos have not been released
18:24hiredmanamalloy: for a single thread that is the same as your dosync
18:24amalloyhiredman: so some-fn leaves x alone if it's too large? now you can't tell whether someone tried to square 25 and failed, or tried to square 5 and succeeded
18:25hiredmanfine, call it some whatever from your dosync instead of swap!
18:25hiredmanthe point is, it is exactly the same
18:26amalloyhiredman: you're right. i didn't flesh out the dosync well enough to do exactly what i meant
18:26hiredmandoesn't matter if you did
18:27amalloy(dosync (let [newval (whatever @ref), succeess (cond newval)] (when success (set ref to newval))) success)
18:27mabesjweiss_: this video may be of interest to you though: http://www.infoq.com/presentations/Clojure-Expression-Problem
18:27jweiss_mabes: thanks
18:27amalloyhiredman: i really don't see how you can do this with an atom
18:27_ato`did I miss a constraint or isn't that just: (swap! a (fn [old] (let [new (f old)] (if (condition new) new old))))
18:27_ato`ie if the condition fails, swap! in the old value (hence in effect leaving the atom unchanged)
18:28amalloy_ato`: the constraint is that you want to be able to know whether the atom changed
18:28hiredmanamalloy: just make the dosync a do
18:29amalloyhiredman: hmm. yes, in a single-threaded app that would be sufficient. good point
18:29Lajlaamalloy,
18:29Lajlacould you give hiredman a hug with my compliments?
18:30amalloyi prefer coding for multithreading when using STM, but i did (erroneously, i now see) claim that this was a problem for single-threaded apps
18:33kotarakamalloy: watches will tell you whether an atom changed or not, and what it's old and it's new value are.
18:34nickikHow do i simply get the values from a form i submited with the post method?
18:34amalloykotarak: then you have to deal with asynchronous-like callback semantics
18:36hiredmanif only there was a set of types and a macro that made async programs look like sync programs...
18:38eyerisI have one file blabber/exchanges.clj with (ns blabber.exchanges (:use blabber.queues)) and blabber/exchanges/test.clj with (ns blabber.exchanges.test (:use blabber.exchanges)). The first ns macro runs fine but when I run the second ns macro, it complains "No such namespace blabber.queues".
18:38eyerisActually, "No such namespace: queues"
18:39hiredmancircular dependencies are not allowed
18:39eyerisThere is no circular dependency though. blabber/queues.clj uses (ns blabber.queues (:gen-class))
18:41eyerisSince it dropped the blabber. prefix in the error message, it seems like the resolver is looking for blabber.exchanges.queues
18:46eyerisAhh, it was complaining about a fully qualified use of a function in that namspace
18:47eyeristhat I missed when I changed from :require to :use
18:47eyerisslime just lost that line reference in the backtrace
19:04eyerisIs there any way to add jars to the classpath of swank while it is running?
19:05raekthere is (add-classpath "file:///path/to/jarfile.jar") but it doesn't work in every case (that's why its deprecated)
19:06eyerisOkay
19:07raekit has something to do with classloaders, I think...
20:59coldheadthanks clojurebot
21:10abedrabuild.clojure.org just got and upgrade to the latest bits
21:11abedraif anyone experiences any strangeness please let us know
21:46tonyldoes anybody know if there is a roadmap for clojure-in-clojure
21:49tonylor maybe is there a plan to use protocols, types, records and/or multimethods to help on this?
21:51dnolentonyl: that's certainly the groundwork for moving a lot of the Java bits into Clojure.
21:53tonylok, do you know if version 1.3 is a step towards that goal?
21:54dnolenthose things happened in 1.2
21:54dnolentonyly: I'm not sure what else is planned for 1.3.
21:54tonylyeah, but to replace some of the java bootstrapping with protocols, types, etc...
21:54tonylok
21:54tonylmmm ...
21:55tonylI'll have to do some digging
21:57dnolentonyl: I'm have suspicion that c-in-c will be primarily community driven, as c-in-c benefits, for now, a small community.
22:00tonylcommunity driven is the only way clojure is being developed, or at least that is what I thought.
22:00scottjtonyl: my guess is pods/scopes/invokedynamic/forkjoin stuff will happen before cinc gets much work
22:01amalloytonyl: community + rich *chuckle*
22:01amalloyand rich is busy
22:01tonylyes, there are a lot of milestones besuce cinc
22:02scottjwhat's rich so busy with?
22:02dnolentonyl: sure what I meant was that rich tends to lead the language design of most things. c-in-c will probably be less lead by him. could be wrong tho.
22:02amalloyspeaking of pods, dnolen, any news on what they are? i've only heard vague mutterings about constrained mutability
22:03dnolenamalloy: constrained mutability?
22:03amalloydnolen: amendment: vague mutterings that could be total nonsense
22:03dnolenamalloy: oh yeah, no I think the gist is still the only concrete implementation of the ideas
22:04amalloy"the gist"? is there something concrete on github somewhere?
22:04dnolenamalloy: I do note some some similarities between the idea and some sections in the last sections of CTMCP where they discuss Cells (old name), http://www.info.ucl.ac.be/~pvr/book.html
22:04tonylI don't see it in the next.release milestone
22:06dnolenamalloy: https://gist.github.com/306174
22:07amalloythanks dnolen. looks interesting
22:24quizmeI'm having a "lein deps" problem: http://pastie.org/1319114 anybody know what i shoudl do ?
23:18Licensermorning
23:18tonylnight :P
23:19trybeingarunnoon :P
23:24Licensernight tonyl, noon trybeingarun
23:33trybeingarunI am planning to read 1) On Lisp 2) Paradigms of Artificial Intelligence Programming 3) Structure and Interpretation of Computer Programs
23:33trybeingarunafter finishing Programming CLojure
23:33trybeingarunwhat order do u guys think would be good/
23:35dnolentrybeingarun: PAIP looks pretty hardcore. I know SICP is hardcore, you'll probably need a break between those two.
23:35coldheadi'd read 1 and 3 simultaneously
23:35coldheadthey're about different things
23:36trybeingarundnolen: have you read SCIP? Is it really worth the credit it gets?
23:36coldheadyou might get some interesting harmonics between the two
23:37dnolentrybeingarun: it is worth and more yes. I worked through all the chapters and almost all the problems of up and including the MetaCircular Evaluator
23:37dnolen7 years ago I didn't see the point of covering lazy eval, logic programming, or the compiler chapter.
23:37trybeingarunI am trying to showcase some nice work in Clojure @ work to get more developers interested
23:37dnolenI've of course changed my mind about that since then.
23:37amalloytrybeingarun: SICP is pretty amazing
23:38trybeingarunI want to move in a direction which will get me up and running quickly
23:38coldheadmost of the exercises in SICP are very satisfying to complete
23:38dnolentrybeingarun: neither will do that for you :) On Lisp might be better bet then.
23:38coldheadyeah, on lisp is the pragmatic choice
23:38coldheadSICP goes well with a wizard bong
23:39dnolenthat said I think this is not talked about enough as a rich source for Rich's ideas, http://www.amazon.com/Concepts-Techniques-Models-Computer-Programming/dp/0262220695
23:39dnolenPAIP and SICP are light on concurrency issues
23:39dnolenCTMCP is filled with ideas about concurrency.
23:41dnolenbut that's yet another massive tome
23:43trybeingarungot disconnected from the chat (actully tripped on my mode and its power chord came off :P)
23:43trybeingarun*modem
23:43trybeingaruncould you guys repeat your suggestions?
23:44Licensertrybeingarun: see your query
23:45trybeingarunthanks Licenser :)
23:45Licenserif I can't help with suggestions I can with copy & paste ;)
23:46trybeingarunis SCIP a good time investment? Lets say, I am able to spend 2 hrs daily on that?
23:46dnolentrybeingarun: On Lisp if you want to get moving, SICP and PAIP are for digging in. I recommend Concepts Techniques and Models of Computer Programming for a rich reference for many of Clojure's concurrency ideas. transactions/futures/promises/etc
23:46trybeingarunOf course I am considering learning On Lisp also as dnolen had suggested
23:47dnolentrybeingarun: SICP great but it's also a rehash of a lot of stuff if you're an experienced programmer.
23:49amalloydnolen, trybeingarun: it goes over some basic stuff, but in a way that is revelatory anyway
23:50trybeingarunA few guys (forums) have suggested "How To Design Programs" is "THE CORRECT WAY THAT SCIP SHOULD HAVE BEEN WRITTEN"
23:50trybeingarunanybody has read that book?
23:52Licensertrybeingarun: are you in a big company?
23:53trybeingarunI work for ThoughtWorks, if you have heard of that
23:54trybeingarunit is a medium sized company
23:54Licenserhmm
23:55Licenserhmm hmm do you have silly management people?
23:55trybeingarunJoined the company last month only dude; so can't say much
23:56Licenserheh okay
23:56trybeingarunas far as I have observed management's role is to enable and facilitate devs (unlike my previous company *I WONT NAME IT* :) )
23:57Licenserwas just wanted to suggest how to convince your colegues, show them this http://manager.licenser.net/ and tell them to reload a few times then tell them the code for that are 25 lines clojure that were done during a telco :P
23:57trybeingarun25 lines??
23:58Licenseryap
23:58Licensernot including html and dataase
23:58trybeingaruni hope it is not like rails; you use the entire framework and nothing counts as a line of code :)
23:58Licenserbut it randomly generates management like phrases and does it very well
23:59Licensernah I just did not count 50 lines of html strings in there since it would be lame
23:59trybeingarunthat is okay. Just the code part is nice
23:59trybeingarunis there any heavyweight web framework available for clojure?