#clojure log - Nov 21 2012

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

0:00 flying_rhino: atom_: to me seven consequtive closed parens look psychotic.

0:03 atom_: flying_rhino: Perhaps. I'm likely not a very good source. I'm new to programming in general, I have seen both perspectives and I think it may be as much culture as it is structure.

0:03 amalloy: (inc atom_)

0:03 lazybot: ⇒ 1

0:03 flying_rhino: atom_: look this way: Thera aren't many lispers around. One of the reasons is that code looks weird. Making code looking less weird is imho the cheapest way to make lisp more approachable.

0:04 atom_: amalloy: Thanks! I guess I can now say I'm inc'd.

0:04 egghead: heh that's like alman style braces for lisp

0:04 wait what are these dangling -- oh

0:04 amalloy: there's no reason parens *have* to go the way they do. but everyone who's spent any amount of time writing lisp has agreed that's the way they should go. that's why the arguments about code formatting in lisp are between the experts and the newcomers, and not between experts and other experts like in C/java/etc

0:05 flying_rhino: atom_: marketing is something I am ionterested in

0:05 *interested

0:05 augustl: flying_rhino: I recommend "simple made easy" by Rich Hickey, he has a lot of great things to say about the importance of familiarity

0:06 flying_rhino: hope no one will get heart attack when they see my code.

0:07 egghead: flying_rhino: your second example is inconsistent tho, why not finish the let statement on another line as well

0:07 augustl: flying_rhino: the tl;dr is that familiarity is relatively unimportant, and I tend to agree

0:08 amalloy: egghead: don't forget the ] from the start of the let-bindings. why is it trapped behind the later )?

0:08 flying_rhino: amalloy: since it is [ it already stands out from (

0:09 amalloy: so no need for new line there

0:09 amalloy: flying_rhino: perhaps a useful criticism is that you're trying to make the parens stand out. they're supposed to fade into the background so you can pay attention to the important stuff, like actual code

0:09 atom_: flying_rhino: Well, Lisp is based off of Lambda Calc if I remember correctly. You could just as easily tie it to the degradation in mathematical rigor, especially the absence of proofs, in many high school and university mathematics. Thus, less familiarity with that structure and by happenstance less familiarity with the structure of Lisp.

0:10 royaldark: the stacked ) vs newline ) is one reason I think comparing lines of code for Cish languages vs Lisp-like languages is deceptive

0:10 nilmethod: any recommendations for whirlwind tours on clojure or resources for me to learn enough clojure to be dangerous in about 8 days?

0:10 amalloy: early, early on, when you're struggling to see what's going on, it can be useful to have that extra emphasis so that you can make sense of anything at all. but long-term, it's bad for you

0:10 nilmethod: 8 evenings, that is

0:11 flying_rhino: atom_: comparison with math doesn't really work since lisp insists on prefix notation which is unusuall for math.

0:12 I compare it to XML and JSON

0:13 mrowe: flying_rhino: that is an odd thing to do :)

0:13 jkkramer: nilmethod: there are several good clojure books - clojure programming, joy of clojure, etc

0:13 atom_: flying_rhino: It's the structure I think you're concerned with here. The structure of a proof doesn't change much wether you're using prefix or standard notation.

0:13 flying_rhino: mrowe: that's my story and I am sticking to it. At bottom, LISP is programmable data.

0:14 mrowe: er

0:15 egghead: flying_rhino: xml and json are programmable data as well? I don't much see the similarity besides them being tree structures

0:15 that's like saying lisp is just like c because both have ASTs

0:15 nilmethod: jkkramer: i've got the pragmatic press book. may just plow through it

0:15 flying_rhino: egghead: xml and json are representation of data. Lisp is just more executable :)

0:16 jkkramer: nilmethod: also clojure.org, clojure-doc.org, 4clojure.com

0:17 nilmethod: and rich hickey videos, for the big picture

0:18 flying_rhino: amalloy: I am not trying to make parens to stand out. I am trying to make CODE stand out. In my example (* @x @y @z) is the place where stuff from let block comes together. It deserves it's own line.

0:18 technomancy: nilmethod: try clojurebook.com

0:19 flying_rhino: amalloy: it is also, incidentally function that returns value

0:20 haruki_zaemon: mrowe *waves*

0:21 miclorb: I think to close off all parens )...) or )<->). The ruby guys led the way http://d.hatena.ne.jp/ku-ma-me/20110718/p1

0:21 * miclorb is never serious

0:21 haruki_zaemon: miclorb genius!

0:22 miclorb: I like the close parens - someone had the rule "more than 5 to close and you need to refactor" - which seems handy

0:22 if it looks bad, need to rethink

0:25 atom_: flying_rhino: You mentioned marketing. Are you hoping to make functional more palpable by making it look more like OOP?

0:26 flying_rhino: atom_: look just becuase we can't make everything more palpable doesn't mean we shouldn't try with some stuff. And clojure does have multimethods which should make OOP guys a little less grouchy.

0:27 mrowe: flying_rhino: I still don't get why you're so keen to use clojure, then want to make it just like java/scala/etc.

0:28 muhoo: when in rome

0:30 flying_rhino: mrowe: because (1) Functional programming is good for a lot of things. I would like more mutable state here and there but still prefer functional for a lot. (2) Macros and code as data philosophy rules (3) Scala syntax looks like crap. (4) using multicore more efficiently is something I like.

0:30 egghead: clojure can look pretty ugly

0:30 flying_rhino: mrowe: do I need to go on?

0:31 mrowe: flying_rhino: you can avoid mutable state and write functional code in java and scala

0:31 clojurebot: scala is https://twitter.com/#!/timbray/status/153996532952203264

0:31 mrowe: flying_rhino: what about macros and "code as data" rules?

0:31 Sgeo: flying_rhino, if you want a language with Lisp macros and lots of mutable state, go with Common Lisp

0:31 flying_rhino: mrowe: makes easier to parse code and write your own tools if you are so inclined.

0:32 mrowe: flying_rhino: you can write efficient parallelisable code in many languages

0:32 Sgeo: CL is OO to a good extent

0:32 egghead: lisp as a programming language for programming languages. mmm

0:32 flying_rhino: Sgeo: I doubt CL has immutable structures as sophisticated as clojure.

0:33 Sgeo: I'm sure you could implement them.

0:33 ^^a bit trollish

0:33 egghead: lol

0:33 Bergle_1: thats like a bit pregnant ?

0:34 flying_rhino: Sgeo: I'm sure you guys could implement slightly more mutablility, huh?

0:34 egghead: flying_rhino: but whyyy

0:34 mrowe: flying_rhino: so can you. it's a lisp, after all :)

0:34 Sgeo: flying_rhino, we don't want to, but the tools are there for you to implement highly mutable data structures if you wish.

0:35 Or just use the native Java data structures.

0:35 flying_rhino: Sgeo: I will, probably. Won't use them all or even most of the time, but they will be there. I would prefer someone else does it so it is more standardized.

0:36 atom_: flying_rhino: That sounds like feature creep that is unnecessary.

0:36 Sgeo: The native Java data structures are pretty "standard"

0:36 egghead: Heh, reminds me of tao, don't swim against the river

0:36 Sgeo: Not used all that often, but anyone who wants to use them would use them in the same way.

0:37 egghead: flying_rhino: have you seen the hickey talks on 'place oriented programming' or encounted that term in something like SICP ?

0:37 Sgeo: Does place-oriented programming have anything to do with CL's setf?

0:38 flying_rhino: Sgeo: I guess java structures are the way to go then :) So we are all happy.

0:39 egghead: Sgeo: you tell me :)

0:39 Sgeo: Except for any other Clojure programmer who touches your code, who will curse you out for needless mutability.

0:39 flying_rhino: Sgeo: happy ending, end credit music plays etc etc...

0:39 Sgeo: egghead, I don't really know what "place-oriented programming" is

0:39 egghead: flying_rhino: http://www.infoq.com/presentations/Value-Values

0:39 Sgeo: basically dealing with addresses of things instead of the values of things

0:40 if you have a value you don't have to worry about it slipping out from under you, when you only have an address you can never be sure what will be there at any given time

0:41 Sgeo: Tcl's append is place-oriented

0:41 Seriously, I think Tcl's great, except for all the mutability.

0:42 And fun fact, Tcl values (aka strings) are immutable, but variables etc. are all highly mutable and often passed around like candy

0:44 Tcl arrays (basically hash maps) are not first-class things. Dictionaries are, but those were added in recently

0:44 Arrays in Tcl are just a collection of similarly named variables

0:44 :/

0:59 augustl: FYI, programmers of europe! http://techmeshconf.com/

0:59 seems like there are still tickets left. Very relevant for Clojure programmers

1:00 atom_: Is there a place where tickets are filed for bugs/patches etc. and marked with beginner tags for clojure?

1:01 augustl: atom_: afaik there's only the jira

1:01 tpope: devn: I've been 80% through for about 2 weeks :/

1:03 amalloy: atom_: if you have submitted a contributor agreement (which you must, to be allowed to help), you can read andy fingerhut's weekly summaries on the clojure dev mailing list

1:04 eg http://groups.google.com/group/clojure-dev/browse_thread/thread/d98c4c3841bfd4b2/1972bd1b90178008?q=#1972bd1b90178008 but i think you need to have a CA to even read it

1:05 atom_: amalloy: Thank you. I'll print it out and save it for when I feel like I could contribute back productively.

1:21 flying_rhino: Sgeo: what's basic difference of hash map and dictionary?

