#clojure log - Feb 12 2016

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:27 bsima: skjljsk: looks like you're missing a dependency

0:30 skjljsk: its complaining about boot.core

0:36 bsima: did you `require` boot.core in build/tasks.clj?

0:40 jack_rabbit: I'm reading core.async docs. If I use >!! or <!! instead of >! or <! in a go block, what happens?

0:56 rhg135: you block the thread

0:59 skjljsk: bsima: yes

1:00 this pod buisness is often very dangerous

1:00 i mean the boot pod

1:02 shit man i can not test my code with boot

1:03 irctc: would anyone be interested in using a version of Clojure, that implemented SystemF-omega type inference on the JVM?

1:03 basically get all the type benefits of haskell, the syntax of clojure, and the power of the JVM

1:04 specifically designed for industry, not academia

1:16 rhg135: I'm not sure what that means but it sounds cool

1:17 python476: hes gone anyway

1:17 Fomega seems harder to do than gradual typing

1:18 * rhg135 just nods

1:27 bsima: I'm a big fan of Shen. Uses sequent calculus for its types

1:36 skjljsk: if you're still here, check out #bootclj

1:36 alan and micha might be able to help you

1:39 skjljsk: thanks

1:41 btw boot is great

1:41 i am sure it must be something i am doing

1:41 at least with boot i can write my own test task

1:50 python476: bsima: is shen 'sound' ? or does it fail on some weird cases ? I've never used it. First time someone says he used it

1:52 skjljsk: sean corfield made articles about moving his company app from lein to boot. At my level I don't see the value (except that boot task composition seems a good thing)

1:52 skjljsk: i have been on boot for a year now

1:52 more than that actually

1:52 wmealing: its on my list of things to look at

1:53 bsima: I've been using boot for over a year as well

1:53 skjljsk: it is mindblowing, but not as stable as lein i would say

1:53 bsima: I actually use it on top of lein, to do some extra tasks. Specifically tests

1:53 python476: unstable mindblowing, 70s are back

1:53 clojurebot: Titim gan éirí ort.

1:54 python476: Gvgvz tna éveí beg

1:54 skjljsk: hurmm i dont know i have contributed patches to it in the past

1:54 recently i changed job and get very little time to debug boot issues

1:55 if you are in same position i would recommend lein

1:56 but i would still chose boot over lein no matter wat

1:56 bsima: boot wins for clojurescript

1:56 skjljsk: python476: everything was once mindblowing unstable

1:57 your contribution makes it mindblowing stable

1:57 python476: hey

1:57 skjljsk: in form of issues patched etc

1:57 anyhow no debate here

1:57 use what suites you man

2:00 python476: no worries, I'm not complaining I'm far from that position

2:37 jonathanj: how do you do the equivalent of setting jvm-opts to "-Djava.awt.headless=true" with boot?

2:39 actually, now i'm not sure if those are somehow also set when running via an uberjar

3:05 bsima: jonathanj: https://github.com/boot-clj/boot/wiki/JVM-Options

3:06 not sure about uberjar settings. I would assume that they are carried over

3:08 jonathanj: what i'm wondering is how to do the same for boot uberjars, if they are included.

3:08 Glenjamin: jvm opts don't kick in for uberjars

3:08 jonathanj: anyway, i'm using boot too, it has some definite benefits, but i have to supply about 5 envvars to prevent permgen errors and such things

3:08 Glenjamin: okay, thanks

8:02 timvisher: justin_smith, xemdetia: thought you might be interested in my solution to my TLS problems https://github.com/dakrone/clj-http/issues/304

8:02 also wondered if you had any thoughts on whether i did something wrong there :)

9:19 benjyz1: hello. I'm trying to do a transformation of a matrix

9:21 https://www.refheap.com/114737

9:23 ,(def x {:a [[1 2] [2 5]] :b [[7 2] [8 9]]} )

9:23 clojurebot: #'sandbox/x

9:23 justin_smith: ,(apply map into ((juxt :a :b) x))

9:23 clojurebot: ([1 2 7 2] [2 5 8 9])

9:26 benjyz1: justin_smith: thx once yet again :)

9:26 justin_smith: np

9:26 benjyz1: do you do clojure consulting or can recommend anyone?

9:27 justin_smith: benjyz1: I'm busy with my day job. I do know some people who do consulting / contract work though.

9:28 benjyz1: I'll hope to give back to clojure one day.. still learning

