# #clojure log - Mar 13 2014

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

0:00 seangrove: mr-foobar: Well, with that approach, you get state-serialization, user-playback, etc. for free

0:00 And the code stays tiny, your state-transitions are forced through once choke-point so it's manageable, etc.

0:00 Lots of nice things just fall out.

0:01 danielszmulewicz: seangrove mr-foobar : and that's the way to go.

0:01 :-)

0:03 mr-foobar: seangrove, you should definitely add this in the om wiki. shall I add it now ?

0:04 mr-foobar: seangrove link to omchaya

0:04 seangrove: Oh, sure. Sounds like a good idea.

0:05 brainproxy: working w/ a seq abstraction over read-line

0:05 in cider repl

0:06 stuck ... how can I close stdin

0:06 without killing the whole thing

0:08 loneworlf: hey guys - i am reading "Clojure Programming" from Oreilly and i have a question about one of the examples

0:09 here is the example

0:09 sdegutis: loneworlf: refheap.com

0:09 loneworlf: (require '[clojure.string :as str]) (def camel->keyword (comp keyword str/join (partial interpose \-) (partial map str/lower-case) #(str/split % #"(?<=[a-z])(?=[A-Z])")))

0:10 muhoo: i'm confused by the purpose of secretary. why would you need routing on the client side?

0:10 is it even possible for js browser clients to receive incoming http connections?

0:10 bob2: because in that world you're writing JS that redraws the whole page based on actions

0:10 loneworlf: my question is i understand that comp is combing functions together - i dont know what keyword is referring to - is it just the parameter name ?

0:10 bob2: it's not about incoming http

0:11 amalloy: &(doc keyword)

0:11 lazybot: ⇒ "([name] [ns name]); Returns a Keyword with the given namespace and name. Do not use : in the keyword strings, it will be added automatically."

0:11 bob2: loneworlf, the name of the variable is literally "camel->keyword"

0:11 oh, in comp, sorry

0:11 muhoo: bob2: what is it for then?

0:11 loneworlf: bob2 - yeah in comp

0:13 akhudek: muhoo: it's to handle # urls in single page apps

0:14 muhoo: akhudek: oh, cool, thanks. that makes sense

0:14 mheld: why would something work in a repl but not in lein run?

0:15 loneworlf: bob2, is the keyword in comp a "self" reference to the outer function ? (the camel->keyword function we are defining in the example)

0:15 muhoo: loneworlf: i have a threading-macro fetish, so i'd do it as https://www.refheap.com/57613

0:16 actually, sorry https://www.refheap.com/57614

0:16 mheld: let in clojure is lexically scoped?

0:17 loneworlf: muhoo, yeah they mention that you can do it as a threading-macro - that site you linked is cool - in your example what is the meaning of the keyword at the end of your macro ?

0:17 mheld: so I can do (let [x 1 y x] y) and it'd evaulate to 1, yes?

0:17 muhoo: loneworlf: that thing amalloy doc'ed you to

0:17 ,(doc keyword)

0:17 clojurebot: "([name] [ns name]); Returns a Keyword with the given namespace and name. Do not use : in the keyword strings, it will be added automatically."

0:18 amalloy: mheld: yes, although it's not clear what lexical scope vs some other scope has to do with that

0:19 mheld: amalloy: non-globally scoped

0:19 bob2: loneworlf, keyword is a function in clojure.core

0:19 loneworlf: muhoo, clojurebot, amalloy - thanks i didnt know there was a keyword "keyword" and i was slow to grok the doc command - with you know much appreciated

0:20 bob2, thanks i got it know :)

0:20 bob2 - correction now ;)

0:20 muhoo: np. and, just for accuracy: https://www.refheap.com/57615

0:20 * muhoo hopefully learns to run code first before refheaping it

0:22 Raynes: mheld: LETsically scoped. ;)

0:23 muhoo: bahaha

0:23 really wish there was an as->> macro :-/

0:23 mheld: Raynes: heh

0:24 seangrove: muhoo: Write one, put it in your personal 'useful ns. I have (comp first filter) as ffilter in mine, for example

0:24 muhoo: 'cause most of the time most of the stuff is ->>, and like one or two is ->. so it'd be neat to have (->> foo (bar baz) (as->> x (quux x blah)) (bleah yeah huh))

0:25 seangrove: good point. i do have one of those misc-libraries

0:25 pdk: what would as->> do

0:25 muhoo: pdk: let you accomodate the rogue function that takes the arg you want as its FIRST argument :-)

0:25 seangrove: muhoo: Doesn't as-> do that already though?

0:26 muhoo: not afaict.

0:26 actually, not last i tried. hmm, maybe i shoudl try again

0:27 seangrove: nope, unsupported binding form

0:27 seangrove: muhoo: refheap?

0:27 amalloy: muhoo: i don't really love any of these definitions of camel->keyword, but yours starting with ->> is particularly silly. you could much more legibly write (-> camel (str/split #"...") (->> ...))

0:27 muhoo: seangrove: https://www.refheap.com/57616

0:28 amalloy: of course?

0:29 seangrove: muhoo: https://www.refheap.com/57619

0:29 muhoo: huh, and so it goes. provided everything in the back end of the chain is ->> otherwise i could be going back and forth between ->> and ->

0:30 Raynes: muhoo: Also remember that you do not have to chain everything.

0:30 :p

0:30 muhoo: seangrove: yeah, but all those x's are annoying.

0:30 amalloy: muhoo: you don't even have to go back and forth. (-> x (f 1) (->> (g 2) (h 3)) (q 4))

0:30 muhoo: Raynes: what! of course i do. :-P

0:30 seangrove: muhoo: Not that big a deal, but I understand if you're seeking perfection

0:30 muhoo: naw, it's not even perfection, it's just a tic

0:31 or, a fetish really, for threading

0:32 Raynes: muhoo: Not appropriate for HQ, man. Not appropriate for HQ.

0:32 amalloy: i think that function reads better with no threading at all, personally

0:32 muhoo: with the partials and comps? hmm.

