#clojure log - Sep 11 2013

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

0:00 clj_newb_2345: how do I get clojure.edn ?

0:00 what line do I need to add to my lein project.clj ?

0:00 bbloom: nothing

0:00 clj_newb_2345: clojure.edn/read-string is NOT available at my repl

0:01 bbloom: so (require 'clojure.edn)

0:03 clj_newb_2345: (worked now

0:03 thanks :-)

0:10 one more dumbass question: what is the clojurescript counterpart to edn?

0:13 amalloy: c'mon, clj_newb_2345, that is not hard to google

0:13 clj_newb_2345: actually, "clojurescript edn" brings up surprisiiiiogly little documentation

0:13 dnolen: clj_newb_2345: what counterpart is needed. EDN is like JSON

0:14 bbloom: let's play bbloom's favorite game!

0:14 dissipate_: amalloy, i thought #clojure was google?

0:14 bbloom: it's called: "Have you tried grep?"

0:14 clj_newb_2345: bbloom: what would I grep for?

0:14 what code base would I grep over?

0:14 bbloom: git clone github.com/clojure/clojurescript

0:15 considering clojure.edn is baked in to your repl, the primary repository is a good guess

0:16 clj_newb_2345: your suggestion is not completely unreasonable

0:16 sdegutis: Thanks

0:16 bbloom: clj_newb_2345: i'll give you one more hint: try "defn" is a likely hit

0:17 dnolen: although now that i mention it, we probably should have a clojure.edn namespace in cljs

0:17 dnolen: trying to bring clj & cljs closer together

0:17 coventry`: clj_newb_2345: google(clojurescript intext:edn) is the trick.

0:17 dnolen: bbloom: perhaps, but that's more churn, cljs.reader predates clojure.edn

0:18 bbloom: dnolen: grumble grumble. who does that rich hickey guy think he is using a different namespace than the cljs team :-)

0:19 xeqi: if only there was a nice plugin to a build tool to paper over the differences with feature expressions

0:20 bbloom: :-/

0:20 dissipate_: bbloom, you realize these issues would go away if there was a pure clojurescript framework that allowed you to put client and server code in the same file? look at the opa framework.

0:20 * sdegutis is excited about this new quick project and can hardly contain it

0:21 dissipate_: "Write simultaneously the frontend and backend code, in the same language, within the same module. Even better: the Opa Slicer automates the calls between client and server. No more manually written AJAX calls or value serialization!"

0:21 but we can't have nice things because running javascript server side is blasphemy!

0:22 bbloom: you've totally misunderstud the goals and tradeoffs selected for clojurescript

0:26 xeqi: dissipate_: while I haven't seen anything that chooses where to run the code for you, there are libs to make the http calls hidden, like shoreleave

0:26 or pedestal

0:27 dissipate_: xeqi, that's certainly an improvement

0:27 coventry`: The study required to understand pedestal would leave no time for trolling.

0:30 dissipate_: coventry`, hmm, and what's the payoff for all that study?

0:32 xeqi: bbloom: I was refering to https://github.com/lynaghk/cljx incase there was any confusion

0:32 coventry`: Anyone got ready-made code for walking a tree and changing one symbol to another where ever it appears?

0:32 bbloom: xeqi: i'm familiar with it

0:33 dnolen: dissipate_: I think the value proposition of things like are Opa (similarly Meteor) are grossly overstated

0:35 dissipate_: dnolen, seems good for rapid prototyping in any event, no?

0:36 dnolen: dissipate_: doesn't look any worse or better than ClojureScript in that regard IMO

0:39 dissipate_: actually reading over the docs, it looks worse - but of course it's always hard to say w/o actually using. Doesn't seem to have a good async story outside of the small part of many apps that is client/server comm

0:43 coventry`: Why is there zip/vector-zip as well as zip/seq-zip? Is it faster?

0:45 dissipate_: dnolen, i wouldn't use opa. the database stuff is way too heavily integrated and seems to promote accessing the database wherever you please.

0:46 coventry`: Is loop the best way to walk a tree with zip, as in the examples at http://clojure.org/other_libraries#Other%20included%20Libraries-Zippers%20-%20Functional%20Tree%20Editing%20(clojure.zip) ?

0:47 dissipate_: good god, someone needs to fix those URLs.

0:47 Pupnik_: its just irc

0:49 dissipate_: coventry`, http://bit.ly/14E0MYX you are welcome

0:50 bbloom: coventry`: recur is definitely the way to go with zippers b/c that's kinda half the point of them

0:50 coventry`: zippers reify the context of your traversal as a data structure.

0:50 coventry`: generally, that context is stored in your program's evaluation stack!

0:52 coventry`: bbloom: Got it, thanks. It just looks ugly, but not as ugly as traversing the tree myself, and easier than writing inner and outer functions for walk.

1:16 amalloy: bbloom: i dunno, lazy-seq functions seem to work pretty well with zippers

1:17 bbloom: amalloy: sure, capturing the context for delayed (or repeated) execution is the other half the point :-)

1:33 clj_newb_2345: does clojure have a built in binary tree? i.e. I want a sorted list of items where I can do insertion / deletion in logn time

1:33 I don't think vectors provide this, as they tend to be O(n) time insert/delete

1:34 bbloom: (doc sorted-set)

1:34 clojurebot: "([& keys]); Returns a new sorted set with supplied keys. Any equal keys are handled as if by repeated uses of conj."

1:35 bbloom: it's built on a persistent red black tree

1:35 clj_newb_2345: this doesn't seem to support (insert after n/2-th element)

1:35 so I'm trying to mirrot the DOM tree

1:36 actually, now that I think about it

1:36 what I really want is a doubly linked list

1:37 since why do I want O(log n_) time insert/delete when I can have constant time insert/delete ?

1:37 bbloom: clj_newb_2345: b/c you get to keep persistence and the tree's generally shallow enough to be amortized constant

1:39 clj_newb_2345: hm

1:39 so what is the "correct" way to mirror a dom tree

1:39 dom trees have the notion of NodeList

1:39 bbloom: it's impossible to have a doubly linked list that is also fully persistent w/ structural sharing. not that that means there is never a use for a double linked list, but it's highly unlikely you need that compared to a persistent structure

1:39 how could there possibly be a "correct" way? different representations make different trade offs

1:39 clj_newb_2345: I think I can get away with a zipper, since I only walk up/down the list one item at a time

1:40 so I have a representation, which is: left: list of nodes, right : list of nodes, cur : current node

1:40 where "left" is stored in reverse order

1:40 dissipate_: bbloom, what about a sorted map?

1:42 bbloom: gotta run

1:42 dissipate_: clj_newb_2345, http://clojuredocs.org/clojure_core/clojure.core/sorted-map

1:50 Raynes: amalloy: Answer to why lazybot was down: because f*** you, that's why.

2:25 fredyr: ls

2:25 lazybot: boot home lib lost+found media mnt opt proc root sbin selinux srv swap sys

2:25 fredyr: :o

2:25 sry seems like i'm tired, mixing up the windows

2:42 andyfingerhut: Do you know if/how Clojure+Ring+Compojure web servers with multiple instances share session state between them? Or do they rely on load balancers that usually cause same client to go to same server?

2:48 fredyr: i don't know how it is done w/ ring/compojure, but there are a couple of common choices

2:48 first as you said, you can have sticky sessions

2:49 or otherwise a shared session cache of some kind

2:49 usually database backed or a distributed cache like memcached

2:50 andyfingerhut: fredyr: Thanks. Do you know which events typically cause that session cache to be updated? i.e. would it pretty much need to be updated on every user request?

2:55 fredyr: don't really think that's needed

2:56 SegFaultAX: I had bangers and mash for dinner... and it was amazing. Just saying.

3:00 fredyr: andyfingerhut: to answer your question, no i don't really know specifically for ring

3:02 andyfingerhut: fredyr: Thanks. Haven't done any web dev before, and just learning a little bit about it. Bought Dmitri Smotnikov's new Web Development with Clojure book and going through that.

3:04 fredyr: nice

3:04 i'm sure you'll get better answers once the americans wake up also

3:04 :)

3:12 s4muel: andyfingerhut: the basic idea is that yes, you wrap your application handler in ring's wrap-session, essentially just a handler fn that reads the :session for a request. you update it by sending (an updated copy of) the :session back in the response

3:13 check out the ring wiki, there's a whole page on it. in terms of session storage, there's stuff built into ring, and whatever your app server might provide too (for larger stuff).

3:19 andyfingerhut: s4muel: Thanks. So ring by default will use an in-memory session store. That is sufficient if you have a single web server, I can see. fredyr mentioned memcached or a database as a potential storage for session state if you have many web servers. Do you know how often such a session store is updated typically?

3:28 SegFaultAX: andyfingerhut: It really depends on the application. Session can be used for all kinds of stuff.

3:28 Server-side memory store and cookie stores are quite common.

3:29 Typically the main thing in there is the identifier for a user (perhaps the primary key on the users table)

3:29 But other information you might want to cache could be in there. Stuff you access often that changes slowly.

3:30 clj_newb_2345: does clojurescript support "format" ?

3:30 i.e. the clojure format command

3:31 andyfingerhut: If the web app implemented a "shopping cart", and the user could add another item to it with every request, would that typically be implemented by putting the shopping cart items in the session, or in some database that was accessed via the user id?

3:32 fredyr: clj_newb_2345: it does

3:34 clj_newb_2345: fredyr: what namespace is it in, what is it called?

3:35 SegFaultAX: andyfingerhut: In the database.

3:35 fredyr: clj_newb_2345: i believe it's straight in core

3:35 ,(format "%.3f" 2.0)

3:35 clojurebot: "2.000"

3:36 clj_newb_2345: in clojurescript ...

3:36 fredyr: yeah, but i believe it is the same in clojurescript

3:36 it uses goog.string instead of the java.lang.String though

3:37 SegFaultAX: andyfingerhut: Generally don't trust highly valuable data to something that isn't persisted.

3:37 andyfingerhut: If the server crashed, for example, you'd lose your shopping cart.

3:38 andyfingerhut: Furthermore when using cookies as your session store, don't store anything private or really anything at all of value.

3:38 andyfingerhut: Makes sense. Wasn't sure how "highly valuable" shopping cart data is, but it certainly would annoy customers if they were lost a noticeable fraction of the time.

3:39 SegFaultAX: andyfingerhut: A good rule of thumb is to never put anything in the session that can't be resurrected from the primary data store.

3:39 andyfingerhut: In memory session stores also have some other rather important problems to consider.

3:52 ddellacosta: how do I access a protected member within a gen-class method (fn) definition? I've tried (.member this) and it says that it doesn't exist…is it even possible?

3:56 tomjack: can I do `lein new $NAME` if $NAME is two letters long?

3:57 fredyr: tomjack: $ lein new ts

3:57 Generating a project called ts based on the 'default' template.

3:58 tomjack: I should have explained the question better, but wasn't sure how to

3:58 I know it works, I mean I would feel like an asshole pushing that to clojars

3:59 SegFaultAX: Just give it an artifact group.

3:59 com.tomjack/fu

3:59 tomjack: ok

3:59 fredyr: you should probably include `core` somewhere also

3:59 tomjack: but (ns fu.ba) ?

3:59 fredyr: :)

4:00 SegFaultAX: Also, I laughed at this so hard: https://github.com/mperham/sidekiq/blob/master/lib/sidekiq.rb#L25

4:00 I don't know why.

4:00 tomjack: so we stick to RDN for GAV, but in ns's?

4:01 er, "reverse-dns"?

4:02 * ucb waves

4:06 * SegFaultAX waves back to ucb

4:07 * ddellacosta waves to alls y'alls

4:08 ddellacosta: SegFaultAX: that ruby method is hi-larious

4:09 SegFaultAX: ddellacosta: Yup

4:18 ucb: SegFaultAX: heh that made me chuckle

4:18 just finished listening to This is Water by DFW, so I'm in a gloomy/pensive mode. Otherwise I would've really laughed at that method :)

4:19 muhoo: that's an amazing lecture

4:21 ucb: muhoo: yeah. I only recently came across the audio.

4:22 muhoo: i've never seen a video of it, just the audio.

4:22 i discovered when he died. so sad that he was so ill. brilliant guy.

4:23 ucb: indeed

4:23 I don't think I've ever witnessed so much clarity packed in such a small amount of time

4:23 SegFaultAX: ucb: Link?

4:24 ucb: SegFaultAX: https://dl.dropboxusercontent.com/u/1640144/This%20Is%20Water%20by%20David%20Foster%20Wallace%20Full%20Speech-PhhC_N6Bm_s.mp4

4:24 SegFaultAX: Thanks!

4:24 ucb: no worries

4:24 muhoo: also here, looks like http://www.youtube.com/watch?v=8CrOL-ydFMI

4:26 ucb: muhoo: I made a copy just in case :)

4:28 SegFaultAX: muhoo: The number of views on that video is pissing me off.

4:28 65,534

4:28 fredyr: hah

4:29 ucb: ODD kicks in it seems

4:29 muhoo: odd?

4:30 ucb: (see what I did there?)

4:33 ddellacosta: I cannot get :exposes-methods working at all in gen-class. What is the meaning/order of the arguments in that hash-map?

4:33 it's not clear to me which is the name of the parent method I want to expose, and it's not clear what the other arg is meant to be, or where it occurs

4:33 muhoo: know what pisses me off?

4:34 ,(let [foo (atom {})] (-> 1 @foo :ugh))

4:34 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$deref>

4:34 muhoo: uh, i'm only passing 1 arg to deref

4:35 clgv: muhoo: no you are not.

4:35 muhoo: (-> 1 blah) passes only one arg, which is 1, to blah

4:36 clgv: muhoo: @foo expandes to (deref foo)

4:36 muhoo: ,(doc ->)

4:36 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

4:36 ucb: muhoo: shouldn't it be (-> 1 (blah)) ?

4:36 clgv: ,(read-string "@foo")

4:36 clojurebot: (clojure.core/deref foo)

4:36 clgv: muhoo: hence you get ##(read-string "(-> 1 @foo :ugh)")

4:36 ucb: e.g. (-> 1 (@the-ref) :ugh)

4:36 muhoo: clgv: ah, macro expansion

4:36 lazybot: ⇒ (-> 1 (clojure.core/deref foo) :ugh)

4:37 ucb: ,(let [a (atom {})] (-> 1 (@a) :ugh))

4:37 clojurebot: nil

4:37 ucb: right

4:37 muhoo: surprising

4:37 ucb: ,(let [a (atom {1 {:ugh :yay}})] (-> 1 (@a) :ugh))

4:37 clojurebot: :yay

4:37 ucb: there

4:37 clgv: muhoo: no. not normal macro expansion. it is a reader macro so to say

4:39 muhoo: thanks, makes a bit more sense now.

4:48 SegFaultAX: ucb: Wow

4:48 That was awesome.

4:48 ucb: SegFaultAX: INORITE

4:49 SegFaultAX: I'm going to listen to it again tomorrow.

4:49 That was awesome.

4:49 ucb: I just did today :)

4:49 SegFaultAX: Thanks for sharing.

4:49 ucb: it's one of those things I like to do periodically, just to remind myself of the awesomeness

4:49 no worries, glad you liked it

4:49 SegFaultAX: On that note, I must sleep.

4:49 Night all.

4:49 ucb: night

4:50 supersym: good morning :)

4:50 clgv: ucb: what is he talking about? ;)

4:51 ucb: clgv: DFW's "This is Water" speech

4:51 DFW = David Foster Wallace

4:51 muhoo: a man of infinite jest

4:54 clj_newb_2345: the following is almost certainly a bad idea, but I want to try it anyway

4:55 is there a way I can setup to have "(refresh)" called once every second

4:55 (refersh is referring to clojure.tools.namespace/refresh)

4:55 actually, I want it to be sent over emacs

4:55 whenever I do a write

4:56 clgv: clj_newb_2345: fire up a future with an infinite loop that Thread/sleep for a second and then calls refresh

4:56 clj_newb_2345: yes, this is what I wnat: to add in a hook to my emacs, so that on every write, it sends nrepl a "(refresh)"

4:56 no, I no longer want one per second

4:56 I'd like it to work via emacs write hook

4:56 or something like cljsbuild

4:56 to monitor that when a *.clj file has been modified

4:56 supersym: use a watcher

4:56 clgv: cant help you there. I have no knowledge about elisp and emacs internals ;)

4:57 supersym: me neither, I'd use a watcher for that in pedestal

4:57 clj_newb_2345: https://github.com/derekchiang/Clojure-Watch ?

4:57 actually, this was moditivated by pedestal

4:57 how does pedestal do it?

4:57 supersym: let me have a look

4:58 schmir: clj_newb_2345: take a look at https://github.com/schmir/.emacs.d/blob/master/setup-clojure.el, it may help you with executing code from emacs

4:58 clj_newb_2345: if you don't mnind, could you (1) refactor the code, (2) post it to git up, and (3) add it to clojars so I can just add it to my project.clj :-)

4:58 supersym: https://github.com/konrad-garus/pedestal-routing/blob/master/dev/dev.clj#L82

4:59 ddellacosta: I cannot get this to work: http://stackoverflow.com/questions/9060127/how-to-invoke-superclass-method-in-a-clojure-gen-class-method, any ideas? I just keep getting exceptions like "No matching field found: bar for class foo."

4:59 clj_newb_2345: most likely a type issue

4:59 i.e. clojure won't auto convert a char to a int for you

5:00 so if it expects an int, and you pass it a char, it "can't find the function"

5:01 ddellacosta: clj_newb_2345: are you responding to me?

5:01 supersym: ddellacosta: did you lein compile?

5:01 ddellacosta: supersym: yes.

5:01 supersym: I've been going to the extreme of deleting the class files to make sure that's not it, but anyways, my exceptions change so I'm pretty sure it's unrelated anyways.

5:02 supersym: ah

5:02 ddellacosta: this further adds to the confusion: http://dev.clojure.org/jira/browse/CLJ-1027?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel#issue-tabs

5:02 supersym: I had that last part all too often as well

5:02 clj_newb_2345: https://github.com/ibdknox/watchtower + (refresh) should suffice

5:02 ddellacosta: just really not sure how this is supposed to work, but at this point I've tried all sorts of variations, so I'm deeply perplexed.

5:03 supersym: http://stackoverflow.com/questions/3318671/clojures-gen-class-and-double-arrays

5:03 ucb: ddellacosta, supersym, clj_newb_2345: you have to keep in mind that tools.namespace/refresh doesn't play nice with aot

5:03 ugh

5:03 wrong context probable

5:03 probablY

5:03 clj_newb_2345: ucb:ucb: why do I want gen-class / aot ?

5:03 supersym: its not exactly what your problem is, but that should help you check a few things

5:03 ucb: yep :)

5:03 ucb: clj_newb_2345: I'm not saying you do; I just barged in a conversation and made an arse of myself.

5:04 clj_newb_2345: hmm

5:04 supersym: that I know as well

5:04 clj_newb_2345: does "file system watchers" basically just poll ?

5:04 or do they something clever and get push notifications from the OS?

5:06 ddellacosta: supersym: hmm, thanks but not sure this is going to help--I'm having trouble just deciphering how to get access to a parent's protected method. It seems like I'm not successfully exposing it, even using expose-methods. I can successfully create and override methods otherwise, however--there's no issues there.

5:09 clj_newb_2345: hmm, can (refresh) only be called from the lein repl>

5:09 Exception in thread "Timer-0" java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set at clojure.lang.Var.set(Var.java:233) at clojure.lang.RT$1.invoke(RT.java:239)

5:10 ddellacosta: oh, fer #$!@s sake, I forgot to pass the right args into the parent method

5:10 * ddellacosta slaps himself in the head for not looking at the damn method arguments for an hour

5:12 supersym: :)

5:14 dissipate_: can someone explain why you need the 'apply' function in this: https://www.refheap.com/18531

5:14 why not just '+' without the 'apply'?

5:15 TEttinger: dissipate_, numbers is a collection

5:15 fredyr: ,(+ [1 2 3 4])

5:15 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentVector to java.lang.Number>

5:15 fredyr: ,(apply + [1 2 3 4])

5:15 clojurebot: 10

5:17 ddellacosta: omg…could it really be…working…? Is it true??

5:17 lazybot: ddellacosta: Definitely not.

5:17 * ddellacosta sobs tears of joy

5:17 ddellacosta: lazybot: you are one tough customer.

5:17 way to be a downer, you damn bot

5:18 * ddellacosta sticks out tongue at lazybot

5:18 dissipate_: TEttinger, I see, thanks

5:19 TEttinger: fredyr thanks for the example

5:19 np dissipate_

5:19 fredyr: np

5:48 sdegutis: So, I got pretty far in my Lisp interpreter tonight. Now I'm stuck at the hard part.

5:48 Scoping.

5:49 For anonymous functions, it's confusing since there's 2 scopes, the calling scope and the definition scope, and I don't understand how lookups are split between these two. How does Clojure do this?

5:50 Maybe it's just as simple as putting the definition scope at the tail of the calling scope's parent-chain.

5:53 jjttjj``: +

5:54 sdegutis: jjttjj``: ?

5:54 fredyr: sdegutis: you just merge them together into one env

5:55 sdegutis: fredyr: Okay. And the caller-env should have precedence, right?

5:55 fredyr: right, shadowing bindings that are in both

5:55 sdegutis: So in Clojure it would be (merge definition-env caller-env)

5:55 Cool.

5:55 jjttjj``: sdegutis: ignore that

5:56 sdegutis: jjttjj``: I'm trying!

5:57 fredyr: sdegutis: have you looked at paip? the environment stuff is explained pretty good there

5:58 sdegutis: http://norvig.com/paip.html ?

5:58 fredyr: yes

5:58 sdegutis: fredyr: nope, will check it out, thanks

5:58 fredyr: sure

5:59 i implemented a (very!) basic scheme interpreter in clojure over the summer based on that

6:00 sdegutis: fredyr: on github?

6:00 fredyr: nah

6:00 but its like 40 loc

6:00 so i can put it in a gist

6:00 if you want

6:00 sdegutis: that'd be really nice of you :)

6:03 fredyr: https://gist.github.com/fredyr/6521407

6:03 here u go

6:03 sdegutis: Woo, thanks :)

6:04 fredyr: oh, i see now that i used a ref instead of an atom for the global env :S

6:04 so disregard that if you please

6:04 * sdegutis has a really stupid interpreter at https://github.com/sdegutis/Beowulf/tree/master/Beowulf with tests at https://github.com/sdegutis/Beowulf/blob/master/BeowulfTests/BeowulfTests.m

6:04 sdegutis: fredyr: heh will do

6:06 fredyr: looks nice

6:06 sdegutis: fredyr: heh, you name things like i do.. "maybe-add"

6:07 fredyr: oh i think that one might be courtesy of Norvig though

6:07 sdegutis: ah

6:07 fredyr: but i do like it anyways

6:08 begin is like do in scheme

6:08 and just as in clojure you have an implicit begin inside of lambdas

6:08 sdegutis: right

6:10 fredyr: your lambdas never get a called-at-env, they only house the defined-at-env

6:11 fredyr: isn't (ext-env parms args env) exactly that?

6:11 env is the called-at

6:12 and parms+args is defined-at

6:12 or maybe i'm misunderstanding

6:13 sdegutis: fredyr: the 'env' (last arg of ext-env) that you just mentioned is only bound as the second arg to interp

6:14 and in this case, the call to interp is where the lambda is defined.

6:14 fredyr: but called-at-env is the global-env at the top level

6:15 and if you have lambdas inside lambdas you get extended local versions

6:16 sdegutis: fredyr: well i could be mistaken, but i think you're mistaken

6:16 either way, it's not that important :)

6:16 fredyr: i don't think i understand what you mean exactly

6:17 but it's entirely possible i'm wrong

6:17 sdegutis: im not 100% sure i do either.

6:18 fredyr: what i was trying to say earlier, but wasn't very clear, is that the lambda code is interpreted with env bound to the extended env

6:18 sdegutis: all i can say is, i think your code will probably fail with this code: (((lambda (x) (lambda (y) (+ x y)) 1) 2)

6:18 right

6:18 sanity check: ##(+ 1 2)

6:18 lazybot: ⇒ 3

6:19 sdegutis: sanity check: ##(((fn [x] (fn [y] (+ x y))) 1) 2)

6:19 lazybot: ⇒ 3

6:19 sdegutis: ok just making sure

6:19 ,(((fn [x] (fn [y] (- x y))) 1) 2)

6:19 fredyr: right, i see your point

6:19 clojurebot: -1

6:19 * sdegutis is just testing the bots

6:19 sdegutis: fredyr: dont mind me :)

6:19 fredyr: but i think the key here is that the lambda gets interpreted with (interp code (ext-env parms args env))

6:20 sdegutis: fredyr: i think your solution might work on account of it being mutable.

6:20 i havent ran it though..

6:20 fredyr: i'm about to

6:20 :)

6:20 i wanna test your let w/ lambda construct

6:23 sdegutis: you mean ##(((fn [x] (fn [y] (+ x y))) 1) 2) ?

6:23 lazybot: ⇒ 3

6:23 sdegutis: my goal is to get that working right now, God help me.

6:25 fredyr: thankfully, it works like a charm!!

6:26 i updated the gist

6:27 sdegutis: fredyr: woot

6:27 fredyr: i cant say i fully understand how

6:27 fredyr: but on the other hand, i also cant say im capable of understanding how at this hour

6:28 fredyr: :)

6:30 sdegutis: yay i got it working

6:31 not sure my solution is super good but whatever

6:31 fredyr: cool

6:31 sdegutis: https://github.com/sdegutis/Beowulf/blob/master/Beowulf/BWFunction.m#L17-L20

6:31 and https://github.com/sdegutis/Beowulf/blob/master/Beowulf/BWEnv.m#L40-L45

6:32 im not 100% sure right now that envs need parents, but i vaguely think they probably should seeing as im setting them in some places.

6:32 clj_newb_2345: when a blah.clj file is reloaded, does its old go-blocks get killed?

6:32 or do they continue to run?

6:34 sdegutis: clj_newb_2345: refheap.com it

6:42 sandbags: if i'm just html scraping is there an advantage to using enlive over clj-tagsoup?

6:42 wei_: I'm having trouble reading json POST params server-side. the params appear as an InputStream under :body in the request map, but when I read with slurp it's empty. any ideas?

6:42 sandbags: they're the two options (even if i think enlive is actually built on tagsoup) that seem to come up most often searching for clojure html scraping

6:45 cgrand: sandbags: enlive defaults to tag soup but you can opt for jsoup

6:45 sandbags: cgrand: ah, the author himself :)

6:46 i get the feeling enlive is a complete solution

6:46 for parsing & templating

6:46 right now i'm definitely still a newbie so, in general, trying to reduce complexity of what i'm doing

6:47 would you recommend clj-tagsoup (or jsoup) as a simpler alternative for the single use-case?

6:48 cgrand: (-> "http://..." e/html-resource (e/select [:#some-id])) to scrape a specific id

6:48 sandbags: hrmm... that does look enticingly simple :)

6:48 sold

6:48 cgrand: sandbags: you d'ont have to learn the template stuff (which is 90% of enlive) to scrap

6:49 sandbags: yeah my concern was mostly about separating the two concerns but your example is pretty compelling :)

6:49 thanks

6:49 clgv: clj_newb_2345: very likely they continue running, except there is some special implementation for that exact case in the lib

7:01 sandbags: for a tool i am writing that i'll be putting on github i need a way of configuring a username/password and some other details (but the creds are the reason).. i'm thinking the easiest approach is to use an EDN file containing a configuration map. is there anything better?

7:02 sdegutis: fredyr: what do you think of macro scopes? they should probably have the same kind of scoping rules as lambdas, right?

7:04 clgv: sandbags: define "better"! maps are used in leiningen for config as well

7:05 sandbags: clgv: i suppose by better i mean, more standard, more appropriate, "the clojure way" if that helps

7:05 clgv: sandbags: having config in maps is a clojure way

7:05 sandbags: but, thinking about it, i guess project.clj is just a map

7:05 oh wait

7:05 no a function call

7:05 clgv: yes it is

7:05 sandbags: :)

7:05 clgv: some macro magic for convenience

7:06 sandbags: but in my case a map would work fine... i guess i was just looking to see if there were shreaks of "No! No! You must do XYZ instead!" :)

7:06 thanks clgv

7:06 wakeup: hi

7:06 :)

7:06 clgv: if there are no special requirements just go for config map. since you do not have to implement anything additional for that you can easily change when requirements for the config are introduced

7:07 sandbags: ^^

7:07 sandbags: clgv: thanks

7:08 here's something i'm having trouble googling up... if i want to package some of my own code as a private library and include it via project.clj

7:09 wakeup: Is there something like GNU readline (but with an LGPL/MIT license) available to clojure?

7:09 sandbags: is that possible, without publishing to clojars or maven?

7:09 clgv: sandbags: you can set up a privaten maven repository

7:10 sandbags: clgv: will i find myself clawing my eyes out long before i have a working solution? (I hear nothing much good about maven)

7:10 clgv: sandbags: I had success with "Apache Archiva". I also heard that "Artifactory" works

7:10 sandbags: i guess i was hoping there was a project.clj short-hand for "find library in ~/blah"

7:11 clgv: sandbags: no eyes clawing here, but I invested 2-3 hours to set it up

7:11 sandbags: do you have only one development machine?

7:11 sandbags: two

7:11 clgv: sandbags: well. then you will need a private repository

7:11 sandbags: well i can easily put the code in Dropbox

7:12 i mean, i might just do that and symlink it into these projects

7:12 since i suspect 2-3hr for you might be a monumental yak shaving party for me

7:12 clgv: not necessarily, since I did not use anything like that before.

7:13 sandbags: or i guess, i suppose, i could just put it on clojars and endure the shame of anyone ever reading it :)

7:14 clgv: sandbags: just have a look at the "apache archiva" page to see if it might be easy enough to setup

7:15 sandbags: (reading that now, thanks)

7:15 clgv: and maybe also the artifactory one

7:35 wakeup: Maybe a little OT: Imaine a propritary application, which includes a shell script that contains a pipeline like like 'somegplprg | somepropritaryprog'. Is that violating the GPL?

7:39 jamii: I would have expected this to work: (case (class 1) java.lang.Long :ok)

7:40 Since (identical? java.lang.Long (class 1)) => true

7:41 vijaykiran: wakeup: In your proprietary app do you bundle the GPL program ?

7:41 jamii: Ah - https://groups.google.com/forum/#!topic/clojure-dev/AB6A9u7ohSc

7:43 sm0ke: hello, i am just fresh to clojure and lisp in general. I am having hard time figuring out what to write in place of what i used to write in oop langs? For E.g. ..

7:43 An api which creates a object with some vals and then invoke functions on it?

7:44 ucb: sm0ke: can you be more concrete?

7:45 sm0ke: umm i am not sure... its hard to figure out where to start when all i have is functions!!

7:46 is defining records equivalent to oop in clojure?

7:46 ucb: sm0ke: you'll probably want to forget about oop for a while while you learn clojure

7:47 just think in terms of functions that operate on data structures

7:47 and you'll be fine :)

7:49 sm0ke: thanks... thats a start

7:50 TEttinger: sm0ke, have you seen 4clojure? good way to start

7:50 4clojure and clojuredocs

7:52 sm0ke, if you don't have it already, https://github.com/technomancy/leiningen is vital to clojure dev :) handles projects and can be used for all sorts of related things as well

7:52 sm0ke: TEttinger: i think i have some basic knowledge of clojure.. But my question is more about software design patterns!

7:52 TEttinger: ohhh

7:53 sm0ke: sounds boring but..i bet there must be some standard way to write clojure system

7:54 TEttinger: sm0ke, yeah think of it kinda like C, you have a main function (the top-level, and also -main in some cases) and everything gets called in order.

7:54 sm0ke: i was thinking exactly the same thing...but feared you guys will kick my ass if i say do i think like programming in C :P

7:54 TEttinger: sm0ke, if you're collaborating with people, you have namespaces that correspond to java namespaces

7:55 well C and Clojure are both not OOP

7:55 mathiasp: I'm puzzled: I wrote a small script to convert a simple csv to an html file, using enlive, running in immutant. The test.csv and the template are UTF-8, I have set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8, and <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> in the template, and still I get iso-8859-1 in the output. Maybe even something else, recode complains when trying to convert the result to utf-8. Any ideas how I

7:55 can find out where this happens? It happens in the template and in the csv content. I'm stumped.

7:55 TEttinger: in some ways that's a big advantage

7:57 mathiasp, that is odd. some programs occasionally depend on terminal encoding too

7:57 if you use pipes then terminal encoding matters I think

7:57 windows has it as an ugly isssue

7:57 mathiasp: TEttinger: nope, I'm using konsole on FreeBSD, with utf-8 as encoding...

7:58 TEttinger: mathiasp, it's a small script right? can you pastebin?

7:58 cgrand: mathiasp: you have to set the charset/content-typ on the ring response map for the ring handler to pick the correct encodng

7:58 TEttinger: or listen to cgrand since he knows what he's talking about...

7:58 ...and I don't...

7:59 sm0ke: i am finding this answer helpful http://stackoverflow.com/questions/5232654/java-to-clojure-rewrite

8:00 mathiasp: TEttinger: good, I'll do that :) @cgrand. thanks, I didn't try that since the response heeader showed utf-8, but now i will try it

8:01 sm0ke: https://speakerdeck.com/stilkov/clojure-for-oop-folks-how-to-design-clojure-programs .. i think i am not alone

8:01 TEttinger: sm0ke, good finds

8:02 clojure's built-in data structures are wonderful. advice #1 in that stack overflow post is on target for sure

8:03 tcrawley: mathiasp: if that doesn't work, and it smells like an Immutant bug, come see us in #immutant and we'll see what we can figure out

8:06 TEttinger: sm0ke, part that was hard for me learning clojure was the concurrency primitive stuff. coming from java, my instinct was to make every possibly mutable thing a ref, but it is generally better to just use clojure's immutable persistence and return/use new values (good performance on this too).

8:06 I've found atoms are pretty simple to use, but they all have uses of course

8:08 sm0ke: dont know what ref is but atom seems to be a paranoid's variable :)

8:09 TEttinger: something like that.

8:10 sm0ke: sorry i am just a newbie ..

8:10 TEttinger: a ref is a reference, it can only be modified in a dosync block IIRC

8:10 but

8:10 it can be read outside of it at any time

8:11 so you can have a ref being updated by multiple threads, each one waits for dosync to finish before starting its own modifications

8:11 sm0ke: sounds horrible

8:12 something like a sync {} block in java i guess

8:12 TEttinger: yeah ref is kinda verbose for simple modifications. but it's easier than manual locks.

8:16 sm0ke, in my clojure game, I really barely use anything other than atoms (I don't need multithreading because so much has to happen on the swing thread), and I barely use atoms either. for total performance intensive stuff I use raw arrays, but I didn't need the speed of arrays for most other stuff.

8:17 also, when you create a java object from clojure, it acts like it does in java, mutable

8:18 sm0ke: game in clojure?

8:18 are there enough libraries?

8:18 TEttinger: clojure has all of java's libs

8:19 I'm only using 3 or so total deps.

8:19 sandbags: sm0ke: have you seen https://leanpub.com/fp-oo ?

8:19 sm0ke: but i gues using java libs without syntactic sugar isnt as nice!?

8:20 sandbags: thanks ill have a look

8:27 Kototama: hi, how can I use ~/.lein/init.clj to define a function for my REPLs sessions? This won't work: http://cljbin.com/paste/52305b42e4b0cc31d37fe96e

8:30 supersym: sm0ke: this is something recent people have been working on the web side of things http://rigsomelight.com/2013/08/12/clojurescript-core-async-dots-game.html

8:30 for the rest, I don't think Java is famous for its game engines either

8:30 jmonkey or something I know of

8:40 czpqw: hey guys, has anyone tried playing with libgdx + clojure?

8:40 sm0ke: nice!! supersym

8:50 dcunit3d: whats up?

8:50 i'm looking at the 4clojure problemsets

8:51 specifically, the black-box testing problem, where you're trying to determine the type of a sequence (map/set/vector/list) without using reflection

8:52 but the last test for this question requires that you distinguish each empty sequence type (http://www.4clojure.com/problem/65#prob-title)

8:52 (= [:map :set :vector :list] (map __ [{} #{} [] ()]))

8:53 is there any way to do that without try/catch

8:54 i mean maps/sets always return nil when you ({} 1) or (#{} 1), but doing this with ([] 1) or ('() 1) will blow up

8:57 hyPiRion: dcunit3d: how do you get an empty version of the current collection?

8:57 clgv: ,(doc empty)

8:57 clojurebot: "([coll]); Returns an empty collection of the same category as coll, or nil"

8:58 clgv: dcunit3d: you got a hint per private message to avoid a spoiler for others ;)

9:00 dcunit3d: clgv: thanks

9:00 hyPiRion: it's passed into the function

9:00 clgv: np

9:00 ,(type (empty (range 10))

9:00 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

9:01 clgv: ,(type (empty (range 10)))

9:01 clojurebot: clojure.lang.PersistentList$EmptyList

9:02 hyPiRion: dcunit3d: it was a hint :)

9:02 ,(= () (empty (range 10)))

9:02 clojurebot: true

9:03 hyPiRion: whoops

9:03 mdrogalis: Hahah

9:04 hyPiRion: oh right, yesh. Something about empty and conj and things

9:05 clgv: I also like manutter51's solution ^^

9:42 squidz: i'm reading into the new schema library and see that you can compose type shapes with using def like (def verb s/String). I also noticed that you can define using defrecords, but I can't figure out what the difference/advantage would be using one over the other? Can somebody enlighten me?

9:49 glosoli: is there something basic in Compojure to just cause reload of current route ?

10:15 supersym: you mean after you changed the route / file content the server reloads that?

10:16 https://github.com/pedestal/samples/tree/master/auto-reload-server

10:16 see how they did it ;)

10:18 sandbags: cgrand: enlive++ thanks again

10:27 xeqi: hiredman: did you write a clojurescript nrepl client?

10:32 deech: Hi all, how do I load use a generated class `(:gen-class ...)` from the repl? The file is in my source tree and I've restarted the REPL but I get a SOURCE_PATH error.

10:33 TEttinger: deech, is the class listed in project.clj as one of your aot'ed namespaces?

10:33 I think aot is needed for all gen-class using ns s

10:34 deech: TEttinger: I don't know how to do that.

10:34 TEttinger: deech, are you using leiningen?

10:34 deech: yes

10:34 clojurebot: yes isn't is

10:35 llasram: clojurebot's been hitting the sauce a little early again

10:35 TEttinger: :aot [deech.core] ;; this would be in your project.clj

10:35 llasram: deech: Backing up a level though, why do you want a generated class?

10:35 TEttinger: for whatever ns you need gen-class to be seen with I think

10:35 deech: TEttinger: Ok, got it.

10:35 TEttinger: also, what llambda

10:36 deech: I've got it to compile my core.clj file.

10:36 TEttinger: llasram said

10:36 you don't usually need gen-class for pure-clojure code

10:36 there are totally cases for it though

10:36 deech: TEttinger: because I need to extend a Java class that has multiple constructors. And I need to pass that extended class as a constructor argument to a class that I'm proxying.

10:37 TEttinger: ah.

10:37 devilish

10:37 llasram: deech: For that I would suggest writing a small Java stub which exposes the exact Java surface you need and then calls into your Clojure code

10:38 deech: TEttinger: So it compiled my deech.core, but I have another in the deech namespace with the gen-class that isn't getting picked up.

10:38 llasram: Why is that a better approach? Not contradicting, just curious.

10:38 TEttinger: oh, it was a vector, you're supposed to just have all the namespaces to aot listed in the vector, sorry

10:39 also, the easy way is

10:39 deech: TEttinger: I have :aot :all in my project.clj. That's not enough?

10:39 TEttinger: :aot :all yeah

10:39 that works

10:39 ok, maybe it can't find the java source you're extending?

10:39 lein javac ?

10:40 java interop where another language has to imitate java... is a tricky business

10:40 llasram: deech: It gives you exact control over the Java surface you're exposing to the Java APIs which expect something which doesn't map well to Clojure semantics

10:41 deech: TEttinger: That's possible, but all dependency which contains the jar which contains the class that I'm extending is available if I start up the repl.

10:41 llasram: Ah, thanks.

10:41 TEttinger: I've googled similar issues in the past. llasram is right I think, and it probably won't be a large java class to write

10:41 llasram: deech: From a practical argument, gen-class is semi-abandoned, and rhickey has moved to advocate the approach I've described

10:42 deech: llasram: Good to know. Thanks!

10:42 Is there some document which shows how to include Java files in a Clojure project?

10:43 llasram: deech: lein has some docs...

10:43 Here you go: https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md

10:43 deech: llasram: Will do. Thanks again!

10:43 gfredericks: wait wait why does not-empty exist if seq is supposed to be the idiom for emptiness testing?

10:44 supersym: deech: http://blog.jayfields.com/2011/12/clojure-java-interop.html thats pretty elaborate as well on Java/clj interop

10:45 deech: supersym: Nice!

10:45 llasram: deech: And here's an example project using the specific approach I've personally found works the best: https://github.com/damballa/abracad/blob/master/src/java/abracad/avro/ClojureDatumReader.java

10:46 danielszmulewicz: Is Clojure prone to dependency hell (via maven/leinigen)?

10:46 deech: llasram: Whow.

10:46 kaw: :gen-class is semi-abandoned? What's the standard approach to creating a jar with a -main that can be used on the command line now?

10:47 deech: llasram: That'll take a bit to digest. :)

10:48 llasram: kaw: When I say `semi-abandoned` I mean that the kind of elaborate constructions it lets you generate seem to be considered a dead-end. If you just want a class with a static main you can invoke from the command line, it's still a reasonable approach

10:48 kaw: Ah, okay

10:48 Yeah, that's pretty much what I use it for

10:48 llasram: kaw: Alternatively, you can just use the `clojure.main` class. If you do `java ... clojure.main -m my.name.space ARGS...` you get essentially the same results

10:50 kaw: I think I prefer the other way for consistency with other command-line jars

10:51 llasram: kaw: There's also https://github.com/timmc/lein-otf

10:51 The benefit of that (and of core.main) is that you don't need AOT

10:52 I've come around personally to the opinion that anything which *requires* AOT is a Clojure design smell

10:52 squidz: if I use :foreign-libs in my cljsbuild which refers to a simple js file that contains console.log("test"), should that be printed out after compiling with lein cljsbuild once?

10:57 andrewmcveigh|wo: llasram: that link to abracad came just at the right time for me. Been messing around with AOT/compile order for the last 30 mins and getting nowhere. Thanks!

10:58 danielszmulewicz: I have an issue I don't know what to make of it. I have a project that stops working if I add a particular dependency. I just note that the dependency references data.json, which is also being used elsewhere in the project. The error message I get is: No such var: json/write-str. But json/write-str is present in data.json! I don't understand.

10:58 The error jumps very early, when I do `lein repl`for example

10:59 How should I go debugging this?

10:59 TEttinger: danielszmulewicz, could they be using different versions?

10:59 llasram: andrewmcveigh|wo: Hope it actually helps! :-)

10:59 TEttinger: also, make sure you're referring to data.json as json

11:00 danielszmulewicz: TEttinger: yes, but I played with the versions, making them match, still same error

11:00 andrewmcveigh|wo: Yeah, I think it will. :)

11:00 TEttinger: it would help to see some code though, if possible

11:00 danielszmulewicz: TEttinger: Yes, they are referring data.json as json

11:00 llasram: danielszmulewicz: Re: dep hell; it makes dependencies easy, which leads to lots of tiny libraries, which can cause problems if they don't e.g. sanely use semantic versioning. But in my experience it isn't worse than anything else (Python, Ruby, etc)

11:01 danielszmulewicz: TEttinger: gladly, but what code?

11:01 andrewmcveigh|wo: llasram: just deleting an old :gen-class block made me smile.

11:01 danielszmulewicz: llasram: no version locking like in ruby, isn't that a detriment?

11:01 TEttinger: danielszmulewicz, I guess the code that's throwing the error, and maybe project.clj in a gist

11:01 supersym: also tried `lein deps :tree`?

11:01 llasram: danielszmulewicz: Have you used `lein deps :tree` ?

11:01 heh

11:01 danielszmulewicz: llasram: yes

11:01 supersym: to see if there are dependency conflicts

11:01 llasram: supersym: jinx!

11:01 supersym: what

11:01 ffs lol

11:02 danielszmulewicz: supersym: the thing is that all recent versions of data.json have the fn write-str defined

11:02 llasram: danielszmulewicz: I've come the opinion that the leinigen/maven way is the worst possible dependency version-resolution system, except for all the others :-)

11:03 danielszmulewicz: TEttinger: the code that's throwing the error is in a dependency, not in my project

11:03 TEttinger: in liberator.clj

11:03 TEttinger: maybe you have a weird version in ~/.m2 ?

11:03 ok, what's the project, liberator.clj ?

11:03 danielszmulewicz: TEttinger: yes, that's possible

11:03 llasram: danielszmulewicz: For a particular set of dependencies and versions, you will consistently and always get the same resolved set of dependencies+versions, exactly like Gemfile.lock

11:04 danielszmulewicz: TEttinger: I did `lein install`for the other dependency. IS that how I can reference a library locally?

11:04 TEttinger: uhhh don't google liberator

11:04 danielszmulewicz: TEttinger: :-)

11:05 TEttinger: I didn't honestly know that there was a class of pillow called "adult pillows", nor that one is the liberator.

11:05 danielszmulewicz: llasram: I noticed that the order in which you reference the dependencies play a role

11:06 supersym: btw danielszmulewicz you know about cheshire?

11:06 I always tend to use that

11:06 TEttinger: which library is throwing the error?

11:06 xeqi: danielszmulewicz: what do you mean by "reference a library locally"?

11:06 danielszmulewicz: llasram: if you have two dependencies that use a third party library of different versions, the first one in the list "wins"

11:07 llasram: danielszmulewicz: Yep. But *consistently* wins

11:07 danielszmulewicz: If there are problems, you resolve them via adding dependencies / exclusions

11:07 TEttinger: can you file an issue on the lib you're using?

11:07 danielszmulewicz: xeqi: I mean that I have a project I want to use as a library. It is not in clojars or maven, so I did `lein intall`, and then used the local copy in my .m2 repo

11:08 Is this correct?

11:08 llasram: ~guards

11:08 clojurebot: SEIZE HIM!

11:08 xeqi: yep, that should allow lein to resolve the project coordinates

11:08 llasram: danielszmulewicz: If you absolutely need to, but it's counter-recommended, because now your build is tied to your local system

11:09 danielszmulewicz: llasram: what are you suggesting for private libraries?

11:09 llasram: danielszmulewicz: Have a private artifact repository

11:09 supersym: you can take a clojars account

11:09 sorry :P

11:10 llasram: danielszmulewicz: For personal use, you can ^^ use clojars, or setup a repository in S3. W/in a company etc you can run archiva or nexus

11:11 danielszmulewicz: llasram: good, will do. thanks

11:12 A ticket was opened on liberator: https://github.com/clojure-liberator/liberator/issues/14

11:12 I have the same message

11:12 However, without that local library, everything works fine

11:12 The error only appears when I add the dependency

11:13 It doesn't make sense, does it?

11:13 llasram: danielszmulewicz: Just double checking -- you compare `lein deps :tree` w/ and w/o your dep and have the same data.json version dependencies in both cases?

11:14 danielszmulewicz: llasram: yes

11:14 llasram: Yep -- that makes no sense :-)

11:14 danielszmulewicz: llasram: And write-str is present in all versions by the wa

11:14 y

11:14 TEttinger: check .m2 see if something's wrong

11:15 danielszmulewicz: Yes, I suspect it's what lein install does. First question, should I aot :all or not?

11:15 llasram: danielszmulewicz: Idea: is the extra dep an uberjar which may contain the same namespace?

11:16 danielszmulewicz: the extra dep is https://github.com/ianbarber/clj-gapi by the way

11:16 And it's not on clojars

11:16 just github

11:17 so if i want to bring this in my project, I need to do lein install and put it on a private repo, right? Are there extra steps?

11:18 llasram: danielszmulewicz: Convince the original project author to deploy a release to clojars :-)

11:18 danielszmulewicz: in other words, clj-gapi and liberator both use data.json, not the same version by default, but all versions have write-str so I don't understand the error

11:18 llasram: yes, it's Ian Barber from Google, I'll ask him

11:21 you were discussing aot compilation before, I'm trying to understand when it's required. I understand it's required for an uberjar, but outside of that scenario, are there other use cases?

11:21 llasram: danielszmulewicz: If you can fire up a REPL w/in the project w/ the dep, you should be able to use clojure.java.io/resource to find the file which will loaded for the data.json namespace

11:22 danielszmulewicz: llasram: good idea

11:23 llasram: danielszmulewicz: Using AOT compilation also means any `gen-class` (and semi for `deftype`) classes have real class files on disk, and thus may be loaded via e.g. Class/forName or other reflection methods

11:24 AOT does also improve load time, and (IMHO) makes sense as a deployment optimization

11:25 danielszmulewicz: llasram: OK, so the usual thing is to generate the core class with the main method, and the rest can be left as clojure source code?

11:26 llasram: danielszmulewicz: It definitely seems to be a common approach. Lately I've mostly been just adding wrapper scripts which launch via `clojure.main`, but it's pretty 6 vs half-dozen

11:27 danielszmulewicz: llasram: cool

11:40 OK, I'll be redoing it from scratch. My purpose is to add clj-gapi in an existing, working project. I clone clj-gapi from github (https://github.com/ianbarber/clj-gapi). I type `lein install`.

11:40 The message I get is : Implicit AOT of :main will be removed in Leiningen 3.0.0.

11:41 But it does create the jar.

11:41 llasram: Oh... Oh!

11:41 Hmm

11:42 What's in the JAR? Did the AOT'd class files for everything end up in the dep?

11:42 danielszmulewicz: No, at this point only :main is aot'd.

11:43 llasram: Yeah, but so one of the big problems w/ AOT is that it has to transitively AOT compile everything mentioned by the AOT'd namespace

11:43 Which means AOTing anything usually means AOTing everything, including all of Clojure itself and all of your deps

11:44 If those end up in the resulting JAR, the AOT'd versions will be on the classpath, and preferred over the source versions provided by other JARs

11:45 danielszmulewicz: The JAR should be under target/ after you do the `lein install`. Just `unzip -l` it (or whatever is appropriate for your platform) to list the contents

11:45 danielszmulewicz: llasram: OK, so first question, can I add clj-gapi as a pure clojure source code dependency

11:46 llasram: danielszmulewicz: Yeah. Just modify the project.clj to either remove the :main key+val or add ^:skip-aot metadata to the namespace symbol

11:46 danielszmulewicz: llasram: now that I like.

11:46 llasram: It looks like the original author only marked it as :main out of inexperience

11:47 akmeena: ,(into-array String ["foo"])

11:47 clojurebot: #<String[] [Ljava.lang.String;@4790c>

11:48 akmeena: How to denote a java array's class in clojure?

11:48 danielszmulewicz: llasram: you helped solve my problem. I bow to you, sir.

11:48 llasram: akmeena: For what purpose? Metadata type-hinting?

11:48 danielszmulewicz: llasram: it works now.

11:49 mpenet: ,(doc make-array)

11:49 clojurebot: "([type len] [type dim & more-dims]); Creates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."

11:49 llasram: danielszmulewicz: Awesome! Glad to hear it

11:50 TEttinger: akmeena, uh... it's a bit odd. you can type hint an array in 1 dimension with ^booleans I think, but 2d needs ^"[[Z"

11:50 danielszmulewicz: llasram: half aot'd projects are a sure way to shoot yourself in the foot, isn't it? But it must happen a lot among users who are not experts in java. Talking about incidental complexity. Clojure was meant to free us from it!!!

11:50 TEttinger: which is the JVM code for boolean 2d array

11:50 and can be gotten with a call, let me find it

11:50 akmeena: llasram: specefically I need to pass the class in gen-class's constructor spec

11:50 so I can't use a function to return class since that's a macro.

11:51 llasram: danielszmulewicz: Well, there are good reasons technomancy wants to deprecate :main being implicitly AOTed :-)

11:51 TEttinger: akmeena, array of...what?

11:51 akmeena: URL's

11:51 TEttinger: just strings? ok

11:52 devn: http://emareaf.deviantart.com/art/Rich-Hickey-321501046 -- lol, not a flattering image

11:52 llasram: akmeena: You can hint as e.g. ^"[Ljava.net.URL", but

11:52 danielszmulewicz: llasram: Right. God bless him, by the way. He's doing an awesome job.

11:53 llasram: if you scroll back / look at the recent log, this just came up, and I highly recommend just writing a Java stub to call your Clojure for anything more complicated than a static `main()` method

11:54 akmeena: So no way to denote it using a symbol?

11:55 TEttinger: ^"[Ljava.lang.String" or ^"[Ljava.net.URL"

11:55 err

11:55 wait is this a type hint?

11:58 akmeena: TEttinger: :constructors {[[Ljava.net.URL ...

11:58 TEttinger: uh

11:59 actually I don't know if [[ is right. also it may need to be in a string

11:59 ,(class (make-array java.lang.String 5 3))

11:59 clojurebot: [[Ljava.lang.String;

11:59 TEttinger: so that's a 2D array of strings

11:59 ,(class (make-array java.lang.String 5))

11:59 clojurebot: [Ljava.lang.String;

11:59 TEttinger: 1D is only one [

12:00 but that should be in double quotes I think, otherwise it becomes a weird vector

12:01 akmeena: I'll try a string there.

12:06 jml: I'm working on an edn implementation, where's the best place to raise questions?

12:07 mimieux: Hi all!

12:08 mdrogalis: jml: Probably here.

12:09 mimieux: How would be a function with the same arity but different type args? (fn ([^Boolean arg] arg) ([^String arg] arg))

12:10 opqdonut: that's not really possible

12:10 using just a function

12:10 jml: ok. first up: edn strings can span multiple lines, and also can contain escape characters '\n'. *But* the equality section says that strings are equal to strings with the same edn representation

12:11 which means that "foo\nbar" is not equal to "foo

12:11 bar"

12:11 opqdonut: you should either do (fn [arg] (cond (instance? Boolean arg) arg (instance? String arg) arg))

12:11 or use a protocol or multimethod

12:11 mimieux: ^

12:11 jml: because the representation is different (escape char vs literal)

12:12 mimieux: opqdonut: Ok, I see.

12:12 thanks

12:13 jml: second, it's not clear whether a reader should attempt to decode strings into unicode

12:14 mdrogalis: There are a lot of things that aren't clear about EDN. :/

12:28 llasram: jml: Can you elaborate on "decode strings into unicode"?

12:29 jml: llasram: how do you know if a string you get should be interpreted as a sequence of literal bytes or as human-readable text?

12:31 llasram: jml: Interesting that the EDN spec doesn't mention Unicode... I'd argue that Clojure's handling of strings is that they are pretty clearly sequences of Unicode codepoints, not arbitrary bytes

12:31 modulo the JVM 16-bit char wackiness

12:32 jml: llasram: if that's the case (and it's a reasonable guess), then it doesn't have an obvious way of sending literal bytes.

12:32 #base64 "r0flcopter"

12:33 llasram: jml: Yep. And that's a known limitation of Clojure reader data

12:33 jml: llasram: ah, interesting.

12:34 '#bytes (72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100)' perhaps

12:35 llasram: Yeah. It's not clear what the best approach would be. Maybe different ones for different situation :-)

12:36 jml: well, the prob with those is that they aren't very compact.

12:37 the newline thing is perhaps more obviously a bug in the spec

12:38 ambrosebs: wow, nanopass compilers session at clojure conj! https://twitter.com/alandipert/status/377825887397216257

12:40 * alandipert is a big fan

12:41 alandipert: ambrosebs: have you studied/used nanopass?

12:42 ambrosebs: alandipert: no, I'm looking at your links

12:42 I just know Andy Keep is a boss.

12:43 bbloom: are you familiar with nanopass compilers? ^^

12:43 supersym: haha

12:45 jml: anyway, I've filed https://github.com/edn-format/edn/issues/59 and https://github.com/edn-format/edn/issues/58 if anyone is interested in pursuing further.

13:00 alandipert: ambrosebs: chris frisz pointed me at a paper and i was enthralled, i did a little spike into a static clj and came to the realization that the real trick with compilers is organizing their insides. the nanopasses aren't unlike ring middlewares

13:14 je: why is the both a clojure.xml and clojure.data.xml they seem to have some overlap?

13:14 bbloom: ambrosebs: yeah, read the dissertation the other day

13:15 will definitely go to that talk :-)

13:15 ambrosebs: bbloom: was it you messing around with multipass CLJS compilers?

13:16 bbloom: ambrosebs: i've been discussing with dnolen how to move away from our monolithic two-pass compiler to something easier to maintain and extend

13:16 ambrosebs: ah nice

13:19 bbloom: alandipert: yeah ring middleware is a reasonable analogy

13:25 alandipert: kovas: hi!

13:25 kovas: alandipert: word

13:25 psa: still drinking my first coffee

13:26 dcunit3d: has anyone used gloss?

13:28 llasram: dcunit3d: A tiny bit

13:34 dobry-den: Is there a simple way to lazily read objects from an edn file?

13:36 saml: (read-from (edn-file) lazily)

13:36 callen: bbloom: wouldn't the trade-off be compile time though?

13:37 llasram: dobry-den: Something like: (take-while #(not (identical? ::eof %)) (repeatedly #(edn/read {:eof ::eof} pbr)))

13:37 dobry-den: (where `pbr` is a PushbackReader instance)

13:38 bbloom: callen: yes, however, if you read the dissertation they talk about "micropass" compilers which are basically the naive approach & how their nanopass approach recovers much of that lost performance

13:38 callen: also, in our case, it's worth pointing out that google closure compiler is already highly modular into passes & is, in fact, quite slow

13:38 alandipert: callen: i don't think, necessarily, esp. in light of persistent data. also with discrete pieces there may be ways to parallelize in ways previously very hard

13:39 bbloom: callen: CLJ is far easier to analyze than JS, so we could dramatically speed up the optimization process by doing CLJ-level tree shaking before doing JS level optimizations

13:40 in short, they generate record data structures from grammars & then generate traversal code from pass configuration

13:41 callen: bbloom: seems reasonable. Thanks.

13:41 bbloom: I actually need to simplify the parser in Selmer but haven't had time to attack it lately.

13:41 alandipert: also, easier CinC! (maybe?)

13:41 callen: It's a raw recursive descent parser and could be a lot nicer given a GLL

13:42 bbloom: alandipert: *shrug* i don't think that it would help there much, since Compiler.java is already monolithic & step one would be to just port it over more or less unchanged

13:44 alandipert: bbloom: it just seems to me that w/ nanopasses it would be much easier to target new things, possibly building on existing passes

13:45 esp. a target in JS's ballpark, like java

13:46 bbloom: alandipert: i mean the compiler backend is like 800 lines of code. Targeting a new platform isn't the hard part, it's all the work around the standard library, macro system, interop code, build infrastructure, performance optimizations, etc

13:47 alandipert: sure, a nanopass compiler would mean that the compiler could be 500 lines instead of 800 lines

13:47 but *shrug* no big deal really

13:47 the big win is in being able to *share* optimizations across backends

13:47 alandipert: i'm taking those into account, the things you list seem to map to passes

13:47 dcunit3d: llasram: i'm trying to find some examples. i'm looking on clojuresphere and found a few good projects there. i'm trying to parse data from the MNIST handwritten digits database, which is in a fairly simple format.

13:48 saml: http://cufp.org/conference/sessions/2013/t7-luke-vander-hart-clojure-tutorial is this worth taking it?

13:48 bbloom: alandipert: a lot of optimizations in Compiler.java are *very* java specific

13:48 alandipert: there are a *few* things that are more general than JS in compiler.cljs

13:48 alandipert: like tag inference

13:50 llasram: dcunit3d: There's also some examples in the gloss wiki. I don't really have a corpus of examples to point you to which would be better than ones you've probably already got

13:50 alandipert: i envision passes that do more platform-specific opt. are just just closer in the chain to final emission than the general optimizations

13:50 llasram: dcunit3d: If you run into trouble, ztellman is frequently on this channel

13:50 Oh, and is here now apparently

13:50 ztellman: yes, I got dinged

13:50 llasram: hah

13:51 dcunit3d: cool

13:51 ztellman: but yeah, let me know if you have any questions re: gloss

13:51 bbloom: alandipert: yeah, absolutely. all i'm saying is that spinning up a new backend is actually pretty easy & i actually probably *easier* to do with a monolithic backend, since we already have a model to follow.

13:52 alandipert: don't get me wrong. i'd rather see lots of small passes, just don't think that easier new backend is a motivation for that. i'm much more interested in shared analysis & optimization + easier reasoning about those things.

13:52 ztellman: alandipert: did you score tickets to StrangeLoop?

13:53 alandipert: ztellman: yeah man and i'm amped!

13:53 ztellman: cool, see you there

13:53 alandipert: bbloom: dream big :-)

13:53 bbloom: alandipert: if you wanna dream big, then you should talk to tbaldridge about doing an SSA intermediate target & compiling *that* to JVM or JS :-)

13:54 mdrogalis: ztellman: Did anyone ever reply to your tweet about Java getting booted from Script Bowl?

13:54 alandipert: bbloom: gclosure does my SSA ;-)

13:54 ztellman: mdrogalis: nope, but I wasn't really serious

13:55 bbloom: alandipert: for alternative backends? :-P

13:55 mdrogalis: ztellman: I got a good laugh out of it, anyway.

13:58 alandipert: bbloom: SSA could be a pass, no? multiple passes even

13:59 ztellman: are you gonna be there for ELC or workshops?

14:00 ztellman: alandipert: ELC

14:00 bbloom: alandipert: conversion to SSA would be a pass & then there are *many* SSA optimization you (or LLVM or whatever) could perform. then you'd have an SSA->target code generation pass

14:01 alandipert: let me be clear: smaller simpler passes are a very good thing that will make the compiler better in many many ways

14:02 alandipert: however in terms of time-to-CinC, i don't think it will make anything faster or dramatically easier, since the problems are practically unrelated to the complexity of the *code generator* which is the (currently) final and most platform specific pass

14:02 alandipert: there are lots of little optimizations that we can do that will make our lives easier for code generation

14:03 alandipert: for example, we talked about ANF transform which will mean we don't need to do those (function() { })() scope thinggies in JS. similar simplifications would be available for the JVM

14:05 so yeah, nanopass would benefit code generation to some extent, but not nearly to the same degree as analysis & optimization

14:05 alandipert: bbloom: i guess i feel differently re: CinC, as i see conforming to target platform idioms/constraints as a kind of optimization, made easier when the compiler framework isn't allowed to make many assumptions about target

14:05 bbloom: bb in a bit

14:05 alandipert: bbloom: oh hey are you strangelooping btw? would be awesome to hang again

14:05 bbloom: i'll be at the conj, but probably not strange loop

14:05 brb

14:23 mmitchell: Could anyone here recommend a Clojure validation lib? Kinda looks like bouncer and validateur are the main choices? Anyone here have experience with either of them?

14:31 Leonidas: Is there a better solution for something linke (if (contains? @cache (first args)) (@cache (first args)) …)?

14:32 I'm kinda annoyed by having to do the cache lookup basically twice.

14:32 metellus: if-let

14:32 Leonidas: thanks

14:32 tbaldridge: Leonidas: look up clojure core.cache https://github.com/clojure/core.cache

14:32 Bronsa: Leonidas: if-let + find

14:32 bbloom: Leonidas: you shouldn't deref (the @) twice in a row if somebody else can invalidate the cache out from under you

14:32 Leonidas: tbaldridge: that's overkill, my cache is just a Map :)

14:32 tbaldridge: Leonidas: has memorizing wrappers, if you need that.

14:32 kk

14:33 Leonidas: tbaldridge: jup, I was playing with a recursive memorizing macro :)

14:33 bbloom: yup, I was thinking about this too. Not likely to happen, since the cache is local, but something I'd better avoid in any case :)

14:42 * Leonidas wishes clojuredocs would update to 1.5 :-(

14:45 ToBeReplaced: where can i learn the difference between ILookup and Associative?

14:46 nvm, just looking at the java works

14:47 I'm wondering if maybe we should document that more... I don't like when libraries say "accepts a map" when they mean "ILookup"

14:48 or worse when "accepts a map" doesn't accept records

14:57 tbaldridge: ToBeReplaced: who does that? (maps not records)

15:01 ToBeReplaced: tbaldridge: clj-http

15:01 tylere: Is there any way to get something sort of paredit-like in intellij for closure? E.g. something that constantly reformats code alignment and keeping everything pared up.

15:02 ToBeReplaced: tbaldridge: try (client/get "http://www.google.com" {:connection-manager (make-reusable-conn-manager)})

15:02 then do it again with the map as a record

15:03 tbaldridge: ToBeReplaced: ick, I'd love to know why that bug exists

15:05 ToBeReplaced: tbaldridge: maps are functions, records aren't

15:06 nDuff: tylere: ...it exists, but it's not as good as the canonical emacs implementation.

15:06 supersym: /join #linguistics

15:06 tbaldridge: , (do (defrecord Foo [x]) (:x (->Foo 42)))

15:06 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

15:06 tbaldridge: ToBeReplaced: it works in a real repl

15:07 mdrogalis: Can anyone expand on what Rich is trying to say at 8:20? http://www.infoq.com/presentations/Design-Composition-Performance

15:07 ToBeReplaced: do it the other way aroud ((->Foo 42) :x)

15:08 mdrogalis: Is he advocating using constructs like deftype more for problem logic and maps/sets for solution logic?

15:08 tbaldridge: ToBeReplaced: ah I see

15:08 mdrogalis: Like, I get the idea. I just don't get how to put it into practice.

15:08 Bronsa: ToBeReplaced: that has nothing to do with Associative or ILookup, it's because record don't implement IFn (I wonder why)

15:09 ToBeReplaced: right; the issue is that clj-http requires your "m" to implement IFn ... where a reasonable guess woudl have been you just need Associative

15:11 Bronsa: my point was more that we use "map" everywhere, and that's a pain, because sometimes I just want to pass an ILookup or a Record, and i tend not to know if it will work

15:11 tbaldridge: mdrogalis: the gist is that we should not conflate data with code.

15:12 mdrogalis: so yes, use maps,sets,vectors for data. Only resort to deftype/defrecord when you need better performance.

15:13 mdrogalis: tbaldridge: I find that conclusion kind of conflicting. It's not that I disagree with your first statement, but I was always under the impression that deftype was there to carve out abstractions in the problem space.

15:14 hiredman: deftype is not abstract at all

15:14 dnolen: bbloom: http://vimeo.com/74314050, great stuff from Jonathan Edwards

15:14 bbloom: dnolen: love that guy! will definitely watch it soon

15:15 tbaldridge: mdrogalis: not really. You can do good abstraction via pure data and multimethods. It's just that these things were way to slow to build an entire language off of (like cljs)

15:15 dnolen: mdrogalis: protocols carve out the abstractions, deftype fills in the blanks

15:15 tbaldridge: dnolen: lol, just got an email for that video

15:15 mdrogalis: dnolen: What does fill in the blanks mean?

15:16 dnolen: mdrogalis: ISeq is the big idea, the 20 deftypes that implement it make it work

15:16 mdrogalis: I kind of find that maps are so flexible in Clojure that the 'how to navigate' the map bit seeps through my entire program.

15:16 So I think that's where I get tripped up about it.

15:17 dnolen: Yeah, I suppose I shouldn't read too hard into the English idiom.

15:17 dnolen: mdrogalis: it can be problem in larger programs, core.typed and Prismatic's Schema look promising solutions

15:18 mdrogalis: dnolen: Was considering core.typed. It becomes a jungle after a while for sure.

15:18 tbaldridge: mdrogalis: yeah, I'm not saying "don't use protocols", there are times however, when I'm coding and I step back and say "Oh My....I'm using protocols like I would in OOP". And that's just wrong. So perhaps if you spend the first part of a project writing 20 protocols each with 5 members, you're doing it wrong.

15:19 dnolen: mdrogalis: it just depends on how much discipline you apply and what your timeline is. generally you don't have time to uniformly apply discipline, so you need something else

15:19 mdrogalis: tbaldridge: I recall someone, maybe Stu Halloway, driving home the point about that. I believe he was noting that protocols should have 1-3 functions ish.

15:20 The topic would probably make a really good blog post on the front of more abstract design topics.

15:20 callen: I've done a really good job of avoiding protocols.

15:21 but I'm not allergic to multimethods either.

15:22 asteve: what is going on here: (let [[a & other-a :as ab] @a-b])?

15:22 mdrogalis: Well, example in core.async: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/buffers.clj#L16

15:22 Was that in the name of performance?

15:23 tbaldridge: mdrogalis: yes

15:23 mdrogalis: tbaldridge: The alternative being a multimethod?

15:24 callen: core.async is out on the hairy edge though. I'd argue most clojure users would be better served with multimethods.

15:25 core.async only needs to be implemented once, you shouldn't use the unusual constraints and priorities of one library to inform design principles for your Twitter clone.

15:25 tbaldridge: mdrogalis: yeah, I wouldn't use core.async as a good example of idiomatic clojure code. The core.async CLJS code doubly so. We take tons of shortcuts in the name of performacne.

15:25 *performance

15:26 mdrogalis: Got'cha. Yeah, definitely noted that the rest of the code is off-par. That one bit caught my eye though.

15:28 callen: technomancy: used paredit on my coworker's machine who is learning Clojure, immediately turned around and installed paredit on mine as well.

15:37 technomancy: sweet

15:39 won't say I told you so

15:39 but everyone else told you so

15:40 callen: technomancy: I used paredit twice, once before Clojure and once briefly after. It was finickier back then.

15:40 I figured I'd end up using it eventually, just didn't know when.

15:41 dissipate__: anyone use counterclockwise with eclipse?

15:41 technomancy: ~anyone

15:41 clojurebot: anyone is anybody

15:41 callen: dissipate__: nope never.

15:41 technomancy: dammit clojurebot

15:42 dissipate__: :(

15:42 callen: dissipate__: one of the philosophies of Clojure is that you should concern yourself with queries and results - values. Not "places".

15:43 dissipate__: if you have a question, ask it. Don't concern yourself with how many "nouns" you can possibly derive arbitrary information from.

15:43 cored: hi

15:43 `cbp: Hello, what do people do when they wanna prevent getting/updating non-existing keywords on maps/records?

15:43 callen: cored: hi.

15:43 `cbp: prevent?

15:43 cored: why isn't this equal (= '(:a :b) (conj '(:a) :b))

15:43 `cbp: callen: Like I'd rather they throw an exception than return nil

15:43 tbaldridge: `cbp: they don't. Sometimes I want extra keywords on a record

15:44 cored: callen: hello

15:44 callen: `cbp: that's pretty bad style. You might be trekking into core.typed territory perhaps?

15:44 if you need to statically define a "this and only this" shape of a map.

15:44 tbaldridge: `cbp: in general clojure programmers prefer to let people do what they want.

15:44 `cbp: callen: Is it? I just seem to waste so much time sometimes hunting down misstyped keywords :(

15:44 callen: tbaldridge: except ask bad IRC questions. that's verboten.

15:45 tbaldridge: callen: touche

15:45 callen: `cbp: core.typed helps a lot with misstyped keywords. If you must throw an exception on a non-existent keyword, make it dev-only.

15:46 `cbp: callen: Ok I'll check it out. Sry for the bad questions :P

15:46 callen: `cbp: my vote is a debug/dev-only macro that throws as the alternate to a "get" or core.typed

15:46 `cbp: I wasn't talking about your question.

15:47 `cbp: callen: oh ok

15:47 callen: `cbp: yours was fine and is pretty common/standard to learning the "we're all consenting adults" attitude of Clojure.

15:47 I really really do not like Python-esque "throw on non-existence" behavior.

15:47 really. Really. It's an obnoxious default.

15:47 tbaldridge: (inc callen)

15:47 lazybot: ⇒ 9

15:48 dnolen: anybody want to lend a helping hand tracking this bug http://dev.clojure.org/jira/browse/CLJS-586

15:48 I've constructed a minimal repo after what's described in the ticket (see last comment), I cannot reproduce the issue at all

15:50 `cbp: callen: Oh btw I'm _still_ working on it :P. Just had to put some extra hours at work these last 2 weeks. Good news though, no more windows whining

15:50 callen: my attitude is that if you must catch situations where you want to enforce map shape, you might as well do it at compile-time with ambrose's baby. The awkward middle-territory of runtime exceptions just makes me stabby.

15:50 `cbp: still working on what?

15:50 `cbp: callen: the sync stuff

15:50 callen: `cbp: http://hugoduncan.org/post/alembic_reloads_your_project_clj_dependencies/

15:51 `cbp: are you doing it differently from hugod's alembic?

15:51 cored: read the documentation on the repl

15:51 `cbp: callen: I had no idea it existed I'll read it

15:51 callen: `cbp: I thought I emailed it you as a heads up.

15:51 cored: but it's still kinda weird, the parameter for the new item in the conj function is in the end; at first glance it's implies to me that th eitem will be added to the end of the list

15:52 but it's get joined at the first element

15:52 callen: cored: conj is a generic "add to coll" function. If you need to worry about the "placeness" then think about the data type you're passing it.

15:52 vector -> tail, list -> head

15:53 `cbp: callen: Got no email :(

15:53 jonasen: dnolen: I can reproduce

15:53 callen: `cbp: oh balls. I have no idea who that email went to then. Sorry!

15:53 dnolen: jonasen: can you gist your steps? It doesn't matter which file I modify I don't see the issue.

15:54 cored: callen: oh, great way to remember this, thanks

15:54 callen: `cbp: you should sync up ( http://i.imgur.com/wjANVCD.jpg ) with me on IRC more often :)

15:54 dnolen: jonasen: being able to copy and paste your steps will remove any variables here

15:54 cored: callen: which means I can use a vector or a list with the same function?

15:54 jonasen: https://www.refheap.com/18555

15:54 dnolen: ^

15:55 callen: cored: http://i.imgur.com/RInU1Nr.jpg

15:55 muhoo: any clues as to anything i can do to mitigate lots of "Unexpected end of ZLIB input stream." in clj-http?

15:57 jonasen: dnolen: copy/paste messed up some of the commands but I hope you can follow it

15:57 coventry`: asteve: That is assigning the value from dereferencing a-b to ab, the first value of that to 'a' and the rest to other-a. http://clojure.org/special_forms#Special%20Forms--Binding%20Forms%20(Destructuring)

15:57 callen: muhoo: are you holding onto the head?

15:58 asteve: coventry`: ah, thank you

15:58 `cbp: callen: Its pretty much what I had. I just had a bit more care when needing auth for a repo + you could specify a profile on mine. The issue with conflicting dependencies remains though, and I have so far not much of an idea on how to solve it

15:59 * callen nods

15:59 dnolen: jonasen: so you had to touch two files to trigger?

15:59 callen: muhoo: is Accept-Encoding being set?

16:00 `cbp: I had a dream where you could switch profiles on the repl, like suddenly (sync! :1.2) :P

16:01 jonasen: dnolen: i don't know. no warnings when I touched the first file so I tried the other...

16:01 callen: `cbp: I'm getting close to needing that, but not quite yet.

16:02 dnolen: jonasen: yep can't reproduce

16:02 jonasen: dnolen: weird

16:03 dnolen: I only need to touch core.cljs to get the warnings

16:05 dnolen: jonasen: yep can't repro

16:07 jonasen: ok, typo in my require ns, can repro now. Thanks!

16:14 asteve: is clojuredocs.org deprecated?

16:16 noprompt: asteve: it's a bit outdated, but the majority of the reference is still relevant.

16:16 asteve: you can choose between 1.2.0 and 1.3.0 is that referring to clojure versions or clojuredoc versions?

16:16 mdrogalis: asteve: Clojure versions.

16:16 asteve: because it claims 1.3.0 is the latest stable on some modal where the clojure.org claims 1.5.1 is the latest stable

16:17 mdrogalis: asteve: The latter is correct.

16:18 noprompt: asteve: i would look at this http://clojure.github.io/clojure/clojure.core-api.html

16:18 asteve: noprompt: thank you

16:19 mdrogalis: thank you as well

16:19 mdrogalis: :)

16:21 callen: asteve: clojuredocs is hella out of date.

16:21 It will be replaced soon.

16:22 asteve: it was outdated in the late 90s? :)

16:23 callen: asteve: hella is Yay!speak, not 90s.

16:23 asteve: I remember using it in the 90s and then I stopped

16:23 I'm glad I stopped

16:23 :)

16:26 danielszmulewicz: I always thought that interactive and incremental development at the REPL was as prevalent with Clojurians than with other Lispers, but after reading about Stuart Sierra reloaded patern, where you reload the whole system after modifying code, I'm starting to wonder if things are different in Clojureland. I thought I'd ask here first to see what other people are doing.

16:27 What's your workflow like?

16:27 callen: danielszmulewicz: like Sierra's.

16:27 Mostly.

16:28 danielszmulewicz: Interesting.

16:28 callen: I used to have persistent sessions in Common Lisp but I got tired of worrying about it.

16:28 rhg: load a repl, code, reload and repeat

16:28 callen: it got almost Erlang-esque. yuck.

16:28 danielszmulewicz: You don't do incremental development at all

16:28 ?

16:28 callen: that's...not true at all.

16:28 sierra's model of development is incremental

16:28 it's just not especially stateful.

16:28 danielszmulewicz: ok

16:29 callen: which helps to keep local dev in sync with prod.

16:29 danielszmulewicz: rhg: you reload and when it's broken, what do you do?

16:29 coventry`: I do a lot of experimentation in a long-running repl without reloading, but I am not currently tracking a lot of complex state.

16:29 rhg: broken how?

16:30 danielszmulewicz: rhg: when the system is messed up

16:30 seangrove: Just wanted to double check, sohuld we change the Clojure license?

16:30 rhg: i also sometimes just evaluate short snippets

16:30 danielszmulewicz: coventry`: so you keep track of state mentally?

16:30 callen: seangrove: er, what?

16:30 seangrove: you mean in the default project.clj or something else?

16:31 seangrove: callen: Just the mailing list again :P

16:31 Also, we should consider a white-space clojure syntax

16:31 rhg: state is unneeded 90% of the time

16:31 mdrogalis: That number is scientifically well-founded.

16:32 danielszmulewicz: callen: so you never C-c C-k a buffer at the repl? I should ask if you're an emacs user first I guess?

16:32 rhg: or maybe more

16:32 coventry`: danielszmulewicz: No, actually I am just throwing the state away on each run, so I guess what I'm doing is a little like Sierra's workflow, but accidentally.

16:32 callen: danielszmulewicz: I do C-c C-k all the time.

16:32 danielszmulewicz: I've been using Emacs for over a decade. How else would I do CL?

16:34 danielszmulewicz: callen: so how often do you C-c C-k and when do you reload the whole?

16:34 system?

16:34 callen: (inc seancorfield)

16:34 lazybot: ⇒ 5

16:35 callen: I refresh when I've changed a bunch of code and I'm too lazy to manually eval individual forms.

16:35 I don't "reload" strictly speaking.

16:35 I C-c C-k whenever I enter a new namespace.

16:36 danielszmulewicz: callen: cool. So when you do refresh, how do you do it?

16:36 callen: the same way Sierra does...

16:36 danielszmulewicz: callen: right, so you design your application in such a way that you can reload the whole system at the repl

16:36 callen: it doesn't take much "design"

16:37 good habits in general will end up meshing naturally with how Sierra develops.

16:37 unless you've got really strange constraints that are probably contrived.

16:37 danielszmulewicz: callen: how prevalent is this strategy you reckon in the community?

16:37 callen: I don't really care how many people use it/

16:37 I care that people continually improve how they work.

16:38 danielszmulewicz: coventry`: when you throw away the state, how do you do it? Sierra style or you just restart the REPL?

16:39 callen: restarting the REPL is really annoying.

16:39 anybody that had killing/restarting the REPL as part of their workflow needs the am-blamps.

16:40 danielszmulewicz: callen: :-)

16:40 rasmusto: callen: Is there a way to tell nrepl to stop running w/e infinite loop I sent the repl into? (from nrepl.el or otherwise)

16:41 coventry`: danielszmulewicz: I'm re-evaluating clojure.core and test-clojure into gensym'd namespaces. I effectively just throw those namespaces away. That is the extent of my state at the moment.

16:41 rasmusto: C-c C-b.

16:41 callen: coventry`: IIRC you're working on something kinda weird anyway.

16:42 rasmusto: coventry`: thank you

16:42 dnolen: ok pretty sure I have a fix for CLJS-568, cut another release 1878

16:42 seangrove: callen: Ah, beat me too it

16:42 C-c C-b is also awesome for a hung cljs repl

16:42 danielszmulewicz: coventry`: Interesting. But makes me more curious.

16:43 dnolen: if anybody wants to help me please try reproducing the error with 1878 http://dev.clojure.org/jira/browse/CLJS-586

16:43 callen: seangrove: in the silly thread?

16:43 dnolen: thanks!

16:43 seangrove: callen: woops, meant coventry`

16:43 coventry`: danielszmulewicz: I'm working on a debugging tool. I want to make sure that all of clojure can run under it without breaking/breaking the tool.

16:43 noprompt: dnolen: have the new compiler optimizations made it in?

16:43 dnolen: it's like laser beams fast now. i love it.

16:43 coventry`: seangrove: no worries.

16:43 callen: seangrove: you saw the silly license thread right?

16:43 seangrove: callen: Yeah, just a small sigh when it comes up

16:43 dnolen: noprompt: nope, it'll probably be while before I get around to it, but it my list of todos

16:43 danielszmulewicz: coventry`: oh, I see. That must come with its own challenges.

16:44 seangrove: If it changes that's cool, but I don't care much one way or another

16:44 callen: "IRC, where we discuss the mailing list", "mailing list, where we discuss the JIRA"

16:44 dnolen: noprompt: it won't be a dramatic difference, but at least we know we won't have that overhead to consider when benchmarking

16:44 coventry`: danielszmulewicz: Yes, it's quite challenging and fun.

16:44 seangrove: callen danielszmulewicz: But I agree with the repl bits - there's rarely much state to "throw away"

16:45 dnolen: noprompt: glad to hear, these kind of details make a lot of difference I think.

16:45 danielszmulewicz: seangrove: there's components like databases, servers, that's state too

16:45 seangrove: dnolen: Will check the bug out

16:46 dnolen: seangrove: thanks!

16:46 danielszmulewicz: coventry`: wouldn't be related with ritz, would it?

16:46 callen: danielszmulewicz: and there are smarter ways to manage those components than def'ing a dynamic db var.

16:46 noprompt: dnolen: it's exciting stuff. not having to wait a few seconds before refreshing the browser makes a huge difference.

16:46 dnolen: noprompt: agreed

16:46 seangrove: danielszmulewicz: Sure, but they can either be recreated or don't have to be touched. Every now and then something like the jetty server can be annoying, but you come up with functions that handle it fine

16:46 coventry`: danielszmulewicz: Yes, but if you're routinely testing at the repl with those resources, you're probably not working in the most efficient way.

16:47 danielszmulewicz: No, not related to ritz. This is pure-clojure.

16:47 danielszmulewicz: callen: Yes, I suppose you mean sierra style. I agree it's a good strategy.

16:47 noprompt: dnolen: the seconds lost waiting for builds can really have an impact on the workflow.

16:48 callen: danielszmulewicz: sometimes. the point is to pause to reflect on what you actually want.

16:48 Sierra's workflow is a reflection of that process, not reified perfection-in-itself as a workflow.

16:48 noprompt: garden is going to support clojurescript soon. :-) i'm super excited about htat.

16:48 danielszmulewicz: callen: fair point

16:48 noprompt: or rather, be available to use from clojurescript.

16:49 dnolen: noprompt: yep - it really wasn't CLJS was slow, just the way incremental builds worked. The fact that analyzer can get through about 15000 lines of Clojure ~1second on my machine ain't bad IMO.

16:49 er ClojureScript

16:50 noprompt: dnolen: that's amazing.

16:53 callen: seancorfield: thanks for that MEAP coupon :)

16:53 snagged me a JoC 2ed

16:53 danielszmulewicz: coventry`: not sure what you mean with routinely. I'm spending much time at the REPL testing stuff out, then I write what works in buffers, reload the system eventually, it's an iterative process. I'd love to know more about your approach.

16:56 coventry`: danielszmulewicz: The code for talking to those resources should be very simple. Most of the stuff you test at the repl should be with pure functions and data you would get from those resources.

16:56 seangrove: dnolen: This is the warning output from the current build https://www.refheap.com/60e1e83393484e38f22626947

16:56 danielszmulewicz: coventry`: oh, yes, we're in agreement.

16:57 seangrove: Will try with the 1878 release

16:57 dnolen: seangrove: that looks like completely different bug that 568

16:57 seangrove: those are GClosure warnings, not CLJS compiler ones

16:58 seangrove: will need a different ticket for that and a minimal case

16:58 seangrove: dnolen: Ok then, nevermind about it

17:00 dnolen: seangrove: might be a dependency ordering on recompile issue ... perhaps lynaghk's spelunking in Closure Compiler might deliver something more sensible than what's in closure.clj

17:01 seangrove: dnolen: I think that's what it was before, I was thinking about looking at it sometime soon

17:02 dnolen: seangrove: things definitely get out of order under incremental compilation, though I haven't encountered issues with that myself.

17:03 coventry`: What's the right way to get the unqualified symbol from the qualified? Like (symbol (last (str/split (name 'clojure.core/partial) #"/")))?

17:04 Bronsa: coventry`: ##(symbol (name 'foo/bar))

17:04 lazybot: ⇒ bar

17:05 seangrove: dnolen: Yeah, I just haven't used incremental compile because of it. It broke early in my cljs days, and I just do everything via repl almost. I wouldn't mind using it though, so I'll check into it later

17:06 coventry`: Bronsa: Heh, I had "clojure.core/partial" as a string when I was testing out name. Thanks.

17:06 seangrove: Where is lynaghk's research on the compiler?

17:06 dnolen: seangrove: you'll have to ask him in person, not written up anywhere as far as I know

17:08 callen: It's a pity the pro license for Datomic doesn't let me disclose benchmarking results...

17:08 Very nice stuff. :)

