#clojure log - May 29 2014

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

0:09 dsadapa: I'm not understanding the order in with macros evaluate. I'm trying to write some macros that output html just for learning. They are supposed to nest, so you have one macro inside another one. But the output of the inner macro is not evaluated, instead I just see the sexpr with it's name? http://pastebin.com/J8Lpj7uJ This is surely a rookie mistake, but I just don't get it!

0:10 bbloom: dsadapa: are you just guessing how they work, or are you going off some tutorial or something?

0:10 dsadapa: Trying to understand it from reading docs and trying different ways

0:10 bbloom: dsadapa: i suggest you play with the macroexpand function

0:10 for example:

0:11 ,(macroexpand '(-> x f))

0:11 clojurebot: (f x)

0:11 bbloom: notice that didn't do anything, it just showed the result of expanding the macro

0:11 the macroexpand function only happens on the front of the list, it's not recursive. but it lets you kinda step-debug macro expansion

0:11 another example:

0:12 ,(macroexpand '(let [[x y] (range 2)] [y x]))

0:12 clojurebot: (let* [vec__51 (range 2) x (clojure.core/nth vec__51 0 nil) y ...] [y x])

0:12 bbloom: the ... is part of the irc printout, you can try it local in your repl

0:13 dsadapa: bbloom: wow, that's pretty nifty. Thanks, I'll do my debugging!

0:13 bbloom: dsadapa: experiment with different examples, make sure you understand quoting before playing with defmacro

0:14 you can use ' and ` outside of a macro, so experiment with them in your repl too

0:14 and http://www.paulgraham.com/onlisptext.html is basically the bible of intros to macros, even though it's common lisp, not clojure, it's worth checking out

0:14 good luck!

0:15 dsadapa: bbloom: thanks for helping a confused lisp newbie! This is great stuff :)

0:16 bbloom: dsadapa: i may also add, if you're totally new to lisp... you should consider: avoiding writing macros at all! especially when you're still learning the core library

0:16 most clojure programs have very very few macros

0:17 dsadapa: bbloom: yeah? is it better to use functions over macros, or do you mean that somebody already wrote most things you'll ever need in macros?

0:17 amalloy: dsadapa: indeed, while it's great to learn how macros work, most of the time functions are sufficient. certainly for your html thing a macro is the wrong choice

0:17 dsadapa: amalloy: why is macros the wrong thing for outputting markup?

0:18 bbloom: dsadapa: 1) it's harder to write macros 2) they are less composable than functions 3) even when you do genuinely want/need a macro, it should be limited to a thin layer on top of a function-based core

0:18 amalloy: because functions can do the job. and, as you're discovering in your example, it's a lot more work to think properly about how to do it with macros

0:19 dsadapa: I see. I chose it as an exercise because I thought it was the simplest form of a code-that-writes-code, what people tell me macros are for, but yeah I guess things like that are simpler in functions

0:20 bbloom: dsadapa: macros aren't themselves code that writes code. they are a particular style of usage of code that writes code

0:20 ,(eval (list + 5 10))

0:20 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

0:20 bbloom: &(eval (list + 5 10))

0:20 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

0:20 bbloom: eh, screw you bots

0:20 anyway

0:20 that's an example of me making code and running in it

0:20 no macros involved!

0:20 ,(list + 5 10)

