#clojure log - Jan 20 2016

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

0:13 irctc: is clojure is a dialect of lisp, what is english language?

0:20 montanstercat: php

0:30 TEttinger: irctc: clojure is to some dialects of Scheme, like Racket for example, as english is to Dutch

0:31 I have a "thematic gibberish" generator, that makes random text that seems like an existing language or a combination of them. it's written in java but was originally a literal one-liner (400+ character line, but one line) in Clojure

0:31 the english-like stuff it makes is basically dutch

0:31 it's hard to tell apart

0:35 irctc: hmmm

3:14 cenzhe: hi all

3:15 Having heard of the 1.8 release went out, I tried it with my project, but sadly sees a minor performance drop, instead of a gain because of the direct linking feature

3:16 is this just me, or it's common among you folks?

3:45 puredanger: I can't see how it would make things slower although there are certainly many projects where you would not see much change

3:46 Are you comparing 1.7 to 1.8 or 1.8 with and without direct linking

3:48 cenzhe: it's between 1.7 and 1.8

3:55 By minor, in our case, 1.8 will roughly, but consistently be about 3% slower after initial stabilization

3:56 I haven't done any further profiling to spot the problem, just wonder if other people seeing the same problem

3:58 TEttinger: what is direct linking?

4:02 cenzhe: if a fn is direct linked, it does not need to go through the var lookup phase any more to invoke it

4:06 TEttinger: huh, that slows things down? could it be another change other than direct linking?

4:16 jonathanj: can't you disable the direct linking feature to see if that is the cause? (it does seem extremely unlikely that direct linking has a negative performance impact)

4:37 cenzhe: yah, i'm thinking the same

4:37 good idea to disable direct linking and try again

4:37 i'll try and report back

4:39 wow, I thought direct linking was enabled by default

4:40 I have to add `-Dclojure.compiler.direct-linking=true` in order to use direct linking?

4:40 amalloy: cenzhe: 3%? that's surely within experimental error. how did you benchmark

4:43 cenzhe: the way is rudimentary. Within both versions, I run my task 20 times, exclude the first 5 results, and compare the rest

4:47 my project has a `parallel?` flag indicating whether to pmap things. With parallel off, the stabilized difference can go as wide as 7%. With parallel on, the gap is around 3%, but consistent

4:48 btw, though i used the word stabilize, the overall response time is still slowly dropping. I guess it's because JIT comes in.

4:50 if I plot the response time versus experiment index curve, it's slightly sloped down

4:50 and by consistent, i mean those two curves given by 1.7 and 1.8, the difference between two curves, is consistently around 3%

4:51 leaving for a while, BRB

5:04 irctc: Hi. Is this channel right place to ask stupid newbie questions?

5:06 neoncontrails: irctc: They've always helped me with mine. I say shoot

5:12 irctc: neoncontrails: I'm working through modern clojurescript tutorial, and trying to write some macros to automate some things. For instance, validate function (validate.cljsc from the gist below). I wrote some macro (my-validate.cljc for the gist below) but my function does not compile. And i don't understand why. The gist: https://gist.github.com/mbakhterev/86c4ac21ced119a5e90c

5:13 neoncontrails: The error is: java.lang.IllegalArgumentException: No matching ctor found for class valip.predicates$gt$fn__2332

5:14 neoncontrails: but everything works fine, when i'm trying in repl (apply validate {} (concat (quantity-check)))

5:15 TEttinger: it appears to be complaining about (gt 0)

5:15 irctc: TEttinger: Yep. But what exactly is wrong?

5:18 TEttinger: irctc: are you passing a string to where it expects a quantity?

5:19 irctc: TEttinger: No. All the parameters to valip predicates should be strings. So i pass only strings

5:20 TEttinger: what strings are they? I'm wondering if the issue is with the data

5:21 irctc: TEttinger: It seems not. Because in the repl expression (apply validate {:quantity "10"} (concat (quantity-checks))) works as expected.

5:22 TEttinger: hmm

5:23 irctc: TEttinger: it looks like i missunderstand macros

5:23 TEttinger: I'm not super great with them

