#clojure logs

2014-01-30

00:01akurilinbbloom: not 100% sure what you're referring to
00:01bbloom(def ^:private cleanup-process (future (let [cleanup myns/cleanup] (loop [] (when (= cleanup myns/cleanup) (cleanup) (recur)))))
00:01bbloomer stick a @ on that
00:01bbloomor rather no @ sorry ignore me
00:02bbloomthe future won't run w/o somebody demanding it, right? so you need to spin up a thread somewhere
00:02bbloomcan also just use stupid agents:
00:03bbloom(def cleanup-agent (agent nil)) .... (send-off (fn rec [_] sleep (cleanup) (send cleanup-agent rec)))
00:03bbloommake that (Thread/sleep whatever)
00:03bbloomand send vs send-off i always forget
00:03bbloombut the idea is the same
00:04bbloomrely on the agent thread pool
00:04bbloomuses the agent as a trampoline for tail recursion
00:04akurilinBrain's melting a little bit.
00:05akurilinI think I'm going to roll with the var version first
00:09elarsonare there any tutorials or anything that provide a good overview of testing in clojure using emacs, clojure test mode and cider?
00:09elarsonthis is based on a lein new app based project
00:10technomancyelarson: apart from recommending the starter kit, the clojure-doc emacs tutorial is pretty good http://clojure-doc.org/articles/tutorials/emacs.html
00:10technomancyor at least it was last I checked
00:11elarsontechnomancy: I'm pretty sure I'm doing something pretty similar to the starter kit. my emacs config is a bit to personalized (IMHO) to start from scratch
00:11elarsonthat said, I'll will take a closer look
00:11technomancyyeah, that's a good thing =)
00:12elarsonassuming I did use the starter kit though, is C-c , the only way to run the tests?
00:12technomancyno, just the quickest
00:12technomancyyou can always invoke them manually in the repl with (run-tests)
00:12elarsonin python I used my pytest.el mode which did the test run in a compile buffer so I was able to jump through the trace, so I didn't know if there was something similar
00:12elarsonah
00:12elarsonthat is good to know
00:13elarsontechnomancy: is it normal that you have to re-eval the clojure files in order to get the tests to find changes in the tests and/or file being tested?
00:14technomancyyeah, run-tests does not reload things for you
00:24gtrakhrm... any chance we can get file info from cljs-repl eval? it seems to have line, but not file.
00:28dnolengtrak: you would need to give the repl file info, the repl doesn't know
00:29gtrakI'm looking at the impl of cljs.repl
00:30akurilinIf I want to atomically look at the value of a var and decide whether I want to update it or not, returning what exactly I did, should I use a ref rather than an atom?
00:30gtrakseems like it's gotta bootstrap from some manner of source files... looking at 'assoc in the analyzer output.
00:30akurilinDoesn't look like swap! has semantics to inform the caller whether anything was done to the atom or not.
00:33dnolengtrak: I don't know what leads you to think this
00:33gtrakdnolen: not sure :-), just scratching the surface of how it bootstraps a repl..
00:33dnolengtrak: anyways, evaluate-form take an optional filename
00:34gtrakwas surprised to find no file info for builtins
00:34dnolengtrak: you have to *give* it
00:37gtrakhuh odd. seems like it oughta work, then, rhino repl calls load-file with "cljs/core.clj", calls load-stream, which calls evaluate-form with same
00:38gtrakcore.cljs, sorry
00:39gtrakI will trace it through at some point
00:42dnolengtrak: where are you expecting :file info? on the meta of a form or something?
00:43gtrakin the analyzer env, there's a :file key for assoc but it's got a nil value.
00:43gtrak(-> env :cljs.analyzer/namespaces (get 'cljs.core) :defs (get 'assoc) :line)
00:43gtrakoddly it's got a line number, :file is nil
00:45dnolengtrak: k I follow now, yeah that is weird
00:45gtrakI'm hacking piggieback to get to this... I can investigate more in the morning, good to know you think it should work.
00:47dnolengtrak: actually looks like a simple problem
00:47dnolengtrak: line 242 in analyzer.clj
00:47dnolengtrak: we check *cljs-file* instead of first checking that :file isn't present env
00:49dnolengtrak: hrm, actually *cljs-file* should be bound, dunno, something subtle going on
00:51gtrakmaybe it's bound to nil? :-)
01:05gtrakdnolen: nothing's actually calling analyze-source, from what I can tell.
01:07gtrakrhino-setup calls repl/load-file directly, but repl/repl actually calls analyze-source which populates the path info.
01:11gtrakpiggieback doesn't call repl/repl either
01:13gtrakso... I think I can hack something together now.
01:53sm0kehello anyone know of a sane ctags file for clojure syntax?
03:21sm0kehmm its awfully quiet today in here
03:34quizdrinteresting article that suggests coffescript is the most expressive of the major languages. clojure and haskell close behind: http://www.infoq.com/news/2013/03/Language-Expressiveness
03:49TEttingerquizdr, I saw that. not sure how effective their metrics are.
03:51carkthat's pretty stupid, javascript is actually very expressive
03:52carkthis measure the habits of a population rather than the languages
03:55fredyrexpressiveness is a really weird metric isn't
03:55fredyrit
03:56carkyes
03:59atyzIs anyone here familiar with core.async? I have a function for validating entities (that calls an external service) however it takes the same amount of time as if I was doing it synchronously. I feel like I"m missing something. https://www.refheap.com/29715 . Any guidance would be greatly appreciated
03:59dsrxusing LOC to measure anything, especially across languages, is absurd
04:00quizdram i thinking correctly that having an explicit recur form is actually a win for clojure, rather than tail recursion being automatic? reading scheme, for example, the syntax for optimized tail recursion (iterative recursion) vs. linear recursion (memory-consuming) are not different, therefore you must look more closely to see if scheme will actually optimize it
04:03carki seem to remember ritch saying that even if we had TCO he would keep recur in the language
04:03carkmight be wrong tho
04:04carki kinda disagree there
04:04carkyou learn to see tail recursion at a glance
04:04carkif you can't see that, you certainly didn't understand the function at all
04:05carkso you might as well just not read it !
04:05cark=)
04:05quizdrif you use recur at least you know that, if it works, you have used it properly. if you had normal TCO you could still have a working function, even if it wasn't optimized, due to an error of logic
04:06carkatyz: i don't even understand how that would run, isn't <!! supposed to be in a thread block or something ?
04:07carkquizdr: seriously, there is no added cognitive load with tail recursion, and i say that as a fairly limited person =)
04:07atyzcark: I think you can run that ona channel
04:08carkyou'll get bitten by it once or twice as a newbie, then never again
04:08atyzhowever, I'm very lost at the moment
04:08d11wtqHave to agree. Having previously done Scheme and Erlang, TCO is just something you learn.
04:08deadghostI like clojure because it is very good for cognitively challenged people like myself
04:09d11wtqA deadghost would be fairly cognitively challenged, one would assume :)
04:09carkatyz: hum but you're blocking your full thread aren't you ? i'm usually using <! myself (single !) that must go in a go block
04:09carkhum wrong person
04:09atyzcark: it seems that way.
04:10atyzare you suggesting (go (<!! (async/into [] validated)))?
04:10carknope
04:11atyzsorry (go (<! (async/into [] validated)))
04:11carki'd put the while thing in a go block ... but this is not his problem i think
04:12carkquizdr: what's coming in the assets parameter ?
04:12carkwhat's in this collection ?
04:12carkand what does f ? is it just a predicate?
04:13quizdrcark: not sure what you are talking about
04:13atyzcark: this is just a collection of entitys '({:some :key :anoter :key}). The function would be something that validates that collection. in this case. valid-asset? which acceps an asset
04:14carkatyz: that's not how it works
04:14carkyou should first map your collection of entities to a collection of channels
04:14lvhso, are there any decent string interpolation things that do *NOT* work at compile time? I am interpolating some templates only available at runtime.
04:14lvh(They're markdown templates.)
04:15atyzOh. so you want a channel for each entity?
04:15lvhI am aware of format, but I'd like something with named parameters, and hopefully also code eval.
04:15carkatyz: then you may filter it with filter<
04:15carkatyz: yes
04:15carkatyz: your goal is to have those requests done in parallel ?
04:15atyzcark: yep
04:16atyzSec, just looking up something in the api
04:16carkdon't use map< that's not it
04:16atyzSo filter only takes one channel at a time
04:17atyzI will have to doseq over every channel and call filter on that?
04:18carkatyz : nope you can do it declaratively ...f
04:18carkfirst you need a function that initiated a request, returning a channel that will contain the requested data
04:18carkinitiates*
04:19carklet's call it request-chan
04:19carkthen you can do this : (map request-chan assets)
04:20carkthat will give you the list of channels
04:20carkthat's the standard clojure map
04:20atyzOk
04:21carkthen i *think* you need to use (async/map identity asset-chans)
04:22carkand finally you can filter like you did, only using a simple predicate
04:22atyzhttps://www.refheap.com/29715
04:22atyzSomething like that
04:22atyz?
04:23carki don't see where you initiate your request in there
04:23carkyou would do that in request-chan
04:23atyzOops it was meant to be to-chan
04:24carklet me fork and write soemthing
04:24atyzSo if you look now, request chan will take an asset and add it to a chan
04:27quizdrIs there anyway to somehow save or dump all the various definitions including functions that you've created while working at the repl?
04:27atyzquizdr: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns-publics
04:28atyzWould that be what you're looking for?
04:28atyzyou could also probably use ns-map
04:29atyzcark: heh I keep killing my repl :\
04:29carkatyz: https://www.refheap.com/29723
04:29quizdratyz: well, except that the mapping only shows function names, not contents; I guess the funcitons are immediately compiled and don't exist as code any more, unlike a data type which can be printed exactly the same way as you'd need to recreate it
04:30carkatyz: there might be a sinpler way to do that async/map part
04:31quizdri guess one potentially bizarre but maybe useful workaround would be to have a macro that i'd use to define functions; you pass the function body etc as normal and the function is created, but the source for your function is also stored to an atom or something. you could then print out the atom to get all the source you came up with for various improvised functions, and then read them back in
04:31carkatyz: ah indeed looks like async/merge will do it
04:33carkatyz: there you go https://www.refheap.com/29723
04:34atyzcark: sorry this is a dumb question, but I'm not sure what the initiate request function is doing?
04:34carkat some point you need to call your service
04:34carki don't know how you do it, you didn't say
04:34atyzthat would be done through a library I've written that is encapsulate int eh validate-function
04:35atyzso the function I'm passing (f) encapsulates all of that
04:35carkwell, that's bad style =)
04:35atyzMight I ask why?
04:35carkwhat does that function return ?
04:35atyzIts part of a library I've written
04:35atyzIt returns true or false
04:36carkwell, it "complects" doing the request and validating it
04:36carkor rather validating the result
04:36carkthese are 2 different concepts : 1 network request, 2 data validation
04:37carkif your service is doing the validation, you may put it all in request-chan
04:38carklet me do it
04:38zoldaranybody working with cloact/reagent here?
04:38carkyour function returns a chan ? or does it use a callback ?
04:39carkor is it blocking ><
04:39atyzI suppose I see that, its that this library is being used in several places and I dont liek the idea of moving teh service network request to this file. However I suppose I could this async code into the library
04:39atyzIt would be a http request
04:39atyzSo blocking
04:39carkwell then, there is you bottleneck
04:39carklet me fix that
04:40atyzYeah its a huge bottleneck
04:40zoldarI have an issue where I'm rendering a component being a table row (tr). The problem is, I want to conditionally render additional row in the the same component. Reagent seems to require the subcomponents being wrapped in another component, however I can't nest tbody inside already existing tbody.
04:41zoldarReact.js itself is perfectly fine with putting components in a simple array, whereas Reagent seems to always require a component at the top level. Maybe I'm missing something.
04:44carkatyz: https://www.refheap.com/29723
04:44carkatyz: actually it's not bad style if it's the service doing the validation
04:44zoldarmy temporary workaround for that is using mapcat instead of map a level higher and wrap the rendered component in a vector.
04:45atyzcark: I"m confused. filter returns the channel?
04:46atyzThere is nothign on any channels?
04:46carkhum
04:46carkwhat does your validation function return exactly ?
04:46carkis it a boolean ?
04:47atyzit is
04:47carkhttps://www.refheap.com/29723
04:49carkassuming my-lib-validation-func is blocking, the validate function would return a serie of filtered maps all having :valid? true
04:49atyzIt is
04:49carkmerge is async/merge
04:49carkmap is clojure.core/map
04:49carkfilter< is async/filter<
04:49atyzasync/merge takes a collection of source channels
04:50atyzBut we're not creating any?
04:50carkmap creates a collection, right ?
04:50atyzIt does
04:50carkthe request-chan function creates a channel, right ?
04:50atyzno?
04:50clojurebotno is tufflax: there was a question somewhere in there, the answer
04:50atyzOH wait
04:50atyzThread returns a channel
04:50carkthe thread macro returns a channel, that will contain the result of the body, then close it
04:51atyzAhh I understand
04:51atyzI just have to move some code around then I'll give this a shot!
04:52carkheh good luck
04:52atyzThanks so much - I feel like I understand this better
04:52carkcool!
04:52atyzSo if I was to take this a step further? What shoudl I look at?
04:53carkwell you have to get the data out of this channel, and do something with it =)
04:53carkmaybe just print it at firsty
04:53atyzcan't I use (async/into [] result-of-filter) ?
04:53carktest it with some valid and invalid data
04:54atyzI have those tests setup already for when it was working "synchronously)
04:54atyz*"synchronously"
04:54carkwell no
04:55carkinto will give you a channel with a collection of maps ....just what you had before
04:55atyzThast what I need
04:55carkah let me show you
04:55carksecond
04:59carkatyz: https://www.refheap.com/29723
05:00atyz*looks up take*
05:00carkforgot the recur ...but you get the drift
05:01carkhttps://www.refheap.com/29723
05:03atyzwhy are both the as-you-wanted and print-results calling the validate function?
05:03carkthat's 2 ways to do about the same thing
05:05carkthat's how you get the data out of the chan in the end
05:05atyzOh wow
05:05atyzThis is like 100 times faster
05:05carkahwell... must not be working then =)
05:06atyzAnd I understand how its working!
05:06carkgreat ... i'll go back to AFK then =)
05:06carkgood luck !
05:06atyzthank you! :)
05:12SNBarnettcs
05:17tim_hi, i'm new to emacs http://elpha.gnu.org seems to be unavailable for at present, is there an alternative repo apart from marmalade as trying to install cl-lib-0.3?
05:24no7hingbinding apparently only works in the lexical scope - is there a way to use a binding in calls to other functions without using alter-var-root?
05:24carkno7hing: that's not true
05:25no7hingthen i must've made a mistake
05:26carkit works in the dynamic scope
05:26carkthat means in all the functions that are called inside the binding form, and the ones called by those
05:27carkbut you might want to declare you var this way : (def ^:dynamic myvar "hello")
05:28carkyour*
05:29carkalso there are a few gotchas with lazy sequences
05:33no7hingthatoh
05:33no7hinglooking into this, as then binding stops working some function calls deep
05:34carkare you returning a sequance out of the binding form ?
05:34carksequence*
05:37no7hingactually yes
05:38carkthat's a common problem
05:38carkuse doall on those sequances that will go out
05:38carksequences* ..
05:38no7hingis there a way so solve/circumvent it?
05:38no7hingi'll try that
05:39no7hingnow i got it, sorry for being so thick
05:39carknp
05:48doody1how does one reload changed code referenced from checkouts folder in repl? Is restart necessary?
05:50carkrequire and :reload-all
05:54doody1can this be automated?
05:55carki guess, that's not part of my workflow .... usually i edit a file, then evaluate it from my editor, which knows how to send it to the repl
06:01doody1hmm, I edit a referenced source (the doc of a ns) and evaluate it in cider, but it seems repl does not see it
06:02carkhum did you start the repl with cider-jack-in ?
06:03doody1hmm using emacs live, there's nrepl not cider, i did connect to a running repl
06:03carkmhh i can't help at all with emacs-live. never tried it
06:03doody1thanks
06:07doody1its the same thing with nrepl instead of cider
06:08doody1ahh interesting, when I change the doc for a function it does show the changed doc
06:08doody1but not so with the doc of a ns expression
06:27AeroNotixwhat's that error handling library?
06:27AeroNotixslugger?
06:27AeroNotixsomething like that
06:29AeroNotixslingshot!
06:35noncomdoody1: namespaces are strange in clojure
06:35noncomthey are different from everything else
06:40silasdavishow can I pass an unbound var as a function argument?
06:40silasdavisI should say a possibly unbound var
06:43CookedGryphonsilasdavis: do you mean so if the var changes the function changes with it?
06:43CookedGryphonjust wrap it in (var my-defnd-fn)
06:43CookedGryphonand it'll look up the var every time, var implements ifn
06:47noncomi am trying to parse xml with clojure.data.xml/parse and i get this exception: https://www.refheap.com/29786
06:47noncomwhat am i to do with that?
06:54gkowhat's the equivalent of clojure.contrib.repl-utils.show in 1.5.1?
06:54rurumatehow to do a 'select distinct' in cascalog?
06:57rurumateok found it, it's (:distinct false)
06:57vijaykirangko: http://stackoverflow.com/questions/5821286/how-can-i-get-the-methods-of-a-java-class-from-clojure
06:58gkovijaykiran Thanks!
07:04bordatouehi just a quick question why does (= 1 1.0) return false in clojure
07:04bordatoue(= 1 1.0),
07:05clgv,(== 1 1.0
07:05clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
07:05clgv,(== 1 1.0)
07:05clojurebottrue
07:05clgv,(doc ==)
07:05clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"
07:06bordatoueclgv: what is difference between = and == in clojure
07:06bordatouethanks clgv
07:07clgvnumerical comparison is ==
07:08clgv$source ==
07:08lazybot== is http://is.gd/XeIlE5
07:08bordatoue clgv: but in the doc it says = can be used for numerical comparison
07:08clgvtranslates to (. clojure.lang.Numbers (equiv ~x ~y)) when used as call
07:09clgvbordatoue: well it works if they have the same type. the docs should be more specific there
07:09clgvusually it is no good idea to compara floating point numbers via equals
07:10bordatoueclgv: when it says comapres numbers what are they actually refering to
07:11clgvbordatoue: there are also known bugs in clojure <=1.5.1 with respect to comparisons of big integers or big decimals
07:12clgvbordatoue: will be fixed in 1.6 afair
07:12bordatouecould you please explain when it says in the document it compares numbers what kind of numbers are is it mentioning
07:13Bronsabordatoue: with = you can only compare integer types with integer types (Integer, Long, BigInts) or floating types with floating types (Float, Double, BigFloat)
07:13clgvintegers
07:13Bronsawith == you can compare integers with floating types too
07:13clgvright, what Bronsa said ;)
07:14bordatoueI'm getting confused it says in the doc in a type-independent manner
07:14bordatouefor "="
07:14clgvbordatoue: as I said, the docs should be more specific there
07:15bordatoueso clgv, with "=" we can compare numbers in a type dependent manner is it correct
07:15clgvbordatoue: maybe there is a jira issue for that otherwise you should create one, since it is documentation only chances should be good for inclusion in 1.6
07:16clgvyeah
07:16Bronsaactually looks like with = you cannot compare a Float/Double with a BigDecimal
07:16bordatoueok, thanks very much
07:16Bronsa,(= 1.2M 1.2)
07:16clojurebotfalse
07:16clgvBronsa: thats a bug being fixed in 1.6 though
07:16bordatoueBronsa: they are different type
07:17lvhHi! could someone review my couple of lines? I'm afraid I might be committing Abominations Unto Rich: https://github.com/lvh/fomp/blob/master/src/fomp/core.clj#L12
07:17Bronsaclgv: nope
07:17lvh(ignore make-body; I know it's broken)
07:17Bronsaclgv: at least, hasn't been pushed yet
07:18clgvBronsa: damn, I remembered some dicussion about it...
07:18Bronsayeah clgv the bug has been fixed for ==
07:18clgvbut you are right it is not in the current changelog
07:18bordatoueclgv: Bronsa , are you saying with version 1.6 it would be possible to compare different type using "="
07:19lvhI'm also thinking that maybe recipients should be part of params :)
07:19clgvbordatoue: no probably not
07:19clgvbordatoue: I jsut stated you could try to get the docs adjusted
07:20Bronsaclgv: ok looks like it's expected behaviour as BigDecimal is considered in the decimal category, not in the floating
07:20bordatoueclgv: you mentioned to Bronsa it is an issue fixed in 1.6 (= 1.2M 1.2)
07:21Bronsabordatoue: he was mistaken
07:21sm0kecan i lauch lein repl with some jvm properties ?
07:21sm0ke-Dxyz=1
07:21bordatoueok thanks guys
07:21clgvbordatoue: yeah, but that was an error. the discussion I remembered was obviously around ==
07:21clgvbronsa corrected me
07:21Bronsabordatoue: https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/numbers.clj#L68-L79
07:22Bronsathe comment there explains nicely how = is supposed to work for numbers
07:23pyrtsa,[(== 11/10 1.1) (== 1.1 1.1M) (== 1.10M 1.1) (== 1.10M 1.1M)]
07:23clojurebot[true true true true]
07:23pyrtsaOh, so that got fixed as well. (Returns [true true true false] on Clojure 1.5.1.)
07:23emlynsm0ke: add :jvm-opts ["-Dxyz=1"] to project.clj
07:24sm0keemlyn: is there another way
07:24sm0kechanging file is not very friendly
07:25deadghostso if I'm reading this right
07:25emlynsm0ke: I'm not sure, sorry
07:25deadghostI shouldn't be using jquery with cljs
07:25deadghostor maybe I should
07:26sm0keemlyn: i think i can set JVM_OPT
07:27clgv,*clojure-version*
07:27clojurebot{:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}
07:27clgvpyrtsa: ^^
07:28pyrtsaclgv: Thanks, I knew that. Just didn't know how = and == behave in 1.6.0.
07:29emlynsm0ke: yes I think that should work too
07:32pyrtsaNumbers in Clojure are a mess. I think Clojure should've done something to help those poor programmers who believe that comparing equality of a Double against a BigDecimal is an okay thing to do. :/
07:33pyrtsa,(BigDecimal. 1.1)
07:33clojurebot1.100000000000000088817841970012523233890533447265625M
07:33clgvpyrtsa: that only bytes you when comparing nested data structure, afaik
07:34clgvwhen you really care for numbers in computation then you have them "in hand" and compare them via ==
07:35deadghosthmm so there's domina, dommy, jayq for dom manipulation
07:35pyrtsa,(doc ==)
07:35clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"
07:35pyrtsa,(nil? false)
07:35clojurebotfalse
07:35deadghostare any of them the generally recommended choice?
07:38clgvdeadghost: arent there plenty blog posts on that topic - I feal as if the people using clojurescript were really chatty about the technologies in the last half year
07:39lvhis there an easy way to turn abitrary strings into something that looks like an easy to type keyword
07:39lvhie a valid keyword literal?
07:40lvhI have a CSV file with a header that has a bunch of stuff in it like single quotes and spaces that don't work for keywords
07:41clgvlvh: you could use clojure.string/replace for conversion
07:41lvhclgv: Cool, thanks :)
07:45lvhThe compiler appears to be complaining about: [:require clojure-csv.core :refer [parse-csv]] ; saying Exception :only/:refer value must be a sequential collection of symbols clojure.core/refer (core.clj:3840)
07:45lvhI don't understand why [parse-csv] doesn't count
07:47llasramlvh: You need [:require [clojure-csv.core :refer [parse-csv]]] -- one more set of nesting
07:48lvhoh, derp. okay :)
07:56atyzHey all. so I'm doing some work wiht core.async but its not behaving as I would expect. Many of the results I'm receiving are nil and it seems to be giving me a random subset of correct answers and I suspect this is because the channel has been closed. https://www.refheap.com/29811
07:58sobelwhat's a zipper?
07:58sobeli find myself more lost in clojure land than most languages because it doesn't have much baggage from java OR native libs typically bound to python/perl/ruby wrappers
07:59sobelnomenclature-lost. the language is fine. :)
08:13lockssobel: a zipper is a functional data structure http://en.wikipedia.org/wiki/Zipper_(data_structure)
08:17AeroNotixdoes cider support "find callers of this function" ?
08:17AeroNotixkind of like the reverse of M-.
08:22hyPiRionAeroNotix: So functions calling the function, essentially?
08:23AeroNotixhyPiRion: yep
08:29sobelwell, i wasn't quite getting it until wikipedia explained it in terms of decategorification. seems my feeble math background still pays off.
08:29sobelthx locks, that pretty much hit the spot
08:33sobelwhat's the clojure idiom for coalasce? i'll get a value or a nil from a function, and i'm hoping/assuming there's a common expr/macro for "value or default-if-nil"
08:34gtrakcemerick: I nearly got file/line working yesterday, but I think piggieback needs a fix, any thoughts? https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl.clj#L181 repl/repl calls analyze-source, which calls analyze-file, which is where the file info comes from in the first place, but piggieback never makes it through that part of the code.
08:34sobelbetter question: is 'if' the best idiom for value-or-default?
08:34llasram,(or nil :default) ;; sobel
08:34clojurebot:default
08:35sobelah ok
08:37cemerickgtrak: isn't it just a matter of analyze-path being truthy?
08:38gtrakit needs to be given the file path to the core.cljs somehow
08:38gtrakyea, analyze-path is the key
08:41marcschwartzAnyone have any advice on the best way to find freelance Clojure developers?
08:43goodgerthey probably all hang out here, marcopol_
08:43doody1how to jump to definition of a function in emacs
08:43goodgerby which I mean marcschwartz
08:43doody1if its in another namespace
08:44doody1or file
08:48marcschwartzgoodger: Thanks. I'll just put the description of the project on the web somewhere and post the link here every couple days.
08:49mdrogalismarcschwartz: You have a PM. :P
08:51stuartsierradoody1: M-. if the Clojure code has been loaded by CIDER.
08:51silasdavishow can i get the name of a var?
08:52silasdavisas in (declare foo), (name-of (var foo))
08:53stuartsierrasilasdavis: indirectly, via (meta (var foo))
08:53noncomis there any ready tool to count top-level forms in clj files allover my project?
08:53silasdavisstuartsierra, is that the way to do it?
08:53silasdavisthe only way?
08:53noncomjust wanna estimate how much unit testing be pain in the ass
08:54doody1stuartsierra: connected to lein repl via nrepl in emacs, i guess that does not count as being loaded by CIDER
08:54stuartsierradoody1: Compile/load the file you're looking at with C-c C-k and it should work.
08:55silasdavisstrange that Vars aren't Named
08:59quizdrin general is it better to look up a key in a map using the key or the map as the function?
08:59Anderkentquizdr: key, it works with nil maps then
09:00stuartsierraquizdr: If the key is a keyword literal, use that as the function.
09:00stuartsierraIf either the key or the map could be nil, use `get`
09:00quizdri suppose one reason to use the collection as the function is then it would be more general in case you use a vector instead of a map and search on key of index
09:01AnderkentWell yes if your keys arent literal keywords then use get or the collection
09:02quizdrAndrekent if the map has nothing in it (is nil?) then it still seems to work whether you search by key or map -- or are you saying that if you search by key you can specify the default return value?
09:02Anderkentquizdr: no, if someone passes nil as the map trying to use it as a function will NPE
09:03Anderkent,(let [mp nil] (mp :foo))
09:03clojurebot#<NullPointerException java.lang.NullPointerException>
09:03quizdrah i see. regarding keys that aren't keyword literals, using a symbol as a function for a map seems to also work fine
09:03Anderkentuh that depends on what the symbol 'points to'
09:04Anderkent,(let [key :keyword] (key {:keyword :yes}))
09:04clojurebot:yes
09:04quizdr,('a {'a 5})
09:04clojurebot5
09:04Anderkent,(let [key 3] (key {3 1}))
09:04clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
09:05Anderkentoh you mean a literal symbol. I didn't know that
09:05lvhhi, is there a standard for clj docstrings
09:05quizdryeah
09:10quizdrmaps must do some sort of implicit lexical binding or something if you use them as a function, right? for example:
09:10quizdr,(let [bbb 5] ({bbb 6} bbb))
09:10clojurebot6
09:10quizdrobviously the keyword is overriding the binding of bbb to 5
09:11Anderkentquizdr: that's just equivalent to ({5 6} 5)
09:11quizdroh i see. the bbb form is evaluated prior to its insertion in the map
09:43mdrogalisstuartsierra: Vagrant set up you posted is nice. There's some good stuff in there.
09:43stuartsierramdrogalis: thanks!
09:43mdrogalisEspecially the Emacs24 thing. It's a pain every time you gotta do it.
09:44cemerickdnolen: I ran into some difficulty trying to use :as to bind the result of an :or match; I expected either of the first expressions to work, and was surprised that the third did. Bug, or are :or and :as not necessarily supposed to work together? https://gist.github.com/cemerick/6b7bb333293fd11855d9
09:44lvhI have a bunch of n-vectors; what's the idiomatic way to filter out all the ones where all the elements are empty strings
09:46lvhI guess I want (all (map empty? vec)) where all is reduction with and? (is that a core function?)
09:46stuartsierralvh: `remove` and `every?` should do it
09:48dnolencemerick: interesting open a ticket though I can't say when I'll get to that. patch welcome
09:49lvhstuartsierra: Thanks!
09:49cemerickdnolen: Will do. I may take a whack at a patch, depends. What *should* happen?
09:49stuartsierralvh: you're welcome.
09:50dnolencemerick: the first one looks like sugar to me, so I don't really care whether that works or not.
09:50dnolencemerick: the other 3 should all work
09:51cemerickdnolen: thanks
09:54lvhCan I do destructuring def?
09:54lvhI guess I don't really need it
09:55stuartsierralvh: def does not support destructuring
09:56octane--stuartsierra, mdrogalis: could you please repeat that about the vagrant setup?
09:57Anderkentlvh: not without a non-core macro. (let [[x y & rest] (def x x) (def y y) (def rest rest)) kinda works, but i'd avoid it if at all possible
09:57stuartsierraoctane--: https://github.com/stuartsierra/devbox
10:04edbondcemerick, changed lein-cljsbuild to 1.0.2 and got NPE - https://www.refheap.com/29856 1.0.2-SNAPSHOT works fine.
10:09edbondcemerick, to reproduce -> "lein new mies-om ommm", change lein-cljsbuild version to "1.0.2" in project.clj and "lein cljsbuild once"
10:09cemerickedbond: I think you've somehow gotten a stale cljsbuild dependency in there; try `rm -r ~/.m2/repository/lein-cljsbuild/cljs-compat`, and rerun lein
10:10edbondcemerick, yes, that helped. Thanks a lot!
10:10edbond(inc cemerick)
10:10lazybot⇒ 15
10:11cemerickedbond: thanks for the report, I'll make it so that won't happen again
10:12edbondnow I can switch to 1.0.2 without SNAPSHOT. Nice.
10:16noncomis there a simple way to know if a string can be parsed into a, say double or integer, without try-catch or regexps?
10:21fredyr,(doc re-matches)
10:21clojurebot"([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups."
10:21octane--stuartsierra: lovely, thank you.
10:21fredyrnoncom: oh, misread
10:22fredyrnoncom: so nvm me
10:23fredyrnoncom: i think try-catch is the way
10:23noncomi better go with regexps then :)
10:25fredyrhah
10:27john2xwhat could cause clojure.walk to not be found? https://www.refheap.com/29863
10:28stuartsierrajohn2x: If the namespace being loaded uses clojure.walk without requiring it.
10:31john2xindeed.. a bug in revise? strange, I tried the same version in another project a few days ago and didn't get the issue.
10:31wei__anyone know a good method for specifying config variables through a file? kind of like leiningen's profiles.clj, but it has to work when running from an uberjar
10:32Anderkentwei__: edn? is the config file supposed to be *in* the uberjar or not? (depending on that, read it as a resource or filesystem url)
10:32wei__Anderkent: good question. it's supposed to be outside the uberjar
10:32wei__but in the same directory (on the classpath)
10:33Anderkentwei__: if you'd rather not have your config file be lisp syntax (picky users), you can use java.util.Properties. to parse a java properties file and then read that into a map
10:33AnderkentI'm not sure if the current directory is actually guaranteed to be on the classpath
10:34wei__"slurp" seems to always check in the current directory
10:34wei__i think java properties will work, thanks!
10:34wei__(inc Anderkent)
10:34lazybot⇒ 6
10:35Anderkentwei__: check out https://github.com/michaelklishin/propertied
10:36wei__perfect. it's clojurewerkz too, which i know writes good stuff
10:40noncomwhat would be the regexp to check if a string can be parsed into a double?
10:41Anderkentnoncom: (try (Double. str) (catch NumberFormatException)
10:42edbondnoncom, (if (re-find #"\." s) :double :integer)
10:42Anderkentedbond: "asdf.fdsa"?
10:42fredyrand ".5" and "1e-1000"
10:42fredyretc
10:43Anderkentin short - why regex, who needs two problems?
10:43edbondit's quite complicated, consider localization (, . etc)
10:43fredyrit can easily get kinda hairy
10:44edbond,(Double/parseDouble "1e-100")
10:44clojurebot1.0E-100
10:44edbond,(Double/parseDouble "123")
10:44clojurebot123.0
10:45Anderkentif you don't want integers as doubles (but why not?!), you can do (try (Integer. str) (catch NumberFormatException (try (Double. str) (catch NumberFormatException (throw+ :nope
10:51noncomthanks!
10:51lvhhi
10:52lvhIm trying to use atoms and failing :(
10:52lvhhttps://gist.github.com/8711482
10:52lvhinteresting function starts at 13
10:52lvhso I am returning an atom and a function closed over it from that function at line 13
10:52lvhwhen I call the returned function with 2 args, itcomplains that I'm only calling it with 1
10:53lvhfomp.core-test> ((second test-send) :a :b) -> ArityException Wrong number of args (1) passed to: ...
10:53Anderkentlvh: you're using swap wrong
10:53Anderkentlvh: it should be (swap! sent #(into % [recipients body]))
10:53Anderkentswap gives your function one argument - the current value of the atom
10:53Anderkentyou don't need to reference the atom inside of your function
10:55lvhoh, okay; that actually makes more sense. Swap takes a function that maps the current value to the next one?
10:57`cbpIf I use a var from another namespace and properly qualify it do I still have to require the namespace?
10:57`cbpIt seems to work without requiring it
10:57`cbpmost of the time..
10:58Anderkentlvh: yeah
10:58luxbockhello, I want to create a function that takes a vector of ints, e.g. [3 2 2] and creates a sequence between [1 1 1] and the input vector based on the following rule: try to increment the leftmost number until it matches the one in the input vector
10:58Anderkent`cbp: yes you do. It will work if some other already laoded namespace required the one you refer to, but there's no reason to depend on that
10:58luxbockso with my example the first steps would go: [1 1 1] [2 1 1] [3 1 1], then reset back to 1 and increment the second leftmost number: [1 2 1], and now continue incrementing the leftmost number again until we hit a limit: [2 2 1] [3 2 1] [3 3 1] etc. until we reach the input vector [3 2 2]
10:59luxbockbut I can't think of how to do this, any help?
10:59Anderkentluxbock: I'd try a recursive solution. First think of a function that will take the current vector and the 'max' values, and generate the next entry
10:59Anderkentthen wrap that in a lazy-seq
11:00Anderkentooor you can just use for
11:01luxbockhow would for work for that? the order of the sequence matters
11:01Anderkentjust reverse the order in for
11:02llasramI think `iterate` is the way to go
11:02Anderkent,(for [z (range 1 3) y (range 1 3) x (range 1 4)] [x y z])
11:02clojurebot([1 1 1] [2 1 1] [3 1 1] [1 2 1] [2 2 1] ...)
11:02Anderkentthat looks right to me?
11:03luxbockyeah that's right, but I would also like it to work for an input vector of any size
11:03llasramActually, more state is nice -- an explicit lazy-seq is probably better
11:04Anderkentyeah, for arbitrary length vectors a lazy-seq would probably turn out nicer
11:04TimMc"more state is nice"
11:04TimMc~guards
11:04clojurebotSEIZE HIM!
11:04llasramheh
11:04luxbockhow does the call to lazy-seq look like if the fn that creates a new vector is called myinc ?
11:04llasramTimMc: I didn't say *mutable* state :-p
11:04TimMcOh! OK.
11:05TimMc~unguards
11:05clojurebotTitim gan éirí ort.
11:05Anderkent(def vector-seq [cur limit] (cons cur (lazy-seq (vector-seq (my-inc cur limit) limit))))
11:05Anderkentthen just a wrapper fn that gives [1 1 1] for cur
11:05Anderkent(or you know, arities)
11:05luxbockcool, thanks
11:08noncomyea, try catch seems more versatile for doubles parsing from strings
11:12llasram,((fn [v] (->> v (map-indexed vector) (mapcat (fn [[i x]] (map #(-> [i %]) (range 2 (inc x))))) (reductions (fn [v [i x]] (assoc v i x)) (vec (repeat (count v) 1))))) [2 1 4])
11:12clojurebot([1 1 1] [2 1 1] [2 1 2] [2 1 3] [2 1 4])
11:13Anderkentllasram: nah, it should reset to [1 1 2] after [2 1 1]
11:13ambrosebs,(def foo (fn [] `bar#))
11:13clojurebot#'sandbox/foo
11:13llasramOh, I missed that
11:13Anderkentalso, I find the lazy-seq version much easier to read / reason about
11:14ambrosebs,(def foo (fn [] `bar#))
11:14clojurebot#'sandbox/foo
11:14ambrosebs(foo)
11:14ambrosebs,(foo)
11:14clojurebotbar__49__auto__
11:14ambrosebs,(foo)
11:14clojurebotbar__49__auto__
11:14Anderkentambrosebs: sounds like you want (gensym)
11:14ambrosebsBronsa: does tools.reader have that behaviour with syntax quote?
11:14Anderkentnvm :)
11:15ambrosebsAnderkent: well I assumed they were interchangeable..
11:15Anderkenthm, I think `# runs on read time
11:16ambrosebsAnderkent: yes. I assumed it expanded to (let [gsym (gensym bar)] `~bar)
11:17ambrosebsrather ##(let [gsym (gensym 'bar)] `~gsym)
11:17lazybot⇒ bar11970
11:17jazzorn(+ 1 2)
11:17clojurebot3
11:17jazzorn;-)
11:17Anderkentof course you have to be careful about manually using gensyms
11:18Anderkent,(let [goal (gensym "f1")] (loop [s (gensym "f")] (if (= s goal) [goal s] (recur (gensym "f")))))
11:18clojurebot[f1123 f1123]
11:18Bronsaambrosebs: yes
11:18ambrosebsBronsa: do you know if it's by design?
11:18Bronsathe gensym is done at read-time, not run-time
11:21ambrosebsBronsa: could the run-time behaviour be implemented?
11:22ambrosebsa reader macro can emit code as well, right?
11:22Bronsait most definitely could, sure
11:23ambrosebsBronsa: ok.
11:24Bronsaambrosebs: you could implement it as a tagged literal if you need it
11:24ambrosebsBronsa: I just want to fix syntax-quote for everyone.
11:25AnderkentI still don't see how it's broken
11:25llasramambrosebs: Why do you want autogensyms to emit code instead of read-time gensyms?
11:25Bronsaambrosebs: making run-time gensym the default behaviour of `a# would be problematic
11:26ambrosebsBronsa: I haven't thought about it. Go on.
11:28ambrosebsllasram: I assumed that's how syntax-quote worked.
11:28ambrosebsllasram: haven't thought of an example which it makes a difference, but it still disturbs me.
11:29llasramambrosebs: Interesting. I've definitely always thought of it as read-time behavior, and the thought of it generating new symbols on subsequent evaluation disturbs me :-)
11:29ambrosebsBronsa: the biggest problem I can see is the implementation burden of bookkeeping the current gensyms for the same syntax-quote expression.
11:29Bronsasuppose you are doing `(let [a# 1] (some-macro a#)). with the current read-time behaviour you'd get (let [a__whatever 1] (some-macro a__whatever 1))
11:30Bronsawith the run-time, you couldn't even bind the let
11:31ambrosebsBronsa: I guess I mean macroexpand time then?
11:32Bronsaambrosebs: that doesn't do it for special forms
11:32ambrosebsBronsa: ok.
11:32jph-anyone know if i can get a request uri from within a (selmer) template?
11:32Bronsa(let [(macro) 1]) the call to macro won't get macroexpanded
11:33Bronsaambrosebs: I'd guess there could be a way to make it work, just not as simple as just expanding to a run-time call to gensym
11:33noncom,(= 100 100.0)4
11:33clojurebotfalse
11:34noncomwhy is not 100 == 100.0 ?
11:34llasramnoncom: It is
11:34noncomhow do i check properly
11:34llasram,(== 100 100.0)
11:34clojurebottrue
11:34noncomoh
11:34llasramIt just isn't the case that 100 = 100.0 :-)
11:34noncom))
11:35Anderkenteh, isn't = supposed to be type-independent for colections and nums?
11:35Anderkent,(doc =)
11:35clojurebot"([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."
11:35Anderkenti'd call that a bug
11:35Anderkent,(= 100.0f 100.0d)
11:35clojurebot#<NumberFormatException java.lang.NumberFormatException: Invalid number: 100.0f>
11:35Anderkentoups
11:36llasram(doc ==)
11:36clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"
11:37AnderkentI guess it's just a documentation error?
11:38llasram,[(= (int 100) (long 100)) (.equals (int 100) (long 100))]
11:38clojurebot[true false]
11:49BobSchackis there a good technique or collection to get the neighbors of an element (the elements to the left and right of it)?
11:50sdegutisBobSchack: I can't figure out how that question would make sense.
11:51bbloomBronsa: you mean you have a sequence and want to have a cursor in to that collection and move left or right?
11:51sdegutisLike, you're never *in* a collection. You always just have some data-path that you're using to access deep within a collection. In which case, sure, you can adjust that.
11:51bbloomBobSchack: whoops, that was for you, not Bronsa
11:51BobSchackbbloom: yes
11:52AnderkentBiohazard: something like
11:52Anderkent,(let [f (fn [pre cur next] [pre cur next]) cl [1]] (map f (cons nil cl) cl (concat (next cl) [nil])))
11:52clojurebot([nil 1 nil])
11:52Anderkentwoups
11:52Anderkentwrong name
11:52AnderkentBobSchack: that's for you
11:52gfredericksAnderkent: it's just subtle; = is type-independent for numbers, but won't compare exact with inexact
11:52bbloomBobSchack: two man choices: 1) hold on to the pointer to the root of the collection and pair it with an index or path or whatever
11:52BobSchackI should get a new name :)
11:52gfredericksAnderkent: e.g., ##(= 3 3N)
11:52lazybot⇒ true
11:52Anderkentgfredericks: yeah I looked inton Numbers/equal and saw the category() calls
11:53bbloomBobSchack: 2) alternatively, use something like a zipper (look it up, but not necessary the clojure.zip api)
11:53gfredericksAnderkent: it's perhaps similar to why #(= [1 2 3] (sorted-set 1 2 3))
11:53BobSchackYeah I'm looking at zippers right now
11:53gfredericks&(= [1 2 3] (sorted-set 1 2 3))
11:53lazybot⇒ false
11:53Anderkenthah.
11:53BobSchackbbloom is there a good zipper non clojure.zip zipper impl out there?
11:54bbloomBobSchack: not general purpose, but the reason i say to study zippers & not necessarily the API is b/c for a sequence, zippers are trivial
11:54bbloomfor example if you have [1 2 3 4 5] and you have a "zipper" at 3, then you can define it simply as [(3 2 1) (4 5)]
11:55bbloomBobSchack: but generally just use an index: [[1 2 3 4 5] 2] ; would be at the three
11:55bbloomor better yet: {:vector [1 2 3 4 5] :index 2} ; this is all you need
11:56BobSchackWell I'm trying to implement the borderline sequence of Fortune's algorithm (http://blog.ivank.net/fortunes-algorithm-and-implementation.html)
11:57drorbemetHi, can clojure.data.xml be used to roundtrip xml, or has it some unresolved issues?
11:57drorbemetIt is based on stax parser that's nice.
11:57drorbemetBut I am getting an error when trying to partition large xml file into chunks of smaller xml files
11:57drorbemetXMLStreamException Prefix cannot be null
11:57drorbemetcom.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeAttribute (:-1)
11:58BobSchackwhich calls for getting a point in a sequence and it's neighbors quite frequently
11:59drorbemetI am back in about 10min
12:00AnderkentBobSchack: sounds like you maybe want a different structure than a list?
12:00bbloomBobSchack: clojure's data structures don't get you out of the business of considering and creating your own data structures.... it simply delays that so far that often you don't have to do it :-)
12:01bbloomBobSchack: get the algorithm working (however slowly) with the dumbest thing that can work, then decide if you need to tune and whether or not that tuning requires custom data structures
12:01BobSchackbbloom: thats what I figured. I was hoping someone knew a clojure corner I didn't
12:01BobSchackI'll go do the naive impl first then go back later thanks everybody.
12:04zoldaris there a library similar to flatland/ordered but for clojurescript? I need a map that maintains insertion order
12:05lvhhi
12:05lvhto do autocomplete in emacs, should I get ac-cider-compliment or ac-nrepl
12:07drorbemetI am back in about 60min
12:10sdegutisdevn: I'd love to see how we could use Julia types to represent token types in the lexer and parser. That might be really cool.
12:11gfredericksis compojure the most egregious violation of halloways "data-model > API > DSL" pyramid in the clojure-oss-world?
12:14gfredericksnow I know why ratios auto-convert to bigints
12:15gfredericks,(= 3 (clojure.lang.Ratio. (biginteger 3) (biginteger 1)))
12:15clojurebotfalse
13:09sdegutisSomeone should name their next project Dragicorn.
13:09sdegutisThat'd be pretty sweet.
13:28aaronj1335hey folks, is there a way to drop into a clojure repl in the middle of a program?
13:28aaronj1335kinda like `import pdb; pdb.set_trace()` if you're familiar w/ python...
13:31bbloomaaronj1335: there are a few things in that category around...
13:31aaronj1335this seems like it might b the thing i'm thinking of: http://georgejahad.com/clojure/debug-repl.html
13:36stompyj#clojurecorner
13:36stompyjlove it
13:37aaronj1335stompyj yea? sounds like #clojure but in a leisure suit
13:37aaronj1335(which sounds awesome)
13:38stompyjhaha someone wrote clojure corner up in the chat earlier, and that sounds awesome. If I give a talk on clojure, I'm going to call it the #clojurecorner
13:38srrubyHow do I send commands via the Linux command line to a clojure repl or nrepl ? I want to do something like $ echo "(+ 1 1)" | ???? to pipe some commands to the repl process
13:39technomancysrruby: grenchman does that
13:39technomancythere might be a python thing too maybe?
13:39SegFaultAXsrruby: Plus the nrepl protocol isn't that complicated. It's described on the github project page.
13:40SegFaultAXYea, there is a Python impl of the nrepl protocol.
13:40technomancyocaml's so much cooler than python though
13:41SegFaultAXtechnomancy: Lots of things are cooler than Python.
13:41srrubyThanks.
13:43sdegutistechnomancy: I've heard great things about Haskell from many people but not OCaml. Have you done a comparison of them on your blog?
13:44hyPiRionsdegutis: no, but I'm sure bitemyapp would help you with that
13:44hyPiRionOh, he's not here
13:44sdegutiscallen's gone.
13:44technomancysdegutis: probably the biggest difference is you can learn ocaml in a week no problem
13:44llasramsdegutis: Forever?
13:44technomancyit's really simple
13:44stompyjI have a buddy who's a huge haskell guy. We gently argue about who's made the right choice. :)
13:45sdegutistechnomancy: Haskell isn't as simple?
13:45technomancysdegutis: ocaml is more like clojure in that it has facilities for imperative programming when necessary
13:46sdegutisI see.
13:46sdegutisllasram: Probably.
13:46SegFaultAXsdegutis: Why?
13:46SegFaultAXI know Chris IRL but I haven't been around much since I've been on vacation. Did something happen?
13:46sdegutisSegFaultAX: No. He's fine.
13:47sdegutisHe just moved on from Clojure.
13:47stompyjthat sounds ominous :)
13:47sdegutisSorry to phrase it poorly at first.
13:47SegFaultAXOh, probably switching to Haskell full time.
13:47sdegutisHe's in #haskell, you can ask him.
13:48sdegutisI'm writing a terrible admin section in Hiccup right now. No idea what I'm doing.
13:48sdegutisKinda wish I could just write native apps. I'm sick of "web as a platform". It's so easy to mess something up catastrophically.
13:48technomancysdegutis: it's actually a lot nicer than clojure at isolating side-effects since the type system will ensure they're all returning unit
13:49sdegutistechnomancy: OCaml?
13:49sdegutisSweet.
13:49technomancyhaskell goes further by requiring side-effects run in a monad, but I find that OCaml's approach is a really pleasant middle ground
13:50yazirianthe "web as a platform" is an elaborate plot to prevent programmers from taking over the world
13:50technomancy(inc yazirian)
13:50lazybot⇒ 2
13:50yazirianwhy else would it be so awful?
13:50stompyjdon't say that on hacker nes
13:50stompyjnews*
13:50stompyjor bye bye karma
13:51yazirianlucky for me i don't say anything there, and in fact dumped the RSS feed even just last week!
13:51yaziriani prefer more linear jerks
13:51sdegutisyazirian: we so could have done it by now if not for CSS/JS :'(
13:51SegFaultAXyazirian: LtU
13:51yazirianI think so!
13:51sdegutisstompyj: speaking of which
13:51sdegutisWhat IRC would look like in 2014: https://news.ycombinator.com/item?id=7147396
13:52sdegutisthe only difference being that there are no chanops
13:52llasramIs submitting links to hacker news to hacker news a new meme or something?
13:52sdegutisllasram: no, I just invented this idea just now.
13:53stompyjhahahahahahahahah
13:53sdegutisllasram: (well, 20 hours ago)
13:53technomancysdegutis: check out the free book at http://realworldocaml.org if you want to dig in; I find it a great fit for small native distributables that clojure is bad at
13:54sdegutiswell, not always small, according to your blog
13:54technomancyright, if size is a priority you have to choose your libs carefully
13:54hyPiRionyeah
13:54hyPiRion`-import core async` and then bam
13:55technomancythe author of the book told me they were working on improved tree-shaking for an upcoming version that would solve that
13:55technomancysdegutis: nevar
13:55yazirianwhich reminds me again of the web as a platform and the horror of a cljs/pedestal/om 'hello world' app downloading over a megabyte of js to run
13:55sdegutistechnomancy: it had a beginning, it must have an end
13:55technomancysdegutis: I will take it with me to the grave
13:55hyPiRionsdegutis: so uh, you're betting on when technomancy will... die? =/
13:56hyPiRionoh, he beat me to it too, argh
13:56sdegutishyPiRion, technomancy: i doubt http://technomancy.us/ will even be a valid URL in 15 years
13:56technomancysdegutis: what with the fall of the US?
13:57technomancy*impending fall
13:57sdegutisand im assuming by then we'll be using XAML or something instead of html/css/js
13:57TimMcLaTeX
13:57stompyjclojure is the first language I've worked in where I feel like i could use a tutor at times
13:57TimMcLaTeX everywhere
13:58bbloomsdegutis: latex scares you but xml-based object initialization syntax is A-OK?
13:58ToxicFrogLaTeX \o/
13:58sdegutisanyway, in all seriousness, i think https://news.ycombinator.com/item?id=7147396 is actually a pretty good joke
13:58bbloomthere are some brilliantly designed bits of WPF, but the decision to use XML for XAML was political & brain dead
13:58yaziriansdegutis: it'll be Dart, and the runtime will inject ads into your source
13:59sdegutisbbloom: im not that picky about syntax tbh
13:59sdegutisyazirian: of course, how else will chromium os make its money?
13:59technomancySergei gots to eat, son.
13:59bbloomsdegutis: xml's verbosity is only half the problem. the other half is that it has horribly broken semantics that clash with the desired semantics for UIs
14:00sdegutisoh?
14:00sdegutisbbloom: can you cite a paper demonstrating this please?
14:00bbloomsdegutis: no b/c i haven't written such a paper yet :-P
14:00sdegutis(i only read papers these days, it's the only way i can sleep at night now that i have a HN account)
14:01stompyjhey bbloom I missed the last clojure meetup where you gave your talk. is the video online?
14:01bbloomstompyj: http://www.hakkalabs.co/articles/clojure-software-dendrology
14:01sdegutis(that joke came out wrong, i meant it to be a joke about how HN is fine with random articles on the web, not a description of how i fall asleep)
14:01stompyjmuch appreciated!
14:06sdegutis,[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]
14:06clojurebot[[[[[[[[[[#]]]]]]]]]]
14:07sdegutiswat
14:07hyPiRion,*print-depth* ;; I guess
14:07clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *print-depth* in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:08hyPiRionah, *print-level* it is
14:10sdegutis##[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]
14:10lazybot⇒ [[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]
14:11eggheadwhy does edn make a distinction between vector and list?
14:11technomancyegghead: because it's secretly clojure
14:11sdegutis##(repeat 500 nil)
14:11lazybot⇒ (nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ni... https://www.refheap.com/29927
14:11technomancydon't tell anyone
14:11sdegutisneat.
14:11sdegutis,(repeat 500 nil)
14:11clojurebot(nil nil nil nil nil ...)
14:11sdegutisokay, lazybot it is
14:12eggheadtechnomancy: it seems like for edn that would make sense as a tagged literal
14:13technomancyegghead: I'm not entirely convinced EDN is anything but a sneaky way to get people to write datomic libs for other platforms
14:13sdegutisClojure's destructuring is probably the number one feature I miss in other languages. Some of them get kinda close, but not nearly as convenient as Clojure.
14:13sdegutis(In other high-level languages, i.e. Ruby and Python)
14:13eggheadsdegutis: sml? :p
14:14eggheadOH
14:14hyPiRionOCaml's good at that. And Erlang, although it lacks both map and sets, which is super annoying.
14:14technomancythat's funny; destructuring just seems so limited compared to pattern matching
14:14hyPiRionoh, right. that's pattern matching, not destructuring.
14:15sdegutistechnomancy: i.e. OCaml?
14:15technomancysdegutis: or any FP language that isn't clojure, basically
14:15sdegutisAh.
14:15eggheadya technomancy
14:16sdegutisI started using a pattern of functions that update the database returning [db val], and functions that update an entity taking [db val] as their first argument.
14:16sdegutisThat way I can do chaining with ->, i.e. (-> (create-episode ...) (set-episode-title ...)) etc
14:17sdegutisPretty handy for carts when writing tests: (-> (open-cart db user) (add-license-to-cart ep1) (receive-stripe-payment ...))
14:18sdegutisThat's where I'm loving destructuring the most right now. I can access either the db or the val in a let block in my tests without using an extra (first ret-val) line.
14:18srrubytechnomancy: Is there a 32 bit version of grenchman? I'm on Linux wheezy
14:19CaptainLexSo I see there is no true literate programming engine for Clojure. Is this because a) true literate programming is overrated? b) true literate programming is not as useful for FPs? or c) language-agnostic FP tools are good enough?
14:19llasramDo they still make 32-bit computers?
14:19technomancysrruby: no, sorry;
14:19sdegutisCaptainLex: what does literate programming mean to you?
14:19technomancyall the precompiled stuff is 64-bit
14:20CaptainLexsdegutis: The kind of thing described by Knuth, with compile-time reordering of content, macro-substitution, &c &c
14:20hyPiRionCaptainLex: most likely it's because noone has bothered to make one yet.
14:20sdegutisCaptainLex: I haven't found a need for one.
14:20CaptainLexsdegutis: It's mostly useful when making a large codebase that many people will have to poke around in
14:20sdegutisWell-written Clojure reads like English to me.
14:20hyPiRionWhether that is the cause of a, b, c or some unknown x I'm unsure of.
14:20CaptainLexi.e. where documentation is the most important part of the software
14:21dkinzerllasram: I've seen plenty of 32-bit VMs
14:21TimMcCaptainLex: I don't see what FP has to do with it.
14:21sdegutisllasram: we bought a 32-bit PC from a local shop for like $100 last year
14:21sdegutisit has MS-DOS 6.22 on it
14:22CaptainLexOops, C was supposed to read "language-agnostic LP tools"
14:22sdegutismy son's been trying to make games using QBasic on it
14:22CaptainLexTimMc: Well, maybe FPs are more readable. Not really, though :P
14:22TimMcah
14:22sdegutis<3
14:22CaptainLexI was just imagining responses from the peanut gallery, and I could see someone saying "Well, literate programming is mostly useful for spaghetti code" or some such a thing
14:24devnhmmm, anyone in here know anything about iota and reducers?
14:25devnI want to use iota in combination with clojure.data.csv. What's the best way to go about doing something like this? Perhaps extending the Read-CSV-From protocol to iota.FileVector?
14:25technomancyCaptainLex: I would suspect it might be because people value a literal and clear mapping of files on disk to namespaces.
14:25devnIs this a foolish thing to do in any case?
14:25technomancypeople are rightly suspicious of anything that gets in between them and the compiler
14:26devnclojure.data.csv just doesn't work for the size of files I'm dealing with
14:26CaptainLextechnomancy: Makes sense. I haven't written any LP stuff, but it sounds interesting!
14:27drorbemetXMLStreamException Prefix cannot be null
14:27drorbemetI think I found the cause of the error
14:27drorbemetI don't declare namespaces in the new xml file in which I copy the xml chunks
14:27drorbemetI read about a repairing mode in
14:27drorbemethttp://jira.codehaus.org/browse/WSTX-170
14:27drorbemetcan I use repairing mode with clojure.data.xml/emit?
14:28tmciverIf anyone is interested in a Clojure job in Framingham, Massachusetts, feel free to PM me.
14:28CaptainLextmciver: Were that it were five months from now!
14:29llasramdevn: Are you sure that's the problem? data.csv should be producing a lazy sequence of the rows in your CSV input file
14:29llasramdevn: Are individual rows too large to fit into memory?
14:29shep-werktmciver: got anything in Pittsburgh? ;-)
14:29tmcivershep-werk: sorry, no. :(
14:29shep-werktmciver: time to open a remote office
14:30tmciverHey, man!
14:30tmcivero/
14:30TimMc \o
14:30tmciverMissed you at the last Boston Clojure meet up.
14:30TimMcOh! Yeah, things have been busy.
14:31TimMcI have too many projects and too much ADHD.
14:31tmciverTell me about it.
14:31tmciverGoing to the next meet up?
14:32tmciverTimMc: ^
14:33TimMcI hope so.
14:34TimMcI've been getting into electronics, so reading up on circuits has been occupying me some nights.
14:35tmciverCool. Yeah, I have an Arduino project in my basement collecting dust.
14:35technomancyTimMc: what kind of projects?
14:37devnllasram: hmmm, maybe I was mistaken? I think I know the issue. walk/keywordize-keys across my data.
14:38llasramYeah -- that's probably forcing full realization in memory
14:40tjdphilosophical question: (map some-f some-seq), if some-f throws an exception, what ought happen? swallow it and map to nil? raise the exception?
14:43technomancyexception hiding is pretty evil
14:43shep-werktjd: mu
14:44hyPiRiontjd: Whenever the value is calculated, the exception is thrown.
14:45hyPiRionso for example ##(do (map #(< 10 %) (concat (range 1 100) [nil])) nil) will not throw
14:45lazybot⇒ nil
14:45hyPiRionbut ##(map #(< 10 %) (concat (range 1 100) [nil])) will.
14:45lazybotjava.lang.NullPointerException
14:45sdegutistechnomancy: evil is such a strong word. how about "malutile"?
14:45hyPiRion(because it attempts to print the value)
14:45technomancysdegutis: maybe "reprehensible"
14:45sdegutisactually im gonna coin malutile.
14:46technomancymore power to you
14:46sdegutistechnomancy: that phrase is so malutile
14:46devnllasram: is there anything decent that i can do with iota to deal with that? basically I want to create a map out of every row, by zipmapping the headers across all of the rows, and keywordizing the keys on those maps
14:46mmitchellstuartsierra: I've been playing around with your component lib/idea. Question... for web apps, how are you getting the "system" into your handlers? Or are the handlers reaching out the the "system" var?
14:47llasramdevn: I don't know iota, but that isn't anything you shouldn't be able to do with lazy seqs. The headers are just the first row, right?
14:51stuartsierrammitchell: construct the handlers when you start your app
14:51stuartsierraCompojure makes this awkward but still doable.
14:52devnllasram: yeah, im trying it out, doesn't seem to make much of a difference with reducers and iota
14:53mmitchellstuartsierra: Right, so (GET _ #(my/handler system %)) etc.?
14:53devni find it a bit annoying clojure.data.csv keeps read-cell and so on private fns
14:53TimMctechnomancy: I want to build a Joule Thief or five, and then start playing with high-power LEDs.
14:54llasramdevn: So data.csv returns a lazy seq of the rows, right? So you get (let [rows ...] ...) at some point. Then you just: (let [headers (map keyword (first rows)), data-rows (map (partial zipmap headers) (rest rows))] ...)
14:55llasramThen data-rows is a lazy sequence of your keyworded maps
14:55technomancyTimMc: cool
14:55stuartsierrammitchell: no, don't use defroutes at all. Do something like (defn make-app [… service components …] (routes …)) and call it from your app component's start method.
14:55stuartsierraThe handler functions are no longer top-level defns.
14:55llasramdevn: Any processing you do on that sequence, including reducers, you just need to make sure you don't realize the whole thing into memory at once
14:55TimMctechnomancy: I'd really like to make my own LED grow light, but to get to the point of making the necessary constant-current mechanisms I need for learnin'.
14:55TimMcs/for/more/
14:56mmitchellstuartsierra: Ahh I see. Is there any example of this (a ring web app) somewhere?
14:56stuartsierrammitchell: no
14:57stuartsierraBut it's not hard.
14:57mmitchellOK, I'll give it a try
15:08dobry-deni have a user-upload avatar system that saves avatars to "/public/avatars/custom/{{user-id}}.{{gif/png/jpg}}". even though i cache the path, i'm having trouble figuring out performance without the cache.
15:08dobry-denis it faster to try 42.gif, 42.png, 42.jpg and pick the one it finds. or is it faster to search the file-seq for a match on 42.png/gif/jpg?
15:09Raynesgf3: You live outside the snapchats!
15:09gf3Raynes: YOU HUSH
15:09gf3SHOOSH YOUR MOUTH, Raynes
15:11mdrogalisMan, the last time you guys were talking about Snapchatting, there was a helicopter incident involved.
15:14AeroNotixhow likely is it that Clojure would get fully preempted user space threads?
15:16sobellike Java's?
15:16mdrogalisAeroNotix: What does that mean?
15:17lvhI'm having some problems with clj-postal; it's reporting success with or without metadata (so SMTP server info) and in no case is any mail actually getting sent.
15:17sdegutislul i trull u
15:17sobelgiven the clojure concurrency model, i am not really seeing why or how it makes sense to use a preemptive process model in clojure
15:18AeroNotixsobel: like Go's
15:18AeroNotixsobel: Java doesn't have user space threads anymore
15:18AeroNotixafaikt
15:18llasramAeroNotix: You mean like core.async then?
15:18AeroNotixllasram: no, that's cooperatively scheduled.
15:19llasramIn what sense?
15:19sshackSo what libraries are people using to do graphs in their web apps?
15:19AeroNotixllasram: you know what preemptive scheduling is, right?
15:19sobelsshack: http://d3js.org/
15:19AeroNotixIf I make a go block which literally blocks, it blocks that thread completely.
15:20ToxicFrogllasram: basically he wants preemptive greenthreads rather than preemptive kernel threads or coroutines.
15:20AeroNotixToxicFrog: exactly
15:20sshacksobel: Ahh, so you're just emitting json and letting the fronted take care of it?
15:20ToxicFrogAeroNotix: what does that get you over just using kernel threads?
15:20sobelsshack: bingo
15:20AeroNotixToxicFrog: a lot
15:20AeroNotixToxicFrog: kernel threads are not cheap, for one.
15:20ToxicFrogAeroNotix: I've never used greenthreads before, so I don't know the implications
15:21sobelthey're cooperatively scheduled
15:21AeroNotixe.g. in Go/Erlang a green thread is very, very small.
15:21AeroNotixsobel: we've been saying this
15:21AeroNotixbut the preemptive scheduling is what does it
15:21AeroNotixdoes it for me *
15:22AeroNotixsince it means you have no real rules about what a thread can do
15:22sobelare they green threads or process threads?
15:22sobelone is preemptive and one depends on the language vm
15:22lvhcan someone please explain what the difference is in this example between send-message2 and send-message3? (this is a clj syntax question) https://github.com/drewr/postal/issues/22#issuecomment-5220583
15:22AeroNotixsobel: right, I'm asking how likely is it that clojure could have this
15:22AeroNotixsobel: these things are baked into languages, so they're not trivial things to implement overnight.
15:22llasramAeroNotix: It's not clear to me that go employs any sort of preemptible user-level threads. Reference?
15:23sobelunless you are speaking strictly from the VM perspective, then i guess you can call green threads preemptive with the VM as the preemptor but i don't get the use case for making that distinction
15:23AeroNotixllasram: They're coming
15:23ToxicFrogsobel: java (and thus clojure) already supports process/kernel threads. The question is about support for green threads with preemptive scheduling, which it doesn't currently have. Java used to, but it was dropped from the JVM in 1.2, IIRC.
15:23llasramAeroNotix: Reference?
15:23sobelAeroNotix: i more than get the 'baking in' aspect.
15:23AeroNotixllasram: second
15:23ToxicFrogsobel: the distinction is that you can treat them like preemptive threads and not have to worry about whether the preemption is handled by the kernel or the VM.
15:23stuartsierraAeroNotix: Not exactly what you're asking, but some of the latest Fork/Join thread pools can detect blocked threads and expand the thread pool. That combined with core.async can prevent a real blocking action in a `go` block from blocking other work.
15:23AeroNotixllasram: https://code.google.com/p/go/issues/detail?id=543
15:24AeroNotixllasram: not perfect preemption, but a start.
15:24ToxicFrogsobel: whereas with coroutines scheduling is handled by the coroutines themselves
15:24AeroNotixstuartsierra: gah what's the point of a pool (limited, bounded etc) when you just grow it?
15:25stuartsierraAeroNotix: I assume there are still limits, it's just slightly more flexible than a fixed-size pool.
15:25AeroNotixGo has a similar tactic for IO fwiw
15:25AeroNotixwhen a goroutine blocks on IO, another kernel thread starts. AFAICR
15:26AeroNotixstuartsierra: the point is, core.async isn't exactly perfect
15:27stuartsierranobody said it was
15:27AeroNotixstuartsierra: I know :)
15:27bbloomit's kinda amusing to me to watch language VMs reinvent OS stuff, even when the VM designers are OS people :-)
15:27hyPiRionAeroNotix: I would guess that's a limitation with the JVM. (Disclaimer: I know how hard it is to predict when IO will block the thread)
15:27sdegutisSome days, I want to just quit programming for 20 years and come back when everything's not so insane.
15:28AeroNotixhyPiRion: therein is kind of my question, really. How hard does the JVM make preemption of user-space threads?
15:28bbloomsdegutis: add a zero
15:28AeroNotixbbloom: what's the alternative?
15:28AeroNotixbbloom: we all just use threads?
15:28sdegutisbbloom: 020 years? I don't know octal.
15:28bbloomsdegutis: :-P
15:28llasramAeroNotix: Reading that issue, I believe that you have somewhat mistaken ideas about what Go is changing, and what is possible. What mechanism do you see allowing for user-level threads engaged in blocking kernel operations to be preempted?
15:28sdegutisOh, 020 = 16.
15:29stompyj(inc bbloom)
15:29lazybot⇒ 26
15:29sdegutisRight, that makes sense. Only 8 digits, so 8 * 2
15:29AeroNotixllasram: it's just a better tactic for preempting goroutines
15:29AeroNotixbefore they were preempted just on chan blocks
15:29sdegutislulul i truuul u
15:31llasramAeroNotix: That's my reading as well. Which is where I'm confused as to where you're getting this user-level preemptive threading thing from. If code makes a system call which blocks the kenel thread, then there's nothing you can do to preempt it
15:31AeroNotixllasram: it's better than just requiring everything use channels everywhere
15:31sobelsdegutis: it will be insane in 20 years, too.
15:31AeroNotixsobel: probably moreso
15:32sobelif the past 20 are any sort of a blunt hint
15:32ToxicFrogllasram: typically this is done at the VM level - the VM knows when you're making a blocking call and replaces with an asynchronous call and reschedule under the hood
15:33sobelmy time-travel fantasy is pretty much limited to delivering a MacBook Retina to my 12 year old self
15:33ToxicFrogOr it just doesn't make synchronous IO available at all, or does so with a "this will break greenthreads" caveat
15:33sobelloaded with software, patents, stock charts, MLB scores...
15:33sdegutissobel, AeroNotix: I'm not so sure of that. Professional OSes are moving towards really good architectures, the only thing holding them back is backwards compatibility, which isn't that hard a problem to solve when you have virtualization.
15:34AeroNotixsdegutis: which are the professional OSes/
15:34AeroNotix?
15:34sobelwith WinXP as my example, i disagree that virtualization the problem of backward compatibility holding OSes back
15:34sdegutisAeroNotix: Windows 8, Mac OS X, etc
15:34sobelsolves
15:34technomancylol
15:34AeroNotixsdegutis: how do you know anything about their architectures?
15:35sdegutisAlso Ubuntu.
15:35sdegutisAeroNotix: I dunno. Programming?
15:35AeroNotixsdegutis: but it's not kernel level hacking though is it
15:35sdegutisnot usually, no
15:36sdegutisso?
15:36AeroNotixSo how do you know what their architecture is like?
15:36sdegutisAeroNotix: I dunno. Programming?
15:36AeroNotixsdegutis: you keep saying that
15:36sdegutisNo, you keep saying that.
15:36Nottetroll...
15:36llasramAeroNotix: Friendly reminder: IRC is not a contest
15:36AeroNotixllasram: I know this
15:37sdegutisAeroNotix: I don't care about the kernel, I wasn't talking about the kernel.
15:37sdegutisAeroNotix: I was talking about userland libraries and available tools.
15:37AeroNotixsdegutis: you mentioned architecture, usually this is used with kernels. Never mind then friend.
15:37sdegutisAeroNotix: Also I really liked the paper I read on MS's Singularity.
15:37dobry-denI'm running a Compojure app behind Nginx with proxy_pass. How do you prevent the runaway spiral of users f5'ing when load is high?
15:38sshacksobel: So, coming from Mathematica, D3 is an utter nightmare. two pages of code to do a bilevel partition pie chart that takes one in Mathematica.
15:38AeroNotixdobry-den: have you had this problem already?
15:39bbloomsdegutis: for all the things i hate about browsers, they do provide an opportunity to escape the backwards compat nightmare when coupled with virtualization
15:40bbloomsdegutis: at least at the user application level
15:40sdegutisAeroNotix: When I made my comment, I was mostly thinking of LightTable. While I kinda like the app in itself, I think it's insane that HTML/CSS/JS is the best we can do for cross-platform GUI programming right now.
15:40dobry-denAeroNotix: yeah. and so far my comical solution is to `sudo service nginx stop` until server catches up
15:40AeroNotixsdegutis: there's Qt, I've had great success with that
15:40sshackdobry-den: Does nginx have rate limiting?
15:41AeroNotixdobry-den: so what's your load? Req/s?
15:41sdegutisAeroNotix: True, I did have a hello-world in Qt that I haven't seriously investigated yet.
15:41sshackA hack, yes, but sometimes simple solutions are the best.
15:41sdegutisAlthough they dropped Qt-Jambi, which means Clojure integration won't be so pleasant.
15:41AeroNotixsdegutis: I used pyqt mostly, very nice. Moved some stuff to C++ from Python if you can believe it.
15:41sdegutisbbloom: They're their own backwards compatibility nightmare in terms of browser support.
15:42dobry-denAeroNotix: nginx reports 50 req/sec.
15:42AeroNotixdobry-den: and it dies on 50/s/?????
15:42AeroNotixcan anyone confirm that this is all Compojure can do?
15:42dobry-denyeah, there's a bottleneck i'm working on
15:43sdegutisllasram: yes it is and i win
15:43sshackdobry-den: Is it io constrained on a DB or something?
15:43dobry-denAeroNotix: it's a dynamic website. doesnt really have much to do with compojure
15:43sdegutisI also think we could do a lot better with IPC. I was impressed by Singularity's solution for a simpler and faster IPC model.
15:44AeroNotixdobry-den: but like.. 50/s, that's pretty poor.
15:44sdegutisIt might make it a little more feasible to have Clojure running in the background and a C app just communicate with it over nREPL or something, for use with scripting.
15:44dobry-densshack: i've found the bottleneck, i just dont want the server to get stuck in a cpu-load spiral every time
15:44dobry-denAeroNotix: yeah, well, the idea is to optimize as i go
15:44AeroNotixhmm ok
15:45dobry-denthe bottleneck is actually the use of a swap! on the homepage
15:46AeroNotixdobry-den: huh, what for?
15:47sdegutisbbl
15:47dobry-denAeroNotix: my introspection skills are pretty poor, but it seems that my naive use of noir.util.cache will make everyone halt on the homepage when any of the cache! are invalidated
15:48dobry-deni've been replacing it with a simpler atom where a cache recomputed in another thread (scheduled)
15:48AeroNotixdobry-den: what are you caching?
15:49dobry-denAeroNotix: it's a forum homepage. so the latest-post of each forum, forum stats, total-posts in each subforum.
15:49AeroNotixdobry-den: ever heard of memcached?
15:49AeroNotixor redis
15:49dobry-denwell, that's unnecessarily complexity that doesn't address this particular problem
15:50AeroNotixOh I assure you it will
15:50dobry-deni believe the problem is that the recalculation function is inside the swap! that the user has to wait on
15:51dobry-deni've fixed it by scheduling the swap myself and letting all users simply deref it, which is how it should be for such trivial cache
15:52AeroNotixdobry-den: what's the calculation?
15:53dobry-denit makes a db call and there seems to be some sort of blocking contention when multiple people land on an invalidated homepage
15:54AeroNotixdobry-den: depending on the application you can forgo atomic changes, if the later calculations don't depend on the previous ones...
15:54AeroNotixe.g. "latest forum post"
15:54stompyjIs it terrible practice to have a configuration namespace where you declare vars that other namespaces may need?
15:54AeroNotixyou'd just use memcache and overwrite a key
15:54stompyj(trying to get myself out of circular dependency hell)
15:54AeroNotixand cache the ARSE out of that
15:55AeroNotixbecause you only need to invalidate the cache when new posts are created, I'd have middleware on the routes which create posts to invalidate caches.
15:55AeroNotixbecause if you're using TTL, it's just stupid
15:55hiredmanyes
15:56hiredmanstratify your code
15:56dobry-denAeroNotix: right, i invalidate the cache on new posts. but it seems better to swap the new latest-post myself instead of make users trigger it
15:56dsrxmove your code into the highest strata - rewrite it in Haskell
15:56dobry-denbut i dont see how it matters if i use memcached, redis, or an atom.
15:57AeroNotixdobry-den: then test it
15:57AeroNotixdobry-den: I don't see anywhere where you mentioned testing
15:57dobry-denwell, i didnt even mean to talk about the issue because it actually turns out i dont need to cache it (the cache introduced a block). i was just asking about nginx
15:59sdegutisgfredericks: you guys ever file that speclj bug?
16:00dobry-denAeroNotix: funnily enough, the only reason i hastily cached it (incorrectly) was because i was hastily trying to resolve a load issue that was actually caused by -- wait for it --- running lein-ring in dev mode
16:00AeroNotixah
16:00dobry-denwhich i dont recommend
16:01AeroNotixi didnt even know dev mode was a thing
16:02arohneris there a library/trick for generating ring session cookies, for use w/ clj-http cookie-store?
16:03arohnerI would like to directly add cookies to clj-http, that look like they've been signed by ring
16:04hiredmanisn't the whole point of signing cookies to avoid that?
16:07akurilinFor my integration tests I just have a couple of hardcoded cookies lying around
16:08AeroNotixsame
16:08akurilinI think there might be an issue with generating cookies procedurally on machines that don't get a lot of entropy
16:08akurilinmy dev boxes can get stuck waiting for entropy for something like 10s
16:09stuartsierraakurilin: This can be a problem in virtualization containers.
16:10akurilinstuartsierra: what's an example?
16:10stuartsierraakurilin: dunno, just heard that as conventional wisdom
16:11akurilinI remember filing a bug against ring about those stalls back in the day and weavejester pointed out it was nothing he could do on his end.
16:11akurilinI still need to come up with a way of bypassing this issue in my integration test suite :(
16:11akurilinstuartsierra: fair enough
16:14akurilinSo, mixing dosync and clojure jdbc transactions can be potentially a bad idea, huh?
16:14stuartsierraakurilin: Yes. JDBC is a side effect. Don't put side effects in dosync transactions.
16:15akurilinI have a shared map in memory that I want to run some checks against and then runthe transaction (which can also fail)
16:15akurilinmeaning that ideally I could roll back both
16:15shep-werkakurilin: if you can guarantee that that machine is only used for tests, you could probably set a kernel option to use a PRNG instead of a crypto-hard one
16:15shep-werkwhich might be easier in a virtualized env
16:16akurilinshep-werk: this is pretty much exclusively on my dev machine which is on bare metal, I think the issue is that I might not have enough network traffic to it to generate enough entropy
16:16arohnerhiredman: this is for integration tests. I want to set up the ring session in a certain state, and then bang on the server
16:16akurilinshep-werk: but yeah that's a good idea, I'll try that perhaps
16:17arohnerhiredman: looks like it's not too hard to reach into the ring middleware, I was just checking if there was a lib to do this already, because I remember a few ring / clj-http testing libs
16:18akurilinRegarding the dosync / jdbc transaction issue: it seems that the least error prone way would be to start a JDBC transaction, do all the DB operations without committing, then run the dosync and use the result of it to decide whether to rollback JDBC or not.
16:18akurilinWhich sounds incredibly convoluted, but probably isn't.
16:20stuartsierraakurilin: yes that should work
16:21shep-werkakurilin: if it's your dev machine i'd be surprised - I'd expect keyboard / mouse input to also go into entropy pool
16:21shep-werkunless you enter code by force of will ;-)
16:24akurilinstuartsierra: thanks for confirming, apprecaited.
16:24akurilin*appreciated
16:25akurilinshep-werk: yeah I really need to find time to drill deeper into what exaly is stalling in the process, have yet ot figure out how to "break" in clojure
16:25akurilinto see what's waiting
16:26shep-werkakurilin: just do a JVM thread dump :-)
16:27akurilinshep-werk: any particular tools you'd recommend?
16:28shep-werkTBH, I haven't done much specific to Clojure, but I'd start with just sending a SIGQUIT to the JVM when it's slow and browse the result
16:29shep-werkor use something like (J)VisualVM and attach to it
16:30gfrederickssdegutis: not that I know of
16:30sdegutismy coworker writes it, so i may be able to help get the ticket some attention
16:32gfrederickssdegutis: okay, I'll probably pull one together
16:33gfrederickssdegutis: it would basically involve reverting an earlier accepted PR
16:33sdegutisgfredericks: make sure to put in the explanation for what bug it caused
16:33sdegutishe's understanding, but very skeptical and untrusting of anyone but himself.
16:34sdegutis(he said this himself; i am not slandering)
16:34sdegutisin other words, be sure to give a good argument that it really did cause the bug you saw
16:34gfredericksoh I wonder if that approach means running with an old version of clojure?
16:38gfredericksindeed it does
16:38gfrederickshow does that not damn it all by itself?
16:41gfredericksoh technomancy commented on the original PR
16:49technomancy"technomancy will yell at you unless you revert this commit" <- good argument?
16:49ddima_depends on how badly you can yell
16:49sdegutistechnomancy: doubtful, unless you also wag your finger
16:49sdegutisin which case maybe
16:49gfrederickssdegutis: https://github.com/slagyr/speclj/issues/7
16:49gfredericksE
16:49gfredericksum
16:49gfrederickshttps://github.com/slagyr/speclj/issues/78
16:50gfredericksis what I failed to paste somehow
16:50sdegutisThanks.
16:50technomancysdegutis: I can do M-x look-of-disapproval if that helps
16:51sdegutisgfredericks: most excellent, theophilus. thank you.
16:51AeroNotixtechnomancy: so lame, I have that on C-x M-l d
16:51brehauthiredman: what was the aphyr video you were talking about yesterday?
16:51technomancyAeroNotix: hehe
16:51sdegutisAeroNotix: why not just have it auto-run inside init.el and save time
16:52AeroNotixSERIOUSLY though (= (+ :clj-refactor :cider-mode) :omfg-amazing)
16:52AeroNotixsdegutis: one needs to do it on demand
16:52sdegutisAeroNotix: i'd try it but my setup is pitifully fragile
16:53AeroNotixsdegutis: Why?
16:53AeroNotixI *do* spend a lot of time on my .emacs stuff
16:53AeroNotixhttps://github.com/AeroNotix/dotfiles/blob/master/.emacs
16:54sdegutisAeroNotix: why is mine fragile?
16:54technomancyif it were scheme I'd recommend switching all your parens to []
16:54technomancymore structurally stable
16:56sdegutisAeroNotix: last time i tried to upgrade a dep from melpa, it broke and was a pain to revert. this is cuz melpa builds off master, which is a bad idea. so i stopped using melpa and froze my dependency graph in fear of breaking anything else.
16:56AeroNotixsdegutis: yes
16:56AeroNotixsdegutis: put your .emacs/.emacs.d into a repo
16:56AeroNotixI regularly just rm -r elpa/* stuff just to see what breaks
16:56sdegutisAeroNotix: also, any time i touch my init.el i get sucked in for hours. constantly changing, reverting changes, trying new things, etc. its a black hole of experimentation.
16:56AeroNotixsdegutis: Yes, this is emacs.
16:57sdegutisits in a repo already.
16:57sdegutisbut i took it off github cuz no one wants to see that stuff. its like underwear.
16:57AeroNotixsdegutis: nah, the guys at work usually steal stuff from mine, and I theirs.
16:58technomancysdegutis: melpa is fragile by design
16:58sdegutisAeroNotix: i have no "the guys at work". nobody knows about my github repos. im the only employee in this company, i work from home, sole developer on this project.
16:58sdegutistechnomancy: yes.
16:58technomancydo not want
16:58sdegutisthe only dependency manager ive seen done well is whatever leiningen uses.
16:59AeroNotixtechnomancy: it's better than what it was
16:59technomancysdegutis: aether still screws up version ranges pretty badly
16:59technomancybut that's relatively easy to avoid
16:59technomancywell... it took a couple years, but we mostly squashed the issues
16:59sdegutisive had a lot of trouble with pip and bundler. havent used npm so cant say much there.
17:00sdegutisand i refuse to use cocoapods on principle (its not ruby dangit, its objc!)
17:00AeroNotixone must say that I'm postively happy about lein. It Just Works.
17:00AeroNotixend of story.
17:00sdegutisonly one i havent had trouble with is whatever leiningen uses (nobody knows what its called)
17:00AeroNotixComing from Erlang/Rebar+Python/PIP it's a whole new world.
17:00jacortinassdegutis: Maven?
17:01sdegutisno, clojars
17:01sdegutisor whatever
17:01zerokarmaleftnpm got a lot of things right
17:01technomancyjacortinas: Maven and Leiningen both use Aether
17:01jacortinasah ok
17:01sdegutisoh, aether.
17:01insamniacmake up your mind!
17:01sdegutiswhy not name it Dragicorn?
17:01technomancyzerokarmaleft: having JS modules be first-class data structures helps a lot there
17:01technomancy(the one thing JS does better than clojure)
17:02sdegutishttp://bit.ly/1nrYLp0
17:02insamniacThis channel makes me feel dumb all day.
17:02sdegutisinsamniac: isnt it awesome?
17:02technomancysdegutis: you can suggest a rename: https://bugs.eclipse.org/bugs/buglist.cgi?query_format=specific&amp;order=relevance+desc&amp;bug_status=__open__&amp;product=Aether
17:02insamniacIt's refreshing, but I kind of like feeling like a hero at work all day too.
17:02sdegutiscant.
17:03technomancysdegutis: you can if you believe in yourself
17:04insamniacYou forgot to drop the mic.
17:04sdegutisha
17:04sdegutisback to manipulating the DOM directly via clojurescript
17:05technomancymodern technology is getting to the point where it can glare back
17:05technomancydammit
17:05sdegutisha
17:05insamniacanyone here use parkour?
17:05insamniacwe have some hadoop project coming up
17:06bbloomtechnomancy: javascript's modules are only first class because javascript doesn't have anything even approaching modules
17:06bbloomtechnomancy: it's easy to make something first class if it's also practically useless :-P
17:07ddima_insamniac: no idea about parkour, but another solid alternative would be cacalog
17:07ddima_err, cascalog
17:07rhg135modules are maps there
17:07technomancybbloom: well, there's a silver lining to that cloud
17:07insamniaci like caca log
17:07ddima_it's the best
17:07insamniaci just mean i like the typo. never heard of it!
17:08insamniacI won't be able to sell anyone on using anything but Java probably anyhow.
17:08ddima_i knew you meant the typo :)
17:08insamniaci knew you knew i knew
17:08ddima_insamniac: once they see what a job of moderate complexity looks like in java they will at least go for pig probably
17:09ddima_one could use cascading though, but then jumping to cascalog is not a big step anymore. It's not that pig is much easier to grasp than some clojure dsl.
17:12seangroveWish there was a gofmt for clojure
17:12seangroveerm, and cljs
17:14hyPiRionbut there is
17:15hyPiRionseangrove: alias cljfmt='emacs --batch -l ~/.emacs.d/init.el --eval='(clojure-mode)' --eval='(indent-region (point-min) (point-max) nil)' -f save-buffer'
17:15locksand I bet it’s even customizable
17:15seangrove
17:15seangrovehyPiRion: Clever. But not all the way there
17:16seangroveAlso looking to enforce things like "one line of separation between defs"
17:18technomancyknowing where to add \n can be tricky too
17:18sshackAre there any tutorials.examples of web apps using friend with an sql backend?
17:18arkhanyone know what causes the following on perfectly valid ns syntax: "ArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473)"
17:19arkhin one project, it give me that error but in another project, essentially the same syntax, it doesn't error
17:19arkh*gives
17:21turbofailit'd probably help if you showed us the syntax
17:22arkh(ns foo.bar.baz (:use [vertigo.structs]))
17:23arkhfrom 'lein repl', if I (load-file "src/foo/bar/baz.clj) I get that error but not in another project
17:23arkhsorry ... long day and it makes no sense
17:35hiredmanbrehaut: it was basically a recap of his strangeloop presentation, with a little more focus on cassandra
17:35brehauthiredman: thanks
17:38bbloomdnolen: do you know of a handy list of X where there exists a CLP(X) ?
17:39dnolenbbloom: hmm, I don't - and people implement new domains fairly regularly
17:39bbloomdnolen: i figured that they did, but i was hoping to see a list of like "here's ones that people agree are generally worth studying or knowing of"
17:40tbaldridgeCLP(all-the-things)
17:40bblooma friend of mine is doing some procedural generation for a game & he's trying to improve the uniqueness of the results without creating totally alien impossible things
17:41bbloomi was wondering if CLP of some sort might be helpful
17:44seangroveWho's generally taking care of clojars these days? I suppose it's not the same burden as npm given it's able to ride off of maven repos, but it still seems like npm struggles *a lot* more
17:45bbloomseangrove: npm struggles for a few reasons 1) a totally unscalable design 2) massive abuse of a central repository (seriously people, host your own packages for production) 3) crazy unjustified popularity of javascript ... etc
17:46stompyjI think the difference is that clojars is written in clojure, and npm is written in node *cough*
17:46stompyjjk
17:46bbloomstompyj: lol but no seriously, you're not that far off
17:46technomancybbloom: no, it is
17:46technomancyit's the difference between couchdb and nginx
17:47brehautcouchdb O_O
17:47bbloomtechnomancy: sure
17:47technomancyactual downloads of packages don't hit any dynamic code in either case
17:47technomancybrehaut: it actually makes mirroring really easy
17:47technomancybut no one uses mirrors because it's easier to just hammer the central repo
17:47brehauttechnomancy: win!
17:50sdegutistechnomancy: btw, have you seen that guy's response to your response to my response on HN about the problem with Marmalade?
17:51sdegutishttps://news.ycombinator.com/item?id=7114490
17:51technomancysdegutis: somehow I remain unconvinced =)
17:52technomancyactually that's crap anyway; with marmalade you try to get teh original authors to submit too
17:52sdegutisseems like a major flaw to me, that anyone can push to any given marm package
17:52technomancyyeah, if someone squats on a package with a fork and the original author comes along, the marmalade guy will give them the name
17:53sdegutisoh
17:53sdegutisbbloom: #3 is totally right on
17:54sdegutisin it self it just mystifies me
17:54bbloomi mean, node has its (limited) uses & i'm glad it exists and is maturing
17:54bbloomi'm just glad that other suckers are trying to build scalable infrastructures on it so that my puny use cases for it aren't problematic
17:55seangrovebbloom: Hrm, what're your use cases?
17:55technomancythe npm guys don't really understand couch all that well either
17:55brehauttechnomancy: being one of the people melpa crapped on, i agree with your position ;)
17:55technomancythey were putting password hashes in unprotected fields for years, and then also http://writing.jan.io/2013/12/19/understanding-couchdb-conflicts.html
17:55bbloomseangrove: pretty much just builds for front end code
17:56seangrovebbloom: Ah, so compilation tooling, more or less?
17:56technomancywell, they didn't understand it when they originally designed it. they probably understand it better now.
17:56bbloomseangrove: primarily, which also includes to a limited extent something like react-page
17:56bbloomseangrove: https://github.com/facebook/react-page
17:56bbloomseangrove: but there are alternatives that are preferable there: like clojure + clojurescript
17:57sdegutisbrehaut: you mean you were bit by it too?
17:57brehautsdegutis: i was part of the stream of people technomancy helped because i had melpa in my config when i didnt want it
17:57sdegutis:)
17:57sdegutiswas this back when Magit broke?
17:57technomancy"My Emacs is broken" / "Are you using melpa?" / "Yes" / "Well then."
17:58sdegutisi was bit hard by that.
17:58technomancy^ basically a weekly theme either in here or #emacs
17:58brehauttechnomancy: followed by "what is melpa?"
17:58technomancybrehaut: those are the worst, yeah =/
17:58brehauttechnomancy: sorry :(
17:58technomancybrehaut: not your fault
17:58sdegutisAnother reason I don't touch my init.el is because I'm afraid of breaking muscle memory.
17:58technomancybrehaut: it's people putting "just copy/paste this snippet into your config" in their readme without explaining it
17:59sdegutisFor example, newer versions of Magit changed the shortcuts, so it's doing all sorts of things I don't expect or even want.
17:59brehauttechnomancy: weell, i should know by now not to just cargo cult
17:59sdegutisbrehaut: cargo-culting is a legitimate and time-honored way to get started with emacs
17:59deadghostcargo culting is a good way to begin in a lot of things
17:59brehautsdegutis: and still wrong ;)
18:00technomancyI think it's feasible to limit the cargo-culting to "install this set of packages"
18:00sdegutisbrehaut: it's impractical to start learning everything about how emacs works when you're just getting started. You just copy bits/pieces from other people's configs that make your stuff work right, and learn why afterwards.
18:00technomancyif you install packages one at a time, you'll have a better chance of understanding what each one does
18:00deadghost1. start using something 2. decide it sucks 3. recur
18:01sdegutisSpeaking of deleting repos, does anyone want to fork https://github.com/sdegutis/LVReplClient ?
18:01technomancydeadghost: catch StackOverflowException -> become a carpenter
18:01AimHereMaybe there should be an emacs-from-scratch install, where it just gives you the lisp interpreter and the minimal set of lisp things and tells you to built it yourself from then on
18:01technomancyAimHere: no, start with SKI
18:01technomancyor maybe logic gates
18:01brehauttechnomancy: SKI is for lazy people. Start with SK
18:02sdegutisI really want to see an Emacs Reboot.
18:02technomancybrehaut: touché
18:02sdegutisLike, a minimalist program with a similar language to Emacs Lisp, and a similar API for handling text, but with less 1980s baked in.
18:02seangrovesdegutis: It's pronounced "LightTable", I believe
18:02bbloomlol
18:03seangrovesdegutis: It just needs another decade or so to fully form
18:03technomancysdegutis: rms goes back in time and prevents his past self from writing a lisp-2, creating an alternate timeline in which elisp is actually not a terrible language for doing FP
18:03technomancyexcept there are romulans and stuff
18:03turbofailneeds moar borg
18:03deadghostI'd watch that movie
18:03sdegutisseangrove: Something about compiling Lisp into JS and running it inside a WebView just makes me feel all weird inside.
18:03brehauttechnomancy: how could you tell which is evil RMS though? the tiny beard is going to be lost in wild hill man beard
18:04brehautor does the beard have a beard?
18:04technomancybrehaut: mind_blown.gif
18:04AimHereRMS is beard all the way down
18:04seangrovesdegutis: Well, give it time
18:04sdegutisseangrove: I thought the ClojureScript route was only for prototyping, and then it suddenly became the official thing. That confused me.
18:05technomancysdegutis: it sounds like embracing the madness of the modern stack instead of staunchly insisting on DTRT
18:05sdegutisseangrove: Plus I'm very skeptical of any API design. But simpler always seems better, and LT's API seems complex right off the bat.
18:05technomancyproblem is that staunchly insisting on DTRT leads you to either loper-os or opengenera
18:05dnolensdegutis: it's actually an incredibly simple system.
18:06sdegutisdnolen: Oh? Can you recommend a specific write-up describing it?
18:06dnolensdegutis: http://www.chris-granger.com/2013/01/24/the-ide-as-data/
18:06dnolensdegutis: writing a hello world plugin is ridiculously easy
18:06sdegutisdnolen: Sweet.
18:07dnolensdegutis: all the hard stuff is interacting with Node, WebKit, CodeMirror
18:07sdegutisMy only other objection was arrogance (I didn't write the IDE myself) and that one has to go cuz it ain't founded in any kind of sanity.
18:07arkhI finally have my problem down to the simplest case: 1) do a 'lein new baz' 2) in your new project.clj, add as dependencies [aleph "0.3.0"] and [vertigo "0.1.1"]. 3) make this the contents of your src/baz/core.clj "(ns baz.core (:require [vertigo.structs :as vs]))" 4) breaks when loaded
18:07sdegutisdnolen: That sounds kinda painful. I've been writing ClojureScript interacting with the DOM this afternoon and it's not pleasant at all, even with Dommy.
18:08seangrovesdegutis: It also seems like ibdknox's approach of allowing plugins to fundamentally change anything means it'll grow along the lines of emacs
18:08technomancydrracket might qualify on the "staunch dtrt" front actually
18:08technomancyreading about racket's approach to image handling just made me sad about quil
18:08dnolensdegutis: Dommy doesn't really try to fix anything, nor does LT fundamentally
18:08dnolensdegutis: try React, Reagent, or Om for something more sensible
18:08sdegutisdnolen: Sounds like it needs some good third party wrapper APIs.
18:08sdegutisOh.
18:09sdegutisThanks for the recommendations, I'll check them out dnolen.
18:09TEttingerarkh, what kind of breaks?
18:09arkhTEttinger: ArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473)
18:10seangroveWe should probably find someone local who can talk on reagent
18:10seangroveThen we can divide the next meetup into three talks: React, Om, Reagent
18:10arkhTettinger: I did a (load-file "src/baz/core.clj") at a repl
18:10dnolenHoplon looks cool too, though I haven't looked at it closely enough to understand how you model components or if the model more less obviates them
18:11insamniacs/re le/re or le/
18:12sdegutistechnomancy: dtrt = do the right thing?
18:12TEttingerarkh, I'll try to reproduce
18:12arkhTettinger: awesome!
18:12sdegutistechnomancy: opengenera exists!?
18:13technomancyyeah
18:13technomancyclojurebot: DTRT is do the right thing
18:13clojurebotIn Ordnung
18:13technomancyopengenera ... mostly exists?
18:16TEttingerarkh, I can reproduce.
18:16ztellmanarkh Tettinger: this is my fault?
18:16TEttingerI am guessing it's a problem in a lib
18:17TEttingerztellman, is vertigo yours?
18:17ztellmanyup
18:17TEttingerI guess I should have checked the google ads
18:17arkhztellman: I was going to try to contact you next : )
18:17ztellmanvertigo is one I haven't used in a production context yet
18:17arkhTEttinger: thank you for trying it
18:17ztellmanjust a sec
18:17TEttingerno prob arkh
18:19TEttingerztellman, it looks like you need a new version! https://github.com/ztellman/vertigo/compare/0.1.1...master
18:20ztellmanTEttinger: coming to that conclusion, yeah
18:20TEttingeror could arkh use the snapshot, is it published?
18:22ztellman0.1.2-SNAPSHOT should be there, but it's also marginally out of date
18:25aperiodictechnomancy: what were you reading about racket's image handling that made you sad about quil?
18:25technomancyaperiodic: the first chapter of htdp.org, oh man
18:26technomancyit starts with numbers and how to do arithmetic
18:26technomancythen it goes on to strings and how to append them, upper-case them, etc
18:26technomancybut how they're all just values you call functions on
18:26technomancythen it's all «oh yeah, and you can do "arithmetic" with images too»
18:27technomancythey're first-class values that display in the repl; you can compose them like data
18:27technomancyquil is all "here's a function to draw a line on the screen" or whatever; very imperative and primitive =\
18:27hiredmanoverloading math :(
18:27technomancyhiredman: it doesn't overload the actual symbols
18:28technomancyit's just a way of saying "these are all values you can do things with"
18:28aperiodicyeah, i understand pragmatically the motivation to build on top of processing, but it's basically impossible to escape its imperative paradigm
18:29aperiodiceverything you do is a side-effect on a graphics buffer
18:32sdegutis"oh, camel! you so silly!"
18:32arkhztellman: looks like vertigo 0.1.2-SNAPSHOT does the same. I'll just have to wait for the next version! Thank you
18:32sdegutisI don't think there's actually a topic for this channel, right? It's just kind of like, in-general programming-ish, right?
18:33technomancysdegutis: maybe you're thinking of #emacs
18:33technomancythis was the "argue about haskell" channel until like a week ago
18:33sdegutisWhen will it be the argue-about-ocaml channel?
18:33arkhI thought that was just that one guy, instigating problems
18:33technomancyarkh: well yes
18:35TimMceternal haskember
18:37TimMchahaha
18:40TimMcI should really have irssi write my logs file-per-day
18:40TimMcMy log for this channel is over 1000000 lines long.
18:41xuserso bitemyapp finally ditch clojure for haskell?
18:42`cbpI believe he uses clojure at work
18:43sdegutisBut Haskell is more fun.
18:43`cbp~guards
18:43clojurebotSEIZE HIM!
18:44sdegutisI started reading Learn You a Haskell, and so far it's just Clojure, but without parentheses, and everything is wrapped in an implicit (fn ...)
18:45RaynesYou haven't read much then.
18:45sdegutisOh right, it also does static typing.
18:54AeroNotixsd
19:04ztellmanarkh: try vertigo 0.1.3
19:04ztellman0.1.2 was tragically lost in a dependencies mishap
19:11TEttingersame error ztellman
19:11ztellman!
19:11TEttingerI'll try cleaning first?
19:12TEttingerit's an arity issue still.
19:12TEttingerArityException Wrong number of args (2) passed to: namespaces$import-fn clojure.lang.Compiler.macroexpand1 (Compiler.java:6473)
19:12ztellmanwhy is the test suite not catching that
19:12ztellmanok, back to the drawing board
19:14TEttingeroooh
19:15TEttingerztellman, if I use the ns that requires vertigo.structs (might have spelled it wrong): Exception namespace 'vertigo.primitives' not found clojure.core/load-lib (core.clj:5380)
19:15ztellman...
19:16ztellmanI mean, it's there
19:16ztellmanthat's also something which uses import-fn, so maybe it's related
19:23ztellmanarkh: ok, figured out your issue, which wasn't the one I was tracking down
19:23ztellmanadd [potemkin "0.3.4"] to your depdnencies
19:23`cbpMan I thought compiling c was hard but then i stumbled upon clojurescript
19:23ztellmanor exclude potemkin from the aleph dependencies
19:24mikerodHaskell is just like Clojure, without all of the awesome
19:25`cbpwithout all of the java? ;)
19:25mikerodi.e.: (remove the-awesome Clojure) ;= Haskell
19:25eggheadhuh...
19:25mikerodjust joking, I don't know enough to say that :)
19:25technomancy(remove NullPointerException Clojure)
19:25brehautremove the-awesome Clojure #= haskell ;)
19:25eggheadmikerod: clojure is just like haskell.. without all the types?
19:25mikerodtechnomancy: that was a good one. haha
19:27tjdi'm looking for a way to "map
19:27tjd"map" a hash map, something like (defn f [k v] [k (+ v 1)]) then (map f {:a 1 :b 2}) and have the result be {:a 2 :b 3}
19:28`cbpAm I missing something? I can't seem to find docs for cljs compiler options
19:31TEttingertjd, I think that's kvmap?
19:33tjdTEttinger: i can't find taht in standard library
19:34TEttingeryeah I was confused
19:34TEttingeryou can map over hashmaps, it just has entries
19:34TEttingertjd: ##(letfn [(f [[k v]] [k (+ v 1)])] (map f {:a 1 :b 2}))
19:34lazybot⇒ ([:a 2] [:b 3])
19:35tjdyeah, and i can reconstitue the result of that map into a hashmap, its just kind of a pain in the butt
19:35TEttingertjd: ##(letfn [(f [[k v]] [k (+ v 1)])] (into {} (map f {:a 1 :b 2})))
19:35lazybot⇒ {:a 2, :b 3}
19:35whilo`cbp: have you had a look at: https://github.com/clojure/clojurescript/wiki/Quick-Start ?
19:36mikerod,(into {} (map (juxt key #(inc (val %))) {:a 1 :b 2}))
19:36clojurebot{:a 2, :b 3}
19:36mikerod(into {} (map (juxt key (comp inc val)) {:a 1 :b 2}))
19:37mikerod,(into {} (map (juxt key (comp inc val ) {:a 1 :b 2}))
19:37clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
19:37whiloztellman: at euroclojure we talked briefly. with critical theory and frankfurt school i meant especially http://books.google.de/books?id=l-75zLjGlZQC&amp;printsec=frontcover&amp;hl=de#v=onepage&amp;q&amp;f=false
19:37TEttingeryou could just declare a function that does this. (fn [f coll] (into {} (map #(f (first %) (second %)) coll)))
19:37mikerod,(into {} (map (juxt key (comp inc val)) {:a 1 :b 2}))
19:37clojurebot{:a 2, :b 3}
19:37whilodon't know if you know it, just for reference
19:38TEttinger,(defn map-map [f coll] (into {} (map #(f (first %) (second %)) coll)))
19:38`cbpwhilo: yeah. I still can't figure out how to add .js libraries though
19:38clojurebot#'sandbox/map-map
19:38tjdawesome!
19:38tjdi learned something
19:38`cbp(even though they're supposed to work with closure)
19:38TEttinger,(map-map + {1 10 2 20})
19:38clojurebot#<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Long {:instance 11}>
19:38TEttingeruhhhh I might have screwed up
19:39mikerodtjd: my example was just trying to use all built ins to do the job
19:39whilo`cbp i am not very experienced. the easiest i found was to include the js somewhere on the html page, use whitespace compilation and exploit the fact that symbols are not munged, so you can reference js objects just by their name
19:40whiloif your js library supports google closure you can compile it in, there was fairly little information on that. the easiest is to grab (or create) some extern file for your library, reference that once you move from whitespace compilation to optimized js
19:40mikerod,(reduce (fn [m [k v]] (assoc m k (inc v))) {} {:a 1 :b 2})
19:40clojurebot{:b 3, :a 2}
19:41sdegutisAeroNotix: Yes?
19:43sdegutismikerod: or maybe (->> clojure :features (remove awesome?))
19:43tjdthank you mikerod and TEttinger. i'm still learning and stuff like this really helps. cheers.
19:43mikerodsdegutis: indeed :P
19:46TEttingerah, here we go.
19:46TEttinger,(defn map-map [f coll] (into {} (map (fn [[k v]] [k (f v)]) coll)))
19:46clojurebot#'sandbox/map-map
19:46TEttingerthat one takes a function and a map, calls the fn on each value of the map, and keeps the same keys
19:47TEttingerthere's a way to do that with juxt too, but it's uh not as easy
19:47devnsuggestions on how to do this more efficiently: https://gist.github.com/devn/cf948a57216bb8eb83c6
19:48devnthe ref need not be there, fwiw
19:48devnthis is a CSV file that is around 200MB
19:48devnI want to very quickly find all distinct values for each column within that file
19:49TEttingerdevinus, hm? (dosync (alter r assoc header-name distinct-vals)) is at the last line, and r is the ref?
19:49TEttinger^ devn
19:49devnr is the ref there, yes
19:49devnbut i mean, try and use reducers, whatever
19:49TEttingeroh ok
19:49devni dont care how i do it, but i've been playing with solutions and am hitting a roadblock
19:50devnI think maybe loading this into a database is a requirement
19:50llasramdevn: Do you known that all distinct values for all columns will fit into memory?
19:50TEttingerwell are you sure of what the core.data.csv fns return?
19:50devnllasram: I do not.
19:50devnMy motivation for writing this is: I have 100 CSV files, from 1k to 1.2GB
19:51devnI know for a fact there are relationships between the data, but they are fuzzy connections
19:51llasramdevn: Also, trying to create a lazy seq which holds on to resources and releases them when the seq is exhausted pretty much guarantees that you'll have resource leaks
19:51devnthe column names do not match, for instance
19:52devnso I want to accrete all the discrete values for each colum, and when the number of discrete values for a column is more than 90% of all values found for a column (excluding empty? vals)
19:52devnso I can try and test whether or not they're related CSV files
19:52devnto find a common unique value between them
19:52devnto basically sniff out "ID"-esque columns
19:53devnllasram: yeah, im finding this out. again, looking for suggestions on a good approach
19:54devnTEttinger: I'm not realizing the core.data.csv result
19:54devnI'd have to do (doall ...) around it to realize it
19:54devnim running with Xmx2g and -server
19:54TEttingerI actually wrote my own (tab) separated value parser not long ago.
19:55TEttingerit wasn't hard
19:56devnyeah, it really isn't, but i've looked at core.data.csv and it looks fine
19:56devni dont think that's where the problem is
19:57llasramdevn: Actually taking a look at your code, you are definitely forcing the whole CSV to be realized in memory at once
19:58llasramYou bind the CSV to `rows`, then in the `doseq` iterate by column. After you finish the first column, `rows` can't be cleared (because you need it for the next column), but has been fully realized (because you've walked all the rows)
19:58devnllasram: that used to be a for
19:59devnthe doseq
19:59llasramSame problem
19:59llasramYou still need to realize the entire CSV in order to produce the results for a single column
19:59devnright, because i need distinct values
19:59llasramYou need to structure your code so that you walk the CSV row-wise, holding only a single row at once, and accumulating the results for all columns at the same time
19:59devnah, i see
19:59devnright that makes sense
20:00devnso i should reduce over it maybe
20:00devnand check whether i have that value or not
20:00devnand then continue walking
20:00llasramOr just add to sets
20:00devnyeah, good idea
20:00devnthanks llasram. much appreciated.
20:00llasramnp and good luck
20:04ztellmanwhilo: thanks, I'll give it a look
20:04kristofAll this talk about walking csv's feels eerily familiar
20:07turbofailalso make sure you don't hold on to the CSV sequence's head anywhere. if it's in a local variable, that will force the whole thing to remain in memory
20:07devnkristof: :)
20:08kristofdevn: Was that you?
20:08kristofA few days ago, maybe a week ago
20:08devnkristof: i have a TON of legacy data I'm trying to form relationships between
20:08kristofLegacy code SUCKS, YUCK
20:08devnkristof: perhaps. i've been mucking around with csv transformations
20:08devnkristof: it's kind of fun FWIW
20:08devnjust daunting
20:08devnwhich is why i want to write a tool to do this
20:09kristofdevn: Give me an example of what you're doing
20:09devna.csv is a 500MB file of information, like first name, last name, a, b, c, d, e, etc.
20:10devne is actually concatenated from a c d, it serves as a key
20:10devnin all other tables, i want to check to see if the value in e exists, and if it does, i want to form a relationship to that table from my table+column, to its table+column
20:11devnkristof: ^
20:11safetyis there a way to get a running total of a vector without using loop? e.g. [1 2 3] -> [1 3 6]
20:12devnsafety: reductions
20:12safetynot sure how to reduce to a vector
20:12kristofinto
20:13kristofer
20:13turbofail##(into [] (reductions + [1 2 3]))
20:13lazybot⇒ [1 3 6]
20:13kristof"reducing to a vector" makes no sense. reduce is a mapping from a collection of a's to an a
20:13kristofor some b, actually
20:13kristofah right reductions
20:13technomancywhut
20:13safetyturbofail: thanks!
20:13kristoftechnomancy: where's the what coming from
20:13devn,loop
20:13clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/loop, compiling:(NO_SOURCE_PATH:0:0)>
20:13devnwhoops
20:13devn,([] [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5])
20:13clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (5) passed to: PersistentVector>
20:14devnahhh!
20:14devn,(reductions (fn [res x] (conj res x)) [] [1 2 3 4 5])
20:14clojurebot([] [1] [1 2] [1 2 3] [1 2 3 4] ...)
20:14technomancy"reduce is a mapping from a collection of As to an A"
20:14kristoftechnomancy: corrected in the subsequent statement since the return value can be of any type, the point being that it's always a single value
20:14turbofaila single value that might be a sequence of values
20:15kristofI can't think of a scenario where you reduce over something and end up with a collection
20:15technomancyI literally just did that a few hours ago
20:15kristofwhat was the scenario?
20:15technomancywell, it was erlang
20:16kristofstill relevant
20:16technomancyit was in order to map and filter in a single pass
20:16brehaut,(reduce conj () [1 2 3])
20:16clojurebot(3 2 1)
20:16devnbrehaut: i like to keep it verbose :)
20:16technomancybut I reduce into maps in clojure fairly frequently
20:16kristofbrehaut: I meant something useful :P
20:17kristoftechnomancy: oh, that's a good point
20:17kristofI think I was just thinking of lists and vectors
20:17devnkristof: if you never ended up with a collection
20:17devnwhy would reduce-kv even exist?
20:17devni suppose that's /over/
20:17devnnevermind
20:17devnbut yeah, i build collections all the time with it
20:17devnit's not uncommon at all
20:18kristofhmmm
20:18kristofoh, related: is there an unfold/unreduce in clojure?
20:18devnnot that im aware of
20:19hyPiRionkristof: I think the confusion is partially coming from the reduction definition in parallel programming terms is usually considered to be to a single A.
20:19devnyeah, that's a good point
20:19kristofhyPiRion: yeah
20:19devnand frankly, i remember learning reduce
20:19devnthe canoncial example was reduce + [1 2 3 4 5 6]
20:19brehautkristof: if you discard returning collections from reduce you have just made map, filter… a lot harder to write
20:20kristofbrehaut: Are those implemented in terms of reduce? I had no idea!
20:20devnit's a building block
20:20brehautkristof: well they can be. i think they may be a big squirrly maze for performance reasons
20:20brehautkristof: reduce is just 'primative recursion' abstracted as a function
20:21jajajaAnyone using Clojure on a VM with 1GB RAM or less?
20:21brehautjajaja: yes
20:21devnfilter isn't written in terms of reduce
20:21jajajaWondering how pared down you can get the JVM if tuned properly
20:21brehautjajaja: i run two clojure apps on a VPS with only half a gig
20:21turbofaildevn: it could be
20:21brehauttheres room to spare
20:21devnturbofail: sure
20:21devnim just saying it isn't
20:21devni believe the same is true for map
20:21devnbecause it defers to applyTo
20:21jajajabrehaout Great! I'm new and had my doubts
20:21devninside apply
20:22jajajabrehaout Also room for db and mailserver?
20:22brehautjajaja: i have no idea about mailserver because im not crazy / have copious spare time but yes. ive run postgres and couch concurrently with those two apps
20:22devnbrehaut: 16g is a lot
20:23devnerr, jajaja
20:23jajajabrehaout Did you need to tune your JVM a lot?
20:23brehautjajaja: i didnt tune it even a bit
20:24brehautit'll obviously depend on your app / load whether thats necessary
20:24brehautjajaja: surely your irc client autocompletes nicks?
20:24jajajabrehaout What's the first thing that happens when a JVM runs out of memory?
20:24brehauti dont know. its never run out of memory
20:25jajajabrehaout Does it handle the situation gracefully?
20:25turbofailit throws an exception
20:25brehauthow would i know this
20:25turbofailand then dies
20:25jajajaturbofail So not quite so graceful
20:26kristofjajaja: Why don't you try it?
20:26turbofaili don't think any system really handles running out of memory gracefully
20:26turbofailif you can't garbage collect anymore, what else are you going to do?
20:26devnmonit
20:27devnthat's what you do in that case
20:27devnmonitor it and fire an alert
20:27jajajaSwap to disk?
20:27turbofailjajaja: well you can do that by just giving java a max heap size larger than your physical memory and enabling swap in the OS
20:27devnjajaja: load test it
20:27jajajaturbofail That could be handy to know
20:28jajajaBetter than dying, maybe
20:28devngive it an order of magnitude more queries/connections/whatever, and run some tests
20:28turbofailthat said without an SSD (or maybe even with an SSD) relying on swap is probably not going to be a great experience
20:28jajajadevn Will do
20:29jajajaturbofail Thinking more of a last resort, obviously
20:30devntaking the time to verify your stuff works in production under load is so important when you get an alert that's like: "OMG I'm dying!"
20:30`cbpwhilo: hi, just read your comment. Yeah I think I need to make an extern file. Need to figure that out somehow. I'm trying to compile react + om with advanced optimizations. Thanks for your help
20:31aperiodicyou can definitely run two clojure webapps, postgres, and a mailserver all with less than a gig of RAM
20:31aperiodicIn fact, this box is running four clojure webapps, postgres, a mailserver, and irssi
20:31devnaperiodic: depends on the traffic
20:31jajajaaperiodic Good to know. I have a number of clients who run everything on VMs with 1GB RAM
20:32aperiodicdevn: yeah, none of them get very much traffic. YMMV
20:32devnaperiodic: i've run lots of stuff on a tiny VPS before
20:32devnbut i've also watched kingdoms crumble when GC limits got hit
20:32devnmore time spent in reclamation than performing tasks
20:33turbofaillook upon my heaps, and despair!
20:33devn:D
20:33jajajaaperiodic devn: I read somewhere that beyond the startup memory allocation the JVM is more efficient under load than, say a Rails app because it doesn't have to spawn a new process for every request
20:34turbofailhm, looks like i left out "ye mighty"
20:34kristofdevn: Is there an implementation strategy for really, really large applications where you almost entirely decouple two big chunks of a program and garbage collect them separately?
20:34kristof...I think I just described distritubed computing.
20:34aperiodicdevn: did you ever explicitly set the max heap size and have the JVM die on OOM?
20:37aperiodicthat's what we used to do when we were running HBase on AWS machines with crappy disks at my old job, and it really helped to avoid instances getting bogged down in GC
20:45quizdrI can't understand why (map #(-> (% 2 4)) '(+ - *)) doesn't simply return the value of the function (-> (% 2 4)) for each fn in the map, as you'd expect a map to do.
20:45quizdr,(+ 2 4)
20:45clojurebot6
20:45quizdr,(map #(-> (% 2 4)) '(+ - *))
20:45clojurebot(4 4 4)
20:49quizdri'd have expected 6 for the first value in the map's return, for example
20:51aperiodicquizdr: i can't understand either. i suspect it has something to do with the fact that you're mapping over symbols, since ##(map #(% 2 2) [+ - *]) does what you'd expect
20:51lazybot⇒ (4 0 4)
20:52aperiodicquizdr: and so does ##(map #((resolve %) 2 4) '(+ - *))
20:52lazybotjava.lang.SecurityException: You tripped the alarm! resolve is bad!
20:53quizdrhm, that's interesting. very curious why that happens.
20:53aperiodicbut i don't understand what exactly is going on in the example you provided
20:54sdegutisThis is a weird client.
20:55aperiodicquizdr: ##(map #(% 1 2 3) '(+ - *))
20:55lazybotclojure.lang.ArityException: Wrong number of args (3) passed to: Symbol
20:57hyPiRionquizdr: It's because symbols are ifns themselves
20:57hyPiRionIt's a weird thing
20:57hyPiRion,('foo 'a 'bar)
20:57clojurebotbar
20:58quizdrwhat is "ifns" ?
20:58hyPiRionWell, I say "weird". They work just like keywords.
20:58quizdr,('+ 4 5)
20:58clojurebot5
20:58hyPiRionifns are values which are also functions. E.g. sets, maps, vectors, keywords and symbols are all IFns.
20:58turbofail,('+ {'+ 8} 5)
20:58clojurebot8
20:59quizdrso what exactly is happening with '+ as the operator?
20:59turbofailquizdr: see above
20:59hiredman'+ is the quoted symbol +
21:00turbofailit's roughly similar to (get 4 '+ 5)
21:00hyPiRionquizdr: it tries to look itself up in the first argument, and if the first arg is not a map or doesn't contain the symbol, it returns the second value (or nil, if none is passed).
21:00hyPiRionyeah, turbofail got it
21:00quizdrah
21:00quizdrthe final value is the "if not found" value
21:00hyPiRionyes
21:01quizdrok that explains, man, thanks a lot. that was going to bother me all day
21:01quizdr(inc hyPiRion)
21:01lazybot⇒ 32
21:01hyPiRion:D
21:06quizdr(inc turbofail)
21:06lazybot⇒ 1
21:15fortruceis there a clean idiomatic way to re-bind a local based on a predicate without dealing with dynamic, it seems like there should be an easy way to accomplish this (https://gist.github.com/fortruce/8725445) without repeating '(format)' in an if
21:17brehaut'rebind' a local?
21:18brehautyou cant rebind a local, clojure is a single assignment language (for locals). you can shadow it however, but thats practically identical to introducing a new local
21:18brehautztellman might have a library for you though
21:19fortrucei'm sure my terminology is off, if you look at my gist, i am wondering if it is necessary to repeat my format command
21:19brehautfortruce: however, you could simply move your let and if inside the format (or bind s' outside)
21:19llasramfortruce: Are you looking for `cond->` ?
21:19alandipertfortruce: https://www.refheap.com/30118 is another way
21:19llasram(or `as->`)
21:20brehautwhat alandipert just said
21:20fortrucealandipert: thats exactly the easy solution I can't believe I missed, thanks
21:21brehautfortruce: fwiw a pluralizer without an optional plural form is broken by design ;)
21:22fortrucebrehaut: thats a good point, i'll add another arity to let you specify the plural form :p
21:22brehautyup
21:22brehautenglish is to wacky to be cattered to by simple functions
21:24fortrucethanks for the help
21:25Bronsafortruce: or you could just use cl-format
21:26Bronsa,(clojure.pprint/cl-format nil "~r car~:p" 1)
21:26clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.pprint>
21:26Bronsa,(require 'clojure.pprint)
21:26clojurebotnil
21:26Bronsa,(clojure.pprint/cl-format nil "~r car~:p" 1)
21:26clojurebot"one car"
21:26Bronsa,(clojure.pprint/cl-format nil "~r car~:p" 2)
21:26clojurebot"two cars"
21:30fortruceBronsa: I'll keep that in mind, the docs for it are a little overwhelming atm
21:30ztellmancl-format is such a clown car
21:32sobelis nil a value?
21:33brehautclojurebot: cl-format is such a clown car
21:33clojurebotIn Ordnung
21:33sobeli want to say no, since there is a special function to test for it
21:33brehaut~cl-format
21:33clojurebotcl-format is such a clown car
21:33llasramsobel: But then what of `zero?`
21:34sobelllasram: wait until you see my code for ... `seven?`
21:35sobelall seriousness aside, zero? is syntax-sugar, right?
21:35llasramheh
21:35llasramBut how is it less so than `nil?`?
21:35llasramOr more so
21:35llasramWhatever
21:35sobeli guess it works out the same if nil? is shorthand for (= % nil) (i may have butchered that expression...new at clojure)
21:36sobelbut the reason i asked, is it's really handy for nil<>nil
21:36brehaut,(source nil?)
21:36clojurebotSource not found\n
21:36brehaut(source nil?)
21:36sobeli use this in SQL land a lot
21:36sobeli am translating nil as NULL
21:36llasram,(= nil nil)
21:36clojurebottrue
21:37sobelin theory, null is not a value. = is not defined on not-a-value. the result is not a value.
21:37sobel(relational)
21:38llasramYeah, that's not the case on the JVM or in Clojure
21:39sobelwell, it's complicating my recursive sexpr :)
21:39llasramOh?
21:39fortrucebrehaut: https://www.refheap.com/30125
21:39sobeli'm sure it's nothing interesting, i'm just doing 4clojure tutorials
21:39sobelthinking like a sql guy
21:40brehautfortruce: sure
21:40sobelbuuuut this is functional not declarative, so i'm sorta grappling
21:40brehautwho said functional isnt declarative?
21:40brehautthe terms arent mutually exclusive
21:42sobelfair nuff
21:52technomancy...?
21:53technomancywould you expect zsh to look in .bashrc?
21:54taliosno - but if you're going to put things in "the local maven repository", that's not a hard coded value.
21:54arkhztellman: thanks! I'll try that tomorrow
21:54technomancytalios: of course not
21:54technomancyjust set :local-repo in your user profile
21:54taliosdoes that eval environment variables?
21:55taliosor... can it?
21:55taliosI'm doing dynamically located local repositories.
21:57taliosmmm, I guess I can get around it with symlink love actually
21:58technomancyyou can use ~(System/getenv "STUFF"), sure
21:59technomancythere is no aether-wide config file though
22:01taliosmmm, actually - I don't need to. I misread arbscht's code review comment.
22:02taliosgetting jenkins to do adhoc pipelining of builds based on the gerrit review branch/topic
22:02taliosworking quite well. will need to do the :local-repo thing at some point I suspect tho.
22:15hola_Really basic question about immutable data: if in a large app some part can modify a data structure what does it matter whether a new copy is created or the original is mutated?
22:16hola_You can still end up with unexpected changes whether via re-bindig or mutation
22:19brehauti think you are going to have clarify your question a lot.
22:20hiredmanhola_: it depends on what you mean, but if you have an immutable structure, and it is immutable, someone else can do whatever, but your structure is fine
22:22hola_As I understand it Clojure's immutable data structures are a bit like git commits ie. the latest version is the earlier version plus the last change, no?
22:23hola_Rich Hickey is selling the advantages of immutable data structures based on retaining historicity but as I understand you can only ever reference the current version of a Clojure data structure, not earlier versions
22:23hiredmanhola_: but if you want to keep the old versions, you can, but for example, with a mutable hashmap, if you put a new value in, you have destroyed the old version
22:23hola_You can't roll back, say, a few changes to a vector once you've added something to it
22:24hiredman,(let [x {:a 1} y (assoc x :a 2)] [x y])
22:24clojurebot[{:a 1} {:a 2}]
22:24hiredman,(let [x (doto (java.util.HashMap.) (.put :a 1)) y (doto x (.put :a 2))] [x y])
22:24clojurebot[{:a 2} {:a 2}]
22:26hola_I'm aware there are data structures to handle mutability (eg. records). It's just that I don't quite undertand how the basic immutable data structures in Clojure save you from all the unintended consequences Rich claims they circumvent.
22:28brehauthola_: perhaps you need to suggest some specific examples that you dont understand rather than waving an abstract cloud of "all" around? its hard to refute or discuss a vaguery
22:28hola_If I add an element to a vector, for example, and don't rebind it to a new variable I end up, effectively, with the same result as an assignment in a non-functional programming language
22:28john2xhow do I update my dependencies, other than visiting each project's page to check if my they're are up to date?
22:29brehautif nobody else holds a reference to the original vector thats true
22:30hiredmanjohn2x: don't update deps unless you need to
22:30brehauthola_: however, that vector cant be changed at a later date by a black box function you call at a later date, whereas if it were an arraylist it could
22:32brehautits always up to you if you discard your old state, not a callee you need to pass that state too
22:33hola_(def arr [1 2 3 4]) (def arr (cons 5 arr))
22:33brehauthola_: def is a dev time feature; you dont rebind vars as part of the operation of a running program
22:33srrubyWhat are the advantages of using zippers vs postwalk? So far I've just been using postwalk.
22:35hola_brehaut I can save prior state in any language if I choose to by creating new variables so what's the big win with Clojure? See my example.
22:36brehautwhat example
22:37hola_I'm not trolling. The penny just hasn't dropped as to how immutable data structures automatically save you from anything.
22:37brehauthola_: nevertheless, what example are you talking about
22:37hola_(def arr [1 2 3 4]) (def arr (cons 5 arr))
22:37hola_The end result is just the same as mutating a variable in, say, Ruby
22:38brehauthola_: that is not remotely idiomatic clojure. dont use def for storage.
22:39brehauteven with (let [a [1 2 3 4] b (conj a 5)] …) its not the same as in ruby
22:39brehautbecause functions you call cannot mutate that vector
22:39hola_arr = [1, 2, 3, 4] ; arr.unshift 5
22:40hola_brehaut There are plenty of tutorials using def for storage
22:40brehaut(let [a [1 2 3] _ (any-function-ever a)) (= a [1 2 3])) ;; true. its completely invariant
22:40hola_.. and books
22:40dsrxarr = [1, 2, 3, 4]; arr2 = arr; arr.unshift 5
22:40brehauthola_: then there are plenty of tutorials that are wrong
22:41brehauthola_: its useful in a tutorial to explain repl exploration (as i said previously, dev time) but that is in no way how you write a program
22:41fortruceusing def to set up initial state for an example is a lot different than using def to change state in the middle of code...
22:42hola_I can understand if it's idiomatic but what I'm getting at is that the language itself, ie. immutable data structures, doesn't protect you from unintended consequences as Rich Hickey claims. What you're saying is .. only if you know how to write idiomatic Clojure
22:42chippieCan I use (iterate ...) to create a finite lazy-sequence? I have an extremely large sequence of dates, but it is not infinite. Aside from using lazy-seq directly, would the idiomatic way to do this in Clojure be to use (iterate ...), but return nil (or some other "end" marker) once the sequence end is reached, then wrap that with something like take-while? (take-while (complement nil?) (iterate ...))
22:42brehauthola_: consider the following JS: var a = [1, 2, 3]; any_function_ever(a); a == [1, 2, 3]; // no way to know if this is true or false
22:43brehauthola_: go ahead, write all your programs with mutable global storage. its no skin of my nose.
22:44hola_brehaut If you insert my example in the middle of this in Clojure the result would be the same
22:44dsrxhola_: nobody should or would write code the way you did in that example
22:44brehauthola_: no, it wouldnt. i used let. let introduces local, signal asignment bind. there is exactly no way in which you could change it
22:44brehauts/signal/single/
22:44brehautanyway its 4:30 on a friday. why am i on the computer
22:44hola_If you didn't use let it would blow up just the same
22:45brehautno it wouldnt
22:45hiredmanpeople coming from scheme often think def and let must do the same thing, but in clojure they are very different
22:45brehautyou are welcome to disagree of course, but you'll be wrong
22:46alandipertchippie: i find take-while+iterate pretty common, and use this myself: https://www.refheap.com/30149
22:46chippiealandipert: Thanks! :)
22:47chippiealandipert: Ah nice pattern
22:48alandipertchippie: i guess it's the same as (take-while pred (iterate f x)), which is a little more straightforward
22:49chippieNobody really talks about design patterns in functional languages (or at least, there's not a lot of literature out there about them), but they clearly exist.
22:51quizdrI'm getting a null pointer exception on this little code snippet, don't know why: https://gist.github.com/quizdr/8726329
22:53quizdrif r is nil, then using (r) as a cond should not run that branch in the cond, right?
22:54alandipert,(nil)
22:54clojurebot#<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)>
22:55alandipert,(let [x nil] (x))
22:55clojurebot#<NullPointerException java.lang.NullPointerException>
22:55quizdroh my
22:55quizdrok, thanks
22:55quizdrwhoops
22:56alandipertnp
22:57quizdrlol I fixed it by doing (not (nil? r)) before realizing that just r by itself would suffice
23:01gtrakanyone know elisp here? #emacs is no help.. . trying to debug a cider thing. read-from-string seems to inexplicably kill further execution.
23:30johnjelinekhihi all, how's it goin'?
23:31quizdrkeeping it real, johnjelinek
23:31johnjelinekway to be :)
23:31dsrxi'm keeping it complex, personally
23:31johnjelinekhad a question -- are you familiar with clojure.tools.namespace.repl/refresh?
23:31quizdrdsrx well at least you aren't imaginary
23:32johnjelinekI get errors when I try to do (clojure.tools.namespace.repl/refresh)
23:33johnjelinekhere's a pastebin of the error: http://pastebin.com/BYxuEB9M
23:33johnjelinekdoes that look familiar to you?
23:34seangroveHrm, I'd like to write an html parser in ClojureScript
23:35seangroveActually, I'd like to use an html parser written in ClojureScript, but I haven't seen any
23:35seangroveAny recommendations for writing a parser in cljs?
23:44dsrx(defn parseHtml [s] (.parseFromString (DOMParser.) s "text/html")) :P
23:44dsrxer parse-html
23:44dsrxack
23:47seangrovedsrx: Yeah, but I don't want to instantiate any html objects, I only want clojure data structures
23:49dsrxseangrove: ah, i see. there's hickory as well but in cljs it just uses DOMParser internally I think, but only ever returns clojure data structures
23:50seangrovedsrx: Ah, interesting, that looks like exactly what I'd like, but skipping the DOMParser bit. I wonder how the jvm-clj side it handled. Thanks!
23:53seangroveAh, Jsoup. Damn.
23:58carkparsing html isn't easy considering most of it is malformed
23:59seangrovecark: Yeup. But we'll approach it iteratively