0:20 clojurebot: (#<core$_PLUS_ clojure.core$_PLUS_@555e61> 5 10)

0:20 bbloom: ,`(+ ~@(range 5)

0:20 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

0:20 bbloom: ,`(+ ~@(range 5))

0:20 clojurebot: (clojure.core/+ 0 1 2 3 ...)

0:20 bbloom: notice that's code making other code!

0:21 macros are about how code-that-writes-code gets evaluated

0:21 dsadapa: compile time versus run time?

0:21 or reader vs eval

0:21 bbloom: to a first approximation, yes

0:22 ,(let [x 1] [x 'y `z])

0:22 clojurebot: [1 y sandbox/z]

0:22 bbloom: quoting is an important thing to learn

0:22 and even tho the eval function is uncommon in clojure programs, it's super useful for learning about how evaluation works

0:23 dsadapa: In the html example I guess some way of un-quoting the argument of the macros, to evaluate them instead

0:26 bbloom: ,(defmacro foo [expr & body] `(do (prn ~expr) ~@body (prn ~expr)))

0:26 clojurebot: #'sandbox/foo

0:26 bbloom: ,(foo (java.util.Date.) (prn 1) (prn 2))

0:26 clojurebot: #inst "2014-05-29T04:20:27.633-00:00"\n1\n2\n#inst "2014-05-29T04:20:27.637-00:00"\n

0:26 bbloom: ~reader

0:26 clojurebot: reader is http://clojure.org/reader

0:26 bbloom: see there ^^ for some syntax

0:26 i'm off, good luck

0:29 dsadapa: bbloom: thanks a lot! Very helpful! I wish I could send a medal for great noob-helping skills. Thanks! amalloy too!

0:38 gastove: Hello. This is an embarassingly newbie question, but here we go all the same: I have a lein project that defines `:dependencies [[incanter "1.5.4"]]`. Project compiles just fine, dependency is there. But when I start a lein repl in the project directory and call `(require 'incanter)`, I get a lot of "could not find incanter on classpath`.

0:39 What the blazes am I not groking about this?

0:39 tolstoy: If only there was a way to tickle an om re-render from a cljs repl.....

0:39 (require '[incanter])?

0:39 mange: gastove: (require 'incanter.core) ?

0:39 tolstoy: Putting the name in a quoted vector?

0:40 And that. ;)

0:40 gastove: Quoted vector gets the same thing -- haven't tried specifying which part of incanter, sec...

0:40 oh ffs

0:40 ,mange++

0:40 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: mange++ in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:40 gastove: HA.

0:41 Good. In the room for twenty seconds and already making clojurebot throw runtime exceptions.

0:41 This is working splendidly.

0:41 Thanks for the suggestion, mange. Appreciated!

0:42 mange: No worries! If you still want to use symbols like incanter/blah then you can do (require '[incanter.core :as incanter]) to alias it in your namespace.

0:43 gastove: *nods* Good to know!

0:52 tolstoy: Huh. Git 2.

0:53 Raynes: ?

0:53 Fare: I am thinking of yet another parser (or maybe it already exists?) where the input is a lazy stream of (values, context) where initially, values is characters and context is file location, but passes transform that, so that e.g. lexing makes values into tokens and context into file location, and various phases of parsing make that into sexpressions where the context contains also binding information, and where macros can be literally expanded int

0:53 o stuff prepended to the stream.

0:53 alisdair: this time, it's personal

0:53 tolstoy: Git has reached 2.0. Not sure if that's significant.

0:55 Raynes: amalloy: https://dl.dropboxusercontent.com/s/2x3lf432djw4py6/2014-05-28%20at%209.49%20PM%202x.png Didn't we have a weeklong discussion about this at Geni?

0:57 amalloy: mike and justin came back to it every so often

1:06 Raynes: $ git --version

1:06 git version 2.0.0

1:06 Welcome to the future, kids.

1:32 danielcompton: I'm using test.check to generate random ip addresses. Is there a more elegant way to do it than

1:32 (def inet-gen (gen/fmap #(clojure.string/join "." %) (gen/tuple (gen/choose 0 255) (gen/choose 0 255) (gen/choose 0 255) (gen/choose 0 255))))

1:32 How can I get 4 of the same generator in a tuple?

1:43 platz: is git 2 rtm or rc ?

1:43 Rhymor: ,(take 3 (repeatedly #(rand-int 256)))

1:43 clojurebot: (237 61 45)

1:44 platz: ahh the ppa is up now, nvm

2:14 storme: Is loop/recur recursion?

2:14 http://clojure.org/special_forms#recur

2:15 *technically speaking*

2:15 beamso: yeah, recursion

2:17 storme: That's what I thought, someone just told me loop/recur does not recurse

2:19 platz: everything is an abstraction at some level. who knows what special definition of recursion someone has

2:19 beamso: that someone was probably mentioning what is discussed in http://clojure.org/functional_programming#Functional%20Programming--Recursive%20Looping

2:20 i can't believe i'm going to quote sicp too, but it's probably also linked to http://mitpress.mit.edu/sicp/full-text/sicp/book/node15.html as well

2:24 storme: beamso, Thanks!

2:24 zeroem: I'm seeing some unexpected behavior in a macro, https://gist.github.com/zeroem/8aaf26fb33a657072d73

2:24 platz: I guess if you require recursion to create a new stack frame it's not recursion, but then that rules out languages with TCO

2:24 zeroem: can anyone explain why two references to what I understand should be the same gensym are actually getting two different symbols generated

2:25 storme: platz, So it's purely a difference in the definition of what recursion is?

2:26 platz: loop/recur does the same thing 'recursion' does, just implemented differently under the hood

2:27 and it all looks the same at the assembly level anyway

2:28 dbasch: storme: loop/recur does not generate stack frames, it’s like a for loop in java

2:28 storme: dbasch, Got it

2:28 platz, I see

2:32 dbasch: zeroem: http://stackoverflow.com/questions/2840119/controlling-symbol-generation-in-clojure-macros

2:33 storme: ,(source loop)

2:33 clojurebot: Source not found\n

2:33 zeroem: dbasch: thanks for the google-fu, what did you search for?

2:33 storme: ,(source take)

2:33 clojurebot: Source not found\n

2:33 storme: ,(doc loop)

2:33 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

2:34 dbasch: $google clojure macro gensym

2:34 lazybot: [Controlling symbol generation in Clojure macros - Stack Overflow] http://stackoverflow.com/questions/2840119/controlling-symbol-generation-in-clojure-macros

2:34 dbasch: I’d seen it before

2:34 storme: Interesting, typing "(source recur)" into the repl give ;= Source not found

2:36 zeroem: dbasch: ah, thanks still :)

2:36 dbasch: np

2:52 (doc source) ;; storme

2:52 clojurebot: "([n]); Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)"

2:53 storme: dbasch, So it cannot find the source I'm assuming

2:54 dbasch: storme: it’s not in a .clj file

2:55 mange: storme: recur won't be found by "source" because it's a special form. There isn't even a var for recur.

2:55 ,recur

2:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: recur in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:55 storme: So where can I find it?

2:56 mpenet: github search :)

2:56 storme: mpenet, :)

2:57 mange: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L42

2:57 I know that's not really helpful, but the compiler deals with recur internally.

2:59 dbasch: storme: a significant part of clojure is written in clojure, but obviously the foundation has to be in java

2:59 storme: or javascript, for cljs

3:00 storme: mange, Thank you for the link

3:00 dbasch, Thank you for the information

3:01 dbasch: actually there’s very little cljs in js, it’s mostly in clj

3:19 hellofunk: what is ICloneable? i'm having some difficulty tracking it down; is it part of the clojure base or clojurescript?

3:25 beamso: icloneable looks to be from om

3:29 whodidthis: clojurescript

3:30 hellofunk: beamso i don't think it is part of Om

3:30 it came up in an Om tutorial but it's namespace along with other Om protocols

3:30 *not namespace

3:30 beamso: i do see the protocol mentioned in om code

3:31 hellofunk: beamso yes but I think it is referencing something that is part of clojurescript as far as I can tell. It's not one of the Om protocols I don't think

3:31 beamso: but whodidthis may be more familiar with clojurescript than i

3:32 whodidthis: i'm not familiar but i use specify! with om components https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj

3:34 mange: It looks like ICloneable is internal to clojurescript, based on my reading of this: https://github.com/clojure/clojurescript/blob/c63db9544738fc094cc04680bbee1534cf436204/src/clj/cljs/core.clj

3:34 ... Which is the exact same file that whodidthis just linked to.

3:36 beamso: oops. my bad, then.

3:36 clojurebot: Cool story bro.

3:37 beamso: thanks bro.

3:37 :p

3:58 hellofunk: thanks guys

4:22 anyone here using Datomic in the wild?

4:39 szymanowski: Hi, what is the idiomatic way to test if something is a protocol?

4:47 ddellacosta: szymanowski: you could use satisifies? if it is a specific protocol

4:48 szymanowski: assuming you have a type/record

4:48 szymanowski: what exactly are you trying to do?

4:48 szymanowski: just want to know if something is a protocol

4:48 no records/types involved

4:49 for doing something in schema

4:49 ddellacosta: szymanowski: prismatic's schema?

4:49 szymanowski: yes

4:50 basically i would like to extend schema protocol to protocols

4:51 ddellacosta: szymanowski: so, for example, as the second argument to validate?

4:52 szymanowski: I know there already a Protocol record in schema

4:52 wagjo: szymanowski: no idiomatic way. Protocol is just a map

4:52 szymanowski: but it need to be created via the protocol function defined in schema

4:52 wagjo: wagjo: you can check for the keys to determine whether given map looks like a protocol, but nothing absolute

4:53 szymanowski: yes this is what I do so far

4:54 ok thank you ddellacosta and wagjo

4:54 ddellacosta: szymanowski: that was all wagjo, but sure thing. :-)

5:03 ergh: i want to make a game and i thought i'd make my entities maps, but then i wondered what i would do if i wanted to turn one of the values into a function that needs to be called to retrieve the value later. for example:

5:05 if i had an :img entry for whatever image is supposed to be drawn for an entity, but i later want to make it depend on the amount of health the entitty has so it would have to be (get-img (:img entity)), but i would want that to be an implementation detail.

5:05 how would i best design that?

5:06 hm, i guess i could just leave it as a simple entry and change the image whenever the health is being changed

5:07 beamso: or you could pass the map into a function and have the function return the appropriate image for the map

5:09 ergh: that would kinda put all the image logic for all entity types in one place. so if i wanted to add a new type, i would have to add things all over the place. hm

5:14 beamso: if you have multiple entity types you could create a protocol and an implementation for each entity type.

5:14 or a multimethod.

6:00 kurofune: I am using LightTable with Clojurescript and everytime I try to evaluate a name-space I get errors saying, either "goog not defined" or "no file app.core found" I am able to compile the project and am following the tutorial here: http://swannodette.github.io/2013/11/07/clojurescript-101/

6:01 Could sombody please troubleshoot this with me?

6:05 Can anybody see this?

6:12 wagjo: kurofune: you might have a better luck at https://groups.google.com/forum/#!forum/light-table-discussion

6:12 kurofune: thanks wagjo I'm not sure if it's an IDE thing or what.

6:28 Guest_: lost my connection a moment ago

6:28 was looking for some help with a dumb CNFE

6:29 I am trying to use http-kit

6:29 here is my project.clj

6:29 (defproject heroku-data "0.1.0-SNAPSHOT"

6:29 :dependencies [[org.clojure/clojure "1.5.1"]

6:29 [http-kit "2.1.18"]]

6:29 :main heroku-data.core)

6:30 ran lein deps and http-kit is downloaded

6:30 try to lein compile this minimal code

6:30 (ns heroku-data.core)

6:30 (:require [org.httpkit.client :as http])

6:30 and it blows up with a CNFE

6:31 any ideas ? seems so dumb

6:31 same if I say lein repl

6:40 mattfield: Guest_: is your require expression inside the ns declaration?

6:40 Guest_: no

6:41 mattfield: Guest_: It needs to be if it's in a CLJ file

6:41 Guest_: doh!

6:41 I knew it was something idiotic

6:41 thanks matt

6:41 mattfield: ^_^

6:41 No probs!

6:42 Easy to look straight past that sort of thing

6:42 Guest_: boom - working again..

6:42 mattfield: ace

7:49 mi6x3m: hey clojure, when do we put a * at the end of a function name?

7:53 h0bbit: mi6x3m, I follow the convention of adding * to the end of a function name when I'm going to memoize the function.

7:53 the memoized function has the same name, (without the *) and is exposed to the world

7:53 mi6x3m: h0bbit: but the function knows nothing of it being memoized?

7:53 h0bbit: nope.

7:54 mi6x3m: ah, okay, so foo* is a cached foo

7:54 h0bbit: something like

7:54 mi6x3m: I see

7:54 h0bbit: yup

7:54 (defn- foo* [x] ...)

7:54 (def foo (memoize foo*))

7:54 mi6x3m: ok, this makes sense :)

8:04 ddellacosta: mi6x3m: I use it more generally when I need a function that does the "actual" work that foo is supposed to do

8:04 mi6x3m: ddellacosta: give an example please :)

8:04 ddellacosta: mi6x3m: I good example may be if I have a loop that has to start with initial parameters, and it makes more sense to isolate that loop

8:04 *a good example

8:05 mi6x3m: I've also seen the ' notation for similar functions/variable naming: foo foo'

8:06 mi6x3m: I haven't heard of h0bbit's convention of using it for a memoized function, but it seems kind of generally consistent with what I'm talking about

8:06 mi6x3m: okay I see

8:07 so generally it's some kind of designation for a workhorse

8:08 ddellacosta: mi6x3m: I guess so. Honestly, I'm not sure what the general clojure community convention is wrt this, I'm just telling you how I use it

8:08 mi6x3m: here's a stack overflow question on it: http://stackoverflow.com/questions/5082850/whats-the-convention-for-using-an-asterisk-at-the-end-of-a-function-name-in-clo

8:09 mi6x3m: technomancy I think explains it well, and I feel like he can be considered authoritative, in the context of the Clojure community

8:10 mi6x3m: and Paul Legato's comment there is related to what I was trying to say

8:11 mi6x3m: ah, I see, thanks a bunch

8:11 this clarifies it

8:11 ddellacosta: mi6x3m: sure thing

8:12 Glenjamin: In Clojure it basically means "foo* is like foo, but somehow different, and you probably want foo".

8:12 i like that

8:12 noncom: how do i force a port of a CCW repl?

8:13 ddellacosta: Glenjamin: yeah, it emphasizes the point that it is probably private or should be private, which I neglected to mention

8:13 Glenjamin: i guess its a bit like _func in python

8:13 ddellacosta: Glenjamin: do you usually have func also, in that context?

8:13 Glenjamin: sorta private, but you can call it if you really want to

8:14 ddellacosta: Glenjamin: ah, the _ is a "this is private" convention?

8:14 Glenjamin: probably not, to be fair - but the privacy aspect is similar

8:14 yes

8:14 ddellacosta: gotcha

8:41 trap_exit: http://grokbase.com/p/gg/clojure/13bp2s9s81/ann-clojurescript-0-0-2060

8:41 I ran into this same error

8:41 how do I fix it?

8:41 there's some dumbass cljs.core error

8:41 that apears in ":optimizations :none" but not in ":optimiations :advanced"

8:56 noncom: does anyone here use CCW? how do i force some permanent port to the repl?

8:58 ambrosebs: noncom: no idea, tried this in your pom? :profiles {:dev {:repl-options {:port <num>}}}

8:58 project.clj rather

8:58 if you have one

9:01 noncom: ambrosebs: thanks! adding this to project.clj worked!

9:01 ambrosebs: noncom: np

9:07 noncom: uh, now i setup a repl on a fixed port on a remote macine and trying to connect to it via the IP address from te internet and it does not connect

9:07 other programs work fine, so it is someting specific to nrepl...

9:11 does amyone have any ideas on this?

9:11 *anyone

9:12 beamso: my only idea is : have you tried telnetting to the port?

9:22 pcn: noncom: On the host, check netstat -an and look for that port. Make sure it's listening, and listining on ipv4 maybe?

9:24 noncom: pcn: strange, but it gives this readout for the port 55555 which i'm using: https://www.refheap.com/86060

9:25 how do i interpret it?

9:25 beamso: did 55555 appear more times than that?

9:26 it reads like it's only listening on localhost

9:26 noncom: no, these three occurencies are the only..

9:27 beamso: so, it's only listening for connections on localhost

9:27 noncom: well, usually i do not have a problem with connecting from internet. i just setup a server and open the port on the router..

9:27 what do i have to do in this situation?

9:27 how can it be restricted to receiving connections from localhost only?

9:28 how is that possible?

9:28 beamso: i don't use a repl, so maybe the repl has to be configured to listen from all hosts?

9:29 you may wish to check that the port isn't firewalled off, as well.

9:33 noncom: huh, i added :host "" parameter to the repl-options and now the result is somewat different - CCW hangs up when conneting. this is definitely a progress. possibly there is some bug inside

9:36 so now there is one another ccw bug

9:36 it freezes

9:41 pcn: noncom: yeah, it looks like your :repl option defaults to localhost (which is a sane precaution. Having a backdoor into a running jvm on your server is handing the keys to j.random cracker)

9:41 Errr... :host not :repl

9:42 noncom: yeah

9:42 but now i wonder wy ccw has troubles with it

9:42 pcn: If it's not using ssl, use ngrep or wireshark to see what's going on.

9:42 beamso: you could ssh from your machine to that machine, forwarding the connection on your local machine to port 55555 on the remote machine

9:43 pcn: ngrep -Wbyline . port 55555

9:43 beamso: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding

9:45 pcn: Yeah, use ssh forwarding for sure.

9:45 but... figure out the freeze. If it's not simply a bug, it could mean networking problems that are harder to diagnose when ssh is involved

9:48 noncom: ok, i will try ssh and debuggging ccw later... now can you tell how i connect with emacs live?

9:48 there is no repl-connect or cider-connect command...

10:03 pcn: noncom: have you tried just "M-x cider" ?

10:05 noncom: pcn: haha :)

10:05 cool

10:06 actually i have found out that the problem is that the server nrepl falls with an exception!

10:06 pcn: The documentation for that is... :facepalm:

10:06 noncom: i just did not think it'd be that easy

10:07 te message is this: https://www.refheap.com/86061

10:07 any idea on this? :)

10:13 pcn: Googling the top of the stack shows a 2012 post by cemerick but it's from 2012 about some incompatibilty with ccw and nrepl...

10:14 but otherwise I am not a deep resource. Maybe pinging cemerick as I am will bring enlightenment?

10:16 cemerick: noncom: You have mismatched versions of nREPL, one or more of which have been AOT-compiled. FnTransport is definitionally a Transport: https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/transport.clj#L25

10:36 philandstuff: cemerick: hi there, I've been looking at this commented-out line in test.check: https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check/clojure_test.clj#L134

10:37 cemerick: I think this is a fix but I'm not certain enough to go to JIRA and raise an issue: https://github.com/philandstuff/test.check/commit/2714f325f72abfe47c6b128512494d6b26f60768 does it look good to you?

10:38 reiddraper: philandstuff: fwiw, no shame in filing an issue as a question, either

10:39 cemerick: philandstuff: I can't say I remember the context around that comment; I'd have sink into it for a bit to grok it again. Like reiddraper said, do file an issue, either he or I will look at it. :-)

10:40 philandstuff: if you have a use case that it affects, that would be super-helpful as well (since apparently I didn't bother documenting the objective of the TODO very well :-/)

10:40 hyPiRion: philandstuff: just a question -- would `doto` be needed in the fix? It seems like you just call ct/report on the element

10:40 oh nevermind, you want to return it too.

10:40 philandstuff: reiddraper, cemerick: thanks, I'll file a ticket

10:41 * hyPiRion has forgotten Clojure.

11:06 noncom: cemerick: thank you, will look into synching the versions!

11:26 are there any version control systems that allow explicit centralized blocking of files that one is working on? or at least, giving realtime messages on what files are being edited by others?

11:30 michaelr525: hi

11:31 hi what do you use in emacs for switching buffers quickly?

11:31 ctrl-tab/ctrl-shift-tab maybe?

11:31 mdeboard: noncom: Centralized blocking? None that I know of

11:31 llasram: noncom: Sure. That's how most of the really awful old proprietary ones work

11:31 mdeboard: michaelr525: Switching buffers I use C-x b then type the name of the buffer (I have auto-completion)

11:32 * llasram shivers in recollection of StarTeam

11:32 mdeboard: if I'm using multiple panes yeah I use Ctrl-Tab to switch back and forth

11:32 cbp: michaelr525: if you mean switching windows i use window-number mode

11:32 mdeboard: I sometimes trip over myself when I'm switching between tmux and emacs a lot tho

11:32 cbp: you can also make it so that shift + keys or something moves between windows

11:32 switching buffers it's C-x b + ido-mode

11:33 noncom: llasram: what was the drawback on that?

11:33 llasram: noncom: On which?

11:33 mdeboard: Yeah ido, that's the thing

11:33 michaelr525: cbp: yeah, that's what I use, but I'd like to use ctrl-tab style like in all other editors in the world :)

11:33 noncom: llasram: why is centralized blocking/notification is bad?

11:34 cbp: michaelr525: you can do anything in emacs

11:34 michaelr525: cbp: ctrl-x b requires two hands, i'd like to switch buffers quickly using only the left hand

11:34 llasram: noncom: Its possibly not bad in itself, but in my experience all the systems which support it fatally complect workflow and mechanism

11:35 noncom: i see.. if you could recall some names, i would look them up in google, for a research

11:37 llasram: noncom: http://en.wikipedia.org/wiki/Comparison_of_revision_control_software and "Concurrency model" includes "lock"

11:38 dkinzer: noncom: when you are working on a file, can others edit that file while you working on it? Usually you can set up your environment so that only you access your own repository.

11:38 noncom: llasram: cool, thanks!

11:38 dkinzer: llasram: nice use of "complect" :)

11:39 noncom: dkinzer: well, actually conflicts among pushes are a trivial thing in this place

11:39 i am interested in knowing whats and whys of all this stuff

11:39 oh, and since it is a clojure cannel, i also think about doing something with the situation, employing clojure

11:40 maybe

11:41 dkinzer: noncom: I guess I didn't understand your question, then.

11:41 noncom: yeah, there are many possible situations wit concurrent data read/writes

12:35 Glenjamin: the usual "real" causes of that in my experience are: large files, poorly factored code and long lived branches

13:03 the-kenny: (when-let [[a b] []] 42) => 42. Is this expected? Feels counter-intuitive to me.

13:04 Bronsa: the-kenny: destructuring is not pattern matching

13:04 the-kenny: Bronsa: I know, still feels a bit strange. And has caused a bug in secretary

13:04 gtrak: the-kenny: all that matters is if [] is truthy.

13:05 I tend to not to do destructuring in if/when-lets for clarity

13:05 agarman: ,(some-let [[a b] []] 42)

13:05 gtrak: only really been bitten by this once.

13:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some-let in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:05 Bronsa: the-kenny: consider (when-let [[a b :as form] []] form)

13:05 the-kenny: would you be ok with that returning nil rather than [] ?

13:06 the-kenny: Bronsa: that's a good example, haven't thought about :as

13:06 gtrak: there's no coherent set of rules besides the current behavior.

13:07 maybe you could make a '(let-if a [[a b] []] a)'

13:07 the-kenny: Adding a seq should work

13:08 ,(when-let [[a b] (seq [])] 42)

13:08 clojurebot: nil

13:08 the-kenny: ,(when-let [[a b] (seq [1 2])] b)

13:08 clojurebot: 2

13:08 gtrak: ah, yea.

13:08 that covers most real use-cases :-)

