#clojure log - Aug 01 2012

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

0:00 amalloy: *shrug* i don't want clj-stacktrace in repl or test either

0:00 how nice

0:00 technomancy: yeah... there might be a way to do it

0:00 IIRC tavisrudd added that stuff in

0:01 amalloy: oh, last message was mischanneled

0:01 technomancy: you could probably just add an exclusion to clj-stacktrace; I think it degrades gracefully

0:01 muhoo: where's the source for reply?

0:01 technomancy: muhoo: https://github.com/trptcolin/reply

0:01 Raynes: amalloy: Are you going to switch to nrepl.el?

0:01 muhoo: thx

0:01 Raynes: I mean, at some point at least.

0:02 amalloy: probably

0:02 muhoo: technomancy: no :caught in there either

0:02 technomancy: muhoo: ok, I must have misremembered; too bad

0:02 it's possible it's all the way upstream in nrepl itself

0:02 * muhoo chases that rabbit for a while

0:04 technomancy: woo; so the whole coding-buffer-ns-not-getting-set bug is squashed: https://github.com/kingtim/nrepl.el/pull/51

0:05 man, he's merging pull requests fairly quickly and there's still 5 open

0:06 that's the last issue that was blocking wider uptake in my mind

0:06 muhoo: that won't affect nrepl.el usage though; it sounds like raw `lein repl` already does what you want

0:07 sorry if I wasn't clear on that

0:08 muhoo: right, and, with my rather brutal hack, nrepl.el does what i want too :-)

0:33 rabbit caught, fwiw. :caught is in clojure.tools.nrepl.middleware.interruptible-eval/evaluate

2:11 TheBusby: so has there been any discussion of moving "merge" into PersistentHashMap?

2:11 amalloy: what. that sounds awful

2:12 TheBusby: why?

2:12 clojurebot: why not?

2:13 TheBusby: why not, reducers into maps is dramatically slower than into other data types. The main bottleneck appears to be merge

2:13 amalloy: lots of reasons. suddenly every clojure impl (eg cljs) needs to reimplement it, instead of just being a repeated conj

2:14 TheBusby: maybe a pmerge then?

2:15 amalloy: performance is a ludicrous reason, and pmerge doesn't make sense. first look at using ##(doc into) instead of merge, if intermediate persistent collections are feeling expensive to you

2:15 lazybot: ⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

2:16 amalloy: (or transients in general)

2:16 TheBusby: doesn't (into {}) just use a transient?

2:16 amalloy: yes

2:17 TheBusby: I'm curious what the rational for pmap is then?

2:17 dnolen: TheBusby: pmap is old.

2:18 amalloy: pmap is more or less crazy

2:18 i think it exists for advertising: "look how cool functional programming is, you can just add a P and your code goes on threads!"

2:18 TheBusby: amalloy: too true

2:19 when using reducers though merging maps is dramatically more expensive than any of the other collection types...

2:19 amalloy: reducers, and specifically fold, promise to actually make that a reality, but pmap isn't it

2:20 ro_st: forgive the newb question, but what's the difference between reduce and fold?

2:20 amalloy: TheBusby: (a) that's a way more broad statement than you can possibly prove without qualifiers about what kind of reduce you're done, and (b) it's not astonishing because maps are paying a cost to provide random-access lookup that you don't care about while reducing

2:20 TheBusby: fold uses fork/join for collections > 512 of a pre-determined size (vector)

2:20 ro_st: is there a nice primer on all these map/reduce/fold/fork/buzzword techniques i can read somewhere?

2:21 TheBusby: ro_st: http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

2:21 ro_st: ok so fold is parallel reduce+combine. what's combine in this context?

2:23 TheBusby: amalloy: (a) I'm not trying to prove it for every case, it's just a case I run across often and I suspect others will as well. (b) I suspect the cost is more to do with ensuring lack of duplicates. Vectors also have random-access lookup

2:23 amalloy: TheBusby: are you using transients yet for your reduce?

2:23 TheBusby: amalloy: yes

2:23 clj_newb_2039: i'm feeling somewhat lucky: time to order glass cups from amazon. anything else I should try?

2:23 amalloy: then merge in IPersistentCollection wouldn't help you anyway

2:24 IPersistentMap, whatefver

2:24 you should try to find out if reduce-kv is getting involved or not - it would be another substantial improvement for a number of map operations

2:24 TheBusby: amalloy: doesn't the transient version still just assoc everything one by one?

2:25 reduce-kv is single threaded for 1.5-alpha2

2:25 s/reduce-kv/kvreduce/

2:26 amalloy: you couldn't profitably parallelize merge

2:26 TheBusby: amalloy: why is that?

2:26 amalloy: try writing a pmerge yourself

2:27 at some point you need all the k/v pairs in a single place to make the output map

2:27 and you need to know what order they came in so later ones can override earlier

2:28 TheBusby: if you have two maps, can't you isolate each branch of the tree?

2:28 amalloy: i haven't tried, but it doesn't seem like it to me for the reasons i just said. feel free to prove me wrong with an implementation of pmerge

2:31 TheBusby: amalloy: thank you for the feedback, I'll certainly give it a try since that seems to be my current bottleneck

2:44 emezeske: muhoo: lein-cljsbuild pulls in the cljsbuild JAR by depending on it, that is all

2:45 muhoo: I don't know of any way to checkout-depend on that. I you figure out how, I'd love to know.

2:46 clj_newb_2948: is there some library that will let me use CLojure to directly modify the DOM of a webpage? i.e. the library wil bridge Clojure with safari/firefox/chrome? I want to use HTML/CSS/DOM elements for my GUI, but I don't want to develop in ClojureScript

2:49 emezeske: clj_newb_2948: Why not clojurescript, just out of curiousity?

2:49 clj_newb_2948: becuase debugging clojure is about 100x easier than debuging clojurescript

2:49 ro_st: there is a fantastic way to do this, clj_newb_2948: clojurescript

2:50 and it's not as tough as you might think

2:50 emezeske: I might argue that interacting with the DOM in a web page is about 100x easier with clojurescript than with clojure, so maybe it balances out? :)

2:50 ro_st: it's not as fun as jvm repl, but it's not so bad that you want to, say, code php

2:50 clj_newb_2948: I have spent the last 2 months coding clojurescript and written two interactive web apps

2:50 I'm fairly certain that I like clojure a lot more.

2:51 ro_st: what are you using to do dom manip?

2:51 enfocus? domina? your own concoction?

2:51 clj_newb_2948: goog.dom/appendChild

2:51 emezeske: I could be wrong, but if you want to drive the DOM, clojure could maybe perhaps not be the right tool

2:51 ro_st: i suggest checking enfocus out. i'm in active dev with it at the mo. -ing rocks.

2:52 dnolen: clj_newb_2948: there's lot of room for improvement that's for sure ... did you submit any tickets or patches?

2:53 clj_newb_2948: dnolen: no, I tend to just complain

2:53 ro_st: dnolen: one idea that i had that would make reading the output js significantly easier, is to split the goog.* and the app code into two js files

2:53 clj_newb_2948: though for starters, if each line of gnerated javascript just had a comment ot tell me which line of clojurescript it came from ... that owuld be nice

2:54 dnolen: clj_newb_2948: if you're going to go that far might as well just do source mapping.

2:54 ro_st: having to wade through an ocean of cljs/goog code to get to one's own code is tedious, and it slows down whichever editor i have pointed at foo-debug.js quite a bit

2:54 dnolen: ro_st: if you don't optimize, everything gets compiled to separate.

2:54 ro_st: clj_newb_2948: they're working on source-mapping at the moment, which, when it's done, would show you the source cljs in the chrome dev tools

2:55 dnolen: ro_st: though this is also an issue addressed by source mapping.

2:55 ro_st: dnolen: i'm using whitespace

2:55 clj_newb_2948: ro_st: what is the time line on this?

2:55 dnolen: ro_st: nobody's actively working on it. I've done some initial work.

2:55 ro_st: I may pick it up again before StrangeLoop. It seems likely that no one else will do it.

2:55 * dnolen *sighs*

2:55 clj_newb_2948: actually this seems like a great way to learn about clojurescript internals

2:55 ro_st: ah. there you go. it's obviously not a big enough problem for anyone yet

2:56 clj_newb_2948: dnolen: if I try to pull this off, will you provide mentorship?

2:56 which basicaly means answer all my questions conerning how clojurescript internals work

2:56 dnolen: ro_st: I wouldn't go that far. It's a massive pain in the butt. But people put up with it, god knows why.

2:56 clj_newb_2948: because working on compilers is hard work

2:56 ro_st: dnolen: incidence pit. easier to go forward than to stop and detour

2:57 dnolen: clj_newb_2948: sure I'm glad to help.

2:57 clj_newb_2948: CLJS is relatively pleasant, being very small.

2:57 clj_newb_2948: do I check out the master branch, or is there some other branch I should start with?

2:58 dnolen: clj_newb_2948: there's a source-map branch.

2:58 clj_newb_2948 :http://dev.clojure.org/display/design/Source+Maps

2:58 clj_newb_2948: VLQ64 encode/decode already done. We need to be able to read in the entire Closure generated source map.

2:59 clj_newb_2948: that's step 1. that would be a big step.

2:59 clj_newb_2948: next step would be able to serial a Clojure data structure into a source map. Step 2.

3:00 clj_newb_2948: isn't step just (clj->json ...) ?

3:00 isn't *step 2*

3:00 dnolen: clj_newb_2948: maybe, maybe not. the format is a little involved because of compression concerns.

3:01 clj_newb_2948: the greatest perfomrance gain is from not working to working

3:01 dnolen: final step is figuring a sensible way to generate the necessary data during emission.

3:02 clj_newb_2948: the first result on google for

3:02 "VLQ64 sourcemap" is the clojure design docs

3:02 what is VLQ64 ?

3:02 dnolen: clj_newb_2948: I gave you a link - read it and the referenced links :)

3:02 clj_newb_2948: then I'll be happy to answer questions.

3:02 ro_st: homework time :-)

3:03 dnolen: i thought you could generate sourcemaps with, like, 12 maybe 15 lines of core.logic? sourcemapo, maybe? -grin-

3:03 dnolen: ro_st: ha!

3:03 ro_st: that sudoko solver is siiick

3:04 dnolen: ro_st: it was fun to put together I'm actually a bit suprised that's it's as zippy as it is.

3:04 ro_st: i look forward to understanding it

3:04 dnolen: ro_st: certainly not the fastest out there, but fast enough to be practical which is the goal.

3:05 ro_st: yup

3:05 clj_newb_2948: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ does not explain why people did not say "we'll do it with json + use bzip2 instead of inventing a new format"

3:05 ro_st: i'm *so* glad cljs uses the goog library. makes so much stuff easier to do

3:05 dnolen: clj_newb_2948: I'm heading out, but I'm willing to pair on this. I kinda would like to get it working in time for StrangeLoop as that would be a pretty SWEET demo.

3:06 ro_st: case in point: goog.dom.iframe

3:06 clj_newb_2948: I dont' know when strangeloop is, but we're probably on different time schedules

3:06 dnolen: clj_newb_2948: 2 months away.

3:07 clj_newb_2948: in anycase, I'm not expecting anything. But will be pleasantly suprised if someone chip in!

3:07 clj_newb_2948: dnolen: one last question before you go

3:07 dnolen: clj_newb_2948: what's up?

3:07 clj_newb_2948: the key idea behind source map is that we do NOT make the minified js larger

3:07 instead, we have a separte file, called blah.js.map

3:08 and this file provides an index from characters/lines in blah.js to the un-minimifed version, right?

3:08 dnolen: clj_newb_2948: yes

3:08 clj_newb_2948: i.e. this is the problem the base64 VLQ solves ;

3:08 great; thanks

3:08 dnolen: clj_newb_2948: as well original sources and everything.

3:08 clj_newb_2948: hope to see you later here

3:08 dnolen: clj_newb_2948: I'm nearly always around. talk soon.

3:08 ro_st: the sourcemap + the min js gives you everything you need to break and step through the source right there in chrome dev tools

3:09 https://www.youtube.com/watch?v=-xJl22Kvgjg&feature=player_embedded

3:10 clj_newb_2948: it's amazing; I would never click on a random youtube link on reddit; but in irc, somehow no second thought

3:10 ro_st: -grin-

3:10 clj_newb_2948: chrome is amazing

3:10 ro_st: 1:26

3:10 on that vid

3:11 should get you salivating

3:11 Fossi: clj_newb_2948: depends a whole lot on the channel ;)

3:11 clj_newb_2948: "compiled in pretty mode; but debugging this is still a pain" <-- no it's not, not pain at all, compared to what cljs output looks like

3:11 Fossi: in notorious ones we have a bot that fetches the title ;)

3:11 clj_newb_2948: wtf

3:12 why is there java code in a chrome console?

3:12 ro_st: sourcemaps :-)

3:12 clj_newb_2948: so the app is written in java?

3:12 ro_st: sourcemap has all that detail inside it, and chrome groks it and shows you the source

3:12 ya that app is a GWT app

3:12 clj_newb_2948: how is it compiling java to javascript?

3:12 hmm

3:12 ro_st: it's not

3:12 clj_newb_2948: why am I not using GWT ? :-)

3:13 ro_st: it's already compiled ont he server. the source map is just presenting the code that was compiled earlier

3:13 coffeescript, clojurescript, objective-j, etc etc etc, would all do the same, once they are able to produce full sourcemaps

3:13 clj_newb_2948: ro_st: your video may have just set back clojurescript sourcemaps until another volunteers comes along :-)

3:13 ro_st: you can already do this with 'traditional' google closure javascript

3:13 clj_newb_2948: because writing java is sucky

3:14 imagine seeing .cljs instead of .java? :-)

3:15 clj_newb_2948: no ... why can't I use GWT with Clojure? :-)

3:15 ro_st: you probably can

3:15 never used gwt

3:16 clj_newb_2948: crap:

3:16 http://stackoverflow.com/questions/2135335/a-good-alternative-to-gwt-for-clojure

3:16 GWT requires native java code; not compilex clojure bytecode

3:26 emezeske: I want sourcemaps as much as the next guy, but honestly I don't think debugging the JS output from the compiler is really that bad

3:30 ro_st: whitespace or simple, emezeske?

3:30 i'm debugging whitespace and i find it ok

