#clojure logs

2012-07-03

00:03TimMcHi Fare!
00:04TimMcThis is my writeup of how collections are organized in Clojure: http://www.brainonfire.net/files/seqs-and-colls/main.html
00:05TimMcFare: I'd say the biggest pitfalls/tradeoffs (in my personal view) are nil-punning for empty seqs, the similar-yet-different nature of seqs and lists, and the lack of a way to ask whether an object can be seq'd.
00:08TimMcFare: Also, maps have a weird dual nature as collections of pairs of values vs. collections of values. They make the collections API kind of bumpy.
00:10TimMcFare: As for docs: http://clojure.org/data_structures#Data%20Structures-Collections and http://clojure.org/sequences
00:10FareTimMc, thanks a whole lot!
00:10michaelr525good morning clojurians!
00:10Farequite some reading for me
00:11FareI'm meeting with my co-author tomorrow, so I'll try to read it all tonight / tomorrow morning
00:11taliosFare: book writing?
00:11michaelr525Fare: writing another clojure book?!
00:12Farenah, writing a library for common lisp
00:12michaelr525a library of books?!
00:12TimMchaha
00:13carlo_auTimMc: those tables are good
00:13carlo_auwith the ticks and crosses
00:13TimMccarlo_au: They need better icons. :-/
00:13michaelr525we call them light tables!
00:13locojayhi i have a clojure noir entry point (defpage '_someentry' [& options]...) when i do (assoc hash-map options) i get java.lang.IllegalArgumentException: No value supplied for key: [:iDisplayStart "0"]
00:13TimMcHow does one represent logical booleans?
00:14TimMcI was thinking of idealized on/off symbols, like |/O
00:14carlo_auTimMc: what's wrong with coloured T and F?
00:14michaelr525locojay: hash-map is core function i think and assoc requires 3 arguments
00:15michaelr525locojay: (assoc a-map key value)
00:15TimMccarlo_au: Too visually similar in shape. Something like 10% of people won't see the color difference clearly enough.
00:16locojaymichaelr525 : i mean (apply hash-map options)
00:16carlo_auTimMc: ah, true.
00:16locojayi only what they args (options) as a dict
00:17FareTimMc: what's this seq'd thing? (sorry, I'm not familiar with clojure)
00:17TimMc,(seq "foo")
00:17clojurebot(\f \o \o)
00:17locojayalso tried [& {:as options}] but that raises that exception imediatly
00:17carlo_auTimMc: google image search for "icons true false" gives green ticks with red crosses
00:18michaelr525locojay: try pprinting options, looks like something is wrong there
00:18TimMcFare: If you give seq a thing that it knows how to make into a sequence, it will hand you back something that implements ISeq, or nil if empty.
00:18TimMcFare: But if someone hands you a random object, e.g. the number 17, you can't tell if seq will throw an error on it. :-/
00:19wingyyezz .. clojure is so concise that its being used as the query syntax in datomic
00:19wingylol
00:20michaelr525,(hash-map [:a 1])
00:20clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [:a 1]>
00:20michaelr525locojay: see the problem?
00:20wingydoesn't that mean that all coders from other langs will be using clojure when they are using datomic .. what a great marketing for clojure
00:20michaelr525locojay: you have to explode(?!) the vector in order to pass it to hash-map
00:20Fareso it's an ISeq, nil, or an error?
00:20michaelr525,(hash-map :a 1)
00:20clojurebot{:a 1}
00:20Fareand you don't have ignore-errors or something to catch the error?
00:21nDuffwingy: One can use datomic without any Clojure; it's just a lot more work and boilerplate.
00:21nDuffwingy: ...but then, I expect that Java programmers would feel uncomfortable if they *didn't* need boilerplate to get things done.
00:21wingyyeah and convert to clojure :)
00:21Fareis datomic free software or a trade secret?
00:21locojaymichaelr525: explode?
00:22dnolenFare: not free software.
00:22wingyFare: free for Open Source projects
00:22nDuff...free-of-cost
00:22TimMcFare: As far as I know, no. The best I know of is to check whether the object is nil?, coll?, array?, or string?.
00:22michaelr525locojay: options in your case is a vector of vectors, it has to be just a vector if you use (apply hash-map..
00:22nDuffwhich is certainly not Free
00:22technomancywingy: that's not what free software means
00:22michaelr525locojay: maybe flatten
00:23wingytechnomancy: oh :)
00:23michaelr525,(apply hash-map (flatten [[:a 1] [:b 2]]))
00:23clojurebot{:a 1, :b 2}
00:23locojaymichaelr525 thanks
00:23locojayworks
00:23michaelr525my pleasure :)
00:23wingyis that a good or bad thing that its not free software?
00:23Fare,(file-contents "/etc/passwd")
00:23clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: file-contents in this context, compiling:(NO_SOURCE_PATH:0)>
00:23TimMcFare: If Clojure were rewritten today, I'm sure the boundaries of what seq accepts would be much clearer.
00:24wingyor doesnt it matter
00:24aduhry
00:24TimMcFare: clojurebot isn't the most secure thing, but it is backed by the JVM SecurityManager sandbox.
00:25adui.m trying to use ring
00:25TimMcUntil recently you could still get your paws on eval.
00:25dnolenTimMc: I doubt it.
00:25TimMcdnolen: No protocol?
00:25dnolenTimMc: ISeqable protocol maybe, but Clojure will never validate inputs.
00:26TimMcLike 80% of this would be cleaned up with protocols: https://github.com/clojure/clojure/blob/1.3.x/src/jvm/clojure/lang/RT.java#L462
00:26dnolenTimMc: at runtime anyhow.
00:26dnolenTimMc: well ... actually never say never ... but I don't see it happening in the near future.
00:26TimMcdnolen: I'm not asking seq to validate inputs, I just want something that can tell me whether a thing is seqable if *I* want to know.
00:26technomancyit could certainly be clearer
00:27Farehow closely do clojure and clojurescript keep in sync with each other?
00:27technomancythat's what TimMc said
00:27dnolenFare: as close as possible, concerning data structures pretty much identical.
00:27Faredoes clojurescript implement all the interface infrastructure of clojure?
00:27technomancythat's different from stricter
00:27Fareis it the same compiler code base?
00:28dnolenTimMc: yes CLJS already has ISeqable
00:28TimMcdnolen: Good to hear!
00:28xeqiTimMc: I've fairly certain you could still get your hands on eval if you tried
00:28dnolenFare: no, CLJS compiler infrastructure is written in Clojure, Clojure compiler infrastructure in Java
00:29dnolenFare: interface instructure is actually improved in CLJS
00:29dnolener infrastructure
00:29aduFare? from TUNES?
00:37amalloy~flatten
00:37clojurebotflatten just means you failed to use ->> and mapcat correctly
00:37amalloylocojay, michaelr525: ^
00:37brehauthaha that sounds snarker than it used to
00:37Fareadu: yes
00:37aduFare: I'm a big fan of your writings
00:37Farethanks :)
00:37amalloyyeah, that's not very helpful :P
00:37Fare<blush>
00:37aduI think we talked about 3 years ago
00:38amalloy~flatten list
00:38clojurebotlist* doesn't actually make a `list?`
00:38amalloyi hate you, clojurebot
00:38Farewe did
00:38TimMc~flatten
00:38clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
00:41brehautthats much better
00:45amalloybrehaut: it's what i put there before you taught him your nonsense :P
00:46brehautme‽
00:46amalloywas it not you? i thought it was you
00:47brehautwell it might have been me, but i dont thing so
00:47amalloyi wonder what kind of detective work i'd have to go through to figure out the magic words to make him unlearn that
00:47TimMcamalloy: It was you.
00:48amalloydirected by M. Night Shyamalan
00:48TimMcdirected by M. Night Shyamalog is more like it.
00:49brehautthe man reason i dont think it was me is that i dont believei have ever successfully taught him anything
00:49amalloy2011-11-21.txt:[19:34:19] brehaut: ~flatten |just means| you failed to use ->> and mapcat correctly
00:49brehauthaha well bugger
00:50brehautim very sorry
00:50amalloyhaha
00:50brehaut(dec brehaut)
00:50lazybotYou can't adjust your own karma.
00:50brehautbah
00:50brehautyou shuld be able to decrement your own karma
00:50technomancyagreed
00:50amalloyclojurebot: forget flatten |just means| you failed to use ->> and mapcat correctly
00:50clojurebotI forgot that flatten just means you failed to use ->> and mapcat correctly
00:50amalloybrehaut: you're just being encouraged to use the clojurebot workaround
00:51amalloy,(println "(dec amalloy"))
00:51clojurebot(dec amalloy
00:51amalloy,(println "(dec amalloy)")
00:51clojurebot(dec amalloy)
00:51lazybot⇒ 23
00:51amalloyclojurebot: you're my own little tor relay on the way to lazybot
00:51clojurebotthe best way to represent X is as a regular clojure map. (for most values of x)
00:51TimMcThis is amazing.
00:52brehaut,(println "(dec brehaut)")
00:52clojurebot(dec brehaut)
00:52lazybot⇒ 6
00:52TimMc(referring to the provenance of those two factoids)
00:52amalloyTimMc: how so?
00:52brehautive got to stop being an idiot. my karma is going through the floor
00:52technomancybrehaut: must conserve vital whuffie
00:53brehautthat ones lost on me
00:53TimMcamalloy: Unless I misunderstood one of your msgs, I took it that both of you were wrong about who had authored each factoid.
00:53amalloyTimMc: i was spot-on, bro
00:53technomancybrehaut: admittedly quite obscure: http://en.wikipedia.org/wiki/Whuffie
00:53TimMcHmm, OK. "it" is a tricky pronoun.
00:54brehauttechnomancy: thats far my sophisticated than my usual reading allows for
00:56amalloyRaynes: any idea what's up with lazybot?
00:56Raynesamalloy: That'd be me.
00:56Raynesamalloy: I'm done now. Was upgrading his clojail.
00:57amalloyk
00:57amalloydid xeqi hack us again?
00:57RaynesNope, this was just something I forgot in the last release.
00:57RaynesWell, I'm sure he did, but this is unrelated to that.
00:57Raynes:p
00:58michaelr525,(apply hash-map (->> [[:a 1] [:b 2]] (mapcat identity)))
00:58clojurebot{:a 1, :b 2}
00:58michaelr525i'd still use flatten instead of this
00:58michaelr525much more concise
00:58amalloymichaelr525: flatten is anathema
00:59amalloydo not do it unless you want your program to break the moment it gets more complicated
00:59xeqiI try not to actually break anything
00:59amalloy&(into {} [[:a 1] [:b 2]])
00:59lazybot⇒ {:a 1, :b 2}
00:59michaelr525ok, you win :)
01:00michaelr525but why would a program break with flatten?
01:00TEttingerit undoes ALL nesting
01:00TEttingernot just one layer
01:00michaelr525ok, i can see when it can be a problem
01:01michaelr525then there must be flatten-1 in core or something like this
01:01amalloyit's apply concat, mate
01:01michaelr525'cause all i wanna do is flatten
01:01brehautthat would be concat
01:02michaelr525,(apply concat [[:a 1] [:b 2]])
01:02clojurebot(:a 1 :b 2)
01:02brehautthe other gotcha with flatten is that some times people expect it will flatten maps
01:02brehaut,[(flatten {:a 1}) (flatten [{:a 1}])]
01:02clojurebot[() ({:a 1})]
01:02michaelr525,(flatten {:a 1 :b {:c 2}})
01:02clojurebot()
01:03michaelr525ooh ugly ;)
01:03brehauti recall lazybot / clojail being caught by that one for a while
01:03adu,(->> [[:a 1] [:b 2]] (concat) (hash-map))
01:03clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@2e4f937f>
01:03adu,(->> [[:a 1] [:b 2]] (apply concat) (hash-map))
01:03clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@1038a40f>
01:03adu,(->> [[:a 1] [:b 2]] (apply concat) (apply hash-map))
01:03clojurebot{:a 1, :b 2}
01:04adusorry, I'm learning about ->>
01:04michaelr525<amalloy> &(into {} [[:a 1] [:b 2]])
01:04michaelr525^^^^^^^^^ best so far
01:04brehautthats because its the idiomatic way to do it
01:04michaelr525brehaut: who says?
01:04brehautthe clojure community
01:05michaelr525i want to talk with him
01:05amalloythe clojure language
01:05aduidioms are by definition, not one person
01:05brehautwell, rhickey can define any idiom he wants for clojure and we all ussually follow along
01:05michaelr525brehaut: that's acceptable
01:05michaelr525;)
01:06adunot all idioms are nice, for example, birthday punches
01:07michaelr525but seriosly the (into) solution is the most _simple_ one, it does exactly what it says (unlike flatten)
01:07amalloyi <3 into/for
01:07brehauti <3 outof/doseq
01:08brehautnot really
01:08xeqiwho is it that <3 juxt ?
01:08Raynesamalloy:
01:08brehautEVERYONE
01:08RaynesYou did see my talk!
01:08Raynes:D
01:08brehautfree all the points
01:08amalloytechnomancy founded the juxt fan club
01:09aduJuxtaposition?
01:09brehautyup
01:09aduyup
01:09brehaut,((juxt inc dec) 1)
01:09clojurebot[2 0]
01:09aduwow
01:10technomancyit's so gooooood!
01:10aduthat is incredibly pointless
01:10brehaut~rimshot
01:10clojurebotBadum, *tish*
01:10amalloy~rimshot
01:10clojurebotBadum, *tish*
01:10amalloydamn you, brehaut!
01:10aduer i mean points-free
01:10brehautits hard to snipe from this side of the world!
01:13michaelr525,((juxt inc inc inc) 0)
01:13clojurebot[1 1 1]
01:13michaelr525what's so good about it?
01:14michaelr525(except the cool name)
01:16michaelr525,(juxt juxt juxt inc 0)
01:16clojurebot#<core$juxt$fn__2476 clojure.core$juxt$fn__2476@241bd8cd>
01:16michaelr525,((juxt juxt juxt inc 0))
01:16clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$juxt>
01:17amalloywe should see if TimMc can develop a turing-complete clojure dialect using only juxt
01:17brehautlol
01:21brehaut,((comp (partial apply +) (memfn invoke) (partial apply juxt) (partial map (constantly (constantly 1)))) [1 2 3 4])
01:21clojurebot4
01:23brehautim slightly amazed that that worked
01:23amalloythat looks like count
01:23xeqi,(doc memfn)
01:23clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."
01:23brehautit is the worlds dumbest count yes
01:23brehauti had to force the juxt in unnecessarily
01:23technomancystylin'
01:27brehaut,(require 'clojure.reducers)
01:27clojurebot#<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/reducers__init.class or clojure/reducers.clj on classpath: >
01:27brehaut,(require 'clojure.core.reducers)
01:27clojurebot#<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath: >
01:28amalloybrehaut: they're both on 1.4
01:28brehautamalloy: and i got the NS wrong the first time
01:29taliosbrehaut - you just hurt my brain.
01:30brehauttalios: i do what i can
01:31brehauttalios: its the dumb version of ##(apply + (map (constantly 1) [1 2 3 4]))
01:31lazybot⇒ 4
01:32brehautbut that has no juxt, so who would want that
01:33taliossane people not from the 'tron
01:33brehautsame people would call count ;)
01:33brehauts/m/n/
01:33xeqi,(map apply [inc dec] ((juxt inc dec) 0))
01:33clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
01:35brehaut,(map apply [inc dec] ((juxt (comp vector inc) (comp vector dec)) 0)) ; xeqi
01:35clojurebot(2 -2)
01:36brehaut&(use 'useful.fn)
01:36lazybot⇒ nil
01:36xeqiblah, I was hoping for a closer equivalent to &&&
01:36brehaut,((knit inc dec) ((juxt inc dec) 0))
01:36clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: knit in this context, compiling:(NO_SOURCE_PATH:0)>
01:36brehaut&((knit inc dec) ((juxt inc dec) 0))
01:36lazybotjava.lang.RuntimeException: Unable to resolve symbol: knit in this context
01:37brehautxeqi: useful has 'knit which is what you want
01:38xeqi&useful.fn/knit
01:38lazybotjava.lang.RuntimeException: No such var: useful.fn/knit
01:38brehautamalloy: does lazybot roll with an archaic version of useful?
01:38amalloyi'm not sure he has useful at all
01:39amalloyoh, he does
01:39amalloyyes, probably ancient
01:40brehautxeqi: https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L94-100
01:41brehautalso http://swannodette.github.com/mori/#knit
01:41michaelr525what would you use to format a date into string in this format: "10/10/2012" ?
01:42amalloy$javadoc java.util.text.SimpleDateFormatter
01:42amalloywas i close? maybe not
01:42amalloy$javadoc java.text.SimpleDateFormatter
01:43amalloyi guess for starters i'd advise that you make sure the date is always the same as the month, if you're going to format it that way
01:43amalloycuz europeans and americans will disagree about what that date means
01:43brehautwell, not that date
01:44brehautthats the tenth of october no matter how you slice it
01:44augustlare there any systems for "environments" for Ring apps? Like "development", "test", "production", etc, with different db settings and what not
01:44brehautbut 1/10/2012 would the the tenth of jan here
01:44augustlthere's always environment variables I guess
01:45brehautring itself doesn't concern itself with settings, but yes, env vars are a common approach
01:45brehauterr apparently i have been americanized
01:45brehautit woudl the the first of october here
01:45amalloyyou can also put your config into a .clj file on the classpath and read it at startup
01:45xeqiaugustl: env vars, or some fun use of lein2's profiles
01:46augustlxeqi: looking up lein2 profiles, tnx
01:46xeqibasically used as a way to seperate configs in different resource paths, and read it on startup like amalloy mentioned
01:47xeqiclojars does something like that
01:47augustlmakes sense, so I can have stuff in project.clj without checking it in to git, basically
01:51michaelr525i really like the interop stuff in clojure, easier to write java in clojure-java interop than java in java
01:54michaelr525,(-> (java.text.SimpleDateFormat. "MM/dd/yyyy") (.format (java.util.Date.)))
01:54clojurebot#<RuntimeException java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class java.util.Currency>
01:56xeqiof course, the Currency class is required for one of those
02:00amalloy&(-> (java.text.SimpleDateFormat. "MM/dd/yyyy") (.format (java.util.Date.)))
02:00lazybot⇒ "07/02/2012"
02:07michaelr525(diff lazybot clojurebot)
02:07michaelr525,(clojure-version)
02:07clojurebot"1.4.0-master-SNAPSHOT"
02:07michaelr525&(clojure-version)
02:07lazybot⇒ "1.4.0"
02:10amalloyreally? i thought for sure clojurebot was on 1.4.0
02:23Raynesmichaelr525: lazybot is a totally different bot.
02:23RaynesYou'd have one hell of a diff to look at.
02:26gtuckerkelloggahh, it was
03:27augustlhow do I access the full request in compojure routes? All I can find is how to access path parameters from the URL.
03:27weavejesteraugustl: (GET "/blah" request …)
03:28weavejesteraugustl: Or: (GET "/blah" [x y :as request] …)
03:28augustlah
03:28augustlwhere x and y are keys in the request map?
03:28weavejesteraugustl: No, where x and y are parameters
03:29augustlI want to access more than the parameters, like the request body
03:29weavejesteraugustl: ":as" raises you up, like normal destructuring
03:29augustlbut that's what 'request' does?
03:30weavejesteraugustl: Yes, so with normal destructuring you could bind "request" or "{:as request}"
03:30weavejesteraugustl: With the vector bindings you can also use [:as request]
03:31augustlI see
03:38kralnamaste
03:56augustlhmm, cheshire doesn't like a org.eclipse.jetty.server.HttpInput
03:57augustlshould I turn it into a string or something by hand?
04:00augustlslurp to the rescue
04:02augustlwhere are the options I can pass to slurp documented? the docs for slurp refer to clojure.java.io/reader, but the docs for that one does not document the options either
04:19amalloyaugustl: perhaps just in the source, though i imagine clojuredocs has some supplementary explanation
04:19augustlamalloy: I'll look that up, thanks
04:33dsabaninhey guys
04:34fmwthis piece of code is irking me somehow: http://paste.lisp.org/display/130373 - there must be a prettier way to write this with the standard functions?
04:35augustlfmw: what's the x and y symbols?
04:35fmwit feels like I'm missing something very obvious as to how to implement this cleanly
04:35fmwaugustl: just ignore those, its basically a simplified version of some code I'm working on
04:36augustl(merge {:bar foo :barfoo :foobar} your-map)
04:37fmwaugustl: http://paste.lisp.org/display/130374 that is the full version, but the sample should do
04:37augustlif I'm reading it correctly
04:37fmwaugustl: what about the conditionals?
04:37augustlah :)
04:37fmwI meant to ignore the values of x/y, should've been clearer there, sorry ;)
04:38fmwbecause I still need the conditionals
04:39augustlthe symbols come from a destructured map, perhaps you should work directly on the map instead of on the destruct values
04:39fmwI'm sure I could write a macro to make this prettier, but imho that is overkill, but somehow I have the feeling that I'm overlooking a much prettier solution using the standard stuff that is available in Clojure
04:39augustlthey don't come from a map and now I'll shut up
04:40fmwaugustl: don't worry, I'm happy someone is responding ;)
04:40fmwreading other peoples code is always a pain.
04:41augustlespecially when you're not very familiar with the language ;)
04:41fmwaugustl: liking Clojure so far?
04:43augustlvery much so
04:43augustlit's mostly just the lispyness that's causing trouble
04:43augustlfmw: loving the separation of values, identity and time!
04:44fmwit takes some getting used to, but once the pieces starting falling into place and you wrap your head around it, it feels so natural
04:45fmws/starting/start
04:45augustlfmw: btw have you considered changing your API to take a map instead of a large vector?
04:45noidithe CCW documentation states that "Once you have started a REPL for your project, eclipse will use a backdoor connection to this REPL to automatically compile and load the files you edit (if the eclipse Project > Build automatically option is selected, of course)."
04:45augustlthat will solve your problem and make for a better api imo :)
04:45noidiand "In conjunction with auto-compile functionality, compilation problems are reported as problem markers"
04:45noididoes that work for anyone else? I can't get it to work.
04:46augustlfmw: indeed, it feels very natural. Like Rich Hickey said in a talk, it doesn't really make much sense to change the date of a month (like with date.setMonth in Java), immutability maps much better to the real world as long as you leave time out of the equation
04:46fmwaugustl: the API isn't taking a vector, I'm just using it for destructuring optional values
04:46noidiI've tried this on two boxes now (Linux and Windows) and neither report compilation problems, even if the source is not valid and I get an error if I try to load it
04:46augustland in most programs, you do want to leave time out of the equation, usually in the form of locks
04:47fmwyou call it like e.g. (get-documents-for-feed "vix" "en" "blog" 10)
04:47fmwwhere 10 is the first optional argument, you can have two more (i.e. startkey and startkey_docid)
04:47augustlfmw: well, a list of some kind, if not a vector
04:48augustlit's just that in general I prefer APIs like (get-documents_for_feed {:db "vix" :language "en"}) etc
04:48augustlI've programmed too much Objective-C I guess
04:48fmwaugustl: I see. I'm not sure if that is idiomatic in Clojure, but I guess it is a matter of taste.
04:49augustlfmw: perhaps a multi-method is better in your case
04:49fmwit is practical for some functions, but doesn't have added value for most, yet still adds a lot of cruft you have to type all the time
04:50fmwaugustl: that could work, yes!
04:52augustlfmw: iirc the syntax is something like this http://paste.lisp.org/display/130375
04:52augustlnot sure if there's a clever way other than named refs to avoid duplication of the defaults
04:52augustland obviously some definitions are missing from that example
04:52fmwaugustl: a multimethod is with (defmulti ...)
04:53augustlyeah not sure what the difference is there..
04:53augustlI think my paste is a valid method for creating a function that dispatches based on the number of args though
04:54fmwaugustl: the syntax you pasted is nice for simple cases, defmulti gives control over the dispatch if you want to dispatch by custom things, like type
04:54fmwyes, it is
04:54fmwaugustl: its actually exactly like my original implementation of the dispatch: https://github.com/fmw/vix/blob/master/src/vix/db.clj#L204
04:55fmwI'm currently refactoring that code to make it cleaner, with the knowledge I gained since I wrote it
04:55fmwe.g. fixing silly things, like (map #(:value %) some-map) into (map :value some-map)
04:56augustlclojure does have a gazillion small features
04:57fmwI'm actually refactoring those (defn some-fn ([x y] (some-fn x y nil)) ([x y z] (do-something x y z))) into (defn some-fn [x y & [z]] (do-something x y z))
04:58fmwI prefer the latter, because it is more concise and arguably makes it more clear which variables are optional at a glance
05:00fmwaugustl: I'm quite fond of multimethods for more complicated dispatch scenarios, though, like https://github.com/fmw/alida/blob/master/src/alida/lucene.clj#L90
05:00dsabaninfmw: what about http://paste.lisp.org/display/130376?
05:01fmwdsabanin: I think that must be the solution, thanks. let me adapt it into my code and see
05:02dsabaninfmw: cool, np
05:02dsabaninwell, actually it's even better
05:02dsabaninmerge accepts nil as arguments
05:03dsabaninso it's just http://paste.lisp.org/display/130377
05:04dsabanindamn, not, you just can do (if x {:bar :foo})
05:04fmwdsabanin: I think you can, but I'd use when?
05:04dsabaninyep
05:04augustlwhat's the #^ part of this? `(defn #^IndexWriter create-index-writer`
05:04augustlthe docs for defn doesn't seem to mention it
05:04dsabaninaugustl, it's a type hint for performance optimization
05:05dsabaninit specifies the kind of java type that is being returned
05:05fmwaugustl: that is like soft typing (telling Clojure what type to expect, for performance gains)
05:05augustlit's not documented for `def` either, where is it documented?
05:05clgvaugustl: #^IndexWriter is deprecated! use ^IndexWriter instead
05:06augustlclgv: and where's _that_ documented? :P
05:06clgvaugustl: it is called a typehint
05:06fmwaugustl: http://clojure.org/java_interop#Java Interop-Type Hints
05:07clgvaugustl: you'll only need those if clojure complains when compiling and having set *warn-on-reflections* to true
05:07fmwclgv: that was my code actually, thanks for pointing it out, will have to fix that at some point
05:08fmwI actually like type hints as semi-documentation in java glue code too, not just for performance gains
05:08fmwbecause it makes it instantly clear what your fn is supposed to return
05:08augustlfmw: out of curiousity, do you do any locking etc to make the IndexWriter work across threads? I'm currently writing an HTTP API that will write to Lucene indexes actually, and need to handle that.
05:09fmwaugustl: which version of Lucene?
05:09augustl3.6
05:09fmwaugustl: Lucene 4.0 has built-in stuff for that
05:09fmw(so does 3.x, afaik, but you really should be using 4.0)
05:10augustlhmm, IndexWriter is thread safe it says for the 3.6 docs
05:10fmw4.0 has been used in production for a while and should be released soon with a lot of backwards compatibility breakage and all sorts of improvements, so best to use it for new code already
05:11augustlhmm
05:11fmwaugustl: yes, they have their own manager classes that deal with your writers/readers (4.0 fully breaks them apart, btw, while in 3.x you could write using a reader IIRC)
05:11augustl4.0 is not even mentioned on http://lucene.apache.org/
05:12fmwaugustl: https://twitter.com/kucrafal/status/218633823976566784
05:13fmwaugustl: it has been stable for the last 12 months, or so, and people have been using it in production a lot, so it is a safe bet, imho
05:13fmwLucene developers are *very* conservative and don't generally break things
05:13augustlwhy not (tm) :D
05:14augustlfmw: do you happen to know if there are JavaDocs hosted for 4.0 anywhere?
05:14fmwaugustl: yes, let me find them. there are also some very good background docs on the changes
05:15fmwaugustl: https://builds.apache.org//job/Lucene-trunk/javadoc/
05:15augustlyay
05:15augustlwut, why does it say 5.0? :)
05:16fmwaugustl: good question. I think they've updated their trunk to 5.0 now, to make the 4.0 branch stable for release
05:16fmwhttp://blog.mikemccandless.com/ is a good resource about some of the changes in 4.0, too, btw
05:16augustlmakes sense
05:18augustlLucene is pretty darn awesome. After struggling to figure out a way to start Solr other than the start.jar in the "example" of the tarball and browsing through a zillion XML files, I thought I'd might as well use Lucene directly
05:18augustlturned out to be a sound decision ;)
05:18fmwaugustl: feel free to use http://github.com/fmw/alida as a starting point for your stuff, as I wrote it as example code for a Lucene talk (and don't be afraid to ping me if you have any questions/requests for improvement, as I'm planning to build a real-world thing out of the alida project)
05:19fmwaugustl: yes, Solr is nice if you don't have access to a JVM or need some of their specific features, but I haven't used it at all so far, despite doing quite a lot of search-related work
05:21augustlfmw: great :D
05:26augustlfmw: very off topic, but there's not much activity in #lucene.. My data will always be queried by a foreign key. Do you think I should put everything in one index, and always add the foreign key to all queries, or have a separate index per foreign key/group?
05:27fmwaugustl: can you specify the foreign key?
05:27augustlfmw: I'm indeing attendants, the foreign key is an alphanumeric id, "event_id"
05:28fmwaugustl: unless you're data is really big, just put the event_id in a field and filter your queries on that
05:28fmwno need to split anything
05:28augustlI'm thinking one large index, and shard it manually later. The number of events will grow and grow, which means a lot of files in one folder, lots of open files, etc.
05:28augustlfmw: yeah makes sense
05:30fmwaugustl: Lucene has built-in IndexReaders for that, and you can also write your own
05:31augustlfmw: as in built-in IndexReaders for foreign key type queries?
05:31fmwdsabanin: thank you, that was exactly the cleaner solution I was looking for.
05:31fmwaugustl: as in dealing with large datasets
05:33fmwthe foreign key type thing is just something to filter on in Lucene, next to your query. There is a performance consideration, though, because Lucene 4.0 has switched to byte indexing, so its actually fast to store/filter on numbers now
05:33augustlfmw: ah
05:33augustlthe semantics of a progammatic API vs query strings is reason enough to use Lucene directly imo
05:33fmwso if its an integer that won't take up much space and its best to store it as a numeric value
05:34fmwaugustl: yes, even though you can use both.
05:34augustlthe foreign keys are alphanumeric, but I suppose I'll figure something out
05:34augustl(ObjectID's from MongoDB)
05:35fmwaugustl: probably not worth changing them to numeric values in that case
05:42fmwI'm going for a swim now, getting too hot in the afternoon sun here in Greece (I'm a northener and not used to the heat). Feel free to contact me if you have more questions about using Lucene from Clojure (https://twitter.com/#!/filipdewaard or fmw@vixu.com).
07:40augustlis there a function to flip a boolean? Need it for dosync/commute.
07:40AWizzArdaugustl: you could use “not”.
07:40augustloh wait I can just pass in my own function I guess
07:40augustlAWizzArd: ah, of course
07:40AWizzArd$(not true)
07:40AWizzArd,(not false)
07:40clojurebottrue
07:40AWizzArd,(not true)
07:40clojurebotfalse
07:41augustlor just ref-set I guess
07:41Licenserworth reading: http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/
07:54winkworth reading, yes. but it's written by a seemingly very angry person, it's not necessarily very correct
08:35jweissjust discovered edebug in emacs. is there any reason (beyond that no one has sat down to do it yet) that clojure couldn't have a similar debugger?
08:38romain_pHi everyone, can anybody help me create the simplest possible raphaeljs example (e.g. a circle) using clojurescript (maybe starting from cljs-template)? I am just beginning with cljs and a bit bewildered... :)
08:39gfredericksromain_p: I'm doing cljs + raphael right now! :D
08:39gfredericksI'm doing it all with js interop though, so if you know how to do it in js it shouln't be hard
08:39romain_pgfredericks: awesome :D could you point me in the right direction?
08:41gfredericksromain_p: (def paper (js/Raphael ...args...))?
08:41gfredericks(.circle paper ...)
08:42gfredericksnot sure what you're having trouble with
08:42romain_pgfredericks: ah well, it's more about setting stuff up. Where should I import the raphael lib?
08:43gfredericksromain_p: I just have the js file lying around
08:43gfredericksand a <script> for it in my html file
08:44romain_pah OK, will try. I started from the cljs-template leiningen target, so I do not use a static html file, but I suppose I can require the javascript from the hiccup template
08:44romain_pinclude-js or something
08:45gfredericksromain_p: I don' know anything about cljs-template
08:46romain_pgfredericks: it is a sample noir+cljs+hiccup application, kind of a "getting started" kind of thing apparently...
08:47gfredericksah ha
08:52gfredericksIs there no easy way in cljs to dynamically call a method? i.e., ob[s]()?
08:52gfredericksI just wrote a macro for it
08:53augustlare therre any utils for making a string of hex encoded bytes into a byte array?
08:55jcromartie"A LISP dialect? LISP was far and away the worst language I ever had the misfortune of having to use in school" - people keep saying this
08:56romain_pgfredericks: OK, that did it. Thanks for the help!
09:00augustljcromartie: I like to say that Lisps are as similar to other lisps as Java and JavaScript are similar.
09:01jcromartiepeople I interview, new hires out of school, people who call themselves "Java EE guys"
09:01augustljcromartie: "Lisp is a language" doesn't make sense to me, it's a bit like saying "camel case and curly brackets is a language"
09:02jcromartieand saying "Lisp is for AI" is like saying "Ruby is for web apps"
09:02jcromartienot even… "Ruby is for web apps" is at least closer to truth in a statistical sense
09:03jcromartiebut anyway, yeah, there's an image problem there
09:03jcromartieI don't know what people do with Lisp in school… I never went, myself
09:03jcromartieBRB… going for a run
09:12mystiiqcan anyone point out an example how to use declare function. basically some my functions want to use a shared Java object and I want that the first one who will try to use it must initiate it
09:13gfredericksmystiiq: would delay do what you want? or does the first one trying to use it also have to decide _how_ to initiate it?
09:14gfredericks,(let [foo (delay (make-foo))] (defn get-foo [] @foo))
09:14clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
09:14gfredericksmystiiq: something like that ^
09:15mystiiqthe first one does not have to decide how to initiate it
09:15gfredericksdelay should work then
09:27TimMcamalloy_: Just juxt and parens, eh? You'd have to use encoded numerals, but it might actually be possible.
09:28TimMcamalloy_: Wait, no -- juxt produces vectors, which expect system integers for dereference. Not feeling it.
09:28uvtcWhat does "immutability precludes backreferences" mean? (seems to be in the context of nested data structures)
09:31gfredericksuvtc: backreferences I think is synonymous with self-reference or cycles
09:31uvtcIt's mentioned in the CP chapter on zippers.
09:32augustlwaat. What am I not getting here? `(byte 0xff)` => IllegalArgumentException Value out of range for byte: 255
09:32augustlwhat kind of bytes are these? ><
09:32gfredericksuvtc: it's why you can't use normal mutable-data-structure approaches to walking a tree
09:32gfrederickslike parent.children() and child.parent()
09:33gfredericksfor going down and up respectively
09:33uvtcHm.
09:34uvtcgfredericks, Ok. I was thinking I could "walk the tree" by using assoc-in...
09:34mystiiqin java !false is true, what's the similar syntax in clojure?
09:34gfrederickswell that's good for single updates
09:34gfredericksmystiiq: (not false)
09:34augustloh, bytes are signed
09:34mystiiqok thanks
09:35gfredericksuvtc: if you want to be effiient and you have a lot of work to do at the bottom of the tree you don't want to keep walking from the root for each operation
09:35gfredericksuvtc: it's a lot of time and unnecessary object allocations
09:35TimMc~byte
09:35clojurebothttp://homepages.inf.ed.ac.uk/kwxm/JVM/codeByNo.html
09:35TimMcfeh
09:36augustlTimMc: :D
09:38TimMcAlthough I do like that URL: "code by number"
09:38uvtcgfredericks, why would a data structure being immutable have anything to do with being able to figure out where a parent/child is? Seems like that's more related to the items in the d/s not being OO-style objects...
09:38gfredericksuvtc: figuring out the child is usually easy, but not the parent
09:39TimMcuvtc: Try to build a Clojure list or vector that contains a reference to itself.
09:39TimMcOr two that reference each other, rather.
09:39gfredericksif I have a tree [:ul [:li] [:li]] and call (nth tr 2) on that,, the return value has no idea that it "is in" a tree
09:40gfredericksit is simply [:li] and has no reference to its parent
09:40gfredericksso when you get to that point you can't get back up
09:40tbaldridge.parent() is a horrible way to transverse a tree anyways (IMO)
09:41tbaldridgerecursive functions have always done the trick for me.
09:41gfredericksyeah they work for most cases
09:42gfrederickshell if I've ever used a zipper for anything
09:42TimMctbaldridge: Unless you're doing zipper type stuff, of course.
09:42gfredericksTimMc: have you ever done zipper type stuff?
09:42TimMcIt's sueful if you need to carry child information back up to parents.
09:42TimMcgfredericks: No, but I told someone else to use them once. :-P
09:42gfredericks:)
09:43gfredericksit's like refs. We all know what they do.
09:43tbaldridgeTimMc: if you need to carry data up to the parent. Then start at the top, and have the function applied to the child return the data to the parent
09:43gfredericksand then we use proper databases instead because they are persistent
09:43TimMcSay you have a tree of maps, and you want to add an incrementing :id field to each map according to an in-order walk.
09:43TimMcThat's a use-case for zippers.
09:45uvtcTimMc, if I try to make 2 data structures with parts that refer to parts of eachother, it fails because I Clojure gives me the value of things, not references to them.
09:45uvtcTimMc, but this appears to me to be because of not using any reference types ... not because of immutability...
09:45TimMc(Specifically, a binary tree.)
09:46gfredericksuvtc: no it's because of immutability
09:46gfredericksyou do have references
09:46TimMcuvtc: You get references to their values.
09:46gfredericksin the jvm sense
09:46TimMcThose references are immutable in Clojure.
09:46TimMcOr, well, they're immutable anyway.
09:46gfredericksin java you could (let [a (new A), a' (new A)] (.setFoo a a') (.setFoo a' a))
09:47gfredericksthe only difference between that and clojure data structures is mutability
09:47uvtcTimMc, thanks. gfredericks : still reading your comments.
09:47gfredericksyou can't set a vector's contents after you construct it
09:47gfredericksyou CAN do this with lazy-seqs I believe
09:48gfrederickslazy-seqs have a kind of mutability
09:52gfredericks,(let [x (promise), self-containing-seq (lazy-seq (cons @x ()))] (deliver x self-containing-seq) self-containing-seq)
09:53clojurebot((((((((((#))))))))))
09:53gfrederickso_O
09:53gfredericks&(let [x (promise), self-containing-seq (lazy-seq (cons @x ()))] (deliver x self-containing-seq) self-containing-seq)
09:53lazybotjava.lang.StackOverflowError
09:53gfredericksthat's better
09:53uvtcgfredericks, you wrote "the return value has no idea that it "is in" a tree ... it is simply [:li] and has no reference to its parent ... so when you get to that point you can't get back up". I see what you mean here. Thanks!
09:54gfredericksuvtc: awesome
10:04scriptorhave a question that isn't really clojure-related, but still fp-related
10:04scriptorI'm trying to stick to the idea of data as data, and just using plain hashmaps instead of more complex objects
10:05scriptorhowever, I'd also like to be able to listen for changes to the data and re-render parts of the interface when needed
10:06augustlwhat's the canonical way of despatching a method based on the types of its arguments? Multimethods? Protocols? Something else?
10:06scriptorshould I just create an interface through which the hashmaps are 'modified' (either in-place or by doing something assoc-style) and then these functions are responsible for updating the view?
10:07dnolenscriptor: I need to start keep track of how many times this question comes up :)
10:08dnolenscriptor: nothing exists, we need a functional answer to data binding - probably something FRP-like that isn't a hassle to use.
10:08scriptordnolen: not surprised, I'm basically asking for very limited FRP :p
10:09scriptorhmm, I'm trying to at least move away from the idea of models in js
10:10dnolencljs.core.rx sounds like a pretty compelling contrib ...
10:11scriptorlink please? Can't find anything on google or github
10:11dnolendoesn't exist.
10:11zerokarmaleftdnolen: reactive extensions?
10:12scriptorah, as in a name idea :)
10:12dnolenzerokarmaleft: yes
10:14tbaldridgeI've been playing around with trying to do something rx-esque in Clojure. My work still is way too mutable for my liking though
10:14tbaldridgeOt'
10:14madsyIs there a nice article somewhere on how to setup lein-cljsbuild and clojurescript manually? The stuff on Maven is like a century old, with non-official version numbers.
10:15tbaldridgeFrom my reading FRP is functional, but highly complex (at least the flapjax way), while Rx is highly un-functional, and mutable, but easier to learn/design
10:15dnolentbaldridge: my sense is we need to learn from both and design something better
10:16TimMcdnolen: In FRP as you used it, R = relational?
10:16TimMcor reactive?
10:16scriptorTimMc: I think it's Reactive
10:16dnolenTimMc: no, Functional Reactive Programming
10:17tbaldridgednolen: agreed. That's why I've been looking into dataflow recently, it's not quite there either, but it's simpler than the hardcore FRP stuff.
10:17scriptoryou represent an otherwise mutable value as a behavior, which represents both the present and all future values
10:17TimMcOK. I'm reading Out of the Tar Pit and keep getting mixed up when I see "FRP". :-)
10:17tbaldridgemadsy: this tut worked for me when I used it last week: https://github.com/emezeske/lein-cljsbuild
10:18tbaldridgemadsy: i was using lein2, so I had cljsbuild to my .profile.clj but besides that it "just worked(TM)"
10:19otfromCfP for 6 December Clojure eXchange if anyone fancies giving a talk in London. :-D http://bit.ly/clojurex12-cfp
10:19madsytbaldridge: How does lein2 find your custom-built lein-cljsbuilt plugin? Did you just copy it to the ~/lein/plugins directory?
10:20madsyOr did you set up a local maven repo?
10:21tbaldridgemadsy: I mis-typed there. You need to add {:user {:plugins [[lein-cljsbuild "0.2.2"]]}} to a file in ~/.lein/profile.clj Then just do lein deps and lein will install it.
10:21madsytbaldridge: Maybe what needs to be done is supposed to be obvious from the github readme, but it's not obvious to me
10:21tbaldridgemadsy: https://github.com/technomancy/leiningen/wiki/Upgrading
10:22madsytbaldridge: So you got lein-cljsbuild prebuilt from maven?
10:22madsyBecause, that's not what I asked about.
10:23tbaldridgemadsy: bleh, my bad...I missed that first part. Sorry, I thought you were just trying to get it working with lein2
10:23madsyNo worries :)
10:24madsyBut yes, incidentally I should get lein2
10:25xumingmingvhi all, need help on this line of code: https://github.com/xumingming/storm/blob/master/src/clj/backtype/storm/thrift.clj#L19
10:26xumingmingvit creates a new java object according to the classname using the *new* macro
10:26xumingmingvmy question is: the corresponding class is not imported, why this line of code can work?
10:27mystiiqwhen a java method returns an array of strings, how can I extract first one from the array in clojure ?
10:28xumingmingvmystiiq: (aget arr 0)
10:29mystiiqxumingmingv: thanks
10:30mduerksenmystiiq: ##(first (long-array [1 2 3]))
10:30lazybot⇒ 1
10:30dnolentbaldridge: let me know where the dataflow stuff goes, would like to check it out.
10:35dnolenlynaghk: your todo example looks nice, tho I agree, not really MVC (which is a good thing)
10:36scriptorI was dissapointed by the move article that floated around yesterday
10:37scriptorit's basically just MVC+events
10:39mystiiqhow can I make java String array or convert clojure array into one
10:40mystiiqlist is also an option
10:40augustl"To re-iterate: MVC is awesome, but it's designed with decades old technologies. MOVE is just a update to make better use of the new tools we have." is that content-free or what
10:41mystiiqlets hope to-array works
10:41augustlmystiiq: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/to-array
10:41augustlafaik
10:43S11001001mystiiq: no
10:43S11001001,(instance? (map identity [1,2,3]) java.util.List)
10:43clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Class>
10:43S11001001right
10:43TimMcS11001001: You lost the argument order lottery.
10:43S11001001,(instance? java.util.List (map identity [1,2,3]))
10:43clojurebottrue
10:44S11001001the way I do
10:44TimMcmystiiq: Do you need a list, or any sequential coll?
10:44TimMcmystiiq: Also, there's no "clojure array".
10:44S11001001,(type (to-array [1,2]))
10:44clojurebot[Ljava.lang.Object;
10:45mystiiqTimMc: I need something that implements java.util.List interface or String array
10:45lancerowhat am I doing wrong here: http://pastebin.com/JRBW1ckb ? I expect that when test-promises gets called it will start delivering 5 futures into promises, then start blocking (since old isn't realized yet). Instead the function returns immediately with nothing delivered.
10:45S11001001mystiiq: then all you have to deal with is the nil case
10:49S11001001lancero: for isn't a looping construct
10:50jweiss(binding [*print-length* 50] (iterate inc (System/currentTimeMillis))) -> OOM. what am i missing?
10:52TimMcjweiss: The print is happening outside your binding.
10:53S11001001I wish for required you to specify what monad you wanted
10:53jcromartie *facepalm*
10:53locojayhi i m using jayq and would like to do something like this in js $("td:eq(1)", this).text(); (.text ($ "td:eq(1)")) works but i need this so i don't always get the same val
10:53jcromartiethe "LISP was far and away the worst language I ever had the misfortune of having to use in school" guy
10:54jcromartieI said, "well I didn't go to school, I don't know how they tortured you with it there"
10:54jcromartieand I get "You didn't get a degree, are you joking with me? How did you get a job?"
10:54TimMchaha
10:55TimMc"Market forces."
10:56jweissTimMc: ah yes, knew it had to be something obvious
10:56jweissthanks
10:58mefisto`jcromartie: I think people who went to school for it can more easily miss the fact that we are living in the most exciting time for computing ever :D
10:59jcromartiemefisto`: I just don't know how you can work in programming for any length of time and still be incredulous about non-credentialed professional programmers
11:00jcromartiemefisto`: I mean this guy has even written books (not great ones…)
11:00wkellyit is easy to be oblivious when you are self-absorbed!
11:02lanceroS11001001: I changed for to doseq. Now test-promises returns after about 10 seconds like I expected. But everything is already realized immediately when on return.
11:02mefisto`jcromartie: same reason he didn't like LISP I imagine... he's stuck in some fixed idea of the way things are "supposed to be" and so is blind to seeing anything that challenges that
11:03tbaldridgemefisto: I agree. Our architect told me "I just don't like this FP stuff...I mean we abandoned it when we invented OOP. It's all just such a step backwards..."
11:03gfrederickshaha
11:03tbaldridgethen he goes and sits for a day trying to figure out what a object does with its mutable state
11:03tbaldridgeSo yeah...my face and my palm are well acquainted
11:05mefisto`tbaldridge: try not to blame him too much, because he's half right. OOP was invented because FP was too difficult for some people to understand, and there was unmet demand for programmers
11:05dnolenmefisto`: I hope you don't really think that :)
11:07achengwhy not? mefisto`s just describing well-intentioned wrong people.
11:07gfredericksplausible != accurate
11:08dnolenacheng: "OOP was invented becausae FP was too difficult"
11:08achengtoo difficult for some
11:08gfredericksalso that part
11:08dnolenfar as I know, Smalltalk OOP (which is in wide use in various perverted forms), was created as a response to Lisp's special forms.
11:08dnolennothing to do w/ difficulty around FP or anything else.
11:08achengoh. ok
11:08gfrederickswhat's wrong with special forms?
11:09achengnothing :)
11:09dnolengfredericks: nothing, but nobody at the time had a good answer why we needed them.
11:09hyPiRionYeah, it's not like people say "Oh, this is too hard! Let's invent something easier" and then magically came up with OOP.
11:09gfredericksdnolen: as if you can have a language with no primitives? :/
11:09dnolengfredericks: so Alan Kay et al looked at messages.
11:09tbaldridgeAnd SmallTalk is not very much like what the Java/C# people think it is.
11:09hyPiRionBut OOP was a concept which was easier to understand for imperative programmers.
11:10hyPiRion(I suppose?)
11:10mefisto`dnolen: Well, only sort of. But OOP allows you to substitute a large number of easy to understand problems (tracking down where some variable is getting changed or some little bug is happening) for the smaller number of hard to understand problems (really understanding the algorithm and modeling the problem properly). So I guess I'm really talking about why OOP became popular for business programming rather than why it was invented :D
11:11dnolenmefisto`: hyPiRion: these arguments don't really make that much sense considering the amoutn of pushback there was too OO in the 80s, the slowness of C++ etc.
11:11dnolenOO wasn't taken seriously by the mainstream until the mid 90s I'd say.
11:12wkellywhen craziness ensued with STL and java
11:13mefisto`yeah, I wonder if that wasn't just a function of tooling and platform maturity
11:13tbaldridgeAnd even Alan Kay didn't mean for OOP to end up like Java. To quote him "Erlang looks like almost what I've been talking about since the mid-60s, I wonder how I missed it for so many years?"
11:13scriptoror marketing ;)
11:14scriptorwhen did java become the defacto language for cs curriculums?
11:14scriptorbecause I wonder how much of a cause it was for OOP popularity vs how much it was a reaction
11:14mefisto`scriptor: somewhere in the 90s is when that really started, from what I heard
11:15achengscriptor: at MIT it felt like a reaction
11:15ohpauleezScriptor: Yeah, later 90's it started to get picked up. Early 00's it was pretty well established - mostly because other school started doing their research in Java
11:16scriptoracheng: how long ago? I know they continued to use scheme until a couple years ago for sicp, but I don't know about their other courses
11:16ohpauleezso if you wanted to build off of it, or interop with it, you also had to use Java, and if you wanted your lab to be well established in Java, you used it as the intro language
11:16scriptormefisto`: ohpauleez: ah, thanks, so it sounds pretty reaction-y
11:16ohpauleezAt Drexel, you learned Java, Python, JavaScript, C++, and a little Common Lisp
11:17achengscriptor: there were classes using java, maybe in 96-97
11:17ohpauleezScriptor: it's a reaction to the fact that some DOD and DOJ bids HAD to be in Java
11:17jcromartieWas the adoption to OOP really a reaction to FP? I don't think so.
11:17jcromartie"adoption of"
11:18scriptornot reaction to FP
11:18mefisto`I think the less prestigious schools just picked up java because the top schools started using it, but more because it was becoming the most popular enterprisey langauge
11:18jcromartieNobody had heard of FP when they were picking up OOP in the industry…
11:18scriptorwell, I was talking about adoption of java in school as a reaction to OOP and Java popularity rising
11:18jcromartieah yeah
11:19jcromartieit reminds me of "if we evolved from monkeys, why are there still monkeys?"
11:19scriptorheh
11:20borkdudebecause they also evolved from monkeys we evolved from?
11:20pipelineafaik modern OOP came from an older OOP that was built around message passing
11:20scriptorwe didn't evolve from monkeys ;)
11:20achengthe universe could have been created 2 seconds ago and we wouldn't know the difference :-P
11:21borkdudeacheng most git repositories histories are fake too, just for messing up with people's understanding of it
11:21achengadam and eve stood next to a tree... did it have rings? :-P
11:22tbaldridgeacheng...that's actually close to the truth. See, the universe is immutable. So what we see as reality now is just a copy of the universe as it was a microsecond ago, with certain parts replaced. This sounds expensive, but the universe uses some interesting trie structures so it's all not that computationally expensive.
11:22tbaldridge:-P
11:22achengfirst saw message passing in lisp with sicp
11:23TimMcNah, the universe is mutable. It has some nasty race conditions, too.
11:23jcromartie(inc tbaldridge)
11:23lazybot⇒ 1
11:23scriptortbaldridge: so you're saying that the day we verify string theory is the day FP becomes faster than C?
11:23TimMcThere isn't even a universal clock, just local clocks that are always going out of sync.
11:24achengif C code tends to be buggier, then FP is faster
11:24borkdudehistory is mutable, just study the history of writings about WW2 for example
11:25jcromartieI was just thinking last night: I think it's impossible to create a computer to simulate the universe in real time
11:25jcromartiei.e. all the particles
11:25uvtcTimMc, sounds like time in fast-moving threads runs slower relative to slow-moving threads. :)
11:25jcromartieand I don't mean that it's impossible today
11:25jcromartieI mean ever
11:25mefisto`jcromartie: only impossible if you care about it being accurate :D
11:25borkdudejcromartie you don't say?
11:25scriptorjcromartie: I think there's an smbc comic about that
11:26jcromartieyou could simulate a smaller universe
11:26achengthere is a computer that does that. it's God's mind (allegedly)
11:26borkdudejcromartie it could ir the behavior of the universe is like a fractal, according to a repeating pattern, maybe
11:27jcromartieacheng: and I think some sophisticated theology could make a solid argument there
11:27uvtcacheng, Wait, are you thinking of the Milliard Gargantubrain at Maximegalon?
11:28jcromartiewhen you zoom in enough, things just start flitting in and out of existence, effectively "off limits" to conventional observation
11:28jcromartieanyway
11:28achengit's how i think of free will and election :-P the author writes, the character chooses. i don't know Milliard.
11:28jcromartieI'd better be careful or I won't get anything done today
11:28borkdudehttp://en.wikipedia.org/wiki/G%C3%B6del's_ontological_proof
11:29jcromartieand of course, Gödel, Escher, Bach started all of this :)
11:30jcromartiefantastic book
11:30borkdudejcromartie I missed that part
11:30jcromartiegood for Lispers too
11:31jcromartieI just mean it started me thinking about the nature of information and the universe
11:32lynaghk`Is there a core fn to check if something is between two other things? E.g., (between? 5 [2 9]) ;=> true
11:32borkdudehow is the find-fn syntax in here again? ;)
11:32lynaghk`I can never remember the clojurebot syntax for looking up fns by arguments
11:32borkdude$find-fn
11:32lynaghk`yeah, right!
11:33borkdude$find-fn 5 [2 9] true
11:33borkdudesomething like that?
11:33lynaghk`clojurebot: help
11:33clojurebothttp://www.khanacademy.org/
11:33borkdude$findfn 5 [2 9] true
11:33lazybot[clojure.core/not= clojure.core/distinct?]
11:33borkdudehmm...
11:33clgvlynaghk`: how about ##(< 2 5 9) ;?
11:33lynaghk`$findfn [2 9] 5 true
11:33lazybot⇒ true
11:33lazybot[clojure.core/not= clojure.core/distinct?]
11:34lynaghk`clgv: yeah, I was thinking that. Just thought I'd check the enormity of clojure.core first =) thanks
11:34borkdudelynaghk` yes, the answer is not= :P
11:34borkdude,(doc <)
11:34clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically increasing order, otherwise false."
11:34clgvlynaghk`: depending on your semantic you should maybe switch to <= ;)
11:35borkdudeah monotonically increasing, I didn't know that!
11:35clgvborkdude: pairwise could be useful as well ;)
11:35borkdudeeven about the most simple of things there's something new to learn every day
11:35borkdude,(doc pairwise)
11:35clojurebotCool story bro.
11:36S11001001lancero: yes, all your promises will have values when you return from that
11:36borkdudeclgv what's that
11:36clgvnot a clojure function ;) nvm
11:36scriptor,(-> 5 (< 2 9))
11:36clojurebotfalse
11:36borkdudeNice, Clojurebook 50% off today (ebook): http://shop.oreilly.com/category/deals/best-of-oreilly-dotd.do
11:37scriptorargh
11:37scriptor(-> 2 (< 5 9) doesn't seem as clear
11:37borkdude,(macroexpand '(-> 5 (< 2 9))
11:37clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
11:38scriptorborkdude: it makes it the 2nd argument
11:38jcromartieborkdude: is it worth getting that book? I feel like Clojure moves too fast
11:38borkdudescriptor anyway, it expands to (< 5 2 9)
11:38scriptorso it'd be (< 5 2 9)
11:38zoldarIs it possible and reasonable to use different url patterns based on server name in scope of a single django project?
11:38borkdudejcromartie yes, get it
11:39jcromartieif I buy the ebook do I get updates?
11:39S11001001,(partition-all 2 1 [1,2,3,4,5]) ; clgv, pairwise
11:39clojurebot((1 2) (2 3) (3 4) (4 5) (5))
11:39borkdude"Ebooks from oreilly.com are DRM-free. You get free lifetime access, multiple file formats, and free updates."
11:39zoldaroops
11:39jcromartieyeah
11:39zoldarsorry
11:39S11001001jcromartie: yes (generally for o'reilly), but not new editions
11:39jcromartieI just wonder if that encompasses editions
11:39jcromartieoh, OK right :)
11:39jcromartiestill a good deal
11:40foxdonutnever bought an ebook at more than 50% or 60% of the retail price
11:40borkdudejcromartie I like it, I have the paper version as well, but I read it from my screen most of the time anyway..
11:40foxdonutor more clearly, at least 40% off, most often 50%
11:40uvtclynaghk, (defn between? [x a b] (and (< x b) (> x a)))
11:41metellusthat gets messier if you also want it to work for (between? 5 [9 2])
11:41TimMc(< a x b)
11:42uvtcTimMc, ah, missed that. Thanks!
11:42TimMcThe more interesting case is when you want a half-open range: (and (<= a x) (< x b))
11:42borkdude,(apply (fn between? [x a b] (< a x b)) 5 [2 9])
11:42clojurebottrue
11:43borkdudeTimMc this begs for a macro...?
11:44cemerickborkdude: thanks for linking people up :-)
11:44borkdudecemerick what do you mean, linking up? ;)
11:44scriptorborkdude: why a macro?
11:44lanceroS11001001: why? Using printouts I can see that the function starts blocking during the sixth element (waiting for the first element to be reliazed), then continues to deliver the rest of the elements and returns. The last 5 elements should still be sleeping when the function returns (I mean this is the behaviour that I'm trying to create).
11:44cemerickborkdude: RT'ing the oreilly link here
11:45borkdudecemerick sure!
11:45TimMcborkdude: A fn will do.
11:45scriptorright, a macro might introduce unneeded complexity
11:45S11001001lancero: you delivered 5 immediately, all at once, then slept long enough for them all to finish
11:46borkdudeTimMc what if you have a half open range, like: [-2,2[, it would be nice if you could check for that with this short notation? well, maybe too complex to be worth it, I realize
11:46TimMcThat wouldn't even read. :-/
11:47borkdudeTimMc that is the mathematical notation I learned at high school
11:47borkdudeTimMc -2 is included, 2 is excluded
11:47scriptorit's invalid clojure, unfortunately
11:47borkdudescriptor TimMc I said "like", not "exactly this notation" :P
11:48borkdude(is-in-range? x (range -2 2))
11:48borkdudeforget it :P
11:49scriptorcould try (between? 2 [-2 2 _])
11:49borkdudea math dsl would be appropriate if you use it very much
11:49borkdudefor convenience
11:50scriptorand have it so that 3 arguments makes it exclusive for the max
11:50TimMc(map (partial inside? (range-co -2 2)) [-3 -2 1 2 3]) => [false true true false false]
11:50TimMcco = closed, open
11:51borkdudeTimMc the normal range is already closed, open, but it contains only integers
11:51TimMcYou could have a whole lib for ranges: Membership, union, etc.
11:51borkdudeTimMc yes, maybe it already exists in incanter or smth?
11:51borkdude(never used incanter really)
11:52scriptorthere's probably something like it in haskell
11:53TimMcborkdude: Oh, incanter is a good bet.
11:53kremlonwtf is clojure
11:53borkdudekremlon your next addiction
11:53foxdonutborkdude: :)
11:53kremlonhope so
11:53bhenryhow can i make a &nbsp; in clojurescript without it being escaped and displayed in the browser?
11:53foxdonutnext thing you know, you're reading a novel and you think "closure" has a spelling mistake.
11:53TimMc"I'm sorry, Bill, I just need clojure."
11:54foxdonutshe said in response to "how about going out with me for a Java?"
11:54jcromartieloving the DRM-free ePub
11:55TimMcjcromartie: The only kind worth buying. :-)
11:55jcromartiekremlon: someone needs to make an introductory "WTFAQ"
11:55foxdonutlol
11:55TimMcjcromartie: Isn't clojure.org just that?
11:55llasramWell, any EPUB can become DRM-free with a little elbow grease...
11:55borkdudeclosure means 1) google closure, 2) a spelling mistake for clojure and 3) a function capturing its environment, in that order for me
11:55kremlonlol do u geise get that question alot
11:55scriptoris the oreilly clojure book easy to read on smaller kindle?
11:55jcromartieclojure.org is for people who can learn by reading man pages
11:55TimMcI'm pretty sure I'm not a geese.
11:55foxdonutjcromartie: that is just too funny. what the FAQ?!
11:56jcromartiescriptor: I shy away from tech books on Kindle… they never fit right, code looks awful, etc.
11:56borkdudejcromartie I tried clojurebook on kindle and it's doable
11:56scriptorjcromartie: yep, some books work alright though
11:56scriptoras long as the code samples are short
11:56borkdudejcromartie but wth man, you always want a REPL close to your book for trying it out
11:56TimMcbhenry: Sounds like what you want is either non-HTML-encoded output or a NBSP character.
11:56foxdonutscriptor: I don't know about the kindle, but my sony reader uses epub, and epub is just html+css in a zip file, so I totally hack mine to use the fonts that I want :)
11:57bhenryTimMc: any way for me to put an empty html tag that won't lose its shape for being empty
11:57scriptorfoxdonut: ah, neat, my biggest issue with tech books on an e-reader is that they're never wide enough
11:58jcromartieborkdude: yeah, but I like the iPad because I can at least pick it up and sit on the couch if I don't need a REPL
11:58jcromartieand touch controls for reading
11:58jcromartieI hate reading on a monitor
11:59foxdonutscriptor: sure. some tech books don't work well. it depends. novels are best on the e-reader. I still hack the fonts though :D
11:59scriptorfoxdonut: hah, yep, novel's are so much easier to fit to the screen
12:00scriptorI have 80 minutes of commute time, so I'm toying with the idea of using some of it for technical books
12:00scriptorin addition to novels
12:00borkdudeI like novels on the kindle, but also non-fiction non-tech books (lots of text, no code, big pictures)
12:01borkdudeclojure literature is better suited for small screens though, the code is usually more compact
12:01scriptortrue
12:01borkdudewhy don't they make e-readers a bit bigger I wonder though
12:01scriptordon't they already do?
12:01llasramfoxdonut: That's funny -- I do that too, re: ebook fonts. I have this pipeline using a custom-hacked version of Calibre from back when I used to contribute to it which basically auto-reformats most stuff I read
12:02scriptorkindle fire is an inch bigger, which isn't much I guess
12:02borkdudescriptor fire isn't e-ink
12:02Wild_CatKindle Fire is LCD though. It's meh.
12:02scriptoryea :/
12:02scriptorDX is 9.7, but way too expensive
12:02borkdudescriptor there are some bigger models, but one company who made that is now bankrupt :(
12:03Wild_Catfor reading novels though, I'm totally in love with my Kindle Touch.
12:04Wild_Cat...although I am sort of disappoint that the Kindle version of A Dance With Dragons doesn't come with a map of Westeros.
12:05scriptoris the resolution good enough to support a map like that?
12:06Wild_Catscriptor: it's 600x800, landscape mode should do the trick.
12:06zoldarscriptor: I've got one DX under a thin cover of dust - sadly in current conditions I can't use it - do my reading mostly from phone with 4.2" inch screen - far from the eink comfort but must put up with that.
12:06Wild_Catit's working okay for the map at the beginning of Greg Rucka's "Alpha" (which I'm currently reading), at the very least.
12:07Wild_CatI mean, it's not ideal, but it's better than no map :p
12:12zoldaralso, with DX it's beter to read with support for arms. It get's quite heavy on arms when holding it in air for example when lying on bed
12:12zoldar*gets
12:14borkdudefor novels I'm quite happy with my kindle touch, I get the impression that I read faster than on paper
12:14borkdudebecause turning pages is effortless
12:15borkdudethis is off topic, but novel reading can sometimes be very important for programmers to keep sane ;-) @technomancy
12:15technomancyFSVO sane
12:18technomancyI'm bummed they dropped the analog scroll wheel that's in the v1 kindle
12:18technomancythat's one of my favourite parts of the design
12:24borkdudetechnomancy no need when touch screen right?
12:25technomancyborkdude: depends on the refresh rate. the scroll wheel has a realtime indicator that lets you make selections without being tied to the e-ink screen for input feedback
12:30dnolenEuroClojure core.logic video is out, http://twitter.com/euroclojure/status/220185504744878081
12:40jcromartieman, this guy… the last word is "As for lisp, I'm a mediocre programmer, so don't plan on using lisp.... :-/"
12:45gfredericksjcromartie: you're reading something?
12:45jcromartieno just a conversation with a recent hire
12:45gfredericksah right
12:46tbaldridgeI don't understand why someone wouldn't want to self improve, that seems so backwards.
12:47technomancyI find it kind of refreshing for someone to admit they're not so hot.
12:47technomancybeing OK with staying that way, not so much though.
12:47gfredericks"I'm a mediocre programmer, so I intend to stay mediocre"
12:48gfredericks^ non-sequitur?
12:52gfredericksof course if it's just a job then it's hard to fault the person
12:52gfredericksas a person at least; maybe not as an employee
12:53tbaldridgeeh...I disagree though. There's an apathy I've seen in the programming world. People accept that Java is all they'll ever be able to use, so the learn java, and just deal with the crap day in and day out.
12:54gfredericksbut if they're not doing it for the love, what does it matter? as long as they're employed.
12:54technomancyyeah, but maybe his passion is to write a novel in the wee hours of the night and he writes java to pay the bills.
12:54tbaldridgeSo for instance, here at work, I complained that our serializer was slow. The response I got was "eh...it uses .NET's serializer, it works...if you think you can do better than MS, try...hahaha...."
12:55gfredericksas long as the industry is booming you can't expect everybody to be an idealist
12:55tbaldridgeBut for me, I couldn't take that, so I rewrote it using multimethods (ported to C#) and code generation, and the new serializer is about 20x faster and produces data 1/10th the size.
12:56zoldartbaldridge: what was their reaction?
12:56tbaldridgeWe use it in production right now ;-)
12:57S11001001wait, tbaldridge, did someone suggest that doing better than ms would be difficult, in earnest?
12:57foxdonutllasram: that's very cool! (custom calibre to format your ebooks)
12:57tbaldridgeoh yes, yes they did.
12:58uvtctbaldridge, zoldar asks an interesting question though. "What was their reaction?" That is, at some places, you might get, "did you do this on company time? Were you asked to do this?" etc.
12:59foxdonutI'm interested in the reaction as well
12:59uvtcMy point is, sometimes doing things one better isn't rewarded, and so that behaviour isn't selected for among sucessful employees...
12:59zoldaruvtc: that's what I wanted to ask, but due to my crap english I couldn't put it into words
13:00tbaldridgeuvtc: well we ended up hitting a brick wall at one point. Loading data for a certain project was crashing .NET because the to serialize 20k records it was taking 700MB. So I developed in my spare time (on company time) and presented it as "look, now it doesn't crash, it's way faster, and we can actually send these datasets over the internet".
13:00tbaldridgeThat's about all it took to convince them.
13:02mabesthat is probably the key point.. if the company didn't need a faster serializer then they may have still used the slower MS one due to maintenance concerns
13:02tbaldridgeBut what irks me is that no one even thought enough about the process to say "hey...maybe XML serialization isn't best here". No it was "this framework has existed for 5+ years, let's just use that and slap a ORM on to it, and barf it all up on the UI, and YAY! we're done!"
13:02uvtctbaldridge, Ah, so in this case it was indeed solving a concrete problem the team was facing.
13:02tbaldridgeuvtc: exactly
13:03zoldartbaldridge: maybe that's something for a success story blog post material ? :)
13:04tbaldridgeperhaps
13:06zoldarespecially that it leverages the not (yet) so common platform for clojure
13:06tbaldridgebut back to the original topic, I have to wonder sometimes if we teach people to be too apathetic, Java/C# is so complex that people don't have time to do anything but read up no the latest features of IIS, EF, Spring, etc.
13:07tbaldridgeAs I told a co-worker the other day: "I really don't care to know where IHttpHandler fits into the IIS stack vs IHttpModule..." When simplify the web server down to a few functions (like Ring does) suddenly we have more time to think about things that really matter.
13:08tbaldridgeAt least that's my idea </rant>
13:09Jayunit100Wow this reduce word-count function is really slow : http://pastebin.com/raw.php?i=2X5UaTG3 … I'm not sure why though. any insights? Im using let with assoc to bind new words into a map and increment their count iteratively.
13:11gfredericksJayunit100: why passing a single arg to assoc even do anything?
13:11gfrederickss/assoc/reduce/
13:11ohpauleezJayunit100: You also can get rid of that let and just destructure
13:12gfredericks&(doc reduce)
13:12lazybot⇒ "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as... https://www.refheap.com/paste/3429
13:12Jayunit100ah the reduce … yeah well it needs to sum
13:12ohpauleezthey pre clause can use `string?`
13:12gfredericksthere is no single-arg version of reduce
13:12uvtcJayunit100, what is that hash-map doing there underneath `[str_in]`?
13:12mhanson,(doc constantly)
13:12clojurebot"([x]); Returns a function that takes any number of arguments and returns x."
13:13Jayunit100the hash map is counting words
13:13ohpauleezuvtc: it's how you do constraints/contracts in Clojure
13:13foxdonuttbaldridge: what was the reaction from "haha you will never be able to do it" to "here, I did it" ?
13:13Jayunit100so, it assocs a new word to the hash map every time it sees one
13:13uvtcohpauleez, Oh, don't know about those yet. Thanks. :)
13:13Jayunit100and (inc)s it the 2nd time, 3rd, etc....
13:14Jayunit100so if input is "a b b" the output is {"a" 1,"b" 2"{
13:14ohpauleezJayunit100: You can use group-by
13:14gfredericksor frequencies
13:14gfredericks,(frequencies ["a" "b" "b"])
13:14clojurebot{"a" 1, "b" 2}
13:15zoldar,(frequencies (map str (seq "a a b")))
13:15clojurebot{"a" 2, " " 2, "b" 1}
13:15Jayunit100UHOH ! :)
13:16Jayunit100well… i wrote the code for pedagogical purposes so I'm still curious about why it is slow.
13:16Jayunit100but thanks everybody for your help. Im wondering -- is there anything truly unidiomatic in the function that i pasted ?
13:17ohpauleezJayunit100: Turn the let to destructuring
13:17ohpauleezThe pre should use string?
13:17dnolenJayunit100: "slow" for what size input and compared to what?
13:17ohpauleezbut no, using reduce to build up collections is standard
13:18tbaldridgefoxdonut: the reaction was "heh...good job". I don't think it really sunk in that we had something really usable until the framework we use (CSLA.NET) decided to accept my patch (or the ideas behind it) and use them by default in the framework.
13:18Jayunit100it must be the let, that is taking a while.
13:18Jayunit100so how does reduce optimize creating a new map over and over agin ?
13:18Jayunit100(i.e. how does reduce optimize assoc)?
13:18pbostromJayunit100: there is also reduce-kv
13:18dnolenJayunit100: it doesn't optimize assoc
13:19Jayunit100Is it a "bad" idea to do an assoc in a reduce where we expect a large number of elements in the [ ] ?
13:19dnolenJayunit100: no
13:19uvtcpbostrom, reduce-kv?
13:20pbostromhttp://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reduce-kv
13:20uvtcpbostrom, Oh, whoops. Didn't see it on clojuredocs, but it's here in my repl.
13:20uvtcpbostrom, thanks.
13:21pbostromI believe that might provide some optimization, but I'm just guessing
13:22foxdonuttbaldridge: wow..well done!
13:23Jayunit100how does assoc implement performance under heavy insert load given the immutability constraints of clj ?
13:24S11001001Jayunit100: structure sharing
13:24gfredericksJayunit100: I think you use transients if you can't bear the immutability overhead
13:24Jayunit100ah ok
13:24jweissany slimv users know if you can do the equivalent of kill-sexp?
13:26dnolenJayunit100: without explaining what kind of performance you're looking for, or without any extra information about how you are running your environment (JVM server setting etc). it's really hard to say anything meaningful in response.
13:26dnolenJayunit100: are you expect it to be 2X faster? 4X faster? 10X faster?
13:26uvtcJayunit100, re. your word-enrichment func; personally, I usually like using the fn form instead of the function literal #() --- so that you can give your parameters descriptive names.
13:28nDuffJayunit100: ...in a lot of cases, the immutable types are fast enough -- they *don't* involve full copies.
13:30scriptordoes it still use copy-on-write for small numbers of assoc?
13:30dnolenscriptor: yes
13:40tbaldridgecemerick: ping
13:41lynaghkdnolen: re: TODO, thanks. Any suggestions for cleanup before I submit it to the wider JS world?
13:42dnolenlynaghk: hmm not really, though I expect it to be thoroughly misunderstood
13:42lynaghkdnolen: heh. I'm still trying to train myself out of the OO/MVC mindset a lot of the time.
13:43lynaghk"This is simple. Too simple. I must be doing something terribly wrong."
13:43brainproxylynaghk: what are you about to unleash on the world?
13:43dnolenlynaghk: it could get a lot simpler ...
13:43dnolenlynaghk: I'm realizing that JS MVCs are just queries+databinding, not much else.
13:44scriptora lot of people won't be used to cljs's mutability primitives, so you'll see complaints about that
13:44dnolenlynaghk: I'm looking forward to to getting the DB functionality of core.logic working under CLJS - then you can run arbitrary queries over indexed data.
13:44dnolenlynaghk: instead of this linear filtering crap
13:44lynaghkdnolen: yeah, I'd be all about that.
13:45lynaghkbrainproxy: Todo app written in cljs using C2's new databinding stuff: https://github.com/lynaghk/c2-demos/tree/master/todoMVC
13:46dnolenlynaghk: also thinking it would be cool to support using raw JSON as the data source instead of converting into CLJ data structures.
13:46lynaghkdnolen: You can get core.logic to work directly against an array of js objects?
13:46brainproxylynaghk: sweet!
13:47dnolenlynaghk: core.logic can unify anything so I don't see why not.
13:47scriptorwhat does bind! do?
13:47brainproxyi know i've asked this before, but I want to get into the core.logic stuff, but I feel a bit lost; recommendations for getting up to speed when armed w/ general knowledge of clojure but no logic prog experience
13:47brainproxy?
13:48lynaghkdnolen: I think that would be pretty powerful. I'm not sure how well that would work for doing actual data manipulation in CLJS though---i.e., if you want to change the underlying data. You'd need to drop to aset, no?
13:48dnolenbrainproxy: it's an up hill battle - and then it seems so simple ...
13:48dnolenbrainproxy: it's worth investing in a good Prolog book + The Reasoned Schemer
13:48brainproxymeaning links to books, ebooks, tutorials that help one to dive in, but don't require a B.A. in math
13:49lynaghkscriptor: there's a bit of explaination in the release announcement: https://groups.google.com/forum/?fromgroups#!topic/clojure/KCe96DbMD6k
13:49brainproxydnolen: i tried looking at the minkanren dissertation, but the learning curve seemed n^n
13:49scriptorlynaghk: ah, nice, was just about to suggest something like that announcement
13:49TimMcbrainproxy: Fast, then?
13:49TimMc:-)
13:50Jayunit100dnolen: good point. well…. this whole thing came from an experiment - i wanted to see if (reduce) with (assoc) would indeed be "fast".. by fast, i mean that its O(n) time would be steady as the # of words increased. Indeed, it did. I just was having some fears that it wasn't "fast enough". But now, after benchmarking it against standard java/maps and another clojure impl, I'm pretty happy :)
13:50dnolenbrainproxy: yeah, requires a couple of reads. The Reasoned Schemer + Prolog book. Then some head-scratching, then try dissertation again :) and only chapter 3.
13:50dnolenJayunit100: well there you go :)
13:50scriptorlynaghk: before releasing it to the js world, just make sure to explain some of the more clojure-y bits, mutability, dereferencing, destructuring, and the templating
13:51brainproxydnolen: recommendation for prolog books?
13:51brainproxyfree, paid, out of print, whatever
13:51lynaghkscriptor: I've been meaning to just ping the TodoMVC guys and see what they think about including such a black sheep.
13:51Jayunit100dnolen: . thanks for your help. I believe you were the one that said "tools don't mean s**t without a good community"… and the clj community is always there for me in times of despair :)
13:51lynaghkscriptor: but yeah, I've been thinking about this kind of stuff for a bit. I'm giving a talk at OSCON in two weeks about this compared to MVC, so I'll probably record a screencast and get everything written down.
13:52dnolenbrainproxy: Bratko Prolog book (new edition!) or Sterling Shapiro Prolog
13:52scriptorlynaghk: one other recommendation is that I'd make another very simple js app and see how much code you can share between the two
13:53scriptorlynaghk: but I remember you mentioning that it gets rough when you factor in edge cases, still, one major complaint will be what it offers over plain js :)
13:53lynaghkscriptor: Not sure what you mean / what that would show. Whenever something seems useful to share between apps, I put it in a library.
13:55dnolenlynaghk: I think it could work fine with most JS MVC workloads, I think the whole datomic DB as value thing could work well and be efficient for many use cases.
13:55lynaghkdnolen: think you could find some time to write the TodoMVC data fns in core.logic?
13:55dnolenlynaghk: most JS MVCs require cloning anyhow ... so it possible we could do better ...
13:56pbostromare there any plans to add (:require ... :refer ...) to cljs?
13:56dnolenlynaghk: yes, gotta wrap up this other core.logic stuff first ... but beefing up CLJS core.logic is on the list
13:56dnolenpbostrom: it's already there.
13:57dnolenpbostrom: well in master, perhaps not in a release
13:57lynaghkdnolen: cool. I worked through the reasoned schemer but the most advanced example was building some bit-manipulation adding circuits, and I didn't have the energy to try and work from that to something closer to my day-to-day domain.
13:57pbostromah, ok, thanks, I guess it hasn't made it through to cljsbuild (still a little unsure of the relation between versions of those 2)
14:00scriptorlynaghk: well, let's start with this, how *is* it better than plain (non-mvc) js?
14:00scriptorbesides that it's in clojure :)
14:03dnolenscriptor: people use JS MVCs for a reason - it does control complexity in larger JS apps.
14:04scriptordnolen: right, so how does using cljs also control complexity?
14:04dnolenscriptor: having done both - IMO, yes.
14:05scriptorhow, exactly? The mutability primitives?
14:06dnolenscriptor: simpler notions of truth, sensible extensibility, namespaces, no aliasing, no pervasive mutability, useful sugar, recursive definitions, etc
14:07brainproxyanyone got an example of a cljs project using domina which makes heavy usage of XHR
14:09lynaghkscriptor: the biggest part for me is moving away from thinking of the DOM as some mutable thing that you want to hit with stuff (addClass, appendChild, ...) and starting to think of it as a plain data structure (e.g., Hiccup vectors). Write functions to transform your domain data to "view data", and then let the library handle updating the DOM for you.
14:10scriptorah, so representing the DOM in the same data structures that the language uses, that's pretty big
14:10clojurebotmake a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive
14:10dnolenscriptor: oh, unified iteration for all types, and protocols prevent API proliferation / incompatibility also big.
14:10lynaghkscriptor: yeah, because you can use your actual programming language in that case. Not some janky franken-handlebar-js-html crap.
14:10scriptorhehe
14:11lynaghkscriptor: I wrote Singult to be usable from plain JS, and I'm interested to see if anyone actually tries using it out from there since that idea---treating your view as just another data structure---isn't Clojure-specific.
14:11lynaghkThough, like dnolen says, there's also a ton of great shit in Clojure =)
14:11scriptorwait, singult can be used from native js?
14:12scriptorholy shit, that's pretty awesome
14:13lynaghkscriptor: yeah, JavaScript has Arrays and Objects, so you can play the Hiccup game there too.
14:13lynaghkYou just need a hell of a lot more commas =P
14:13goodiebo_how do you write (append) to a file in clojure?
14:13borkdudegoodiebo_ http://stackoverflow.com/questions/7756909/in-clojure-1-3-how-to-read-and-write-a-file/7757674#7757674
14:14goodiebo_ha geez, thanks!
14:17scriptorlynaghk: bind! seems to solve the problem of binding data to view data structures really well
14:18lynaghkscriptor: checkout the source. it's just using computed-observables (from the Reflex library) and merge (from Singult).
14:18scriptorso, when you release this more widely, I'd definitely stress that clojure's forcing you to constrain mutability to only what you must mutate means that you can easily listen for changes
14:19lynaghkcomputed-observables are pretty simple, and handy for data stuff too.
14:20scriptorI think knockoutjs is the only other tool that does a similar thing in js
14:21ohpauleezScriptor: As a corollary, a lot of my CLJS apps deal with stream data and a specific process
14:21ohpauleezso something like enfocus works great for me
14:22ohpauleezwhere I want to take one piece of a the DOM (like a container) and represent all of my search results in there
14:22ohpauleezwhere my search results from from a JSONP request to a different server
14:22scriptorgot it
14:23dnolenscriptor: I refuse to use anything with the word Model in it anymore when it comes to JS.
14:23scriptordnolen: agreed :)
14:23ohpauleezbut it requires me to wire up my apps differently, so I use a lot of pubsub stuff
14:24scriptorI sent out a long email to the dev list this morning that basically amounted to "hashmaps are better than models"
14:24lynaghkscriptor: yeah, knockout is where I took the computed-observable idea from. The implementation too---they did a great job of design documentation.
14:24ohpauleezthe misunderstanding of (or perhaps overuse of) "model" and MVC is laughable
14:25ohpauleezand a little annoying
14:26ohpauleezso I'm with you guys
14:44mhansonAnyone else see that ebook Clojure Programming is half-off today?
14:47borkdudemhanson it has been noted, but can not be overemphasized
14:47mhansonHah. Excellent.
14:48tbaldridgemhanson: is that through O'Reily?
14:49mhansontbaldridge: Yep.
14:49tbaldridgehrm, I'm not seeing the 50% off part...
14:49mhansonI believe the discount code is "deal".
14:50mhansonIf you go to the shop front page, it's under the daily deals section.
14:50tbaldridgeah yeah, discount code
14:50mhansonBut yes, on the actual book page that is not reflected.
14:51tbaldridgecool, thanks, I think I'll pick it up
14:52ptambalahi
14:52ptambalaare you talking about Clojure Programming or Programming Clojure?
14:52foxdonutthe former
14:52ptambalaok, I'm currently reading Clojure Programming.
14:53foxdonutthe latter has a 2nd edition out, btw.
14:53ptambalayep, I saw this
14:53ptambalabut I don't like the swan on the cover, so I'm not really tempted to buy it :)
14:54borkdude=)
14:54johndeoI'm reading it now. It is good.
14:54borkdudeI don't like the clojure logo, so I will stop using clojure
14:55ptambalaok
14:55ptambalaI was thinking about buying a 2nd book, and I was thinking about Joy of Clojure, dunno
14:55borkdudeptambala http://stackoverflow.com/questions/2578837/comparing-clojure-books
14:55ptambalaso many choices...
14:55ptambalaoh thx
14:57foxdonutptambala: JoC probably has the least overlap with CP
14:58johndeoDatomic looks super cool, but I'm hesitant about a cloud-only proprietary app for the DB. Should I be? Does someone have a perspective on this?
14:58technomancyjohndeo: seems reasonable to have hesitations about that
15:00ptambalafoxdoughnut: after reading the description JoC seems to be the right book indeed. thanks.
15:01borkdudeptambala can't go wrong with that one
15:04devnjohndeo: free for open source FWIW
15:06TimMc*gratis
15:16nDuffdevn: ...bah; "free-of-cost for open source" ~= useless
15:16nDuffalmost all the OSS work I do is backing commercial projects, and selling them on a for-pay database backend, however much better it may be, when there are more battle-tested Free ones available is basically impossible.
15:16dustingetzwhats the easiest way to make async http requests in clojure
15:17jsabeaudrydustingetz, jayq
15:17dustingetzeven from the server? not in browser e.g. not using cljs
15:18jbarriosI am hiring for backend engineering positions, if anyone's looking. We are starting to introduce Clojure into the mix.
15:18dustingetzlink to jobs page?
15:18jbarriosdigging it up now.
15:19jcromartiedustingetz: clojure-http-client
15:19vojdis there any clojure service out there i can point to, stating "THIS is a full fledged clojure app"
15:19jcromartieer never mind
15:19technomancyno don't use clojure-http-client
15:19jcromartiehow about https://github.com/neotyk/http.async.client
15:20jcromartiesorry :)
15:20vojdfor those colleagues and friends saying "but meh, clojure is just a research language right?"
15:20dustingetzhttp.async.client
15:20technomancyvojd: clojars
15:20technomancyclojurebot: success stories?
15:20clojurebotclojure success stories is http://dev.clojure.org/display/community/Clojure+Success+Stories
15:20technomancy^ if it doesn't need to be OSS
15:20vojdsuper :D thanks
15:20dustingetzfinal question, for mocking async queries, i basically want `(defn sleep-async [ms callback] …)`
15:20jbarriosdustingetz: here's one: https://sjobs.brassring.com/1033/ASP/TG/cim_jobdetail.asp?partnerid=25348&amp;siteid=5039&amp;jobid=42321
15:21dustingetznot exactly sure how to go about implementing that without having my own while loop
15:21dustingetzi want the OS to do the polling/eventing/reactor/whatever for me
15:21jcromartiedustingetz: you can use Thread/sleep
15:21dustingetzasynchronously?
15:21jcromartieput it in another thread :)
15:22dustingetzit gets really really complicated, i want the callback to happen in my main thread
15:22dustingetzim exploring continuations
15:22jcromartieI don't think it needs to be that complicated
15:22jbarrioshow about a future?
15:22dustingetzfutures imply threads
15:22jcromartieand futures block while they wait
15:23jcromartiebut it shouldn't be that hard to dispatch something on the main thread, right?
15:23jcromartiehm, yeah you'd need something like a run loop
15:23dustingetzi guess i can have a reactor loop on my main thread polling some cross-thread queue
15:23dustingetzbut this isn't how things look in real life
15:23jcromartieno
15:24scriptorwith clojurescript, are error line numbers mapped back to the original cljs yet?
15:24jcromartieyou can use exceptions
15:24jcromartie:)
15:24scriptorbut in the case of syntax errors and such?
15:25jcromartiedustingetz: this is your ticket http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html
15:26dnolenscriptor: nope, help welcome
15:26scriptordnolen: where would I start?
15:27dnolenscriptor: read up on SourceMap v3, once you understand the format it's pretty clear what needs to be done.
15:27dnolenscriptor: VLQ64 encode/decode already in a branch, so that part is done
15:28dnolenscriptor: but we need to write the code that can actually decipher a source map as well as generate one.
15:29scriptorwhere is the sourcemap project located? This/ http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
15:29jcromartieI love it when someone gets mad at me for not telling them something that I googled
15:30dnolenscriptor: that's the goto high level explanation, also links to the Google doc describing it.
15:31dnolenscriptor: another good reference is Mozilla's JS implementation, which also linked to.
15:32jcromartiehm, how the heck would I access this interface from Clojure http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html
15:33jcromartieah
15:33jcromartiehttp://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html
15:33amalloydnolen: i noticed that != doesn't seem to have the same "descend into lists" behavior that == does: https://gist.github.com/3042234 - is there a reason this isn't possible, or is otherwise a bad idea? (i think i'm still using != too much, but i was surprised this doesn't do what i expected)
15:35dnolenamalloy: what is suprising you there?
15:36amalloydnolen: i thought that x would fail to unify with [1 d], because c is 1 and i said x is not [c d]
15:37amalloyif i'd said (== x [c d]), then a and b would be in lockstep with c and b, respectively; but using != they seem to be entirely unconnected
15:37dnolenamalloy: ?
15:38amalloydnolen: i'll rephrase: i expected (!= x [1 d]) to mean: "x is not a two-element list whose first element is 1"
15:38dnolenamalloy: you say that (== x [a b]), then you unify a & c with 1, so (== x [1 b]), (!= x [1 d]) doesn't say anything - b has no value, nor d.
15:38dnolenamalloy: yeah that's not how disequality works.
15:39amalloyright. i've figured that much out, i was wondering why
15:39dnolenamalloy: != just means two terms should never unify, that's it. nothing more.
15:40dnolenamalloy: if you want your behavior you have to use firsto + !=
15:40amalloy*nod*
15:40amalloyokay, thanks. i'll come back to this when i understand more about the mechanics of unification
15:40amalloy(or not, since most of the time when i use != it's a mistake)
15:41dnolenamalloy: != is very useful - it's kind of a limited form of negation.
15:41dnolenamalloy: it really helps with conde where you want the clauses to be non-overlapping w/o resorting to cut (conda/u)
15:42dnolenotherwise all clauses get tried - which may not be what you want.
15:43amalloyyeah. actually, do you have a moment to look at http://stackoverflow.com/questions/11256242/solving-dinesmans-multiple-dwelling-example-using-clojures-core-logic-core-mat/11280559#11280559 ? my first implementation used conda and != in not-adjacento, and then i realized that was causing problems so i went back to conde and ==
15:44amalloyspecifically (not-adjacento x y l) is supposed to say "x and y are not next to each other in the list l", but i couldn't get that to work in a purely relational way, so i backed off to "x and y are both in l, separated by a gap of at least one"
15:49dnolenamalloy: looking
15:56ipostelnikwhat's the difference between (next) and (rest)?
15:56gfredericksexpressing negatives is pretty hard :(
15:56amalloy&((juxt rest next) [1])
15:56lazybot⇒ [() nil]
15:58gfredericksamalloy: x and y are from a finite domain?
15:59gfredericksmaybe I should read the SO thing first
15:59amalloygfredericks: in not-adjacento? in my first draft they were and it didn't really work; i think the current version works for any x, y, l
16:01gfredericksthis is assuming x and y occur exactly once?
16:01gfredericksman I like the vector syntax there; I've never seen that done
16:02amalloycurrently (not-adjacento 1 2 [1 1 2]) succeeds, because the first 1 is not adjacent to the 2
16:02amalloygfredericks: what vector syntax?
16:02uvtcipostelnik, for one thing, compare the output of `(next [1])` and `(rest [1])`.
16:02gfredericksall my code is a pile of parens
16:02gfredericks(conde [(...) (...)]) instead of (conde ((...) (...)))
16:02amalloyi didn't even know parens were an option
16:03gfredericksand vice versa
16:04ignaciois anyone deloying a ring app as a WAR file?
16:04gfredericksI've done that before I think
16:04gfredericksbut not currently
16:04ignacioI just have a question about resources in the file
16:04gfredericksyes?
16:04clojurebotyes is is
16:05TimMcclojurebot: forget yes |is| is
16:05clojurebotI forgot that yes is is
16:05ignacioi'm looking to preproces some of the files in resources :)
16:05ignacioi'm looking to preproces some of the files in resources
16:05gfredericksclojurebot: yes |isn't| is
16:05clojurebotRoger.
16:05TimMcWhat have you done?!
16:05gfredericksignacio: at build-time?
16:05ignacioand am going to copy the code out of ring.util.response/resource-response
16:05RaynesTimMc: It just occurred to me that I'm an idiot.
16:05ignacioactually, it can be at deploy time
16:05ignacioeither.
16:05ignaciobut not at request time
16:06gfredericksignacio: so a leiningen hook would be appropriate?
16:06ignacio(where i have a "servlet context" or some such)
16:06RaynesTimMc: You want to 'safe-require' a file. You can't do that with 'require'. You want to load the file yourself, pumping the code through a sandbox, right?
16:06gfredericksclojurebot: yes?
16:06clojurebotyes isn't is
16:06RaynesTimMc: You'll have to write your own thingy for that. Sorry for being so dense.
16:06amalloyclojurebot: forget everything, man. it's all too difficult
16:06clojurebotRickInGA: of course :-) *everything* is in Clojure
16:06ignaciowell,
16:06fenton1technomancy: Phil, what was the darker color theme you use for emacs again?
16:07ignacio@gfredericks: well, a leiningen hook wouldn't be totally appropriate, because i need access to the file contents when serving a response
16:07TimMcRaynes: I just want to load an entire namespace that someone hands me (as file, inputstream DB field, etc) and then safely call fns that are in that ns.
16:07gfredericksignacio: pre-processed or post-processed?
16:07ignacio(eg: imagine that i want to minify JS and then include it directly in the body of hte returned html)
16:07RaynesTimMc: Right, but you can't safely call a fn loaded with require unless you know it is safe.
16:07gfredericksignacio: I'm not sure why hooks aren't appropriate; in the hook, muck with your resources directory until you have it like you like it
16:08RaynesTimMc: You have to look at the defns first before you load them and not even let them load of they aren't safe.
16:08amalloyfenton1: i use tty-dark, if you want high-contrast really-dark
16:08Raynesclojail can't look inside of functions.
16:08ignaciogfredericks: then read the file using servlet-context?
16:08ignaciowould that be the preferred way?
16:08fenton1amalloy: thx, i'll try that....
16:08gfredericksignacio: I dunno, however you read resources
16:08TimMcRaynes: My outer code isn't going to try to use an actual :require block or anything, I'm speaking in analogy.
16:08gfredericksignacio: your app shouldn't have to care if the file was there before deploy-time or not
16:09technomancyfenton1: I use monokai and zenburn
16:09ignacioright, that's what i'm looking for: it seems that ring.util.response/resource-response will do exactly what i want, but i just want to verify that there's no security issue there
16:09TimMcRaynes: 1) Someone submits a .clj file 2) I load it into a sandbox (which might reject it), 3) I call a fn in that sandbox and get the results back.
16:10RaynesTimMc: Cool. That will work fine for you.
16:10TimMcsweet
16:10RaynesTimMc: If you write a safe-require function, send me a pull request and I'll put in clojail.
16:10foxdonuttechnomancy: is it molokai or is there a different one called monokai?
16:11fenton1technomancy: thank you!!!
16:11fenton1foxdonut: its monokai
16:11technomancyfoxdonut: it's this one: http://marmalade-repo.org/packages/monokai-theme
16:11TimMcRaynes: Could I keep the sandboxed ns around and periodically make timeout-limited calls into it?
16:12RaynesTimMc: Not sure I understand the question.
16:12foxdonuttechnomancy, fenton1: got it. sorry about the confusion. I didn't realize you were talking emacs. molokai is monokai port to vim :)
16:13fenton1foxdonut: ah ok.
16:13foxdonutfenton1: definitely one of my faves.
16:14TimMcRaynes: The .clj file (containing one namespace, as usual) represents a user-submitted bot that will compete against others. I'd like to load it up and then call it repeatedly over time with a game-state object so that it can make moves.
16:15RaynesTimMc: What if two people use the same namespace?
16:15TimMc...and I want a timeout on each of those calls. I'll have to set up my own timeouts for those calls, yes?
16:15nicholasfhi, I'm working through some clojure basics (with SICPs and 'Clojure Programming'). I have my lein repl open and am trying to define an anonymous function and pass it a number: https://gist.github.com/ada8e7fb1454afa8ee53
16:15nicholasfshouldnt this work?
16:15amalloy&((fn [x] (+ 10 x)) 8)
16:15lazybot⇒ 18
16:15RaynesTimMc: The sandbox will timeout for you.
16:16RaynesBut still, I'd be worried about namespaces.
16:16nicholasfamalloy: ok thanks
16:16TimMcOh, hmmm.
16:16amalloynicholasf: sure should work in the repl, yes
16:16amalloythe & is just asking the bot to eval it for us, not part of clojure syntax
16:16nicholasfok it's not working in my repl, so that must be what's wrong here
16:16uvtcnicholasf, Are you using Leiningen to create a project and start a repl in it?
16:16nicholasfyeh, it's definitely my lein repl
16:17fenton1foxdonut: yeah, i liked it...phil's got good taste ;)
16:17nicholasfamalloy uvtc I just tested it in my clj repl (homebrew repl project) and it worked
16:17nicholasfso I was assuming that 'lein repl' worked anywhere I typed it, like a regular repl
16:17amalloynicholasf: i wonder if you've accidentally redefined the 'fn macro
16:17amalloysince i can't think of any other way you'd get this behavior
16:17TimMcdef fn
16:17nicholasfamalloy: I think Ive just gone to any directory and used lein repl, and it hasnt found important class files in the background
16:17TimMcThat might do it.
16:18nicholasfk cheers guys
16:18amalloynicholasf: i don't think so. you'd get failures long before this, if something this fundamental were broken
16:18uvtcnicholasf, right. You need to run it from your top-level project dir.
16:18TimMclein repl will work anywhere, it just might give you a random version of clojure.
16:18amalloyare you guys all crazy? lein repl works anywhere
16:18foxdonutfenton1: no doubt he does. there is also Tomorrow that you might find nice.
16:18nicholasfamalloy: I think lein even requires clojure for you, so if I'm opening lein in a dir without clojure, it wont be able to evaluate basic stuff
16:19amalloynicholasf: humor me: if you just type (without quotes) "fn" into the broken-looking repl, what do you get?
16:19uvtcamalloy, Whoops. I suppose so. I didn't know you could just run `lein repl` in any old directory.
16:19TimMcnicholasf: Run lein repl anywhere and execute this: *clojure-version*
16:19nicholasfamalloy: https://gist.github.com/4616b766bb428a4d4d0b
16:20amalloybut i bet in that repl your ((fn [x] (+ x 10)) 8) construct works
16:20nicholasfuser=> *clojure-version*
16:20nicholasf{:major 1, :minor 2, :incremental 1, :qualifier ""}
16:20fenton1foxdonut: I'm on the road and having trouble loading the color theme, what is it again I need to throw into my .emacs?
16:20nicholasfit only works if Im doing it in a lein project directory (that I've run deps in)
16:22uvtcnicholasf, which version of lein are you using? Run: `lein version`
16:22nicholasfLeiningen 1.7.1 on Java 1.7.0_05 Java HotSpot(TM) 64-Bit Server VM
16:22foxdonutfenton1: sorry friend, I don't know :( I use vim
16:23raeknicholasf: is that paste *exactly* what you typed?
16:24nicholasfraek: yeh
16:24foxdonutfenton1: source is here if it helps: https://github.com/chriskempson/tomorrow-theme
16:24fenton1foxdonut: ok, i'll keep looking...I look into tomorrow after i get *any* theme working!
16:25RaynesWhat theme?
16:25raeknicholasf: and if you try running `lein repl` outside a project (which is supposed to work), does the problem still occur?
16:25Raynestomorrow?
16:25RaynesIf you're using Emacs 24, just put the latest tomorrow themes somewhere and then (add-to-list 'custom-theme-load-path "/path/to/dir/with/themes") and then (load-theme 'that-theme t). For tomorrow, it'd be (load-theme 'tomorrow-night) or whatever tomorrow varient you want.
16:25Raynesfenton1: ^
16:25nicholasfraek: that is what I'm doing in the gist. If I run lein repl in a lein project, fn won't have that problem
16:26nicholasfraek: yeh, I think I picked up using 'lein repl' from something written in Clojure Programming (OReilly)
16:26raeknicholasf: and that happens every time?
16:26nicholasfbut it's obviously stopped working how people think it should
16:26nicholasfraek: each time so far, yes :)
16:27foxdonutwe need an abbrev. for Clojure Programming (O'Reilly)
16:27uvtcfoxdonut : CP ?
16:27TimMcnicholasf: At times like this I tend to blow away ~/.m2/repository
16:27raekyes, lein repl outsude a project is one of the most common ways to start a "just clojure" repl
16:27TimMcfoxdonut: CPOR?
16:27nicholasfTimMc: hrm ok
16:28fenton1Raynes: thx i'll try that.
16:28TimMcMaybe you have a corrupted Clojure 1.2.1 binary.
16:28nicholasflike I said, all of these tools are new to me, but this felt wrong
16:28uvtcnicholasf, I go a step further than TimMc ; `rm -fr ~/.lein` `rm -fr ~/.m2` `rm ~/bin/lein`, then download the latest lein and start over. :)
16:28nicholasfhang on, let me try using lein repl on my mac air (currently on another machine)
16:28foxdonutuvtc, TimMc: I was thinking one of those, yeah.. alongside JoC, CiA, PC
16:28nicholasfok, Ive installed lein on two machines in the last week
16:29nicholasfthey are both behaving the same way
16:29raekthis is very, very odd
16:29TimMcnicholasf: Is your gist a *precise* copy of your REPL, or did you retype anything?
16:30foxdonutJoC, CiA, PCAP, PCPP, CPOR
16:30nicholasfTimMc: it's a precise copy
16:30raeknicholasf: is there something else that doesn't work, for instance let expressions?
16:30nicholasfive programmed a bunch of other languages, I know about the importance of sharing info
16:30nicholasfraek: I guess let would be broken too, if fn is
16:30TimMcnicholasf: How about arithmetic expressions like (+ 2 3)?
16:31nicholasfhttps://gist.github.com/357cf99cdc5982fc0015 TimMc and raek
16:31TimMcnicholasf: 'let and 'do are no surprise
16:31TimMcTry (let [x 5] (+ x 4)) and (do 1 2 3)
16:32nicholasfhttps://gist.github.com/75eee8531281f8b84700 they work
16:33nicholasfaltho that confuses me a little
16:33nicholasfcos if let works I would have assumed fn would too
16:33TimMcThe compiler may handle them at different levels.
16:34nicholasfyeh ok, I guess special forms arent all equal
16:36raekthis is very odd. I can't reproduce that with my lein 1.7.1 / clojure 1.2.1 repl
16:36ppppaulanyone here using clojurscript and couchapps?
16:36nicholasfraek: you're cding into a dir that doesnt have a lein project, right?
16:37raeknicholasf: yes
16:37raeknicholasf: what does `sha1sum ~/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar` return on your computer?
16:37nicholasfraek: that is strange
16:37raekwe should be using the same clojure jar
16:38nicholasfthat's not available via brew
16:38nicholasfandromeda:~ nicholas$ ls -ltrh ~/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar
16:38nicholasf-rw-r--r-- 1 nicholas staff 3.1M 28 Jun 10:34 /Users/nicholas/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar
16:39nicholasfbut I'm using clojure-1.3.0 in my lein projects
16:39raeknicholasf: try replacing "sha1sum" with "openssl sha1"
16:39nicholasf(that's the jar it pulls down)
16:39nicholasfok
16:40raekI get be088d20c078ce48d42afba05984f1ef7c02142b here
16:40nicholasfSHA1(/Users/nicholas/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar)= be088d20c078ce48d42afba05984f1ef7c02142b
16:40TimMcnicholasf: When not run from a project, lein uses its own Clojure dependency for the REPL environment. In this case, 1.2.1.
16:40nicholasfTimMc: ok thanks
16:41raeknicholasf: and the same thing happens if you write a similar expression, like ((fn [y] (+ y 5)) 3) ?
16:41brainproxyanyone using visionmedia's superagent lib in conjunction w/ their cljs projects?
16:44nicholasfraek: https://gist.github.com/7f52d9573761da1e9e0e
16:44nicholasfthat's interesting
16:44raeknow that's expeced behavior
16:44raekI wonder why it doesn't like your xs... :)
16:45nicholasfhrm
16:45wingywhat does the # in the first line mean: https://gist.github.com/3042912
16:45raeknicholasf: is your OS set to a language that uses right-to-left directioned writing, like Arabic or Hebrew?
16:45nicholasfwait something is different
16:45nicholasfmy original example (which wasnt working) now passes
16:46TimMcnicholasf: Try *clojure-version* in that REPL.
16:46nicholasfraek: nope
16:46nicholasfuser=> *clojure-version*
16:46nicholasf{:major 1, :minor 2, :incremental 1, :qualifier ""}
16:46TimMcwingy: That's the new reader literal datatype something something syntax.
16:47nicholasfsomething bizarre is happening
16:47raekindeed
16:47TimMcI blame leap-seconds.
16:47nicholasfhaha
16:47raekI blame invisible characters
16:47nicholasfhrmn
16:47TimMcindeed
16:47amalloyoh, that's an interesting possibility
16:47amalloythough i still think his original broken repl had just redefined fn accidentally
16:47nicholasfit must be something like that
16:48TimMcamalloy: But it failed on two machines.
16:48nicholasfthe function I tested with just works on my mac air
16:48nicholasfno, what failed on the mac air was me writing 'fn'
16:48TimMcAh! Yes, that would.
16:48nicholasfI thought that was an adequate test
16:48nicholasfso I'm sorry for wasting people's time
16:48amalloy&(let [fn inc] ((fn [x] (+ 1 x)) 2))
16:48lazybot⇒ 3
16:48amalloy,(let [fn inc] ((fn [x] (+ 1 x)) 2))
16:48clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)>
16:48amalloythere we go. man, i need to fix that issue in clojail
16:48raeknicholasf: 'fn' is hardcoded into the compiler, but only at "call positsion"
16:49amalloyraek: no it isn't
16:49TimMcfn* is
16:49raekah, sorry
16:49amalloyfn* is; fn is just a regular macro
16:49raekit's a macro, yeash
16:49nicholasfah ok, fn is a macro using let and do, right?
16:49TimMcMore complicated.
16:49amalloywell, using let and fn*
16:49nicholasfok
16:49TimMcnicholasf: (source fn) in your repl
16:50raekno, it expands to fn*, which is like fn but without destructuring, IIRC
16:50nicholasfha cool TimMc
16:50nicholasfthat is *really* cool
16:52jeremyheiler ,(interleave [1 2 3] ['a 'b]) ; is there a nice way to have the 3 added to the end?
16:52clojurebot(1 a 2 b)
16:53jeremyheileri mean, have the 3 be part of the lazy sequence.
16:53TimMcjeremyheiler: An interleave-all, in other words?
16:53jeremyheileryeah
16:59jeremyheilerI know I can hack on the interleave implementation, but was just wondering if there's another way.
17:04S11001001jeremyheiler: do you know which list is shorter?
17:05jeremyheilerYes
17:05S11001001what happens for [1 2 3 4] and ['a 'b]?
17:06jeremyheilerFor my purposes, I would be ok with (1 a 2 b 3 4) but that is not an expected use case. I really only care about the second list being one element smaller.
17:07S11001001,(rest (interleave (cons nil ['a 'b]) [1 2 3 4]))
17:07clojurebot(1 a 2 b 3)
17:10raek,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleve a b)))
17:10clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: interleve in this context, compiling:(NO_SOURCE_PATH:0)>
17:10raek,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleave a b)))
17:10clojurebot(1 a 1 b 2)
17:10raek,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleave a (rest b))))
17:10clojurebot(1 a 2 b 3)
17:10raek:)
17:11jeremyheilernice, i guess that last use-case makes it that much simpler :-P
17:11jeremyheilerthank you both
17:12solussd_is it possible to add custom json encoders for use with noir.response/json ?
17:13TimMcjeremyheiler: Will either list ever be of length 1?
17:16wingyTimMc: where can i read about it?
17:16jeremyheilerTimMc: Yeah, but never both at the same time.
17:20jeremyheilerTimMc: It seems raek and S11001001 solutions work for my current problem. but a proper interleave-all would be nice addition to core, i think.
17:21nDuffdnolen: Should I file a ticket against zi for that classpath issue (being unable to find clojure.plexus.compiler.impl)?
17:21raek(defn alternate [long short] (lazy-seq (when (seq long) (cons (first long) (alternate short (rest long))))))
17:22raekjeremyheiler: ^
17:22S11001001jeremyheiler: not useful enough
17:22nDufferr
17:22raekanother solution I came up with once
17:22hugodnDuff: if you meant me, then yes please - sorry haven't got to it yet
17:22nDuffindeed.
17:23raekfor some reason that old gist 404s for me...
17:24jeremyheilerraek, nice, i like it
17:27solussd_dakrone: you there? :)
17:27dakronesolussd_: yes
17:29solussd_dakrone: excellent… quick cheshire question: so I'm trying to add a json encoder for org.bson.types.ObjectId, did this: (add-encoder org.bson.types.ObjectId (fn [o json-generator] (.writeString json-generator (str o)))), but calling (generate-string (org.bson.types.ObjectId.)) still throws a JsonGenerationException. Am I missing something?
17:30dakronesolussd_: and you're sure you're using cheshire.custom/generate-string instead of cheshire.core/generate-string?
17:31solussd_dakrone: ah, I am not. :) I'm trying to add an encoder so noir.reponse/json will encode ObjectIds… looks like this wont help me then. :/
17:31dakronenoir should support being able to override the json encode/decode methods with whatever you'd like
17:31dakronetoo bad it doesn't
17:32solussd_(it does work with cheshire.custom/generate-strin)
17:32solussd_yes.. too bad. :/
17:32dakronemaybe open an issue with the noir project and see if they have any way to work around it?
17:32TimMcwingy: See 2.1: https://github.com/clojure/clojure/blob/master/changes.md
17:33solussd_k. thanks
17:43hugodnDuff: you'll need mvn 3 for zi
17:56nDuffhugod: ...ahh.
17:57dnolenamalloy: ping
17:57amalloydnolen: pong
17:58dnolenamalloy: heh that problem was annoying enough that I added permuteo :)
17:58amalloyhah
18:00dnolenamalloy: some of those answers on Rosetta are epically convoluted
18:00dnolenamalloy: http://gist.github.com/3043632
18:00dnolenamalloy: based on core.logic master
18:00talios'lo hugod
18:01taliosanyone using maven should be using maven 3 by now anyway.
18:01nDuff...looks like Atlassian's plugin development toolchain is rather tied to Maven 2.
18:01dnolenamalloy: the only subtle one is not-above1o, this is a bit tricky because I'm trying to be pure, no cut.
18:01wingyseems that clojure 1.4 has some features added for datomic
18:02wingyuuid, instant and reader literals
18:02technomancyfact: no one outside datomic has ever cared about uuid reader literals
18:03wingyyeah thats why they added it in 1.4?
18:05wingyi mean that datomic needed uuid literals and added it to clj 1.4
18:07amalloydnolen: i haven't really tried to learn the defne and/or matching syntax that you're using, yet. certainly looks like a nice shorthand for piles of conso's
18:08dnolenamalloy: cleaned up the gist a bit.
18:08dnolenamalloy: yes conso and raw conde usage drives me insane now :)
18:09amalloyis there a reason you went with != for not-above1o, instead of taking the approach in my not-adjacento? it seems like if the list elements are unique, then just asserting that they're separated by at least one is equivalent to asserting that they're not next to each other with !=
18:11nDuffhugod: Hmm. After moving to Maven 3, I'm not getting that issue -- but I'm also not getting line numbers or useful error messages on compile errors; they're all of the form file.clj:[0,0] null
18:12dnolenamalloy: yes that approach seems just as good, but perhaps this shows how you can use != and non-overlapping clauses to accomplish the same thing.
18:13dnolenamalloy: note in my not-above1o it's only possible for one clause to ever succeed.
18:15dnolenamalloy: same thing with aboveo, using != will be more efficient than using rembero.
18:15amalloy*nod* because you turned not-adjacento into two separate applications of aboveo
18:15dnolenamalloy: yeah
18:17dnolenamalloy: again your not-adjacent approach seems good in this case. items are unique and membero after a gap.
18:17jcromartiethere is only one thing that I can think of when people discuss core.logic http://wonkette.com/assets/resources/2007/12/awesomeo.jpg
18:17amalloyokay. i think performance concerns are a little beyond me for now, so i'll just file that away
18:18technomancyjcromartie: nice!
18:19brehautthats something clojurebot should learn
18:19dnolenamalloy: thanks for bringing it up. your run* looked solid ... reads like the puzzle :)
18:19dnolenbrehaut: haha
18:20brehaut(historical evidence suggests that i am not the right person to be teaching clojurebot facts however)
18:20amalloydnolen: so i'm not sure i understand the implementations of rembero and permuteo you committed (aside from me not understanding defne syntax). does your rembero remove *all* instances of x? if so, permuteo will have surprising results
18:21amalloyi wrote it to remove a single instance of x, so that, for example, (permuteo [1 2 2] [2 1 2]) succeeds
18:22amalloybut if you're removing all instances of x it seems to me that (permuteo [1 2 2] [1 2]) will also succeed
18:22dnolenamalloy: it doesn't not remove all occurrences
18:22amalloyokay. i'll just squint at the defne some more, then
18:23dnolenamalloy: this is what I mean by non-overlapping. either we found it & we're done - or we didn't find it (guaranteed by !=) and we keep looking.
18:23dnolenamalloy: this is where Prolog used to cause a lot of trouble, no disequality operator. I forget which Prolog (II ? III?) got it
18:24amalloydnolen: so your rembero removes specifically the first instance of x?
18:24dnolenamalloy: yes
18:26amalloyand if you removed the != assertion it would still work, but be willing to remove any instance of x. i wrote it to remove any instance of x because i imagined that was useful for permuteo, but i suppose it actually doesn't need to be that general
18:28dnolenamalloy: that might be useful - hard to say w/o people sending me to fun logic puzzles on SO ;)
18:28dnolenamalloy: permuteo is definitely useful tho - that should have been there.
18:28amalloydnolen: i'm on target though, right? != is what makes it remove exactly the first instance, and do so quickly; if you removed it it would remove any instance, more slowly?
18:31dnolenamalloy: yes
18:31hugodtalios: hi!
18:31dnolenamalloy: if != fails if unification succeeds.
18:31dnolener I mean "!= fails if unification succeeds"
18:31amalloycool. glad to see permuteo and rembero added, even if i didn't write them; i feel like i've impacted core.logic now :)
18:32dnolenamalloy: you have! thanks!
18:32hugodnDuff: mm, that sounds strange - any chance of adding a minimal failing java file to the issue
18:32wolgowhen destructuring a map to bind I see the following in a clojure book: (let [{k :unknown x :a :or {k 50}} m] -rest of the code here-
18:32wolgowhat is :unknown doing?
18:32wolgoI see that the :a value gets assigned to x, that is fine
18:33amalloy,(macroexpand-1 '(let [{k :unknown x :a :or {k 50}} m] foo))
18:33clojurebot(let* [map__30 m map__30 (if (clojure.core/seq? map__30) (clojure.core/apply clojure.core/hash-map map__30) map__30) k ...] foo)
18:33amalloy&(macroexpand-1 '(let [{k :unknown x :a :or {k 50}} m] foo))
18:33lazybot⇒ (let* [map__10199 m map__10199 (if (clojure.core/seq? map__10199) (clojure.core/apply clojure.core/hash-map map__10199) map__10199) k (clojure.core/get map__10199 :unknown 50) x (clojure.core/get map__10199 :a)] foo)
18:34amalloywolgo: you can see that this expands to (let [k (get m :unknown 50)])?
18:34wolgolet me take a tias break. I didn't try enough stuff to teach myself. Sorry
18:35wolgoamalloy: thanks, I do see that
18:40wolgookay so :unknown is not a special argument
18:40wolgoI understand
18:41wolgoclojure is cool man
18:41wolgolots of neat ideas.
18:42locojayhi i m new to cljs : is it a big deal to mix js and cljs (most in cljs via closure opt and some part in js like d3 charts...)
18:42ohpauleezlocojay: You can use c2 for the charts (a d3-like library)
18:43ohpauleezand you can mix JS as you need
18:43ohpauleezthere's (js* …) for that very purpose
18:43ohpauleezbut you'll soon find out that JS offers you little once you're embedded in CLJS
18:47locojayyeah i ve seen c2 but i have lots of animation's ... I could reference d3 and use (js* -) as you mentioned but since the code is already their i don't think i will refactor to cljs for the time beeing. mixing parts in cljs and js seems like a good approach to me until i get more familiar with cljs
18:48ohpauleezlocojay: talk to lynaghk - I think you can pull off all the animations you need
18:49ohpauleezand you should prefer CSS animations and effects when possible
18:50locojayohpauleez: thanks will do (looking for thing's like brush... will send mail to userlist)
18:51ohpauleeznp
18:54emezeskelocojay: FYI you should probably never be using (js* ...)
18:55emezeskelocojay: I do a ton of interop and it has never been necessary to use it
19:16wingyupsert = UPdate + inSERT :)
19:16wingyfirst time i heard that
19:22emezeskeAnyone else using clojurescript 0.0-1424? I am seeing (:dne {} 42) return nil instead of 42... :(
19:24wingywhy is datomic using a dash as in -10000002 in the id nr: {:db/id #db/id[:db.part/user -1000002], :neighborhood/name "Capitol Hill",
19:26wingyhttp://datomic.com/company/resources/transactions
19:26Bronsaemezeske: http://dev.clojure.org/jira/browse/CLJS-330 i think this issue refers to that problem
19:26emezeskeBronsa: thanks!
19:27emezeskeBronsa: That's a pretty major bug to slip into a release O_o
19:27Bronsayeah
19:28Bronsabut clojurescript is still alpha i think
19:28emezeskealpha != super obvious regressions should go into tagged releases
19:45meliponeI am using math.numeric-tower and when I do (ceil (/ 4 5)) I get 1N. What does the N mean?
19:45hiredman,(type 1N)
19:45clojurebotclojure.lang.BigInt
19:46meliponehiredman: thanks!
19:46sjlanyone know what incantation I need in :repositories in my Leiningen map to get one of these suckers to work? https://repository.sonatype.org/index.html#nexus-search;quick~lanterna
19:46meliponeStill, why is it a BigInt?
19:57dnolen,(.numerator (/ 4 5))
19:57clojurebot4
19:57dnolen,(inc' (.numerator (/ 4 5)))
19:57clojurebot5N
19:57dnolen(doc inc')
19:57clojurebot"([x]); Returns a number one greater than num. Supports arbitrary precision. See also: inc"
19:58dnolenmelipone: ^
19:59dnolenmelipone: under the hood it uses a primitive long until it no longer can - does that address your concern?
20:10gfredericks,(-> (iterate #(*' 2 %) 7) (nth 383) type)
20:10clojurebotclojure.lang.BigInt
20:15gfrederickswhat are "reify" and "this-as" in cljs?
20:15gfredericks(is there some better way to find that out than asking here?)
20:15dnolenejackson's core.logic presentation is pretty nice!
20:16dnolengfredericks: reify is the same as Clojure's
20:16dnolengfredericks: this-as is a interop thing.
20:16gfredericksyeah I shoulda checked what clojure's does first :)
20:16gfredericksdnolen: is it like (let [foo js/this] ...)?
20:17dnolengfredericks: except no promise that js/this will continue to work.
20:18gfredericksoh I didn't even know if it did
20:18dnolengfredericks: it probably won't, I think this always becomes this$
20:18gfredericksit doesn't work in himera
20:18gfredericksdnolen: okay cool thx
20:44gfredericksweird himera behavior: () => (), ()() => nil, ()()() => (), ()()()() => nil, and apparently all nil after that
20:44RaynesHah
20:50dnolenpretty cool http://github.com/jonase/scape/commit/51d75b11b5919a1b019d4d3288b8cc28c0ee32f5
20:54pdkwhat i learned today:
20:55pdkdon't dispatch a bunch of agents grinding on a search tree in parallel on your local machine
20:57sabeevening
21:01sabeI'm craking my head but I can't find a solution. Perhaps someone can help?
21:01sabegiven this: https://gist.github.com/3044453
21:01sabehow can I call "f" with ["a" "b" "c"] and an initial "context"?
21:03dnolen(->> 0 (fn "a") ...) doesn't work?
21:03dnolensabe: ^
21:04sabehm but how can I create that call from a seq?
21:04dnolenneat http://code.google.com/p/lanterna/
21:04dnolensabe: what do you mean?
21:05Raynesdnolen: Like reduce.
21:06sabednolen: given that I have ["a" "b" "c"], how do I call f 3 times passing the result of the first call to the second one and so forth
21:07dnolensabe: like Raynes said, why not reduce?
21:08sabelemme try
21:08gfredericks,(reduce str "teehee" ["a" "b" "c"])
21:08clojurebot"teeheeabc"
21:08sjldnolen: sabe: the context being the second arg is going to bite you when you try to reduce
21:08sabesjl: that's exactly the problem :(
21:09sjlotherwise (reduce f 1 ["a" "b" "c"]) would work
21:09gfrederickssabe: you can wrap it in an anon fn to reverse the args
21:09sjlunfortunately I don't think Clojure has a flip function, but it should be trivial to write http://zvon.org/other/haskell/Outputprelude/flip_f.html
21:09sabesjl: :[ ]
21:09sabeit works :~ you guys rock
21:09gfredericksI'm sure useful has it
21:09RaynesIt actually doesn't.
21:10gfrederickswat
21:10RaynesI added it once, but amalloy didn't like my version, preferring his 20 line version that he never actually added.
21:10gfredericksRaynes: does it have (partial partial apply)?
21:11sabethanks sjl, dnolen, Raynes, and gfredericks
21:11amalloygfredericks: no, though at one point i was thinking of adding that
21:11gfredericks,(let [pap (partial partial apply), + (pap +)] ((comp + range) 10))
21:11clojurebot45
21:11amalloyi called it ap, not pap, personally
21:11gfredericksamalloy: for some reason I woke up one morning with that function in my head
21:12gfredericksI don't know why I called it pap. should be ppa if anything.
21:12gfredericksoh Partial APply was it
21:12amalloyright
21:12gfredericksbut I like ap too
21:12amalloyi just called it ap because who cares that partial is involved in the impl
21:12amalloy(map (ap +) (...))
21:12gfredericksyeah who cares
21:13sjl(defn flip [f] #(apply f (reverse %&))) ?
21:14gfredericks(defn flop [f] #(apply f (shuffle %&)))
21:15brehautgfredericks: i believe the canonical name for that operation is PHP
21:17gfrederickswhy aren't there more newbs having trouble with macros?
21:19amalloyisn't the most common macro-newbie problem "help, i foolishly wrote a macro"
21:19gfredericksyes
21:20sabegive me a couple days ;)
21:21gfredericks&clojure.tools.macro/macrolet
21:21lazybotjava.lang.RuntimeException: Can't take value of a macro: #'clojure.tools.macro/macrolet
21:21gfrederickssweet we can write macros on lazybot
21:23sabedanger
21:23gfredericks&(clojure.tools.macro/macrolet [(fark [expr] (clojure.walk/postwalk #(cond (seq? %) (vec %) (vector? %) (seq %) :else %) expr))] (fark [let (foo 12 bar 15) [+ 12 [- 15 18]]]))
21:23lazybot⇒ 9
21:39dnolenamalloy: fwiw, I think a cKanren dinemans solution might look something like this - https://gist.github.com/3044626, which would be close to the brevity of Haskell's solution.
21:40amalloydnolen: fd is some kind of...constraints-based numbers thing?
21:40dnolenamalloy: yep
21:40gfredericksjust finite domains right?
21:40dnolenamalloy: so no permutations, should be fast
21:41gfredericksdnolen: (interval 1 5) takes linear space?
21:42dnolengfredericks: stores lower and upper bound. might grow as constraints run of course, but as a sequence of intervals.
21:42dnolengfredericks: all this stuff is done on protocols so optimizations possible - bit vectors, discrete interval encoding trees, etc
21:43gfredericksdnolen: oh nice; I must misunderstand the finite domain idea then
21:43gfredericksi.e., why not simply all integers?
21:43dnolengfredericks: what do you mean?
21:44gfredericksdnolen: it wouldn't support (interval -infinity +infinity) for example, would it?
21:45Shambles_There was a lot of discussion about OO in history that I just see now. Few people seem to understand 'how we got there'.
21:46Shambles_It makes quite a lot of sense if you consider that we started out with unstructured code, so you couldn't tell what modified a particular variable, or where the code you needed to change was.
21:46dnolengfredericks: protocol waiting to happen, pretty sure unbounded intervals could work.
21:46Shambles_Structured programming got the code packaged in orderly procedures, but you still couldn't figure out what modified a particular variable.
21:46gfredericksdnolen: oh nice; I'll stop doubting then. really looking forward to arithmetic.
21:47dnolengfredericks: in fact probably a requirement for the kinds of things I'd like pred dispatch do.
21:47Shambles_OO bundled the variables with the code that modified them (assuming you didn't use any public variables, which, if memory serves, Simula and Smalltalk don't allow).
21:48Shambles_From the imperative programming point of view, OO really was 'easier to understand', since you didn't have to read the entire program to understand how to fix a bug.
21:50Shambles_I think functional programming was its own thing. It was the first (as far as I know Lisp was the first) attempt at declarative programming. I don't think it had to do with ease of anything.
21:51kovasbis functional programming declarative programming?
21:52gfredericksI can imagine an argument that HOFs allow more declarative things
21:52brehautyou can do declarative programming with functional programming
21:53Shambles_kovasb: It's usually lumped in that category, along with everything else that isn't (blantantly) imperative, yes. Other things that are in that category are concatenative, dataflow, and logic programming languages.
21:53dnolengfredericks: well read a POPL12 paper where Scala folks got it to work, can't let them show us up or anything!
21:54gfredericksdnolen: did you attend that?
21:55dnolengfredericks: nope
21:55Shambles_kovasb: Theoretically declarative languages let you worry less about control flow. They 'figure it out' for you. In practice they either aren't much help (e.g. Fortran-like and Lisp-like languages don't tend to do anything particularly 'clever' for you), or you end up fighting them every time you want to do I/O (e.g. when doing logic programming), since the order of evaluation in I/O matters.
21:56kovasbI guess i think of declarative as something that possible in parts of the program
21:57kovasblike, you have a spec for something
21:57kovasbeg project.clj file
21:57kovasband something else interprets that, but its pretty domain specific
21:58kovasbbasically declarative == parameterized in this POC
21:58kovasbPOV
21:58Shambles_kovasb: I think the problem is people really need to be able to use different language designs for different purposes. I/O hurts less in imperative style than anything else. GUI's probably should be built out of some weird mishmash of OO and dataflow. Functional and logic programming are probably handy where you'd want to do fancy math, including symbolic math, or proofs and planning and the like.
21:59Shambles_kovasb: Of course Lisp lets you embed domain-specific languages so you can actually do that.
21:59kovasbyeah
21:59kovasba computation for every occasion
22:01dnolenkovasb: I think declarative programming can be much broader than people think. People always consider putting everything into one paradigm or another. Instead if you understand what's possible in a declarative paradigm, you have a better understanding where it can be powerfully applied - i.e. a rich assertion language that you gradually annotate your program w/.
22:01kovasbright
22:01dnolenkovasb: jonasen's scape is great example, dump your code into a DB and figure out meaningful queries over it.
22:02kovasbi guess declarative programming is where data meets programming constructs
22:02kovasbdnolen: yes i agree it can be much broader
22:03Shambles_It does make me a bit sad when I see people bash on OO without even understanding why it exists, which is pretty often. It really is nice not to have to wonder where to look for code that might have corrupted your variable.
22:04dnolenkovasb: I think part of the problem is that people consider code some holy kind thing instead of just another piece of data. In this regard Lisp still got the one-up - you don't lose that clarity.
22:05kovasbdnolen: another problem is they don't have nice homoiconic datastructures
22:05amalloyShambles_: doesn't help much if you expose setFoo(x) methods that just do what they're told
22:06dnolenkovasb: that's what I mean about the clarity. You can do the same thing with many languages - but people consider that the realm of the compiler / tool writer.
22:06kovasbright
22:06hugodnDuff: your repro case works for me - Apache Maven 3.0.4 (r1232337; 2012-01-17 03:44:56-0500), Java version: 1.6.0_33 or 1.7.0_4
22:06Shambles_kovasb: Well, there's two reasons for the 'holy code' point of view too. Until fairly recently (about the 90's), there were a lot of programmers that considered self-modifying code to be great. They were rather famous for creating unmaintainable messes. The other is the drive toward better security that was hardware-based (non-executable pages). This drove programming toward very-static environments where code wasn't dat
22:06Shambles_That probably got cut off. Sorry. "This drove programming toward very-static environments where code wasn't data."
22:06kovasbdnolen: i watched the guido pydata talk .. the whole thing was people asking for extending language syntax, and wanting macros
22:07dnolenkovasb: haha
22:07kovasbShambles_: right
22:07kovasbdnolen: it was crazy. that was the the "python scientific community" has on the frontburner
22:08Shambles_amalloy: It's not /as/ helpful as it could be, perhaps, but nobody is forcing you to do that with OO, and it's still better than the structured code situation, because if you need something to happen whenever that variable changes, you can at least stick it in the setFoo method and take comfort in knowing it will always occur when appropriate.
22:08kovasbfor core language dev at least
22:09kovasbdnolen: btw got the cljs tagged literal support working in session. bit of a hack but
22:09Shambles_I'm a Python (my preferred language anyway) programmer trying to move to Lisp. It's close enough for me to understand why people would be asking for those things in Python. There's not a lot else missing.
22:10kovasbShambles_: i am not against OO, just the programs people tend to write with it
22:10Shambles_I don't think they can add it without causing major headaches, and Guido is dead set against it.
22:10dnolenShambles_: it not clear to me that self-modifying in the mainstream was ever popular. Do you mean in languages like C++ / C ? If so, yeah nightmare.
22:11amalloydnolen: before that, i think. assembly
22:11dnolenamalloy: that would have been in the 50s and 60s then.
22:11kovasbShambles_: yes he did a good diplomatic job of knocking them down
22:11dnolenand was probably better than writing all the assembly by hand.
22:11amalloyoh, i missed his "recently" claim. yeah, i agree that doesn't seem true
22:11Shambles_kovasb: Self-modifying code was, until about the miod 90's *wildly* popular with assembly programmers. You could get away with that stuff easily in DOS. It was used to save RAM, do copy protection, and in rare cases improve speed (by removing the need for subroutines or branches).
22:12Shambles_kovasb: Assembly seems to have fallen out of favor, even with game programmers, and given higher level languages were trying to avoid quite so much mess, it's not surprising it's not as doable now.
22:12dnolenShambles_: do you have any evidence that it's not popular among assembly devs today?
22:13dnolenShambles_: isn't the whole point of modern runtimes self-modifying code?
22:13kovasbsomehow "self-modifying code" tends to sound more scary than it usually is
22:13Shambles_dnolen: It's not as popular today due to most OS's (Windows and Linux at least) setting most pages non-executable.
22:14kovasbi think it's fair to say we have OO in clojure
22:15Shambles_dnolen: Using data to decide what code to execute usually achieves the same ends as self-modifying code, but it's more painful, so isn't done when you don't really *need* to. It also makes it blatantly clear that that is being done from looking at the source.
22:16dnolenShambles_: completely disagree with that. Data is control is great.
22:16dnolenData as control.
22:17kovasbi agree they are very similar
22:17kovasbalso data as control is great so long as writing the executor is easy
22:18Shambles_dnolen: I didn't say anything about whether it was 'great' or not. I just said it's clearer that it's being done (no mystery code overwrites at some point in your memory map), and that it's more painful, which it is, since you have to manually specify the mapping rather than relying on what the hardware considers a particular binary sequence to 'mean'.
22:19Shambles_dnolen: I also have a healthy respect for the lessons of history. 'Cute' control flow may be necessary, but I don't like to use it when I don't *need* to. There's no point in using a kaiser bomb to kill a housefly.
22:19dnolenShambles_: yes, self-modifying assembly is not something I want to know anything about.
22:19dnolenShambles_: no argument there. I'm not going to replace my ifs with maps.
22:20kovasbi definitely went through i stage in mathematica programming where i tried to do everything with replacement rules
22:20technomancyhas anyone written ring applications that return DB-altering functions in parallel to the HTTP response map?
22:20kovasbbut if is pretty good
22:21technomancyit's probably not feasible, but I'm curious if anyone's tried it
22:21kovasbmore complex control often indicates you are doing it wrong
22:22ohpauleeztechnomancy: can you give an example?
22:22Shambles_As for OO in Clojure, I guess you have it due to Java interoperability, and reference types, but mutable variables are clearly the red headed stepchildren in Clojure, and I'm finding the adjustment to extreme-minimal-mutation to be rather painful. I've been trying to get my head around zippers for that. I don't think anybody would like it if I just kept to a OO style.
22:23technomancyohpauleez: {:status 201 :body "dude I made a thing for you" :db ["INSERT INTO widgets VALUES ('hello', 'world')"]} or some variant
22:23kovasbShambles_: one big argument for the declarative style is that there are fewer functions to worry about.
22:23kovasbShambles_: and so tends to be easier to copy code, serialize it etc
22:23technomancyohpauleez: you'd probably want DB functions to work like swap! or alter functions
22:23dnolenShambles_: not true, about the OO stuff & Java interop.
22:24kovasbShambles_: i think the datatypes and record lend it OO status -- functions and data together
22:24dnolenShambles_: Clojure distills the good OO stuff - and leaves the baggage behind.
22:24Shambles_kovasb: You are kidding right? Functional programming tends to be all about having lots of itty bitty functions. In theory if they're named well (i.e. not like a mathematician would), they read a bit like a English description. If you're using Forth, they even call them "words" that are in a "dictionary", but it all reads like Yoda talking.
22:24technomancyohpauleez: it probably wouldn't work without PLV8 and cljs I think
22:24ohpauleeztechnomancy: not via ring explicitly, but I have done something similar with CLJS and datomic
22:24ohpauleezonly as a thought experiment
22:24dnolenShambles_: also, local mutation is perfectly acceptable in Clojure.
22:25kovasbShambles_: i mean, in my definition of declarative. Its just some piece of data.
22:25kovasbShambles_: like, the datomic api is 1 function
22:25kovasbShambles_: and then you pass in the declarative spec of your query
22:26technomancyohpauleez: I think plv8 makes it feasible in postgres, but I imagine the build to get there could be a worlde o' pain.
22:26Shambles_dnolen: Trying to figure out how to alter a simple tree, based on user response, is giving me a headache. It wouldn't if I just used vars, but I'm sure that's not the 'correct' style. I'm pretty sure what's excpected is for me to use zippers and only one var to hold the root.
22:27ohpauleeztechnomancy: Would be interesting to see how far you could get in a day though
22:27dnolenShambles_: do you know the path to the thing you want to change? If so why do you need zioppers?
22:27kovasbShambles_: do you have a function that outputs the modified tree?
22:28technomancyohpauleez: I suck at both postgres and cljs, so I'm going to delegate that to someone else who happens to be listening to this conversation
22:28ohpauleezbut the details are most certainly difficult - datomic has some padding that made it easier (queries are just data structures - remoting via CLJS to the server-side peer was an easy hack to tie over pieces)
22:28kovasbShambles_: (swap! your-atom your-function function-arg)
22:29technomancyohpauleez: I suspect queries are just data structures with cljs/plv8 too
22:29Shambles_dnolen: It's a 'toy' program to try to help me understand things. It's basically a miniature expert system. It traverses a tree to answer questions. If it can't answer the question it needs to add a new node at the tip of what was a 'leaf'.
22:29kovasbwhere you have (defn your-function [original-tree function-arg] ..produce new tree..)
22:29technomancybut you have to do the heavy lifting yourself I guess
22:30kovasbShambles_: zippers create new data structures as you are doing your insertions etc
22:30Shambles_dnolen: My current thoughts are to keep passing a path as it gets built up traversing the tree, then convert that into zipper operations to modify the tree if necessary. That would keep the tree from mutating. There'd only have to be one point of mutation in the program; the variable that holds the current tree's root.
22:30dnolenShambles_: is a tree a good representation? Why not tuples + indexing?
22:31kovasbShambles_: if the issue is saving it at the end, there is a function to output the new modified tree. you can stuff that into a ref type
22:31technomancyanyway, someone who's good at postgres should implement that; kthxbai
22:32Shambles_dnolen: I'm not sure what you have in mind, but yes, a tree is a good representation. There are questions, whose yes or no answers lead to more questions.
22:33dnolenShambles_: so you have indexes, why do you need a tree?
22:33Shambles_dnolen: I don't have a index in the sense of 1 through n. It's not look-up-able like a index in a array.
22:34dnolenShambles_: don't the questions have ids? And each question can point to the next one?
22:34Shambles_dnolen: In the sense that there is a pointer, I suppose.
22:35dnolenShambles_: so flatten the tree, create a pointer. Less programming.
22:35kovasbi don't see why bother
22:35kovasbupdate-in works fine
22:36kovasbstep 1. look up in tree using get-in
22:36kovasbstep 2. update tree with update-in
22:36kovasbor assoc-in
22:36dnolenkovasb: it mostly does, but it really depends on the use case. nested update costs add up.
22:36dnolenkovasb: indexed tuple representation is cheap to update.
22:36kovasbit sounds like performance is not a concern in this case :)
22:37Shambles_dnolen: Why would I want to flatten the tree? If something has a natural branching tree structure based on yes or no answers, cramming it into a flat data structure seems rather ugly. It also means I'll have to start manually managing what pointers were doing for me. I'll have to say "jump to question 1... uh, okay, now let's go lookup 1, alright, ask question, get answer, now I need to jump to question 89, let's look tha
22:37dnolenShambles_: because now you're playing around with zipper which makes no sense to me.
22:38dnolenShambles_: you have first class data structures, getting the next question is trivial.
22:38kovasbShambles_: i would check out get-in, assoc-in, update-in
22:38dnolen(questions (:next question))
22:38Shambles_dnolen: What I want to do is mutate a tree. Mutating is demonized, so I need to find a way to do it without mutation. Zippers appear to be the promoted salve for the need to mutate a tree.
22:39kovasbShambles_: use swap! in combination with the aforementioned functions
22:39dnolenShambles_: your assessment would be incorrect.
22:40dnolenShambles_: if you want to mutate a tree you're bringing a solution to a problem - not solving the problem.
22:40kovasbzippers do not mutate. they generate new datastructures
22:40dnolennot "actually" solving the problem.
22:40kovasbits just a more cumbersome way of doing the retrieval/update operatons
22:40Shambles_I have no trouble imagining how to flatten this into a list. I've seen people do that in one language I've had the misfortune to use, since it had no pointer or reference type. It wasn't easy to tell what was going on when reading such code (it didn't /look/ like a tree). But with enough blood sweat and tears it could be made to work. Lists could be appended in the language so you could add new nodes that way.
22:41Shambles_That was actually the only aggregate data type. There were strings, but you couldn't interact with them like arrays. Very unpleasant, especially given lists were not nestable.
22:42dnolenShambles_: huh, databases work like this - even graph databases - it's not that bad.
22:43Shambles_dnolen: I suppose I've gotten spoiled by 'easy' data structures. In Python if you want a tree, you make a class, and assign instances of that class type to various variables. There ya go. Easy to understand, easy to read. Everybody knows what you're up to. Anything else seems like handcuffs on.
22:44dnolenShambles_: too many things to not like about Python to care about "easy" mutable graphs.
22:44dnolenfor me
22:44Shambles_I could flatten this into a list, and avoid learning how to use a zipper I guess.
22:45kovasbwhat is wrong with {:node value :children [ … ]}
22:46dnolenkovasb: Shambles_: I agree if this is a "toy" that works best.
22:46kovasbi mean, that is pretty easy to iterate over
22:46Shambles_kovasb: As for zippers don't mutate, I'm aware of that. I said it's the promoted salve for /wanting/ to mutate a tree. When you say "I want to mutate" and the response is "mutation is bad", there has to be a solution "so do it this way". You end up needing to understand category theory if it's Haskell. Other languages usually have easier solutions. :P
22:47kovasbif i knew what computation you wanted to do, I'm sure it would be a one or two liner
22:47dnolen,(update-in {:value 'foo :children []} [:children] (fn [c] (conj c {:value 'bar :children []})))
22:47clojurebot{:value foo, :children [{:value bar, :children []}]}
22:48Shambles_There is at no point a need to 'iterate over' the tree. It's a tree. You need to be able to crawl it based on responses. You definitely don't need/want to pass over the entire tree. The only problem is trying to figure out how to change the tree (without mutation) when it needs to be updated.
22:48technomancywanting to mutate a tree for the sake of mutation doesn't sound like a very useful goal
22:48kovasb,(assoc-in {:value 'foo :children []} [:children] {:value 'bar :children []})
22:48clojurebot{:value foo, :children {:value bar, :children []}}
22:49kovasbwhoops
22:49kovasb,(assoc-in {:value 'foo :children []} [:children 0] {:value 'bar :children []})
22:49clojurebot{:value foo, :children [{:value bar, :children []}]}
22:49kovasbdang
22:49kovasbthere we go
22:50Shambles_The code is a lot easier for me to understand. If this was Python I'd just use a reference to the current node to change the values. That's quite possible in Clojure too (you can apparently put reference types in data structures), but apparently not the way you're supposed to do things, so I've been trying to figure out how to drive mutation out of the program except where it *has* to exist.
22:50dnolenShambles_: you can keep on talking or you can show your code at this point :)
22:50kovasb,(get-in {:value 'foo, :children [{:value 'bar, :children []}]} [:children 0 :value])
22:50clojurebotbar
22:51dnolenShambles_: I'm sure people will / can offer up improvements to your approach.
22:52kovasbi guess i am not seeing where the zippers are falling down
22:52Shambles_dnolen: The code doesn't exist, since, as I said, I've been trying to figure out how to update the tree, but essentially it's this Python program ported to Clojure: http://openbookproject.net/py4fun/animal/animal.py
22:53kovasbyou use the zipper, and then.. ? how is that not working
22:53iDesperadOCould not transfer artifact org.mongodb:mongo-java-driver:pom:2.6.5 from/to central (http://repo1.maven.org/maven2): Checksum validation failed, no checksums available from the repository
22:53iDesperadOhow about this error?
22:54kovasbsounds like a busted artifact no?
22:55dnolenShambles_: for that I agree w/ kovasb, that seems trivial w/ zippers
22:56kovasbdnolen: one limitation i can see, is if you want to maintain tree position, but also make the new tree concurrently available
22:57kovasbdnolen: because you need to emerge from the zipper to create the new top level value
22:57Shambles_kovasb: It's mostly me trying to understand how to do it. Currently my only guess is to pass a list, probably of symbols, that states the path taken to the node (it depends on the answers someone has given), as a argument, so if its guess is wrong, it can use that to reach and change the appropriate node.
22:57technomancyiDesperadO: whoever deployed the java mongodb driver screwed up pretty badly
22:57iDesperadOso...how to fix it?
22:57Shambles_Zippers don't exist in any language I've used before, so the idea is pretty foreign.
22:57kovasbShambles_: if you already have the path in-hand, why not just use update-in or assoc-in ?
22:58iDesperadOtechnomancy: I just git cloned incanter project and run `lein deps` only to find the dependencies can't be met
22:58technomancyiDesperadO: you can add :checksum :warn to project.clj, but that opens you up for accepting corrupted jars into your projects
22:58kovasbthe only reason to incrementally walk the tree is if the next step in the walk is dependent on an answer you don't have yet
22:58technomancyiDesperadO: probably better to add :exclusions for the mongo junk
22:58dnolenkovasb: hmm, the cursor is purely functional tho right? you can hold on to it like any other value.
22:58Shambles_kovasb: You wouldn't necessarily have the path. You just need to loop (or recur) and follow the references so long as the tree doesn't need changing.
22:59technomancyor just delete it out of project.clj if it's mentioned explicitly
22:59kovasbdnolen: yes, but if someone else changes the tree at the ref, you won't see that
22:59dnolenkovasb: is that relevant here?
22:59kovasbno idea
22:59Shambles_kovasb: That's what's happening with the while loops in the Python code. When it needs to modify the tree it does it by mutating it, by using the reference to the current node.
23:00iDesperadOtechnomancy: im afraid the incanter project uses mongodb...
23:00dnolenkovasb: it is not relevant
23:00technomancyiDesperadO: really? I thought it was optional.
23:00kovasbShambles_: i see. should be able to do a direct port with zippers
23:01dnolenkovasb: the questions are asked once you have an aswer you can then update the zipper
23:01Shambles_kovasb: I would need to keep passing the path as it's traversed, right?
23:01kovasbright
23:01kovasbShambles_: i don't think so
23:01dnolenShambles_: in this case I think a zipper is more natural for a close port.
23:02kovasbShambles_: i believe the path is accessible natively in the zipper
23:02kovasbShambles_: when you are at a child, pretty sure that data structure keeps its path around. don't know the zipper api offhand
23:03Shambles_kovasb: The tutorials I've read on zippers show a long series of down, left, right, and so on, to be able to modify something. This one looked like what I'd need to use. http://tech.puredanger.com/2010/10/22/zippers-with-records-in-clojure/
23:03kovasbShambles_: check out this talk, it has everything i know about zippers http://blip.tv/clojure/luke-vanderhart-clojure-zippers-4521622
23:04kovasbShambles_: i suggest that talk, it does simpler stuff
23:05Shambles_kovasb: I'll see if I can find the "pwd" equivalent in the API. If it exists, yes, this would be easier.
23:05kovasbpwd?
23:06Shambles_kovasb: Path to Working Directory. Unix command.
23:06kovasbShambles_: that exists in zippers
23:07kovasbi believe its :ppath
23:07kovasbi mean, the zipper is a datastructure
23:07kovasbi suggest making one and just looking at its contents
23:07kovasbits actually pretty instructive of the benefits over oo
23:08kovasbyou can just print it out and its a collection of normal clojure datastructures
23:09kovasbi suggest watching the last 4th of the talk where heres doing stuff at the reok
23:09kovasbrepl
23:10amalloykovasb: annoyingly, it's a collection of normal data structures...but with some hidden metadata that doesn't print unless you ask for it
23:10kovasblol
23:11technomancyso I was listening to ejackson's core.logic talk in the car today and I'm pretty sure there was a siren in the background of the talk's audio track.
23:11technomancyhad me kind of confused for a minute
23:12amalloythat was just the thought police
23:12kovasbi was trying to listen to that talk, but the speech pattern was too much
23:13technomancyhis pronunciation of A in a few words didn't match my conception of the british accents I'm familiar with
23:13technomancyI guess there are tons of regional variations
23:17gnarmisHey all, I was wondering if anyone knows where the latest snapshots of lobos are? They don't seem to be on clojars
23:20gnarmisBtw, currently using [lobos "1.0.0-SNAPSHOT"]
23:21botterIs there anything like ClojureBox for Windows for 1.5?
23:21gnarmisbut found a closed issue which suggested there's a newer one on clojars. https://github.com/budu/lobos/issues/36
23:23technomancybotter: clojurebox is old and unmaintained; recommend you not use it
23:23botterYea, I'm looking for an alternative
23:25technomancyyou'll probably have to download the parts separately
23:25botter:|
23:26technomancyorthogonal things are best kept orthogonal
23:26technomancytrust me, you don't want to have to upgrade your editor just because a new version of clojure came out
23:27botterI only want to try CLojure for a bit, so I don't want to spend too much time setting up the environment
23:27botterBut I'll give it a shot
23:28technomancyif you don't already have Emacs set up, you probably shouldn't learn it at the same time you're learning Clojure
23:29kovasbbotter: does clooj work for you?
23:29botterI'll try clooj, I've never head of it before
23:30kovasbits pretty good for a quick editing and repl solution
23:30bottertechnomancy: Setting up emacs right now. I've only used vi
23:31technomancybotter: strongly advise you wait on that until you know your way around clojure
23:31technomancylearning two things at once is a recipe for a headache
23:31botterWait on what?
23:31technomancywait on Emacs
23:32iDesperadOtechnomancy: how to download org.mongodb/mongo-java-driver? there are pom/jar/javadoc.jar/sources.jar to download...I have to download them all?
23:32botterSo clooj then
23:32kovasbiDesperadO: you can also clone the repo and install it locally. very easy with lein install
23:33kovasbo wait.. that is not a clojure package
23:33iDesperadOhttp://search.maven.org/#search|ga|1|a%3A%22mongo-java-driver%22
23:33technomancyiDesperadO: are you sure you need it? from what I heard it's just a convenience thing for incanter; it's not really required.
23:33iDesperadOO
23:34technomancybut you can set :checksum :warn in project.clj to turn off verification if you must =(
23:34iDesperadOwhat if i need it? I want to know how to download it manually
23:35iDesperadOI see lein install dependencies in ~/.m2/repository/. I guess I can do it manually
23:35technomancydon't do it manually
23:35technomancyjust turn off checksum verification in project.clj
23:35iDesperadOO
23:35technomancylesser of two evils
23:35sjl,(when-let [foo false bar true] 1)
23:35clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: when-let requires exactly 2 forms in binding vector in sandbox:>
23:36sjl:(
23:36sjlis there an idiomatic way to do that other than nested when-lets?
23:36technomancysjl: the official story is that it's ambiguous whether the two conditions would be ANDed together or ORed.
23:37kovasband-let
23:37iDesperadOI've already done that
23:37kovasbor-let
23:37sjltechnomancy: I'd assume ANDed
23:37xeqiI think I remember that spawning a long mailing list thread
23:37technomancynot saying I agree, but that's the official position
23:39sjlhow would or even make sense? would it short-circuit the binding like (or) and leave one unbound?
23:40sjlI guess it could just do them all and leave them bound to falsy stuff
23:40sjlwheras AND would behave the same as (and) where it short-circuits
23:40kovasbyou let them bind to whatever the value was
23:40kovasbwhat the multi form should do is
23:40kovasblet you specific which variables must not be nil
23:40sjlkovasb: yeah, just seems weird since (or) short circuits but (when-let-or) wouldn't
23:41kovasbgood point
23:41michaelr525good morning!
23:41sjlwhereas both (and) and (when-let-and) short circuit the same way
23:42sjland there's no nice way to do the and version now, wheras you can do the or version with a single (let [...] (when (or bindings...) ...)) now
23:42botterclooj is what I'm looking for. thanks.
23:42kovasbbotter: np
23:43kovasbsomething like (when-let2 [a … b …] [a b] …)
23:43kovasbwhere a b specifies that a and b must be not falsey
23:43sjlkovasb: eh, that's getting a bit fiddly
23:44kovasbseems flexible to me
23:44kovasbunless you want to only all or any behavior
23:44kovasbif you want all, might as well list them out
23:45kovasbor just give a symbol :all, or :any, and then have the vector case for specifying granularly
23:45sjlwell, the when-let-or version can be done in a 3-level structure for N bindings right now
23:45sjlbut the when-let-and version requires N levels for N bindings
23:45sjlso it seems that AND would be more beneficial
23:46kovasbi haven't had a need so i can't really tell :)
23:46amalloy$google github egamble let-else
23:46lazybot[egamble/let-else · GitHub] https://github.com/egamble/let-else
23:46kovasbbut its pretty reasonable to have a spec that says how the logic should work
23:46kovasbunless there is a slam dunk case for a more specific taylored version
23:46technomancyamalloy: fancy-town
23:47amalloyeh?
23:47technomancylet-else
23:47technomancylots of options there
23:48amalloyyeah. i don't like it enough to use it myself, but i helped him write it, and it seems like the road these folks are headed down
23:49sjlI don't need lots of crazy functionality -- I was just thinking when-let would do something useful instead of just explode
23:49brehautlooks like a special syntax version of the maybe monad
23:50sjlbut it's only three levels right now so I'll just type the extra when-lets
23:51brehaut(that wasnt intended to sound disparaging. merely an observation)
23:52technomancybrehaut: "That looks like a monad. Not that there's, you know, anything wrong with that."
23:52brehauthaha
23:54technomancysjl: what was the dependency you were having trouble with?
23:55sjltechnomancy: Lanterna -- it's a Java lib and the version I want/need is only on Sonatype
23:55sjltechnomancy: and I couldn't find the magic :repository incantation to get it working, so I just ended up using lein-localrepo to install the jar
23:55technomancy=(
23:56sjlmeh, it's a throwaway project to relax and unwind after a day of tracking down git/python insanity -- getting it working is more important than 100% build purity
23:58technomancyfor the record, it goes like this :repositories {"sonatype-snapshots" "https://oss.sonatype.org/content/repositories/snapshots&quot;}
23:58sjlhmm, I could have sworn I tried that...
23:58sjldoes the key matter?
23:58sjl(the "sonatype-snapshots")
23:58technomancyshouldn't
23:58sjlhmm
23:59sjlI thought I tried that, but maybe not
23:59sjlanyway, how would I have figured that out? I looked for a repository URL on the sonatype page for that lib, but there wasn't one
23:59sjl(I only vaguely know Maven, etc so it might be over my head)