#clojure logs

2011-05-10

01:44seancorfield__great to meet amalloy tonight at bay area clojure user group
01:45amalloyyou too, seancorfield__
01:45amalloyjlf from #emacs keeps rsvping for these things and telling me we'll get to meet, but then he doesn't show :P
01:47seancorfield__:)
01:47amalloymoral: trust clojure hackers, not emacs users
01:47seancorfield__lots of interesting folks at tonight's meeting... the autodoc guy, the appengine-magic guy... the clojure in action guy :)
01:47amalloywhose is autodoc?
01:49seancorfield__tom faulhaber
01:49seancorfield__was sat to my right
01:49amalloyyeah, i recognized the name and noticed the intro. just didn't really know what he did
01:50tomojwhere?
01:50clojurebotwhere is your source code
01:50amalloytomoj: sf
01:50tomojoh, bay area
01:50tomojthat was my guess :)
01:50tomojhere's hoping someone out there gives us money so I have an excuse to go there
01:50seancorfield__he is updating autodoc to work with the new contrib libs... http://clojure.github.com/java.jdbc/ is the guinea pig...
01:51amalloytomoj: there's $20 with your name on it, direct from me, if that encourages you to make the trip :)
01:51tomojheh
01:52tomojare you out there too?
01:52amalloytomoj: that's why sean was saying he met me
01:53seancorfield__the bay area is *horrendously* expensive
01:53tomojaha
01:54tomojI'm quite willing to live in a tiny bare box for a few years if I get the opportunity
01:54amalloyeh, the software companies pay well enough to make it entirely livable
01:56markomanI have a strange problem. (if ... (do (myfunc ... (otherfuncs ... for some reason in myfunc for each loop doesnt work. but if i put (if ... (do (println (myfunc ... (otherfuncs then all is fine. what may cause this behaviour?
01:57amalloyclojurebot: laziness?
01:57clojurebotlaziness is what will save us all
01:57tomoj"for each loop"?
01:57amalloywow that is wrong
01:57amalloyclojurebot: laziness is hard
01:57clojurebotIn Ordnung
01:57amalloy&(do (map println (range)) 1)
01:57sexpbot⟹ 1
01:57markomansorry, just for loop
01:57tomojas in the macro for?
01:58tomojclojurebot: for?
01:58clojurebotfor is not used enough
01:58markomanlol
01:58tomojI vaguely remember "for is not a loop"
01:58amalloymarkoman: (do a b c) evaluates a and b *for side effects*, then throws them away and returns c
01:58tomojbut my memory sucks
01:58markomanlazyness may save but I dont get it
01:59amalloyfor *returns* a lazy seq, and if you throw it away you never realize any of its elements
01:59tomojclojurebot: for?
01:59clojurebotfor is not used often enough.
01:59tomojbah
01:59amalloytomoj: he only has one entry for each thing, iirc
01:59amalloy&(doc doseq)
01:59sexpbot⟹ "Macro ([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
01:59tomojgot two there that really are one
02:00amalloymarkoman: compare that to ##(doc for)
02:00sexpbot⟹ "Macro ([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost f... http://gist.github.com/963983
02:00markomanso yeah, I have some side effect going on in (do, saving data to session and datastore
02:00amalloyclojurebot: doseq?
02:00clojurebotIt's greek to me.
02:01amalloyclojurebot: doseq is like for, but for side effects instead of values
02:01clojurebotOk.
02:01amalloythere
02:01amalloyall fixed
02:01amalloymarkoman: now ask clojurebot about doseq and he'll solve your problem
02:02tomojclojurebot: for?
02:02clojurebotfor is not a loop
02:02tomoj:D
02:02tomojclojurebot: botsnack
02:02clojurebotthanks; that was delicious. (nom nom nom)
02:02amalloytomoj: did you overwrite his existing entry in PM? i think "for is not used often enoguh" is pretty useful too
02:03tomojI asked him in PM but didn't edit anything
02:03amalloyah
02:03markoman:) to me it looks like looping over all items in list
02:03tomojwonder if it's random with or without replacement
02:03tomoj..or that
02:04seancorfield__just signed up for amit's day of macros training course - should be fun!
02:04tomoj&(first (for [x (range)] (* x x)))
02:04sexpbot⟹ 0
02:04markomanhmh, so I should use doseq instead of for or doseq instead of do?
02:04amalloyinstead of for. it is literally a drop-in replacement
02:05markomanand it supports :let :when behavior too?
02:05amalloyi know a great way to find out. try it in the repl
02:07opqdonut_it's not drop-in. doseq doesn't return the values
02:07markomanok, thanks. i used several hours yesterday trying to find out, why (for didnt work. makes some sense now
02:07opqdonut_but yeah, it's the same syntax
02:08amalloyopqdonut_: if it were "drop-in" in the way you mean, it would have to be exactly the same function
02:08amalloysince he's using it in the context of (do (for ...) (whatever else)), it's as drop-in as you can imagine
02:08markomanin this case i dont need values anyway, because its a side effect sequence
02:09amalloyspeaking of it being the same sequence, did you know the code for parsing arguments to for is repeated almost verbatim in doseq? nobody refactored that into a helper function
02:09amalloysyntax, not sequence
02:10markomani should really get a book. soon its summer holidays and time to read
02:15markomani doubt there is any Clojure user groups in Finland, but how about in New York City?
02:19tomojyou must construct additional pylons
02:20tomojyou must
02:21amalloyi guess i need to spawn more overlords, cause my poor lil brain can't do all this thinking itself
02:21tomojactually this is just my battery notify-send message but I didn't anticipate the protoss voice burrowing into my brain once a minute when I already know I need to plug in
02:22amalloyhaha
02:22amalloyi've barely played sc2, but i was always least effective with protoss anyway
02:22codedigestionhmmmmmmmmmmmm................ Anyone about that would be able to help me get sessions working in Ring????
02:23tomojthat's a lot of dots
02:23amalloyi use sandbarrrrrrrrrrrrrrrrrrrrrrrrrrrrr for my sessions
02:26markomani have made my own session.clj but I think it overlaps with Rings own functionality plus doesnt use Rings custom session store handles
02:29markomanand I have to say this channel has been a great help on learning Clojure
02:30markomanbetter than any of the web sites
02:32thorwilmarkoman: do you know that there are libs specifically for handling sessions, using ring?
02:34markomani never found other than sandbar. but at that point i didnt understand the code and how to use it... maybe im now educated more. but what libs you mean thorwil?
02:37thorwilmarkoman: actually it looks like i shouldn't have used plural. sandbar, yes
02:45markomanwell, less libs, easier decisions
02:50tomojseems sandbar is 2577k raw lines
02:50amalloyjeez
02:50amalloyer
02:50tomoj1067 of which in forms.clj
02:50amalloysurely you don't mean 2.5M lines
02:50tomojthat's small, though, right?
02:50tomojoh, heh
02:50tomoj2577 lines
02:51amalloytomoj: it's pretty large if you consider how big ring itself is
02:52tomojstateful_session.clj which sounds particularly relevant is only 135 lines
02:52codedigestionI can't figure out sandbar??? :P
02:52codedigestionI'm trying to use ring session....
02:53tomojring-core seems to be only 955 total
02:53codedigestioncan't figure out how to store to a session variable :name, for example....
02:54codedigestion:session :name = :param :name type of deal...
02:54amalloytomoj: right. and most of that is optional middlewares
02:54tomojhmm
02:54codedigestion(let [name (session :name (params "name"))]) doesn't seem to cut it???
02:54tomojisn't wrap-session enough to get the barebones?
02:54codedigestionI've got wrap-session up...
02:55codedigestionwrap-params works, but I can't figure out wrap-sessions. :p
02:55amalloyincidentally, i was delighted to find how simple it is to write a new ring middleware. that is a very nice model he built
02:56tomojseems you just read out the :session from the request map and update the :session in the response map ?
02:56codedigestionno, I'm taking the params from the response map and and trying to store it into the sessoin...
02:57codedigestionI'm not sure how to get sessionn going in the first place - so, what I'm doing may be completely wrong in the first place. :((((((((((
02:57codedigestionI'm a COMPLETE newb to clojure....
02:57markomani got a feeling wrap carries vars over requests, but doesnt really store them?
02:57tomojI am blind and so probably shouldn't lead you :D
02:58codedigestionhmmmm......
02:58markomanI made this study a month ago: https://github.com/mmstud/websesstudy/tree/master/src/websesstudy
02:59codedigestionthanks markoman.... You've included several comments! hopefully, I'll be able to figure it out!
02:59codedigestionthanks! :)
03:02markomannp, I'm sure you can do it. there is probably even easier way to handle sessions than on my study, but it may give some hints how you want to implement whole thing
03:03codedigestionI certainly hope so! :)
03:07codedigestion@markoman, what's "flash" messages, btw?
03:08markomanthey are meant to show any message on web page from previous page request and then clear message
03:08codedigestionreally has nothing to do with sessions, eh? What's a use case of a flash message?
03:09markomanit uses session to store message between two requests, then cleans session variable
03:11markomanits like a flash, shows up once. say you make some actions, like storing form and want to inform user after submitting form all was fine. you dont want to keep message popping on screen continously, just once. its very common practice on web frameworks
03:14markomanpost page -> store message -> load new page -> show message -> delete it from session. thats how it works
03:14codedigestiongot ya'! :)
03:15codedigestiondoes flash store to a specific variable, or just to "flash" and you request "flash" and it gives if somethings there, else nothing?
03:17markomanit stores to session store to :flash variable internally and like you figured, I use only flash function for both functionality, setting and getting depending if I pass message or not
03:21codedigestionquestion, you've got -> (:require [websesstudy.session :as ses]))
03:21codedigestionisn't that the ring.session?
03:22codedigestionwhere does your session actually come from?
03:22codedigestionwhen did you load it?
03:22markomanno, its my session.clj but inside there you can see, I wrap both ring session and my session by middleware
03:23tomojI can't help feeling an existential crisis about sessions after that question
03:23tomojdude, where DO they come from?
03:24markomansession.clj you can see (:use [ring.middleware.session]) so there it is
03:24codedigestionICKES!!!!
03:24codedigestionyeah, just looked at yoru session.clj
03:24codedigestionI don't understand ANYTHING in it???????????? looks very complicated, man! Just to store a key/value pair to a session???
03:26markomanyeah. I had a same feeling when I looked to sandbox. and I thought I made it easier. for me apparently, lol
03:27codedigestion:'(
03:27markomanbut yes, you need to store session information somewhere, I use atom memory based store. it could be database too. I think ring session handler doesnt really take opinion where you want to store data if anywhere
03:28codedigestiongosh, tooo many layers of crap just to get things working!
03:28thorwileek, how do i get out of an "Debugger entered--Lisp error: (end-of-file"?
03:28amalloythorwil: C-g?
03:28amalloyor just q?
03:29thorwilq, thanks
03:29codedigestion@markoman, any idea on how to use ring.middleware.session, or is this as complicated? :P
03:29tomojit's only got one function
03:29codedigestionnevermiind...
03:29codedigestioni see that's what you used...
03:30amalloycodedigestion: if only there were a programming language where writing new libraries to expose new ideas took no effort at all. just wave some fairy dust and you have a webserver with stateful sessions
03:30markomanwell at the end you just include file and use two functions. codedigestion, I know the feeling really. I was used to easier session variable handling by PHP
03:30codedigestionDo I need the UUID?
03:31markomanyes, either one generated by ring or your own
03:31tomojseems PHP built their castle on web conveniences, luckily rich was not so foolish
03:31codedigestionhmmm.............
03:31fliebel00211111
03:31amalloyonly if you want to IDentify your clients in a Universally Unique way. if you don't mind client A getting sent client B's session data, you can drop the uuid
03:31fliebelthat was my cat, sorry
03:31codedigestionI didn't think it was rick that made ring?
03:31markomanring session wrapper creates cookie and session id, but I found it better to use my own
03:31tomojexactly!
03:32thorwilfliebel: your cat communicates in ternary?
03:34amalloywell-educated cats would communicate in balanced ternary: +-=====
03:34fliebelthorwil: Nope, it knows more key commands than I do :) It choose the numpad as an appropriate location for some tail wagging today.
03:35markomanbut Im still happy, now I know better how sessions work under the hood. never needed to thin kabout it with PHP, but its same principle
03:35codedigestion@markoman, if I just use your websesstudy.session, should I be able to get my stuff to work provided I follow the principles you've laid out in your core.clj, you think?
03:35fliebelI didn't even know there as an enter key there.
03:36markomancodedigestion: yes. core.clj is the frontend, you have a session set and get functions and thats all you need
03:37tomojis session set/get much more more than assoc/get?
03:38tomojI've only ever dabbled in ring but the session middleware seems perhaps deceptively simple
03:38markomanI recently made a small fix there with session del function, but havent commited it yes
03:38markomanyet*
03:38codedigestion@markoman, do I just copy your file into my src folder? I'd like to keep it as (:require [websesstudy.session :as ses]), but wouldn't know what folder to put your session file in so that I'd be able to accomplish this in leiningen - any thoughts?
03:40markomanyou probably just use: (:require [yourpackage.session :as ses]) im not sure of your src layout
03:41markomanhave to go to the meeting, be back later
03:41amalloywow it's been too long since i did balanced ternary. my +-===== is nonsense; 00211111 in "traditional" ternary is +-+++++ in balanced ternary
03:42codedigestionfair enough! thanks Mark! I appreciate the patience! :)
03:48thorwili really wonder what's going on there: http://www.foopics.com/showfull/d57a41526055b6001110a2788f45a935
03:49amalloylooks vaguely like a bug in swank-clojure
04:03raekthorwil: probably a non-ascii character in the file
04:04raekyou could try customizing slime-net-coding-system to 'utf-8-unix
04:04raekand then start the swank server with "UTF-8" as an encoding parameter
04:07raekby adding :jvm-opts ["-Dswank.encoding=utf-8"] to the project.clj
04:08raektoo bad slime has to default to latin-1 when everything in clojure-land defaults to utf-8
04:09tomojseems I didn't need any :jvm-opts
04:10tomojat least, I haven't seen that damn error since I customized slime-net-coding-system
04:12raekhrm. maybe swank-clojure defaults to UTF-8 nowadays...
04:14raektomoj: so you can type (seq "ĉĝŭ") in the repl and get (\ĉ \ĝ \ŭ) back?
04:19tomojyeah
04:20thorwilah, (seq "ĉĝŭ") is a killer here
04:21tomojeven with the 1.4.0-SNAPSHOT swank-clojure bin
04:22raekencoding issues are tricky, since the effects a bad configuration can cancel each other out in some cases (the seq test reveals this, though)
04:23tomojmaybe get-system-encoding in swank.swank is relevant
04:24tomoj(.name (java.nio.charset.Charset/defaultCharset)) here returns UTF-8
04:24tomoj.. but this is the only key in the encodings-map anyway
04:24tomojswank.core.connection confusingly has (def default-encoding "iso-8859-1")
04:27thorwilcan't find any slime-net-coding-system
04:27tomoj`C-h v slime-net-coding-system` says "No match"^
04:27tomoj?
04:28thorwil(.name (java.nio.charset.Charset/defaultCharset)) says "UTF-8" here, too
04:40raekthorwil: tomoj: are you using emacs-starter-kit?
04:41raekI don't have it on the computer I'm currently sitting at, and for some reason, the slime.el file is not automatically loaded. if I load it manually, slime-net-coding-system appears
04:41tomojraek: no
04:41tomojI have slime from tromey's package.el
04:43tomojI also (setq slime-net-coding-system 'utf-8-unix) in init.el, so that test is pointless..
04:51thorwilno, no starter-kit
05:08thorwilno init.el, but i found a place for (setq slime-net-coding-system 'utf-8-unix), so now (seq "ĉĝŭ") works
05:08thorwilthanks, raek, tomoj
05:15tomojI spent months dodging unicode bombs in the repl before, I think, raek gave me that tidbit
05:16_extermHi everybody. I have implemented some modifications to the clojure 1.1 compiler to allow bytecode generation on Android (building on the work of george jahad). Now I have problems porting it to clojure 1.2.
05:17_extermsee my changes here:https://github.com/exterm/clojure/commit/9bf7109960e2468d00daecd8756c65cb8d1c2f32
05:17fliebelIs there something like cond-let? (cond-let [x false] x [y true] y) > true
05:18_extermwith clojure 1.2 I can evaluate (defn test [] "") to get a new function test into the namespace (I do this via a modified swank instance that is deployed on the phone)
05:19_extermBut any definitions that are compiled AOT I can't overwrite at runtime
05:19_extermTrying to find the change in the clojure compiler between 1.1 and 1.2 that is responsible
05:21_extermany clojure compiler hackers here today? :-)
05:21tomoja bisect to the phone would probably be quite tedious :(
05:21_extermyes, i thought about that
05:21_extermi'd have to reapply my changes in each step too
05:22tomojouch
05:22fliebel_exterm: Not me. But I do wonder why you are targeting 1.2 with 1.3 just around the corner?
05:22tomoj..ouch
05:22_extermI wanted to base it on a stable version to make it useable now.
05:22_extermI could of course try 1.3
05:23fliebelI use 1.3… Not sure if that qualifies it as usable though.
05:23_extermbut I think the relevant change will most likely be in there too
05:23_extermso that wouldn't really solve my problem
05:24fliebelNo… except that 1.3 has this ^:dynamic thing that would make life hard for you.
05:24clgvhumm one of incanter's example doesnt work for me - anybody know why? here it comes:
05:24clgv(use '(incanter core datasets stats bayes charts))
05:24clgv (def ols-data (to-matrix (get-dataset :survey)))
05:24clgv (def x (sel ols-data (range 0 2313) (range 1 10)))
05:25clgvlinear-model fails with NullPointerException in cern.colt.matrix.tdouble.DoubleMatrix2D.zMult
05:26_extermBTW anyone who wants to try developing for android with a swank server on the phone, I have a little script that downloads and builds my project so it's quite easy to get it up and running (using clojure 1.1 though, obviously): https://github.com/exterm/swank-android-builder
05:26clgvx and y are proper values
05:28fliebelclgv: Maybe it's because you are not using y?
05:28clgvfliebel: what exactly do you mean?
05:29fliebelclgv: I don't see y being used in your code.
05:29clgv-> (linear-model y x :intercept false)
05:30clgvit's not my code, it's example code from doc ;)
05:31_extermfiebel: ^:dynamic? Do you have a link?
05:34Fossi_exterm: i'll try ;)
05:35fliebel_exterm: Uhm, no. Maybe Google has. But the short version is that vars cannot be changed in 1.3, unless you mark them dynamic.
05:35fliebel&*clojure-version*
05:35sexpbot⟹ {:major 1, :minor 2, :incremental 0, :qualifier ""}
05:38raekchanged, as in rebound with (binding [*foo* ...] ...)
05:38_extermgood to know ^^
05:38raekdef still works to correct vars, but causes functions to be recompiled
05:39_extermthat could make interactive development on android a bit slower. Anyway, I think I will concentrate on 1.2 for now, could make it easier to port to 1.3 once I have solved the current problems.
05:48raek_exterm: btw, have you presented your work to the clojure-dev mail list? I think the core team would be interested since Android support seems to be in the pipeline
05:50raekalso, I know that Remco van 't Veer and Daniel Solano Gómez has worked on android support too. is your work related to theirs?
05:52_extermraek: oh, I didn't know that. No, I haven't presented it there. My work builds on Remcos modifications to the clojure compiler and his clj-android library, yes
05:54raek_exterm: http://dev.clojure.org/display/design/Android+Support
05:55Fossinifty
05:55Fossiups the prio/visibility
05:57_extermnice
05:57_extermbtw: Some forms fail to compile due to excessive stack use, e.g.
05:57_exterm(for [x (range 5) y (range 5)] [x y])
05:57_extermquote from your link, raek
05:57_extermI have implemented a workaround for that, but I believe Remco also did that
06:06thorwiltrying to improve my understanding of enlive, what's the minimal case for using Enlive's content fn? ((en/content {:tag :p, :attrs nil, :content '("TOM")}) "JERRY") doesn't work
06:44fliebelthorwil: What is the error?
06:44thorwilfliebel: java.lang.String cannot be cast to clojure.lang.Associative
06:45SLLCLLfinally made a fast primes sieve
06:45SLLCLLhttp://pastebin.com/9F6vfEA2
06:45fliebelthorwil: That'd be the jerry. I think that should be a map as well. Or… I don't know actually.
06:46fliebelSLLCLL: Didn;t dnolen do a fast on already?
06:46thorwilfliebel: also surprising to me is that the value for :content can't be just ("stuff"), despite that being the way those maps are represented
06:47SLLCLLno idea
06:47fliebelhttp://dosync.posterous.com/lispers-know-the-value-of-everything-and-the
06:47SLLCLLI'm still happy because this one works around 600000 times faster than my last one
06:47SLLCLLfor x = 1e6
06:48thorwilfliebel: ah, this works: ((en/content {:tag :p, :attrs nil, :content '("TOM")}) {"JERRY"})
06:48thorwilbut now i feel like understanding even less about it
06:49fliebel&{"JERRY"}
06:49sexpbotjava.lang.ArrayIndexOutOfBoundsException: 1
06:50fliebelHow could that possibly work, without magic?
06:50thorwilactually, it works only in so far as it does not throw an error
06:50thorwilcontent isn't replaced
06:51fliebelhttps://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L598
06:51clgvfliebel: the force might be strong with him. ;)
06:52fliebelclgv: We will not train him then, he is to young.
06:52clgv:D
06:52fliebelclgv: Where you referring to cgrand or thorwil?
06:52thorwilyes, i know how that source looks. i successfully modeled another transformation on it, but i'm failing at constructing yet another
06:53clgvfliebel: thorwil ;)
06:53fliebelflatten-nodes-coll is dense...
06:55thorwilyeah, i don't get through that one at all
06:56fliebelI see many macros in there. macros lead to doubt, doubt leads to anger, anger leads to hatred, hatred leads to the dark side of the force. s/everything/correct wording/
06:57fliebelthorwil: At least I think it takes a node, not text. html-content is what you want, I think.
06:58thorwilfliebel: if used in a defsnippet as intended, en/content does take plain text
06:59fliebelthorwil: Have you tried putting it off and on again? Uh, I meant, macroexpand, to see what happens.
06:59thorwilwith my new transformation, i get errors regarding number of args, so i figured there's something about the mechanism that i should better get to know
07:00fliebelthorwil: readme says it's (content “xyz” a-node “abc”)
07:00raekthorwil: what does ((en/content "JERRY") {:tag :p, :attrs nil, :content ["TOM"]}) return?
07:02raekI think the call to content returns a transformation function, which is the one that takes a node and returns some nodes
07:02thorwil{:tag :p, :attrs nil, :content ("JERRY")}
07:04thorwilraek: i thought these transformations are functions that take nodes via & values in their signature, to deliver an anon fn that takes whatever args needed
07:05raekto compose transformers, I think you should be able to use ordinary function composition: ((comp (content "Jerry") (add-class "character-name")) {:tag :p, :attrs nil, :content ["Tom"]})
07:05Fossiraek, anybody: what's the main way of communication for something like android support? the ml?
07:06raekI think (content “xyz” a-node “abc”) means "construct a transformer that takes a node and returns the node, but with ("zyz" a-node "abc") as its content"
07:07raek"Transformations (the right-hand parts of rules) are now plain old closures.
07:07raekThese functions take one arg (the selected node) and return nil, another node
07:07raekor a collection of nodes."
07:11raekoh, scratch the comp thing. looks like do-> is the proper way
07:15thorwili've been using do->
07:16raek(comp would only work if each transformation returns exactly one node)
07:16thorwilmy entire problem is how arguments are taken via function signature and then by the inner anon fn
07:17thorwili got it backwards
07:26thorwilah, finally, a transformation that applies a fn the the content: (defn tryout [to] #(update-in % [:content] (fn [c] (apply (partial replace-str "token" to) c))))
07:26thorwilyou guys are awesome :)
07:54mat1Is there a way to call a function given the first part of the function is variable and the second part is constant. for example (${MYTYPE}Reader [somevar])
07:56clgvmat1: you can create a symbol from a string and resolve it
07:57mat1sounds exactly like what I want.. using the gensym function?
08:00Chousukemat1: like (resolve (symbol "+"))
08:00Chousukegensym creates unique symbols
08:02mat1awesome that works
08:03mat1thanks
08:06fliebelDoes anyone know where I can get the latest apache commons from maven? Latest is 2.0.1, but central only seems to have 1.3.whatever.
08:06fliebelhttp://mvnrepository.com/artifact/org.apache.commons/commons-io
08:06fliebelhttp://commons.apache.org/io/
08:08cemerickfliebel: org.apache.commons is a deprecated groupId, IIRC
08:08cemerickfliebel: http://search.maven.org/#search|gav|1|g%3A%22commons-io%22%20AND%20a%3A%22commons-io%22
08:09fliebelcemerick: Thanks! So even java land is leaving the reverse domain thing?
08:10cemerickfliebel: I don't know the details. The "reverse domain thing" isn't demanded; junit has had a groupId of 'junit' forever.
08:11cemerickThat said, I'd prefer the reverse domain idiom here; just how many "commons-io" libraries might various orgs produce?
08:11fliebelThat is what the paranoid part of me was about to say.
08:24cemerickhow is it that Clojure source apparently looks great in IntelliJ, but absolute shite everywhere else?
08:30dnolencemerick: that's what rhickey used, right?
08:31cemerickdnolen: yeah, and according to fogus, it does look decent there.
08:31fliebelcemerick: What is wrong with the source?
08:31dnolenI personally don't really understand the complaints about Clojure's Java source. It's quite readable to me.
08:32cemerickIndentation is jacked up all over the place.
08:33cemerickNot in an unusual way -- in an irregular, totally inconsistent-from-method-to-method way.
08:33cemerickanyway
08:33dnolencemerick: hardly important considering how clean the code is written. the most beautifully formatted crap is still crap.
08:34dnolenparts of Django's source case in point (sorry to rag)
08:34fliebeldnolen: Sure? Explain this then ##(source when-let)
08:34sexpbotjava.lang.Exception: Unable to resolve symbol: source in this context
08:34cemerickdnolen: some of the more deeply-nested blocks that suddenly swing to the left require very careful reading, at least for me.
08:35cemerickfliebel: I'm talking about the Java source, not the .clj Clojure source.
08:35fliebelsexpbot, where is your source?
08:35fliebelah...
08:39fliebel&(use 'clojure.repl)
08:39sexpbot⟹ nil
08:40fliebelThere we go! ##(source when-let)
08:40sexpbot⟹ Source not found nil
08:41cemerickfliebel: source reads from the classpath, which the sandboxes probably don't allow.
08:41fliebelprobably… :(
08:42fliebel$source when-let
08:42sexpbotwhen-let is http://is.gd/bqDRKj
08:42fliebel(inc amalloy-or-raynes-or-whoever-did-that)
08:42sexpbot⟹ 1
08:52gfrlogdo watchers of atoms have to be side-effect-free?
08:53cemerickcertainly not
08:53gfrlogwell that is quite convenient
08:53gfrlogI am going to use a watcher!
08:53cemerickwrite-behind logs are handy :-)
08:53gfrlogI'm always writing side-effecty-swap functions and then kicking myself later
08:57shanmuhello, all! is there a replacement for duck-streams module in clojure-contrib 1.3?
09:07technomancyshanmu: clojure.java.io
09:14shanmutechnomancy: thanks!
09:17gfrlogI'm having a surprising amount of trouble managing a mutually exclusive resource
09:18gfrlogactually the mutual exclusivity is not the issue
09:18gfrloglet's pretend it's a database connection
09:18gfrlogand multiple threads can access it at the same time
09:19gfrlogbut I only want one of them to be open ever
09:19gfrlogso I use an atom to keep track of how many threads are using the thing
09:19gfrlogwhen the first registers, I create one, and when the last unregisters, I close it
09:20gfrlogand I believe my error is caused by trying to open one before the previous one was closed
09:20fliebelgfrlog: Maybe a CyclicBarrier, ReadWriteLock, or something else in the java.util.concurrent package.
09:20gfrloghmm
09:20gfrlogsince "closing" is a side effect, I moved that out of the swap function and into a watcher
09:21gfrlogbut now that it's in the watcher, there's no guarantee somebody else isn't opening a new one at the same time
09:21gfrlogI don't think the cyclicbarrier is appropriate
09:22fliebelNo, I'm looking for another one… hmmm
09:22gfrlogI was going to cook up something complex involving promises, but there's gotta be a better way...
09:24gfrlogI could use an agent that handles all the swapping + side effects, and any function that wants to do something sends it to agent and waits on a promise :-|
09:24gfrlogwhich just sounds inappropriate
09:26jedii'm trying to get slime working with acquamacs and swank-clojure as per the instructions on https://github.com/technomancy/swank-clojure, but M-x slime-connect results in this error: "Symbol's function definition is void: define-slime-contrib"
09:27jediis it fruitless doing this in aquamacs?
09:27ejacksonjedi: not at all - it should work fine
09:29jediok i'll keep at it ejackson, thanks
09:29fliebelgfrlog: I'm not sure I really understand the problem.
09:29ejacksonjedi: i followed the instructions for getting the emacs side working here: http://technomancy.us/126
09:29ejacksonusing ELPA, and it works 100%
09:29gfrlogfliebel: there's a thread-safe resource that obeys the open+close interface, but it breaks if you open two at the same time
09:29technomancyaquamacs is untested
09:30gfrlogso I just want to make sure that when two threads use the resource simultaneously that they're using the same one and not trying to open different ones
09:30technomancyGNU Emacs is strongly recommended; I don't test on xemacs or any of the other forks.
09:30fliebelah!
09:30gfrlogand I don't want to leave one open, I want it closed when everybody is done with it
09:30ejacksontechnomancy: OK, FWIW I use it all the time with no problems.
09:31ejacksoni'm happy to help you to test aquamacs if you like
09:34technomancythere's too many arbitrary changes in aquamacs for me to officially support it, but of course bug reports are welcome.
09:35fliebelgfrlog: I'm thinking…
09:35gfrlog:) strange that it's so hard what with clojure's emphasis on this sort of thing
09:36fliebelgfrlog: well, clojure makes it easy to work with persistent stuff. as I discovered with seque, and now again with your problem, clojure does not cover the mutable stuff any better than java.
09:37gfrlog does the agent + promise hack sound like it would work correctly?
09:37gfrlogactually I don't think you need promises, I think there's a method for waiting on the agent
09:37gfrlog,(doc wait-for)
09:37clojurebotPardon?
09:37gfrlog,(doc wait)
09:37clojurebotHuh?
09:37gfrlog,(doc what-function-am-I-thinking-of?)
09:37clojurebotTitim gan éirí ort.
09:38technomancy,(doc await)
09:38clojurebot"([& agents]); Blocks the current thread (indefinitely!) until all actions dispatched thus far, from this thread or agent, to the agent(s) have occurred. Will block on failed agents. Will never return if a failed agent is restarted with :clear-actions true."
09:38gfrlogtechnomancy: thx :)
09:38technomancynp
09:38gfrlogokay, so instead of using swap!, I use send + await
09:39gfrlogwhich is effectively swap! + side-effects, if I'm not missing anything
09:39fliebelgfrlog: I think that as soon as you use agents and promises as a queue, you are better of using a real queue.
09:39gfrlogyou say it's a queue because I want the functions to execute once and synchronously?
09:40fliebelgfrlog: agent is serial, so then you might as well just lock the whole file then.
09:40gfrlogfliebel: I wouldn't use the agent for the whole operation, just for opening and closing
09:40fliebelgfrlog: explain that please.
09:41gfrlogkay one sec
09:42gfrlogfliebel: https://gist.github.com/964497
09:44gfrlogI'm starting to like that solution more, because then I get the added benefit that do-stuff can return before the resource is closed
09:46fliebelgfrlog: okay… I wonder what magic goes inside *-resource-user, because that will have to decide whether the resource is already open/closed and if others are using it or not. So do you want to maintain a counter and the state of the resource inside the agent?
09:46gfrlogexactly
09:46gfrlogthe agent keeps a counter
09:46gfrlogwhen it drops to 0, it closes the resource
09:47gfrlogif it's at zero when register is called, it opens the resource, else just increments the counter
09:48fliebelokay, that might work. What I had in mind uses AtomicInteger to do about the same thing, but without the agent.
09:49gfrlogand like I said before, with the agent I get a quicker return
09:49gfrlogso maybe I'll go with that
09:50fliebel(locking at-int (when (zero? (.getAndIncrement at-int)) (open))))
09:51fliebeldon;t forget to use a try-finally block, or you might get the thing into a weird state.
09:51gfrlogyep :)
09:52gfrlogfliebel: thanks for the thinkings
09:52fliebelnp :)
09:53desertWalkertest
09:53gfrlogtest passed
09:54gfrlogRan 1 test containing 0 assertions.
09:54gfrlog0 failures, 0 errors.
09:54fliebeldesertWalker: You failed for punctuation though.
09:54gfrlogwhat should he have punctuated?
09:55fliebelgfrlog: Because most sentences are supposed to start with a capital and end with a dot, but apparently these rules don't apply on IRC.
09:56gfrlogI guess you take it as a sentence because it could be an imperative?
09:58jediusing plain ol' gnu emacs seems to work a lot better than aquamacs
09:58fliebel… maybe? It wasn't an assertion at least :) Anyway, I'm glad he got his charset right. Or at least he did not pick one of those ancient ones that even have the first 255 all scrambled,
09:59technomancyI mean you could also try Chewy Ranch Emacs, but the Original Flavour is preferred by thousands of hackers.
09:59jediyum
10:47dnolenDatalog used to detect race conditions in concurrent Java programs - http://code.google.com/edu/languages/index.html#_java_racedetect, yet not a single Functional, or Logic programming language in their list of PLs.
12:20micahmartintechnomancy: Is the leiningen IRC channel dead?
12:22dakronepeople still occasionally ask questions in it, if that's what you meant
12:22micahmartinyeah. It
12:23micahmartinIt's just that I get leiningen questions answered more in this channel these days
12:25dnolenwow Google App Engine for Go, that's a big endorsement...
12:25ejacksonlol !
12:26technomancythe #leiningen channel is more about developing lein than using it
12:27technomancyjust doesn't make sense to keep things in a separate channel when it's general usage questions I guess
12:27dakronenot everyone knows there's a separate channel for it either
12:30fliebeldnolen: Meh, why not OCaml :P
12:32dnolenone valid criticism of OCaml is that it really didn't get on the concurrency bandwagon until just recently.
12:34micahmartintechnomancy: So I'm been thinking about the way leiningen is distributed and used by plugins... and I kept coming back the one question: Why doesn't leiningen live in a maven repo like all the other libraries?
12:35technomancybecause it's not a library
12:35technomancyit's an application
12:35micahmartinit's a library for plugins
12:36technomancyplugins are libraries
12:36micahmartinyes... libraries that depend on leiningen
12:37micahmartinWhy don't you want leiningen to be a library. It'd make my life easier
12:38micahmartinin fact.. I might even say that my hair is about to catch on fire.
12:38dakronewhat are you trying to do that you need lein as a library for?
12:39technomancysupporting a library is a very different thing from supporting an application
12:39micahmartinbuild a shell wrapper that uses leiningen functionality
12:39technomancyI'd rather not sign up to support more use cases if it can be avoided
12:40micahmartinBut becoming a library is a natural path for a build tool.
12:40micahmartinAnt is a library, Rake is a library.
12:41technomancygem isn't
12:42micahmartinah... good point... So leiningen is both a build tool and library management tool
12:43micahmartinCan the build tool aspect be extract out into a library?
12:44technomancymaybe. seems like it's a whole lot easier to just call leiningen from the shell wrapper though.
12:45micahmartinokay... I can do that... but then I have to maintain the shell script which leiningen so nicely generated before.
12:45micahmartindependencies, version numbers, they all get duplicated
12:46no_mindI have a function in a given namespace. I have the name of the namespace and function available as strings. How do I call the reuiqred function in the given namespace ?
12:47amalloywhy do you have them available as strings? are you reading user input and then eval'ing it?
12:49no_mindamalloy: nope, its part of menu system. The path and corresponding namespace/function name is stored in db and I have to callback required function for given path
12:50whidden__no_mind: you might want to look at ns-resolve as a starting point
12:51no_mindwhidden__: I have used ns-resolve but it wont callback the function
12:51technomancymicahmartin: shouldn't need to duplicate dep list in the shell wrapper; just include %s and the classpath will get inserted.
12:51amalloyno_mind: huh? it returns a var to you; you just (optionally) dereference the var, and call the result as a function
12:51amalloy,(doc ns-resolve)
12:51clojurebot"([ns sym]); Returns the var or Class to which a symbol will be resolved in the namespace, else nil. Note that if the symbol is fully qualified, the var/Class to which it resolves need not be present in the namespace."
12:52amalloy,(@(ns-resolve 'inc) 1)
12:52clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$ns-resolve
12:52amalloy,(@(ns-resolve *ns* 'inc) 1)
12:52clojurebot2
12:52no_mindwell I tried this ((resolve (symbol (str ns "/" fn)))) but it is throwing nullpointerexception
12:53amalloythat / is wrong
12:53amalloy&(namespace (symbol "foo/bar"))
12:53sexpbot⟹ "foo"
12:54amalloyhm
12:54amalloy,((resolve (symbol "clojure.core/inc")) 1)
12:54clojurebot2
12:54amalloyif that doesn't work for you, you're doing something else wrong
12:56whidden__no_mind: other things to look for is that fn is really defined in the ns. I always have spelling trouble in cases like this.
12:57no_mindthe fn is defined cause I can call it directly...
12:59amalloyno_mind: post a gist of you calling it directly and failing to call it indirectly
13:01whidden__&(resolve (symbol "foo"))
13:01sexpbotjava.lang.SecurityException: You tripped the alarm! resolve is bad!
13:03whidden__&(ns-resolve 'user (symbol "foo"))
13:03sexpbotjava.lang.SecurityException: You tripped the alarm! ns-resolve is bad!
13:03whidden__,(ns-resolve 'user (symbol "foo"))
13:03clojurebotnil
13:03no_mindswitched to ns-resolve from resolve and now getting this error java.lang.String cannot be cast to clojure.lang.Symbol>
13:03amalloywhidden__: ns-resolve wants a namespace as a first arg, not a symbol
13:04amalloyno_mind: you can keep making vague complaints or you can paste some actual output so someone can see why the "works for us" solution isn't working for you
13:06whidden__no_mind: if 'ns' is a string then you can make it a symbol by calling symbol.. and getting something like (ns-resolve (symbol ns) (symbol fn)), where ns and fn are strings with the appropriate names.
13:08amalloywhidden__: ns-resolve still wants a namespace as its first arg like i said a moment ago
13:08amalloy,(ns-resolve 'clojure.core 'inc)
13:08clojurebot#'clojure.core/inc
13:08amalloydang. apparently i'm wrong again
13:08amalloyclojurebot: thanks for keeping me honest
13:09clojurebotthanks for your suggestion, but as usual it is irrelevant
13:09kzarif Clojure is a bit to slow on Android does anyone know of a good Lisp that works well?
13:09kzartoo*
13:10whidden__kzar: have you looked at ecl?
13:10whidden__kzar: maybe someone is already porting sbcl over to android ;)
13:11kzarheh well I guess as long as it's not Java
13:12technomancypeople have run sisc on it IIRC
13:13whidden__kzar: what's the arch of android? if its close to ppc, amd then sbcl might not be that hard to port.
13:13dnolenkzar: yeah until phones get more memory and a bit faster, Clojure won't have much luck. Fortunately that's probably summer 2012.
13:13whidden__kzar: for what its worth, I got ecl running on the gumstick eval board.
13:17fliebelPattern matching is awesome :)
13:20kzarheh ok thanks everyone
13:23dnolenfliebel: heh, what makes you say that?
13:30fliebeldnolen: Reading about erlang :) I gues the same is true for OCaml and Prolog, pattern matching is everywhere!
13:34dnolenfliebel: totally. Erlang got it from Prolog, Erlang was originally written in Prolog and retaining the Prolog-y syntax.
13:34dnolens/retaining/retained
13:34sexpbot<dnolen> fliebel: totally. Erlang got it from Prolog, Erlang was originally written in Prolog and retained the Prolog-y syntax.
13:36fliebeldnolen: To bad they don;t do the real prolog stuff anymore :)
13:37dnolenfliebel: well ... Prolog had a reputation for being too slow for many common tasks. Mitigated now by things like CHR, but it's hard to shake an image.
14:20no_mindhow can I load a namespace from a file ? I tried using (load "ns") but it looks for file relative to classpath. Can I load a namespace from a file using absolute path ?
14:23dnolenno_mind: did you try using an absolute path?
14:23no_mindyes
14:24fliebelno_mind: load-file?
14:26gigamonkeyIs there consensus on what's the best Clojure book?
14:27jlf`gigamonkey: idk about consensus but the joy of clojure is quite good
14:27gigamonkeyjlf`: have you read others and prefer that one?
14:28jlf`i've also read programming clojure, yeah
14:28technomancygigamonkey: depends on the audience
14:28technomancyprogramming clojure is introductory
14:28fliebeljoc contains more stuff I should know ;)
14:29dnolenhugod: heh, those were the days.
14:30cemerick…when men were men, and sbcl seemed like the best possible option… :-)
14:35gigamonkeyWhat do you folks who like JoC like about it?
14:38technomancygigamonkey: the bibliography, for starters =)
14:41gigamonkeytechnomancy: hmmm.
14:44dnolengigamonkey: I think people like the fact that JoC is a deeper dive, assumes you've already read something introductory or spent enough time w/ the lang.
15:04dnolencemerick: speaking of which, you should get that blurb about Clojure fixed on Amazon.
15:05cemerickdnolen: tell me about it :-|
15:05cemerick(we didn't write it)
15:05dnolenooph
15:05dnolenClosure, and mentioned Ruby and Python even though JRuby and Jython exist.
15:06cemericka far better description is on the O'Reilly catalog page at this point http://oreilly.com/catalog/0636920013754/
15:08dnolencemerick: in anycase, it's exciting that O'Reilly is a doing a Clojure book. Never thought I'd see the day they'd put a Lisp book out.
15:08dnolencemerick: that is much nicer.
15:08cemerickdnolen: Barriers broken, indeed.
15:09cemerickNow the question is, what's the latency between ORM and AMZN
15:12gigamonkeycemerick: who's your editor? Loukides?
15:12technomancycemerick: are you coming to the meetup on thursday?
15:13cemerickgigamonkey: He got things through the pub board. Julie Steele is with us now.
15:13cemericktechnomancy: Vaguely possible.
15:14cemerickhah
15:15cemericktechnomancy: though I'm strikingly bad at the hackfest format.
15:15cemerickLooks like it's full anyway.
15:19technomancycemerick: yeah, I'm not sure how the seajure recipe is going to translate to this setting
15:21technomancywhere did you see it's full?
15:21cemerickI'm a fish out of water in such models regardless of setting.
15:21cemerickhttp://www.meetup.com/Boston-Clojure-Group/events/17395470/
15:21technomancywell I mean at our meetings we rarely have more than ten
15:21cemerickah
15:21cemerickProbably going to be 5-10 hacking at the problem, with the rest eating pizza and bs-ing.
15:22technomancythat'd work too =)
15:24fliebelHow do you organize these hackathons over there? At the Amsterdam Clojurians we moslty go pizza, blabla, end.
15:26technomancyfliebel: well we only do a hack project every other meeting or so when someone has a nice juicy idea that's small enough
15:26technomancybut I guess the coffee helps
15:27fliebeltechnomancy: So it's just that someone brings up an idea that you can finish in one meetup, and you all work on that?
15:27technomancyfliebel: yeah, and there's a tmux session everyone joins over SSH
15:28fliebeltechnomancy: You mean you work with 10 people in one session?
15:28technomancy"swarm coding", like pair programming
15:28technomancyyeah
15:28chousertechnomancy: how many people per session?
15:28chouseroh, wow.
15:28technomancy7 or 8 on average
15:29chouserso, does that mean 1 person typing, one or two actively suggesting things, and 4 or 5 just watching?
15:30cemerick…or eating more pizza. :-)
15:30jweissif i do (def x [1 2 3]) (defmacro blah [nums] `(apply + ~nums)) - can i get it to actually insert the vector [1 2 3] at compile time, not just a symbol pointing to a var containing it?
15:30fliebelI was at a Python hackathon recently, and there everyone just tell about their plans, and then start doing it. Which led to small groups clusters around laptops.
15:31technomancychouser: usually there are only 3 or 4 people actively involved, yeah
15:32technomancyfliebel: yeah, I don't know if it scales
15:32chouserseems like it could scale sideways. 30 people show up and split into 6 totally unrelated projects
15:33fliebeltechnomancy: What is the level of Clojure expertise there? Amsterdam has a lot of starters I think. I'm trying to get them to do some more hacking :)
15:33technomancyyeah, we will probably split the group for this boston one
15:33hiredmanthen it becomes a graph labeling problem
15:33technomancyfliebel: it's about half newbies maybe
15:35fliebelOkay, well, I'll see what happens tomorrow.
15:39jweissif i want to pass a symbol to my macro and have my macro have access to the data stored in that var (at compile time), should i use eval?
15:41raekjweiss: one approach is to not send it as a parameter. you can still access its value in the body of the macro
15:41fliebeljweiss: Should you do that at all? Well, maybe.
15:41raekjweiss: another one is to use resolve to get the var, and then deref to get its current value
15:42jweissraek: i'm generating java classes and methods here, so i think it's necessary
15:42jweissyeah that was the other technique - resolve and var-get
15:42jweissbut then i can't use a literal
15:42jweissso maybe eval is what i want here
15:44timvisherhey all
15:44timvisheri'm having trouble getting a command line program i'm working on working
15:44timvisherhttp://pastie.org/1886262
15:44raek(def x {'foo '+}) (defmacro bar [] (cons 'do (for [[name f] x] `(defn ~name [& args#] (apply ~f args#))))
15:44raekjweiss: ^
15:45raekthen x can be any value
15:45timvisheri call that from the command line after `lein install`ing with `:shell-wrapper true` in the project.clj
15:45timvisherlike so: `wallpaper-manager-cli wallpaper-seq`
15:45timvisherand it complains that it can't resolve the symbol `wallpaper-seq` in this context
15:46jweissraek: ok thanks
15:46timvisherwhereas if i comment out the doseq line
15:46timvisherthe manual call to `(wallpaper-seq)` runs exactly as i expect
15:46timvisherwhatcha think?
15:49raektimvisher: where is wallpaper-seq defined?
15:50timvisherin wallpaper-manager-core.core
15:51technomancytimvisher: if you can, I'd avoid eval
15:52timvishertechnomancy: would you simply map string inputs to their corresponding function calls?
15:52technomancywhat you're doing looks a bit like the command loop in mire; maybe you could try a similar approach? https://github.com/technomancy/mire/blob/master/src/mire/commands.clj
15:52timvisherthat's actually not a bad idea
15:52technomancyyeah
15:52timvisherI think I like that better than what i was planning on doing anyway
15:52timvisherbut what's confusing in this situation is that i wrote an incredibly similar app, with a core and then a cli
15:53timvisherand the exact same construct works in that context
15:53timvisherexcept that I call (load-file ...) before evaling
15:53timvisherI guess that load-file probably puts the relevant functions into the current namespace
15:53timvisherbut then why would the direct (wallpaper-seq) call work?
15:54timvisherwallpaper-seq is clearly in the namespace, although i've proven clearly in the path that haven't the foggiest understanding of what namespaces really are
15:54technomancyyeah, that is bizarre
15:56gfrlogso I guess it's not always the case that (-> ob pr-str read-string (= ob))?
15:56dnoleninteresting, SymbolicWeb lives! https://github.com/lnostdal/SymbolicWeb
15:57chousergfrlog: no not always. objects for which that holds are sometimes called "printable"
15:57gfrlogchouser: so keywords aren't printable?
15:57chousergfrlog: it is possible to create keywords that aren't printable
15:57lnostdaldnolen, i think it's migrating to Clojure actually
15:58gfrlogI like ruby's syntax
15:58dnolenlnostdal: hullo. SymbolicWeb and Webblocks are what got me excited about Lisp in the first place.
15:58chouser,(keyword "foo bar")
15:58clojurebot:foo bar
15:58chousergfrlog: that's an "unprintable" keyword, for example
15:59gfrlogruby would print it as :"foo bar"
15:59cemerickgfrlog: there are lots of objects that are not printable, including "manually created" keywords as well as most Java objects.
15:59gfrlogwhich as far as I can tell would be an unambiguous addition to the syntax
15:59chouserand an open issue, which I think is most likely to be resolved by some new reader syntax for awkward keywords and symbols
15:59chousergfrlog: yeah, that strikes me as not at all bad
16:00gfrlogchouser: probably not anything that elegant for symbols though
16:00chouser|this has been| suggested
16:00gfrlogI stand corrected
16:00lnostdaldnolen, yeah, the dsl thing is just too awesome to miss out on i think .... :)
16:00cemerickchouser: Quotes leading to keywords is odd. |funny symbol| and :|funny keyword| is better IMO.
16:00chousercemerick: yeah, that has a nice symmetry
16:01cemerickI can't imagine that's going to happen before the reader is clojure-ified though.
16:01gfrlogcemerick: okay, so a symbol that starts with a colon is |\:colon-symbol|?
16:02cemerickI wouldn't think so. Why escape the colon there?
16:03cemerickonly constituent pipes would need to be quoted
16:03dnolenlnostdal: it's cool to see an experienced CLer hacking on some Clojure :D
16:05gfrlogcemerick: because |:colon symbol| looks like (keyword "colon symbol")
16:07jweissgrr. the difference between a symbol for a class, and a class, is *painful*. they both look exactly the same.
16:07gfrlog,(class 'Double)
16:07clojurebotclojure.lang.Symbol
16:07gfrlogjweiss: you mean how they're printed?
16:08cemerickgfrlog: no reason to make more work. In any case,
16:08jweissgfrlog: no, now they're interpreted
16:08jweisshow can my macro spit out this: ^{org.testng.annotations.Test {:groups ["blockedByBug-703528"], :description "Test that invalid URL is rejected."}, org.testng.annotations.Test {:groups ["providers" "validate"]}}
16:08chouserjweiss: yeah, it can be confusing. especially in literal metadata
16:08cemerick|sym| and :|kw| more accurately conveys the relationship between the two
16:08jweissand then fail to evaluate it due to duplicate keys
16:09gfrlogcemerick: what's the difference between (symbol ":foo bar") and (keyword "foo bar") then?
16:09gfrlogcemerick: if nothing, then the syntax is ambiguous or incomplete
16:09jweisschouser: yeah literal metadata is what i'm working with here
16:09cemerickgfrlog: The first returns a symbol that starts with a colon. The second returns a keyword.
16:10gfrlogI mean what's the difference in the piping syntax?
16:10dnolen,{0 1 0 1}
16:10clojurebotDuplicate key: 0
16:10dnolenjweiss: do you expect to not get a duplicate key error?
16:10dnolen,{'a 'b 'a 'b}
16:10clojurebotDuplicate key: (quote a)
16:10jweissdnolen: the value above was the result of deep-merge-with.
16:10cemerickgfrlog: well, there is no piping syntax, this is all hot air :-)
16:10dnolen,{String 0 String 1}
16:10clojurebotDuplicate key: String
16:10gfrlogcemerick: I know, but if there was then you would want |\:colon symbol|
16:11jweissdnolen: so clearly that deep-merge-with fn didn't think they were the same key
16:11gfrlogelse you couldn't express symbols that begin with colons because they would be interpreted as keywords
16:11jweissor they would have been merged.
16:11jweiss(which is what i wanted!)
16:11cemerickgfrlog: so then pipes would evaluate to symbols *or* keywords, depending on the first constituent character? Bleh.
16:11chouserjweiss: how are you generating that map? and are your printing and then re-reading, or is the map passed directly to eval?
16:11gfrlogcemerick: I thought that's what you suggested.
16:11chousergfrlog: |:foo bar| vs. :|foo bar|
16:11dnolen,(merge {String 0} {String 1})
16:11cemerickNo; |funny symbol| vs. :|funny keyword|
16:11clojurebot{java.lang.String 1}
16:12gfrlogI'm getting smileys
16:12gfrlogso I guessed at what it meant
16:12jweisschouser: i'm merging 2 maps - 1 is a literal passed to my macro, (not evaled), the other is metdata from a literal that is eval'd
16:12chouser,{String 0, `String 1, 'String 2}
16:12clojurebot{java.lang.String 0, java.lang.String 1, String 2}
16:12cemerickgfrlog: damn smileys! :-)
16:13jweissyeah that ^^
16:13jweissif you eval it, you get duplicate key
16:13chouserjweiss: ah, I see. yep. because although a symbol and a class *are* different, both evaluate to the class
16:13gfrlogcemerick: chouser: http://imgur.com/rg7WG
16:14gfrlogso I still have no idea what the suggested syntax was :)
16:14chousergfrlog: you might want to fix your IRC client
16:14gfrlogoh I bet it was colon and then pipe?
16:14jweisschouser: ok, that's good to know, that will help me get them to match
16:14chousergfrlog: yes. : then | for a keyword
16:14dnolen,(eval (merge `{~String 0} `{String 1}))
16:14clojurebotDENIED
16:14cemerickgfrlog: yes; you need yourself a better irc client or something ;-)
16:14gfrlogchouser: okay thanks
16:14dnolenjweiss: (merge `{~String 0} `{String 1}), works, eval'ing fails.
16:15gfrlogsmileys disabled
16:15gfrlognot sure why I thought uploading a screenshot would be easier than that
16:15cemerickI have a little key macro that toggles them off when necessary
16:16chouserjweiss: If you know the user is passing a symbol that represents a class, I'd recommend using 'resolve' to fetch the appropriate class (or generate an error) at macroexpand time
16:17jweisschouser: yeah, i had been trying to preserve the symbol, but looks like i'll go the other way :)
16:17chouserwell, you could create a symbol from the class, but then you have String vs. java.lang.String to worry about
16:19jweisschouser: yup, had that problem and had been fully qualifying, which i had wanted to fix, and this is apparently going to fix it :)
16:19chouserhm, I wonder if dealing with class objects can run afoul of classloader issues. bleh. anyway, that's not a problem I've actually experienced
16:20chouser...and I've done a rather unfortunate amount of class-wrangling in macros
16:20jweisschouser: i haven't noticed any problem either
16:22markomani forgot how to see, if some item exists on a list? (:x [:x :y :z])
16:22gfrlog,(some #{:x} [:x :y :z])
16:22clojurebot:x
16:25markomanthx
16:25gfrlognp
16:25gfrlogyes, it oughta be nicer than that
16:26chouser(.contains [:x :y :z] :x)
16:26chouser,(.contains [:x :y :z] :x)
16:26clojurebottrue
16:26chouser,(#{:x :y :z} :x)
16:26clojurebot:x
16:26gfrlogchouser: is java interop the official recommendation there?
16:27chouserno
16:27chouser:-)
16:27gfrlog,(some #{false} [false nil ""])
16:27clojurebotnil
16:27gfrlog,(.contains [false nil ""] false)
16:27clojurebottrue
16:28chouserMost of the time I find it worth while to keep such things in a set instead of in a vector or list
16:28gfrlogI guess the (some) route doesn't even solve the problem in edge cases
16:28chouserand when not, 'some' seems to do the trick nicely
16:28gfrlog,(#{false nil ""} false)
16:28clojurebotfalse
16:28gfrlogchouser: you have to admit that for a language that has mapcat in the core, it's a glaring empty spot
16:29chouser,(#{nil ""} false :not-found}
16:29clojurebotUnmatched delimiter: }
16:29chouserd'oh
16:29chouser,(#{nil ""} false :not-found)
16:29clojurebotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentHashSet
16:29chouseroh!
16:29gfrlog(and that's only the obscurest function I could think of without thinking about it)
16:29chouser,(get #{nil ""} false :not-found)
16:29clojurebot:not-found
16:29chouserhuh
16:30chouser,8)
16:30clojurebot8
16:30gfrlogwth
16:30chousersorry
16:30chouserpaste fail
16:30gfrlogI guess it parses the first object and stops
16:30chouserthat's just the bot
16:30gfrlog,(readstring ",8)")
16:30clojurebotjava.lang.Exception: Unable to resolve symbol: readstring in this context
16:30chouser,({1 2} 3 :not-found)
16:30clojurebot:not-found
16:30gfrlog,(read-string ",8)")
16:30clojurebot8
16:30chouserthat's what I meant. Map as a function takes a :not-found arg, but set as a fn does not.
16:31chouserI hadn't realized that.
16:31gfrlogeven the not-found option is insufficient if your domain is all objects
16:32chouser(let [not-found (Object.)] (identical? not-found (get my-set my-key not-found)))
16:32chouserbut yes, this certainly gets tedious
16:33gfrlogdo you think contains? wins the most-missing-from-core contest?
16:34dnolenchouser: why don't you use a namespaced keyword there?
16:35gfrlog,:clojure.core/kw
16:35clojurebot:clojure.core/kw
16:37jweisschouser: i think resolving all symbols and replacing those that resolve to classes with the class has fixed it.
16:37lnostdaldoes clojure have weak references/pointers and weak hash-tables?
16:37chouserdnolen: that's theoretically still gameable, but (Object.) and identical should be impossible to thwart
16:38chouserlnostdal: Java does, and they are useful in Clojure.
16:39dnolengfrlog: one benefits I'm really beginning to appreciate about Clojure's design is that easy to reason about the computational cost of a piece of Clojure code. contains? as people want it would break that reasoning model.
16:40gfrlogdnolen: by that reasoning nth should also not exist
16:40technomancydnolen: that doesn't mean the current name is well-chosen
16:40dnolenchouser: heh, tho no more/less gameable than people some how messing around with interned symbols while your macro is expanding right?
16:40technomancythe only reason contains? exists as in its current form is to trick newbies into thinking about O(n)
16:41gfrlog,(doc contains?)
16:41clojurebot"([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."
16:41gfrlogI forgot that existed.
16:41dnolentechnomancy: you're basically agreeing w/ what I said.
16:42gfrlog,(doc has-key?)
16:42clojurebotHuh?
16:42gfrlog,(doc key?)
16:42clojurebotCool story bro.
16:42gfrlogeither of those would be clearer
16:42technomancydnolen: I'm not saying it shouldn't exist, it's just a crappy name
16:43gfrlogtechnomancy: I think he was saying there should not be a has? function
16:43gfrlogor equivalently that there should not be an appropriately named contains? function
16:46dnolentechnomancy: I agree I could have lived w/ has-key?, but some is fine, it's clearly means search.
16:46technomancy"some" implies a plural result
16:47technomancy"give me some of that" "ok, here's one" "wait, what?"
16:47gfrlogdnolen: and I think we wouldn't want the has? function to always search
16:47gfrlogif I happened to have a set I'd prefer it not to be treated like a seq
16:47gfrlogmaybe that's going too far though
16:47gfrlogI can imagine people already yelling at me
16:48dnolentechnomancy: some to me means - at least *one* such thing exists that satisfies a condition. but it's my bias.
16:48gfrlogdnolen: why not (any?)?
16:49dnolengfrlog: why not (exists?)?
16:49technomancygfrlog: as a predicate, any? is great
16:49technomancysome isn't a predicate though
16:49gfrlogI know
16:49gfrlogbut I've never used its output beyond its truthiness
16:50gfrlogand anyhow we may as well have both, if we're allowed sugary things like nnext
16:52technomancyyeah, you have to wonder how common non-predicate some usage is. I'd guess rare.
16:53gfrloglet's start a lib called c.c.mantle for all things that are inexplicably not in core
16:53dnolengfrlog: i fell like that nnext et al is there to make the code bearable up to the point that destructuring appears.
16:54technomancyeither that or to silence the people complaining about the loss of car/cdr
16:54gfrlogdnolen: okay, but I'm sure I could find some other strange functions in core
16:56dnolengfrlog: it would be entertaining to make a list of the most useless core fns.
16:57gfrlogyeah. It'd be highly relative though. My 3 minutes of thought say that it'd be worth swapping out mapcat for any?, if we have to remove something
16:58dnolengfrlog: no way, mapcat is great.
16:58gfrlog:-| I didn't say it wasn't great
16:58gfrloghalf the stuff in clojure.string and clojure.sets is great too
17:06gfrlog,(prn [[] '() #{} {} "" (keyword "") (symbol "") #""]
17:06clojurebotEOF while reading
17:06gfrlog,(prn [[] '() #{} {} "" (keyword "") (symbol "") #""])
17:06clojurebot[[] () #{} {} "" : #""]
17:12dnolenwell Clojure isn't the only one that struggle with names, Haskell chose Monoid over Appendable.
17:13hugodtechnomancy: so what do you use to get the first element that matches a predicate?
17:14technomancyhugod: I destructure a filter call. but that's not even what some does.
17:15hugod(some #(and (some-pred? %) %) col)
17:16technomancyyeah, I find filter+first or filter+destructuring much clearer
17:58technomancyso has anyone tried the lein search task yet?
17:58technomancyspoiler alert: it's pretty rad.
18:00dakronetechnomancy: hasn't been working for me
18:00dakronestill get Could not locate clucy/core__init.class or clucy/core.clj on classpath after installing it with lein plugin install
18:01technomancyhave you tried the one that's built-in now?
18:01gfrlogtechnomancy: my old version of lein doesn't have it. Why can't doesn't the future feature lein time-machine take care of this for me?
18:01gfrlogs/can't//
18:01sexpbot<gfrlog> technomancy: my old version of lein doesn't have it. Why doesn't the future feature lein time-machine take care of this for me?
18:02technomancygfrlog: don't worry; it'll be implemented in a future version
18:02gfrlogoh good
18:02dakronetechnomancy: I haven't run from git, so I don't have it
18:02technomancydakrone: ok, that should solve it
18:25dakronetechnomancy: works really well, thanks for this
18:29technomancydakrone: great
18:29technomancyI'm wondering if it should collapse all the different versions
18:30technomancyprobably not worth bothering with
18:30technomancyneed to add better pagination though
18:30dakronepipe it into $PAGER ?
18:31technomancyhmm... I wonder if there's a way to make that play nice with laziness on the clojure side =)
18:32technomancyas it is it takes a list of max results, so you can always just bump that way up
18:32technomancygood enough, I guess
18:33dakronenot too bad to lazily fetch pages it's not too bad: https://gist.github.com/843310
18:34dakroneexcuse my poor grammar typo there
18:37amalloytechnomancy: arriving late here, i guess, but "some" absolutely does not imply plurality
18:37amalloy"let x be some even integer. then it is true that x is divisible by two"
18:39gfrlogamalloy: clearly that is an exception, because I define it to be one.
18:39gfrlogamalloy: I quite like that example actually
18:39amalloygfrlog: that's where the name came from
18:40amalloywhat *I* think it implies is that (some even? (range)) should return 0, not true
18:40gfrlogokay, so you have some beef with it as well. just different beef.
18:40amalloyyeah
18:41gfrlogwhat should (some beef? [amalloy]) return?
18:42gfrlogthere was another poorly name function that we discussed but now I can't remember what it was
18:42gfrlogoh contains?
18:43gfrlogdo you have an explanation for that one?
18:45pyrhi
18:46gfrlogpyr: hi
18:46pyrdear lazyweb, is there a way to do 'mod' in clojure
18:46pyrnumerator works on a ratio
18:46pyrbut not on int's
18:47pyrso i could do the instance testing dance
18:47pyrbut there might be a faster way
18:47pyrthat i don't know of
18:47gfrlog$findfn 19 5 4
18:47sexpbot[clojure.core/rem clojure.core/mod clojure.core/unchecked-remainder]
18:47gfrlog,(rem 19 5)
18:47clojurebot4
18:47pyr:/
18:47gfrlognot what you meant?
18:47pyrok, thank
18:47pyrs
18:47pyryes, should've looked better
18:47pyrsorry
18:47gfrlogno prob
21:58zrilakIf I want to perform several update-in or assoc-in modifications of a map, should I just do (let [s1 (update-in s ...) s2 (assoc-in s1 ...) ...], or is there a "more Clojure" way?
21:59brehaut(-> s (update-in …) (associ-in …))
21:59zrilakah, THAT's what threading is for! :)
21:59zrilakthanks :)
22:00zrilakfacepalm
23:14gfrlog$findfn (constantly 5) 5
23:14sexpbot[clojure.core/trampoline]
23:24symboleCan swank-clojure work with SLIME from its original source, or does it depend on the version in the Marmalade repo?
23:24amalloysymbole: cvs trunk of slime is frequently broken or incompatible
23:26symboleProbably what's causing my problems.