3:30 emcken: I've written a function that reads a csv file lazy and the lines are transformed into maps... I just can't figure out how to use a filter on the data ie. to only return some of the lines

3:30 ro_st: emcken: using (filter pred coll) ?

3:31 emezeske: ro_st: Well, just whitespace of course for debugging

3:31 ro_st: yeah. i just wish all the cljs+goog stuff was off to one side. would make spelunking in the app's js much easier

3:33 emezeske: When I debug, the cljs+goog stuff is all at the top, and my app is at the bottom. Is it not that way for you?

3:33 emcken: ro_st: Yes I'm trying to user the filter function... but obviously I'm doing it the wrong way.

3:33 ro_st: i know it's all in one file to avoid deps.js hopscotchery. yes, like that for me too. it just slows Sublime Text 2 down because it has to reload a meg of js every time (i use it to read the js)

3:34 emcken: ro_st: If I pasted my code (pastebin) would to care to take a look at it?

3:34 emezeske: ro_st: Ah, yeah, that is not ideal

3:34 ro_st: emcken: happily

3:35 emezeske: ro_st: Finding errors is not that bad, though; my functions are all pretty short and the JS function name lines up perfectly with the cljs function

3:35 ro_st: emezeske: i'm guessing the cljs+goog stuff changes based on what your app uses, or is it the same stuff every time?

3:35 emezeske: ro_st: The dead code elimination only kicks in for :advanced mode

3:35 ro_st: yup, agreed. i'm getting pretty quick at identifying common issues

3:36 ok so it's all the same. that means it's quite worth splitting the two, if only just for whitespace

3:36 emezeske: ro_st: If you really really want that, you might try compiling with no optimizations and doing the whole deps.js thing

3:37 ro_st: All your namespaces will be in their own files

3:37 ro_st: ah. no, i don't want it quite that badly -grin-

3:37 emezeske: ro_st: Although I have never set that up for a real project, so I don't know if it's easy/hard

3:37 haha yeah same here

3:39 ro_st: emezeske: what do you use for dom wrangling? domina? enfocus?

3:39 emezeske: ro_st: jquery

3:39 ro_st: or, jayq

3:40 ro_st: ah

3:40 emezeske: ro_st: One day I'd like to drop jayq in favor of one of the swanky cljs libraries

3:40 ro_st: But for now, jquery has the plugins

3:41 ro_st: $ is fine for simple page decoration stuff, but for single-page apps it just feels a bit lacking

3:41 that's true, though. there are a lot of plugins

3:42 emezeske: I use crate for templatey-type stuff

3:42 ro_st: my big issue is that i can't compile jquery and its plugins into the js binary

3:42 i'm absolutely fanatical about load performance. trying to keep it down to one html, one js, one css

3:42 and one sprite png

3:43 emezeske: It is possible to get one JS with jquery and :advanced optimizations

3:43 But it is not simple

3:43 ro_st: exactly. whereas with enfocus/domina, it's the default

3:43 emezeske: Yeah. I do really want to switch to using a native cljs lib instead of jquery, but not yet

3:43 ro_st: isn't jquery externed?

3:44 emezeske: Yeah it's externed, but you can concat its minified source with the :advanced closure output (with some namespace dicking around)

3:44 ro_st: or are you saying some intrepid explorer has managed to get jquery compiled with advanced

3:44 emezeske: No, not that

3:44 ro_st: ohh i see. after-compilation concatenation

3:44 yuck :-)

3:47 emezeske: yuck indeed!

3:49 emcken: ro_st: awesome thanks alot... I've tried to simply my example: http://pastebin.com/eiBnSUj4

3:49 francis: http://paste.lisp.org/display/130801 http://www.4clojure.com/problem/120 When I run my solution (see lisp paste) on the problem (see 4clojure) it times out - however when I run it on my my machine (in the repl) everything works great. I've tried running random stuff on 4clojure for that problem and it fails the tests - however I'm not sure what would be such a long running operation. No loops, no recursion. Anyone have thoughts as to why this would be?

3:50 eml: Hey. Is there a function in either core or contrib to round up eg. 0.1 to 1? Round up to closest integer

3:51 emezeske: eml: Use the java math library: &&(Math/ceil 0.1)

3:51 ro_st: emcken: ok, so how do you want to filter this data?

3:51 eml: emezeske: Ah, ceil is usually what it's called yeah. Thanks!

3:51 emezeske: ,(Math/ceil 0.1)

3:51 clojurebot: 1.0

3:51 eml: Yup :) thanks man

3:52 emezeske: I had to look around for a while too before I found out that you just use the Java library

3:52 francis: ,(println ", to call clojurebot?")

3:52 clojurebot: , to call clojurebot?

3:52 francis: nifty

3:54 ro_st: emcken: i'm assuming you only want to write to sql if :text is 'good' ? if so, line 17 would be wrapped with (when (= (:text map) "good") ...)

3:58 emcken: ro_st: actually the println was only so that I could see that something was happening... at some point I want it to lazy write out to a new csv file and/or database the lines the match a filter function

3:59 ro_st: but I'll play at little with the when function, thanks :)

3:59 ro_st: the filter function operates on a collection

3:59 in this case, you don't have a collection, because you're creating the elements one by one from the csv

4:00 it makes more sense to just use plain old conditionals to validate the data directly in that loop

4:00 if you had a collection in memory already, you'd use: (filter #(= (:text %) "good") map-of-csv-lines)

4:01 to produce a new collection of only good maps, which you could then doseq over to write to csv or a db

4:05 TheBusby: emcken: since line-seq returns a line at a time, and CSV file formats allow multi-line records, will that work?

4:06 TSV for the win :)

4:06 emcken: TheBusby: propably not... though the csv files I'm working with right now doesn't have multi-line records *hehe* one problem at the time xD

4:08 ro_st: would a filter around the entire parse-file function work... and would i make sense? - just trying to understand how it works

4:08 ro_st: what does parse-file return?

4:09 in that code, due to the doseq, it'd return nothing

4:12 emcken: ro_st: you are right... of course it should return a collection but would a filter force the entire file to be read into memory before filtering - thus make the lazy stuff not matter?

4:12 ro_st: irc://irc.freenode.org:6667/#(=

4:12 eek

4:12 https://www.refheap.com/paste/3955

4:13 filter would necessitate loading the entire file, unless your csv-line reader produced a lazy sequence

4:14 i'm not sure if parse-file in this instance would produce a lazy-seq. i've no direct experience with intentionally lazy programming

4:15 have fun finding out :-)

4:15 TheBusby: line-seq is lazy

4:15 emcken: ro_st: thanks a lot mate, nice example... about intentionally lazy programming: as you might have noticed neither do I xD

4:16 TheBusby: All nice and lazy I think... (->> (line-seq file) (map get-as-map) (filter #(= "good" (:text %)))

4:17 ro_st: and there you have it

4:17 this is why i try to help out. i get to learn stuff too

4:19 gosh, magit is awesome

4:19 Raynes: francis: There are some issues with clojail java interop taking a long time. We're working on fixing it and hopefully that'll solve time out issues. In the meantime, best I can recommend is try to write solutions that don't do much java interop.

4:20 francis: thanks

5:19 Raynes: Everyone stop panicking. I'm here now.

5:22 * otfrom stops running around, randomly hiding and sweating profusely

5:23 * otfrom beams at Raynes and looks grateful

5:23 otfrom: Hi Raynes!

5:32 ro_st: Raynes: can you summon ohpauleez? i'd love to use shoreleave but it's broken :-(

5:32 Raynes: I don't think so.

5:33 I don't know that particular spell.

5:33 ro_st: pity :-)

5:33 how are you enjoying nrepl.el?

5:33 Raynes: Very much.

5:34 ro_st: why'd you switch? what about it attracted you to it?

5:35 Raynes: nrepl.el is deprecating swank-clojure. It makes sense to move to it.

5:36 ro_st: ok so not any one particular thing

7:31 eml: Could anyone here perhaps recommend an example Noir app to look at? Specifically one that includes testing (which the noir-blog doesn't :()

7:33 ro_st: testing of noir-specific code, eml?

7:34 eml: ro_st: Pretty much, though to be honest any code would be good to look at, I'm not even getting "lein test" to run :)

7:35 cshell: isn't there a (with-noir ..) macro which you can then call your pages just like functions?

7:35 yeah, http://bit.ly/MynCUl

7:35 eml: Yeah, but I don't have the slightest idea how to write tests in clojure and I sort of want to pick up the style too

7:35 (I'm completely new to Clojure)

7:36 cshell: Look at clojure.test and Midje for testing instructions

7:37 eml: Midje looks sweet but I suppose I should learn about clojure.test first

7:37 cshell: yep

7:38 clojure is just ab unch of functions, so you just validate outputs given sets of inputs

7:40 eml: Yep, at least I'm running some stuff without getting namespace errors now, just gotta get the actual tests to run!

7:41 cshell: haha

7:41 ro_st: i went straight to midje

7:41 cshell: clojure.test/run-tests or something

7:41 ro_st: i've written enough 'normal' unit tests for one life time. gimme the fancy

7:42 eml: I come from Ruby and went straight to RSpec there instead of Test::Unit, so I've only used the fancy :p

7:45 ro_st: go for midje. i can give you a template project.clj if you like

7:45 https://www.refheap.com/paste/3953

7:46 this includes both lein1 and lein2 data, because i got tired of fussing with that

7:46 with this, you can run lein2 midje —lazytest and get a reloading-test-runner

7:48 this includes lein-swank as well if you're brave enough to start with emacs

7:57 eml: ro_st: Thanks man! Always such great help :)

7:58 ro_st: i do it for selfish reasons. i want clojure to take over the world

7:58 … pinky.

8:09 eml: :D

8:19 Frozenlock: Is there an easy way to add an icon in the notification zone? Or is this OS specific?

8:23 eml: Ah by the way ro_st, refheap's source code is quite nice to read too (to learn) :)

8:24 ro_st: very true

8:24 don't know why i didn't think of that, actually

8:25 eml: I understand so little of Clojure to be honest, mainly because it takes a long time for me to read it at this point, but damn you get so much done with so little lines of code.. :)

8:25 ro_st: yeah, it's awesome. coming from Ruby, right?

8:26 eml: Pretty damn happy my boss gave me an "OK" for learning Clojure/Noir and making our next project in it!

8:26 Yup

8:26 ro_st: it blows your mind on so many levels

8:26 have you watched the Rich Hickey talks?

8:26 Simple vs Easy, Hammock-driven Dev, Are we there yet?

8:27 eml: Have not :o

8:27 ro_st: vvv highly recommended

8:27 Simple vs Easy was the pebble that started the avalanche, for me

8:29 cshell: I bought a hammock :)

8:29 ro_st: -grin-

8:29 i just realised i never finished watching that one

8:29 eml: http://www.infoq.com/presentations/Simple-Made-Easy/ this one?

8:30 ro_st: yes

8:30 eml: Sweet, gonna watch it now :)

8:32 ro_st: enjoy

8:46 djcoin: It seems many people coming to CLojure have a ruby background no ?

8:47 ro_st: it does

8:49 djcoin: How is that ? Not afraid of the java boilerplate environment ? Yet, taking the risk to switch to a non statically typed language ? :)

8:50 ro_st: it's more a case of a Rails background. rails has too much magic in it

8:50 djcoin: (I mean taking a switch and still not making the move to a statically type language)

8:50 ro_st: it's the opposite of small and composable

8:50 too much for a single brain to hold

8:51 this is why *I* looked away from it, anyway

8:52 llasram: ro_st: +1 to that. I haven't been in love with Ruby for a long time, but I recently reached for Rails when I needed a basic CRUD web app, because I thought it would it be easiest. Was v frustrating, pouring through doco to find the one magic line to put in the magic place to make things happen

8:52 cshell: I thought it was because of the functional programming constructs

8:53 ro_st: llasram: exactly. you have to take on too much data to accomplish stuff

8:53 cshell: that's a pull factor. i'm talking about the push factors

8:53 _nmmn: im still puzzled how ROR particularly could get that popular

8:53 ro_st: why *not* ruby rather than why clojure

8:54 _nmmn: because php

8:54 _nmmn: well php is php, still dont know how rails made ruby that popular

8:54 llasram: _nmmn: Yeah. I used early rails for some projects, and when it first came out it at least seem to me to be light years ahead of everything else

8:54 _nmmn: but it was used in quite some places without ROR, seems like ROR was the real hype

8:54 well thats what i thought at first also llasram

8:55 ro_st: it had convention-over-config and all the agile stuff arrive along with it

8:55 pragprog books, 37signals' own rise, etc

8:55 djcoin: And aren't you afraid of all the java background (whether it's java, java lib and of course java build/environment). This kinda scare me

8:55 _nmmn: i started from java, way too bloated to be usefull, imo :>

8:56 but jvm is different stuff, many strange/nice langs use it

8:56 for example ioke, ehehe

8:59 ro_st: djcoin: also, Rhickey gave his simple-vs-easy talk at the latest rails conf

8:59 djcoin: yeah - I already watched this video

8:59 ro_st: that might help to explain why ruby folks are arriving

9:00 djcoin: Still wonder - if so many people can make the move to a JVM environment

9:00 why not switch to scala ? - it has also many benefits

9:00 ro_st: what's problematic about that?

9:00 djcoin: But I guess it's even more far

9:00 Nothing - I, myself, am wondering about this choice

9:01 Still not made the move (Im on python right now)

9:01 ro_st: well, you're not switching to jvm, you're switching to clojure/lein. jvm is underneath

9:01 djcoin: Sure

9:01 ro_st: come on in, the water's great :-)

9:02 _nmmn: =]

9:02 well i had smilar choices like djcoin erlang/scala/clojure/go

9:02 go is out of the choices for now hehe

9:03 djcoin: _nmmn: ahah, same for me ! I may also add lua

9:03 _nmmn: why did you put Go out ? Did you choose clojure at last ?

9:04 _nmmn: dont have enought time for clojure right now, but it still does look very promising

9:04 ive mostly into erlang now

9:04 *im

9:04 djcoin: _nmmn: Oh RLY ? :) It seems nice

9:05 _nmmn: well i start to see bad "points" of it now =] so i think i will dive more deep into clojure soon

9:05 just for kicks

9:07 brunchpoems: scala is intimidating and clojure seems to have a more established community for helping out those learning it.. in my experience and view

