#clojure logs

2011-02-14

00:26amalloychouser: i just got here but sexpbot seems to have been pretty quiet. what does he need to tell stu?
01:30simardwhy does (:bah #{:test 3, :bah "hey"}) return :bah instead of "hey" ?
01:30danlarkinyou've constructed a set
01:30danlarkinnot a hash map
01:30simardoh
01:31simardis there a syntactic sugar for that ?
01:31amalloysimard: drop the #
01:31amalloy&(map :bah [#{:bah 1} {:bah 1}])
01:31sexpbot⟹ (:bah 1)
01:33amalloyan amusing alternative, i guess, is ##((juxt #{:k 1} {:k 1}) :k)
01:33sexpbot⟹ [:k 1]
01:33hsaliakhello, if i need to generate a class that in which I need to override the super class's constructor, the only way to do this is via gen-class's :init right?
01:33simardnice, I'm a little confused about the keyword being a function though, is it the parser doing the work "as if" it were a function or is a keyword really a function ?
01:34amalloysimard: the latter
01:34amalloy&(instance? IFn :some-kw)
01:34sexpbotjava.lang.Exception: Unable to resolve symbol: IFn in this context
01:34amalloy&(instance? clojure.langIFn :some-kw)
01:34sexpbotjava.lang.ClassNotFoundException: clojure.langIFn
01:34amalloy&(instance? clojure.lang.IFn :some-kw)
01:34sexpbot⟹ true
01:35amalloysimard: evidence that the parser isn't doing magic: ##(let [k :keyword] (k {:k 10}))
01:35sexpbot⟹ nil
01:35amalloysimard: evidence that the parser isn't doing magic: ##(let [k :keyword] (k {:keyword 10}))
01:35sexpbot⟹ 10
01:36hsaliakproxy has no access to super, and it looks like deftype/defrecord only work on interfaces.
01:37amalloyhsaliak: what. you don't "override" a constructor. you provide your own constructor that calls the superclass constructor, and proxy lets you supply whatever args you want to super()
01:42hsaliakamalloy, what if i want to do further initialization code after calling the superclass's constructor? As you would in a normal java subclass constructor
01:44amalloyhsaliak: an init function of some kind seems right to me, but i dunno. i don't think this is the sort of java that clojure is very good at writing
01:47hsaliakamalloy, I feel the same way too, maybe i need to have another look at how to structure this in a way that's better suited to clojure
02:11khaliGis there a way to initialise a struct using a map?
02:22amalloykhaliG: just use an actual map. what benefits are structs giving you, if you're initializing them from a map and don't know which keys you'll be supplying?
02:37khaliGamalloy, that thought occured to me too..
02:41khaliGamalloy, i do know what keys i a going to supplying though, it's just i'm reading a slurped form which throws away the struct info so i've to recreate it from just a map
02:43amalloykhaliG: ##(doc struct-map)
02:43sexpbot⟹ "([s & inits]); Returns a new structmap instance with the keys of the structure-basis. keyvals may contain all, some or none of the basis keys - where values are not supplied they will default to nil. keyvals can also contain keys not in the basis."
02:43amalloykhaliG: ##(doc struct-map)
02:43sexpbot⟹ "([s & inits]); Returns a new structmap instance with the keys of the structure-basis. keyvals may contain all, some or none of the basis keys - where values are not supplied they will default to nil. keyvals can also contain keys not in the basis."
02:47khaliGalmost but not quite
02:47khaliGbecause i have a map
02:49khaliGie (struct-map my-struct-type {:boom 4 :bar 4}) not (struct-map my-struct-type :boom 4 :bar 4)
02:50amalloykhaliG: apply
02:50khaliGtried using apply
02:51amalloyah, but it thinks it's a seq of pairs, not a plain list
02:51khaliGyep
02:51amalloy(apply struct-map my-struct (apply concat {...}))?
02:52khaliGlets see
02:52khaliGthat works!
02:55amalloyindeed, though yuck :)
02:56Scriptorhey everyone, so I've been reading through http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii/
02:57Scriptorfrom the explanation, it makes it sound like a new root node+path is created with each assoc
02:57Scriptoreg: when assoc'ing a new key-value pairing, it finds the appropriate node, copies it and adds the pairing to its array
02:58Scriptorand then it copies each parent on the way back up
02:58Scriptorjust wanted to make sure I got the idea right
03:00khaliGamalloy, so after all that, it prints the exact same thing in the repl. I wonder if it is the same thing really :/
03:01amalloykhaliG: structs print as maps, iirc. but if you check (class ...) it should be structmap rather than hashmap
03:01khaliGah i see
03:01amalloyScriptor: yeah that sounds accurate to me
03:02amalloyignoring what happens if the appropriate node is full
03:02Scriptorright
03:03Scriptornow to implement that
03:06amalloyScriptor: writing a version for another language, or for educational purposes?
03:06Scriptoramalloy: another language
03:06amalloycool. which?
03:06ScriptorPHP...:p
03:09Scriptormy main concern is that while Java probably optimizes all the copying pretty well (it's just references after all)
03:09ScriptorI'm not as confident about the zend engine
03:09amalloyScriptor: you can try fairly hard to make php use references
03:10Scriptorright, &$var, but I've seen a few things about PHP's references being slow for some reason
03:10Scriptorhaven't looked into it much
03:11amalloyhm
03:11amalloyi've only read a bit of the php source, but if you want me to look into something in particular let me know
03:12Scriptoramalloy: great, I'll hopefully be getting into the gritty details soon
03:14Scriptorquick question, do java arrays have to be explicitly converted to a seq if you wanted to use them as such?
03:15amalloy&(map inc (int-array [1]))
03:15sexpbot⟹ (2)
03:15amalloylooks like no
03:16Scriptor&(first (int-array [1]))
03:16sexpbot⟹ 1
03:17Scriptor&(rest (int-array [1 2 3]))
03:17sexpbot⟹ (2 3)
03:17amalloyScriptor: just in case i've trained sexpbot to lie when i ask him a question? :)
03:18Scriptoramalloy: well, map could've been calling (seq) internally :)
03:18amalloyScriptor: it's calling first and rest internally, i expect
03:19Scriptorright, and I just checked the source for first
03:20Scriptorwhat exactly is clojure.lang.RT?
03:20amalloyScriptor: the runtime supporting language-level stuff
03:20Scriptorah, runtime
03:22Scriptorah, here we go: ISeq seq = seq(x);
03:22Scriptorfrom the source for first(), looks like it *does* call seq
03:23amalloyindeed
03:24amalloymost of the basic sequence functions act on seqs
03:24raekall the fns that operate on sequences (has a 'coll' param) usually call seq on the argument
03:26Scriptoryep, but unless it's always lazy, I'd imagine looping through a sequence by constantly calling first/rest would have a large overhead, right?
03:26Null-AWhen I call read-line in the repl, it always returns nil
03:26Null-Ai can't figure out a way to get console input more generally
03:26Scriptorsince it'd be converted to some seq for each call
03:27amalloyScriptor: no
03:27amalloy(seq some-seq) returns some-seq
03:27Scriptoroh, right
03:27Scriptorthe meat of the conversion is only done once
03:27amalloy&(let [x (seq (range 10))] (identical? x (seq x)))
03:27sexpbot⟹ true
03:30raekyes. an element of a lazy-seq is only forced once.
03:31amalloyraek: i don't think laziness/forcing are related to Scriptor's issue. if a lazy-seq created a new data structure every time you forced it, even if it didn't recompute the element, that would be inefficient
03:32raeka question of allocation, I see
03:33Scriptorraek: just had a mental slip-up, (rest (rest (int-array [1 2 3]))) would only convert the array to a sequence for the first call of rest
03:33rata_Null-A: in which repl are you calling read-line?
03:34Null-Arata_: actually, it works in the repl, but not in swank server repl
03:34Null-Arata_: slime repl*
03:34raekScriptor: yes
03:34Null-Arata_: also lein run, have read-line returning nil always
03:34Null-Arata_: lein repl works
03:35rata_Null-A: yes... it doesn't work for me either, but swank repl is weird in some senses
03:35Null-Ai think lein run is just broken
03:35Null-Ai've had so many problem with it
03:35rata_don't use it then ;)
03:35amalloyslime does funny business with the repl. you'll never get console input through it
03:36rata_I've had issues with threads in swank repl too
03:36raekthe "conversion" wouldn't be a heavy operation though, since it will just create one of these: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ArraySeq.java#L55
03:37raek(without optimizations for primitives, an element of an array seq could be described as a (array, index) pair)
03:41amalloythe code duplication in those primitive optimizations make me sick. let me know when java supports treating primitives like objects :P
03:45raekhomoiconism ftw!
03:46khaliGyea i've noticed if i print something in my clojure code it wont show up in the repl, something to do with threading?
03:46Scriptorprimitives as objects would be a start :)
03:57rata_amalloy_: .NET has primitives as objects, doesn't it?
03:57brehautit has value types that look a bit object like
03:57brehautand it has autoboxing
03:58rata_khaliG: it should show up, unless you're printing from a thread
03:58khaliGguess so
03:58khaliGits from the swing thread
03:58khaliGit's annoying because i cant print debugging info out to the repl
03:58brehautrata_: http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx
03:59rata_khaliG: yes, it is... that cost me two hours some days ago searching for a bug in a swing app
03:59brehautrata_: eric lippert's blog is a gold mine of 'how C#/.net actually does thing'
04:00rata_*costed
04:00rata_thanks brehaut, I'll read it
04:00TobiasRaedermorning
04:01ejacksonHello
04:07raekkhaliG: (alter-var-root #'*out* (constantly *out*))
04:08raekdo that in your slime repl, and that repl will be the default *out* for clojure
04:08khaliGraek, oh wow, thats sweet!
04:08khaliGany downside to doing this?
04:08rata_yes, I didn't know that
04:08raekby default, *out* is bound to the slime repl only for the repl thread (you can actually have multiple repls)
04:08khaliGi see
04:09raekyou lose the reference to the original *out*
04:09raeki.e. the one connected to the swank terminal
04:09raekbut that's no big deal, I guess.
04:10khaliGnod
04:10khaliGsounds like it's harmless
04:11raekyou can also use bound-fn and bound-fn* to let a function remember the *out* value. (if it is invoked in another thread, it will use its remembered values)
04:13rata_raek: and do you know how to let exceptions thrown in thread to appear in the swank?
04:13rata_*in other threads
04:14khaliGraek, good question
04:14khaliGi get a lot of these silent exceptions thrown that i never find otu about, except to know something is wrong
04:14khaliGrata_, even
04:15raekrata_: put a (try your-code (catch Throwable e handle-in-some-way)) in the code
04:15khaliGat the top level?
04:16rata_raek: that's in the case I'd know that an exception is being thrown, but some times you don't know
04:16rata_it just doesn't work
04:16raekat the top level of the code you run in another thread
04:17raek(def handle-in-some-way (bound-fn [e] (.printStackTrace e *out*)))
04:17raekor just skip the bound-fn part if you set the root value
04:18raekto be certain, you should have something like this in all your calls that run in other threads
04:19rata_well, it's not a magic solution like the other one
04:20raekfutures have a default solution built in
04:20raekwhen you dereference them, they will throw the exception wrapped as the cause of a ExecutionException
04:23raek,(let [f (future (throw (Exception. foo)))] f)
04:23clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
04:23raek,(let [f (future (throw (Exception. "foo")))] f)
04:23clojurebot#<core$future_call$reify__5500@1c8b313: :pending>
04:23raek,(let [f (future (throw (Exception. "foo")))] @f)
04:23clojurebotjava.util.concurrent.ExecutionException: java.lang.Exception: foo
04:24rata_I need to sleep... see you tomorrow guys
04:24raekfutures are a great way of checking "you know that thing I wanted you to do in another thread, how did it go?"
04:24raekrata_: good night
04:24rata_yes, futures are great... I just forgot to deref them last time
04:24rata_good night
04:25rata_(I didn't deref them because I didn't care about the return value, just the side-effects)
04:26khaliGi've been meaning to check out out futures but haven't had a use case for them yet
04:29raekkhaliG: <shamelessPlug> http://blog.raek.se/2011/01/24/executors-in-clojure/ </shamelessPlug>
05:11mattdwanyone seen a problem where 'lein compile' hangs/never exits?
05:12mattdw(it also happens during jar and uberjar, but I suspect that's still the compile step)
05:18raekmattdw: watch out for code with side-effect at the top level of your namespaces (e.g. code that starts a web server)
05:19raekideally, only code that results in defs should be at the top level
05:20mattdwah I'll bet that's it
05:20mattdwit's a def, but it's a web server ;)
05:21mattdwperfect, thanks raek
05:21raek(you can also put that code in a function called -main and use genclass or lein run)
05:22mattdwyeah, I had -main, but I was deffing the server at the top-level
05:25khaliGraek, cool article, i just finished going through it :)
05:28TobiasRaederare there any new openid libraries for clojure i just missed? (just found jopenid and openid4java which both seem ... not that nice)
06:17ejacksonWas any way discovered of attaching messages to :pre and :post assertion errors ?
06:25khaliGhm i'd like to produce a vector using the FOR form..
06:28AWizzArdkhaliG: for is LIST comprehension.
06:29AWizzArdYou could go with reduce
06:29khaliGok, i'll read on reduce, cheers
06:29AWizzArd,(reduce #(conj %1 (+ %2 1000)) (vector-of :int) (range 20))
06:29clojurebot[1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...]
06:30AWizzArdInstead of (vector-of :int) you can of course also just say: []
06:33ChousukeI think you should prefer into to reduce
06:33Chousuke,(into [] (for ...))
06:33clojurebotjava.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$for
06:33Chousukeoops, didn't mean to put the , there :)
06:33bsteuber(why not just (vec (for ...))
06:33Chousukethat works too
06:33ChousukeI tend to forget vec exists :P
06:37khaliG:)
06:39AWizzArdThe nice thing about reduce is that it will not consume too much memory.
06:39Chousukeit'll consume more than into :/
06:39Chousukesince it creates the intermediate vectors
06:39AWizzArdYou think?
06:39AWizzArdAh ok
06:39Chousukeyeah, it's slower than into, because into uses a transient
06:40Chousukevec does too I guess.
06:40AWizzArdHmm, in principle vec could/should be the most efficient way, yes.
09:04TimMctechnomancy: Any way to turn off warn-on-reflection for lein repl? Whenever I start it, I get a bunch of reflection warnings for dev or repl code.
09:05TimMc(Alternatively, a way to turn it on just for lein compile/run.)
09:28AWizzArdTimMc: the best solution would be to type hint those modules and really eliminate the reflection warnings that way.
09:29TimMcAWizzArd: I type hint my own code. The problem is some dev-dependencies or some such.
09:34khaliGis there a nice clojure way of doing this: if (method. getName) returns nil use "Text" otherwise whatever the method returns
09:34AWizzArdkhaliG: maybe if-let
09:35AWizzArd,[(if-let [x nil] :a :b), (if-let [x 5] :a :b)]
09:35clojurebot[:b :a]
09:35raekkhaliG: there's a really neat clojure function called 'fnil'
09:36khaliGthat sounds like what i'm after! :)
09:36raekit returns a new function like the one you pass it, but lets you "patch" what happens when you *pass* the function nils
09:36raekso maybe it was not what you were looking for anyway
09:37khaliGooh
09:37khaliGyea doesn't sound like it
09:37raekkhaliG: (or code-that-mgith-return-nil replacement-value)
09:38khaliGi like it, thank you
09:39TimMckhaliG: What if the function returns false, do you still want the return value?
09:40khaliGTimMc, well it will be nil or a text, im sure of that
09:40TimMcOK, then you'll be fine.
09:41khaliGsomethign like this (or (.getName table-model) "Exercise"))
09:44khaliGone thing i really miss from Netbeans/enclojure in slime is who-calls a function
09:45raekkhaliG: from swank-clojure readme: C-c C-w c: List all callers of a given function
09:46khaliGdoes that call slime-who-calls? that doesnt seem to work for me
09:46khaliG"error in process filter: Wrong type argument: char-or-string-p, nil"
09:46khaliGanyway it's not the end of the world
09:50raekcould perhaps be new to the 1.3.0-SNAPSHOT swank-clojure version
09:50raekor it requires some specific slime version
10:46TobiasRaederanyone knows how to create a route in compojure which accesses a value from the path i.e. /somepath/:id and the complete request object?
10:54raekTobiasRaeder: see Destructuring the request section at https://github.com/weavejester/compojure/wiki/Routes-In-Detail
10:55raeklooks like the path variables gets added to :params
10:56TobiasRaeder@raek that would make sense, i will check it out. thanks
11:07TobiasRaeder@raek works like a charm, tyvm
11:40mattmitchellanyone know of any existing code to do a batch insert with the clojure.contrib.sql lib?
11:50ejacksonmattmitchell: no - I was looking for exactly that a while back.
11:51mattmitchellejackson: yeah i'm thinking about writing to a file and executing LOAD DATA INFILE instead
11:51ejacksonmattmitchell: yes, that is actually often the fastest way :) !
11:52ejacksonis ugly as sin though
11:52mattmitchellejackson: yes :)
12:06jcromartiehi all
12:07jcromartieI'm revisiting this idea of a hash with history... where assocs and dissocs are done with a timestamp, and I'm wondering: why use a hash at all?
12:07jcromartieby hash I mean hash-map
12:07jcromartieWhy not just a seq of times and values
12:08technomancyTimMc: you could set it to false in :repl-init-script maybe
12:09AWizzArdjcromartie: {ts1 va1, ts2 val2, ...} vs [ts1, val1, ts2, val2, ...]?
12:10jcromartieAWizzArd: no, not quite... the idea is a document (hash-map) stored as a sequence of values
12:10dnolenjcromartie: why not a vector of hash-maps states and use a zipper to navigate the different states?
12:10jcromartiezipper, eh
12:11jcromartieI might be over engineering this anyway, since the system will likely just use a RDBMS to store these documents anyway
12:11AWizzArdjcromartie: I don't really understand. You said: "Why not just a seq of times and values" which sounded like: I want no map but a seq. But now you want a map again?
12:11jcromartiesorry let me clarify
12:12jcromartieI started out wanting a hash-map to represent a "business object" type of "document" that had a history of values
12:12jcromartielike, an invoice
12:13AWizzArdSounds okay so far.
12:14jcromartieso each version of the document is associated with a timestamp, and I made an interface that acts like assoc but also stores a timestamp, and allows you to grab the value at points in time
12:14jcromartieso this is designed for assoc-style modification
12:15AWizzArdIf you use a sorted-map then you can even say: "Computer, give me all events that occured between t1 and t2".
12:15AWizzArdsubseq
12:15jcromartieyeah
12:15jcromartiebut what I'm thinking is some kind of general purpose ref-like object that lets me do that with anything, like a number or a string
12:15jcromartieso basically a ref but with history
12:16jcromartieand it would be great if I could use @ or deref and some simple way to modify it
12:16jcromartiebut I guess the question is: is this over thinking it
12:16jcromartieit seems useful
12:17chouserjcromartie: I think it's a value, not an identity
12:17chouserand as such could be stored in whichever reference object makes sense (atom, ref, etc.)
12:18jcromartieso then maybe it's better to just build on a ref
12:21chouserWell, idependant of ref. Something more like assoc than like swap!
12:22dnolenjcromartie: to me a sorted-set with it's values sorted on timestamp seems ideal, (conj doc-timeline doc)
12:22jcromartieyeah
12:22jcromartiebut it all goes down the tubes when the database gets involved anyway
12:22jcromartieso... :(
12:22dnolenjcromartie: I don't see why.
12:23jcromartieat least, that's my experience with interfacing with a DB
12:24dnolenjcromartie: what do you see as the issue here?
12:24jcromartielet's say I have a million documents, with ten versions each
12:24jcromartieI don't want to manage that across Clojure and the DB
12:25jcromartiebut maybe it could load lazily on dereferencing some version that only represents the "current" value
12:25dnolenjcromartie: still unclear, what is there to manage that's any different from any other DB + programming language ?
12:25jcromartiewell, because it's not just the current state of an object
12:26jcromartieunless the documents (just an ID) are in one table and the changes over time (including the implicit latest) are in another table
12:26pdloganjcromartie: here's some food for thought re: values with history... both PDFs unfortunately...
12:26jcromartiethat might make more sense
12:26pdloganhillside.net/plop/plop98/final_submissions/P63.pdf
12:26jcromartie:P
12:26chouserjcromartie: https://gist.github.com/826197
12:27pdloganwww.manfred-lange.com/publications/TimeTravel.pdf
12:27chouserjust as a thought
12:27jcromartieVery nice, chouser
12:27chouserplease excuse the underscore
12:28jcromartieIn the end, I want to eliminate the accidental state
12:28jcromartiewe handle invoices, and currently have lots of highly denormalized state
12:28jcromartiethere are lots of "states" within the state, like we talk about "what state is the bill in"
12:29jcromartieand that is always, invariably, a real mess
12:30jcromartieand even then, we don't store ENOUGH state!
12:30jcromartieso the history is what really matters
12:36jcromartiethanks for the papers, pdlogan
12:37jcromartieoh look, Smalltalk :)
12:37jcromartie<3
12:37pdlogan(yep - some good ideas still hidden in the Smalltalk world)
12:38jcromartieI really like Pharo and Seaside. I wish there was something as nice as Seaside for building web apps in Clojure... I'm toying with stateful components in compojure
12:38jcromartiebut it's still nothing like the control flow that Seaside gives you
12:39jcromartiebut even Avi Bryant, who wrote Seaside, admits that the future is in fully client-side UI with server-side controllers and storage
12:40pdloganjcromartie: yeah, and so we wish there were something as good at control flow... for javascript!
12:41jcromartieenter Clamato: http://clamato.net/
12:41jcromartieby Avi :)
12:41pdloganbtw re: seaside, there are similar systems for CL and Scheme that could apply to clojure, e.g. http://double.co.nz/scheme/modal-web-server.html
12:41jcromartiebut still very beta
12:41jcromartieI have a hard time getting my head around making the server wait across HTTP requests
12:41jcromartiebecause it's just so updside-down
12:42jcromartienot just the server waiting, but one block of code waiting for the next HTTP request
12:43jcromartieI bet a macro for web app control flow would go a long way
12:43pdlogan"waiting across requests" amounts to hashing a closures and the hash keys round-trips to the browser associated with various URLs.
12:43pdlogan(and I apparently need coffee)
12:44pdloganre: macros, yes... see http://www.paulgraham.com/vwfaq.html
12:45jcromartieyay
12:45jcromartiemacros FTW
13:10TobiasRaederanyone knows a java/clojure http client that doesn't use a java.net.URI? i need to make a get request to a url containing |
13:12jcromartiehave you tried encoding the pipe as %7C?
13:12TobiasRaederyeah then facebook complains the code is supposedly wrong
13:16jcromartiewhere is the |
13:16jcromartiein a parameter value? anchor part?
13:18TobiasRaederparameter value
13:24jcromartieand what does your final encoded URL look like?
13:35khaliGanyone familiar with clj-time? i'm wondering if there is a way to find the number of days in a month from clj-time or do you need to go into jodatime for that
13:44ejacksonkhaliG: don't see it directly. But you can construct and interval over the month easily using the fact that interval is open on the right. Then just use in-secs and divide by (* 60 60 24) ?
13:45khaliGsounds like a good idea, was just doing that atm
13:45ejackson:)
14:07amalloyejackson: a time library that makes you (/ x 60 60 24) yourself seems kinda misguided
14:08ejacksonyou're right, i'm sure there's a better way to do that
14:08ejacksoni just didn't happen to know off hand
14:08amalloyAWizzArd: oh neat, i didn't know about vector-of
14:09ejacksonamalloy: it would be trivial to do the same thing as I suggested to get the magic number
14:10ejackson(let [magic-number (in-secs (interval today tomorrow)] ...)
14:11amalloyhah
14:12kjeldahlI think I figured out why my ring wrap-reload with enlive deftemplate wasn't reloading when I changed the underlying template (html) file.
14:12kjeldahlAvoid gen-class. Found a clue here: http://stackoverflow.com/questions/3902545/force-clojure-reload
14:13amalloyejackson: and i'm not really in a good position to criticize: i'm responsible for the last code snippet of the uuid section of http://wiki.apache.org/cassandra/FAQ#working_with_timeuuid_in_java
14:14ejacksonoooh magic number kabuki fest
14:14ejackson:)
14:14amalloyi like that it ends with COOOOOOL
14:14ejacksonlol
14:15ejacksoni like: 0x01b21dd213814000L
14:15amalloyyeah, that's the disgusting part
14:15amalloybut it's 100% correct, so who am i to argue
14:16amalloyi'll try to find an excuse to use graham's number in a clojure program
14:16ejacksontoo right
14:26albertidanyone from clj-sandbox arround?
14:35amalloyalbertid: no, but i've written ~1/2 of clojail, which is another sandboxing lib
14:39albertidah, didn't know that one, looks nice too
14:41amalloyalbertid: so feel free to switch, or if you have general sandboxing questions i may be able to help
14:41amalloyi think Licenser is responsible for clj-sandbox, but i'm not sure
14:42scode_I have a macro that generates multiple top-level forms (it's a defmy-type-of-test which autogenerates deftest:s). What is the idiomatic way to do so? I did `(let [] ,@(...)) but the "useless" let feels ugly.
14:42dnolenscode_: you have do
14:43dnolen(do ...)
14:43scode_Ah. That feels cleaner.
14:43scode_Thanks :)
14:46amalloyscode_: it's not just cleaner, it's more correct. iirc (do a b c) causes each arg to be compiled after the previous is run, while (let [] a b c) compiles them all then runs them all
14:47amalloy(i believe this is only true at the actual top level, so if you were doing this in a function instead of a macro it probably wouldn't matter)
14:47scode_I was about to ask about that since normally all is compiled first, but right - the top-level is special.
14:47scode_Subtle difference there.
14:48amalloyyes, it can matter if a is a macro that b depends on
14:48amalloyor probably for other reasons as well but i don't know what they are :P
14:48scode_:)
15:13apexi200sxmsg NickServ identify gasher
16:09arkhto do a simple HTTP GET, one can do the following: (slurp (URL. "http://www.google.com&quot;)). Is there something equivalent/similar for POST?
16:10arkhhere's the simplest thing I have so far: (slurp (.getInputStream (doto (.openConnection (URL. "http://www.google.com&quot;)) (.setRequestMethod "POST"))))
16:12jcromartiearkh: it doesn't really matter how simple it is if you can put it in a function, is it?
16:12jcromartieerr, does it
16:14arkhYou're right - I think I just wanted to make sure I wasn't missing something in the libraries. It would be like using (with-open ...) if slurp could do the job just fine.
16:15arkhor, a more harsh example would be driving file io from java when with-open is available.
16:15brehautarkh your best choice for all http is the clj-http library
16:17arkhhmm ... it's more than what I need but maybe I'll use that
16:17rata_hi
16:19brehautmorning rata_
16:20rata_hello brehaut
16:22ohpauleezdnolen: Nice quick post, and thanks for linking to that paper
16:28TimMctechnomancy: :repl-init-script doesn't help -- the reflection warnings come from Lein or something.
16:31dnolenohpauleez: np, a good read. Clojure agents, which always have confused me, seem particularly well suited to this style of computation.
16:32ohpauleezawesome!
16:50technomancyTimMc: ok, go ahead and create an issue for that then
16:51technomancyif you can provide a patch I will send you an official leiningen sticker, otherwise I'll try to get to it before 1.5.0
17:51kencauseyIs the status of PersistentQueue about the same in 1.3 as in 1.2? i.e. use clojure.lang.PersistentQueue/EMPTY as the foundation?
18:13TimMctechnomancy: Haha, cool.
18:13scode_What is the idiomatic way to do constructors with deftype? Do you just defined a function that initializes an instance?
18:15rata_scode_: I'd think so
18:15scode_Ok. So i'm not missing some way of directly hooking up a constructor with deftype itself?
18:22dnolenscode_: there was some talk about that, but rhickey had modularity concerns, so nothing was decided upon.
18:22scode_Ok. Thanks.
18:23amalloyscode_: i don't think so. and it's fairly painless to call the init function yourself: (doto (MyObj.) (.init args))
18:24pdk(doc doto)
18:24clojurebot"([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"
18:25scode_amalloy: Sure, just trying to be idiomatic. :)
18:45AWizzArdamalloy: yes, it is now one year old but seems to still be secret, though it is indeed useful (efficient and documentation of code).
18:55TimMcAha, get-in has different behavior from assoc-in and update-in when a zero-length keys collection is passed in.
18:55TimMc,(get-in {:foo [4 {:bar 5}]} [])
18:55clojurebot{:foo [4 {:bar 5}]}
18:56TimMc,(update-in {:foo [4 {:bar 5}]} [] identity)
18:56clojurebot{nil nil, :foo [4 {:bar 5}]}
19:00amalloyTimMc: i imagine get-in is implemented as (reduce get m ks), while update-in is implemented as (assoc m (first ks) (some-recursive-call))
19:01amalloy$source get-in
19:01sexpbotget-in is http://is.gd/BqhsBt
19:01TimMcbingo
19:02TimMcI understand the differences in their behavior -- it comes down to implementation -- but I'd like them to not have surprising behavior in the base case.
19:03amalloyhm. assoc-in could use a quick refactor, to (assoc m k (if ks ...))
19:05TimMcI'll just make some helper functions for my own project, but out of curiosity, how would that get changed in Clojure? That is, who decides?
19:07TimMcIs Hickey the benevolent dictator, or is it a sort of committee?
19:13amalloyTimMc: mostly rich, but the core team has influence
19:44simardaren't integers supposed not to overflow ? (ie.: (* 1000000000 100000000000000000)
19:45brehautit depends
19:46brehauti would expect a default big integer not to
19:46simarddoesn't look like it's defaulting to big integer here
19:47brehautwhat version?
19:47simardhum svn 1.3.0
19:47simardgit that is
19:47brehautthere you go then
19:47simardor is it
19:47companion_cube,(* 1000000000 100000000000000000)
19:47clojurebotjava.lang.ExceptionInInitializerError
19:47brehaut*clojure-version* will tell you
19:47simardso what do I need
19:47companion_cube,(* 1000000000 100000000000000000L)
19:47clojurebotInvalid number: 100000000000000000L
19:47simardyeah it's 1.3.0
19:47brehautsimard: if you dont know what is in 1.3 you should be using 1.2
19:48brehaut1.2 is stable
19:48simardI see..
19:48brehaut1.3 has very significant changes to the numerics support
19:48simardwhy did I do that update anyway
19:48brehautin particularit defaults to primative integers with error-on-overflowing operations
19:48brehautand bigints as an option
19:49brehaut,*clojure-version*
19:49clojurebot{:major 1, :minor 2, :incremental 0, :qualifier ""}
19:50brehaut,(* 1000000000 100000000000000000)
19:50clojurebotjava.lang.ExceptionInInitializerError
19:51simardok fixed, thahnks
19:51simardjust a question thought, what's the rationale behind that change ? am I gonna have to "unlearn" stuff whenever 1.4.0 comes out ?
19:52brehautsimard: the TL;DR omiting heaps of vital context version: performance is a priority
19:53simardtalking about performance, how does clojure compare to "other languages" ?
19:53brehautit depends
19:53simardis it as slow as python ? :)
19:53brehautno
19:53simardgood
19:53brehautit is possible to be as fast as java
19:54brehautin 1.2 this requires some fairly unidiomatic code
19:54brehautin 1.3 that is much less so
19:54simardI see, well I have to agree with performance being a priority then
19:55simardit's fun to have a nice language to play with... but not at all cost
19:55brehautand re:breaking changes i believe 1.3s primatives changes are the first real breaking change in the language
19:55brehautin 3ish years
19:58technomancy^ changing from meta to meaning #^
19:58technomancy(which was a really good change)
19:59brehautthe lazy-seq change was pre 1.0?
19:59technomancyyeah, and also the moving of package nesting levels (clojure.clj -> clojure/core.clj)
20:00technomancyancient history
20:00pdk`hm
20:00pdk`can we expect existing code that doesn't worry about type hints or java interop to work in 1.3
20:00pdk`just with all our formerly autoboxed numbers being direct primitives
20:01brehautdepends if they are going to overflow ;)
20:01technomancythere are also binding changes
20:07jkdufairi'm using clj-json to serialize clojure objects to json, but need to represent the metadata also, probably including the classname of objects. has anyone done anything like this?
20:09TimMcI don't suppose there's a function like map that takes 2 elements from the input list at a time?
20:10brehaut,(map identity (partition 2 (range 10)))
20:10clojurebot((0 1) (2 3) (4 5) (6 7) (8 9))
20:10TimMcAha, partition...
20:10TimMcThanks, brehaut.
20:12technomancyclojurebot: partition
20:12clojurebotExcuse me?
20:12technomancyclojurebot: partition is probably not what you want; see partition-all.
20:12clojurebotIn Ordnung
20:12technomancyTimMc: ^^
20:14TimMctechnomancy: I think I'm fine. I do a check for even-length collection ahead of time, which is a requirement for the input.
20:14technomancyoh, ok. it's just a naming mistake that trips up a lot of people... too late to fix in Clojure unfortunately.
20:20fdaoudtrying to load a namespace with a dynamic name using (use). it works if the ns exists. I want to return nil if it does not exist. right now I catch the FileNotFoundException. Is there a cleaner way?
20:21fdaoudI thought find-ns would work but it returns nil even if the name is valid.
20:35pdk`this is unique
20:36pdk`i got a project that crashes immediately with a null pointer doing lein run
20:36pdk`but runs fine with lein repl
20:36pdk`main- works too
20:40TimMcpdk`: What happens if you do lein compile?
20:40TimMc(I have no idea what the result would mean either way.)
20:41pdk`returns no errors
20:41pdk`for some reason
20:41pdk`the project name has a dash
20:41pdk`but lein put an underscore in its place in src\project-name
20:42pdk`that and i'm still having these fn issues with irclj
20:42TimMcI think that's standard.
20:42pdk`keep getting "no text to send" if i try to use send-message for an :on-join event handler in fnmap
21:02TimMcpdk`: Is the NullPointerException in your code or somewhere in lein?
21:03pdk`i'll try again
21:03pdk`the message itself is less than helpful
21:03pdk`it's at NO_SOURCE_FILE:1 which is just awesome
21:03pdk`"at clojure.lang.Compiler.eval etc etc"
21:04pdk`and i'm still pondering why tf i can't send messages to channels with irclj
21:04pdk`it just goes NO TEXT TO SEND LOL if i use send-message
21:04pdk`granted this is inside an :on-join method for the fnmap being passed to create-irc
21:13pdk`criminy
21:13pdk`even if i stick a sleep in there it still cant send the msg
21:17tomojdon't think anyone's likely to be able to help without code
21:47TimMcSo, I've got this graphical application. Should I have one global (def *state* (ref ...)) that is nested maps, or a bunch of def'd refs instead?
21:48TimMcA bunch of them need to see each other -- some are GUI components with event handlers that mutate state and each other.
21:52TimMcThe global structured object incurs more verbose code in order to access the parts.
21:54simardhow do I get the definition of a keyword ? say.. :test
21:54simardie.. the function associated to it
21:54brehautTimMc: it depends on how you need to access stuff. if you have one big ass map (which is fine), but need to change two parts at once from different places, you need to break it down.
21:54brehautsimard: in what respect?
21:55simardwell I was told (I believe) that the reason you could do (:test {... :test 4
21:55simardwas because :test was a function
21:55brehautit is
21:55simardhow do I get its body
21:55brehaut,(ifn? :keyword)
21:55clojurebottrue
21:55brehautyou dont
21:55simardhum
21:55brehauta function is anything that implements the iFn interface
21:55brehautfrinstance ##(ifn? {})
21:55sexpbot⟹ true
21:56brehaut,(ifn? 1)
21:56clojurebotfalse
21:56brehautso clearly maps are functions but numbers arent
21:56simardifn then..
21:57brehautyou cant 'get the function' for it, it _is_ the function
21:57rata_simard: a keyword just search for itself in the set or map you give to it and returns the associated value
21:57brehautsimard: you can however use get
21:57TimMcsimard: Clojure expands the notion of "function" beyond just lambdas.
21:58simardso that ifn interface, must define some... functions to implement
21:58TimMcA map is a function of keys to their values. A keyword is a function of maps (and records and structs...) to the value at that keyword.
21:58rata_raek: ping?
21:59brehautsimard: for keyword its probably some java code
21:59TimMc$source Keyword
21:59sexpbotSource not found.
21:59TimMcWorth a try. :-P
22:00TimMcANyway, it is clojure.lang.Keyword.
22:00simardok so it's java defined, good enough
22:00TimMcsimard: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java
22:00brehauthttps://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/Keyword.java#L104-217
22:01simardhehe
22:01brehautits more complicated than that though
22:01brehautkeywords have a callsite cache
22:01brehautto improve performance when used on records
22:01brehaut(frinstance)
22:02brehautif you want a lookup function then you have 'get'
22:02brehaut,(get {:a 1} :a)
22:02clojurebot1
22:02brehautit performs exactly like a keyword, so its useless there
22:03brehaut,[(get {:a 1} :b 2) (:b {:a 1} 2)]
22:03clojurebot[2 2]
22:03brehautbut if you have non-objectish maps you'll need it
22:03simard,(:sdfg {:sdfg32 54} 6)
22:03clojurebot6
22:09TimMcbrehaut: I think I'll go for a mixed approach for now, leaving GUI components as defs (so they can see each other) and consolidating actual state into maps and records.
22:12brehautoh right
22:12brehautsorry yeah, keep your non-data stuff out of your data
22:22TimMcah, OK
22:22TimMcThat makes more sense now.
22:23brehautTimMc, as long as you are aware that its making a singleton UI ?
22:26simardwhat should I read as an advanced "tutorial" for clojure ?
22:26simardcould be a program..
22:28amalloysimard: hard to say, if you aren't specific on what an "advanced tutorial" means. maybe you want a particular topic, or what? otherwise just grab a random project from github
22:31simardhum I'd like to see some heavy macro language...
22:31simardby heavy I mean, using macros to create a language atop of clojure
22:31simardas is typical of lisp
22:31brehautsimard: thats not idiomatic clojure
22:31simarddamn
22:31amalloybrehaut is right
22:32brehaut'DSLs' are 95% composable functions and clj data literals
22:32brehautoccasionally sprinkled with macros for convinence at the end
22:32simarddsl ?
22:33brehautdomain specific language: ie a mini-language created ontop of a host language
22:33brehautbut. see: https://github.com/cgrand/enlive https://github.com/cgrand/moustache and https://github.com/cgrand/regex for examples of them
22:34brehautregex is the simplest and there is at least some slides around explaining the process
22:35brehautslides in question: http://vrac.cgrand.net/DSL.pdf
22:35simardso when you say "not idiomatic"... you mean.. discouraged, by what/who ?
22:35amalloysimard: discouraged because they're not composable. you have to use them exactly as the designer planned
22:35amalloyyou can't map over them, etc
22:37simard"Do you spot a pattern?" hahaha
22:38brehautthe associated video http://blip.tv/file/4522250
22:39simardwhat IDE do you use
22:39simardemacs ?
22:39amalloyyes
22:39brehautyes
22:39brehautive also used eclipse with counterclockwise and its good too, but way heavier and im not a java person
22:39simardthat's of course funny
22:39simard:)
22:40brehautim not sure why?
22:40simardwell because clojure runs on java..
22:40simardso do you use CEDET, or basic clojure-mode ?
22:40simard(it'S an inclusive or)
22:40brehauti use the emacs-starter-kit
22:41brehautand i dont use slime/swank etc though i hear it makes life much easier
22:41simardat least for lisp, dunno about clojure anywya
22:47amalloysimard: i use swank/slime and clojure-mode with paredit
22:47tomojhooray
22:48amalloytomoj: ?
22:49fujinemacs isn't an ide
22:50simardI know it's an OS
22:50brehautits not an OS either, its a sentient text editor
22:51tomojdo you say it's sentient because it seems to have a mind of its own? :)
22:51brehautyup :)
22:52brehauti need to enlist the help of qualified emacs wranglers like technomancy whenever i try to do anything new
22:53fujinIt's pretty good having technomancy around ;)
22:54fdaoudis there a cleaner way than (try (use (symbol "some.namespace")) (catch java.io.FileNotFoundException exc nil)) ?
22:57amalloyfdaoud: i think ninjudd's clojure-useful has something like this written already
22:58amalloyor maybe it's in cake
23:00fdaoudthanks amalloy
23:01fdaoudhe's using a try-catch so I guess that's the way to go
23:01amalloycool, glad you found it
23:01fdaoudbtw brehaut you were right, (f1 (f2 (f3 (f4 f5)))) is just comp
23:03brehautcool