13:09 kenrestivo: unless you want both a and b to be truthy for the if to succeed

13:09 gtrak: (let-if (and a b) ...

13:10 but it looks backwards

13:10 still possible

13:10 kenrestivo: cool

13:11 gtrak: or you could use the 'for' style.

13:11 (let+ [[a b] [] :when a]..)

13:12 also awkward unless you only need one branch.

13:12 prepor: let-if? like this http://www.crossclj.info/clojure/let-if.html ?

13:13 gtrak: kind of, except the condition would be dependent on bindings.

13:13 kenrestivo: is there an implementation somewhere?

13:14 gtrak: I could trivially make one.

13:15 but then I would have to do a thing.

13:15 cbp: oh noes

13:17 prepor: gtrak it dependent on bindings https://github.com/flatland/useful/blob/develop/src/flatland/useful/experimental.clj#L48

13:17 gtrak oh no, sorry

13:17 kenrestivo: that crossclj is interesting. is it a codeq/datomic thing?

13:19 prepor: kenrestivo "We will do a proper announcement with details" on 15 May 2014

13:20 kenrestivo: ahm

13:40 herman_: hi

13:40 can i ask about a counterclockwise problem here?

13:41 im getting: FileNotFoundException Could not locate clj_http/client__init.class or clj_http/client.clj on classpath: clojure.lang.RT.load (RT.java:443)

13:41 when i try to load a file using clj-http

13:42 lein repl + (require '[clj-http.client :as client]) works fine though

13:42 but eclipse can't seem to find it in the classpath

13:59 amalloy: gtrak: there's egamble's let-else: https://github.com/egamble/let-else

14:04 dbasch: quick, guess what this evaluates to: (reduce map reduce [])

14:05 justin_smith: (defn stupid-identity [thing] (reduce map thing []))

14:06 dbasch: (inc justin_smith)

14:06 lazybot: ⇒ 44

14:06 justin_smith: hell, you could even make it (reduce thing thing [])

14:06 dbasch: ,(reduce 1 1 [])

14:06 clojurebot: 1

14:07 justin_smith: the whole "1 isn't a function" thing never comes up

14:07 lol

14:07 dbasch: I see an obfuscated clojure contest

14:07 justin_smith: it is way to easy to do evil clojure code

14:08 dbasch: but c is easier, what with multiple pointer indirection and all

14:08 justin_smith: and the relatively weak type system and implicit casts

14:09 gtrak: amalloy: nice

14:09 cafC7ll_: hey

14:09 dbasch: “with enough eyeballs all bugs are shallow” <- yeah right heartbleed

14:11 KeithPM: justin_smith: Sorry guys I walked in at an 2 pm (reduce 1 1 []). I am doing some exercises on reduce in teh Helsinki clojure MOOC. What were you guys discussing?

14:11 amalloy: dbasch: pretty sure at least a thousand people said that on like day zero. why bring it up now?

14:11 KeithPM: tomfoolery

14:11 KeithPM: OK

14:12 dbasch: amalloy: are you following the truecrypt debacle?

14:12 amalloy: $google truecrypt debacle

14:12 lazybot: [TrueCrypt warns that it is not secure, advises users to switch] http://grahamcluley.com/2014/05/truecrypt-insecure/

14:12 dbasch: KeithPM: in (reduce 1 1 []), the last line of the documentation of reduce applies

14:13 (doc reduce)

14:13 clojurebot: "([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 is supplied, returns t

14:13 KeithPM: dbasch: Thanks… I was just about to ask how did that work..

14:13 dbasch: If coll contains no items, returns val and f is not called.

14:13 amalloy: &(doc reduce)

14:13 lazybot: ⇒ "([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... https://www.refheap.com/86066

14:13 amalloy: pastes what was cut off! a glorious invention

14:14 KeithPM: OK… Great… I read that somewhere, but it didn't compute at the time :)

14:14 amalloy: dbasch: that's really weird. what does stopping xp support have to do with truecrypt?

14:15 dbasch: amalloy: anybody’s guess

14:15 technomancy: amalloy: the official story is it's because newer versions have built-in crypto, but it's probably a cover story for a gag order.

14:16 ToxicFrog: amalloy: the best guess I've seen is that post-XP, windows comes with built in encryption support

14:16 dbasch: but people are up in a frenzy about whether truecrypt is secure or not, and the source is all there for anyone to “inspect"

14:16 ToxicFrog: Assuming it's legit.

14:20 KeithPM: While we're (or were) on reduce. I was working with reducing into something like a map for example. Is there some rule governing how one arranges the parameters to the function? e.g (fn [myMap elem] (assoc myMap elem (* elem elem)))

14:23 ergh: uh, i trying to start my first clojurescript project with leiningen, but im not quite sure how to set it up and there are many tutorials on how to do that and im not quite sure which one to use. is there a best/most current way to start a clojurescript project? (it will only be client sided)

14:24 _alejandro: KeithPM: the function passed to reduce signature looks like [last-result next-item]

14:24 KeithPM: In the case where you don't pass an initial value (e.g. {}), last-result will be the first item in the collection, and next-item the second

14:25 KeithPM: _alejandro: OK thanks. That clarifies it.

14:25 * Jaood uses dm-crypt

14:25 dbasch: ergh: I like this template https://github.com/swannodette/mies

14:25 _alejandro: ergh: I used http://swannodette.github.io/2013/11/07/clojurescript-101/ to start

14:26 ergh: thanks

14:28 doesn't seem to be using the newest versions of things, though. no idea if that's important

14:28 cbp: ergh: If you need a repl, easiest is lighttable

14:29 if you're using emacs you can try https://github.com/cesarbp/pudge#usage which is equivalent to mies-om

14:30 + an austin repl

14:32 ergh: i'm using light table

14:40 sandbags: i'm getting an error (attempted duplicate class definition) which is pretty inexplicable to me. full details https://www.refheap.com/9bf9763daf7ab05301148a124 wondering if this is something to do with Compojure and aot:all in project.clj?

14:41 arrdem: lein clean is your friend

14:41 amalloy: no, it's not lein clean

14:42 sandbags: you shouldn't have two defns with the same name: they both resolve to the same var and the same classname. since you're AOT-compiling, they both get compiled

14:42 at runtime you'd only pick one of them to be the value, probably, but you can't save them both with the same filename

14:42 sandbags: oh hello, where am i defn'ing the same symbol twice?

14:42 amalloy: lines 18-22

14:43 sandbags: oh, i assume the if would result in only one defn

14:43 so i've misunderstood something

14:43 am i misunderstanding when that "if" is operating? I'm still grokking macros

14:44 amalloy: all defs are hoisted to the top level, so the functions both get compiled, with the same name. then the if clause chooses which one to set as the actual value held by the var

14:44 sandbags: ahh.. i don't really understand but i do sort of grasp what you're saying

14:44 amalloy: you should really be writing something like ~(if (= 1 (count slots)) `(defn ...) `(defn ...))

14:45 sandbags: okay i got you... my train is just coming in but i will have a play with that

14:45 thank you

14:45 amalloy: or, shorter: (defn ~(symbol ...) ~@(if (= 1 (count slots)) `[[arg#] (~ctor ...)] `[[& args#] (let ...)]))

14:46 Pourletain: amalloy, anyway

14:46 sandbags: ah yes, neater still

14:46 Pourletain: what's your opinion on people who use the objective-who?

14:46 amalloy: what. whom are you and why are you starting this discussion with me as if we were already in the middle of it?

14:47 llasram: Pourletain: Didn't you already pull this yesterday?

14:47 technomancy: wait they ported Doctor Who to objective C

14:47 arrdem: amalloy: he's a troll that used this same opener yesterday.

14:47 technomancy: and no one told me?

14:47 sandbags: amalloy: very neat ... thanks again

14:47 amalloy: technomancy: it's subjective whether the port was successful

14:48 technomancy: amalloy: either that or it's randian tardis fanfic

14:48 Pourletain: llasram, I asked someone else.

14:48 amalloy, I have no idea.

14:49 Probably because I am retarded.

14:49 technomancy: remember when we used to have trolls with creativity?

14:49 (neither do I actually)

14:49 Pourletain: That was a good time indeed.

14:49 arrdem: technomancy: no... we've had chare and this guy... and arguably bitemyapp.

14:49 amalloy: technomancy: help me with my starcraft clone

14:49 clojurebot: Excuse me?

14:49 Pourletain: Where is Chousuke at anyway?

14:49 amalloy, you play?

14:49 technomancy: sdegutis was pretty subtle about it

14:50 I think he has the gift

14:50 amalloy: should be able to whip something up in clojure in just a couple days

15:04 tuft: heh, sc in clojure, cool

15:05 amalloy: i've apparently made too obscure a reference

15:05 guys, the joke was: technomancy was pining for the days of creative trolls

15:05 and there's this guy who used to come in here and demand people help him write a starcraft clone

15:06 as if that were something you could do in a week with two guys

15:06 Frozenlock: amalloy: You think he was trolling? I thought he was just VERY bad at estimating.

15:06 amalloy: well he was a rude jerk either way

15:07 arrdem: amalloy: idk man isometric graphics engines are pretty easy these days..

15:07 amalloy: i'm pretty sure he was writing sc2

15:07 no isometrics for you!

15:07 tbaldridge: arrdem: you're thinking Starcraft 1, Starcraft 2 is a bit more complex

15:08 hiredman: my ignore list is at 283, bascically entirely from #clojure because I don't pay attention to other channels as much

15:08 arrdem: tbaldridge: sc2.2 is unbalanced and boring tho..

15:08 Frozenlock: Who would want to make a SC2 clone? There's no skills with stacking muta...

15:08 amalloy: arrdem: i don't play, but i'm pretty sure the people who cry "imba" are just mad they're bad at the game

15:09 cbp: :-O

15:09 Frozenlock: You should just watch Supreme Commander FAF. Now that's a good RTS. :-p

15:10 dbasch: #clojure-gaming

15:10 arrdem: amalloy: shrug. I don't have the time to practice "esports". I'd rather be hacking or playing drunk dota with people casually. the SC2 pro scene is pretty boring tho because the different races are taking turns at being OP rather than converging to a balance point like SC1 did.

15:10 Frozenlock: Anyhow... How would you guys call the stuff *around* launching a product/website? All the 'buy a domain', 'host your program', 'built account architecture for the users', 'setup a databse'... Things that aren't necessarily directly related to the main product, but that must be done anyway?

15:10 dbasch: Frozenlock: work :)

15:10 tbaldridge: Frozenlock: ops

15:10 tuft: dbasch++

15:11 arrdem: I'll just be over in offtopic..

15:11 amalloy: is it offtopic now? or social?

15:11 arrdem: social exploded when I po'd sdegutis.

15:11 so we're all in offtopic.

15:12 Frozenlock: I'll bring it back on topic. Look: "Anyhow... How would you guys call the stuff *around* launching a -clojure- product/website?"

15:12 tuft: Frozenlock: slightly more enjoyable work =)

15:12 Jaood: I think I saw sdegutis rambling somewhere about how Go is better than Clojure ;)

15:12 Frozenlock: tuft: Good point

15:12 arrdem: tbaldridge: scope question if you've got a minute

15:13 tbaldridge: sure

15:13 gtrak: Jaood: we should introduce him to bitemyapp.

15:13 arrdem: gtrak: they've met.

15:13 Frozenlock: I was thinking peripheral or administrative, but none of them really capture it. :-/

15:13 cbp: gtrak: way ahead of you

15:13 Frozenlock: I lack vocabularyz

15:13 arrdem: (inc cbp)

15:13 lazybot: ⇒ 7

15:13 dbasch: Frozenlock: whether it’s clojure or not doesn’t change it much really

15:14 Jaood: gtrak: at leas bitemyapp did it against haskell ;)

15:14 arrdem: tbaldridge: this isn't something that's blocking, but I'm pondering how much if any support oxcart should seek to provide for multimethods.

15:15 tbaldridge: I could see statically collecting all defmethods and trying to do static dispatch, but the implementation thereof may not be trivial due to the code that defmethod macroexpands into, being a top level def with an alter.

15:16 s/top level def/conditional def/g

15:16 tbaldridge: arrdem: agreed. So perhaps it's better to start simpler and add that at some point?

15:17 arrdem: tbaldridge: that's what I was thinking. I've almost got lambda lifting and letfn lifting working, and I figured that the best place to start was to be able to demonstrate a scheme-like subset of Clojure that's entirely static.

15:18 getting right to the compacting emitter and tree shaking.

15:20 tbaldridge: arrdem: I think that's a good approach. If you have support for basic data structure manipulation + all the control flow stuff (fn, let, if, etc.) then additional optimizations/features can be added in as there is time.

15:21 socksy: what does independent vs co-ordinated mean re: STM types?

15:21 can't find a good description via google/docs

15:22 tbaldridge: socksy: co-ordinated means that two refs can be updated atomically.

15:22 every atom is separate, you can't update two atoms in a single transaction.

15:22 socksy: ah, and independent means that only one thing can happen at once?

15:23 tbaldridge: socksy: independent means that you can't sync two atoms so that everyone sees them change at exactly the same time

15:23 socksy: co-ordinated is only a "can" relationship, right — they don't *have* to happen at once?

15:23 tbaldridge: you can do that with refs

15:24 right, with refs you start a transaction, do some work on refs and then commit it, all the work on those refs is done atomically.

15:24 Jaood: tbaldridge: not even on different threads?

15:24 jumblerg: technomancy: i'm looking at a .jar generated by lein; i see two different project.clj files in the hierarchy. any chance you should shed some light on what purpose they serve?

15:24 tbaldridge: Jaood: ?

15:24 Jaood: tbaldridge: about syncing two atoms

15:25 arrdem: Jaood: using n threads to attempt simultaneous updates of n atoms is a race condition :P

15:25 tbaldridge: Jaood: right, there's no way to make sure that two atoms are updated at exactly the same time.

15:25 socksy: would it make sense to have co-ordinated and asynchronous? (regardless of any judgement put in the value of such a language feature)

15:25 Jaood: ok

15:26 tbaldridge: socksy: perhaps, but I've never needed it, and actually people very rarely use STM in clojure. It's often better to just put all your state in a single place (an atom)

15:26 From what I understand this is even what Datomic does, not a single use of STM in the transactor, just a few atoms.

15:26 Jaood: so refs are not used much in clojure?

15:27 socksy: hmm. I have everything in an agent around a map, and am trying to justify why on earth i'm doing this in the write up :)

15:27 (i may well not be justified in doing this)

15:27 tbaldridge: Jaood: not that I've seen. They are a cool feature, but often there's better ways of doing the same thing.

15:29 socksy: so atom isn't STM? I guess that makes sense since you're doing the compare and set operation. Are agents and refs are STM though?

15:30 cbp: refs are stm, nothing else

15:30 socksy: s/are//

15:30 ah right

15:31 technomancy: jumblerg: one of them might be for backwards-compatibility

15:31 jumblerg: the fully-qualified one is new-ish

15:32 jumblerg: technomancy: ah, good to know. any idea which one? :)

15:32 ok!

15:33 technomancy: one more while we're at it, may i ask the same about the pom.properties and pom.xml files?

15:33 agarman: tbaldridge: does a single atom for state get cumbersome when an app has a lot of state?

15:34 tbaldridge: agarman: that's kindof the point, have less state :-P

15:34 socksy: "Agents are integrated with the STM - any dispatches made in a transaction are held until it commits, and are discarded if it is retried or aborted." So they're implemented around STMs? I am getting a little confused

15:35 agarman: tbaldridge: I agree wholeheartedly, but for something like an multiplayer game, you're pretty much juggling state

15:35 tbaldridge: socksy: they aren't STM, they simply communicate with the transactions in STM. a transaction may be re-run several times. This communication keeps events sent to agents from getting duplicated.

15:36 dbasch: agarman: state is cumbersome regardless, why is an atom worse than having a bunch of objects all over the place?

15:36 socksy: I was under the impression that STM meant: changing shared memory using transactions, that can fail and be backtracked. Am I wrong? Is it more specific than that?

15:36 tbaldridge: agarman: you're also often in a situation where the game engine is managing turns (quite quickly, but still turn based). So it may make sense to deref the state atom once at the start of each engine update then reset! it after the engine returns a new game state.

15:37 arrdem: dbasch: s/worse/better/g

15:37 technomancy: jumblerg: pom.properties just gives you a subset of the data in easier-to-parse format

15:38 agarman: dbasch: tbaldridge: partly I was trying to find a place where coordinating refs may be a good solution vs a large central atom

15:39 jumblerg: technomancy: understand, is that part of the spec for a jar file? i was looking at a few jars generated by maven and they didn't have one.

15:39 dbasch: agarman: if you were doing a trading system with thousands of independent users, you wouldn’t want to keep all the state in an atom

15:40 tbaldridge: agarman: I'd say places where you have a high level of contention. in the case of a game engine though it's probably possible to farm out the processing to multiple threads then write back to the atom a single time. If you can't do that, then yeah it might be better to have 10 threads pounding on 100 refs instead of 10 threads pounding on one ref.

15:41 agarman: tbaldridge: dbasch: I've yet to have a need for refs in any of my apps...a few atoms, a few agents.

15:41 dbasch: agarman: imagine implementing Google, how would you do it?

15:42 agarman: as a thought exercise of course, not that you’d do it in clojure

15:42 jumblerg: technomancy: just found some reading material on the subject after a bit of googling: http://maven.apache.org/shared/maven-archiver/#pom-properties-content, can figure it out from here. many thanks!

15:42 dbasch: agarman: maybe google is not the best example, let’s say ETrade

15:43 noncom|2: are there any code generation libraries for clojure? for example, if i want to generate C code from clojure?

15:43 agarman: dbasch: I was mostly trying to find an example for folks asking about STMs above

15:44 dbasch: agarman: say you have thousands of independent trading orders open at any point in time

15:44 agarman: (inc tbaldridge)

15:44 lazybot: ⇒ 7

15:44 dbasch: agarman: each one must execute independently, and you must pair a buy and a sell

15:45 agarman: so if joe buys 100 AAPL from bob, bob sells 100 AAPL to joe

15:45 agarman: those two must update atomically, but the rest of the orders don’t care

15:45 yotsov: I have heard of the existence of a tool which checks your code and finds places where you could have used existing clojure expression instead of something longer you wrote. Anybody knows if such really exists, and its name?

15:45 bwreilly_: yotsov: kitbit

15:45 yotsov: bwreilly_: thanks!

15:49 agarman: yotsov: eastwood is also useful

15:49 tbaldridge: dbasch: that's the classic example, but has anyone ever really built a system like that?

15:51 dbasch: another method is to simply store all owners of AAPL in a single agent, and the queue all orders regarding AAPL to that agent. group agents onto multiple boxes for a distributed system.

15:52 dbasch: tbaldridge: I know STM is used in high frequency trading (not in clojure, I imagine) but I don’t personally know any implementations

16:03 lemonodor: yotsov bwreilly: to help with your searches, it’s “kibit”

16:05 yotsov: agarman: thanks, I know about eastwood, but kibit seems to be doing something quite different, by suggesting you shorter forms if I understand correctly

16:05 lemonodor: yes, thanks

16:10 AeroNotix: Kibit is pretty good

16:11 But there's no reason to choose one over the other. Use both

16:11 with a dynamic language you need all the help you can get

16:19 yotsov: AeroNotix: sure. I am already using eastwood and core.typed. kibit is something I definitely want to try though because I am sure I often use too long forms out of laziness to learn alternatives to them

16:22 drojas: Hello: anybody knows a form (using alter-var-root) that restores the original value of the altered var??

16:22 lazybot: drojas: What are you, crazy? Of course not!

16:27 technomancy: drojas: maybe you mean with-redefs?

16:27 gtrak: drojas: are you sure you don't want binding's threadlocal semantics?

16:28 arrdem: Bronsa: is there an operation for merging two envs?

16:29 Bronsa: arrdem: no but wouldn't merging :locals suffice?

16:30 sandbags0: amalloy: not that i think you thought it wouldn't, but your neat replacement drop-in worked very nicely. thanks. my clojure has definitely improved since doing some 4clj problems but still a very long way to go :)

16:30 arrdem: Bronsa: not unless :locals contains vars...

16:33 sandbags0: amalloy: i would like to ask you about something you said that i still don't understand though, about the defs being evaluated at the top level

16:37 noncom|2: are there any code-generation libraries for clojure, like for example if i want to generate c code?

16:37 gtrak: , (let [] (println a) (def a)) ;;sandbags0

16:37 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:38 gtrak: hrmm... bad example.

16:38 Bronsa: arrdem: I don't understand what you mean

16:38 sandbags0: gtrak: the context was within a macro, trying to define a function one of two ways

16:38 socksy: Briefly flirting with what we were talking about earlier — can I clarify something about agents? If I have an agent on say, a map, and two operations are sent to the agent, is it possible for two threads accessing that agent at the same time to see different states?

16:38 Jaood: noncom|2: only in our dreams

16:38 gtrak: ,(do (defn a [] (def b)) b) ;;sandbags0

16:38 clojurebot: #<Unbound Unbound: #'sandbox/b>

16:39 noncom|2: :)