9:29 pretty amazing that all the power is available in the browser also. using that code in CLJS

10:02 Glenjamin: justin_smith: if you had a way to do microtransactions over IRC, i think you'd be minted

10:10 ridcully: or when some philantrope starts paying out lazybots karma points as bitcoins

10:25 justin_smith: Glenjamin: hah

10:43 benjyz1: thanks to BTC thats now possible

10:47 anyone using H2?

10:47 I tried korma, but it still requires migration AFAICS

10:54 justin_smith: I worked on a db abstraction that supported h2 for a while

11:12 cortexman: idiomatic way to loop over deeply nested hash map / edn file?

11:13 justin_smith: either clojure.walk/postwalk or a recursive function that maps over each key/entry pair

11:15 cortexman: get-in looks useful as well

11:16 doesn't seem to be good for looping though

11:18 ridcully: depending on your data also tree-seq can help

11:19 cortexman: i am iterating over a very nested json / edn file and inserting into datomic

11:19 i wrote a nested (for (let (for (let ... structure but it seems wrong

11:19 i need access to each outer key/value

11:30 justin_smith: what does "outer" mean here? because by my definition of outer, all you need to do is map on the hash map if that's what you need

11:31 cortexman: justin_smith just like a deeply nested loop where you have access to all the outer loop variables from inside

11:31 i'm trying to use postwalk but i don't get why this prints [nil nil] (postwalk (fn [x] (println x)) {:a "a" :b "b"})

11:31 justin_smith: cortexman: ok yeah, postwalk won't let you carry context like that

11:32 cortexman: the return value of your function replaces the item it receives as an argument

11:32 postwalk is designed for nested transformations

11:33 cortexman: i think the recursive function approach is the natural way to clean up my (for (let structure

11:33 with -> threads, maybe

11:33 justin_smith: for nested context, you need a recursive function, calling map, for, or mapcat if done to generate data, calling doseq if it is done for side effects

11:57 cortexman: justin_smith, this is where i'm at. it doesn't work.. ;) https://gist.github.com/brianmingus/ffa2486b6d657ffaeeb2

12:10 justin_smith: ,(defn loop-with-keys ([f e] (loop-with-keys f e [])) ([f e keychain] (f e keychain) (let [tr (cond (map? e) e (coll? e) (map list (range) e) :else nil)] (doseq [[k el] tr] (loop-with-keys f el (conj keychain k)))))) ; cortexman

12:10 clojurebot: #'sandbox/loop-with-keys

12:11 justin_smith: ,(loop-with-keys #(println % "at" %2) {:a 0 :b [1 2 3]})

12:11 clojurebot: {:a 0, :b [1 2 3]} at []\n0 at [:a]\n[1 2 3] at [:b]\n1 at [:b 0]\n2 at [:b 1]\n3 at [:b 2]\n

12:12 justin_smith: cortexman: that's probably not what you want, but probably also close enough to adapt for what you want

12:12 cortexman: if you wanted values not side effects, change the doseq to for

12:13 well I guess it would also need the call to f to move...

12:14 cortexman: if all you want is all the leaves, (remove coll? (tree-seq s)) suffices

12:15 err, (remove coll? (tree-seq coll? seq s))

12:47 ack006: leiningen question here: why do some repl middleware projects suggest adding plugins to :user while others suggest adding to :repl in ~/.lein/profiles.clj? doesn't adding to :repl improve lein startup time when you don't need a repl?

13:53 benjyz1: hi, trying to understand this snippet

13:54 (defmethod attach-route :all

13:54 [^Chain chain [method & handlers]]

13:54 what is "^" ?

13:54 justin_smith: it means apply this metadata to the next item

13:54 ,(meta ^:foo [])

13:55 clojurebot: {:foo true}

13:55 justin_smith: ,^:foo []

13:55 clojurebot: []

13:55 benjyz1: how many input arguments does this method have?

13:55 chain, method & handlers?

13:55 justin_smith: two

13:55 ridcully: two

13:55 a chain and some sequence

13:55 justin_smith: [method & handlers] is a destructuring of a single argument

13:56 ridcully: is this from catacumba?

13:56 benjyz1: ridcully: yes, exactly!

13:57 https://github.com/funcool/catacumba/blob/master/src/clojure/catacumba/impl/routing.clj#L135

13:59 why?

13:59 clojurebot: http://clojure.org/rationale

13:59 benjyz1: ^^^

14:02 ridcully: benjyz1: just out of curiosity. i spent quite some time reading the code to get my registry in there, so that rang a bell

14:02 benjyz1: ah good to know some people are using it

14:02 I've switched from ring

14:03 looking to contribute a little bit here and there

14:07 couldn't this methods be simplified there? :get :post :put are the same

14:09 justin_smith: benjyz1: yeah, looks like someone doesn't know about :default for defmethod

14:10 in fact it looks like all the methods would be the default which means it doesn't even need to be a multimethod

14:11 oh wait, except for :error and :setup

14:11 ridcully: and :any ?

14:12 different handler

14:12 benjyz1: :any and :all are the same

14:12 :get :post :put :delete

14:12 fantazo: hi, why the f* is cider not listed doing package-refresh-contents && package-install on emacs 24.5?

14:13 do I need to do something special just to get it working?

14:16 sry, I'm a little bit unrelaxed.

14:18 benjyz1: justin_smith: chaining of methods is the same as with functions?

14:18 :default doesn't help here

14:41 justin_smith: benjyz1: what? I mean when you implement a method for :default then all unmatched args get that method. Then you only need to define :default, :error, and :setup

14:41 benjyz1: when I suggested it could be a function, I had not noticed that :error and :setup were different

14:42 ridcully: i guess the author wants the http verbs there explicitly

14:42 benjyz1: I'm trying to have a method call another method

14:42 ridcully: or otherwise fail?

14:43 benjyz1: so (defn- addroute [..]) (defmethod :get [] addroute)

14:43 justin_smith: ridcully: in that case you could have a method that mapped :get :put :post :patch :delete :any and :all to the same value

14:43 *a dispatch, that is

14:43 ridcully: that sounds nice

14:43 justin_smith: benjyz1: that would just return addroute

14:44 benjyz1: I mean (addroute) ... i.e. calling the function

14:44 better would be catching :get :put ... etc?

14:49 hmm, these functions are a bit weird. method is an argument an a type dispatch..

14:49 justin_smith: ,(defmulti verb (fn [v & args] (get {:get :verb :put :verb :post :verb :patch :verb} v v)))

14:50 clojurebot: #'sandbox/verb

14:50 justin_smith: ,(defmethod verb :verb [v & args] (println 'verbing))

14:50 clojurebot: #object[clojure.lang.MultiFn 0x4e5f2dd7 "clojure.lang.MultiFn@4e5f2dd7"]

14:50 justin_smith: ,(verb :get)

14:50 clojurebot: verbing\n

14:50 justin_smith: ,(verb :put)

14:50 clojurebot: verbing\n

14:50 justin_smith: etc.

14:52 benjyz1: thx. what does (get {..} v v) do?

14:53 justin_smith: benjyz1: it looks up v in a hash map, returning v if not found

14:53 ,(get {} :a :a)

14:53 clojurebot: :a

14:53 justin_smith: ,(get {:a :b} :a :a)

14:53 clojurebot: :b

14:54 justin_smith: in other words, it looks for a replacement, but returns unchanged if no replacement is available

14:55 benjyz1: some more wisdom to digest. trying to follow in the context of this multi-method

14:55 justin_smith: benjyz1: so it's using that hash-map to map multiple keywords to the same dispatch

14:57 benjyz1: what about something like this

14:57 justin_smith: so it's like implementing :default and not specifying those keys, but it explicitly specifies the keys and also errors if an unknown key is provided (which would not occur if :default was defined (unless you errored from default))

14:57 benjyz1: "(defmethod attach-route [:get :post] ..."

14:58 justin_smith: benjyz1: that would work if your dispatch value was the vector [:get :post]

14:58 benjyz1: ah no. I want to dispatch for :get and :post

14:58 justin_smith: benjyz1: vectors are valid dispatch values, they are not treated as a series of matches

14:58 benjyz1: individually

14:58 justin_smith: right, multimethods don't work that way

14:59 you need a dispatch function that matches both of them to the same value, or to repeat your definition, or to have them use a default

14:59 ,(defmulti vds identity)

14:59 benjyz1: I'll try

14:59 clojurebot: #'sandbox/vds

15:00 justin_smith: ,(defmethod vds :default (constantly :unmatched))

15:00 clojurebot: #error {\n :cause "Unable to resolve symbol: vds in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: vds in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: vds in this conte...

15:00 justin_smith: ,(defmulti vds identity)

15:00 clojurebot: #'sandbox/vds

15:00 justin_smith: ,(defmethod vds :default (constantly :unmatched))

15:00 clojurebot: #error {\n :cause "Parameter declaration constantly should be a vector"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Parameter declaration constantly should be a vector, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.IllegalArgumentException\n :message "Parameter decla...

15:00 justin_smith: ergh

15:00 ,(defmethod vds :default [_] :unmatched)

15:00 clojurebot: #object[clojure.lang.MultiFn 0x5232c67d "clojure.lang.MultiFn@5232c67d"]

15:01 justin_smith: ,(defmethod vds [:a :b] [_] :matched)

15:01 clojurebot: #object[clojure.lang.MultiFn 0x5232c67d "clojure.lang.MultiFn@5232c67d"]

15:01 justin_smith: ,(vds :a)

15:01 clojurebot: :unmatched

15:01 justin_smith: ,(vds [:a :b])

15:01 clojurebot: :matched

15:01 justin_smith: benjyz1: ^ that's what I was trying to say about dispatch with a vector

15:02 benjyz1: in this case the code is a wrapper around the Java lib ratpack

15:03 I think ring uses a few simple macros for routing

15:03 justin_smith: benjyz1: ring has no routing

15:03 benjyz1: compojure uses a few moderately complex macros for routing

15:03 benjyz1: ah I see

15:04 the cool thing about catacumba is it has better async support (afaics)

15:04 justin_smith: what about ring prevents async from working? (honestly I don't know)

15:06 benjyz1: not sure. Ratpack and netty are highly optimized

15:06 justin_smith: aleph is ring compatible and uses netty

15:06 iirc

15:07 benjyz1: yes. cata is not aiming at that

15:07 "Provide a simple and lightweight approach for defining asynchronous web services with support for different abstractions such as promises, futures, core.async, manifold, reactive-streams, etc…​"

15:07 https://funcool.github.io/catacumba/latest/#rationale

15:07 justin_smith: you're aware ring is a protocol and not a web server, right?

15:07 benjyz1: yes

15:07 justin_smith: OK

15:08 benjyz1: if I understand much of this is designed around jetty

15:08 justin_smith: no, it is a protocol

15:08 it has implementations for many servers

15:08 benjyz1: ok. it would be good if that doc would go into more details

15:08 justin_smith: jetty is the default for dev because it is a small dep

15:09 benjyz1: don't know too much about jetty itself, but it doesn't seem that active

15:10 justin_smith: I mean it could be that catacumba just wants to be less modular and do it's own monolithic thing, that's legit, but I don't see why avoiding ring would help them be more async or have better performance at all

15:10 benjyz1: or at least it looks to me not that versatile. its the old J2EE kind of stuff I'm trying to avoid

15:10 justin_smith: benjyz1: I don't use jetty

15:10 I always use ring but I never use jetty

15:10 jetty isn't part of ring

15:10 benjyz1: you're right. I don't know the answer to that

15:11 its a young project and only 1 contributor

15:11 but leveraging Ratpack and Netty look like a good strategy

15:11 Ratpack is a kind of re-implementation of Grails

15:12 justin_smith: interesting, not a reference to sinatra?

15:12 benjyz1: yes, it is

15:12 https://ratpack.io

15:13 justin_smith: yeah, looking at that now

15:13 benjyz1: the other thing what I thought would be cool is a full-stack Clojure/Clojurescript

15:13 I've seen some talk about it , and a few templates

15:13 justin_smith: that's what luminus does

15:14 benjyz1: MeteorJS developed something like that in JS

15:14 where only data goes over the wire

15:14 and then gets re-rendered... so no HTML server side at all

15:14 justin_smith: wait what other than data would go over the wire?

15:15 oh

15:15 yeah, that's what reagent is like too

15:15 benjyz1: right. Om / React. but that's only on the client ;)

15:15 justin_smith: you can render reagent's hiccup syntax on the server too

15:16 they intentionally picked a syntax that had a server side implementation

15:16 benjyz1: e.g. what do you do if there is a change on the server

15:16 you have to send an update to the client

15:17 Meteor does this with keeping by keep a Mini Mongo database in the browser

15:17 but as its all in JS, I think the project is a failure. not so surprising

15:17 justin_smith: om puts a datascript impl in the browser

15:17 benjyz1: ah cool

15:18 yes, I'm sure a few people are doing similar cool stuff

15:18 with a full Clj/Cljs stack

15:21 ,(defmulti verb (fn [v & args] (get {:get :verb :put :verb :post :verb :patch :verb} v v)))

15:21 clojurebot: #'sandbox/verb

15:21 benjyz1: ,(defmethod verb :verb [v & args] (println 'verbing))

15:21 clojurebot: #object[clojure.lang.MultiFn 0x2cbcb5f6 "clojure.lang.MultiFn@2cbcb5f6"]

15:22 sdegutis: Aha! I figured it out! (I think. Maybe.) This recursive algorithm should use /reduce/, not /for/!

15:22 benjyz1: ,(verb :get)

15:22 clojurebot: verbing\n

15:22 benjyz1: ,(verb :test)

15:22 clojurebot: #error {\n :cause "No method in multimethod 'verb' for dispatch value: :test"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No method in multimethod 'verb' for dispatch value: :test"\n :at [clojure.lang.MultiFn getFn "MultiFn.java" 156]}]\n :trace\n [[clojure.lang.MultiFn getFn "MultiFn.java" 156]\n [clojure.lang.MultiFn invoke "MultiFn.java" 229]\n [sandbox$eval103 invokeS...

15:22 benjyz1: ,(verb :put)

15:22 clojurebot: verbing\n

15:25 sdegutis: reduce rocks

15:27 justin_smith: ,(reduce :rocks nil (take 10 (iterate (fn [x] {:rocks x}) :rocks)))

15:27 clojurebot: {:rocks {:rocks {:rocks {:rocks {:rocks :rocks}}}}}

15:29 justin_smith: sdegutis: quick, without trying it, what happens if you change (take 10 ...) to (take 15 ...)

15:30 sdegutis: justin_smith: you break 24 legacy .NET apps

15:30 justin_smith: ,(reduce :rocks nil (take 15 (iterate (fn [x] {:rocks x}) :rocks)))

15:30 clojurebot: :rocks

15:30 justin_smith: !

15:30 sdegutis: whaaaa?

15:30 justin_smith: ,(reduce :rocks nil (take 16 (iterate (fn [x] {:rocks x}) :rocks)))

15:30 clojurebot: {:rocks {:rocks {:rocks {:rocks {:rocks {:rocks {:rocks {:rocks {:rocks {:rocks #}}}}}}}}}}

15:31 sdegutis: justin_smith: you break my brain

15:31 justin_smith: your welcome

15:31 sdegutis: I think it's a weirdo version of modulo

15:32 discovered accidentally

15:32 sdegutis: That's insane.

15:32 justin_smith: I am pretty printing your code and experimenting with it in CIDER to understand wth is going on.

15:33 justin_smith: sdegutis: reductions might help

15:33 sdegutis: Also ->> considering you really just had (->> :rocks (iterate (fn [x] {:rocks x})) (take 10) (reduce :rocks nil))

15:34 justin_smith: sdegutis: oh wow nothing like modulo at all, this is a very odd pattern

15:35 oh, the pattern follows powers of 2

15:35 of course

15:35 1, 7, 15, 31, ... are all :rocks I think

15:36 and then it counts back to deeper and deeper nestings as you move back to lower numbers

15:36 oh and 3 duh

15:37 sdegutis: :D

15:38 justin_smith: or you could say instead that a power of two will have N repeats of :rocks, and then it counts down as you go up until you hit the next power of 2

15:39 sdegutis: Hmm, (update-in m [:some-key last] ...) isn't a thing, is it?

15:39 Dang.

15:39 justin_smith: no, unless last is a key!

15:39 sdegutis: Heh nope.

15:39 justin_smith: ,(update-in {} [:some-key last] assoc :a 0)

15:39 clojurebot: {:some-key {#object[clojure.core$last__4383 0x11c286fb "clojure.core$last__4383@11c286fb"] {:a 0}}}

15:40 sdegutis: My structure is like {:some-key [[:a] [:b :c] [:d]]} and given :e I need to derive {:some-key [[:a] [:b :c] [:d :e]]}

15:40 Perhaps I should reverse them and just use a constant 0 instead.

15:40 justin_smith: sdegutis: maybe you need to peek etc. in your update function

15:40 sdegutis: peek? hmm what's that?

15:40 justin_smith: ,(peek [:a :b :c])

15:40 clojurebot: :c

15:40 sdegutis: Neat!

15:41 justin_smith: ,(pop [:a :b :c])

15:41 clojurebot: [:a :b]

15:41 sdegutis: So it's like conj but a getter for first.

15:41 justin_smith: sdegutis: "get the last thing conjd" is maybe one way to put it

15:41 useful for stacks for obvious reasons

15:41 sdegutis: Yeah I'll just use linked-lists then and use 0.

15:41 justin_smith: ,(peek '(:a :b :c))

15:41 clojurebot: :a

15:42 sdegutis: Otherwise this requires counting the thing inside the structure, which kind of defeats the purpose of using update-in.

15:43 justin_smith: ,(update-in {:a [1 2 3]} [:a] (fn [x] (conj (pop x) (inc (peek x))))) ; yeah kind of sucks

15:43 clojurebot: {:a [1 2 4]}

15:43 sdegutis: :D

15:43 justin_smith: sdegutis: though one could implement pupdate and make it nicer

15:43 sdegutis: Meh, nobody ever said the intermediate data structure needs to resemble how we logically think about it nor what the end result will be.

15:44 justin_smith: ,(defn pupdate [s f] (conj (pop s) (f (peek s))))

15:44 clojurebot: #'sandbox/pupdate

15:44 justin_smith: ,(update-in {:a [1 2 3]} [:a] pupdate inc)

15:44 clojurebot: {:a [1 2 4]}

15:44 sdegutis: So this is a bit off topic, but are you able to automatically know/hear whether two different notes are the same note just in different octaves?

15:45 justin_smith: sdegutis: it's pretty distinctive and easy to learn

15:45 yes

15:45 I like pupdate because puppies

15:45 p(eek/op)update

15:46 sdegutis: If someone plays two different C's on the piano, I can tell they're the same note. But nobody else in my family can, and I'm surprised because I thought it was something everyone automatically just knew.

15:46 justin_smith: sdegutis: well I think you kind of have to know what to listen for (though it is a simple thing to hear once you know what it is)

15:46 sdegutis: Hmm. Yeah maybe.

15:47 ridcully: pubdate!

15:47 justin_smith: ridcully: that would be a good one too

15:51 amalloy: https://github.com/amalloy/useful/blob/ecbdaf10ffe341d7af3ed47b2706d1c668a37da4/src/flatland/useful/utils.clj#L134

15:51 update-peek

15:52 justin_smith: amalloy: ok I guess that name is easier to understand and all

15:53 amalloy: unlike a lot of the cutesy names in useful

16:01 useful, feature such obvious names as knit and glue

16:02 ridcully: to knit a castle and sniff glue?

16:23 justin_smith: ridcully: you know I would have said knit a scarf but I guess that works

16:26 sdegutis: Right.

16:33 ,(update-in () [0] conj 1)

16:33 clojurebot: #error {\n :cause "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.Associative"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.Associative"\n :at [clojure.lang.RT assoc "RT.java" 792]}]\n :trace\n [[clojure.lang.RT assoc "RT.java" 792]\n [clojure.core$assoc__4371 invokeStatic "core.clj" 191]\n...

16:33 sdegutis: Okay so that's unintuitive to me.

16:34 ,(update-in [] [0] conj 1)

16:34 clojurebot: [(1)]

16:34 justin_smith: sdegutis: you are conjing onto element 0

16:34 element 0 is nil, conj on nil gets a list

16:35 sdegutis: the first one fails because you can't look up 0 in ()

16:35 because () is not associative

16:35 sdegutis: Right, it just seems like you should be able to do nth on () though.

16:35 justin_smith: sdegutis: update* only work on associative things though

16:35 there's no "replace-nth" for lists

16:36 sdegutis: Oh right because you can't re-associate 0 in ().

16:36 Well technically you can but not 1 easily.

16:36 I see now.

16:36 Thanks justin_smith.

16:36 justin_smith: it might be clearer if you were doing (update '(1 2 3) [2] inc)

16:37 sdegutis: Right on.

16:42 fantazo: ok. sometimes you need to throw away old elpa installed code just to be able to install new packages.

16:42 thx emacs, that's so totally obvious.

16:42 justin_smith: fantazo: common cider issue

16:44 fantazo: justin_smith, but why? this is so totally counter intuitive and you waste hours with this stupidity. no bells, no warnings.

16:44 sdegutis: fantazo: justin_smith isn't a fan of cider, but I'm a super fan of it ever since version 0.10.x

16:44 I really enjoy the inline execution results.

16:45 fantazo: well, I tried to install it and I wasted hours of why it didn't want to install from elpa

16:46 when you do a package-refresh-contents and a package-install ci<tab><tab> and are expecting that it completes with cider but no, just circe or any other package.

16:46 sdegutis: Is it inefficient to keep "appending" to a string via (str original-string new-string)?

16:47 lockdown: what I have noticed of cider is that they care more about features than improving stability

16:47 s/about/about adding/

16:47 sdegutis: Would it be way more efficient to just keep a coll of strings, and then (apply str) them together at the end?

16:47 justin_smith: sdegutis: better to consolidate into one str call if you can, or use a StringBuilder (which is what str uses internally)

16:47 sdegutis: Ah cool.

16:47 fantazo: lockdown, like its normal in emacs?

16:47 sdegutis: I had my suspicion about that.

16:47 justin_smith: sdegutis: right, applying str will definitely do the trick

16:48 sdegutis: Sweet.

16:48 lockdown: fantazo: no, core emacs is pretty stable ;)

16:48 sdegutis: rhickey thought of everything!

16:48 fantazo: emacs is all about features hacked together without spending any time on making them flow

16:48 justin_smith: sdegutis: though directly using a StringBuilder might be a little better than that (at the cost of explicitly mutating!)

16:48 lockdown: fantazo: if you mean external packages, then yes

16:49 sdegutis: justin_smith: thanks

16:49 justin_smith: yeah, there's lots of featureful things for emacs that I try sometimes and find out there are still buggy and stop using again

16:49 fantazo: hmm ok. still not convinced, but you have an opinion and I have mine.

16:49 justin_smith: *they are ...

16:50 fantazo: I've never seen serious issues with emacs itself (beyond how it handles long lines, and that's strightforward to avoid usually)

16:56 sdegutis: Should rest or next be used when you know it's a list?

16:57 justin_smith: next, rest is the lazierer one

16:57 sdegutis: well, depends which you want really...

16:57 ,((juxt next rest) [1])

16:57 clojurebot: [nil ()]

16:57 sdegutis: Ah.

16:58 ((juxt next rest) [1 2])

16:58 ,((juxt next rest) [1 2])

16:58 clojurebot: [(2) (2)]

16:58 sdegutis: Neat.

16:58 justin_smith: yeah, they are the same until they return something empty

16:58 next has to peek ahead

16:58 rest does not

16:59 sdegutis: I see.

17:00 I am determined to complete this recursive function before 5pm, one hour from now!

17:01 Oh wait I think I just did.

17:35 Wow. Nope. So close yet so far.

17:36 I'm just gonna roll this out with a bunch of (let)s and refactor once it's working. This is getting crazay.

17:41 rcassidy: post a gist!

17:41 sdegutis: ^

17:41 sdegutis: Oh yeah good idea.

17:41 If I give up then I will.

17:41 But it'll probably be an open source library anyway.

17:44 When you have more than one prefix is it prefices?

17:46 AimHere: Prefixes.


17:47 I don't know if they're actually doing their job of increasing code readability.

17:47 They're so long too!

17:53 Haha, turns out I forgot to use the recursed value from above in each deeper iteration of the function.

17:53 Oops! LOL.

17:55 rcassidy: long variable names are a good thing if they are desceriptive

17:55 descri**

17:55 sdegutis: :D

17:55 creat();

18:04 Dang. Both clojure.math.combinatorics/cartesian-product and amalloy's hand-rolled version have unexpected behavior in the case of [[] [:a :b]]

18:05 Fortunately remove empty? probably fixes that. But still, weird property of (for).

18:05 amalloy: unexpected? that's like, the obviously correct result

18:05 the cartesian product of the empty set with anything is also empty

18:06 sdegutis: Oh.

18:06 Okay then

18:06 Well I don't know math very well.

18:07 amalloy: well, the cartesian product of two sets isn't that hard to describe. suppose the two sets are colors and shapes

18:07 then their product is all the ways to choose exactly one color and exactly one shape

18:08 if there are zero colors to choose from, there's zero ways to make that choice

18:08 sdegutis: Ahh!

18:08 Kind of like multiplying by zero.

18:08 Hence "product". Got it.

18:08 amalloy: exactly

18:10 sdegutis: Thanks amalloy. I don't care what they say about you, you're a really helpful nice guy.

18:12 amalloy: (That's supposed to be a joke.)

18:12 amalloy: i laughed

18:12 sdegutis: Yay!

18:21 Does Clojure offer some simple way of "moving" an item matching a predicate to the beginning of a coll?

18:23 TEttinger: i liek malloy macro magic

18:29 sdegutis: Two reduces in one day! Man I'm honor roll!

18:30 *on a

18:30 ewilazarus: Hey guys! I would like some help here: I am trying to be smart with macros, but I think that what I'm trying to achieve is impossible. Please check out this snippet: https://gist.github.com/ewilazarus/76195fb152e843be7222 . Now, what I'm trying to do is to pass a list to a macro, which its contents should reference the variables in the scope "inside of the macro". Can you please help?

18:34 sdegutis: ewilazarus: I think technically it may be possible, but it's "bad practice"

18:35 ewilazarus: I think you have to do it by quoting them though. Try that.

18:37 Oh man, I just used str/starts-with? and str/includes? !!!

18:37 ewilazarus: sdegutis: thanks! I tried but I can't make it work

18:39 sdegutis: ewilazarus: no idea then sorry :(

18:40 ewilazarus: sdegutis: np, thanks anyways

18:55 rhg135: the thing is iit's always possible, just not sanely

18:55 sun.misc.Unsafe exists

18:57 justin_smith: ewilazarus: so you want to be able to use request and handler in mw-logic right?

19:00 ewilazarus: if so, you want this --

19:00 ,(defmacro defmw [mw-name & mw-logic] `(defn ~mw-name [~'handler] (fn [~'request] ~@mw-logic)))

19:00 clojurebot: #'sandbox/defmw

19:00 justin_smith: ,(macroexpand-1 '(defmw wrap-options (handler request)))

19:00 clojurebot: (clojure.core/defn wrap-options [handler] (clojure.core/fn [request] (handler request)))

19:01 justin_smith: ewilazarus: this is a problem in the general case (magic binding names, spooky action at a distance), but this is arguably idiomatic enough to work. It's a value judgment.

19:04 rhg135: hmm, if I read an use of that and say how the result is used I'd not be confused

19:04 ewilazarus: justin_smith, that's exactly what I wanted!

19:06 justin_smith, thanks a lot!

19:08 rhg135: I do like how it discourages closing over (maybe stale) state

19:11 ewilazarus: that's actually amazing...

20:22 athinggo1ngon: hi, can anyone help with the following problem? http://pastebin.com/j8b03FRY

21:25 rhg135: https://www.refheap.com/114756, something about that method implementation is offputting but I can't tell what

21:40 justin_smith: rhg135: I find the usage of vectors somewhat surprising - is it an api that takes List or something?

21:42 rhg135: That is me being too lazy to type the key names

21:45 justin_smith: athinggo1ngon: you can do it with a filter to remove the things lacking 'ds1 and a (map #(update-in % ... ) ...) to remove the 'nope things. It's about twice as big if you need the results to be a vector and lazy-seqs don't suffice

21:47 pilne: lisp/scheme/clojure/haskell (and to some extent forth) have ruined any other languages for me >.<

22:28 rhg135: That's good, they run everywhere

22:30 Just lisp is near universal

22:31 justin_smith: rhg135: but forth runs on more cpus than all the others put together

22:32 rhg135: Elaborate, please

22:32 justin_smith: there are processors that have never had an os implemented that still run forth

22:33 rhg135: And jvm bytecode too

22:33 And probably js

22:33 justin_smith: forth easily runs on 100x the sheer number of processor models js and jvm combined run on

22:34 it's not even in the same league in terms of complexity / resources needed, by far

22:34 rhg135: That is true, but in practice, I only care about x86 and arm

22:34 justin_smith: rhg135: forth code is typically smaller in RAM usage than the equivalent assembly

22:35 rhg135: OK, I was just making a pedantic point

22:35 rhg135: Inb4 I write a clojure based toaster

22:39 TEttinger: cloaster

22:40 rhg135: And a typo burnt my toast

22:41 justin_smith: quarter bagles for (), toast for [], eggos for {} and you are good to go

22:42 of course, # is a pat of butter, so a buttered eggo is a set, etc.

23:05 rhg135: When I first learned of C in cars, I thought why!?

23:31 as an aside, what happened to the other 550 people in here?

23:32 TEttinger: rhg135: netsplit?

23:32 I see a ton of people

23:32 rhg135: maybe but none of the other channels I'm on seem affected

23:33 ah there we go

23:33 (dec znc)

Logging service provided by n01se.net