5:23 clojurebot: excusez-moi

5:30 neoncontrails: I forget how immutable structures work. In Clojure to update a map without returning it, I'd do this

5:30 ,(def record (atom {:success [] :failed []}))

5:30 clojurebot: #'sandbox/record

5:30 neoncontrails: ,(swap! record update-in [:success] #(cons 'yay %))

5:30 clojurebot: {:success (yay), :failed []}

5:31 neoncontrails: Is that the best way to handle it in clojure too?

5:32 Err... sorry. In *cljs I'd declare as an atom, then do etc.

5:40 jonathanj: they're basically the same language, except one interops with Java and one with JavaScript, so yes that method is still worth considering

6:34 shaym: anyone using slamhound ? im getting class not found errors when running it

7:28 cenzhe: reporting back

7:28 after setting the flag `-Dclojure.compiler.direct-linking=true`

7:29 the performance drop no longer appears

7:29 but the performance gain is also negligible, basically less than 1%

7:31 that means, in my scenario, some other things in 1.8 can cause a slight performance penalty, but this can be made up with the gain introduced by direct linking

8:25 Guest96152: best way to get the value of of a symbol in a tupple? so '(my value is x) where x is a symbol, but I want x's value

8:48 cenzhe: Guest96152: what is known? the position of 'x, or the name will always be 'x?

8:59 beaky: hello

9:05 powered: good day

9:06 Bronsa`: cenzhe: did you try any of the 1.8 alphas/betas? would be interesting to understand where that slowdown was introduced

9:08 cenzhe: not yet, only the two major versions

9:09 I'll try testing some other interim versions when I got some time

9:36 pseudonymous: I was hoping anyone remembers/knows how to change the ns of one's REPL. I have a lein project and always start in dev/user.clj (which is fine), I just want to hop to another file/ns on occasion

9:39 cenzhe: (in-ns 'your-namespace)

9:40 pseudonymous: cenzhe: ah, of course, thank you :)

9:53 Kamuela: completely forgot how I installed clojure so now I’m not sure of my upgrade path

10:09 sdegutis: ,(remove #{:bar} #{:foo :bar :quux}) ;; Apparently this works.

10:09 clojurebot: (:foo :quux)

10:09 sdegutis: Pretty cool if you ask me.

10:09 Saying "remove this set from this other set."

10:10 It's like clojure.set/difference almost, but more intuitive for the simpler case.

10:10 Good morning. Hi.

10:51 Is there plan to integrate Clojure 1.8 Socket REPL into Leiningen.

10:54 wink: as it was released... yesterday? I think not

10:55 But feel free to open an issue or PR :)

10:56 sdegutis: Cool.

10:59 mynick12345: hi

11:00 heard about clojure. the git hub pulse is low. is this becoming deprecated?

11:00 egli: mynick12345: haha

11:00 pbx: mynick12345, i hope you are trolling

11:02 mynick12345: ok, so is it one of the big tecnologies for the future? really I'm blind

11:06 wink: aaw

11:07 https://github.com/clojure/clojure/pulse vs https://github.com/nodejs/node/pulse

11:08 it's clearly winning. mynick12345 has a point

11:09 sdegutis: myguidingstar: Yes. Clojure is becoming deprecated.

11:10 myguidingstar: In favor of Clojure 1.8.

11:10 myguidingstar: Please upgrade at my earliest convenient.

11:10 wink: sdegutis: tab complete is a lie

11:11 sdegutis: Nooooooooooooooo.com !!!

11:11 Aww mynick12345 left too.

11:16 Sorry myguidingstar. Wrong nick. Tab-complete lied to me.

11:22 alex``: good troll xd

12:32 justin_smith: cenzhe: I was just reading the scrollback, has anyone mentioned criterium yet? because I think you need to run things more than 100 times for hotspot to really come into play. Criterium helps with this sort of thing, for microbenchmarks at least.

12:58 lxsameer: hey folks, is there any thing like ruby's sprockets in clojure

12:58 ToxicFrog: What are ruby sprockets?

12:59 justin_smith: sprockets is some library for ruby, related to rails somehow iirc

12:59 https://github.com/rails/sprockets

13:00 basically we would use lein plugins (things like lein less, or even lein shell) in clojure land for this sort of thing

13:00 (usually)

13:04 lxsameer: justin_smith: thanks man,

13:04 justin_smith: lxsameer: nothing in the clojure world will be quite as "magic"

13:04 oh, I alsmot forgot, hlshipp has something too... one moment

13:05 lxsameer: justin_smith: what do you mean by quite as magic?

13:08 justin_smith: lxsameer: this is hlshipp's version of sprockets for clojure (clever name) https://github.com/hlship/dieter

13:08 lxsameer: justin_smith: awesome

13:09 justin_smith: lxsameer: what I mean is that ruby prefers convention over configuration, and has a lot of implicit / assumed behavior in its frameworks (including sprockets), and clojure libs on the other hand prefer causes of behaviors to be local to the thing they respond to and explicit

13:10 lxsameer: justin_smith: thanks man I completely got it

13:19 Kamuela: Ah I think I’ve installed lein through homebrew and I don’t think there’s an update for 1.8 yet

13:21 hiredman_: every lein project specifies the version of clojure it wants

13:22 the version of clojure you use for your projects is has nothing to do with lein

13:23 hiredman: this is what specify dependencies looks like https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L45-L57

13:25 for your projects using lein, you have your own dependnencies specified, and clojure and the version of clojure the projects build should use is included in there

13:33 lokien_: hello j-pb_ :D

13:37 Gregory: I have a noob question, and no one seems home at #clojure-begginers, may I ask it here?

13:38 beaky: hello

13:38 yes ask away :D

13:38 Gregory: thanks

13:38 Why can I do this: (def i #(identity %)) (-> 'wat' i) But not this: (-> 'wat' #(identity %) )

13:38 j-pb_: lokien_: hey :)

13:39 lokien_: j-pb_: I was hunting for you for like a week!

13:39 j-pb_: lol sorry, I have a super bad cold

13:40 lokien_: what can I help you with ?

13:40 lokien_: j-pb_: well, do you feel better now?

13:40 j-pb_: kinda ^^

13:41 Gregory: Oh DERP i just answered my own question---- (-> 'wat' (#(identity %)) )

13:41 justin_smith: Gregory: responded on #clojure-beginners because I saw the question there first

13:41 Gregory: thanks JS

13:41 justin_smith: ,'#(identity %)

13:42 clojurebot: (fn* [p1__25#] (identity p1__25#))

13:42 justin_smith: ,(macroexpand-1 '(-> "wat" #(identity %)))

13:42 clojurebot: (fn* "wat" [p1__50#] (identity p1__50#))

13:42 beaky: right you need to surround the #() with an extra parens

13:42 justin_smith: Gregory: in this channel I can show you the result from the bot, instead of just assuming you trust me :) ^

13:43 beaky: or just use identity

13:43 beaky: ye or that

13:43 j-pb_: lokien_: so what's been bugging your ^^?

13:43 beaky: btw im developing a webapp with clojure

13:43 justin_smith: cool

13:43 beaky: but for frontend stuff im used to relying on npm and the build tools with it (like babel and stuff)

13:43 does clojure have something for that

13:43 or should i do it the node way

13:44 lokien: j-pb_: that's great! I'll pm you, I don't want to pollute the irc :)

13:44 j-pb_: sure

13:44 justin_smith: beaky: npm for the frontend? so it's a js hosted app and not a webapp?

13:45 or do you mean it's a cljs app, with node on the backend?

13:45 beaky: its a clojure webapp with some extra frontend stuff

13:45 like babel

13:45 (clojure for backend app server)

13:46 wow i can use clojure for the browser stuff as well?

13:46 justin_smith: with clojurescript you can yeah, that's why I was confused why you called it clojure but also you are using node- but I guess you are using node for server side processing of js stuff?

13:47 with clojurescript we have google's closure compiler built in

14:12 tos9_: Hi. Can I get the REPL to not exit on sigint?

14:13 Hrm it looks like the vanilla REPL doesn't actuall exit, so it must be something else that's ruining that

14:18 Ah, maybe it's lein repl vs lein run -m clojure.main repl.clj? Is it the former that is setting up signal handling etc.?

14:23 justin_smith: yeah, lein sets up the signal handling

14:23 tos9_: it looks like lein trampoline cljsbuild repl-listen also exits

14:23 justin_smith: funny that lein repl is now "vanilla" while just running clojure.jar is the special case, lol

14:24 tos9_: justin_smith: I meant vs clojurescript in that case :P

14:24 justin_smith: right, any task but repl will lack that signal handling that repl sets up

14:24 tos9_: (But also I'm a noob)

14:24 A ha. OK. So I guess I want to ask how I can make lein repl get me to a clojurescript repl then?

14:24 justin_smith: tos9_: clojure.jar or the equivalent, running clojure.main, won't install the interrupt handlers

14:24 tos9_: I see https://github.com/cemerick/piggieback but I've had a couple of issues with it

14:24 justin_smith: /nod

14:25 justin_smith: tos9_: I guess - you could look into using chestnut / weasel

14:25 tos9_: ah cool, I found weasel too

14:25 justin_smith: OK I'll give that a shot, danke.

14:26 Oh, one other unrelated question -- how can I get core.async to propagate warnings / "exceptions" if that's what they are

14:26 e.g. (go (<! completely-does-not-exist)) appears to just block indefinitely

14:27 hiredman: catch them and propagate them

14:28 although that would be a compiler error

14:29 (if a name doesn't exist you should get a compile time error)

14:30 tos9_: hiredman: So this I'm guessing is a clojurescript thing

14:31 When I call (asdf), I get a WARNING and a TypeError printed

14:31 when I try to have a channel read from asdf, I get silence.

14:31 But in a non-clojurescript REPL I thiink that appears to not be the case

14:31 hiredman: that is likely a bug in the cljs core.async stuff then

14:36 tos9_: I'm trying to produce a SSCCE but my clojure is terrible :P -- how come when I run lein repl without a project.clj (hoping to just get a repl I can do stuff at) I don't get access to the clojure stdlib

14:36 * tos9_ downloads clojure.jar

14:36 hiredman: tos9_: what do you mean by stdlib?

14:37 tos9_: hiredman: (require 'clojure.core.async) -> FileNotFoundException Could not locate clojure/core/async__init.class or clojure/core/async.clj on classpath.

14:37 hiredman: tos9_: sure

14:37 tos9_: core.async is a separate library that you have to say you want

14:38 it is not distributed in the clojure jar

14:38 tos9_: Ah. OK -- I guess that's not true in clojurescript land

14:38 Because my project.clj for that project doesn't declare it in :dependencies?

14:38 Or maybe it's a sub dep of cljs-http... that seems more likely.

14:40 hiredman: Can I specify deps on the CLI if I just want a standalone REPL with pulled in deps to play with for a moment

14:40 hiredman: no idea, I never use lein without a project

14:41 * tos9_ nods

14:41 tos9_: Do you just never not have a project? Or do you not use lein when you don't have a project?

14:41 hiredman: I don't use lein when I don't have a project

14:41 rhg135: Tos9_ yes with profiles.clj

14:42 tos9_: rhg135: This looks persistent too -- right?

14:42 I guess that will work.

14:43 rhg135: Yeah it's persistent

14:44 msw: how does one type-tag return type of a function which is documented? (defn tagged ^long [^long x] x) is the correct way to say (tagged) returns long according to fikes & clj 1.8. Now try and add docco. (defn tagged ^long "docstring" [^long x] x) doesn't parse. Is there another way rather than brutally manipulating the meta manually after definition to get a docstring in?

14:45 heh, keep experimenting. It's (defn tagged "docstring" ^return-tag [...] ...). Thanks for listening to the question ;)

14:54 tos9_: :/ OK now I found my actual problem -- so in clojure, for things that take additional options in a map or whatever, is it up to the library to raise errors for unknown keys

14:55 Or can you use like a destructuring to force the map to only contain keys that you explicitly define

14:55 terom: tos9_: you can use lein-try for trying out libraries without a project

14:55 tos9_: terom: awesome, this looks exactly like waht I was asking for

15:15 hiredman: destructuring is short hand for pulling a value out of a datastructure and binding it to a name

15:16 for example (get {:foo 1} :foo)

15:16 get doesn't constrain the keys the map can have, it doesn't even throw an error if the map doesn't contain the key you are asking for

15:26 tos9_: /nod -- OK, so same as Python.

15:27 So the answer is "yes" roughly? Specifically my actual issue turned out to be I called (foo {:bar 12}) but it was in fact (foo {:baz 12})

15:27 and :bar was just silently meaningless.

15:27 In Python this would basically be like having an API that took **kwargs, but we try to avoid those for this reason.

15:28 (Even more specifically, I called: https://github.com/r0man/cljs-http 's http/post, and gave it {:json-parameters {}} rather than {:json-params {}})

15:29 pvinis: hello. i have a map that has vectors or vectors as values, and i want to do update-in to conj a vector in one of the vector. can i get a [] as a default value for that conj?

15:29 hiredman: ,(doc fnil)

15:29 clojurebot: "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."

15:31 pvinis: a fnil..

15:31 thanks

16:18 numberte1: is there a core function for returning true if every predicate in a collection of predicates returns true for a given value

16:19 i know you can write this pretty easily wrapping 'every?', but it seems common enough to have a builtin for it

16:19 justin_smith: (apply every-pred preds) returns a function that returns true if every one in the pred is true

16:19 numberte1: justin_smith: ahh, thanks

16:20 justin_smith: ,(def big-even (apply every-pred [even? (partial < 10000)]))

16:20 clojurebot: #'sandbox/big-even

16:20 justin_smith: ,(big-even 10002)

16:20 clojurebot: true

16:20 justin_smith: ,(big-even 10001)

16:20 clojurebot: false

16:20 justin_smith: ,(big-even 10)

16:20 clojurebot: false

16:20 justin_smith: of course if you just know the funcitons you don't need the list or to apply

16:21 numberte1: yeah, was just thinking about thank

16:21 s/thank/that

17:08 lokien_: ,(doc every-pred)

17:08 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates."

17:36 WorldsEndless: Do I need to encode java objects as atoms when I pass them from function to function, or are they automatically passed by reference not copy?

17:37 amalloy: on the JVM, object values are always passed as pointers

17:37 WorldsEndless: ok

17:40 justin_smith: amalloy: modulo some hotspot magic, if it proves it can pull it off, in 1.8+ iirc

17:41 but yeah, that shouldn't affect WorldsEndless 's case at all

17:42 amalloy: it shouldn't affect any cases at all, ever. i could write, "objects are always passed in a way that is indistinguishable to you from being passed as pointers", but doing that for every statement would get tiring

17:42 justin_smith: true

17:59 WickedShell: when I defrecord is there a way I can associate the type hints with the fields directly? IE if I (defrecord foo [^long bar]) when I have a lookup of (.bar inst-of-foo) I still have to type hint that use later (obviously my actual use is with java interop/classes where I need the type to avoid reflections)

18:48 blake__: Does Clojurescript "need" the ready function the way Javscript does? I ask because I'm applying stuff to various controls and it's working, and I just realized that it's not inside the ready function. Not sure if this is luck or standards.

18:49 Or maybe a little of both....

18:51 justin_smith: blake__: depends - how are you managing the dom? if using jquery, you'll likely need to use .ready, if using one of the react libs it's less often you'll need it

18:54 blake__: I'm not really. Managing the DOM, I mean. I'm basically just attaching events to controls which are generated server-side. I am using JQuery to do this, however, which is why I thought about the ready event.

19:02 justin_smith: blake__: right, thus you are using jquery to manipulate the dom, thus you should be using .ready

19:02 shoky_: blake__: you don't need to worry about .ready or equivalent if you just include your <script> at the end of <body> tag. that ensures the initial DOM has already been parsed & built. otherwise, you need .ready if your code touches stuff that's supposed to already be in the DOM

19:05 blake__: justin_smith, shoky_: Thanks, guys.

19:05 schmudde`: I also apply the strategy of placing the JS at the end of the body tag because I don't use jQuery.

19:10 blake__: One thing at a time for me: I'm switching a Compojure project to use ClojureScript instead of Javascript.

19:33 SilverParens: Congrats on 1.8! A quick question, why won't (read-string ":key1 :key2") capture both keys? I'm trying to pass zip-xml/xml-> a sequence of keys to traverse the zipper.

19:33 justin_smith: SilverParens: read-string returns a value

19:33 that's two values

19:34 ,(read-string "[:key1 :key2]") ; one workaround

19:34 clojurebot: [:key1 :key2]

19:34 SilverParens: For example, (zip-xml/xml-> root-document :head :meta) should traverse two nests... because two keys were sent

19:34 justin_smith: sure, then you need to use apply I guess

19:35 (apply zip-xml/xml-> root-document [:head :meta])

19:35 SilverParens: justin_smith: Oh, thanks, let me try that. I had the apply before the read-string

19:35 justin_smith: there is also read, which uses a bufferedreader iirc, and you can make a bufferedreader out of a string

19:36 but probably easier to put the keys in a vector and use apply, if that's an option

19:36 SilverParens: justin_smith: Interesting! I'll give it a shot

19:39 justin_smith: Indeed, it works! Thanks...

19:40 I though my issue had to do with the clojure.org point about "The read table is currently not accessible to user programs." (http://clojure.org/reference/reader). What could that be referring to?

19:40 Do they mean the compiled programs that are running on the JVM?

19:41 amalloy: a program written by you cannot query or mess with the read table

19:41 justin_smith: SilverParens: in common lisp you can manipulate the read table in order to make custom data reading behaviors

19:41 this is something we don't do in clojure, on the otherh and

19:43 data_readers.clj and the *data-readers* var are the closest we get

19:46 SilverParens: Interesting. So one couldn't modify the meaning of #, for example.

19:51 justin_smith: right, and you can't add readers that don't start with #

20:00 blake__: Is there a clojure function that returns true?

20:01 I mean, I've got #(or true %), because I'm using it in swap!

20:02 justin_smith: (constantly true)

20:04 blake__: Yeah. Hmm.

20:05 SilverParens: (identity true)

20:05 (and)

20:07 sfz-: SilverParens: I don't quite understand why (and) works for that, care to explain?

20:07 blake__: sfz- So that "and true" returns true.

20:08 sfz-: that seems like it would be the equivalent of (and nil) though

20:08 justin_smith: but it's not a function

20:08 (constantly true) is a function, always returns true

20:08 sfz-: ,(and)

20:08 blake__: Yes, but doesn't take a parameter.

20:08 clojurebot: true

20:08 justin_smith: blake__: false

20:08 ,((constantly true) 1 2 3 nil false :whatever)

20:09 clojurebot: true

20:09 SilverParens: (and) and (and true) both return true because the and function keeps going from left to right until it reaches a false (upon which it returns a false and stops going to the left), if it doesn't reach a falsey value it returns true, so (and) doesn't reach a falsey value because they're aren't any values at al

20:09 justin_smith: ,((constantly true))

20:09 clojurebot: true

20:09 justin_smith: SilverParens: right but (and) is not a function

20:09 sfz-: SilverParens: now I understand, thanks

20:10 ,((and) :a)

20:10 clojurebot: #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval95 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval95 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval95 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java"...

20:10 blake__: justin_smith: Aha! Thank you I did not see that.

20:10 sfz-: ,((and (and)) :a)

20:10 clojurebot: #error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval119 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval119 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval119 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.ja...

20:10 justin_smith: (constantly true) is a function, and does what was asked

20:10 sfz-: ,(and (and) :a)

20:10 clojurebot: :a

20:10 sfz-: lol

20:10 sorry for spam

20:11 ianhedoesit: sfz-: it's always good to mess around locally first if possible and if you think there's something interesting feel free to use clojurebot for some show and tell.

20:11 justin_smith: also, clojurebot replies to dms

20:12 sfz-: ianhedoesit: I'll be more conscientious in the future.

20:12 ianhedoesit: it's not that big of a deal, but the error messages can get somewhat disruptive; especially if there's other conversations going on.

20:28 sfz-: ACK

20:40 TimMc: justin_smith: It bugs me that (constantly x) and (complement x) can always be golfed down to (fn [& _] x) and (comp not x), respectively

20:41 justin_smith: there's more to life than golf!

20:41 but it's true

20:41 TimMc: I feel like they're basic enough fns that they should have shorter names.

20:41 justin_smith: com and con

20:41 TimMc: Same goes for partial, although that one at least can't be golfed further.

20:42 justin_smith: p

20:42 TimMc: I was thinking par.

20:42 complement -> !f ?

20:43 justin_smith: or even just !

20:43 TimMc: ;-)

20:43 Eh, this is why lisps have a reputation for over-terseness.

20:48 amalloy: but not languages that actually use ! to mean not

20:49 * TimMc proposes a reader syntax that transforms !foo into (complement foo)

20:59 WickedShell: Is there a way to track down why a dependency is pulled in? I'm curious why mainfold (among other libs) is pulled into my uberjar/compilation process

21:01 justin_smith: WickedShell: lein deps :tree

21:01 WickedShell: justin_smith, thanks

21:01 justin_smith: WickedShell: manifold is likely coming from aleph, if you use that

21:01 WickedShell: not directly anywhere

21:02 sfz-: ,(do (defn ! [arg] (complement arg)) ((!(constantly false)) :whatever))

21:02 clojurebot: true

21:02 justin_smith: sfz-: alternately (def ! complement)

21:03 * sfz- smh

21:03 WickedShell: justin_smith, ah it's from byte-streams, again thanks

21:03 sfz-: justin_smith: thanks, only been clojuring a couple months

21:03 justin_smith: sfz-: that's why we're all here, to help each other learn

21:04 sfz-: justin_smith: appreciated, I'm responsible for a riemann box that's processing ~2.5 million metrics every n seconds... so the help is appreciated.

21:04 justin_smith: cool

21:05 sfz-: in the process of building a framework around riemann and learning to program clojure idiomatically as I go

21:05 still a long way to feel comfortable

21:06 justin_smith: sounds like a cool project though

21:48 WickedShell: I have to admit, I love how fast I can build my project with clojure 1.8, uberjars went from a 2+ minute thing to <15 seconds

21:48 justin_smith: yeah, startup and build is faster now for sure

21:49 puredanger: WickedShell: really? that's pretty big

21:50 probably http://dev.clojure.org/jira/browse/CLJ-703

21:56 WickedShell: apparently the human time clock is poor, lein uberjar with 1.8.0 24.58 seconds, 1.7.0 166.86 seconds

22:11 I do have a question though since swapping to clojure 1.8.0 and using direct linking I get an error during uberjar that I wasn't seeing previously while uberjaring. The builds seem to work correctly, and I don't see it when I do a lein clean; lein repl any idea how to track down what causes http://pastebin.com/7r8Un0nD?

22:12 justin_smith: woah, that looks like a weird heisenbug I've been seeing since my 1.8 update...

22:12 "clojure.core.async$fn_handler$reify__4798 cannot be cast to java.util.Iterator"

22:13 not identical of course, but suspicious that both of these only come up since the 1.8 switch

22:13 I looked at the relevant code, and there's no way the item I am using iterator methods on is created by core.async

22:14 (unless I'm reading my code wrong, which I can't rule out completely, ever, of course)

22:14 WickedShell: I don't even think that error is in my code? But I could bre reasing the stack trace wrong...

22:15 justin_smith: core.async can be confusing that way, but it probably is in your code

22:15 WickedShell: I mean everything *appears* to be behaving correctly but I get worried when I see a bug in compilation I can't track down

22:15 any idea how to find where in my code its getting upset?

22:17 justin_smith: one moment

22:24 WickedShell: yeah, definitely no recognizable non-clojure code in that stack trace

22:25 WickedShell: how many places do you call pub?

22:25 WickedShell: very few iirc should all be in one place

22:25 justin_smith: cool, because the error definitely happens in the context of a pub call

22:26 not that I think your code is causing the problem here...

22:27 John[Lisbeth]: Is clojure a true, compilable lisp?

22:27 WickedShell: justin_smith, the one and only place pub is called... http://pastebin.com/ZftPzYhG (obviously the outgoingMessages channel gets put on elsewhere)

22:27 justin_smith: John[Lisbeth]: does generating byte-code count as compiling?

22:28 fwiw clojure doesn't have an interpreted mode, every function is always generated as byte code before being run

22:28 but some people are pickier about what "compile" means

22:29 clojure doesn't generate machine code, it generates byte code for the jvm (or for clr, or javascript)

22:29 John[Lisbeth]: I mean x86

22:29 justin_smith: no, it does not do anything x86 specific

22:30 John[Lisbeth]: muh 32 bit

22:39 TEttinger: John[Lisbeth]: I don't think anyone's made a new Lisp that a) has seen wide use and b) isn't JIT-compiled, in the last at least 10 years. I am fairly sure Racket is JIT compiled, no idea about Arc