17:08 patchwork: callen: How does it prevent you disclosing benchmarks?

17:09 That seems counterproductive

17:09 callen: It's pretty normal/standard for a product like Datomic, or .NET, to disallow disclosure of benchmarks.

17:09 Well, considering how bad most people are at *designing* benchmarks, it makes sense to me.

17:09 patchwork: So it seems like they would provide their own in that casxe

17:09 *case

17:10 callen: They could. I suspect they're busy/popular enough that they don't need to engage in 10gen-esque self-promotion though.

17:10 hard to tell as an outsider though.

17:10 Either way, super-pleased.

17:11 patchwork: Theme of the week: Everyone talking about evidence they can't show people…

17:11 kaw: Is there a way to suppress warnings for cljsbuild that aren't coming from my own code? I'm getting this every time I compile: http://lpaste.net/1592370575374811136

17:12 Alternatively, a way to eliminate those warnings, if they're something I can/should eliminate without digging into the domina code

17:12 bbloom: dnolen: lol! "pretty much incomprehensible to, you know, regular people"

17:12 callen: patchwork: well. I can't. I'm going to show my coworkers in ~2.5 hours but they're the only ones who'll know how awesome Datomic is I guess :)

17:13 I'm tempted to adapt that Yahoo test for Datomic and see what it spits out.