16:39 gtrak: normally what you get is

16:39 ,d

16:39 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: d in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:39 socksy: noncom|2: maybe to LLVM IR?

16:40 amalloy: it's always nice to know the random junk i type into irc actually works, sandbags0. just ask your question; no need to ask to ask

16:40 noncom|2: socksy: llvm ir is cool to have too, but i have a specific task of generating c# code, i thought there might be some base for at least c

16:41 sandbags0: apparently a lot of people put stuff in refheap

16:41 socksy: noncom|2: something like https://github.com/halgari/mjolnir

16:42 arrdem: Bronsa: I'm not sure I do either. Trying to clean up what I've got.

16:42 gtrak: noncom|2: generate ASM, then generate C# from that?

16:42 noncom|2: heh, that's an overkill i guess :)

16:43 gtrak: this might be of interest: http://xmlvm.org/overview/

16:43 sandbags0: amalloy: i'm confused about how both defn's got executed

16:43 amalloy: they don't, really. but a class is generated for each of them, for use if they *do* get executed

16:44 and you gave them the same name, so those classes conflict

16:44 sandbags0: ah so the compiler is basically grabbing all defn's

16:44 and making a class out of them

16:44 amalloy: well, all fns, really

16:44 sandbags0: but the var assignment is only made by the codepath