22:40 it seems silly to have repl-based languages require a separate lengthy compile step

22:42 clojure does have a slower step when it compiles to certain things; standalone jars need more work to assemble and can take a little while for large apps

22:42 normally that step is done for a release but not during development

23:27 felixn_: https://gist.github.com/munro/dbda79e245a469e7fe6a <-- hey, still trying to wrap my head around transducers. python generators seem to do the exact same thing, the difference I see is transducers were built around HoF instead of language semantics, does that sound correct?

23:36 baritonehands: Hello

23:38 Wondering if there's a preferred way to refactor this code so I don't repeat many of the functions

23:38 https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/groups.clj

23:38 felixn_: https://gist.github.com/munro/dbda79e245a469e7fe6a#file-transducer-py-L18 <-- the transducer completion API is the same as a generator, using partition-all as an example. also the init would just be yielding at the top

23:38 baritonehands: https://github.com/baritonehands/avalon/blob/master/src/clj/avalon/models/games.clj

23:38 many functions are the same, just swap out variable name

23:39 or record type

23:41 felixn_: baritonehands: macros work well

23:44 baritonehands: Is that the idiomatic clojure way?

23:51 felixn_: I was thinking closing around the ref, macros seem like overkill

23:53 luxbock: baritonehands: why not just keep all the state in one place?