17:14 asteve: this might be slightly OT but I'm needing help understanding defbolts and storm, I figured some people in here may use storm. here's the question: what is the purpose for ["word"] for a defbolt like (defbolt sentences ["word"] [tuple collector]...)

17:15 callen: asteve: an aside, if you aren't already, you should be following sritchie.

17:15 sritchie: asteve: that's the name of the stream that the bolt outputs

17:15 asteve: so, other bolts can subscribe using that name

17:16 asteve: is that written in the docs somewhere that I've missed?

17:17 sritchie: asteve: I guess nathan talks about it here...

17:17 https://github.com/nathanmarz/storm/wiki/Clojure-DSL

17:17 but that whole page is confusing even for me

17:17 bbloom: dnolen: as soon as he showed that red/blue arrow, i knew exactly where he was going. i agree big time.

17:18 dnolen: bbloom: good stuf

17:18 f

17:18 asteve: heh, well I'm glad I'm not the only one; thanks sritchie

17:18 sritchie: asteve: :) for sure

17:19 callen: sritchie: is there a clojure equiv to summingbird?

17:19 sritchie: callen: not yet, but I did a bunch of work on Cascalog 2 that pushes it in that direction

17:20 asteve: so, on another related note, I'm battling with upgrading storm for 0.5.2 to 0.8.2 and I'm getting a type casting errors for a number that I believe should be a long