9:07 djcoin: _nmmn: how about scala and actors (vs erlang) ? What bother me is that i like the "lightweight" of erlang vm (+ other benefits as code reload)

9:07 _nmmn: djcoin: so far i actually didnt do much benchmarks, but scala seemed a bit too *java like*

9:08 while i really liked akka, but havent got above the ground when doind stuff with it

9:08 i mean just some basic stuff only...

9:09 erlang feels more like "buit for this kinda stuff" compared to akka+scala which is like "good third party extensions/libs" feel

9:13 djcoin: Yep yep yep

9:48 tsdh: Oh my god, lazyness bit me again in a new form.

9:50 In a macro, there was something like ~@(if (seq? more) (map convert more) (convert more)), where the convert function depends on a dynamic var which was always correctly bound by the macro, but its value was wrong if convert was called thru map.

9:51 Somehow, I expected ~@ to be eager, which it seems its not...

9:52 Of course, I found the problem while trimming down my code to a minimal example I can show to you.

9:53 Well, now it's solved, but maybe the example is still entertaining: http://pastebin.com/ytw6WgzB

9:56 ro_st: macros, that's like, magic, right?

9:56 -sigh-

9:58 tsdh: ro_st: I'm fine with macros, but a mix of macros, dynamic vars at compile-time, and lazyness was a bit too much. :-)

9:59 ro_st: hehe

9:59 i haven't grokked macros yet. going to see how long i can hold out :-)

10:01 joly: I've only used them for simple things, but the code looks so much better for them being there

10:02 ro_st: i can believe it

10:02 my angle of attack will be to attempt to eliminate any boilerplate i might have creeping in

10:04 gah. how did i ever get anything done without jenkins?

10:13 casion: is it possible to shortcircuit a loop form?

10:14 ro_st: shortcircuit how?

10:14 casion: have it exit the loop before recur, or have it recur earlier

10:15 ro_st: you can recur multiple times, as long as it's the tail of that block

10:15 if … recur | lots of stuff, recur

10:15 hyPiRion: casion: a loop form is basically recursion.

10:15 tail-recursion, but recursion nevertheless.

10:16 casion: yes, I get that

10:17 I think I'm trying to ask something that you wouldnt want to do in a functional language anyway

10:18 ro_st: you want to jump out of your function early? if ( blah == null ) { break; } ?

10:18 matteop: Hi guys just a question .....

10:18 casion: yes

10:18 ro_st: ohpauleez!!!

10:19 matteop: How transform a String into function in Clojure ?

10:19 casion: like a break or continue I suppose

10:19 joly: should be able to just not call recur if that condition is true

10:19 ro_st: casion: (if-not (nil? blah) (recur …))

10:19 casion: I suppose the idea is that you put everything in a conditional

10:19 ro_st: not-recurring exits the loop

10:19 casion: that just seemed bulky to me

10:19 ohpauleez: ro_st: How's it going?

10:20 ro_st: better now that you're here. i am ITCHING to use pubsub and remote

10:20 i literally have a comment saying 'refactor this update-ui tarball function to use pubsub'

10:20 matteop: i need to pass a function from java to clojure , anyone can help me ?

10:21 ro_st: i tweeted at you. i tried to use pubsub but it had some screwy dependency on localstorage somethingsomething

10:21 matteop: (resolve "clojure.core/some") ; #'clojure.core/some

10:21 hyPiRion: casion: ah. I know what you're after. It seems bulky at first, but when you know Clojure better, you find ways to avoid break; and continue;. The language and the way you work with it is completely different.

10:22 matteop: thank ro

10:22 casion: hyPiRion: yeah... I'm fighting it tooth and nail so far

10:22 ro_st: casion: a recur that isn't inside a conditional is by definition an infinite loop

10:23 i found this out the hard way (having to reboot repl)

10:23 casion: ro_st: I'm thinking that I want multiple recursion calls... except I know that's not right in clojure

10:24 I'm just strugging to understand the common way of dealing with that

10:24 ro_st: you can recur multiple times

10:24 casion: multiple call poins

10:24 points*

10:24 ro_st: you just need to put those calls in the tail position of their respective blocks

10:25 casion: ro_st: recur has to be the tail of the loop block only doesnt it?

10:25 hyPiRion: ,(loop [a 1] (case a, 1 (recur 3), 3 (recur 2) 4))

10:25 clojurebot: 4

10:25 ohpauleez: ro_st: Just sweeing the tweet now (didn't show up in my email for some reason)

10:25 I'm going to fix that - CLJS jar has an older version of the Closure Library

10:25 ro_st: i'd be happy to help you convert an imperative fn in a paste

10:25 cshell: hyperboreean: why don't you put the value you pass to recur into a local variable

10:26 ro_st: ohpauleez: i'm using goog-jar right now. should i use something else?

10:26 casion: ro_st: give me a few minutes here, I've learned a bit in the last few lines

10:27 ohpauleez: ro_st: No, that's totally fine. The LocalStorage stuff in Google Closure lib was recently added. I'm going to take the offending code back out for now

10:27 I'll be cutting a stable 0.2.2 release sometime soon

10:27 ro_st: or wrap it in a check for support?

10:29 casion: ro_st: hum... this works now

10:29 ohpauleez: ro_st: it'll probably be a conditional load, yes

10:29 casion: last night everything I tried complained about recur not being in the tail

10:29 no idea what I was screwing up

10:36 pandeiro: how do i create a secret key to be able to use lein deploy clojars?

10:37 sorry, not really clojure-related i guess... i thought i already had a secret key tho, guess i deleted it at some point

10:43 hyPiRion: pandeiro: Ask in #leiningen, perhaps.

10:44 A google search should help you too.

10:47 pandeiro: yeah i'm getting there

11:11 goodieboy: technomancy: is it possible to specify more than one "resources" directory in project.clj?

11:25 jonhicks: question: how can I decrement a value from a hash-map and get back the new hash-map?

11:26 ro_st: (assoc map :foo (inc (:foo map)))

11:26 replace inc with whatever

11:26 jonhicks: yup. testing in repl. thanks!

11:27 stain: (update-in p [:age] inc)

11:27 from http://clojuredocs.org/clojure_core/clojure.core/update-in

11:27 ro_st: there's that, too :)

11:27 goodieboy: anyone using leiningen 2 preview?

11:28 duck1123: oh, update-in, I know it's there, but I never think of it till after I've typed the assoc version

11:28 ro_st: yeah

11:28 duck1123: goodieboy: lein2 is very good, time to upgrade

11:28 goodieboy: duck1123: that's great to hear. Would you happen to know if :resource-paths works? I'm trying it in version 1 with no luck.

11:29 duck1123: unless you have a very good reason to stay on 1.7, lein 2 is worth the upgrade. In most cases it's pretty easy

11:29 goodieboy: duck1123: are there upgrade instructions anywhere? Or do I just install lein 2, and go for it?

11:29 jonhicks: update-in. excellent

11:30 need more time with the docs

11:30 duck1123: There was a precate task that listed what you need to change. can't remember if it came baked in or if it was a plugin

11:30 https://github.com/technomancy/lein-precate

11:31 raek: goodieboy: :resource-paths was probably called :resource-path in lein 1.x

11:31 mabes: clojure.contrib.ns-utils doesn't seem like it survived the 1.3 move.. Is something like it's immigrate still considered good practice or not? (http://clojuredocs.org/clojure_contrib/clojure.contrib.ns-utils/immigrate)

11:31 uvtc: goodieboy: Since even Clojure itself is just another library/jar, if you like, you can simply upgrade like so: `rm ~/bin/lein`, `rm -fr ~/.lein`, `rm -fr ~/.m2`, download the latest lein, `chmod +x lein`, and run it.

11:31 ro_st: duck1123: cljsbuild is lein1 only

11:31 duck1123: ro_st: you sure, works fine for me

11:32 ro_st: crossovers don't :-(

11:32 goodieboy: raek: cool thanks, i'll try that out in the meantime

11:32 duck1123: ahh, haven't gotten into that yet

11:32 goodieboy: uvtc: yeah, i'll give 2 a shot

11:32 * nDuff has used crossovers with lein2 sorta-successfully.

11:32 raek: goodieboy: make sure you read the correct version of the docs for the version of lein you use. lein 2 breaks compatibility with lein 1.

11:33 goodieboy: raek: good point yeah

11:33 nDuff: ...when playing with cljsbuild on lein 2, it appeared that one could require code from the crossover libraries into .cljs files, but they don't appear to be compiled into .js by default, oddly enough.

11:33 raek: (you can change branch on github)

11:33 ro_st: nDuff: i was getting couldn't-find-crossover-namespace errors

11:34 i'm sure it's a small issue, emezeske will get there sometime

11:34 works just fine with lein1

11:34 i use both 1 and 2

11:34 duck1123: I keep both a lein2 and a lein1.7 in my bin directory then symlink lein2 to lein

11:35 arkh: cemerick, do you mind if I PM you?

11:35 cemerick: go ahead

11:35 * raek has switched from having .bin/lein and .bin/lein2 to having .bin/lein1.x and .bin/lein

11:36 goodieboy: raek: oh too bad, 1x only accepts a single path for :resources-path

11:36 duck1123: I ran into a few odd cases where things were actually looking for a bin named "lein2"

11:36 goodieboy: all the more reason to switch :)

11:40 * nDuff eyes Rincanter

11:41 ro_st: anyone know of a tool that formats clj source co… nevermind. i'm sure i can use pprint.

11:42 just need to learn how to load clj source as plain old clj data

11:44 Chousuke: ro_st: read does that.

11:45 ro_st: though if the code uses read-time evaluation that approach won't work

11:46 gtrak: ro_st: M-x indent-region?

11:46 duck1123: C-x h <tab>

11:49 ro_st: it'd be plain clojure data. maps and vectors of ints and strings

11:49 and the people producing this won't be using emacs

11:50 it's a transitory step until we can get the software built that allows you to create this data in a nice UI

12:13 goodieboy: what's the best way to expand a jar file in clojure?

12:13 nDuff: goodieboy: expand to disk, or read contents of?

12:14 goodieboy: nDuff: expand to disk

12:14 nDuff: goodieboy: I'd expect that you'd be using the regular Java API for that (see the java.util.zip package).

12:15 goodieboy: nDuff: gotcha, thanks!

12:31 dnolen: looks like all those type hints in core.logic were unnecessary - keyword lookup via implementing valAt + case is really fast.

12:33 xumingmingv: https://github.com/killme2008/clj.guava/blob/hash/src/clj/guava/hash.clj#L50

12:33 why type hint here does not work?

12:34 I got many warning int the following lines:

12:34 Reflection warning, clj/guava/hash.clj:53 - call to putByte can't be resolved.

12:34 Reflection warning, clj/guava/hash.clj:54 - call to putShort can't be resolved.

12:34 Reflection warning, clj/guava/hash.clj:55 - call to putInt can't be resolved.

12:34 Reflection warning, clj/guava/hash.clj:56 - call to putLong can't be resolved.

12:36 nDuff: xumingmingv: the obvious guess is that the compiler isn't inferring the type of x from the instance? tests

12:37 xumingmingv: ...you can check for that by hinting x in those calls.

12:37 xumingmingv: x? but The warning is saying that putByte cannt be resolved, but I type hinted the Hasher

12:38 actually i dont know the type of x, this is why i use instance?

12:38 nDuff: xumingmingv: you know it at call time.

12:38 xumingmingv: (.putByte hasher ^Byte x)

12:38 xumingmingv: oh, let me try it

12:39 nDuff: ...by the way, that smells like a use case for a Hashable protocol.

12:40 xumingmingv: it did work!, but not for the putObject call

12:41 :else (.putObject hasher ^Object x)))

12:42 oh, its my fault..

12:42 wrong api

12:42 why it is not enough to just type hint Hasher here?

12:43 nDuff: xumingmingv: Because the type inference done by the compiler isn't (currently) smart enough to track when a branch is only reachable via a type test

12:44 * nDuff wouldn't be surprised if that were improved somewhere in the future.

12:44 nDuff: ...I'd expect you wouldn't have that issues with protocols, though, and those are the preferred approach for doing that kind of thing.

12:46 xumingmingv: nDuff: thanks a lot!

12:59 zerokarmaleft: dnolen: if i want to dynamically declare a bunch of facts in core.logic (e.g. after parsing a bunch of relations from a file), what's the best way to do that?

13:00 dnolen: zerokarmaleft: assuming you used defrel, just call fact or facts

13:01 zerokarmaleft: dnolen: https://gist.github.com/3219448 <= this is an extension to a blog you tweeted about...simple genealogy example

13:02 dnolen: zerokarmaleft: haha sweet, Game of Thrones

13:03 zerokarmaleft: cool, yeah, just call fact / facts

13:04 zerokarmaleft: the problem i'm running into is difference in facts persisting at the repl and running as a script

13:05 llasram: zerokarmaleft: maybe you want a doseq vs map for calling `fact`? W/ `map` just have an unrealized lazy sequence and no actual applications of `fact`

13:06 alexyakushev: Is there some kind of map for clojure.org site? I've just discovered there are hidden pages like clojure.org/streams for which I can't find any links

13:08 dnolen: zerokarmaleft: yes fact / facts is side-effecting, you definitely want doseq

13:10 zerokarmaleft: llasram, dnolen: got it, thanks!

13:13 technomancy: alexyakushev: streams were actually removed on purpose; they were abandoned

13:50 aaelony: a friend is asking me to comment on using Clojure for data science. before I weigh in, does anyone have comments or experiences?

13:51 gtrak: what kind of data science?

13:51 pandeiro: emezeske: https://github.com/pandeiro/ghost & https://github.com/pandeiro/casper-cljs

13:51 technomancy: http://28.media.tumblr.com/tumblr_l7dfo7dpYS1qzamioo1_500.jpg

13:52 gtrak: aaelony: we have incanter for statistics stuff, and having JVM libs is pretty useful. Also this comes to mind: http://strataconf.com/strataeu/public/schedule/detail/25204

13:52 aaelony: yes, let's collect a bunch of links

13:53 gtrak: "the research team work in one language to do the research in a ‘mathsy’ language. That is then handed off to a programming team who reconstruct the code in a production language like C# or C++. This fracture causes severe pain and error.

13:53 Clojure has solved this problem for me, allowing me perform the entire process from research to production in one language. "

