#clojure logs

2013-07-25

00:30aaelonywhat's the best way to read a small edn format file entirely into memory?
00:33brehautaaelony: (clojure.edn/read-string (slurp file-or-filename)) ?
00:34aaelonybrehaut: thank-you, but that only yields the first line
00:34brehautaaelony: the first line or first form?
00:34aaelonye.g. (count (clojure.edn/read-string (slurp data-file)) ) ;; gives 2
00:35alandipert(clojure.edn/read-string (str "(" (slurp f) ")")) is a quick fix
00:35aaelonybrehaut: It's likely my fault, there is a edn structure on each line and I need all the lines
00:35tomjackyou'd have to call read repeatedly
00:36aaelonyalandipert: thank-you! that works :)
00:37tomjackhttps://www.refheap.com/7fac4581dac79e910dbbba793
00:37tomjackthe less quick fix..
00:38tomjackhttps://www.refheap.com/67eedfdc3b75112b6cacc9a26 grrr
00:38aaelonytomjack: that's cool thanks. I googled a bunch of explanations, (such as http://stackoverflow.com/questions/15234880/how-to-use-clojure-edn-read-to-get-a-sequence-of-objects-in-a-file) but none of them fit exactly. thanks for everyones help
00:38hiredmanI wish clojure would just throw an exception when it encounters def not at the top level
00:39tomjackeh
00:39tomjackso one macro -> one def?
00:39aaelonyerrors
00:40tomjackor is the body of a top-level do also top-level?
00:40tomjackhmm (partial not= foo), that's cool
00:40tomjackI can't decide whether I like that or (complement #{foo}) better
00:41hiredmanwhich ever, I am just tired of seen people try to use def like schemes define
00:41alandiperthiredman: but what about my defcoolthing macros :-(
00:42brehautno cool things allowed. this is clojure. we only do serious computing
00:42tomjackinside let basically? or what?
00:42aaelonyI'm still waiting for some macro named defleopard...
00:42hiredman(defn make-memo [fn] (def table ...) (fn [& args] do stuff with table))
00:42alandiperthiredman: in seriousness, i think i agree. i was investigating static compilation and a def in a closure makes compiling defns to java methods super trixty
00:42brehautaaelony: thats only allowed in common lisp (and other languages from the 80s)
00:42aaelonyhaha
00:43tomjackah right
00:45hiredmanalandipert: I have a lisp -> go source compiler that ends up having to hoist lots of stuff like that in to the top level
00:45alandiperthiredman: do your generated methods take an env arg?
00:46hiredmanyes
00:46hiredmanI end up generate the go equiv of what clojure does with IFn's
00:46alandipertcost of doing business w/ inner defs i suppose
00:46hiredmanclass and method(s) per function object
00:50hiredmanwe need an urclojure like, uh, whatever that is that shenanigans has
00:50hiredmaner
00:50hiredman"shen"
00:50hiredmanklambda
00:50hiredmanbut with more protocols and reify
00:51futilehey guys, remember when OOP was brilliant?
00:53alandiperthiredman: yes, into it. also the AIM 514 'lisp-based processor' thing
00:54hiredmanlook, the thing I said could actually happen :)
00:56alandiperthiredman: oh, you have explored the AIM 514 stuff? i'm tempted to learn VHDL on account of it
00:56hiredmanI haven't, but it seems unlikely that lisp machines will make a come back
00:58alandipertthey will, on my machine
01:17aaelonyanother silly question. I have a nice doseq that outputs lines to a file, but I want to label the line number of the line the data came from. I've tried (let [i 0] (doseq [row data] (let [i (inc i)] … but that doesn't seem to do it.
01:19alandipertaaelony: maybe (doseq [row data, i (range)] ...)
01:19tomjackthat would be interesting
01:19tomjack(doseq [[i row] (map vector (range) data)] ...) ?
01:20aaelonyalandipert: I think that works!
01:20aaelonyalandipert: thanks :)
01:20tomjack&(for [row [1 2 3] i (range)] [row i])
01:20lazybotExecution Timed Out!
01:20aaelonycool
01:21alandipertor rather, (doseq [[i row] (map-indexed vector data)] ...)
01:21tomjackI think it's weird you can't use doseq-like bindings for zippy mode
01:22aaelonyactually, that works then goes overboard… i'll need to bound the (range) ;)
01:22zRecursive,(range)
01:22clojurebot(0 1 2 3 4 ...)
01:24alandipert,(for [[i row] (map-indexed vector "stuff")] [i row])
01:24clojurebot([0 \s] [1 \t] [2 \u] [3 \f] [4 \f])
01:26tomjack(for+ :zip [row data i (range)] ...) ?
01:28alandiperttomjack: fancy
01:30aaelonytomjack: what is for+ … having trouble researching that...
01:30tomjackit's hypothetical
01:30aaelonyah!
01:42aaelonyok, I gave up and am using an agent instead...
01:43tomjack..for the index?
01:46ddellacostawhat's the idiomatic way to compare hash-maps for equality? I'm just doing = and that's not working how I want.
01:47ddellacostaI guess I should be specific: I want to compare two clojure.lang.PersistenArrayMaps.
01:47ddellacostaPersistentArrayMap
01:47tomjackwhat is an example of = not working how you want?
01:47egghead,(= {:foo :bar} {:foo :bar})
01:47clojurebottrue
01:47aaelonytomjack: yes
01:48egghead= is by value instead of ref
01:48eggheadwhat is ref equality in clj
01:49amalloyegghead: identical?
01:49eggheadah nice, thanks amalloy
01:50ddellacostathanks folks. I realized I'm being dumb and actually the maps I'm working with are not, in fact, equal, which is why it's telling me they are not equal. D'oh.
01:50tomjackclojure.data/diff
01:51callenddellacosta: you really wanna use diff as a sanity check :)
01:52ddellacostatomjack, callen: thanks! I didn't know about that one.
01:54ddellacostaoh that is SO much nicer than how I was doing it
01:55callenddellacosta: don't thrash around, ask. :)
01:56ddellacostacallen: totally…the problem is that it doesn't even occur to me to ask sometimes. I wouldn't have thought to have asked the appropriate question, which was, "how can I best find the diff between two hash-maps?"
01:56ddellacostahence the thrashing
02:29ddellacostawhat are people using to measure test coverage for their Clojure codebase?
03:05tsdhHi. I have 2 deftypes A and B which have mutual (instance? A/B ...) checks in some protocol implementation methods. Is there a way to make that compile other than splitting the instance checks in functions A? and B? and adding forward declarations?
03:35ucbmany ohais
03:40Uakhohaïs were had
03:40hyPiRionohai
04:07tsdhUh, is it intended that different clojure.core.cache types require different usage patterns? I.e., SoftCaches update in-place with (miss ...) whereas the other's return a new cache one has to use in place of the old one.
04:11hiredmantsdh: I'd checkout core.memoize
04:12hiredman(if you are looking at core.cache, because core.cache on it's own has never made sense to me)
04:13tsdhhiredman: I already use its SoftCaches in my project, so I thought I use its BasicCaches at another place, too. But now I simply use an (atom {}) which is as good for my use-case.
04:57darkest_podWhich concurrency primitive is best to share state between two working threads?
05:00hiredmanhttp://wiki.gungfu.de/uploads/Main/clojure-conc.png
05:00hyPiRion(inc hiredman)
05:00lazybot⇒ 21
05:01echo-area(def hiredman (atom 20))
05:01echo-areaWhy does lazybot ignore me
05:03hyPiRionthat's not legal lazybotian
05:03hyPiRion,(let [hiredman (atom 20)] (swap! hiredman inc))
05:03clojurebot21
05:04darkest_podhiredman: Thanks!
05:40tsdhIs there a nrepl.el command that lets me load the current buffer and reload all required namespaces, too?
05:40ucbtsdh: https://github.com/clojure/tools.namespace
05:40ucbthat might come in handy
05:42hyPiRiontsdh: you may want to look into Stuart Sierra's setup, it's thought out by a smart man
05:42tsdhucb: That looks great, and it's motivated by the same problem I have. Compile a ns with protocols, now you need to recompile all ns with types implementing these protocols.
05:43ucbalso what hyPiRion said
05:43hyPiRiontsdh: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
05:45tsdhhyPiRion: Yes, very useful. Thanks.
06:04noncomwhat is the current fashion for cljs analog for clj-time?
06:04noncomi need a full-scale date manipulations with cljs
06:43dnolennoncom: probably worth taking a look at what's available via Google Closure
06:44noncomdnolen: yeah, looks like will have to. also found this http://stackoverflow.com/questions/17041115/clojurescript-date-time-library so not so out-of-the-box, but still not alone :)
06:44g3ntlemanhey, everybody!
06:44g3ntlemanDid anyone successfully build clojurec on os x?
06:44dnolennoncom: I would personally avoid anything that cannot be Closure optimized
06:45g3ntlemanI'm running into compile problems.
06:45noncomdnolen: ok, this makes sense, i will make the priority
06:47dnolennoncom: which means there's an opportunity for a nice wrapper about the Closure date stuff if someone is so inclined.
06:49dark_elementdnolen noncom, maybe even name it cljs-time
06:50noncomyes..
06:50noncomdark_element: i'm still not in twitter, btw :D but gonna be soon, also gonna make audiovizs things and will share
06:50dark_elementnoncom hey. I am now looking at webgl video filters for visualisations
06:51noncomdid you go about shadertoy?
06:51dark_elementnoncom i am soon going to push the project and you will most probably reuse the code and just write plugins for viz
06:51noncomwow!
06:53dark_elementnoncom plugins are nothing fancy. just new namespaces and you will have to provide basic functions for viz.
06:54dark_elementnoncom shadertoy is fun place. i am looking into both shaders and applying filters on the output
07:08noncomdark_element: so r u using shadertoy or on your own?
07:12noncomdoh, forging an entire time-date library for cljs is a big task..
07:15dnolennoncom: and unrealistic, which is why I suggested Closure + clj-time approach, just implement basics and over time (heh) people will likely submit enhancements
07:16dnolenso does leiningen plugins and tasks use the JVM settings specified in project.clj?
07:17hyPiRiondnolen: almost
07:17dnolenhyPiRion: what do you mean?
07:18hyPiRionGive me a moment, I'll find the ticket related to this
07:18SomelauwToo bad that error messages don't include the lines in which my clojure code actually gives an error.
07:18SomelauwClassCastException java.lang.Character cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:619)
07:19SomelauwThat could be anywhere
07:19hyPiRiondnolen: technomancy/leiningen#1230 contains information about how :jvm-opts works, the patch will be in 2.3.0 which is right around the corner
07:19lazybotSet default :jvm-opts in :base profile to :displace -- https://github.com/technomancy/leiningen/issues/1230 is closed
07:21dnolenhyPiRion: yeah that's mostly about the project, I'm wondering about plugins and tasks
07:23hyPiRiondnolen: right. Those won't use the jvm settings specified within project.clj. You'd have to use the environment variable JVM_OPTS for extra opts
07:23hyPiRioneven then, I would've inspected what the leiningen shell script adds, because it is quite... configured
07:30dnolenhyPiRion: hrm, yeah the reason I'm looking at this is that CLJS compiler is nearly twice as slow for auto builds if you don't use server settings
07:33instilledWhat validation libraries is the most popular among clojurians? i'm looking for a general purpose validation library not tied to web, e.g. Sandbox. The other libraries (listed on clujure toolbox) all seem very similar and still actively developed. Any thoughts?
07:33hyPiRionyeah, we do some tweaks to speed JVM+Clojure loading up, at the cost of hotspot speed
07:34dnolenhyPiRion: is it possible to override?
07:34dnolenhttps://github.com/technomancy/leiningen/blob/master/bin/lein#L120
07:37hyPiRiondnolen: hrm, not the way the arguments are ordered, unfortunately
07:37dnolengrr
07:40hyPiRionI'll put up an issue on it and see if we can find a way around it, may be that we can put something in for 2.3.0 if we figure out it's safe.
08:24squidzwhat options do I have when dealing with the datastructure differences between javascript and clojurescript? is there a good way to have our clojurescript sequences converted 'automagically'?
08:26squidzany libraries or anything that enable me to skip on using clj->js
08:27dnolensquidz: it's not possible
08:27squidzokay so it is just something that we have to pay attention to
08:28squidzdnolen: do you think that could be something that could be brought to clojurescript, or is there a fundamental limitation in the language that prevents it?
08:28dnolensquidz: ES 6 Proxy's could be used to work around this problem, but adoption seem unlikely
08:29squidzadoption of proxies?
08:29squidzin ES 6?
08:30dnolensquidz: yes
08:30dnolensquidz: what library are you trying to interact with where marshaling is a big issue?
08:40squidzdnolen: I am using D3
08:43g3ntlemanDid anyone successfully build clojurec on os x?
08:51tbaldridgesquidz: there was a Clojure/West talk about doing this (I think even using D3), it guy went to a ton of trouble to make cljs/js interop better.
08:51tbaldridgesquidz: let me see if I can find his library
08:53tbaldridgesquidz: the lib https://github.com/dribnet/mrhyde
08:53tbaldridgesquidz: and a D3 wrapper using mrhyde https://github.com/dribnet/strokes
08:56squidztbaldridge: okay. Do you know if the video is available to watch anywhere?
08:57tbaldridgesquidz: the Clojure/West video schedule says it comes out on 7/29
08:57tbaldridgesquidz: and that'll be on InfoQ
09:01SomelauwIs there a _ in clojure.core? Or what could the _ refer to in ClassCastException clojure.core$_ cannot be cast to java.lang.Number clojure.lang.Numbers.multiply (Numbers.java:146)?
09:06squidzcool can't wait to see it
09:06BronsaSomelauw: ##(class -)
09:06lazybot⇒ clojure.core$_
09:06Bronsa,(* -)
09:06clojurebot#<ClassCastException java.lang.ClassCastException: Cannot cast clojure.core$_ to java.lang.Number>
09:07BronsaSomelauw: you probably missed a paren somewhere
09:10SomelauwBronsa: Okay, but what does it mean? Is _ a minus sign?
09:11SomelauwI found the error I was doing (for [x [1 - 1]]) instead of (for [x [1 -1]])
09:11BronsaSomelauw: class names get munged ##(munge '-)
09:11lazybot⇒ _
09:12BronsaSomelauw: java don't premit dashes and other symbols in class names
09:12Bronsaso clojure has to convert them to other things
09:12Bronsa- becomes _
09:22SomelauwIs there also a unmunge or something?
09:23Bronsa,(clojure.repl/demunge "clojure.core$_")
09:23clojurebot"clojure.core/-"
09:24hyPiRionbe wary though, munging and demunging is not one-to-one
09:24hyPiRion,(map munge ["-" "_"])
09:24clojurebot("_" "_")
09:25SomelauwBronsa: thanks
09:25hyPiRion,(let [identity (comp clojure.repl/demunge munge)] (identity "_"))
09:25clojurebot"-"
09:26SomelauwhyPiRion: does that mean that I can't have both a function - and _ in a namespace?
09:26Somelauwbecause they both get munged the same
09:26BronsaSomelauw: no, namespaces don't need to munge vars
09:27Bronsait's only the class name that'll be the same
09:27Bronsait's probably not going to work when AOT'ing though
09:29Bronsayeah, if you AOT compile (defn a- []) and (defn a_ []) you overwrite a- with a_
09:32SomelauwBut (def - 5) and (def _ 6) can conflict?
09:32SomelauwI'm not sure I completely understnad yet, but I'll avoid having both a_ and a- anyway.
09:32Bronsano, defs don't break
09:33Bronsait's fns that break when AOT
09:33BronsaSomelauw: yeah, just avoid having the same name with - and _ and you'll be fine
09:33Somelauwoh, because functions are compiled to classes and classes can't have - in their name?
09:33Bronsayes
09:34Bronsaso both a_b and a-b get compiled to the.ns%a_b.class
09:34Bronsas/%/$
09:44chrisrossiI came across this: http://clojure.org/streams
09:44chrisrossijust wanted to say +1
09:44chrisrossii'm coming from python and find python generators to be extremely useful.
09:49noncomdid anyone ever read an mp4 with opencv and clojure?
09:50noncomi did that in java, but interested if someone had good experience with clojure oto
09:51noncomalso there were many changes to opencv-java and javacv...
09:52learner_Hello All, a newbie question. What does "list comprehension" mean ?
09:55squidzhyPiRion: is it possilbe to use leiningen into an already existing non-clojure project?
09:57squidzlearner_: list comprehensions are kind of like mathemetical set definitions
09:57squidzso something like the set of x where x is greateer than 10 and less then 20 {x | x > 10 : x < 20}
09:58squidzwhich is [11,12,13,14,15,16,17,18,19]
10:01SomelauwIs there something like a .leiningenrc or .clojurerc file, so I can always require pprint when starting a repl?
10:02Somelauwchrisrossi: python generators are a poor man's stream.
10:03Somelauwlearner_: You can create them in clojure with the for macro.
10:07Somelauwok, I found I can put stuff in user.clj
10:09hyPiRiondnolen: false alarm, you can in fact override the default settings. I am just not able to properly read bourne-again shell scripts.
10:10hyPiRiondnolen: it's just LEIN_JVM_OPTS="your settings here"
10:10nDuff...random aside, coming from #bash: LEIN_JVM_OPTS="foo" is probably the _worst_ way to pass a list of arguments around
10:11nDuff...as you can't include something like -f "filename with space" inside that argument list without forcing use of eval
10:11nDuff...and if you use eval, then arbitrary code inside that environment variable is necessarily executable
10:11nDuffand a great deal of work (which most folks writing scripts don't know how to do) is necessary to sanitize arguments being passed in.
10:11nDuffIt's seriously bad news, and it's also completely endemic among shell scripts used to start Java processes for some reason.
10:12hyPiRionnDuff: We'd love improvements, fork Leiningen and send a pull request
10:17futile,(doc ffirst)
10:17clojurebot"([x]); Same as (first (first x))"
10:17futileneat
10:18futile,(doc rrest)
10:18clojurebotIt's greek to me.
10:18futile:D
10:19hyPiRion,(doc nnext)
10:19clojurebot"([x]); Same as (next (next x))"
10:21futileha
10:21futile,(doc fffirst)
10:21clojurebotGabh mo leithscéal?
10:21futile,(doc fnext)
10:21clojurebot"([x]); Same as (first (next x))"
10:21futileha!
10:21futileoh man, caddddr all over ahead
10:21futile*agan
10:21futile*again
10:23futileAre there any Clojure libs that complement Datomic?
10:24mmarczykfutile: sure: https://github.com/rkneufeld/conformity https://github.com/halgari/fafnir
10:25futileThanks mmarczyk :)
10:25mmarczyk:-)
10:25chrisrossiSomelauw: I'll withhold judgement but "poor man's" seems overly pejorative at first glance. i understand the dangers inherent in stateful iteration, but the allergy to it seems a little extreme to me. usually the scope a stateful iterator is used in is local, nonconcurrent, and entirely safe.
10:40pyrhhoWhat's the clojure equivalent of MyClass.class ?
10:41clgvpyrhho: MyClass
10:41clgv,String
10:41clojurebotjava.lang.String
10:41clgv,(type String)
10:41clojurebotjava.lang.Class
10:41pyrhhook. so I don't need to call anything to turn it into a class object..
10:41clgv,(type java.util.List)
10:41clojurebotjava.lang.Class
10:41futile,(.new String)
10:41clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: new for class java.lang.Class>
10:41futilei dunno
10:42pyrhho,(new String)
10:42clojurebot""
10:42futile,(String/new)
10:42clojurebot#<CompilerException java.lang.NoSuchFieldException: new, compiling:(NO_SOURCE_PATH:0:0)>
10:42clgvpyrhho: a class name is automatically resolve to a class symbol in the examples above
10:42futileok fine
10:42pyrhhoah ok.
10:42tolitius,(String.)
10:42pyrhhothanks
10:42clojurebot""
10:42futileyeah that
10:42clgvpyrhho: delete the "symbol" ^^
10:42futile,`~String
10:42clojurebotjava.lang.String
10:43futile,``~~String
10:43clojurebotjava.lang.String
10:43pyrhhoSo, when I have a java method with the type signature methodName(Class<? extends C> arg1), I could just do (.method obj MyClass), then, right?
10:43futileOH NO
10:43futile,`````~~~~~String
10:43clojurebotjava.lang.String
10:43clgv,(type `~String)
10:43clojurebotjava.lang.Class
10:43clgv,(type `String)
10:43clojurebotclojure.lang.Symbol
10:43clgv^^
10:43futile,(= java.lang.String String)
10:43clojurebottrue
10:43clgvpyrhho: yes
10:44pyrhhook cool thanks
10:44clgvpyrhho: try out your current scenario on the REPL
10:48silasdavisAny convention/idiom for use of 'single' and "double" quoted strings?
10:49Somelauwchrisrossi: I'm not allergic to stateful iteration. It's more that streams can do more than generators. For example, when doing s = generator(), you can only iterate through s once in python, but if s were a stream, it can be iterated multiple times.
10:49chrisrossiok, gotcha.
10:49silasdavisoh ignore that last comment
10:50silasdavisquestion rather - too long away from clojure, forget what everything does
10:50chrisrossione thing i'm missing from the streams writeup is any example of what generator code might look like.
10:51chrisrossithe python 'yield' makes writing those things really nice. anything similarly clever here?
10:51Somelauwchrisrossi: concat and keep?
10:52Somelauwand mapcat
10:53futileI bet Python generators could usually be done with plain old lazy sequences.
10:53Somelauwthere is no direct equivalent to yield. But using concat, keep, mapcat and (for :when) you can get equivalent functioning code.
10:54nDuffchrisrossi: see http://clojuredocs.org/clojure_core/clojure.core/lazy-seq
10:55nDuffchrisrossi: ...core.async actually results in code that looks very, very much like Python generators, but that's rather a different thing.
10:55chrisrossinDuff: yeah i was looking at core.async yesterday. tickles some of the same brain cells, but still different.
10:56chrisrossii came to core.async looking for a gevent work alike, then realized it doesn't help with io.
10:57nDuffchrisrossi: eh? helps perfectly well with async IO.
10:57nDuffchrisrossi: ...and Java has had async APIs ever since NIO was introduced, which was ages ago.
10:59chrisrossihmm, maybe i still haven't grokked something essential, but it looks like the only time in core.async that you yield back to the go loop is when you push or pop from a channel. if there were io channels...
11:00nDuffchrisrossi: if you kick off an IO operation with a on-receive callback that feeds into a channel...
11:01chrisrossiok, sure. that's doable. you still have to use callbacks to do that--something gevent or core.async is designed to allow you to avoid doing explicit callbacks and write synchronous style code.
11:02tolitiuschrisrossi:
11:02tolitius(go
11:02tolitius  (let [c (chan)]
11:02tolitius    (future (>!! c (blocking-io-read some-stream)))
11:02tolitius    (let [msg (!< c)
11:02tolitius      (do-something-with msg))))
11:04chrisrossiyep, that'd work, but it's still not the same. now you have a thread dedicated to one file/socket/etc...
11:09pyrhhoSo, I have a proxied Object, and I'm trying to call a method it got by extending an abstract class, but am seeing "IllegalArgumentException Can't call public method of non-public class"
11:11pyrhhoSorry, it's not a proxied object, actually..
11:12pyrhhoI have a "public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>", but am trying to call a method it gets from AbstractBootstrap.
11:12pyrhhoIs it the generics, maybe?
11:14pyrhhoI get the error when I do: "(doto (new ServerBootstrap) (.channel MyChannel))"
11:17tolitiuschrisrossi: true, but hopefully a very sort lived thread
11:18tolitiuscan be wrapped in a cached thread pool
11:19alexgunnarsonhey everyone - i was wondering… what are some options for clojure iOS development?
11:19alexgunnarsoni know of some instances where clojurescript has been used
11:20alexgunnarsonbut clojure… the jvm doesn't run on ios
11:20chrisrossi looks like clojure.java.shell doesn't support streaming to/from subprocs. some 3rd party libraries do. any favorites?
11:20gfredericksdoes anybody know what was meant here about reader metadata & IReference? https://groups.google.com/forum/#!topic/clojure-dev/mAHFtuaEXRk
11:21tolitiuschrisrossi: what are streaming from shell?
11:21tolitius(e.g. that can't be streamed from JVM)
11:22tolitius*what are you
11:23chrisrossii just want to call out to shell prog, get an output stream that can be used to write to the subproc's stdin and/or an input stream that can be used to read from a subproc's stdout.
11:24chrisrossijust a pipe, basically.
11:26nDuffalexgunnarson: I've seen some folks working on an ObjC compilation target for that reason.
11:27alexgunnarsonnDuff: any success with it?
11:27nDuffalexgunnarson: ...that's something closer to cljs than Clojure proper, though.
11:27tolitiuschrisrossi: https://github.com/Raynes/conch might do what you want. check it out
11:27nDuffalexgunnarson: Don't know -- haven't tracked it closely.
11:28alexgunnarsonnDuff: okay. thanks :)
11:28chrisrossitolitius: i was actually looking at that one. thanks. have you used it?
11:29tolitiuschrisrossi: e.g. (grep "ssh" {:in (ps "-e" {:seq true})})
11:29tolitiusno, did not have a need, but I am looking for an excuse to :)
11:30tolitiuschrisrossi: Raynes is solid though, so I would expect it to work as doced
11:33chrisrossicool. i see the low-level api gives you :out as an input stream, just like i want. ;)
11:33chrisrossiand the method of composing pipelines is pretty cool.
11:34eggheadwe're using conch for a little task runner, works well
11:34tolitiuschrisrossi: yep, very clean
11:41jvchi, I wrote this help mode for clojure https://github.com/judevc/clojure-here
11:46mmarczykgfredericks: going by the code, objects implementing IReference would have their metadata reset to the leftmost metadata item specified in the source
11:46mmarczykgfredericks: ^:foo ^:bar ^:quux iref -> iref with {:foo true}, but not :bar or :quux
11:46futilejvc: can you put it in melpa?
11:48mmarczykgfredericks: the relevant concrete classes are Namespace, Agent, Atom, Ref, Var -- not exactly read in very often -- so not a terribly big deal
11:48jvcfutile: i put it in marmalade
11:48jvcI haven't put anything in melpa, let me have a try.
11:48gfredericksmmarczyk: how do you read them?
11:49futilejvc: melpa is awesome
11:50gfredericksmmarczyk: oh I see: (meta (read-string "^{:foo 12} ^{:bar 15} #=(atom nil)")) => {:foo 12}
11:52mmarczykgfredericks: right
11:52mmarczykgfredericks: no way to read these in besides read-eval that I can think of off the top of my head
11:55eggheadcan I have a macro that behaves differently in cljs than clj somehow?
11:56eggheadjust want to reference 'go' by clojure.core.async/go and cljs.core.async.macros/go depending on the env its used for
11:57dnolenegghead: there's not really a simple way to do that
11:57eggheadc'est la vie
11:57bgilbertegghead: maybe two separate macros under different namespaces, and shared functions in a common namespace
11:57eggheadcurrently i'm just not qualifying it and assuming that 'go' will be available at expand time
11:57nDuff(feature tags? something that made the language implementation queryable)
11:58eggheadya two namespaces is probably a better way to do it
11:58eggheadthanks
11:58mmarczykdnolen: egghead: haven't tried this, but checking whether there's a dynamic binding in place for *cljs-ns* (in cljs.analyzer) might be a way to do it
11:59mmarczykand incidentally I think it would be nice to have a supported way to do this
12:01dnolenmmarczyk: sounds like feature expressions to me :)
12:03mmarczykdnolen: sure :-)
12:03mmarczykdnolen: I'd still like to have *clojure-version* bound to something sensible when compiling cljs
12:04mmarczykwould be super funny if a compiler macro then used *clojure-version* to determine which Clojure-side facilities are available though
12:04mmarczykoh well.
12:06mmarczykoh wow, confluence uses some sort of rich text editor? no markup? :-(
12:07dnolenmmarczyk: I think it's possible to support Markdown, not sure Clojure Confluence does
12:08futilePOCT = plain old Clojure tricks
12:08futilePOCT is great. libs should encourage POCT instead of reinventing them
12:10mmarczykdnolen: oh great, help mentions some markup too, so that's encouraging... I'll find out soon enough if we've got it enabled
12:10ChongLihttp://dev.clojure.org/display/design/Feature+Expressions
12:11ChongLithis is a nice article
12:11dnolenChongLi: pretty sure it's on the table for Clojure 1.6 - we'll see
12:11ChongLisweet
12:13futilednolen: im probably way uninformed.. but would it make more sense to just define a stdlib-interface that each platform has to conform to?
12:13futilethen each program wouldnt care where its running, its just written one way.
12:13learner_squidz: Thanks for your answer about List comprehension. Really appreciate it
12:13ChongLino
12:13ChongLione of the core philosophies of clojure is platform power
12:14ChongLiby wrapping the platform in a standard interface, you lose that
12:14futiletouche
12:14futileyeah, it would require wrapping every single platform feature. thats not realistic
12:14dnolenfutile: it only sound good in theory, platforms tend to differ in dramatic ways
12:15llasramAlso, that kind of stuff is hard to get right. If you do it well, it saves users a ton of time. If you do it wrong, you get the Java process API
12:15futileah right, exceptions/types/concurrency/etc
12:15ChongLiit pushes you into a "lowest common denominator" standard platform
12:15ChongLifeature expressions help you to detect and leverage your platform specifically
12:26mmarczykdesign page re: recur to enclosing loop: http://dev.clojure.org/display/design/Named+loops+with+recur-to
12:26mmarczyk(incl. links to clojure-dev discussion and cljs proof of concept)
12:58callenDear #clojure, this is your daily reminder that https://github.com/uncomplicate/fluokitten exists.
13:02futileI thought I wanted comp, but that wasn't right. Then I thought it was iterate, that's not right either.
13:02futileI guess I want (f1 (f2 (f3 f4))) or something.
13:03futileIt's kinda like iterate, but with different functions each time, from a list of functions.
13:03futileHow would you do this?
13:04futileMaybe reduce...
13:05futile,(not (zero? (inc 3)))
13:05clojurebottrue
13:05justin_smith((apply comp fn-list) input)
13:05futile,((apply comp [not zero? inc]) 3)
13:05clojurebottrue
13:05futileOh.
13:06futileThanks justin_smith :)
13:06futile(inc justin_smith)
13:06lazybot⇒ 3
13:07futileYeah that makes a lot of sense suddenly.
13:09justin_smithanother option: (defmacro ->vec [input fns] `(-> ~input ~@fns))
13:09futileWell even so, I think I'm doing it all wrong.
13:09justin_smithI don't think the bot will do macros, but that will work like -> but take the fns in a list/vector
13:09futileI'm trying to implement around-each fixtures.
13:10futile(but it's all wrong)
13:10Bronsa,(get (sorted-set 1) :foo) ;; this was surprising to me
13:10clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword>
13:11justin_smitha fixture should be a function that takes the action it wraps as an argument, and it can decide whether to do it's action to the functions input or output or both
13:11futilejustin_smith: can you show me in code (refheap)?
13:11justin_smiththat way you can compose fixtures (similar to ring handlers for example)
13:11futilecuz im confused by what you mean
13:12justin_smithI have a meeting in four minutes, but remind me sometime later if I forget
13:12futilejustin_smith: oh ok
13:13futilefor anyone else following along, this is my plan so far: https://www.refheap.com/16903
13:19amalloymmarczyk: neat!
13:20bbloommmarczyk: another current "solution": trampolines
13:21amalloytrampolines solve everything in real life; why not in clojure too?
13:24bbloomhmmm… the letfn comment about loop layers is interesting
13:24bbloomin theory, if you have mutually recursively defined functions, couldn't you recur from tail position to another function in the letfn block?
13:25amalloybbloom: in scheme you could. in clojure it's not possible, and i don't think mmarczyk can change that
13:26amalloyi mean, i guess he could conceivably code-walk the letfn and transform it to a single function, but it would be as much work as core.async's go macro
13:26bbloomyeah, i guess you'd need to inline all the mutually recursive functions into each other, in case you were to let such a fn escape
13:27bbloomi *really* like the explictness of recur
13:27bbloomsuper useful to have that checked for you at compile time
13:27futileOh man, I think I have to use recursin.
13:32callenbbloom: https://github.com/bmillare/dj.compose
13:33callensigh, did he ignore me again?
13:33callencan somebody copy-paste my message to him please?
13:33callenthat repo might help him.
13:34Bronsa19:19:53 <callen> bbloom: https://github.com/bmillare/dj.compose
13:34llasramfutile: (reduce #(partial %2 %1) test-fn [fixture-1 fixture-2 fixture-3])
13:34futilellasram: ah!
13:34llasramI'm not sure if that's *really* what you want, but produces what you mentioned
13:34futilewhy do you think its not?
13:35callenBronsa: thank you.
13:35bbloomBronsa: i heard him :-P
13:35llasramfutile: Just seems odd, but thinking about it for a second, I see what you're going for
13:35futilellasram: yeah, each fixture receives a function it should call, which is either the test function, or another wrapped fixture.
13:36futilellasram: this does that perfectly without forcing the users to wrap all fixture bodies in an anon func
13:36bbloomcallen: this is interesting. thanks. in generally, i'm deeply interested in this sort of composition
13:36bbloomi frequently lament about the fact that extend is useless b/c all the core abstractions are still interfaces :-/
13:38callenbbloom: glad it was useful. good luck.
13:38callenbbloom: here's a puzzler, is there a way to generate java annotations with Clojure without using AOT/gen-class?
13:38callenbbloom: ideally with proxy?
13:39callenI saw the clojure.asm and AnnotationVisitor
13:39callendoesn't seem like there's anything shake-n-bake.
13:39llasramcallen: This came up a few days ago... I'm not sure it actually worked out for aphyr, but can invoke the internals of gen-class w/o AOT, and give the results to the same class-loader used by deftype
13:39callencomposing proxy could be annoying.
13:39callenllasram: he was in here last night and it still hadn't been resolved.
13:40llasramOh, well, there we go
13:40llasram(checks some logs)
13:40callenI think realistically it's going to require rewriting/wrapping proxy and using the AnnotationWriter/AnnotationVisitor.java stuff in clojure.asm.
13:41llasramHmmm, I wonder why the reach-into-internal stuff didn't work for him
13:42stuartsierracallen: deftype supports annotations.
13:42stuartsierrahttps://github.com/clojure/clojure/blob/229bf8fe9a751e4f48bb2b7ea57e27ebc43d26ae/test/clojure/test_clojure/annotations/java_6.clj
13:44callenstuartsierra: I tihnk it's needed for proxying classes from Netty.
13:44callenstuartsierra: I'm pretty sure aphyr already knows he can use annotations with deftype.
13:44callenThat's not the issue.
13:45stuartsierraOh, sorry, I tuned in halfway through.
13:45callenstuartsierra: Netty uses/requires annotations and it's making his life difficult. Proxy needs to support annotations for better java interop.
13:46stuartsierraI recall using Netty in the past (version 3.x?), and I didn't need any annotations then.
13:46callenstuartsierra: aphyr is out on the hairy edge apparently.
13:47stuartsierraOften annotation-based APIs have an alternative, lower-level API that doesn't require annotations.
13:47callenstuartsierra: http://docs.jboss.org/netty/3.1/api/org/jboss/netty/channel/ChannelPipelineCoverage.html http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/class-use/ChannelHandler.Sharable.html
13:47callenstuartsierra: I'm sure, given the signs of madness he was exhibiting, if such a thing were possible he would've done so.
13:47callenproxy needs to support annotations.
13:48stuartsierraOK, I'm not disputing that.
13:49stuartsierraWhen faced with an annotation-heavy Java API, I usually recommend writing wrapping Clojure functions in Java to do the annotation stuff.
13:49stuartsierras/writing//
13:50callenI'd rather fix proxy.
13:50futileWhat's that function that lets "defsomething" macros keep the metadata users gave it?
13:55futileSaw it a lot in clojure.core functions, can't remember which ones though.
13:56gfredericksfutile: if the macro passes the symbol through then it's normally not an issue I think
13:56pbostrom`futile: name-with-attributes?
13:57futilesounds right
13:57futileexcept i thought whatever it was was in core
13:58futilegfredericks: oh i think im just losing metadata because my macro uses with-meta instead of vary-meta
13:58futileyou're right. thanks.
14:07miwaI went to bed too late last night after having started to explore the world of clojure.. I dreamed of rainbow coloured parantheses o.O
14:07seangrovemiwa: There's an emacs mode for that
14:08miwawell, I'm a vim user =P
14:08callenmiwa: sorry to hear that.
14:08seangroveWell, heaven have mercy
14:08seangroveDoes your family know?
14:08miwahah, I've even converted one or two emacs users actually ;)
14:08seangrovemiwa: vim's good stuff, no worries :)
14:09seangrovehttps://github.com/kien/rainbow_parentheses.vim
14:09ziltiI once tried to use vim, I didn't even manage to set it up for clojure
14:09miwawell, setting it up is the hard part unfortunately zilti
14:10ziltiThough I'd miss elisp too much.
14:10futilewelp
14:10ChongLivim is great for editing tasks
14:10ziltiAnd orgmode
14:10futilewriting good macros is hard
14:10ChongLiemacs is great for running processes like repls and stuff
14:10miwawell, I hear there's a vi mode in emacs for those who are so inclined :P
14:10ChongLiyeah evil
14:10futileive been impressed by the architecture of Sublime Text
14:11futileits like Emacs but for 2013 instead of 1982
14:11miwayeah, Sublime Text seems pretty cool.. it's a bummer it isn't free though =/
14:11ChongLiyeah that's a dealbreaker
14:11futilethats what employers are for, to pay for it
14:11ziltiBut it's not using lisp... bah
14:11futilezilti: so?
14:11ChongLiit's not about the money
14:11futileChongLi: oh, libre?
14:11ziltiSublime is free, isn't it? It's "just" not open
14:11ChongLiyes
14:12futileChongLi: yeah, i dont care about that anymore. look what good libre did to emacs.
14:12futileits stuck in 1983 thanks to libre
14:12ChongLithat does not follow
14:12futileand look at linux vs mac. libre isnt doing anything for me, the user.
14:12ziltiWell, I'd not want Emacs to change much
14:12ChongLiI'm sorry you feel that way
14:13futileChongLi: i believe you
14:13llasramYeah....... RMS's fears of non-free software polluting Emacs through runtime shared library loading aren't exactly a necessary property of libre software
14:13futilei used to care about libre on principle, but pragmatially, it gives me no real power as a user.
14:13ChongLiclojure is libre as well
14:13nDufffutile: speaking as an end-user, I feel hamstrung whenever I use a system I can't get into the guts of and modify.
14:13nDufffutile: ...and, to be clear, I _do_ use that capability with some frequency.
14:13llasram(inc nDuff)
14:13lazybot⇒ 4
14:13ChongLiif it weren't, most of us likely wouldn't be here
14:14futilei think that xkcd about scripting linux to keep the screen from going black sums up my argument against any supposed benefit of libre
14:14fowlslegsI am having a problem with the clojure.java.javadoc api
14:14fowlslegsThe javadoc function is rendering incromprehensibly
14:14futile"oh she got dressed and left only 30 minutes into me reading the manual on scripting the cursor"
14:15futileor however it goes
14:15fowlslegsIs there a way to fix this or should I investigate alternative java documentation?
14:15seangrovefowlslegs: Sorry, haven't used the javadoc pieces at all
14:15ChongLifutile: you could repeat the same exercise with pretty much any proprietary software product
14:15nDufffutile: last month, I patched Ivy to add SSH agent support; to fix revision mapping support, and... eh, something else.
14:15ChongLiit does nothing to support your point
14:15nDufffutile: if the source had been closed, I would have had no recourse at all.
14:15seangroveI don't get the feeling that it's used all that much
14:15futileChongLi: right. meaning libre or not makes no difference.
14:15fowlslegsseangrove: thanks!
14:16ChongLifutile: convenience is not the goal of free software
14:16ChongLifreedom is
14:16futilenDuff: not true. if the demand is high enough, a competitor comes out that gives you what you really want, and kills out the other guy
14:16fowlslegsanyone else know about the javadoc fxn?
14:16nDufffutile: that's in the long run. In the long run, as they say, we're all dead.
14:16futileChongLi: freedom is a means to an end, not an end in itself
14:16nDufffutile: The short run matters.
14:16futilenDuff: no, in the short run too. datomic for example.
14:16ChongLiwithout freedom, you may lose everything
14:17nDufffutile: in the short run, I can't typically afford switching costs.
14:17fowlslegsOr does anyone know of a doc library that's good and contains java?
14:17futileChongLi: thats an exaggeration
14:17futiledatomic isnt libre and its wonderful compared to postgres and mongo which are libre
14:17nDufffutile: ...and, by the way, the licensing on datomic hurts it a lot.
14:17ChongLifutile: tell that to the users of google reader
14:17futilenDuff: time will tell if it actually does hurt it or if thats just a false opinion
14:17nDufffutile: I haven't been able to use it in any of the places I've worked since it came out due to the licensing
14:17futilenDuff: even datomic free?
14:18nDufffutile: ...because we weren't willing to put down $$$ until we knew it was worth it, and we couldn't evaluate without risking lockin.
14:18ziltiI don't mind using non-libre software sometimes, but as a future software developer I'll do everything I can to make my money with libre software
14:18nDufffutile: go with free, and you're betting transition costs on the product being worthwhile.
14:18nDufffutile: that's a hard sell to management.
14:19futilenDuff: yeah, so some corporations lose out in the shortest-term due to that. but maybe thats actually a good thing. if you'd jumped in and found out it wasnt performant, youd have lost that valuable time. better for everyone to wait til it proves itself, not just people who dont wanna pay
14:19futileChongLi: i dont know any users of google reader
14:19seangrovenDuff: same concerns over lock-in with datomic as well
14:20nDufffutile: "better for everyone to wait" gets you things like the Python2->Python3 transition, where it's years after 3.0 is called preferred by the dev team but everybody is waiting for someone else to go port libraries over first.
14:21futilenDuff: thats a library concern, not analogous to datomic's issue. once datomic proves itself, everyone can jump in without hesitation. python3 isnt adopted because every lib author needs to wait for every other lib author.
14:22nDufffutile: how in the world is datomic going to prove itself is the strong majority of its userbase aren't willing to consider it because it's unproven and too risky to use the free version for a pilot that might need to scale?
14:22nDufffutile: if people _do_ use it successfully, you have things like Viaweb's use of Common LISP
14:22nDuff-- a competitive advantage they keep to themselves and don't publicize.
14:22nDuff...so others don't *know* that it's been used successfully until years after the fact.
14:23futilenDuff: thats only assuming every one of them needs that competitive advantage, which im sure they wont.
14:23futileif we were to use datomic where i work, im sure we wouldnt mind publicizing that fact, we dont have many competitors.
14:23futileour niche is something else, not how well we scale.
14:23nDufffutile: Right. Fact of the matter is that the Clojure community is limited in size. There are only so many potential adopters you can afford to drive off.
14:24futilenDuff: isnt datomic just java? tons more people can use it than just us.
14:24nDufffutile: Not everyone's projects are going to work out -- many to most will fail for reasons completely unrelated to the datastore.
14:24futilenot to mention it uses rest lately, so even rails guys can use it
14:24nDufffutile: it's "just Java", but it's not nearly as usable from Java.
14:24futilenDuff: heh, nothing is :)
14:24nDuff...is the impression I got last time I looked.
14:24nDuffAs in, hard enough to use from Java that nobody would want to.
14:24ziltifutile: You still have to write the requests in EDN aka Clojure if you use it from Java
14:25futilezilti: edn isnt hard for java devs to learn for this small purpose
14:25futilelook, we're way off topic
14:25nDufffutile: anyhow, any shop using Java is a place prioritizing being able to replace their staff over making their staff productive
14:25ziltiSo in Clojure you can use data structures but in Java you have to put together Strings
14:25nDuffthose aren't the places that are going to be using Datomic anyhow.
14:25futilemy main point was that Sublime Text looks like its emacs-done-right. and thats pretty cool.
14:25futilemain thing holding me from switching altogether is that its paredit-mode is lacking some important keys
14:26futilezilti: just like sql
14:26futilewhich they've managed fine so far ;)
14:27futileanyway, writing good macros is hard.
14:27ziltiDamn, today is the first time I hate clojurescript for not having runtime macros...
14:27futileoh?
14:28amalloydoes anyone happen to know what the jvm does when it receives a signal (sigterm, sigint, etc)? it seems to be doing basically what i want (giving InterruptedException to my running threads, then shutting down), but i wonder if that's actually what's going on, and whether that's promised behavior
14:29hyPiRionamalloy: Starts a new thread with max priority, and handles the Signal through a SignalHandler
14:29ziltiI'm working on a project where it should be possible to just define forms for database editing with basically no logic to be inside, and have to somehow get that form out, modify it and listen to everything. Would have been way easier with some clojure.walk magic in a macro
14:31hyPiRionWhat happens with the specifics one, I'm not sure. Most of them are implemented natively, for whatever reason.
14:34futile,(let [list [:foo :bar "baz" :quux :yay], [a [b & c]] (split-with (complement string?) list)] [a b c])
14:34clojurebot[(:foo :bar) "baz" (:quux :yay)]
14:34futilesweet
14:34futileis that terrible code, or fine?
14:36seangrovefutile: the code seems fine, but the intent seems terrible
14:36futileseangrove: whyzat?
14:36seangroveBut I don't know what you're trying to do, so maybe it makes sense
14:36futilewell, im writing a horrible macro.
14:36Raynes"That sounds like a terrible idea! I don't know what it is, but I bet it's horrible!"
14:36futile:D
14:36futileim making this work (deftest "testing foo" ...body...)
14:37futileexcept, since it uses a string instead of a symbol, you cant put metadata before that string, since it wont compile
14:37futileso im going to just let people put a list of keywords there that will act like ^:kw
14:37seangroveRaynes: Far too many bangs
14:38futileie (deftest :foo :bar "testing something" ...body...)
14:38futilewhich i admit is "terrible, just terrible". but i dont have a better idea yet.
14:38seangrovefutile: That's not so bad
14:38seangroveIt just wasn't clear why you'd be splitting/destructuring like that from the a b c example
14:39futilethe inconsistency between ^:foo and :foo is bad
14:43squidzzilti: how would you do it with javascript?
14:44ziltisquidz: Oh, I won't touch javascript, I'll stick to clojure :) Sure there's a way, but runtime macros would have made it simpler.
14:44futileis there a better way to do this? &(into {} (map vector [:a :b :c] (repeat true)))
14:44futileoops i meant &&(into {} (map vector [:a :b :c] (repeat true)))
14:44futileoh man whatever.
14:44futile,(into {} (map vector [:a :b :c] (repeat true)))
14:45clojurebot{:a true, :b true, :c true}
14:45hyPiRion,(zipmap [:a :b :c] (repeat true))
14:45clojurebot{:c true, :b true, :a true}
14:45SegFaultAXarohner: Ping.
14:45arohnerpong
14:45SegFaultAXarohner: Circle is awesome.
14:45arohnerthanks :-)
14:45SegFaultAXIs github integration on the roadmap?
14:46fowlslegs(.printStackTrace *e) is giving me nil
14:46arohnerWDYM, integration?
14:46fowlslegsbut an exception was just thrown
14:46SegFaultAXI want to replace our CI with circle, but my team needs github commit status api.
14:46arohnerwe already do that
14:46SegFaultAX:O
14:46SegFaultAXDocs?
14:46squidzzilti: exactly
14:46fowlslegsany ideas on where the error is?
14:47callenSegFaultAX: what are they using right now?
14:47SegFaultAXarohner: Also, I really enjoyed your talk on infoq.
14:47arohnerSegFaultAX: you shouldn't need to configure anything
14:47SegFaultAXarohner: Orly?
14:47arohnerif we run the build, it updates commit status
14:48SegFaultAXarohner: Weird, the initial tests we did didn't seem to do that. But maybe we missed it since we're also testing codeship
14:48arohnerthanks! you might also enjoy https://www.youtube.com/watch?v=9wgsDosgWhE . I was going to do that talk, then it interfered with my honeymoon
14:48SegFaultAXarohner: Are you in SF?
14:48arohnermost of the time
14:48SegFaultAXarohner: You open to lunch sometime?
14:48arohnerabsolutely
14:51ToxicFrogHow do I take the sqrt of an integer? The docs I can find all refer to 'clojure.contrib.math or 'clojure.math.numeric-tower, neither of which I seem to have (in 1.4)
14:51futileis remove-ns expensive?
14:51ToxicFrogShould I just make it a double and use java interop?
14:52llasramToxicFrog: It should auto-coerce to a double when you call `Math/sqrt`
14:52zilticlojure.contrib is "dead" since 1.3
14:52llasramToxicFrog: Or are you looking for an exact answer for when the square root is an integer?
14:53ToxicFrogllasram: nah, I don't need an exact answer
14:54SegFaultAX,(Math/sqrt 16)
14:55clojurebot4.0
14:55futile,(gensym)
14:55clojurebotG__31
14:55futile,(gensym "foo")
14:55clojurebotfoo60
14:55futileneat.
15:01stuartsierraHuh. clojure.lang.Range isn't used anywhere.
15:02bbloomstuartsierra: `git rm` is my favorite command :-)
15:02eggheadhmm, is there any utility around to split a command line string into an argument vector?
15:02amalloystuartsierra: i always assumed it was an early prototype before lazy-seqs made (range) possible
15:03stuartsierraamalloy: That's my guess too. Probably left for backwards compatibility.
15:03eggheadseems like a tricky problem, things like "foo -x 'bar 23' --foo bar"
15:03amalloyegghead: well, your shell will do the "hard" part there, of making "bar 23" a single arg
15:03amalloytools.cli isn't bad
15:04eggheadamalloy: I'm taking in command strings as input, so I have to do it myself :(
15:04bbloomstuartsierra: but backwards compatibility inhibits my ability to git rm freely.....
15:04eggheadunless I just forward it to sh -c or something
15:05seangrovestuartsierra: Isn't that something codeq could tell you?
15:06stuartsierraseangrove: I don't think codeq has a Java parser yet.
15:06fowlslegsCan someone help me understand a REPL error I am having?
15:07seangrovestuartsierra: Ah, good point
15:07fowlslegsIt should be quite simple for most here I'm sure.
15:08llasramfowlslegs: Questions are welcome, so need for ceremony before asking :-)
15:08llasrams,so need,so no need,
15:08fowlslegsSo I have this fxn: http://paste.ubuntu.com/5912118/.
15:09llasramOk
15:10fowlslegsAnd when I try to use java.lang.Math methods I get this error "CompilerException java.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math, compiling:(NO_SOURCE_PATH:1:1)".
15:10llasramOh, that's because JVM object static methods aren't Clojure functions
15:10fowlslegsFor example, (f-values Math/hypot 5 5) gives me this.
15:10llasramRight. ##(class Math/hypot)
15:10lazybotjava.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math
15:11llasramThat's a method, which isn't a "thing" you can pass around
15:11llasramYou need to wrap it in a function, which can be anonymous, like (f-values #(Math/hypot %) 5 5)
15:12llasramBecause then: ##(class #(Math/hypot %))
15:12lazybotjava.lang.IllegalArgumentException: No matching method: hypot
15:12llasramHah
15:12llasramBecause then: ##(class #(Math/sqrt %))
15:12lazybot⇒ sandbox11278$eval15202$fn__15203
15:12llasramAnyway
15:12llasramYou get the idea
15:15fowlslegsHmmm maybe I need to read up on methods
15:15fowlslegsI don't really understand how they differ from functions.
15:16gfredericksthey're interop things
15:16gfrederickshas anybody written an intro-to-the-jvm-for-clojure-programmers yet?
15:16fowlslegs(Math/hypot 1 1) works
15:16gfredericksI might volunteer if not
15:16seangrovegfredericks: That would be wonderful
15:17gfredericksokay that's on my todo list
15:17gfredericksmaybe this weekend
15:18fowlslegsSo why does it work in this single instance, but not when I use the for macro to use it generate the third value of each vector in my lazyseq
15:18gfredericksfowlslegs: are you still tripping on (f-values Math/hypot 5 5)?
15:18zerokarmaleftgfredericks: jvm = vm internals or core libraries often used via interop?
15:19fowlslegsyes
15:19gfrederickszerokarmaleft: not vm impl -- like the object model (what are methods? interfaces? etc?), the classpath, properties...
15:20gfrederickssuggestions welcome
15:20gfredericksfowlslegs: try (f-values #(Math/hypot %1 %2) 5 5)
15:22gfredericksalso should it be a blog post or something more communal?
15:22llasramgfredericks: Inner classes (because it's such a commonly asked question). Probably how `.method` and `Constructor.` are builtin pseudo-macros (or whatever the official name is)
15:22zerokarmaleftgfredericks: that sounds more like a communal effort
15:22zerokarmaleftthere's a lot of rabbit trails
15:22gfredericksshould check that clojure-doc site
15:22llasramMaybe something on clojure-docs
15:22llasramclojure-doc even
15:23llasramHuh, which seems to be in a sadness-state right now
15:23llasramOh, there already is one: http://clojure-doc.org/articles/language/interop.html
15:23gfredericksby which you mean it's missing its stylesheets?
15:24llasramAnd having encoding issues
15:24gfredericksI feel like an interop guide should be a separate thing
15:25llasramA separate thing from what?
15:25gfredericksan intro to the jvm
15:25llasramAh
15:25gfredericksyou can tell somebody "here's how you call a static method" and that's interop, but if they don't know what a static method is in the first place...
15:25llasramThat does seem reasonable
15:25zerokarmaleftgfredericks: I remember handling those gaps by just shoehorning myself into java for awhile
15:25gfredericksI didn't have them since I had done java enough
15:26gfrederickszerokarmaleft: you wrote java code?
15:26zerokarmaleftonly in an academic setting, years before I started clojure
15:26zerokarmaleftwhich is to say, not really
15:26fowlslegsgfredricks: thanks very much. I just read up on the #() reader form.
15:28gfrederickszerokarmaleft: I was referring to your "shoehorning myself into java for awhile"
15:28gfredericksfowlslegs: np
15:29gfredericksfowlslegs: equivalent would be (fn [a b] (Math/hypot a b))
15:30ltwCan Clojure libraries be made interoperable with Java?
15:30zerokarmaleftgfredericks: oh yes, I did some stuff with hadoop in java even though I knew about cascalog
15:31konrhaha, so amazing; I managed to get our scala programmer excited about clojure just by showing my test suite :)
15:33fowlslegsgfredericks: So I still don't understand *why.* Should I read up on Java?
15:33fowlslegsgfredericks: So I still don't understand *why.* Should I read up on Java?
15:33zerokarmaleftgfredericks: it was more like revisiting an old language I was already familiar with and applying it to some useful albeit small scope
15:34gfredericksltw: you're asking about java code calling clojure libs?
15:34ltwgfredericks: yeah, I want to write a library that will be called from Clojure and Java, but I want to write it in Clojure.
15:35gfredericksltw: yeah you can go one of two ways depending on how easy you want to make it from the java side
15:35gfredericksanything you can do in clojure can be done clunkily from java via the RT class
15:35gfredericksso in that sense any clojure lib trivially qualifies
15:35zerokarmaleftfowlslegs: you can read up on Java a la carte as you run into jvm concepts that are unfamiliar
15:35gfredericksbut you can also generate classes with methods, which makes it much cleaner from java
15:36ltwgfredericks: oh, like using gen-class?
15:36gfredericksthat certainly works
15:37gfredericksI think I wrote a lib once for exporting a whole namespace as a java class with static methods
15:37gfrederickshttps://github.com/fredericksgary/lib-2367#export-ns
15:37gfredericksit uses gen-class
15:37gfredericksbut is minimal effort
15:37ltwI think I'll go that way if it's reasonably non-trivial.
15:38fowlslegsthanks, will do
15:38callenRaynes: that's what you get for writing Haskell.
15:38ToxicFrogI'm running into something really weird with a recursively defined lazy infinite seq: http://hastebin.com/duforatapi.lisp
15:38ltwgfredericks: I think you've just solved the only problem I saw with the gen-class method approach.
15:38ltwit's a client library wrapping a service, so there was going to be many function definitions
15:38gfredericksmy work here is done
15:39Raynescallen: I'm not writing Haskell. Just observing how horrible the support for it in Vim is. I mean, I can use Emacs for it, but Christ. After all these years I would have expected it to at least be able to indent Haskell half-assed.
15:39ToxicFrogI would expect that (0 1 2) are in the seq (because they are < 3), and then 3 and 4 should be also (because by the time it's calling (tasty? 3) it's realized the list head and discovered that is (= 0)
15:40ToxicFrogInstead it seems to be the case that (first tasty) is something other than 0 until it calls (tasty? 32) and then suddenly it is 0.
15:40ToxicFrogIs this a weird interaction with (declare)? Am I not understanding something fundmental about how lazy seqs work?
15:41gfredericksToxicFrog: this is super weird
15:41ToxicFrog(this is 1.4.0, btw)
15:41gfredericksI get it in 1.5.1 too
15:42ToxicFrogAlso I'm glad it's not just me who thinks it's weird
15:42gfredericksToxicFrog: this has something to do with chunking
15:42gfrederickswhich you can tell by replacing (range) with (iterate inc 0)
15:43ltwis there an existing convention on how to name Clojure libraries that are interoperable with Java? (I have a Ruby library for this functionality already)
15:43gfredericksbut I haven't figured out why that should be relevant though
15:43RaynesNot really, because nobody writes libraries that are interoperable with Java.
15:43RaynesThey value their sanity.
15:43Raynes:p
15:43stuartsierraToxicFrog, gfredericks: You're running into chunked lazy sequences there.
15:44stuartsierraThe 32 is a giveaway.
15:44gfredericksstuartsierra: oh definitely
15:44gfredericksstuartsierra: that's what I just said -- it's just not clear why it's relevant
15:44gfredericksas best I can tell, the act of computing a chunk of a chunked lazy seq is calling first on itself
15:45gfrederickswhich is not throwing an exception but is instead returning something weird
15:45ltwRaynes: ha, I'd rather write it once in Clojure and make it interop than have to write it in Java.
15:46ToxicFrogAdding a (println) says that it's nil until the first 32 elements have been evaluated, then 0
15:47gfrederickslooks like (first my-chunked-seq) is nil during the computation of the first chunk
15:47gfredericksoh you just found out the same thing
15:47ToxicFrogIs there any documentation on chunked sequences? The docs for (range) don't mention that it chunks, nor that this optimization(?) may break things.
15:47gfredericksToxicFrog: yeah I'd say a self-referential chunked lazy seq is a bad idea :)
15:47gfredericksToxicFrog: in general a self-referential lazy seq probably shouldn't be necessary I don't think
15:48ToxicFroggfredericks: necessary, no, but it's a convenient way to write some things
15:48ToxicFrog(I ran into this when making a simple prime generator as practice; when testing to see if the next number is prime it's useful to be able to refer to earlier primes)
15:49ToxicFrog(there are undoubtedly non-toy applications for this technique)
15:49jcromartiethere needs to be a Jekyll for Clojure…
15:49jcromartiethis is happening
15:49gfredericksjcromartie: somebody was working on that a week or so ago
15:50ToxicFroggfredericks: in any case it should probably be mentioned in the docs for functions that generate chunked sequences that they do so and are thus not safe for recursion.
15:51ToxicFrogI would not normally expect replacing (range) with (iterate inc 0) to change the results of my code.
15:52stuartsierraMost of the core sequence functions used chunking when possible as an optimization.
15:52stuartsierras/used/use/
15:53stuartsierraIn general, Clojure's lazy sequences make no guarantees about *when* a particular part of the seq is realized.
15:53ToxicFrogI think the underlying surprise here is that I thought it was guaranteed that (first foo) would be realized before (rest foo)
15:54ToxicFrogWhen this is not actually the case.
15:54futileSo,
15:54futilethe other night, I did "lein deploy", typed in my credentials, and it Just Worked™
15:54futiletoday i try again, and it gives me a confusing msg
15:54ToxicFrogIT seems likely that this guarantee isn't actually stated anywhere, but it's still super surprising.
15:57futileAh. I really did "lein deploy clojars" last time.
15:57futileWorks like a charm.
15:58ToxicFroggfredericks, stuartsierra: to make it even more confusing, (chunked-seq? tasty) returns false in both versions
15:59ToxicFrogAs does (chunked-seq? (take 5 tasty))
16:01SegFaultAXToxicFrog: It just occured to me that I know you from #lua.
16:01stuartsierrachunked-seq? isn't documented, probably an internal function.
16:01atyzHey all - I'm doing the following (with kormasql) https://www.refheap.com/16907 and getting an error saying I cannot use Can not issue data manipulation statements with executeQuery(). I've done some research and It would require me using executeUpdate() . Is there a way to get around this?
16:02futileok
16:02futilenevermore 0.0.1 released, its official :)
16:02ToxicFrogSegFaultAX: yep
16:03ToxicFrogstuartsierra: anyways - is there literature on sequence chunking, which functions I should beware of, etc?
16:04stuartsierraToxicFrog: Not that I'm aware of. Assume any core function which generates a sequence may use chunking.
16:04ToxicFrog:(
16:05llasramToxicFrog: What's the actual ultimate problem?
16:05gfrederickshe wants to use haskell-style laziness-backed self-reference
16:05ToxicFrog^ that
16:05stuartsierraThen use Haskell.
16:06llasramOh. You can always explicitly unchunk your sequences
16:06ToxicFrogSadly my underlying assumption that the n'th value in the seq won't be realized until after the (n-1)th value has been turns out to be false.
16:06bbloomToxicFrog: decompile the problem into a lazy traversal and a state machine
16:06bblooms/decompile/decompose
16:06ToxicFrogllasram: how? (and how did you learn about chunking?)
16:07bbloomif you need linear execution, just loop over a sequence and conduct your side effects in the loop
16:07ToxicFrogbbloom: there are no side effects.
16:07bbloomToxicFrog: evaluation is a side effect
16:07ToxicFrogI'm just trying to compute an infinite lazy sequence where the value of later values in the sequence is an expression of values earlier in the sequence.
16:07SegFaultAXIIRC chunked seqs are implemented in such a way that they should be transparent.
16:08ToxicFrogIf evaluation is a noticeable side effect your abstraction is leaking, IMO.
16:08bbloomToxicFrog: this is why people complain about understanding space complexity in haskell, b/c you can get UNBOUNDED lookahead w/ laziness
16:08llasramToxicFrog: I read about it in /Joy of Clojure/ very early in my Clojure-programming. /JoC/ has this function: https://www.refheap.com/16909
16:08SegFaultAXShould being the operative term. They exist only as a performance optimization.
16:08ToxicFrogSegFaultAX: the genesis of this discussion is that they are actually not; I have code that returns different values when using a chunked seq vs. a non-chunked one.
16:08bbloomyou can achieve what you want, but you must be explicit about your buffering
16:09SegFaultAXToxicFrog: Bummer :/
16:09ToxicFrogbbloom: I would prefer unbounded lookahead (and thus terrible performance, OOMs, etc) to getting the wrong answers quickly.
16:09llasramIt still depends on the implementation detail that `lazy-seq` recursion is evaluated one thunk at a time, but in practice it works
16:09ToxicFrogllasram: thank you.
16:10bbloomToxicFrog: the answer is right, your assumption about the semantics are wrong :-P if you want to achieve haskell-like semantics, you need to implement either A) fully lazy evaluation or B) a particular data structure for your use case
16:10bbloomthis is why i'm suggesting: use a state transducer
16:11SegFaultAXProbably option b is easier.
16:11llasramToxicFrog: Note that the docstring (which I wrote when I stole the function) isn't actually right -- it doesn't de-chunk the input seq, but returns a new seq which isn't chunked. So you wrap your input, not the seq your producing (if that wasn't obvious)
16:11SegFaultAXbbloom: Can you define that term?
16:11bbloomhttps://github.com/brandonbloom/transduce
16:12llasramoooh
16:12ToxicFrogbbloom: so, the objection I'm arriving at here is that chunking is an optimization that (a) does not seem to be documented outside JoC and (b) when applied can result in actual functional changes even in pure code
16:12ToxicFrogThere is no indication which library functions produce chunked sequences, or even that chunked sequences are a thing, and if an optimization is meant to be that completely invisible it had better not change the results of code that triggers it!
16:13SegFaultAXbbloom: Ah, neat.
16:13llasramomg, bbloom, these are great
16:13ToxicFrogAlternately, a warning like "don't try to use self-referential lazy sequences, they will produce garbage due to internal optimizations used by clojure's lazy seq implementation" would be nice,.
16:13bbloomSegFaultAX: llasram: thanks!
16:14zerokarmaleftwhy is set! restricted against local vars?
16:14bbloomToxicFrog: i just joined the conversation a tad late, so i need to look at your particular paste & understand the problem
16:14llasramToxicFrog: The problem is that there really isn't a good way to tell when you're building a self-referential lazy-seq. If there were, I'd agree there should be a warning
16:14SegFaultAXbbloom: That's really useful. I'm sad to only just be learning about this library.
16:14ToxicFrogbbloom: http://hastebin.com/duforatapi.lisp
16:15alandipertzerokarmaleft: i take it you mean lexical bindings? it's because there isn't a mutable reference type (Var) behind them
16:15ToxicFrogbbloom: If you replace (range) with (iterate inc 0) it works.
16:15SegFaultAXToxicFrog: The whole point of range chunking is that it's more efficient to generate groups of numbers rather than single values.
16:15alandipertzerokarmaleft: it can be achieved via macros though, see https://github.com/ztellman/proteus
16:16SegFaultAXIf you're ok with the potential performance hit, though...
16:16zerokarmaleftalandipert: well, a bit more context, I'm simply trying to mutate a DOM element
16:16bbloomToxicFrog: neither range nor iterate is bugged. your example is using declare to create mutual recursion but you're missing one level of indirection
16:16ToxicFrogSegFaultAX: which is fine. But it's a performance optimization that can change program behaviour and thus should be more visible than it is.
16:16zerokarmalefte.g. (set! (.-innerHTML el) "foo")
16:16ToxicFrogbbloom: how/where?
16:16alandipertzerokarmaleft: oh, you probably want 'aset'
16:17alandipert(aset el "innerHTML" "foo")
16:18ToxicFrogWhat should I have done instead to avoid this? What should I have read to know I was meant to do that?
16:18zerokarmaleftalandipert: perfect, thanks
16:18zerokarmaleftodd that set! seemed to compile and run fine intermittently
16:18bbloomToxicFrog: (first tasty) is going to be a constant
16:19bbloomor should be
16:19llasramToxicFrog: I don't think there was anything official you could have read. It's come up a few times on the mailing list, but AFAIK is basically tribal knowledge
16:19ToxicFrogbbloom: this is just a minimal test case; in practice (first tasty) might be some more complicated expression involving, say, (take limit tasty) where limit is some function of n.
16:20bbloomToxicFrog: change (first tasty) to (doto (first tasty) prn) and you'll see what's happening
16:20bbloomyou're getting 32 nils
16:20ToxicFrogI already know that
16:20bbloomb/c (first UNDEFINED-VAR) is bad
16:21gfredericksbbloom: he knows what's happening he thinks it should not happen or be better documented
16:21bbloomif you want mutual recursion, you must define things simultaneously
16:21bbloomi dunno what he want's documented
16:21gfredericks"don't use self-referential chunked seqs"
16:21gfredericksand also "chunked seqs exist"
16:21ToxicFrog...how do I do that? Because last time I looked for "how do I do mutual recursion in clojure" the answer I got was "(define) one of the things first"
16:21xpein choosing a JDK for Clojure, is there a significant difference between 7 and 8?
16:21bbloomno, it's don't use mutual recursion without a layer of indirection
16:21ToxicFrogbbloom: what gfredericks said.
16:21xpeor runtime?
16:21bbloomit's more than just chunked sequences
16:21ToxicFrogOk, what layer of indirection? You keep saying I'm missing one and I'm asking what
16:22bbloomyou're trying to evaluate tasty? while tasty is being defined
16:22bbloomthat's undefined behavior b/c it's mutually recursive
16:22bbloomyou need to add a delay or a fn call
16:23bbloomand if you do that, you'll get a stack overflow, which is precisely what your function is trying to do :-P
16:23gfredericksnow we need documentation saying "Don't be mutually recursive because it's undefined"
16:23gfredericksbbloom: it works perfectly well w/o chunking
16:23bbloomby luck
16:23ToxicFrog...well, no, because by the time (tasty?) needs to evaluate part of tasty, the parts of tasty it's referring to are already realized non-recursively
16:23bbloomb/c of some internal order of execution
16:24gfredericksbbloom: if "some internal order of execution" means "evaluating lazy seqs in order one item at a time" then yeah
16:25ToxicFrogThe first three values of tasty (0 1 2) are evaluated without any recursion; 3 onwards require evaluation only of (head tasty). It does not seem controversial that "the elements of a lazy seq are realized in order" is a reasonable assumption to make, and that the fact that this assumption is wrong should be documented.
16:25gfredericksfor the record I don't think we should write code like this; but I think it's reasonable that he had different expectations and that this will happen to others
16:25bbloomi agree with that gfredericks
16:26gfredericksToxicFrog: they _are_ realized in order, just some of them in parallel
16:26ToxicFrogYeah, I would also be ok with the answer to "how do I do mutual recursion in clojure" being "don't", even if that is a really aggravating restriction in some cases
16:26ToxicFrogAs long as that was actually documented somewhere.
16:26bbloomgfredericks: parallel == "observably simultaneously" ?
16:26gfredericksbbloom: I think so yes
16:26gfredericksbbloom: certainly I didn't mean wrt threads and such
16:27supersymis it me or do other ppl find defrecord a bit unwieldy as well
16:27amalloyToxicFrog: that's not really true, though; the thing that's discouraged is self-recursive data structures
16:27amalloymutually-recursive functions are fine, although because we lack TCO you have to be careful
16:28ToxicFroggfredericks: that doesn't really count as "in order" to me; "in order" implies that, at the moment the n'th element of the sequence is realized, all prior elements have already been realized.
16:29gfredericksToxicFrog: okay; definitions I guess
16:30ToxicFroggfredericks: basically the assumption of mine that was violated was that s[n] will always be realized after realization of s[n-1] is complete (and thus, by implication, that a definition of s[n] that depends on s[m] where m<n is safe).
16:32bbloomToxicFrog: that assumption is valid, what assumption is invalid is that the evaluation of s[n] and s[n-1] will necessarily occur at alternating locations in the stack frame
16:33bbloomin theory, chunking could maybe recognize and correct this
16:35gfredericksbbloom: but probably wouldn't if it makes it slower
16:36bbloomgfredericks: probably
16:36bbloomall this discuss, incidentally, motivates my total lack of interest in the academic obsession with non-termination
16:37bbloomthe fact that evaluation TAKES TIME is a lie that haskell programmers wish would go away :-P
16:37bbloomis IS NOT a lie & that
16:37bbloomi failed to say that in any way that makes sense, but somebody will understand wtf i'm talking about
16:38futileis it a terrible idea to do (alter-meta!) on #'some-var which will be thrown away in a minute anyway?
16:40gfredericksyou're throwing away vars?
16:41futilegfredericks: via (remove-ns)
16:41futile,(clojure.string/join "," [1 2 3])
16:41clojurebot"1,2,3"
16:42futile,(do (remove-ns 'clojure.string) (clojure.string/join "," [1 2 3]))
16:42clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>
16:42futile,(clojure.string/join "," [1 2 3])
16:42clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>
16:42futileoops
16:42futile,(require 'clojure.string)
16:42clojurebotnil
16:42futile,(clojure.string/join "," [1 2 3])
16:42clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>
16:42futile,(require :reload 'clojure.string)
16:42clojurebotnil
16:42futile,(clojure.string/join "," [1 2 3])
16:42clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>
16:47futiledont worry ill figure this out
16:51futileok yeah i give up
16:51futilei broke it. im sorry.
16:52llasram,(do (require 'clojure.string) (clojure.string/join "," [1 2 3]))
16:52clojurebot"1,2,3"
16:52futilebut.. but..
16:52futilei tried that, didnt i?
16:52futile,(clojure.string/join "," [1 2 3])
16:52clojurebot"1,2,3"
16:53PuercoPopOi, in order to use select from enlive do I have to transform the html string into an specific representaion?
16:54squidzis it possible to create and use source maps now wwith clojurescript?
16:54ToxicFrogbbloom: what?
16:55bbloomToxicFrog: what about what?
16:55ToxicFrogIf, during evaluation of s[n], the value of s[n-1] is nil, it is not the case that s[n-1] has been realized (even if the value has been computed internally and is being buffered somewhere invisible to my code)
16:56ToxicFrogAnd I'm not sure what you mean by "alternating locations in the stack frame"
16:56gfredericksI also don't know what he meant by that
16:57futilellasram: thanks for fixing it somehow :)
16:58llasramComputers just like me
16:58bbloomit's the difference between (do (realize! s n) (observe! s n) (realize! s m) (observe! s m)) vs (do (realize! s n) (realize! s m) (observe! s n) (observe! s m))
16:58squidztogether with lein cljsbuild i mean
16:59bbloomactually, it's worse than that
16:59ToxicFrogbbloom: except in either case (realize! s m) is called after (realize! s n) completes, and thus (observe! s n) should succeed if (realize! s m) calls it.
17:00ToxicFrogWhen, in fact, it doesn't.
17:01bbloomlet me clarify a few things: 1) i'm not saying clojure is PERFECT here. surely it may be possible to improve this behavior to meet your expectations w/o violating anybody else's 2) i think it's perfectly reasonable for this behavior to be undefined
17:02bbloomnow, with that said, the issue is more subtle than what i said, b/c it's really
17:02bbloom….
17:02bbloom(realize-cps! s n callback)
17:02bbloomor rather k for continuation
17:02bbloom(realize-cps! s n k)
17:02bbloomand when k gets called is important
17:03bbloomi'm saying that it's currently undefined when it gets called, you're saying there is a reasonable definition
17:05bbloomdoes that explain my comment?
17:06ToxicFrogNot really; I don't know realize-cps!. Documented?
17:06bbloomi just made it up
17:06bbloomthat's just realize with a callback
17:06bbloomcps = continuation passing style
17:06ToxicFrogAah
17:07llasramcps vs csp -- fight!
17:07bbloomllasram: both!
17:08llasramheh
17:08bbloomllasram: that's like saying "space vs time -- fight!"
17:08bbloom:-)
17:09bbloomToxicFrog: make sense now?
17:10bbloomToxicFrog: also, i should add… if you can write a patch that doesn't hurt perf, break anything else, and fixes this, you should submit it!
17:10ToxicFrogI don't feel like my brain is entirely here right now, but AIUI you're basically just saying that it is undefined in what order the elements of a lazy seq are evaluated?
17:11bbloomi'm saying it's undefined how sequence realization and sequence observation will be intertwined
17:12bbloomlazy sequences are little stateful machines that consumers take on the responsibility of executing, if unrealized
17:12bbloomthere is no rule that says the producer can't execute the machine a little bit before passing it along
17:13ToxicFrogRight.
17:13ToxicFrogWhich is exactly what's happening here: it's evaluating the first 32 elements before making the results of any of those evaluations available.
17:14bbloomright, and this issue is only visible b/c you're at the top level
17:14bbloomyou would be UNABLE to write the program you write using let, b/c let doesn't allow mutual recursion, so you'd need to use letfn
17:14bbloomor use mutation
17:15bbloomletfn would require you call () to dereference the function name
17:15bbloomwhich would create infinite recursion
17:15bbloomwhich is one of two possible outcomes in your (broken) program: infinite recursion, or incorrect termination
17:15bbloomyou got incorrect termination
17:15ToxicFrogIt seems that this should not create infinite recursion; it will eventually hit the base case (s[n] <= 3) and terminate correctly.
17:16bbloomToxicFrog: there exists some set of operation semantics for which your program will not create infinite recursion
17:16bbloom:-D
17:16bbloomdef's semantics are different than promises, are different than manual use of set! are different from function calls are different from deref calls
17:17ToxicFrogThat said, when I get home I'll rewrite this using function calls (and it won't infinitely recur)
17:17bbloomyeah, do that
17:17bbloomdef is mutation
17:17bbloomdeclare, def, def == 3 mutations
17:17bbloomletfn will give you observably simultaneous mutations
17:17ToxicFrogwait wait wait, where's the third def?
17:18bbloomdeclare, defn, def
17:18ToxicFrogAah.
17:18ToxicFrogI thought you meant three defs of tasty specifically.
17:18bbloomno
17:18bbloomletfn will make it seem like all those mutations happen simultaneously
17:18bbloomit acheives that by forcing an indirection on all definitions (that indirection is a function call)
17:18ToxicFrogAnyways, the main reason I wanted an infinite seq for this is that then it doesn't need to re-calculate earlier values repeatedly, which it will with fns.
17:19ToxicFrogI guess I could explicitly memoize.
17:19bbloomyou want to write a corecursive function :-)
17:19bbloomhttp://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/
17:20ToxicFrogI do, and thanks
17:21mmarczykToxicFrog: (defn unchunk [xs] (lazy-seq (cons (first xs) (unchunk (rest xs)))))
17:21bbloommy pleasure, explaining that helped me understand it too :-)
17:21ToxicFrogAlthough based on what just happened it seems like that definition of fib should explode if chunking happens to occur, so either the example is bad or I still don't understand what's going on :(
17:21mmarczykToxicFrog: if you wrap (range) in unchunk, result will be as you expect
17:21bbloomthat's why i hang out here. teaching is a great way to learn!
17:21mmarczyknot that it answers all the points raised
17:22ToxicFrogAnyways, tests run, CLs out for review, to the bus!
17:22bbloommmarczyk: you're the rrb guy, right? awesomeness! just studied that a bit yesterday
17:22mmarczykbbloom: wow, cool :-)
17:23bbloommmarczyk: just so i understand correctly… this would enable vectors to have efficient push/pop on both sides?
17:23mmarczykbbloom: right
17:23mmarczykbbloom: although I should say, regular conj (at end) will still be the "natural", fast, zero-cost option
17:23bbloommmarczyk: right b/c you pay some extra cost on the left, but only if you use left push/pop, right?
17:24mmarczykbbloom: whereas conj to front has a certain cost attached in that you'll end up with a less regular tree
17:24mmarczykbbloom: right
17:24bbloomso i read the abstract, but didn't really dig into the paper
17:24bbloombasically reading/writing to the left (or middle, or splitting, whatever) will somehow manage to preserve amortized costs?
17:24mmarczykbbloom: one of the things I've got on the roadmap is making it so the "new" ops
17:24bbloomie i can't like perma-fuck-up my vectors?
17:24mmarczykbbloom: do a little bit of extra work to try and return regular trees whenever possible
17:25noncom|2hi, i am writing a thin wrapper for a java lib and i find myself thin-wrapping lots of getters and setters. Id it okay that all setters names are with exclamation marks? An how do you usually go about naming getters?
17:25mmarczykbbloom: basically there's a limit to how much "damage" there can be, yes
17:25bbloommmarczyk: and even with that damage, the constant factors should beat 2-3 finger trees?
17:26mmarczykbbloom: oh absolutely
17:26bbloomkiller.
17:26mmarczykbbloom: shouldn't be slower by more than a factor of 2
17:26mmarczykbbloom: paper indicates less
17:27mmarczykbbloom: actually there's a tradeoff here between concat speed and loss of lookup (etc.) speed
17:27bbloommmarczyk: https://github.com/brandonbloom/fipp/issues/6
17:27mmarczykbbloom: a regular vector is a tree whose shape is completely determined by the lookup algorithm, with the minor tweak of having a separate tail
17:28mmarczykbbloom: wow, great! thanks for the link
17:28bbloommmarczyk: i only need left/right push/pop
17:28mmarczykbbloom: I've been chatting with Jozef Wagner lately
17:28bbloommmarczyk: don't need to thank me. thank you for creating cool stuff
17:29lpetitHello, any adventurous Counterclockwise user, willing to give feedback on a new feature I've been developing recently?
17:30bbloommmarczyk: i don't know Jozef Wagner
17:30mmarczykbbloom: heh, I'm rather a fun of fipp and sort of wanted to write factjor myself, so glad to be reciprocally useful :-)
17:30mmarczykbbloom: he's been benchmarking cljs recently
17:30bbloommmarczyk: oh cool
17:30mmarczykbbloom: there's a thread on the mailing list
17:31mmarczykbbloom: also, there's a ticket of his in cljs jira re: arrayvectors
17:31bbloommmarczyk: fipp and factjor are both part of my master plan… mwahaha
17:31mmarczykbbloom: so he's done some benchmarking with 2-3 finger trees
17:31mmarczykbbloom: I imagine they would be :-)
17:31mmarczykbbloom: and apparently there's no contest
17:32mmarczykbbloom: in fact, funny thing, core.rrb-vector is faster for conj than PV in cljs (so I'll be fixing PV in near future :-P)
17:32bbloommmarczyk: killer.
17:32mmarczykbbloom: that's without any unbalanced trees, but the cost in that should be a small constant factor
17:32bbloommmarczyk: if jonase doesn't take a try for rrb in fipp, i'll do it
17:32mmarczykbbloom: fantastic! also very happy to cooperate on this
17:33lpetitmmarczyk: do you envision a point in time where rrb could replace PV in clojure proper?
17:33bbloommmarczyk: after that, i need to port to cljs and explore reducers vs core.async on cljs side b/c i've got a core.async branch that makes fipp multithreaded :-)
17:33mmarczykbbloom: I've noticed the c.async branch, very cool :-)
17:33bbloombut the ioc threads variant on jvm is much slower than the reducers variant
17:33mmarczyklpetit: that's possible, but actually getting comparable perf in pure Clojure is a bit of a research project ATM
17:34mmarczyklpetit: part of the purpose of core.rrb-vector is to do that research, I think
17:34lpetitmmarczyk: okay. What's the gross constant difference for usual usages?
17:34bbloommmarczyk: you mean compared to the java implementation of PV, right?
17:34mmarczykbbloom: right
17:34bbloommmarczyk: so gvec is slower than APersistentVector
17:34mmarczykbbloom: it is
17:35mmarczykbbloom: lpetit: by about a factor of 2 IIRC
17:35bbloommmarczyk: but if you can get gvec == APV, then you can get RBB == APV ?
17:35mmarczykbbloom: lpetit: core.rrb-vector is on a par with gvec, with an important caveat
17:35lpetitmmarczyk: I must confess I don't know much about gvec
17:35mmarczykbbloom: lpetit: the caveat is that that's only true as long as you only use rrb vectors of objects or rrb vectors of primitives, not mixed
17:36mmarczykbbloom: lpetit: I'm going to fix this one way or another... my understanding of what's going on is a bit of a conjecture at this point anyway
17:36bbloomand on cljs, there is no host-native-impl, only the cljs-impl, so rrb can definitely == pv, right?
17:36mmarczykbbloom: lpetit: (but I'll take this opportunity to point out that jvm rrb vectors already support both objects and primitives at leaves and interoperate happily with both PV and gvec ;-))
17:36mmarczykbbloom: right
17:36bbloomglorious
17:36bbloommmarczyk: great work man
17:36mmarczykbbloom: or at least with a very small extra overhead
17:36bbloomlooking forward to developments. i'll let you know if/when i switch fipp over
17:37mmarczykbbloom: well the idea and feasibility research is due to Bagwell & Rompf
17:37mmarczykbbloom: I totally think they've done a great job :-)
17:37bbloomof course. can't forget to thank the smarty pants dudes who write the papers
17:37mmarczyk:-)
17:37bbloomi'm always glad to see citations in readmes
17:37bbloomi try to make it a habit
17:38lpetitmmarczyk: impressive
17:39mmarczykbbloom: lpetit: it's important to note that in contrast to regular vectors, rrb trees' tree shape is not fully determined
17:39mmarczykbbloom: lpetit: so there's room for tweaking concat speed vs. lookup & Co. speed
17:39bbloommmarczyk: which is also in contrast to 2-3 trees, too...
17:39mmarczykbbloom: right
17:40mmarczykbbloom: lpetit: my plan is to do some extra work in slice/concat to preserve regular tree shape whenever possible (or very nearly so)
17:40bbloomif i only need left/right push/pop, can i do better than arbitrary splicing?
17:40mmarczykbbloom: ah, so that's something which I'm planning to work on in near future
17:40lpetitmmarczyk, bbloom : you guys seem to know your stuff, I'm a bit lost. Anyway, that's what I like about this community, so much more to learn!
17:40bbloomlpetit: i didn't know SHIT about this < 1 year ago
17:41mmarczykbbloom: direct impls of "prepend", "insert-at", "remove slice"
17:41bbloomlpetit: http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki
17:41mmarczykbbloom: I'm totally in the market for good names for these functions, by the way
17:41bbloomstart with Okasaki, then go to that thread :-)
17:41callenlpetit: yeah, Okasaki is the place to start.
17:41mmarczykbbloom: hah! that's my favourite stack exchange thread ever :-)
17:41callenlpetit: you can derive the essentials yourself if you try to figure out how to make efficient immutable data structures without tons of copying.
17:41arrdembbloom: that's an awesome thread
17:41lpetitbbloom: I had started once, but not knowing Standard ML was really slowing me down
17:41bbloommmarczyk: i often write conjX functions for fnil things, like (def conjs (fnil conj #{}))
17:42bbloommmarczyk: but left/right/push/pop would be nice to have very clearly
17:42mmarczyklpetit: "I'm lost", says the a guy who built complex systems in assembly :-)
17:42bbloomhaha
17:42bbloommmarczyk: may i suggest left/right, prepend, and append?
17:42mmarczykbbloom: yeah, I'd sort of like to have standardized names for these
17:43bbloomright == fast last
17:43mmarczykbbloom: left/right access, prepend/append insertion?
17:43bbloomi guess left == first
17:43bbloomyeah
17:43bbloombut left/right as the protocol makes some sense
17:43noncom|2in clojure how do i know if a mapping is a (def) or (defn) ??
17:43lazybotnoncom|2: What are you, crazy? Of course not!
17:43mmarczykbbloom: yeah, sounds reasonable
17:43mmarczykbbloom: still good to brainstorm a bit
17:44mmarczykbbloom: also, I'd sort of like a standardized set of names
17:44nooniannoncom|2: defn is just sugar for def
17:44bbloomwell i guess there are THREE things you need
17:44mmarczykbbloom: for example there's a cool confluently persistent deque
17:44bbloompeek/pop/push
17:44bbloompeek/pop/push-left/right
17:44bbloomblargh.
17:44mmarczykbbloom: I think concat there is actually constant-time
17:44bbloomhaha
17:44mmarczyk:-)
17:44nooniannoncom|2: (defn my-fun [] ...) == (def my-fun (fn [] ...))
17:44bbloomill brb in a bit
17:44noncom|2noonian: yes, but maybe there is some simple way... like what is it bound to? like (instance? clojure.lang.IFn)...?
17:45mmarczykok, see you around
17:45mmarczykamalloy: do I understand correctly that you like recur-to? :-)
17:45bbloom+1 recur-to
17:45nooniannoncom|2: yeah, you could probably do (fn? my-fn) to test if its a function
17:45bbloomok going.. really..!
17:45noonian,(doc fn?)
17:45clojurebot"([x]); Returns true if x implements Fn, i.e. is an object created via fn."
17:46justin_smith,(doc ifn?)
17:46clojurebot"([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"
17:46noonianjustin_smith: nice, I didn't know about that
17:46noncom|2noonian: gonna try it now..
17:46noncom|2ifn seems wider than fn
17:47justin_smithyes, I use it to see if something can have an arg applied to it, basically
17:47noncom|2yeah
17:47noncom|2well, fn works for my case
17:47ToxicFrognoncom|2: yeah, IFn is basically "can be called like a function", which includes many things which are not actually functions.
17:48noncom|2i think this is very beautiful that we have both fn? and ifn?
17:48noncom|2and why we have them
17:48lpetitbbloom: ok, I need one or two sabbatical years, just to read&digest okasaki + the marvelous stack exchange link with tons of undecipherable names :-)
17:50mmarczyklpetit: bbloom: I'll add that IIRC slowdown with mixed object/primitive rrb vectors in single jvm image is ~3x compared to PV, ~1.5x compared to gvec; perhaps actually a bit less; that's with regular trees though, before concats
17:51mmarczykbut this should be fixable
17:52noncom|2in clojure, is there a function to execute a function?
17:52mmarczykif need be, I'll make it so different node types use different containing vector types -- actually I'll probably want to do the things required to make this less of a hassle for unrelated reasons
17:52noncom|2so that i can do like (-> f EXEC)
17:52noncom|2where f is fn
17:53noncom|2i mean defined with fn
17:53mmarczyknoncom|2: functions are callable, so you can say (.call f)
17:53mmarczyknoncom|2: there's also apply, but that requires a seq of args
17:53mmarczyknoncom|2: no "call" function, but you can write one: (defn call [f] (f))
17:53noncom|2so (-> f .call) does it!
17:53noncom|2i just checked
17:54noonianalso (apply f [])
17:54noncom|2yeah, cool!
17:54mmarczykyou can also say (f) ;-)
17:54noonianlol
17:54lpetitFirst version of Counterclockwise with "fix indentation as you type" feature is available in the "auto shift" branch
17:54lpetitUpdate Site : http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/
17:54noncom|2yeah, but my point was that i cant say (-> f ())
17:54lpetitStandalone apps: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/
17:55noncom|2although i remember i was in wonder a few times in the past when realized that all i need is (f) without complications :D
17:55mmarczyklpetit: awesome!
17:55lpetitmmarczyk: still very alpha. Feedback required !
17:56mmarczyklpetit: pulling ahead of Emacs in Clojure support feels vaguely indecent ;-)
17:56lpetit(the standalone version can be downloaded and discarded easily ;-) )
17:56noonianmmarczyk: what is?
17:56noncom|2lpetit: hi! is the option to enable full-blown leiningen available in the new builds?
17:57lpetitnoncom|2: no, I have split it into a branch, it was too unstable, and I needed more hammock time
17:57noncom|2okay! i'll be waiting :)
17:57mmarczyknoonian: ?
17:58noonianmmarczyk: what is ahead of emacs for clojure support?
17:58mmarczyknoonian: lpetit's Counterclockwise pulling ahead in this particular area
17:59noonianmmarczyk: ah, cool thanks
18:01lpetitThe first person to download and find a bug in the "fix indentation as you type" feature will get …. many thanks from me! ;-)
18:02lpetitStandalone version installs in a blink: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/
18:04lpetitmmarczyk: note, it's not just calling "reindent" on each line. It's shifting all children lines of the form being pushed to the right or the left while typing, plus all its right sibling forms, plus all the right sibling forms of the parent form if the parent form's tail has been shifted along the way, etc. until reaching a line which is not shifted
18:05lpetitmmarczyk: so this preserves, as much as possible, manual indentation such as in 'cond
18:07lpetitNext on the todo list: extend this behavior after paredit commands (so that e.g. "raise over" really works as expected), and also between copy/cut/pastes inside Eclipse (requires serializing the current "column" and not just the selected text)
18:08lpetitmmarczyk: I *think* this is doable in emacs, I've seen some options to do that. But Counterclockwise's advantage is that it works with a real parse-tree: multiline strings are handled correctly, for instance
18:09bbloomlpetit: everybody should take a 1 to 2 year sabbatical every 10 to 15 years :-) at minimum! it's good for you
18:09lpetitbbloom: sure! Let's save some money then …. ;-)
18:09bbloomworked for me :-)
18:10zerokarmaleftdoes core.async have anything like golang's panic?
18:11bbloomzerokarmaleft: both JVM and JS have exceptions
18:11bbloomzerokarmaleft: is there something particularly interesting about panic you're looking for?
18:11zerokarmaleftrather, does it facilitate looking at the state of the goroutines/blocks
18:12bbloomi believe the state is currently opaque, short of implementation details
18:12bbloomtbaldridge is the man to summon :-)
18:12zerokarmalefti.e. it's blocked waiting for a put! on such and such channel
18:14bbloomin general, you don't want to be able to query the state of channels or the little channel reading/writing machines
18:14bbloomdoing so can lead to race conditions
18:14bbloomnow, if i want it for debugging purposes, that's a different story
18:14zerokarmaleftthat's precisely where I was heading mentally
18:15zerokarmalefte.g. in a long-running app, how can I know whether or not I have a bunch of go blocks spinning b/c I forgot to clean them up properly
18:15bbloomi'd like to see some sort of tracing/logging functionality, but i don't think it makes sense to expose much else for prying into the internals
18:16zerokarmaleftand to debug deadlocks
18:16bbloommaybe some aggregate values, like metrics
18:16bbloomhttp://blog.golang.org/race-detector
18:16zerokarmaleftyea, something like that would be nice :D
18:16bbloomthe core.async announcement post expressed some interest in that sort of thing
18:26dfarmerHey all, I've got kind of silly practical question. Is there any way to turn off ANSI color in nrepl? I run 'lein repl' in an admittedly clunky term and every output line is preceded by "[14G[8G[15G, etc"
18:31lpetitDo you know a good resource to learn enough Standard ML to be able to read & understand the code examples in Okasaki?
18:32lpetitand/or to be able to quickly mount a dev environment to really "run" the examples? (emacs not an option : one "hill" at a time ;-))
18:33yogertHey, are there any Vim users here that could offer a beginner some help in getting situated with Clojure? : )
18:33yogertI've been finding a lot of conflicting instructions on the web regarding how to bet integrate the repls and such
18:34yogertbest integrate
18:35yogertno Vim users eh?
18:35futileused to be one
18:35futilebut i got tired of having to hit so many keys just to move up a line
18:36yogertHeh, well im not looking to argue about the merits of your favorite editor, I'm just looking to try out clojure
18:36futileah, misunderstood
18:37futileguys, how would you benchmark two different types of databases without writing your whole application in both?
18:37brehautyogert: im not a vim user, but i understand that integration is a bit in flux there
18:37brehautyogert: if you are just learning clojure, start with a lein repl and text editor seperately, rather than getting lost in an integration quagmire
18:38futileor just clojurebot
18:38brehautಠ_ಠ
18:38futile,(dotimes 3 [i] (println i))
18:38clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: dotimes requires a vector for its binding in sandbox:>
18:38futileoh
18:38brehauthow about a web based repl or private messaging the bot
18:39futilebut then how can we show him cool ways of doing the same thing?
18:39yogertok, I've never used a lisp before, but I've been told that integration with repls etc is a very attractive feature
18:39brehautyogert: certainy is nice
18:39yogertnot crucial tho?
18:39futile,(reduce + [1 2 3])
18:39clojurebot6
18:39brehautnot when you are starting out
18:40futileyogert: in terms of running programs, you can use clojure just like you use ruby
18:40brehautit makes you a lot more productive when you are already productive, but its just a side show to start with
18:40futileor whatever
18:40yogertok
18:41futile,(reduce + (take 3 (repeat 5)))
18:41clojurebot15
18:41brehautyogert: if you use a lein repl, you can easily (require 'my.namespace :reload) to relaod your code
18:41futilethats a shortcut for (* 3 5)
18:41brehaut:reload-all will also reload the dependancies too
18:41futileyogert: yeah just `lein repl` is fun too
18:42futile,(reduce + (take 3 (iterate 99 dec)))
18:42clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
18:42futileoops
18:42futile,(reduce - (take 3 (iterate dec 99)))
18:42clojurebot-96
18:42futileso confusing.
18:42yogertokay. I should watch some videos or something demonstrating the repl integration. I honestly don't have a clue what it is exactly, just that it is great. Is the repl itself any different than GHCI or Python's?
18:42futileyogert: same as python's
18:43futileyogert: install leiningen (via homebrew or whatever) and type `lein repl` and then type (+ 1 2) in it
18:43brehautNot via homebrew
18:43yogertjust that its in your editor...
18:43futilebrehaut: why not?
18:43yogertnot via homebrew?
18:43yogerti already did
18:43yogert
18:43futileyogert: i did too, no harm in it
18:43yogertosx package management sucks
18:43brehautideally you just grab the version from the lein website
18:44futilebrehaut: thats what they all say.
18:44brehautyou dont need to package manage lein because it doesnt install globally
18:44futile(inc homebrew)
18:44lazybot⇒ 1
18:44brehautlein manages its own updates
18:44futilebrehaut: homebrew isnt about globally or not.
18:44futilebrehaut: homebrew is about me not having to type boring crap in the terminal :)
18:44justin_smithhomebrew stinks
18:44futileliterally just `brew install leiningen` and im done.
18:44futile(or is it lein?)
18:44futilejustin_smith: whats with the homebrew hate today?
18:45brehautfutile: stop talking out your arse; lein is simple to install without a package manager
18:45futilebrehaut: yeah it is simple. you're right about that.
18:45futilebut its even simpler with homebrew.
18:45justin_smithit is literally one file, homebrew makes it MORE complicated
18:45justin_smithas usual for homebrew
18:45futilejustin_smith: it may complicate HOW its done, but not WHAT i do to install it
18:46brehautfutile: ease vs simplicity
18:46futilebrehaut: yep
18:46brehautartificial ease now that sacrificies simplicity is asking for problems later
18:46futileand in this case i like easy better.
18:46justin_smithcompare: create ~/bin/lein vs. install homebrew and brew install $(lein || leiningen whichever works)
18:47futilejustin_smith: `brew install leiningen` and im done. to create ~/bin/lein i need to open Chrome and go find the dang file
18:47futilethen i need to download it. how? curl, wget, or just use my browser?
18:47futilethen i have to move it.
18:47justin_smithand then deal with brew when you want to update lein (vs. just letting lein autoupdate)
18:47futileman, just `brew install leiningen`
18:47futilejustin_smith: not true. itll update all the same
18:48justin_smithnope, it fucked up my coworker's install, in the middle of a workshop he was trying to run
18:48futilejustin_smith: all `brew install leiningen` does is downloads the same trampoline file that you would normally download manually, and puts it somewhere on your path for you
18:48justin_smithbrew is a mess, and you don't need it for something as simple as lein
18:48futileoh come on, you dont have to go making everyone leave irc just cuz you disagree with me
18:49futile;)
18:49noonianhomebrew may be a mess, but not using it on a mac is even messier in my experience
18:49futile(inc noonian)
18:49lazybot⇒ 1
18:50justin_smithnoonian: my solution was to stop using my mac, and getting a system76 box
18:50bbloomjustin_smith: all package managers are a mess, but brew is 100X more pleasant than any other mac package manager i have ever encountered
18:50bbloomit's perfect for "eh, i just want to try it real quick"
18:50futile(inc bbloom)
18:50lazybot⇒ 10
18:50noonianjustin_smith: I'd just get a thinkpad but I need a mac for iOS stuff
18:50futileglad im not the only one who's perfectly ok with homebrew
18:51justin_smithnoonian: I have a mac sitting on my desk, work gave it to me, I open the lid about once a week
18:51futileok looks like i cant upgrade leiningen via homebrew.
18:51futilethat does suck.
18:51bbloomall the other package managers should take a lesson from homebrew on how to run a project tho
18:51bbloomholy hell those guys rock
18:51bbloom`brew edit foo` is trivial & pleasant
18:51justin_smithand a big part of that reason is there is no non-shit package manager under macos
18:51bbloomand they homebrew ppl are extremely responsive to tickets
18:51bbloom`brew doctor` works magic
18:51bbloomit's a damn well run project
18:52bbloomthey have all kinda of auto-build, CI github bot voodoo too
18:52technomancyhomebrew's quality control leaves a lot to be desired
18:52justin_smithmy biggest problem with brew is /usr/local is MINE and no system tool should fucking touch it, ever
18:52justin_smithpisses me off
18:52clojurebotGabh mo leithscéal?
18:52callentechnomancy: they don't have any
18:52futilejustin_smith: ah, you're a linux user.
18:52futileim not.
18:52callenthey just axe bad formulae occasionally, that's it.
18:52technomancythat said, using a computer without a package manager is madness
18:52futilei mean in spirit of course
18:53callenfutile: Macs have a /usr/local too.
18:53callenfutile: which is what homebrew runs on. Macintoshes.
18:53futilecallen: thanks for the reminder
18:53justin_smithfutile: switched back to linux, mainly because I missed package management
18:53justin_smithI have an unused osx machine sitting right here
18:53technomancyclojurebot: macports?
18:53clojurebotmacports is not a package manager, it's a satire about package management.
18:53arrdemtechnomancy: TIL windows is sparta.
18:53bbloomlol.
18:53technomancyclojurebot: botsnack
18:53callentechnomancy: aye.
18:53clojurebotThanks! Can I have chocolate next time
18:54futileits probably not perfectly accurate, but people who get upset with mac stuff often closely resemble http://imgs.xkcd.com/comics/command_line_fu.png
18:55brehautjust what we need; more broad sweeping insults based on operating system choice. high five ◔_◔
18:55bbloomnot to start an OS war, but i've never seen anyone succeed w/ linux+projector on the first try before
18:56bbloomsoftware sucks.
18:56bbloomnext topic!
18:56brehautbbloom: operating systems are about as shit as text editors and command shells
18:56arrdembbloom: .. this is a software channel
18:56futileyeah, i basically hate all software.
18:56arrdembbloom: and yes I have succeeded with a projector on the first shot before
18:56futilebut when i can repress it for a period, i dont mind most of it.
18:56isaacbwwoo, koans complete
18:57isaacbwI don't feel enlightened, lol
18:57bbloomfutile: knowing when and for how long to hold your nose is a key skill for programmers
18:57futilemy colleague switched to linux for a year or so, and literally switched back to mac because of a projector problem during a talk at a user group or conference, i forget which.
18:57futilebbloom: +1
18:57jkjjust know your xrandr :P
18:58arrdem(inc jkj)
18:58lazybot⇒ 1
18:58isaacbwubuntu could probably use a projector plug n play
18:58arrdemisaacbw: you would think that, wouldn't you.
18:59arrdemisaacbw: as with most things ubuntu it works 85% of the time right off, but when it doesn't you're in deep
18:59technomancyseriously though, the whole editing x.org config files stereotype is so 2007
18:59isaacbwI'm not an ubuntu user, but as far as linux goes it's the closest to a "just works" experience
19:00arrdemisaacbw: understood and agreed, I'm just making the point that there really is no such thing as "just works"
19:00arrdemas far as the linux world goes at least.
19:01noonianI would prefer to use linux, but it always takes me a week at least to get a proper setup when I want to get a linux box working and configured to be productive with
19:01technomancy"just works" just comes down to "spend a bit of time researching before you buy"
19:02brehauttechnomancy: yeah; i researched and came back with a mac and virtual box ;)
19:04arrdemhum.. anyone have a better DSL design than this? the general case of an ASM op is ["ADD" "EAX" "EDX"] or some such, but this gets funky when you want to use inline constants or chase pointers because you wind up with modifiers on the operands.
19:04arrdemThe current fix is that modifiers are macros, so you pre-expand the operand into its encoding
19:04callenas an XMonad user, things like projectors emphatically DO NOT just work.
19:05technomancycallen: I don't think xmonad has anything to do with that
19:05jkjmy solution before mac was Arch Linux. just the eeepc i was running it on was quite horrid. never got used to the keyboard and it had just 1GB of mem.
19:05technomancyit's just a matter of knowing which brands of video card to avoid
19:06jkjand do think xmonad doesn't get on your way with projectors as long as you are willing to xrandr yourself
19:06arrdembut that means you loose data about your instruction sequence at read time, making any subsequent (prints) or other inspection less meaningfull/symbolic
19:06technomancyjkj: that hasn't been my experience; on debian and ubuntu you just plug it in and it rearranges everything
19:07technomancyit's probably more complicated on arch; archies love to make things complicated
19:07arrdemtechnomancy: ah but at least our complicated has good wiki manuals and flat text file configs!
19:07jkjappreciating my mac now
19:08jkjbut i actually liked arch. it was easy in the form of not having intrusive automation that just tries to work but ends up doing something stupid
19:09noonianthats how I felt after trying to get my Arch UI setup to work on Ubuntu
19:10justin_smithregarding linux and "just works", best to compare apples to apples (so to speak) - get a linux box, built to run linux with a distro pre-configured by the manufacturer
19:11justin_smithI mean imagine judging macos based on hackintosh
19:11seangrovenrepl really does seem nice
19:12seangroveI was skeptical it would be better than swank/slime, but having multiple repls, one evaling in clojure, the other in the browser, and having them communicate and seamlessly update defs... very nice
19:12RaynesAnd being able to make use of it from vim with reasonable ease is useful as well
19:13teit has continued to get better
19:13seangroveRaynes: good point
19:13tei was skeptical too and dragged my feet for awhile
19:13brehautseangrove: isnt the canonical spec for swank 'whatever the head of cvs currently does'? its not too surprising that nrepl is better than that ;)
19:13technomancyit's still missing a bunch of stuff; hopefully now that nrepl.el is maintained we can move forward with new features via nrepl-discover
19:14technomancy(inspector, tracing, etc)
19:14jkjarrdem: have you tried just having ops be funs/macros themselves?
19:14jkj(asm/add :eax [:edx])
19:14jkjarrdem: which cpu or generic?
19:17callentechnomancy: I can't even get YourKit or jvisualvm to work in Xmonad.
19:18callentechnomancy: attaching an external display upsets Xmonad sometimes, it's usually otherwise multi-display friendly.
19:18futilexmonad was the one thing i liked about linux
19:18futileso i wrote a kind-of port for mac
19:18futilei mean, i tried to hit the right balance between what xmonad is and what mac allows
19:19futileanyone want a binary of it? im handing them out for free.
19:19jkjfutile: sure!
19:19futilehold on, let me strip out the licensing code
19:24futilesweet, it still builds
19:25pcarrieris there a pmap with custom parallelization factor?
19:28futilejkj: ok https://www.dropbox.com/s/8dzp2irtn8ssuvy/AppGrid.zip
19:28futilejkj: if it doesnt load, let me know. code signing certificate crap sometimes pretends to work for me but not for others.
19:30Deranderfor anyone who remembers the moron trying to shuffle vast quantities of shit through clojure yesterday: it seems like java actually is fast enough for it
19:30Deranderdecided to implement in java in the name of stack homogeneity and it's shuffling along pretty close to as fast as gnu awk
19:30Derander(aka roughly 50x as fast as clojure)
19:30Deranderthis implies (to me) that I was probably doing something wrong.
19:31jkjfutile: fuking splendid!
19:31futilejkj: thx
19:31futilejkj: i have a custom build that lets me attach random keyboard shortcuts to shell commands and stuff, but it needs polishing up. interested?
19:31futilebtw, if anyone else wants to use this app, let me know and ill give you a link
19:32jkjfutile: yes, very
19:32futilei think its jkj-approved
19:32futilejkj: actually do you just want the fully scriptable one?
19:32futileits scriptable via JS (or coffeescript)
19:33futilei hate it cuz im getting tired of scripting everything.
19:33futilei want my computer to just think for me.
19:33jkjfutile: sure. don't mind testing either
19:34futilejkj: https://github.com/evanescence/zephyros
19:35futileim thinking of ripping out all the scripting though. only like 5 people ever liked it.
19:35futilenot that it costs me anything to keep it, but, its just like, whats the point if only 5 people use it?
19:35futilei dunno anymore.
19:43brehautfutile: are you taking credit for zephros?
19:43futilebrehaut: yeah, i wrote it
19:43brehautnot matt gemmell?
19:43futilenot him.
19:43futilei think i caused too much confusion by asking him to house it for me
19:44futilei think ill just ask for it back.
19:46callenfutile: you hadn't mentioned you were a cocoa dev.
19:46futilecallen: you told me not to talk about myself!
19:46futile(over and over again)
19:47callenUsually it's blubbery self-deprecation or personal stuff. Talking about one's work is another matter.
19:48futilecallen: noted
19:49rebcabin,'(reduce 'or (list true false))
19:49clojurebot(reduce (quote or) (list true false))
19:50rebcabin,(reduce 'or (list true false))
19:50clojurebotfalse
19:50arrdemjkj: right now it's for platform specific assemblers
19:51arrdemthe hope is to build a macro abstraction atop them that's portable
19:51rebcabin,(reduce 'and (list true false))
19:51clojurebotfalse
19:51amalloyrebcabin: 'or and 'and are symbols, not functions
19:51arrdemjkj: as to making the notation fns or macros in itself I think that's the approach I settled on while driving home.
19:52amalloysymbols happen to also be callable as functions, but they don't do anything like what you're hoping
19:52rebcabindarn :)
19:53rebcabini just saw someone in a video do this, and i didn't believe it then :)
19:53rebcabinvideo is by tmarble at linux australia
19:54nooniandid it work in the video?
19:54rebcabinhe does (reduce 'or (map even? '(1 2 3 4 5))) and purports that it works :)
19:54noonian,(reduce and (list true false)))
19:54clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>
19:54noonian,(reduce and (list true false))
19:54clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>
19:54rebcabin,(reduce 'or (map even? '(1 2 3 4 5)))
19:54clojurebotfalse
19:55noonianah
19:55rebcabinso dunno might have been some earlier version of Clojure or a jacked version
19:55noonian,(ifn? 'foo)
19:55arrdem,(type and)
19:55clojurebottrue
19:55clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>
19:55rebcabinhttp://www.youtube.com/watch?v=ii-ajztxALM
19:55noonian,(type or)
19:55clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(NO_SOURCE_PATH:0:0)>
19:55rebcabinaround 36:36
19:56clojurenewbRaynes: hi do you have time for a laser question ?
19:57rebcabinhe's using emacs org-mode in his video, and runs other things in the live repl -- but this one he just has a repo transcript
19:57alexgunnarsonare we talking about las3r or laser?
19:57jkjfutile: thank you for the software. you got me hooked. these are features mac os x is really missing
19:57futilejkj: appreciated
19:57futileim getting some more apps out in a second
19:57futilejust cleaning it up
19:58clojurenewbalexgunnarson: laser as far as I know
19:58alexgunnarsonclojurenewb: okay
19:58futileok, anyone else want an xmonad-like app for Mac OS X? last chance.
19:58clojurenewbnow I am intrigued by what las3r is
19:58rebcabini like monads :)
19:59jkjfutile: everybody needs it, but not many know they do i quess :)
19:59callenfutile: sizeup is fine.
19:59bbloomi prefer monoids
19:59futilecallen: if you say so
19:59futilejkj: thats how i felt. i avoided sizeup/divvy/etc for a long time.
20:00rebcabinsize up is great; "optimal layout" is pretty good too
20:00futileturns out, it wasnt the idea i was against, but their execution
20:00alexgunnarsonclojurenewb: las3r is basically a clojure interface/wrapper for actionscript/flash
20:00futilei like AppGrid because its "composable".
20:00futileyou just remember a few key commands, and you can do a whole lot with them
20:00alexgunnarsonclojurenewb: it's cool but even though i love flash functionality i just hate flash player…
20:00rebcabini'll take a look at app grid -- can you tell us about monad, futile?
20:01rebcabinxmonad rather
20:01noonianfutile: I'll probably checkout out zephyros when I have the time
20:01clojurenewbalexgunnarson: yeah I don't like proprietary plugins at all really
20:01rebcabinsomething is helping my spelling i want to turn it off!
20:01alexgunnarsonclojurenewb: me neither
20:01futileAppGrid is just Zephyros with a hard-coded config, so you dont have to write one
20:02futilei personally dont wanna write 100 lines of CoffeeScript (or JS) to configure a wm
20:02futileand i know some people who feel the same
20:02futilebut i also know some people who love tinkering
20:02futilerebcabin: xmonad is a dead-simple tiling window manager for linux.
20:02noonianfutile: has anyone got zephyros working with clojurescript?
20:02futilenoonian: i tried really hard for like 2 hours, couldnt figure it out
20:02futileplease be the first :)
20:03noonianfutile: heh, I'll probably give it a shot but it took me a while getting it working in a simple clojure webapp so no promises :P
20:03futileoh nevermind then
20:03futileits not a high priority
20:03futilejust would be really cool
20:03noonianyeah
20:03futilepossibly not even that practical
20:03rebcabinanything that saves me a trip to the mouse is a win
20:04futilehere's the source to AppGrid if you want: https://github.com/evanescence/grs
20:04futile\cc jkj
20:06alexgunnarsonhey everyone - so i'm considering developing a clojure app. obviously i'd like it to be write-once-deploy-everywhere but there's no "silver bullet" in terms of platform/VM/whatever for it to be deployed on. between Clojure+JVM+JavaFX, Clojure+Flex+AIR+Flash Player, and ClojureScript+Pedestal+HTML5+CSS, I'm not really sure where to go.
20:07alexgunnarsoneveryone thinks HTML5 is the future of everything but it's way behind flash and java libraries in terms of functionality
20:07futilealexgunnarson: i personally just use Clojure + HTML (via Hiccup lib) + CSS (via Garden lib) + JS (via ClojurScript) and dont care how it runs, just using lein-ring
20:07alexgunnarsonand plus the HTML5 specs haven't even been hammered out yet
20:07futilealexgunnarson: yeah but there are other priorities besides just functionality. like searchability and runnability
20:07jkjAppGrid is probably better for most users as it makes a statement how things should work and is self documenting
20:08noonianI'm using Clojure for the backend and HTML5 + javascript on the frontend using handlebars for templating. Wasn't ready to commit to ClojureScript
20:08alexgunnarsonwell of course i would do a website with clojurescript + HTML5
20:08futilejkj: i agree. some people find it too limiting but i think its just what most people really want even if they dont know it yet
20:08alexgunnarsonbut an RIA? clojurescript is not quite what i want...
20:09alexgunnarsonfutile: lein-ring does what again? async?
20:09jkjfutile: maybe zephyros could also preconfigure itself to resemble AppGrid and have some presets bundled?
20:09futilealexgunnarson: magically runs your ring app for you. ring is a web server type thing.
20:09jkjnot it's bound to repel some people as it requires configuration (minimal though) out of the box
20:09alexgunnarsonoh. okay that makes sense
20:09futilewell, its a spec really, i think. lein-ring uses jetty by default.
20:10futilejkj: i think even with a preconfiguration, its way too scary for most people.
20:10jkjfutile: true
20:10futilejkj: even if it comes with its own zephyros.coffee file, itll still be like 80 lines
20:10futilejkj: i have another idea.
20:10alexgunnarsonwhat's the idea?
20:11futilejkj: i was thinking of a middle-ground between zephyros and appgrid, where you can configure it within the app, using a custom interface
20:11futilejkj: it obviously wouldnt be as flexible as straight-up JS would be, but more flexible than appgrid.
20:11futilejkj: then every type of user could use it.
20:11futilei mean, there would be options for everyone.
20:11alexgunnarsonwell i'm not looking for an out-of-the-box thing necessarily… i'm willing to put up with coding hell
20:11jkjfutile: true
20:11bttfi wrote a private function in my ring app that gets called by one of my handler functions ...the handler fn and private fn are in the same ns, but im getting errors at compile time
20:11alexgunnarsonjust as long as it gets easier
20:12futilealexgunnarson: sorry, this is off topic and its probably confusing you.
20:12bttferros about so-and-so not a public function
20:12futilejkj: if you want to keep chatting about it feel free to come to #zephyros
20:12bttfwots the deal
20:12alexgunnarsonfutile: i'm not much of a server genius really
20:12futilealexgunnarson: sorry, those were two different conversations.
20:12alexgunnarsonfutile: ah okay
20:13futilealexgunnarson: ok about lein-ring. basically you just install lein-ring and it runs your Clojure web app for you.
20:13futilealexgunnarson: you wont have to deal with how it does it, it just does it.
20:13futilealexgunnarson: its really handy. https://github.com/weavejester/lein-ring
20:13alexgunnarsonfutile: that sounds awesome
20:14alexgunnarsonfutile: but i'm not really looking to run something in a browser… it'll be an app really
20:14jkjarrdem: do you have some intermedia presentation for the ops behind the notation?
20:14alexgunnarsonfutile: it might theoretically have some sort of limited functionality able to run in a browser, but that wouldn't be the focus
20:15futilealexgunnarson: it wouldnt run in the browser
20:15futilealexgunnarson: are you familiar with Rails?
20:16alexgunnarsonfutile: so when you say web app you don't mean SaaS you mean like an app that uses the web like a social app or a weather app
20:16alexgunnarsonfutile: not too familiar, no
20:16futilealexgunnarson: what are you familiar with?
20:16alexgunnarsonfutile: not very much - pretty much java and scheme… i'm still making inroads into clojure
20:17futilealexgunnarson: have you ever written any kind of website, like php or anything else?
20:17alexgunnarsonfutile: yes but i did the frontend only
20:17alexgunnarsonfutile: i never set up any servers or really messed around with the back-end
20:17futilealexgunnarson: oh. i ee.
20:17futilealexgunnarson: yeah im not sure what a good way to get started with doing that in Clojure would be.
20:17futilealexgunnarson: i would almost recommend getting your feet wet with Ruby on Rails
20:18alexgunnarsonfutile: why is that?
20:18futilealexgunnarson: pretty much every lib ive seen for clojure assumes you know all about that kind of thing.
20:19futilealexgunnarson: so html-generating libs assume you know all about html, etc
20:19alexgunnarsonfutile: well i know some HTML, CSS, etc. but i'm no expert yet
20:19futilealexgunnarson: if you arent super familiar with how http works, ring and compojure might seem a little confusing
20:19alexgunnarsonfutile: i'm really trying to determine the direction i want to go in so i can dive in to whatever solution is best
20:20futilealexgunnarson: ah. sorry, i got off topic again
20:20alexgunnarsonsorry i've gotta go but keep me updated
20:20futileuhh
20:20futileok?
20:20clojurebotgrok is a little hard to juxt but it's the best thing ever
20:20alexgunnarsonbye :/
20:20futilebye
20:47callenalexkira: if you want to do a web app you might want to look at Luminus.
20:49callener
20:49callengod dammit.
21:27yedibest way to use bcrypt from clojure?
21:28yedinvm
21:33yedican someone help me understand this line: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/signup_and_redirect.clj#L77 (specifically: `{{:keys [username password confirm] :as params} :params :as req`})
21:34yedii know it sets those vars to the corresponding keys in (:params req), but how exactly does the :as work
21:38`cbpDoes anyone have a link to that blogpost "understanding clojure's persistent vector implementation", I can't seem to find it anywhere nor can I remember the author :-P
21:42`cbpyedi, it's destructuring a map that has a shape like {:params {:username "foo" :password "bar" :confirm "baz"}}
21:42`cbp:as binds the whole map
21:43`cbp,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c r])
21:43clojurebot[1 2 3 {:p {:a 1, :c 3, :b 2}}]
21:45`cbp,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c p r])
21:45clojurebot[1 2 3 {:a 1, :c 3, :b 2} {:p {:a 1, :c 3, :b 2}}]
22:54futilequiet night
22:56brehautafternoon talios
22:56taliosoh hai
22:56brehauthows north of the hills
22:57taliosgrey, threatening rain
22:57brehautlikewise
23:01yediwhy is the=is bcrypt fn returning different values after hashing the same thing? https://gist.github.com/yedi/9f219c53d6e5db95519c
23:01futilei think Clojure cant be appreciated fully until you first know C
23:02futileyedi: im guessing its using an algorithm that adds some randomization
23:03callenyedi: that's what makes bcrypt useful dude
23:03callenyedi: you can't store passwords with something that lets you precompute the value->hash relationship.
23:05yediwait what? then how do you expect to do equivalence testing for passwords / auth when someone logs in? i though the whole point of a hashing function was quick deterministic 1 way hashing
23:06callenit's not that simple.
23:06callenyedi: http://codahale.com/how-to-safely-store-a-password/
23:06callendo NOT use generic hash algorithms for storing passwords.
23:06callenUse scrypt, bcrypt, or PBKDF2
23:07TimMcAw, I missed all the fun?
23:16yediok, so callen, how do you test that a password is equivalent to a bcrypt hash? im just confused about that part
23:20bbloomyedi: normally, i'm all for teaching stuff and letting people make mistakes while they learn.. but security, and cryptography in general, is a different story: let somebody who knows that they are doing do it. use a well tested library for this! and if you do want to learn, then there are LOTS of good articles about this topic, b/c it's something people get wrong A LOT
23:21bbloomyedi: with that disclaimer out of the way...
23:21bbloomthere are different hash functions for different use cases
23:21bbloomyou don't want password hash functions to be super fast
23:22bbloomif you are trying to hash a lot of files for bulk equality testing later, then yeah! go w/ the fastest hash that fits your other needs
23:22bbloombut don't do that for passwords :-P
23:22bbloomb/c the only person bulk-testing passwords, are hackers
23:22bbloomif a user needs to wait an extra 1 to 100ms to login, that's no big deal b/c they do that so infrequently
23:23yediok yea i get it, but i just want to get bcrypt to work for my authenticate users function. I don't conceptually understand how to test for password = hash equality if bcrypt hashing isn't deterministic.
23:23yedibrb wiki
23:25seangroveIs bcrypt non-deterministic?
23:26brehautits probably doing something like salting the phrase
23:26brehautbut its consistently slow
23:26seangroveAh, yes
23:26yedihttps://gist.github.com/yedi/9f219c53d6e5db95519c -- yea i feel like i'm missing something really dumb
23:26bbloomi am NOT AN EXPERT, but iirc, it's intentionally non-deterministic
23:26bbloomand you have to run a number of iterations
23:27bbloomand statistically, you'll get a matching hash eventually
23:27callenyedi: don't use friend
23:27bbloombut the number of iterations determines how slow it is
23:27callenyedi: understand what you're using.
23:27callenif bcrypt had predictable output for a given input, it wouldn't be useful.
23:27futilei just use openid and let google deal with it
23:28bbloomfutile: i have fixed so many openid implementations, it's not even funny
23:28seangrovebbloom: Makes sense
23:28bbloomthe 3 leg thing or whatever, people fuck up 2.5 legs of it :-P
23:28futilebbloom: yeah. im sure ive messed it up too.
23:28futilewe all do.
23:28futileno such thing as security, amirite?
23:28brehautyedi: im pretty sure you want to use bcrypt-verify to compare a password to a hashed password btw
23:29brehautoh, my bad. the docs explicitly say to use bcyrpt-credential-fn; bcrypt-verify is just an implementation detail
23:30brehautyedi: cryptography lesson one: read the docs on the library you are using ;)
23:31bbloomlesson 2: don't do it yourself :-P
23:31bbloomit's at least NON_DETERMINISTIC -ly harder than concurrency :-P
23:31brehautbbloom: maybe these lessons are out of order
23:32yedibbloom: know of a good library for it?
23:32yediand ok, thanks guys
23:32bbloom*shrug*
23:32brehautyedi: well, friend for http authentication. the stuff you linked to is already wrapping up all the internals
23:33zRecursive,(sqrt 10000000000)
23:33clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sqrt in this context, compiling:(NO_SOURCE_PATH:0:0)>
23:33callenyedi: I generally advise people against Friend unless they know pretty far ahead what they need and want.
23:34brehautyedi: btw, i think cemerick has a clojure-sec mailinglist somewhere in the depths of google groups
23:35yedicallen: is there something you'd suggest instead? for like a user management system in a webstore
23:35callenyedi: if it's a simple web app, just use bcrypt and a secure cookie store for sessions.
23:36brehautor, if you arent planning to use https, just dont even both with passwords
23:36callenyou'll spend more time fighting Friend than writing your web app if you're not building something big/elaborate with a lot of auth-flow corner-cases and don't know what you're doing all that well.
23:36brehauts/both/bother/
23:36callenClojure noobies trying to make a web app should almost never be using Friend unless they're participating in a large enterprise migration project.
23:37callenhow you poor bastards end up on Chas's doorstep I'll never know.
23:39callenyedi: actually yeah I'd like to know, what made you try to use Friend?
23:44TimMcbbloom: What's this about bcrypt being non-deterministic?
23:44TimMcThat sounds entirely wrong.
23:50callenTimMc: deterministic with respect to hashing refers to the ability to arrive at the same hash from the same value.