17:20 sritchie: Cascalog 2 generalizes the execution platform idea...

17:20 callen: I was about to ask if Cascalog 2 was intended to accomplish that.

17:20 sritchie: callen: yup

17:20 rasmusto: any preference for auto-complete+ac-nrepl vs the nrepl.el default completion?

17:20 callen: sritchie: very cool. Thanks for your work :)

17:20 sritchie: so the datalog planning engine generates an immutable DAG,

17:20 asteve: I'm getting long cannot be cast to double and double cannot be cast to long when I attempt to use .getLong and .getDouble on the tuple

17:20 sritchie: and then a platform compiles that down to a physical plan, like a Cascading plan

17:23 bbloom: dnolen: so i subscribe to these same ideas as edwards, but i'm a little more radical in my stance. instead of dynamic/static split, i want arbitrary stages with a sliding scale of dynamic/static

17:23 dnolen: in general, yes, stages go from more dynamic to more static. but that might not always be the case

17:23 coventry`: rasmusto: I just use hippie-expand or dabbrev, or whatever comes with emacs. But emacs-live seems to have some good autocomplete functionality. Never played with it myself. http://vimeo.com/22798433

17:24 rasmusto: coventry`: thanks, will take a look

17:24 bbloom: dnolen: also, i advocate for "capabilities" as a mechanism for controlling access to various features. so for example if you have first class environments, that's pretty dynamic & hard to optimize, but if you don't ever give the first-class-environment module to the next stage, then you can treat that entire stage as being sans first class environments. just as one example