1:22 lynaghk`: ure

1:23 dnolen: just pushed up a patch for the core.logic walk stuff. Right now it walks over map keys just for completeness, though unification won't work with lvars inside of a complex map key because of how that process works.

1:35 Sgeo: flying_rhino, in what language?

1:36 flying_rhino: Sgeo: is there a general difference?

1:36 Sgeo: Different languages tend to use the same term to mean different things

1:37 Array is a frequent offender, but there are others.

1:37 "Functor" is particularly bad

1:37 "hash" map does somewhat imply something about the internals of how it works

1:37 That it hashes the key

1:37 And uses that for efficiency purposes.

1:41 brainproxy: why is it I get cool insights about the time I really should go to bed ... and just must stay up coding lest I lose the spark? :p

1:43 Sgeo: What is this "bed" of which you speak?

1:43 brainproxy: i dunno, it could be like (sqrt -1)

1:45 Sgeo: any good w/ call-cc?

1:45 Sgeo: Um, I understand it at a basic level

1:46 Madsy: brainproxy: Some people are naturally more awake and creative at night

1:46 Which makes sense to me. It's perhaps dark outside, little background noise, no traffic and everything is calm

1:46 brainproxy: Madsy: yeah, I'm definitely one of those ... will often work until 4/5am in the morning

1:47 Madsy: Seconded

1:47 brainproxy: but can create ... issues ... in a world where things need to get done during the day

1:47 Madsy: Just sleep a bit in the afternoon. That's what I do

1:48 I often go to bed at 3 or 4 am. Then I sleep for 4 hours. After work I sleep for 2-3 hours, then I wake up at 6-7 pm and do chores.

1:48 brainproxy: sometimes that helps, but after i hit my mid 30s I find I've pretty much got to get 8 hours of sleep

1:49 Madsy: Yeah, age definitely plays a role.

1:50 What was your question about call/cc ?

1:51 brainproxy: oh, it's just that protocol-monads needs call-cc implemented, but I don't understand the concept well enough to pull it off, though I've made progress w/ other parts of the library

1:51 Madsy: call/cc In Clojure?

1:52 brainproxy: well, something that works like it

1:52 Madsy: Not sure if that's possible. Afaik, Clojure doesn't support full continuations due to limitations with the JVM

1:52 brainproxy: see algo.monads, it has it

1:52 Madsy: Monads.. brr. The name scares me D:

1:52 brainproxy: :)

1:54 amalloy: $google swannodette delimc

1:54 lazybot: [swannodette/delimc · GitHub] https://github.com/swannodette/delimc

1:54 amalloy: brainproxy: ^

1:55 Madsy: brainproxy: I'm sure algo.monads managed to make an approximation

1:55 But proper call/cc lets you jump *anywhere*

1:55 brainproxy: amalloy: awesome, delim'd conts are, I've heard, "better" than call/cc

1:56 saw an interesting presentation on them a few months ago, but didn't know any Haskell at the time, so I was a bit lost

1:56 amalloy: well, they're a bit "weaker", in that there's some stuff you can't do. but in general the stuff you can't do is an unspeakably bad idea to do

1:56 brainproxy: i think there's a paper "call/cc considered harmful"

1:57 or something like that, which advocates for delim'd conts

1:57 Madsy: It's "kind of" harmful

1:57 Sgeo: Any monad-based Continuation system is going to be delimited continuations I think

1:57 amalloy: ∀x∃p such that p is a paper titled "x considered harmful"

1:58 brainproxy: hehe

1:58 Sgeo: I should also note that that delimc library is a bit broken in some ways

1:58 For starters, anything wishing to use it must use all the vars

1:58 And there might be other flaws

1:58 Madsy: The problem with call/cc is that it allows you to jump both forwards and backwards. It guarantees that optimization is close to impossible

1:58 Sgeo: It's a not thoroughly executed port of a Common Lisp library

1:59 brainproxy: the impl in algo.monads looks deceptively simple

1:59 just a couple lines of code

1:59 building on top of its continuation monad impl, of course

2:04 amalloy: Sgeo: use all the vars?

2:05 Sgeo: amalloy, as in, (:use) in the ns macro or (use)

2:06 Or... well, just the ones you intend to use, I guess. The problem is that it won't, say, see delimc.core/shift as shift, it will only see shift as shift

2:07 * Sgeo swaps see and say

2:07 amalloy: i have to say, the macro forms there look a bit bonkers. but it's not totally unprecedented; reset introduces an anaphor named shift, in the same way that loop introduces one named recur, or try introduces one named catch

2:25 alex_baranosky: does anyone have experience with serving dynamically generated files (such as CSVs) from a Ring app?

2:27 WE've been using the 'wrap-resource' ring middleware to server static files, but it looked like it wouldn't recognize something generated dynamically

2:34 amalloy: alex_baranosky: just find out the http headers you need to set, and set them, while making the :body be whatever you need. eg, 4clojure generates image files on the fly with {:response 200 :headers {"Content-Type" "image/png"} :body (...some input stream with the right bytes...)}

2:35 to make the files "downloadable" you probably need to set content-disposition as well, or something

2:35 alex_baranosky: amalloy: thanks , I'll look at that

2:35 Apage43: Content-Disposition: attachment would force a type that would normally be displayed to be downloaded

2:36 if you need that sort of thing

2:36 clojurebot: most horrible thing is http://tinyurl.com/b65o8e

2:42 alex_baranosky: APAge43: thanks looking into Content-Disposition: attachment

3:11 amalloy & Apage43 - thanks guys that worked

3:22 augustl: http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure could use some multimethods or protocols

3:25 and there we go, reading the whole article before posting it is a good idea :)

4:36 thorwil: ,(map #(identity %) [{:a 1 :b "bert"} {:a 3 :b "jim"}])

4:36 clojurebot: ({:a 1, :b "bert"} {:a 3, :b "jim"})

4:37 thorwil: ,(map #(cons % %) [{:a 1 :b "bert"} {:a 3 :b "jim"}])

4:37 clojurebot: (({:a 1, :b "bert"} [:a 1] [:b "bert"]) ({:a 3, :b "jim"} [:a 3] [:b "jim"]))

4:37 thorwil: i do not understand at all what happens in the second case

4:38 ucb: ,(doc cons)

4:38 clojurebot: "([x seq]); Returns a new seq where x is the first element and seq is the rest."

4:38 ucb: ,(seq {:a 1})

4:38 clojurebot: ([:a 1])

4:38 ucb: thorwil: ˆˆˆˆ

4:39 ,(cons {:a 1 :b 2} {:a 1 :b 2})

4:39 clojurebot: ({:a 1, :b 2} [:a 1] [:b 2])

4:39 ucb: cons takes the 2nd argument as a seq (my guess is that it even calls seq on it) and hence you end up with a seq of [k v] from your map

4:39 ,(source cons)

4:39 clojurebot: Source not found

4:40 ucb: &(source cons)

4:40 lazybot: ⇒ Source not found nil

4:40 ucb: pah

4:43 thorwil: hmm. i need something that allows me to assemble (:b %) and %

4:44 Bergle_1: I am looking at http://clojuredocs.org/clojure_core/clojure.core/spit - it has a type hint of #^java.io.Writer - what is the '#' ? I've just done a dozen plus searches in google but not finding any enlightenment

4:44 thorwil: ah, seq or vec

4:55 cemerick: Bergle_1: #^ was the original type-hint prefix.

4:55 Bergle_1: ahhhh.

4:55 i couldnt find that :) thanks.

4:55 i thought it might be the case.

4:56 thorwil: ,(apply hash-map (mapcat #(vec [(:b %) %]) [{:a 1 :b "bert"} {:a 3 :b "jim"}]))

4:56 clojurebot: {"bert" {:a 1, :b "bert"}, "jim" {:a 3, :b "jim"}}

4:56 thorwil: is there a ncer way from the 2 maps to that result?

4:56 nicer, even

5:03 ucb: thorwil: maybe this http://clojuredocs.org/clojure_core/clojure.set/index

5:06 thorwil: interesting, but that seems to be a much more complex mechanism with some other goals

5:15 ucb: you would end with a map where the keys are maps like {:b value}

5:16 it's not that much more different; but perhaps you don't need that complexity in the real code :)

5:17 thorwil: it must be string keys. not my choice :)

5:51 borkdude: hello guys (and maybe girls)

5:52 the last two years I have put two groups of students (2 to 4) on a "research" project involving clojure

5:52 the first was about the differences in OO and functional approach to a common/random application

5:52 the second focussed more on web frameworks

5:53 but this year I want to have a similar group at work. any nice ideas about what they could research? they don't know clojure yet, only Java

5:53 so in the first few weeks I'll teach them clojure, and then they can go into something specific

5:56 thorwil: borkdude: at work? shouldn't that suggest some specific areas of interest already?

5:56 borkdude: thorwil education

5:57 thorwil: ah, parsed with wrong context

5:57 borkdude: thorwil my mistake

5:58 thorwil: nah, no worries anyway

5:59 to just throw something out: database -> text reports. think stock market or sport reports

6:03 borkdude: maybe I could let them investigate smth about clojurescript

6:03 because I don't know much about it myself yet

6:03 maybe they could port some libs as an exercise

6:04 thorwil: i think yesterday someone asked about a clojurescript version of trammel

6:09 borkdude: if you have any good ideas, please e-mail them to (apply str (interleave ["michiel" "borkent" "hu" "nl"] ["." "@" "." ""]))

6:16 deg: What are good packages for doing chart/plot style graphics in Clojure? I'm looking at incanter now; which others are good too?

6:29 babilen: deg: I've used incanter, but it has serious problems with its charts and I abandoned it. I am currently playing with https://github.com/quil/quil which is a different approach

6:30 deg: If you find something good that is more like mathplotlib (Python), matlab or ... let me know. Clojure seems to lack a good graphing library

6:33 deg: See http://tgk.github.com/2012/11/visualising-gcse-statistics-using-datomic-and-quil.html for an example -- It is still a bit too "manual" for my taste, but that might just be because I haven't mastered processing yet

6:34 deg: thanks.

6:34 What problems did you find with incanter?

6:34 The first issue I hit is that I need a way to replace the contents of a chart from time to time (like a dashboard display) and that appears to be non-trivial, at best.

6:38 babilen: deg: A common issue is, for example, that graphs are not labelled ... This has been discussed on the mailing list and the "solution" was to use the underlying API directly. https://groups.google.com/forum/?fromgroups=#!topic/incanter/g2k2M6JllYE

6:39 deg: I also have the impression that incanter is a bit, well, undermaintained.

6:41 bordatoue: has anyone figured out a way to work with local jar files using lein ver 2 , in version 1 it was easy as the local requirement could be added to lib directory .

6:42 i don't wat the local jar to be installed , it should be just temporary

6:43 deg: babilen: thanks. I'll look at quil and see what else I can find.

6:45 xeqi: bordatoue: while not recommended, you can abuse :resource-paths for that

6:45 bordatoue: xeqi seriously, you are picking up on me

6:50 xeqi thanks ,

7:07 Chiron: Hi, where can i find a sample profiles.clj file ?

7:07 Foxboron: Chiron, 2 sec and ill pastebin mine :)

7:08 andrewmcveigh|wo: Chiron: https://github.com/technomancy/leiningen/blob/master/sample.project.clj

7:08 Chiron: that is project.clj sample

7:08 Foxboron: O.o didnt know about those

7:09 Chiron: i'm talking about .lein/profiles.clj

7:09 andrewmcveigh|wo: Ah, sorry. Reading blindness.

7:09 Chiron: no, thanks any way :)

7:10 babilen: Chiron: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md -- Not sure if there is a sample as it very much depends on what /you/ want :)

7:10 (lein2 btw)

7:11 Chiron: profiles.clj isn't available for lein 1.7 ?

7:11 babilen: Chiron: No

7:11 thorwil: all my profiles.clj contains is: {:user {:plugins [[lein-immutant "0.12.0"]]}}

7:12 * babilen has a bit more in his, but that is the general idea, yeah :)

7:22 Chiron: it is deprecated :)

7:22 Please use ~/.lein/credentials.clj.gpg instead.

7:22 * josteink wonders about clojure and message-passing style objects

7:23 josteink: if I define an object as a map of keywords and functions

7:23 (def foo { :test (fn [x] (+ 1 x)) })

7:23 do I have to go ((:test foo) 1) or is there a shorthand I can use?

7:23 a special form?

7:24 bordatoue: i find this lein really painfull, is there any other command to get detailed help on localrepo, when i type lein help localrepo ==> work with local Maven repository, is that it

7:24 is it something to do with my version of lein

7:25 which is leing lines.

7:25 ^E or * Search multiple files (pass thru END OF FILE).

7:26 sorry, lein 2.0.0-preview10

7:27 mishok13: hey guys, how would you achieve the following in Clojure: given a list of indices and a vector, extract a seq that contains items referenced by those indices?

7:28 e.g. indices = [1 3], vector = [42 :foo 12 :bar :baz], result -- [:foo :bar]

7:29 pyr: mishok13: (map (partial nth my-vector) my-indices)

7:30 ,(map (partial nth [:a :b :c :d :e]) [1 3])

7:30 clojurebot: (:b :d)

7:30 mishok13: thanks, pyr

7:30 I started looking into some and juxt for some reason

7:31 josteink: pyr: oooh. nice "trick" :)

7:32 xeqi: bordatoue: try `lein localrepo`

7:33 bordatoue: xeqi: is that the recommended way to get help

7:34 babilen: Is anybody aware of how the PDFs of the clojure cheatsheet are generated? The current version is horribly aligned and just unusable and I wanted to see if I can improve it.

7:36 josteink: link?

7:36 clojurebot: your link is dead

7:36 * josteink wants that cheatsheet :)

7:36 babilen: Also: is https://github.com/jafingerhut/clojure-cheatsheets/ the source for the cheat sheet linked on http://clojure.org/cheatsheet

7:36 josteink: horrible or not

7:36 babilen: heh

7:37 josteink: ive seen bigger marvels of design

7:37 but still contains quite a bit of compact information :)

7:37 xeqi: bordatoue: depends on how the plugin implements it, in this case it looks like localrepo built its own help system

7:37 which would have been needed until recently

7:38 bordatoue: xeqi: thanks very much, how would you go about getting help on lein

7:40 xeqi: bordatoue: combination of `lein help`, https://github.com/technomancy/leiningen/tree/master/doc , sample.project.clj, and asking here or #leiningen

7:40 depending on what you need help with

7:44 ambrosebs: That's weird. It seems doing a `lein install` on a git project with zero commits gives this error: /home/ambrose/Projects/lein-typed/.git/refs/heads/master (No such file or directory)

7:44 bordatoue: xeqi: finding it quite hard to get a grip on lein, i don't know where to start from. What would be the recommened way to understand lein

7:45 ambrosebs: Whoops, wrong room

7:46 bordatoue: xeqi: i have got a set of depencies on one project A, i would like to have the same set of depencies when i create the second project, is there any way i could do it with manually editing project.clj

7:47 xeqi: bordatoue: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md ?

7:47 bordatoue: with or without?

7:47 bordatoue: with

7:47 xeqi: copy the :dependencies in project A's project.clj to project B's

7:51 bordatoue: xeqi: there any way a project.clj file to refer to another project.clj file

7:51 xeqi: nothing builtin

7:53 and no plugins that come to mind

7:53 bordatoue: xeqi: just one more question if i specify a directory under "resource-path" will it add all the .jar files under that directory

7:53 xeqi: though I can imagine a way to do it.. though its not great

7:54 bordatoue: no

7:55 bordatoue: xeqi: so its a vector of files that i want to add to the class path .

7:56 xeqi: its meant to be a directory the jvm can use to find resources; adding jars is just abuse that happens to work due to the way the resources are added to the classpath

7:56 * directories

7:58 bordatoue: xeqi: thanks very much for your time

8:51 gauravag: how do I iterate over a map with key value?

8:54 xumingmingv: ,(for [[k v] {:james :bond :jack :rose}] [k v])

8:54 clojurebot: ([:james :bond] [:jack :rose])

10:02 maleghast: Afternoon

10:03 jcrossley3: maleghast: morning! :)

10:03 * babilen endorses UTC

10:04 xeqi: today

10:07 jsabeaudry: What is the correct way to do this: (defn foo [& [{:or {b 10 c 15} :as all}]] (list (:b all) (:c all)))

10:07 dysinger: hrm. I'm trying to get paredit to automatically hook in on nrepl in emacs. it's not working. anyone have tips for me?

10:08 broquaint: What have you got at the moment, dysinger?

10:09 bordatoue: \who bordatoue

10:11 dysinger: broquaint: I have (add-hook 'nrepl-interaction-mode-hook 'paredit-mode) which I found on stackoverflow.

10:13 broquaint: You may want nrepl-connected-hook instead there, dysinger.

10:14 dysinger: ah - I'll try it

10:14 broquaint: WFM at least :)

10:17 dysinger: that didn't work for me :(

10:24 broquaint: yes that did work. I was doing it wrong.

10:24 thanks!

10:24 actually I added the hook to nrepl-mode

10:24 seems to work

10:25 where as connected-mode didn't

10:26 mmitchell: I just installed leiningen 2 as lein2, created a new project, but "lein2 deps" doesn't seem to do anything at all?

10:27 "lein2 test" works, hmm

10:27 babilen: mmitchell: Have you actually added any dependencies for which something needs to be done?

10:27 mmitchell: babilen: yes, a few of them

10:27 xeqi: mmitchell: lein2 uses jars from your ~/.m2 cache

10:27 if you have them there already it doesn't do anything

10:27 mmitchell: xeqi: so it doesn't put anything in your project's lib dir?

10:28 babilen: mmitchell: And have they already been downloaded? Dependencies are handled differently in leiningen2 in that it uses a central repo for all projects

10:28 xeqi: also, `lein deps` should get called automatically when needed, you shouldn't have to manually invoke it

10:28 mmitchell: correct

10:28 babilen: mmitchell: No, $proj/lib is not used anymore

10:28 mmitchell: ahh nice. OK all is well then. I just launched the repl without problems

10:28 thanks!

10:29 babilen: mmitchell: Do you actually have a problem that is caused by missing dependencies or did you just expect lein2 to behave like lein1?

10:29 mmitchell: babilen: i was expecting it to behave like v1

10:29 Raynes: But then it wouldn't be lein 2!

10:30 babilen: ack - well, there have been quite some changes. You might want to read https://github.com/technomancy/leiningen/wiki/Upgrading

10:30 mmitchell: Raynes: exactly!

10:31 babilen: thanks, I'll check that out

10:32 I want to create a few tasks in my project. Is it possible to use code from my project in the tasks? Is there a wiki page somewhere for creating custom lein tasks?

10:34 xeqi: mmitchell: lein2 keeps a good seperation between the project jvm and lein jvm

10:34 usually tasks go in plugins, but if they *really really* are project specific https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#project-specific-tasks

10:35 mmitchell: xeqi: yeah, these are definitely project specific

10:45 enigmeta: Is there an easy way to flatten one "level" of a nested structure?

10:45 I have something like: [[[1 2] [3 4]] [[5 6] [7 8]]]

10:45 And I would like: [[1 2] [3 4] [5 6] [7 8]]

10:46 tufflax: Maybe concat?

10:46 ,(apply concat [[[1 2] [3 4]] [[5 6] [7 8]]])

10:46 clojurebot: ([1 2] [3 4] [5 6] [7 8])

10:47 enigmeta: Thanks! (apply concat [...]) seems to work. I was looking for something called "combine".

10:47 tufflax: Hm, did you get that from another language or something?

10:48 enigmeta: No, just guessing.

10:48 tufflax: ok :p

10:48 jballanc: Anyone know if clojurebot or lazybot's source is available somewhere?

10:48 tufflax: jballanc, i think they are, search github

10:49 jballanc: hmm...there's a few forks looks like

10:52 Chiron: Hi, are Clojure functions serializable ?

10:54 nDuff: ChiralSym: not out-of-the-box, but see https://github.com/technomancy/serializable-fn

10:54 err

10:54 Chiron: ^^

10:55 chronno: jballanc: http://www.clojure-toolbox.com/ look under "IRC Bots"

10:55 nDuff: ...or do you mean implementing Serializeable?

10:55 Chiron: nDuff: thanks!

10:56 i mean implementing Serializable

10:58 nDuff: ,(supers (class (fn [] 1)))

10:58 clojurebot: #{java.lang.Runnable clojure.lang.IObj clojure.lang.Fn clojure.lang.AFunction clojure.lang.AFn ...}

10:59 nDuff: ...ahh, the bot doesn't print the whole thing -- but java.io.Serializable is there.

10:59 Chiron: first time i know about supers

10:59 super!

10:59 jweiss: is it possible to add an interface implementation to someone else's record type?

11:00 extend-type requires a protocol, not an interface

11:00 jules2: is there a way to get basic clojure out of clojurescript, with all macros expanded, stdlib imported, etc., but without any javascript bits?

11:02 Foxboron: Is there any great way on Windows to reduce Clojure startup time?

11:02 Googling around but wanna see what people recommend ^^

11:03 Raynes: Not really.

11:03 ambrosebs: Chiron: see also `bases` and `ancestors`

11:03 Raynes: The JVM is slow to start up. Not really a way to mitigate it.

11:03 Chiron: that could be changed in JVM 9 ?

11:04 Raynes: I guess. Pigs could also grow wings eventually, given evolution.

11:04 Foxboron: I know drain stores the stuff in memory so the overall startup time is reduced by 1 sec, but its not available on windows :/

11:04 Raynes: drain?

11:04 Foxboron: Lemme find source :)

11:04 Raynes: You mean drip?

11:05 Foxboron: was it drip..? hmm

11:05 Raynes: It doesn't work like that though.

11:05 Foxboron: ah, drip.

11:05 Raynes: All drip does is start a new jvm when you run a command, warming it up for your next command. It gives the appearance of fast startup time by having a JVM already running when you're ready to use it.

11:05 nooooo: If I have a list of 2-element vectors, is there a more idiomatic way of transforming them into a map then just reducing across the list?

11:05 Raynes: It could also probably be ported to Windows if someone cared enough.

11:06 Foxboron: Raynes, i see. I'll try google some more.

11:06 Chiron: ambrosebs: thanks!

11:07 ambrosebs: Chiron: np

11:08 nDuff: ,(into {} [[:a :b] [:c :d] [:e :f]])

11:08 clojurebot: {:a :b, :c :d, :e :f}

11:08 nDuff: nooooo: ^^^

11:09 scriptor: nDuff: what about it?

11:09 nDuff: scriptor: it's an answer to nooooo's question

11:09 scriptor: ah, heh

11:10 jsabeaudry: Is there a lein-outdated that also checks plugins?

11:18 PudgePacket: where can i find info about string manipulation with clojure ?

11:20 nDuff: PudgePacket: http://clojure.github.com/clojure/clojure.string-api.html and http://docs.oracle.com/javase/6/docs/api/java/lang/String.html are the bulk of what there is.

11:20 PudgePacket: Looking for anything particular?

11:21 PudgePacket: ...well, you might also see the "strings" section on the cheatsheet at http://clojure.org/cheatsheet

11:22 jweiss: is there a way to extend ILookup to other types so that when i do (:mykeyword theirtypeobj) i get my own behavior for the lookup?

11:29 nDuff: jweiss: Unfortunate that ILookup isn't a protocol -- that _would_ be shiny, but I don't think it's possible.

11:29 jweiss: darn, was hoping there was some avenue i was missing.

11:30 i wonder if there's any plan to make some of the internal interfaces into protocols?

11:36 dnolen: jweiss: a JVM backend for CLJS would be a good start ;)

11:37 Bronsa: have you considered putting Blind into contrib - it would be nice to have all the necessary pieces for bootstrapping in contrib.

11:43 Bronsa: dnolen: honestly, I hadn't thought about it

11:45 dnolen: Bronsa: I'd definitely +1 that. Would love to switch ClojureScript to use a pure Clojure reader that doesn't have to wait for modification to the Clojure one.

11:47 Bronsa: dnolen: ok, i will check out what's the process to get it into contrib and do it in the next few days

11:47 dnolen: Bronsa: sweet, not much beyond pinging the dev ML really. I'd get behind it and I'm sure all the folks doing tooling (LightTable) would too.

11:48 Bronsa: what should the contrib name be then?

11:49 dnolen: Bronsa: I'm sure that can get sorted on the ML - tools.reader ?

11:49 Bronsa: mmh, yeah

11:49 scriptor: cljs's reader isn't pure clojure already?

11:49 abp: neat :D

11:50 dnolen: scriptor: cljs reader just does EDN, we want a full Clojure source reader

11:51 Bronsa: dnolen: the fact is, blind is currently an order of magnitude slower than clojure's reader

11:51 scriptor: ah, all cljs is valid EDN, right?

11:51 Bronsa: and i suck at profiling.

11:51 abp: dnolen: Wouldn't it be much easier and more expandable to do closure style dead code elimination in clojure?

11:51 dnolen: Bronsa: order of magnitude isn't a bad start - I'm sure we can optimize. Even then - I seriously doubt that time would dominate analysis, compilation etc.

11:52 scriptor: Bronsa: your repo mentioned that it used to be faster?

11:52 Bronsa: yeah

11:52 scriptor: any idea around when the slow-down started to happen?

11:52 Bronsa: sadly, no

11:52 dnolen: abp: I have no idea - never looked at tree-shaking. But yes, it would be nice to have some system for compiler passes for pluggable optimizations.

11:52 scriptor: hmm

11:53 I guess theoretically it's possible to take a repo and go through it from the first commit, all the while running benchmarks, it'd be cool to automate that

11:53 be hell to do it manually

11:53 Bronsa: scriptor: i was so dumb that i didn't use git.

11:53 nDuff: sounds like the kind of thing git bisect is good for.

11:53 dnolen: Bronsa: fortunately it's not that much code

11:54 Bronsa: if i did, i would have already done that

11:55 dnolen: the most loved CLJS commit yet http://github.com/clojure/clojurescript/commit/cd66e6b9e63ad5ef1896a9c7a117148beb04301d

11:57 egghead: oh nice dnolen

11:58 might be time to give cljs another shot

11:58 dnolen: egghead: source map work is moving along - getting close

11:59 egghead: last time I tried I was turned off by having to marshall clj -> js/dom back and forth when using gclosure stuff

11:59 is everyone just using jayq these days?

12:00 I think I will pick up http://shop.oreilly.com/product/0636920025139.do

12:01 dnolen: egghead: I know that ibdknox has moved on to a much lighter weight solution - jQuery is dead weight.

12:01 IMO

12:02 egghead: ya I didn't want to add it, especially since it can't eliminated by gclosures tree shaking, but last time I used cljs it was just so painful to have to write helper functions over around every dom interaction

12:03 that commit looks like it'd get rid of a lot of that boilerplate, however :)

12:04 dysinger: what's the point free version of haskell's flip in clojure again? I'm super rusty

12:06 egghead: dysinger: flip reverses the argument order?

12:10 technomancy: dysinger: you have to pull in useful for flip

12:10 also, hey

12:11 egghead: technomancy: does useful have any documentation anywhere

12:12 technomancy: not sure

12:13 egghead: at least it's got a full test suite :3

12:13 Raynes: It has docstrings.

12:14 Whether or not they're useful depends on whether or not amalloy_ or ninjudd was putting the function in there because they wanted to use it in two different projects without duplicating effort and get it all done in 5 seconds or if they honestly thought other people would use it.

12:16 egghead: heh, thanks Raynes

12:16 seangrove: ,(apply str (interleave ["a" "b" "c"] ["." "-" "."]))

12:16 clojurebot: "a.b-c."

12:16 seangrove: Wow, cool stuff

12:17 Raynes: Far out and funky.

12:17 egghead: ,(apply str (interpose ["a" "b" "c"] ", "))

12:17 clojurebot: ",[\"a\" \"b\" \"c\"] "

12:17 egghead: oops

12:17 :)

12:18 Raynes: &(clojure.string/join "," [\a \b \c])

12:18 lazybot: ⇒ "a,b,c"

12:19 egghead: hmm, kind of cool that interpose considered ", " as a list of chars

12:19 Raynes: Well, it is.

12:19 If you call seq on it.

12:19 &(seq ",")

12:19 lazybot: ⇒ (\,)

12:21 egghead: aah, didn't know interpose was defined in terms of interleave either, neat

12:28 kevincolyar: I'm writing a simple ray tracer to learn clojure... what would you guys recommend I use to store screen of rays/pixels? A 2d vector of refs?

12:28 abp: Is there something like a unified "jump to line in file"-url invoker for existing editors and IDEs? With wich editors is this even possible?

12:29 seangrove: abp: you mean jump to line in either a fil or a url?

12:29 file*

12:29 qerub: abp: For the record, TextMate has txmt://open?url=…&line=…&column=…

12:29 abp: seangrove: No, communicating, please jump to line x in file y. To an editor, programmaticaly.

12:30 qerub: Noted. Just in case I need to write that by myself. :x

12:34 dnolen: kevincolyar: I would just use Java arrays for a raytracer.

12:39 kevincolyar: dnolen: I'm not worried about performance right now, just learning clojure.

12:41 dnolen: kevincolyar: I wouldn't use refs, probably one big vector of ints.

12:44 kevincolyar: I'm kind of stuck trying to figure out the best way to update the state of the screen when I cast each ray

12:45 wingy: i am converting a curl request to cljhttp code . is this correct https://www.refheap.com/paste/6892

12:45 dnolen: kevincolyar: you can treat the vector just like you would an array. (set-pixel vector-of-ints x y new-value)

12:45 wingy: im not sure about the attachment field

12:45 abp: Hm, I can't use e* on lein repl with Clojure 1.5.0 Beta1?

12:45 dnolen: kevincolyar: use x and y to index into the array, and update it with assoc.

12:45 ,(assoc [0 1 2 3] 0 5)

12:45 clojurebot: [5 1 2 3]

12:47 kevincolyar: dnolen: ahh, i thought could only use assoc with maps

12:49 dakrone: wingy: no, you need to look into :form-params. you also have two basic-auth things when only one is needed

12:49 kevincolyar: dnolen: wont that give me a new vector each time since it's immutable?

12:50 dnolen: seems like i could be updating the vector via a reference type

12:50 wingy: dakrone: oh yeah i missed that i already added one basic auth

12:51 ghadishayban: anyone know what happened to fill-queue from old contrib?

12:52 dnolen: kevincolyar: if you want understand Clojure - this is what you want to do. you can probably construct your raytracer so that it doesn't need any real mutation at all.

12:52 wingy: dakrone: seems that i need to use :multipart and not :form-params in this case since its sending files

12:52 https://github.com/dakrone/clj-http

12:53 dnolen: kevincolyar: that in fact should be constraint - can you construct the raytracer without using reference types.

12:53 "should be the constraint"

12:54 dakrone: wingy: it depends on what your server is expecting

12:54 curl's -F is :form-params I beleiev

12:54 *believe

12:54 wingy: dakrone: ok

12:55 kevincolyar: dnolen: cool, i'll give it a try. thanks for the help

13:03 alexnixon: kevincolyar: I wrote a raytracer in clojure on a hackday, it used a for comprehension over x and y values, and a function taking the pixel x y and returning a color

13:24 kevincolyar: alexnixon: it used a?

13:27 lynaghk: kevincolyar: I think he meant a "for comprehension". In Clojure for is a list comprehension that returns a value, not a control flow operator like in other langugaes

13:28 ,(for [x (range 3) y [:a :b :c]] [x y])

13:28 clojurebot: ([0 :a] [0 :b] [0 :c] [1 :a] [1 :b] ...)

13:28 kevincolyar: lynaghk: ah, ok

13:28 dnolen: lynaghk: thanks for patch - one unimportant enhancement would be to throw on the presence of lvars in map keys - but it's not critical.

13:30 lynaghk: dnolen: I did that initially, but I realized it would take quite a bit of change in the implementation and thought it'd be worth some discussion

13:31 dnolen: i.e., to support that you would need to seq over all of the keys of the target map and try to unify each one with the key-in-hand of the source map.

13:32 dnolen: lynaghk: like I said - would be nice - but not a priority.

13:32 lynaghk: dnolen: ah, sure. yeah, I'd wait til you get some feature requests about it before throwing unifier perf out the window =P

13:33 dnolen: thanks for the fast merge turnaround, btw.

13:34 abp: Hey lynaghk, how can I render directed svg-graphs with c2?

13:34 lynaghk: Would that be hard? I have basically no expierience with writing visualization algorithms.

13:34 lynaghk: abp: there isn't a graph layout engine in c2, if that's what you're asking about. If you're using c2 on cljs you can just use the force-layout engine from d3

13:35 abp: though in that case you would need to use mutable javascript objects since D3's engine just has a tick routine and updates the x and y properties of graph objects.

13:35 abp: lynaghk: Not cljs only.

13:36 lynaghk: And that's something I can't imagine to consider.

13:36 lynaghk: abp: graph layout is a very tricky problem; I'm not sure what's avaliable on the JVM side---you could probably do the layout calculations with graphviz

13:37 abp: A friend of mine at AT&T research also mentioned that there are some really good new algorithms based on shortest-path distances rather than the physics-y stuff

13:37 abp: lynaghk: Yes, I render svg now using lacij, but that's just to inflexible. Undocumented wrapper of a bunch of java-libs. A big bunch actually.

13:37 lynaghk: abp: but yeah, if you can get a list of nodes and connections with x & y coordinates already you can use c2 to draw them in SVG no problem. Take a look at the c2 svg namespace for some arc generation stuff

13:39 dnolen: lynaghk: on thought about yesterday's conversation - perhaps it would be uniform to only have symbols or vectors of symbols on the left handside instead of fns as keys.

13:42 lynaghk: dnolen: I'm not sure you'd be able to support all possible constraints in that case

13:44 dnolen: say you have predA and predB that both constrain vars ?x and ?y. If you allow functions on the left you can say {predA [?x ?y], predB [?x ?y]}. If you don't allow functions on the left, how could you express it?

13:45 dnolen: {[?x ?y] #(and (predA %1 %2) (predB %1 %2))} ?

13:46 dnolen: lynaghk: yes

13:48 lynaghk: dnolen: I think each of the syntaxes we've discussed has some awkward situations. Making lvars or vectors of lvars the map keys seems as good as any to me.

13:49 dnolen: sugar-wise, maybe people will want to write {#{?x ?y ?z} numeric?} to mean that those three vars should all be numeric

13:49 dnolen: but that's just something nice to have instead of having to write {?x numeric?, ?y numeric?, ?z numeric?}

13:50 dnolen: the thing I do like about having functions as keys in the constraint map is that it makes it easier for people to add/remove classes of constraints.

13:50 dnolen: lynaghk: yes special handling of set keys would probably be ok. I just want what appears on the left hand side to be consistent - vars or collections of vars.

13:50 lynaghk: dnolen: in my use case I can imagine wanting to talk in terms of constraint predicates more often than talking in terms of individual variables or sets of variables.

13:52 seangrove: Are there any cljs interface libraries wrapping goog.ui.*?

13:52 lynaghk: dnolen: also, I tend to have a nicer handle on predicate fns (which are usually toplevel vars created by defn) than I have on lvars (which I don't usually have a reference to at all---they're created for me by prep)

13:53 dnolen: lynaghk: yeah I don't really see any expressiveness issues here - just going for consistency.

13:53 {?x numeric?

13:53 er

13:54 {'?x numeric? '[?x ?y] complex-constraint}

13:54 lynaghk: dnolen: yeah, I agree with you on consistency. Now it's just a question of whether we want to talk in terms of lvars or constraints

13:55 dnolen: this is something that folks can solve for themselves using clojure.set/map-invert, though.

13:56 dnolen: lynaghk: yep, it's also about making it simpler / cleaner to process.

13:58 lynaghk: dnolen: is one of these forms easier to handle internally?

13:58 dnolen: I'd have thought in either case you are just doing something like (doseq [[vars pred] constraint-map] ...)

14:03 trinakria: Hello

14:05 dnolen: lynaghk: no it's not a matter of easier to handle - it's about picking just one thing, also it's pattern everywhere in core.logic for vars to appear on the left hand side

14:05 whether in substititons or when calling bindings-map etc

14:05 lynaghk: dnolen: that's good enough for me, then; lvars or collections of lvars on the left, preds on the right

14:06 dnolen: lynaghk: I agree that at first glance constraints on left seem ok, but I think in the long run systemic consistency trumps conveniences.

14:07 lynaghk: dnolen: agreed; as I said, if it's a big enough problem consumers can manipulate the constraint maps themselves.

14:07 dnolen: good call on that vs. metadata.

14:07 dnolen: lynaghk: yes :)

14:12 bbloom: dnolen: how do you maintain the cljs version of core logic?

14:12 dnolen: i want to release a lib for both clj and cljs, but i'm not super excited about the idea of copy pasting a whole file and then extracting the macros

14:13 dnolen: bbloom: copy & paste

14:14 bbloom: dnolen: :-(

14:14 lynaghk: bbloom: you can check out my cljx leiningen plugin. It's a hack, but so is every other solution to that problem.

14:14 bbloom: dnolen: I'm almost positive I could pull this off with make and sed ...

14:14 dnolen: bbloom: not much to be done until we get compiler support for feature expressions.

14:15 bbloom: dnolen: so i was following the feature expressions discussion

14:15 but i wasn't sure why that couldn't be added as a macro

14:16 Sgeo: I think nREPL might be a bit slow for me

14:16 bbloom: Kevin Downey pointed on in that thread that common lisp's issues don't affect clj here

14:16 Sgeo: Sometimes if I leave it running for long then do something it takes a while

14:16 seangrove: <p class="integration_menu full_contact_integration_menu active" style="top: 54.80000305175781px; overflow: hidden;"><div class="link_list_menu">

14:16 <h3>FullContact Profile</h3>

14:16 <div>

14:16 Social Profiles <small>(91% confidence)</small>

14:16 <table class="zenbox-table">

14:16 <tbody><tr>

14:16 <td class="link-action">

14:16 Sgeo: I tried (time (+ 1 1)) and it said it took 22 ms but it seemed on the order of seconds.

14:16 seangrove: <span class="social vimeo">

14:16 Sgeo: So what's going on

14:16 seangrove: <img src="https://www.zenboxapp.com/assets/service_icons/vimeo.png">

14:16 </span></td>

14:16 <td>

14:16 Sgeo: seangrove, /flushq

14:16 seangrove: <a href="http://vimeo.com/user9118251" target="_blank">user9118251</a>

14:16 </td>

14:16 </tr>

14:16 Sgeo: Then use a pastebin

14:17 seangrove: <tr>

14:17 <td class="link-action">

14:17 <span class="social plancast">

14:17 <img src="https://www.zenboxapp.com/assets/service_icons/plancast.png">

14:17 </span></td>

14:17 <td>

14:17 <a href="http://plancast.com/yayitswei" target="_blank">yayitswei</a>

14:17 Sgeo: @ops

14:17 ~ops

14:17 clojurebot: Gabh mo leithscéal?

14:17 seangrove: </td>

14:17 </tr>

14:17 <tr>

14:17 uvtc: How did all this html get in here? :)

14:17 seangrove: <td class="link-action">

14:17 <span class="social facebook">

14:17 <img src="https://www.zenboxapp.com/assets/service_icons/facebook.png">

14:17 </span></td>

14:17 <td>

14:17 <a href="http://facebook.com/yayitswei" target="_blank">yayitswei</a>

14:17 </td>

14:17 </tr>

14:17 nDuff: Someone mention when the flood is over so I can unignore. :)

14:17 seangrove: <tr>

14:17 <td class="link-action">

14:18 <span class="social gravatar">

14:18 <img src="https://www.zenboxapp.com/assets/service_icons/gravatar.png">

14:18 </span></td>

14:18 <td>

14:18 <a href="http://gravatar.com/yayitswei" target="_blank">yayitswei</a>

14:18 </td>

14:18 </tr>

14:18 </tbody></table>

14:18 </div>

14:18 </div>

14:18 ahem...

14:18 Sorry about that... command-v right next to M-v

14:18 mefisto: nDuff: flood complete

14:18 seangrove: Just meant to scroll up

14:18 I pasted instead of hitting M-v (in erc)

14:18 bbloom: dnolen: lynaghk: https://www.refheap.com/paste/6896

14:18 Sgeo: Oh

14:19 Does ERC have an equivalent to XChat's flushq?

14:20 dnolen: bbloom: dunno just seems uglier than CL syntax for that.

14:20 Sgeo: Who was Nosrat and why was e telling me not to say bullsh*t?

14:20 bbloom: dnolen: what does feature expressions buy us except for splice?

14:20 Sgeo: Only noticed it now

14:20 Name seems familiar

14:21 dnolen: bbloom: shipping one code base to multiple implementations of Clojure

14:22 nDuff: Sgeo: a bot that said the same thing to everyone, and not just in this channel.

14:23 Raynes: seangrove: You are hereby exiled from all of Clojure. Begone.

14:23 * seangrove wanders off with his tail tucked in-between his legs...

14:23 Raynes: If you're going to flood the channel, at least do it with Clojure and not HTML.

14:23 hiredman`: Kevin Downey is me, fyi