16:44 amalloy: yes

16:44 sandbags0: however the class is there

16:44 hence the weird error

16:44 well, not weird now

16:45 okay, now i understand, thanks again

16:45 useful thing to know

16:45 amalloy: as a general rule, macros shouldn't emit code that they don't expect to be run

16:45 (if false x y) is not the same as y, for some x

16:45 sandbags0: that seems like a sound rule

16:46 i'll try and keep in mind to look for better ways of writing such things if there's a next time

16:47 Jaood: will deref block while an atom is being modified whith swap! ?

16:47 amalloy: no, deref is free

16:48 that is, you get the current value; if someone's busy figuring out a new value, who cares

16:49 noncom|2: socksy, gtrak: thank you for the references, i'm taking a look. although i was more looking into manipulating text source files of C#, these technologies are worth knowing

16:49 Jaood: amalloy: ok, the swap! operation does block the current thread right?

16:49 gtrak: Jaood: as much as doing anything blocks the current thread.

16:50 arrdem: Bronsa: Okay. this is what I'm working with. https://www.refheap.com/86087#L-73

16:50 gtrak: it runs the function, it might re-run it, it's synchronous.

16:50 agents are asynchronous if you need that.

16:50 aperiodic: Jaood: there's no lock to acquire so it won't wait for something to free up or deadlock

16:51 gtrak: that's like saying a function call blocks the current thread.

16:51 which is _true_ albeit useless.

16:52 Jaood: got it

16:53 mikerod: ,(symbol "a/b" "c")

16:53 arrdem: Bronsa: what's going on here is that I already have working code that can take the inline fns of the letfn and rewrite them as fully parameterized top level defs. However with a letfn as the bindings are mutually recursive it isn't enough to simply lift all the fns to the top level I have to emit a (declare) and rewrite each fn to use its letfn mates via the (declare)'d names. This is the sticking point. I know what the top level vars will be since I'm just

16:53 clojurebot: a/b/c

16:53 gtrak: I don't think you'd ever do a (future (swap! )) in other words. You're not supposed to put long-running functions in there.

16:53 tbaldridge: Jaood: atoms just use CAS under-the-hood http://en.wikipedia.org/wiki/Compare-and-swap

16:53 mikerod: ,(name (symbol "a/b" "c"))

16:53 clojurebot: "c"

16:53 mikerod: ,(name (symbol "a" "b/c"))

16:53 clojurebot: "b/c"

16:54 mikerod: What is the deal with symbols that have more than 1 forward /

16:54 it is allowed, but I find it really inconsistent to deal with

16:54 the "/" is interpreted differently depending on the way the symbol was constructed

16:54 gtrak: that would increase the likelihood of contention no matter what thread the work is actually running on.

16:55 mikerod: I'm guessing the thought is just, "no symbol should have multiple forward slash "/" in it.

16:55 ,((just namespace name) (symbol "a/b" "c"))

16:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: just in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:55 mikerod: ,((juxt namespace name) (symbol "a/b" "c"))

16:55 clojurebot: ["a/b" "c"]

16:56 mikerod: ,((juxt namespace name) (symbol "a" "b/c"))

16:56 clojurebot: ["a" "b/c"]

16:56 mikerod: I just ran into a scenario where we were "accidentally" turning some strings into symbols. Later `name` was being used and it was leading to this due to multiple "/"'s.

16:56 Jaood: tbaldridge: useful, thanks

16:57 amalloy: mikerod: i mean, the reader would never construct those symbols. if you do it yourself, by specifying a namespace part and a name part, then what you get out is what you put in

16:57 Jaood: gtrak: yeah, that is what I was thinking, running the swap! operation on a future

16:57 amalloy: ie, (name (symbol a b)) is b, regardless of what silly nonsense you put in for a or b