17:24 tbaldridge: bbloom: I still question if it really makes things any simpler with the half-dynamic stuff. And he basically side-stepped the whole template error message thing by putting error message construction on the user.

17:24 sritchie: callen: I'm speaking about it at clojure/conj, btw

17:25 so I'll have to have the storm planner done by then :)

17:25 bbloom: tbaldridge: still watching. will comment on that in a sec

17:25 callen: another reason to go to the conj. hrrrm

17:30 bbloom: tbaldridge: ambrose just wrote a whole thing about witnesses for types in core.typed :-) http://frenchy64.github.io/2013/09/08/simple-reasoning-assertions-core-typed.html

17:32 tbaldridge: i think that it's a pretty reasonable approach. we've got the same issues in clojure where you fuck up and give a number instead of a map or something and you get a stack trace from *deep* in the app

17:32 tbaldridge: if you just add an (assert (number? x)) somewhere, you're fine. you don't need to (assert (number? x) "Some friendly message") necessarily

17:33 dnolen: bbloom: tbaldridge: I agree with the idea that witnesses sound reasonable - sounds close to contracts and blame stuff

17:33 bbloom: tbaldridge: he alluded to it, but an even better solution is the "blame calculus" which is what folks are researching both for dynamic types AND things like concepts

17:33 dnolen: hello world in ClojureScript now generates 49 lines of pretty printed advanced compiled code