14:23 seangrove: I just see HTML as a subset of Clojure

14:23 Apage43: What about hiccup?

14:23 bbloom: lynaghk: I saw cljx, but I'm going to refrain from using it so that i don't need to manually change all that stuff when a real solution comes along :-P until then, i'll just ignore the jvm for this one task

14:25 lynaghk: bbloom: yeah, for sure. I wrote it to get some stuff out the door, but I'll be the happiest of anyone to tear that shit down once a real solution lands in core = )

14:26 bbloom: lynaghk: lots blocking a "real solution" sadly. from the simple (there needs to be a uniform way to raise an error) to the complex (macro system)

14:27 hiredman`: I would much rather "feature expressions" introduce a new special form or macro than make backwards incompatible changes to the reader

14:28 Sgeo: Ooh, feature expressions coming to Clojure soon?

14:28 bbloom: Sgeo: no change on status, just discussion

14:34 dnolen: i want to extend IMeta and IWithMeta to javascript functions. if I just do a simple aset/aget with a "__meta" string on the function, would that destroy perf? or be relatively harmless?

14:35 dnolen: bbloom: won't work because of advanced optimization, ohpauleez has a proper patch

14:35 bbloom: dnolen: although i think i might prefer to do a little wrapper object that implements IFn

14:36 dnolen: ah. is there a ticket for it?

14:36 dnolen: bbloom: yes

14:36 bbloom: funny how we all run into the same issues :-)

14:38 hiredman`: metadata on functions is kind of gross