16:58 (as long as they're strings)

16:58 mikerod: amalloy: why are multiple "/"s supported? just so you can make really crazy symbol names? I know the reader wouldn't support it. I think any symbol with multiple "/"s is just going to be messy.

16:58 the reader wouldn't *produce it I mean.

16:58 amalloy: no, it's because the alternative is to do expensive string-inspection checks every time someone makes a symbol

16:58 mikerod: It just seems to me that a "/" in a symbol name is special and should not just be thrown in wherever

16:59 amalloy: you can have any string at all be the name or the namespace of a symbol. if you have good taste, you should refrain from poorly chosen names

16:59 mikerod: amalloy: that makes sense I suppose. just have to be careful :P

16:59 amalloy: "multiple /s" is not the issue, it's "any string at all"

16:59 &(symbol "foo bar baz" "whoa this is just one ////symbol")

16:59 lazybot: ⇒ foo bar baz/whoa this is just one ////symbol

17:00 mikerod: amalloy: hah, yes I stumbled on this one before too. it shocked me a bit, but makes sense.

17:00 Bronsa: arrdem: I'm reading now, btw your last message cut off at "since I'm just"

17:00 gtrak: Jaood: you might just want an agent then.

17:00 mikerod: ,(pr-str (symbol "a b c///" " hello "))

17:00 clojurebot: "a b c//// hello "

17:00 mikerod: ,(read-string (pr-str (symbol "a b c///" " hello ")))

17:00 clojurebot: a

17:00 arrdem: Bronsa: the comment block on 73 says the same thing

17:00 mikerod: amalloy: the implication there is that the symbol is no longer "reader" friendly

17:01 gtrak: Jaood: it would have the advantage of giving you a queue to throw stuff on and not doing extra work.

17:01 bbloom: tpope: after I run the piggieback command, attempting to eval a form just hangs

17:01 amalloy: sure

17:01 Jaood: gtrak: are their only differences is synchoronous vs async (atom vs agent) ?

17:01 bbloom: tpope: any way to determine what's failing?

17:02 gtrak: Jaood: essentially, yes, also the tasks run on a threadpool, which is managed for you.

17:02 a single agent is just going to serialize the actions, it won't be running concurrently.

17:02 but the threadpools are shared across the agents.

17:04 if you need to go even further, then that's core.async territory.

17:05 if your coordination needs get complex enough.

17:06 Jaood: gtrak: thanks, I'm still on reference types, looking to learn core.async later, I hear is very usefull in cljs

17:06 gtrak: yes, UI coordination gets complex fast. I'm having a lot of fun with that.

17:07 except I have no idea how to test it.

17:07 Bronsa: arrdem: I understand what you're doing but I don't understand what issue you're having :/

17:07 Jaood: gtrak: are you doing a web UI?

17:08 gtrak: yea, some informational node-webkit stuff, using it as an excuse to learn Om and core.async.

17:09 Jaood: cool

17:10 arrdem: Bronsa: The issue I'm having is that I can't seem to build a working rewrite from locals to the newly declared vars in part because when I analyze the renamed symbols the analyzer doesn't know they exist because the declare and the individual symbol uses are analyzed separately.

17:13 felher: Hey folks. Does clojure.data.generators/weighted have a problem with non-integer weights? I looked at the api doc, but it doesn't state anything about that. I tried using numbers between 0 and 1 as weights, which didn't seem to work, but it didn't complain either, so maybe I'm just using it wrong.

17:13 Bronsa: arrdem: mh, analyzing a declare makes the var get interned in the namespace so I really don't see how that could be a problem

17:15 arrdem: Bronsa: understood, and that's what I was counting on. Lemme cut an in progress commit of this and try to get you a concrete error to work from.

17:15 Bronsa: arrdem: long shot but maybe you're analyzing the bindings with their original env? that has the letfn bindings in the env :locals, you need to dissoc those to make the analyzer use the vars instead

17:16 arrdem: Bronsa: that may well be what I'm seeing, but I wouldn't expect that to be the case because I'm trying to do this local -> var replacement where the vars have radically different names than the remaining garbage :locals

17:17 TEttinger: interesting trick: ##(repeatedly 40 #(rand-int 7/6))

17:17 lazybot: ⇒ (0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0)

17:18 mikerod: What is the *best* Clojure testing tool available to give good failure messages when deeply nested maps are being compared.

17:18 It'd be nice to know which key-val was found to not be =

17:19 that sort of thing

17:19 amalloy: TEttinger: cute, i guess, but isn't it the same as ##(repeatedly 40 #(int (* 7/6 (rand))))?

17:19 lazybot: ⇒ (1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)

17:19 TEttinger: it's just odd that rand-int doesn't need to be passed an int to make them

17:20 amalloy: clojure.core is not exactly famous for validating inputs

17:20 sandbags0: mikerod: i can't speak to it being the *best* but expectations definitely does produce intelligent diffs when a test fails

17:22 seancorfield: mikerod: I'll second sandbags0 comment - Expectations generally does a really good job of highlighting exactly what part of the result differed

17:22 sandbags0: mikerod: here's an example https://www.refheap.com/86090

17:23 locks: http://blog.nitrous.io/2014/05/06/learn-clojure.html

17:23 pretty cool

17:23 mikerod: sandbags0: seancorfield Yeah, I've heard a little on expectations before. The example looks promising. Failure message can be rough when dealing with deeper maps.

17:24 I'll have to try out expectations.

17:24 sandbags0: i really like it, but i've zero experience of the alternatives

17:25 aperiodic: mikerod: you can also use lein-difftest if your tests are already written and use clojure.test

17:26 seancorfield: mikerod: we used to use clojure.test but we switched to Expectations after Clojure/West a year or two ago... we love the way they read and how easy the library is to use...

17:26 aperiodic: it's sort of weird (it uses string-based comparisons so sometimes the diffs are more fine-grained than you really want) but it's certainly worlds better than the stock experience

17:28 seancorfield: what motivated you to switch?

17:30 mikerod: aperiodic: I'll check this out as well.

17:31 seancorfield: aperiodic: clojure.test seemed very imperative by comparison: do stuff, assert this, assert that

17:31 mikerod: seancorfield: I wanted to avoid jumping into some "testing framework", but the failures can be painful to figure out (mostly in the case of nested maps). So I think it is worth exploring.

17:31 seancorfield: aperiodic: and I like the BDD style language of Expectations

17:33 mikerod: Expectations is deliberately minimal - and easy to use with Leiningen, Emacs, LightTable...

17:34 sandbags0: yep... when i was looking for a testing library it seemed a simple & elegant choice

17:34 nothing really to learn

17:34 drojas: technomancy: with-redefs don't play well with concurrency

17:35 technomancy: with-redefs do not play well with concurrency

17:36 gtrak: in order to use binding I need to set the function dynamic, and I do not want to do that

17:38 arrdem: Bronsa: failing test case, https://www.refheap.com/86091

17:39 Bronsa: codebase https://github.com/arrdem/oxcart/blob/develop/src/oxcart/passes/lambda_lift.clj

17:40 Bronsa: it looks like what's happening is that after I rewrite the locals to vars they continue to be resolved to locals indicating that something funky is afoot or no rewriting took place.

17:42 looks like the answer is that no locals are rewritten.

17:44 Bronsa: arrdem: shouldn't it be (let [baz (partial baz$baz__.. bar$bar__..) ..) ?

17:45 drojas: anybody knows a form (using alter-var-root) that restores the original value of the altered var (with-redefs does not work with concurrency and binding needs the var to be dynamic)??

17:45 lazybot: drojas: Uh, no. Why would you even ask?

17:46 technomancy: drojas: you can't change the root *and* play well with concurrenty

17:46 concurrency

17:46 they're mutually exclusive

17:47 arrdem: Bronsa: this is the desired output https://www.refheap.com/86092

17:47 mikerod: seancorfield: well, sounds promising. minimal = win.

17:47 I appreciate the feedback on this.

17:48 arrdem: Bronsa: I claim that output is reasonable because within the original letfn forms, "bar" and "baz" are locals and thus should be rewritten to their lifted names.

17:48 Bronsa: arrdem: you probably just need to dissoc the letfn locals from https://github.com/arrdem/oxcart/blob/develop/src/oxcart/passes/lambda_lift.clj#L63

17:48 arrdem: Bronsa: re-running collect-closed-overs then will not show them as closed over and they do not need to be partials.

17:49 Bronsa: will the re-run of collect-closed-overs that I do here https://github.com/arrdem/oxcart/blob/develop/src/oxcart/passes/lambda_lift.clj#L126 not achieve that?

17:50 Bronsa: because I'm completely killing the {:op :local}s for {:op :var}s which I don't expect can resolve to :local bindings

17:50 amalloy: technomancy: note that lazybot's ?? plugin was right again. the accuracy of that one single predictor is remarkable

17:50 arrdem: but this is your toolchain and not yet mine so I may be mistaken.

17:50 drojas: technomancy: what I need to do can't be done with binding or with-redefs but it can with alter-var-root. I just can't make it in one single form, if I don't get that macro done soon I'll use ^:dynamic and binding.

17:51 amalloy: what you asked for is not possible, drojas, as technomancy said. alter-var-root is the antithesis of safe concurrency

17:51 drojas: technomancy: ... it can be done with binding but I do not want to define dynamic functions

17:56 hiredman: drojas: have you looked at the implementation of with-redefs?

17:56 Bronsa: arrdem: let me play a bit with your code

17:57 arrdem: Bronsa: please do. I'm digging in to the unmodified AST to confirm that it's structure the way I think it is.

17:57 Bronsa: thanks for taking a look at this

17:58 drojas: hiredman: nope, since with-redefs changes can be persistent when executed in concurrency...

17:58 hiredman: drojas: the same is true for alter-var-root

17:59 drojas: a var is a mutable memory cell, if you alter the contents, every sees the different contents, unless you use dynamic vars

17:59 drojas: hiredman: never tried but I believe in that now... I'll use dynamic vars and binding

18:00 technomancy: amalloy: it's a pretty great heurstic

18:01 arrdem: Bronsa: yeah that (baz [z] (dec (bar z))) does come down to a {:op :invoke :fn {:op :local :name bar__#0}}, which I am seeing replaced with a {:op :var}.

18:02 and then I get that local right back again.... oh.

18:06 {blake}: OK, I need help braining... Given the nested structures here: https://www.refheap.com/86093

18:06 I want to get the data out as shown by the nested mapcats, without nesting the mapcats manually, obviously.

18:07 arrdem: nope if I do a (ast/prewalk #(assoc %1 ::no-replace true)) and conditionalize lambda lifting on (not (::pre-walk ast)) I see that the local to var replacement happens and that {:op :local} bar -> {:op :var} bar$bar__...

18:07 {blake}: Or if there's another way without using mapcat. My previous attempts all ended up with deep nesting that felt forced to try to flatten.

18:08 gfredericks: the factory method for the j.u.c ScheduledExecutorService is surprisingly ambiguous about what its thread-count arg means

18:08 drojas: technomancy: which tdd library would you recommend (I'm using clojure.test but I'm a little bit confused about switching to midje for the stubbing features)?

18:08 technomancy: I would not recommend midje

18:09 gfredericks: using component for mocking instead of with-redefs means you have concurrency-friendly tests

18:09 noonian: technomancy: why not midje? just curious

18:09 amalloy: sounds like you want a function (read-tag stuff :L3), such that you can write (-> sample3 (read-tag :L1) (read-tag :L2) (read-tag :L3)), {blake}

18:09 where read-tag is just that mapcat/when function you wrote a hundred times

18:10 {blake}: amalloy: Well, yesterday I got this to where I could say "(by-tags data [:L1 :L2 :L3])" and I liked that, just not the results. =P

18:10 amalloy: and maybe a better name than read-tag is like...descend-into

18:10 {blake}: amalloy: Yeah, all names are a work-in-progress...

18:10 technomancy: noonian: it has a bunch of macros that are too clever; they look good on the surface but obscure what's really going on

18:10 amalloy: the...results?

18:11 technomancy: also it encourages side-effects at the top-level, though supposedly that's optional

18:11 hiredman: midje is basically written by rubyists while they are learning clojure, it tends to do things the ruby way vs the clojure way until some one points out how broken it is

18:11 noonian: technomancy: thanks

18:11 {blake}: amalloy: The results of my previous attempts. I had a for-loop with a when filter that recursively called itself.

18:12 amalloy: It got the right data, just nested deeply, and with empties when there was a branch that didn't qualify.

18:12 amalloy: This was the first shot: https://www.refheap.com/86027

18:12 amalloy: {blake}: that's just missing a level of flattening. i liked your previous approach better than the one with mapcat. re-paste that and i'll show you how to flatten it

18:13 {blake}: amalloy, OK, hang on, let me put up the latest.

18:13 amalloy, https://www.refheap.com/86094

18:14 If I "(by-tags sample2 [:L1 :L2 :L3])" I get " ((() ([{:stuff :otherdata}])) (() ([{:stuff :otherdata}])))" which is yucky. And doesn't allow me to chop off a branch and pass it back in.

18:15 hiredman: you need to hoist the if up in to the for

18:15 gfredericks: programmers say the weirdest things

18:15 justin_smith: (inc gfredericks)

18:15 lazybot: ⇒ 65

18:15 gfredericks: I wonder how many layfolk can parse that sentence correctly

18:15 hiredman: is it odd that I never get to use the word hoist outside of s-expression manipulation?

18:16 gfredericks: bring back the hoisting

18:16 {blake}: Steer clear of any petards, then.

18:16 arrdem: hiredman: it's rarely sematically valid outside of sexprs..

18:16 hiredman: the first thing that needs to happen is both branches of the the if need to return the same shape of data

18:17 justin_smith: arrdem: that's just because it's been too long since we had a proper bloody revolution

18:17 hiredman: the first branch returns a thing, the second a list of things, so box the first in []

18:17 {blake}: hiredman: but ":content r" is a vector...

18:17 justin_smith: arrdem: (or maybe you just don't spend much time in warehouses)

18:18 amalloy: {blake}: the simplest fix is https://www.refheap.com/b76736928aca08236316971a9, which is sorta the opposite of what hiredman is saying

18:18 hiredman: if I ever get a regular kayak that I need a car rack to carry around I'll be able to talk about hoisting the kayak on to the car

18:18 amalloy: his way should be fine too, depending on exactly the shape of data you have/want

18:18 {blake}: Vectors of hashes containing vectors of hashes.

18:18 gfredericks: hoistable

18:19 cbp: /[

18:19 arrdem: justin_smith: DOST THOU EVEN HOIST

18:19 cbp: er oops

18:19 justin_smith: lol

18:19 * arrdem goes back to lifting lambdas

18:19 gfredericks: cbp: I was trying to interpret that as an emoticon about hoisting

18:19 amalloy: you're not alone, gfredericks

18:19 hiredman: my lisp targeting go had a special form that would cause the compiler to hoist a given expression to the outer most scope

18:19 gfredericks: it kind of looked like hiredmand & a kayak

18:19 arrdem: this channel says the damndest things..

18:20 gfredericks: s/hiredmand/hiredman/

18:20 (hiredmand is hiredman persistently in the background)

18:21 could a lisp have a comacro that gets to replace the code it's embedded in?

18:22 arrdem: you could invent such a construct but I've never heard of one before..

18:22 hiredman: gfredericks: continuations for macros

18:22 {blake}: amalloy, hiredman: thanks

18:22 (inc amalloy)

18:22 lazybot: ⇒ 114

18:22 {blake}: (inc hiredman)

18:22 lazybot: ⇒ 46

18:23 hiredman: sort of logically the continuation of a macro is the code in to which it is being expanded

18:23 I have no idea how that kind of thing would work

18:24 gfredericks: it seems like there'd be some definitions to work out wrt how they interact with normal macros

18:25 hiredman: and what would the boundaries be, would the continuation be the entire compilation unit?

18:25 gfredericks: the WHOLE PROJECT

18:25 and its libraries

18:26 and...clojars

18:28 hiredman: delimited macro continuations

18:29 gfredericks: this reminds me of that character in Hitchhiker's who built a shack on the beach and defined the area outside it to be the inside

18:29 gtrak: gfredericks: I think that's called dynamic scoping.

18:29 hiredman: I am waiting of bbloom to explain that an effects system would handle this

18:30 gfredericks: "Watson, distressed and fearing for the world's sanity, built 'The Asylum' to put it in and help it get better."

18:30 tolstoy-: (Asking for a colleague): Is the Clojure in Action book pretty reasonable?

18:31 gtrak: tolstoy-: I'm reviewing the second edition, I'd recommend to not get the first.

18:31 tolstoy-: gtrak: Is the 2nd edition out?

18:31 gtrak: no :-)

18:31 arrdem: gtrak: I thought the PDF was out

18:31 tolstoy-: Ah, I see it's 2011.

18:31 Bronsa: arrdem: http://sprunge.us/gWeN?diff

18:31 gtrak: but I think it'll be better, haven't read the first, but I didn't like the first transcript they sent me, the recent one was much better.

18:32 gfredericks: back when vars were vars and arithmetic couldn't overflow

18:32 Bronsa: arrdem: you had a really dumb bug and two non obvious ones :)

18:32 noonian: are vars not vars anymore?

18:32 arrdem: Bronsa: do tell.

18:33 gfredericks: ~vars

18:33 clojurebot: vars are a linking construct

18:33 gtrak: tolstoy-: early access: http://www.manning.com/rathore2/

18:33 Bronsa: arrdem: 1- you were using a transient to do mutability in place + you were calling get on the transient rather than on (persistent! the-transient)

18:33 arrdem: changed that to an atom

18:33 arrdem: Bronsa: yep got that.

18:33 Bronsa: arrdem: also you were calling patter/binding->symbol on a local

18:33 tolstoy-: gtrak: Personally, I like Joy of Clojure, but it's abstract. Any recommendation for a first book for an experienced Java dev (who's not too thrilled about folks using Clojure in the company)?

18:34 amalloy: Bronsa: er, don't transients support get? they should

18:34 gtrak: I've heard good things about Clojure Programming

18:34 arrdem: Bronsa: lolz yeah that I fixed not long after cut that commit for you

18:34 amalloy: &(get (transient {:x 1}) x)

18:34 lazybot: java.lang.RuntimeException: Unable to resolve symbol: x in this context

18:34 tolstoy-: gtrak: Chas Emerick?

18:34 amalloy: &(get (transient {:x 1}) :x)

18:34 arrdem: amalloy: they do

18:34 lazybot: ⇒ 1

18:34 gtrak: yea

18:34 Bronsa: arrdem: oh well I didn't know that.

18:34 arrdem: Bronsa: yep, that was my fault. what's the update-ns-map!?

18:34 cbp: tolstoy-: maybe the clojure cookbook

18:35 gtrak: tolstoy-: I also really loved Joy of Clojure.

18:35 bbloom: hiredman: gfredericks: read http://lampwww.epfl.ch/~rompf/pldi2014.pdf

18:35 hiredman: gfredericks: shows an example of this sort of thing

18:35 gtrak: is the second edition worth getting if you've already gotten the first?

18:35 Bronsa: arrdem: you don't specify the env when you analyze (declare foo) so a new empty one gets created automatically, the :namespaces atom of that env gets updated with the newly interned var but not the original one

18:36 bbloom: but in short, yeah, "on the stack replacement" of the continuation is pretty natural with an effect system

18:36 cbp: gtrak: 2nd edition of joy of clojure?

18:36 gtrak: yea

18:36 arrdem: Bronsa: gotcha. that was one thing I was worried about for a while.

18:36 Bronsa: arrdem: ideally you should always use the same env that builds up incrementally, if you don't you'll have to manually update the env to reflect the changes

18:37 noonian: Clojure Programming is good for an intro to the language, i know people who tried Joy of Clojure first and thought it was 'preachy'

18:37 arrdem: Bronsa: okay I was wondering about that.

18:37 gtrak: noonian: which was preachy?

18:37 Bronsa: arrdem: and finally, you were calling (:form ast) rather than regenerating the form with emit-form, so it was emitting (fn [] bar) rather than (fn [] bar$whatever)

18:37 noonian: Joy of Clojure, those aren't my words though, i very much enjoyed it

18:39 gtrak: I wouldn't recommend JoC to someone who's just trying to get something done.

18:39 cbp: gtrak: Well I know it has a bit on reducers which is new

18:39 havent read it completely yet though

18:39 Bronsa: amalloy: do you know if transients always supported get? or is that a recent addition?

18:40 gfredericks: Bronsa: frequencies couldn't work without it, no?

18:40 arrdem: Bronsa: mm..... I don't think the last one was right, but the others definitely are. thanks for the help.

18:40 gfredericks: frequencies is my goto example for transients

18:41 amalloy: Bronsa: it's not recent

18:41 Bronsa: gfredericks: I don't recall all of clojure.core by heart but I trust you :P

18:41 amalloy: it's been that way since at least 1.2, and i don't know if transients even existed before that

18:41 gtrak: gfredericks: zipmap is my goto example for 'why not transients?'

18:41 gfredericks: clojurebot: Bronsa |trusts| me to recall all of clojure.core by heart

18:41 clojurebot: Alles klar

18:41 gfredericks: gtrak: mine is set

18:42 gtrak: that just calls into java

18:42 gfredericks: gtrak: vec does as well, but uses transients in java

18:42 amalloy: gtrak: yes, but it's *slower* calling straight into java than if it had used transients

18:42 gtrak: heh

18:42 Bronsa: arrdem: you mean about emit-form?

18:42 gtrak: didn't know that one.

18:43 But I've definitely favored seq filter/remove over clojure.set functions for perf reasons.

18:43 massive difference.

18:43 arrdem: Bronsa: emit-clojure. I have my own AST structure built atop yours that it processes.

18:43 gfredericks: oh all of clojure.set is non-transient isn't it

18:44 gtrak: but people that know math intuitively reach for clojure.set.

18:44 gfredericks: haha set.clj has a (comment) at the bottom

18:44 amalloy: gfredericks: a lot of the old files do

18:44 Bronsa: arrdem: oh well, I didn't read all your code so you're probably right

18:44 amalloy: see xml.clj

18:44 gfredericks: gtrak: have you seen a ticket for this?

18:44 gtrak: don't think so.

18:45 gfredericks: seems kinda low-hanging

18:45 or high-growing in the case of vegetables

18:45 gtrak: gfredericks: well, in my case simply not running inputs through (set ..) made a big difference.

18:45 but it could use transients there.

18:46 rather, I ran the smaller input through set, then used that as a predicate.

18:46 Bronsa: I just discovered clojure.template is a thing.

18:47 gfredericks: "You won't believe this weird namespace that Bronsa found in the clojure source code."

18:47 gtrak: gfredericks: we'll just keep whipping arrdem to produce a whole program optimizer.

18:47 arrdem: gtrak: I'm self-whipping, for whipping defined as coffee overloading

18:48 gtrak: even better.

18:48 amalloy: oh, that's weird, Bronsa. i knew stuart sierra had written it, but i guess i forgot it was part of clojure.core. thought it was some contrib

18:49 arrdem: Bronsa: hum.... something's fishy. if I reset, restart my REPL and apply your patch the case is still b0rken.

18:49 technomancy: Bronsa: it was included in clojure simply because clojure.test/are uses it iirc

18:49 from what I've heard it never would have landed on its own merits

18:49 dbasch: transients is from 1.1

18:51 amalloy: man, that's terrible, technomancy. it would be so easy to just inline the template code into clojure.test/are

18:51 Bronsa: arrdem: durr I forgot to include the emit-form thing in the diff http://sprunge.us/GZjW

18:51 gtrak: dbasch: didn't stop him from changing stuff around for reducers.

18:52 amalloy: but you're right, that's the only place it's used at all

18:52 arrdem: Bronsa: Ah. Okay yeah that's very significant :P

18:52 herp a derp

18:52 technomancy: amalloy: at the time my only thought was "man, it'd sure be great to be able to write tests without contrib"

18:52 arrdem: dat (:form)....

18:52 amalloy: i wish they'd instead implemented macrolet, and used *that* for are

18:52 Bronsa: yeah that's what I was talking about

18:52 * arrdem feels silly

18:53 amalloy: or i guess it's more like symbol-macrolet, but whatever

18:53 arrdem: (inc Bronsa) ;; and everything works

18:53 lazybot: ⇒ 21

18:54 amalloy: (are [a b c] (= a (+ b c)), 3 2 1, 6 4 2) could have been (do (symbol-macrolet [a 3 b 2 c 1] (is (= a (+ b c)))) (symbol-macrolet [a 6 b 4 c 2] (is (= a (+ b c)))))

18:54 and then we'd have symbol-macrolet!

18:54 hiredman: yep

18:55 * amalloy pines for macrolet facilities

19:00 hiredman: "pines" could go so many ways "you should use mutt instead, or maybe gnus", "sure you pine for it, but what do you yew for?" etc

19:00 * arrdem ponders a "pining for the fjords" joke

19:00 amalloy: hiredman: i just have finger dyslexia. i meant spine

19:00 hiredman: and then you can start in on yew and you

19:02 amalloy: i noticed something weird on stackoverflow. of the users with the gold "clojure" badge, one of them got it in 2010, and then in 2012 three users got it within three months of each other, and then nobody has gotten it since then. does that mean anything interesting?

19:02 (list at http://stackoverflow.com/help/badges/250/clojure but i don't think it matters much)

19:03 gfredericks: amalloy: nobody uses clojure anymore

19:03 amalloy: disaster! how do i un-learn this useless language, gfredericks?

19:03 gfredericks: clojure has mostly been supplanted by node, which has similar features but can scale

19:03 amalloy: embrace the async

19:04 arrdem: `tbaldridge likely has something to say on the matter of async and Clojure's obsolescence...

19:04 amalloy: you'll be the death of me one day, gfredericks

19:04 hiredman: peak stackoverflow

19:04 dbasch: node is web scale, unlike clojure

19:04 arrdem: as is mongodb...

19:05 amalloy: dbasch: you're too late, gfredericks already made that joke

19:05 tbaldridge: does anyone use stackoverflow anymore?

19:05 dbasch: but I sent the request 3 minutes ago through my node app!

19:06 gfredericks: stackoverflow is a website that google sends you to when you have programming questions

19:06 arrdem: tbaldridge: why would you make async requests for support when you can synchronously bug the library maintainers on IRC?

19:06 tbaldridge: :-)

19:06 dbasch: $google ask a programming question

19:06 lazybot: [Stack Overflow] http://stackoverflow.com/

19:07 technomancy: stack overflew

19:07 gfredericks: huh -- sync vs async is exactly why people use text messages instead of calling

19:07 go tell your grandmother

19:07 dbasch: arrdem: because they have badges

19:08 * dbasch waits for the reference

19:08 arrdem: dbasch: badges? badges? we don' need no steenkeeng badges..

19:08 besides we have bot karma!

19:08 * dbasch unblocks

19:10 gfredericks: $karma lazybot

19:10 lazybot: lazybot has karma 26.

19:11 gfredericks: his karma is so high because most of his dec's are a result of being offline

19:12 {blake}: $karma chameleon

19:12 lazybot: chameleon has karma 0.

19:12 {blake}: aww

19:12 gfredericks: $karma rhickey

19:12 lazybot: rhickey has karma 2.

19:12 gfredericks: welp.

19:13 noonian: lol

19:14 dbasch: (inc chameleon)

19:14 lazybot: ⇒ 1

19:14 dbasch: that wasn’t right

19:46 arrdem: Bronsa: (let [x 2] (letfn [(bar [z] (* z x)) (baz [y] (bar (inc y)))] ...)) should x not be a closed-over of baz as well as bar?

19:52 hyPiRion: arrdem: why should x be closed over baz? Unless you're doing inlining

19:53 storme: $karma storme

19:53 lazybot: storme has karma 0.

19:53 arrdem: hyPiRion: that's close to what I'm doing :P

19:53 storme: $karma seancorfield

19:53 lazybot: seancorfield has karma 12.

19:54 hyPiRion: arrdem: oh, hrm

19:54 arrdem: hyPiRion: yeah :|

19:54 kenrestivo: $karma karma

19:54 lazybot: karma has karma 0.

19:54 kenrestivo: $karma karma karma chamelon

19:54 lazybot: karma has karma 0.

19:55 kenrestivo: oic, someone already went there.

19:55 gtrak: $karma lk;asjdfal;ksjdf;alksdjfa;slkdfjasl;kdjf

19:55 lazybot: lk;asjdfal;ksjdf;alksdjfa;slkdfjasl;kdjf has karma 0.

19:55 gtrak: it's a big database :-)

19:55 hyPiRion: arrdem: Well, Bronsa is probably sleeping right now, FYI

19:55 kenrestivo: $karma korma ;; drop table users

19:55 lazybot: korma has karma 0.

19:56 amalloy: arrdem: baz doesn't close over x

19:56 hyPiRion: (identity hyPiRion)

19:56 lazybot: hyPiRion has karma 36.

19:56 arrdem: hyPiRion: yeah I need a "T-12" clock on my desk.

19:56 dbasch: gtrak: not as big as the one with all the bitcoin keys :) http://directory.io/

19:56 amalloy: if you want the closure of the "closure relation", then you can compute that based on the depth-one relation that's presumably what Bronsa is actually using

19:56 gtrak: wow

19:57 amalloy: (here closure means two different things in one sentence! very exciting)

19:57 arrdem: such terminology wow what does mean very confuse

19:58 gtrak: dbasch: it only goes up to 20

19:58 arrdem: amalloy: jokes aside you're right, and what I need to do is figure out a nice way to compute exactly that result.

19:58 s/nice/working/h

19:59 dbasch: gtrak: I guess it broke :(

19:59 gtrak: probably a php thing

19:59 amalloy: it's going up and down

20:00 gtrak: someone used single quotes when they should have used double ones.

20:02 arrdem: gah it's 1:55 AM there. I feel bad now. good call hyPiRion.

20:03 amalloy: dbasch: if you request http://directory.io/904625697166532776746648320380374280100293470930272690489102837043110636675 their server crashes

20:03 hyPiRion: amalloy: or http://directory.io/13

20:03 amalloy: no, that works fine, hyPiRion

20:03 hyPiRion: amalloy: what, doesn't work here

20:03 arrdem: that crashes for me..

20:04 dbasch: amalloy: the site is offline, cloudflare caches some pages for them apparently https://www.dropbox.com/s/mq3mig0zy1ttw7m/Screenshot%202014-05-29%2016.57.41.png

20:04 gtrak: I get a banner, 'this page is current offline'

20:04 amalloy: dbasch: the site auto-restarts itself, and appears to be fine for a while, until you request a high-numbered page like http://directory.io/904625697166532776746648320380374280100293470930272690489102837043110636675 - then every page gets that offline banner, until the server restarts

20:04 gtrak: hehe

20:05 amalloy: of course now that i've said it out loud, it will be hard to repro as everyone is hammering it

20:05 but that was my experience playing around. could load low-numbered pages easily; attempted to load high-numbered page; now all pages are temporarily offline. wait for server to come back up: same behavior

20:06 dbasch: they should have implemented the address derivation client-side :)

20:06 amalloy: hahahaha http://www.reddit.com/r/Bitcoin/comments/1ruk0z/dont_panic_directoryio_thing_is_fake/ - completely missed the joke

20:07 dbasch: and technically it’s not fake, it’s an approximation of The Book of Sand by Borges

20:08 (a book with an infinite number of pages, infinitely thin)

20:09 but computing tons of bitcoin addresses server-side can get expensive

20:10 hyPiRion: The Book of Sand sounds sorta like dirac delta?

20:10 dbasch: hyPiRion: yes, the integral is such that it’s a regular tome

20:11 hyPiRion: hahah, nice.

20:11 arrdem: (count sand)

20:11 Bronsa: arrdem: x is not a free variable of baz there, I guess if you need it to be there you'd have to figure out which other letfn bindings are used inside a binding body and merge their :closed-overs

20:12 arrdem: Bronsa: yep that's what I'm working on. sorry to bug you this late.

20:12 hyPiRion: hurray for European CS students not yet sleeping

20:12 arrdem: hyPiRion: insomnia seems to go with the major...

20:13 Bronsa: having classes in the afternoon helps

20:13 hyPiRion: When you're working on a master's thesis, you don't even have classes

20:14 arrdem: s/helps/hurts/g I'm gonna have to turn in early today this waking up at noon and then GSoCing till 8 thing is nice but it makes for grinding starts.

20:17 Bronsa: arrdem: btw you might want to use analyze' rather than analyze and use the lastest t.a snapshot. it removes all the :namespaces entries for env so it makes it nicer to pprint the AST

20:18 arrdem: Bronsa: ok. I've just been running my own "throw out :env" pass before I pprint to start digging around.

20:21 erlis: emacs question: I have a project and everytime I want to use the REPL (cider) I have to C-c C-k file by file

20:21 is it possible to do that for all the files in my project

20:22 is there a C-c C-k en emacs that load the entire project at once?

20:22 gtrak: C-c C-k an entry point

20:23 I dunno, never bothered me in practice :-)

20:23 i think you can hack something together with tools.namespace

20:24 erlis: is bothering me now, I have several files and if I want to evaluate something I have to load one by one ...

20:25 gtrak: if it's bothering you, it's possible you haven't structured your app correctly.

20:25 technomancy: erlis: almost every clojure codebase has a single namespace that requires all the others to get compiled when it's compiled

20:25 erlis: technomancy: let me try that

20:26 gtrak: erlis: you're likely also using fully-qualified names instead of 'require' like you're supposed to.

20:26 arrdem: erlis: baring aught else you could always write a `find` equivalent emacs function that searches recursively for clojure files and evals them..

20:26 gtrak: you shouldn't rely on load ordering.

20:27 erlis: in my core.clj I'm referencing all other namespaces

20:27 arrdem: load ordering and load time evaluation are evil and things I look forwards to killing off in oxcart.

20:28 gtrak: erlis: the key is what you mean by referencing

20:28 erlis: I do a change on one of the files, C-c C-k in core.clj and I got an error

20:28 can I paste here my (ns) declaration, it's short

20:28 gtrak: it won't reload namespace unless you do require reload :true

20:28 technomancy: arrdem: "load time evaluation" being side-effects specifically or what

20:28 arrdem: ^

20:29 gtrak: but you're already in the file, just hit C-c C-k and it'll ask you to save first.

20:29 what's the problem?

20:29 technomancy: isn't there a C-c C-k alternative that does reloads?

20:29 arrdem: technomancy: load for side effects is one, the other that's messy is (def foo (System/getEnv "$PWD"))

20:29 technomancy: arrdem: yeah, that's something I see customers get wrong on heroku =\

20:29 gtrak: then you hit 'y' and all is well.

20:30 arrdem: technomancy: the if that a defmulti compiles down into as well..

20:30 technomancy: ouch

20:30 arrdem: technically it's a (when (bound? <method>) (alter <method>)) which makes sense but yeah.

20:31 collecting those would be nice if I ever get that far.

20:31 technomancy: arrdem: someone who used clojure.core/load was telling me how it was so lame that slamhound doesn't work with it

20:32 amalloy: speaking of which, technomancy, could you get slamhound to work on my codebase? it is scribbled on the backs of thirty napkins, written in barbecue sauce

20:32 technomancy: because clojure.core/load is so cool

20:32 http://p.hagelb.org/oh-yeah.gif

20:33 arrdem: amalloy: well at least you got the right ink..

20:36 mr-foobar: alandipert here ? haplon doubt

20:37 alandipert: mr-foobar, what's up?

20:38 mr-foobar: alandipert: hey ... have a bit of trouble understanding the documentation. by html compiler, do you mean a pre-renderer ?

20:40 * mr-foobar oops hoplon

20:40 alandipert: mr-foobar, the kinds of compilation are prerender and html syntax -> cljs syntax

20:41 the html syntax -> clojurescript syntax is probably closer to translation than compilation

20:41 mr-foobar: alandipert: neat. also, how does the sync happen to the browser ? is it complete client side rendering ? or server side + websocket updates ?

20:42 alandipert: mr-foobar, many of us are in #hoplon btw if you want Enterprise Support :-)

20:42 mr-foobar, server isn't a requirement, we use the 'castra' library to do RPC. people have used liberator & http-kit backends & experimented with websocket

20:44 mr-foobar: alandipert: will checkout castra and also join #haplon :) Are you planning on a clojure port of javelin ?

20:44 alandipert: mr-foobar, complete client-side rendering is most supported, but dynamic server-side prerender has been experimented with

20:45 mr-foobar, there is a clj port but it's not as featureful or documented, check out https://github.com/tailrecursion/javelin/blob/master/src/tailrecursion/javelin_clj.clj

20:49 mr-foobar: alandipert: neat. making a fork. I'm trying to build a javelin based app. not sure whether to go with om, which I sorta understand, or hoplon which seems more close to what I want.

20:50 alandipert: mr-foobar, cool, be sure to check out https://github.com/tailrecursion/hoplon-demos/ - we may already have what you want :-) also we're very active on http://hoplon.discoursehosting.net/, our forum, if you want advice/help

20:52 mr-foobar: alandipert: yup. for testing purposes I should be able to :require tailrecursion.javelin_clj from clojure right ?

20:54 alandipert: mr-foobar, javelin-clj instead of javelin_clj in your require, but yup. full: (ns test (:require [tailrecursion.javelin-clj :refer [defc defc= cell cell=])) gets you the stuff

20:55 mr-foobar: alandipert: thx !

20:56 alandipert: http://t.co/rqFo4zoweO :)

20:57 alandipert: mr-foobar, love it! devn was working on a javelin tracker at one point

20:59 mr-foobar: alandipert: i have one in the works too ! ask him to github it :)

21:00 alandipert: mr-foobar, really awesome. we need it to make music to program to

21:00 mr-foobar, a good tracker would be a key piece of my dev tooling

21:02 mr-foobar: alandipert: buy renoise ! I highly recommend it .. it has OSC and Lua API. I learnt a lot from it, like RTFM .. also there are tons of drum samples

21:03 as the techno producers say, loop the 909 kick for 4 hours and you have a party

21:05 m00nlight: How can I lazily read 200 lines each time from a file?

21:11 blur3d: I’m trying to use the Prismatic Schema clojure library, and an writing a custom coercion function, but I’m blanking on how to more easily write it

21:12 basically, I have a map, and I need to update certain keys (only if they exist), using a transform function

21:13 alandipert: blur3d, sounds reduce-y - initial value is the map, sequence is the keys you want to transform, reducing function is the update-in + transform

21:14 ,(reduce (fn [xs y] (update-in xs [y] str)) {:number 123} [:number])

21:14 clojurebot: {:number "123"}

21:14 blur3d: would that work for a few different functions (depends on the keys)

21:14 some I want to convert to UUID and TIMESTAMP

21:15 This is terrible code.. but what I have working http://pastebin.com/dW9innnu

21:16 (it also doesn’t check if key exists, before performing function)

21:18 they give this example http://pastebin.com/yxZp2K1i - but i’m not sure how best to adapt it

21:19 danneu: arrdem: my conf was meant to be public, but thanks for letting me know

21:22 dbasch: blur3d: the one thing that stands about about your code is that you don’t need to create anonymous functions, that’s what the threading macro is for

21:23 blur3d: i.e. remove the (# ) and the %

21:23 blur3d: yeah, I added them when I was playing around with the if contains? check

21:27 dbasch: you could do what alandipert said with a cond for different keys

21:27 blur3d: I’ll give that a go

21:35 akhudek: is the ring 1.2 documentation still around anywhere?

21:38 Jaood: git never forgets

21:40 blur3d: dbasch alandipert: I got it working fairly nicely with reduce and condp http://pastebin.com/y0dRjZuq - Thanks for your help

21:59 rhg135_: can I get a quick opinion on some code I wrote? https://github.com/rhg/cljnio

22:01 work_op: is it possible to make an atom that evaluates a function whenever its dereferenced?

22:01 rhg135_: work_op, yes, using watchers

22:01 but i haven't tried

22:02 work_op: hm

22:02 benkay: is there a function like (do ...) that fires off its expressions immediately?

22:02 hellofunk: work_op you might also consider a more functional approach, such as storing the atom as a closure in a function, accessing the atom through the function, in which case the function can do other things as well during that access

22:02 rhg135_: work_op, oops that's on updates

22:03 work_op, maybe wrap it in another IDeref

22:03 hellofunk: benkay what do you mean? do is synchronous, it fires off its enclosed functions

22:03 benkay: instead of in the case of (do) which evaluates the expressions in order?

22:03 hellofunk: i guess asynchronously fires off the enclosed functions.

22:03 hellofunk: well, look at core.async of course

22:03 work_op: hellofunk, in the context of a small game, i have a settings file, and what i want is for the atom to use the latest version of that file. so if i have red tiles, and i save the settings file with blue, the tiles would change on each draw

22:03 rhg135_: like async's go?

22:04 auto-update "magic" seems wrong here

22:04 hellofunk: work_op why would you *need* to incorporate the model you are suggesting where you have an automatic link beween a deref and a function call? seems better to keep those separate, more flexible

22:04 benkay: "Asynchronously executes the body" >.<

22:04 work_op: what do you mean separate?

22:05 benkay: and here I was thinking it just turned on the non/blocking takes/puts.

22:05 thanks, hellofunk .

22:05 rhg135_: we all have those 'I'm stupid' moments, benkay

22:05 hellofunk: benkay core.async is pretty amazing stuff. watch the various presentation on youtube, play with it

22:05 work_op: idk if you are familiar with light table's settings architecture, but thats what im trying to implement, hellofunk

22:05 rhg135_: read lt's code

22:06 it probably is more concise :P

22:06 hellofunk: work_op not sure I don't see why you couldn't just have a function that derefs an atom internally and does other stuff as needed too

22:06 benkay: hellofunk: i descended into dependency hell trying to require core.async in one of my own namespaces today.

22:06 hellofunk: watchers or other complexities don't seem that necessary here

22:07 Jaood: I wonder if LT would have been design any differently it react had existed then

22:07 rhg135_: somn like a readd-config! fn wrapping a atom

22:07 work_op: yeah but the atom itself

22:07 rhg135_: Jaood, i don't doubt it

22:07 i long for om in lt plugins

22:09 benkay: has anyone else here run into "No such var: clojure.core.cache/through" when requiring clojure.core.async?

22:09 rhg135_: not really

22:09 but several others yes

22:10 work_op: a little macro would do fine for this hellofunk, now that u said that. if i just swap it whenever its needed and then dereference it inside the function it would be fine

22:38 benkay: what's the idiomatic way to pull from a channel until it's closed?

22:38 or closed + drained?

22:39 ah stuartsierra with the hotsauce: http://stuartsierra.com/2013/12/08/parallel-processing-with-core-async

22:43 hellofunk: work_op though probably even a macro wouldn't be needed, a regular function will usually work for most things you might think a macro is needed for

Logging service provided by n01se.net