17:33 I don't think we can actually get much smaller than that :)

17:33 bbloom: tbaldridge: it's funny, but creating inhabited generics is roughly the same as evaluating dynamically typed code :-P hence the same tech works on both

17:39 tbaldridge: bbloom: and is also the same tech used in the PyPy tracing JITs. bytecode tracing -> partial evaluation of the bytecode -> static type the byte code -> remove mallocs -> generate machine code.

17:40 scriptor: dnolen: wait, the days of 4000 lines of generated js are over?

17:40 bbloom: tbaldridge: haha yeah, that too! I'm telling you, partial evaluation & specialization via abstract interpretation is a big fucking idea :-)

17:40 dnolen: scriptor: absolutely not

17:40 scriptor: but the dependencies in core.cljs are very clean now, you get what you use.

17:42 rasmusto: coventry`: ac-nrepl is pretty easy to setup, I'll go with this for now :)

17:43 coventry`: rasmusto: Oh, is it ac-nrepl? People were complaining about that here the other day. http://clojure-log.n01se.net/date/2013-09-09.html#14:15

17:44 rasmusto: coventry`: haha, no blood/sweat/tears here, but I'll take that under advisement

17:46 callen: ac-nrepl is really slow sometimes.

17:46 people should still try it out, but z0mg it drives me nuts sometimes.

17:46 rasmusto: callen: it's all backgrounded though, right?

17:46 callen: it slows down my namespace switching hardcore.

17:46 rasmusto: if it is, I haven't noticed.

17:48 rasmusto: callen: ah, I see what you're saying, typing "def" and waiting will make it chug a bit

17:49 callen: no, I mean nrepl-set-ns blocks for awhile when I'm using ac-nrepl.

17:49 which sucks because my work-style is to jump from ns to ns when I'm testing assumptions.

17:49 I don't do everything in (ns user) like some people.

17:49 rasmusto: callen: me either, I usually just do a c-c c-k and go from there

17:50 (which might be bad)

17:50 callen: I do the same.

17:50 C-c M-n + C-c C-k

17:50 rasmusto: oh, does c-c c-k not change your namespace automatically?

17:51 callen: hrm. lets find out.

17:51 coventry`: rasmusto: no.

