#clojure log - Mar 29 2015

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

13:43 danlentz: I'm self taught, so I'm quite aware of what a prick I can be as a teacher.

13:46 Also as a student. Hmmm.

13:46 justin_smith: danlentz: realizing I can be a jerk has been a repeated theme as I grow older, it comes back in so many nuanced varieties.

13:48 gfredericks: it culminates at your death bed when you realized you never actually succeeded at not being a jerk at all ever not even once

13:48 justin_smith: haha

13:48 danlentz: In that final realization, you attain humanity

13:49 Wait, wasn't that what happend to Spock?

13:56 joe124: http://pastebin.com/dECUn04R why is this not tail position?

13:57 brb

13:57 mavbozo: parens solve everything?

13:57 justin_smith: joe124: (( means you are calling something, then calling what it returns

13:58 joe124: ok i removed extra parens around the if statement?

13:58 justin_smith: joe124: it's not tail position, because your code wants to call it

13:58 now you'll likely see an error with (result ...) because result is a collection

13:59 well, depending on the arg, I guess the arg could be a number, then you just get a nil...

13:59 joe124: i have an out of bounds exception

13:59 justin_smith: what do you intend (result(last coll)) to do?

14:00 joe124: i want to append the last element of coll to result

14:00 justin_smith: joe124: how would clojure know you wanted that, and not calling result as a function?

14:00 because that syntax means a function call, right?

14:00 joe124: well earlier result was defined as []

14:00 and [] is a function

14:01 justin_smith: yes, but it doesn't do what you want

14:01 joe124: should i use conj or something

14:01 justin_smith: ,([] 3 :out-of-bounds)

14:01 clojurebot: #error{:cause "Wrong number of args (2) passed to: PersistentVector", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: PersistentVector", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compi...

14:01 justin_smith: oops

14:01 danlentz: (foo ) invokes a function foo

14:01 justin_smith: ,([] 3)

14:01 clojurebot: #error{:cause nil, :via [{:type java.lang.IndexOutOfBoundsException, :message nil, :at [clojure.lang.PersistentVector arrayFor "PersistentVector.java" 152]}], :trace [[clojure.lang.PersistentVector arrayFor "PersistentVector.java" 152] [clojure.lang.PersistentVector nth "PersistentVector.java" 156] [clojure.lang.APersistentVector invoke "APersistentVector.java" 283] [sandbox$eval49 invoke "NO_SOUR...

14:01 justin_smith: so that's your error

14:01 joe124: yes

14:02 justin_smith: joe124: so yeah, ##(conj [] 3) is likely what you want

14:02 lazybot: ⇒ [3]

14:03 danlentz: It would be funnier if somehow the Chinese could launch an attack on Gravatar and give us embarrassing icons

14:03 joe124: ok cool it worked, but i had defined result as []. So why does it work when the input is a list?

14:04 justin_smith: joe124: can you rephrase that?

14:04 joe124: https://www.4clojure.com/problem/23#prob-title

14:04 justin_smith: do you mean, how can it take things out of a list and put them in a vector?

14:05 joe124: (= '(1 2 3) [1 2 3]) ?

14:05 justin_smith: ,(= '(1 2 3) [1 2 3])

14:05 clojurebot: true

14:05 joe124: ok well that solves that haha

14:05 gratimax: when checking for equality, you don't care about the type of the sequence

14:05 justin_smith: joe124: my favorite definition for reverse is (partial into ())

14:05 joe124: but that is way over your head for now

14:06 joe124: ok let me look up partial and into then maybe u explain it to me?

14:06 justin_smith: joe124: sure, feel free to ask any follow up you need

14:08 danlentz: ,((partial into ()) (range 8))

14:08 clojurebot: (7 6 5 4 3 ...)

14:08 justin_smith: danlentz: of course as a literal you can just do ##(into () (range 10000))

14:08 lazybot: ⇒ (9999 9998 9997 9996 9995 9994 9993 9992 9991 9990 9989 9988 9987 9986 9985 9984 9983 9982 9981 9980 9979 9978 9977 9976 9975 9974 9973 9972 9971 9970 9969 9968 9967 9966 9965 9964 9963 9962 9961 9960 9959 9958 9957 9956 9955 9954 9953 9952 9951 9950 9949 9948 9947 9... https://www.refheap.com/99036

14:09 ggherdov: Hello. I googled "rest api clojure" and got to https://mmcgrana.github.io/2010/08/clojure-rest-api.html (the post is from 2010)

14:09 question: in the toy example the author wraps the data he's exposing over the API in an atom.

14:09 Is that because he wants to prevent concurrent http requests to have inconsistent views of the data? Is that what one would do in a "real world app" as well, where the data comes from a db?

14:09 tahmid: When’s a good time to learn macros ?

14:10 justin_smith: ggherdov: I think the atom is just for representing a state that PUT etc. can manipulate

14:10 swarthy: ggherdov: He likely did it because he wanted a mutable piece of data that he could add to by hitting the rest API.

14:10 danlentz: tahmid: we call that macroexpansion time

14:10 swarthy: ggherdov: in production you would just update/read from your DB

14:10 tahmid: LOL

14:10 ggherdov: justin_smith: swarthy: ah right

14:11 danlentz: You should be really comfortable using functions

14:11 justin_smith: ggherdov: but, bigger picture, in clojure we almost always put something that we expect to mutate in runtim inside an atom, or ref, or agent, because they have good behavior when interacting with updates from multiple threads

14:11 ggherdov: justin_smith: ok

14:11 tahmid: I am really comfortable using funcions

14:11 justin_smith: so in that sense you are right, we could have used a mutable java data structure or class instead, but it would not likely be as well behaved

14:12 tahmid: I'd use macros when you have the functionality dialed in, but usage is clumsy and could be fixed if you could modify syntax

14:12 tahmid: I mean when should one try to solve something with macro ?

14:12 danlentz: The best way to approach macros is to look at examples and build up practice examples

14:12 justin_smith: tahmid: for example not needing to quote an arg, or just specifying optional forms instead of functions to call as args

14:12 tahmid: justing_smith: Okay, got my ans

14:12 danlentz: When it cannot be done with a function

14:13 joe124: ,((partial into ()) '(1 2 3))

14:13 clojurebot: (3 2 1)

14:13 tahmid: Cool

14:14 mavbozo: ,into

14:14 clojurebot: #object[clojure.core$into "clojure.core$into@2f18c986"]

14:14 mavbozo: ,(doc into)

14:14 clojurebot: "([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied."

14:14 joe124: ,((into ()) '(1 2 3))

14:14 clojurebot: #error{:cause "Wrong number of args (1) passed to: core/into", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (1) passed to: core/into", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 32] [sandbox$eval93 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784...

14:14 danlentz: When you are in some way looking to change the normal syntax of clojure

14:14 joe124: ,(into () '(1 2 3))

14:14 clojurebot: (3 2 1)

14:14 joe124: ,(into () [1 2 3])

14:14 clojurebot: (3 2 1)

14:14 oddcully: ,(doc conj) ?

14:14 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

14:15 justin_smith: ,(into '(1 2) 3) ; joe124

14:15 clojurebot: #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.core$seq__4079 invoke "core.clj" 135] [clojure.core.protocols$seq_reduce invoke ...

14:15 justin_smith: oops, I mean ##(into '(1 2) [3])

14:15 lazybot: ⇒ (3 1 2)

14:16 joe124: since lists and stuff are immutable does into do the exact same thing as reverse

14:16 mavbozo: ,((partial into []) '(1 2 3))

14:16 clojurebot: [1 2 3]

14:16 danlentz: Macros (generally) operate programmatically on the source code of your program, rather than directly contributing to computing the result

14:16 tahmid: that’s why I am scared of macros

14:16 joe124: if you write your macro wrong it will delete your program

14:17 justin_smith: joe124: the implementation is not exactly the same, but the behavior is

14:17 joe124: and auto save over it

14:17 danlentz: Delete your program?

14:17 tahmid: I read in somewhere that I should always prioritize data over functions over macros

14:18 mavbozo: i am still scared of macros

14:18 justin_smith: joe124: do you know about clojure.repl/source ? if you look at the source of reverse, and the source of into, you should be able to see that (partial into ()) and reverse are very close to being identical when you go down a couple layers

14:18 tahmid: that is solid advice

14:18 mavbozo: that's healthy

14:19 tahmid: I understand the function part

14:19 But how can data > function

14:19 danlentz: Macros are really nice in clojure

14:19 justin_smith: tahmid: there are a lot of things we can do with data, that we can't do to functions

14:19 tahmid: I mean datas are just data

14:19 example pls

14:19 justin_smith: and similarly, there are a lot of things we can do with functions, that we can't do with macros

14:22 tahmid: ##(do (require 'clojure.walk 'clojure.string) (clojure.walk/postwalk (fn [x] (if (string? x) (clojure.string/reverse x) x)) {"hello" {:a "world"}})

14:22 Jaood: tahmid: why do you mean by data? functions operate on data

14:23 justin_smith: tahmid: we can scramble, reorganize, store and retrieve, query from users, aggregate and analyze

14:23 tahmid: you don't have the same flexibility with functions

14:23 bbloom: when clojure ppl say "data" in this context they are referring to a particular style of data

14:24 justin_smith: we don't even have useful equality predicates for functions, other than object identity

14:24 tahmid: WoW never thought of that way before

14:24 bbloom: in particular, 1) immutable values with 2) structural equality and 3) printable/readable representations

14:24 justin_smith: (inc bbloom)

14:24 lazybot: ⇒ 51

14:24 justin_smith: very important point, thanks

14:24 tahmid: Yes you are write I can store pass and scramble data

14:24 justin_smith: yup

14:24 mavbozo: (inc bbloom)

14:24 lazybot: ⇒ 52

14:24 tahmid: lol what am I writing

14:25 justin_smith: then, functions we can compose, pass as first class values at runtime - these things don't work so nicely with macros

14:26 tahmid: guys why are you increasing people’s name ?

14:26 oh I get it

14:26 justin_smith: tahmid: fake internet points

14:26 tahmid: (inc bbloom)

14:26 lazybot: ⇒ 53

14:26 tahmid: (inc justin_smith)

14:26 lazybot: ⇒ 224

14:26 * bbloom grows stronger with every inc

14:27 danlentz: CL can pass macros as first class values

14:27 swarthy: there are some pretty cool white papers on something called Language Oriented Programming that I read recently. They have altered my views a bit such that now I ask, "Can I solve this problem with Clojure the language?" When the answer is no, I then create the missing piece of the language with a macro. The answer however is usually: yes I can do it in clojure.

14:27 danlentz: Well, there is macro-function

14:28 swarthy: that's what I love about lisp

14:28 bbloom: danlentz: macro-function isn't exactly what ppl would consider first class macros

14:28 danlentz: Yes

14:28 bbloom: I was sorry I made the point

14:29 bbloom: danlentz: we can do macro-function in clojure too

14:29 danlentz: First class macros are FEXPRS

14:29 bbloom: @(find-var `binding)

14:29 danlentz: fexprs are a little different than first-class macros too

14:30 ,@(find-var `binding)

14:30 clojurebot: #object[clojure.core$binding "clojure.core$binding@5996f646"]

14:31 bbloom: ,(@(find-var `binding) nil nil '[x 1 y 2] '(+ x y)) ; heh, don't try this (impl detail) at home

14:31 clojurebot: (clojure.core/let [] (clojure.core/push-thread-bindings (clojure.core/hash-map (var x) 1 (var y) 2)) (try (+ x y) (finally (clojure.core/pop-thread-bindings))))

14:33 danlentz: Yes I see regarding FEXPRS

14:34 Something I've clearly not gotten to use in real life

14:35 bbloom: i'm not sure anyone in the last few decades has really :-)

14:35 danlentz: Kernel

14:35 I think it's called.

14:36 http://web.cs.wpi.edu/~jshutt/kernel.html

14:37 bbloom: there's no "real life" implementation of it, for a value of "real life" that equals "actually useful"

14:37 danlentz: i've built a handful of kernel-style interpreters ;-)

14:42 danlentz: There was an experimental build of SBCL a few years ago I think, but obviously it was just a curiosity

14:46 tahmid: is ed an editor for clojure ?

14:46 justin_smith: ed is a text editor, and I think it is mocked more often than used

14:46 it doesn't have any language specific features

14:49 if I had to use an editor from within my repl, I would probably pick ed

14:50 tahmid: I was reading clojure irc log and someone mentioned ed

14:50 bensu: Does anybody have experience with the timber logging library?

14:50 ticking_: timbre?

14:50 justin_smith: tahmid: it was probably a joke

14:50 clojurebot: timbre is awesome if you are tired of java logging (c.f. java logging)

14:50 bensu: ticking: yeah! timbre

14:51 ticking_: bensu: yeah it's nice

14:53 bensu: ticking_: I'm thinking of storing my logs in DynamoDB or S3. Do you think I'll can with timbre?

14:54 *I'll be able

14:54 justin_smith: bensu: yeah, that can be done, it's just a clojure-friendly config frontend for java logging

14:54 and java can log to just about anything

14:55 bensu: justin_smith: I thought it was *all* Clojure and that clojure.logging was the wrapper over java

14:56 ticking_: bensu: yeah you can just write a custom appender

14:56 https://github.com/ptaoussanis/timbre/tree/master/src/taoensso/timbre/appenders

14:56 justin_smith: bensu: timbre uses jvm logging

14:56 ticking_: a bunch of example appenders

14:58 bensu: justin_smit: I guess I misread the README. I'm not sure what "Small, uncomplicated all-Clojure library." means

14:58 justin_smith: I thought that meant it implemented it's own thing.

15:00 ticking_: thanks, I looked at those but I'm not yet familiar with the abstractions, so I don't really understand the code.

15:00 ticking_: I'll have to dive in and try until I get it.

15:00 ticking_ justin_smith: Thanks for your help!

15:01 ticking_: justin_smith: I don't think so, timbre doesn't use java logging internally

15:01 bensu: you're right I think

15:02 bensu: tibre has this simple concept of appenders, which is just a function that will get called when a log occurs

15:02 you can do whatever you want in there

15:02 it's also doccumented in the timbre readme

15:03 justin_smith: ticking_: hmm, I was looking for the proof that it used java logging, but yeah, not finding it - I'll have to figure out how I got confused

15:03 ticking_: I wonder if this changed at some point?

15:03 ticking_: would have to be a long time ago I guess

15:03 I fixed a big a 2 years ago or something like that, and it wasn't using logging back then I think

15:04 justin_smith: ticking_: in that case I was just wrong, thanks

15:04 danlentz: I recently had a pretty unpleasant experience with log4j/slf4j

15:05 justin_smith: I have a syslog appender in caribou.logger that I should totally adapt for timbre and submit there

15:05 ticking_: justin_smith: There are mentions of tool.logging all thoughout the codes comments though :/

15:05 justin_smith: ticking_: that could be it - via tools.logging it can end up using log4j ?

15:05 ticking_: yeah I think so

15:06 danlentz: In general. Nothing specific, but some really sticky conflicts in transitive dependencies with Datomic

15:06 justin_smith: when was tools.logging made optional? that would make me feel less stupid if that was some time in the last year or so

15:07 anyway, syslog appending is handy, I should submit that to timbre

15:07 danlentz: justin_smith: you are caribou?

15:07 justin_smith: danlentz: not the founder, but one of the core devs

15:07 danlentz: Nice

15:08 justin_smith: danlentz: we lost our corporate funding, so it hasn't been as active in the last year or so

15:09 danlentz: If people ask why the project is not more active, just tell them it's because the code is already near perfect

15:09 justin_smith: oh man I would die of hypocrisy

15:10 danlentz: Ive seen great deal of evidence that hypocrisy is not fatal.

15:11 I thought it had a nice "product launch"

15:11 Very clean, well presented

15:12 tahmid: Me too

15:12 I wanted to use caribou in prod

15:13 But later used plain ring

15:13 danlentz: I think you guys go about this ass-backwards. I'm going to pick the animal first, then come up with some kind of software to write for it to represent

15:14 (Going off to create http://github.com/danlentz/clj-naked-mole-rats)

15:15 tahmid: (page-not-found github is under ddos )

15:17 danlentz: tahmid: sorry i was just joking about all of the animal-named projects

15:18 justin_smith: danlentz: tahmid: thanks, patchwork definitely put a lot of work into the docs and the frontend design

15:18 danlentz: no joke, this is really how caribou was named

15:18 there was a big taxidermied caribou head on the wall

15:19 so the lib got named after it

15:19 danlentz: Ha poor caribou

15:19 justin_smith: patchwork is a genius and or madman when it comes to naming things

15:20 there are certain strings that if you google them are only found in caribou source, and in irc logs asking what the hell the names in the caribou source mean

15:20 :)

15:20 danlentz: The small print: "Very few animals were beheaded during the implementation of this web framework"

15:21 justin_smith: $google jopotonio

15:22 * justin_smith pokes lazybot.

15:26 bensu: justin_smith: I didn't know of caribou, it looks pretty cool

15:27 justin_smith: bensu: thanks, it's very opinionated, but as a bonus it gives you a GUI admin for your data (including modeling data in the gui, and defining routes and pages in the gui and defining where they get their data) right out of the box

15:27 bensu: dalentz: so log4j doesn't play well with Datomic

15:27 danlentz: log4j/slf4j is used internally by datomic

15:27 justin_smith: bensu: in fact, it might be worthwhile to just modularize that admin to be used as a CMS / RAD tool.

15:28 tahmid: danlentz: is there any uuid generator for cljs ?

15:28 bensu: dalentz: got it. explains the conflict.

15:29 danlentz: so if you have another dependency which requires a different version, you have to do a hairy :exclusions kind of thing

15:29 bensu: justin_smith: I'm definitely gonna checkout the src since the admin side of things is universal

15:29 tahmid: justin_smith: how to modularize that admin to be used as CMS / RAD tool ?

15:30 danlentz: tahmid: good question

15:30 justin_smith: bensu: well, specifically the way you can define pages / routes etc. in the admin requires some integration, at least with your routing layer

15:30 tahmid: it is alreayd a CMS / RAD tool, but it would need an adaptor layer to use it with your favorite routing lib, template lib, etc. since otherwise it can't help your with those things.

15:31 or you can just use caribou. and then use polaris, and antlers, and all these work together already and you have a framework.

15:31 of course

15:31 danlentz: hoo-hoo antlers

15:32 justin_smith: or use the CMS but not its page definition functionality

15:32 and just use it for data modeling / content entry

15:32 making it slightly less convenient

15:33 tahmid: This is the missing part of my clojure web-dev tools

15:33 I find myself moving to django for the admin panel they provide

15:33 danlentz: in the java mentality if software is not constantly being patched and rewritten it must not be any good

15:33 tahmid: and then come back to clojur e

15:33 justin_smith: tahmid: well caribou is out there, and you can use it, and the docs are very good

15:34 tahmid: we took a lot of ideas from django actually

15:34 tahmid: What I don’t like about caribou is it’s very tightly coupled

15:34 justin_smith: we were working on that...

15:34 tahmid: i want to use aleph with compojure + caribou admin panel

15:34 danlentz: i think the idea that software may just work well and be stable does not usually occur

15:34 danneu: pgadmin is my admin panel

15:34 justin_smith: tahmid: like I said, you totally can just use the admin (plus the data modeling in core) and skip the rest

15:35 tahmid: I would definitely like to help with modularizing the admin panel

15:35 Okay I am giving it a try now

15:35 Thanks

15:36 justin_smith: tahmid: oh, that would definitely be welcome. I still am in #caribou last I checked, and will gladly answer any questions that will help get you up and running with that.

15:42 gfredericks: hello

15:43 justin_smith: fancy seeing you here

15:44 not-much-io: Does anyone know why clojure.org is so "bare bones"? I visited haskell.org and felt motivated to learn the language based on the cool homepage. It makes haskell look cool! Superficial reason I know. Still for new people it might be offputting to see this new language they are interested having such a boring homepage. People can be quite shallow like that sometimes. :)

15:45 bbloom: not-much-io: clojure.org is actually useful

15:45 it's just for a different audience

15:45 Frozenlock: bbloom: it is? I always considered #clojure to be the official doc.

15:46 bbloom: Frozenlock: the documentation on clojure.org is excellent

15:46 justin_smith: not-much-io: I think it's a very different (and pragmatic) design approach.

15:46 bbloom: it's clear, succinct, and correct

15:47 justin_smith: not-much-io: I think haskell.org is optimized for your first visit, clojure.org is optimized by your 10th visit, and all following visits

15:47 Frozenlock: on that note, clojure.org does have a link to this irc on its front page

15:48 joe124: ,(reverse (seq "abc"))

15:48 clojurebot: (\c \b \a)

15:48 not-much-io: bbloom: I have not really looked at haskell.org in any depth but it SEEMS to be quite "content rich", under the documentation tab and news tab :)

15:48 joe124: (reverse "abc")

15:48 justin_smith: joe124: the seq call there is redundant

15:48 tahmid: clojure.org is simple made easy

15:48 joe124: ,(reverse "abc")

15:48 clojurebot: (\c \b \a)

15:48 justin_smith: ,(apply str (reverse "abc"))

15:48 clojurebot: "cba"

15:48 Frozenlock: justin_smith: and the cheatsheet points to clojuredocs

15:49 bbloom: not-much-io: justin_smith is definitely right about visit # optimization. the haskell docs page has a big list of books, courses, tutorials, etc

15:49 joe124: in 4clojure problem 27 #(= % (reverse %)) does not work while #(= (seq %) (reverse (seq %)) ) does work

15:49 not-much-io: justin_smith : Well would it become less pragmatic and useful with some added css? *honest question*

15:49 bbloom: the references are buried on that page & not really highlighted

15:49 most haskellers know to use hoogle

15:50 and hackage refs

15:50 justin_smith: not-much-io: it's a good question, it might be worth trying some variant designs and proper UX research to see what is most effective

15:50 bbloom: not-much-io: by adding visual design, you make information design more rigid

15:51 mavbozo: not-much-io: is clojure.com style much more preferable to you?

15:51 justin_smith: not-much-io: my impression is that it may not feel "impressive" but the things that catch my eye when I glance at the page are the useful things I would be looking for

15:51 bbloom: as it is, Alex Miller (among others) can make changes to clojure.org trivially w/o having to worry about messing up a beautiful page layout

15:52 justin_smith: bbl, lunch

15:52 bbloom: the more visual polish you put in to things, the harder they are to change, so you should delay doing it until you understand the information design

15:52 and then you have to ask: what value do i get from spending the effort on visual design?

15:52 not-much-io: mavbozo : It's kind of what I was thinking.

15:52 mavbozo: not-much-io: haskell.org website is built from scratch, clojure.org is built from wikispaces

15:52 bbloom: a few more low quality community participants? *shrug*

15:53 mavbozo: i think there is a limitation in wikispaces though

15:53 bbloom: if you want high quality design, check out the cognitect pages

15:53 http://cognitect.com/clojure

15:53 the mission there is to sell you clojure and services

15:53 optimized for first visit

15:53 joe124: https://www.4clojure.com/problem/27 why doesn't it work with #(= % (reverse %))

15:53 not-much-io: bblook: I have to say, you've made your point about trading information manipulation ability for eye candy

15:53 dnolen: not-much-io: people are aware of the issue, the lack of an attractive official ClojureScript website is also annoying. Hopefully will eventually get addressed.

15:54 not-much-io: there's no real reason other than, it's a lot of work and hasn't been made a priority

15:55 Frozenlock: "a few more low quality community participants? *shrug*" o_O

15:55 bensu: Frozenlock: what do you mean?

15:56 justin_smith: joe124: (reverse "racecar") is not equal to "racecar"

15:56 not-much-io: Thanks for the info, I suppose it really is just a pragmatic decision as I suspected. And nice to keep cognitect.com/clojure in your backpocket for showing friends :)

15:56 Frozenlock: I'm surprised by this sentence. I find it harsh.

15:56 bbloom: Frozenlock: if a pretty picture is the difference between using clojure and not, then i'd rather not :-P

15:57 i'm not discounting the value of visual design. i'm only making a statement about the value produced in this instance being low

15:57 mavbozo: ,(reverse "racecar")

15:57 clojurebot: (\r \a \c \e \c ...)

15:58 mavbozo: joe124 ^not working for string

15:58 joe124: ok im getting it know

15:58 bensu: Frozenlock: I'm sorry, I missed the earlier comment (just found it)

15:59 bbloom: is "You work for me, Computer" your blog?

15:59 bbloom: bensu: yes

16:00 bensu: bbloom: first, kudos on the blog, it's been the end of long google journeys a couple of times :)

16:00 bbloom: bensu: heh, really? cool :-)

16:00 thanks

16:00 not-much-io: Frozenlock: Didn't mean to spark any controversy. I was just thinking to myself that a "pretty page" for a language would help getting young college kids more attracted to clojure

16:01 Don't know if they count as "low quality community particiapnts" :)

16:01 Frozenlock: not-much-io: Sure. IMO the best intro page for clojure is probably http://www.tryclj.com/ (depending on your background)

16:01 bensu: bbloom: I'm surprised you find the value of visual design in this instance low, when your blog is quite good visually

16:03 bbloom: my blog and a programming language landing page are quite different

16:03 not-much-io: Frozenlock : tryclj.com is just what I went with when showing some friends. :)

16:06 mavbozo: not-much-io: clojuredocs.org is also cool

16:06 bensu: bbloom: I agree but it is still unexpected. In my experience people that produce a visually appealing blog tend to be strict about everything being visually appeling

16:06 *appealing

16:07 bbloom: bensu: and here in the clojure community, you find people who understand that the world is available in shades of gray ;-)

16:07 mavbozo: bensu: and use emacs

16:07 * bbloom uses vim :-P

16:08 bensu: bloom: sure, I agree. Do you really use vim?

16:09 mavbozo: bloom: xmonad?

16:09 not-much-io: Frozenlock: IMHO people, even otherwise smart, pragmatic and productive people can be easily swayed by a cosmestic reason. Our visual sense is our strongest sense afterall :) But I suppose their numbers are debatable. :D

16:09 bbloom: bensu: yes

16:09 mavbozo: no

16:09 mavbozo: bbloom: :)

16:09 not-much-io: mavbozo: clojuredocs is cool :P

16:10 joe124: i think the clojure landing page should be as visually appealing as possible to attract newbies

16:10 Frozenlock: justin_smith: caribou looks very nice! Is it possible to have authentification in the API? Customer A login/password, customer B login/password...

16:10 mavbozo: not-much-io: as far as i know, clojure core actively encourages community contribution

16:10 bensu: bbloom: I was in vim myself until evil-mode :)

16:10 mavbozo: not-much-io: maybe you could build a clojure-for-college-kids website

16:11 not-much-io: clojuredocs.org is the result of community contribution

16:11 bbloom: joe124: i'd rather attract people who respect and nurture newbies. it's a slower growth strategy, but seems to produce good results :-)

16:11 not-much-io: mavbozo: Would if I could do it in a matter that would actually be visually as cool as clojure is conceptually :)

16:12 mavbozo: clojuredocs.org wasn't as beautiful as it is now

16:13 bensu: not-much-io: you would have to be very talented! :)

16:13 oddcully: yeah, the design of the home page is really what makes a programming language viable...

16:14 not-much-io: mavbozo: Understood, I was just thinking today that I should offer to fix some example snippets I've seen using strange s-syntax. (braces on new lines) Just to contribute something :)

16:14 adamhill: speaking of clojuredocs.org. Is search broken for everyone else?

16:14 searched for 'http' got 0 hits

16:15 not-much-io: oddcully: Please don't misunderstand, that is not what I am saying. Just a bit more appealing to quite a few newbies perhaps.

16:15 mavbozo: adamhill: me too, search http also got 0 hits

16:15 not-much-io: bensu: Awfully talented! :)

16:16 andyf: adamhill: Safari doesn't work in my experience. Firefox is better there

16:16 adamhill: ok, other core things do return something, so just a gap in the knowledge base

16:17 andyf: ClojureDocs is not comprehensive on libraries

16:17 mavbozo: not-much-io: great!

16:17 oddcully: not-much-io: you mean: let's use bootstrap

16:23 not-much-io: oddcully: No, I am not saying to do anything, just asking about the reason. If it was just that noone got around to doing it I thought maybe I would lend a hand. (ever so slightly as my skill would allow it) But as was made clear, and I agree, that the versatility of the page's content would be limited by "styling". There are other more visually appealing sites for the "first look" effect :)

16:24 oddcully: not-much-io: i'm just pulling your leg

16:25 it really p*sses me off, when usability get's sacrificed for "mobile first" or "da appeal". like e.g. with elasticsearch recently

16:28 not-much-io: mmm, dat css

16:28 jkjk

16:29 mavbozo: oddcully,: elastic.co ?

16:30 oddcully: yes. it seams they have paddeld back. you can search again without javascript

16:30 in the recent days of the change you had to remove some full-site-overlay divs

16:37 justin_smith: Frozenlock: just got back, yes, you can have arbitrary role based auth, where you have multiple users and each have apropriate roles

16:37 Frozenlock: one of these days I may even plug it into friend

16:38 and thanks

16:42 danlentz: i for one would not complain if someone were to spend some time on the clojure site/documentation

16:44 and generating clojuredoc style documentation really isn't as easy as "lein doc" with codox for example

16:45 Frozenlock: justin_smith: I'm trying it and loving every bit so far.

16:45 justin_smith: Frozenlock: awesome!

16:45 mavbozo: danlentz: most of active denizens here like justin_smith already wrote one such as this http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/defmulti/

16:46 andyf: Alex Miller has spent nontrivial hours on adding text to the docs on clojure.org over the past year or so. Not saying he is finished, and I don't know what future plans might be, but the content there has improved.

16:47 mavbozo: danlentz: and andyf too also actively wrote in clojuredocs.org

16:47 *writes*

16:48 andyf: There is a preference for concise docs on clojure.org and official doc strings that will likely never change. Other doc sites can be more verbose, like ClojureDocs.org, which is easy for anyone to edit in bits and pieces.

16:49 mavbozo: ,(doc future-cancel)

16:49 clojurebot: "([f]); Cancels the future, if possible."

16:50 hyPiRion: Oh no, time freezes yet again

16:50 danlentz: well, as a language it seems that (and Im just speculating) the lack of an explicit specification is at odds with the direction clojure has taken towards implementations across various platforms

16:52 andyf: Anyone that wants to can try writing a spec :). I would not expect clojure core team to want to spend time on such a project.

16:52 danlentz: no. i wouldn't want to be the guy to do it. Im just saying I think lets not undersell the value of _having_ such a thing if it were possible

16:54 arrdem: danlentz_: core will never write a spec I suspect.

17:00 gfredericks: that'd be an interesting thing to try to sell for bundling with clojure 2.0

17:00 in particular taking the opportunity to break a few things in the name of a simpler spec

17:00 arrdem: I would agree.

17:01 Bronsa: i'd rather have a more open development process than a spec

17:03 bbloom: genuine question: why do you want a spec?

17:04 Bronsa: bbloom: have you ever used IPersistentMap in your code?

17:05 andyf: Guess: a more precise spec gives more guarantees on behavior than docs that leave much behavior unspecified.

17:05 bbloom: Bronsa: only after making a portability/compatibility risk tradeoff :-)

17:05 Bronsa: or any of the c.l interfaces that you kinda know you can use, but there's actually no *guarantee* of it

17:06 bbloom: Bronsa: well there is a guarantee of binary compat for public java code

17:06 but it's a microsoft/sun style promise, rather than a source compatability promise

17:06 which is a separate thing from portability between implementations

17:07 Bronsa: bbloom: afaik the only public java api is c.l.ifn and c.java.api.clojure

17:08 everything else is technically implementation details

17:08 bbloom: Bronsa: yes, but rich & alex have gone out of their way to preserve binary compat of the impl details

17:10 https://groups.google.com/d/msg/clojure/BAlKtMB8pp8/F_4ru1ISf3sJ

17:11 i also don't necessarily buy the argument that having a spec would improve the situtation

17:11 the spec would simply neglect to mention implementation details that you'd then have to make the same cost/benefit risk tradeoff decision about

17:11 w/o any material new info

17:12 danlentz: wow

17:13 bbloom: what's so wow?

17:13 danlentz: I think a spec would go a long way toward advancing clojure in a number of ways

17:13 bbloom: i'm not arguing against having a spec, i'm arguing that the spec would be useful for the IPersistentHashmap interface Bronsa mentioned

17:13 happy to hear other arguments

17:15 danlentz: i mean, I'm not talking about creation of the CLJHS (or at least not in the image of CLHS)

17:15 Bronsa: bbloom: my only other argument is the usual "metadata is evaluated weirdly, also :tag" one :P

17:15 bbloom: Bronsa: lol, metadata :-P

17:15 danlentz: type hinting

17:16 hyPiRion: There are some funny edge cases lying around

17:16 ,(#(`{~@% ~@%&} %) 1 2 3 4)

17:16 clojurebot: #error{:cause "Don't know how to create ISeq from: java.lang.Long", :via [{:type java.lang.IllegalArgumentException, :message "Don't know how to create ISeq from: java.lang.Long", :at [clojure.lang.RT seqFrom "RT.java" 506]}], :trace [[clojure.lang.RT seqFrom "RT.java" 506] [clojure.lang.RT seq "RT.java" 487] [clojure.core$seq__4079 invoke "core.clj" 135] [clojure.core$concat$fn__4166 invoke "core...

17:16 danlentz: but at minimum we could specify what we intend to leave unspecified

17:16 hyPiRion: whoops

17:17 andyf: Has an attempt and later abandonment of a Ruby spec hurt Ruby adoption?

17:17 bbloom: andyf: no, but i don't know if adoption was the objective

17:17 Bronsa: ,(map meta ['^:foo [] '^:foo [1]])

17:17 clojurebot: (nil {:foo true})

17:17 danlentz: are we trying to be the most popular or the most useful/best?

17:18 the spec encourages implementations

17:18 arrdem: porque no los dos?

17:18 danlentz: i mean, without a spec what are you even trying to implement

17:19 andyf: Clojure does not seem to be lacking in implementations.

17:20 danlentz: i think that their existence does not necessarily justify the conclusion that no specification is the most effective environment to nurture those implementations

17:22 bbloom: ,(defn print-spec [] (->> (ns-publics 'clojure.core) keys (map #(eval (list 'doc (symbol "clojure.core" (name %)))))))

17:22 clojurebot: #'sandbox/print-spec

17:22 bbloom: ,(print-spec)

17:22 clojurebot: ("; " "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Supports arbitrary precision. See also: +" "([n]); Returns true if n is a BigDecimal" "([a new-state & options]); When an agent is failed, changes the agent state to new-state and then un-fails the agent so that sends are allowed again. If a :clear-actions true option is given, any actions queued on the agent that were bei...

17:22 andyf: danlentz: Have you considered that specs can be a hindrance in some cases, too? They beget language lawyers :)

17:22 danlentz: yeah, language lawyering is painful

17:23 bbloom: danlentz: the lack of a spec also meant that clojurescript could find a happy tradeoff

17:23 a clojure spec would have restricted clojure to provide features that may not have been possible on javascript runtimes

17:23 or not possible with good perf

17:23 Bronsa: it also meant that I wanted to kill myself twice a day when making sure t.a could handle both clj and cljs :P

17:23 bbloom: by writing a spec, you constraint what gets to be called "clojure"

17:24 Bronsa: would the existence of a spec have prevented that problem?

17:24 rhg135: it also means you can write code that works identically on all platforms

17:24 danlentz: well, going forward can't we look ahead and anticipate what is going to be a reasonable set of abstractions to support?

17:24 bbloom: and if so, would the spec have had to existed before or after clojurescript was implemented?

17:25 danlentz: we can only look backwards to see which reasonable set of abstractions have been supported successfully

17:25 rhg135: how about a versioned spec?

17:25 say when clj only existed we had 1.0 then cljs came and it's 1.1

17:26 bbloom: rhg135: but you're proposing a solution to a problem with a solution that hasn't been successfully motivated by a problem :-P

17:26 i ask again: what benefit does a spec provide us?

17:26 andyf: Perhaps the spec could be versions with sha1 values? (ducks)

17:27 arrdem: (inc andyf)

17:27 lazybot: ⇒ 26

17:27 danlentz: i mean, as a developer I would love to have definitive language to refer to in addition to the "few well chosen example" approach of the clojure doc

17:27 bbloom: danlentz: the doc strings in clojure.core are definitive

17:27 danlentz: do they tell me how to type hint?

17:27 rhg135: i know that, andyf, that's just my view on a way a spec would be useful and maintainable

17:27 andyf: Albeit sometimes leaving details unspecified

17:27 bbloom: no, but type hints differ between clojure and clojurescript

17:27 Bronsa: bbloom: it would have probably made some of the problems I had to work around, somebody else's problems when implementing cljs

17:28 bbloom: so type hints wouldn't have been covered in this theoretical hint anyway

17:28 Bronsa: bbloom: type hints are dialect-specific things though

17:28 bbloom: Bronsa: as far as i'm concerned, your implementations are specs

17:28 danlentz: they should be documented as unspecified

17:28 rhg135: type-hints are details anyway

17:28 mainly for performance

17:29 bbloom: danlentz: but how were we to know apriori the ways in which type hints would or wouldn't map to other platforms?

17:29 danlentz: well, details are not important in documenting a language

17:29 Bronsa: rhg135: it stops being details when you need that performance and they don't do what you'd expect them to do

17:29 danlentz: we could say where they belong

17:29 bbloom: the danger of writing a spec is that you screw up and now it's a spec

17:29 the if you change it, ppl get pissed you broke it

17:29 danlentz: we could say what the syntax of defn should look like

17:30 bbloom: (doc defn)

17:30 clojurebot: "([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata. prepost-map defines a map with optional keys :pre and :post that contain collections of pre or post conditions."

17:30 bbloom: the syntax is defined there

17:30 arrdem: bbloom: without the spec you have the same problem. Imagine the ire if defn got changed in 1.7.

17:30 bbloom: ,(-> #'defn meta :arglists)

17:30 clojurebot: ([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...])

17:30 danlentz: so if i am returning a long where do i put the type hint?

17:31 bbloom: arrdem: sure, which brings me back to my question: what value does the spec provide us?

17:31 TEttinger: you can't return a long on JS because JS doesn't have longs

17:31 bbloom: the web is a place where we have 1) specs and 2) many implementations

17:31 rhg135: js is a prime example of a spec

17:31 TEttinger: internet explorerjure!

17:31 bbloom: and i find the spec to be of significantly less value then mozilla's community maintained documentation, which records facts about implementations

17:31 danlentz: the type hint can go on the var or on the arg vector

17:32 if on the var, it cannot be primitive

17:32 rhg135: i'm not sure what the opposite would be

17:32 danlentz: if on the type vector, it must be fully qualified

17:32 show me where it says that in the clojure documentation

17:32 TEttinger: danlentz: that's what's called a wart

17:32 bbloom: rhg135: js mainly benefits from being a spec b/c js code is trasmited as data to agents w/ unknown execution environments

17:32 rhg135: most languages have varying degrees of specs: from ansi to 'what is a spec'

17:32 bbloom: clojure doesn't have that use case

17:32 jbizzle: hey

17:32 arrdem: bbloom: I would argue that we have an implicit spec in the form of the Clojure implementation which should be better rendered in the form of a clear document so that people like Bronsa and myself who are interested in making "near Clojure" langs have something more to work with and some idea of the extent to which we are breaking compat.

17:33 danlentz: so it should DEFINITELY be documented

17:33 TEttinger: and they've been meaning to change it, but it would break a lot of code

17:33 jbizzle: what us clojure

17:33 TEttinger: jbizzle: see topic

17:33 rhg135: bbloom: that's the key. one language, lots of platforms

17:33 TEttinger: it's a programming language

17:34 bbloom: rhg135: the fundamental distinction is whether the code runs on a KNOWN platform/implementation, or an *unknown* one

17:34 you'll notice that EDN has a spec

17:34 danlentz: things and intents are left unspoken

17:34 bbloom: that's b/c it's expected to be interpreted by unknown implementations

17:34 jbizzle: ok ok

17:34 danlentz: even if "everbody knows" how a particular implementation works

17:34 bbloom: writing specs is 1) time consuming 2) difficult and 3) not without risks

17:34 so you need a strong motivation, like with JS or EDN

17:34 danlentz: looking at that in another context might not be so clear cut

17:35 i think having things expressed explicitly facilitates the discussion that helps bridge those gaps

17:35 bbloom: arrdem: if you were trying to implement a scheme and the spec said "you must have tail calls" but your platform doesn't support them, well then, you're going to spend a whole hell of a lot of time trying to match the spec & dealing w/ ppl bitching you don't have tail calls

17:35 rhg135: i think we should start on a spec once we hit 150 platforms

17:36 bbloom: arrdem: now granted, if you tried to run some scheme code on your no tail calls platform, it would fail... but what if tail calls were spec'd LATER and all the code out there didn't rely on them?

17:36 arrdem: like is the case with javascript

17:36 danlentz: well lets not call the other languages "clojurexxxxx" then

17:36 bbloom: arrdem: if rich specs something, ppl like you will force yourself to adhere to the spec

17:36 danlentz: because clojure is defined by this one java implementation and that is what we should expect as clojure

17:37 bbloom: arrdem: and while admirable, that would be a detrimental effect to your experiments

17:37 arrdem: bbloom: agreed, one of the many reasons I've abandoned calling my experiments "clojure".

17:37 bbloom: look at pypy which runs some % of all python code, minus some c ffi stuff, and subject to dozens of caveats

17:37 rhg135: a good test suite should work

17:38 bbloom: rhg135: yes, i'd much prefer a portable test suite than a spec

17:38 rhg135: it'd be nice

17:38 if you pass the clj suite, you're good. if not, no

17:38 danlentz: i think there is a very close relationship between a formal portable test suite and a spec

17:39 arrdem: danlentz: loosely construed Curry/Howard, yes.

17:39 bbloom: danlentz: there's a critical difference in my mind, which is that a spec aims to be exhaustive, or at least is treated as such

17:39 tests are expected to not necessarily be comprehensive

17:40 danlentz: but even with tests its important to understand test coverage

17:40 e.g. what is currently remains untested

17:40 bbloom: anyway, my position is not that a spec is a bad idea

17:40 only that it 1) is not without costs/risks and 2) would provide limited value for clojure

