#clojure log - Jul 10 2014

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

0:01 rbrito: Someone asked which programs in python are my most popular. I would say this one:

0:01 gfixler: rbrito: just for one more vote of confidence, I'm in chapter 7 of Learn You A Haskell, and it's all been very straightforward, fun, and a little bit eye-opening

0:01 rbrito: https://github.com/coursera-dl/coursera

0:01 gfixler: I found Learn You a Haskell more engaging than Graham Hutton's book on Haskell.

0:01 gfixler: oh, have you already read it?

0:02 rbrito: But, then, I have only read the 1st chapter of LYAH and only the first 3 chapters of Hutton's book.

0:02 gfixler: good start

0:02 rbrito: gfixler: only a small bit.

0:02 systemfault: LYAH was a good book beside one or two things.

0:02 gfixler: The friend who got me into Haskell, right as I was starting to learn Clojure rewrote my Clojure 2048 'smoosh' function

0:02 Mine was maybe 10 lines; his was something like 4, and all very clear in that point-free style

0:03 rbrito: :)

0:03 systemfault: what should I be careful about LYAH?

0:04 systemfault: rbrito: Nothing, I liked 95% of it… Just hated its description of type kinds.. and when he just lists a lot of functions for no reasons at the end of some chapters (“here are some monad-related functions”)

0:05 I’m learning… just don’t dump me a list of functions and a 1 line description of them

0:06 rbrito: I see. Makes sense.

0:11 Oh, just a terminology thing: pattern matching in clojure is called "destructuring", right?

0:11 brehaut: rbrito: nope

0:11 rbrito: pattern matching is a much more powerful feature

0:11 akhudek: https://github.com/clojure/core.match

0:12 rbrito: brehaut: I know pattern matching in scala only.

0:12 akhudek: thanks for the link.

0:12 brehaut: pattern matching has conditional behaviour based on a variety of possible structures. pattern matching also does destrructuring.

0:12 but destructuring just assumes the structure matches and pulls it apart

0:13 rbrito: OK, great.

0:15 Do I need to import/require/use something to use match?

0:17 ttasterisco: yes, core.match is its own lib

0:17 and all those 3 words mean different things..

0:18 Shayanjm: actually speaking of - what're clojure best practices with regards to using import/require/use?

0:18 brehaut: rbrito: basically you always want require except for sometimes use in a repl

0:18 import is only for java classes

0:19 rbrito: brehaut: thanks. That's to avoid namespace pollution, right?

0:19 brehaut: right

0:19 and require has :refer to import specific names anyway so it does both

0:21 ,(require '[clojure.set :refer [subset]])

0:21 clojurebot: #<IllegalAccessError java.lang.IllegalAccessError: subset does not exist>

0:22 brehaut: fine

0:22 apparently i cant remember the name of function in the set namespace

0:23 johnwalker: maybe subset?

0:23 ,(require '[clojure.set :refer [subset]])

0:23 clojurebot: #<IllegalAccessError java.lang.IllegalAccessError: subset does not exist>

0:24 johnwalker: ,(require '[clojure.set :refer [subset?]])

0:24 clojurebot: nil

0:24 brehaut: ,subset?

0:24 clojurebot: #<set$subset_QMARK_ clojure.set$subset_QMARK_@300ec4>

0:24 brehaut: johnwalker: thanks

0:25 sir_pinecone: I'm trying to use a var/fn from within a record that implements some Java interfaces, but when I compile to a jar and run the code, I get an unbound exception. here is a gist showing a snippet https://gist.github.com/sir-pinecone/9cde707504df436c45bd ... any ideas how to fix this?

0:26 (i'm a clojure noob :P)

0:26 johnwalker: you're welcome :)

0:42 rbrito: OK, people. Thank you a lot for the help with my newbie-style questions. I feel that I am better after this discussion and I hope to be coming back to this channel soon to tell you of my experiences with the course (and potentially more silly questions). :)

0:43 Thanks for the warm reception, hints and tips. They were appreciated and now I have new books on my queue of functional programming to read. :)

2:00 devn: so, this is basically finished: https://github.com/spinningtopsofdoom/longshi

2:00 commit coming within a couple of days which matches Fressian in features

2:23 sir_pinecone: sleep time..if anyone can help with https://gist.github.com/sir-pinecone/9cde707504df436c45bd it would be awesome if you left a comment on the gist page. thanks!

4:42 swi: Hello. Can i start nrepl serevr without using leiningen to use it with my cider ?

4:46 i-blis: swi: directly with cider-jack-in?

4:48 swi: i-blis: well, i was thinking to run nrepl server manualy and than connect to it with M-x cider specifying host:port

4:49 i-blis: swi: i see, then why would you avoid lein?

4:50 swi: i-blis: cause it start two copy of jvm and eat 17% of my 4G mem :)

4:51 Glenjamin: lein trampoline repl :headless

4:52 swi: Glenjamin: hm.. can i 'ask' cider-jack-in to run like this ? :)

4:52 Glenjamin: no idea, i don't use emacs

4:52 i assume it lets you pick a port, or read .lein.port

4:52 i-blis: swi: oh, are you on os x?

4:53 if so, you should probably export LEIN_JVM_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.awt.headless=true"

4:54 swi: i-blis: i'm on debian

4:55 Glenjamin: yep, this work :) Thanks

5:01 figoe: Hi, trying to compile clojure macros in clojurescript, but the clojure libraries were down loaded... hence i get the error, "aused by: java.io.FileNotFoundException: Could not locate selmer/parse__init.class or selmer/parse.clj on classpath: "

5:01 I have already added selmer dependency, but the target directory is blank, except for stale/extract-native.dependencies

5:02 I meant the clojure (.clj) libs were not being downloaded...

5:06 okay, problem fixed, clj libs doesn't get downloaded for clj to cljs macros

5:07 referenced the wrong lib path

5:56 TerranceWarrior: i'd like to create a headless local server in clojure that talk to other servers using the browser as the interface. what is the smallest number of steps and how for a user to download and install this headless local server?

6:07 Planet_EN: What should I use to connect to SQL Lite?

6:12 ddellacosta: Planet_EN: https://github.com/clojure/java.jdbc

6:12 Planet_EN: I recommend HoneySQL as a DSL on top of it if you need such a thing. I recommend staying away from Korma.

6:46 noidi: Planet_EN, many people seem to like https://github.com/krisajenkins/yesql

7:17 donbonifacio: hello

7:19 we're having a "functional architecture" doubt. Imagina that we have 100 use cases and a function for each one. All function should receive a context (the current user for example). Is there a better way than to have the context on every function's arbument list?

7:19 nathan7: donbonifacio: dynamic vars!

7:20 donbonifacio: (declare ^:dynamic *ctx*)

7:20 donbonifacio: (binding [*ctx* foo] (some-fn))

7:21 donbonifacio: great nathan7 ! thanks, we'll look into it :)

7:22 nathan7: donbonifacio: it means you don't need to pass it on all the time and such

7:22 donbonifacio: and the one use case for it is pretty much 'context'

7:41 hhenkel: Hi all

7:41 I'm trying to use the jolokia client java library described here: http://jolokia.org/reference/html/clients.html#client-java

7:42 I'm able to use J4pClient with new and bind that to "client" with new

7:43 But once I try to do the same with the J4pReadRequest (as described in the example code in the link)

7:43 I get the following error: IllegalArgumentException No matching ctor found for class org.jolokia.client.request.J4pReadRequest clojure.lang.Reflector.invokeConstructor (Reflector.java:183)

7:44 As far as I understand there is no constructer that matches my use case, right?

7:44 Error is produced when I try it like that: (J4pReadRequest. 'java.lang:type=Memory', 'HeapMemoryUsage')

7:46 From the source I see that there is a constructor like this:

7:46 public J4pReadRequest(String pObjectName,String ... pAttribute) throws MalformedObjectNameException {

8:07 Okay, I managed to get it working....for the record, this is needed:

8:07 (new J4pReadRequest "java.lang:type=Memory" (into-array String ["HeapMemoryUsage"]))

8:38 Any hint on how to use the J4pClientBuilder described at http://jolokia.org/reference/html/clients.html#client-java => 8.2.2. J4pClient with Clojure ?

8:45 Okay, looks like this helps: http://stackoverflow.com/questions/8821751/how-do-i-create-a-java-like-object-in-clojure-that-uses-builder-pattern

9:26 TimMc: hhenkel: Yep, that's a good approach.

9:32 luxbock: I'm trying to debug a situation where my Clj/CLJS web-app works fine on my local machine, but when I run it on a EC2 instance the ajax-calls I'm doing on the front end fail with net::CONNECTION_REFUSED

9:32 so the first thing I'm doing is trying to see is how the request looks like

9:33 teslanick: What happens if you curl the ajax call instead of running it from the browser?

9:33 luxbock: it works fine

9:33 I can curl the ec2-instance from my local machine and that works fine too

9:33 https://gist.github.com/luxbock/945c8f116c5e39d63967

9:33 teslanick: Can you confirm that the URLs are identical?

9:34 luxbock: I believe so, I did check for that as well

9:34 teslanick: (especially that they're using the same protocol https/http)

9:34 hhenkel: TimMc: Thanks, that's good to know.

9:35 luxbock: yeah they are

9:36 teslanick: ajax usually passes a set of headers. Could one of those be messing up the request somehow?

9:37 luxbock: yeah that's what I'm trying to see with my `wrap-println` function but it's not working as I thought

9:38 but I'm very new to doing anything web-related so it's possible I'm approaching this the wrong way

9:38 teslanick: It's way easier to debug that kind of thing in your browser developer tools.

9:38 luxbock: but I thought ring-middleware wrappers worked just like that

9:38 teslanick: They have a network tab that lets you inspect requests.

9:39 luxbock: true, I guess I should just test the ajax-request on its own

9:39 right now it's wrapped in a Om component that just keeps repeating the call over and over

9:40 ifesdjeen: hey guys, does anyone know why CojureScript compiler may say that WARNING: No such namespace: goog.string at line 9 file ...

9:40 weird, since i've made basically no changes to my scripts, didn't recompile them for around a week, and now that stuff happens...

9:41 looks like i have some kind of dependency missing but i can't figure out which

10:08 hhenkel: TimMc: Any hint what to provide here when I want to provide multiple request objects (in a list):

10:08 public <R extends J4pResponse<T>,T extends J4pRequest> List<R> execute(List<T> pRequests,Map<J4pQueryParameter,String> pProcessingOptions)

10:10 TimMc: hhenkel: From Clojure's perspective, generics don't exist.

10:10 public List execute(List pRequests, Map pProcessingOptions)

10:12 &(instance? java.util.List [1 2 3]) ;; hhenkel: Vectors implement the List interface

10:12 lazybot: ⇒ true

10:12 hhenkel: TimMc: I tried this: https://www.refheap.com/88045

10:13 But I get an error: J4pRemoteException Bad Request org.jolokia.client.J4pClient.extractJsonResponse (J4pClient.java:225)

10:13 If I try the request one by one, the request seems okay.

10:13 TimMc: Sounds like your syntax is fine, then.

10:15 hhenkel: Hmm...

10:16 I looked in the source and it seems like the http response code is not okay, therefore the exception is thrown.

10:17 Okay, in the server log I see: Malformed request "null". Request parsing failed, Code: -1

10:18 sveri: Hi, is there a way to do a redirect with friend when I try to access a resource that I dont have the rights to access? Currently I only get a string stating: Sorry, you do not have access to this resource. A webpage that I can configure would be nice

10:20 TimMc: hhenkel: By the way, https://www.refheap.com/88046 might be a nicer syntax for constructor and method calls.

10:21 hhenkel: TimMc: Yes, absolutely. I traced what I type I get and it states it is a clojure.lang.PersistentVector

10:22 sveri: nevermind, I finally found it in one of the examples

10:22 hhenkel: Also checked that there are two request objects within....

10:24 TimMc: hhenkel: Well, I don't know the API you're working with, so that part's up to you. :-P

10:25 hhenkel: TimMc: http://jolokia.org/reference/html/clients.html#client-java

10:26 TimMc: I haven't found a javadoc for it therefore I started digging around in the code.

10:26 I just tried my example with only one request in the vector and that also fails.

10:27 If I use my code with one request and without a vector around it, it works

10:28 TimMc: In the link I provided there is this part

10:28 The J4pClient provides various variants of a execute() method, which takes either one single request or a list of requests. For a single request, the preffered HTTP method (GET or POST) can be specified optionally. The List<R> argument can be used type only for a homogenous bulk request, i.e. for multiple requests of the same time. Otherwise an untyped list must be used.

10:29 I guess I'm doing something wrong here... :(

10:32 gfredericks: hhenkel: how does it fail?

10:33 hhenkel: gfredericks: On the server side: <Ma

10:33 lformed request "null". Request parsing failed, Code: -1>

10:33 and after executing my command on the client side I see: J4pRemoteException Bad Request org.jolokia.client.J4pClient.extractJsonResponse (J4pClient.java:225)

10:34 Looking in that code I see that the http response code is the reason for the exception.

10:34 But the question is, why is the request null...

10:35 The easiest implementation I found for the thing I want to do is this:

10:36 https://www.refheap.com/88049

10:37 I decided to paste the complete class...

10:37 TimMc: ^^

10:38 L170 - L183 should be the code that get executed I guess

10:39 mikerod: Why does tools.analyzer.jvm use tools.analyzer v0.2.2-SNAPSHOT when it is currently working at v0.3.1-SNAPSHOT?

10:40 I'd think they'd be closer up-to-date with each other than that

10:40 hhenkel: gfredericks: Any idea what's wrong?

10:43 gfredericks: hhenkel: no, I can't look at it in detail right now, sorry

10:44 hhenkel: gfredericks: okay, thanks anyway.

10:44 Here is the complete code I currently use: https://www.refheap.com/88050

10:45 Only requirement for testing it is a jvm with jolokia running (jetty, tomcat, weblogic, plain jvm)

10:46 User/PW is only required if enabled in the container.

10:50 mbriggs: hey guys, trying to use compojure with spyscope (latest of both), getting java.lang.IllegalAccessError: in-seconds does not exist, compiling:(ring/middleware/cookies.clj:1:1). if I remove spyscope from my profiles.clj, everything is cool. Bit of a clojure noob, not sure how to fix it

10:50 Bronsa: mikerod: I just forgot to bump the dep in project.clj, fixed now

10:50 mikerod: btw project.clj is only there for dev conveniency, it's not actually used for deployment. t.a.j 0.3.0 depends on t.a 0.3.0

10:58 mikerod_: Bronsa: Oh, thanks that's helpful to know

10:58 (I was disconnected)

10:58 I saw your 2 comments concerning the deps though.

11:00 hhenkel: How do I need to call a method that looks like this from clojure? public <R extends J4pResponse<T>,T extends J4pRequest> List<R> execute(List<T> pRequests) throws J4pException {

11:00 Full code is at: https://www.refheap.com/88049 line 180

11:01 I just used wireshark and it looks like the post request is empty when I try something like https://www.refheap.com/88050

11:02 mikerod_: hhenkel: what do you mean how to call it?

11:02 it looks like you are calling it

11:02 hhenkel: mikerod_: I meant "What it the correct way to use it?" as I keep failing with my request on the server.

11:03 Using a different implementation that executes a get request is fine, I get back data.

11:04 But as I want to fetch multiple values I currently fail. So I was wondering what might be wrong.

11:04 mikerod_: I wouldn't think anything is wrong with the way you are calling it from a "how does clj call it standpoint"

11:04 I can't really say if the arguments you are passing are correct or if the rest is set up right, since I don't know what any of this does/is supposed to do

11:08 hhenkel: mikerod_: I updated https://www.refheap.com/88050 with a working example.

11:11 MaxDH: Hi! I'm pretty new to Clojure and using Prismatic Schema and I'm having an issue with schema/explain, I am able to use schema/either where some of the options are hard coded such as: (s/either s/Int "" "NA") and I can validate inputs against this successfully. However if I try to call s/explain on this I get an illegal argument exception (no implementation of explain found for java.lang.String) as some of the options are hard coded. Does anyone know if there is

11:22 TimMc: MaxDH: "either" is weird, one of my coworkers just ran into something with it

11:22 By the way, your message is cut off after "if there is".

11:23 MaxDH: TimMc: Thank you, and the cut off message: Does anyone know if there is a way to still use explain and get around this?

11:23 hhenkel: TimMc: One last question....found some code example (in a test): List resps = j4pClient.execute(Arrays.asList(req1,req2),params);

11:24 TimMc: Do you know what the equivalent for "Arrays.asList" is in clojure?

11:24 rurumate: seq?

11:25 TimMc: hhenkel: THat's just a Java-ism for making a List in-place.

11:25 rurumate: hhenkel: I advise you to experiment in the repl

11:25 hhenkel: rurumate: Thanks for the advice....I'm doing it: https://www.refheap.com/88050

11:25 bbloom: arrdem: 20s slower? how long did it use to take?

11:26 hhenkel: TimMc: So, you're still convinced that using a vector in my case is the thing to do?

11:26 TimMc: Well, I see no reason not to.

11:26 arrdem: bbloom: the existing code successfully loads all of core in ~25s, the patch fails halfway though loading core in ~30+ s

11:27 bbloom: arrdem: crazy. something must be wrong...

11:27 hhenkel: TimMc: hmm, okay thanks.

11:27 rurumate: Any suggestions?

11:28 rurumate: Corresponding code used in the library: https://www.refheap.com/88049

11:28 TimMc: MaxDH: Actually, the thing I'm thinking of may be unrelated. Are you using schema coercion? Apparently Either uses backtracking, so your coercer *may* be given already-coerced output (it needs to be idempotent.)

11:28 arrdem: bbloom: Bronsa was proposing that chunking could be enough of a win that the vector representation is able to do better but we were both pretty shot and didn't play with it.

11:28 bbloom: arrdem: can you look me to the "outer loop" of the code?

11:29 arrdem: and are you using reducers?

11:29 reducers would be much better than chunking for that outer loop

11:29 arrdem: working on the first, neg to the second

11:30 MaxDH: TimMc: I'm not (consciously) using any coercion

11:32 arrdem: bbloom: https://github.com/clojure/tools.emitter.jvm/blob/7b6896dfc42119aebbc34eb5c636c14492402865/src/main/clojure/clojure/tools/emitter/jvm/emit.clj

11:33 TimMc: MaxDH: Probably unrelated, then.

11:33 (I have not used the library myself.)

11:33 arrdem: bbloom: the "outer loop" is mutual recursion between the -emit multimethod, the emit function and the emit-class function. we have to flatten all exit case in emit-class, so we do so, and emit flattens because we were encountering stack overflows in concat if we didn't.

11:34 bbloom: arrdem: *scratches head* i can't really study this at the moment, but i'm sure there's some way to speed it up dramatically :-)

11:35 arrdem: bbloom: heh you and me both. I'll check out reducers, been meaning to for a while anyway.

11:35 MaxDH: TimMc: Ok, thank you anyway for replying and giving it some thought.

12:11 gill_: anyone have experience with digitalocean 1cpu/512mb and running a basic clojure web app?

12:13 arrdem: gill_: I ran the 1st iteration of my blog off of a laptop with equivalent specs for 18 months. it took 100K req/sec like a champ.

12:14 ymmv

12:16 gfredericks: your mileage may be very good

12:17 zilti: Is there a neat way to test core.async stuff with midje? All I came up with so far is a blocking read from a channel, but that's kinda problematic, and embedding a fact inside a go-block breaks core.async

12:17 gfredericks: problematic?

12:18 zilti: gfredericks: Well, if the fact "fails" I have to kill midje and restart it

12:18 gfredericks: you do?

12:19 zilti: gfredericks: Plus it seems that sometimes it just blocks forever even if it shouldn't (or I haven't understood mult/tap)

12:19 gfredericks: you can use a timeout channel

12:32 gill_: arrdem: thanks, good to know

12:33 5$/mo is hard to beat, I want to move off my dev box and use something public

12:39 my concern is that java takes up like 400-600MB ram, at the least

12:42 technomancy: gill_: at heroku the default size is 512MB. it's common for JVM apps to have to bump up to a larger size, but simple clojure apps run fine.

12:42 Frozenlock: Wait, what did I miss? What is $5/mo?

12:42 * Frozenlock tries to get in the conversation

12:42 technomancy: Frozenlock: Taco tuesdays!

12:42 mdeboard: bbatsov is everywhere i look lately

12:42 puppet-mode, clojure-mode

12:43 arrdem: Frozenlock: digitalocean's smallest VM.

12:43 Frozenlock: Tacos, perfect solution to... dev box transitioning.

12:43 mdeboard: i had fish tacos yesterday

12:43 technomancy: heh, he's ... extending the menu-bar entries? okay.

12:44 Frozenlock: Oh, interesting. 5$/mo is pretty sweet indeed.

12:44 gill_: yea i think so

12:44 okay great, I guess I'll spin one up and see how it goes

12:45 `I wonder what they use on the back end for virtualization

13:04 robotblake: gill_: They use KVM, they don't let you boot your own kernels though, you have to use kexec trickery :(

13:05 arrdem: this also means you can't use arch because they have to maintain a fork of the arch kernel package T_T

13:06 gill_: ah okay

13:10 zilti: Am I the only one who finds it a bit paradox that core.async's mult and pub mechanisms are synchronous?

13:12 mdeboard: probably

13:13 TimMc: &(map class (for [i (range 5)] (clojure.set/union #{1 2} (range i)))) ;; ystael

13:13 lazybot: ⇒ (clojure.lang.PersistentHashSet clojure.lang.PersistentHashSet clojure.lang.PersistentHashSet clojure.lang.Cons clojure.lang.Cons)

13:14 * TimMc files this away for the inevitable Obfuscated Clojure Contest

13:14 bbloom: zilti: making concurrency understandable with synchronous operations is kinda half the point

13:16 zilti: bbloom: Yes, but I assumed that mult and sub would work asynchronously, since, you know, it's core.*async*. Instead it synchronously waits until every subscribed channel has read the value before it writes to the next chan

13:17 bbloom: zilti: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L703-L705

13:18 zilti: bbloom: Exactly.

13:18 bbloom: zilti: it's about back pressure

13:18 without that property, you have unbounded buffering

13:18 teslanick: I believe the recommendation is that if you want non-blocking with pub/mult, you should use buffered channels.

13:18 bbloom: right, what teslanick said.... which is also true of all channel operations

13:19 arrdem: TimMc: the winner of the obfuscated clojure contest will write code using only the java standard library and Clojure interop. it'll be amazing. in place updates everywhere.

13:20 teslanick: core.async is basically a set of abstractions to make working with queuing (an asynchronous-by-definition problem) appear synchronous.

13:25 gfredericks: ,(clojure.java.api.Clojure/var "clojure.core/first")

13:25 clojurebot: #'clojure.core/first

13:25 gfredericks: ,(.invoke (clojure.java.api.Clojure/var "clojure.core/first") '(7 8 9))

13:25 clojurebot: 7

13:27 shanemhansen: Without backpressure you have re-invented node.js. poorly.

13:29 There are good arguments that synchronous appearing code is the easiest to reason about. (CSP, etc)

13:44 seangrove: kwargs?

13:45 clojurebot: kwargs |is| are a bad idea.

13:45 clojurebot: Ok.

13:45 seangrove: kwargs?

13:45 clojurebot: kwargs is are a bad idea.

13:45 seangrove: lgtm

13:45 TimMc: clojurebot, forget kwargs |is| are a bad idea.

13:45 clojurebot: I forgot that kwargs is are a bad idea.

13:46 arrdem: kwargs |are| a bad idea should work

13:46 TimMc: clojurebot, kwargs |are| a bad idea.

13:46 clojurebot: Ok.

13:46 TimMc: ~kwargs

13:46 clojurebot: kwargs are a bad idea.

13:46 TimMc: :-)

13:46 Glenjamin: is that the map-last-position type, or the splatted type, or both?

13:46 seangrove: (inc TimMc)

13:46 lazybot: ⇒ 63

13:46 seangrove: Glenjamin: splatted type

13:46 TimMc: clojurebot, clojurebot |accepts| arbitrary verbs

13:46 clojurebot: c'est bon!

13:47 Glenjamin: i wonder who'd win if we took the bots from various language's channels into some sort of irc-bot-off

13:47 * seangrove grumbles that clojurebot should learn self-documenting s-exps

13:48 arrdem: Glenjamin: first you'd have to define a "bot contest"..

13:48 seangrove: ~(learn 'kwargs "kwargs are just a bad idea")

13:48 clojurebot: Gabh mo leithscéal?

13:48 arrdem: I don't think that a contest at maintaining karma is "winnable" :P

13:50 seangrove: proj

13:57 TEttinger: heh, my lazybot fork adds quote grabs from supybot (a commonly requested feature in non-language channels), all sorts of last seen or last message with text functionality, and a few other features I can't remember

14:13 aaelony: Been playing around with reading csv files with read-csv. For some reason, read-csv and reducers map don't play nice together unless there is a final call to into. Any reason why this is? https://www.refheap.com/88058

14:16 bbloom: aaelony: reducers just build up a "recipe" for a reduction, they don't actually do anything until you kick-it-off with something like into

14:16 aaelony: bbloom: many thanks, that makes sense

14:39 shanemhansen: I've been having a *really* good time with clojure for the last few days. First serious use of lisp despite being an emacs user for 10 years.

14:39 </gush>

14:40 puredanger_: aaelony: I recently updated the http://clojure.org/reducers page - if that doesn't help you understand it, would be happy to learn of gaps

14:41 gfredericks: ,(defn unapply [f & args] (f args))

14:41 clojurebot: #'sandbox/unapply

14:41 tjd: I've noticed that a lot of active members of the Clojure community are either consultants or freelancers. Why is that? Is is attraction to the diversity of projects?

14:43 amalloy: gfredericks: you forgot to do the variadic unrolling; how will this version ever make it into core?

14:43 https://www.refheap.com/2b192ca3397c62b5e6aef56f1

14:44 gfredericks: amalloy: thank goodness!

14:44 I exercised variadic-unrolling-vigilance on a jira ticket a month or two ago

14:44 for clojure.core/update

14:45 puredanger_: and we thank you :)

14:45 gfredericks: always stay alert

14:46 that "factor out the unrolling" ticket is probably one of the more fascinating ones I've seen

14:46 arrdem: gfredericks: link?

14:47 gfredericks: man it's an oldy but a goody.

14:47 http://dev.clojure.org/jira/browse/CLJ-731

14:48 man now it's got me thinking about it again

14:49 amalloy: yeah, it's such a hard problem. i remember trying to figure out an approach and giving up

14:50 gfredericks: you'd want it to apply to single-level unrolling as well as double

14:51 amalloy: yeah, juxt and comp are brutal

14:51 gfredericks: it HAS to be general because what if somebody comes around and wants to do three levels but you just wrote the two of them THEN WHAT

14:54 hiredman: obviously it needs core.logic

14:54 amalloy: although really, gfredericks, i don't think you want to be general like that. you want to only handle one-level, but in a way that you can just call this unroller twice for juxt/comp

14:59 verma: how do I check if an object is a javascript null? (nil? x) doesn't seem to catch it

14:59 just null?

14:59 gfredericks: amalloy: let's use core.async and have the unroller send messages with different arities

14:59 verma: null seems to work, but clojurescript while compiling is compalining about undefined "null"

15:00 but yeah, its not really javascript null, because the (= v null) is failing

15:01 technomancy: verma: js/null maybe?

15:02 hiredman: verma: what makes you think nil? isn't working?

15:02 * technomancy <- a guy who has never used cljs

15:02 amalloy: yeah, i think that's exactly what nil? is supposed to do. maybe your object is actually js/undefined

15:03 in which case nil? is correct in returning false

15:03 verma: technomancy, js/null isn't working

15:03 gfredericks: technomancy: what happened to that lofty idea for an entirely in-browser rewrite of leiningen?

15:03 verma: hiredman, I am making sure

15:03 amalloy: technomancy: it's okay, surely with *three* people who've never used cljs we'll figure this one out

15:03 technomancy: gfredericks: gonna give me nightmares

15:03 amalloy: bahaha

15:04 amalloy: $google emperor's nose story

15:04 lazybot: [The Emperor of China's Nose - The Imaginatorium] http://imaginatorium.org/stuff/nose.htm

15:04 verma: hiredman, technomancy, my bad nil? seems to work, sorry

15:06 technomancy: one thing I don't understand about web people is how greasemonkey type stuff isn't standard issue in every browser everywhere

15:07 do people just not want to fix problems in websites they visit?

15:07 I guess there's some primitive user-level stylesheets you can apply

15:07 but the lack of imagination is really boggling

15:08 gfredericks: http://www.marriedtothesea.com/070814/the-land-of-cascading-style-sheets.gif

15:08 shanemhansen: technomancy, I'm confused. firebug and chrome developer tools give you an in-browser repl.

15:08 bbloom: technomancy: i don't particularly want to have to maintain patches for rapidly changing minified code....

15:08 shanemhansen: For scripts both browsers make it pretty easy to make user scripts.

15:09 technomancy: shanemhansen: I've never heard people actually talking about doing this

15:09 bbloom: technomancy: web technologies are just too bad to justify changing complicated crap

15:09 technomancy: I guess part of it is because FF profiles are so broken and automation-resistant

15:10 bbloom: it's like how everybody says "oh, it's open source! you can just add the features you want!"

15:10 but then you need to figure out how to compile that shit, and manage the modified package, and nevermind the fact that the C code looks like it was written by an 8 year old

15:10 technomancy: and people look at me weird when I say I do everything in emacs

15:11 benkay: look weird back at them

15:11 technomancy: bbloom: the tools are all there though. it's just a tragic lack of imagination afaict.

15:11 benkay: this is me, doing that. =)

15:11 benkay: i'm fixing a bunch of lighttable indentation right now

15:12 bbloom: technomancy: "tragic" maybe, but surprising? not at all

15:12 shanemhansen: I agree. The tools are all there. I've occasionally ran scripts that fired when I went to a specific web page. I edited some sort of random user.js or prefs.js in firefox do to that.

15:12 technomancy: like... the key bindings on twitter are terrible; I'm always fav'ing stuff by accident. in emacs, I'd view the twitter-mode-map, and rebind the F key.

15:13 gfredericks: technomancy: why don't you ever fav my stuff by accident

15:13 bbloom: technomancy: i was face palming so hard at the hacker news comments on the mathematica 10 announcement post.... people were like "it's open source, and therefore it is shit" and nobody realizes that they can have a fucking lisp-machine dream for a hundred bucks

15:13 technomancy: gfredericks: I started browsing twitter with js turned off

15:13 gfredericks: also kept me from going beyond one page of history, which was actually a benefit

15:13 gfredericks: hah

15:14 bbloom: technomancy: there's this assumption that because massive creativity and the output of decades of effort exist, that everybody should just go around makign everything more awesome for themselves and everybody else all the time

15:14 but in reality, it's just not that easy

15:14 jephree: :yogthos is there a way to redefine the second curly brace when using selmar e.x. <<var>> instead of {{?

15:14 technomancy: bbloom: there are smalltalk users who are stuck using web browsers today

15:14 jephree: yogthos: is there a way to redefine the second curly brace when using selmar e.x. <<var>> instead of {{?

15:14 bbloom: technomancy: yeah, you can't tell me that those people "lack imagination"

15:14 technomancy: it's just that browsers *fucking suck*

15:14 technomancy: are they just too weighed down with the burden of shame in the entire industry to do anything sensible?

15:14 gfredericks: bbloom: bits don't rot so things can only get not-worse!

15:14 benkay: is there a clojure community standard about excessively long lines?

15:15 i'm trying to compress a lighttable collaborator's work into ~86 cols so that I can use magit without linebreaks

15:15 bbloom: technomancy: C sucks too, which is another part of the problem

15:15 technomancy: benkay: it's not a clojure thing, it's a "decent human being" thing

15:16 benkay: or a "I actually use an editor/wm that lets me see more than one file at a time" thing rather

15:16 benkay: technomancy: see i like this guy and he's actually a bang-up programmer, but he does come from IDE and tab-land

15:17 technomancy: bbloom: so are there fragments of broken dreams littering the landscape?

15:17 is greasemonkey one of them1?

15:17 gfredericks: clojurebot: greasemonkey is one of them1

15:17 bbloom: technomancy: http://userscripts.org:8080/ returns "This website is under heavy load"

15:17 clojurebot: Ack. Ack.

15:18 bbloom: technomancy: the web has just diverted all the creative energy of an entire generation in to a different direction, it will swing around again eventually

15:18 technomancy: bbloom: if you want to fix twitter.com, the easiest way is to move to SF and get a job with twitter?

15:18 Frozenlock: bbloom: isn't the other direction the 'mobile' thingy?

15:19 bbloom: technomancy: argh. terrible, isn't it?

15:19 benkay: here's to the mobile thingy!

15:19 bbloom: technomancy: there was a common internal-mailing-list thing at microsoft that made me aaaaaanngggrrrry.

15:19 technomancy: if somebody gave feedback that a particular team had heard one too many times, or if you just didn't say your feedback quite right...

15:19 technomancy: you'd get somebody replying with a URL: http://careers

15:20 which was the intranet page for internal team transfers, essentially

15:20 * bbloom rage

15:20 technomancy: hehe

15:20 bbloom: benkay: at least mobile is reminding people what software CAN BE LIKE

15:20 technomancy: though on the bright side, html/js UIs means more API-driven applications, which means it's easier to just throw up an elisp version

15:20 bbloom: (ie attractive and smooth)

15:21 Frozenlock: bbloom: walled garden?

15:21 technomancy: bbloom: for a long time I used mobile.twitter.com on my laptop. way faster, no hashbangs.

15:21 bbloom: technomancy: two steps forward, one step back.... grumble grumble http/rest/json/apis

15:21 Frozenlock: doesn't bother me at all that your ios app doesn't work on android, or vice versa. matching the platform look and feel is worth it to me... as a user

15:22 Frozenlock: I can understand that. But I don't like the look and feel of those platform :-p

15:23 bbloom: if apple went out of business tomorrow, and suddenly all ios apps magically stopped working... half the world would take a collective vacation, while the other half the world ported all their apps to android fast enough that by christmas nobody would remember the event ever happened :-P

15:23 technomancy: I think of software these days as being like what it would have been like for literacy if handwriting never existed.

15:24 literacy means everyone can read, but writing is something you need a printing press for

15:24 Frozenlock: Everyone can use software, but only a few can actually code?

15:25 (just to be sure I understand right)

15:25 technomancy: Frozenlock: because you can't just grab a piece of paper and scribble on it

15:25 ivan: https://greasyfork.org/ is the new userscripts

15:25 bbloom: technomancy: i'm not so sure that universal ability to write has produced significantly more/better literature :-P

15:25 technomancy: bbloom: it's not about literature, it's about empowerment

15:25 bbloom: but i get your point

15:25 yeah

15:26 technomancy: bbloom: did you see this? http://www.papert.org/articles/ACritiqueofTechnocentrism.html

15:26 bbloom: technomancy: no

15:26 * bbloom adds to reading list for later

15:27 technomancy: I think professional programmers bring their own biases to the question of code literacy because we're constantly thinking about long-term maintainability, while most people are happy to write throw-away code and are interested in the specific artifacts of its output

15:27 ivan: thanks, I'll take a loot

15:28 look

15:28 bbloom: technomancy: that's certainly true, and one of the reasons i'm interested in language/library designs that encourage experimentation, but scale smoothly, even given naive usage

15:28 ivan: and a word of caution: the thing everyone uses for scripts in Chrome, tampermonkey, is not FOSS

15:29 technomancy: ivan: ah, shitty

15:29 is it fairly divergent from greasemonkey?

15:29 I've ditched chrome anyway

15:29 ivan: it used to be; the author changed it, he might go back

15:29 (FOSS)

15:29 I don't know about divergence

15:29 it should be very close

15:29 technomancy: cool

15:30 now if only I could figure out how to put firefox dotfiles into version control =(

15:30 ivan: "write Firefox profile generator" has been on my todo list for about two years

15:30 technomancy: it's sooooo bad

15:31 the other day I moved my FF profile out of the way to experiment with it

15:31 when I moved it back and relaunched FF, it deleted all my history

15:31 ivan: technomancy: was the old Firefox still running when you moved it?

15:33 I don't think that should happen normally but I have not tested

16:08 TimMc: technomancy: The new versioning scheme makes it even worse -- you can't easily tell when a Firefox (or THunderbird) upgrade will break your profile for downgrades.

16:10 hhenkel: Hi all, I allready wrote this afternoon and I'm still struggling with some issue.

16:10 technomancy: TimMc: it's not bad on debian. =) upgrade -> it's fine, dist-upgrade -> gonna break.

16:10 ivan: I don't think so, but maybe by accident.

16:10 hhenkel: I made an easy to follow setup to check my issue out: https://www.refheap.com/88062

16:11 I would really appreciate if someone could have a look and tell me what is wrong.

16:14 I allready traced with wireshark and all I see is that there is no post request data as far as I can see.

16:15 vijaykiran: hhenkel: I get Unmatched delimiter: ), compiling:(/private/tmp/jolokia-test/jol-test/project.clj:8:23)

16:16 hhenkel: let me try with copy pasting just the code

16:18 hhenkel: vijaykiran: any luck with c&p ?

16:18 vijaykiran: hhenkel: yeah - I'm able to reproduce the same error .. so that's the first step

16:20 hhenkel: vijaykiran: http://www.jolokia.org/reference/html/clients.html#client-java => search for "The J4pClient provides various variants of a"

16:20 For my understanding of the docs, the javadocs and the source I should be able to use a list.

16:21 But maybe I get something completly wrong...

16:21 glitch83: anybody know if I future something and then drop scope (destroying the variable) whether or not the future will complete??

16:21 lazybot: glitch83: What are you, crazy? Of course not!

16:22 glitch83: lazybot: are you real?

16:23 llasram: lazybot: Is glitch83 for real???

16:23 lazybot: llasram: How could that be wrong?

16:24 llasram: glitch83: I don't futures are not canceled if they go out-of-scope

16:24 glitch831: llasram: alright ;-) I don't trust bots is all

16:29 hhenkel: vijaykiran: Any idea what I do wrong?

16:29 boxed: is there any lib to make multiple changes to a bit map easier? I find ->, assoc, dissoc, update-in, etc to become rather clunky when the complexity grows a bit

16:30 big map, not bit map -_-;

16:34 dbasch: boxed: how is a big map different from a small map in that sense?

16:35 boxed: it’s not just {:foo 1 :bar 2 :baz 3} but has nested maps, vectors etc

16:37 so concrete example: http://cljsfiddle.net/fiddle/boxed.foo

16:38 dbasch: boxed: I would use the above functions as primitives to build functions to alter that specific map schema

16:38 boxed: or create a protocol if you want to be more OO

16:42 boxed: that’s what I’m doing, but it seems like I’m writing a lot of the same hard to read and verbose code over and over

16:43 if you reload the fiddle I’ve added an example of the code I have to do the transformation now, and below what I’d like to have in some kind of pseudo code

16:45 aaelony: 13:42 *** glitch83 QUIT Read error: Connection reset by peer

16:45 amalloy: i can understand the code you wrote, but your pseudo-code is a complete mystery to me. even looking at the real code, i can't figure out a scheme that makes the pseudo-code correspond to reality

16:46 boxed: yea, it’s a bit vague in my mind still heh… basically I want to give some path into the map, that’s the vector arguments in my pseudo-code, and then some transformation on that, which is the rest

16:48 update-in is nice and all, but the paths it supports are pretty limited

16:48 amalloy: that's literally update-in. the problem is your "*" variable, which basically corresponds to "magic", and the loose way you hope to deal with arguments. i'd favor the explicit update-in heavily over having to learn a dsl to work with maps

16:48 boxed: I’d like to have wildcards in the path for example

16:48 Raynes: boxed: I think we know each other.

16:49 boxed: raynes: the irclj guy?

16:49 Raynes: Oh right

16:49 You've been complaining about documentation.

16:50 boxed: raynes: well, complaining makes it sound so dirty :P I’ve also written a chat bot and put that code on github so there’s an example for people to look at. I think that’s pretty close to helping more than complaining :P

16:51 Raynes: But it's easier if I just think of you as an angry consumer.

16:51 boxed: amalloy: do you get my drift about the wildcard path handling? like “for all paths into this map that matches ‘foo/*/bar’ do baz”

16:51 raynes: heh, well since I didn’t pay I’m certainly not a customer

16:51 amalloy: yes, but i think that what you want it to do in that case is basically magic

16:52 Raynes: That doesn't seem particularly magical.

16:53 boxed: amalloy: eh? why? just “if the object denoted at * is a non-sequence, throw an exception, otherwise apply the transformation on each item of that sequence”

16:53 Raynes: Anyways, I'd just update-in an update-in at the level where you want to update-in *.

16:53 :D

16:53 boxed: that’s what I have now, but it’s fugly as hell

16:53 stuartsierra: Didn't somebody write an Enlive-like thing that works on arbitrary data structures?

16:53 Raynes: I agree that the wildcard feature would be cool, but I'd definitely rather that not be a supported feature of Clojure's update-in.

16:54 It'd make it significantly more confusing.

16:54 Also, you should try doing any sort of *-in thing in Python.

16:54 You'll be humbled.

16:54 boxed: sure… I’m asking for something else clearly :P

16:54 Raynes: :<

16:56 boxed: stu: can you remember the name?

16:57 Raynes: boxed: If you press 'tab' after typing the first few letters of a nickname, chances are your client will expand it to the full name of that person.

16:57 The usefulness of this is that when you say a person's entire nick, it often pings them so they notice you're responding to them.

16:58 bbloom: boxed: "lenses" may be related to what you're thinking of

16:58 stuartsierra: boxed: no

17:00 boxed: cool, I’ll look into lenses… bbl for more help I’m sure :P thanks guys

17:04 TimMc: technomancy: Unfortunately, that's not true for add-ons. Upgrading icedove breaks compat with Lightning (calendaring add-on) and downgrading doesn't work. I had to restore from a week-old backup.

17:05 hhenkel: vijaykiran: Did you find anything?

17:06 anyone else willing to give it a shot? https://www.refheap.com/88062

17:17 verma: anyone here use vim-clojure-static, I'd like to see how people configure it

17:20 Frozenlock: Raynes: I've been amazed recently by how insanely superior tokumx is to mongoDB. (And it's a drop-in replacement). You might want to take look if you haven't already.

17:21 Raynes: I don't use mongodb because I want to as much as because I used it a long time ago and now it's too hard to change to postgres.

17:22 vijaykiran: hhenkel: did you try the plain Java API ?

17:23 Frozenlock: Raynes: Sure, but for your legacy project it 'might' be worth it.

17:23 Raynes: I don't actually have problems with mongodb for my legacy project though.

17:24 amalloy: yeah, i don't know why Raynes would want to switch

17:24 Frozenlock: disk space would be one reason.

17:25 Raynes: I have enough disk space for about... 15 or so years of growth at the rate refheap gets pastes.

17:25 Frozenlock: But if everything's fine, let it be. No reason to lose time on this.

17:25 Nice!

17:25 amalloy: Raynes: i think you can go infinite. linode gives you free disk faster than refheap uses it up

17:25 vijaykiran: hhenkel: I get the same error using the JavaAPI directly

17:25 Raynes: Indeed.

17:25 technomancy: refheap's gonna hockeystick though

17:26 amalloy: some people would like to hockeystick mongodb

17:26 Raynes: I could clear up a ton of disk space instantly by deleting all the 40k or so bot-created forks when I was dumb enough to use a GET request for forking.

17:26 technomancy: right after it pivots to a mobile latté-tracking app for moms

17:26 Frozenlock: My mongoDB started acting up after ~20gb :-(

17:29 dbasch: Fisher Price should market MongoDB as "My First Database"

17:30 * arrdem used mongoDB as his first database

17:31 Raynes: MongoDB was indeed my first database.

17:31 Hence refheap.

17:31 Absolutely 100% want to move to postgres, just that I don't feel like it and nobody else wants to do it either :P

17:33 amalloy: the thing about postgres is some of the letters are too close together. i typo it as postgers

17:33 it's worth it to use mongodb if i don't have to deal with that

17:33 vijaykiran: hhenkel: when sending multiple requests - I get a 302 back. I'm not familiar with this api - so I guess you should first try the JavaAPI directly to get the behaviout you want

17:33 technomancy: the other annoying thing is that sometimes it's pg, sometimes it's postgres, and sometimes it's postgresql

17:33 amalloy: technomancy: don't forget psql

17:33 technomancy: it's like ... make up your mind

17:34 amalloy: exactly!

17:34 amalloy: i vote we standardize on postgers

17:34 gabnex: what lisp is most functional (as in leaning toward the functional programming side, not bein the least dysfunctional :) )

17:34 is it clojure? sheme?

17:34 +c

17:35 technomancy: gabnex: iirc r5rs scheme doesn't have any data structure mutation functions in the spec

17:35 amalloy: liskell, naturally

17:36 arrdem: technomancy: whaaaa no way.

17:36 * arrdem digs for the r5rs pdf

17:36 technomancy: "most functional" is not a very useful notion since you can just take away non-functional features till there are none left and technically still have a language

17:36 amalloy: technomancy: most functional lisp is lambda calculus

17:36 technomancy: arrdem: setcar! and setcdr! are from an sfri iirc

17:37 you can still mutate bindings though I think

17:37 dnolen_: technomancy: the mutation ops are in the spec far as I can tell - http://www.schemers.org/Documents/Standards/R5RS/r5rs.pdf

17:38 gabnex: Clojure is likely the most functional lisp available today

17:38 technomancy: dnolen_: oh dang, true. they just don't have !

17:38 catern: what about shen

17:38 what now!!!

17:39 arrdem: technomancy: nope. set-car/set-cdr are r5rs standard

17:39 page 26

17:39 technomancy: I am disappoint

17:39 arrdem: I'm not... the traditional lisps are all about car/cdr manipulation

17:40 technomancy: maybe it's mutable strings I'm thinking of

17:40 arrdem: you dare sully scheme by associating it with MACLISP derivatives?

17:40 arrdem: technomancy: yep strings don't have update in place it seems

17:41 * technomancy demands satisfaction

17:42 dnolen_: catern: shen is less batteries includes for functional programming as far as data structures

17:42 s/includes/included

17:42 catern: dnolen_: the less it can interact with the external world, the more functional it is

17:42 so i rest my case

17:42 arrdem: wat

17:45 dnolen_: have you wroked with shen? I looked at it just before I got into Clojure and went with Clojure because of the library support/community

17:46 mikerod: What's the magic behind this: (defrecord MyTest [x] java.lang.Object (bogus/toString [_] (str x)))

17:46 (.toString (->MyTest 2)) := "2"

17:46 It looks like somewhere along the way

17:46 The method name doesn't care about things before "/"

17:46 Bronsa: mikerod: deftype* just ignores the namespace of method names

17:46 mikerod: it's in the compiler

17:46 mikerod: Bronsa: I haven't found where this happens

17:46 I was digging around the compiler

17:46 amalloy: mikerod: the compiler just calls name

17:46 arrdem: mikerod: Symbol/name gets used

17:47 amalloy: or probably not the compiler, but the code in core_deftype

17:47 mikerod: amalloy: ah

17:47 I was trying to find a line that did that

17:47 and failed

17:47 I figured it was a Symbol.name thing

17:47 Bronsa: amalloy: pretty sure it's in the compiler

17:47 mikerod: Is this just by mistake?

17:47 or is there a good reason for it

17:47 amalloy: mikerod: no, it's an important feature!

17:47 Bronsa: mikerod: well, method names can't be namespaced

17:48 mikerod: I noticed we had a bogus macro doing something like `(toString [~'this] <etc>)`

17:48 amalloy: otherwise, macros expanding to defrecord would be hellish to write: `(defrecord Foo [~@xs] Object (toString [this#] "x"))

17:48 mikerod: amalloy: exactly, we have that

17:48 but I feel like that is just wrong

17:48 Bronsa: you'd have to write ~'toString

17:48 amalloy: right. and it should be allowed. the alternative is too horrible to contemplate

17:48 mikerod: To me it is weird that code that you generate is bogus, but it works :P

17:48 amalloy: who says it's bogus? so far just you

17:48 mikerod: bogus/toString

17:49 just gets coerced to toString

17:49 Bronsa: mikerod: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7889

17:49 amalloy: so?

17:49 clojurebot: so is (add-to-list 'erc-keywords '("\\bso\\b" erc-default-face))

17:49 mikerod: but macroexpand shows you the bad code, so it is just misleading

17:49 arrdem: lol clojurebot

17:49 mikerod: amalloy: it has helped us by accident as well. I just think it is a very weird "feature" :D

17:49 Bronsa: ,(foo/.toString []) ;; mikerod

17:49 clojurebot: "[]"

17:49 mikerod: oh...

17:49 I didn't know it went that far

17:49 amalloy: mikerod: a lot of clojure code ignores namespaces in contexts where it can't possibly make sense

17:50 mikerod: I suppose that is fair

17:50 amalloy: and you generate "bogus" code all the time, as Bronsa has just demonstrated

17:50 mikerod: Oh, I didn't see this "dotname.name" piece

17:50 thanks for that Bronsa

17:51 amalloy: mikerod: i wonder: when you write a macro that expands to a use of & destructuring, do you write ~'&?

17:51 mikerod: Ok, so lesson learned. It is acceptable to do `(toString [~'this] <blah>) sort of things

17:51 amalloy: i did that for a while, and then discovered you don't have to

17:51 ,`(foo & bar)

17:51 clojurebot: (sandbox/foo & sandbox/bar)

17:51 Bronsa: amalloy: heh, nobody actually thinks about why that works

17:52 amalloy: Bronsa: it's actually *not* because the compiler calls name on &, thus ignoring the namespace

17:52 Bronsa: I didn't either until I tried to understand why & in the special symbol table

17:52 is in

17:52 mikerod: amalloy: that is different if syntax-quote leaves it alone

17:52 amalloy: oh, is it? that makes sense

17:53 mikerod: sure, but did you know before just now that syntax-quote leaves it alone?

17:53 Bronsa: amalloy: yep ##(special-symbol? '&)

17:53 lazybot: ⇒ true

17:53 mikerod: amalloy: debatable :)

17:53 I never thought to ~'&

17:53 amalloy: `(foo bar/& baz)

17:53 mikerod: but I never tried to look at it either

17:53 amalloy: ,`(foo bar/& baz)

17:53 clojurebot: (sandbox/foo bar/& sandbox/baz)

17:54 mikerod: So, I guess the main take away is the "ignore Symbol.ns when it doesn't make sense" is a feature I can rely on

17:54 for macros like `defrecord` or similar

17:55 I was about to run around fixing macros expanding to this stuff

17:55 amalloy: mikerod: except in binding contexts like let and fn, where symbols' namespaces are illegal on purpose to prevent you making any mistakes

17:55 mikerod: amalloy: yeah, those make sense

17:56 `(defrecord myr [x] Object (toString [_] "hello"))

17:56 ,`(defrecord myr [x] Object (toString [_] "hello"))

17:56 clojurebot: (clojure.core/defrecord sandbox/myr [sandbox/x] java.lang.Object (sandbox/toString [sandbox/_] "hello"))

17:56 mikerod: ,`(defrecord myr [~'x] Object (toString [~'_] "hello"))

17:56 clojurebot: (clojure.core/defrecord sandbox/myr [x] java.lang.Object (sandbox/toString [_] "hello"))

17:57 amalloy: (inc Bronsa)

17:57 lazybot: ⇒ 29

17:57 mikerod: So you still need to ~' the params right?

17:58 amalloy: well, often you probably want to gensym them instead

17:58 i had just assumed there was a special case in ` for & somewhere; it never occurred to me it's counted as a special symbol

18:00 mikerod: I see

18:01 well thanks for the advice on this stuff

18:01 (inc Bronsa)

18:01 lazybot: ⇒ 30

18:01 mikerod: (inc amalloy)

18:01 lazybot: ⇒ 147

18:02 erdos: hello everybody. in data.clj:75 says (extend nil Diff ...) what does (extend nil.. ) form mean?

18:03 Bronsa: erdos: that's how you implement a protocol for nil

18:04 stuartsierra: erdos: It means the methods of the `Diff` protocol will use the implementations in the `extend` when called with `nil` as their first argument.

18:04 erdos: wow great thanks

18:13 dnolen_: arrdem: only toyed around with it, it's conceptually pretty cool, but Clojure seems more useful to me.

18:20 cespare: Is it possible to get at a tag using a macro when the type hint is, say, in a function param or a let? (In the same way the compiler can.) http://pastie.org/9375498

18:24 Bronsa: , (defmacro x [x] (-> &env (find x) first meta :tag))

18:24 clojurebot: #'sandbox/x

18:24 Bronsa: ,(let [^String a ""] (x a))

18:24 clojurebot: java.lang.String

18:24 Bronsa: cespare: ^

18:25 cespare: &env? what is this magic

18:25 lazybot: java.lang.RuntimeException: Unable to resolve symbol: env? in this context

18:25 cespare: heh

18:25 Bronsa: cool, i'll look into that. Thanks

18:26 amalloy: didn't Bronsa suggest &env to you yesterday too?

18:27 cespare: not that i recall

18:27 maybe after i left.

18:28 amalloy: you pointed out that i was hinting the wrong thing, and I thought that solved my problem and moved on to something else.

18:28 * cespare looks at logs.

18:29 Bronsa: I rememebr talking about it with gfredericks a couple of days ago, I don't recall cespare asking for it

18:29 cespare: ah yeah, there was a discussion about env but i had stopped listening

18:29 nobody used my name so i never noticed.

18:31 Bronsa: should I avoid using this for some reason?

18:31 (perusing logs from yesterday)

18:31 Bronsa: cespare: well &env is not really a documented feature AFAIK

18:32 arrdem: Bronsa: I haven't heard of it previously :P

18:32 Bronsa: well along with &form it's an implicit arg passed to macros

18:32 cespare: Bronsa: yeah, exactly what I needed.

18:33 Bronsa: which actually means that while functions can take up to 20 args, macros can take only up to 18 args

18:33 * cespare adds to the body of work that will break if these change.

18:33 amalloy: i also can't think of any very good reasons you would want to know at compile time what type a symbol is tagged as. it seems dubious

18:33 Bronsa: amalloy: dude I'm pretty sure you told me a while ago that you have a macro in useful that uses &env for that reason

18:34 amalloy: haha that's true, isn't it. i didn't write that, though, ninjudd did

18:34 cespare: amalloy: writing macros for record access that throw at compile-time if the thing you pass in is not actually a record or doesn't have that key.

18:34 Bronsa: and not even the keys part of &env, it's using the vals

18:36 amalloy: Bronsa: well, if you use the vals you get the benefit of the compiler's type inference

18:36 (let [^MyObj x (foo), y x] (typeof y)) ; it's nice to get back MyObj

18:37 Bronsa: right but then you're starting to abuse internal details which always make me sad

18:37 amalloy: sure. i wouldn't have written that code, myself, but it's useful

18:39 flatland.useful.datatypes is basically nothing but abuse of internals

18:39 gabnex: how functional is python compared to clojure?

18:39 arrdem: gabnex: arduino supports functional style in spite of Guido

18:40 gabnex: arduino??? :)

18:40 arrdem: sorry installing arguino crap in emacs

18:40 brain in too many places

18:40 Raynes: gabnex: It depends on how you define functional. Python has a lot of what you'd expect from a functional language, but people don't often use those things.

18:40 For example, map, filter, reduce.

18:40 gabnex: arrdem hah aok

18:40 Raynes: I've had use for map exactly once.

18:41 I do Python professionally after using Clojure professionally and still have only used map once.

18:41 gabnex: Raynes I can't define it. the most functional languages I have used are python and C#

18:41 amalloy: python almost has lambdas

18:41 Raynes: Functions are first class though.

18:42 So you can pass along any given function to higher order functions.

18:42 gabnex: do you mean that you use map in python less than in other languages? why?

18:42 Raynes: Like adults.

18:42 technomancy: I would argue that "how functional" is a question that makes more sense to ask of a program than a language.

18:42 Raynes: Because Python doesn't often give me reasons to use functional idioms like that.

18:42 technomancy: "how common are functional programs in $lang" might make more sense

18:42 Raynes: Usually I'd just use for or a list comprehension.

18:42 arrdem: Raynes: abusing list comprehensions is so much fun

18:42 Raynes: 'abusing'

18:43 I prefer to call it gettin' kinky wit it

18:43 gabnex: i don't like list comprehensions much

18:43 Raynes: lol why?

18:43 They are effectively syntactic sugar for map with extra features.

18:43 amalloy: list comprehensions are fantastic

18:43 python's are weird because they have to be one-liners, but they're still nice

18:44 * technomancy snickers at languages with statements

18:44 gabnex: my issues with it are largely cosmetical, it just looks weird. like a for loop read backwards, first the value then the loop. likewise with if statement

18:44 if expression, rather

18:45 r[x for x in [1,2,3,4,5] if x % 2 == 0]

18:46 the order is all whacky

18:46 arrdem: gabnex: sure, but the meaning is obvious in terms of the input value sequence

18:46 Raynes: amalloy: https://www.refheap.com/88071

18:46 bryanmaass: ,(filter even? (range 1 6))

18:46 clojurebot: (2 4)

18:46 bryanmaass: sorry, I had to

18:47 amalloy: Bronsa: is there a reason that `(fn [~@(repeatedly 30 gensym)] 1) fails to compile, rather than just emitting a RestFn that checks that its arg count is exactly 30?

18:47 gabnex: that is a valid clojure? nice

18:47 it looks like python's filter

18:47 Raynes: gabnex: God no

18:47 gabnex: what?

18:47 clojurebot: what is not a bug

18:47 Raynes: Oh, referring to the filter example.

18:47 gabnex: yes

18:47 Raynes: Okay, we're on the same page.

18:47 amalloy: clojurebot: many things |are| not bugs

18:47 clojurebot: In Ordnung

18:47 Raynes: Thought you were talking about my paste.

18:48 gabnex: I wasn't. I clicked it now

18:49 what would be the clojure equivalent of that?

18:50 Bronsa: amalloy: I believe it would be quite hard to manage multiple arities with 20+ args that way

18:50 amalloy: (string/join ",\n" (for [[name redshift-type] (columns table overrides nulls)] (str name " " redshift-type))), although there may be something a bit more clever

18:50 Raynes: (clojure.string/join ",\n" (for [[name, redshift_type] (columns table overrides nulls)))

18:50 Bronsa: amalloy: also it would probably mess with recur

18:50 Raynes: I gave up

18:50 Just closed my parens and went home.

18:50 amalloy struck me down

18:50 arrdem: Bronsa: really? I thought that at 19 the compiler silently switched to varargs destructuring.

18:50 amalloy: (string/join ",\n" (map (partial string/join " ") (columns table overrides nulls)))

18:51 arrdem: or at least that's what I would expect.

18:51 * Raynes ponders

18:53 Bronsa: amalloy: not saying it can't be done but that would require possibily collapsing multiple fn-methods into a single one, which is not something the compiler does right now

18:54 I can try prototyping that with t.e.j, shouldn't be hard

18:54 amalloy: nah, it doesn't seem like a compelling feature

18:55 Raynes: amalloy: ',\n'.join(map(' '.join, self.columns(table, overrides, nulls)))

18:55 pwnt

18:55 Jesus, amalloy is making my code better using an entirely different language.

18:55 Bronsa: amalloy: yeah recur would be broken, it currently doesn't handle varargs

18:56 ,(fn [& b] (recur 1 2))

18:56 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:(NO_SOURCE_PATH:0:0)>

18:56 Bronsa: this could probably be considered a bug I guess

18:57 technomancy: I've run into that. it's pretty annoying

18:57 arrdem: I'd call that a bug...

18:57 technomancy: supposedly it's by design iirc

18:57 arrdem: or at least an obvious failure

18:58 Bronsa: technomancy: seems weird that'd be by design

18:58 technomancy: I agree

18:58 amalloy: well, how else is it going to work? you want to write (apply recur (rest xs))?

18:59 Bronsa: amalloy: the compiler can put xs in seq for recur args just like it does for function calls

18:59 hiredman: amalloy: well, given that you can call the function with (f 1 2), should you be able to recur inside the function with (recur 1 2)

18:59 arrdem: amalloy: recur isn't a fn and can't be applied. it's a special form and its arity is statically known, so you can do what Bronsa just said.

19:00 Bronsa: amalloy: I mean right now you need to do (fn [& x] (recur (list 1 2))) but the compiler could do that automatically

19:01 amalloy: Bronsa: my point is, consider (defn last-arg ([x] x) ([x & xs] (if (empty? xs) x (recur ...????)))). what do you fill in the blank there with, if the compiler automatically wraps things up in a list for you?

19:02 you need another special form like apply-recur to define this function, if that's how varargs work

19:02 technomancy: amalloy: iirc you can't recur across bodies

19:03 amalloy: technomancy: of course not. my definition doesn't require you to

19:03 the ([x] x) case is just so that it still works for one-arg calls; mabye it's clearer if i leave it out entirely

19:03 technomancy: right

19:03 Bronsa: amalloy: ah, I see

19:04 technomancy: I agree you'd need apply-recur

19:04 it would make a lot more sense than what we have now

19:04 amalloy: technomancy: meh. if you had apply-recur, then every variadic function would need to use it; needing to recur and *not* apply it is super rare

19:05 except in constructed examples to show how confusing recur is

19:05 Bronsa: technomancy: that's debatable, with amalloy's example in mind I can understand the decision to make recur varargs ignorant

19:05 technomancy: I don't see anything wrong with that

19:07 amalloy: technomancy: recur is only confusing if you view it as "call this function again with these args" instead of as "go back to the recur anchor-point and bind the named variables to this, this, and that"

19:07 technomancy: I'd rather have two forms for different things than one form that you can usually treat as a self-call, except for certain cases

19:07 amalloy: which is exactly how everyone sees it, until they run into this weird quirk

19:08 that's what recursion means in every other language

19:08 Bronsa: anybody knows the rationale for not optimizing self tail calls to recurs btw?

19:08 amalloy: Bronsa: so that if you accidentally make a non-tail call it's obvious (ie, fails to compile)

19:09 if self-calls silently upgrade into recur, then you'll write a function that depends on this behavior, and then change it subtly so that it doesn't upgrade anymore, and never notice the difference

19:10 technomancy: [x] more compile-time correctness checking than scala

19:10 wait did I say that out loud

19:10 Bronsa: the solution is easy: add the optimization without telling anybody

19:10 amalloy: hah. you know #clojure would notice it inside of a week

19:11 Bronsa: bonus points if the change makes in through a totally unrelated commit

19:11 something that Rich does all the time

19:11 amalloy: and then it'd become a feature as well-documented as "(zipmap (keys m) (vals m)) is guaranteed to work in the way you expect"

19:11 Bronsa: heh

19:11 technomancy: meaning core team members would contradict it publicly?

19:13 Bronsa: the one comment that probably bothered me more than Stu's on zipmap, is Rich saying that definlines should not work as HOFs

19:13 amalloy: technomancy: send yourself a thatsthejoke.jpg from me

19:13 technomancy: oh, dang

19:14 hiredman: Bronsa: subtilty tends to get lost online, could he have meant just the inline part of definlines?

19:14 cause otherwise...

19:14 Bronsa: hiredman: I'm pretty sure Rich actually meant "you can't use them as functions"

19:15 hiredman: but, like, +

19:15 amalloy: Bronsa: do you have a link? i only vaguely remember this

19:15 Bronsa: hiredman: that uses {:inline ..} not definilne

19:15 amalloy: one sec

19:15 hiredman: Bronsa: yeah, those are totally different

19:15 (that was sarcasm)

19:16 Bronsa: http://dev.clojure.org/jira/browse/CLJ-1227?focusedCommentId=33522&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-33522

19:16 Raynes: I was incredibly sad to find that core folks were uninterested in a polymorphic range function.

19:16 Bronsa: well, it was actually Alex speaking for Rich

19:16 hiredman: yeah, I feel like something is lost there

19:17 Bronsa: hiredman: amalloy I find it pretty ridiculous that Alex/Rich would say that when reading through the implementation it's clear that they're supposed to behave as functions

19:18 hiredman: Bronsa: well, but there is no real way in clojure to say "this function isn't for higher order use" or something

19:18 Bronsa: where as, in a lisp-2 like common lisp that is sort of the default stance

19:18 (common lisp being mentioned in the ticket)

19:19 amalloy: hiredman: i don't get that, though - isn't a function that is only intended for inline use just a macro that evaluates each arg exactly once?

19:19 hiredman: so e.g. you want the compiler to try to optimize the expansion, and if it fails, you have a function in place to be used, but you don't want people to run around HOFing it up

19:19 Bronsa: also I'm pretty sure there's an example of a definline used as HOF in one of Stu's books, can't recall which Stu though

19:20 hiredman: amalloy: if you look at common lisp's compiler macros or whatever, they can sort of decline being expanded

19:20 amalloy: hiredman: by returning &form?

19:21 hiredman: amalloy: so you could write something that, as a clojure example, looks for certain type hints, and expands if they are there, and otherwise doesn't and turns in to a function call

19:21 amalloy: I guess

19:21 amalloy: hiredman: sure. and that's a nice use of compiler macros. but what's the harm in also allowing it to be passed as a HOF?

19:21 hiredman: I don't know what the huge difference is, my initial reading about common lisp compiler macros, it seems like definline could do all that

19:21 amalloy: dunno

19:21 Bronsa: that's funny

19:22 definilnes used to have a bug where they could work as HOFs but not in call position

19:22 https://groups.google.com/d/msg/clojure/iAt_DDUt6ZA/6RtFapvJugUJ

19:22 hiredman: http://dev.clojure.org/display/design/Inlined+code cgrand and I are the only ones to drop comments

19:23 amalloy: i think clojure's {:inline ...} is basically equivalent to CL's compiler macros. i don't know of anything one can do that the other can't

19:23 hiredman: right, so what is rich going on about

19:24 heh

19:24 " (map square xs) would still need to be compiled as a function invocation.

19:24 "

19:25 Bronsa: and that's exactly how definline currently works, as implemented

19:26 the bug preventing it to work was related to AOT compilation, had nothing to do with definline itself

19:26 hiredman: except for the compiler bug, which arguably has nothing to do with definline

19:26 right

19:26 stupid aot

19:26 amalloy: Bronsa: i think the joke was that alex miller wrote that wiki page, and in the jira article he was saying the opposite

19:26 did the aot issue get fixed for 1.6?

19:26 Bronsa: nope

19:27 amalloy: gross

19:28 Shayanjm: amalloy: so I'm running into some issues with my NLP program. I may be attempting to analyze too much data at a time. I can either throw things into some sort of queue/handle them sync, or scale the computationally intensive tasks horizontally

19:28 amalloy: Bronsa, hiredman: another case of https://twitter.com/hiredman_/status/446003708015304704

19:28 Shayanjm: The issue specifically is that I have some 30 articles coming in, and I'm attempting to do sentiment analysis + keyword extraction on the whole scraped article contents in parallel

19:29 have I missed a more obvious solution/design pattern in clj?

19:29 hiredman: huh

19:29 Bronsa: TBH I really don't see how clojure/core can be so dismissive wrt AOT bugs given that both clojure and Datomic are AOT compiled

19:31 amalloy: Bronsa: don't forget, if you want your app to have a -main, you AOT compile everything under the sun. but at least this only impacts people who want to run clojure programs, which surely is a tiny subset of clojure programmers...

19:31 technomancy: cider is my shell; I don't know what your problem is

19:32 hiredman: cider is 99 problems

19:32 but aot may aslo be one

19:32 also

19:32 Bronsa: I actually used clojure today to batch rename a bunch of files because I can't into bash

19:32 (inc amalloy)

19:32 lazybot: ⇒ 148

19:33 catern: you don't need bash for that

19:33 use rename

19:33 man rename

19:33 (assuming your batch rename was simple...)

19:33 technomancy: just use emacs

19:33 Bronsa: I had to rename foo_bar_baz to "Foo Bar Baz"

19:33 technomancy: wdired-mode, M-x replace-regexp, save

19:34 catern: ew

19:34 Bronsa: tried using zmv which I think is similar to rename

19:34 catern: why would you do that?

19:34 that's the exact opposite direction that you should go

19:34 adding white space and capitals

19:34 yuck!

19:34 Bronsa: technomancy: I contemplated doing that. next time.

19:35 catern: dude I want my mp3 file names to look nice

19:35 also it's 2014 and I can afford spaces in file names

19:35 catern: Bronsa: let your MP3 player show the names in the ID3 tags

19:35 and your file manager too

19:35 amalloy: Bronsa: nice to meet another fan of the Metasyntactic Variables. Foo Bar Baz is my favorite song on their newest album

19:36 catern: (oh, you don't have a file manager that's scriptable enough to do that? yeah, neither do I ;_;)

19:37 Bronsa: catern: yes, I use id3 tags but it still bothers me when my files aren't named in The Right Way™

19:37 catern: Bronsa: spaces is The Wrong Way

19:45 justin_smith: catern: that idiom ("the wrong way") always bugged me, there are always more wrong ways than right ways. For example, make the filename be the bytes of the mp3 data, and the file contents be the name. That is clearly wrongerer

19:46 technomancy: every happy mp3 is the same, and all unhappy mp3s are different in their own way.

19:46 tolstoy said so

19:47 justin_smith: heh

19:47 catern: justin_smith: does the file contents have spaces?

19:48 {blake}: heh

19:48 justin_smith: no, they are replaced by NULL bytes

19:49 hiredman: NULL bytes are replaced by 0x2a and so on in that fashion

20:00 Shayanjm: so when processing large sets of data

20:00 is it better to run things in parallel or in series if I'm concerned about memory usage?

20:01 (i.e: how much 'worse' is running it in parallel? any optimization magic that happens in the back?)

20:08 gabnex: ah, clojure has list comprehensions too

20:08 when do you use them over map/filter?

20:09 i kind of hated them in python, as I said earlier

20:09 justin_smith: gabnex: for tends to be more readable than nested map calls

20:09 technomancy: gabnex: the filtering in c.c/for is clearer IMO than in python

20:09 since it's almost always on its own line

20:10 gabnex: (they looked weird/backwards in python, and also leaked variable names).

20:10 technomancy yeah they do look cleaner. I think I will still like filter/map more

20:11 technomancy: usually I filter/map if you have a readymade function that works and use for if I'd have to construct a lambda

20:11 justin_smith: gabnex: if your mapping function is also your predicate (maybe returning nil for unwanted elements, and the transformed version otherwise), keep is handy

20:11 gabnex: techno even with nifty % syntax to shorten lambdas?

20:11 justin_smith: (doc keep)

20:11 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."

20:12 technomancy: gabnex: yeah

20:13 Bronsa: I hate that keep doesn't have a 1-arity with f defaulting to identity

20:13 justin_smith: Bronsa: yeah, I bet that would be the most common usage if it existed

20:13 Frozenlock: Bronsa: I would use that.

20:14 technomancy: there's a jira for that!

20:14 TM

20:14 justin_smith:

20:14 technomancy: actually I think the jira issue is for a similar function; it's been around so long it predates keep

20:14 Bronsa: might be for filter?

20:14 amalloy: Bronsa: why would you put that on keep? i'd put it on filter

20:14 technomancy: sounds right

20:15 amalloy: amusingly, (remove xs) and (filter xs) would kinda have to do the same thing

20:15 Frozenlock: (filter [1 nil 0]) --> (1 0)... ohhh now I want that

20:15 Bronsa: amalloy: I mean, keep identity and filter identity behave the same way, keep is 2chars shorter

20:15 amalloy: maybe that's why it doesn't exist

20:16 Bronsa: *almost* the same way

20:16 &((juxt keep filter) identity [1 nil 2 false 3])

20:16 lazybot: ⇒ [(1 2 false 3) (1 2 3)]

20:16 Bronsa: oh, right

20:17 justin_smith: amalloy: perhaps (remove xs) could simple return all nil items in the input, discarding the non-nil

20:17 gabnex: can I mutate a list in clojure?

20:17 justin_smith: which is of course pretty much useless

20:17 amalloy: gabnex: no

20:18 technomancy: and even if you could, you wouldn't

20:18 gabnex: I probably would :).

20:19 technomancy: "For the same reason we don't wear animal skins or hunt the woolly mammoth. Because we're not savages."

20:19 http://www.penny-arcade.com/comic/2005/06/06/

20:21 justin_smith: gabnex: probably the greatest boon in clojure is the wide range of errors that become impossible with mutation (this especially comes into play when you have multiple threads). it's harder to think in immutible objects at first, but it is worth it

20:21 *impossible without mutation, that is

20:25 gabnex: justin_smith it is probably my ignorance but I don't understand how lack of mutation helps when having multiple threads. if a value is immutable we must take it and return a new one. if two threads do this at the same time, one thread could be working on the old, dated value, and not on the current one. so don't we still have issues, only in a different way?

20:25 justin_smith: gabnex: the class of errors avoided are partial updates

20:26 that is, where something is read in the middle of an update, and the contents are invalid

20:26 gabnex: but we introduce another class of errors, working on a dated value

20:26 technomancy: gabnex: that kind of mistake is trivial to catch because it's deterministic

20:26 justin_smith: gabnex: one of these is tractable, the other just leads to reading garbage

20:27 gabnex: how do you prevent this? locks?

20:27 justin_smith: gabnex: that is the mutation oriented solution

20:27 technomancy: gabnex: you just don't do it because it doesn't make sense

20:27 justin_smith: and that leads to deadlocks, livelocks, etc. - errors that pretty much never happen in live clojure code, because we don't ever use locks

20:27 gabnex: don't do what

20:27 justin_smith: (don't use them directly that is)

20:28 gabnex: I recommend the book "Java Concurrency in Practice"

20:28 it gives a really good overview of why locks are tricky, and whenever possible, immutability is easier and less error prone

20:28 clojure simply increases the range of domains where immutability becomes reasonable

20:29 technomancy: gabnex: the mistake you're describing is just that of thinking imperatively in an fp language. it's not something that you do when you know how clojure works.

20:31 gfredericks: gabnex: if you're using an atom, then swap! will ensure that if you are working on a dated value, you end up redoing your computation on the current value

20:31 if you're using an agent, then the updates are guaranteed to be serialized

20:31 two different ways of solving the problem depending on your needs

20:32 gabnex: gfredericks interesting. is immutability a requirement for those techniques to work, though?

20:32 gfredericks: certainly for atoms

20:32 because you will have multiple threads processing the same value

20:33 justin_smith: gabnex: remember that in clojure we can simplify questions of identity and state, and both of those approaches come from clojure's simplified view of identity and state

20:33 which is of course rooted in immutability

20:33 gfredericks: and in both cases the current value can be read by any other thread without locking, so you wouldn't want it to be stateful

20:36 justin_smith: also, the mutable java collections are all easily accessible from clojure via interop. It's just that outside of specialized applications we don't really find them that useful given the persistent alternatives.

20:37 gabnex: do we only have mutable collections from java? clojure does not introduce any new ones?

20:37 justin_smith: well, you can introduce a deftype with mutable fields for example

20:38 but java has a very rich and complete set of data structures

20:38 so in practice you won't find much missing, if you are OK with the mutation aspect

20:39 trees, lists, vectors, sets and maps of all sorts, queues, deques, etc. etc.

20:39 amalloy: but justin_smith, what if i want a mutable finger tree? i bet java doesn't have *those*

20:40 justin_smith: amalloy: I am sure some brilliant clojure programmer would set you up with something nice for that

20:40 amalloy: (answer: if i want that, i am probably a madman, beyond science's reach to rescue)

20:40 justin_smith: or that

20:47 gfredericks: A -> (B -> A)

20:49 amalloy: gfredericks: what what?

20:51 gfredericks: A = "I am probably a madman, beyond science's reach to rescue"

20:51 B = "If I want that"

20:52 my apologies I had a conversation with a logician yesterday and so apparently this is what happens to my jokes

20:52 justin_smith: lol

20:53 amalloy: gfredericks: must not have been a very good conversation - you seem to be concluding causation based on this correlation

20:55 gfredericks: come on what is causation anyhow

20:55 also I don't think my statement literally said anything about causation

20:56 amalloy: i think "and so" is correlated quite strongly with implying causation

20:56 justin_smith: in all fairness, it could have been a claim about how things are considered "apperent", natural language is nicely ambiguous that way

20:57 *apparent

20:57 gfredericks: I'm a parent

20:58 (my apologies I had a conversation with amalloy today and so apparently this is what happens to my jokes)

20:58 justin_smith: (inc gfredericks)

20:58 lazybot: ⇒ 75

22:20 hiredman: hmmmm

22:20 test.check's defspec prints stuff out to stdout on success

22:20 seems terrible

22:24 catern: https://news.ycombinator.com/item?id=8017588

22:24 god this is awful

22:24 https://github.com/eobrain/funcgo

22:24 whyyy

22:24 so awful

22:25 justin_smith: eta for the "fuckgo" offshoot?

22:25 which of course has an obvious crossover with "self"

22:56 puredanger_: amalloy: sometimes I am a flawed translator for Rich :)

23:29 noprompt: seems kinda silly that (keyword 'foo) works but (symbol :foo) doesn't :/

23:39 trptcolin: noprompt: hmm, yeah i don’t see any reason why keyword & symbol shouldn’t offer the same conversions

23:39 there’s other fun too:

23:39 ,:123

23:39 clojurebot: :123

23:39 trptcolin: ,(keyword 123)

23:39 clojurebot: nil

23:50 noprompt: trptcolin: ha! i hadn't discovered that one yet. any reasons why this has/hasn't been patched?

23:51 trptcolin: not sure if there’s a jira ticket for that or not

23:52 dbasch: trptcolin: I think it's intended behavior

23:52 or at least it's properly documented

23:52 (keyword name): name can be string, symbol, or keyword.

23:53 symbols cannot start with numbers

23:54 noprompt: dbasch: i can perhaps understand (keyword 123) not working, however the former case i mentioned seems a bit weird.

23:54 because you seldom want keyword -> integer.

23:55 trptcolin: dbasch: yeah, i mean i agree, but attempting to match the docs on the numeric-keyword thing breaks existing code, so it’s not happening anytime soon (see http://dev.clojure.org/jira/browse/CLJ-1252)

23:55 noprompt: the error message you get from (symbol :foo) is also not helpful either.

23:55 ClassCastException clojure.lang.Keyword cannot be cast to java.lang.String clojure.core/symbol (core.clj:546)

23:56 dbasch: yes, that's par for the course for core

23:57 trptcolin: right, i mean it seems to me that (source keyword) vs. (source symbol) ought to be symmetric with each other, since they’re so close now and it shouldn’t break anybody (nobody should depend on that CCE)

23:57 i’d vote up a jira for it

23:57 noprompt: trptcolin: is there an open issue?

23:58 sorry, interleaving some work atm

23:58 trptcolin: i don’t think so

23:58 puredanger_: I don't know of one

23:58 noprompt: puredanger_: what are your thoughts?

23:59 puredanger_: all sounds reasonable to me.

Logging service provided by n01se.net