14:38 bbloom: hiredman`: why?

14:38 hiredman`: there are identity issues

14:39 bbloom: i have a hash table of symbols to functions and a *small* percentage of functions are going to have some metadata on them

14:39 hiredman`: functions have identity equality, but at least with clojure functions implement the same metadata stuff as values

14:39 bbloom: i basically want to ask (-> f meta :some-flag) on dispatch

14:39 hiredman`: not the reference metdata stuff

14:40 bbloom: hiredman`: ah. yeah, dnolen mentioned ohpauleez' patch, which i found has this wrapper object: https://github.com/shoreleave/shoreleave-core/blob/master/src/shoreleave/efunction.cljs

14:40 * Sgeo thinks metadata on vars is gross

14:40 Sgeo: When they should be on functions

14:40 bbloom: hiredman`: seems to be lacking equality

14:41 hiredman`: yeah, you cannot do equality

14:41 because adding metadata returns a "new" wrapper function with the metadata

14:41 so, as I said, gross

14:41 bbloom: hiredman`: couldn't you just define equality on the wrapper and the built in and make them co-dependent? when comparing, just compare the unwrapped functions

14:41 technomancy: that's not metadata's fault

14:41 bbloom: hiredman`: doesn't seem to gross

14:41 technomancy: it's clojure's fault for doing a crappy job of equality

14:41 bbloom: too*

14:41 Sgeo: If you comp a bunch of functions, the result should have the same argslist as the first function to be applied.

14:42 arglists

14:42 amalloy: Sgeo: and indeed it does, in that neither of them have an arglist key

14:42 bbloom: amalloy: heh.

14:42 amalloy: (or, indeed, any metadata at all, on the function object)

14:43 bbloom: Sgeo: consider type hints too. you'd want the arglist of first and the return type hint of the last. the comp function suddenly gets quite expensive and complex....

14:45 Sgeo: I don't see a problem with comp doing that, but I guess it could be a PITA dealing with similar considerations for people writing their own functions?

14:46 llasram: Typed Clojure to the rescue?

14:46 bbloom: Sgeo: the performance cost would add up. quick. and you'd have to either A) throw away unknown keys or B) have a mechanism for comping them

14:46 B implying an *open* mechanism

14:46 technomancy: llasram: I don't want to have to annotate everything to get simple things like that

14:46 bbloom: seems absurdly complex and yes, llasram, get's into the typing world :-)

14:47 dnolen: if i took a crack at a function wrapper object with meta and equality working correclty, would you take that patch? :-)

14:48 llasram: I really agree with technomancy, but it seems like a type system is the endgame. Otherwise every function-returning function is doing the same legwork to correctly generate and propogate metadata

14:48 Or just live without it :-)

14:48 bbloom: I'd argue that (let [f (fn)] (= f (with-meta f {:x 1}))) is bugged in clojure

14:48 technomancy: clojure just needs better inference built-in

14:51 bbloom: with serializable-fn you could theoretically have equivalence between two functions that do the same thing but have different argument names

14:51 Sgeo: technomancy, um, not really?

14:51 technomancy: though of course true operational equivalence is undecidable

14:51 Sgeo: ?

14:51 Sgeo: technomancy, was thinking of operational equivalence

14:51 bbloom: technomancy: yeah, down that path lies dragons :-P i just want reference equality to work with-meta

14:56 dnolen: bbloom: I'm not in the least bit concerned about equality.

14:57 * nDuff files that away to pull out if dnolen ever goes into politics

14:57 dnolen: bbloom: if the patch supports Clojure's behavior that's good enough for me.

14:57 bbloom: dnolen: ok, let me take a crack at it

14:58 dnolen: bbloom: or look at the ticket and just implement ohpauleez's code

14:58 bbloom: dnolen: yup, i see his code. was going to grab that and then extend-protocol to function & should be done

15:04 dnolen: presumably fn? should work too

15:04 dnolen: bbloom: does it work in clojure>

15:05 ?

15:05 bbloom: #(fn? (with-meta (fn) {:x 1}))

15:05 ,(fn? (with-meta (fn) {:x 1}))

15:05 clojurebot: true

15:05 bbloom: yup

15:06 dnolen: bbloom: you could make a marker protocol Fn, and change fn? to check that too

15:07 bbloom: dnolen: good idea

15:11 ,(let [f (fn)] (= (hash f) (hash (with-meta f {:x 1}))))

15:11 clojurebot: false

15:11 bbloom: dnolen: gonna ignore hashcode too then

15:18 dnolen: core.cljs is kinda hard to navigate… kinda wished it was divided up and layered :-/

15:18 abp: Periodically posting, just in case anybody likes to yell at me for it: https://gist.github.com/4115467

15:19 dnolen: bbloom: would require something like load which doesn't exist - even then not sure if it's worth it.

15:30 bbloom: dnolen: the file is large enough to slow down vim, presumably due to some slow parens/ident logic in vimclojure…. where's tpope when you need him? :-)

15:31 dnolen: bbloom: heh I don't have that problem

15:34 jamii: looking forward to your presentation!

15:37 bbloom: dnolen: debugging advanced mode is still making me want to weep. we need source maps and we need them tied into the assert mechanism badly :-) gg get lunch before i do battle with single letter variable names

15:37 dnolen: bbloom: heh yep working on that right now

15:42 jamii: dnolen: :-S

15:52 thorwil: "Could not locate tlog/test/data/account__init.class or tlog/test/data/account.clj on classpath"

15:53 how's the stuff below "test" handled, different from "src"?

15:53 defa: new to emacs/nrepl… after adding deps to lein's project.clj, how to make them available inside emacs nrepl? Need to run "lein repl"? After connecting to the new nrepl evaluating expressions sometimes does not work and I have to restart emacs. Am I missing something essential here?

15:55 thorwil: defa: there are several ways to run an nrepl server

15:56 defa: if evaluating an expression does not work, you should get an error message. you can close error buffers. no need to restart emacs

15:57 defa: you repl session is in a namespace. starts in "user". you can do (in-ns project.your.ns) to switch into one o fthe namespaces defined in your clj files

15:58 defa: thorwil: terhmial: "lein repo" emacs M-x nrepl … after adding a dependency to project.clj how do I make these symbols available in emacs nrepl?

15:58 thorwil: I ment "lein repl"

15:59 Hodapp: thorwil: didn't know you were here, haven't seen you since #lad...

16:00 thorwil: doesn't "lein repl" start a server and client right there? haven't used it in a long time

16:00 Hodapp: heh, if i'm here, i'm also in #lad

16:00 Hodapp: haven't been in #lad in awhile

16:01 thorwil: defa: the repl works with namespaces just like in your clj files. besides the ns form, you can use "use" and "require"

16:02 still wondering how i get my test file unto the classpath

16:03 defa: thorwil: it's not a namespace issue… thanks anyway.

16:04 thorwil: defa: there seems to be a misunderstanding

16:05 defa: thorwil: never mind… I'll find out… something like: http://immutant.org/builds/LATEST/html-docs/interactive.html#sec-4

16:10 llasram: defa: That's an immutant-specific feature. You can do it yourself piecemeal by pulling pomegranate into your dependencies, but AFAIK there isn't a general-purpose "reload by project.clj deps w/ restarting the REPL server" library

16:11 xeqi: ritz has something similar

16:11 they all suffer from possibly loading incompatible libraries

16:11 thorwil: defa: i assumed the case where the dependencies are actually in place. whenever i add a dependency here, i restart immutant, to be honest :/

16:12 llasram: Oh yeah, that's right! I need to try that. I think it didn't stick because it blew up during hugod's Conj talk *sadface*

16:12 defa: xeqi: okay, thanks… good to know… so simply start "lein repl" again in reconnect in emacs?

16:13 xeqi: I use M-x nrepl-jack-in rather then `lein repl` and M-x nrepl, but either way works

16:13 jcromartie: ~seen ignacy

16:13 clojurebot: excusez-moi

16:14 thorwil: xeqi: nrepl-jack-in starts an nrepl server, right? if so, it's the wrong choice for immutant which provides ones

16:15 xeqi: thorwil: I didn't think `lein repl` was a choice for using immutant anyways; though it started its own nrepl server

16:15 tcrawley: ^ ?

16:15 hugod: xeqi: ritz is supposed to check if any of the dependencies have been replaced, and create a new instance of the clojure runtime if so

16:16 tcrawley: xeqi: correct. nrepl-jack-in/lein repl will not work with immutant, since you have to deploy to it with nrepl enabled for the app

16:16 at that point, it starts an nrepl server for you

16:16 thorwil: xeqi, defa : yes, it's "lein immutant run" and just "nrepl" in emacs

16:16 tcrawley: if you aren't in immutant, I recommend ritz

16:17 Foxboron: mmm, Going to buy 2 clojure books. The Joy of Clojure and Programming Clojure should be the two best for a beginner?

16:17 xeqi: I recommend http://www.clojurebook.com/

16:18 Urthwhyte: Foxboron: I really enjoyed Programming Clojure and am starting Joy this weekend

16:18 Foxboron: umm, yeah. I mixed Programming Clojure with Clojure Programming...

16:18 Urthwhyte: the former + my roommate had me up and running in a few days

16:18 Foxboron: Like srsly, why did they name those two books the same?

16:19 cemerick: We unfortunately had no input on the name. :-(

16:19 Raynes: Theyd idn't.

16:19 cemerick: xeqi: and, thanks :-)

16:19 technomancy: could be worse; could be Programming Scala

16:19 Raynes: cemerick: As if you don't pay him each time he says that.

16:20 Foxboron: technomancy, what about programming php?

16:20 cemerick: xeqi: Your 25¢ is in the mail!

16:20 Sgeo: I like what I've read of The Joy of Clojure

16:20 xeqi: hurray!

16:20 technomancy: clojurebot: Programming Scala is <reply>wait, do you mean Programming Scala, Programming Scala, or Programming in Scala?

16:20 clojurebot: scala is val foo = bar ~-> 45 <~< "Fred" %% x

16:20 technomancy: aw come on

16:20 clojurebot: Programming Scala |is| <reply>wait, do you mean Programming Scala, Programming Scala, or Programming in Scala?

16:20 clojurebot: flatten |is| rarely the right answer. What if your "base type" is a list

16:20 brehaut: cemerick: the side effect of having no control on the name is that everyone refers to it by domain

16:20 technomancy: clojurebot: jerk

16:20 clojurebot: you cut me deep, man.

16:21 Urthwhyte: brehaut: but there's no do before it

16:21 Sgeo: What should I name a converter function?

16:21 Foxboron: If there is any Sublime uesers here, i just updated my collection of snippets with new triggers. Should be easier to type them naow :3

16:21 Sgeo: flat-to-shaped, or shaped<-flat (the latter is a convention I saw somewhere, which makes sense I guess if you're nesting)

16:21 cemerick: brehaut: Indeed; it should have just been titled "The Clojure Book", and everything would have worked out nicely.

16:22 Sgeo: or flat->shaped and just use -> for nesting?

16:23 brehaut: Urthwhyte: err…?

16:25 Urthwhyte: brehaut: it was a joke - you said there was a side effect of naming it in that manner, so I was riffing on the need for a do for functions with side effects

16:25 brehaut: Urthwhyte: ah. well thats wrong. you do not

16:26 Urthwhyte: you need a dosync to do STM transactional side effecting stuff, but any function can just go ahead and mutate anything anywhere

16:28 amalloy: Sgeo: flat->shaped is by far the more common if you're choosing from those three options

16:28 brehaut: ,(repeatedly 5 #(rand-int 5)) ; Urthwhyte, side effects without do

16:28 clojurebot: (1 1 3 2 0)

16:28 Sgeo: amalloy, well, if there are other options for the name I'm open to them

16:28 I'm not really restricted here, except ideally the name should be clear

16:28 amalloy: or you could just call it shaped, or something equally basic, if in context that still makes sense

16:29 Sgeo: Well, there's no other conversions except shaped->flat, but I want to refer to the results as flat or shaped, so

16:29 Clearer to just use the longer name

16:30 gfredericks: brehaut: how about (println "foo")?

16:30 brehaut: gfredericks: well yes obviously that too

16:33 technomancy: eh; non-referentially-transparent functions aren't necessarily side-effecting

16:33 bbloom: dnolen: http://dev.clojure.org/jira/browse/CLJS-359

16:34 gfredericks: technomancy: I was just having a side-argument with him about that

16:34 technomancy: side-argument? are you in new zealand?

16:34 gfredericks: no; the internet has other communication channels

16:34 technomancy: lies

16:34 gfredericks: but now that you've taken my side I think that means I get 15 kiwi-points

16:35 technomancy: redeemable for delicious kiwi at any roadside stand?

16:35 gfredericks: not sure yet

16:35 brehaut: wait, you people eat kiwis‽

16:35 gfredericks: I love how much I have no idea if he's actually surprised

16:35 technomancy: oh did I say that out loud; oops

16:36 brehaut: gfredericks: but they are endangered

16:36 dnolen: bbloom: I don't think we should use a Function type, just use reify for now.

16:36 gfredericks: they make the bald-eagle tacos a little less bland

16:37 bbloom: dnolen: ok

16:40 dnolen: hmm that makes me wish there was a way that extending a protocol to function would also affect the reified value

16:40 dnolen: ie reify and delgate

16:40 dnolen: but anyway, i can't just reify

16:40 dnolen: because -with-meta needs to call Function.

16:42 dnolen: bbloom: you can make anon reify constructor fn

16:42 (fn [f meta] (reify ...))

16:43 bbloom: dnolen: hm ok

16:43 dnolen: hmm actually you do want to share that, so you probably need to name it, still not a big deal

16:44 oh take that back - I don't think you do

16:44 you only with need that in the IWithMeta case

16:44 so yeah anon ctor fn will work

16:45 bbloom: dnolen: you need it in *two* IWithMeta cases

16:45 dnolen: er ... it needs a local name - but you get the idea.

16:45 bbloom: dnolen: yeah

16:45 doing it

16:46 deeply indented reify looks ugly as sin, but it's ok :-P

16:47 dnolen: bbloom: also your fn? looks wrong, you need still need to call goog.isFunction as well

16:47 bbloom: dnolen: nope, tested that

16:47 and looked at goog.isFunction

16:47 dnolen: it's testing typeof x === 'function'

16:48 this will basically be testing x.prototype._some_magic_protocol_thing

16:48 dnolen: note that I do (extend-type function Fn)

16:48 dnolen: bbloom: yeah you don't want to do that. do both tests - perf thing.

16:49 that will make testing regular JS fns crazy slow

16:49 typeof x === 'function' is crap JS engines optimize

16:49 don't want to lose that and go through all those tests in satisfies? for JS natives

16:49 bbloom: dnolen: is satisfies? really slow? i thought it was pretty fast !!x.protocol.y

16:49 dnolen: bbloom: we don't mess w/ natives

16:50 bbloom: dnolen: oh duh. the hash lookup

16:50 of course

16:50 you're right

16:50 dnolen: bbloom: separate lookup after the optimized stuff fails

16:50 bbloom: dnolen: forgot :-)

16:50 dnolen: sadly then, this will slow down fn? tests against primitives that aren't functions

16:50 dnolen: so if you're doing fn? and expect it to *usually* return false, then that's slower

16:51 dysinger: technomancy: remind me what the equiv of flip is in clojure again

16:51 Prelude> let divBy3 = flip (/) 3

16:51 Prelude> divBy3 12

16:51 4.0

16:52 bbloom: dnolen: could do something like (or (goog/isFunction f) (and (not (primitive? f)) (satisfies? Fn f)) if we had a fast primitive? test

16:53 dnolen: bbloom: eh don't really think it's worth it, don't see how you can make primitive? any faster than satisfies?

16:54 bbloom: typeof x != "object" ?

16:54 dnolen: bbloom: or much faster anyway.

16:54 bbloom: dnolen: ^^

16:55 dnolen: bbloom: typeof everything that is not native is "object", so how would that work?

16:56 bbloom: dnolen: assumption being if typeof anything is "object" then you need to run satisfies? to see if it's a function. but i won't pretend to have fully internalized the subtlies of javascript's odd typeof and instanceof and primitives and what not

16:58 dnolen: bbloom: I think goog.isFunction + satisfies? is good enough for now, just remember to hint the return value of goog.isFunction in the or.

16:58 (or ^boolean (goog.isFunction f) (satisifes? Fn f))

16:58 bbloom: dnolen: got it

17:00 dysinger: I'm too rusty

17:00 * dysinger goes back to haskell

17:01 brehaut: dysinger: (/ 3) ?

17:03 gfredericks: clojure don't got no flip

17:03 dysinger: it needs a point free flip

17:03 user=> (def one-third (partial / 3))

17:03 #'user/one-third

17:03 user=> (one-third 12)

17:03 1/4

17:03 user=>

17:03 wrong answer with that

17:03 gfredericks: I think flatland/useful has it

17:03 dysinger: k

17:04 gfredericks: dysinger: partial is just so much effort compared to haskell currying :/

17:04 dysinger: just curious

17:04 Sgeo: You probably want (def one-third #(% / 3))

17:04 Although that's not pointfree

17:05 brehaut: yeah, if you need to reach for partial and flip in clojure #(…) is better

17:05 dysinger: I was trying to do cobbling together comp, partial & reverse

17:05 but yeah - I know I can do it with # & % but that's cheating

17:05 gfredericks: oh man guys we need to try to define flip point-free

17:05 just to be obscene

17:05 Sgeo: Clojure doesn't even have $ you have to write #(%1 %2)

17:05 brehaut: incidentally, haskell calls the partial application of infix operators 'sections' ;eg, (/), (/ 3) and (3 /) are sections of /

17:06 Sgeo: Or #(apply %1 (rest %&)) or something depending on circumstances

17:08 ChongLi: there's a tradeoff here

17:08 Haskell functions are curried by default

17:08 whereas Clojure functions have variable args

17:08 at least that's my understanding of it

17:10 dnolen: Clojure functions also have the benefit of being backed by something malleable - they are not primitive.

17:11 comparing Haskell fns & Clojure fns just doesn't make any sense

17:11 ChongLi: yeah, they are very different animals

17:11 and support different abstractions

17:11 gfredericks: what malleable thing are clojure fns backed by?

17:12 dnolen: gfredericks: IFn

17:12 ChongLi: so to really compare them you need to make a judgment about which abstraction is important to you

17:12 * gfredericks hmms

17:12 bbloom: dnolen: duuurrrrr reify automatically adds meta support

17:12 * bbloom facepalm

17:13 gfredericks: yeah anytime I thought about trying to port parts of clojure.core to haskell the vararg thing came back making everything ugly

17:13 or impossible

17:13 you just can't do apply in haskell

17:14 dnolen: lots of things are impossible like this "function": http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L3853

17:14 ChongLi: or how about clojure's map?

17:14 Raynes: You can, but for concrete numbers of args.

17:14 ChongLi: it's way more general than haskell's in some ways

17:15 dnolen: bbloom: ah right heh :)

17:15 bbloom: so that patch is trivial :)

17:15 bbloom: dnolen: yes :-)

17:15 dnolen: i was staring at the generated javascript… wondering "wtf is all this extra meta meta shit in here?"

17:15 dnolen: bbloom: haha

17:15 gfredericks: Raynes: that's what I mean by "can't" :)

17:16 bbloom: dnolen: oh this is much nicer :-)

17:20 dnolen: updated http://dev.clojure.org/jira/browse/CLJS-359

17:20 dnolen: hopefully that does the trick because id like to go back to making what i hope will become the jquery of clojurescript :-)

17:21 gfredericks: cljquery

17:22 dnolen: bbloom: I hope by that you mean, something everyone uses - and not actual analog of jQuery which a complected mess.

17:22 bbloom: dnolen: yeah, i mean the library that is so good and obviously the the right way to do it that everybody uses it

17:22 dnolen: very clojury: data all the things!

17:23 gfredericks: data the whole dom? webfui?

17:24 bbloom: gfredericks: the idea is to treat dom manipulations as little programs in postfix notation :-)

17:24 gfredericks: are you inventing the dom monad?

17:24 bbloom: gfredericks: not a monad, think factorcode.org

17:24 dnolen: boom, fns w/ metadata in CLJS now http://github.com/clojure/clojurescript/commit/6ce3b1cef3824fd36e75402f5a8ed5053252b15e, thanks bbloom

17:25 bbloom: dnolen: sweet thanks

17:25 * gfredericks has not seen factorcode.org

17:25 dnolen: bbloom: pleasingly simple change.

17:26 bbloom: gfredericks: yeah, the idea is that stacks and trees like the dom play nice together. clojure is all about immutibility, but the dom is this big mutable mess. so the premise is to treat it like a remote service: you send it programs written in a notation similar to how you send printers postscript

17:27 gfredericks: being a postfix notation means you can compose programs trivially via concatonation

17:27 factor is to forth as clojure is to common lisp

17:27 entertainingly enough, factor started out as what is no called JFactor ;-)

17:28 gfredericks: bbloom: that is an intriguing approach

17:29 bbloom: gfredericks: here's a working example

17:29 "root" get-element "div" tag "button" class "i am a button" text append

17:29 clearly you'd format that with newlines, etc

17:29 but that adds a button to the "root" element

17:30 with the right class, text, etc

17:30 get-element pushes the element onto the stack

17:30 all the jquery transformations can be implemented as applying a map function to a list of elements on the top of the stack

17:30 so you don't even need to wrap each dom element in some kinda of monad thing

17:31 brehaut: …other than the list

17:31 bbloom: brehaut: well yeah, but this also works:

17:31 ".button" select

17:31 which has stack effect ( selector -- elements )

17:32 gfredericks: as long as a list of elements is a different thing from a single element then I'm happy :)

17:32 bbloom: gfredericks: it will be, but all of the transformation operators will wrap and unwrap elements in lists as necessary

17:35 this brings up an interesting thought tho

17:36 eh nevermind, i need to noodle to myself more first

17:38 gfredericks: is it roughly accurate to call jquery's approach "weak typing"?

17:38 at least at a high-level

17:39 bbloom: gfredericks: in what sense?

17:40 gfredericks: hmm

17:40 I recant everything

17:41 hugod: wow, core.logic has working inequalities - thanks dnolen!

17:41 gfredericks: either dnolen is the man or that term is not very useful.

17:43 bbloom: hugod: w00t! somebody likes my 1 and only patch to core.logic! :-) (granted, dnolen did all the hard work to make that possible, i just added some inequality symbols to a map, heh)

17:43 hugod: bbloom: oh, didn't realise - thanks bbloom!

17:44 bbloom: hugod: heh, my pleasure, but really all dnolen on the meaty bits. core.logic is damn awesome

17:44 gfredericks: bbloom: I have one patch to core logic, and it made its way into dnolen's strange loop presentation; his commentary was "don't pay any attention to that part some guy added it" :D

17:44 bbloom: gfredericks: heh, what part was that?

17:45 gfredericks: oh um (run [a b c] ...)

17:45 multiple query variables

17:46 I got real tired of (run [q] (fresh [a b c] (== q [a b c]) ...))

17:49 dnolen: gfredericks: haha, oh right :) I didn't mean that patch wasn't useful of course - I've been thinking about a few more enhancements along those lines.

17:50 hugod: yeah the finite domain stuff is more or less working but it'll be some time before it's efficient ... but I'm not going to let that hold up a release. I think as soon as I get lynaghk enhancements and I fix tabling - 0.8.0 will be wrapped up.

17:50 gfredericks: dnolen: it did make me wish I had factored the patch a bit better so it didn't get in your way :)

17:53 hugod: dnolen: I'm not too worried about efficency at the moment - look forward to a release ;)

17:53 dnolen: hugod: cool, not far off.

18:10 Raynes: FYI, I just broke the crap out of refheap. It'll be down for a minute while I sort it out.

18:11 Fixed.

18:11 Okay, so.

18:11 Dear everybody and persons, I have finished moving refheap to compojure and have deployed it for a trial run before I release to my master branch.

18:12 Please report any issues promptly, and I will pretend to fix them immediately.

18:15 Bronsa: dnolen: ping

18:15 dnolen: Bronsa: pong

18:16 Bronsa: i got blind to run 5x times slower than clojure LispReader

18:16 the bottleneck was my implementation of StringPushbackReader

18:17 dnolen: Bronsa: nice

18:19 Bronsa: dnolen: right now the bottleneck is satisfies?

18:19 without calls from satisfies to attach line/column metadata, it runs as fast as LispReader

18:21 dnolen: Bronsa: yes you don't want to use satisfies? it's slow as crap

18:21 Bronsa: dnolen: should i use instance? instead?

18:21 dnolen: Bronsa: use instance? to check the interface directly

18:21 yes

18:22 the problem is that is satisfies? fails, it tries to walk the entire class hierarchy to find a type that satisfies the protocol :(

18:22 Bronsa: yeah

18:22 dnolen: inheritance I mean

18:23 but that's SWEET

18:23 fast as LispReader and in pure Clojure :)

18:23 gotta run that's good news

18:23 Bronsa: :)

18:26 tomoj: satisfies? is slow in cljs?

18:26 or jvm?

18:27 Sgeo: Blah, how do I take a seq of characters and turn it into a string

18:27 gfredericks: apply str

18:27 ,(->> "foo" seq (apply str))

18:27 clojurebot: "foo"

18:27 Sgeo: Hmm

18:28 gfredericks: ,(str \a \space \+ \space \b)

18:28 clojurebot: "a + b"

18:30 Sgeo: Could also do clojure.string/join I guess

19:04 seancorfield: in the incanter docs it suggests (use '(incanter core stats charts)) as a way to pull in all the appropriate names for casual use... what would be the 'modern' equivalent with require and :refer :all ?

19:04 Raynes: callen: You might be particularly interested in my move of refheap to compojure, since you used it as something of a reference.

19:07 tomoj: (pprint #'AProtocolVar) prints endlessly

19:07 since (= #'AProtocolVar (:var AProtocolVar))

19:09 Sgeo: Anyone experienced with JNA and JNAerator here?

19:09 I have a function that accepts a const char *

19:09 gfredericks: tomoj: I think of pretty printing as just for data

19:09 Sgeo: JNAerator made a method that takes a String

19:10 The C function will make a copy of the C string that it's passed in, so I should free the memory that JNA used for its copy of the C string. How do I do that?

19:10 Or will the memory not leak for some reason if I don't?

19:10 tomoj: was trying to pprint analyze's output

20:01 Frozenlock: Will the clojure-conj presentations be uploaded to blip.tv?

20:02 ChongLi: I sure hope so!

20:06 wingy: cant wait for it

20:09 Frozenlock: We want clojure-conj videos! When do we want them? Now!

20:12 Any good struct/record/protocols introductions around? Something for children would be terrific!

20:12 'cause for adult hurt ma brain

20:14 ChongLi: http://oredev.org/2012/sessions/expressing-yourself-polymorphism-in-clojure

20:14 there you go :)

20:15 it doesn't cover structs, however, but they are deprecated afaik

20:15 technomancy: Frozenlock: use maps

20:15 and defns

20:15 Frozenlock: ChongLi: Thank you very much!

20:15 ChongLi: yeah listen to technomancy

20:15 use maps

20:15 egghead: until you don't need to :)

20:15 ChongLi: unless you need to do some polymorphic stuff

20:15 egghead: until you can't*

20:16 Frozenlock: I agree that listening to technomancy is usually a smart thing to do :)

20:16 ChongLi: turning your data into records should be viewed as an optimization step

20:17 and so the rule of thumb against "premature optimization" applies

20:17 Frozenlock: I'm trying to make a clojure wrapper around a java library with maaaaaany classes, each with multiple methods and I still don't know where to begin.

20:17 ChongLi: unless of course you need to dispatch on the type

20:17 technomancy: probably don't want to begin by repeating their mistakes =)

20:17 ChongLi: why are you wrapping a library?

20:18 Frozenlock: ChongLi: I don't like it :P

20:18 ChongLi: just build a new, higher level library above it

20:18 a wrapper (to me, anyway) implies a dumb repeating of work

20:32 Frozenlock: Hmmm... is there a way to eval a function when retrieving a value in a map? {:a 1 :b 2 :c (get-some-value)}

20:32 ChongLi: Frozenlock: not sure what you mean

20:32 clojurebot: Excuse me?

20:32 gfredericks: Frozenlock: ditto

20:32 Frozenlock: The value is time sensitive. I would like to 'look it up' only when necessary.

20:33 ChongLi: you're associating :c with the value returned by applying (get-some-value)

20:33 gfredericks: you could make the value an atom? or a function?

20:33 brehaut: or a delay

20:33 ChongLi: yeah, a delayed function

20:34 gfredericks: ,(let [m {:a (partial rand-int 15)}] [((:a m)) ((:a m))])

20:34 clojurebot: [9 11]

20:34 brehaut: ,(let [m {:a (delay (rand-int))}] [(@(:a m) @(:a m)])

20:34 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: ]>

20:34 loliveira: is there any way to the macro ->> return nil if any part returns nil? (->> %2 :attrs :x:num utils/toDouble). For example, if :x:num return nil, toDouble should be never called.

20:35 Frozenlock: (let [m {:a (partial rand-int 15) :b 1 :c 3}] [((:a m)) ((:b m))])

20:35 &(let [m {:a (partial rand-int 15) :b 1 :c 3}] [((:a m)) ((:b m))])

20:35 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

20:35 brehaut: ,(let [m {:a (delay (rand-int 1))}] [@(:a m) @(:a m)])

20:35 clojurebot: [0 0]

20:36 brehaut: delay has slightly different semantics to just a fun; it caches the result i believe, rather than reevaluating

20:36 Frozenlock: :/

20:36 ChongLi: you can write your own delay

20:37 wingy: do you add a doc-string to all your functions?

20:37 * Frozenlock looking the source now

20:37 gfredericks: loliveira: I think what you want is called -?>>

20:37 and it might be in the incubator lib

20:37 loliveira: thought -?> would work just as well in your example

20:37 brehaut: ChongLi: but why would you? if you dont want delays semantics, then a function of no arguments probably does it just fine

20:38 ChongLi: brehaut: yeah

20:38 delay is just a macro that wraps a function of no arguments in a memoizer

20:38 Frozenlock: Suppose I've written my own delay function which re-evaluates each time. Is there a way to avoid the @ (or deref call)

20:39 ChongLi: and then force just calls that function on no arguments

20:39 you can avoid deref

20:40 Frozenlock: I suppose what I want is a lazy map that re-evaluates each time...

20:40 loliveira: gfredericks: thank you!

20:45 Sgeo: user=> (clj-vp.attributes/produce-getset-map)

20:45 CompilerException java.lang.IllegalArgumentException: Malformed member expressio

20:45 n, expecting (. target member ...), compiling:(NO_SOURCE_PATH:1)

20:45 Sorry

20:45 That's... not really a helpful error message :(

20:48 ChongLi: what is clj-vp.attributes?

20:48 the . seems to be invoking java interop

20:49 Sgeo: clj-vp.attributes is the namespace of the code in question

20:49 And there is a lot of Java interop involved

20:49 ChongLi: ah

20:49 can you require with :as

20:49 to give a shorter name

20:49 so that it won't have a . in it?

20:50 gfredericks: Sgeo: any chance the exception was from your previous command?

20:51 Sgeo: Same error

20:52 ChongLi: then you'll have to work your way back through the stacktrace

20:53 you have some malformed java interop expression

20:53 Sgeo: But... the stack trace gives little useful information

20:54 Looking at the output of a function that the macro calls, where any errors are most likely

20:54 (It's horrific ugly and repetitive code)

20:55 ChongLi: produce-getset-map is a macro?

20:55 expand it

20:55 Sgeo: I did

20:56 ChongLi: and...? I don't have enough information to help you

20:58 wingy: to mock or not to mock, that is the question

21:00 gfredericks: wingy: the revered hickey says something about your mock objects mocking you for needing them

21:00 so the answer is unquestionably "not to mock"

21:00 xeqi: except when you should mock

21:00 wingy: gfredericks: is there a presentation about that?

21:00 it takes a lot of time to mock .. im mocking http request responses

21:02 jamesmacaulay: Hi folks, I'm looking to package up my first clojure lib and I have zero Maven experience. Is there a good guide somewhere? I figure I should test locally first by packaging and including as a dependency of another project.clj, to make sure everything works before pushing to clojars or whatever. I found lein-localrepo, am I on the right track here?

21:02 wingy: gfredericks: i mock for some reasons: 1. sometimes you can't automate eg. you need to manually interact with UI 2. sometimes you can't set up the correct testing env in the service you are using (eg. can't reset the state of the service)

21:02 gfredericks: wingy: maybe somewhere; I really don't know :/

21:02 wingy: gfredericks: would be cool to hear what the legendary hickey says about testing/mocking

21:03 gfredericks: wingy: I think the OOP people have maybe a more specific definition of mocking than what you're using? but I couldn't say for sure

21:06 amalloy: you don't need to mock http responses, if your business code doesn't make http requests of its own accord. it could, for example, return a function that expects a map representing an http response

21:06 in prod you call that function with actual http responses, and in a test you call it with mock data

21:07 that's a simplistic version, but you can elaborate as needed

21:08 ChongLi: things become a lot simpler when you try to put the bulk of your code in pure functions

21:08 gfredericks: usually

21:09 I imagine in extreme cases you might end up just reinventing the IO monad

21:12 wingy: amalloy: sounds advaned

21:12 advanced

21:12 but some code has to do the http requests

21:13 amalloy: you're mocking, man. attempting to redefine arbitrary pieces of your business code from outside is pretty "advanced" too

21:13 wingy: im wrapping the http api for a service

21:14 amalloy: so you are saying my api functions should not make the http requests themselves but be passed a response map?

21:15 hmm .. their job is to return the response map :)

21:16 Sgeo: Sorry, dealing with RL BS right now

21:17 wingy: if everyone was using datomic we would have it easier writing tests

21:17 s

21:17 ince

21:18 since there would be no changed state .. so you setup a database value and then you use that one to test against .. that db value will never change

21:19 gfredericks: wingy: I realized the other day that "database as a value" could make it a lot easier for a web server to be a pure function

21:19 at least for the read-only requests

21:20 wingy: yeah .. in -> out

21:22 really cool if you think about it .. no side effects .. the same http request give exactly the same browser view

21:22 Frozenlock: ChongLi: Thank you very much for the video, I'm really enjoying it!

21:22 wingy: making it easier to catch bugs .. just give me the http request and i can produce the same view

21:23 Sgeo: Spitting the pretty-printed macroexpansion to a file

21:23 Maybe that will help me

21:23 muhoo: "Your mock object is mocking you.... for needing it" -- Rich Hickey

21:23 Sgeo: Avoid losing my sanity

21:23 ChongLi: Frozenlock: that's good!

21:23 it's a nice presentation

21:23 Sgeo: Is a macro that expands into 29kb of code a bad idea

21:23 >.>

21:23 ChongLi: wow

21:23 gfredericks: probably

21:24 ChongLi: Sgeo: perhaps you want to step through evaluation a bit

21:24 gfredericks: are you expanding to (def one 1) (def two 2) (def three 3) ...?

21:24 Sgeo: gfredericks, I'm expanding into a map of maps of functions

21:25 wingy: i so want to watch that presentation https://twitter.com/ybits/status/173225782678794241

21:26 ChongLi: wingy: haha

21:26 gfredericks: Sgeo: what fer?

21:26 Sgeo: This is what I'm expanding into https://www.refheap.com/paste/bca9e92373ae550f90e473e9c

21:27 gfredericks: Sgeo: one thing to keep in mind is that each of those fn's is a separate class on the jvm

21:28 Sgeo: is there any reason you can't create this at runtime with a regular function?

21:28 Sgeo: Would it be better to use Java reflection to try to do (. vp.VPLibrary$VPFloatProperty x) where x is supplied at runtime?

21:28 Because I have no idea how to do that

21:29 Kowboy: so, all Clojure functions implement java.lang.Runnable, right? Isn't that only useful if the fn has no args?

21:29 ChongLi: just call class on the object

21:29 and dispatch on the result

21:29 gfredericks: Sgeo: ah ha so it's that you have a big pile of instance methods you want to call?

21:29 ChongLi: (to do reflection)

21:29 or write a protocol for that matter

21:29 Sgeo: gfredericks, well, they're static

21:29 gfredericks: Kowboy: probably so

21:30 Sgeo: ah ha

21:30 Sgeo: Wait, no

21:31 vp_float is a method on a thing that always stays the same, which is why I have call-vp

21:31 Kowboy: seems like most fns would simply throw ArrityException if you passed them to a thread

21:31 amalloy: Sgeo: what is clj-vp.private/call-vp?

21:31 Kowboy: unless I'm missing something, it simply seems like a shortcut for creating a Runnable when that is actually what you want

21:32 Sgeo: amalloy, very trivial macro

21:32 amalloy: Kowboy: yes

21:32 Sgeo: https://www.refheap.com/paste/f9d6cf4df13fdb64d671332e2

21:33 ...I'm not supposed to be using call-vp here at all.

21:33 It's fine for the set but not for the get

21:34 But I don't see how that mistake would cause this error, hmm

21:35 ChongLi: you said all those were static methods?

21:37 Sgeo: .vp_float is not static, it's called on +INSTANCE+

21:37 ChongLi: oh

21:37 Sgeo: vp.VPLibrary$VPFloatProperty/VP_OBJECT_X for example, though, is a static field

21:42 ChongLi: where are you getting the keys (such as :avatar-name) to look up in this map?

21:42 wingy: http://www.exampler.com/blog/2011/09/29/my-clojure-problem says rich hickey is not fond about tdd .. what does he suggest?

21:43 ChongLi: this seems like protocols or multimethods would solve this issue

21:43 Sgeo: Obtained via reflection on vp.VPLibrary$VPStringProperty and massaged to be a keyword

21:43 Maybe I'm doing the . form wrong

21:44 Apparently not

21:44 amalloy: Sgeo: tbh your code looks good to me

21:44 xeqi: jamesmacaulay: https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md or https://github.com/clojuredocs/cds/blob/master/articles/ecosystem/libraries_authoring.md

21:44 amalloy: have you tried macroexpanding one of the clj-vp.private/call-vp forms?

21:45 jamesmacaulay: xeqi: thanks!

21:45 ChongLi: or how about macroexpand-all on the entire thing?

21:46 and then just testing one of the resulting expressions a bit in the repl

21:47 amalloy: ChongLi: no good, because macroexpansion is what's throwing the exception

21:47 &(macroexpand-1 '(.foo))

21:47 lazybot: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)

21:47 ChongLi: oh

21:48 Sgeo: I just wish it says what it saw

21:49 That would be nice

21:49 ChongLi: hmmm

21:51 what does throw-rc do?

21:51 Sgeo: It's a function, if the result is not 0, throws an exception based on it

21:52 Erm, if its argument

21:53 ChongLi: what if you get rid of call-vp so it's just (.vp_string ...)

21:53 just for testing

21:53 then we'll know if it's call-vp causing the failure to expand

21:54 wingy: "These are the facts as I know them: Rick doesn’t practice TDD (in fact he finds it a “waste of time”), but several other clojure/core contributors actually do. "

21:54 i don't get how he test that his code works without testing :)

21:54 ChongLi: that doesn't mean he does no testing

21:55 just that he doesn't write tests first

21:55 gfredericks: clojure has tests

21:55 Kowboy: one thing I like about TDD is that it puts you immediately in the seat of the person that is using the public api of your library

21:56 wingy: to TDD or not to TDD, that is the question

21:56 ChongLi: Kowboy: on the other hand, it forces you to make decisions before you might feel ready to do so

21:57 bbloom: is there some way to use clojure.walk/prewalk but cull a branch of the walk?

21:57 wingy: but shouldn't we design before implement

21:57 Sgeo: Got rid of call-vp

21:57 Kowboy: true

21:57 there are good things about top-down and bottom-up

21:57 wingy: how can you build Eiffel tower without a blueprint

21:57 Kowboy: starting small, you get nice, reusable chunks of coide

21:57 ChongLi: wingy: according to Gerald Jay Sussman; no

21:58 wingy: so perhaps if you can't make design calls then you have to study design first

21:58 Kowboy: but how to compose them together to build a nice api for the user can be tricky

21:59 Sgeo: https://www.refheap.com/paste/769824be706624249f57b547c

21:59 Kowboy: I think starting top down, with your public functions defined at a high-level, and working tests, you can then break up these functions as you go and be confident that you haven't changed the behavior

21:59 so both ways have benefits

22:00 ChongLi: Sgeo: ok, does this still fail?

22:00 Sgeo: Yes

22:00 I'm going to comment out this macro and do the reflection thing

22:01 Kowboy: wingy: that's not very agile. I mean, some design is required, but only as much as is necessary to solve today's problem

22:01 wingy: here he explains what he means http://www.codequarterly.com/2011/rich-hickey/ but it seems that he is against testing overall

22:01 ChongLi: Sgeo: macros are very tricky to get right in situations like this

22:02 wingy: no, he's against writing a lot of tests

22:02 wingy: ok

22:02 sounds fair

22:02 ChongLi: I don't think he has any problem with writing some regression tests

22:02 wingy: im not very fond of writing a lot of tests myself

22:03 ChongLi: that's totally different from designing your entire system by writing all of the tests

22:03 before writing any code

22:03 wingy: yeah

22:03 ChongLi: a lot of what I see in TDD could be called pathological testing

22:03 testing of things which are obvious

22:04 wingy: yeah i have seen that a lot

22:04 ChongLi: which is silly, because real problems are usually not so obvious

22:04 wingy: yepp

22:04 Kowboy: ChongLi, I think that is more white box testing

22:04 ChongLi: if you write pure functions you can avoid a lot of test-writing

22:04 by using generative testing

22:05 Kowboy: possibly, but you have boundary conditions in pure functions as well

22:07 ChongLi: a particularly good generative testing framework can really help you with the corner cases

22:07 wingy: ChongLi: http://stackoverflow.com/questions/562845/what-is-a-generative-unit-test-framework

22:07 ChongLi: yeah I know

22:08 quickcheck et al

22:08 wingy: have a look at the first test .. so it's just asserting that the sum is a integer?

22:08 how can i be sure that the integer returned is the sum of the values

22:08 ChongLi: wingy: subtraction

22:08 you simultaneously test addition and subtraction

22:09 wingy: cool :)

22:09 ChongLi: that leaves only the case where they're both broken in such a way as to give false negatives

22:09 wingy: so that example was a pretty bad one

22:09 ChongLi: this is usually tests like this work

22:10 another example is reversing a list

22:10 Kowboy: so, at what point do you recommend writing your tests?

22:10 ChongLi: if you reverse a list twice you should get back the same list

22:10 Kowboy: after a feature is "complete"? After a bug has been discovered?

22:10 gfredericks: are there any common clojurescript templates for lein-newnew?

22:10 ChongLi: after a bug has been discovered = regression testing

22:11 wingy: but you get false positive if the fn is not doing anything at all

22:11 ChongLi: wingy: sure, but that's only one test

22:11 another test is to reverse a list and check if the last element has become the first

22:12 Kowboy: so, I don't see TDD and generative testing being mutually exclusive

22:12 ChongLi: combine those two tests and you start to get a pretty good picture

22:12 Kowboy: they're orthogonal

22:12 TDD is a development methodology

22:12 generative testing is just a framework

22:13 TDD says you're only allowed to write code in order to satisfy a test

22:13 Kowboy: so what I'm trying to get out of you is, what is a reasonable alternative, well-defined methodology for writing tests

22:14 well, I guess that's the extreme definition

22:14 wingy: then i guess im doing TDD

22:14 Kowboy: I guess I'm more TFD

22:14 wingy: i write test for all public fns

22:14 Kowboy: TFD?

22:15 Kowboy: test first

22:15 subtly different

22:15 wingy: whats that about .. sounds the same

22:15 Kowboy: strict TDD, as ChongLi points out, says that you only write code to satisfy a test

22:15 tomoj: https://www.refheap.com/paste/e2cffd71eaa8fee108469f1a6 doesn't clojure.tools.macro make an effort for this not to happen?

22:16 wingy: so TDD :)

22:17 Kowboy: lol, honestly I sometimes write tests first, other times I play with the code a bit until I know what it is I really want to do, then I write the test

22:18 still, you can test your code at the REPL, or you can save those tests in a file that can be executed many times for ever and ever, amen

22:19 project automation is not made obsolete by functional programming

22:19 ChongLi: Kowboy: sure, that's fine

22:19 but that's not what Rich is against

22:19 tomoj: it seems like symbol-macrolet respects let*, but macrolet doesn't?

22:19 Kowboy: non-trivial functions have a tree of dependencies on other functions

22:20 some of those may be in 3rd party libraries you do not control, or they may be maintained by other people on your team who do stupid things like change the behavior

22:20 without telling you

22:21 I think if you are Rich Hickey, and you've written your own language, you've earned the right to write code without tests.

22:21 but for us mere mortals who work on teams with other mere mortals, tests save lives

22:21 ChongLi: again, that's not what Rich is against

22:22 he is not against writing tests; he just doesn't do TDD

22:23 Kowboy: ChongLi, should tests only be written as a response to a defect?

22:23 if not, what is the discipline?

22:23 what (and when) do you test?

22:23 ChongLi: you write tests according to what you anticipate will fail

22:24 but you don't have to do TDD

22:24 Kowboy: most software developers, in my opinion, are terrible at anticipating what their code will do

22:24 ChongLi: it's silly, though

22:25 if you can't anticipate what will fail, how can you write a test?

22:25 Kowboy: if you don't test, how do you know your software is correct?

22:25 ChongLi: you prove it correct

22:26 Kowboy: maybe that works if you live in a bubble of really awesome developers

22:26 ChongLi: testing doesn't tell you your code is correct

22:26 it only tells you whether the tests pass/fail

22:27 Kowboy: that is true

22:27 ChongLi: it's like a virus scanner

22:27 wingy: what is like a virus scanner? i disconnected

22:27 ChongLi: wingy: writing tests

22:28 Kowboy: ChongLi, what are your thoughts on code coverage?

22:28 assuming we are not doing TDD

22:28 because I think there is something very valuable with having good code coverage

22:29 ChongLi: sure, though I think 100% code coverage is pathological

22:29 Kowboy: In many cases I have had a developer tell me that they would have checked in a terrible bug if my unit test hadn't been there

22:29 ChongLi: what language are they writing in?

22:29 just curious

22:30 Kowboy: I just think that having a formal discipline for testing is a good thing, even if it isn't TDD

22:30 but if it isn't formal, then it becomes easy to "do it later"

22:30 and then later never happens

22:31 that would be Java in my case, and I get that FP is a different animal

22:31 wingy: i test all public functions

22:31 ChongLi: yeah, I think a lot of the testing you do in Java comes as a result of shortcomings in the language

22:31 Kowboy: but I don't think writing tests, even first, is a bad habbit

22:31 sure, but it's all executable code

22:32 its just that in Java, much of our testing is devoted to changes in state

22:32 wingy: if you think about it it's just telling that certain inputs generate certain outputs

22:32 if i don't have a test for a fn .. i don't get how i would know that it works

22:32 Kowboy: what I really would rather focus on is testing the behavior

22:33 wingy: i can manually test it in the repl or in app .. but that is unsaved testing

22:33 Kowboy: I think TDD ought to be much easier in Clojure

22:33 because you don't have to worry as much (not at all in most cases) about state changes

22:34 wingy, well, not totally true. Have you heard of Session?

22:34 wingy: have a link?

22:35 Kowboy: it's like a persistent repl

22:35 saves the inputs and outputs

22:35 you can go to any of the lines that were saved and re-run them

22:36 Kovas Boguta presented on this at the Clojure/conj

22:36 wingy: i thought about skipping the mocking and use live responses from other services .. advantages: 1. don't need mock data 2. if api changes my tests fail and i can update the code

22:36 Kowboy: https://github.com/kovasb/session

22:36 wingy: any inputs/feedback on ditching mocking and use live responses from services?

22:37 Kowboy: search google for Kovas Boguta session

22:37 xeqi: wingy: so you have to have internet access to run the tests?

22:37 Kowboy: some presentations on youtube and such

22:37 wingy: xeqi: yeah but that is reasaonble

22:38 Kowboy: wingy: depends on how frequently you run the tests

22:38 also, are all the service calls read-only

22:38 because you can't control the initial state of an external syste,

22:38 wingy: nope .. some are write .. which means i have to be able to reset the service state

22:39 Kowboy: ok, so this works in this particular case

22:39 wingy: eg. create -> read -> update -> delete

22:39 Kowboy: I'm not sure that automated testing for external services is always a worth-while exercise, though

22:39 wingy: all services should imo have a RESET api so we can reset the state

22:40 Kowboy: but testing the layer immediately beneath that is a good place to start

22:40 well, that's certainly not practical in many cases

22:40 wingy: Kowboy: nah .. they should have a testing account like Braintree payment

22:41 for testing only

22:41 Kowboy: *should*

22:41 wingy: in that case you can make charges etc

22:41 or .. i just do mocking and can test whatever i want :)

22:43 Kowboy: again, external services to me represent the "edge" of a program, where you may have to deal with some mutable state. Just beneath that we should have a functional core which we want to be solid.

22:43 so not sure whether that's a part of the system I want to test, although it may end up being the most volatile part of the system

22:44 I don't know... it's a case-by-case thing

22:50 wingy: perhaps that problem is not in our end .. its in those services

22:57 Kowboy: right, but all we can gain from that is how our code *might* behave under external failure conditions

22:57 I think that's the worst part of mocking

22:58 you can't really know how the external system might fail

22:58 maybe some common cases, like 404's or what not

22:58 wingy: so perhaps the question is not how will it look like if it fails, but what does it look like when we get what we need

22:59 Kowboy: ChongLi, you still here?

22:59 wingy: if it fails we debug .. perhaps the server is down, or they are having a bug etc .. but that won't help our app, we just show "something went wrong, we will fix it ASAP" .. and we debug it

23:00 Kowboy: I'd be interested to know what (if anything) generative testing can do for us if our inputs are nested data structures (like maps of maps)

23:00 wingy: so all my tests are just testing that one scenario my app wants, not all the scenarios that are not wanted since that can be infinite

23:04 ChongLi: Kowboy: it sounds like you may need some data abstraction

23:05 doing a lot of complex destructuring is a code smell

23:11 Kowboy: well, what if you are consuming XML or JSON from a service?

23:13 if you use cheshire you can get it as a nested Clojure data structure. What is the general approach for extracting data from a nested data structure?

23:13 ChongLi: do you expect the data to take on some specific form or is it totally arbitrary?

23:15 if the data is in a predictable shape, you can build abstractions out of it

23:16 otherwise you're sort of stuck with this blob

23:17 Sgeo: Does into force sequences?

23:17 amalloy: Sgeo: into is (reduce conj)

23:18 Kowboy: I'm not sure what "build abstractions out of it" means exactly

23:18 it is a predictable shape

23:19 ChongLi: you design your project as a bunch of layers of abstraction

23:19 at the bottom you are dealing with the concrete data

23:19 it's entirely dependent on what you're doing, exactly

23:20 Kowboy: say we are transforming a JSON document into some cononical data format

23:21 in some cases, there may be a straight 1-to-1 key mapping, but some parts might be flattened or "normalized" in the canonical format

23:21 ChongLi: right

23:22 Frozenlock: Ah damnit... I tried to make my own protocol for a custom hash-map. Then I added a new record with 'get'.... and overwritten the default get function -_-

23:23 Kowboy: I feel this is one of those common and practical "recipes" that you don't get simply by learning the language

23:24 Frozenlock: Is protocol and record the right way if I want my own hash-map datatype with a special get function?

23:25 ChongLi: that seems odd

23:25 why would you do that?

23:26 Frozenlock: To solve my everlasting problem of course! :) I want a map that updates itself on lookup. http://stackoverflow.com/questions/4568875/overloading-a-clojure-hash-map-in-an-stm-transaction seems to want something similar.

23:27 ChongLi: updates itself on lookup?

23:27 why?

23:27 clojurebot: why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

23:28 Sgeo: Is Java reflection slow?

23:28 Because I'm considering creating closures in order to avoid repeatedly performing reflection

23:28 ChongLi: Sgeo: yep

23:28 Raynes: It depends on how fast it turns around and sees itself.

23:28 amalloy: phenomenally slow, yes

23:28 ChongLi: there's a reason *warn-on-reflection* exists

23:28 Sgeo: Well, I need to use some reflection to maintain my sanity

23:28 Frozenlock: ChongLi: I want to link it with an outside value, for example a stock price.

23:29 Sgeo: I could try to get that huge macro working again

23:29 ChongLi: Frozenlock: so you want an object?

23:29 Sgeo: So, making closures is worth it here?

23:29 This way, all reflection should occur when the library is loaded

23:30 Frozenlock: ChongLi: I honestly don't know how I could call it...

23:32 ChongLi: Sgeo: I'm still unsure what this is all doing

23:32 you're interop'ing with an existing java codebase?

23:32 Sgeo: Existing C API

23:32 ChongLi: ohh

23:32 Frozenlock: I think I'm getting near a solution... http://stackoverflow.com/a/5586959/1642155

23:33 Sgeo: Made Java stuff for it with JNAerator

23:33 ChongLi: Frozenlock: why does this have to be a map?

23:34 Sgeo: a generated java wrapper?

23:34 Sgeo: Yes

23:34 ChongLi: no wonder it's so hard to work with

23:34 haha

23:34 Frozenlock: listen to Stuart Sierra

23:35 Clojure prefers pure data structures over objects that combine data and behavior. You can get the behavior you want by accessing your data structure through a function:

23:35 Frozenlock: ChongLi: I have multiple values, only some of them need to have this behavior. Seemed like an easy way to handle it. {:a 1 :b 2 :c (update-value-on-lookup)}

23:38 Like using my-own-get-fn? But then I won't be able to do assoc and merge and all the other sweet map functions.

23:39 ChongLi: yeah, which is why you shouldn't make some weird variant of a map with custom methods

23:40 (defn a [] {:a 1 :b 2 :c (rand-int 100)})

23:40 now just do (a)

23:40 you'll get a different one each time

23:41 Frozenlock: Sure. (defn a [] {:a 1 :b 200ms-fn :c 300ms-fn :d 10m-ram}). Now if I do (a) only to get :b, I'll be very sorry.

23:43 amalloy: do you need any features other than lazy computation of values?

23:44 ChongLi: would a lazy-seq vector instead of a map work?

23:44 Frozenlock: It needs to update every time. Unless I'm mistaken, all lazy-x in clj keep their value once realized.

23:45 amalloy: so it's a map that's in fact not a value at all?

23:46 ChongLi: yeah this shouldn't be a map

23:46 or any clojure collection

23:46 amalloy: ie, you give it to someone, and they use it for a while, and it mutates out from under them? that's a fine thing to do in some cases, i suppose, but i would recommend against making it act like a map

23:46 ChongLi: it should be a java object

23:48 how about a protocol which you simply reify when you need to?

23:48 Frozenlock: A custom datatype that uses the same map functions is bad?

23:49 ChongLi: well what you're creating is not really a map

23:49 a map is a value

23:49 you're creating a computational object that has state

23:52 Frozenlock: I don't get the distinction. It sill has a key-'value' form. Inside I intend to store a function. To this point it's still a map. Difference is with the lookup function; instead of returning the function, evaluate it.

23:55 I'm also very new to defprotocol/deftype/reify... like I said earlier, I ended up overwritting my get function.

23:55 ChongLi: https://www.refheap.com/paste/6911

23:56 here's an example

23:56 Frozenlock: So what you propose might be the right way, I'm just not there yet.

23:56 ChongLi: a is an object

23:56 it has 2 methods: stock-price and random-stuff

23:56 stock-price takes 1000ms to run and returns 20

23:56 random-stuff returns a random-int up to 100 every time it is invoked

23:59 to use it you do this

23:59 (.stock-price a)

23:59 Frozenlock: Ok, so (stock-price a) ---> 20

23:59 ChongLi: yeah

23:59 note that if you call it again

23:59 it'll take the same amount of time

23:59 it is re-computing the value

Logging service provided by n01se.net