17:41 danlentz: just as with a spec you are free to say what you are specifying, what is implementation defined, and what is undefined

17:41 bbloom: i'll also add that, in my career, i've never once encountered a spec that was widely implemented correctly by multiple independent vendors

17:41 and i've coded to a lot of specs...

17:42 danlentz: "we all suck, so why bother trying..."

17:42 bbloom: "this isn't working, let's double down"

17:42 danlentz: :)

17:42 mavbozo: guys, how many pages needed to write a clojure spec? I guess it won't be that many cause clojure is a lisp

17:43 bbloom: microsoft pushed the W3C to start publishing test suites, and surprise surprise, that seems to be working :-)

17:43 mavbozo: algol-60 spec is 34 pages

17:43 arrdem: mavbozo: this is left as an exercise for the reader

17:46 rhg135: for the syntax? maybe a paragraph

17:46 aside from the edn spec of course

17:46 danlentz: there are actually other lisp specifications we can look at an learn from

17:48 at minimum, do no worse

17:54 the way w3c tests sparql and ttl and n3 is really quite good

17:56 also the ansi-cl test suite demonstrates some very extensive and concerted effort to verifiably test an implementation and correlate the results with the standard

18:13 justin_smith: wow, this contributor agreement is weird (on google chrome, linux) http://i.imgur.com/YTTeTgn.png

