#clojure logs

2014-09-01

02:28sm0keso if i am building this nested map {:a {:b {:c 1 :d x}}}, i want if x is nil its not assoc'd to the map
02:28sm0keis there a nice way to do this
02:31TEttinger,(let [m {:a {:b {:c 1}}} x nil] (if (nil? x) m (update-in m [:a :b :d] x)))
02:31clojurebot{:a {:b {:c 1}}}
02:31TEttinger,(let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] x)))
02:31clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
02:31TEttinger,(let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] (constantly x))))
02:31clojurebot{:a {:b {:d 2, :c 1}}}
02:31sm0keyes thats the obvious way, i was looking something `easy`
02:32TEttingerwell I imagine it wouldn't be hard to make that into a more general function. the update-in is the tricky bit
02:33TEttingerclosest thing I can think of is when-let
02:33TEttinger(doc when-let)
02:33clojurebot"([bindings & body]); bindings => binding-form test When test is true, evaluates body with binding-form bound to the value of test"
02:33sm0keyes yes, but i want this to work on arbitary data e.g.
02:33sm0ke{:a {:b {:c [1 2 x]}}}
02:33sm0kei want to eliminate that x
02:34TEttingercomplex nesting is not the kind of thing there's pre-written solutions for
02:34TEttingerupdate-in is as close as it gets
02:34TEttingerI could be wrong and amalloy swoops in with a half-of-one-liner
02:35sm0kei think it is impossible
02:35TEttingerwell you haven't really described what you want
02:35sm0kewhat i want is something like compile time with consitions on runtime
02:35sm0kecondition*
02:36TEttingerdo you want to be able to replace any instances of some variable, like 'x , with a value regardless of where it is?
02:37sm0kei just want an prettier alternative to what you did, (let [m {:a {:b {:c 1}}} x 2] (if (nil? x) m (update-in m [:a :b :d] x)))
02:37TEttinger,(count "(if (nil? x) m (update-in m [:a :b :d] x))")
02:37clojurebot42
02:38sm0keyou are ignoring the let form
02:38TEttingerbecause that's just your predefined stuff
02:38TEttingerthat's stuff you would pass in
02:38TEttinger,(def m {:a {:b {:c 1}}})
02:38clojurebot#'sandbox/m
02:39sm0kewhat if there was something like {:a {:b {:c 1 **-x :d x}}}
02:39TEttinger,(def x 2)
02:39clojurebot#'sandbox/x
02:39TEttinger,(if (nil? x) m (update-in m [:a :b :d] x))
02:39clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
02:39sm0ke**- is magic condition which ignores depending on x
02:39sm0ke:P
02:39TEttinger,(if (nil? x) m (update-in m [:a :b :d] (constantly x)))
02:39clojurebot{:a {:b {:c 1, :d 2}}}
02:39TEttingerwell uh your map has 5 items
02:40sm0keyes **-x is a reader macro
02:40TEttingerok, you could probably do that yes. reader macros are kinda discouraged...
02:40TEttingerI'm thinking of reader literals
02:40TEttingerwhich are not recommended in libraries
02:40sm0ke#only/if
02:41sm0kei am not sure if even that would work
02:41sm0keit is impossible to do this {:a {:b {:c 1 #only/if :d x}}}
02:41TEttingerit should be. hang on
02:42TEttinger,{:a {:b {:c 1 #_ :d #_ x}}}
02:42clojurebot{:a {:b {:c 1}}}
02:42TEttingerso you can already ignore forms, you just want to do it selectively
02:42sm0keyes my first though was also using (comment)
02:43TEttingerwhich returns nil, for some reason...
02:43sm0ke,{:a {:b {:c 1 (if false [:d 2] (comment))}}}
02:43clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
02:43sm0kewow stupid
02:44TEttingerit's true though
02:44TEttingerthat's a key, [:d 2]
02:44sm0kebut it has to be a compile time thing you see? but (if x..) is a runtime thing
02:45sm0kecant be done!
02:47TEttingeryeah, I think because you're trying to do it inside the map {} literal
02:47sm0keyes we would need a special macro for [] {} etc to do this
02:47TEttingerif is a macro, and I admit I'm not an expert on macros
02:48sm0keugh, i am going back to if's and let's
02:49TEttingeryes, if is what you should use here
02:49TEttingerall other solutions are much more hackish
02:52sm0keso all that we need is this (runtime-to-compiletime-if x [:d 2]) this evaluates x during runtime and spats :d 2 (flattening them) for the compiler
02:52sm0kewhich makes no sense
02:53sm0keyay! I just wasted your 15 minutes
03:10SagiCZ1anyone remembers how do i access this channels logs?
03:11beamsohttp://logs.lazybot.org/irc.freenode.net/%23clojure/2014-09-01.txt
03:12SagiCZ1beamso: thank you
03:13SagiCZ1i need couple more hours back
04:53JL235Has anyone got any experience with clojure-clr?
04:53JL235I am thinking of using it
04:53JL235I have a .net project and thinking of rebuilding it with clojure (as I also want to get into Lisp too)
04:55clgvJL235: what is stopping you from trying it?
05:15JL235nothing
05:15JL235but I don't want to invest time moving a project over to something that may have a lot of warts
05:15JL235not when I could go with something else instead
05:15JL235so just asking around on people's experiences
05:18clgvJL235: well, before migrating a project you need to learn the language. Hence, I asked what is stopping you from trying out clojure and start learning the basics?
05:24JL235I am not asking in regards to learning the language
05:25clgvJL235: what are you asking then? the more specific the question the likelier you get a helpful answer
05:26JL235"Has anyone got any experience with clojure-clr?"
05:30maxthoursieJL235: I've tried to use it, but while core is there, lot's of libraries aren't. I ended up going with jvm clojure instead
05:37jyfl987hi can anyone give me some example showing parsing weblog file , the filename should be given by cmdline
05:40riffraffhi everyone
05:41riffraffI'm tryint to add test.check tests to my project and I'd like to have them run as normal tests as per clojure.test
05:41riffraffAFAIU I shoiuld use defspec, but I get a Unable to resolve symbol: defspec in this context
05:42riffraffany ideas of what I'm doing wrong? Sorry if' it's a silly question, I'm a newbie :/
05:44JL235thanks maxthoursie
05:44riffraffah I found it in another namespace maybe
06:13clgvriffraff: why not deftest?
06:13riffraffit was my understanding defspec was the preferred way to use test.check with clojure.test
06:13clgvriffraff: ah defspec is part of test.check
06:13riffraffyeah
06:13riffraffthe name is somewhat confusing to me as it seems to refer to some BDD framework
06:13clgvfrom the tests in test. heck it seems to be the way to go
06:13riffraffyes I got it working now
06:13riffraffthe trick was that it's defined in clojure.test.check.clojure-test
06:13clgvfor future readers, it is in clojure.test.check.clojure-test
06:13riffraffbut this is not called out in the readme. As a noob I assumed I was doing something stupid with requires :)
06:13clgvyeah, there could be more documentation.
06:13clgvI am just fiddeling with recursive generators
06:16riffrafferr, another silly question: given "lein repl" where my project.clj has org.clojure/test.check in the dependencies, should (require '[clojure.test.check :as tc])
06:16riffraff work ?
06:20clgvriffraff: yes, it should
06:20clgvriffraff: do you do any profile magic?
06:20riffraffnot that I am aware of
06:21clgvdid you restart the repl after adding the dependency?
06:23riffraffthe one I just opend yes
06:23riffraffnot sure if there is some daemin process I need to restart too
06:24clgvriffraff: no. requiring should work then
06:25clgvreplace "should" with "must"
06:26riffraffeh :)
06:29riffraffah I think it _is working, but I was looking at it wrongly
06:30riffraffbasically, trying to see if the symbol "tc" was bound to something (by typing "tc" in the repl)
06:30riffraffbut it's not, while tc/quick-check instead is
06:30riffraffI think I need to study this namespacing thing a bit more
06:30riffraffthanks anyway
06:51clgvriffraff: ah ok.
06:52clgv,(require '[clojure.string :as str])
06:52clojurebotnil
06:52clgv,(keys (ns-aliases *ns*))
06:52clojurebot(str)
06:52clgvriffraff: that's a way to check the alias ^^
06:52riffraffawesome, thanks
06:53clgv,((ns-aliases *ns*) 'str)
06:53clojurebot#<Namespace clojure.string>
06:53clgv^^ to see where it maps to
06:56martinklepschwhen evaling (println "something") in cider, is there a buffer where I can see the result?
06:56martinklepschah, nevermind
06:56martinklepschthe cider-repl buffer :)
07:30SagiCZ1if i have a non-atom list of atoms can i see their changes?
07:34clgvSagiCZ1: example?
07:35SagiCZ1(def a (atom 0)), (def b (atom 1)), (def v [a b]), .. now i keep the reference to "v" i can swap! the atoms in it right?
07:37noidiyes, but not atomically :)
07:37SagiCZ1noidi: elaborate?
07:38clgvSagiCZ1: you cant guarantee any consistence between the two atoms
07:39clgvSagiCZ1: your options are to have the vector within an atom or to use references instead of the atoms
07:39noidiSagiCZ1, say both atoms start at 0 and you want to `inc` them. an observer may observe a world in which one atom has the value 1 and the other 0
07:39clgvSagiCZ1: btw your usage of def for `a` and `b` is alarming
07:46SagiCZ1why is alarming?
07:53SagiCZ1(ns my-ns (:require [ui]))
07:53SagiCZ1this says it could not locate ui__init.class but i have the ui namespace in the same folder, whats wrong?
07:56llasramSagiCZ1: namespaces are always absolute, never relative
07:57SagiCZ1thank you, it works now
07:58clgvSagiCZ1: because `def` is only intended for *global* variables
07:59SagiCZ1clgv: these are supposed to hold game's state and i read that game state should be global and immutable
08:00lqls
08:00lazybotbin etc home lib lost+found media mnt opt proc root sbin sys usr var
08:01llasramSagiCZ1: Yeah, but you don't need two top-level references to the same object. E.g., just: (def game-state [(atom 0) (atom 0)])
08:01llasram(or whatever)
08:02SagiCZ1oh yes ive already changed that.. it was just for the example.. thank you though
08:02clgvSagiCZ1: what llasram said ^^
08:04clgvSagiCZ1: I think the decision between game state as global variable or game state as function argument is not that clear as you state
08:04SagiCZ1clgv: its the only that makes sense to me.. i cant wrap my head around passing game state around 20 functions
08:05llasramSagiCZ1: And yet it has a lot of benefits
08:05clgvSagiCZ1: that way you are tempted to have no pure functions at all
08:06SagiCZ1if i try to use only pure functions i cant progress at all.. do you have any examples of very simple games with pure functions?
08:06clgvSagiCZ1: pure functions are "easy" to test
08:06llasramAt my company we started off with several things that it seemed to "make sense" would just be global state, like configuration
08:07llasramAnd we've realized it was pretty much all a terrible idea, which has made code much harder to test, and are moving to pure-as-possible functions for everything
08:07SagiCZ1llasram: i understand all the advantages of pure functions.. which does not make me able to write them
08:07clgvSagiCZ1: well, you will have at least one function that holds the atom, e.g. the main game loop
08:07llasramSagiCZ1: Why is it harder? You just have an extra first argument to your functions which is the game state
08:08lvh_is there a codecs library I'm missing? I need urlsafe base64; the only one I can find is inside buddy
08:08lvh_and dragging in all of buddy for 10 lines or so seems silly
08:08llasramlvh_: Apache Commons?
08:08lvh_(as does copying those 10 lines)
08:08lvhllasram: does that have urlsafe base64? I thought it didn't, I'll double check
08:08llasramOh, maybe not. I just assumed it would
08:08clgvlvh_: isn't there some clojurewerkz lib for URLs that is able to do that?
08:08llasramWhat makes normal base64 not URL-safe?
08:09lvhllasram: wait, you're right, it does :)
08:09llasramcool
08:09lvhclgv: that'd be great!
08:09SagiCZ1the thing is.. i am using swing for rendering, i.e. paintComopnent method which has fixed amount of arguments.. how could i pass the state in there?
08:09lvhclgv: *looks*
08:09lvhllasram: some parts of the alphabet
08:09lvhllasram: + and /, specifically
08:09llasramAh, of course
08:10clgvSagiCZ1: do you use seesaw?
08:10SagiCZ1clgv: yes
08:11lvhclgv: there's https://github.com/clojurewerkz/route-one, but it doesn't appear to know anything about base64.
08:11clgvSagiCZ1: well, you can easily build closures as paint handlers, that close over the game state atom. on each paint call you deref the atom
08:11SagiCZ1clgv: either the entities i want to render must be global or the canvas i want to paint on must be global
08:12SagiCZ1yeah using clojure while not understanding closures sounds like a terrible idea
08:13clgvSagiCZ1: the functions that do the actual painting cant be pure of course, but the game logic that updates the state can be
08:14SagiCZ1they cant be pure because the fact that they actually "paint on screen" is a side-effect right?
08:15clgvlvh: the contrib lib data.codec has base64 encoding but it's also a bigger dependency...
08:16clgvSagiCZ1: yeah. but functions that determine how something needs to be painted (e.g. color dependend on several state values) can be pure
08:17SagiCZ1clgv: could u write a pseudocode example of this please? "well, you can easily build closures as paint handlers, that close over the game state atom. on each paint call you deref the atom"
08:20clgvSagiCZ1: here is the example how to add a paint handler https://github.com/daveray/seesaw/blob/master/test/seesaw/test/examples/paintable.clj#L31
08:22SagiCZ1i am using that.. but the "draw-a-red-x" is not "closing over" anything is it?
08:23clgvSagiCZ1: in the function creating your gui you could do something like (defn create-gui [game-state-atom, ...] (<CANVAS-COMPONENT> ... :paint (fn [component, graphics] (let [game-state @game-state] ....paint...))))
08:23SagiCZ1clgv: now i see it.. perfect!
08:23clgvSagiCZ1: just replace <CANVAS-COMPONENT> with whatever you use as canvas
08:24clgvchange "@game-state" to "@game-state-atom"
08:24SagiCZ1yeah.. no the atom does not have to be global
08:24SagiCZ1*now
08:29lvhIs there a ring/compjure thing that lets me say "this part of the URL is a base64 thing; please give me the decoded version"
08:36SagiCZ1clgv: back your example.. is it possible to create the inner function somewhere else for clarity? or it has to be nested to access the atom?
08:38SagiCZ1clgv: maybe i should have a "factory-function" that can output a function with the closure?
08:41jeffterrelllvh: I found ring.util.codec/base64-{en,de}code here: http://mmcgrana.github.io/ring/ring.util.codec.html
08:41jeffterrelllvh: Does that work for you?
08:41lvhjeffterrell: yeah, me too. Not urlsafe though.
08:41lvhjeffterrell: (also doesn't automagically do the encoding btu I can live with that
08:43jeffterrellFair enough.
08:44lvhI wish clojure.string.trim let me specify which chars I wanted to trim
08:46SagiCZ1i would like to call a function n times to generate a list of n items, how do i do that?
08:46hyPiRion(repeatedly n fun)
08:46hyPiRionit's lazy though, so be aware of that
08:46hyPiRion,(repeatedly 10 rand)
08:46clojurebot(0.5949458375138312 0.08279190123529145 0.14265751227133672 0.07628975550512085 0.7772873079770356 ...)
08:47SagiCZ1hyPiRion: thats what i want
08:47SagiCZ1ty
08:48SagiCZ1,(repeatedly 4 #(0))
08:48clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
08:48SagiCZ1why this doesnt work though?
08:49SagiCZ1,(repeatedly 4 (fn [] 0))
08:49clojurebot(0 0 0 0)
08:49SagiCZ1and now it does??
08:49lazybotSagiCZ1: Definitely not.
08:50SagiCZ1,(repeatedly 4 #((0)))
08:50clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
08:50hyPiRionSagiCZ1: What is (0) ?
08:50SagiCZ1i just want a function that returns 0
08:50SagiCZ1this is not correct? #(0) ?
08:50clgvSagiCZ1: (constantly 0)
08:50r4vi(0) is trying to function call a Long
08:50hyPiRionIf you want a constant you could use (repeat 4 0), btw
08:51clgv,(read-string "#(0)")
08:51clojurebot(fn* [] (0))
08:51clgvSagiCZ1: ^^ that's why
08:51riffraff(repeatedly 4 #( 0 ) ) wouldn't work either though, why?
08:51clgvriffraff: see above
08:51SagiCZ1it wraps it with another set of braces
08:51hyPiRion,'#(0)
08:51clojurebot(fn* [] (0))
08:51riffraffahihi, got it
08:51clgvhyPiRion: uhh shortcut :D
08:52SagiCZ1,(constanly rand)
08:52clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: constanly in this context, compiling:(NO_SOURCE_PATH:0:0)>
08:52SagiCZ1,(constantly rand)
08:52clojurebot#<core$constantly$fn__4178 clojure.core$constantly$fn__4178@147fc78>
08:52SagiCZ1,((constantly rand))
08:52clojurebot#<core$rand clojure.core$rand@15e8c9d>
08:52hyPiRionthat's a function returning the function rand all the time
08:52SagiCZ1,((constantly (rand)))
08:52clojurebot0.3298967693738979
08:53SagiCZ1,(repeatedly 5 #(constantly (rand)))
08:53clojurebot(#<core$constantly$fn__4178 clojure.core$constantly$fn__4178@b873c> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@dbb0af> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@12cea05> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@1b7fb2c> #<core$constantly$fn__4178 clojure.core$constantly$fn__4178@1cb30a4>)
08:53SagiCZ1nevermind
08:53clgv,(repeatedly 5 (constantly (rand)))
08:53clojurebot(0.17791487825993624 0.17791487825993624 0.17791487825993624 0.17791487825993624 0.17791487825993624)
08:53clgvSagiCZ1: no idea why you want it that complicated but that works ^^
08:54clgv,(repeat 5 (rand))
08:54clojurebot(0.9761251033774431 0.9761251033774431 0.9761251033774431 0.9761251033774431 0.9761251033774431)
08:54clgvSagiCZ1: same effect ^^
08:54SagiCZ1clgv: ^^ just playing around
08:55SagiCZ1so is there a nicer way to do exactly this?
08:55SagiCZ1,(repeatedly 4 (constantly {:a 0 :b (rand)}))
08:55clojurebot({:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073} {:a 0, :b 0.49531751143064073})
08:56SagiCZ1,(repeat 2 {:a 0 :b (rand)})
08:56clojurebot({:a 0, :b 0.8084007871336014} {:a 0, :b 0.8084007871336014})
08:56SagiCZ1got it
09:02hyPiRionyou want (rand) to be the same value for each item? Asking, just to ensure you get the right thing out
09:03lvhWhat's the idiomatic data structure in Clojure for bytestrings?
09:03lvhI've been using bytes[] but that just feels super gross.
09:04clgvhyPiRion: yeah, looks like a code smell. should be something like (let [r (rand)] (repeat 5 {:a 0 :b r})) to make the intention clear
09:05SagiCZ1hyPiRion: nope that is a mistake
09:05SagiCZ1hyPiRion: why is not calling random again?
09:05justin_smithlvh: you can use a vector of Byte values, byt bytes[] is an actual array of bytes, and is the right way to represent that
09:06lvhjustin_smith: also mutable though right
09:06justin_smithright
09:06justin_smithwhat do you mean by "bytestring", actually?
09:07justin_smitharrays of bytes are not CharSequences because they are made of 8 bit signed values
09:07llasramSagiCZ1: Because you are calling it yourself vs passing the function `rand` to something
09:07llasram,(repeatedly 5 rand)
09:07clojurebot(0.013326642964774371 0.40762242985735264 0.7708784528135172 0.9785686587084479 0.7638473865027904)
09:07justin_smithlvh: maybe you want an array of shorts, or even ints, if you want to represent anything beyond 8 bits
09:08SagiCZ1,(repeatedly 2 (fn [] {:a (rand) :b (rand)}))
09:08clojurebot({:a 0.7095231468043378, :b 0.2359827909847596} {:a 0.7883582125143982, :b 0.8835072257869794})
09:08SagiCZ1this is what i want
09:08SagiCZ1i just dont like the fn notation
09:08clgvSagiCZ1: so why dont you use it? that why? :P
09:08clgv*way
09:08SagiCZ1clgv: fn seems uncool to me
09:08SagiCZ1especially with no arguments
09:09hyPiRionSagiCZ1: ##(map #(assoc {:a 0} :b %) (repeatedly 2 rand))
09:09lazybot⇒ ({:b 0.7055591223129442, :a 0} {:b 0.004841332288907818, :a 0})
09:09llasramSagiCZ1: No no -- `fn` is the coolest
09:09justin_smith,(repeatedly #(hash-map :a (rand) :b (rand)))
09:09clojurebot({:b 0.7774605426166392, :a 0.5457287633034817} {:b 0.9351205665136824, :a 0.10940327234871117} {:b 0.2785826781824663, :a 0.06663172148153373} {:b 0.6237813005636965, :a 0.6235348439569292} {:b 0.2189573584793213, :a 0.11105258859414224} ...)
09:10justin_smithyes, fn is awesome
09:10SagiCZ1thanks for the ideas
09:10llasram,(repeatedly 2 #(-> {:a (rand)}))
09:10clojurebot({:a 0.3764276763964761} {:a 0.28425055137631283})
09:10clgvSagiCZ1: doh!
09:10lvhjustin_smith: I mean bytestrings as in sequences of bytes. Like a C string, or a Python string.
09:10lvhjustin_smith: Not like a java String, of course.
09:10llasramlvh: s/Python string/Python 2 string/
09:10justin_smithlvh: yeah, byte-array is that (and is of course mutible)
09:11lvhllasram: python3 doesn't exist ;)
09:11llasram:-p
09:13SagiCZ1another question.. if i want to have an inner function close over some local symbol, can i define it somewhere outside?
09:13SagiCZ1scratch that..
09:14justin_smithyou can pass local values to a function that creates a new function closing over those values
09:14SagiCZ1yep.. gonna do just that
09:14justin_smithlike the classic make-adder
09:30SagiCZ1can i deref atom by destructuring? (doseq [{a :a b :b} [(atom {:a 0 :b 1}) (atom {:a 2 :b 3})]] (println a b))
09:31clgvSagiCZ1: no not like that. first deref it to get the value then apply destructuring on the value
09:32SagiCZ1ok
09:32justin_smith,(let [{a :a} (atom {:a 42})] a)
09:32clojurebotnil
09:32justin_smith,(let [{a :a} @(atom {:a 42})] a)
09:32clojurebot42
09:32SagiCZ1yeah that works for let, but not for doseq when u have a coll of atoms
09:32justin_smithyou *can* destructure an atom, it just won't return the value you want
09:33justin_smithSagiCZ1: doseq and let use exactly the same destructuring
09:33vladh_Hey guys — does anyone know how I can keep a script running via lein-exec? I’m trying to run a simple cron-style thing with at-at and don’t want to script to immediately.
09:33vladh_to die*
09:33SagiCZ1justin_smith: no they dont?
09:34justin_smithSagiCZ1: doseq needs a sequence, but doseq and let both call clojure.core/destructure to do destructuring
09:34SagiCZ1doseq does that for each element of the sequence separately though
09:35justin_smithsure - so it destructures each element of the sequence
09:35justin_smithI am just saying the actual destructuring, when it happens, is done by the same function
09:35SagiCZ1alright..
09:35SagiCZ1i see
09:36justin_smithand my ,(let [{a :a} (atom {:a 42})] a) is exactly analogous to your (doseq [{a :a b :b} [(atom {:a 0 :b 1}) (atom {:a 2 :b 3})]] (println a b))
09:37justin_smithbut I switched to let because there is less noise there, and the destructuring happens in the same manner
09:37SagiCZ1but in let u can solve the problem with prepending @ to the right sight of the binding.. in doseq u cant
09:38llasramwat
09:38justin_smith(doseq [{a :a b :b} (map deref [...])] ...)
09:38SagiCZ1oh.... wow
09:38SagiCZ1mind - blown
09:38llasramSagiCZ1: @ is a reader macro for `deref`
09:38llasram,`@whatever
09:38clojurebot(clojure.core/deref sandbox/whatever)
09:38SagiCZ1thats news to me
09:39clgvSagiCZ1: well you should probably read the chapter on atoms and refs ^^
09:39SagiCZ1clgv: i read it so many times .. i just figured that i should also write some code to help me remember
09:40SagiCZ1my theoretical knowledge of clojure is higher than the practical experience.. im not saying it's very high anyways
09:40clgvSagiCZ1: use the chapter while writing code ;)
09:40SagiCZ1alright
09:41lvhIs x.y.z-SNAPSHOT before, or after x.y.z?
09:41llasramlvh: "Before", but snapshots are non-release, so you have no way of knowing what's in one
09:42justin_smithllasram: well you can always look inside :P
09:42justin_smithbut yeah, no way to know beforehand what you'll get if you ask for it
09:42llasramjustin_smith: Except that the non-pinned SNAPSHOT revision could be updated at any time
09:42clgvlvh: use snapshots only for experimenting with new features that are not in any release, since they might sabotage repeatable builds
09:43lvhI'm trying to publish software thoguh :)
09:43justin_smithllasram: I meant you can check strictly a-posteriori, but really that hardly matters compared to not knowing what you'll get if you ask for it
09:45clgvlvh: well at the end of a dev cycle release a non-snapshot, during the dev cycle you can use snapshot versions
09:46lvhok :)
09:48zeebrahY do i need do add the eval here: ((eval (read-string "first")) [1 2 3])
09:48llasramzeebrah: mu
09:49zeebrahllasram: dont know mmu
09:49clgvzeebrah: because you are doing weird stuff ;) a `resolve` would suffice
09:50clgv,((resolve (read-string "first")) [1 2 3])
09:50clojurebot1
09:50zeebrahclgv: i'm watching bob martin so yes definitely weird :)
09:50clgv,((resolve 'first) [1 2 3])
09:50clojurebot1
09:50clgvsame ^^
09:50clgv,(first [1 2 3])
09:50clojurebot1
09:50zeebrahso resolve is taking a symbol and then finding the function? but why is that necessary
09:51llasramzeebrah: Needing to manually `read` string which contain code is unusual, and probably means there's a more common way to do whatever you're trying to do
09:51llasramzeebrah: Or do you just want to understand why a symbol is not identical to the function a particular namespaces maps that symbol to?
09:51zeebrahllasram: just trying something out because the dude said you can build lisp code and then execute it using eval
09:51zeebrahllasram: i guess :)
09:52zeebrahif the symbol is in function position then why doesn't it just work as I expected?
09:52clgvzeebrah: what are you watching exactly?
09:52zeebrahhttps://www.youtube.com/watch?v=SYeDxWKftfA
09:52justin_smithzeebrah: the normal way is to just type into the repl, it does the eval and read for you
09:52clgvzeebrah: since the symbol is a symbol and is not a function
09:52llasramzeebrah: So in Clojure (and most Lisps) "reading" and "compiling" are separate steps
09:53llasramReading turns text into a data-structure
09:53llasramCompilation turns a data-structure into code
09:53zeebrahclgv: right but its not like there are multiple namespaces so there isnt any ambiguity in just using the only one in the namespace?
09:53clgvso Uncle Bob uses Clojure, eh?
09:53zeebrahapparently!
09:54clgvyou explicitly constructed a symbol in your example, so no it can not
09:54zeebrahis namespace the right word there? i mean in the sense of lisp 1 and 2
09:54clgvif you just put a symbol in call position it is resolved to a function on compilation or an error is thrown
09:54llasramzeebrah: In that sense Clojure is a Lisp-1 and has only one "namespace", but it has a concept of namespaces (like CL packages), so the same bare symbol could refer to multiple functions in different namespaces
09:54zeebrahoh i see
09:55justin_smithsymbols can have namespaces, but a bare one doesn't - but it gets resolved according to the mappings of the current namespace to a var
09:55llasram^^ During compilation
09:55clgvjustin_smith: but not in his case where he explicitely constructed a "symbol value"
09:55llasram(well, or manual resolution via e.g. `resolve`)
09:56justin_smith,(map namespace '[foo user/foo sandbox/foo clojure.string/foo])
09:56clojurebot(nil "user" "sandbox" "clojure.string")
09:56justin_smithclgv: right, not always resolved - but it uses the same rules once you ask for it to be resolved
09:58zeebrahso the reason ((read-string "first") [1 2 3]) didnt return 1 is b/c first doesn't yet belong to a namespace but yet it is still a symbol
09:59justin_smithit's just the symbol, not the var the symbol points at
09:59justin_smith,((read-string "clojure.core/first") [1 2 3]) ; this is no better
09:59clojurebotnil
10:00justin_smithresolve says "find the var for this symbol"
10:00zeebrahoh
10:00hyPiRion,('+ 1 2)
10:00clojurebot2
10:00justin_smith,((read-string "clojure.core/first") [1 2 3] 1) ;P
10:00clojurebot1
10:01justin_smiththat's just a trick
10:01zeebrahso how is this not like a lisp-2 doing (function ..) first? i thought going to a lisp 1 made that unnecessary
10:01zeebrahhmmm interesting
10:01hyPiRionzeebrah: Because a symbol is not a function
10:02justin_smithzeebrah: in normal code, you type the name of the function, and it gets the value pointed at by the var indicated by the symbol
10:02zeebrahunderstood thanks :)
10:02justin_smith,(let [plus +] (plus 1 1))
10:02clojurebot2
10:02justin_smithcan't do that in a lisp-2
10:03hyPiRionRight. (let ((plus #'+)) (funcall plus 1 1)) is the closest
10:03justin_smithwhich reminds me I should make my above statement more precise: it gets the value pointed at by the local binding, or failing that, var resolution
10:04zeebrahdoes scheme have a version of resolve too?
10:05SagiCZ1lets say i refer to a different ns "other-ns" using :require in my (ns) .. i am working in the current ns in repl.. what if i want to change a function in the "other-ns" and reflect the change in my working repl? should i call (ns) again to :require it again? it didnt reflect the changes
10:05xeqidoes ` have a name?
10:05justin_smithxeqi: syntax-quote
10:06xeqiquasi-quote, symbol-quote ..
10:06xeqiah
10:06xeqithanks
10:06hyPiRionI've always referred to it as backquote
10:06justin_smithzeebrah: I think in scheme eval is more likely to be used
10:06hyPiRionbut that's cl history I guess
10:06justin_smithhere it is called syntax-quote http://clojure.org/reader
10:06mi6x3mclojure
10:06mi6x3mwhat is a way to extract only a subset of the keys in a map?
10:07mi6x3mlike (subset map [:a :b :c])
10:07justin_smithselect-keys
10:07mi6x3m,(doc select-keys)
10:07clojurebot"([map keyseq]); Returns a map containing only those entries in map whose key is in keys"
10:07justin_smith,(select-keys {:a 0 :b 1} [:a])
10:07clojurebot{:a 0}
10:07SagiCZ1cfleming: hi, are you here by any chance?
10:08mi6x3m(inc justin_smith)
10:08lazybot⇒ 71
10:18SagiCZ1ok let me ask once again.. how do i reload a library in repl?
10:19clgvSagiCZ1: library or namespace of the current project?
10:19SagiCZ1other namespace
10:19clgvusually you use "send to repl" or something similar which your ide/editor provides
10:20SagiCZ1ok i just tried that and it owrks
10:20SagiCZ1works
10:20SagiCZ1i thought there is some programatic way
10:20clgvSagiCZ1: well yeah, there is but you'll end up with tools.namespace then
10:20SagiCZ1yeah i dont want that..
10:21clgv+likely
10:21SagiCZ1but this works so thats fine
10:22justin_smithSagiCZ1: (require 'some.ns :reload) works in a vanilla repl
10:22SagiCZ1justin_smith: thank you
10:23justin_smithclgv: the reason to use tools.namespace there is if a definition is removed from the ns, :reload does not undefine it, right? or is there some other nuance?
10:27clgvjustin_smith: types and records are problematic. if you redefine a type by reloading its defining namespace other functions from different namespaces that were not reloaded but use that type will break
10:27justin_smithahh, right
10:28lvhI have a bunch of forms in a threading macro. I want to conditionally add one. Is there a reasonable trick for that?
10:28clgvjustin_smith: that's an example from my experience where using require only will break
10:29elazarTrying to go through Clojure koans: https://github.com/functional-koans/clojure-koans. Hitting an issue with cons. http://pastebin.com/raw.php?i=mkPrG1zn Any suggestions?
10:29justin_smithelazar: note how they create the sequence you are consing onto?
10:30justin_smith*they are consing onto
10:30elazarAh, I think I see.
10:30justin_smithyou have to do the same thing with your sequence
10:30elazarWell, I'm a little further now. Thank you, justin_smith. :)
10:30justin_smith,[(:a :b :c :d :e) '(:a :b :c :d :e)]
10:30clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a>
10:31justin_smith:a is a keyword, it invokes get on its args if used in a function position
10:32elazar,(= (quote (:a :b :c :d :e)) (conj (quote (:a :b :c :d)) :e))
10:32clojurebotfalse
10:33justin_smithconj is a little funny ##(= (conj [:a :b] :c) (conj '(:a :b) :c))
10:33lazybot⇒ false
10:34elazar,(= (quote (:e :a :b :c :d)) (conj (quote (:a :b :c :d)) :e))
10:34clojurebottrue
10:34elazar^ Yeah, figured it out. :)
10:34elazarhttp://clojuredocs.org/clojure_core/clojure.core/conj <-- second example
10:34elazarSorry, first example, second input.
10:35justin_smith,(conj #{:a :b :c :d} :e)
10:35clojurebot#{:e :c :b :d :a}
10:48maxthoursielvh: cond-> ?
11:41sm0keusing java.jdbc is there a way to preserve order of columns?
11:42sm0keselect a,b,c from ... gives {:a 1 :b 2 :c 3} which loses the order
11:42bjasm0ke, I can't imagine relying on ordering there is safe
11:44sm0keyes, that is why i am asking, jdbc result is ordered
11:44bjahttps://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L800
11:45bjait looks like query takes :as-arrays? true to make the result set fn into vdc
11:45bjaI didn't try it, but it sounds exactly like what you want
11:45sm0kelet me try
11:45sm0kethanks bja
11:47sm0keugh, that is for the outer data structure
11:47sm0ke[{},..] instead of '({},..)
11:48bjaoh
11:48bjait looks like the code maps :row-fn across the results
11:49sm0kerow-fn is identity by default so internally it is map as lower denominator
11:49sm0kesad
11:50justin_smith(map (fn [k] [k (m k)] [:a :b :c])
11:50justin_smith)
11:50justin_smithwhere m is the result, and that last arg has the order you want?
11:51sm0kewell thats not the point
11:51justin_smithwhat is the point?
11:52bjasm0ke, https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L362 exists to turn the raw ResultSet into a seq of maps
11:53sm0keugh read the comment
11:53sm0kesad
11:54luqiHello everyone. As a beginner in Clojure, I find it really daunting when things go wrong and the stack trace is just huge. Any suggestions on it?
11:54sm0kehmm there is a interesting comment which says "but using into {} should preserve order for up to 16 columns"
11:56clgvsm0ke: do you need additional features of the default clojure.java.jdbc functions? if not just write a function that handles the resultset directly
11:56bjasm0ke, maybe you only need 16 columns? :(
11:56justin_smithluqi: there are various tools for colorizing output to help you find the relevant parts
11:56sm0keno i need more
11:57sm0kegrr.. i will have to go back to basic jdbc
11:57justin_smithluqi: at this point, I have learned how to read the stacktraces, and I look for the frames that are in files I wrote.
11:58luqiyeah, I always look for my files. but they are kinda buried inside massive Java/JVM frames
11:59justin_smithluqi: https://github.com/AvisoNovate/pretty
12:00justin_smithluqi: this ns in particular https://github.com/AvisoNovate/pretty/blob/master/src/io/aviso/exception.clj
12:00sm0ke(inc bja)
12:00lazybot⇒ 1
12:00sm0ke(inc bja)
12:00lazybot⇒ 2
12:00justin_smithin particular, write-exception
12:00sm0keseems like i was missing the "?" in :as-arrays?
12:00luxbockluqi: if you are using Emacs, I find the cider-stacktrace mode you get with C-c C-s pretty helpful
12:01sm0ke:as-arrays? indeed is the solution!
12:01clojerAnyone know what this compilation error refers to: "NullPointerException clojure.lang.Numbers.ops (Numbers.java:961)" ?
12:01justin_smithclojer: you tried to do math on nil
12:01justin_smith,(+ nil 1)
12:01clojurebot#<NullPointerException java.lang.NullPointerException>
12:01bjanice
12:01luqijustin_smith, yeah this looks much nicer!
12:02clojerjustin_smith: Great, but why doesn't the error come with a line number?
12:02luqiluxbock: I am using Vim primarily but I'd love to learn Emacs :)
12:02justin_smithluqi: awesome, our own hlship (not online right now) worked on it, and introduced me to it
12:02luxbockI use Emacs with evil, which is pretty close to Vim
12:03justin_smithclojer: Numbers.java - on another stack frame you may find a line number in your own code
12:03luqiAha, that's actually what I'm thinking about
12:03clojerjustin_smith: How do I get that in Emacs/cider?
12:03zwerjoin #java
12:03justin_smithluxbock: luqi: as far as I am concerned, getting cider to work would be a terrible way to learn emacs
12:04justin_smithclojer: (pst)
12:04clgv~guards
12:04clojurebotSEIZE HIM!
12:04clgvjoining #java tsk tsk tsk
12:05justin_smithluxbock: luqi: I subscribe to that repo's issues feed, I intend to switch to cider when the bug reports slow down (if they ever do)
12:05justin_smith(cider's that is)
12:05clojerjustin_smith: Brilliant. You're a life-saver.
12:05justin_smithclojer: np - I think the decision to only show one line of the exception by default is kind of silly
12:06justin_smithclojer: also you can access the last uncaught exception object thrown using *e
12:06clojer(pst)
12:06luxbockI think the cider-stracktrace mode as a more convenient version of pst
12:07justin_smithif you want to assign the exception to some var to do something with later, or write your own code that analyzes the exception, *e is quite handy
12:07clojerjustin_smith: Damn. I posted this on the clojure mailing list not realising that was a truncated error message :(
12:08justin_smithI'm sure this isn't the first or last cider bug / cider UI deficiency that has ended up there
12:09clojerjustin_smith: Yes and I'm stuck with cider 0.6 as I'm using Emacs Live awaiting the 0.7-compatible update :(
12:09nbeloglazovIn order to send pull requrest/patches to libs under clojure namespace (e.g. tools.reader) do I have to sign contributor agreement?
12:09justin_smith~emacslive
12:09clojurebotNo entiendo
12:10clojerjustin_smith: My Emacs foo is pretty non-existent :(
12:10luxbockis there something about Emacs Live that preventes you from getting the latest cider-version from elpa/melpa?
12:10justin_smithclojer: emacs live is easy to port to regular emacs, and you can even switch between the two by specifying the config files to run on launch. See also technomancy's https://github.com/technomancy/better-defaults
12:11clojerjustin_smith: I often wondered if that could be done but never found the details.
12:11justin_smithluxbock: not really - but the point of emacs live is you don't want to mess with your own configs freeform yet - you want a compatible zero-effort it just works setup out of the box
12:11justin_smithclojer: it's doable, just not compatible with the whole "it just works" thing :)
12:11clojerjustin_smith: Problem I had in the past was `git submodule <something or other>` wiping out my customisations
12:12luxbockhmm right, I think I started out with one of the starter kits and then ditched most of it once I got a handle of how things worked
12:12justin_smithclojer: put your .emacs.d under git version control :)
12:12clojerjustin_smith: Yes, I like what "just works" with Emacs Live
12:12justin_smithluxbock: clojer: see the readme from technomancy 's better defaults repo I linked above, has a really good sumarry of the situation
12:13clojerjustin_smith: Unfortunatley Dr. Sam Aaron is a bit tied up right now to finish testing Cider 0.7 compatibility
12:14clojerjustin_smith: There's an update in the dev packs somewhere but I'd rather not mess about
12:14justin_smithfair enough, you could be patient, save yourself some pain, and wait for him to do it, or go through the pain and make it work yourself (or maybe "just barely work, good enough for now")
12:15clojerjustin_smith: I'll defer to his greater Emacs skills. Emacs Live is great for my laziness, hubris & impatience :)
12:16justin_smithclojer: in terms of switching configs, the default config is ~/.emacs.d/init.el (or ~/.emacs for legacy, but that is not recommended) - you can launch emacs -q -l alternate-init.el to use a different init file
12:16clojerjustin_smith: OK, sounds like it's worth a try.
12:16justin_smiththis is useful while experimenting, you can copy init.el and then use -q -l to launch an emacs using the alternate, modified init
12:16justin_smithwithout breaking your default init file
12:17riffraffmh how does one get a vector of ints with a skewed distribution with test.check? I tried (gen/vector (gen/frequency [[ 50 gen/int 5] [50 gen/int 100]])) but it doesn't seem to work
12:17martinklepschwhats (go *(while true)* ... ) good for?
12:18reiddraperriffraff: you just need [50 gen/int 5] [50 gen/int 100] isn't a valid syntax for gen/frequency. What are you trying to achieve with that/
12:18justin_smithmartinklepsch: I assume that's (go (while true (do-async-things)))
12:18martinklepschIn clojure it seems to be the default in clojurescript it kills my browser
12:19reiddraperriffraff: err, ignore the 'you just need' part of that message
12:19justin_smithmartinklepsch: related to the fact that js has no threads maybe?
12:20riffraffreiddraper, I was trying to say "get a frequency of 50% ints in 0..5 and 50% in 0..100"
12:20reiddraperriffraff: use gen/choose to create ranges
12:21riffraffisnot gen/choose 0 y the same as gen/int y ?
12:21reiddraperriffraff: (def f (gen/frequency [[50 (gen/choose 0 5)] [50 (gen/choose 0 100)]]))
12:22dnolen_martinklepsch: it not the default in Clojure either - that will result in burning CPU cycles doing nothing
12:22riffraffmh, apparently not
12:22riffraffthanks!
12:22reiddraperriffraff: no. And if it were, you'd need parenthesis around (gen/int x)
12:22martinklepschdnolen_: you're right, I had those examples wrong in my memories.
12:24riffraffI see, I must have tried [5 (gen/int x)], got an error, tried [5 gen/int x], saw it not exploding and moved on
12:25martinklepschso in (go (while true (do-something (<! c)))) —VS— (go (do-something (<! c))) is the (while true ... useful in what scenario?
12:49dnolen_martinklepsch: there aren't really cases where (while true ...) is desirable beyond demo examples, you almost always want loop/recur with some exit condition
12:49devnusing slime + lein-swank again
12:55justin_smithdevn: how is it?
12:55devnsimpler
12:57justin_smithis that an endorsement? it sounds like an endorsement
13:24riffraffOkasu, one last thing I don't really understand about test.check and the above mentioned test. I'd expect to run (tc/quick-check 10 my-prop) and have it test ten random sequencies in a few seconds
13:24riffraff(sorry okasu, I meant "ok", darn autocomplete)
13:25riffraffwhat appears to happen is that the repl runs forever visiting tens of thousands of nodes
13:34reiddraperriffraff: does your test fail?
13:35reiddraperif so, then what you are seeing is something called shrinking. depending on your generators and property, the shrinking process may have to do a large search
13:36clgvreiddraper: is there a possibility to limit the shrinking search or turn it off completely. On occasions this makes sense.
13:38reiddraperclgv: you can wrap your generator (or even your whole property) in gen/no-shrink
13:38reiddraperthere isn't a way (yet) to pause/cancel/limit shrinking otherwise
13:41grincherchange the value of the string if the value contains a specific substring? Eg. map = {:a "nora", :b "sara}; if VALUE contains "nora" replace with "bob", if VALUE contains "ra" replace with "ma" etc
13:42grincherSorry, how can I iterate a nested map and change the value of the string if the value contains a specific substring? Eg. map = {:a "nora", :b "sara}; if VALUE contains "nora" replace with "bob", if VALUE contains "ra" replace with "ma" etc
13:42clgvreiddraper: ok thx
13:42riffraffreiddraper, I think that may be it cause if I try to trace the checking of my property I can see it executed a ton of times, but is there a way to ask the quick-check method to fail fast?
13:43reiddraperriffraff: wrap the property in gen/no-shrink to disable shrinking
13:43riffraffah perfect thanks
13:43reiddraper(tc/quick-check 10 (gen/no-shrink my-prop))
13:44riffraffI didn't notice this in the docs, seems what I need thank you very much
13:45reiddraperriffraff: not documented at the moment
13:46justin_smith,(reduce-kv (fn [m k v] (assoc m k (-> v (clojure.string/replace #"^nora$" "bob") (clojure.string/replace #"ra" "ma")))) {} {:a "nora" :b "sara"}) ; grincher
13:46clojurebot{:a "bob", :b "sama"}
13:47grincherthank you justin_smith :)
13:48justin_smithof course in real code you would require clojure.string :as string and string/replace
13:48justin_smithor something like that
13:49justin_smithalso if you don't want the substitutions to stack, you would want a cond rather than ->
13:53grincherjustin_smith, I am getting some "clojure.lang.LazySeq@d055e162" istead of the "bob" value
13:53justin_smithwith what code? care to share on refheap or a gist?
13:59gfredericks,(clojure.string/replace (str (range 10)) #"clojure\.lang\.LazySeq@[0-9a-f]{8}" "bob")
13:59clojurebot"bob"
13:59justin_smithlol
14:00justin_smithgrincher: if you did a lazy op on a string, then you can get a string out the other end with (apply str ...)
14:00justin_smithgrincher: in my example there are no lazy ops, which is why I asked to see a paste
14:11grincherjustin_smith, https://gist.github.com/gildo/d8f3c6f7614df2368479
14:15justin_smithOK - I don't see anything there where the "bzip2" value would become a lazy-seq
14:15justin_smithwhat yaml lib are you using? I will see if I can reproduce.
14:17grincherjustin_smith, in line 3 you can find the the parsed yaml
14:17grincherline 3 == x
14:17justin_smithcan you share the pr-str version?
14:17justin_smiththat verison is not readable
14:18justin_smithie. the result of (pr x) or (println (pr-str x))
14:19grincherjustin_smith, gist updated
14:19grincherI'am using [circleci/clj-yaml "0.5.2"]
14:22martinklepschI'm trying to write a transducer that takes a map and runs a few api calls based on the maps input, kind of pipelining the output of the first transducer function to the second and so on.
14:23justin_smithgrincher: https://www.refheap.com/89666 I get bob as expected (see the last line)
14:24justin_smithI do see some lazy-seq output there though! I see what you mean.
14:24martinklepschnow I have a function that looks kind of like the following https://gist.github.com/mklappstuhl/67a7cde18575ecf4e39d — point is it takes a callback function to return it's result. how do I properly feed that back into the flow of the transducing function?
14:25martinklepschdo I put it in a channel and take from that channel at the end of that function?
14:26martinklepscham I maybe on the wrong path using transducers here?
14:27Bronsa,(clojure.string/replace (range 10) #"" "")
14:27clojurebot"clojure.lang.LazySeq@9ebadac6"
14:27Bronsajustin_smith: ^
14:27justin_smithgrincher: https://www.refheap.com/89666 updated, no longer tries to regex replace non-strings
14:27justin_smithBronsa: yeah, I just caught that :)
14:28justin_smithI guess I can take the apply str out to, for that matter
14:31justin_smithgrincher: of course you may want to go deeper and recursively work on some of the values that are not strings, updating the strings inside, but what's there should be a start
14:33grincherthank you justin_smith
14:35justin_smithnp
14:40justin_smith,(update-in {:a {:b "value"}} [:a :b] str " modified") ; grincher
14:40clojurebot{:a {:b "value modified"}}
14:46joobuscan someone give me an example of how to use with-open? I was using slurp to fetch a webpage in the repl, but then if i fetched the same page again the output was all garbled. I think it had something to do with not closing the file descriptor.
14:47justin_smithjoobus: slurp closes the file descriptor
14:47joobushmmm
14:47justin_smithjoobus: and generally, things like streams get closed properly if they go out of scope in the jvm.
14:48justin_smithand given that the stream slurp opens never enters your scope...
14:48joobusi guess it was the page i was slurping then
14:48tenchi?reduce
14:49justin_smith~reduce
14:49clojurebotreduce accumulates the men from the boys
14:49justin_smithhaha
14:49tenchijustin_smith: Haha...no just a chat issue (not clojure).
14:49justin_smithoh, OK
14:50llasramjoobus: Are you passing `slurp` the URL for a page, or something you opened yourself via e.g. `clojure.java.io/reader` ?
14:50joobus(slurp "http://zerohedge.com&quot;)
14:50justin_smithllasram: oh, good point, I don't even think about that usage
14:50llasramjustin_smith: But you were apparently correct anyway :-)
14:50joobussometimes it comes back with messed up output, like the charset was wrong or something
14:51ben_vulpesI'm using peridot to test some forms with file uploads - does anyone know how to use the peridot (request "/upload" :request-method :post :params {:some "values" :file (file "resources/myfile.txt")) in such a way that it posts all the values in addition to the multipart file? or am i missing something important in how multipart uploads works?
14:51justin_smithjoobus: sounds like a problem on their end to me, maybe they are load balancing and some of their servers are sending bad content encoding headers
14:51ben_vulpeshm i guess if i use a map keyword other than "file" all the headers come through
14:52joobusyeah, that sounds reasonably accurate
14:52justin_smithjoobus: you could try putting the string into a byte-array, then coercing it back to string with various encoding arguments
14:53joobustbh, i don't particularly care about that site, i was just testing out slurp
14:53justin_smith&(-> "snowman ☃" .getBytes (String. "UTF-8"))
14:53lazybot⇒ "snowman ☃"
14:53justin_smith&(-> "snowman ☃" .getBytes (String. "UTF-16"))
14:53lazybot⇒ "獮潷浡渠�"
15:06ricky____I'm going through the unless macro example from Clojure in Action and wondering why when unless is a function, the 'then' portion of the 'if' doesn't get evaluated twice when it's true.
15:07ricky____If it's easier to understand this as code, why does (exhibits-oddity? 7) not show 'Very odd, indeed!' twice? @ http://pastebin.com/JfbjW4QT
15:07justin_smithricky____: then is fully evaluated before the function even sees it
15:08justin_smithunless only sees the fully evaluated form - the printing happens before unless even runs
15:08ricky____So what does unless actually see as its second argument?
15:09justin_smiththe return value of the form provided as a second arg
15:09ricky____So since it's println, it gets nil?
15:09justin_smithin exhibits-oddity? the value is nil
15:09justin_smithyes
15:11justin_smith,(letfn [(unless [test then] (println "in unless") (if (not test) (do then (println "unless done"))))] (unless (even? 1) (println "arg to unless")))
15:11clojurebotarg to unless\nin unless\nunless done\n
15:11justin_smiththat should make it clear
15:15bcmdoes anyone here use emacs with add-on packages?
15:15bcmwww.elgethub.com
15:17thesaskwatchHi .. is there some simpler / idiomatic mechanism for pub-sub pattern than atom and adding watches to it?
15:18justin_smiththesaskwatch: you can do pub-sub nicely with core.async
15:18justin_smithhttp://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/
15:19thesaskwatchjustin_smith: ok, but my use case uses blocking i/o
15:22justin_smiththesaskwatch: what about blocking from outside the go block, and sending to a channel when the io completes?
15:22justin_smithor doing a blocking read from outside a go block, before a blocking write outside a go block, for that matter
15:23thesaskwatchjustin_smith: I'm not sure how all those mechanisms are gonna work together. I'm wring an irc client. I'd like to be able to start it and send/receive messages asyncronously (which is a hint for core.async, true).
15:24justin_smiththesaskwatch: all that said, there is pubsub via 0mq http://zguide.zeromq.org/clj:psenvsub
15:24thesaskwatchjustin_smith: so I guess I could start a thread within this client and return two channels
15:24thesaskwatchwring -> writing
15:25justin_smithso, if you want to send / receive messages, what about having a go block doing pub sub with an input channel and output channel, then writing to the input and reading the output from your other threads?
15:25schmeethesaskwatch: I'm doing a client server thing as well, I have a thread that just reads things of the socket and push them onto a channel
15:25justin_smithall the IO can be on the outside of the go block
15:25schmeethen all the other communication happens over channels
15:26justin_smithschmee: yeah, what thesaskwatch needs sounds like that plus a third thread that writes out to the TCP connection again
15:27thesaskwatchI actually don't mind using a real thread, there will be no many connections
15:27milos_cohagenthesaskwatch: i wrote a wrapper for netty and core async https://github.com/marsmining/nettyca it's an example for simple tcp server
15:27thesaskwatchmilos_cohagen: thanks, I'll take a look
15:27schmeejustin_smith: yep, that's how I'm doing it now
15:28milos_cohagenthesaskwatch: maybe you could write the client code :)
15:28schmeethesaskwatch: it seems to work pretty well, although I have no experience whatsoever in writing servers
15:28thesaskwatchmilos_cohagen: yeah, I have to wrap my head around it first :)
15:29thesaskwatchschmee: could you share the code with me?
15:30thesaskwatchschmee: or is it proprietary?
15:33phuuhey #clojure. core.async question. why does alts! get priority if I <! then alts! in separate go blocks? gist here https://gist.github.com/phuu/32ab6737141d989ea280
15:34phuugiven (def c (chan)) and (def c2 (chan))
15:34dnolen_phuu: it doesn't get priority, you should assume the behavior is non-deterministic
15:37phuudnolen_: ah, ok. i must have just got the same result a few times in a row.
15:38phuudnolen_: is this true of multiple takes? if i <! 3 times then >!, is the choice also non-deterministic?
15:39dnolen_phuu: yes
15:39phuuAhha!
15:39phuuright. well, i got my JS channel implementation wrong then
15:39milos_cohagenphuu: assuming the takes are each in their wn go block
15:40milos_cohagen*own
15:40phuumilos_cohagen: right
15:45phuuok, thanks both
16:29SagiCZ1any easy way to destructure map within map?
16:30SagiCZ1(let [<desctructuring> {:a {:x 0 :y 2} :b 3}] ... get 0 and 2 ..
16:31llasramSagiCZ1: yeah -- destructuring nests
16:31xeqi,(let [{:a {:keys [x y]}} {:a {:x 0 :y 2} :b 3}] [x y])
16:31clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:32llasram,(let [{{:keys [x y]} :a} {:a {:x 0 :y 2} :b 3}] [x y])
16:32clojurebot[0 2]
16:32xeqibah
16:32Bronsaheh
16:32llasramzoom
16:33SagiCZ1ok.. i thought it was possible.. thank you guys
16:33BronsaTBH I Never use "multiple levels" destructuring, it gets kinda noisy IMHO
16:34xeqiagreed, I usually just make another binding in the let
16:40SagiCZ1why does this not work?
16:40SagiCZ1,(apply String. "hello" ["world" "!"])
16:40clojurebot#<CompilerException java.lang.ClassNotFoundException: String., compiling:(NO_SOURCE_PATH:0:0)>
16:40SagiCZ1cant apply on constructors?
16:40SagiCZ1could the exception get any more stupid?
16:41xeqi"error"
16:42SagiCZ1yeah.. but seriously class not found? how did it even get to THAT
16:42hyPiRionSagiCZ1: String. is not a class
16:43hyPiRion(String. ..) is syntactic sugar for (new String ..)
16:44hyPiRion,(macroexpand '(String. "foo"))
16:44clojurebot(new String "foo")
16:44hyPiRion,(macroexpand '(apply String. "foo" ["bar" "baz"]))
16:44clojurebot(apply String. "foo" ["bar" "baz"])
16:44SagiCZ1,(apply (partial new String) "hello" ["world" "!"])
16:44clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0:0)>
16:45hyPiRionand new is a macro, heh.
16:45SagiCZ1>:C
16:45llasramSagiCZ1: Unfortunately you can only `apply` functions, and there's nothing built into Clojure for turning constructors into functions
16:45SagiCZ1,(macroexpand '(new String "foo))
16:45clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
16:45SagiCZ1 ,(macroexpand '(new String "foo)))
16:45clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
16:46hyPiRionforgot a "
16:46SagiCZ1 ,(macroexpand '(new String "foo"))
16:46clojurebot(new String "foo")
16:46SagiCZ1wat
16:46SagiCZ1is it a special macro then?
16:46hyPiRionyes. it's a core macro.
16:47hyPiRionIt's probably better to call it a special form (?)
16:47SagiCZ1mmkay.. no apply for me then..
16:47SagiCZ1well i could wrap the constructor in a function if i wanted
16:54ben_vulpeshas anyone ever seen wrap-multipart-params fail to do the expected tempfile behavior?
16:57blaenkI'm wondering if I create an uberjar out of my program, how can I handle (can I?) external configuration files? so preferably I'd like for a configuration file to be along-side the jar file, not within it, so that it can easily be edited
16:59ben_vulpesblaenk: i uberjar my apps and launch them in docker containers with environment variables
16:59blaenkcool
16:59ben_vulpescourse, that entails all sorts of other overhead in deploy...
17:00xeqiben_vulpes: expected tempfile behavior? I've had problems when I attempted to read it twice
17:02ben_vulpesxeqi: i'm failing to even get wrap-multipart-params to write the file to disk instead of reading it in as a...string?
17:03mi6x3mif x is a function returning a function
17:03mi6x3mis there a saner way to call the result than ((x)) ?
17:03ben_vulpesin the "file" paramter in :multipart-params, i'm just getting a string and in the body of the request I'm getting a buffered input stream.
17:03ben_vulpesmi6x3m: what's insane about ((x))?
17:04mi6x3mdunno, looks kinda funny
17:05ben_vulpesdem parens
17:05lodinmi6x3m, I guess you could do (apply (x) [...]), but I would hesitate to call that saner.
17:05catern(trampoline x)
17:05catern(please don't)
17:06jjidocatern: hey, I like trampoline ;)
17:06caternjjido: i do too :)
17:06jjidocatern: for trampoline work though
17:06caternbut i was just joking, please don't use it for this
17:07caternunles you're
17:07caterntrampolining an algorithm
17:07caternin which case, do use it
17:08lodinParticularly, don't use it if ((x)) can return a function.
17:10lodinIs there any function f such that (into (empty x) (f x)) is the same as x, other than #(into (empty %) %)?
17:12caternid
17:13caterner, identity
17:13lodincatern, identity fails for lists.
17:14catern`(into (empty '(42)) (identity '(42)))
17:14caterner
17:14catern,(into (empty '(42)) (identity '(42)))
17:14clojurebot(42)
17:15lodin,(let [f identity x '(1 2 3)] (into (empty x) (f x)))
17:15clojurebot(3 2 1)
17:15caternoh, right
17:16gfrederickslodin: so your #(into (empty %) %) works because it reverses a list twice?
17:16lodingfredericks: right.
17:16lodingfredericks: Not a very nice solution.
17:16gfrederickslodin: why on earth do you need such a thing?
17:17lodingfredericks: Makes it easier to deal with mixed seqables when the return type is important.
17:18llasramlodin: If the return type is important, your function should return an instance of the correct type
17:19llasramlodin: I can't think of a situation where I've needed a function which took either a list or lazy seq or a vector and was guaranteed to returned an instance of the same type
17:20bcmhi clj-learner
17:20amalloyllasram: well, conj
17:20clj-learnerhi
17:20llasramamalloy: pfft, fine :-p
17:20llasramBut just `conj`
17:21gfredericksalso into
17:21lodinllasram: Right, and into uses conj.
17:21gfredericksand intos uses into and multi-intos uses intos
17:29hyPiRionWhere's fmap when we need it
17:29lodinllasram, Consider (defn map-generic [f x] (into (empty x) (map f (into (empty x) (seq x)))))
17:30lodinthen (= (map-generic inc [1 2 3]) [2 3 4]) and (= (map-generic inc #{1 2 3}) #{2 3 4}) and (= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4})
17:31llasramlodin: I honestly have difficulty imagining wanting that :-)
17:31hyPiRionlodin: huh, I'm not sure the last example is correct
17:32hyPiRionI think you want (fn [[k v]] [k (inc v)]) instead of that anonymous function
17:33gfredericks,(defn applicate [& fs] (fn [& vals] (mapv #(%1 %2) fs vals)))
17:33clojurebot#'sandbox/applicate
17:33gfredericks,((applicate identity inc) [:foo 41])
17:33clojurebot[[:foo 41]]
17:33gfredericksoh right
17:33lodin,(defn map-generic [f x] (into (empty x) (map f (into (empty x) (seq x)))))
17:33clojurebot#'sandbox/map-generic
17:33hyPiRionlodin: however, have you looked at fluokitten? it provides an fmap function
17:33lodin(= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4})
17:34lodin,(= (map-generic #(update-in % [1] inc) {:a 1 :b 2 :c 3}) {:a 2 :b 3 :c 4})
17:34clojurebottrue
17:34hyPiRionlodin: ohh
17:37zwerllasram the idea is that the caller picked an approriate sequence type, and that the function that is processing it generically shouldn't change it
17:39llasramzwer: Sure, I get the idea. I just disagree that it is (very often) useful
17:44lodinllasram: I figured (empty x) and (conj) is for situations when you want to deal more generally with a collection.
17:54SagiCZ1hi.. how do i get the first element from seq of maps that has 0 as a value of :number? [{:number 6 :a 0} {:number 0 :a 3}] --->{:number 0 :a 3}
17:55llasramSagiCZ1: (first (filter (comp zero? :number) ...))
17:56luqiSagiCZ1: also you can use some
17:57luqi(some (comp zero? :number))
17:57amalloyluqi: try that; it won't work
17:58SagiCZ1yeah comp will be handy
17:58gfredericksclojurebot: amalloy is <reply> try that; it won't work
17:58clojurebot'Sea, mhuise.
17:59luqihmm, I see.
18:00luqimy bad. some won't work
18:11martinklepsch(def xform (comp (map fetch-data) (map munge-data)))
18:11martinklepschis that something transformers are meant for?
18:13martinklepschI have a fn that I want to map over a seq that has side effects and I'm not sure how to do that or if it's the right thing at all
18:14justin_smithmartinklepsch: do you want both the side effects and the results?
18:17martinklepschjustin_smith: yes. I'm trying to implement some sort of pipeline: channel-in > fetch-data > do something with data > return result of last function in pipeline
18:19martinklepschI was initially thinking about using map< for that but now I'm not even sure if that would have been the right approach
18:25justin_smithreduce is eager, and you can build up your result either element by element or by accumulating a total, whichever is apropriate
18:28martinklepschjustin_smith: so in my case element by element is what I want, right? do you think the scenario I described makes sense for using transducers?
18:29justin_smithit really does (from what I have seen - have not used transducers yet myself, but this looks right for them)
18:46martinklepschjustin_smith: ok, thats reassuring enough to keep digging :)
18:46martinklepschthanks
18:56martinklepschjustin_smith: pipeline-async looks exactly like what I'm trying to do: https://github.com/clojure/core.async/blob/e7de6747e5d90e08fb9d6d6dbe41c2bdd1ef00a0/src/main/clojure/clojure/core/async.clj#L523
19:57lavokadwhy :keys can only be bind to symbols which the same names as the keys?
19:57amalloylavokad: :keys is shorthand for doing exactly that; if you want to give explicit names, use the longhand map-destructuring form
19:58amalloy,(let [m {:xpos 1, :ypos 2}, {x :xpos, y :ypos} m] [x y])
19:58clojurebot[1 2]
21:00zanesIs there a built-in function that takes a seq and returns the same seq with repeating values removed?
21:00zanesI feel like this exists, but I can’t find it.
21:01tac_like a uniq?
21:02zanesFor example, (non-repeating [1 1 1 2 3 3 1]) ; => (1 2 3 1)
21:02zanesIt’s pretty simple to write.
21:03amalloy&(doc distinct)
21:03lazybot⇒ "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"
21:03amalloyoh, but you want to remove only consecutive duplicates
21:04amalloy&(map first (partition-by identity [1 1 1 2 3 3 1]))
21:04lazybot⇒ (1 2 3 1)
21:06zanesamalloy: So, I tried that, but I’m in a situation where the second value of the lazy sequence being consumed may take a while.
21:06zanesI’d love for the first value to be realized immediately, rather than only after a change happens.
21:06zanesDoes that follow?
21:06amalloysure. you have to write that yourself, but it's not hard
21:06zanesOkay, great.
21:07Ifiht'(def s "lorem ipsum datum")
21:08Ifiht'(def s "lorem\u000A ipsum\u000A datum\u000A")
21:08Ifiht'(println s)
21:09Ifihtoh darn, no clojurebot.
21:10justin_smith,"Hello Ifiht"
21:10clojurebot"Hello Ifiht"
21:10Ifiht,8
21:10clojurebot8
21:10Ifiht,"Thanks justin"
21:10clojurebot"Thanks justin"
21:11Ifiht,(def s "lorem\u000A ipsum\u000A datum\u000A")
21:11clojurebot#'sandbox/s
21:11Ifiht,(println s)
21:11clojurebotlorem\n ipsum\n datum\n\n
21:11Ifiht,(def s "lorem ipsum\u000A datum\u000A")
21:11clojurebot#'sandbox/s
21:11Ifiht,(def s "lorem\u000A ipsum\u000A datum\u000A")
21:11clojurebot#'sandbox/s
21:12zanesamalloy: Something like this? https://gist.github.com/zane/33a5b77162441ec3a25e
21:12Ifiht,(def s (split s #"\u000A"))
21:12clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this context, compiling:(NO_SOURCE_PATH:0:0)>
21:12Ifiht,(def s (clojure.string/split s #"\u000A"))
21:12clojurebot#'sandbox/s
21:12Ifiht,(def s (sort s))
21:12clojurebot#'sandbox/s
21:13justin_smithIfiht: does \u work the same way in regexes?
21:13IfihtIt does in my code, let's see
21:13Ifiht,(print s)
21:13clojurebot( datum ipsum lorem)
21:14justin_smithit would sort weird because of the the leading spaces though
21:14Ifihtyes
21:14Ifiht(def s (clojure.string/trim-whitespace s))
21:14Ifiht,(def s (clojure.string/trim-whitespace s))
21:14clojurebot#<CompilerException java.lang.RuntimeException: No such var: clojure.string/trim-whitespace, compiling:(NO_SOURCE_PATH:0:0)>
21:15Ifiht,(def s (clojure.string/trim s))
21:15clojurebot#<CompilerException java.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to java.lang.CharSequence, compiling:(NO_SOURCE_FILE:0:0)>
21:15amalloyzanes: yes, that's a fine implementation. i would make a few changes: (1) "last" is a pretty confusing name; i'd call it "prev". (2) i would start each arity with (lazy-seq ...) instead of putting it in the middle; (3) you should use when-first instead of when-let/first (especially because your implementation is broken for seqs containing nil or false)
21:15zanesGreat feedback. Thanks!
21:15Ifiht,(def s "lorem ipsum datum")
21:15clojurebot#'sandbox/s
21:16Ifiht,(def s (clojure.string/split s #"\u0020"))
21:16clojurebot#'sandbox/s
21:16Ifiht,(print s)
21:16zanesIs it always more idiomatic to start each arity with lazy-seq?
21:16clojurebot[lorem ipsum datum]
21:16Ifihtgot it
21:16amalloyzanes: there are probably some exceptions, but none spring to mind
21:17Ifiht,(def s (join (str "(latin)" \u000A) s))
21:17clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: join in this context, compiling:(NO_SOURCE_PATH:0:0)>
21:18justin_smithIfiht: you can send messages to clojurebot
21:18justin_smithIfiht: unless there is something you are trying to show all of us
21:18justin_smithor even run your own repl locally
21:18Ifihtyes, I have it working locally, but clojurebot doesn't have my code, one step left?
21:19Ifiht,(def s (clojure.string/join (str "(latin)" \u000A) s))
21:19clojurebot#'sandbox/s
21:19IfihtYES
21:19Ifiht,(println s)
21:19clojurebotlorem(latin)\nipsum(latin)\ndatum\n
21:19IfihtTHERE!!! ^
21:19Ifihtcan anyone tell me why join skips the last item?
21:20justin_smithit only goes between items
21:21amalloyIfiht: also instead of writing a million separate lines with def, collapse it all into one form with let
21:22Ifihtwould let still work if I want to use the same identifier?
21:23justin_smithyou can repeat ids in let
21:23llasram,(let [s 1, s (inc s)] s)
21:23clojurebot2
21:23justin_smith,(let [s "a" s (str s "b") s (str s "c")] s)
21:23clojurebot"abc"
21:24IfihtThanks justin, amalloy. I'll do that.
21:26bounbdo you clojure-heads have the feeling you could never go back to your C++/Java days
21:27justin_smithbounb: horses for courses
21:27justin_smiththere are certain things I would never do in c++/java, other things I would never do in clojure
21:28justin_smiththough personally for lower level stuff I would skip straight from c to java and not touch c++ if it was purely up to me
21:28bounbhm so it's philosophy does not revolutionize they way you approach programming
21:28justin_smithoh it does
21:28justin_smithbut there are some things clojure will never be good at
21:28justin_smithbut the set of things c will never be good at is larger
21:30bounb"never" meaning "due to some actually existing irreparable theoretical shortcoming"?
21:30justin_smithbounb: for example there are certain tasks in clojure where even (especially) an experienced clojure dev will tell you you are better off writing some java code rather than trying to do that task in pure clojure
21:31justin_smithbounb: heap allocated persistent data structures are bad for realtime, and are not cache-line friendly
21:31justin_smithfor example
21:31bounbwow ok
21:31bounbmy bubble is slightly deflated
21:32justin_smithalso, clojure has to be able to redefine certain things at runtim - which is terrible for your heap usage - it won't really fit in embedded
21:32bounbaha
21:32justin_smithall that said, clojure is awesome - it isn't perfect for all tasks though
21:32zanesamalloy: Out of curiosity, how would you do it without multiple arities?
21:32bounbso you have to make considerations of hardware to find the negatives?
21:33bounbthat doesn't bother me. storage/computation is bigger and faster day by day
21:33amalloyzanes: (defn whatever [xs] ((fn [xs prev] (lazy-seq ...)) (rest xs) (first xs)))
21:33zanesAh, okay.
21:34justin_smithbounb: it's more like knowing what your limitations are - if your requirements include low ram usage, fast startup time, low gc churn, or cache friendliness / low latency, than clojure is likely not a good fit. But much of programming does not have these limitations.
21:34amalloyand that is actually how i would write it: i generally prefer helper lambdas over multiple arities. but i don't think it's important enough to suggest it as a critique
21:34zanesCool. Thanks!
21:34bounbjustin_smith: well said. thanks
21:35justin_smithnp
21:35bounbi'm just a smitten newbie
21:35bounbwatched several hours of hickey talks in the past couple days
21:36justin_smithcool, he is a good speaker
21:36bounbyeah absolutely
21:36bounbwhich other speakers in the programming/comp sci world are on his level
21:38justin_smithI saw a Rob Pike speak once, he was pretty good
21:38bounbi see him almost like a prophet, a visionary the way he speaks (ok sounds a bit sycophantic but honestly)
21:38bounbyeah! i like rob pike too
21:38bounbseen a couple great talks from him on go/concurrency
21:40bounbhickey is basically showing me everything i thought i knew about programming is wrong
21:41bounbit can be really simple
21:42zanesamalloy: That’ll drop the first value, no?
21:42amalloyzanes: yes, you need to be more careful than i was; i just wanted to show you the structure of the helper-function skeleton
21:46zanesbounb: Maybe Joe Armstrong?
21:46bounbthanks!
21:53bounbjustin_smith: related question then. does your job impose those limitations - if not, do you use clojure at work?
21:53justin_smithbounb: yup, I do backend for web stuff, and use clojure
21:54justin_smithand I love it
21:54justin_smith(inc clojure)
21:54lazybot⇒ 19
21:54bounbah that is good to hear
21:54bounb(inc clojure)
21:54lazybot⇒ 20
21:54bounbis this like a karma system
21:54justin_smith$karma clojure
21:54lazybotclojure has karma 20.
21:54justin_smithindeed it is :)
21:55justin_smithit looks like clojure code, but really it is just a command for the bot
22:00bounb(repeatedly (partial inc bounb))
22:00bounbam i doing it right?!
22:00justin_smithit's just a pseudo-syntax
22:00justin_smithalso, the partial wouldn't execute
22:01justin_smith,(repeatedly (partial + 1))
22:01clojurebot(1 1 1 1 1 ...)
22:01bounbdisappointed :(
22:01justin_smithor wait, yeah it would
22:01justin_smithd'oh
22:01bounbB)
22:01bounb(tbh i tested it first)
22:01bounb(inc bounb)
22:01lazybotYou can't adjust your own karma.
22:02bounbfoiled!
22:04iamdustanI’m just starting to learn clojure so decided to do some codeeval challenges with it
22:04iamdustanbut I am always blowing the memory constraints of codeeval
22:04iamdustananyone else experience this?
22:05justin_smithif they have ram limits, that's gonna be rough on clojure
22:05tac_iamdustan: what are codeeval challenges?
22:05justin_smithhttps://www.codeeval.com/
22:05iamdustane.g. simple sorting. my memory usage is 65413120 bytes
22:05bounbthe copy on that site is funny
22:06tac_iamdustan: are you using recursion?
22:06bounb"unlock exclusive hacker deals"
22:06justin_smithiamdustan: yeah, clojure needs to load the whole language into memory at runtime (though arrdem tried to change that - but it looks like that will become a different language)
22:06iamdustanwith this code: https://gist.github.com/iamdustan/83d8f3c8759e31eb0f74
22:07iamdustanbounb: haha yeah let’s pretend it doesn’t say that
22:07iamdustantac_: I don’t believe I am
22:07justin_smithiamdustan: what's with the redundant vec call on line 7?
22:07iamdustanbounb: the design of that site is just as bad as the copy.
22:07iamdustanjustin_smith: oh nice. I didn’t even realize I had done that when I added the map
22:08bounbyeah it's so cheesy
22:08bounb"Incredible profile pages that allow you to show the info you want while protecting your privacy."
22:08justin_smithiamdustan: that will help with ram a little - but the main factor unless your task is huge is going to be the huge resident size of clojure itself
22:08bounbWOW what a great feature so generous
22:09bounbsorry i'm not helping you
22:09iamdustanbounb: you are adding to my nightly entertainment :)
22:10bounbhaha good
22:10iamdustanI realized why I have no stackoverflow answers for anything...all the attempted answers I’ve begun to write were troll-ish in nature.
22:10bounbi can't wait to redeem an Exclusive Hacker Deal IRL!
22:11iamdustanjustin_smith: thanks a lot. Good to know that even though clojure is “supported” it’s not possible to pass their requirements.
22:11iamdustanbounb: http://cl.ly/image/1c0q0p2n3W0s
22:12bounbLOL
22:12justin_smithiamdustan: you could suggest they look at the baseline size mem usage wise of "lein repl", and only count usage past that, but it seems like that would require reworking their whole deal
22:12iamdustanWe recommend everything
22:12bounbthey so keen to sell yr info to other companies
22:12bounb"Not recommended"
22:12iamdustanoh yeah. the “actually” private one
22:12bounbbecause then we can't monetize you
22:13iamdustanjustin_smith: good idea. it’d be nice to at least see my own success progress through these.
22:13dbaschiamdustan: https://getsatisfaction.com/codeeval/topics/clojure_time_memory_stats_seem_wrong
22:15iamdustandbasch: I just started reading that same thread
22:15iamdustanfrom 2013 so you’d think something would be fixed by now
22:17iamdustanand that thread proves justin_smith correct
22:17justin_smithalso, regarding the comment on that page that "clojure needs the whole jvm" - the jvm is lazily loaded to some degree, the real bottleneck is that it needs the whole of clojure compiled and in memory at runtime
22:18andrewchambersdnolen_: I found the thing I was talking about before http://bddbddb.sourceforge.net/ . I don't know if its the sort of thing you are interested, datalog, binary decision diagrams and program anaylsis.
22:18dnolen_andrewchambers: I'm aware of it :)
22:18bounbpop poll: who here is not a linux user
22:18justin_smithiamdustan: and that's the nature of clojure - they are just measuring things in a way that is not friendly to this language
22:18andrewchamberscool :)
22:18caternbounb: are you a Linux user?
22:18bounbno comment
22:19caterni see
22:19caternyou are interested in switching
22:19caternwell do so
22:19andrewchambersI liked the part where they said pointer anaylsis was 10 times less code and ran a bit faster in datalog
22:20caternit saves so much effort in the long run
22:20zanesIs there a reason why clojure.core functions like distinct don’t have a 0-arity version that returns a transducer?
22:21justin_smithcatern: as a linux user of 15+ years now, I'll have to say it can also be a huge pain in the ass. But if you don't play flashy games or do graphic design work and you like good command line tools, it's great.
22:21bounbcatern: nah, i am a fairly long time user. just wanting to confirm my suspicion that this community is pretty much a subset of the community of linux users
22:21iamdustanjustin_smith: thanks for the help.
22:21justin_smithiamdustan: np, too bad about how they are scoring our favorite language
22:22bounbjustin_smith: well said again about linux
22:22caternbounb: oh okay. well in that case, no, there's probably a lot of OS X users around, judging by today's sad trends
22:22bounbwe don't really have any good OSs
22:22bounbthey're all a bit naff in various ways
22:23justin_smithjust by observation I would say that OS usage in the clojure community is in order: osx, linux, windows
22:23bounboh i see
22:23bounbyes i forget just how big apple is these days
22:23justin_smiththat's really informal :)
22:23bounbjustin_smith: don't worry. it was a "pop poll"
22:24bounbim not writing a scientific study
22:24justin_smithand I'd say in terms of convenience of developing clojure, the ranking is linux, osx, windows
22:25justin_smithbut that's even more subjective
22:26zanesamalloy: I guess the most succinct implementation is (partial sequence (comp (partition-by identity) (map first))). Heh.
22:27zanesOr maybe that would have the same problem of delaying the first value. Hm.
22:27iamdustanjustin_smith: ha. That’s a bit of a stretch for me yet. I still will claim javascript as my fave, but I’m excited about clojurescript and om.
22:28blaenkanyone use cljsbuild? I have it in my :hooks and it keeps saying Compiling ClojureScript whenever I run lein repl lol
22:28blaenkthought it was only supposed to run when other things were run, such as compile and clean
22:28amalloyzanes: probably does, yeah
22:30bounbiamdustan: javascript is your favourite language?
22:31iamdustanbounb: guilty
22:31andrewchambersiamdustan: what languages have you used?
22:31iamdustanbounb: though that is not for breadth of experience
22:31bounb...explain?
22:31iamdustanoh goodness
22:31iamdustanpersonal history.
22:31andrewchambersjavascript is pretty average overall
22:32andrewchambersnot super bad
22:32andrewchambersnot great
22:32iamdustanI’ve been a developer for ~3 years (that I’ll count at least)
22:32andrewchambersYou code webstuff only though right?
22:32iamdustanand that is all as a front end dev
22:32zanesMan, writing transducers by hand is weird.
22:32andrewchambersI think you just like javascript because you are comfortable iwth it
22:32iamdustanand I went to were I work now to learn back end dev
22:33andrewchambersI think typescript is decent
22:33iamdustanbut they realized how good I was at front end and I got pigeon-holed so I just followed the rabbit trail down
22:33bounbanyone here not primarily a "programmer" in their day job?
22:33dbaschbounb: you’re assuming everyone here has a day job
22:33andrewchambersSoftware engineer might still be a programmer :)
22:33iamdustanI’ve done a bit in python, ruby, read a haskell book, started SICP (since I’m self-taught) which got me into lisps, and then because of Om I shifted to clojure
22:34bounbbounb: if you don't then your answer is implicitly "no" and you don't need mention it
22:34iamdustanI read most of a C++ book last year, but that was still biased towards web development (browser engines)
22:34bounbuh fuck i addressed myself
22:34bounbdbasch: ^
22:34iamdustanhaha
22:34bounb<- moron
22:34iamdustanlong-winded way to say, yeah I am a web developer through and through
22:35andrewchambersyeah, javascript is decent compared to those. Haskell is just way out there, and just reading doesn't give you the proper feel for it.
22:35andrewchambersyou don't really have any typed languages :P
22:36iamdustantrue, true. To that point: I have played with typescript and C#
22:36andrewchambersbut thats ok for what you seem to workon
22:36iamdustanwell, C++ no?
22:36andrewchambersi dunno
22:36andrewchambersC++ is horrible
22:36andrewchambersBut at least with C and C++ you will learn more fundamental computer science stuff
22:36andrewchamberssince its much lower level
22:37iamdustanI have a (former) coworker who is big into haskell and I read the “...for great good” book and finished and was like “that was really interesting and I have no idea how I could solve anything with it if my life depended on it”
22:37iamdustanI did write a couple lines of C for a project actually :)
22:37iamdustanwell, modified.
22:37andrewchambersyeah, i dunno clojure is pretty high level and cool once you are used to it
22:38andrewchambersclojurescript is alot better than javascript imo, but thats just an opinion
22:38andrewchambersJavascript is quite verbose and the callbacks get very nested
22:38dbaschandrewchambers: it depends on what you mean by “fundamental cs stuff.” You do get closer to hardware, but that’s not necessarily what cs is about
22:38andrewchambersdbasch: yeah, you are right
22:38bounbhow can you compare clojurescript and javascript?
22:38andrewchamberscloser to computer stuff
22:39andrewchambersnot algorithms or anything
22:39andrewchambersbut understanding hardware etc
22:39iamdustanit’s like java to javascript. They both have common parts in the name!
22:39bounbhah
22:39andrewchambersI dunno, clojurescript has its own problems
22:39andrewchamberslike way harder for abeginner to get started
22:39andrewchambersmore setup
22:40andrewchambersthey aren't problems with the language, but they are real problems.
22:40iamdustanlike everything with java :)
22:40andrewchambersTo code in clojurescript you need to understand all the javascript stuff AND all the clojurescript stuff
22:40andrewchambersso its not really beginner friendly
22:40bounbcorrect me if i'm wrong but i thought clojurescript was just a clojure->javascript compiler
22:40andrewchamberssame with clojure<->java
22:40iamdustanI installed maven for a quick freelance project the other day and immediately lost all faith in the java world.
22:41andrewchambersjava is horrible
22:41andrewchambersi dunno, The only language that has tools I enjoy is Go at the momeny
22:41andrewchamberslittle setup, just works
22:41bounbwhy not clojure
22:41andrewchambersclojure is freaking hard to get started with
22:41andrewchambersstuff is outdated
22:42andrewchambersthe lein project.clj stuff took me ages to get started with
22:42andrewchambersbecause the templates i was copying were out of date
22:42bounbhmmmmmm
22:42andrewchambersthen my laptop was really slow
22:42andrewchamberslein version took 6 seconds
22:42bounbso complaints about the language ecosystem
22:42andrewchambersto print
22:42andrewchambersbut i understand that
22:43andrewchambersTo use clojure, you need to know java and clojure and the tools
22:43justin_smithandrewchambers: I got pretty far with clojure before I learned any java
22:43justin_smithandrewchambers: though I did have to figure out just enough to read some javadoc
22:44andrewchambersYeah, but if you don't understand java exceptions or you don't understand what a classpath is
22:44andrewchambersyou are screwed
22:44andrewchamberssomeone with experience can easily work it out
22:44andrewchambersbut if you are totally new then its harder
22:44bounbandrewchambers: good to hear that point of view. thx
22:44andrewchambersI mean, 4clojure is decent
22:44dbaschandrewchambers: that’s more jvm stuff than java proper
22:44andrewchamberssince it lets you play with no setup
22:45justin_smith(inc dbasch)
22:45lazybot⇒ 9
22:45blaenkanyone know how to generate a certain length random string? I found crypto-random which lets me specifies the size in bytes the size then increases when its encoded in base64 or whatever
22:45justin_smithyeah, you need to learn the tooling / ecosystem, but not so much the language (until you decide to go deeper)
22:45blaenkI mean, short of truncating the string
22:46andrewchambersThe clojure language itself is pretty easy.
22:46andrewchambersMy one complaint was the using and ns :refer
22:46andrewchambersso many ways to include stuff
22:46justin_smithblaenk: like cryptographically secure random string?
22:46andrewchambersnot really explained well anywhere
22:46blaenkyep
22:46blaenkto use for ring's cookie key
22:46dbaschblaenk: what characters do you want to use / exclude?
22:46blaenkI'd just like something that's printable, i.e. no unprintable characters
22:46dbaschblaenk: use java uuid
22:47andrewchambersall that being said, i think clojure is great once you know how to use it
22:47blaenkuuids can be 16 characters long? I don't know the implications of truncating something
22:47brehauttautology is tautological
22:48iamdustanwhat are some use cases that you folks are using clojure for?
22:48avi__testing java libraries
22:48iamdustanMy viewpoint is entirely too focused on the web platform in any fashion
22:49justin_smithiamdustan: backend for http
22:49avi__I use clojure's repl to test out Jars and explore them before I have to write a lot of java code.
22:49iamdustanavi__: interesting. so you still write java, but clojure is to get familiar with something?
22:49bounbanyone by the name jony hudson itc?
22:50iamdustanjustin_smith: with ring and compojure and the like?
22:50avi__iamdustan: I try to avoid Java, but yes
22:51andrewchambersiamdustan: I have played with writing parts of a compiler in clojure with core.logic
22:51avi__iamdustan: it allowed me to plumb the guts of DB4o and see the crazy stuff it was doing
22:51andrewchambersdidnt actually use it for a few reasons
22:52andrewchambersthen I wanted to use clojurescript + core.async + om for a ui for a payment system
22:52andrewchambersbut shelved that project for now
22:52andrewchambersI like to try and think of projects that clojure will be good for as a hobby :P
22:52justin_smithiamdustan: ring and our own custom router, edn record mapping layer, and template renderer (the project is open sourced, called caribou)
22:53iamdustanif/when I get to the point of clojurescript + om I will let you know to pick that project back up
22:53justin_smithcaribou is a bit too heavy weight / frameworky for clojure (it's an adaptation of some ruby stuff built for an agency to smooth a transition)
22:53andrewchambersclojure also changed the way i write some code at work in normal java
22:53andrewchambersmore immutability
22:53andrewchambersmore atomic swapping of values
22:55bounbavi__: that's interesting.
22:55bounbthanks
22:56andrewchambersmore emphasis on pure functions too
22:58avi__so much in java needs to be immutable
22:58avi__thank goodness they made the strings immutable