#clojure logs

2014-12-28

00:04andyfHere it is: https://github.com/technomancy/leiningen/issues/1750
00:58kenrestivoalter-var-root is the monkeypatcher's dream
03:11suppithis triangle is killing me :(
04:11tuckerhey, can someone please explain to me how
04:11tuckerthe lazy seq in
04:11tucker(defn- coll-or-scalar [x & _] (if (coll? x) :collection :scalar)) (defmulti replace-symbol coll-or-scalar) ; <label id="code.replace-symbol.multi"/> (defmethod replace-symbol :collection [coll oldsym newsym] (lazy-seq ; <label id="code.replace-symbol.lazy-seq"/> (when (seq coll) (cons (replace-symbol (first coll) oldsym newsym) (replace-symbol (rest coll) oldsym newsym))))) (defmethod replace-symbol :scalar [obj oldsym ne
04:11tuckerbetter yet: https://github.com/stuarthalloway/programming-clojure/blob/e10099afa98f342647ab6ec89e826b360272c8c7/src/examples/replace_symbol.clj
04:11tuckerbreks the recursion
04:11tuckerbetter yet, how does lazy-seq work here?
04:12tuckeri don't understand how it can prevent the stack being blown
04:12tuckerthere is still recursion
04:14Dynastyis there an order in which macros are expanded? ie, are outer macros expanded first when there is a nesting situation?
04:28nuwanda_tucker: (seq col)
04:28nuwanda_is an idiomatic way of saying not-empty? col
04:39Manaphy91Why if I have a namespace like a.b-c and in `b_c.clj` I have a typed named `Foo` I need to use it like a.b_c.Foo in my REPL?
04:39Manaphy91*type
04:50SagiCZ1nuwanda_: yes, u should prefer (seq coll) to ((complement empty?) coll)
05:25visof,(do (println "Hello") (println "world"))
05:25clojurebotHello\nworld\n
05:25visofis this the best way to group the statements ?
05:28Bronsavisof: that's what do is for, yes
05:28visofBronsa, Good, Thanks
05:33borkdudedo a lot of people here still use lib-noir?
05:33SagiCZ1i find myself doing a lot of (map #(hash-map :a %) coll) i there a shorter way?
05:34Bronsavisof: obviously inside other macros that have implicit `do`s, you won't need it
05:34SagiCZ1visof: let, fn, when and others have implicit do's .. note that if does not
05:35SagiCZ1visof: 'let', 'fn', 'when' and others have implicit 'do's .. note that 'if' does not
06:06cflemingSagiCZ1: Your only other option is to use an fn: (map (fn [i] {:a i}) coll)
06:06cflemingSagiCZ1: Which is not much shorter, but arguably clearer and also uses more efficient small maps
06:08SagiCZ1cfleming: oh.. so {} are different than hash-map?
06:09cflemingSagiCZ1: Yes, I believe it uses PersistentArrayMap for up to 8 items - larger maps will use a hash map.
06:10cflemingSagiCZ1: See http://blog.factual.com/using-clojure-to-generate-java-to-reimplement-clojure for a very interesting discussion of the technique, and a patch that will hopefully be in Clojure 1.8
06:11cflemingSagiCZ1: That will extend that technique to other data types too
06:13cflemingSagiCZ1: I'm not sure how much difference it will make in practice in your case though.
06:14cflemingSagiCZ1: I often have a similar need with vectors when using into with maps: (into {} (map (fn [i] [(name i) i]) coll))
06:17SagiCZ1cfleming: very good to know, thank you.. i wonder if changing the all the hash-map calls in my project will speed things up.. all of these are usually one key maps
06:18SagiCZ1(inc cfleming)
06:18lazybot⇒ 6
06:19cflemingSagiCZ1: I'm not sure, you'd have to test it - if you use them a lot in tight loops it might help
06:19cflemingSagiCZ1: mostly I just think the code is a little clearer since I think most people don't use hash-map much
06:20whysoserious-Hi, I have a probably noob question but I 've already been stuck for >15 minutes:
06:20whysoserious-When trying to compile my project I see this error:
06:21SagiCZ1yeah.. i was too keen on using the #(..) construct everywhere.. but (fn [.] .. ) is not much worse
06:21whysoserious-ption: reduce already refers to: #'clojure.core.async/reduce in namespace: caniche.server, compiling:(/Users/jan/Dev/caniche/src/caniche/server.clj:1:1)
06:21whysoserious-uh, once again:
06:21whysoserious-
06:21whysoserious-CompilerException java.lang.IllegalStateException: reduce already refers to: #'clojure.core.async/reduce in namespace: caniche.server, compiling:(/Users/jan/Dev/caniche/src/caniche/server.clj:1:1)
06:21whysoserious-and my ns sexp looks like this:
06:21whysoserious-(ns caniche.server
06:21whysoserious- (require [clojure.java.io :as io]
06:21whysoserious- [compojure.core :refer :all]
06:21whysoserious- [compojure.core :as route]
06:21whysoserious- [clojure.core.async :as async :refer :all]
06:21whysoserious- [ring.adapter.jetty :as ring]
06:21whysoserious- [ring.util.codec :as c]
06:21whysoserious- [ring.middleware.multipart-params :as multipart-params])
06:21whysoserious- (import [org.apache.commons.io IOUtils]))
06:22SagiCZ1easy fix would be choosing an alias for core.async
06:22SagiCZ1instead of :refer :all
06:22SagiCZ1oh
06:22SagiCZ1just delete the :refer :all
06:22whysoserious-but
06:22SagiCZ1because you already have an alias there
06:22whysoserious-I don't use reduce anywhere
06:22SagiCZ1that doesnt matter
06:23cflemingOr explicitly referring the symbols you use, which most core.async code I've seen does
06:23whysoserious-I see
06:23whysoserious-So, as I understand, there is another reduce function defined elsewhere
06:23SagiCZ1yes
06:23whysoserious-probably in clojure.core ;)
06:23SagiCZ1in clojure.core
06:23SagiCZ1,(reduce + (range 10))
06:24clojurebot45
06:24cflemingwhysoserious-: :refer :all pulls in c.c.async/reduce, which overwrites clojure.core/reduce
06:24whysoserious-, (prn "Lol nice!")
06:24clojurebot"Lol nice!"\n
06:24cflemingwhysoserious-: Whether you use it or not
06:24whysoserious-I see
06:25whysoserious-So, most reasonable solution would be to import only a few functions right?
06:25weavejesterYes, you typically :refer only the minimum number of functions.
06:26weavejesterI usually have something like [clojure.core.async :as a :refer [go <! >!]]
06:27whysoserious-Hmm, let me check it..
06:28whysoserious-cfleming: Awesome, works!
06:35SagiCZ1does anybody have an experience with plotting in incanter or jfreechart for that matter? i have a hard time configuring the colors and such
07:01augustlin liberator, I want to implement :processable? to handle JSON parsing and custom validation. What's the best way to ensure that it only does this validation on post and put?
07:01augustlmanually check the ctx?
07:27tom39291{ :name "Anakin Skywalker" :children [ { :name "Luke Skywalker" :children [] } ] }
07:27tom39291vs
07:27tom39291{ :name "Anakin Skywalker" :children [ { :name "Luke Skywalker" } ] }
07:27tom39291Which is most idiomatic? (The difference is whether lack of children should be represented as an empty list or as absense of that key)
07:28cflemingtom39291: Either is fine, it's a matter of taste really
07:29cflemingtom39291: Most collection operations treat nil like an empty collection, so generally they're mostly equivalent.
07:34tom39291cfleming: Thanks
07:52frankie_Hi everyone
07:52frankie_Happy holidays
07:54frankie_I'm looking for somebody who knows his/her way around the Clojure class loader
07:54frankie_I'm facing this issue with generated Java classes and I'm stuck https://groups.google.com/forum/#!topic/clojure/dwrJy5ZmcE4
07:54tom39291cfleming: What bit me is http://clojurepastebin.appspot.com/11589001
07:55tom39291I just wondered whether my "fix" (use "seq" as I have done on line 15) was the right fix. Perhaps the right fix is for me to not use represent lack of children as an empty list.
07:56augustlhow would you map /, /users and /users/:user-id with bidi?
07:57Bronsatomjack: do you have a minimal reproducible case?
07:57Bronsaerr, frankie_ ^
08:00frankie_ @Bronsa any :gen-class that :extends javax.annotation.processing.AbstractProcessor and then is loaded at compile time
08:01frankie_When the service loader is trying to create that class using Meta-INF/services you get ExceptionInInitializerError
08:02Bronsafrankie_: I don't have time to try and reproduce it myself but do you mind trying a patched version of clojure to see if that fixes your issue?
08:02luxbockdoes anyone here have experience with memory-mapping files with Clojure? I'm building a web app that allows one to explore the results of a computation that results in a large tree like structure, and I'm afraid that I might run into issues with limited memory if I load the entire file into memory every time the service needs to access a portion of it
08:02luxbockI found this library: https://github.com/thebusby/clj-mmap
08:02frankie_@Bronsa I'll be happy to
08:03frankie_I can also build a minimal project that reproduces the issue
08:03Bronsafrankie_: then try http://dev.clojure.org/jira/secure/attachment/13631/CLJ-979-v7.patch
08:04Bronsafrankie_: removing the lein dependency from the steps required to reproduce the issue would be the best incredibbly helpful
08:04luxbockright now my plan is to have files contain a header which contains rules for the structure of the tree structure stored, which I could then use to calculate the proper index to read from the file
08:05frankie_Sorry, what do you mean by removing the lein dependency?
08:05Bronsafrankie_: not requiring `lein uberjar` to reproduce
08:06luxbockso in this case the nodes of the tree would be stored as an array where the index matches up with the depth-first search order of the tree
08:06luxbockbut if I could somehow use memory-mapping with a Clojure map-like abstraction on top of it then that'd be very nice
08:12tom39291My problem is that zipper's children fn needs to return a seq, but in my "broken" implementation, I am not returning a seq. I am returning a list, which is not a seq.
08:13luxbock##(seq? (list 1 2 3))
08:13lazybot⇒ true
08:13machtyfrom http://clojure.org/special_forms#recur: "Note that recur is the only non-stack-consuming looping construct in Clojure. There is no tail-call optimization and the use of self-calls for looping of unknown bounds is discouraged. recur is functional and its use in tail-position is verified by the compiler."
08:14machtyi'm reading Joy of Clojure and they show how you can convert a mundane-recursive implementation of pow to tail-recursive using a clojure and an accumulator
08:15tom39291luxbock: Okay. Oops. [1,2,3] is a vector, not a list. It's time I read up on collections in clojure, rather than winging it, as I've been doing so far.
08:16luxbocktom39291: you can call (seq x) on most (all?) Clojure data structures to convert them
08:17machtyso is there tail-recursive optimizaiton or not? the docs on recur seem to imply there's not...
08:17machtyohhh nevermind, sorry, didn't realize the inner helper closure used `recur`... disregar
08:18luxbockmachty: the point of recur is that wherever you can use, the compiler can optimize the call
08:18luxbockso when defining a recursive function, you can make sure you are getting the optimization by using recur instead of calling itself
08:18machtyluxbock: confirm, and (current versions of) clojure won't tail-optimize otherwise
08:23jonathanjhow does one correctly reverse a string in Clojure? ie. (correct-reverse "noël") => "lëon"
08:23Bronsa,(clojure.string/reverse "noël")
08:23clojurebot"lëon"
08:24jonathanjclj-codetip.handler=> (string/reverse "noël")
08:24jonathanj"l̈eon"
08:24Bronsajonathanj: that looks like an issue in the encoding of your repl
08:25jonathanjah, right you are, i guess this shell is old (i recently switched shells and didn't resource all of my terminal tabs)
08:31jonathanjBronsa: actually the issue seems to be using a precomposed version versus the combining character version
08:32jonathanj,(vec "noël")
08:32clojurebot[\n \o \e \̈ \l]
08:32Bronsajonathanj: that makes sense then
08:32jonathanj,(vec "noël")
08:32clojurebot[\n \o \ë \l]
08:39dysfunno, the behaviour is predictable perhaps, but it does not make sense
09:26augustldoes Prismatic/schema have functions for returning data about the error instead of throwing an exception?
09:31KristienFTR you can easily construct a wrapper yourself: https://gist.github.com/rightfold/66b0397e1b1ad3e265e6
09:38augustlKristien: yeah, but I was hoping my users would get something more, not just a string :)
09:40Kristienoof
09:52luxbockaugustl: Clojure or CLJS?
09:53vivekramaswamyHello all a quick question, this does not work (take 10 (repeatedly #((rand-int 10))) but this works (take 10 (repeatedly (fn [] (rand-int 10)))) why?
09:55luxbock##(macroexpand-1 '#((rand-int 10)))
09:55lazybot⇒ (fn* [] ((rand-int 10)))
09:55luxbockvivekramaswamy: think of #(...) as the body of a (fn [] ...)
09:57vivekramaswamyok, but isn't #(...) a shortcut for a function itself
09:58luxbockvivekramaswamy: yes but the way you are using it expands to (fn [x] ((rand-int 10)), so you end up trying to call a random integer as though it was a function
09:58luxbockif you swap it with #(random-int 10) it will work
09:58luxbockerr, #(rand-int 10)
09:59vivekramaswamyThanks a lot for the explanation, I think I get it.
10:02akkadhow do you resolve an ip in dns in clj?
10:03davorbwhat is the preferred way to install clojure on ubuntu/debian? apt seems to have a rather old version (1.4, or does that not matter?)
10:04davorband wtf is cider? what advantages does that have over slime?
10:04akkaddavorb: lein
10:05expezdavorb: are you sure that's the most recent? clojure 1.4 is from like 2012.
10:05akkadhttp://www.emacswiki.org/emacs/nREPL.el
10:05davorbexpez, yeah, i just did apt-cache search clojure and got 1.4 as the latest
10:05expezdavorb: slime is for common lisp, cider is for clojure.
10:06vivekramaswamyhere is link that explains cider quite well https://www.youtube.com/watch?v=4X-1fJm25Ww
10:06expezyou could use a clojure backend for slime, swank-clojure IIRC, but you don't get much clojure specific functionality doing that
10:06akkadif anyone ever complains about clojure being difficult to learn, have them implement what they are doing in CL for a couple of weeks.
10:07davorbdon't know much about clojure, but i like cl. except some stuff... like loop and how it handles files. and threads support isn't anything to write home about either.
10:07expezdavorb: if you don't give a shit about tooling and just want a repl then you can use this instead of cider: https://github.com/clojure-emacs/inf-clojure
10:08davorbexpez, i just want to know what the most popular choice is. cl-folks use slime. what do clojure-men use?
10:08expezdavorb: cider is the most popular option for emacs users
10:09davorbguess i'll use that then
10:10vivekramaswamy:davorb many of the people I know are using cider also cursive that runs as a plugin in intellij seems to be getting quite popular
10:11mi6x3mhey clojure, I have a protocol implemented for a java interface Foo
10:11davorbvivekramaswamy, i'll be staying away from intellij.
10:11mi6x3mbut somehow it's not resolved for a class implementing Foo
10:11mi6x3mcould this bee?
10:11mi6x3m-e
10:12mi6x3mnever mind
11:05hellofunkdavorb: what's wrong with intellij? i've been thinking about switching to Cursive
11:05hellofunkdavorb: most of what i've seen has been positive, so i'm curious to know about gotchas
11:21profilHow do I connect to the same repl as my ring application runs in? I start it by running `lein ring server-headless`.
11:31justin_smithexpez: actually slime-swank has a lot of clojure specific functionality, it has better debugging than cider has ever had. slime-swank was discontinued because the upstream slime protocol kept breaking in incompatible ways and it was a pain in the ass to develop against. But it is still usable at its last released state.
11:33expezjustin_smith: yeah, nobody is interested in working on clojure debugging. Personally I think that's a shame, but tools.trace / spyscope usually get the job done.
11:33borkdudeI'm looking for a library that can help me optimize/compress uploaded jpeg files in clojure, any tips?
11:33justin_smiththe ironic thing is that we dropped slime-swank because breaking changes happened too often, then lo and behold we replace it with cider, which has *even more frequently breaking changes*
11:33justin_smithexpez: not nobody. cursive has good clojure debugging.
11:33justin_smithand slime-swank clojure debugging still works
11:34expezjustin_smith: cider is lacking integration tests. It's getting so large nobody is using the entire feature set so breakage sometimes goes unnoticed for some time heh
11:34justin_smiththat's a small part of the issue
11:34justin_smithit's also that apis are changed frequently, and due to elisp's compilation model, this requires full cleans and recompiles of elc code
11:35justin_smithbut the upgrade of versions does not do this automatically
11:35expezanyway, some breakage is to be expected prior to version 1.0 imo
11:35expezwhen I upgrade the old cider is always deleted and the new one recompiled
11:35expezI have no idea how people end up in situations with outdated .elc files lying around
11:35justin_smithexpez: I use a lot of pre-1.0 stuff, I have never seen anything else that unstable
11:36justin_smithexpez: it's easy
11:36justin_smithfor example, update cider but don't upgrade clojure-mode
11:36justin_smithboom, you have stale broken elc files
11:36justin_smiththe auto-updater doesn't catch that
11:37expezcider requires clojure-mode 3.0 according to its package info
11:37justin_smithexpez: right - but the next cider will *also* require clojure-mode 3.0
11:38justin_smithand clojure-mode will break if you replace cider and don't also recompile clojure-mode
11:38justin_smithelisp is weird
11:38Bronsaclojurebot: elisp is weird
11:38clojurebotRoger.
11:38expezjustin_smith: that sounds unbelievable
11:39justin_smithexpez: it happens to a lot of us, just check out the cider bug tracker
11:39justin_smithhappened to me more than once
11:39expezclojure-mode as no deps, how can it possibly require a recompile just because cider changed? Oo
11:39justin_smithI've used emacs for over a decade, never had anything break as much and as badly as cider
11:41samebchaseHi Everyone, I'm trying to remotely run a function using https://github.com/clojure/java.jmx . Basically a function that does some cleanup before the jar can be shutdown. In the documentation there, it looks like the `:gc` operation is invoked. How do I invoke an arbitary function using JMX? Thanks.
11:42justin_smithexpez: I'm perfectly willing to accept I am wrong about what caused / fixed my issue. Point remains that weird things broke in weird ways that were only fixable by nuking it all from orbit.
11:42expez:D
11:43justin_smithexpez: and the critical difference was going from nuking cider, to nuking cider+clojure-mode
11:43expezwriting integration tests for cider is actually a hard problem, because it depends on cider-nrepl for much of what it does
11:43expezwe're not writing any integration tests for clj-refator for the same reason. We just couldn't manage to talk to the refactor-nrepl middleware using ecukes
11:43clojurebotI don't understand.
11:44expezso we only have integration tests for the elisp bits, but we have to mock out the replies from the middleware
11:45justin_smithexpez: I have developed elisp that integrates with an external process forming a unified "app", I feel your pain
11:46borkdudeHere I see a library called imagez at version 0.3.2 https://github.com/mikera/imagez/blob/master/project.clj - yet on clojars I see a library imagez with version 0.5.0, but the group id is a bit different. Cant' seem to find the source code of the newer one.
11:46justin_smithborkdude: are the clj files not inside the jar itself?
11:47borkdudehmm, yeah, good one
11:47borkdudebut still I would like to see the repo somewhere
11:47justin_smithmany editors can open a jar directly, and browse files inside it
11:47justin_smithborkdude: yeah, good luck on that part...
11:47borkdudehttp://crossclj.info/ns/net.mikera/imagez/0.5.0/project.clj.html no link here either, I could ask the author
11:48justin_smithborkdude: I think he is on twitter with the same handle?
11:48borkdudejustin_smith yes
12:30klhttps://github.com/clojure/core.match I'm a little confused - as core, shouldn't I just be able to require it, without specifying dependencies to maven/lein ?
12:30Empperikl: core.* is different than core
12:31Empperiso no, you need to require those
12:32klEmpperi: by "require those", do you mean put dependency info into maven/lein too, or just (require) ?
12:32Empperidependency too
12:32klso, what's "core" about it?
12:32Empperithey are considered to be part of core in the future
12:33Empperiand if I'm not mistaken they need the Clojure contributor agreement to allow contribution
12:34justin_smithif they are ever to be included in clojure.core that would be a prerequisite, yes
12:34Empperiso one can think them as "part of official Clojure project but not part of Clojure the language"
12:38klThanks, that fits my mental model now :)
12:57kl[org.clojure/core.match "0.3.0-alpha4"] shouldn't pasting this into the repl work, for getting the dependency?
12:58klIt's listed under "Leiningen dependency information:" for clojure/core.match's readme
12:58klI'm getting: CompilerException java.lang.ClassNotFoundException: org.clojure, compiling:(NO_SOURCE_PATH:0:0)
13:00zinfandelHi. What's the right way to define tests which would use data from a sequence? Let's say I want to test function f and I have a sequence [{:in x, :out (f x)}...{:in x20, :out (f x20)}] and based on these data I want to define 20 tests. So basically, I want to expand that sequence into the body. I guess it's possible with macros but isn't there a simpler way, which I can't find?
13:00ambrosebskl: that goes in the :dependencies vector in your project.clj
13:00zinfandelLet's say I am using clojure.test or midje it doesn't really matter
13:01andyfzinfandel: With clojure.test you can call the is macro inside of functions, or the body of a doseq. Not sure if that will do what you want, but it is one way to invoke is 20 times without writing it 20 times.
13:04dnolen_kl: you need to put that in your project.clj or if you're using Maven directly your pom.xml
13:05justin_smithzinfandel: it does kind of matter because clojure.test is very flexible in comparison to midje
13:06justin_smithyou can do all kinds of fancy things with clojure.test just by using function composition / first class function passing. midje is much more restrictive about how you use it, and you'll usually need to write a macro in that case.
13:06zinfandelandyf: Tried it before. The problem was that it was running the tests each time I did :reload. Tried again now and that problem disappeared. Thanks.
13:08zinfandeljustin_smith: Good to know. I was got such assumption when I saw => macro. I was like, "Eh, how does it work, and how do I manipulate with this thingy"
13:08zinfandels/was got/got/
13:09klThanks guys
13:12zarkonehello all. May be somebody knows about isomorphic Om + Nashorn apps? is it possible nowdays?
13:13zinfandelandyf: (doseq [test tests] (is (= :out (f :in))) does work, but is it possible to deftest inside doseq?
13:14zinfandelThe first problem is that deftest wants Symbol
13:14andyfI don't know. You want that to get extra messages when a test fails?
13:14justin_smithzinfandel: why would you need to deftest?
13:14andyfIf so, is takes a last arg that is a string containing whatever you want, e.g. return value of a format call.
13:15justin_smithzinfandel: you can put that whole doseq inside a deftest
13:16zinfandelYes I realize that. But it would be messy when I have a lot of tests. In fact each element in the collection is a map with tests of different type.
13:17zinfandelSo I want to define a specific test with specific name for each element of top collection.
13:17justin_smiththen you want a macro that creates a deftest form, inside doseq
13:17justin_smithbut why do you need those names? there is also test/testing
13:17justin_smithor as andyf mentions, the third arg to is
13:18zinfandeljustin_smith: I want to see on which input data it failed.
13:19zinfandelYeah, I guess third arg to 'is would do the job.
13:19justin_smithzinfandel: test/testing, and the third arg to is, are both capable of providing that context
13:20justin_smitherr, second arg actually?
13:20zinfandelActually my use case goes even deeper, I have a sequence of maps that contain maps of sequences of tests for different types of data. :)
13:21justin_smithso a combo of testing / extra if args would help
13:21zinfandeljustin_smith: Yes, but well, it's the third element in the form
13:21justin_smithyou'll get a) test that failed b) testing clause message c) is extra arg d) actual failed expression for each failure
13:22justin_smitha won't be worth much, because you are bundling a loop like that, but b-d should all provide useful info
13:24zinfandelYes, that should do the job, however they wouldn't be logically grouped, of course I can put strings like "test1.subtest1.subsubtest1" but they still wouldn't be grouped at the data-structure level.
13:25zinfandelThanks
13:26justin_smiththey could be logically grouped though
13:26justin_smith(doseq [group test-groups] (testing (:message group) (doseq [test (:tests group)] ...)))
13:27justin_smiththen you don't need to do that silly string construction at all
13:27zinfandelOh, I see.
13:27zinfandelI thought that I can group them only with deftest.
13:28justin_smithwell that whole thing would be inside a deftest form
13:28justin_smithbut yes, the point of testing is that it is for grouping
13:29zinfandelYes, and I thought that I have to use deftest inside a doseq
13:31munderwoHi all. I’m getting a wierd error in this code.
13:31munderwohttps://www.refheap.com/95493
13:31munderwoits saying that “<! used not in (go …) block ..
13:32Bronsamunderwo: for expands its body in a (fn [] ..), go blocks cant cross fn boundaries
13:32munderwoI dont understand as it IS in a go block. is there something im missing? does a for loop not remove the go block for some reason?
13:32munderwoahhhH! bugger.
13:32Bronsamunderwo: aka you can't <! & co inside a for statement in a go block
13:33munderwomacro expansion… dammit
13:33munderwoany suggestions to work around this?
13:33justin_smithmunderwo: the glib answer would be "don't use for"
13:34AimHereCould it be that the for block is lazy
13:34AimHereSo it's resolved only after you left the go block
13:34justin_smithAimHere: it is lazy, but that's not the issue here
13:34BronsaAimHere: no, read my first answer
13:34justin_smithAimHere: the merge-with forces it
13:34AimHereFair enough
13:34munderworight. which I guess I could do…. its the nested for loop that I want. Is there a nicer way to do the nested iteration?
13:34AimHereI just had a similar problem just yesterday
13:34munderwonicer/other
13:35Bronsamunderwo: I believe you're stuck with using loop/recur or refactoring the go block
13:35justin_smithmunderwo: another thing to look out for is (keyword sha) is likely to make keywords that are technically illegal
13:35justin_smithnot that they keyword function cares
13:35justin_smith,(keyword " this is a ...... keyword.///////")
13:35clojurebot: this is a ...... keyword.///////
13:36munderworight. So loop/recur doesnt expand to a (fn [])
13:36munderwoyeah, I’ve got to sort out my keyword stuff. but im putting that off for a bit right now
13:36justin_smithmunderwo: not that this is likely to break anything as is
13:37justin_smithbut it could come up if you try to serialize to edn
13:37justin_smithor if you try to use hypothetical stricter future clojure version
13:37munderwoyeah. its fine at the moment. ok. i’ll keep that in mind for edn. I have worse keywords :)
13:37munderwo:/foo/bar/file.clj springs to mind :)
13:38justin_smithmunderwo: also, you could avoid some complexity by just not turning the keys into keywords
13:38justin_smith(bbloom has a few nice rants on this topic)
13:38munderwoit would be nice if keyword didnt create invalid keywords. but I can see why they might.
13:38munderwoI thought the idiomatic way of creating map keys in clojure WAS to use keys ?
13:38munderwo*keywords
13:39justin_smithmunderwo: for literal keys, sure
13:39justin_smithbut these are constructed keys that do not exist as literals anywhere in your code
13:39justin_smithso making it a keyword gains you little to nothing
13:39munderwoahh I see the distinction… that makes sense.
13:40justin_smithstrings are interned, so you get similar fast lookup iirc
13:40munderwook so suggestions on doing a nested loop not using for? some kind of loop recur?
13:41dysfunam i misunderstanding :repl-options :init for leiningen? i can't seem to make it automatically call a function because it complains the var doesn't exist. i've even tried injecting a require into there, but it still complains. any ideas? https://www.refheap.com/95494
13:44justin_smith&(loop [i 3 a []] (if (zero? i) a (recur (dec i) (conj a (loop [j 3 b []] (if (zero? j) b (recur (dec j) (conj b [i j]))))))))
13:44lazybot⇒ [[[3 3] [3 2] [3 1]] [[2 3] [2 2] [2 1]] [[1 3] [1 2] [1 1]]]
13:44justin_smithmunderwo: ^^ something like that
13:44justin_smithugly, I'll admit, but it works
13:45munderwocool. I’ll give it a try. I also just realised that I can probably macro-expand the function as it exists now and I might get some idea of how its structured to see how I can implement it .
13:45justin_smithmunderwo: the best way to macro-expand for is to take mushrooms first and wait until you are peaking
13:46justin_smithit won't make any more sense
13:46justin_smithbut the lack of sense will be more entertaining
13:46munderwoha! it probably makes even less sense in clojurescript :)
13:46dysfunjustin_smith: some of the code i've seen might better be explained by heroin
13:47justin_smithdysfun: no man, look at ##(macroexpand '(for [i (range 10)] (dec i)))
13:47lazybot⇒ (let* [iter__4760__auto__ (clojure.core/fn iter__17887 [s__17888] (clojure.core/lazy-seq (clojure.core/loop [s__17888 s__17888] (clojure.core/when-let [s__17888 (clojure.core/seq s__17888)] (if (clojure.core/chunked-seq? s__17888) (clojure.core/let [c__4758__auto__ (... https://www.refheap.com/95495
13:47dysfuncool
13:47justin_smithdysfun: that is only explainable by wizardry or hallucinagens
13:48justin_smith(be sure to follow that refheap link)
13:48justin_smithdysfun: munderwo: look at that refheap link, and consider the fact that all that was iterating on was (range 10)
13:48dysfunuhuh
13:48andyffor and doseq have a lot of options like :when and :let that make them more useful, and more complex in their implementation
13:49justin_smithandyf: looking at that expansion (which uses none of those features), the chunking optimizations seem to be the biggest obfuscator
13:49andyfbut the main thing adding extra code there is optimizing for chunked sequences.
13:49munderwoyeah… the for form was super nice.
13:50andyfpprint, man, pprint!
13:50andyfstill not pretty, to be sure, but less of a wall.
13:50TEttinger&(mapv #(mapv (partial vector %) (range 3)) (range 3))
13:50lazybot⇒ [[[0 0] [0 1] [0 2]] [[1 0] [1 1] [1 2]] [[2 0] [2 1] [2 2]]]
13:51justin_smithTEttinger: that leads back to the original problem - the main logic is inside an fn
13:51justin_smithTEttinger: he needs a way for the body of the expression not to be in an fn
13:51TEttingerah
13:51munderwobecause of the core.async infection :(
13:51munderwoand the fact that everything is async….
13:52TEttingerI'm not familiar with core.async right now
13:52munderwoonce you go core.async…. everything is core.async ....
13:53TEttingercore.a-sunk
13:53munderwowell not everything.. but you find your-self adding go blocks all over the place… well thats what I’ve found anyway
13:53justin_smithmunderwo: ztellman's talk at the last conj is on that topic btw
13:53munderwoooh… I was there for the conj, but I think I missed that talk. I’ll have to watch it.
13:53justin_smithmunderwo: he contrasts core.async, his manifold lib, and prismatic/plumbing - each does a very similar thing, with varying levels of contagion / generality
13:54justin_smithplumbing being super general and not at all infectious, and async being the opposite extreme
13:54dysfunis it online? i'm using manifold with core.async because aleph
13:54munderwothe reason I have all this core.async stuff is using nodejs libs… which are all async… so I need a way to deal with all the callback stuff.
13:54justin_smithyeah, it's on the clojure conj youtube account
13:55justin_smith$google clojure ztellman manifold conj video youtube
13:55lazybot[Clojure/conj 2014 Notes - Forays into simplicity] http://eigenhombre.com/clojure/2014/11/27/conj-notes/
13:55justin_smithoops, wrong link!
13:55munderwoclose though
13:55justin_smithhttps://www.youtube.com/watch?v=3oQTSP4FngY&amp;index=17&amp;list=PLZdCLR02grLoc322bYirANEso3mmzvCiI this is the one
13:55munderwo$google clojuretv ztellman minifold conj youtube
13:56justin_smiththeir api limits kind of suck lately :(
13:56justin_smithneed to get that duckduckgo plugin in
13:57munderwoas a relative newcomer to IRC im always amazed by all the little tools that people have.
13:58justin_smithmunderwo: it's fun working on the channel bot, because you get to see people use it (unlike working on other software, where theoretically you know it gets used but you don't get the direct gratification)
13:58justin_smith(I did a pretty major lazybot update not long ago)
14:00benmossis there a better idiom for doing things like `(map #(if (foo? %) (modify %) %) coll)` ?
14:00justin_smithbenmoss: it would be nice to have an "update-if"
14:01justin_smith macro
14:01CodeWar[Question about implementing a language on top of JVM] Do you just compile the source to ByteCode and classes and give it to the VM and wash your hands off or is there an interpreter that is written by the language designer
14:01justin_smithmaybe it exists in useful, or one of those other util libs
14:01benmossyeah i suppose it would have to be a macro
14:01justin_smithCodeWar: clojure has no interpreter
14:02AimHereThat doesn't necessarily mean you can't write one for your own purposes, mindyou
14:02CodeWarjustin_smith: so its straight source to bytecode and let JVM interpret and JIT on its own
14:02justin_smithCodeWar: clojure emits bytecode and has the vm run it directly (and hotspot likely improves said bytecode depending on host settings)
14:02justin_smithwell, the jvm doesn't quite interpret per-se, but yeah
14:03CodeWarAimHere: care to elaborate how? Meaning how do I load a class let JVM transfer control over to me until I can interpret profile and then occasionally for parts of the program transfer control back to the VM
14:03justin_smithCodeWar: the vm is the only thing that is ever doing anything
14:03CodeWarI am aware of Graal but curious if there is something that already exists that languge designers make use of
14:03justin_smithclojure uses the asm lib
14:04mi6x3mhey clojure, what would you rather call an event listener function?
14:04mi6x3mon-xyz or xyz-handler?
14:04clojurebotNo entiendo
14:04justin_smithCodeWar: in fact, clojure embeds a copy of the asm lib inside its own source
14:08CodeWarjustin_smith: what libraries/frameworks do you use for Source to AST generation
14:09justin_smithCodeWar: Clojure is that library, and the AST transformation is trivial, Clojure code is very close to being an AST already
14:09justin_smithbut Bronsa or arrdem could tell you more detail
14:12justin_smithCodeWar: big picture, a reader expands certain forms, then macros are expanded, and finally the resulting tree is turned into an AST by some relatively straightforward tree operations
14:12CodeWarjustin_smith: got it. I forget this is a dialect of LISP so its likely easier than other languages
14:49augustlany liberator peeps around? Looking for advice on composing decision functions
14:49augustlI could just copy `(if (vector? decision) (first decision) decision)` but that seems a bit lame
14:51AimHereYou could multimethod it
14:54TEttingerthere really should be a general "if seqable? then the first item, else the item" idiom, but it gets weird with strings and maps
14:54TEttinger,(sequential? {})
14:54clojurebotfalse
14:54TEttinger,(sequential? {:a :b})
14:54clojurebotfalse
14:54TEttinger,(seq {:a :b})
14:54clojurebot([:a :b])
14:54augustlseems like most libraries has landed on [true result] and [false error] for returning values that signify either success or error
14:55dysfunyeah, it's sort of reminiscent of the 'Either' datatype in haskell
14:57augustlhmm, in the case of liberator, I also have to actually manually merge the truthy values as well
14:58mi6x3mis there some version of case which returns nil on default?
15:06Frozenlockmi6x3m: this? (case "allo" "not-allo" true nil)
15:06TEttingerhm ##(case 2 0 "zero" 1 "one")
15:06lazybotjava.lang.IllegalArgumentException: No matching clause: 2
15:06andyfcase takes an optional last arg which is an expression returning a default value
15:06TEttinger##(case 2 0 "zero" 1 "one" nil)
15:06lazybot⇒ nil
15:07TEttingerneat andyf
15:08TEttinger(inc andyf)
15:08lazybot⇒ 18
15:08andyfDoc strings can be informative sometimes :)
15:09FrozenlockI rest my case.
15:09Frozenlock*badum tss*
15:10justin_smithcase is definitely underappreciated
15:10justin_smith(or maybe it's just that cond is overused - one of these)
15:20augustldecision composition for liberator https://gist.github.com/augustl/518abd83173444747cd2
15:20augustlneed to familiarize myself with the stdlib, I use loop way too often..
15:24justin_smithaugustl: I think you'll find things get simpler if you always have cur-fn return a vector (even if it is a vector of only one item)
15:25justin_smithnever mind, now I see what happens there
15:26dnolen_cfleming: found out the source of the unresolved issue - was reverting my IntelliJ file
15:27justin_smithaugustl: why can't (if (= truthy (if result true false)) ...) just be (if result ...)?
15:30augustljustin_smith: I need to make termination on truthy or falsy pluggable, since liberator has :processable? (truthy) and :malformed? (falsy)
15:30augustljustin_smith: so the "if" returns true or false depending on the truthyness of result, and then I compare with the "truthy" argument passed in
15:30augustlnot sure if there are better ways of doing that
15:30augustls/the "if"/the inner "if"/
15:31justin_smith(if ({:malformed false} result result) ...)
15:31justin_smiththat will be false for :malformed and otherwise just be the input
15:31justin_smithoops, I missed the ?
15:32augustlso it'll be called like `:processable? (comp-decision true foo bar)` or `:malformed? (comp-decision false baz maz)`
15:32justin_smithahh
15:32augustlthe liberator state machine needs false or true to continue depending on the hook :)
15:32justin_smithin that case just replace (if result true false) with (boolean result)
15:33augustlah, that's much better
15:33justin_smith,(map boolean [nil false 1 0 true []])
15:33clojurebot(false false true true true ...)
15:33justin_smithclearly I didn't get the subtlety of what you were doing with liberator there though
15:33augustlthis is pretty "low level" stuff so perhaps a manual "loop" makes sense
15:34justin_smithlooks like it could easily be a reduce to me
15:34augustljustin_smith: normally, you'd have something like :processable? (fn [ctx] (if whatever true [false {:add-this "to the context"}]))
15:34justin_smithyou always go through the list in order, you have an accumulator that is updated at each step
15:34augustlthe vector is so that liberator can add stuff to the context while returning what liberator considers a "falsy" value
15:35augustlhmm, will try to rewrite as a reduce
15:35augustlliberators definition of "falsy" is documented under "decision functions" here FYI http://clojure-liberator.github.io/liberator/doc/execution-model.html
15:37justin_smith(reduce (fn [acc cur-fn] (let [decision (cur-fn ctx) [result context-update] (if (vector? decision) decision [decision decision]] (if (= truthy (boolean result)) (liberator.core/update-context ctx context-update) (reduced decision))) initial-ctx fns)
15:37justin_smithsomething like that
15:38justin_smithmy parens are likely off
15:38justin_smithclearly acc should be ctx or visa versa
15:38justin_smithbut that's the gist of it
15:39justin_smithnotice the destructuring cleverness with decision (too clever?)
15:40augustldestructuring is neat :)
15:40augustlwho says Clojure doesn't have "weird syntax" :)
15:41justin_smithhaha
15:41klIs it possible to exit early from a reduce? Or is there some alternative that would permit such?
15:41justin_smithkl: reduced
15:41justin_smith(doc reduced)
15:41clojurebot"([x]); Wraps x in a way such that a reduce will terminate with the value x"
15:42kljustin_smith: I'm not sure how that relates to folding/reduceing?
15:42justin_smith,(reduce (fn [acc x] (if (> x 10) (reduced (+ acc x)) (+ acc x))) (range))
15:42clojurebot66
15:42justin_smithkl: it says "such that reduce will terminate with the value x"
15:43justin_smiththat is precisely and only about reducing
15:43justin_smithnote above I passed an infinite sequence to reduce, but it only used the values up to 10
15:43klAhh, so it's used *inside* a reduce, I see
15:44justin_smithwell values up to 11 or whatever but hopefully you get the point
15:48kljustin_smith: thank you mate. This is really useful
15:50ordnungswidrigjustin_smith: it's an interesting proposal to use a reduce to execute the decision graph
15:51justin_smithordnungswidrig: the logic of augustl 's loop maps perfectly to reduce
15:51justin_smithhehe, maybe I should have said "projects perfectly", map is a bit overloaded around here as a term :)
15:51ordnungswidrigyes, it would even reduce the stack :-)
15:52ordnungswidrigBut you're missing that the fns are not know a priori. But a loop recur would work.
15:53ordnungswidrigOr a reduction over an infinite sequence that it ignored, *cough* *cough*
15:53justin_smithordnungswidrig: in his case they are, they are a sequence and he repeatedly gets the next item
15:53ordnungswidrigOh, sorry, I skipped that par.
15:53justin_smithand having some case that hits reduced will deal with the infinite sequence as nicely as the loop version did
15:54justin_smithlike I said, reduce is a perfect projection of the logic of his loop :)
15:54ordnungswidrigyes, absolutely
15:54ordnungswidrigI toyed around with decision function composition à la ring middleware the other day but I did not find some expressive and clear way yet.
15:55justin_smithordnungswidrig: have you looked at prismatic/graph?
15:55justin_smithit's an interesting and elegant data driven approach to the domain
15:55justin_smithI mean function composition can also be pretty elegant, but I like the declarative style of graph
15:57justin_smithgraph is part of the "plumbing" lib https://github.com/Prismatic/plumbing
15:57ordnungswidrigjustin_smith: yes, it's very promising. However I'm not sure how it would fit liberator. I see that there's need to factor out common functionality that might span multiple of liberator decision functions and thus raises the question of how to compose them.
15:58ordnungswidrigBut I'm currently thinking that is something you can build on top of liberators decision map abstraction, not something to be provided by liberator
15:58justin_smithordnungswidrig: the graph examples show quite complex interactions between values in a graph block
15:59justin_smithie. the map providing the count, mean, mean-square, variance built on top of each other
15:59ordnungswidrigyou could for sure build something like liberator on top of plumbing.
16:00justin_smithyeah, I don't know the specifics of how liberator uses stuff yet (I have planned to look into it), so I can't comment on that side of it
16:00augustljustin_smith: makes sense with a recur, that's conceptually what I'm doing
16:01augustlbuilding a return value for a collection
16:01augustls/recur/redue/
16:02justin_smithone of my a-ha moments in clojure was when I learned to recognize the signs that something could be expressed as reduce
16:02justin_smith(because often if it can be, that is the best representation of the algorithm)
16:03augustlwas not aware of "reduced" though, that helps
16:03augustlI some times miss my "break" :)
16:03justin_smithyeah, reduced is a total game-changer
16:03justin_smithalong with reducers and transducers if you want to get advanced
16:03augustldoes it actually terminate the reduction though? In the example it just returns a static value
16:03augustlfor me it's important that I actually return the value being reduced at that specific point, and doesn't go further
16:04justin_smithaugustl: if you add a print to the function body you will see nothing else is calculated after it hits reduced
16:04justin_smithand yes, definitely returns the precise value you pass to reduced, that's kind of the whole point :)
16:11TMA,(doc reduce)
16:11clojurebot"([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...
16:11TMA,(doc range)
16:11clojurebot"([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity. When step is equal to 0, returns an infinite sequence of start. When start is equal to end, returns empty list."
16:12TMA,(reduce + (range 12))
16:12clojurebot66
16:15TMAis there a common lisp's (reduce f seq :from-end t) equivalent? or shall I just reverse the sequence manually?
16:17augustlupdated the liberator decision composition gist fyi https://gist.github.com/augustl/518abd83173444747cd2
16:17justin_smithTMA: reverse manually, but use rseq if the input is a vector
16:17justin_smithrseq is basically free because of how vectors are implemented
16:18justin_smithaugustl: opted against the destructuring magic I see
16:19augustljustin_smith: how sloppy of me :) forgot all about it
16:21TMA,(map (fn [x] (apply (fn ([] :a) ([x] :b) ([x y] :c) ([& r] :d)) x)) [[] [1] [1 2] [1 2 3]])
16:21clojurebot#<CompilerException java.lang.RuntimeException: Can't have fixed arity function with more params than variadic function, compiling:(NO_SOURCE_PATH:0:0)>
16:21TMA,(map (fn [x] (apply (fn ([] :a) ([x] :b) ([x y] :c) ([x y & r] :d)) x)) [[] [1] [1 2] [1 2 3]])
16:21clojurebot(:a :b :c :d)
16:22TMAoh, nifty
16:22justin_smithhaha, an arity counter
16:36klis there an idiomatic way to format s-expressions, as far as indentation goes?
16:38mearnshkl: https://github.com/bbatsov/clojure-style-guide#body-indentation
16:43klmearnsh: how about where the closing parens go?
16:43klWhoops: " Place all trailing parentheses on a single line instead of distinct lines."
16:43expez^
16:43klWhy is that a good thing? It harms readability for me
16:44expezThat's just habit
16:45andyfkl: takes unnecessary vertical whitespace. People who program a Lisp for a while tend to not look at the parens very often, but expect it to be indented well, usually automatically by their text editor/IDE, and use that.
16:46andyfkl: If you want to show Lisp/Clojure/Scheme code to someone else and ask for comments or review, and you have trailing parens each on a line on their own, they will cringe.
16:47expezin 99% of the cases indentation makes it clear what goes with what. In the other rare case your editor probably has facilities for highlighting pairs of parens which you can rely on.
16:47expezNobody ever argues that Python code is unreadable due to missing { } pairs :) It's just habit.
16:49tolstoyTo be honest, when using a {} language, I now wish it was okay to condense lines of "}" onto a single line.
16:49tolstoy... else { return finish(); }}}}}
16:49justin_smithkl: it's natural for good style to be dependent on that language. In fact it's helpful to me that lisps do not use trailing brackets, because then I can transition from reading a lisp to reading an algol (like c, c++, java, js) more easily.
16:50dnolen_cfleming: hrm, actually no, still happening, I've got a screenshot for you.
17:38cflemingdnolen_: Cool, can you send it to cursive@cursiveclojure.com?
17:39dnolen_cfleming: done
17:39cflemingdnolen_: There's actually something else you could try. It's very strange to get a symbol resolution problem that's sporadic - normally it always works, or it doesn't. I'm wondering if your indexes might have been corrupted. Try File->Invalidate Caches and Restart, that will force an index rebuild.
17:40dnolen_cfleming: will try that next time - there's no rhyme or reason to the bug as far as I can tell
17:41dnolen_cfleming: it usually happens when I switch to a file/tab
17:41cflemingdnolen_: So it will suddenly happen in a file you already have open in a tab when you switch to it?
17:42dnolen_cfleming: I believe so but I will have to verify
17:43cflemingdnolen_: Ok - don't spend much time on it, I suspect it's actually your indexes, especially since no-one else has reported it. You don't have to wait for the problem to rebuild your indexes, if you do it now with any luck the problem won't come back.
17:43dnolen_cfleming: ok invalidated / restarted, will let you know if I see it again
17:44cflemingdnolen_: Great, thanks.
17:44SagiCZ1most of the time when Cursive bugs out or does something weird, restarting and invalidating caches helps
17:45cflemingYeah, they still have some bugs in their indexing framework, although it seems to happen more with Clojure than with Java - it might be bugs in my code, or I'm just using their framework in different ways
17:45cflemingwhich I almost certainly am.
17:45SagiCZ1i dont even know what the indexes are for
17:46cflemingBasically any information that has to be visible globally is indexed - in Cursive that's things like metadata about vars, information about all the namespaces and so forth.
17:47cflemingThat's why when that gets screwed up the first thing to go is the symbol resolution.
17:47SagiCZ1i see.. by the way are way any closer to being able to slurp into quoted strings?
17:49gfredericksSagiCZ1: do what?
17:49SagiCZ1i think there is no reason why paredit slurping cant work on strings
17:50SagiCZ1"hello |" world --- slurp --> "hello world"
17:50cflemingSagiCZ1: No, no reason other than that I haven't got around to it yet. I have a backlog of paredit related issues, I'm going to do a paredit focused release soon.
17:51SagiCZ1cfleming: alright, sweet
18:08michaniskintolstoy: re }}} https://github.com/boot-clj/boot/blob/master/boot/base/src/main/java/boot/App.java#L230
18:09michaniskinhaha i do it all the time now
18:09michaniskinit rules
18:10dnolen_cfleming: didn't solve the issue
18:11Bronsamichaniskin: my eyes
18:12michaniskini think it's artistic
18:12BronsaI guess that's a way to put it :)
18:12michaniskinyou should see how i do php
18:14Bronsamichaniskin: thanks, I'm good
18:14michaniskinto late though, you can't un-imagine it
18:15Bronsamichaniskin: as humans we have developed selective amnesia exactly for cases like this
18:15michaniskinit will haunt you
18:15michaniskinyou'll see
18:15michaniskinsingle curlies on a line by themselves don't have to be tolerated anymore
18:16michaniskinthe seed is planted
18:22justin_smithto me that says "I would rather be writing lisp code write now"
18:23visofhi
18:23visofhow can i convert this java to clojure ODatabaseRecordThreadLocal.INSTANCE.set( database1 ); ?
18:23visof(.get (ODatabaseRecordThreadLocal/INSTANCE) database1) ?
18:25justin_smithwhat is the relationship between ODatabaseRecordThreadLocal and INSTANCE?
18:26justin_smithstatic member of a class?
18:26visofhttp://www.orientdb.org/releases/latest/javadoc/com/orientechnologies/orient/core/db/ODatabaseRecordThreadLocal.html
18:26justin_smithoh, I guessed right
18:27justin_smith(.set ODatabaseRecordThreadLocal/INSTANCE database1)
18:27justin_smithsince it's a static field, no invocation is needed on it
18:27Bronsabut it would have worket either way :P
18:27Bronsa,(Integer/MAX_VALUE)
18:28clojurebot2147483647
18:28justin_smithBronsa: but not with .get :)
18:28Bronsa,Integer/MAX_VALUE
18:28clojurebot2147483647
18:28Bronsajustin_smith: uuuh really?
18:28justin_smithBronsa: I mean, yes, parens or no, both work (but no parens is better)
18:28Bronsaah, ok
18:28justin_smithbut he should definitely switch his .get to .set
18:29Bronsaah! didn't notice that. you're right
18:30justin_smith:)
18:43dnolen_just pushed some big changes to ClojureScript that considerably improve the REPL experience. Rhino REPL can start ~1 second. added real support for in-ns and require. doc is loaded into REPLs by default. things feel considerably less wonky now.
18:44ambrosebsdnolen_: sounds awesome
18:47justin_smithdnolen_: is that ~1s from jvm startup to rhino repl, or ~1s for startup inside an existing vm?>
18:48dnolen_justin_smith: jvm startup is 86ms on my machine, this meme has to end
18:48justin_smithdnolen_: no, I'
18:48justin_smithm not trying to pick on the jvm
18:48dnolen_JVM startup is ridiculously fast
18:48justin_smithjust asking a clarifying question
18:48justin_smithI know the JVM can start fast
18:48dnolen_everything that is slow in the Clojure ecosystem is of our own doing
18:48justin_smithI know, I know
18:49justin_smithI've timed the startup of java hello world
18:49justin_smiththat wasn't what I was getting at at all
18:49dnolen_~1s is about 800ms of Clojure 1.6.0 boot time - the rest is is loading AOTed ClojureScript and reading some EDN files off disk
18:49clojurebotAck. Ack.
18:50justin_smithdnolen_: that's pretty great actually
18:50justin_smiththanks for clarifying
19:02cflemingdnolen_: Well damn
19:03cflemingdnolen_: Can you zip your project directory up and mail it to me, and I'll take a look to see if there's anything funky about it?
19:04dnolen_cfleming: I could put it wouldn't be any different from the ClojureScript repo, I've been committing ClojureScript.iml changes
19:04dnolen_s/put/but
19:04cflemingdnolen_: Ok, I'll download that and check it out.
20:18kenrestivoheh, on the embedded ARM platform i'm using, jvm and clojure is 10 minutes to start up.
20:18justin_smithkenrestivo: what about jvm for java helloworld?
20:19kenrestivoa uberjar loads faster, a couple minutes. but lein trampoline repl :headless is ~10 minutes.
20:19kenrestivoof 99% CPU usage
20:20justin_smithkenrestivo: I was amazed by how much of the "lein repl" startup time is due to nrepl
20:20kenrestivoi dunno, helloworld is kind of useless to me. the experiment was to see if doing embedded development with a clojure repl was powerful. it is, in a way, but sllloooowwwwww in other ways.
20:20justin_smithkenrestivo: fair enough, just wondering what the vanilla java baseline was
20:21kenrestivohuh, maybe it is nrepl then. i remember doing some experiments and noticing it had a tight loop that consumed 90% cpu under normal conditions (i think this was with visualvm). i asked chas about it, and he said something to the effect of, oh yeah, it does that.
20:21kenrestivothat was a couple years ago, maybe it's all been massively improved since.
20:22justin_smithtry just running clojure.main next time, for comparison at least
20:22kenrestivoall i know is, i've been spending a *lot* of time hanging around in #clojure to kill time while waiting for the repl to start
20:22kenrestivofor the last month
20:23dweavei’m trying to figure out exactly what core.async is and how it relates to futures / promises. Is it built on top of futures?
20:23justin_smithdweave: it uses a thread pool
20:24justin_smithdweave: it's more about queues between threads, and waking up blocks of code when they have data on their queue
20:24dweaveis it “probably” a more suitable solution if I’m using futures
20:25justin_smithdo the futures communicate with anything else? if not, core.async won't gain you anything
20:25dweavei see
20:25dweavejustin_smith is that kinda like actors without their own state?
20:25justin_smithif they need to do extensive coordination, then yeah, core.async has nice ways of coordinating between threads of execution
20:26justin_smithdweave: they also have state, it's a more flexible setup than actors though
20:27justin_smithdweave: core.async implements something called CSP, concurrent sequential processes, there are papers on the model if you look for them
20:27justin_smithsorry s/concurrent/communicating
20:27justin_smithhttp://en.wikipedia.org/wiki/Communicating_sequential_processes
20:27dweavek
20:28dnolen_kenrestivo: there a recent post on the ClojureScript mailing list on using using ClojureScript+Node.js / C++ for Raspberry Pi dev - probably more realistic route
20:28kenrestivohmm... yeah i heard there's some new node goodness for cljs. too late on this project, but maybe in the future
20:29kenrestivoexciting stuff though, i saw your blog post on it.
20:30dweavejustin_smith: might this be a good use case for core.async: Multiple async http requests all of which need to report back to the main thread which will do some data crunching on each result?
20:33justin_smithdweave: yeah, I could easily see a primary go block that reads each http result of a channel and processes it, and then a bunch of others that each put an http result onto that channel
20:34dweavejustin_smith what state do channels have? They just seem like queues
20:34justin_smithbut for something that simple, you could just use one of the queues from java.util.concurrent too (reading from the queueu in a loop in the main thread, writing to it from each http request in a future), but if you need more back and forth, that's when core.async makes more and more sense
20:34justin_smithdweave: they are queues with some limitations
20:35justin_smithfor example you can't check if they have data for you - your options is to read or not
20:36dweavestarting to make sense
20:36dweaveso asyn channels are more about like 2 way communication
20:36justin_smitheach channel is one way
20:36justin_smithbut you can of course have a channel to go each direction, of course
20:36dnolen_dweave: core.async is really just that, a fantastic DSL over queues - concurrent or not
20:37dweaveok
20:54gfrederickshey look I made a regex to match JSON with bounded nesting: https://www.refheap.com/95500
20:55warzhi all, im aiming for a basic clojure environment in emacs. im new to emacs, so i was hoping for something that works out of the box. i was trying cider, and i followed the install directions, but my emacs does not look like the screenshot on cider's github repo: https://raw.githubusercontent.com/clojure-emacs/cider/master/screenshots/cider-overview.png
20:55warzshould my emacs look like this screenshot, after installing?
20:55andyfplease tell me you didn't type that regex in by hand
20:55gfredericksandyf: I didn't type that regex in by hand
20:56gfredericksit seems like a natural example of a situation where you could add a feature to regexes to make them dramatically more succinct but no more powerful
20:56gfredericksa let-like feature
20:56andyfYeah, I think they call them context-free grammars :)
20:56gfredericks"no more powerful" <-- trying to distinguish from CFGs
20:57klhmm
20:57gfredericksCFGs are letrec, I'm talking about regular let
20:57klwhat is the difference between a transducer and a partially applied function
20:57andyfIn Perl you can assign regexes to variables, and then use the values of those variables in other regexes. Should work in Clojure, too, via string concatenation.
20:57klandyf: i tried looking at the wiki page for context-free grammars and i just got confused. is there a simple definition?
20:58andyfyes
20:58gfredericksandyf: well that's where I got mine from; but you're expending a lot of resources with that approach, building strings and parsing the resulting regexes
20:59gfredericksandyf: there's probably some sort of recursion-limited grammar that would be more or less what I'm talking about
20:59justin_smithkl: you can apply a transducer to another transducer, and you get a transducer that is the composition of their behaviors
20:59justin_smithkl: that's not how normal partially-applied functions would behave
20:59andyfkl: The examples might be easier to read than the definition.
21:00gfredericksandyf: this might be it: http://en.wikipedia.org/wiki/Regular_grammar
21:01gfredericksI take it back
21:01gfredericksseems like a different kind of limitation
21:01justin_smithwarz: are you referring specifically to the completion dropdown?
21:01andyfBasically you have some 'non-terminal symbols' which are usually capital letters in the examples. You start with one of them, and at each step you take a nonterminal symbol and replace it using one of the rules in the grammar, which look like: S->aSSb, which means to replace an S with aSSb. When you have replaced all non-terminal symbols so no more remain, you have a legal string in the language your grammar defines.
21:02alandipertgfredericks: epic regex man
21:04warzjustin_smith, the whole theme and everything, the 3 panes, etc
21:04justin_smithwarz: I know nothing about the theme, and I wouldn't expect anything about cider to set the color theme or font etc.
21:05justin_smithwarz: in terms of the panes, managing windows in emacs is very different from other apps
21:05kljustin_smith: I see, I think I get that, thanks. It sounds like an idea that wouldn't be peculiar to clojure, do you find them elsewhere, too?
21:05gfredericksalandipert: heythanks
21:05justin_smithwarz: they are more dynamic, and they don't even have the same names they have in newer software
21:07justin_smithkl: they do what one might intuitively expect nested calls to map / filter / etc. to do if you had a "smart" compiler. Clojure's compiler isn't super clever like ie. haskell's though.
21:08justin_smithkl: functionality wise they don't do anything wrapping one stream transform in another wouldn't, performance wise they are a big change though.
21:10kljustin_smith: sorry, I'm probably being dumb, but I'm trying to work out (again) how this differs from partial application. A partially applied map given a partially applied filter, given a value - is pretty much the same thing, is it not?
21:10justin_smithkl: no
21:10justin_smithbecause the mapping and filtering (though you would naively expect them to) don't happen in one go
21:11amalloygfredericks: putting honest, hard-working regex craftsmen out of work with your automated regex factories?
21:11justin_smithtransducers combine them in a way that the function composition doesn't yet, and eliminate some fiddly stuff in the middle
21:12justin_smithkl: as I was trying to say, at first you would expect this to be automatic, but Clojure doesn't typically try to be that clever (see also our usage of "recur" instead of automatic tco)
21:12kljustin_smith: so isn't what you said effectively what I said, BUT going over a lazy stream?
21:12kl(Trying to reconcile a proper mental model)
21:13justin_smithkl: a map over a filter is still two lazy streams, a transduced map+filter can be one lazy stream, or feed input to one reduce without creating a lazy stream, or...
21:14gfredericksamalloy: hey regex factories create jobs
21:15kljustin_smith: thanks, you've been much help :)
21:15kl+ justin_smith 1
21:15justin_smithkl: what's different isn't the behavior, but the implementation (and thus how well it performs, and incedentally, transducers also make it easy to port all of map, filter, reduce, etc. to a new data source / sink)
21:55uris77alert: newbie question - How do I render a response as edn in ring?
21:58vermauris77: you could return something like: {:status 200 :body (pr-str obj) :headers { "Content-Type" "application/edn"}} from your ring handler
21:58verma,(def res {:status true :values [:hello :world]})
21:58clojurebot#'sandbox/res
21:59verma,{:status 200 :body (pr-str res) :headers {"Content-Type" "application/edn"}}
21:59clojurebot{:status 200, :body "{:status true, :values [:hello :world]}", :headers {"Content-Type" "application/edn"}}
21:59vermapretty sure there's some middleware somewhere
21:59vermauris77: https://github.com/tailrecursion/ring-edn
22:05uris77verma: thank you
22:05uris77googling for clojure stuff (other than lang basics) is a little disappointing. I saw some snippets that had response/edn
22:06uris77tried that and got a compilation error
22:07verma I just searched for "clojure ring edn middleware"
22:07vermaor something similar
22:13uris77i searched for clojure ring render edn
22:53ipaomian_test
22:53fairuztest success ipaomian_
22:54ipaomian_thanks fairuz