17:51 callen: nope.

17:52 it just reloads the vars in that buffer.

17:52 in their respective namespaces.

17:52 rasmusto: oh, you're talking about the repl namespace

17:53 if I want to run code "on the repl" I just drop it into a namespace that requires/uses the namespace with the code that I want

17:53 which is probably where my workflow is a bit strange

17:53 coventry`: rasmusto: It's awfully handy to be able to just type forms in and hit enter, sometimes.

17:54 rasmusto: coventry`: is it more handy than having those forms in a persistant buffer and just have to take one more step to delete it afterwards?

17:55 coventry`: Yes. I don't usually want a record of every dumb thing I tried. When I get the result I want, that goes in a unit test.

17:56 If I learn something substantial along the way about the right/wrong way to do things, that goes in my org-mode notes. :-)

17:56 rasmusto: coventry`: okay, gotcha

17:56 coventry`: are you talking about undo history?

17:58 coventry`: No, I mean using the repl window. E.g. https://www.refheap.com/18560

18:00 rasmusto: coventry`: alright. I appreciate the advice. I bootstrapped my own goofy workflow, so its good to hear how other people do things :)

18:16 callen: ,(get (Object.) :a)

18:16 clojurebot: nil

18:16 callen: yeah aphyr wasn't kidding.

18:18 technomancy: ,(get nil :a)

18:18 clojurebot: nil

18:19 technomancy: wow

18:19 callen: clearly a function after my own heart.

18:19 hiredman: ,(assoc nil :a 1)

18:19 clojurebot: {:a 1}

18:19 callen: ,(assoc (Object.) :a 1)

18:19 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Object cannot be cast to clojure.lang.Associative>

18:20 callen: but nil can? d00d.

18:20 technomancy: yeah_whatever.jpg

18:35 dnolen: CLJS folks I've backed out format/printf - http://github.com/clojure/clojurescript/commit/48c8d0fafc18375876e10caf960a7c7da27ac308

18:36 if I hear a lot of complaints I'll bring it back in but I can't imagine that people used it for much given it extremely limited capabilities

18:36 it cannot be optimized away by GClosure because of it's horrendous design

18:36 so it'll take some convincing for me to move it back in

18:38 this also delivers an extremely clean core.cljs as far as dependencies go - a CLJS program that doesn't use core.cljs now only consists of 10 lines of code.

18:39 sdegutis: I remember saying "I like the idea of Clojure but the JVM startup time just isn't worth it"... back when I was using Bundler. (lol)

18:39 technomancy: grenchman!

18:39 sdegutis: you keep saying that word

18:39 i do not think it means what you think it means

18:39 technomancy: it's a fun word

18:39 * sdegutis screwed up the quote too badly to be recognized

18:40 sdegutis: technomancy: it reminds me of grinch and henchmen every time i read it

18:40 brehaut: heh

18:40 technomancy: that's no good; it should remind you of a high-school skinhead band

18:40 sdegutis: it succeeds in failing at that

19:03 callen: technomancy: I like typing grench :P

19:03 technomancy: grench grench grench

19:04 devn: gwrench


19:09 * noprompt switches to james hetfield mode

19:09 noprompt: M-x james-hetfield-mode

19:10 grench-a. may-na.

19:13 callen: noprompt: I don't think most Clojure users are confronted with the Java that often unless they're tackling weird/arcane problems.

19:13 noprompt: callen: in reference to the tweet?

19:14 callen: when i wrote it i was thinking more of ClojureScript/JavaScript because interop is more in your face there.

19:14 grizninch

19:15 technomancy: the next lib i come up with needs a ridiculous name.

19:15 i always wanted a lib called "blood"

19:16 technomancy: please do

19:16 noprompt: i stole "shodan" from system shock.

19:17 technomancy: https://clojars.org/shodan <- this one?

19:18 (yes, duh)

19:18 apparently your lib has connected to freenode

19:19 SHODAN: please don't kill us

19:19 sdegutis: technomancy: but is grenchman production-ready?

19:20 noprompt: technomancy: there's a clip on youtube with all the S.H.O.D.A.N. quotes.

19:20 technomancy: sdegutis: we are rolling out a full factory run of grenchman units next week

19:21 noprompt: technomancy: be sure to have a counter somewhere on the README that says "X days without an accident."

19:21 sdegutis: shodan... is that the lib that somehow made me end up on the GlaDOS wikipedia page?

19:21 noprompt: sdegutis: haha! yeah! that happened to me too!

19:21 sdegutis: :D

19:22 i havent played portal or portal 2, but ive heard all her quotes. pretty funny stuff.

19:22 noprompt: sdegutis: did you ever play the system shock games?

19:23 sdegutis: only post-SNES games i ever played were Morrowind and Halo 1.

19:23 rasmusto: @_@

19:24 technomancy: the first system shock may have been contemporary to the SNES

19:24 callen: noprompt: yeah that's true.

19:24 noprompt: apparently @polask_1 just started following me. wow. imagine it beautiful girls following me on twitter.

19:24 oh. wait. aww. it's a spammer. this day is ruined.

19:24 technomancy: yeah, 1994. predates Marathon even, wow.

19:25 * sdegutis is close to having 0 issues in my project, yay :)

19:25 sdegutis: and the only non-post-SNES games i really played were Super Metroid and 7th Saga

19:26 oh wait, how could i forget Final Fantasy 7.. i played that one a ton too

19:26 noprompt: super metroid was, as they say in basketball, a "slam dunk."

19:26 sdegutis: noprompt: that comes from basketball? no wonder they looked at me awkwardly at the last superbowl thing

19:27 technomancy: noprompt: I haven't actually played SS1; how does it compare to the second?

19:27 noprompt: was there ever a "First Fantasy"?

19:27 rasmusto: noprompt: this is the only "slam dunk" game IMO: http://www.talesofgames.com/related_game/barkley-shut-up-jam-gaiden/

19:27 noprompt: technomancy: i don't remember much about it. it didn't leave as much as an impression on me as the second one.

19:28 technomancy: going through the wikipedia article brought up old memories and now i'm thinking of replaying them.

19:28 technomancy: noprompt: the second is pretty haunting

19:28 lots of sheer panic moments

19:29 noprompt: sci-fi horror is such a great genre.

19:30 "Irrevocable Fantasy"

19:30 sdegutis: heh

19:30 noprompt: rasmusto: hey remember NBA Jam? where you could, like, dunk from half court.

19:31 rasmusto: noprompt: you mean, "from downtown"?

19:31 noprompt: YES!

19:31 rasmusto: pippin/grant was overpowered

19:31 * noprompt is literally loling

19:31 s4muel: he's on fiiiire!

19:31 * noprompt is rofling

19:31 s4muel: nba jam was the shit.


19:32 sdegutis: alright, that was some pretty high quality bonding, thanks yall. time to hack on a datomic project

19:32 noprompt: there it is. there's the lib name. "shakalaka"

19:32 rasmusto: I knew it would come out eventually

19:33 "sjakalaka"

19:34 sdegutis: i wanted to name all my projects after FFVII stuff. my IDE is named Leviathan and my music app is named Bahamut.

19:34 but i think there's probably legal reasons i cant do that.

19:34 fortunately both those names already come from mythology so i can keep them. but I probably cant, say, name a new lib "Materia"

19:35 Bronsa: why not. "materia" means "matter" in italian

19:35 noprompt: sdegutis: so if i name my kid Bahamut, Squaresoft is gonna sue me?

19:35 or worse, sue my kid?

19:35 s4muel: noprompt: no but your kid is going to be pissed that you named him after such a lowball materia

19:35 brehaut: you could probably name your kid squaresoft and they couldnt do anything

19:36 sdegutis: noprompt: no but if you call it Sephiroth they might

19:36 s4muel: noprompt: name your kid Quadra Magic.

19:36 sdegutis: oh man.. such an awesome materia

19:37 kovas: Bronsa: hows CinC coming? seeing a steady stream of commits

19:38 sdegutis: so i named my lisp interpreter Beowulf. i think its gonna catch on.

19:38 Bronsa: kovas: it's near, it's left to emit fn/deftype/reify and then it should be usable

19:38 kovas: thats awesome

19:38 Bronsa: there's an issue with loop/recur tag inference and primitive support is not exactly tested yet

19:39 kovas: definitely looking forward to studying it once its ready

19:39 noprompt: if technomancy didn't take grenchman i'd name my lisp interpreter that.

19:39 kovas: yeah hard to nail every little thing on the first try...

19:39 any idea what the compilation speed is gonna be like in comparison with the java version?

19:40 Bronsa: to be honest, I think it's going to be pretty slow.

19:40 sdegutis: noprompt: you have one too?

19:40 Bronsa: I havent done any performance work

19:40 kovas: i guess im wondering if its like 10x slower, or a 100x

19:40 Bronsa: kovas: there's plently of room for performance enhancements though

19:40 kovas: if its within the 10x ballpark, some perf improvements should close the gap

19:40 noprompt: sdegutis: oh. i've only written toy lisp interpreters. i helped out with the rouge project for a while.

19:41 Bronsa: is that the Clojure to C compiler?

19:41 kovas: Clojure-In-Clojure

19:41 Bronsa: noprompt: no, it's a clojure to jvm compiler written in clojure

19:41 tufflax: where is cinc hosted?

19:41 `cbp: o_O

19:41 tufflax: or, where is the repo?

19:41 noprompt: Bronsa: that sounds cool?

19:41 Bronsa: https://github.com/Bronsa/CinC

19:42 noprompt: s/\?/./

19:42 kovas: Bronsa: once u get it working, putting some comments in would be very helpful :)

19:42 Bronsa: kovas: yeah, I know :)

19:42 documentation is going to be my main priority once I get everything to work

19:43 kovas: probably more value in that than on polishing the perf etc

19:43 awesome man

19:43 sdegutis: noprompt: ah right, mines probably at toy-level too, but i hope to use it for scripting mac apps: https://github.com/sdegutis/Beowulf/tree/master/Beowulf (doesn't need to be super efficient just for scripting)

19:43 Bronsa: probably more value than in the project itself kovas :)

19:43 sdegutis: i got it to do these things so far: https://github.com/sdegutis/Beowulf/blob/master/BeowulfTests/BeowulfTests.m

19:43 technomancy: Sephiroth is a hasidic concept referring to the names of God

19:43 kovas: yeah i think of the clojure code as a comprehensible explanation of the compilation process

19:43 no way i was gonna read the java

19:44 Bronsa: kovas: CinC is obviously never going to replace the java implementation but it's probably going to be real usefull for experiments/understanding how the compiler works

19:44 yeah, Compiler.java is a mess.

19:44 kovas: Bronsa: I'm not so sure about that statement

19:44 sdegutis: technomancy: only if you spell it differently though :)

19:44 kovas: Bronsa: I think the killer app would be better error messages

19:45 Bronsa: but who knows what technology is more possible with CinC

19:45 tufflax: And having IPersistentMap etc be protocols? That would be nice

19:47 Bronsa: tufflax: CinC is only a port of the compiler, not a full self-hosting implementation of clojure

19:47 that's going to be a lot more work :P

19:47 brehaut: sdegutis: i should mention, that javascript is painfully optimized for one shot runtime performance on webpage load; theres soem pretty horrible crap going on to achieve it

19:48 Bronsa: kovas: I have an open issue for that, it's going to take me a while but that's definitely something I want to try and do

19:48 kovas: Bronsa: yeah thats down the line, but still this is an important project for the long term

19:48 sdegutis: There are 2 things that make ObjC kind of crappy for something like Clojure.. one is that you can't tell when you should use nil or [NSNull null], and another is the lack of runtime reflection on functions, or being able to generate them properly with the right args.

19:48 kovas: (CinC)

19:49 Bronsa: kovas: right now my schedule is: make it work by the end of the GSoC (the end of the week :P), write extensive documentation, performance enhancements/error messages

19:49 sdegutis: Although I have a fix for that which *should* work in 99% of cases, and just have strange bugs if you try to do something super-fancy.

19:50 Bronsa: and hopefully get to standardize the AST between CinC/clojurescript/jvm.tools.analyzer, I'll have to talk with dnolen/ambrosebs for that