18:14 bbloom: justin_smith: *sigh* adobe....

18:14 justin_smith: inorite

18:16 I waited too long to sign this thing.

18:19 gfredericks: back in my day we could only sign contributor agreements with printers and pens and stamps and mailmen

18:20 but we were happier then, though we were poor

18:20 oddcully: weird and from adobe... that is odd

18:28 brehaut: gfredericks: and we waited bloody months for international postage

18:29 gfredericks: hell yes we did

18:29 then we had to email somebody at relevance to ask if they every got the letter

18:30 but did we complain?

18:30 yes.

18:30 pretty much nonstop.

18:30 brehaut: vocally, on the mailing lists

18:30 oddcully: haha

18:31 Bronsa: gfredericks: it's a thing of the past now, let's find something else to complain about ;)

18:31 bbloom: :-)

18:31 brehaut: theres always jira

18:32 gfredericks: yeah why the hell do these unchecked functions do so much checking

18:33 bbloom: gfredericks: numerics are hard :-(

18:34 gfredericks: numbers I will tell you what.

18:39 justin_smith: gfredericks: we should emulate the olive oil people and make extra-unchecked functions

18:40 Glenjamin: its mildly amusing that all computers can do is numbers

18:40 and now we can't get them to do only that

18:42 gfredericks: justin_smith: I can go for that

18:42 ,(defn extra-unchecked-add [x y] (unchecked-add (long x) (long y)))

18:42 clojurebot: #'sandbox/extra-unchecked-add

18:53 brehaut: justin_smith: its like unchecked, but with a more pepper taste

18:55 danlentz: au-poive

19:01 is there a particularly good resource to see a large number of examples of how to build various abstractions with the primitives of core.logic?

19:03 i was really interested in screamer when working in common lisp but I had a look at the source code and porting it seems like a lost cause

19:05 https://github.com/nikodemus/screamer

19:06 first there is the issue of what seems to be a system of delimited continuations

19:06 justin_smith: danlentz: could that be modeled with trampoline?

19:06 danlentz: second there is the issue that this macro system needs to pretty much account for the entire language

19:07 but if I could have a wish this would be it

19:09 it is really an awesome tool

19:10 also (blush) i ported Screamer+ and gathered some extensions and documentation

19:10 https://github.com/danlentz/screamer-plus

19:11 by "ported" i mean de-allegrized it

19:14 well with atoms I would think

19:17 IE, an unknown would be modeled as an atom with a watcher and when it became known, any logical implications of that would be reflected in an update to the other unknowns of the universe

19:17 the trick is to make that calculation lazy

19:27 justin_smith: sounds like a delay, not an atom

19:28 unless it can become known more than once

19:30 danlentz: no, retraction is complicated

19:31 https://github.com/danlentz/screamer-plus/raw/master/doc/screamer.pdf

19:32 "Screaming Yellow Zonkers"

19:32 so the basic idea is "nondeterministic lisp"

19:36 this describes the screamer-plus extensions

19:36 https://github.com/danlentz/screamer-plus/blob/master/doc/screamer-plus.pdf

19:37 yes, delay

19:44 i think there would have to be some adaptation of the concept to a model more conciliatory toward immutability, but I guess that has to be addressed with any layered extension to clojure for deductive logic

19:46 built up as a macro on top of funcall-nondeterministic

20:50 Shayanjm: I have a big vector containing center points of circles that need to be plotted. I'm running through them with map and plotting them with Incanter.

20:50 If I try running the same exact vector with pmap, though, it returns a wildly different result

20:51 it's almost as if pmap doesn't actually run through the entire vector

20:51 any reasoning re: why/how to rectify? I'd like to parallelize this if possible because there could be a non-trivial amount of plotting necessary in the future

20:52 justin_smith: Shayanjm: I don't think pmap will help much because your GUI still only has one event loop to register all these shapes to display

20:52 unless calculating the actual display data is a CPU bottleneck

20:52 which I doubt

20:52 ~pmap

20:52 clojurebot: pmap is not what you want

20:52 Shayanjm: justin_smith: nah, no CPU bottleneck - though in the (near) future i'll be needing to make tons of API requests using these points

20:53 so parallelizing that if possible would be very helpful

20:54 justin_smith: yeah parallelizing that would be good, but pmap has a hard baked strategy that assumes the task is CPU bound, not network bound

20:54 Shayanjm: Gotcha. is there a well-adopted norm for parallelizing network stuff?

20:54 or is it basically bake your own solution?

20:54 justin_smith: you can use an async network client and feed the result into your GUI updating function

20:54 Shayanjm: That works

20:55 justin_smith: also the async network client will do fancy shit like keeping the http connection open for multiple requests

20:55 which is a big plus if you keep hitting the same host

20:55 Shayanjm: nice

20:55 Yeah definitely

20:55 I'm psyched that my general solution packing function works as expected

20:56 so any additional leg work on top to get it wired up is no problem

20:56 justin_smith: yeah, that's always cool

20:56 you have the correct version, so now you can work on turning it into the fast version

20:56 Shayanjm: yup definitely

21:14 prt44: I've got a map keyed by a java.util.Date {d v d2 v2}, I'd like to convert to the map be keyed by year i.e. 2015, then the value is a nested map keyed by month with it's value the original value. Note the day is not really significant because it's always the last day of the month.

21:19 andyf: prt44: Check out group-by. You could start by making a function that extracts the year from a java.util.Date and using that in the call to group-by.

21:19 Then iterate on each value of the map created to do something similar with the month.

21:21 Hmmm, not exactly what you asked for, but not too far from it.

21:21 prt44: andyf: thanks, I had been using reduce and update-in, but I'll experiment with group-by

21:26 amalloy: group-by is probably going to be more work than reduce/update-in

21:27 (reduce (fn [m date] (assoc-in m [(.year date) (.month date)] date)) {} dates)

21:27 or however you get data out of Date objects

21:32 justin_smith: and change that assoc-in to an update-in / conj date if you would care about multiple pieces of data with the same month (which it sounds like you may not)

21:37 ,(reduce (fn [acc date] (update-in acc [(.getYear date) (.getMonth date)] conj date)) {} (repeatedly 8 #(java.util.Date. (long (rand-int 1000000000)))))

21:37 clojurebot: {70 {0 (#inst "1970-01-01T19:42:43.552-00:00" #inst "1970-01-06T07:52:39.424-00:00" #inst "1970-01-07T06:32:57.051-00:00" #inst "1970-01-05T18:26:28.078-00:00" #inst "1970-01-06T01:30:58.082-00:00" ...)}}

21:38 justin_smith: ,(reduce (fn [acc date] (update-in acc [(.getYear date) (.getMonth date)] conj date)) {} (repeatedly 5 #(java.util.Date. (* 10000 (rand-int 1000000000)))))

21:38 clojurebot: {196 {2 (#inst "2096-03-06T03:51:50.000-00:00")}, 280 {2 (#inst "2180-03-11T19:01:10.000-00:00")}, 369 {7 (#inst "2269-08-05T03:25:20.000-00:00")}, 359 {2 (#inst "2259-03-31T01:35:40.000-00:00")}, 171 {10 (#inst "2071-11-27T19:31:10.000-00:00")}}

22:16 elvis4526: Hi! Is it possible to use a regexp when matching a path with compojure ?

22:16 arrdem: elvis4526: yep!

22:16 elvis4526: the context macro allows you to gard path elements with a regexp.

22:16 elvis4526: you may be able to do the same with other routing terms, I can't say I'm sure.

22:17 Lewix: hello folks

22:17 catern: is there a "Java for Clojure programmers" tutorial yet?

22:17 please someone write it soon

22:18 arrdem: elvis4526: (context ["/:a", :a #"fo+"] [a] ...) should work for instance.

22:19 elvis4526: I'm not sure I understand why I would be using context

22:19 What I meant is:

22:19 I want a route like that (GET "^\w*$" [] foo)

22:20 I don't want to prefix all my routes with something necesseraly

22:20 raspasov: catern: https://www.youtube.com/watch?v=P76Vbsk_3J0 Clojure for Java Programmers video

22:20 catern: raspasov: wrong way around

22:20 friend

22:20 arrdem: elvis4526: https://github.com/weavejester/compojure/wiki/Routes-In-Detail#matching-the-uri

22:21 raspasov: catern: oops :)

22:21 elvis4526: alright cool

22:21 catern: I think this is kind of what i'm looking for http://www.braveclojure.com/java/#3_3__Importing

22:21 elvis4526: and are the rules defined after this rule of mine

22:21 will override it ?

22:21 catern: er

22:21 http://www.braveclojure.com/java/

22:21 arrdem: elvis4526: no compojure works on a "first match" basis.

22:22 elvis4526: oh okay

22:22 so basically i just put it at the end

22:22 raspasov: catern: yea I learned most of this stuff with the help of IntelliJ and Cursive, and auto-filling of imports is badass

22:22 elvis4526: thanks

22:22 arrdem: elvis4526: sure, but there is a built in for the route which matches anything.

22:22 elvis4526: are you speaking about ANY ?

22:22 I thought it matches every type of requerst

22:22 arrdem: elvis4526: https://github.com/weavejester/compojure/blob/master/src/compojure/route.clj#L40

22:31 gfredericks: 4L96dmaMgJ

22:33 * gfredericks sends himself a password expiration warning email

22:33 TEttinger: hahaha

22:33 $google 4L96dmaMgJ

22:33 brehaut: gfredericks: your pass is ********** ?

22:33 gfredericks: maybe a security breach email would be more appropriate

22:33 brehaut: that doesnt sound very secure

22:33 TEttinger: also, no symbols? for shame

22:34 you're in #clojure and you don't use symbols whenever possible???

22:34 lazybot: TEttinger: How could that be wrong?

22:34 brehaut: TEttinger: i prefer keywords in my passphrases

22:35 TEttinger: I like BOMs

22:35 just in general

22:36 password: \0\0\0password\0\0\n\r\n\0

22:36 I wonder how many places would even be able to take that

22:52 justin_smith: TEttinger: more as a paste - that way it won't get in the way of widget / tty key bindings

22:52 but with a password like that, you wouldn't be typing it all in by hand anyway I don't think

22:53 catern: that's a really shallow intro to interop, the docs on clojure.org are better

22:54 catern: http://clojure.org/java_interop

22:54 catern: justin_smith: I don't need docs on interop

22:55 justin_smith: I need an explanation of WTF all this Java crap is

22:55 justin_smith: catern: and the extra thing neither resource mentions, is that java is documented by a highly standardized format called javadoc, and there are tools like javadoc-search-pane for modern browsers that make finding things really easy

22:55 catern: this java crap is 100% interop

22:55 that's the way you access it

22:55 catern: well

22:55 let me assure you

22:56 that the brave clojure one is much better for me personally as someone unfamiliar with Java

22:56 TEttinger: catern, are you writing java coming from a clojure bg?

22:56 justin_smith: catern: the problem to me is that the entire chapter there covers like what you could get from half a paragraph on the clojure.org page

22:56 TEttinger: java is, thankfully, not that hard of a language compared to many others out there

22:57 catern: justin_smith: and I need that

22:57 TEttinger: catern, if you have any specific questions we can try to answer some

22:57 catern: well

22:57 I haven't actually read the brave clojure or the clojure.org pages yet

22:57 I have other things I have to get done

22:57 BUT LATER I WILL

22:58 TEttinger: (I'm guessing the package/namespace stuff is a big headache for anyone coming from java or clojure and trying to learn the other)

23:03 justin_smith: TEttinger: no matter what, they are two parallel and weirdly incompatible systems - I came in knowing neither java or clojure and it was confusing

23:03 TEttinger: wow

23:17 devll: How long have you been using Clojure ? justin_smith

23:17 justin_smith: about 3 years

23:18 devll: Yeah. Big relief, I have 2 years to catch up.

23:18 lol

23:19 do you have blog on Clojure?

23:20 justin_smith: devll: funny, I was thinking about that earlier, some ideas for one...

23:22 tolstoy: Hard to think of what to write about with Clojure that hasn't already been done and available via Planet Clojure.

23:22 Maybe an un-clojure Blog?

23:22 Show how you can translate a few lines of Clojure into 100 lines of Java or whatever?

23:23 Blog: Leiningen Considered Harmful -- 1st paragrah: Let us open to chapter 59 of the Gradle documentation site....

23:23 justin_smith: I think I might have a kind of unique intro-to-programming via clojure perspective, different from the other stuff I've seen

23:23 tolstoy: Eh. Barrels. Fish.

23:24 devll: justin_smith: that will be awesome.

23:24 tolstoy: Ah, yeah. Nice.

23:25 justin_smith: my general idea is: first the abstraction, then the various ways you will see it leak, and the signs that particular abstraction is leaking

23:26 eg. "cannot find ... _init.class" usually means you asked for a namespace but clojure failed to load the file for it

23:27 tolstoy: Back in 2008ish, I _always_ got caught with the error for not using a vector for parameters.

23:27 justin_smith: the stuff that held me back for so long, and then I came to IRC and people could tell me instantly what was wrong, when I first started

23:27 tolstoy: yeah, that's another good one

23:27 maybe "the clojure error dictionary"

23:27 tolstoy: It's better now. At least they mention "parameter". ;)

23:27 justin_smith: haha

23:29 tolstoy: I wonder if there's a "how to read clojure" opportunity out there?

23:29 Maybe, "How to read Clojure source for the not particularly detail oriented."

23:29 TEttinger: heh

23:29 justin_smith: tolstoy: that would be another good thing to cover

23:30 "clojure speed reading"

23:30 TEttinger: the lazy guide to lazyseqs

23:30 justin_smith: haha

23:30 oh, here's another idea: stack trace flash cards

23:30 TEttinger: yes!

23:30 tolstoy: Whenever you see "reduce", you know someone's taking a bunch of values and crunching 'em down to a few. So just glance right over that without getting lost in the actual anonymous function.

23:30 That kind of thing. ;)

23:30 TEttinger: I like it

23:30 justin_smith: on one side it has a real stack trace, on the other side, the kind of mistake that makes that stack trace, lol

23:31 TEttinger: OutOfMemoryError

23:31 justin_smith: TEttinger: that would be the name for the clojure flavor of the game memory

23:31 TEttinger: heh

23:31 amalloy: TEttinger: fat-themed yo mama joke

23:31 TEttinger: or dumb-themed, amalloy!

23:31 tolstoy: "For a stack trace, read the first line. That's all you need unless it's a NullPointerException. Then get a cup of coffee."

23:32 TEttinger: "yo mama's so dumb she gets an OutOfMemoryException when she tries to turn on her TV"

23:34 devll: It will be nice if we could stack those to one github repo.

23:34 TEttinger: "yo mama's so dumb she gets an NullPointerException when she tries to figure out if Darnell is really the baby's father on Jerry Springer"

23:34 I'm typoing all over here

23:35 justin_smith: TEttinger: "yo mama got an NPE when she tried to dereference her BabyDaddy field"

23:35 TEttinger: haha

23:35 UnknownInheritanceException

23:35 justin_smith: LOL

23:44 so set!, with-redefs, binding and alter-var-root walk into a var...

23:50 morganthomas: hi all! i have a situation which i don't understand. i have couple instructions which produce different results when run in a "do" block and when run separately on the repl.

23:51 if i write into the repl:

23:51 > (foo bar)

23:51 > (baz abc)

23:51 that produces a different result than doing

23:51 > (do (foo bar) (baz abc))

23:51 justin_smith: morganthomas: if foo is lazy, then printing in the repl will force it to be eager

23:51 but inside do, it won't do anything at all

23:52 the moral of this story is that laziness and side effects are star-crossed features, doomed to a complicated and bug-ridden romance

23:52 morganthomas: ah, thank you!

23:52 justin_smith: morganthomas: options include dorun (if you never use the result) and doall (if you use it)

23:52 morganthomas: so foo uses a for loop to do a series of actions on a java object. i am assuming the action of "for" is lazy?

23:53 justin_smith: morganthomas: yes, for is lazy, and unlike every other language out there, clojure's for is not a loop

23:53 morganthomas: it's easy to test this in general actually

23:53 ,(type (for [a (range)] a))

23:53 clojurebot: clojure.lang.LazySeq

23:53 justin_smith: if type gives that answer, the function is lazy

23:54 morganthomas: justin_smith: ah, thank you so much. so what would be the idiomatic way to perform a series of actions, one for each element in a sequence?

23:54 justin_smith: morganthomas: doseq is identical to for, except it returns nil

23:54 and is not eager

23:55 and accepts N forms in its body

23:55 morganthomas: justin_smith: brilliant, thank you! now i can fix my code. :-)

23:55 justin_smith: but it has the same binding syntax and features as for, so you can just s/for/doseq

23:55 morganthomas: np

23:56 that would be one of the chapters in my tutorial

23:56 when your thing suddenly does nothing, it's usually because it's lazy and you aren't using its result

23:57 morganthomas: i'll go take a look at that.

23:57 justin_smith: morganthomas: my hypothetical not yet existing tutorial, something we were discussing earlier

23:58 morganthomas: ah, i see. yes, it did not come up on google. :-)

23:58 justin_smith: morganthomas: this too I can attribute to laziness

23:58 so if I just edit my inner for and make it a doseq...

23:58 morganthomas: :-p

Logging service provided by n01se.net