23:53 instead of having it spread accross three namespaces

23:54 I think I would just have those funtions take one extra argument, and then you can use the same function for each case

23:54 felixn_: baritonehands: agree with that, plus some of the functions are longer than the original code. (@groups id) vs (get-group id), any impure stuff it's normal to end with ! so (get-group! id)

23:54 justin_smith: you could have a protocol defining what you can do to a game, then write an implementation that uses a ref

23:55 baritonehands: luxbock: idk, maybe I can't shake the OOP background, but I thought games ref should go with games functions

23:55 justin_smith: it's not just for games, my groups and people look very similar

23:56 justin_smith: baritonehands: functions are not the same as methods, a function should be code that isn't owned by some specific data

23:56 baritonehands: I want to write the get method once

23:56 justin_smith: if you want methods, clojure can do OO, do a defrecord and protocols etc.

23:57 or do functions, and let someone else care about the data in some other context

23:57 half and half tends to be a mess

23:57 luxbock: I don't know much about game development, but my impression is that the functional way is generally to keep all state isolated in one place, and try to stick to as many pure functions as possible

23:58 justin_smith: luxbock: exactly, you have your state objects, then a number of pure functions that define the transitions making up the game

23:58 baritonehands: also need to keep in mind that this happens to be a ref for now, but in the future will be a SQL call (or some other datastore)

23:58 justin_smith: baritonehands: all the more reason to leave the functions pure

23:58 let the state-handling code handle the state

23:59 or, to use a protocol, and swap out the ref implementation or the sql implementation etc.

23:59 these both work, things get messy when you arbitrarily mix the two

Logging service provided by n01se.net