13:53 aaelony: following this definition: http://en.wikipedia.org/wiki/Data_science

13:54 "Data science is a discipline that incorporates varying degrees of http://en.wikipedia.org/wiki/Information_engineering, http://en.wikipedia.org/wiki/Scientific_method, http://en.wikipedia.org/wiki/Mathematics, http://en.wikipedia.org/wiki/Statistics, http://en.wikipedia.org/wiki/Computer_programming, http://en.wikipedia.org/wiki/Data_visualization, http://en.wikipedia.org/wiki/Hacker_(hobbyist), and http://en.wikipedia.org/wiki/Subject-matter_expert"

13:57 I think Bradford's talk is a great example: http://www.infoq.com/presentations/Why-Prismatic-Goes-Faster-With-Clojure

13:57 gtrak: ah yea

14:01 aaelony: In any case, I'm putting together a list and will share at some point as well.

14:04 emezeske: pandeiro: Nice!

14:05 pandeiro: I hadn't looked at Casper before, it seems pretty cool

14:06 rabidsnail: Are the semantics of deliver expected to change? Right now (delever p v) is equivalent to (p v).

14:06 (deliver p v), rather

14:06 Bronsa: rabidsnail: that's an implementation detail

14:06 rabidsnail: So,yes?

14:06 Bronsa: I don't think you should rely on that

14:07 (though I don't think it will change)

14:07 technomancy: fun fact: deliver can be used as a one-arg funcall

14:07 rabidsnail: I'd rather there were an IDeliverable the same way there's IFn and IDeref

14:07 pandeiro: emezeske: yeah it is just some utility on top of PhantomJS, the real win are those wait-for fns, great for async stuff etc

14:08 rabidsnail: because right now I'm not sure if my thing-that-looks-like-a-promise will break in future clojure versions

14:08 emezeske: pandeiro: Yeah, that's handy looking

14:12 jsabeaudry: pandeiro, what is the expected mayhem of advanced compilation?

14:17 pandeiro: jsabeaudry: oh it has a fit, i didn't really try to dig into it yet

14:17 simply ^:export'ing all my vars didn't work

14:17 hmm maybe i needed to do it for all the wrapper fns too, didn't try that

14:18 i still don't fully understand externs files either

14:18 hiredman: I've found externs to be very painful

14:19 they don't work and I get no indication of why

14:20 b

14:23 emezeske: hiredman: I haven't been able to find any decent docs for "how to make an externs file", have you? I just had to copy existing files and stumble around.

14:26 hiredman: emezeske: I just gave up and hack ground it

14:26 around

14:27 ((goog/bind (aget obj "MethodName") obj) arg1 arg2)

14:28 emezeske: hiredman: Yeah. That's painful :(

14:28 nDuff: emezeske: I've found https://developers.google.com/closure/compiler/docs/js-for-compiler to be relevant and useful.

14:29 emezeske: nDuff: For generating externs files?

14:29 hiredman: I found an extern file someone made for codemirror, tried to plug it in to cljsbuild, and it just didn't seem to work, builds "succeeded", but it wouldn't run because method names kept getting mangled

14:29 nDuff: emezeske: it's the same comment format given there used for externs files, yes

14:29 emezeske: The comments aren't the important part, compared to just not having the names mangled

14:30 nDuff: emezeske: The comments are essential to not having the names mangled. :)

14:30 ...at least if you're doing anything involving constructors.

14:30 emezeske: nDuff: Nope, I've built probably 5 externs files, no comments in any of them, they all work

14:30 * nDuff points to the immediately above qualifier.

14:30 * emezeske sees.

14:30 dnolen: emezeske: nDuff is right about ctors

14:31 emezeske: hiredman: Yeah, there's no confirmation about "okay I found your externs file, and am using it"

14:31 nDuff, dnolen: I guess I don't have any ctors...

14:31 nDuff: also, @nosideeffects can be essential

14:31 hiredman: emezeske: I started down the path of adding printlns through the pipeline

14:31 technomancy: whoa; pprint emits byte arrays as vectors of ints =\

14:32 emezeske: nDuff: interesting.

14:32 hiredman: I think I did that once :(

14:32 hiredman: but the way cljsbuild works, adding in a dep makes it difficult

14:32 nDuff: ...well, maybe "essential" is a little too strong, but having things get called that you aren't actually using in your code is... err... interesting.

14:32 mk: how does the rationalize function work? (defn rationalize [num] (. clojure.lang.Numbers (rationalize num)) ); this seems recursive with no stopping condition, what am I missing here?

14:32 hiredman: I can't just open the jar in lib/ in emacs and add printlns

14:34 I just put the finishing touches on a type that exposes the goog.storage methods (get,set,remove) but is also an event target, I'll have to see what advanced mode thinks of that

14:34 nDuff: mk: keep in mind that . is a special form, not a function

14:35 hiredman: of course reify and deftype can't deal with closure types, so you have to monkey with it manually

14:35 nDuff: mk: ...so, rationalize is a symbol that indicates a method to call

14:35 hiredman: (defn F [] (js* "/*") (js "*/")) <-- comments out the "return ..." so your function can be a constructor

14:37 mk: nDuff: ah. And I see now that the docs say (. instexpr (method args)) or (. instexpr method args). I thought only the latter was valid

14:38 emezeske: hiredman: It's very easy to use a clojurescript compiler checkout with lein-cljsbuild

14:38 mk: that's strange. Is the paren'd form more efficient?

14:38 emezeske: hiredman: And that's where the printlns would need to go -- lein-cljsbuild just passes through any externs options untouched

14:39 mk: it seems substantially more confusing, since it differs from e.g. apply

14:39 hiredman: emezeske: easy compared to just opening a jar in lib/ ?

14:39 nDuff: mk: it may differ from apply, but it's equivalent to -> / ->>

14:40 emezeske: hiredman: I'd say approximately as easy: https://github.com/emezeske/lein-cljsbuild/wiki/Using-a-Git-Checkout-of-the-ClojureScript-Compiler

14:40 hiredman: anyway, forget it, I have written off externs, maybe I'll care again later

14:40 emezeske: hiredman: sure

14:41 mk: nDuff: ah, great. That helps, thanks

14:43 cpinera: Has anyone had success using lein-droid 0.0.8? I seem to be missing a dependency, [neko/neko "1.2.0-SNAPSHOT"] which I cannot find anywhere

14:45 brainproxy: suggestions for spitting out nicely formatted html, generated with hiccup, served by ring.. i tried tidy-up, but it complains about html5 tags like nav

14:46 i guess i could fork/hack tidy-up and see if I can have it run w/ more permissive settings, but was wondering if there's a ready-to-use alternative

14:46 mk: is clojure presently immune to decompilation?

14:48 technomancy: there are no known tools for turning bytecode back into clojure source, but it's still easy to see what it does by disassembling it

14:49 kvothe9: whois kvothe9

14:49 mk: that'sa you!

14:50 I thought that there was something that clojure did that broke decompilers

14:52 I think I read that here, but maybe I misinterpreted http://news.ycombinator.com/item?id=708950

14:52 nDuff: mk: Clojure does sometimes generate valid bytecode that javac wouldn't. It's certainly imaginable that some decompilers couldn't handle the full range of source Clojure can create.

14:52 hiredman: I started writing a bytecode -> datastructure thing, since disappointingly, asm's ClassReader doesn't give you info about method instructions

14:53 AtKaaZ: hey guys, what am I missing here? http://cljbin.com/paste/50197ad5e4b08788cc6d3f6a

14:53 hiredman: class files are actually easy to pull apart, I've been basing my effort on https://gist.github.com/707630

14:53 AtKaaZ: read the exception

14:54 AtKaaZ: yes I read but I don't understand:)

14:54 cpinera: Anyone working with Android?

14:54 mk: I understand that it's trivial to actually see the bytecode, I'm mostly curious about how far the ...legibility distance between the bytecode and the original source is. For unobfuscated java, that distance is almost nothing

14:55 AtKaaZ: indentation. I'm not experienced enough to parse that easily :)

14:55 AtKaaZ: oh wait, bit-xor was pasted as bitxor ?

14:55 but I pasted it correctly hmm

14:55 mk, sorry, I just copy/pasted thatfrom a pdf in a book

14:56 in repl the exception is: CompilerException java.lang.RuntimeException: Unable to resolve symbol: bit­xor in this context,

14:56 mk: AtKaaZ: pdfs are terrible, and sometimes elide - as end-of-line hyphens

14:56 AtKaaZ: but in the paste the dash was eaten

14:57 mk, but why would first bit-xor work and second one not, they are both spelled correctly in my REPL (but in the paste something ate the dash)

14:57 mk: the dash is missing in the repl as well, it seems. Highlight the dash, and type "-". It might be an imposter dash

14:57 AtKaaZ: omg you were right

14:58 how odd, thank you mk

14:58 so the pdf had evil dash... and the paste should've given me a clue

14:59 mk: they're a devious lot

15:01 vijaykiran: Hi all - I'm trying to run lein swank on a newly created project and getting "Exception in thread "main" java.lang.NoClassDefFoundError:"

15:01 this is with lein-2.0-p7

15:02 anyone seen this before ?

15:03 jsabeaudry: hmmm, missing lein deps?

15:03 I'm pretty sure I've seen that error before but can't remember what exactly I did to fix it, probably something trivial

15:04 mk: http://stackoverflow.com/questions/9285392/lein-swank-doesnt-work-after-lein-upgrade if you haven't seen. I just searched the exception , plus 'swank'

15:05 AtKaaZ: mk, the evil dash was 173 and the normal one is 45, they look the same though heh

15:05 vijaykiran: here's the full trace https://gist.github.com/3229826

15:05 mk: did see that in google-search - but I get error even for repl

15:05 technomancy: vijaykiran: sounds like you have a bad plugin in your user profile interfering

15:06 vijaykiran: technomancy: I have lein-pprint and lein-swank in the profiles.clj

15:07 technomancy: what does `lein classpath` give you in the new project?

15:07 mk: AtKaaZ: good thing it wasn't one of the unicode foreign spies, or we might have never caught on (various cyrillic chars, for example; those don't disappear awkwardly like the dash did)

15:07 vijaykiran: technomancy: https://gist.github.com/77552812859ca6b1fa06

15:08 Moses: Hi, I'm looking to get started using Clojure with Vaadin, does anyone know how to set that up? I've seen some articles, but they all appear to be rather old and outdated.

15:08 technomancy: vijaykiran: if the clojure classes aren't being found, maybe your clojure jar in ~/.m2 is messed up

15:09 vijaykiran: technomancy: ok, let me try with a fresh .m2

15:09 * technomancy heads off for lunch

15:10 Moses: And by "appear", I mean I tried them and they didn't work because something was deprecated (like leiningen-war for example).

15:19 nDuff: Is there a better approach than (apply concat (for [...] [a b])) to have a for expression yield two values for each iteration (without putting them in nested vectors)?

15:21 amalloy: nDuff: apply concat is usually most readable

15:21 Iceland_jack: nDuff: mapconcat

15:21 Just may be what you're looking for

15:21 amalloy: but if you want to be clever: ##(for [x (range 5), item [x (inc x)]] item)

15:21 lazybot: ⇒ (0 1 1 2 2 3 3 4 4 5)

15:22 Iceland_jack: *mapcat

15:22 ,(mapcat (juxt identity inc) (range 5)

15:23 )

15:23 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

15:23 Iceland_jack: ,(mapcat (juxt identity inc) (range 5))

15:23 clojurebot: (0 1 1 2 2 ...)

15:23 Iceland_jack: Been programming in elisp for too long

15:29 mk: is (biginteger ...) effectively deprecated?

15:36 pjstadig: mk: why would you say that?

15:36 ~source biginteger

15:38 mk: pjstadig: due to clojure's bigint, and the fact that clojure arithmetic will never generate a biginteger. I guess it's a shortcut for (BigInteger. ...), but if that's the only time you'd ever use it, then it seems depreciated

15:38 amalloy: &(class (inc' Long/MAX_VALUE))

15:38 lazybot: ⇒ clojure.lang.BigInt

15:40 pjstadig: BigInt doesn't implement all the same methods that BigInteger does, like pow

15:40 which makes it a bit awkward to work with

15:40 if you need to call those BigInteger functions

15:40 i think there's still need to make BigIntegers, especially if you're working with JDBC or any other kind of java interop

15:41 mk: sure, but you shouldn't be using those via java interop. I think there's a clojure lib for that, but I agree that it's strange that it isn't in the core def.

15:42 pjstadig: the BigInteger constructor takes a string, the biginteger function takes and coerces other things so its a bit more convenient

15:42 mk: yeah, I agree with java interop, but it seems safe to say that they're no longer part of clojure in the way that e.g. longs or BigDecimals are

15:42 cemerick: Ratios know nothing of BigInt.

15:42 pjstadig: i would not go so far as to say that you "shouldn't" call methods like pow on BigInteger

15:42 there's no easy alternative in clojure, and that's what interop is for

15:43 mk: cemerick: but do ratios expose BigInteger?

15:43 cemerick: I think it's safe to say that anything not labeled as deprecated isn't deprecated. :-)

15:43 mk: yes

15:43 mk: demo?

15:43 clojurebot: ants-demo is https://gist.github.com/1093917

15:43 cemerick: mk: find yourself some sources ;-)

15:44 mk: cemerick: what sort of arithmetic on a ratio leaves me with a BigInteger?

15:44 gfredericks: &(type (* 3 1/3))

15:45 ,(type (* 3 1/3))

15:45 clojurebot: clojure.lang.BigInt

15:45 gfredericks: hm

15:45 mk: I'm somewhat sure that they've been purged...

15:45 hyPiRion: &(type (let [a (/ 1 3)] (/ a a)))

15:45 lazybot: ⇒ clojure.lang.BigInt

15:46 cemerick: mk: Ratio's only ctor accepts only BigIntegers.

15:46 ,(class (.bigIntegerValue (clojure.lang.Ratio. (biginteger 10) (biginteger 5))))

15:46 clojurebot: java.math.BigInteger

15:46 pjstadig: look, the point is there's probably a use for (biginteger x) when doing interop

15:46 and biginteger is not simply a wrapper for BigInteger.

15:46 cemerick: pjstadig: if only for HOF usage