19:50 kovas: cool. Id love to see a talk on it at some conference someday

19:50 i think most people don't realize this project is happening

19:51 yet

19:51 Bronsa: yeah, to be honest I havent really publicized it, I want to wait until it's complete/cleaned up before releasing it and announcing it properly

19:52 kovas: yup makes sense

19:53 sdegutis: Bronsa: it'll still need the JVM though to run, right? (or node)

19:53 Bronsa: yes

19:55 noprompt: i'm not very good at "selling" clojure.

19:55 sdegutis: noprompt: thats cuz its free

19:55 noprompt: :)

19:56 sdegutis: noprompt: I've found that nobody starts giving Clojure a serious look until they're finally fully fed up with other languages.

19:57 rhg: is just a raw (let ...) ok for side effect code or should i do (do (let ...))?

19:57 sdegutis: noprompt: And no matter what language it is, people are usually content with whatever inconsistencies or poor abstractions of convolutions it has, whether it's C++ or Ruby or Python or Perl or Common Lisp

19:58 rasmusto: rhg: let has an implicit do

19:58 rhg: ik

19:58 i mean for style

19:58 rasmusto: rhg: ok, can't speak to style :)

19:58 noprompt: sdegutis: a friend of mine pinged me saying "i need a new platform for web development".

19:58 rhg: ya

19:59 rasmusto: rhg: maybe put it in a function with a ! in the name

19:59 s4muel: rhg: (defn side-effecty-fn! [] (let ...

19:59 hive mind

19:59 rasmusto: hive mind!

20:00 rhg: its a multimethod, not my choice

20:03 basically it calls alter-meta! to insert a key and returns the value of the key

20:06 squidz: does anybody know why i'm getting this schema errror https://www.refheap.com/18562

20:07 sdegutis: My wife and I can't figure out what the Grenchman comic is referencing.

20:07 She pointed out that it's Simon Cowell, that part I didn't get.

20:07 But still..

20:07 technomancy: hint: it is a hyperlink

20:08 sdegutis: Oh. heh.

20:09 squidz: something is wrong with the stacked-power-form map. When I type in a simpler map it works, but I can't figure out why that map throws that error

20:09 rhg: https://www.refheap.com/18563

20:09 its the fn

20:10 squidz: rhg: what fn?

20:11 technomancy: sdegutis: you might have to go back a bit to get context

20:11 rhg: the multimethod im extending

20:11 technomancy: achewood is very high-context humor

20:11 sdegutis: oh

20:15 rhg: actually my real intent is a cache of sorts, maybe a global memoized html-resource fn, but thatd remove the ability to easily remove something from cache

20:15 clojurebot: Alles klar

20:16 technomancy: clojurebot: say something unexpected

20:16 clojurebot: No entiendo

20:16 rhg: ah

20:18 i had it not cache and even on my inet a few requests took too long

20:21 has anybody used core.cache?

20:21 ddellacosta: rhg: yes

20:21 rhg: hmm

20:25 hiredman: rhg: I would be surprised if anyone uses core.cache directly, I imagine most people who use it actually use core.memoize

20:25 rhg: ah

20:25 sdegutis: How should macros work in an interpreted (minimal) version of Clojure?

20:25 rhg: thx

20:27 sdegutis: I figured they should just be functions that have different evaluation rules: they're called with their args un-eval'd, and the return result gets eval'd. Should be that simple, right?

20:27 noprompt: rouge looked really neat btw, I wonder why it didn't gain much traction

20:27 And why rouge.io is dead

20:28 R_Macy: haha, so the discussion is somewhat relevant with the problem I'm about to has for help with

20:28 I'm getting the following stack trace: No such var: clojure.core.cache/through, compiling

20:28 When trying to: lein with-profile production trampoline run -m app.web

20:29 %/has/ask

20:29 Poking around on the web, and not seeing anything obvious

20:29 rhg: hmm, core.memoize may really help here

20:29 noprompt: sdegutis: we just stopped working on it.

20:30 sdegutis: simple as that.

20:30 clojurebot: It's greek to me.

20:30 sdegutis: noprompt: heh

20:30 technomancy: hrm; I thought I had a dumb defmacro working in bus scheme

20:30 but I can't find it

20:30 hiredman: R_Macy: you are refering the name clojure.core.cache/through with out loading the clojure.core.cache namespace

20:30 noprompt: sdegutis: also, i couldn't understand some of the code so i wasn't sure how to do things i wanted to do.

20:30 sdegutis: noprompt: happens to the best of projects

20:31 (or something)

20:31 R_Macy: hiredman leiningen must be doing, because I definitely am not

20:31 this is almost a base leiningen heroku template with minor modifications

20:32 noprompt: installing software and setting up a server is boring.

20:32 s4muel: R_Macy: And you've got org.clojure/core.cache in your project.clj dependencies?

20:32 technomancy: R_Macy: if it works in a repl then it must be pulled in by your dev deps or something

20:32 R_Macy: I'll try adding it to my deps

20:32 technomancy: you need to declare it explicitly if you use it directly

20:35 R_Macy: Very odd, I must be using a project that depends on it implicitly

20:35 including it in project.clj worked, thanks for the help

20:35 technomancy: it's not that odd

20:36 R_Macy: I think it's odd that it wasn't included in the template that has projects that depend on it

20:37 aka: noprompt: you've obviously never done a bunch of cocain with a drunk stripper and provision a server before.

20:38 noprompt: aka: wut? where is that going down?

20:38 aka: that sounds neat.

20:38 technomancy: R_Macy: it's not a dependency of the heroku template

20:38 aka: noprompt: it's the only way to provision

20:38 noprompt: aka: i knew i was doing something wrong.

20:40 what am i doing with my life?

20:40 aka: Well now you know. I like to think I might have changed your life for the positive.

20:40 noprompt: aka: i think so.

20:41 aka: I like to think I did something good for the stripper and did a decent deploy too. We both know I didn't.

20:43 Anyone have a suggestion for a library for creating and altering torrent files?

20:43 noprompt: aka: the sad thing is i stopped drinking months ago. now, no one calls or texts.

20:43 aka: perhaps cocaine and strippers will get me out of this sober funk.

20:44 aka: noprompt: I'm just getting out of my stop drinking heavy for a few years phase. I was pulling a real noprompt for a few years but I'm snapped out of it now.

20:44 s4muel: ...six weeks later: that didn't go as planned.

20:45 aka: How many times has a night ended in a total blackout after starting with a proclamation of absolute sobriety?

20:45 noprompt: technomancy: cartilage head.

20:45 aka: More times than not I'm afraid.

20:52 noprompt: wow. yeah i just stopped drinking cause it was expensive and distracting.

20:52 geoffeg: I feel like this is much, much more complicated than it needs to be. Any suggestions? https://gist.github.com/geoffeg/6531708

20:55 noprompt: geoffeg: use a multimethod

20:55 aka: I'm finally getting into some serious development with clojure after about a year of full intentions to play with it. I'm curious if there is any value in using a lib like 0mq and proto buffers, or if I should try to enjoy some of the more "pure" facilities that clojure provides to handle that. Anyone have a suggestion in regards to that? I'm building a system that will be processing data in parallel locally

20:55 but communicating to other nodes as well as distributing "large" files to all the nodes.

20:55 noprompt: geoffeg: also use keywords. {:cat "meow"}

20:56 geoffeg: also break up your code in to smaller functions that have a purpose.

20:56 technomancy: aka: if you can use a centralized message broker your architecture will be dramatically simpler

20:56 aka: agreed

20:57 geoffeg: hmm, i tried it as a multimethod yesterday and decided it wouldn't work for some reason i can no longer remember :)

20:58 i'll try again

20:59 technomancy: you can try 0mq, but unless you have really unique requirements I would recommend against it for your first clojure project

20:59 geoffeg: something to do with needing to pass different params to the methods than was passed into the mutlimethod

21:03 callen: don't use 0mq for your first clojure project, yeesh.

21:03 aka: To be clear I am very comfortable with 0mq is the only reason I'm dragging it into this. Ideally this system wouldn't require a central message broker but I'm thinking I'll go that route. wow my life just got about 10x easier just from that little talk.

21:04 callen: aka: well, if that's kosher, you might as well go the whole way and use the core.async 0mq library for Clojure.

21:04 aka: Anything I should know about protocols before I dig in?

21:05 technomancy: don't use protocols on your first clojure project either

21:05 or rather, on your first non-oo project

21:06 aka: Great, I don't get to do anything cool. I guess this app will just have to work instead.

21:07 technomancy: sorry; if you wanted fresh and exciting try #elixir-lang =)

21:07 aka: lol

21:07 noprompt: aka, technomancy is actually giving good advice. he gave me the same advice when i first came here and i'm glad he did.

21:08 aka: Yeah I am def not arguing it.

21:08 noprompt: no. fuck that. we're arguing now.

21:08 technomancy: I still haven't worked on any projects that justified use of protocols

21:08 aka: It is a little frustrating when people don't let you shoot yourself in the foot.

21:08 yeah you're right I'm pissed

21:08 right?

21:09 technomancy: also for goodness sake don't write any macros

21:09 aka: I probably just have a limited *mis*understanding of what protocols are and what they provide

21:09 noprompt: technomancy: how would you do something like hiccup or garden w/o asking map?, vector?, or checking keys/meta?

21:09 just out of curiosity.

21:09 oh and btw, this an an argument. we're totally arguing right nwo.

21:10 *now

21:10 bbloom: noprompt: what's wrong with asking map? vector? etc?

21:10 technomancy: noprompt: hiccup doesn't have any runtime polymorphism afaik

21:10 noprompt: bbloom: hiccup uses protocols.

21:10 technomancy: isn't it all precompiled into functions that take strings?

21:10 aka: oh sweet I have to use hiccup then

21:10 noprompt: whoops, that was @ technomancy

21:11 bbloom: i don't think there is anything wrong with map? vector? etc?

21:11 aka: noprompt: could you do me a favor and spell "now" correct the first time when we are arguing

21:11 it would me a lot

21:11 noprompt: aka: oh wut? oh no you didn't. that's it dawg the glove are off nwo.

21:11 *now

21:12 callen: noprompt: are you trying to dethrone me as resident belligerent Clojure user?

21:12 noprompt: technomancy: so the record/protocol stuff is for perf?

21:12 technomancy: noprompt: yes

21:12 noprompt: or as i like to call it, "PERF madness"

21:12 bbloom: noprompt: and interop with java's interfaces

21:13 noprompt: bbloom, technomancy so should i go an pull out all the protocols/records in Garden?

21:13 technomancy: noprompt: what's Garden?

21:13 bbloom: it's also useful if you need to do some horrible dependency injection-style nightmare thing where you have alternate Whateverers that implement Whateverable

21:13 aka: man I love fighting on irc... I'm just tuff as shit on here

21:14 bbloom: which i've only never needed when interoping with broken ass libraries :-P

21:14 noprompt: technomancy: it's a Clojure -> CSS lib like hiccup

21:15 technomancy: noprompt: don't fix what isn't broken, but it doesn't sound like a good fit

21:16 callen: noprompt: yes

21:16 noprompt: technomancy: well, hypothetically here.

21:16 callen: noprompt: rip them all out. Do it for Lord Satan.

21:17 noprompt: technomancy: seriously. some insight would be nice. i feel like people never give me honest opinions. :-/

21:18 callen: I'm always honest.

21:18 technomancy: noprompt: I don't know anything about CSS

21:18 noprompt: i'm not gonna get "butt hurt" as they say.

21:18 callen: noprompt: protocols and records are probably unnecessary in Garden and you should remove them if you're willing to actually do so.

21:18 noprompt: s/\(they\)/"\1"

21:18 technomancy: if you were just starting, I would first ask if you really need polymorphism, and if you were really sure you did I'd tell you to use multimethods, which are a lot more flexible

21:19 because I can't imagine dispatch ever being a bottleneck

21:19 noprompt: callen: i would be willing to.

21:19 callen: just use maps and functions. If you need polymorphism - maps and multimethods.

21:19 and be *sure* of whether or not you actually need polymorphism.

21:20 noprompt: CSS has a lot more to it than HTML.

21:20 callen: I understand CSS just fine.

21:20 sdegutis: noprompt: alternatively you can use protocols and defrecords

21:20 technomancy: (css [:h1 :h2 [:a {:text-decoration "none"]]) ;-> "h1 a, h2 a{text-decoration:none}"

21:20 sdegutis: noprompt: or Ruby

21:20 noprompt: i could represent things as maps sure. but then during the compilation i'd be constantly frisking every map checking for keys.

21:21 sdegutis: that's what we're talking about.

21:21 aka: You guys make it sound like adding unneeded complexity is a bad thing :)

21:21 callen: ^^ do ho ho ho

21:21 sdegutis: noprompt: sounds like protocols and defrecord is what you want

21:21 callen: probably not.

21:21 technomancy: ^ I would have structured this as {[:h1 :h2] {:a {:text-decoration "none"}}} because you're mapping several things to one value

21:21 noprompt: sdegutis: that's what i have. that's what were talking about not having.

21:21 technomancy: unfotunately order matters in CSS

21:22 sdegutis: noprompt: oh, ok. why go away from protocols and defrecord?

21:22 technomancy: noprompt: ah, gotcha. yeah, I don't know the semantics enough to comment on polymorphism

21:23 sdegutis: noprompt: heh yeah, I got bit when translating my CSS to garden, because I often get lazy and do "margin: 30px; margin-left: 20px;"

21:24 noprompt: sdegutis: that's why i tell people to use multiple maps if order matters.

21:24 sdegutis: noprompt: oh I didn't realize you could do that, cool

21:24 noprompt: sdegutis: i think you can also use an ordered map too but that doesn't "look cool"

21:24 sdegutis: :D

21:24 it will once you define a reader macro for it

21:25 noprompt: sdegutis: oh yes, there's that. :)

21:25 sdegutis: i have reader macros defined for the unit functions like #px

21:26 seangrove: noprompt: https://github.com/flatland/ordered

21:26 noprompt: technomancy: but is that the idea? to check for specific keys, etc?

21:26 seangrove: You could write a custom reader if you wanted it to look cool

21:27 sdegutis: noprompt: I tried to use those but wasn't finding that they helped any

21:27 Maybe with a better syntax highlighter they would have helped.

21:27 noprompt: sdegutis: everyone has things that work/don't work for them.

21:27 sdegutis: Unfortunately I can't allocate any spare time to work on my own IDE that might be able to fix that, because I've got to spend all my energy converting our site from MongoDB to Datomic.

21:27 * sdegutis grins

21:31 noprompt: sdegutis: really the idea was to have a format as the base to build on top of. ideally garden stylesheets should look like clojure code.

21:36 sdegutis: noprompt: ah that makes sense

21:37 noprompt: sdegutis: in fact, i plan to update the README to encourage people to use the at-media function instead of the meta directly.

21:37 sdegutis: hmm interesting idea

21:37 noprompt: sdegutis: i've been making a lot of changes to the lib over the past couple weeks and there are lots of breaking changes in v1.0.0

22:05 coventry`: Why is import* interned as clojure.core/import* rather than just import*, like all the other special symbols?

22:15 clj_newb_2345: are there any clojure libraries for sending android push notifications ? (without having to install an ap on the android device)

Logging service provided by n01se.net