0:32 amalloy: also the interpose \- should obviously be lumped together with the join, for (join "_')

0:32 ugh, no

0:32 those are even worse

0:32 just nested sexps

0:33 muhoo: oh, old-skool lisp. yeah, there's that

0:34 amalloy: (keyword (join "-" (map lower-case (-> camel (s/split #"(?<=[a-z])(?=[A-Z])")))))

0:34 so i guess a little threading

0:35 muhoo: (keyword (str/join (map str/lower-case (str/join "-" (str/split camel #"(?<=[a-z])(?=[A-Z])")))))

0:35 amalloy: str/join twice??

0:35 lazybot: amalloy: What are you, crazy? Of course not!

0:36 muhoo: lolbot

0:36 yeah, an extra one snuck in there

0:37 but your point stands: plain ol' sexps is actually clearer for this

1:07 sdegutis: clojurebot: !help

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

1:07 sdegutis: clojurebot: english?

1:07 clojurebot: excusez-moi

1:07 escherize: haha

1:10 muhoo: ~help

1:10 clojurebot: Nobody can help with "X doesn't work". Please provide context: what you did, what you hoped would happen, and what happened instead. A stack trace is especially helpful, if applicable.

1:11 muhoo: ~english

1:11 clojurebot: Huh?

1:11 muhoo: ~english do you speak it

1:11 clojurebot: It's greek to me.

1:11 muhoo: haha

1:12 escherize: i have a question actually

1:12 escherize: i have a function defintion like (defn f [arg] ["stuff..." arg "stuff"])

1:12 actually it's more like

1:13 i have a function defintion like (defn f [arg] [1 2 3 (- arg 30)])

1:13 is there a way to take f itself and get the fact that it's using (- arg 30) instead of -25 or whatever

1:14 ddellacosta: escherize: what do you mean, look into the function itself?

1:15 escherize: given the fn, i'm trying to get the names of the arguments, and how the args are used

1:16 ddellacosta: escherize: well, metadata may help somewhat

1:16 ,(defn foo [a b] (+ a b))

1:16 clojurebot: #'sandbox/foo

1:16 ddellacosta: ,(meta #"foo)

1:16 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading regex>

1:16 ddellacosta: whoops

1:16 ,(meta #'foo)

1:16 clojurebot: {:arglists ([a b]), :ns #<Namespace sandbox>, :name foo, :column 0, :line 0, ...}

1:17 ddellacosta: escherize: as far as how the args are used, I suspect you'd have to write a macro to do that, but maybe other folks know better...

1:17 escherize: mm, i was afraid of that

1:18 but that's actually useful too. thanks ddellacosta

1:18 ddellacosta: escherize: np, glad I could help

1:43 amalloy: escherize: given a plain function, your goal is unachievable: the information simply doesn't exist

1:43 but you can write a macro (defn-introspectable [a b c] (do-whatever a b c)) that saves that information for later

1:43 escherize: amalloy: what if it's not evaluated

1:43 i see.

2:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Cannot open <http://www.fourmilab.ch/cgi-bin/Hotbits?nbytes=128&fmt=hex&npass=1&lpass=8&pwtype=3'> as an InputStream.>

2:45 clojurebot: #<SecurityException java.lang.SecurityException: denied>

2:45 dissipate: ,(slurp)

2:45 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/slurp>

2:59 Amnesiou_: I noticed that native queues are mentioned in ClojureDocs, but I can't seem to find any relevant syntax token; are they deprecated?

3:37 alew: Amnesiou_: are you talking about PersistentQueue?

3:37 Amnesiou_: alew: Yes

3:37 alew: Amnesiou_: http://stackoverflow.com/a/2495105/1432017

3:37 Amnesiou_: there is no reader syntax for them

3:37 Amnesiou_: Any particular reason why?

3:38 alew: Amnesiou_: Not that I know of.

3:42 Amnesiou_: Thanks

3:45 Ah, I see it's not in cljs yet. Too bad.

3:48 …It actually is, as it seems. I had forgotten about the nomenclature differences in namespaces.

4:06 dsrx: is ##(assoc-in {:foo "bar"} [:foo] "baz") as good as I'm gonna get for idiomatic "add or replace" on a hashmap?

4:06 lazybot: ⇒ {:foo "baz"}

4:06 dsrx: actually... that really isn't that bad

4:07 beamso: ##(assoc {:foo "bar"} :foo "baz")

4:07 lazybot: ⇒ {:foo "baz"}

4:07 dsrx: beamso: yeah... i tried that and then it turns out i completel misread what the repl said

4:09 beamso: ##(conj {:foo "bar"} [:foo "baz"])

4:09 lazybot: ⇒ {:foo "baz"}

4:09 dsrx: danger of using "bar" and "baz" as test strings, they look too similar

4:09 beamso: i think that will work with a map as the second argument as well

4:09 ##(conj {:foo "bar"} {:foo "quux"})

4:09 lazybot: ⇒ {:foo "quux"}

4:10 dsrx: nice nice. i dunno how i forgot assoc and conj would do that, i blame spending too much time with ruby this week

4:11 beamso: i think you just have to check clojuredocs for the examples to see the examples

4:11 or try in a repl

4:24 chare: ok guys

4:24 suppose I wanted to make something like reddit where you have comments and stuff

4:24 how do I make that web app with clojure

4:25 scottj: chare: that's way too broad of a question

4:25 chare: scottj what pieces do I use

4:25 come on you gotta know this

4:26 with ruby I would like use rails and other stuff right?

4:27 scottj: chare: there are tons of web libraries you can choose from. compojure is the most common web server library.

4:28 chare: specifically the Web Frameworks section

4:30 chare: need more guidance than that

4:30 jballanc: chare: Rails is a framework, in general the Clojure community favors libraries over frameworks

4:30 scottj: chare: be more specific than that

4:31 chare: so i'm going to need to store comments and stuff like reddit does. So i use something like postgresql db

4:31 how do I interact with postgres

4:31 do i got some ORM with compojure?

4:31 i know that rails got the activerecord stuff for postgres

4:31 jballanc: chare: there's a number of libraries for working with DBs

4:31 some are more towards the ORM side of things, others are just ways to run queries

4:32 chare: i don't like the vague answers

4:32 need concrete stuff

4:32 jballanc: SQLKorma is probably one of the more popular toward the ORM side of things

4:32 cmdrdats: chare: compojure is purely a routing library

4:32 has nothing to do with db

4:32 scottj: chare: there is a book written specifically for you

4:32 jballanc: chare: apologies for being vague...but you have to understand that if you expect a 1-to-1 translation of Rails concepts to Clojure, you're going to have a bad time

4:32 cmdrdats: http://www.clojure-toolbox.com/

4:33 chare: omg another pots of the toolbox

4:33 oh wtf you post a book that costs money

4:33 cmdrdats: lol chare

4:33 moving along then

4:34 scottj: chare: fine, you need clojure, leiningen, a computer, compojure, a web browser, clojure/java.jdbc

4:34 chare: anything else?

4:34 jballanc: scottj: emacs?

4:34 ;-)

4:34 cmdrdats: emacs! and an elisp book

4:35 scottj: it's free though

4:35 cmdrdats: scottj: a computer isn't though

4:36 chare: cmdrdats, so you got a pdf of the book that you can link to?

4:37 scottj: chare: he only mentioned the elisp one, as a joke.

4:37 cmdrdats: sure - http://www.gnu.org/software/emacs/manual/pdf/eintr.pdf

4:37 xsyn: Why does Clojuredocs only have 1.2.0 and 1.3.0?

4:37 chare: cmdrdats WRONG BOOK I MEAN THE WEB ONE

4:37 scottj: xsyn: something about the way it was built made it hard to upgrade. there have been discussions about it on the mailing list

4:38 chare: I mentioned that book. No, sorry.

4:38 jballanc: xsyn: there's also http://clojure-doc.org

4:38 a bit of a different direction though

4:38 but not covered by the CA, so more open to outside contributors

4:39 if it's in the first world though, no. buy it yourself.

4:40 chare: there are TONS of blogs and docs on compojure and java.jdbc

4:40 xsyn: scottj: I'm in Africa?

4:41 (which is not a country)

4:42 chare: so you guys think that clojure with compojure, etc. is better than ruby on rails?

4:42 cmdrdats: chare: no, it's way worse

4:42 chare: you being sarcastic?

4:43 scottj: chare: compojure is better than rails like a bicycle is better than a car

4:43 cmdrdats: lol, not at all :P 'better' is completely a matter of perspective

4:44 chare: you guys are not giving me straight answers

4:44 scottj: you asked what he thinks. he thinks rails is better.

4:47 cmdrdats: if you know ruby and not clojure, and you have 10 minutes to bash out a throwaway prototype of something

4:47 chare: I refuse to use imperative programming

4:48 I only use clojure, erlang, haskell, etc...

4:48 scottj: chare: congrats

4:49 xsyn: *chuckle*

4:50 chare: what is so funny?

4:50 cmdrdats: chare: anyhow - it's been a fun conversation, thank you, but if you want to chat more about it - chat me directly and I'll be happy to assist.

4:51 chare: uh no I don't do private cyber sex chat if that is what you're asking

4:52 scottj: you private chatted me, so just be honest with cmdrdats, tell him he's not your type

4:53 you can't be with someone who likes rails :)

4:54 cmdrdats: hey, I never said I liked rails

4:55 chare: scottj are there other web clojure books out there

4:55 that don't cost money

4:58 jballanc: cmdrdats: yeah, the clojure-doc articles can be hit or miss, but they've been steadily improving

4:59 chare: ok team

5:00 cmdrdats: jballanc: I'm very impressed!

5:00 chare: is to kill ruby on rails and python django

5:00 clojure MUST WIN

5:00 dissipate: hi

5:00 jballanc: cmdrdats: which reminds me that I've been meaning to write up something for them on core.logic, just haven't had the time

5:00 dissipate: chare, i'm trying to get away from ruby and python, but clojure jobs are slim

5:01 clojurenoob: hey guys, how do I remove instances of a backslash character from a string ? I've failed with all sorts of different attempts

5:01 dissipate: chare, BTW, hasn't clojure already won?

5:01 cmdrdats: ,(.replaceAll "test/test.clj" "[/]" "")

5:02 clojurebot: "testtest.clj"

5:02 cmdrdats: oh, lol - backslash...

5:02 dissipate: chare, i don't want rubyistas and pythonistas coming over to clojure

5:02 clojurenoob: yeah cmdrdats :-)

5:02 cmdrdats: ,(.replaceAll "test\\test.clj" "[\\]" "")

5:02 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

5:03 cmdrdats: dissipate: there's no competition in which to win.. :P

5:03 clojurenoob: cmdrdats that last example fails for me

5:03 regex.Pattern.error

5:04 dissipate: cmdrdats, well, the competition is jobs. more jobs for clojure, the better.

5:04 cmdrdats: hmm, one sec

5:04 scottj: ,(clojure.string/replace "foo\\bar" "\\" "")

5:04 clojurebot: "foobar"

5:04 cmdrdats: clojurenoob: that'll teach me for clojurebot'ting off the cuff

5:05 clojurenoob: cmdrdats: no worries :-)

5:06 cmdrdats: dissipate: perhaps - but while it's a good thing to have a higher demand, it also means that there's more people on board for the wrong reasons (ie. money and software craftsmanship)

5:06 sorry

5:06 bob2: clojurenoob, how did backslashes get in the string?

5:06 cmdrdats: lol

5:06 money instead of software craftsmanship

5:07 dissipate: cmdrdats, that's why people are in ruby and python, right?

5:07 clojurenoob: bob2: clj-json 'generate-string' put them in there

5:07 bob2: it generates something like : {\"k2\":\"blurb\",\"k1\":\"blurb\"}

5:07 dissipate: cmdrdats, i think clojure might be in a sweet spot now. it's big enough to get a job if you really hustle, but not big enough to draw in the money grubbers

5:07 clojurenoob: and I want to remove the backslashes

5:08 bob2: clojurenoob, nope

5:08 clojurenoob, that's just what the repr is

5:08 cmdrdats: dissipate: hmm, I'm not exactly qualified to speak for the Ruby camp, but I think they go there for the productivity gains.

5:08 bob2: clojurenoob, ie it has no backslashes in it, that's just how it prints out strings that have " in them

5:08 clojurenoob, this is a common XY problem in python too

5:09 clojurenoob: bob2: I'm throwing that in a string and outing it on stdout so people can copy the string and run it (does that make sense? )

5:09 dissipate: cmdrdats, there are some smart people in the ruby community, but i keep seeing sites like: 'learn ruby on rails in 5 nanoseconds'

5:09 clojurenoob: so while it may just be a repr... I kind of need to remove them in the rep

5:09 bob2: clojurenoob, nope

5:09 clojurenoob: (hopes this makes sense :-) )

5:10 bob2: clojurenoob, how do you think you enter strings that have " in them into the repl?

5:10 clojurenoob: bob2: I'm not tackling this in the REPL, its part of a cli

5:11 so I think you are right, it is the repr that contains these chars

5:11 bob2: user=> (count "\"")

5:11 1

5:11 clojurenoob: but... I need to remove them or anyone copying the command output from the cli will not be able to run it because of the chars

5:11 bob2: you don't

5:11 the format for /displaying/ strings that have " in them is the same as the format for /entering/ strings that have " in them

5:12 dissipate: clojurebot, is clojure your first programming language?

5:12 clojurebot: excusez-moi

5:13 dissipate: oops. :P

5:13 clojurenoob: bob2: I'm trying to output a string like... "curl -v -H 'Content-type: blah' --data '{"k2":"blurb","k1":"blurb"}' ..."

5:14 dissipate: clojurenoob, is clojure your first programming language?

5:14 clojurenoob: so it can be copied from stdout , pasted into terminal and run

5:14 bob2: then don't do that

5:14 clojurenoob: dissipate: yes

5:14 bob2: what can I do instead ?

5:14 bob2: generate --data "{\"bong\": \"hits\"}"

5:15 clojurenoob: I'll give it a go

5:15 thanks

5:15 dissipate: hmm, interesting. i thought people learning clojure as their first language was a rarity.

5:16 i thought we were all C++, Java, Python, Ruby and perhaps .NET burn outs and refugees

5:16 clojurenoob: dissipate: it looks cool, I like the idea of prefix notation and consistency etc

5:16 I don't want to be mentally scrambled by the other stuff :-)

5:16 dissipate: clojurenoob, keep up the good work. you are on a good path. :D

5:17 clojurenoob: I had a look at Scala, but its a bit crazy :-)

5:17 dissipate: clojurenoob, i keep seeing talks on Clojure by people who had done Java for 15 years. don't be that guy.

5:17 clojurenoob: haha

5:18 dissipate: clojurenoob, yeah, OOP is actually bad for solving most problems. the vast majority of OOP code in the corporate world is just a complete mess. the 'reusabillity' of OOP was a false promise. :(

5:19 clojurenoob: seems clojure breaks things apart to make things simple... I need it simple because I'm simple :-)

5:22 dissipate: clojurenoob, yeah, working with data structures directly is great. however, i have seen some pretty 'intense' clojure code. but it's intense because it is doing a lot in a short amount of space. idiomatic clojure is extremely clever IMO. just have to wrap the brain around it.

5:22 clojurenoob: yep, I'm just doing simple stuff atm

5:22 even failing on string manipulation :-)

5:23 dissipate: clojurenoob, that's because it's your first language. but you are lucky because your brain won't be clouded with bad habits and idioms from other languages.

5:26 chare: so guys how do you architect a gameloop in functional style with clojure

5:26 all the tutorials are all imperative languages for game architecture

5:27 clojurenoob: bob2: I tried your suggestion, but unfortunately : --data "{\"bong\": \"hits\"}" is part of a larger string, so it ends up being : --data \"{\"bong\": \"hits\"}\"

5:27 unsure how to proceed

5:28 I kind of need a way to format one big string

5:31 dissipate: chare, what kind of game?

5:31 chare: ANY

5:32 cmdrdats: nice article on functional game design: http://clojurefun.wordpress.com/2013/03/21/game-development-in-clojure-alchemy-7drl-post-mortem/

5:33 dissipate: chare, i was actually thinking about a game design that used a rule engine

5:34 dissipate: chare, well, a rule engine with events

5:34 cmdrdats: I recently read this very interesting series as well: http://prog21.dadgum.com/23.html

5:35 dissipate: chare, imagine events occur and then the rule engine updates the rule database using backward and forward chaining techniques and then the current 'rule database' at any given moment is rendered on the screen

5:36 chare: like i was thinking your typical game that uses oop has a type hierarchy so it can shove everything into a CObject container which allows iterating over it to do whatever physics or whatever entity interactions

5:37 so in functional languages you do what instead

5:38 dissipate: chare, replace that with data structures passed through pure functions

5:40 chare, entity interactions would be done via async calls

5:42 noidi_: chare, in Clojure you could use protocols for polymorphism

5:43 say you want to update things in your game loop, but each type of thing needs to be updated differently. just define a protocol containing an update function that takes a thing and returns an updated thing.

5:44 (defprotocol Thing (update [thing])))

5:44 clojurenoob: oh... my problems were because I was using 'prn' instead of 'println'.. better go read up on those two

5:44 dissipate: noidi_, and particle collisions?

5:45 clgv: clojurenoob: println is for output. prn is for serialization of datastructures to text

5:45 noidi_: dissipate, I've never written a particle system, but I'd assume it would be a function from a set of particles to a new set of particles

5:45 clojurenoob: clgv: due to ignorance, I kind of thought prn was just an alias :-)

5:45 whoops

5:46 dissipate: noidi_, sure, but you need to detect the collision somehow

5:46 clgv: ,(let [s "Hello World"] (println s) (prn s))

5:46 clojurebot: Hello World\n"Hello World"\n

5:46 pyrtsa: pr ≈ print readably, prn ≈ print readably with newline

5:47 clgv: pyrtsa: thoufh that naming is confusing - readably for whom? ;) in this case it is for the clojure reader

5:47 *though

5:47 pyrtsa: Yeah.

5:48 Agreed.

5:48 clojurenoob: now I'm reading the docs I'm doing better :-)

5:48 usually read the manual as a last resort

5:48 clgv: clojurenoob: you got one of the clojure books?

5:48 clojurenoob: did not help here

5:48 dissipate: ,(doc prn)

5:48 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

5:48 dissipate: ,(doc pr)

5:48 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

5:48 pyrtsa: println is bad for printing data structures though. It removes quotes around strings nested in data structures as well:

5:48 ,(let [xs [1 "foo" {:a "bar"}]] (println xs) (prn xs))

5:48 clojurenoob: clgv: I like the thought of Joy of Clojure, but its a bit advanced for me

5:48 clojurebot: [1 foo {:a bar}]\n[1 "foo" {:a "bar"}]\n

5:48 Pardon?

5:49 dissipate: clojurenoob, have you tried brave clojure?

5:49 clojurenoob: dissipate: not heard of that

5:49 clgv: clojurenoob: yeah. start with "Clojure Programming" or "Programming Clojure" (Rev 2)

5:49 dissipate: clojurebot, free online book: http://www.braveclojure.com/

5:49 clojurebot: I don't understand.

5:49 dissipate: clojurenoob, http://www.braveclojure.com/

5:50 noidi_: dissipate, I'm not familiar with collision detection either, but again, I'd assume you'd compose a function that updates each particle's position according to its velocity with another that resolves collisions, updating each particle's position and velocity

5:50 clojurenoob: thx for the recommendation

5:50 dissipate: clgv, what about brave clojure?

5:50 clgv: dissipate: didnt read it yet

5:50 noidi_: (comp resolve move) :)

5:51 dissipate: noidi_, and would you update those in a transaction?

5:52 noidi_: you don't need a transaction unless you want to update different parts of the world at different rates

5:53 dissipate: noidi_, would it be possible to model the game world using a rule engine?

5:53 noidi_: your game loop can be (loop [state initial-state] (recur (comp render update) state))

5:54 dissipate: noidi_, er, not just possible, but effective as well

5:55 noidi_: no idea :)

5:55 dissipate: noidi_, i'm thinking of a 3 layer architecture

5:56 noidi_: here's a little "game loop" using a tiny wrapper I wrote for quil https://www.refheap.com/57666

5:57 dissipate: noidi_, event emitters (these add facts to the rule engine in real time from external events like a player hitting a button), the rule engine itself which uses backwards and forwards chaining techniques to generate new facts that represent state in the game world, and the rendering engine which takes snapshots of the current rule set and renders the game world on screen

5:58 noidi_: (the only reason the previous state is kept in that example is that I was showing someone how simple it would be to add an undo feature to a purely functional drawing program)

5:59 dissipate: the interesting thing is you could write event emitters that queried the rule set and injected random events based on the rule set at that time

6:00 collisions would be handled entirely by the rule engine

6:01 noidi: sound interesting. write a blog post about it if you ever give it a try :)

6:03 *sounds

7:09 Pate_: Is it possible to write a macro/function that overrides a function with an implementation that calls the original implementation, but returns something else? Like if you wanted println to return the arguments passed to it.

7:11 ddellacosta: Pate_: if you can wrap stuff easily you can do that with with-redefs pretty easily

7:12 hyPiRion: Pate_: already exists, sort of. (alter-var-root #'println (fn [f] (fn [& args] (apply f args) args)))

7:12 Pate_: thx hyPiRion

7:14 noidi: Pate_, check out the with-redefs function and https://github.com/technomancy/robert-hooke/

7:15 Pate_: what is this data type? #'examine

7:15 is it a reader macro?

7:15 josephwilk: var

7:16 (var4 (

7:16 (var examine(

7:16 Excuse me, wrong channel

7:16 Pate_: oh, I was really confused for a second :)

7:24 bob2: Pate_, var quote

7:25 ie #'foo <- always the 'var' foo, ignoring any shadowing bindings

8:07 clojurebot: (var inc)

8:23 k3ny: test..

8:24 1

8:24 thorn: 2

8:28 fredyr: 2

8:28 3

8:34 nightfly: 4

8:35 clgv: 42

8:36 isaacbw: so #' has a different meaning from CL?

8:36 k3ny: test..

8:36 isaacbw: k3ny: stop :(

8:37 I was confused about why clojure had #', since it's a lisp 1

8:44 llasram: isaacbw: Yes

8:46 dnolen_: isaacbw: unrelated to #' in CL. #' gives you the var, mostly useful for meta programming, but also enables live development in some cases like Ring.

9:22 isaacbw: is there a decent workflow loading a namespace just for the repl, so that I don't have to write a bunch of (use ...) and (require ...) every time I open the repl?

9:22 *for

9:25 wink: isaacbw: define it in a file, in a ns and use (in-ns?

9:25 or am I missing somethign?

9:26 isaacbw: so I guess what I'm asking is if lein has a way to set a file as not part of the project code itself, but as something to autoload when the repl starts

9:27 wink: ah, no clue, sorry. I would just use a bogus file and then (in-ns 'bogus) :P

9:32 joegallo: isaacbw: you can use :repl-options {:init ...} to load arbitrary code

9:32 you'd put that in ~/.lein/profiles.clj in your :user profile.

9:32 isaacbw: joegallo: so no way to do it per-project?

9:33 joegallo: ah, let me see if i understand your question:

9:34 are you saying "oh, hey, all the nses in my project are requiring x, y, z, etc, and i want to just say that once and be done with it"?

9:34 isaacbw: let me give a concrete example. I don't need ring.mock.request in my actual server code, but I like to have it in my repl. So I do (use 'ring.mock.request) every time I open the repl

9:34 joegallo: ah, i see

9:34 well, there's two ways i see to do that

9:34 isaacbw: I'm just imagining how much of a pita that workflow will be when I have more "repl libraries" I want to include

9:35 joegallo: on is to have something like your-project/test/repl.clj and you could just require and in-ns to there (which was suggested already)

9:35 next, i believe user.clj is loaded when you are placed in a repl

9:36 so you could just drop some forms into user.clj and then you'll have those forms in your repl when you load it, because, well, you're in the user namespace.

9:36 i'm not 100% positive that works, but i'm like 95% :)

9:36 and lastly, i'm pretty sure you could also use :repl-options {:init ...} from inside project.clj, i don't *think* it has to just be in a profile...

9:37 so there's three possible ways you could do it

9:38 hyPiRion: there should be a distinct-by.

9:38 pjstadig: i think user.clj would be loaded even in production, but you could drop it in your test directory so it is only available in your dev environment

9:38 but i think the third option is probably the best (using a :repl-option in your project.clj)

9:39 that is, agreed re:test/user.clj, and separately, also agreed re: :repl-option (as that seems the most discoverable to me, user.clj seems like magic...)

9:41 and confirmed that both options work, and further that they work happily together, so you could even mix and match if you have a criminal mind

9:42 clgv: isaacbw: if your repl supports backward search you can do it without config. just type "(use" and activate backward search, usually you will have the use-command you want in 3-4 keypressed

9:44 isaacbw: cool, thanks all

9:44 I'll try my options

11:10 jjttjj: what's the simplest way to output what is captured by tools.logging?

11:11 joegallo: cat some.log

11:13 if you're asking for the sake of like, "oh i want to see that xyz is being output to the logs during a test", then you might look at using with-redefs on clojure.tools.logging/log*

11:16 jjttjj: hmm you mean things should automatically be written to some.log? it doesn't seem to be the case. Just using a library that seems to be acting wierd sometimes and it has a ton of :debug logging in the code that will probably be useful

11:18 joegallo: i see, so you're using a library that's using clojure.tools.logging, but you're not seeing any logging.

11:18 jjttjj: exactly

11:18 joegallo: how about you configure c.t.l. to use log4j for logging, and then it'll log to wherever you tell it to log

11:18 stuartsierra: Time to spend some quality time with the Logback (or Log4j) & SLF4J manuals.

11:19 joegallo: eh, there's a sample log4j.properties in the c.t.l. readme (https://github.com/clojure/tools.logging/blob/master/README.md)

11:19 jjttjj: ok cool thanks

11:20 joegallo: you're welcome

11:57 yedi: seangrove: omchaya is pretty sexy -- how did you come up with the architecture / did you look into other methods for organizing client side applications?

11:58 seangrove: yedi: It's how we built our production apps - it grew out of that. A lot of the patterns emerged from growing, refactoring, growing, etc.

11:59 yedi: Definitely open to other ways of organizing SPA though. This is the best we've found so far, but if there's something even better, that's fantastic

11:59 Need to come up with a catchy name for the pattern though, and also blog about it. Both of those would help

12:00 shep-werk: seangrove: +1 blogpost. I like to learn

12:03 yedi: having all the app events handled synchronously in one place seems perfect for dealing with spaghetti code

12:03 seangrove: do you have any plans for omchaya (the app), seems like cool stuff

12:05 seangrove: yedi: I'd like to continue building it out as a large, best-of-breed reference app

12:05 Things like integrating prismatic's Schema + cljx (like we do in our app) to verify data structure/shape between server/client, fuller testing, server-agnostic clients, etc.

12:11 Oh, and actual layout managers, reusable components, etc. That's the stuff I've been hammering on recently, but I've been going a roundabout way.

12:14 yedi: seangrove: not interested in actually getting ppl to use omchaya the app, and not just use it as a reference

12:14 seangrove: yedi: Well, that would be cool, but it would fall out of it just being a good app

12:14 yedi: Certainly not interested in running a business on top of it

12:15 Though making it multitenant is on my todo list

12:16 ystael: I'm having trouble using prismatic/schema's coercion support to define a coercion into an s/defrecord type

12:17 I think I need to define a coercion matcher that applies map->MyRecordType to a raw map, but it's not clear to me where to attach it

12:17 Is there an example of this anywhere?

13:09 chris-free:

13:10 isaacbw: would something like contrib.nlp make sense? (it would be a common API like JDBC, but for NLP libraries)

13:10 the thing I'm not sure makes sense is the contrib.*, but it would be cool

13:17 mpenet: isaacbw: you are building on another lib (open-nlp, stanford, etc)?

13:18 isaacbw: mpenet: well, it would be an abstraction layer with pluggable drivers for standard, clearnlp, opennlp, nltk, etc

13:19 mpenet: That'd be nice. That said, I'd just do it as a regular lib first. There's actually little gain from doing a contrib lib imho

13:20 isaacbw: except I would feel super cool :D

13:20 mpenet: They have boring names most of the time, not cool :)

13:21 to be serious, nothing prevent you to make it a contrib later

13:21 prevents*

13:22 sdegutis: All I'm saying is, I just think libraries shouldn't be so lax with what their inputs may be. It just leads to confusion when an argument is allowed to be either a string or a map.

13:22 jaccarmac: Hi!

13:23 isaacbw: sdegutis: I agree completely

13:23 everyone clojure developer should spend time with haskell on the side

13:23 teaches good habits

13:23 jaccarmac: sdegutis: What is that complaint's context?

13:23 isaacbw: *every

13:23 jaccarmac: isaacbw: Teaches you to think. Even when you have no idea what's going on...

13:24 isaacbw: lol

13:24 I finally figured out the point of monads

13:24 it's so simple once it makes sense, but so difficult until it does

13:24 sdegutis: jaccarmac: I found a function in my code which takes a response argument and leaves it along if it's a map, but if it's a string, it wraps it like {:body response :status 200}

13:25 isaacbw: I tried to learn Haskell but I had no motivation so I played Starcraft 2 instead that day.

13:25 jaccarmac: isaacbw: Pretty much.

13:25 sdegutis: Hmmm... Yeah, doesn't seem very idiomatic. But polymorphism is useful in some cases i.e. map, reduce, and friends.

13:27 technomancy: clojure was mentioned in the erlang factory keynote as having a significantly better getting started story than erlang

13:27 I loled

13:27 locks: sdegutis: they are? that's nice

13:27 Raynes: technomancy: Well, we kinda do

13:27 sdegutis: no, just making a joke

13:28 Raynes: technomancy: "install leiningen"

13:28 sdegutis: sorry, I need practice making jokes

13:28 bbloom: technomancy: you should have shouted "YOU'RE WELCOME!"

13:28 sdegutis: Raynes: erlang's leiningen is elixir no?

13:28 Raynes: sdegutis: Erlang's leiningen is Elixir's build tool, mix.

13:28 hyPiRion: sdegutis: no, that's another language on top of erl

13:28 technomancy: Raynes: I agree, but it just shows how crazy things are in erlang land

13:28 Raynes: sdegutis: Because I made it that way :P

13:29 I purposely wrote the beginnings of the tool before anyone else got to it so that I could inject leiningen into it as quickly as possible.

13:29 sdegutis: Raynes: so elixir:clojure, erlang:java, mix:lein?

13:29 Raynes: I couldn't bear the thought of Elixir having anything less. :(

13:29 Sure.

13:29 If we need to make those comparisons.

13:29 sdegutis: which we do

13:30 hyPiRion: (inc Raynes) ;; for taking one for the team

13:30 lazybot: ⇒ 43

13:30 sdegutis: oh sorry, im getting a bit off topic here

13:30 ill take it back in the offtopic version of this channel

13:31 TimMc: sdegutis: And where would that be?

13:31 sdegutis: #clojure-social

13:32 But yeah, I think those kinds of uses of value introspection are really abuses.

13:33 The sole purpose is convenience, but in the long run it really hurts convenience, since you no longer have confidence in what types the functions take in, and so you have to check the docs for that function(s) every time.

13:38 clojurebot: who owns you?

13:38 clojurebot: Pardon?

13:39 sdegutis: $seen Pardon? 13:39 lazybot: I have never seen Pardon?. 13:40 isaacbw: sdegutis: it's hangedman or osmething like that 13:41 joegallo: it's hiredman :) 13:41 isaacbw: oh rigfht 13:41 dammit, so many typos today 13:41 I look a fool 13:41 joegallo: i've been having a week of typos, so i'm totally sympathetic 13:52 jaccarmac: Clojure on Glass, anyone? 14:00 amalloy: isaacbw: you finally figured them out, eh? i think the next step is one or two crises of faith, and *then* actually remembering what you learned when you figured them out 14:01 locks: LOL 14:09 arrdem: so pardon the heresy, but what Haskell books (if any) would you lot suggest? 14:09 TimMc: "Baby's First Monad" 14:10 systemfault: arrdem: LYAH 14:10 patchwork: I second LYAH 14:10 arrdem: systemfault: really? I didn't find it terribly illuminating on my first pass, although I did read it without a GHCI instance to hand 14:10 patchwork: (except for the fonzie bit, blech) 14:11 arrdem: You have to type everything in and experiment with concepts to make it stick 14:11 arrdem: patchwork: :P this sounds familiar... 14:11 systemfault: arrdem: I bought both LYAH and RWH... RWH can be a hard read if you're starting. 14:11 patchwork: We are working through it in a workshop and it is good to have a group of people to talk through it with and do experiments with the concepts etc 14:12 You don't read it like a novel, it is a guide for your own explorations really 14:12 arrdem: gotcha 14:13 justin_smith: so kind of like Finnegans Wake 14:14 patchwork: Finnegans Wake just open in the middle and start reading, so… a little different 14:14 justin_smith: riverrun, past Eve and Adam's, from swerve of shore to bend of bay, 14:14 brings us by a commodius vicus of Functors and IO Monads to Sir Tristram, violer d'amores, fr'over the short sea, had passencore rearrived from static type checking. 14:15 * justin_smith is off to write The Best Monad Tutorial Ever 14:15 steerio: is it possible to do the equivalent of execv() in the jvm? 14:15 replacing the process image with that of another to be started 14:19 patchwork: Haven't seen bitemyapp around here for awhile… or did he just change his nick? 14:20 The channel has been oddly… civil 14:20 TEttinger: steerio: http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html it does not look like it 14:21 justin_smith: this could be because process clone and exec isn't portable to various jvm targets? 14:21 TEttinger: steerio, what I've found so far has not been encouraging... Runtime/exec always starts a separate process, and ProcessBuilder/start always starts a new one too 14:21 steerio: yep 14:22 TEttinger: justin_smith, yeah, the docs even mention it being non-portable for all cases 14:22 (like dos processes starting on win32) 14:22 steerio: anyway, i'll probably work around this easily 14:22 thx 14:23 amalloy: patchwork: he moved to austin and to #haskell 14:23 justin_smith: depending on compatibility needs, you could just use the libc function or directly use the linux system call 14:24 arrdem: patchwork: can confirm. had dinner with him a couple of times... doubt he'll be back in here ever :c 14:28 tbaldridge: arrdem: well that was kindof his own fault. 14:28 one of these days I should go to #erlang and start convincing them to use shared memory STM. I'd probably have about as much success. 14:30 arrdem: tbaldridge: yeah you're entirely correct and more's the pitty. 14:31 aaanyway. 14:31 tbaldridge: lol 14:34 circ-user-hmcDt: Hello using a new irc client and seems to be acting can someone respond if they receive this message? 14:34 arrdem: circ-user-hmcDt: pong 14:35 Ravi__: thanks 14:35 arrdem: Ravi__: if you ping clojurebot it'll pong for you too. 14:36 AeroNotix: clojurebot: ping 14:36 clojurebot: PONG! 14:36 Ravi__: ah perfect thank you 15:00 stuartsierra: Any more feedback on the new G.Closure lib package? https://groups.google.com/d/topic/clojure/Ekd_ptNY8Jc/discussion 15:01 seangrove: stuartsierra: I can give it a try on a couple of projects if that helps. Anything I should look out for specifically? 15:02 stuartsierra: seangrove: Mostly just make sure all the goog.* stuff works, especially things in or dependent on the G.Closure third-party extensions. 15:19 seangrove: stuartsierra: Our test suites are pretty small, but they all pass 15:21 stuartsierra: seangrove: Good, thanks. 15:54 abaker: is there a way to tell lein to prefer local m2 over maven central? 15:55 joegallo: why do you think you need to do that? 15:56 abaker: local patches on third party jars, in fact general ordering of repos would be good where different repo servers may be preferred 15:56 technomancy: abaker: it always prefers cached jars 15:56 abaker: ah there we go 15:56 thanks 15:57 hyPiRion: abaker: if you need to depend on a patched third party, you should probably deploy the patched jar instead 15:57 abaker: and the :repositories configuration, that'll just traverse the vector till it finds one? 15:57 technomancy: np 15:57 abaker: more or less 15:58 abaker: hypirion: yeah in the process of doing that, but the patched jars still exist for now 15:58 hyPiRion: ah 16:00 TimMc: abaker: You should use different maven coordinates for your patched version. 16:00 katratxo: hi all, is there are way to debug (print) the classpath used by the javac task in lein ? i'm trying to debug lein protobuf compilation issue 16:01 abaker: TimMc: yeah, dropping them in custom group id's is the work in progress 16:01 cbp: katratxo: not the answer to your question but lein protobuf doesn't work on windows if you're using it 16:02 katratxo: cbp: not really, i'm on archlinux ;) 16:03 TimMc: abaker: This should be your first priority when maintaining a forked version -- it's otherwise very easy to get mixed up and have major dev and maintenance problems. 16:03 hyPiRion: katratxo: DEBUG='y' lein protobuf probably 16:03 cbp: katratxo: lein protobuf uses a bash script so you can just check that 16:03 hyPiRion: /s/probably// 16:04 abaker: TimMc: yep, I know 16:05 katratxo: hyPiRion: yes i tried that checking lein code (when/debug ...) but didn't print too much 16:05 cbp: thanks, will check that 16:08 cbp: the code gets generated but the lein javac part is the failing one, any hints? https://dpaste.de/LWJE/raw 16:09 phao: Hi. 16:09 loliveira: Any LightTable user around? I can't make log4j log to LightTable's console. 16:09 cbp: katratxo: I think you might have an error on your protobuf file 16:10 or files 16:10 katratxo: cbp: https://dpaste.de/gV1J/raw 16:11 the example one 16:13 cbp: katratxo: I found this https://code.google.com/p/protobuf/issues/detail?id=493 16:13 I'm trying to find the actual damn github repo but failing miserably 16:13 All I'm finding is an ancient 0.1 version 16:14 Ah nevermind they just didnt update the readme 16:36 katratxo: heh sorry for not being of help. I tried reproducing and got a different error. Protobuffers are no fun :-( 16:43 katratxo: cbp: hehe, thanks anyway :) 16:45 dacc: katratxo: i had some good success with thrift+clojure+lein 16:47 llasram: cbp: What are you using protobufs for? 16:48 katratxo: dacc: using http://xsc.github.io/thrift-clj/ ? 16:48 cbp: llasram: The clojure driver for rethinkdb uses protobufs 16:48 llasram: ah 16:48 So can't be helped 16:48 dacc: katratxo: yes, also lein-thriftc 16:56 katratxo: cbp: now that you mentioned, the lein protobuf plugin 0.3.1 works fine https://github.com/bitemyapp/revise/blob/master/project.clj#L7 16:57 cbp: katratxo: good t kno 16:57 er 16:57 good to know 16:58 that reminds me i really need to maintain that project :( 17:08 arrdem: cbp: good news is that it's a pretty solid project, not too much work needed :P 17:35 cbp: arrdem: thanks :) 17:38 mheld: anybody here use dropwizard with clojure 17:39 technomancy: mheld: I don't think so. I'm tempted because the name is so good though. 17:40 mheld: technomancy: https://twitter.com/stevelosh/status/355160052333678592 17:40 technomancy: mheld: haha nice 17:41 sjl: mheld: we use dropwizard, and clojure, but not together 17:41 technomancy: clojurebot: dropwizard is http://gunshowcomic.com/316 17:41 sjl: also yes that ^^ 17:41 clojurebot: Ik begrijp 17:41 mheld: sjl: boo 17:41 sjl: also, who's we? 17:41 (if you don't mind me asking) 17:41 sjl: mheld: simple.com 17:41 mheld: I'm a fan! 17:41 sjl: thanks 17:41 mheld: congrats on the recent news :-) 17:42 sjl: clojure<->scala interop is pretty much nutbags most of the time 17:42 so we don't really try 17:42 arrdem: technomancy: <3 17:42 sjl: thanks 18:16 Anderkent: ,(binding [*print-meta*] (macroexpand-1 '(NewThing. ^long (long 0)))) 18:16 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: binding requires an even number of forms in binding vector in sandbox:> 18:16 Anderkent: ,(binding [*print-meta* true] (macroexpand-1 '(NewThing. ^long (long 0)))) 18:16 clojurebot: (new NewThing (long 0)) 18:16 Anderkent: Am I right in thinking macroexpand ate the type hint? 18:17 arrdem: Anderkent: no... the reader should eat it before macroexpand happens 18:19 Anderkent: ah, right, I'm not printing it under the binding 18:19 stupid mistake 18:21 amalloy: Anderkent: try, though, (.length ^String (doto "x" identity)) 18:21 in that case the typehint does get eaten during macroexpansion 18:23 arrdem: ,(meta (second '(.length ^String (doto "x" identity)))) 18:23 clojurebot: {:tag String} 18:24 arrdem: ,(meta (second (macroexpand '(.length ^String (doto "x" identity))))) 18:24 clojurebot: {:tag String} 18:24 arrdem: amalloy: lil help here? 18:25 amalloy: arrdem: you're not macroexpanding the doto 18:25 arrdem: yeah I was worried about that.. 18:25 danielszmulewicz: (:require [libpath.libname :as name]) is good in both Clojure and Clojurescript, but (:require (libpath [libname :as namee]), while perfectly fine in Clojure, won't compile in Clojurescript. Aargh. 18:25 arrdem: ok. 18:26 amalloy: in a repl, try: (set! *warn-on-reflection* true) and then eval it 18:27 dnolen_: danielszmulewicz: the second one just seems like an abomination 18:27 stuartsierra: I really wish prefix-lists for namespaces had never been included. 18:27 danielszmulewicz: dnolen_: the second one is handy when you have a lot of libnames under the same libpath, wouldn't you think? 18:27 dnolen_: danielszmulewicz: no 18:28 the ns form is an abomination 18:28 danielszmulewicz: dnolen_: so no prefix-lists for namespaces? 18:28 stuartsierra: what's the alernative? 18:28 dnolen_: danielszmulewicz: CLJS is closer to how the ns form should work but still makes too many concessions 18:29 stuartsierra: danielszmulewicz: Writing out the full namespace name. 18:29 If you have too many namespaces, that's a design problem. 18:30 danielszmulewicz: dnolen_ stuartsierra: your opinion interests me because it seems counterintuitive. The prefix lists saves us from repetition. This seems to be the rationale, right? So I am interested in why you reject it... 18:30 dnolen_: should according to whom/what? Like in Common Lisp? 18:30 technomancy: dnolen_: I'm curious what the concessions are 18:31 bbloom: namespaces != classes in java or whatever. you can put a few thousand lines of code in a single file/namespace and it's no big deal design-wise really 18:31 arrdem: Throw me on the curious list too. 18:31 stuartsierra: danielszmulewicz: You can't grep for it. It's harder to parse, both visually and programatically. 18:31 And it makes it more convenient to create many small namespaces, which I believe is unnecessary. 18:32 danielszmulewicz: dnolen_: I meant to ask how should the ns form look like in your opinion? What model do you have in mind? 18:32 Bronsa: well.. I moved to prefix lists for tools.analyzer.jvm since this https://github.com/clojure/tools.analyzer.jvm/blob/930ddbb6bc6e663f4fcaef54455b605fb41679e2/src/main/clojure/clojure/tools/analyzer/jvm.clj#L16-L40 was really too much :/ 18:32 danielszmulewicz: stuartsierra: OK 18:32 bbloom: dnolen_: it's kinda a shame how bad the ns form is given it's prominence at the top of each file 18:32 Bronsa: see now that's a design problem ... of clojure :-P 18:32 danielszmulewicz: bbloom: it is, right. I always have to look up the docs to remind myself how to work with it. 18:32 stuartsierra: I almost long for the days when literally the only loading option was "load-file" 18:33 danielszmulewicz: stuartsierra: but that's even more interesting: why are many small namespaces unnecessary? 18:34 bbloom: stuartsierra: bronsa's example is a place where i want something "export" like, where everything is not necessarily private, but i only really have ONE or a few api functions to expose 18:34 stuartsierra: danielszmulewicz: Because namespaces have no semantic meaning. If your symbol names don't clash, you don't need more namespaces. 18:34 arrdem: stuartsierra: except that you bring in more symbols for both the programmer and the compiler to handle than are strictly required 18:34 danielszmulewicz: stuartsierra: can I split a namespace in two files? 18:34 arrdem: stuartsierra: if I can throw an entire API in a single set of four functions and stash it away somewhere, why shouldn't I do so? 18:34 bbloom: danielszmulewicz: and if your names are clashing too frequently, than you have to simplify and/or invent some new names 18:35 arrdem: stuartsierra: no need for it to get inlined into some other larger ns.. 18:35 stuartsierra: Yes, you can split a namespace into several files with load, although I've never felt the need to do so. 18:35 Anderkent: I kinda like small namespaces, they're a natural way of separating concerns. Makes tracking things easier 18:35 technomancy: don't use load =( 18:35 arrdem: it's done in a couple of places in clojure core... 18:36 don't do it please. 18:36 stuartsierra: :) 18:36 bbloom: arrdem: the fundamental issue is that namespaces/files/vars/etc complect the issues of avoiding name collisions, organizing subsystems, exposing APIs, etc 18:36 danielszmulewicz: stuartsierra: I want files with little text in them for my sanity. So I would agree with one namespace only if I can spread over many files. 18:36 stuartsierra: I never intended to say you can only have one namespace. But most projects I see have too many, in my opinion. 18:36 bbloom: danielszmulewicz: unfortunately, you're better off just getting used to more text in each file 18:37 danielszmulewicz: stuartsierra: sorry, didn't mean literally one. 18:37 bbloom: danielszmulewicz: it's not ideal, but it's better than working against the grain 18:38 danielszmulewicz: bbloom: very interesting opinion and different than how I use to think. 18:38 stuartsierra: Summary of my take: Think of namespaces more like Java packages and less like classes. 18:38 bbloom: (inc stuartsierra) ; that's a good summary 18:38 lazybot: ⇒ 6 18:40 danielszmulewicz: Good people, here's a scenario: Suppose we're writing a client-side clojurescript application with ten Om components, I would naturally put each component in its own namespace in its own file. I gather that you would find this a terrible idea, right? 18:40 stuartsierra: As usual, I have an old blog post about it http://stuartsierra.com/2011/08/08/clojure-namespaces 18:41 danielszmulewicz: To me, I wouldn't mind put all these ten components in the same namespace (as far as names don't collide), but I would mind having eaverything in one giant file.... 18:42 beamso: i'd have no issues with 10 files if subsets of them were included on each webpage 18:43 if all 10 were included on each webpage :/ 18:43 Morgawr: how can I check in an if statement if a namespace is included/required/imported in a clojure script? 18:44 bbloom: beamso: that's not relevant b/c the compiler does tree shaking (ie dead code removal) 18:44 Morgawr: I mean, this is just for comfort's sake, I'm using LightTable + browser live editing and if I re-evaluate everything it keeps throwing a (harmless) exception about the namespace at the top being already required in the page 18:44 cbp: Morgawr: I think you can just eval the namespace name and check if it's not nil? 18:44 bbloom: danielszmulewicz: your components are what? 3 to 10 lines each? 18:44 danielszmulewicz: seems fine to have them in one file... 18:44 Anderkent: Hm, I still don't get what the problem with small namespaces is. I'd rather thing of directories as packages and namespaces as kinda class-like objects 18:45 danielszmulewicz: bbloom: More likely 25 lines each. 18:45 Morgawr: cbp: how do I do that? with eval? 18:45 bbloom: danielszmulewicz: step one: write smaller components :-) 18:46 danielszmulewicz: eh, nevermind. 25 is reasonable for om b/c of the verbosity of the html building forms 18:46 and the overhead of the various signatures for mounting, etc 18:47 danielszmulewicz: Of course. 18:47 bbloom: still, i blame browsers :-P 18:47 danielszmulewicz: bbloom: So that's a file with 250 lines. 18:47 stuartsierra: you really work with huge source files? 18:48 bbloom: danielszmulewicz: that's a tiny file 18:48 stuartsierra: What's "huge"? My Clojure source files are typically between 250 and 3000 lines. 18:48 hyPiRion: 250 lines is not that much. If you have search functionality, that should be fine 18:49 technomancy: leiningen has 5 namespaces over 300 loc 18:49 only one of them is outside leiningen-core (the pom task) 18:49 hyPiRion: (I'm guessing project.clj is the largest) 18:50 technomancy: hyPiRion: nearly by a factor of 2 18:51 cbp: Morgawr: sorry, actually just check if it's undefined 18:51 danielszmulewicz: I'm an Emacs user like most here, I suppose. We all have search functionality. 18:51 hyPiRion: oh wow 18:51 technomancy: danielszmulewicz: M-x imenu is great for that 18:51 cbp: Morgawr: since a cljs namespace is just a js object afaik 18:51 danielszmulewicz: But it's a cognitive habit. 18:51 technomancy: especially with ido 18:52 Anderkent: it's less about search and more about reducing the amount of context you have to keep; and with jump-to-declaration I don't see how having code split across multiple files is a problem 18:52 danielszmulewicz: technomancy: Ah, so that's your secret sauce! 18:52 cbp: Morgawr: actually that may not work with imports 18:52 amalloy: technomancy: that's pretty neat. i didn't know about imenu. how would i turn on ido for imenu? 18:53 cbp: Morgawr: sorry no clue :( 18:53 technomancy: http://p.hagelb.org/lein-line-count.html 18:53 cbp: Morgawr: to answer your how to question though, (nil? my-ns) 18:53 technomancy: amalloy: ido-ubiquitous does it 18:53 alew: borg 18:54 cbp: Morgawr: there may be a google closure function somewhere that you could use 18:54 justin_smith: I use outline-mode's hide-sublevels command to turn the buffer into the menu 18:54 then I go to the line I want, and re-expand 18:54 arrdem: technomancy: ooh scpaste... do like 18:54 danielszmulewicz: justin_smith: Cool. 18:54 Morgawr: cbp: heh, thanks for the help, it's probably more hassle than anything, I'll live with the harmless exception (or just comment out the line when I'm doing live editing) 18:55 justin_smith: show-all expands it all again 18:55 danielszmulewicz: stuartsierra: How do you navigate a 3000 loc file? 18:55 technomancy: arrdem: those counts include blanks and comments fwiw 18:55 justin_smith: hide-sublevels and show-all are in default emacs 18:55 arrdem: technomancy: ofc 18:56 stuartsierra: danielszmulewicz: search 18:56 hide-show-mode 18:57 M-. 18:57 danielszmulewicz: stuartsierra: Oh, that's interesting. Sound and simple. 18:57 stuartsierra: Ah, OK. 19:13 SegFaultAX: Is there a succinct way to describe reduce/fold to someone who doesn't already understand it? 19:13 Clojure doc sucks and Haskell's is too long winded. 19:13 ,(doc reduce) 19:13 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i... 19:14 arrdem: SegFaultAX: why not just explain it in terms of an accumulator loop? 19:14 SegFaultAX: arrdem: That's what I have right now. 19:14 rasmusto: yeah, do a looprecur and then its reduce equivalent 19:14 SegFaultAX: arrdem: But I'm trying to come up with a prose description as well. 19:14 * arrdem ponders 19:16 amalloy: SegFaultAX: you can also use something like ##(reduce (partial list '+) 0 (range 5)) as a visual aid 19:16 lazybot: ⇒ (+ (+ (+ (+ (+ 0 0) 1) 2) 3) 4) 19:16 SegFaultAX: Not necessarily for clj people. 19:16 amalloy: ,(reduce (partial list '+) 0 (range 5)) 19:16 clojurebot: (+ (+ (+ (+ (+ 0 0) 1) 2) 3) 4) 19:16 SegFaultAX: Again, I'm trying to distill the essence of a reduce or fold. 19:17 amalloy: SegFaultAX: i'm arguing that's what this is. it's the expression tree that reduce evaluates 19:18 technomancy: "making changes to a single accumulator value for each element in a collection" 19:18 SegFaultAX: amalloy: But that's not prose. 19:18 technomancy: Closer! 19:18 amalloy: well you didn't ask for prose until this very second 19:18 SegFaultAX: Uh, yes I did. 19:18 16:13 < SegFaultAX> arrdem: But I'm trying to come up with a prose description as well. 19:18 amalloy: oh, i guess you did in the middle of a discussion with arrdem. i didn't notice it 19:18 SegFaultAX: Np 19:18 brehaut: SegFaultAX: an abstraction of primative recursion 19:19 arrdem: SegFaultAX: someone's on irssi... 19:19 SegFaultAX: arrdem: ;) 19:19 brehaut: I started with a technical definition (more like Haskell's) but I want something more easily parsed. 19:20 3 of the 5 words you named might require additional description. 19:20 brehaut: SegFaultAX: i think its like monads: you can come up with simpler explainations but they miss the full details. 19:21 its hard to explain because its a pretty general operation with a sort of mathematical basis 19:21 SegFaultAX: brehaut: I know. The weird thing is map and filter are trivial to describe. Reduce is only moderately more complex, and considerably harder to describe. 19:21 brehaut: SegFaultAX: the code is only moderaly more complex but the operation is vastly more general 19:21 SegFaultAX: brehaut: True. 19:21 Maybe a more technical definition is warranted then. 19:22 chare: wtf is going on with MH370? 19:22 beamso: chare: it's a mystery 19:30 isaacbw: how do libraries become contrib? 19:30 arrdem: isaacbw: they are invited to become so 19:31 dnolen_: isaacbw: arrdem: people can also propose them on clojure-dev and see what people think. 19:45 SegFaultAX: So here's why I'm asking about describing reduce: I want to see if implementing map, filter, and reduce make for good phone screening material. 19:47 The questions I usually ask are pretty algorithmic and potentially time consuming, and I want to see if using these basic algorithms as a lead in to tougher questions is a good weeder. 19:47 dacc: SegFaultAX: how about "implement map in terms of reduce"? =) 19:47 SegFaultAX: dacc: That'd be a bonus question, yea. 19:48 technomancy: SegFaultAX: in a specific language, or up to the interviewee? 19:48 SegFaultAX: How do people feel about using map/filter/reduce as tech screening questions? 19:48 technomancy: Up to the interviewee. 19:48 I'm giving reference impls in Python, Ruby, and JS, but that's just for the interviewer. 19:48 cbp: I remember implementing map, and the variadic argument one version pretty tough 19:48 was* 19:49 SegFaultAX: cbp: Depends on if your language already has a sane notion of iterators. :) 19:49 cbp: SegFaultAX: I was doing it with just car cdr and stuff 19:49 I mean first rest and stuff ;) 19:49 arrdem: if you're screening people who have written or who claim to have written functional code it seems entirely reasonable. 19:49 beamso_: for me it seems weird to ask phone/tech screening questions of something that you'd never do 19:49 SegFaultAX: But yea, I'd be asking for the simple version, not the zip-style Clojure has. 19:49 technomancy: SegFaultAX: I might be worried if someone who couldn't implement map in terms of reduce actually made it as far as a coding interview 19:49 SegFaultAX: technomancy: That's why I want to use it as a weeder question. 19:49 arrdem: SegFaultAX: I think that particular example is a fair weeder question. 19:50 SegFaultAX: My thinking is have them do map and filter normally to warm up. 19:51 Then reduce, then re-implement map and filter in terms of reduce. 19:51 technomancy: SegFaultAX: yeah, it'd be good to ask early on, big red flag if it's not a quick warm-up 19:51 SegFaultAX: But I'll a/b test my approach to see if I get better results. 19:51 technomancy: Yup, these are purely tech screen questions. 19:51 arrdem: seems reasonable to me... 19:51 but I think about 80% of the kids I go to school with would get hammered by that 19:51 SegFaultAX: As in, if you can't answer these without much help, then you don't make it beyond phase 1. 19:51 arrdem: just by dint of not recognizing the names. 19:51 the idea they could probably get given a reference imp'l. 19:51 SegFaultAX: arrdem: That's why I have a prose explanation. 19:51 amalloy: cbp: what's hard about the vararg case? 19:52 SegFaultAX: you really want to do coding questions over the phone? how does that even work logistically? 19:52 SegFaultAX: amalloy: coderpad.io or stypi.com 19:52 cbp: Im unsure if amalloy is just dissing me :P 19:52 arrdem: amalloy: either of those actually work out pretty well... used coderpad yesterday for IBM coding interview. 19:52 cbp: I cant quite remember I need to look at the source 19:53 SegFaultAX: Yup. 19:53 arrdem: cbp: if you did it in C that's reason enough :P 19:53 SegFaultAX: I used to use collabedit, but it feels significantly worse lately. 19:53 arrdem: I think that 10gen used collabedit but that was a long time ago. 19:54 SegFaultAX: coderpad is soo much better. You can run the code inline. 19:54 And they support quite a large number of languages by now. 19:54 cbp: amalloy: you don't go from a 1 coll to many collections in a straightforward way 19:54 arrdem: well except that a bunch of the "coding screen" questions I've seen are self-answering if you can just run the mother... 19:54 novochar: What is the difference between node's streams and the core.async library? 19:54 SegFaultAX: cbp: Unless you handle them all the same way. 19:55 cbp: SegFaultAX: I mean from the obvious implementation of handling 1 coll to implementing handling many colls 19:55 amalloy: coderpad looks pretty decent. neat 19:55 SegFaultAX: amalloy: It supports Clojure now! 19:55 amalloy: yes, i saw that 19:56 cbp: I mean it's not earth shattering hard but when I was trying to live code it to some people I was like.. yeah I need to do this calmly on my own 19:58 gfredericks: that's the second time at least I've been baffled by clojure catching FileNotFound and assuming it's a namespace typo 19:58 sdegutis: jballanc: same jballanc from #macruby? 19:58 SegFaultAX: cbp: Well that's because clojure.core/map is doing extra stuff 19:58 amalloy: cbp: that's hardly fair. it contains the chunking nonsense and also the variadic unroll. https://www.refheap.com/58039 would be a more normal implementation 19:58 SegFaultAX: Like chunked seqs 19:58 sdegutis: oops, i could have just checked, sorry for the noise 19:58 SegFaultAX: But you don't have to do that. 19:58 hiredman: gfredericks: huh? 19:59 gfredericks: did that patch land? 20:02 amalloy: SegFaultAX: i found it pretty hard to write only the [f & colls] version, without special-casing only-one-collection 20:02 since you end up wanting to use the single-arity version to map first & rest over the input sequences 20:02 gfredericks: hiredman: patch? this could even be leiningen's fault, I dunno 20:02 amalloy: if you have a good example of "handling them all the same way" i'd love to see it 20:02 gfredericks: it's happening with lein run in particular 20:02 hiredman: gfredericks: oh, yeah, that is lein's fault 20:02 gfredericks: sounds haxy to fix 20:02 hiredman: gfredericks: but there is a jira ticket for getting better error messages from clojure when you use - instead of _ in file names 20:02 which is what I assumed you were talking about 20:02 dacc: i think collabedit is defunct 20:02 `cbp: amalloy: That's not valid code =P 20:02 dacc: or was a couple weeks ago when i tried to use it 20:03 amalloy: oh, fine fine. https://www.refheap.com/58040 then 20:04 gfredericks: hiredman: oh no; this is any program that crashes with a FNFE for any reason 20:04 amalloy: i always forget the compiler won't let you do that 20:04 gfredericks: lein reports it as a namespace typo 20:05 * gfredericks upgrades lein 20:05 hiredman: gfredericks: because lein doesn't set your hair on fire or something 20:05 gfredericks: yep current lein too 20:05 hiredman: aw snap 20:06 I should file an issue mentioning my hair on fire in the title 20:12 hiredman: "dear philip, I am penning you this missive because your apparatus has caused my coiffure to alight like dry kindling, rather upsetting those in the local environs. Be a good chap and see what you can do about it. -- YT &etc" 20:13 * hiredman flags down a lad outside his shoppe and tips him a ha'penny to run his note north 20:15 amalloy: north, sir? everyone knows that the only thing north is the mad scientist leiningen! i'll need more than a ha'penny for that task 20:19 hiredman: well, like, canada is up there too 20:19 cbp: amalloy: oh well :-P 20:19 gfredericks: (inc hiredman) 20:19 lazybot: ⇒ 38 20:19 gfredericks: &'where-are-you 20:19 lazybot: ⇒ where-are-you 20:19 gfredericks: so much internet money being lost by lazybot's absence 20:19 hiredman: "the mad scientist leiningen‽ he'll grind me up and use my bones for building keyboards!" 20:19 arrdem: gfredericks: idk what you're talking about... fido is working fine for dogetips :P 20:19 "Good job you go now then son, he just finished his last 'board and it'll be a while yet before inspiration strikes him again" 20:19 hiredman: I really should stop 20:19 I could spend all day implying that technomancy is a mad scientist living in a steampunk world 20:19 arrdem: as long as they have 64 piston adding machines.. 20:19 gfredericks: clojurebot: I could spend all day implying that technomancy is a mad scientist living in a steampunk world 20:19 clojurebot: Ik begrijp 20:20 gfredericks: My Hobby: teaching clojurebot anything that contains "is" somewhere in it 20:20 arrdem: ~technomancy 20:20 cbp: what the hell? 20:20 gfredericks: clojurebot: technomancy? 20:20 clojurebot: technomancy codes while wearing gravity boots to increase the blood flow to the face transplant he got after discovering the world does not treat build tool creators kindly 20:20 hiredman: also he codes using his keyboard pants while hanging upside down to increase the blood flow to his face translate that he got after going in to the witness protection program because he created a build tool 20:20 transplant 20:21 cbp: (I had hoped that would trigger clojurebot) 20:21 arrdem: oooh man this is gold 20:21 technomancy: please tell me you're a tea man 20:28 * dacc 's brain now parses anything in parenthesis as Clojure code. 20:28 gfredericks: you know I might have written this code myself 20:28 oh and it's even fixable without {refactor,hax}ing 20:31 danielszmulewicz: So many options for websockets <-> cljs/core-async communication! Too many! Sente or Chord? Or Http-kit alone? Suggestions welcome... 20:49 amalloy: i guess the easy-mode definition of map is just (defn map [f & colls] (apply mapcat (comp list f) colls), SegFaultAX. i hope an interviewee tries that at some point 21:03 SegFaultAX: Has anyone ever used nginx-clojure? 21:28 gfredericks: hiredman: I put out my own hair-fire: https://github.com/technomancy/leiningen/pull/1470 21:29 sdegutis: welp 21:29 sed-utils: er, welp 21:36 mlb-: Is there any nice Clojure-y way to read in a subset of a file given a byte offset and a length of bytes? 21:37 joegallo: file or inputstream? 21:37 gfredericks: nothing I know of besides the RandomAccessFile class 21:37 i.e., same as in java 21:40 joegallo: gfredericks: agreed, if it's a file, then RandomAccessFile, if it's an inputstream, then you could .skip and wrap it in a commons-io CountingInputStream, but yeah, that's all just the same as in java 21:40 gfredericks: he did say file 21:40 mlb-: yeah, I'm currently dealing with a file 21:40 gfredericks: s/he/the-person/ 21:41 mlb-: reading JavaDocs 21:41 thanks, gfredericks, joegallo 21:41 gfredericks: np 21:41 mlb-: for the moment, I want to effectively grep the first 500MB of a file for a string's existence or not 21:42 I could shell out and just: head -c$((500*1024))K filename | grep -m1 my_string

21:44 but I'd like to try and be a bit less hackish about the whole thing

22:22 isaacbw: ,(. java.util.UUID randomUUID)

22:22 clojurebot: #uuid "cccb4ca3-fa4b-42bd-a58a-372a2ae09316"

22:23 sed-utils: ,(java.util.UUID/randomUUID)

22:23 clojurebot: #uuid "9c35e6c9-7624-409e-9ea6-c3a600b76a91"

22:23 isaacbw: oh

22:23 :D

22:28 sed-utils: xD

22:29 isaacbw: is there a proposal layout guide for clojure?

22:29 sed-utils: what should that mean?

22:30 isaacbw: er, GSoC

22:31 sed-utils: shrug

22:32 TravisD: Anyone here live in Ann Arbor? I'm visiting the University of Michigan, and if you're on campus tomorrow it might be fun to have a chat

23:00 sed-utils: not i

23:17 noprompt: macros are bananas

23:17 seangrove: B-A-N-A-N-A-S

23:18 noprompt: Do you have a plain css parser in clojure?

23:18 noprompt: seangrove: thorn can do it.

23:18 well almost, media-queries aren't finished.

23:19 noprompt: it'll emit (scss->edn "path/to/yo.css")

23:19 seangrove: Oh, that's fantastic

23:19 noprompt: sass' media-query stuff is a bit weird and i haven't worked up the energy to finish emitting proper tags.

23:20 seangrove: Oh, I just need a property parser

23:20 noprompt: oh, well the cool thing is, once you have parsed the css in to edn

23:20 you can just call (filter-tag (tag= :declaration) edn-tree))

23:21 seangrove: noprompt: What about a cljs version? Looks like there's some pretty crazy stuff in the project

23:21 noprompt: i haven't pushed it to clojars yet cause i'm still working on it, but nothing is stopping you from cloning it

23:21 crazy?

23:21 dnolen_: isaacbw: there's a proposal, I would follow the examples you find there

23:21 noprompt: nah it's actually stupid simpl.

23:21 seangrove: noprompt: zweikopf in particular ;)

23:21 dnolen_: isaacbw: er GSoC proposal page

23:21 noprompt: seangrove: oh that's not a big deal.

23:21 takes like 5 seconds.

23:22 once it's loaded it's reasonably fast.

23:22 seangrove: noprompt: Oh, the app I'm working on is entirely in-the-browser cljs at the moment. Will add a server component later, but the more I can do in the browser, the better

23:23 noprompt: seangrove: well one thing you can do is use the CSSOM

23:23 seangrove: if the CSS is already loaded as a stylesheet in the browser you can use goog.cssom's utilities to fetch properties.

23:24 seangrove: noprompt: No worries, will work on it later anyway

23:26 noprompt: this macro is wacky https://gist.github.com/noprompt/9541611

23:26 dnolen_: i'm not sure of a better way to implement it.

23:28 that is if it's easy to tell from the example what it's doing

23:28 iwilcox: amalloy_: I like keywordize in utils.

23:28 noprompt: seangrove: that's the style of selector i'm working on. :-)

23:29 it's kind of a trip.

23:33 iwilcox: amalloy_: (Obviously it should be keywordise, but I'll let you off the heterography.)

Logging service provided by n01se.net