15:47 mk: cemerick: constructing a ratio using java interop and getting the biginteger value using java interop is cheating :)

15:47 michaelr525: hello

15:48 mdeboard: hi

15:48 mk: pjstadig: right, though it's something like a convenience wrapper now, and (it seems) you'd never touch it unless you're doing interop

15:49 pjstadig: "unless you're doing interop" is a big reason for clojure's existence :)

15:49 cemerick: You'd never touch proxy unless you're doing interop, either.

15:50 mk: pjstadig: clojure is close to its platform, but cljs is clojure as well

15:51 if bigint really is gone except for interop, it makes understanding the whole bigint-biginteger thing much easier: "at one time, the clojure big integer structure was just java's BigInteger, but this was a mistake, and now clojure uses BigInt which gives correct hashcodes. You can still, of course, create BigIntegers using java interop, if you really need to"

15:52 pjstadig: clojure != cljs which is a major tenant of cljs' existence

15:52 cemerick: Clojure is not ClojureScript is not ClojureCLR

15:53 hiredman: it kills me that people are basing these "ports" on cljs

15:53 cemerick: Portability may eventually blur the lines enough so you won't care for many things, but they're hardly the same thing.

15:53 hiredman: no vars, no reified namespaces

15:54 mk: I understand that jvm clojure is different from cljs, but I thought that clojure existed as a number of different close-to-platform implementations, clojure-jvm being only one among them and not primary

15:55 hiredman: part of why I am interested in disassembling java bytecode is to take that bytecode and do a "source" to source translation to make the .java parts of the clojure runtime available elsewhere without large amounts of rewriting

15:56 ToxicFrog: mk: no. Clojure is a JVM language first and foremost. cljs and clj-clr are related but secondary projects.

15:56 pjstadig: mk: that's correct, and rich was explicit from the beginning that clojurescript was not about trying to produce the same semantics on both the JVM and JS engines

15:57 so i don't see the point in talking about how biginteger is "only for interop"

15:57 mk: hiredman: perhaps I misunderstand, but why not use the .java source? Or why not simply treat the runtime as a .class black box that you can import as a lib?

15:58 pjstadig: at one time, biginteger was much more important to clojure. It had the status of long, double, Future, Runnable, and BigDecimal. It no longer has that status.

15:59 ToxicFrog, pjstadig: who is correct?

15:59 ToxicFrog: mk: probably pjstadig

16:00 hiredman: and translating one class based language to another should be fairly simple (jvm bytecode => python or ruby)

16:00 mk: it's probably true though that ...cljvm is the reference implementation, or something

16:00 cemerick: mk: biginteger was a Future, Runnable, and BigDecimal? o.0

16:01 pjstadig: i think of it more like clojure is an abstract concept including state management and persistent data structures and cljvm, cljs, and clj-clr and implementations of it

16:01 with cljvm and clj-clr being more "full" implementations

16:02 mk: cemerick: same status. In the way that cljs numbers are all actually just javascript doubles

16:03 there's no longer any construct in clojure that's "actually just a" java BigInteger

16:03 pjstadig: i'm not actually convinced that BigInt was a good idea

16:04 hiredman: pjstadig: it was a decision made before the hashing change

16:04 pjstadig: as much as clojure is about embracing the platform, there are all kinds of nasty little corners where it isn't a good citizen on the jvm

16:04 mk: hiredman: really? What were the reasons besides hashing?

16:05 hiredman: I think motivated to have a bitint that hashed the same as long, of course now that hashing isn't exclusively .hashCode it's not required

16:05 cemerick: mk: Same goes for Future and Runnable; futures happen to be Futures, and functions happen to be Runnable and Callable. Those are interop affordances, not necessary, specified characteristics.

16:06 mk: as I understand it, clojure treats int, long, and BigInt as realizations of a single type, an integer number. The different realizations have different performance characteristics.

16:07 gtrak: is int any faster than long? I think it probably isn't

16:08 dnolen_: gtrak: int is slightly faster in Java - but there not enough support to really leverage that in Clojure

16:08 mk: cemerick: but BigDecimal, double, and long have the sort of status that I'm talking about, then?

16:09 gtrak: long is actually faster than int, in the abstract way that I'm getting at, because integer multiplication takes an infinite or undefined amount of time for integer values above integer.maxvalue

16:11 gtrak: your abstraction defines exceptions in term of values of time?

16:13 mk: gtrak: exceptions, overflows, and so on occur when the language tries to deal with various imperfections. Ideally, a language would, e.g. when multiplying two ints that overflowed, return a different realization of the type, probably a BigInt in this case

16:17 when the value of a particular integer fell back within the range of long, or int, the language might replace it with a more performant realization

16:19 if you're familiar with java string interning, you might imagine a thread, like the gc, that quietly interned strings, saving memory and improving the performance of the compareTo function

16:19 gtrak: mk: clojure used to promote numbers, those functions still exist, eg. +'

16:19 pjstadig: clojure doesn't autopromote anymore

16:20 mk: gtrak: yep, exactly :) clojure is a very high-level language for offering the ability to do that

16:20 gtrak: mk: that sounds like the job of a jvm optimization

16:20 escape analysis, stack allocation, auto-unboxing etc..

16:21 pjstadig: AFAIK BigInt was created to fix a hashing bug that was actually a bug in Clojure's PersistentHashMap implementation, and it is not a drop-in replacement for BigInteger (in the Liskov Substitution sense), I think the vestigial appendage is BigInt, not biginteger or BigInteger

16:22 mk: gtrak: it can't be done at compile-time, if that's what you mean. But yes, it would probably be run on the jvm, like the gc is. Clojure's autopromotion is the same sort of process

16:23 gtrak: mk: right, you're basically defining a VM when you do stuff like that

16:23 brick-wall of abstraction

16:25 it took java like 13 years to get fast?

16:25 mk: pjstadig: are you sure? I mean, you could technically implement a new hashing function for all your collections that returned the same hash for all realizations of numbers in integer, but that doesn't seem the right way to go

16:26 pjstadig: well that's what Clojure has done

16:26 gfredericks: abedra told me that BigInt was for equality semantics? I don't think he got into the details though

16:26 pjstadig: hashing used to be .hashCode but now theres RT/hash and clojure.core/hash

16:26 mk: gtrak: well, even the gc isn't a brick wall, since you can command it to collect, and sometimes system resources that need to be unloaded leak through the gc abstraction

16:27 pjstadig: gfredericks: clojure had already redefined equality for integer types

16:27 gtrak: mk: the actual behavior of System.gc() is left up to the implementation I believe

16:27 pjstadig: which was the problem with PHM, because it didn't use an appropriate hashing function that matched its equality function

16:28 gfredericks: pjstadig: yeah I don't really know what I'm talking about :(

16:28 mk: gfredericks: if both long and BigInt are mere realizations (not to be confused with subclasses) of an integer, then both should return the same value when thrown into hashCode, which they do.

16:28 pjstadig: mk: so does BigInteger

16:28 except in certain ranges

16:28 namely negative numbers

16:29 mk: pjstadig: then it's not a faithful realization of the "integer" type

16:30 zellio: what in the world does the error "Exception in thread "main" java.lang.AssertionError: Assert failed: Vanilla functions must have vars associated with them.

16:30 " mean and can I fix it without needing to defn everyhting

16:30 hiredman: zellio: it is a cascalog exception

16:30 zellio: but yes, it basically means you need to defn your function

16:31 zellio: hiredman: okay, I thought so

16:31 just wanted to make sure, thanks

16:32 pjstadig: mk: actually the problem is that java.lang.Long is not a faithful representation of the "integer" type (according to your definition)

16:32 ,(.hashCode (Integer. -1))

16:32 clojurebot: -1

16:33 pjstadig: ,(.hashCode (Long. -1))

16:33 clojurebot: 0

16:33 mk: pjstadig: clojure now uses longs everywhere, I think for the same reason

16:34 Integer, Long, and BigInteger are not compatible as representations of an integer type

16:34 pjstadig: the Long class cuts its value into two 32-bit halves and XORs them together, which is the "correct" way to hash a long value in java

16:35 but an Integer doesn't have two halves, and a negative Long when represented as two's complement happens to annihilate all of the bits

16:35 which is why the hashcodes come out different

16:35 coercing a long to an int just discards the significant bits

16:35 which seems to be something like what BigInteger does in its hash

16:35 so the inconsistent class is Long

16:35 mk: clojure chose java Longs as the reference, and created the alternate BigInt realization of the "long-based integer" type, because values above maxvalue could not be realized as Longs

16:36 pjstadig: mk: you pretty much don't know what you're talking about at this point

16:37 mk: pjstadig: I suspect that I do

16:38 pjstadig: do you understand what I mean when I say "realization"?

16:38 I'm guessing you're familiar with referential transparency

16:39 gtrak: realization sounds like reification

16:40 mk: gtrak: it might be, but I suspect that term might have baggage

16:40 gtrak: where's the term 'realization' coming from?

16:41 mk: it's not a standard term, but I don't know if there's a non-confusing term for what I'm referring to

16:42 Moses: Is it possible to replace leiningen-war with lein-ring, for someone trying to follow this tutorial? http://blog.rajithdelantha.com/2011/05/complete-guide-to-write-vaadin.html

16:42 gtrak: concretization?

16:42 pjstadig: mk: please enlighten me, i'm all a twitter

16:43 TimMc: snrk

16:43 pjstadig: you're saying that BigInt was created to replace Long, or to replace BigInteger?

16:44 mk: usually, we think of different values as being tied to something like classes, or even prototypes or whatever. But you can "realize" a value under different "structures"

16:45 (you can also realize the same value in different instances of the same structure. This is what happens with java strings.)

16:46 technomancy: Moses: I'm sure you could make it work, but it won't be a drop-in replacement

16:46 Moses: Am I better off just using the deprecated leiningen-war?

16:47 pjstadig: http://en.wikipedia.org/wiki/Equivalence_relation

16:47 Moses: Probably right? At least for the purposes of the tutorial

16:47 I assume I can build it somehow outside leiningen and make it available to the app

16:47 Thanks technomancy

16:48 technomancy: never heard of vaadin, so I couldn't tell you which would be easier

16:48 mk: pjstadig: something like that, but it can't be mathematical. Programmers care about the performance characteristics of potentially different realizations of a single value, which isn't the case for math

16:48 gfredericks: oh man; I remember vaadin

16:48 * gfredericks tries to reforget it

16:48 Moses: That bad?

16:49 gfredericks: eh it was just a big pile of java classes; it might be good by java standards

16:49 Moses: I have a friend using it that thinks its made of win.

16:49 mk: java's ArrayList and LinkedList are realizations of a list, but they have different performance characteristics under different functions

16:49 pjstadig: mk: how is this related to hashing?

16:50 do you understand the fact that java.lang.Object.equals defines and equivalence relation? and the relationship between java.lang.Object.equals and java.lang.Object.hashCode?

16:51 mk: pjstadig: because hashCode is a function like any other. Different *realizations* of the same value must return the same resultant value, unless there's a program error (exception, overflow)

16:52 int, long, and BigInteger are not realizations of the same value

16:52 but long and BigInt are different realizations of a single "longish integer" value

16:53 pjstadig: so what is int?

16:53 not a "longish integer"?

16:53 cemerick: "longish"?

16:54 mk: cemerick: produces the same value as long for the referentially transparent hashCode

16:55 pjstadig: int is a type. long is a type with two realizations (long, BigInt). BigInteger is a third type.

16:55 * cemerick opts out

16:55 gtrak: mk: hashcode is polymorphic on its first arg

16:55 pjstadig: arguments are realization

16:55 and "structures" aren't classes?

16:56 mk: what is different about the int type and the long type?

16:56 gtrak: ,(.equals (int 1) (long 1)) ; mk: check it out

16:56 clojurebot: false

16:56 pjstadig: and what is the same about the long and BigInt as realizations of the long type?

16:57 mk: gtrak: right. All values have a hashcode, so polymorphic. But all realizations of the same value (whether long or int) produce the same value under all ref tranpsarent functions.

16:57 gtrak: turns out java doesn't consider them the same value

16:58 mk: gtrak: as expected?

16:58 pjstadig: mk: so the hashcode for -1 should be the same for an instance of Integer, Long, and BigInt?

16:59 gtrak: I thought one of your assumptions were that they're equal but different hashcodes

16:59 mk: pjstadig: they produce the same value under all functions. It's a big deal that they produce the same value for hashcode because of collections.

16:59 pjstadig: but they don't

16:59 ,(.hashCode (Integer. -1))

16:59 clojurebot: -1

16:59 pjstadig: ,(.hashCode (Long. -1))

16:59 clojurebot: 0

17:00 mk: gtrak: they are different types. long and BigInt are the same type, different realizations (one's a primitive, the other's technically a class)

17:00 pjstadig: i don't think BigInt is "technically" a class

17:00 i think it really *is* a class

17:01 mk: pjstadig: sure, that's fine by me

17:01 gtrak: what makes something a type vs a realization?

17:03 mk: gtrak: java classes aren't types. A type is a collection of values that work well together. A realization is a particular way that a value is represented, and different realizations have different performance characteristics.

17:04 gtrak: so like a domain?

17:05 wiki says "a domain is any connected open subset of a finite-dimensional vector space." That seems to agree with saying ints and longs are different types

17:06 mk: gtrak: you might need to define domain, but probably not. Different realizations are identical mathematical values, in the same way that "1" and "one" 'realize' identical values

17:07 gtrak: yes. Different realizations of a value are probably not in different domains.

17:07 clojurebot: excusez-moi

17:07 pjstadig: mk: now i'm *sure* you don't know what you're talking about

17:07 but that was fun

17:08 and also entirely unrelated to BigInt/BigInteger (somehow)

17:09 mk: pjstadig: I don't know enough about domains to explain the relation to them, and I pointed this out. As for everything else I've said, I'm fairly certain that I'm talking about a very definite abstraction

17:09 pjstadig: bigint and biginteger are different types

17:09 pjstadig: ok

17:09 mk: bigint and long are the same type

17:10 pjstadig: i don't agree

17:10 mk: "but they're... different, ones a primitive and one's a class!"

17:10 gtrak: mk: it seems what you're saying is a little informal at this point

17:10 mk: yeah, they are different. They're different "realizations" of the same type

17:10 emezeske: mk: What terminology are you using? Not Java terminology, it seems

17:10 pjstadig: gtrak: a littel?

17:11 *little

17:11 stain: http://imgur.com/7219T

17:11 gtrak: I don't know enough to be blatant authoritatively :-)

17:11 stain: a bit confusing with those kind of brackets!

17:11 emezeske: mk: Are you using category theory terms?

17:11 mk: gtrak: I'm pretty sure this is easily formally defined, and I've come pretty close to a rather formal definition

17:12 gtrak: mk: it seems like it could be, yes, I agree

17:12 emezeske: mk: If you want to distinguish types in the category theory sense, you should probably be very clear about that, because in Java terminology, bigint and long are most definitely not the same type

17:12 pjstadig: mk: you have failed to show how bigint and long are the same "type" and bigint and biginteger are different types

17:13 mk: emezeske: as I understand it, I'm using "type" in that way. When I say type, I mean haskell-types. When I say value I mean clojure's definition of value.

17:13 pjstadig: what we have are an abstraction and several concrete realizations

17:13 but a failure to show the connection between them

17:13 other than saying "they're different"

17:14 mk: emezeske: in java, bigint and long aren't the same haskell/category-type

17:14 emezeske: mk: Right. In this IRC channel, you should be aware that the overloaded "type" term by default resolves to Java Type

17:15 tc34: hello, looking for some suggestions on having a "rewriting" web reverse proxy. Is ring the right way to go?

17:15 gtrak: tc34: any reason you can't use apache or something?

17:15 mk: pjstadig: bigint and long are the same type because, by design, nothing except performance would change if we made all longs into bigints.

17:16 emezeske: my bad, thanks

17:16 pjstadig: so you're essentially talking about Liskov Substitution

17:17 the problem is that BigInt and Long are not defined solely by their Java classes, but a combination of their java classes and some clojure semantics that overlay them

17:17 tc34: apache mod_rewrite, or nginx. But would like to define the config rewrites, redirects, url mappings in clojure code.

17:17 pjstadig: clojure could have just as easily defined the bits to make BigInteger work the way that BigInt does and BigInt would be unnecessary

17:18 mk: pjstadig: I'm not sure about Liskov, because it's a property of longs that they can't properly realize values above maxvalue, and a property of BigInt that they are substantially slower when thrown into the multiplication function.

17:18 pjstadig: the only reason that BigInt was introduced instead of doing that, was that, at the time, the clojure machinery didn't exist

17:18 gtrak: tc34: sounds a little... gruesome

17:18 technomancy: tc34: unless you are planning on changing them at runtime, a clojure->nginx.conf compiler might be your best bet

17:20 mk: pjstadig: in java, BigInteger and long are not the same type. If clojure treated them as the same type, by treating isomorphic values in one as equal to those in the other, this would have been a mistake

17:21 gtrak: does a category theory type include all of something's polymorphic behavior?

17:21 AtKaaZ: how to create an alias deffn for defn?

17:21 gtrak: AtKaaZ: (def deffn defn)

17:21 pjstadig: mk: then clojure's already full of fail because it does that with Integers and Shorts and Bytes

17:21 tc34: technomancy: gtrak: thanks, i will try generating the config.

17:21 pjstadig: and walks all over equality

17:21 mk: gtrak: the way I understand types (from a programming, close to Haskell, not ct perspective) is that they are roughly defined by one or two functions among the values in that type

17:21 AtKaaZ: gtrak, doesn't seem to work

17:21 TimMc: gtrak: Will that work? Might be some macro metadata problems.

17:21 gtrak: AtKaaZ: ah... oops

17:22 yea, you have to write a macro

17:22 TimMc: I think Raynes or someone was writing a macro aliaser.

17:22 Raynes: A what?

17:22 gtrak: AtKaaZ: (defmacro deffn [& args] `(defn ~@args))

17:23 mk: pjstadig: yeah. And it also doesn't autopromote longs over maxvalue to bigint. On the other hand, I think that what I'm talking about now is one of the main reasons clojure now uses longs-bigints everywhere by default

17:23 Raynes: TimMc: Yeah, that isn't me.

17:23 :p

17:23 TimMc: "or someone" = amalloy

17:23 AtKaaZ: gtrak is it possible to ommit the args ?

17:24 amalloy: that sounds like something Raynes and i know better than to do

17:24 gtrak: AtKaaZ: well, macros take forms as input

17:24 TimMc: Oh, maybe a var copier. I dunno.

17:24 gtrak: the args are those forms

17:24 TimMc: AtKaaZ: What's the point of this anyway -- to make your code harder to read?

17:24 gtrak: TimMc: shh

17:25 AtKaaZ: TimMc I just wanted to know how easily this aliasing can be done :)

17:25 but also the defn was for me def+n instead of def+fn when I first saw it

17:26 pjstadig: mk: "it doesn't promote longs over maxvalue to bigints" but earlier you said long and BigInt were the same type because we could replace every long with a BigInt?

17:26 TimMc: they see me defn, they hatin

17:26 pjstadig: i'm confused as to what you are arguing

17:26 it's like trying to nail jello to the wall

17:26 mk: gtrak: for example, the integer type is a set of values that "work well together" under addition, and various functions derived from addition (integer negation, subtraction, mult, div, etc.)

17:26 AtKaaZ: gtrak, thank you

17:27 gtrak: np

17:27 TimMc: mk: Work well? Hardly! int isn't closed under +.

17:27 gtrak: mk: I think the most we can say at this point is the integer type is a set of values

17:27 mk: TimMc: if you mean overflows, I mean the "integer" type, which is implemented in clojure using longs and bigints

17:28 amalloy: TimMc: useful does have code to alias things, including macros, but i don't really approve of it being used

17:28 TimMc: heh, I thought it might be or someone

17:28 mk: pjstadig: right. Clojure gives up correct representation or what have you when this would be impractical

17:29 AtKaaZ: how could I find out what ` does if I had only clojure repl at hand?

17:29 hiredman: to people just not read docs?

17:29 AtKaaZ: something like (doc or source ?

17:29 gtrak: (inc TimMc)

17:29 lazybot: ⇒ 11

17:29 nDuff: Is there an easy way to conditionally insert something into a ->> pipeline?

17:30 hiredman: 10 minutes of discussion of renaming/aliasing and no mention of the features in `use` and `require` ?

17:30 mk: AtKaaZ: see the answer to http://stackoverflow.com/questions/3704372/how-does-clojures-syntax-quote-work

17:31 gtrak: hiredman: that's some crazy voodoo

17:31 mk: AtKaaZ: there's no equivalent function, so you can't do a doc like you might (doc quote)

17:32 cemerick: hiredman: almost the first rule of programming is, other programmers don't read docs

17:33 xeqi: can you mention the first rule?

17:33 pjstadig: i think that is the first rule

17:33 Wild_Cat: xeqi: you'd know it if you read the docs! :p

17:33 cemerick: Yes, but I can't mention the zeroth rule.

17:34 aperiodic: A robot must not harm humanity, or through inaction, allow humanity to come to harm?

17:35 oh, zeroth rule, not zeroth law

17:35 pjstadig: aperiodic: i like that, though, as the zeroth rule of programming

17:35 mk: gtrak: we can also say that the values in the integer type are realized in clojure by long and BigInt, that long and BigInt values have different performance characteristics, and that int and BigInteger have effectively been purged from clojure because clojure is on its way to distinguishing between types and what I call realizations, and because it doesn't want to deal with more than one integer type.

17:36 hiredman: "A robot must at all times set Will Smith up for witty remarks"

17:37 AtKaaZ: rule #0: source code is also doc and binary

17:37 * nDuff posts http://stackoverflow.com/questions/11767931/conditional-elements-in-pipelines

17:37 mk: or "a robot must at all times provide asimov with a good plotline"

17:37 gtrak: mk: I think I agree with that. It's a consequence of clojure being lovey-dubby with java and not having a clean-break

17:37 pjstadig: mk: you're still missing my point, which is that the same thing could have been accomplished with BigInteger, BigInt is/was unnecessary

17:38 gtrak: I guess we could have done it with protocols instead?

17:39 pjstadig: clojure.core/hash and RT/hash were added to create an "integer type" and the reason they were added was because of Long not BigInteger

17:39 gtrak: this comes back to what I was saying earlier, a protocol implementation alters a java type in some sense, polymorphism is part of the type I think

17:39 dnolen: pjstadig: BigInt was added because of performance complaints

17:39 pjstadig: and clojure could just as well have implemented those functions for BigInteger instead of adding BigInt

17:39 mk: pjstadig: I think I addressed that. You can't do that by creating a special new clojureCollectionHash that returned the same value for longs and BigIntegers, because hashCode would still exist, proving that a long and a BigInteger aren't the same value. And hashCode isn't negligible, because it's the basis for half of java's collections.

17:41 AtKaaZ: ,`(+ 1 2)

17:41 clojurebot: (clojure.core/+ 1 2)

17:41 AtKaaZ: that would've been quite the hint :D

17:41 gtrak: AtKaaZ: yes, I did that in my repl before posting it here :-)

17:42 user=> (macroexpand-1 '(deffn a [b c] d e))... (clojure.core/defn a [b c] d e)

17:42 pjstadig: mk: you are confusing java with clojure

17:42 AtKaaZ: mk, thanks for the previous article link

17:43 mk: pjstadig: I'm not, because clojure "accepts" certain parts of java

17:43 AtKaaZ: no problem :)

17:44 pjstadig: yes you are hashCode is a java function

17:44 and infact even in java you can define a hashmap using something other than hashCode

17:45 clojure doesn't use the same hashCode

17:45 mk: pjstadig: I mean that it doesn't just provide interop, but treats certain parts of the platform as if it were its own (long, double, BigDecimal, and Runnable are examples, I think)

17:45 lucian: mk: that *is* the interop as far as i'm concerned

17:46 AtKaaZ: gtrak, in this: (defmacro deffn [& args] `(defn ~@args)) was the "`" really necessary though ?

17:46 mk: pjstadig: if you give clojure an immutable java collection, I don't think it treats it as a foreign body

17:47 gtrak: AtKaaZ: I think so?

17:47 mk: pjstadig: furthermore, clojure makes an effort to proudly implement various java interfaces, instead of hiding them

17:47 gtrak: ,(read-string "(defn a [b c] d e)")

17:47 clojurebot: (defn a [b c] d e)

17:47 gtrak: hrm... maybe not

17:48 AtKaaZ: well I do get this: CompilerException java.lang.RuntimeException: First argument to def must be a Symbol; if I don't use ` :)

17:48 pjstadig: mk: if you look at Long and BigInt from the java perspective

17:48 they are not equal

17:48 if you put them in a java collection they will behave accordingly

17:48 gtrak: AtKaaZ: could use regular-quote '

17:48 pjstadig: if you put them into a clojure collection they will behave differently

17:48 clojure adds a layer of equality and hashcode semantics on top of java

17:48 gtrak: AtKaaZ: you have to have a quote of some sort, otherwise you have to build the list yourself with cons

17:49 AtKaaZ: gtrak, oh right that makes sense, silly me

17:49 pjstadig: it could have just as easily done so for BigInteger instead of introducing BigInt

17:49 mk: lucian: you can have one without the other, I think. For example, you might build a language on the jvm but reject all java values, but offer ways to create them and call them, as second-class citizens. Or you might base your longs precisely on java longs, without offering any way to call Long.toString, for example.

17:49 pjstadig: how would you have made a long 1 equal to a BigInteger 1?

17:50 make that a -1

17:50 pjstadig: RT/equiv

17:50 AtKaaZ: ,`(defn)

17:50 clojurebot: (clojure.core/defn)

17:50 AtKaaZ: ,'(defn)

17:50 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (0) passed to: core$defn>

17:50 pjstadig: ,(.equals (Long. 1) 1N)

17:50 clojurebot: false

17:50 pjstadig: ,(= (Long. 1) 1N)

17:50 clojurebot: true

17:50 AtKaaZ: '(defn) this works for my repl

17:51 mk: ,(class 1N)

17:51 clojurebot: clojure.lang.BigInt

17:51 gtrak: AtKaaZ: mine too

17:51 AtKaaZ: ,*clojure-version*

17:51 clojurebot: {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"}

17:51 pjstadig: which brings me back to, "I'm pretty sure you don't know what you're talking about"

17:51 technomancy: clojurebot's not on the release?

17:51 AtKaaZ: I'm on 1.3.0

17:52 gtrak: AtKaaZ: I think it's an issue with the stuff on top exposing the repl here, not the lang itself

17:52 &'(defn)

17:52 lazybot: ⇒ (defn)

17:52 AtKaaZ: okie

17:52 gtrak: lazybot does the right thing

17:52 AtKaaZ: &*clojure-version*

17:52 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

17:52 mk: pjstadig: like I said, long (aka Long) and BigInt are the same type. Java .equals isn't a good measure of equality, I think (== is even worse).

17:53 gtrak: mk: it's the only one for java

17:53 == is identity

17:53 amalloy: i'm betting clojurebot's macroexpander is a little broken. lazybot's certainly has been in the past, and that's way more likely than such a crazy error in the 1.4.0 snapshot

17:54 mk: gtrak: many programmers don't understand the difference between equality and identity, and treat == as a more-efficient but broken version of .equals

17:54 pjstadig: mk: like i said, you are conflating clojure and java

17:54 lucian: mk: sure, but that's still be interop, just less deep

17:54 gtrak: mk: turns out they're equally efficient in the case it doesn't break something

17:54 pjstadig: yes .equals fails to exemplify the integer "type"

17:54 that's because it is Java's view of the world

17:54 clojure creates its own view

17:54 and it could just as well have extended that view to BigInteger instead of introducing BigInt

17:55 mk: pjstadig: if I'm in java, using a clojure function (which clojure explicitly endorses as a thing-to-do), and clojure informs me that a BigInteger and a long are equal, but java disagrees, that's a problem.

17:55 pjstadig: yes

17:55 gtrak: mk: a proper Object.equals() implementation first checks for identity

17:55 pjstadig: and it exists

17:55 that's the way things work

17:55 you just have to be "careful"

17:56 AtKaaZ: ,(= 1M 1)

17:56 clojurebot: false

17:56 AtKaaZ: ,(== 1M 1)

17:56 clojurebot: true

17:56 AtKaaZ: ,(.equals 1M 1)

17:56 clojurebot: false

17:57 AtKaaZ: neat:)

17:57 mk: no, you don't. You just trust that java did separate its types correctly into BigInteger and long, and you avoid clobbering them into the same type.

17:57 pjstadig: i just showed you that BigInt and Long are not equal according to java, but are according to clojure

17:57 mk: ,(= 1N 1)

17:57 clojurebot: true

17:57 pjstadig: the same is true for Integer and Long

17:57 and for sequence types

17:57 etc.

17:57 AtKaaZ: ,(class 1N)

17:57 clojurebot: clojure.lang.BigInt

17:58 pjstadig: clojure creates its own view of the world which does not match at every point with java

17:59 mk: pjstadig: right. Initially, clojure treated them as if they were all realizations of the same type (which is ultimately the best view to take). This was a mistake which is now being corrected by dumping BigInteger and int.

17:59 pjstadig: no

17:59 BigInt

17:59 BigInt is the problem not BigInteger

17:59 BigInt is not equal to Long according to Java, but is according to Clojure

17:59 mk: pjstadig: are you saying that BigInteger and long are the same type?

18:00 pjstadig: they could be

18:00 in the same way that BigInt and Long are

18:00 BigInt was and is unnecessary

18:00 lucian: i think the same value of different types should always be equal, regardless of what java thinks

18:00 mk: java's equality is imperfect, but works most of the time. I'm pretty sure different "realizations" are beyond the power of Java.

18:01 gtrak: if only there were an integer interface

18:02 and an xml-configured integer factory

18:02 lucian: of course, it's not complete without xml

18:02 mk: lucian: there's no such thing as a same value in different types. There are isomorphisms, but each value has exactly one type. Null is a practical hack.

18:02 lucian: mk: numerical value

18:03 kaoD_: hi

18:03 mk: lucian: 2 and 2.0 are not the same numerical value

18:03 clojurebot: Huh?

18:04 gtrak: (inc clojurebot)

18:04 lazybot: ⇒ 11

18:04 lucian: mk: 1 and 1M sure are. floats are debatable i guess

18:04 mk: (class 1M)

18:04 ,(class 1M)

18:04 clojurebot: java.math.BigDecimal

18:05 lucian: ,(class 1)

18:05 clojurebot: java.lang.Long

18:05 gtrak: ,(= 1 1.0)

18:05 clojurebot: false

18:05 lucian: ,(class 1L)

18:05 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NumberFormatException: Invalid number: 1L>

18:05 gtrak: ,(= 1 1M)

18:05 clojurebot: false

18:05 lucian: (class 1.0)

18:05 ,(class 1.0)

18:05 clojurebot: java.lang.Double

18:05 AtKaaZ: gtrak what is that inc nick for ?

18:05 gtrak: AtKaaZ: reputations

18:05 (karma clojurebot)

18:06 &(karma clojurebot)

18:06 lazybot: java.lang.RuntimeException: Unable to resolve symbol: karma in this context

18:06 gtrak: hrm

18:06 mk: AtKaaZ: the bot implied that I was being confusing, which was funny. It triggers on the word "are", in case you want to add something to its dictionary

18:07 metellus: ,(karma clojurebot)

18:07 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: karma in this context, compiling:(NO_SOURCE_PATH:0)>

18:07 AtKaaZ: oh that's awesome I was about to ask why it responded

18:08 (find-doc "karma")

18:08 ,(find-doc "karma")

18:08 clojurebot: nil

18:08 mk: I think the point is that longs and BigIntegers are not the same type, at the very least in java. Clojure should and generally does obey that.

18:09 TimMc: $karma clojurebot

18:09 lazybot: clojurebot has karma 11.

18:09 lucian: i don't think clojure should pretend they're the same type, but i do think it should consider them equal and hash them to the same hting

18:09 TimMc: You can /msg lazybot to query for that.

18:10 AtKaaZ: ,(doc =)

18:10 clojurebot: "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."

18:10 kaoD_: I miss wildcards in multimethods (ala pattern matching), is there any way to fake it?

18:10 "compares numbers and collections in a type-independent manner" <- that's odd

18:10 lucian: that's flat untrue

18:10 mk: lucian: that's what it means to be the same type. Equality checks if two representations/instances/realizations of a value are the same value. A value can't have more than one type.

18:11 AtKaaZ: ,(doc ==)

18:11 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false"

18:12 mk: note that equivalent is not equal

18:12 goodieboy: what exactly does the clojure hash function do?

18:12 are there docs on how it works?

18:12 AtKaaZ: ,(and (= 1 1.0) (== 1 1.0))

18:12 clojurebot: false

18:13 mk: goodieboy: see http://clojuredocs.org/clojure_core/clojure.core/hash

18:13 goodieboy: ahh String hashCode, thanks!

18:14 AtKaaZ: how could I do a xor between those two returns ?

18:14 in place of "and"

18:14 mk: goodieboy: Object hashCode. It doesn't do toString.hashCode, in case that's what you meant.

18:14 goodieboy: mk: thanks!

18:14 mk: np :)

18:15 AtKaaZ: xor is (A and -B) or (B and -A)

18:16 alternatively, (A or B) and not(A and B)

18:16 AtKaaZ: I mean like, (bit-xor true false) but I need the boolean to not be boolean:D

18:16 without repeating

18:16 the A and B :)

18:17 any way to convert boolean to bits ?

18:18 mk: (defn xor [a b] (or (and (not A) B) (and (not B) A))

18:18 kaoD_: AtKaaZ: what do you mean boolean to bits?

18:18 booleans are bits

18:19 vijaykiran: technomancy: tried removing .m2 and reinstalling lein - but still no luck on "Exception in thread "main" java.lang.NoClassDefFoundError:" with 'lein repl'

18:19 kaoD_: (internally of course)

18:19 AtKaaZ: ,(bit-xor true false)

18:19 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: bit operation not supported for: class java.lang.Boolean>

18:19 AtKaaZ: that's quite ok mk :)

18:20 mk: kaoD_: booleans are technically not really bits. I take it AtKaaZ wants to drop booleans into bits in order to do (bit-xor) as a way of defining an (xor), but there's a better alternative

18:21 AtKaaZ: yeah, but I was hoping for something easier than having to def

18:21 gtrak: Booleans are a realization of bits, err wait... bits are the realization of booleans...

18:21 kaoD_: mk: booleans are bits in memory, just like any other value

18:21 I get what he means, I understood it the other way around

18:23 hiredman: AtKaaZ: def creates vars, I of course have no context, no idea what your code looks like or is doing, but you almost certainly want let not def

18:23 AtKaaZ: ,(bit-xor (if (= 1 1.0) 1 0) (if (== 1 1.0) 1 0) )

18:23 clojurebot: 1

18:23 technomancy: vijaykiran: sorry, without knowing more about your setup it's impossible to say what's wrong

18:24 gtrak: I've never avoided def out of difficulty

18:24 AtKaaZ: too ugly i know

18:24 mk: booleans like all things are represented by bits. Or pixels. Or ink. Or holes in a surface. Or rotating pieces of metal. But those details are usually irrelevant.

18:24 AtKaaZ: it was a need to use bit-xor for this: ,(and (= 1 1.0) (== 1 1.0))

18:24 or any xor :)

18:24 mk: booleans exist in the mind, man

18:25 AtKaaZ: i like learning like this, it's exploratory somehow

18:25 which implies fun;)

18:26 mk: so like, xor instead of and?

18:26 vijaykiran: technomancy: okay - thx! Will try to figure out what I did wrong.

18:26 AtKaaZ: yes

18:26 ,(= 1 (bit-xor (if (= 1 1.0) 1 0) (if (== 1 1.0) 1 0) ))

18:26 clojurebot: true

18:27 AtKaaZ: aka return true if those 2 are different

18:27 mk: xor is what you get when all of your things are different from each other

18:28 kaoD_: mk: they're not that irrelevant, specially in languages where representation is quite "volatile" (i.e. languages that allow casts)

18:28 although in a Clojure context you're completely right

18:28 mk: perhaps something like (not (= (boolean A) (boolean B)))

18:29 AtKaaZ: nice, much simpler mk

18:29 mk: kaoD_: when a cast is performed, one value goes in and a totally different value comes out

18:29 AtKaaZ: ,(not= 1 2)

18:29 clojurebot: true

18:29 AtKaaZ: awesome

18:30 kaoD_: mk: nope

18:30 AtKaaZ: ,(not= (= 1 1.0) (== 1 1.0))

18:30 clojurebot: true

18:30 kaoD_: not at bit-level

18:30 (which is what we where talking about right?)

18:30 mk: kaoD_: for example, in javascript you might think "1" and 1 are equal, but they are not. As a convenience, javascript offers type conversion on one of its equality functions

18:31 kaoD_: okay, let me rephrase that

18:31 languages that allow hardware-level casts

18:31 mk: kaoD_: there's no such thing as the bit level if we're talking about values. Values don't have a bit level. Realizations of values do.

18:32 kaoD_: ok you can go all technical, but bits do still matter

18:32 AtKaaZ: mk, definitely the right way is to use not equal instead of xor, but I really wanted to see that xor in action back then :D

18:32 kaoD_: e.g. what's the value of a boolean cast to an int in C? that sort of details are quite important

18:33 in-memory value != realized value

18:33 gtrak: in C the semantics are conflated with the hardware, much like clojure and java

18:33 mk: the reason values don't have a bit level is because (gimmebitlevel 1) can't be a function. Two different ones might be realized in different places in the memory, or whatever. Sometimes, floating point 0 and -0 are treated as exactly the same value.

18:33 kaoD_: mk: we're definitely discussing about a semantic issue

18:33 when I say values I mean in-memory values

18:34 not realized values

18:34 mk: kaoD_: a boolean doesn't have a value when cast to an int. You now have a different value in front of you. A potato went in, a carrot came out.

18:34 kaoD_: I must repeat: when I say values I mean in-memory values

18:34 a boolean has a constant value

18:35 even when cast to int

18:35 because it's just a region in memory

18:35 mk: kaoD_: you'll need to correct your terminology. There's no such thing as an "in memory" value.

18:35 kaoD_: hmm

18:35 well, I do think so

18:36 a region in memory is a series of bits

18:36 those bits are an (unrealized) value

18:36 mk: kaoD_: a boolean is an abstract concept, existing in the platonic realm, or in our minds. We can represent "true" by writing T, or flipping bits, or whatever

18:36 kaoD_: what do you mean by unrealized?

18:37 kaoD_: mk: sure, but it turns out that we're dealing with computers and that philosophical stuff is irrelevant

18:37 mk: I would have called them realized, because they ultimately represent a boolean

18:37 kaoD_: no, they don't represent anything

18:37 it's representation is volatile

18:37 now it's an int, now it's a boolean

18:37 and the bits didn't even change

18:38 ThatOneGuy: I believe a boolean is a single byte that is 1 or 0

18:38 kaoD_: ThatOneGuy: nope

18:38 a boolean is as wide as your hardware registers usually

18:38 ThatOneGuy: well in C the std.bool is an int of 1 or 0

18:38 kaoD_: for efficiency's sake

18:38 ThatOneGuy: why is that more efficient?

18:38 mk: kaoD_: the philosophical stuff is what you do when you code. You're trying to represent your mental models of things faithfully, and my mental models don't include bits. If they did, I wouldn't be able to reason about things efficiently.

18:39 ThatOneGuy: are you talking about just doing pure boolean logic in the CPU?

18:39 kaoD_: mk: yep but C is a bit different because it ties you to hardware so you can't abstract as much with basic data types

18:39 ThatOneGuy: is that why its more efficient

18:39 mk: a boolean is not a byte that is equal to 0 or 1. A boolean is a type having two possible values, True or False.

18:39 kaoD_: mk: not in C

18:39 well

18:39 ThatOneGuy: yeah we are talking about C ... low level stuff

18:39 kaoD_: let me rephrase that

18:39 ThatOneGuy: in the clojure channel :P

18:40 ToxicFrog: kaoD_: C doesn't even have a boolean type, it has boolean interpretations of integer types

18:40 Conceptually, mk is right

18:40 kaoD_: just a sec, let me rephrase that

18:40 mk: kaoD_: then either C does not have values, or it has values, and an integer really isn't a boolean and C == is dead-broken.

18:40 kaoD_: you're right in the "boolean is just true/false" argument

18:41 ToxicFrog: The fact that some languages might choose to represent a boolean as a byte and true as nonzero and false as zero doesn't mean that "boolean" and "integer" are synonyms.

18:41 kaoD_: but you can't forget that your type is represented with some other value (not related to the type)

18:41 your typed-value, I mean

18:42 mk: it isn't represented by a value. ink isn't a value.

18:42 kaoD_: there are two values here: the conceptual and the physical ones

18:42 mk: In C, you can pretend that a 0 is a boolean, but it really isn't

18:42 kaoD_: mk: yes, it's a value

18:42 a series of zeroes and ones

18:42 in your memory

18:42 mk: that's not a value

18:42 ThatOneGuy: so converting a C code

18:42 if(*num) {

18:42 somefn();

18:42 }

18:43 kaoD_: then what it is?

18:43 mk: and it's a bunch of magnetic junk, not 0 and 1

18:43 kaoD_: information

18:43 nope

18:43 because it turns out your machine interprets those electromagnetic forces as zeroes and ones

18:43 in an organized and documented fashion

18:43 which is already abstracted in the CPU

18:44 there's a value there and you can represent/realize it in whatever fashion you want

18:44 there's a typed value and a hardware value

18:44 and the value is there in whatever base/representation you want to see it

18:44 mk: your machine never interprets them as anything. It's not conscious. We presume that pulses of energy move around, causing us to eventually see screens with numbers on them.

18:44 kaoD_: I don't care, it's still a value

18:44 mk: what the fuck?

18:45 are you really discussing about machine's conscience?

18:45 mk: kaoD_: your computer doesn't know what a 0 or a 1 is.

18:45 kaoD_: humm

18:45 the CPU does indeed

18:45 it doesn't "know" in the traditional sense

18:45 mk: kaoD_: no, that's what you seem to be suggesting when you attribute human qualities like "interpreting as 0 or 1" to a machine

18:45 ThatOneGuy: haha you guys are fighting over the interpretation of 'know' (in this small segment)

18:46 kaoD_: but it's just a way to use language and say in short that "opcodes in CPUs are tied to the data stored in memory as bits"

18:46 mk: ThatOneGuy: justified true belief, man

18:46 kaoD_: you can't separate CPU opcodes from data!

18:47 CPU opcodes deal with that "magnetic junk" as bits

18:47 you're thinking too abstract

18:47 we're dealing with a electromagnetic machine after all

18:47 it's programmed

18:47 ThatOneGuy: I would say the machine doesn't not perceive therefore it does not know what values it is manipulating, but we can say its knows the values because we are thinking in the abstract mindset of the machine running instructions.

18:47 kaoD_: deterministic

18:47 ThatOneGuy: that's a good point too

18:48 ThatOneGuy: not sure if I said this yet, but booleans are as wide as your registers because if booleans aren't aligned, extra operations must be performed in CPU

18:48 mk: we don't need to talk about this at this level. A boolean value like true is never equal to an integer value like 1, or a byte value like 00000001.

18:49 kaoD_: mk: well, talk to C then

18:49 ThatOneGuy: can you guys answer a clojure question for me?

18:50 just a quick aside.

18:50 ToxicFrog: We can try!

18:50 ThatOneGuy: what is the difference between (some-fn another-fn) and (some-fn #'another-fn)

18:55 ?

18:55 aav: ThatOneGuy: another-fn will evolve to the function, bound to var names another-fn, and #'another-fn will evolve to var named another-fn

18:55 mk: kaoD_: I'm talking about C, and C doesn't try very much at all to have types or values

18:55 aperiodic: ThatOneGuy: the second thing references the var directly, so if later another-fn is redefined, it will still be using the old value

18:56 mk: kaoD_: watch the start of http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

18:56 ThatOneGuy: so when threading does either one work? and which is more idiomatic?

18:57 (-> another-fn some-fn some-fn2 some-fn3)

18:57 technomancy: ThatOneGuy: you would add the var indirection if you would want reloads to work

18:57 otherwise the function value is fixed at compile time

18:59 ThatOneGuy: so when that code is compiled it evals another-fn to whatever function it is and puts it in there. where as #'another-fn would eval to the var that could be rebound in the future?

18:59 technomancy: exactly

19:00 ThatOneGuy: I am mostly being confused by this function in clj-http https://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj#L456

19:00 well actually look at the function below it

19:00 because that is where it passes the #'core/request into the thread

19:00 dakrone: right as I push to the repo to mess up your lines numbers ;)

19:01 ThatOneGuy: really? wow what are the odds

19:01 corrected: https://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj#L459

19:02 technomancy: dakrone: are you sticking with that meta syntax explicitly for 1.1 support?

19:04 dakrone: technomancy: I only support 1.2 and up

19:04 is ^:foo added in 1.2? I thought it was added in 1.3

19:04 technomancy: yeah, you can use it in 1.2

19:04 dakrone: then I'll have to change that

19:04 technomancy: err--^{:key "value"} is in 1.2

19:04 hiredman: technomancy: no ^:foo is 1.3

19:05 technomancy: the only place I still see #^{:key "value"} is swank

19:05 dakrone: okay, that's what I thought

19:07 technomancy: anyway, you're safe to nix the #

19:09 dakrone: nixed

19:09 nicholasf: I'm only getting started with clojure. I'm writing a model class, and I find I keep stepping on the function names from clojure.core - e.g. count, find, get

19:09 what do people do in this circumstance?

19:10 is there like a convention for working around this, or do you just override the core functions in this namespace and use them explicitly whenever required there?

19:10 hiredman: nicholasf: don't make classes

19:10 nicholasf: er, sorry, this isnt a class

19:10 that was just a habit - it's not a type or a record

19:10 just a namespace

19:10 hiredman: nicholasf: clojure doesn't have "classes", so obviously not

19:11 ThatOneGuy: dakrone: if I do (client/get "google.com" {:cookies (cookies/get-cookies cs)}) the Cookie field in the headers is just an empty string. Bug? or incorrect sytax?

19:11 nicholasf: hiredman: so what's the convetion here?

19:11 e.g., my models.foo namespace wants to have a find method

19:11 a find function, rather

19:11 technomancy: nicholasf: use the clojure.core version of count, get, etc

19:11 don't define your own

19:12 nicholasf: technomancy: my version of count, get goes to mongodb

19:12 in this namespace

19:12 hiredman: :(

19:12 nicholasf: https://gist.github.com/fcb3dd33dc23aa7fbc61

19:13 so should tally be count, user-count, or tally?

19:13 Bronsa: you're missing a parenthesis in create

19:13 hiredman: several unhappy things, first of which is: why are people still using mongodb?

19:13 nicholasf: yeh, that's not the question

19:13 o ffs

19:13 forget I asked

19:13 clojurebot: excusez-moi

19:13 hiredman: nicholasf: count-users

19:13 nicholasf: hiredman: thanks

19:14 hiredman: user/count-users seems redundant as a DSL tho

19:14 hiredman: nicholasf: don't write a dsl

19:16 nicholasf: if you really want to write a dsl, the way to do it is not with many functions, it is with a data structure that describes an operation and a single function that interprets the datastructure

19:17 (q {:fetch-count :users}) and (q {:find {:users {:username username}}}) vs. what you have

19:18 but mongodb is dumb, so you'll need a pretty thick skin if you want to persist in using it

19:18 bpr: hiredman: mongodb is dumb in comparison to what?

19:19 or, if you'd rather answer: why is mongodb dumb?

19:19 hiredman: bpr: real databases people use

19:19 aperiodic: nicholasf: FWIW, i have a simple namespace that redefines get & set, that i only every require, never use. you can resolve the clashes with (:refer-clojure :exclude [...]) in that namespace's ns macro, and refer to them by fully qualifying the symbol if you need them

19:19 bpr: hiredman: haha

19:19 nicholasf: aperiodic: thanks mate - that sound spot on

19:19 aperiodic: nicholasf: it probably makes hiredman :(, but so do a lot of things ;)

19:19 hiredman: bpr: mongodb is the worst parts of the nosql movement with the worst parts of rdbms

19:24 timoxley: hiredman why

19:24 gfredericks: mongodb is webscale

19:27 hiredman: timoxley: the "solution" used to "scale" mongodb is the same as used to scale rdbms, namely sharding, but you throw away the years of engineering work that have gone in to a mature rdbms

19:28 * aav right at this moment migrates oracle based db to mongo

19:28 nicholasf: hiredman: that makes no sense

19:28 timoxley: hiredman mongo isn't an rdbms

19:28 hiredman: I am aware

19:28 nicholasf: you're saying that mongodb isnt worthwhile because it uses a similar scaling mechanism to an rdbms, so you shouldn't use mongodb

19:29 and that entirely precludes why you'd choose it over a rdbms

19:29 timoxley: hiredman how do you feel about similar tech like couch?

19:29 hiredman: nicholasf: if anything you should choose an rdbms over mongo because of the query language, the project maturity, etc

19:29 timoxley: couch is cute

19:30 technomancy: couch at least doesn't tune its out of the box settings to discard data in the case of failure just in order to come out looking better in superficial benchmarks =\

19:30 timoxley: technomancy cheap shot

19:31 they have explained that one over and over

19:31 anyway

19:31 * timoxley back to work

19:31 hiredman: couch, last I checked didn't have a good scaling story either

19:31 and was pretty slow, if I recall

19:31 technomancy: bigcouch supposedly implements dynamo on top of couch

19:32 hiredman: we used riak for a while at work, it was not pleasant, all kinds of issues, but that was some time ago

19:32 technomancy: but anyway couch doesn't make outrageous claims at being crazy fast and scalable

19:33 hiredman: my suggestion is to use a sql database (sharded or not, etc) unless you cannot

19:34 and for a new project there is no reason not to

19:35 sql is wonderful compared to shoveling around document store nonsense

19:35 http://static.lolyard.com/lol/key-value-store.png

19:35 to be fair we wrote our mapreduces in js

19:36 timoxley: hiredman rdbms wonderful for certain things, not so wonderful at others. use right tool for the job. rdbms is not a silver bullet.

19:38 aav: hiredman: how would you store documents of arbitary structure in rdbms? implement key-value store on top of it?

19:38 hiredman: aav: it depends

19:38 timoxley: sure

19:38 timoxley: hiredman and don't be so quick to bury something. I learned a lot of new techniques for working with denormalised data by using mongo that I'd have never got using a sql db

19:39 hiredman: I am not quick to bury it

19:39 timoxley: just for that on its own was worth it.

19:39 hiredman: timoxley: *shrug* it may be worth something as a teaching tool, but not as a datastore

19:41 I am not advocating singgle system of record style rdbms, I think the best thing to come out of nosql is the acceptance of fragmented federated data storage

19:41 and picking data storage for the job not, not the other way around

19:41 bpr: i would agree with that

19:41 hiredman: that being said, sql databases offer a lot of great things that most (all?) nosql stores lack

19:42 aav: hiredman: would you agree that for some jobs mongo is the right choice?

19:42 hiredman: like real proper transactions (for some sql dbs and sort of okish, still better than nothing for others)

19:43 timoxley: "real"

19:43 hiredman: aav: if you are storing data for the local boy scout troupe

19:43 aav: hiredman: got your point :)

19:44 hiredman: even then I would look in to rds from amazon

19:44 aav: hiredman: for my scouts, external data service is not an option

19:45 hiredman: aav: no cloud computing merit badges?

19:46 aav: hiredman: they are very paranoid about their data :) lot's of secrets, you know... :)

19:56 hiredman: it's not very easy. if I say - i need an rdbms - i would not be allowed to take, postgres, or mysql. because, there is _official_ rdbms - oracle, and hopless IT who is in charge of it. and if I say, that i'm using some special data storage for documents, which is not, even a database - it's no problem.

19:58 stain: hihi

20:13 TimMc: hiredman: People "actually use" mongo. I don't think you want to use that as an argument one way or another, though.

20:14 * emezeske coughs out something about PHP.

20:52 * gfredericks just found out that zero? is not the same as #(= 0 %)

20:52 Raynes: &(zero? "0")

20:52 lazybot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

20:52 Raynes: gfredericks: Is that what you mean?

20:52 amalloy: gfredericks: #(== 0 %), then?

20:53 xeqi: &(doc zero?)

20:53 lazybot: ⇒ "([x]); Returns true if num is zero, else false"

20:53 gfredericks: yeah

20:53 ah it has "num" in the docs

20:53 Raynes: &(== 0 "0")

20:53 lazybot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

20:53 xeqi: &(= 0 0M)

20:53 lazybot: ⇒ false

20:54 Raynes: &(== 0 0M)

20:54 lazybot: ⇒ true

20:54 gfredericks: &(time (remove zero? (repeat 100000 0)))

20:54 lazybot: ⇒ "Elapsed time: 234.916051 msecs" ()

20:54 Raynes: Pop goes the weasel.

20:54 gfredericks: &(time (remove #(= % 0) (repeat 100000 0)))

20:54 lazybot: ⇒ "Elapsed time: 226.450155 msecs" ()

20:55 gfredericks: &(time (remove #(= % 0) (repeat 10000000 0)))

20:55 lazybot: ⇒ "Elapsed time: 252.81306 msecs" ()

20:55 gfredericks: oops

20:55 xeqi: &(time (remove (partial = 0) (repeat 1000000 0)))

20:55 lazybot: ⇒ "Elapsed time: 260.826661 msecs" ()

20:55 gfredericks: &(time (pr-str (remove zero? (repeat 100000 0))))

20:55 lazybot: ⇒ "Elapsed time: 487.911061 msecs" "()"

20:55 gfredericks: &(time (pr-str (remove #(= % 0) (repeat 100000 0))))

20:55 lazybot: ⇒ "Elapsed time: 340.684657 msecs" "()"

20:55 gfredericks: oh weird

20:56 so never use zero? for anything must be the lesson

20:57 xeqi: &(source zero?)

20:57 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

20:58 gfredericks: $source zero?

20:58 lazybot: zero? is http://is.gd/8YNLhA

20:59 gfredericks: I love that it appears right under the "sequence fns" heading

20:59 Raynes: $examples zero?

20:59 lazybot: You must pass a name like clojure.core/foo or, as two arguments, clojure.core foo.

20:59 Raynes: $examples clojure.core/zero?

20:59 lazybot: https://www.refheap.com/paste/3976

21:00 Raynes: One day I hope I'll learn to use this bot.

21:00 xeqi: $examples clojure.core/juxt

21:01 lazybot: https://www.refheap.com/paste/3977

21:01 aperiodic: where do those examples come from?

21:01 xeqi: ah, it queries clojuredocs

21:01 aperiodic: why not just link to clojuredocs?

21:01 xeqi: I was hoping for some sort of fancy test.generative data set generation

21:02 Raynes: aperiodic: I'm not sure if gives a link to clojuredocs.

21:02 aperiodic: But refheap is cooler.

21:02 if cd-client*

21:03 aperiodic: Raynes: it doesn't link back, even

21:03 Raynes: Is there any legal obligation to give credit?

21:04 * gfredericks sues lazybot

21:04 Raynes: frrl

21:05 aperiodic: Raynes: no legal obligation, no. i think it's crummy to take their examples and not even link back, especially since it means it's not apparent that you can add to/improve those examples

21:06 Raynes: aperiodic: It's an open source project, btw.

21:06 https://github.com/flatland/lazybot

21:06 aperiodic: Raynes: ok, expect a path in your near future

21:06 *patch

21:06 Raynes: Appreciated!

21:06 amalloy: "expect a path in your near future" sounds like a fortune cookie

21:07 Raynes: If cd-client gives a link clojuredocs, I'm fine with just using that link rather than refheaping it. I only recall it giving me the examples themselves though, but I certainly could be wrong.

21:08 So it may very well be that I'm not an asshole and cd-client is an asshole instead. If so, we can just add a "From clojuredocs" to the paste.

21:09 aperiodic: well, i will do my darndest to have it provide a link back to the relevant examples, one way or the other

21:30 TimMc: cd-client had better build the links for you; clojuredocs does its own symbol munging to build doc URLs

22:55 dakrone: Raynes: I believe the cd-client method returns a map with a :url key

23:23 Raynes: dakrone: Awesome

23:59 ro_st: so i'm using goog-jar for my clojurescript project. how do i get a more up to date version of the google library than what's in goog-jar?

Logging service provided by n01se.net