#clojure log - Nov 19 2012

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

0:09 ForSpareParts: arrdem, It's a good thought, though I'd like to be able to do a play/pause/rewind sort of thing -- I'd need some kind of caching trickery to remember recently-used versions in order to get efficient enough behavior.

0:13 arrdem: ForSpareParts: my concern is that in making such a cache of usable size you would either blow out your memory limit or end up serializing entire states by saving a full snapshot as opposed to the changes.

0:15 adiabatic: (cross-posted from #noir) green-as-grass newbie question: I put (defpage "/my-page" …) into my views/welcome.clj like the default website said to, but I get an error in the server console of "Caused by: java.lang.RuntimeException: Unable to resolve symbol: html in this context". Where is `html` supposed to come from?

0:15 ForSpareParts: arrdem, That's what's been on my mind, yeah. I'd have to allow the user to set some kind of limit and let data beyond the limit fall out of the history, I think.

0:17 arrdem: ForSpareParts: one thing you could look into is retaining "cursors" or reset points at some interval in the history. That way if you want to back up you don't have to integrate from t=0 but you don't continually dump either.

0:17 so if you say I will retain three snapshots at 100, 200 and 300 changes back, reverting in that range should be pretty fast.

0:17 beyond that, the user is on their own.

0:25 det4l: Does anyone have any good resources for someone who understands the lisp stuff but wants to understand the java stuff like the classpath, serverlets, javabeans, etc?

0:28 Sgeo: det4l, nice to meet someone in the same boat as me

0:29 I'm a Haskellish Lispish person

0:29 Not much of a Java person

0:29 Actually, I think there are others here in that boat

0:29 It's not a very rare boat

0:46 unnali: Sgeo: I'd say it's quite common. :)

0:46 Java's definitely not my thing.

0:47 yedi: how important is java knowledge when coding?

0:47 Foxboron: yedi, not very.

0:47 You will end up needing some knowledge about JDK and java compiling and what not

0:48 basically, you dont need anything before you start as you get what you need along the way :3

1:05 muhoo: you'll learn more java than you ever wanted to

1:05 unnali: hahaha

1:31 wbs_: hi to all!

1:31 i'm using compojure and ring

1:32 how i can use booth: wrap-session and wrap-json-params ?

1:33 arrdem: wbs_: I suspect that both are macros that provide some preprocessing... check out the source and see if you can create something equivalent to composing them?

1:51 aperiodic: you use the arrow macro

1:52 (-> routes wrap-x wrap-y)

1:59 arrdem: wbs_: aperiodic's got you, sorry for sending you off on a rabbit trail.

2:00 Sgeo: Why do I think of (Object.) as being so heavyweight when it's probably the lightest-weight thing I could make?

2:01 It suddenly occurs to me that primitives are lighter

2:02 wbs_: aperiodic yes, but in parsed json map i can't find session...

2:33 aperiodic: wbs_: odd, wrap-session works fine for me

2:33 wbs_: what do you mean by "parsed json map"?

2:39 Apage43: Sgeo: probably the scary . that means you're in "interop land". How does (keyword (gensym)) feel in comparison?

2:41 Sgeo: (keyword (gensym)) looks like it should be so much more lightweight, even though I know it isn't

2:41 I think it's the interop thing, yeah

2:41 And also the capital O for some reason

2:43 Apage43: (defn obj [] (Object.)) ;)

3:28 wbs_: aperiodic if wrap-session is single macros it's ok. but if i want use wrap-session with wrap-json-params it doesn't work

3:45 Sgeo: ,(and)

3:46 clojurebot: true

3:46 Sgeo: ,(or)

3:46 clojurebot: nil

4:10 bbloom: any word on when/if the conj videos will be available?

4:23 tomoj: so say you want a macro which walks a body passed to it, replacing invocations of some var with invocations of another

4:24 if the macro is called in a scope where the name of the var is clobbered by a local binding, and you pass the env to resolve, you're good

4:25 but what if the clobbering occurs inside the body passed to the macro?

4:42 scottj: bbloom: have heard they will be made available, but I'd guess on a rolling release starting in a couple weeks and lasting several months

4:42 bbloom: scottj: thanks. too bad i couldn't have made it there in person :-/

4:42 scottj: bbloom: I think confreaks did the recording, so maybe they'll be on their site instead of blip

4:43 bbloom: scottj: k, i'lll keep an eye out

4:45 scottj: bbloom: confreaks did rubyconf which happened ~nov2 and they just posted all the videos, so maybe you'll get them in 3 weeks

4:45 bbloom: scottj: heh nice :-)

4:46 scottj: hopefully just in time for holiday travel

4:46 scottj: I think rolling release like infoq does is smartest (most exposure/more views), but I sure like getting em all at once

5:06 merodach: can you explain me what exacty the difference is between commute and alter?

5:07 as i understood sofar, if there is a modification on ref while transactions started with alter, the transaction will be rolled backed and will be retried with the updated value ?

5:09 and with commute, we got always updated value while running in a transaction?

5:11 bbloom: merodach: the difference has to do with retries and failures

5:11 alter does a compare and, if the value has changed, will cause a retry

5:11 commute, however, will apply the operation regardless

5:11 merodach: explaination here http://comments.gmane.org/gmane.comp.java.clojure.user/27176

5:12 however, my experience has been that atoms are more pleasant to work with. if you need multiple values updated together, you can just stick a map in your atom

5:12 swap! and reset! are pretty easy to understand compared to refs

5:13 i'm not even sure when i'd ever use a ref instead of an atom

5:15 also interesting: http://blog.jayfields.com/2011/04/clojure-state-management.html

5:15 tomoj: ants seems like a pathological example

5:15 bbloom: tomoj: ?

5:15 kral: namaste

5:16 tomoj: ants.clj

5:23 bbloom: tomoj: merodach hm yeah, i guess it makes sense when you have like 1 ref per thread and want some threads to communicate together

5:23 hadn't considered that…. i'm so used to having just one IO thread in my apps

5:24 tomoj: heh, thanks. some shit just clicked in my head from skimming that code. hadn't seen it before

5:24 https://github.com/johnlawrenceaspden/hobby-code/blob/master/ants.clj is the version i found

5:25 merodach: it means that the commute allows non-repeatable reads, and can cause with update failures ... etc.

5:27 bbloom: merodach: the name (and doc string) suggests the intended behavior of commute: the function you give it should be either commutative, or you accept last-one-in-wins. the idea being that the order between threads is less strictly enforced

5:27 merodach: for example we've got 2 transactions, A and B. A starts with a tranaaction and reads the counter = 2, whereas the B increments the counter to 3. but the A doesn't know that the counter has a new value

5:28 pyr: hi

5:28 merodach: and A increments also the counter to 3

5:28 and commits

5:29 bbloom: if i follow you, then alter will cause a retry, but commute should increment the counter to 4

5:30 merodach: hm *confusing*

5:30 here found a pretty good article about this

5:30 which confirms my assumptions

5:30 http://squirrel.pl/blog/2010/07/13/clojure-alter-vs-commute/

6:22 ground: Hello how can i get to th dll lib on win32 via clojure script?

6:23 I dont really an expert in this stuff so i need solution as simple as possible

6:25 maleghast: ground: I'm sorry I don't even understand what you are asking… What are you trying to achieve?

6:25 clgv: ground: describe you problem in more detail, maybe by example

6:28 ground: Ive got a script in vba that is able to work with for example ie or lotus notes (i understand it works with com objects) and i am intersting in how its looks like from the "clojure point of view" ?

6:28 And shall i need some java knowledge?

6:29 ucb: ground: if you're going to do pure clojure you don't need to know much java (I don't know more than the basics really)

6:30 ground: More less i know how it works on vb c# and ruby (win32ole)

6:30 tomoj: &(clojure.pprint/pprint '(clojure.core/deref foo))

6:30 lazybot: ⇒ @foo nil

6:30 maleghast: ground: I've got to be honest, I've not written any VBA for years, but I am not particularly optimistic that you'll be able to easily write Clojure to interface with COM Objects...

6:30 ucb: ground: you may want to check the CLR compiler/interpreter for clojure if you want to do OLE


6:37 * maleghast raides an eyebrow at Raynes

6:37 maleghast: s/raides/raises

6:37 Raynes: Don't raid my eyebrow, man.

6:37 I've been through enough.

6:37 maleghast: Raynes: Hey, I figure, but it was a typo

6:53 ivenkys: gents - looking for suggestions on small Clojure projects - for newbs

6:54 maleghast: ivenkys: Are you looking for "stuff to do" or __actual__ cookbook-esque projects?

6:55 ivenkys: maleghast: either i think -

6:56 alexnixon: &[(take 2 []) (drop 2 []) (take-last 2 []) (drop-last 2 [])]

6:56 lazybot: ⇒ [() () nil ()]

6:56 alexnixon: why does take-last return nil?

6:56 ivenkys: maleghast: fwiw - i have been through the Koans - (which i love) - and have done pieces of code converting from Java to Clojure - what would be good is if i can do a something small , as in manageable that would increase confidence and also allow me learn more

6:57 maleghast: ivenkys: Well, for the former I would tend to recommend Project Euler (http://www.projecteuler.net/) and 4Clojure (http://www.4clojure.com) and then there are some commonly discussed standards like Towers of Hanoi, Game of Life etc. You could also look at getting the newbs in question into fun libraries like Quil and Overtone

6:57 tomoj: alexnixon: looks like an implementation detail, take-last doesn't return a lazy seq

6:58 tgoossens: i'm searchig some examples of games writtten in clojure that don't use any identity

6:58 maleghast: As for actual projects… I'm a middleware developer and sometime web-dev, so my natural bias is toward suggesting something like porting an existing app into Clojure, using compojure (for example), but there a million different things that you could do

6:58 tkoskine: ivenkys: I am writing a compiler (for a very simply language) to learn Clojure. :)

6:58 alexnixon: tomoj: not being lazy makes sense, given it needs to count (and so realise) the entire seq

6:58 tkoskine: s/simply/simple/

6:59 alexnixon: tomoj: still, why does it return nil and not an empty list?

6:59 ivenkys: maleghast: good suggestions - had forgotten about Euler

6:59 tomoj: those aren't empty lists, they're empty lazy seqs

6:59 ucb: ivenkys: I'd also recommend you read http://prog21.dadgum.com/80.html

6:59 tomoj: take-last's definition could seemingly have been wrapped in (lazy-seq ...) like the others

6:59 ucb: ivenkys: it's so far the best advice I've found for your question

7:00 ivenkys: tkoskine: ah -.. - always the best way

7:00 ucb: let me take a look at that -

7:01 ucb: fwiw - i love James Hague's writing - no-bs and it fits on 1 screen :-)

7:01 maleghast: ucb: That is good advice, as long as it allows for the idea that sometimes people just need a little inspiration as well

7:01 ucb: ivenkys: yes :)

7:01 maleghast: yes too :)

7:01 maleghast: :-)

7:01 ucb: in any case, I used to not take that advice to heart, now I do

7:02 ivenkys: maleghast: ucb : tkoskine : gents , thanks for this - lots of food for thought there - i am taking it a week at a time and see how far i go in 4 -

7:02 ucb: ivenkys: g'luck

7:02 maleghast: ucb: Oh I completely agree - that advice / mindset is why I don't have any haskell, scala or io source code on my laptop right now… I'm fascinated by all 3 of them but I have no use for them whatsoever :-)

7:02 tkoskine: ivenkys: No problem. Actually, I am killing 2..3 birds with one stone. I am also learning Antlr4 (beta) and making parser with it, and then studying all different compiler optimizations at the same time.

7:02 ucb: maleghast: heh, good stuff

7:02 ivenkys: ucb: danke schon

7:04 tkoskine: fantastic - any specific "type" of simple language / parser

7:04 alexnixon: tomoj: given the truthiness of (lazy-seq nil) and nil are different, do you think there's an argument for take-last to return a lazy sequence for consistency (despite it not actually being lazy)?

7:04 tkoskine: ivenkys: Code is at https://bitbucket.org/tkoskine/antlr-ir/src - The syntax of the language is similar to Pascal/Ada/Oberon.

7:06 tomoj: alexnixon: I dunno, maybe

7:06 if you're testing truthiness of seqs you almost surely should be calling seq on them anyway

7:06 tgoossens: in java when making a boardgame with "Piece" objects. I could give the piece a method ".canSharePositionWIth(Piece piece)". Which i think is a good way of encapsulating that logic. How would you achieve the same in clojure?

7:06 * a function in the map?

7:07 the advantage of .cansharePosition is that I could "double dispatch"

7:07 ivenkys: tkoskine: thanks for that - i am going to take a look at it -

7:07 tomoj: which makes me realize, clojure makes a mistake analogous to the havoc I imagined wreaking on Reactive's Event monad

7:07 tgoossens: what is the idomatic way of doing a similar thing in clojure?

7:07 tomoj: (er, but maybe it's not a mistake)

7:10 tgoossens: it is hard to see how double dispatch would be advantageous there

7:11 tgoossens: well

7:11 for example

7:11 robot.cansharepositionwith(wall)

7:12 it is possible that robot has only information that it cannot share position with another robot. And then asks the caller what he thinks about it

7:12 the wall knows it cannot share position with anything

7:12 an item

7:12 can share positiion with anything but a wall

7:12 which will become clear out of the double dispatch

7:14 or am i complecting stuff here?

7:14 if so. what would be a simpler way of doing this?

7:15 Raynes: You just used the word 'complecting'. You're already a master Clojure programmer.

7:16 tgoossens: i've been doing 2 months investigating and learning from talks. I'm trying to become aware of those things.

7:16 And as an exercise

7:17 last year i had a project (board game) in java (for university). And want to see how i would achieve the same

7:17 in a functional, idiomatic clojure way

7:17 maleghast: Raynes: *applause*

7:17 tgoossens: lol

7:18 tomoj: how do you know not to do triple dispatch?

7:18 and quadruple, and ...

7:18 I mean, what if both objects say "I dunno, ask the other guy"?

7:18 tgoossens: mmyes

7:19 a piece is just a "map" in my code

7:19 clojurebot: Roger.

7:19 tgoossens: would it be a better idea to

7:19 add a key

7:19 :canshare (fn [piece] ....)

7:20 tomoj: I mean, in your java double dispatch, how does it stop at 2?

7:20 tgoossens: because only two objects are involved?

7:21 tomoj: consider: (defmulti can-share? (fn [a b] (type a)))

7:21 tgoossens: mmm

7:21 multimethods

7:21 and perhaps using taxonomies?

7:21 because i don't want to edit

7:22 every method everytime that i introduce a new sort of piece

7:22 nor edit

7:22 tomoj: (defmethod can-share? [:robot] [a b] (and (not= :wall b) (can-share? b a)))

7:22 tgoossens: tomoj: now you are using double dispatch arent you?

7:22 tomoj: I'm trying to figure out what you meant

7:22 tgoossens: yes

7:23 now i'm starting to think about it

7:23 tomoj: if we did stuff like that, how would it not recur indefinitely blow the stack?

7:23 s/blow/and blow/

7:23 tgoossens: its actually pretty complex. To figure out how, why and when the dispatching will stop

7:23 tomoj: (also it probably shouldn't be #'type in the defmulti..)

7:24 tgoossens: tomoj: what do you think of my idea of using a function in the map? and using taxonomies

7:25 tomoj: well

7:25 I don't really understand the domain

7:25 putting the functions in the maps seems strange

7:26 tgoossens: mmm

7:26 tomoj: but I'm not sure what can-share? should mean

7:26 tgoossens: wait

7:26 i'll put it on pastebin

7:27 tomoj: multimethods might make sense

7:27 tgoossens: probably

7:28 what must change when i introduce a new type of piece

7:29 tomoj: I can't see past the double dispatch issue

7:29 but if you have a default implementation, then nothing necessarily at all must change

7:30 tgoossens: tomoj: http://pastebin.com/brrRtqsS

7:31 tomoj: I'm guessing those are three separate files?

7:31 tgoossens: yes

7:32 just extracted the relevant methods out of them

7:32 tomoj: so in order to determine that the stack will never blow, you have to look at all three files and keep them all in your head at once?

7:32 tgoossens: yes that's crazy

7:32 hence i task. whats an easier way?

7:32 tomoj: I imagine instead representing all that information in one def

7:32 but not sure how..

7:32 tgoossens: Because i think it is reallly difficult to figure out. And be sure that there won't be an infinite

7:33 dispatching

7:33 also doubting whether "complex" or "hard" is more relevant here

7:35 tomoj: just thinking: (defmulti can-overlap? (fn [a b] (set (:type a) (:type b)))) (defmethod can-overlap #{:robot :robot} [a b] (= a b))

7:35 eh :(

7:36 that doesn't work out

7:37 tgoossens: that will get really bloated after some time

7:37 and really difficult to keep track

7:38 whether you have all cases

7:38 Raynes: Games are hard.

7:38 Stop programming and just be sarcastic like me.

7:38 tomoj: well

7:39 tgoossens: raynes: that was really useful advice ;)

7:39 :p

7:40 tomoj: does it make sense to ask if a robot can share position with itself?

7:40 tgoossens: that's what happens now

7:40 and that what's makes the dispatching stop

7:40 from going infinite

7:40 piece1.canshare(piece2)

7:40 tomoj: if the domain is really about the different types of things, you can represent the allowed configurations without worrying about identities

7:41 tgoossens: if piece1 doesn't know it

7:41 it will call

7:41 piece2.canshare(piece1)

7:41 if piece2 doesn't know it

7:41 hmm no

7:41 no sorry

7:41 i'm wrong

7:42 tomoj: I mean, obviously an individual piece can share position with itself, always

7:43 tgoossens: yes of course

7:43 thats trivial :p

7:43 tomoj: the simplest representation I can think of of the information in your paste is #{#{:robot :item}}

7:44 which could be interpreted to mean that there is one allowed configuration of piece types for a given location, any number of robots and items

7:45 well.. #{#{:robot :item} #{:wall}} ?

7:46 tgoossens: got to go. i made a post in the clojure google group

7:46 still got to be approved

7:47 so thanks already

7:47 and maybe we speak again

7:48 tomoj: (every? (partial subset? pieces) #{#{:robot :item} #{:wall}})

7:48 oslt?

7:48 5am :<

7:48 tgoossens: wow :p

7:49 ucb: anybody experiences with aleph/gloss in here? :)

7:49 tgoossens: almost 2pm here :)

7:49 ucb: *experienced

7:49 tgoossens: bye

7:49 tomoj: anyone?

7:49 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

7:49 tomoj: incidentally, yes, some..

7:50 ucb: heh

7:50 well, I'm wondering how I can represent the following protocol in gloss

7:50 tomoj: but that doesn't mean I can help you, so better to just ask the question :)

7:51 ucb: the client sends a single byte with 110, and the server responds with multiple messages shaped like :int64 (string :utf-8)

7:51 that's fine, but the thing is this is all TCP and afaik, you can't really just decode messages in an aleph tcp-client since it's all streaing, etc. so you have to have your client have the frame at hand

7:52 that's fine if you use headers, but in this case the frame should be able to infer from the 1st byte whether it's a single byte frame or a 4-byte+string frame

7:52 and I just can't figure out how to do it :(

7:53 tomoj: why infer that?

7:54 server only ever sees the one-byte frame, and client only ever sees the 4-byte+string frame?

7:57 ucb: tomoj: sure, but afaik (keep in mind I'm not too knowledgeable in all things gloss/aleph) since it's TCP (I read this in the aleph google group) you can't just read a message from the channel and manually decode it

7:57 tomoj: so you have to create the tcp-client with :frame the-frame

7:57 tomoj: and then just (encode @client {:some "data"})

7:58 tomoj: assuming the frame has a header and can decode back and forth between server and client messages

7:58 tomoj: to be honest, I'd rather do the manual decoding, and that's how I started. But this cant-really-decode-tcp thing rained on my parade :(

8:00 tomoj: oh, of course

8:01 ucb: so, most other messages in the protocol have a reserved byte for req/resp detection; that's the easy bit, but this other one really sucks :(

8:01 unless I break the 4 bytes in the response in :byte :byte :int16 and then glue them together myself?

8:02 tomoj: I think you can pass separate frames for :encoder and :decoder

8:02 ucb: oh? that'd be ideal!

8:03 tomoj: like (tcp-client {:host "localhost", :port 10000, :encoder (compile-frame :byte) :decoder (compile-frame [:int64 (string :utf-8)])}) ?

8:03 ucb: tomoj: I truly hope that works; let me try

8:04 tomoj: hmm

8:05 I don't think I actually understand the code I was looking at, but maybe it works ...

8:06 see doc for start-tcp-server

8:21 Anderkent: Anyone used clj-http? I'm having issues getting it to work with multipart requests

8:21 ucb: tomoj: sorry, real life got in the way, I'm going to try your suggestion now

8:23 tomoj: where in the src did you see what you saw? https://github.com/ztellman/aleph/blob/perf/src/aleph/tcp.clj

8:28 tomoj: perhaps you meant https://github.com/ztellman/aleph/blob/perf/src/aleph/formats.clj#L464

8:31 deu5: Hi. Do you know any bigger and more mature clojure framework then Noir ?

8:34 ucb: tomoj: that did it; thanks!

9:26 rodnaph: hi - i'm trying to use cljs-watch but getting NoClassDefFoundError clojure/main (have clojurescript and cljs-watch on my path already) - anyone know this tool, something obvious i'm missing? thanks

9:26 ping ibdknox if ur online ;)

9:29 oh actually... i'm trying to use cljs-watch from a non-leiningen project - is this why it's not finding clojure?

9:30 hmm... no, cljs-watch seems to set the cp to use clojure from the clojurescript_home folder...

9:34 gauravag: Hey any suggestions for testing?

9:48 madsy: Is there a tried-and-tested database library for Clojure?

9:48 I'd prefer a SQL backend, but anything goes really

9:48 znDuff: madsy: Lots of 'em. I suggest SQLAlchemy if you're not sure what you want.

9:49 madsy: znDuff: Thanks

10:05 antares_: madsy: clojure.java.jdbc, database clients on http://clojurewerkz.org all count as battle tested

10:09 oskar: I'm doing some Java interop, the Java constructor is defined Fields(Comparable... fields), so I need to pass an array of Comparables, right? How can I construct one of those from a seq for example?

10:15 ucb: ,(doc into-array)

10:15 clojurebot: "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."

10:16 ucb: oskar: ˆˆˆˆˆˆˆ

10:21 oskar: ucb thanks

10:21 ucb: np

10:48 jheander: good morning!

10:49 rodnaph: late afternoon here ;)

10:50 jheander: nice :)

10:50 ro_st: same. south africa?

10:50 rodnaph: uk

10:51 good morning to you anyway jheander

10:52 * vijaykiran mumbles - http://www.total-knowledge.com/~ilya/mips/ugt.html

10:52 jheander: If I have a piece of code that makes calls to a different module and I want to break this out to a separate library and be able to replace the module with a bunch of modules that all contains the same function signatures. How can I do this idiomatically in clojure? Protocols or multi methods?

10:53 or maybe some dynamic namespace loading?

10:53 rodnaph: vijaykiran: :O ...

10:54 znDuff: jheander: That's not really enough information to decide on the appropriate construct

10:55 jheander: If one has multiple modules implementing versions of those functions, how should the correct one be selected? If the answer is "type of the first argument", protocols are the right thing.

10:55 Foxboron: Someone tell me if the Clojure community is overall very "Emacs > everything"?

10:56 ro_st: we like emacs because of the excellent repl support

10:56 and, we're writing lisp. emacs is a lisp. it's a natural fit

10:56 i'd use sublime text 2 in a heartbeat if it had as good repl support and paredit

10:57 but, it doesn't. so, emacs :-)

10:57 jheander: hmm..right. No, today I have a project where I have a layer that deals with a database, and then a processing layer with different kinds of functions that merge and do computations based on information from the DB layer. The app has grown quite a bit and I now want to break out the processing layer and have it work with any db module that contains the same function signatures. So basically there will (so far) only be one module implementing these functions

10:57 any given context although they are probably always different.

10:57 Hodapp: Foxboron: #clojure has plenty of people on Eclipse, on IntelliJ, on Sublime Text (I think), on vim, and on Emacs. But it's my understanding that most Clojure devs use Emacs.

10:57 znDuff: Foxboron: the annual community survey covers editor choices.

10:58 ~survey

10:58 clojurebot: survey is http://cemerick.com/2012/08/06/results-of-the-2012-state-of-clojure-survey/

10:58 znDuff: Foxboron: ^^^

10:58 jheander: Right now I'm trying protocols together with alter-var-root and a dynamic var but it seems kind of cumbersome

10:58 don't really want to manually register my module that way, would be nice if loading it was enough...

10:59 Foxboron: hahahaha

10:59 Sublime Text is not even on the list :P

11:00 ro_st: i use ST to search and browse, and emacs to edit and repl

11:00 but that's because i haven't dedicated a couple days to configuring helm yet

11:00 jheander: plus I kind of have to define my functions twice, once with the real code in the module and once as a kind proxy-definition inside a reify of the protocol

11:08 maybe multimethods would fit?

11:10 Anderkent: Any utility function to read bytes from input stream / file?

11:12 Negdayen: jheander: I might dynamically load the code in using (load _) if the modules all define the same namespace functions and are contained in their own file. i am curious as to the idiomatic solution, too, however.

11:16 jheander: How would you know which file to load inside the lib? Or would you dynamically load the lib-file inside the implementing module?

11:17 Negdayen: the latter, yeah.

11:18 pyr: so what do people use when doing clojurescript for "apps" wrt routing ?

11:18 is snout the de-facto standard ?

11:20 jheander: I guess robert.hooke would work fine too :) Probably not very idiomatic though :)

11:26 DaReaper5: Hi, I am having trouble understanding exactly what deref/@ is/does

11:26 S11001001: ,(doc deref) ; DaReaper5, in which sense?

11:26 clojurebot: "([ref] [ref timeout-ms timeout-val]); Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction, returns the in-transaction-value of ref, else returns the most-recently-committed value of ref. When applied to a var, agent or atom, returns its current state. When applied to a delay, forces it if not already forced. When applied to a future, will block if computation n...

11:27 DaReaper5: Nosrat, say what?

11:27 S11001001: DaReaper5: spammy

11:28 DaReaper5: ? Nosrat is spamming?

11:28 S11001001: apparently.

11:28 DaReaper5: Wierd

11:28 Maybe he does not like my name

11:28 Or broken

11:28 CaptainDerp: Test

11:29 hmm

11:29 uvtc: DaReaper5 , CaptainDerp : Do you know Python?

11:29 S11001001: Not getting your automessaging scripts right counts as spam.

11:29 CaptainDerp: uvtc no

11:29 S11001001 sorry i dont know what you mean

11:29 uvtc: What is "-Nosrat-"?

11:30 S11001001: uvtc, CaptainDerp: someone who set up a script wrong, or a terrible bot; either way, mass pointless messaging on every msg counts as spam.

11:30 CaptainDerp: Ok, so why i am confused with deref is that I do not find their examples usful. It is just returning the number defined. If i could have an example of deref compared to something else that would be helpful

11:30 S11001001: uvtc: the - indicates the message type was NOTICE instead of PRIVMSG in the irc protocol

11:32 uvtc: CaptainDerp: Well, in Clojure, names refer directly to things, and are automatically "dereferenced". You write `(def a 3)`, then `a` and you get back `3` automatically. But Clojure *also* has "reference types", which are explicit references that you manually dereference when you want to access their values.

11:32 S11001001: thanks for the info. :)

11:32 S11001001: CaptainDerp: ##(let [x (atom 42)] (+ x 3))

11:32 lazybot: java.lang.ClassCastException: clojure.lang.Atom cannot be cast to java.lang.Number

11:32 S11001001: CaptainDerp: ##(let [x (atom 42)] (+ @x 3))

11:32 lazybot: ⇒ 45

11:33 CaptainDerp: Ok makes sence now, that helps alot

11:33 Quiet Nosrat :P

11:33 That one example and explanation helped more than the offical doc or stackoverflow haha

11:34 uvtc: :)

11:35 CaptainDerp: Another question, is it extreamly bad practice to have a global def in clojure which multiple threads may be accessing?

11:36 S11001001: CaptainDerp: side effects should be avoided

11:37 CaptainDerp: Is it best to wrap the global def in an atom?

11:37 S11001001: CaptainDerp: if you aren't performing side-effects on it, there is no reason to do so.

11:37 uvtc: CaptainDerp: My understanding is that you should try to restrict your use of global mutable state as much as possible, but you still need it sometimes.

11:39 ejackson: CaptainDerp: if it doesn't change then no

11:39 if it does then it needs to be a def to a reference type

11:39 CaptainDerp: S11001001 basically I need a map that is accessable my multiple threads which contain a blocking queue where the key is tied to the user session (maybe tmi?)

11:40 S11001001: CaptainDerp: depends on whether you change the map.

11:40 CaptainDerp: S11001001 yes i do

11:40 S11001001: CaptainDerp: then follow ejackson's advice

11:40 CaptainDerp: that is why i was thinking that atom might be a good idea

11:41 wow nosrat is anoying, should i rejoin?

11:42 S11001001: CaptainDerp: be warned that atom works in fewer situations than ref

11:43 uvtc: CaptainDerp: I've never seen these "-Nosrat-" notices before.

11:44 ejackson: what are they ?

11:45 who did I annoy ?

11:45 CaptainDerp: i think the question is who did i annoy

11:46 ok i think im getting a better handle on reference types, but what is the difference between a "ref" and an "atom". I am specifically confused about "coordinated" vs "independent"

11:46 uvtc: ejackson: every time I post a message, I get a message ( S11001001 points out that they are NOTICE s) from "-Nosrat-" oddly telling me not to use profanity.

11:46 znDuff: CaptainDerp: refs can participate in transactions

11:46 uvtc: ejackson: why do you ask "who did I annoy?". Is it your bot?

11:46 znDuff: CaptainDerp: ...so you can have a bunch of refs which, to the world outside a transaction, appear to change their values all at once or not at all.

11:47 CaptainDerp: whereas each atom is independent of every other; they aren't transactional in nature.

11:47 ejackson: I have no bots - but every time I say anything it has sage advice for me

11:47 perhaps as they're notices you're not seeing them all

11:47 * znDuff puts Nosrat on ignore

11:47 CaptainDerp: ejackson ... so are you saying we are the only ones seeing nosrat and not other people?

11:47 uvtc: ejackson: I only see the ones in reply to messages I type.

11:47 duck1123: CaptainDerp: The analogy I've gotten is if you've received two events at the same time, do you care that they both happen in the order they're recieved, or just that they both happen properly

11:48 unic0rn: (just a test - ignore this message)

11:48 ejackson: yes me too - I only see nosrat whenever I say anything

11:48 unic0rn: no notice here.

11:48 ejackson: i'm guessing its the same for everybody else ?

11:48 duck1123: I'm not seeing these notices

11:48 CaptainDerp: duck1123 ok i think i understand now

11:48 unic0rn: oh here it is.

11:48 metellus: (test)

11:48 CaptainDerp: Refs coordinate among eachother

11:48 atoms do not

11:48 which means an atom is what i need

11:48 ejackson: CaptainDerp: that's the correct understanding

11:49 bit its those scala kids having a laugh at our expense :)

11:49 duck1123: CaptainDerp: So, say you're incrementing a counter. You don't really care that one increments before the other, just that they both do the right thing when they get to go through

11:50 TimMc: If you need a coordinated counter, you can use `commute` on refs.

11:50 CaptainDerp: Ok, that is a really cool feature. Good to know

11:51 jbroome: ping

11:52 Sgeo: Is there any way to restart a dosync transaction if an arbitrary condition is not met?

11:54 Guest98876: Sgeo: refs can be created with a validate-fn

11:55 TimMc: Sgeo: Sounds hinky, what's the use-case?

11:55 uvtc: test

11:55 Ugh. Tried `/ignore -Nosrat- NOTI` but that didn't do it.

11:56 Sgeo: Have a hash-map I want to update as I scan the world for objects. But as I do that, I may also receive events of objects being added/deleted. So I want to hold off acting on those until my scan is done

11:56 uvtc: another test (sorry)

11:56 znDuff: ~ops

11:56 clojurebot: Huh?

11:56 znDuff: Bah. Was hoping there would be someone handy to kick the bot.

11:57 Anderkent: Sgeo: why not have the entire scan in one transaction? Then no one but the scanner can change the world until it's done.

11:57 uvtc: Using `ALL` didn't work either. If anyone can tell me how to ignore -Nosrat- on xchat, I'm all ears. :)

11:57 znDuff: uvtc: it's just Nosrat, without the dashes.

11:57 Sgeo: Anderkent, because the scan is of an external environment

11:57 uvtc: test

11:58 Sgeo: And to do the scan I would set a callback, which sees each individual item as it is scanned

11:58 I don't think I could hold a transaction over that period of time. Also, bad idea to do I/O in a transaction

11:58 TimMc: uvtc: Drop the hyphens.

11:58 uvtc: znDuff: Thanks! After doing `/ignore Nosrat NOTI`, it reported "Nosrat!*@* added to ignore list." (Dunno what the !*@* was for.

11:58 TimMc: nick!ident@host

12:00 Sgeo: I guess I could have the added/deleted object callbacks store stuff into a ref or maybe an agent if the scan isn't done

12:00 Anderkent: Sgeo: So you want to restart the scan after every event?

12:00 uvtc: TimMc: +1 Informative! :)

12:00 jbroome: See how long that lasts

12:00 Sgeo: There are three events: Object scanned, object added, object deleted

12:00 S11001001: (inc TimMc)

12:00 lazybot: ⇒ 21

12:00 S11001001: uvtc I think you mean :)

12:01 uvtc: Actually, I was looking for the "the more you know" ascii/emoticon, but just went with +1 instead. :)

12:02 S11001001: (inc jbroome)

12:02 lazybot: ⇒ 1

12:04 flying_rhino: hello

12:04 uvtc: flying_rhino: hi.

12:05 flying_rhino: does clojure has something like c 'struct' type? (Java equivalent would be class with no methods and all elements public)

12:06 Bronsa: defrecort

12:06 defrecord*

12:06 TimMc: flying_rhino: maps are pretty similar.

12:06 flying_rhino: TimMc: but dnamic

12:06 which means performace loss.

12:06 *dynamic

12:06 S11001001: flying_rhino: premature optimization is...

12:07 uvtc: flying_rhino: Note, I think that in olden tymes there was a defstruct too, but I believe that's pretty much deprecated now.

12:08 flying_rhino: S11001001: ... punishable by crucifixion. Yeah I know but even if I want late optimization, if clojure doesn't have something then how am I gonna optimize even later?

12:08 Bronsa: flying_rhino: deftype/defrecord are what you want.

12:08 S11001001: flying_rhino: then later, ^^ Bronsa

12:09 flying_rhino: okay

12:10 abev: quit

12:10 bye

12:10 exit

12:10 flying_rhino: bye

12:10 abev: bye

12:16 antoineB: hello, i would use "||" operator of javascript, i suspect "or" don't behave the same

12:17 S11001001: antoineB: you'd be right

12:17 antoineB: there are only two false values in Clojure.

12:21 mycelloandi: if i have [(read-int s) (read-int s) (read-int s)] will the order of evaluating the read-ints be guaranteed to be from left to right or should i read them separately within a let?

12:22 wingy: ibdknox: what the reason for removing the LIVE button in instarepl?

12:39 seangrove: Hey all, I'm trying to switch from swank-clojure to nrepl, and it's more or less fine, except I can't use C-x C-e, or really anything that evals the current buffer into the repl

12:39 technomancy: seangrove: yeah for some reason nrepl.el requires you do a full load of the entire file (C-c C-k) before anything works =\

12:40 I tried to talk him out of it, but apparently it's intentional

12:40 ChongLi: seangrove: you can set up a hook to solve that

12:40 seangrove: Ah, that sounds nice

12:40 Sgeo: technomancy, shouldn't that be documented somewhere?

12:40 seangrove: That may not be the problem though, I'm getting these errors:

12:40 "Symbol's function definition is void: lisp-eval-last-sexp" and "lisp-eval-defun: Process lisp does not exist"

12:41 ChongLi: the question I have is how to get colorized stacktraces in nrepl.el's error window

12:41 technomancy: Sgeo: maybe. I don't really know how to explain it because the behaviour is so batty.

12:41 mycelloandi: seangrove: i noticed that too

12:41 seangrove: Sure those aren't caused by not loading the file first?

12:41 ChongLi: they work fine on loose files but not on files inside a leiningen project's src directory

12:41 technomancy: if I documented it, it would just say "here is the way in which it's broken" which I don't think the maintainer would appreciate =)

12:41 seangrove: you don't have nrepl active

12:42 ChongLi: technomancy: any ideas about that?

12:42 technomancy: ChongLi: I haven't gotten that figured out yet

12:42 seangrove: technomancy: What does 'active' mean in this case? The repl is open and running in another buffer, started via nrepl-jack-in

12:43 technomancy: seangrove: nrepl-interactive-mode isn't enabled in the current buffer

12:43 seangrove: technomancy: Ah, yes, that seems to be it

12:47 dnolen: technomancy: so does checkouts actually get any real special handling in lein 1/2? I'm trying to figure out if people can test patches just by checking out clojurescript into their project and using :extra-classpaths-dirs w/o bothering to create the checkouts dir.

12:49 technomancy: dnolen: I don't know what the requirements for clojurescript are, but checkouts are just one way to get things on the classpath following the most common pattern. you can do it other ways, though checking in changes to the project.clj file for a checkout that only exists on your machine is an antipattern

12:49 that's why I've always emphasized that checkouts are opt-in; someone on a team may be interested in using them without making everyone else go through the same steps. so it's invisible to version control.

12:52 dnolen: technomancy: yeah this isn't about permanently changing project.clj - just a way to easily patch a version of CLJS and test against an existing project.

12:53 technomancy: if I try to use checkouts w/ Lein 2, it doesn't work with ClojureScript because it doesn't have a project.clj

12:53 technomancy: all I care about is a step of steps to override whatever version of ClojureScript the user has w/ a master checkout that they can patch and test w/.

12:53 set of steps.

12:54 technomancy: dnolen: if it's just to test then the simplest way would be to get a snapshot into the local repo

12:54 checkouts are for when you want to make continual changes to the dependency project

12:54 sounds like that's overkill here

12:54 dnolen: technomancy: yeah that's way more complicated than what checkouts lets you do, git clone, git am go.

12:55 antoineB: how to create a javascript object in cljs? (js-obj give me something like that {":abc": 12} where i expect {abc: 12})

12:55 technomancy: you could provide a dummy project.clj file for people to drop in

12:56 dnolen: technomancy: so my question is, for lein 2, is :extra-classpaths-dir sufficient to override what the the CLJS the user has installed?

12:56 technomancy: no, :extra-classpaths-dir is deprecated

12:57 you can abuse :resource-paths to do the same thing in lein2

12:58 s/deprecated/removed/

12:58 dnolen: technomancy: k, this kinda seems tedious for anyone wanting to test patches of libs against their projects tho. I guess people just put up w/ it?

12:59 * dnolen distinctly recalls patch lein install, patch lein install, patch lein install process in the past

12:59 technomancy: haven't heard much complaints. it's not very common that you want to do this for a project that doesn't have a project.clj

13:00 dnolen: technomancy: anyone trying to test patches w/ ClojureScript will encounter this and the list of contributors is growing

13:02 technomancy: but :resource-paths is a sufficient hack for now, thx

13:02 technomancy: sure

13:10 mpenet: antoineB: It seems right, js-obj expects a stringy key, it will just apply .toString to the key I guess

13:12 ivan: is there some evil hack to make pst (and other repl functions) available in nREPL even when you're not in the user namespace?

13:12 preferably not by actually adding them to every namespace

13:12 dnolen: mpenet: all tests pass pushing up your patch now.

13:12 mpenet: antoineB: clj->js will do what you want (it's available on jayq and almost every other cljs lib out there, and hopefully in core soon)

13:12 dnolen: sweet! thanks

13:13 technomancy: ivan: you can intern it in clojure.core, but that's horrible. best to just expose it in your client

13:13 antoineB: mpenet: i use js* until now

13:14 dnolen: http://github.com/clojure/clojurescript/commit/cd66e6b9e63ad5ef1896a9c7a117148beb04301d

13:14 ivan: technomancy: expose it how? some form rewriting in the nREPL server?

13:14 mpenet: the short version of clj->js in jayq is only a couple of lines and it's more powerfull

13:14 antoineB: well, it does this recursively

13:15 dnolen: mpenet: thx much!

13:15 technomancy: ivan: a new command in nrepl.el; eg M-x nrepl-pst or some such

13:15 mpenet: dnolen: Thanks for your help/guidance, lots of new stuff for me

13:15 ivan: technomancy: oh, right, I guess that would work, thanks

13:16 technomancy: ivan: IIRC reply does something similar with doc and cdoc

13:16 ivan: ah

13:16 technomancy: intercepts them and fully qualifies them client-side

13:16 antoineB: mpenet: no

13:16 technomancy: much less likely to cause collision that way since it only applies to directly-entered code

13:16 ivan: right

13:17 mpenet: antoineB: I meant clj->js does, not js-obj

13:18 antoineB: i understand

13:20 dnolen: if anyone cares about moving CLJS source map support forward you could help me out by confirming that the following patch works w/ Lein 2 (read all the comments): http://dev.clojure.org/jira/browse/CLJS-282

13:24 cemerick: ivan: This is an open question. At the moment, I'm leaning towards not offering anything in nREPL itself for it. http://groups.google.com/group/clojuredev-users/t/8f9709be5d8ab041

13:25 seangrove: dnolen: You mean just checkout cljs and use it on an existing project, and see if this problem crops up? I'm hacking in cljs all day today, would be happy to give it a try

13:25 ivan: sounds reasonable, making clients do the expansion makes sense to me

13:26 though I'd have to think about it for hours to make sure

13:26 dnolen: seangrove: I actually want someone to confirm that it works for them using the minimal test case project linked to in the comment thread. the project doesn't do anything, it just has some dependencies setup in a way that the issue can be recreated.

13:26 cemerick: ivan: it's not expansion; just prepending `(use '[lib.name.here :only (var-a var-b)])` to each eval is sufficient

13:27 technomancy: cemerick: eh... is that what reply does?

13:27 dnolen: seangrove: the project has instructions to recreate that have to be followed closely, I've already confirmed that it works for me, but I'd like to hear from at least one other person on Lein 2.

13:27 technomancy: input expansion has much more limited potential for conflict

13:27 and should be preferred when possible IMO

13:27 seangrove: Sure, I'll give it a try. Been on Lein 2 for a few days now

13:28 ivan: if I do (in-ns 'otherns) and paste in some block of code that uses `doc` I expect it to not work

13:28 cemerick: technomancy: no, reply doesn't do anything in this area AFAIK. Maybe I missed the beginning of the conversation; not up on what input expansion implies here.

13:28 technomancy: cemerick: I mean fully-qualifying calls to doc, cdoc, etc in a way that only applies to repl input

13:28 cemerick: ah, ok

13:30 technomancy: trptcolin: is that how reply works or does it refer stuff everywhere?

13:31 cemerick: sure, that'd work as well. Though that requires reading input before sending it, which not all clients do.

13:31 trptcolin: sorry, catching up

13:31 cemerick: technomancy: the implicit refers you're seeing are an interaction between nREPL and Clojure <= 1.4.0.

13:32 technomancy: just wondering how convenience fns are made available

13:32 trptcolin: technomancy: right, unfortunately (doc thing) doesn't have the ability to work outside of the usual explicit refers

13:32 technomancy: oh, gotcha.

13:32 cemerick: technomancy: http://dev.clojure.org/jira/browse/NREPL-31

13:32 technomancy: trptcolin: do you think it's a good idea to refer it at read-time?

13:32 trptcolin: the only current magic outside of the user (or perhaps :main?) ns is for exit/quit

13:33 technomancy: gotcha

13:34 trptcolin: i think it would be *awesome* to have that available from a user's perspective. i'm a little worried about the implications of trying to replace 'doc with the fully-qualified version.

13:34 e.g. does it happen only in function call position? or anywhere it's a symbol?

13:34 technomancy: right; it could lead to unpredictable weirdness I guess

13:34 trptcolin: although i guess nobody really uses those as input to a HOF...

13:34 cemerick: I really need to get my cljx middleware out there.

13:35 ivan: (doc doc) not working would be a little weird, yeah

13:35 clojurebot: "([name]); Prints documentation for a var or special form given its name"

13:35 trptcolin: the good news its it'd be almost trivial implementation-wise with sjacket, provided there's a clear set of rules

13:35 ChongLi: hmm

13:35 cemerick: trptcolin: if only there was a logic-programming-driven code transformation library out there.

13:35 ;-)

13:36 ChongLi: trying to debug this is tricky

13:36 since the callback is a lambda and the arguments are a lot of binary garbage

13:36 trptcolin: cemerick: hehe. sure, just dump it in kibit and it'll figure out the dirty bits :)

13:37 seangrove: dnolen: I see the problematic behavior

13:38 ivan: maybe REPL clients should always be wrapping with some kind of (from-repl ...) form that can be broken out of if needed

13:38 seangrove: I'll gist it...

13:38 ivan: but then we might see weirdness like no working tab completion

13:38 bryanl: Can someone help explain why I am getting the cannot cast long to to ifn message I'm getting? https://gist.github.com/4112597

13:39 dnolen: seangrove: using Lein 2 + :resource-paths?

13:39 seangrove: Ah, no, sorry, didn't use the resource paths

13:39 Confirmed the problematic current behavior :)

13:40 Trying again with resource-paths

13:40 Anderkent: bryanl: you define next-person-id as the result of (alter count inc), which evaluates to 1. Then you call it in (next-person-id).

13:40 oh nvm

13:40 i missed the # :P

13:40 dnolen: seangrove: cool, when testing the patch you need to use :resource-paths to override whatever version of ClojureScript you have installed. Thanks much again for trying this out.

13:41 lynaghk: dnolen: Paul and I did some serious core.logic hacking on the way back from the conj. Two questions: 1) what was that default value syntax that will be overriden if unified against but otherwise act as a usual value?

13:41 cemerick: trptcolin: some WIP cljx (kibit) nREPL middleware https://gist.github.com/4112677 /cc lynaghk jonasen technomancy

13:41 amalloy: bryanl: X cannot be cast to IFn always means, you are calling an X as if it were a function

13:42 Anderkent: bryanl: in your threading macro you try to apply 0 to result of next-person-id

13:42 lynaghk: dnolen: and 2) the new walk protocol doesn't recurse, which feels like a bug. E.g., (prep {:a {:b ?c} :d ?d}) preps ?d but does not prep ?c.

13:42 dnolen: lynaghk: I haven't added that (defaults) yet, I easily can.

13:42 Anderkent: (macroexpand `(-> BirthEvent (next-person-id) 0))

13:42 ,(macroexpand `(-> BirthEvent (next-person-id) 0))

13:42 clojurebot: (0 (clojure.core/-> sandbox/BirthEvent (sandbox/next-person-id)))

13:42 amalloy: in this case your existing code basically makes no sense, and so i can't tell you how to fix it. just keep in mind that your -> form expands to (0 (next-person-id BirthEvent))

13:43 lynaghk: dnolen: ahh! awesome. I recall you mentioned it at 2:30 a.m. and I just assumed that I'd forgotten it and couldn't find it in the source.

13:43 dnolen: lynaghk: hmm, recurse - seems like a simple oversight. surprised that wasn't caught by the tests.

13:43 "by a test" I mean.

13:43 bryanl: amalloy: thank you. that's helpful

13:43 lynaghk: dnolen: yeah, I was too. I can submit a patch with test in the next day or two.

13:43 bryanl: Anderkent: and thank you as well

13:44 lynaghk: dnolen: and, just to be clear, the walk should be over everything---correct? e.g., it should walk into map keys as well as their values

13:45 dnolen: lynaghk: oh right, yeah it probably doesn't do that.

13:45 lynaghk: is that a different issue you encountered? ticket created for the other one - http://dev.clojure.org/jira/browse/LOGIC-69

13:46 lynaghk: dnolen: no, same issue. I just wanted to ask you about the scope before I submitted a patch---i.e., if there is any reason you wouldn't want the walk to act on a map's complex keys

13:48 dnolen: lynaghk: k ticket updated, will probably get to it later today - pretty simple one.

13:48 cemerick: it always saddens me to see people dev things like cljx :)

13:48 lynaghk: dnolen: if you want to handle it, that's cool with me too =P

13:49 dnolen: me too!

13:49 dnolen: lynaghk: yeah easy one - that and defaults. I actually want to wrap up 0.8.0. anything else you want to get on the list? if so make tickets please.

13:50 solidfying the lower level constraint details will have to wait for a later release.

13:51 lynaghk: dnolen: those are the only two I'm aware of at the moment. The record unifications are all working awesome.

13:51 dnolen: lynaghk: SWEET

13:51 cemerick: dnolen: oh?

13:51 w.r.t. portability, you mean?

13:51 dnolen: lynaghk: still interested in or?

13:51 lynaghk: dnolen: the current constraint annotations work fine for me. I am doing a bit of contorting for one specific constraint that I will gist up later for you, but I don't think there's anything that could go into core.logic that'd make it cleaner.

13:52 dnolen: no, I don't need it now that the record stuff is all workin'

13:52 dnolen: cemerick: would prefer feature expression support once and for all.

13:52 cemerick: yeah

13:52 dnolen: lynaghk: any thoughts about the namespace keywords, I was inclined to do ^numeric - but that's asking for clashes.

13:53 cemerick: But there are good reasons to want to implicitly rewrite code.

13:53 s/good/occasionally good

13:54 lynaghk: dnolen: yeah, Paul and I discussed that for quite a bit. some of the fiddly bits I'm doing is to support things like ^:data-numeric, but that's only because I control the input. Not sure how you could do something short like that without the risk of clashes.

13:54 ChongLi: technomancy: ah, I solved my problem; just had to install clj-stacktrace

13:55 seangrove: dnolen: And should I apply http://dev.clojure.org/jira/secure/attachment/11686/cljs_282.patch before testing it?

13:55 I've done it both ways, still getting the same erroneous behavior, but want to double check

13:55 dnolen: lynaghk: yeah it's a little bit tedious I think right now - but I don't see anything better except perhaps passing a map of constraints to the unifier?

13:56 lynaghk: that would be in addition to metadata support

13:56 seangrove: yeah you need to apply the patch - then test.

13:56 cemerick: pp

13:56 lynaghk: dnolen: that would be awesome, actually. In doing that you would be able to put constraints between lvars, correct?

13:56 dnolen: lynaghk: sure

13:57 lynaghk: dnolen: yeah, that would cover the nasty case I'm currently thinking about (which involves a relationship between ?data and ?x in an expression like {:data ?data :mapping {:x ?x}})

13:57 dnolen: lynaghk: I don't have the bandwidth to ponder syntax from scratch - would like some idea contributions on that front - gist of something that works for you would be helpful and I can chime in.

13:57 seangrove: And seeing "WARN ignoring checkouts directory clojurescript as it does not contain a project.clj file." should be fine?

13:57 lynaghk: dnolen: you'll have it by this time tomorrow.

13:57 dnolen: lynaghk: thx

13:58 lynaghk: dnolen: thank you dude, you're a machine = )

13:58 dnolen: seangrove: sorry, last comment in the ticket says - don't create checkouts directory, just checkout CLJS into your project. use :resource-paths

13:58 seangrove: if you're seeing that error from Lein, it's not setup correctly.

13:59 lynaghk: dnolen: one other issue I wanted to ask you about: would you would be open to me exposing some Google Closure options within ClojureScript? In particular, I need to use the --output_wrapper flag to prevent clashes between adv. optimized cljs and other on-page minified JS.

13:59 dnolen: seangrove: and applying the patch won't matter - it's ignoring your local checkout of CLJS

13:59 lynaghk: there's already an output-wrapper option

13:59 lynaghk: accessible from something like lein-cljsbuild?

14:00 dnolen: lynaghk: if lein-cljsbuild passes everything along it should just work. :output-wrapper true

14:00 lynaghk: dnolen: I dug through the clojurescript compiler code and I didn't see a way to get to that flag

14:00 dnolen: lynaghk: line 913 closure.clj in master

14:00 http://dev.clojure.org/jira/browse/CLJS-388

14:01 lynaghk: dnolen: well damn. that's what I get for sitting on an issue for a month.

14:01 dnolen: thanks!

14:01 dnolen: lynaghk: np

14:01 seangrove: dnolen: ok, setup properly, trying again

14:02 tomoj: (deftype Foo [^:unsynchronized-mutable foo] IFoo (swap-foo [this f] (locking this (set! foo (f foo))))) -- pretend locking works here. isn't there still a concurrency bug since the field is unsynchronized?

14:03 i.e. swap-foo may get a cached value of foo in one thread which has already been swapped past in another?

14:04 amalloy: tomoj: i think so, yeah

14:05 tomoj: can't seem to cause it to happen

14:05 amalloy: that's pretty much how race conditions work

14:05 tomoj: :(

14:05 I bought that big java concurrency book but haven't gotten around to reading it yet, oi

14:05 seangrove: dnolen: Still see the bad behavior https://gist.github.com/4112913

14:06 tomoj: my guess is volatile would solve that problem?

14:06 amalloy: tomoj: yes, it would

14:06 http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html is a good article on the topic

14:06 gfredericks: tomoj: amalloy: as someone not very familiar with these issues, I'm curious why (locking this ...) doesn't mitigate the problem you're describing

14:07 (i.e., if it doesn't what _does_ it do?)

14:07 tomoj: that makes sure the swaps are serialized

14:07 but it doesn't (I think) guarantee that any particular swapping thread will have seen the effects of the previously serialized swaps

14:08 dnolen: seangrove: so we need to verify that your local checkout is actually being used - modify your local copy to print something in parse-ns

14:08 gfredericks: there must be complexifying details there I'm unaware of because that doesn't sound possible in my mental model

14:08 seangrove: dnolen: Sure

14:09 amalloy: gfredericks: java variables that aren't declared volatile may be cached for any length of time by any thread, afaik

14:09 cemerick: gfredericks: reads and writes to unsyncrhonized fields aren't atomic

14:11 gfredericks: cemerick: atomicity shouldn't be an issue since it's all serialized; but amalloy's caching description makes sense of it

14:11 cemerick: volatile effectively linearizes potentially-concurrent reads and writes

14:11 seangrove: dnolen: To confirm though, this project.clj looks right? https://gist.github.com/4112913#file_project.clj

14:11 amalloy: to be fair, i just rephrased what tomoj said

14:11 gfredericks: amalloy: "caching" applies to CPU registers specifically? otherwise may as well just let the memory caches do their thing, right?

14:12 amalloy: i dunno, man. ask tomoj, or read the article i linked

14:12 cemerick: gfredericks: just because only one thread is within a context at a time doesn't mean that it is seeing the most recent values of unsynchronized fields.

14:12 gfredericks: amalloy: I am reading it; thanks

14:12 trptcolin: right, so reads would have to lock as well on an unsynchronized-mutable. though i wonder if in some situations an int/byte might be safe?

14:13 (provided the field is typed that way)

14:13 cemerick: trptcolin: no, you can't solve the problem with more locks. The introduction of volatile in Java 5 is the only way out.

14:13 gfredericks: cemerick: it should if they deref the field into the CPU register while inside the locked context, no?

14:14 cemerick: s/is/provides

14:14 dnolen: seangrove: project.clj looks ok to me.

14:15 cemerick: gfredericks: don't ask me to understand what's happening at the register level w.r.t. the java memory model. :-)

14:15 Lost in the mists of time, etc.

14:15 trptcolin: cemerick: no? it'd be less performant, but i guess i was under the impression that locking provided the same visibility guarantees

14:16 seangrove: dnolen: Doesn't seem like it's using the ./clojurescript in the directory though. I add a println and `(assert false) to parse-ns in cljs-sscce/clojurescript/src/clj/cljs/compiler.clj, lein cljsbuild auto still ran like normal

14:16 trptcolin: though at that point there's no win in using unsynchronized-mutable :)

14:16 gfredericks: I'm just trying to figure out "where" these cached values are. Unless java caches stuff in memory, which seems to duplicate what hardware caches already do, the only scenario I can think of is "cached in a register"

14:17 dnolen: seangrove: yeah so it's not picking up your local clojurescript. technomancy anything seem off about that project.clj? http://gist.github.com/4112913#file_project.clj

14:18 cemerick: trptcolin: object monitors are unrelated to the linearization (or not) of operations over a field

14:18 sw1nn: gfredericks: volatile ensures flushed to/from main memory in the order you see in the source code. if not volatile reads and write can happens in any order.

14:18 tomoj: but if it's volatile, we can't do (locking this (when foo (set! foo (f foo)))) ?

14:19 gfredericks: sw1nn: why can they happen in any order if we have the guarantees of a lock?

14:19 * gfredericks must not know how computers work

14:19 cemerick: no one does :-P

14:20 Frozenlock: Computers are like, you know, black magic stuff.

14:20 sw1nn: only threads interested in the lock get the guarantees. in fact if the jit can determine that there is no contention on the lock then the lock will be elided.

14:20 cemerick: gfredericks: a lock linearizes the entry/exit of threads within a scope; volatile linearizes memory reads and writes so that they are all visible to all threads equivalently.

14:21 sw1nn: this: http://stackoverflow.com/questions/1787450/how-do-i-understand-read-memory-barriers-and-volatile

14:21 seems like a good overview on cursory inspection

14:23 gfredericks: cemerick: so what I'm trying to figure out is, if all memory reads/writes happen in the locked block, why does that not give you linearized reads/writes?

14:24 or is the issue that readers probably aren't using the lock?

14:24 cemerick: Because the JIT or the CPU can reorder reads and writes whenever and however they like.

14:25 (for unsynchronized mutable fields)

14:27 trptcolin: iirc, they are not allowed to do that with, for example, 2 synchronized blocks in java-land. there has to be a before/after ordering of the blocks as a group.

14:27 gfredericks: I can't think of any example of "reordering reads and writes" that doesn't violate all sorts of sanity expectations

14:27 trptcolin: but perhaps monitor-enter/monitor-exit is less of a guarantee than synchronized?

14:28 gfredericks: i.e., I don't know how to interpret that sentence without also concluding that I can't reason about single-threaded code anymore

14:29 dnolen: seangrove: another option would be to use checkouts, use :extra-classpath-dirs and create a dummy project.clj just to appease Lein 2.

14:29 flying_rhino: my connection froze. Anyway can you have typed vector that only accepts records of certain type?

14:29 seangrove: Happy to do that if it makes sense

14:30 dnolen: seangrove: I think that will work, checkouts was just complaining that it couldn't find a project.clj file. :extra-classpath-dirs is deprecated but I think will still take effect in Lein 2 previews.

14:30 sw1nn: the re-ordering appears consistent within a thread, so you don't ever have to worry single-threaded. the re-ordering can be done by the jit or as a artifact of the memory hierarchy.

14:30 dnolen: seangrove: all of this is very tedious to just test patches

14:31 sw1nn: Here are some 'surprising examples' in the java language spec: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4

14:31 seangrove: Well, we've been relying on cljs pretty heavily, and moving all of our in-house frontend code over to it, so happy to help out where I can

14:31 Hopefully more substantially in the future, but for now, fine to be a tester

14:31 trptcolin: sw1nn: nice

14:32 tomoj: I use :source-paths and don't put it in checkouts

14:32 I think the warning about project.clj is harmless though

14:32 dnolen: seangrove: ^

14:32 tomoj: since it just means the checkout bit of leiningen is ignoring it

14:32 dnolen: tomoj: but lein ignoring is a problem - it won't get put on the classpath.

14:33 gfredericks: sw1nn: thanks; now I have three tabs devoted to the issue :)

14:33 Foxboron: ohh, while we talk about java, 2 sec.

14:33 SOme java source:

14:33 http://kickjava.com/src/com/sun/java/swing/plaf/nimbus/InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonPainter.java.htm

14:33 sw1nn: gfredericks: make sure you keep all tabs in sync :-/

14:34 seangrove: tomoj: Ok, looks like that worked, at least the assert cause lein cljsbuild to fail

14:34 tomoj: dnolen: it still will since you add it explicitly

14:34 just the checkout bit of lein won't add it

14:34 seangrove: Ok, finally, testing with the patched clojurescript...

14:35 dnolen: tomoj: it did not work for me even w/ explicitly adding it - tested this quite a bit yesterday.

14:36 tomoj: hmm

14:36 well, I just followed the steps and everything seems OK to me

14:37 I see the same thing from the grep with a clean auto and after touch'ing b.cljs

14:37 using the clojurescript submodule in that repo

14:37 seangrove: dnolen tomoj: Looks like the patch does work https://gist.github.com/c880c958adf7ba5f4a0d

14:37 dnolen: seangrove: excellent! thanks

14:38 seangrove: tomoj: I cloned clojurescript from the repo, applied the patch, used :source-paths, and seems like it's working

14:38 tomoj: I'm always nervous about what version of cljs I've actually got :/

14:38 seangrove: On that note, who decides what gets put into cljs' goog-closure.jar?

14:39 I ask because I needed to use the Md5 function, and it wasn't included in the cljsbuild goog-closure.jar I was using, but it's been in the Closure library for over a year

14:39 I then spent a day trying to figure out how to replace/manually update the goog-closure.jar, but seems like that's still a bit over my head right now

14:40 dnolen: seangrove: thx CLJS-282 resolved. so the solution was :source-paths and no checkouts dir right?

14:40 seangrove: dnolen: Correct

14:40 tomoj: (fwiw, leaving clojurescript in checkouts seemed to work here)

14:41 dnolen: tomoj: which preview of Lein 2, 10?

14:41 tomoj: yes

14:41 dnolen: tomoj: what OS?

14:41 tomoj: ubuntu

14:42 dnolen: tomoj: that might be it then dunno - unnali & I are OS X 10.7.5

14:42 seangrove: you?

14:42 tomoj: `lein classpath` when you have :source-paths ["checkouts/clojurescript/clj" "checkouts/clojurescript/cljs"] doesn't include them?

14:42 dnolen: tomoj: I think we're talking past each other :) we weren't using :source-paths + checkouts

14:42 seangrove: lein 2 prev 10, osx 10.7.2

14:43 tomoj: oh, right

14:43 I meant only that if you have cljs in source-paths explicitly, the fact that you put it in checkouts/ and lein complains doesn't matter, it still gets on the classpath

14:43 dnolen: tomoj: yes, this is good to know.

14:47 tomoj: so (swap-foo [this f] (locking this (when foo (set! foo (f foo))))) - would ^:volatile-mutable for foo be problematic here because we read-then-write? or does the locking make this not a concern?

14:48 seems most of the stuff online talking about volatile assumes you're not also locking

14:49 dnolen: tomoj: seangrove: http://github.com/clojure/clojurescript/wiki/Testing-patches, hopefully this looks ok?

14:50 seangrove: dnolen: Looks pretty easy, yeah

14:51 tomoj: yeah, except "git clone clojurescript into your project directory" (vs "into a directory in your project called checkouts" above) suggests what I actually do, which is :source-paths [... "clojurescript/src/clj" ...]. but that just avoids the warning

14:51 seangrove: dnolen: Mind helping me understand about the goog-closure.jar, where it comes from, and who decides which Closure functions get put in?

14:53 aperiodic: @

14:53 dnolen: tomoj: http://github.com/clojure/clojurescript/wiki/Patches

14:53 seangrove: goog-closure.jar is whatever the latest build of goog-closure.jar gets included w/ CLJS

14:55 Frozenlock: I have a uberjared webserver. Is there a typical way to let the user make and add its own plugins?

14:55 tomoj: dnolen: -yeah looks perfect

14:55 sw1nn: tomoj: the lock gets flushed to main memory, so if you are accessing the actual lock you don't need to worry about read/write, but if you are accessing anything else then you only have guarantees if those other things are protected by the same lock. In your swap-foo example, foo can presumably be updated outside a critical section, so not guaranteed to get the value when the lock was acquired

14:56 seangrove: dnolen: Just wondering why it would have some functions included, and others left out - is there any discussion of that?

14:56 tomoj: if you only set! foo inside locking, then "foo can presumably be updated outside a critical section" is false, yes?

14:57 Frozenlock: For lack of a better example, kind of like 'redmine'. There's the main app, but contributors can code new plugins and the users can choose to use them.

14:57 dnolen: seangrove: if things are left out that's a problem w/ goog-closure.jar, we don't leave things out

14:57 technomancy: Frozenlock: require+resolve with a convention around naming namespaces goes a long way.

14:57 dnolen: seangrove: goog-closure.jar seems to change quite a bit

14:58 technomancy: Frozenlock: I don't think it's possible to describe a convention for entry points in an application-agnostic way though; every application is going to be different

14:58 seangrove: dnolen: Is it what's released by google?

14:58 * seangrove feels like he's asking incredibly dense questions

14:59 Chiron: Hi, I have a vector and a lazy seq . what is the output of (concat vector lazy-seq) ?

15:00 technomancy: I bet clojurebot knows!

15:00 Frozenlock: technomancy: Thanks!

15:01 Wouldn't there be an issue finding the jars if they are not in the uberjared resources?

15:01 Chiron: still, it is hard to beat the human factor :)

15:01 dnolen: seangrove: yes

15:01 Bronsa: ,(concat [1 2] (map inc (range 2)))

15:01 clojurebot: (1 2 1 2)

15:02 Bronsa: derp.

15:02 ,(concat [1 2] (map dec (range 2)))

15:02 clojurebot: (1 2 -1 0)

15:02 alexyk: any La Clojure users here?

15:03 today, this moment?

15:05 Chiron: alexyk: me but not a kung fu user

15:06 I migrated to sublime text II

15:08 alexyk: Chiron: I actually am trying that too

15:08 but nrepl breaks syntax highlighting, obviously string escaping is broken

15:08 seangrove: dnolen: Thanks

15:09 alexyk: Raynes poo-pooed it enough in his blog for me to get doubts

15:09 Raynes: alexyk: What did I poopoo?

15:09 Oh, La Clojure?

15:09 alexyk: Chiron: what I need in IDE like IDEA is to be able to find a symbol by name

15:09 Raynes: Did I explicitly mention I didn't like it? I thought I just… disregarded it.

15:10 alexyk: Raynes: I mean it in a good way

15:10 :)

15:10 Chiron: Eclipse CCW ?

15:10 Raynes: I only used La Clojure when it first came out.

15:10 I don't know what shape it is currently in.

15:10 Oh.

15:10 Sublime Text!

15:10 There we go, context.

15:10 Yes, ST2 is pathetic for Clojure.

15:10 alexyk: Sublime Text II got doubts from Raynes

15:11 the real question for IDEs is, I got a humongous project, I want all names indexed and I want to go to their definitions.

15:11 Who can do that well?

15:11 Raynes: It's a good editor, just sucks for Clojure because the author obviously doesn't care much about Clojure support vs Ruby and such. Which is fine, since he isn't a Clojure guy.

15:12 alexyk: IDEA will break into jars and your mother's cupboard. It will decompile library jars if it needs to.

15:12 I didn't see that doggedness from anything else.

15:13 znDuff: alexyk: Yes, IDEA does that, but the paredit mode available for it is a shadow of what's there on emacs

15:13 technomancy: jumping to definition is trivial to implement in any editor

15:13 as is listing all loaded namespaces/vars

15:14 tgoossens: What would be a useful representation for 3x3 puzzle. Currently i'm thinking of [[1 2 3] [4 5 6] [7 8 9]] (most obvious i think)

15:14 but haven't figured out

15:14 how to write a function that does this:

15:14 http://pastebin.com/KnXsmzAw

15:14 znDuff: tgoossens: would you mind using a pastebin without all the ads? gist.github.com and refheap are both much better.

15:15 tgoossens: no probs!

15:15 didn't know github has that

15:16 gist seems ok to me :)

15:16 clojurebot: ClojureBooks is http://clojure.org/books

15:17 tgoossens: znDuff: for you ;) https://gist.github.com/4113588

15:17 Wild_Cat: tgoossens: your function would be easier to write given a map representation of your puzzle

15:17 tgoossens: hmmm

15:17 you mean

15:17 :0 1 :1 2 :3 3

15:17 Wild_Cat: tgoossens: e.g. {[0 0] 1, [0 1] 2, [0 2] 3, [1 0] 4, ... }

15:18 tgoossens: :x (number of the cell)

15:18 ah

15:18 mm

15:18 but the thing is now i'm using a less obvious representation. Just because 1 function is hard to write

15:18 translations

15:18 are very easy

15:19 in my original representation

15:19 alexyk: znDuff: canclojure-mode in emacs index everything with ctags or something?

15:19 sw1nn: tomoj: yes, if only accessed within locking it will be fine. jvm *can* re-order within a synchronized block, but not if it changes logic materially.

15:20 technomancy: alexyk: ctags is silly for languages that have a repl

15:20 it's so much easier to just query the running process

15:21 alexyk: technomancy: I meant through some magic! :) I need to jump from a usage of a symbol to its def/defn, in emacs?

15:21 how do we do that?

15:21 technomancy: sure; nrepl.el supports that

15:21 took under an hour to write

15:22 alexyk: technomancy: how do I invoke it?

15:23 amalloy: M-. unless the nrepl guys were crazy

15:23 tgoossens: Wild_cat: i see how rotation gets easier. hmm

15:23 alexyk: what if I didn't yet load everything into repl?

15:24 Wild_Cat: tgoossens: translation isn't particularly hard in my representation either

15:24 tgoossens: Wild_cat: and maybe i just have to create a simple function that transforms that map into vector representation for human-readable printing

15:24 technomancy: alexyk: M-. for the symbol under point, C-u M-. to browse through the full namespace tree

15:24 Wild_Cat: tgoossens: yup.

15:24 technomancy: if it's not loaded it doesn't exist

15:24 tgoossens: Wild_cat: you're right it isn't hard

15:24 technomancy: loading everything is much easier than keeping a tags table up to date

15:25 alexyk: technomancy: so I have a src/ full of subduers full of *.clj; how do I feed it to nrepl to explore with M-. ?

15:25 subfolders

15:25 technomancy: just make a loader namespace and do (require 'myproject.all)

15:25 Wild_Cat: tgoossens: it's often a good idea to consider alternate representations of your data set. Important lesson learned from the Game of Life example in the Clojure book.

15:26 (which, by the way, I'm enjoying so far -- congrats to cemerick et al.)

15:26 tgoossens: when i have the time i'll take a look at it :)

15:26 so far I have read "programming clojure"

15:26 Wild_cat: sometimes it is difficult to choose the right datastructure. Maybe because i try too much to represent to problem in a human readable data structure. Instead of more

15:26 Mr_Bond: I'm quite pleased with this one: #(last (take 2 (reverse %)))

15:26 jamii: RE: https://groups.google.com/forum/?fromgroups=#!topic/clojure/AsPs9ZonRPQ

15:27 Mr_Bond: 4clojure problem 20

15:27 Wild_Cat: tgoossens: the trick there is that a vector of vectors isn't *that* readable to begin with. The perfect data structure would have been an actual 2D array, but Clojure (or Java) doesn't have that

15:27 jamii: I'm getting the same error (Failed to deploy artifacts: Could not transfer artifact strucjure:strucjure:pom:0.3.2 from/to clojars ... ReasonPhrase:Forbidden.)

15:27 It's not clear from that conversation what the fix is. Anyone know the answer?

15:28 brehaut: Mr_Bond: (comp last butlast)

15:28 Mr_Bond: brehaut: nice

15:28 nicer

15:28 jamii: I do have a gpg key set up in my profile and am prompted for the passphrase when pushing. I have been to the my clojars profile page and re-entered the key.

15:29 Not sure what to do now.

15:29 brehaut: Mr_Bond: free all the points!

15:29 amalloy: sometimes i wonder if brehaut has a clojure version of `pointless` hidden in his back pocket

15:29 tgoossens: Wild_Cat: mmyes

15:29 Wild_Cat: ...I will concede, however, that for human readability a map is worse ;)

15:30 brehaut: lol

15:32 tgoossens: Wild_cat: it takes some effort to get used to thinking in data. 2 months ago my only experience was OO in java (and some php)

15:33 but i got tired of only learning OOP and JAVA at university that I searched for something fresh, new and totally different

15:33 clojure has got them all :p

15:33 Wild_Cat: tgoossens: Java's main inadequacy here is that it has no syntax for vectors or maps.

15:34 tgoossens: Wild_cat: maps syntax in guava makes life more bareable!

15:34 Wild_Cat: map literals are awesome.

15:34 madsy: Wild_Cat: What's just a syntax issue. What's important is the language semantics.

15:34 Wild_Cat: madsy: sure, but IMO, "just a syntax issue" issues quickly add up together.

15:34 madsy: +T-W

15:35 * TimMc reads the backlog about volatile and memory barriers and decides it isn't too late to become a firefighter.

15:35 Wild_Cat: Java's semantics are unremarkable but not hostile. But its lack of literals for anything but arrays (which almost nobody uses in user code, with good reason) and strings hurts it a lot.

15:36 madsy: Wild_Cat: I think the single biggest flaw of Java is the dependency on class/interface hierarchies, with no way to partially override.

15:36 TimMc: Wild_Cat: I'd like to quibble with the statement "main" inadequacy.

15:36 madsy: Want to partially override an interface? You have to define every method.

15:36 Wild_Cat: likewise, == versus .equals. There's a lot of places where Java sacrificed its syntax by dedicating it to features nobody uses.

15:36 tgoossens: in java i just sometimes have de need for some kind of "function" and I have nowhere to put it really.

15:36 TimMc: madsy: Only if you want a concrete class.

15:37 Wild_Cat: TimMc: main but far from only ;)

15:38 TimMc: The type system is completely fucked, for one.

15:38 Wild_Cat: yeah, fair enough.

15:38 TimMc: "Let's spend all this effort getting a safe typechecker and completely ignore nulls and our insane checked exception nonsense."

15:39 Wild_Cat: oh, man, I forgot about checked exceptions.

15:39 there's also the generics that are horribly implemented.

15:39 tgoossens: yes

15:39 f*cking type erasure

15:40 brehaut: tgoossens: type erasure lets clojure be the language it is

15:40 TimMc: James Iry wrote a nice little bit of code that allows you to throw checked exceptions in Java as if they are unchecked.

15:41 pjstadig: TimMc: and the only reason James' code worked is because of generics erasure

15:41 tgoossens: brehaut: i'm talking about idiomatic java code. Not clojure

15:41 TimMc: A coworker and I stared at it for a while and finally figured out that it works because of the Throwable hierarchy.

15:42 Wild_Cat: also, I hate a lot of the stdlib's design. Just like C++'s was "hey, I have that new toy called operator overloading, let's use it everywhere!", Java's stdlib is "overdose of the Decorator pattern."

15:42 TimMc: pjstadig: Actually, he pointed out that if you had *two* Throwable roots (CheckedException, UncheckedException) then it would be typesafe.

15:42 pjstadig: brehaut: right, if generics were reified, then clojure would have a bad time

15:42 Wild_Cat: why a high-level language running on a VM requires the user to manually buffer everything, I may never know.

15:42 brehaut: pjstadig: exactly

15:43 tgoossens: brehaut: oh. you mean how clojure is created?

15:43 TimMc: brehaut: Can you expand on that?

15:43 Wild_Cat: interesting -- why is that?

15:44 * brehaut tries to find the article / post from the clojureCLR guys about this

15:45 tgoossens: Wild_cat: "why a high-level language running on a VM requires the user to manually buffer everything" what do you mean with that?

15:46 Wild_Cat: tgoossens: the fact that FileWriter/FileReader is unbuffered and has to be explicitly wrapped in a BufferedWriter/BufferedReader.

15:46 (which, depending on what you do with your code, may result in a single reader/writer being wrapped in *several* nested buffers)

15:47 tgoossens: oh. that seems a bit strange

15:47 Wild_Cat: every other language I know, when it gives you the choice between buffered/unbuffered (some don't, and those force buffering on you), does it with a flag in the open call, and *always* default to buffered when available.

15:48 tgoossens: so what woudl have been better is : an interface IFileWriter. and a class FileWriter and a class BufferFileWriter

15:48 instead of wrapping

15:48 is that what you are saying?

15:48 TimMc: and then you hand that (Buffered)Writer to someone else and *they* wrap it in a BufferedWriter...

15:49 Wild_Cat: TimMc: exactly.

15:49 tgoossens: TimMc: that seems f*cked up :p

15:49 Wild_Cat: tgoossens: no, just have FileWriter's constructor take a "buffered" argument that defaults to true, and get rid of an extra and unnecessary level of interface inheritance.

15:49 Lemmy knows Java's class/interface hierarchy is already more than deep enough

15:49 amalloy: Wild_Cat: and SocketWriter? and ZipFileWriter? and...?

15:50 putting the buffering functionality in a single place is better than in N places. java.io is a mess, but what you propose is not better

15:50 tgoossens: i still think that in java -idiomatically- it is the good to do interface inheritance

15:50 (without "the")

15:51 Wild_Cat: amalloy: frankly, I'd just get rid of the flag and leave buffering to whatever the underlying OS does (enabled almost everywhere).

15:51 amalloy: besides, ZipFileWriter probably delegates most of its raw reading functionality to FileWriter anyway.

15:52 (leading to the interesting question, does it instantiate a BufferedWriter to write to the actual file? And can you even control that?)

15:55 amalloy: i don't know, i just made up zipfilewriter

15:56 in reality it doesn't exist; there's some ZipStream that wraps an existing stream

15:56 TimMc: It wouldn't be a Writer.

16:03 brehaut: TimMc: i cant find the article sorry.

16:10 TimMc: brehaut: This doesn't help: http://stackoverflow.com/questions/3812644/how-does-types-erasure-help-clojure-exist

16:10 A strange question.

16:11 brehaut: wow yeah

16:13 TimMc: aaaaagh fuck you google

16:13 I meant "erasure", not "erasing".

16:13 * TimMc throws a handful of punctuation after his query

16:14 brehaut: TimMc: my understand is that reified generics become quite pervasive, and anywhere clojure builds ontop of a java level abstract (frinstance, collections API, runnable, etc), there would need to be explicit type parameters provided

16:14 if clojure were less interested in interop, it wouldnt be such a problem

16:14 TimMc: I see.

16:14 So Clojure would be perfectly compatible with Java v1.4.

16:15 it's just that Java v1.5 would look entirely different

16:15 brehaut: yeah i guess so

16:16 TimMc: as opposed to Clojure taking special advantage of type erasure.

16:17 brehaut: well, it uses Object everywhere

16:17 which kinda is

16:17 TimMc: That's like saying that Java v1.4 makes use of type erasure. :-P

16:17 brehaut: ha

16:20 TimMc: unfortunately my memory is woolly on specifics

16:21 so ive only got the handwavey explainations available

16:32 ivan: anyone like some SLOC counter that doesn't ignore .clj files? tempted to write my own

16:34 amalloy: just use cloc

16:40 bbloom: yeah, i add languages to my cloc.def all the time

16:40 danielneal: Hello! I'm new to IRC. Just wondering - is there a way of listing the callers of a function when using nrepl/emacs/clojure?

16:45 vijaykiran: danielneal: if you are using swank - "C-c C-w c: List all callers of a given function"

16:45 not sure if it works with nrepl though

16:47 amalloy: does it even work with swank? i didn't think anyone had implemented the who-* family

16:51 ivan: amalloy: thanks. though my centos refuses to install it. I'll take up with them.

16:53 danielneal: interesting - I just moved away from swank to nrepl as it looked like that's the way things were going

16:53 ambrosebs: Is there a recommended way to extend the special forms in CLJS? This is my current hack https://github.com/frenchy64/typed-clojure/blob/master/src/typed/check_cljs.clj#L9

16:57 hiredman: ambrosebs: I would be surpised if there ever was a "recommended" way to do that

16:57 but that approach seems fine, I might suggest alter-var-root + union

17:02 ivan: so an untyped language usually running on a typed VM is upgraded to be a typed language, compiled to untyped JS, run through a compiler that mixes typed code with untyped CLJS to become untyped JS, and run through V8 which creates hidden classes

17:06 danielneal: thanks vijaykiran

17:07 hopefully someone clever will implement a who-calls for nrepl then

17:07 just wanted to check whether it existed somewhere already

17:08 dysinger: where does one go for the how-to on nrepl replacement of slime/swank in emacs?

17:13 danielneal: dysinger: I just installed nrepl.el, and made sure I was using lein 2

17:14 dysinger: k

17:14 danielneal: then nrepl-jack-in from a clojure buffer to get it going

17:15 I'd been putting it off for months...

17:15 dysinger: so it doesn't conflict or compete with swank it sounds like

17:15 danielneal: it didn't seem to in my case

17:15 dysinger: awesome

17:15 danielneal: it was the upgrade to lein2 that was the most important bit

17:15 the one thing I haven't got completely configured yet is ac-nrepl

17:17 hiredman: nrepl.el is a completely new code base

17:17 so any slime customizations and key bindings may or may not work

17:18 nrepl.el turns on nrepl-interaction-mode for clojure-mode buffers, which does break some slime keybindings (if you are using slime for some projects, and nrepl for others)

17:24 dysinger: I can't even get my emacs to load after adding it

17:24 popup.rcp: (error "Variable binding depth exceeds max-specpdl-size")

17:24 (using el-get)

17:28 mammoth: how fast is accessing vectors and hash tables

17:28 ?

17:29 znDuff: mammoth: vectors are log32n for lookup

17:30 mammoth: danke

17:30 gfredericks: vectors are "good" for lookup

17:30 znDuff: mammoth: ...if you're curious, you should be able to find a video of one of Bagwell's conj talks (or his paper).

17:30 mammoth: thanks

17:31 * znDuff was and remains very impressed re: the amount of knowledge of the underlying hardware -- despite having a JVM in the way -- that went into making vectors efficient.

17:45 dysinger: derp. I had a loop in my emacs dependencies. all fixed.

17:45 devn: go aperiodic

17:45 oops... :\

17:46 flying_rhino: is it possible to to give type to vector so it can only take one type of object?

17:46 devn: flying_rhino: you could use pre or post, or validate with atoms

17:47 flying_rhino: I was thinking more about speed (I assumed that yped vectors could be faster)

17:47 *typed

17:47 aperiodic: i'm going as fast as i can! ;)

17:48 gtrak: flying_rhino: arrays?

17:48 flying_rhino: gtrak: i guess that's an option too

17:48 gtrak: there is no slowness based on type, since the vector only stores a reference

17:49 flying_rhino: so it doesn't really matter?

17:49 good to know

17:50 dnolen: flying_rhino: vectors are pretty fast. you have gvecs which can be more memory efficient since you can specify their contents, but there's no support *yet* to work w/ their contents w/o boxing.

17:50 flying_rhino: okay

17:58 Foxboron: Reading "The joy of clojure". While reading i got the image of me talking to a monk about why he choosed his way of life, how he communicates with the world and life

17:58 then i started thinking back on python, and i saw it like the nazi regime O.o

17:58 mammoth: Steve Yegge seems grumpy about Clojure for some reason.

17:58 tomoj: does clojure-mode indent "(assoc m\n k v\n k v)" in a manner in violation of http://mumble.net/~campbell/scheme/style.txt ?

17:58 amalloy: i doubt if python is disproportionately popular with nazis

17:59 Foxboron: hahaha

17:59 znDuff: Foxboron: Heh. I can certainly see Python as a backlash against TIMTOWTDI, but then, I don't think that was a bad approach.

17:59 amalloy: tomoj: yes, it's a bizarre choice for clojure-mode to make

17:59 mammoth: I wonder if his reason are any good

17:59 Foxboron: I started a threat on reddit once. The topic was to see who used different "hacks"

17:59 znDuff: mammoth: You're a few months late to that flamewar.

17:59 Foxboron: It was downvotes to hell and up again

17:59 znDuff: mammoth: short form: The consensus is that his reasons are not, in fact, good ones.

17:59 mammoth: znDuff: I am not interested in flame

18:00 Foxboron: The overall conservatism of the python community is disturbing tbh

18:00 gtrak: i think yegge likes python though

18:00 mammoth: znDuff: but I can't help but wonder if there is a grain of truth in what he says

18:00 gtrak: "Python, Common Lisp, Smalltalk/Squeak: Liberal"

18:01 Foxboron: gtrak, liberal as in?

18:01 The community?

18:01 znDuff: Foxboron: You'd have to read Yegge's essay -- it provides the context for that.

18:01 Foxboron: ah, ill look it up then.

18:01 gtrak: Foxboron: he has a really silly value-judgment thing... it's inflammatory and makes no sense

18:01 technomancy: liberal as in "able to get people in a seething rage"

18:01 gtrak: https://plus.google.com/u/0/110981030061712822816/posts/KaSKeg4vQtz

18:02 python's has duck-typing, but people look at you funny and say "that's not pythonic"

18:02 znDuff: mammoth: ...classifying the Clojure community as staunchly conservative because we advise against using macros more than necessary struck me as more than a bit silly -- the pitfalls of macro overuse are pretty darned easy to run into in practice; it's not some ideological purity thing.

18:03 Foxboron: Wait

18:03 Sgeo: "necessary" seems a bit harsh

18:03 Foxboron: How can he atall say Python is liberal?

18:03 technomancy: Foxboron: by having a completely useless definition of his terms?

18:03 Sgeo: If macros are strictly speaking never necessary...

18:03 gtrak: to his definition...

18:04 Foxboron: technomancy, i choose to believe he have an ounch of brain

18:04 gtrak: it's more liberal than java..

18:04 mammoth: but fanaticism of clojure people is a little distrubing sometimes. What's so wrong about some state? While I love focus on multicore and stuff, I don't think clojure should deliberately put roadblocks on procedural. Macros are never necesary but they are great way to reduce bloat and bloat is bad.

18:04 technomancy: Foxboron: sure, you have to be clever to troll that hard

18:04 he's definitely a good writer, and he knows it

18:04 and he's using it to mess with people he doesn't like

18:04 Foxboron: hm

18:04 Sgeo: What does he classify Tcl as?

18:05 Foxboron: Its not listed

18:05 mammoth: bottom line there is some truth in what he says and clojure would benefit for some criticism

18:05 Sgeo: Clojure would benefit from sensible criticism.

18:05 brehaut: complete set of things that do not benefit from some criticism: #{}

18:05 gtrak: mammoth: state is a necessary evil, because we don't have infinite memory. It's easier to reason about your program if you can step through every state change.

18:06 it should be minimized or scoped well

18:06 no one's really up in arms about that

18:07 it just feels wrong to people that haven't used clojure before

18:07 for like a week

18:07 like python's indentation

18:08 or java's 'all member functions are virtual'

18:08 flying_rhino: .

18:08 gtrak: to C++ guys

18:08 gfredericks: brehaut: I don't know how the empty set could benefit from criticism so maybe you ought to say #{#{}}?

18:08 Sgeo: "there was a key presenter doing a talk on how Macros were basically harmful and should be avoided in modern Clojure code."

18:08 Did that actually happen, or was it "keep use of macros tasteful"

18:09 gfredericks: that wasn't the point really

18:09 flying_rhino: I switched username becuase my connection died, I am mammoth.

18:09 gtrak: it didn't actually happen, and the guy in question writes a ton of macros

18:09 technomancy: he didn't actually watch the video

18:09 gfredericks: it was about macros not being composable and etc

18:09 so yes it was just "keep use of macros tasteful"

18:09 ivan: he's talking about https://startpage.com/do/search?q=dsls%20not%20macros

18:09 flying_rhino: look I don't think Clojure is all that conservative. But there is one thing

18:10 Foxboron: wait

18:10 Sgeo: We should make a language with a macro-like mechanism that's composable

18:10 Foxboron: Yegge actually rates them conservative to liberal based on what the lang actually got

18:10 thats retarded D:

18:11 gfredericks: Sgeo: how would that work?

18:11 TimMc: On a rating scale and valuation he invented.

18:11 brehaut: Sgeo: pure functions and rewrite rules!

18:11 flying_rhino: I believe Clojure should maybe support old fashioned procedural programming and some old fashioned mutable vars. Because the thing is, all those power tools it has are nice and sometimes necessary, but but what if something you are making DOESN'T require multicore?

18:12 gtrak: flying_rhino: it does that stuff just fine

18:12 Sgeo: gfredericks, maybe something like what Kernel does, although I don't know if that's composable. Or like Tcl does, but same.

18:12 znDuff: flying_rhino: first, the functionality is already there.

18:12 mrowe: flying_rhino: then don't use clojure

18:12 flying_rhino: glibly stating that state=evil is what can be interpreted as fanaticism

18:12 Sgeo: flying_rhino, it has support for mutable vars

18:12 Foxboron: "However, I eventually learned that the Clojure community is extremely conservative. That is is pretty unusual for a Lisp dialect."

18:12 Like really

18:12 You can't base a language as "conservative" just because it choose to have x y and z features

18:13 gfredericks: GOTO has its place too right

18:13 Sgeo: ,(with-local-vars [a 1 b 2] (var-set a 3) (var-get a))

18:13 clojurebot: 3

18:13 znDuff: flying_rhino: second, it's not all about multicore development -- a good chunk of the benefits come from having better tools to use in reasoning about state.

18:13 Foxboron: you gotta base that on philosophy and the state of the community ._.

18:13 gfredericks: all languages should have GOTO just in case

18:13 gtrak: mrowe: I'm not sure I like the idea of 'don't use clojure if you're wrong about it'. I prefer people to stop thinking wrong things.

18:13 Foxboron: gfredericks: i don't like raptors

18:13 brehaut: gfredericks: you kids and your degenerate continuations

18:13 dnolen: I hate switching Clojure tools

18:14 mrowe: gtrak: I was meaning that if you want a procedural language with easily mutable data structures, maybe another language would be more suited to your task

18:14 dnolen: anybody else encountered the nrepl C-c C-K ClassFormatError?

18:14 mrowe: gtrak: but yes, one of the big advantages of using clojure is learning to think in new ways

18:14 flying_rhino: znDuff: is it? Is there example of small p[rogram made in clojure in procedural way? At least as an example of what not to do?

18:14 gtrak: mrowe: yea, I guess so. java-like stuff in clojure for me isn't hard because of mutability, it's hard because of tooling, imo.

18:14 Foxboron: Apparently Yegges says most of the Clojure community comes from Haskell

18:15 mrowe: but if people are going to keep wishing "if only clojure had $convential_language_feature_x"...

18:15 amalloy: why are we still talking about yegge?

18:15 Foxboron: amalloy, lol sorry.

18:15 znDuff: flying_rhino: What do you need an example for? What part isn't obivous?

18:15 Foxboron: I am commenting as i read along :P

18:17 znDuff: flying_rhino: ...I mean, everything you need is right there on the clojure cheatsheet, and most of it is used quite frequently when doing interop code.

18:17 flying_rhino: znDuff: well, where are those mutable vars for one? Please don't be annoyed with me. I do like advanced features of clojure, it just feels like overengeenering for some stuff.

18:17 znDuff: flying_rhino: atoms, and/or dynamic Vars.

18:17 flying_rhino: next question?

18:17 (preferably, atoms)

18:18 flying_rhino: so you can basically create python like code with atoms (if you wanted to) ?

18:18 znDuff: flying_rhino: It'd be silly, but you could.

18:18 Foxboron: Question, i read a place that "loop-recur" is a newbie trap, what would the other option be?

18:19 mrowe: flying_rhino: or you could just use python :)

18:19 brehaut: Foxboron: well, for primative recursion, 'reduce'

18:19 flying_rhino: znDuff: you just made this rhinoceros happy :)

18:19 Foxboron: brehaut, so i got a feeling i should sit down with map,filter and reduce and get a good grasp of that?

18:20 brehaut: Foxboron: yes

18:20 amalloy: IMO usually lazy sequences, not reduce, are usually a better thing to translate a new clojurer's loop/recur to

18:20 flying_rhino: mrowe: what if part of your app needs that aproach but you need multicore somewhere else, and you want to keep everything under JVM?

18:20 mefisto: znDuff: hey, where is that cheatsheet?

18:20 znDuff: mefisto: http://clojure.org/cheatsheet

18:20 flying_rhino: mrowe: my point is that deliberately locking lisp dialect to one scheme isn't wise.

18:21 does ANYONE get my point ??

18:21 lazybot: flying_rhino: What are you, crazy? Of course not!

18:21 amalloy: (inc lazybot)

18:21 lazybot: ⇒ 9

18:21 dnolen: flying_rhino: I don't think you've used Clojure long enough to have an informed opinion about the matter.

18:22 * dnolen switches back to lein-swank and lein 1 which actually ****ing work

18:22 mrowe: flying_rhino: there are already other jvm languages that are mutable by default and have good threading support (e.g. er, java)

18:22 amalloy: dnolen: i haven't tried nrepl, but i've been on lein2 for ages. preview10 works well, although latest master doesn't

18:23 flying_rhino: mrowe: yeah but lack of bloat due to macros is another nice feature of clojure that java (and other jvm langs) lacks. And imho big selling point of lisp is that it is flexible.

18:23 Foxboron: i also had luck with the preview10 where everything else failed

18:24 flying_rhino: mrowe: all in all procedural should not be mocked

18:24 brehaut: flying_rhino: haskellers (in particular) have long since shown that procedural is a special case of function calls

18:25 mefisto: thanks!

18:25 brehaut: also scheme i guess, though less obviously

18:25 mrowe: flying_rhino: have you read SICP? stepping back and thinking about other models of computation than procedural may give you some insight

18:26 mammoth: brehaut: look we are all turing complete here. My point is that one should always pick most straightforward practical approach.

18:26 I hate my ISP

18:27 everything not straightforward is masturbation in my opinion. Clojure is straightforward for multicore.

18:27 Sgeo: flying_rhino, have you considered trying Common Lisp?

18:28 gtrak: mammoth: ... that's very short-sighted

18:28 brehaut: mammoth: go read http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html and come back

18:28 gtrak: just because it's designed for multicore doesn't mean it's worse at other things

18:28 Foxboron: When it comes to language discussion, i enjoy what the father of Ruby said

18:28 "Ruby is the perfect language for me, not everyone else."

18:28 Sgeo: I have a bit of a Haskell background, I really like the immutability, even if I'm not doing multithreading

18:28 * aperiodic wishes that anyone who brings up turing-completeness in the context of comparing languages should be forced to write in a turing tarpit for a week

18:29 Sgeo: (inc aperiodic)

18:29 lazybot: ⇒ 5

18:29 brehaut: hells yes

18:29 mammoth: Sgeo: I figured it would be easier to improve procedural in Clojure than immutable in Common Lisp.

18:29 Sgeo: You could easily make a Common Lisp macro to make an immutable CLOS class...

18:29 I've done it

18:29 gtrak: mammoth: I wrote something over the weekend, kind of a troll, but relevant :-): https://github.com/gtrak/knr/blob/master/src/knr/core.clj

18:30 alindeman: Turing complete is not hard to achieve ;) It's kinda the point

18:30 gtrak: Niiiice

18:30 gtrak: you can see where I'm going with this: (let-free [myarray (-> :complex sizeof (* 16) malloc)]....

18:30 scriptor: alindeman: it's more that people insist just because two languages are turing complete they're essentially the same

18:31 Foxboron: baw.....gtrak looking at that code makes me wanna understand it :c

18:31 alindeman: scriptor: Ah

18:31 gtrak: it's the most mutable of codes

18:31 Sgeo: You can do everything with COBOL that you can do in Clojure!

18:32 bjorkintosh: uh oh.

18:32 Foxboron: You can do everything CLojure do in Assembler

18:32 But i don't think anyone wanna do that?

18:32 bjorkintosh: did i accidentally join #trollol?

18:33 scriptor: Foxboron: volunteering to build us a ClojureMachine?

18:33 Sgeo: bjorkintosh, people were mentioning the silliness of saying "Well, all these languages are TC, therefore they're all alike"

18:33 gtrak: my argument's that lisps ease of up/down abstraction makes it more moot than it would for other languages

18:34 Foxboron: scriptor, it was a response to sgeo :)

18:34 scriptor: I know, but I still think you should :p

18:34 Foxboron: Well

18:34 flying_rhino: scriptor: I do not insist that all languages are the same. All I am saying that since turing completeness makes everythiong possible in every language, practicality should win out. And immutability, although great at many places, is not ALWAYS the most practical thing

18:34 gtrak: think of what that low-level code would look like in java

18:34 Foxboron: scriptor, my experience of "low-level" programming goes as far down as "high-level" languages go.

18:35 Aka, none.

18:35 ^^

18:35 bjorkintosh: you guys are stuck in a frigging ivory tower. let's hear you make these arguments on a shop floor... what wins out? the right tool for the right job. period.

18:35 nothing else matters.

18:35 scriptor: flying_rhino: you could reverse that statement somewhat, couldn't you? While mutability may be practical sometimes, it's not *always* the most practical thing

18:35 it's just a matter of what you're working on

18:35 flying_rhino: scriptor: ofcourse

18:35 scriptor: that's why Clojure should have both

18:36 mefisto: clojure has mutability... what's the issue?

18:36 znDuff: flying_rhino: if you want a language that does everything, go have fun with Scala

18:36 flying_rhino: ...you'll find it to be an utter mess.

18:36 flying_rhino: trying to be too many things to too many people leads to a disorganized mess.

18:36 gtrak: it has *more* support for mutability than java. You can code event handlers and things to state change.

18:38 flying_rhino: mefisto: then why am I laughed at when I ask people to show me an example of mutable code in clojure?

18:38 gtrak: they like = more than reset! ?

18:38 flying_rhino: znDuff: well python isn't utter mess. Scala is but I don't think it is due to existance of mutability

18:39 znDuff: flying_rhino: Python isn't a mess because it's written by one person at the helm with a consistent design vision and purpose... much like Clojure.

18:40 brehaut: flying_rhino: nobody is laughing at you. they are telling you that its not the idiomatic way in clojure

18:40 znDuff: flying_rhino: Python explicitly _rejects_ trying to support all workflows and styles -- deciding that Perl was completely wrong in following TIMTOWTDI was really the Big Idea behind it, in my eyes.

18:40 * Foxboron holds for his ears as someone mentions python and mess in the same line

18:40 mefisto: flying_rhino: it's not idiomatic

18:41 flying_rhino: mefisto: I would still like to see that not-idiomatic code.

18:41 for the lulz

18:41 Foxboron: People should have a more relaxed relationship with "non-idiomatic" code

18:41 mefisto: flying_rhino: you can abuse things like atoms or do it with java classes. I don't have a code example handy

18:42 gtrak: flying_rhino: https://gist.github.com/ec9043e47789bc11d662

18:42 Foxboron: "Its not idiomatic! i refuse to code!"

18:42 bbloom: there is also the set! form

18:42 flying_rhino: gtrak: thanks! What was so hard about this?

18:43 gtrak: nothing?

18:43 clojurebot: @ has nothing to do with whether sth is evaluated or not

18:43 bbloom: and i think you'd be surprised at how far you can push immutability

18:43 :-)

18:43 brehaut: Foxboron: writing non-idiomatic code is fine, if you already create idiomatic normally. writing sensible python in clojure is a silly

18:43 Foxboron: brehaut, sounds like what i am doing now, but i am however a newb, so i feel i can be excused on that ^^

18:44 gtrak: flying_rhino: obviously we want to discourage unidiomatic code to people who are learning the language.

18:44 flying_rhino: brehaut: nothing is silly if it solves certain problem the best.

18:44 bbloom: the more clojure i write, the harder i find it to think in the presence of mutation in other languages… it's made me deeply aware of all the complexities of state. now it's like hearing a voice that i can't silence that says "somebody is gonna mutate that and fuck you up"

18:44 mefisto: Foxboron: I think clojure's approach to idiomatic code is somewhat similar to the notion of fate in the webcomic erfworld... you can fight against it, but you will just end up taking a more painful path to the same place

18:45 gtrak: if you know better, go ahead, but you should make sure you know it all the way before doing it wrong out of habit

18:45 Foxboron: mefisto, what if drop the fighting and live in harmony?

18:45 if we drop*

18:46 mefisto: there's no "we"... the idea is, you will just end up fighting against the language and yourself ;)

18:47 brehaut: flying_rhino: writing python code in clojure is silly.

18:47 flying_rhino: by definition, its not solving the problem best

18:47 Foxboron: oh btw, while i still remember it

18:47 Anyone got any books/sources about thinking in a functional language?

18:47 bbloom: if you really want to do a lot of mutation, maybe for perf or what not, write some java

18:48 and that's not a joke

18:48 Foxboron: kinda stuck with the OO kind of doing stuff, and its a bit anyoing.

18:48 bbloom: i mean seriously: write some java! that's what it's there for. you can call it easily from clojure

18:48 mrowe: Foxboron: http://mitpress.mit.edu/sicp/

18:48 dnolen: cemerick: so does nrepl still blow up if given a large set of contents?

18:48 mefisto: Foxboron: clojure in action from manning, or for the purest of pure functional heroin take a look at http://learnyouahaskell.com/

18:49 gtrak: bbloom: I've worked longer in java, but I find it to be more of a hassle to write a bit of java than to fight through java interop in clojure.

18:49 mrowe: Foxboron: also, Brian Marick's "FP for OOP programmers" is not bad: https://leanpub.com/fp-oo

18:49 bbloom: Foxboron: I'll second SICP. good stuff!

18:49 Foxboron: mefisto, not looking for a new lang ;P

18:49 mammoth: brehaut: I was using it as an example of simple pragmatic language.

18:50 Sgeo: Can that FP for OOP programmers thing teach an FP programmer OOP?

18:50 By showing examples in the reverse?

18:50 ChongLi: Sgeo: SICP includes some stuff on OOP

18:50 Foxboron: Sgeo, OOP is cake....

18:50 mefisto: Foxboron: I learned some haskell first and found it easier to move to clojure from there. to really immerse yourself in functional stuff I think haskell is more direct

18:50 Sgeo: Although I think I still rely on state too much

18:50 ChongLi: but they start from first principles

18:51 which may actually teach you more about OOP

18:51 (from a different angle)

18:51 Sgeo: I've read a bit of Let over Lambda

18:51 Foxboron: mefisto, hahahahaa. I got a friend doing a CMS in Haskell atm :) But i'll do it if i get some time!

18:51 ChongLi: I really love how SICP does it

18:51 mefisto: a CMS in haskell? this I'd like to see

18:51 ChongLi: they start off with pure functions and teach you the great beauty of the substitution model

18:51 Foxboron: mefisto, 2 sec then.

18:51 Sgeo: I started on SICP a while ago, but sort of paused for a long while

18:51 ChongLi: and then they tear that down when they introduce assignment

18:52 it's actually quite traumatic

18:52 Foxboron: mefisto: https://github.com/Tehnix/HsCMS

18:52 mefisto: running on codetalk.io atm

18:52 mefisto: thanks!

18:52 Foxboron: NP :)

18:52 tufflax: Is Let Over Lambda good?

18:54 hcumberdale: hi

18:54 tufflax: hi there

18:57 hcumberdale: how can I access a atom from another thread?

18:59 crease: hcumberdale: as you normally would, I think

18:59 amalloy: tufflax: it's all right

19:00 mammoth: brehaut: are you dave fayr ?

19:00 brehaut: mammoth: no

19:01 amalloy: nothing like as good as sicp

19:01 mammoth: well it was nice read

19:01 thanks

19:01 tufflax: As far as I've understood (without reading LOL) they have different goals :p

19:01 mammoth: thanks for pointing me to it, I mean

19:01 tufflax: SICP and LOL that is

19:02 amalloy: indeed. i think LOL's goal is to tell you that common lisp is the only lisp worth using

19:02 tufflax: hehe

19:02 amalloy: along the way he definitely says some interesting things

19:03 brehaut: mammoth: no problem. i think its a really good article

19:03 mammoth: a great examination of why an initially straightforward looking solution is sub optimal, and how a 'more complex' solution is actually easier to understand

19:04 mammoth: brehaut: I just don't think it changed my point much. Look, I like functional. If I didn't I wouldn't be here. I just think exclusion of other styles is bad. I don't want to start flame again but that was my point.

19:04 abp: hell-o

19:05 technomancy: steve? is that you?

19:05 the whole point of FP is to prevent you from doing harmful things

19:05 just like the point of garbage collection is to prevent you from making memory allocation mistakes

19:06 mammoth: brehaut: take a look at his ruby example. It uses functions in vectors (which I like, very much) but is still mutable. In other words it is potent mix of functional and procedural.

19:07 brehaut: mammoth: thats what i consider a potent mix of shooting myself in the foot in 6 months time ;)

19:07 abp: What is the best approach to build functional graphs? I use clojure.tools.namespace.dependency presently, which gives me a structure like #Graph{:dependencies {:b #{:a}}, :dependents {:a #{:b}}} Would using something zippable be "better"?

19:09 brehaut: mammoth: i (like i suspect a lot of clojure programmers) am fine with small, carefully applied piece of mutability as long as carefully demarcated and has clear access semantics

19:09 abp: I'm ultra afraid of mutable things now. :x

19:10 brehaut: apb: i wouldnt watch John Carpenters The Thing then

19:10 flying_rhino: I like when main thread in program uses mostly mutable data (but still uses other functional stuff like functions as arguments), but it spawns side threads that work on immutable data.

19:11 abp: brehaut: I have watch it. It's our society in terms of objects. :D

19:11 Foxboron: and there i thank Clojure for another night with...... 5 hours of sleep.

19:11 Night peeps :) Remember to sleep and save yer beards ^^

19:11 abp: brehaut: Thanks for help shaping this metaphor.

19:13 OOP, you know, it's like everbody running around, heavily shifting looks and skin, everything! Wait, have you watched Carpenters The Thing?

19:15 brehaut: This summer, coming to a cinema near you: John von Neumann's The Thing

19:15 tufflax: :)

19:19 ChongLi: how about escher's metacircular evaluator?

19:56 devn: Is there a way to limit the buffer length of a slime repl in emacs so it doesn't choke if it wants to print, say, 10,000 lines?

19:57 i know about (set! *print-length* ...) and so on, but I have an open buffer and I'm doing some poor man's debugging and want to stop it from choking.

19:57 CaptainDerp: Hi, how do i cleanly swap an atom within a map that is not an atom?

19:57 tomoj: the only think I know is to be careful what I print :(. I think nrepl mostly fixes the problem

19:58 devn: tomoj: that's not a luxury I have in this case

19:58 CaptainDerp: (swap! theMap assoc key val) swaps the val within a map that IS an atom

19:58 devn: I know what's going to print. It's 280,000 strings.

19:58 CaptainDerp: but i do not want restriction on the map itself (so i do not want to make it an atom)

19:59 brehaut: CaptainDerp: so you have (let [the-map {:atom (atom 1)}] … )

19:59 ?

20:00 ,(let [the-map {:atom (atom 1)}] (swap! (:atom the-map) inc))

20:00 clojurebot: 2

20:00 devn: tomoj: right now I just am hitting C-c M-o every 2000 lines or so, but that is getting...ridiculous.

20:00 CaptainDerp: more like (let [the-map {"123" (atom 1)}]

20:01 (swap! ("123" the-map) inc)) like that?

20:01 brehaut: ,(let [the-map {"abc" (atom 1)}] (swap! (the-map "abc") inc))

20:01 clojurebot: 2

20:02 brehaut: keywords are functions of maps, but strings are not. but maps are functions of their keys

20:02 CaptainDerp: ok awesome

20:02 thanks

20:03 ... also I do not want the map to be an atom because I am afriad that this will restrict access to mapped values.

20:03 Am i right in this justification and by never changing the map itself and only the atoms refereneced i should be fine right?

20:04 brehaut: i guess. you are the only person who knows your programs requirements though

20:04 znDuff: CaptainDerp: waitamoment, why are you trying to do it that way? You talk about not wanting some restriction, but I'm very unclear on what exactly that restriction _is_.

20:05 seangrove: Hey all, I've done something stupid with my project, and now I get: Exception in thread "main" java.lang.ClassNotFoundException:


20:05 CaptainDerp: I did not want to overload with tmi. But basically i will have client front ends polling from blocking queues referenced by the maps.

20:05 clojurebot: maps are *AWESOME*

20:05 seangrove: This has got to be super basic... I'm using (:gen-class :main true), lein 2..

20:05 CaptainDerp: Thanks clojurebot!

20:06 And i need other threads to add to the queues referenced by the map

20:06 by making the whole map an atom, it works

20:06 but wouldn't this be a bottleneck if muliple client front ends are trying to access the mapped values (if another client is already accessing the mapped values)

20:07 znDuff: CaptainDerp: atom derefs are non-blocking.

20:07 CaptainDerp: basically: can muliple threads access an atom at once without slowdown/issues

20:07 ah

20:07 brehaut: CaptainDerp: why are you putting queues in atoms?

20:07 CaptainDerp: it just blocks if a change is being made

20:07 znDuff: CaptainDerp: ...no, I didn't say that either. :)

20:07 CaptainDerp: ok

20:07 seangrove: Maybe lein 2pre10 is borked...

20:08 CaptainDerp: an atom facilitates multiple thread access right?

20:08 znDuff: CaptainDerp: swap! can repeat the operation if a check-and-set indicates that someone else changed it at the same time

20:08 CaptainDerp: an it is synchronous not asych

20:08 znDuff: CaptainDerp: so -- it doesn't block, it just retries.

20:08 CaptainDerp: (which is why you want the operation you pass to swap! to be something fast and free of side effects)

20:09 CaptainDerp: ...so -- the check-and-set / retry thing is very much inherently async.

20:09 brehaut: CaptainDerp: are you using clojure.lang.PersistentQueue or java.util.concurrent.LinkedBlockingQueue ?

20:09 CaptainDerp: ok but if the map itself is an atom and not all the mapped objects then will check-and-set fail if the specified mapped object is not being accessed but another mapped object is?

20:09 amalloy: that's the opposite of async, znDuff

20:10 CaptainDerp: java.util.concurrent.LinkedBlockingQueue

20:10 flying_rhino: brehaut: maybe the thing Yeggie was ranting about can be summed up as "What's more, if you write your liberal-language code in a conservative way, people will just look at it and say: 'Well, it's kinda boring, and you could have saved a lot of coding by using some dynamic features. But I guess it gets the job done. LGTM.' " While in conservative language everyone is upset when you do things libera

20:10 brehaut: CaptainDerp: then you dont need to put them into atoms to handle mutation or access

20:10 znDuff: ...you're ordering completion, yes, but you're not using a lock to pre-serialize.

20:11 flying_rhino: brehaut: when I suggest python-ish way in clojure no one liked it

20:11 * znDuff ponders, and decides he needs more sleep.

20:11 amalloy: try suggesting a clojure-ish solution in python. nobody will like that either

20:11 flying_rhino: brehaut: this might be what yegge was talking about.

20:11 znDuff: flying_rhino: I have to agree w/ amalloy and friends -- "#python is for good ideas only", to quote their policy.

20:12 flying_rhino: ...if you talk about doing things in a non-Pythonic way there, you _do_ get shut down.

20:12 amalloy: hah, really? that's a great policy

20:12 flying_rhino: znDuff: all I am saying is that stuff like this make clojure conservative as yegge said.

20:12 CaptainDerp: ok i am still not 100% clear. I need a map where i have async access to its mapped values but sych access to each specific mapped value.

20:12 znDuff: (more politely than in #bash, but that's a different discussion)

20:12 flying_rhino: it is not all bad znDuff

20:13 znDuff: flying_rhino: ...but Yegge claims that Python is liberal, while it has the same culture.

20:13 CaptainDerp: (multiple threads can access different mapped values, but not the same mapped value)

20:13 flying_rhino: znDuff: he didn't say python is particulary liberal, that's ruby

20:13 CaptainDerp: sorry, access and manipulate

20:13 brehaut: flying_rhino: is it conservative to tell someone not to drive their car on the wrong side of the road? or is that just common sense?

20:14 abp: flying_rhino: What things from python do you mean?

20:14 znDuff: flying_rhino: ...and Ruby is also an utter bloody mess.

20:14 flying_rhino: brehaut: yeah but you guys clasify a lot of stuff as wrong, while liberals clasify frwer stuff as wrong.

20:14 * znDuff shrugs. He has work to do.

20:14 flying_rhino: *fewer

20:14 CaptainDerp: Eh? ... in the flood of messages should i restate what i asked?

20:14 brehaut: flying_rhino: python classifies just as much stuff as wrong

20:15 flying_rhino: writing function code in python is largely considered not pythonic

20:15 seangrove: Uhg just started a new project with lein, and still get this with `lein run`: "Exception in thread "main" java.lang.ClassNotFoundException: zenbox.core"

20:16 CaptainDerp: ok i am still not 100% clear. I need a map where i have async access to its mapped values but sych access to each specific mapped value.

20:16 (multiple threads can access different mapped values, but not the same mapped value)

20:16 (atom {}) does not provide this right?

20:16 but {"abc" (atom 1)} does?

20:16 seangrove: What am I missing here?

20:17 flying_rhino: brehaut: I guess we will have to agree to disagree about some stuff (not as much stuff as you might think). I'll continue with clojure even if I am not as fired up as I might have been.

20:17 technomancy: clojure will not turn bad ideas into good ones

20:17 sad but true

20:17 brehaut: flying_rhino: try programming clojure with the grain, rahter than trying to fight it. you might find it more enjoyable

20:17 (inc technomancy)

20:17 lazybot: ⇒ 40

20:18 brehaut: far out man. spend some of that karma somehow

20:18 technomancy: clojurebot: drinks are on meeeeeee!

20:18 clojurebot: No entiendo

20:18 flying_rhino: brehaut: will do

20:19 znDuff: CaptainDerp: When you say "async access", you really mean non-blocking access, right?

20:19 CaptainDerp: ...and when you say "sync access" for writes, you mean you want them to be coordinated?

20:20 CaptainDerp: because if that's the case, I don't see why you can't just put the whole thing into an atom... _maybe_ a ref, if you have more complex logic going on around updates than you're telling us.

20:20 CaptainDerp: znDuff async as in non-blocking yes (aka not an atom), and sync as in blocking (aka atom)

20:20 znDuff: CaptainDerp: ...ehh.

20:21 CaptainDerp: atoms are always non-blocking on reads.

20:21 CaptainDerp: ...they can spin a little on writes, but it sounds like that's what you want.

20:21 CaptainDerp: znDuff but if i have (atom {}) and try to swap! a value (val1) within it, will it block if val2 if being accessed?

20:21 znDuff: CaptainDerp: if it's a read access? No.

20:21 CaptainDerp: znDuff yes i know for reads, but i am concerned about writes

20:22 i will never be swapping the map or removing the map, just the mapped values

20:22 znDuff: CaptainDerp: I'd suggest doing it the natural way, and changing it only if benchmarks show you have a problem.

20:22 brehaut: CaptainDerp: LinkedBlockingQueues are already mutable; No Requiere Atom

20:23 CaptainDerp: brehaut: so if i have ({"123" LinkedBlockingQueues} then i do not have to care about any of this?

20:23 brehaut: CaptainDerp: they have their own access semantics

20:23 CaptainDerp: hmm ok makes sence

20:23 sense *

20:23 brehaut: CaptainDerp: well, you dont have to care about atom semantics. you have to care about the queue semantics

20:23 CaptainDerp: i can throw atoms out the window for now then :P

20:24 brehaut: (the queues allow nonblocking writes, and blocking reads (with optional timeoutes) from memory)

20:24 CaptainDerp: brehaut true

20:24 but that is easy imo

20:26 god, replacing a map value is anoying as well it looks like i should do this: (update-in entity [:position] #(add % (:velocity entity)))

20:26 ... but i find that a bit confusing

20:27 swap! has easy samantics lol

20:27 brehaut: CaptainDerp: fnil is your friend

20:28 ,(update-in {:a {}} [:a :b] (fnil inc 0))

20:28 clojurebot: {:a {:b 1}}

20:29 amalloy: how does his problem have to do with fnil?

20:29 CaptainDerp: ok thats cool i guess, provides a default value if passed 0

20:29 but ya what amalloy said

20:30 brehaut: amalloy: it has a lot to do with it if you violently misread things

20:30 otherwise: not much

20:30 amalloy: the advice he needs is more like (update-in entity [:position] add (:velocity entity))

20:30 CaptainDerp: hmm all i need is an example

20:30 {"abc" 1}

20:31 replace abc with 2

20:31 :)

20:31 amalloy: look up, one line above your name, for an example :P

20:31 dnolen: ,(update-in {:abc 1} [:abc] inc)

20:31 clojurebot: {:abc 2}

20:31 dnolen: ,(update-in {:abc 1} [:abc] + 4)

20:31 clojurebot: {:abc 5}

20:31 CaptainDerp: ok thanks a lot dnolen

20:31 dnolen: ,(update-in {:abc {:x 1.0 :y 5.0}} [:abc :x] * 0.5)

20:31 clojurebot: {:abc {:y 5.0, :x 0.5}}

20:33 CaptainDerp: (defn update-map [key val] (update-in theGlobalMap [key] val) )

20:33 .. correct?!?

20:34 * CaptainDerp thinks that may be a bit redundant

20:35 dnolen: CaptainDerp: why not pass the state as explicit argument? I'm assuming you're making some kind of game here.

20:35 brehaut: (comp update-in global-map)

20:36 comp‽

20:36 no, partial

20:36 * brehaut grinds coffee

20:37 * dnolen continues working on CLJS source-mapping

20:38 brehaut: CaptainDerp: minor point: camelCase is ugly in lisp. http://mumble.net/~campbell/scheme/style.txt

20:38 section ** Names

20:39 with the exception that camel case is still used for things that generate java classes or interfaces

20:47 dnolen: bbloom: ping

20:49 bbloom: dnolen: pong

20:50 dnolen: bbloom: working on source mapping again - I see you didn't bother to add column info to symbols only seqs?

20:50 bbloom: dnolen: you mean in the jvm's reader?

20:50 dnolen: bbloom: yep

20:50 bbloom: dnolen: hmm. i'm not sure. i basically did a search for all occurrences of "LINE" and added a parallel COLUMN

20:51 dnolen: also, my patch was pretty stale by the time somebody applied it

20:51 dnolen: bbloom: http://github.com/clojure/clojurescript/commit/07e5516aa3cbb022ccf1659e3bf66d270ede049e

20:51 bbloom: dnolen: oh! you mean in the clojureSCRIPT compiler

20:51 dnolen: bbloom: it's better than nothing, but errors now get line & column information

20:51 bbloom: dnolen: sorry, i misunderstood

20:51 dnolen: bbloom: no I mean your patches to the Java reader

20:51 bbloom: those patches affect what we see in CLJS

20:51 bbloom: dnolen: oh, heh ok then i did understand :-)

20:52 dnolen: well 1.5 isn't out yet, it's not too late to sneak in a patch, is it? :-)

20:52 dnolen: bbloom: still, like I said, this is a big improvement even for errors - starting to look into the merge process

20:53 bbloom: we can fully decode Closure source maps, now just need to take that info and merge with compiler mapping and generate the final source map.

20:53 bbloom: dnolen: awesome

20:54 dnolen: bbloom: it would be nice to get into 1.5.0 but I'm not holding my breath

20:54 bbloom: dnolen: I'm peaking at Compiler.java to see what i missed

20:54 peeking*

20:55 dnolen: bbloom: you can't put metadata on arbitary things of course, really I just want them on var symbols (including locals)

20:55 bbloom: dnolen: but you can put them on symbols, right?

20:55 dnolen: if they have line data, they should have col too

20:55 dnolen: bbloom: yes that's what I meant ^

20:55 bbloom: dnolen: keywords can't have them tho

20:56 or am i remembering wrong...

20:56 &^:x 'y

20:56 lazybot: ⇒ y

20:56 bbloom: &(with-meta (symbol "x") {:y 1})

20:56 lazybot: ⇒ x

20:56 bbloom: &(with-meta (keyword "x") {:y 1})

20:56 lazybot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IObj

20:56 bbloom: yeah

20:57 dnolen: bbloom: yeah I'm not even sure column info on keywords is that useful - vars & locals are what you're interested in when debugging.

20:57 TimMc: &(read-string "^:x 'y")

20:57 lazybot: ⇒ (quote y)

20:57 TimMc: &(read-string "^:x y")

20:57 lazybot: ⇒ y

20:58 bbloom: dnolen: yup. just thinking aloud

20:59 dnolen: ok so you said seqs have columns, but not symbols? what about vars?

20:59 abp_: dnolen: Is this: https://gist.github.com/4115467 a legitimate solution to not being able to use qualified symbols in a macro?

21:01 cemerick: dnolen: "blow up given a large set of contents"?

21:01 bbloom: heh, everyone trying to talk to dnolen at once :-P

21:02 dnolen: abp_: what you mean is qualified symbols in fn args?

21:02 cemerick: resolved, old issue in nrepl that affects beta but not RC1

21:02 abp_: dnolen: That's a tiny part of my take on prismatics graph. I want to build reactive systems fully declared in terms of fnk-graphs. But i want to use qualified keywords in maps and need to destructure them into qualified symbols.

21:02 cemerick: oh, probably related to load-file

21:02 abp_: dnolen: Yep, let's too, I think.

21:02 bbloom: dnolen: VarExpr and TheVarExpr don't seem to take source, line, or column values in their constructors. that's likely the source of the trouble

21:02 cemerick: Not super-happy about the resolution there, but it'll do for now.

21:03 dnolen: abp_: anything like will involve some hack - no opinions on that from me :)

21:03 cemerick: yes load-file was broke

21:03 abp_: dnolen: When one get's the source of such an fn.. Now, it's not what it pretends to be. That's my only concern.

21:03 dnolen: bbloom: yeah that sucks, tooling wants that info.

21:04 bbloom: dnolen: I don't really have time to hack on this now, but I think it's a straightforward patch to add that stuff

21:04 dnolen: bbloom: heh, wasn't asking for a patch - just insight

21:05 bbloom: dnolen: well here's my insight: the base Expr interface should have column and line info

21:05 dnolen: right now, that info only exists where strictly necessary for particular categories of errors

21:06 abp_: dnolen: What is the best approach to build functional graphs? I use clojure.tools.namespace.dependency presently, which gives me a structure like #Graph{:dependencies {:b #{:a}}, :dependents {:a #{:b}}} Would using something zippable be "better"?

21:07 bbloom: abp_: what do you mean by zippable?

21:08 abp_: the best approach to representing graphs is gonna vary based on the use case

21:08 dnolen: abp_: I really don't know what's best, I haven't considered that particular problem before. others might have thoughts on that - might want ask on the mailing list as well.

21:08 abp_: dnolen: Yes.

21:09 CaptainDerp: is there any way to replace/add values in a map without having to replace the original map?

21:09 ChongLi: CaptainDerp: put the map in an atom

21:09 and update it with swap!

21:09 CaptainDerp: oh my fucking god

21:09 abp_: bbloom: By zippable I mean hierarchical, glad you asked. ;) The use case is building topological chains and wrapping nodes.

21:09 CaptainDerp: here i was one hour ago and people in here convinced me not to use atom

21:09 ChongLi: ?

21:10 * CaptainDerp twitch

21:10 dnolen: CaptainDerp: that seems like missing the point - functional updates.

21:10 CaptainDerp: sorry

21:10 haha

21:10 ChongLi: what were their arguments?

21:10 I'm not exactly a pro clojure hacker

21:10 bbloom: abp_: it seems that zippers are only really useful for trees with containment. they don't really seem to have any support for some top-level notion of an index

21:11 abp_: by that I mean if you had some map of node-id to a vector of child node ids, there isn't really a clean way to use a zipper on that

21:11 dnolen: CaptainDerp: if perf is an issue there are ways to achieve Java perf mutation - but I would try to understand the Clojure way for the time being.

21:11 bbloom: abp_: immutible graphs almost necessitate that type of node or edge (or both) index

21:12 abp_: but there may be a functional analog of a zipper… although i don't know of one

21:12 analog, for graphs, i mean

21:12 ChongLi: I guess it really depends on what you're doing

21:12 if you end up making the map an argument to every function

21:12 you're probably doing something weird

21:14 abp_: bbloom: Isn't clojure.zip functional? It's able to zip into nested vectors.

21:15 bbloom: abp_: zippers only work on trees, not graphs

21:15 CaptainDerp: ok i am trying to swap an atom within a map but it only accepts a function: (swap! (theMap key) val) fails

21:15 bbloom: abp_: you can project a graph onto a tree via a walk, but zippers provide editing and the interface to clojure's zipper library isn't robust enough to support graph-backed trees

21:15 ChongLi: the map should be in the atom

21:15 CaptainDerp: it is

21:16 oh wait

21:16 sorry no

21:16 i cant have the map as an atom

21:16 ChongLi: why not?

21:16 CaptainDerp: otherwise i would use assoc

21:16 i need it to be non-blocking on writes

21:16 abp_: bbloom: Good to know, then i'll stick with clojure.tools.namespace.dependency for a while. It's basically just the index representing the graph.

21:16 ChongLi: oh

21:17 an agent is probably what you want then, right guys?

21:17 CaptainDerp: hmm

21:17 bbloom: abp_: yeah, that's the simplest and most common graph representation: some index of nodes and some index of edges, plus optionally a reverse index of edges

21:17 ChongLi: a clojure agent provides shared access to mutable state

21:17 and does so in an indepdent, asynchronous manner

21:18 independent

21:18 bbloom: abp_: if you read Huet's original paper on zippers, you might discover a way to apply the principals to graphs :-) or maybe somebody else already has, but i don't know if it

21:19 CaptainDerp: so i have to wrap my map?

21:19 ChongLi: if you want to store it in an agent, yeah

21:19 CaptainDerp: but is that a necessity ?

21:20 ChongLi: would it be a problem?

21:20 you want multiple threads to hammer on this map in an asynchronous, non-blocking fashion?

21:21 CaptainDerp: so are you saying that there is no way i can update a map's values?

21:21 i have to replace the map always

21:21 bbloom: CaptainDerp: yes. and that is a feature

21:21 CaptainDerp: bbloom thank you

21:21 bbloom: CaptainDerp: in fact, that's one of the BEST features of clojure :-)

21:22 ChongLi: CaptainDerp: you're not "replacing the map"

21:22 you're associng new key value pairs with the map

21:22 CaptainDerp: so in order to update a map's values i have to wrap it in an agent

21:22 bbloom: CaptainDerp: no

21:22 CaptainDerp: forget agents

21:22 CaptainDerp: forget atoms

21:22 ChongLi: CaptainDerp: no, you can pass it around all you want

21:22 bbloom: CaptainDerp: take a break from all that stuff for a bit

21:23 CaptainDerp: that stuff exists for concurrency

21:23 loliveira: ,(let [{:keys [c d] :or {:c 0 :d 0}} {:d 5}] [c d])

21:23 clojurebot: [nil 5]

21:23 bbloom: you need to get a handle on the core concepts before you touch the more advanced ones

21:23 loliveira: shouldn't eval to [0 5]?

21:23 bbloom: i recommend 4clojure.com

21:23 CaptainDerp: bbloom: it is the key issue i working through at the moment

21:23 i got it working as an atom but that is innefficent

21:23 ChongLi: CaptainDerp: can you tell us more about what you're actually trying to do?

21:23 bbloom: CaptainDerp: http://www.4clojure.com/users follow 10 or 20 of the top users there

21:24 CaptainDerp: i may not know all the concepts but this best how i learn

21:24 aperiodic: loliveira: ##(let [{:keys [c d] :or {c 0 d 0}} {:d 5}] [c d])

21:24 lazybot: ⇒ [0 5]

21:24 bbloom: try the puzzles on 4clojure and then learn from the other people who solved them

21:24 aperiodic: loliveira: you're providing defaults for the symbols, not the keywords

21:24 loliveira: thank you

21:25 aperiodic: you're welcome

21:25 bbloom: CaptainDerp: you might want a "transient" if you're "birthing" a value. however, everyone in this channel is just guessing what you're trying to do, so the advice is watered down

21:25 CaptainDerp: i just neeed a map with asych access (def will do that), sych reads and writes to the values (no issue there im using a blocking queue), but i need to add/replace key/values in the map without replacing the map

21:25 ChongLi: CaptainDerp: clojure uses structural sharing

21:25 bbloom: CaptainDerp: do *NOT* use def for modifying variables. ARGH that's not even close to right :-P

21:25 ChongLi: it never "replaces the map"

21:25 CaptainDerp: the key issue at the moment is aysch writes

21:26 bbloom: CaptainDerp: no, the key issue is that you aren't comfortable with immutability :-P

21:26 CaptainDerp: bbloom i am not using it for modigying i am using it only for initial creation

21:27 bbloom frankly i think you are being a bit rude. I have no issue with concurrancy or immutability i am learning the clojure process of dealing with them.

21:27 bbloom: CaptainDerp: my apologies

21:27 CaptainDerp: You're right. my comment was out of line

21:27 ChongLi: there's a big difference between typical immutable values in a language like java (where full copies are performed) and the persistent data structures used in clojure

21:27 bbloom: CaptainDerp: I'll go back to work :-P

21:28 CaptainDerp: no problem, 12 hours in at work here and shit can go crazy too

21:28 ChongLi: CaptainDerp: agents are what you want to manage asynchronous change

21:28 (def blah (agent {}))

21:28 CaptainDerp: i almost am done, i already have it working. But i know that efficency is going to be an issue if the whole map is an atom

21:28 ChongLi: (send blah assoc :a "hi")

21:28 (send blah assoc :b "hello")

21:29 atoms and agents are just reference types

21:29 CaptainDerp: ChongLi thanks i will look into it again. I was just hoping to avoid them but after that hepful information by bbloom i understand i cant modify datastructures without replacing

21:29 ChongLi: you aren't "replacing"

21:30 if a map contains 10000 key value pairs

21:30 and you make one change

21:30 dnolen: CaptainDerp: bbloom was trying to suggest that you thread your state as an immutable value through your program

21:30 ChongLi: it will not copy all 10000 pairs

21:30 dnolen: CaptainDerp: I would try to do that first before messing with atoms or agents.

21:30 ChongLi: it'll make a new branch of the tree and copy like 32 values at most

21:30 dnolen: he wants asynchronous updates

21:31 generally the way you want to design your program

21:31 is as a box of pure functions

21:31 dnolen: ChongLi: right, then sure agents could work. that wasn't clear earlier.

21:32 ChongLi: and a small collection side-effecting functions forming a "shell" around the pure core

21:34 CaptainDerp: apologize if i was not clear, often it is hard to be in an irc where a message may have been missed or overlooked or 12 hours in im starting to something... something

21:34 ok i think i know how now:

21:34 (theMap (agent {}))

21:34 (send theMap assoc key val)

21:34 ChongLi: you need def if you want to do that

21:35 CaptainDerp: yes i left that out

21:35 but i am

21:35 ChongLi: it all depends on what exactly you're doing with this map

21:36 but generally what you want is a function that takes a map, some other values and returns a map

21:36 and then use send with that

21:36 don't use send all over the place in your code

21:36 try to use it in only one location

21:37 CaptainDerp: i might not be doing this the best way but i am using this global map as a buffer for "tickets" that will be recieved by a front end

21:37 i am programming a clojure web server

21:37 ... it may be a bit too long to explain in this irc

21:38 ChongLi: have you looked at the existing ecosystem?

21:38 CaptainDerp: I would love to explain it and get your opinion if it is a good structural idea but i dont want to bore you :P

21:38 ChongLi: or are you just rolling your own to learn?

21:39 CaptainDerp: what do you mean by the existing ecosystem?

21:39 ChongLi: noir, compojure, ring etc.

21:40 another lib is aleph

21:40 CaptainDerp: yes not in depth. But my coworker has (who is actually doing most of the web server work)

21:40 ChongLi: I don't have any experience with this stuff

21:40 CaptainDerp: i am just builing a couple components

21:40 ChongLi: just throwing out stuff I know about

21:40 CaptainDerp: i had to learn ring and a couple other things to understand how to respond to messages

21:41 seangrove: Do I have to do anything special to get noir to serve static assets?

21:41 CaptainDerp: this whole thing is to facilitate long polling as well

21:41 seangrove: I've googled quite a bit, can't seem to find it. I have a resources/public folder, but noir isn't service anything from there

21:42 ChongLi: seangrove: hmmm

21:42 seangrove: heh, s/service/serving

21:42 ChongLi: noir may not be optimized for that

21:43 is it not desirable to use something like apache/nginx for those?

21:43 seangrove: Oh, just for development right now

21:43 cshell: how are you referencing the static files?

21:44 ChongLi: oh

21:44 you need to add a route for them

21:44 (route/resources "/")

21:46 oh nvm

21:46 that's compojure

21:46 haha

21:46 seangrove: Yeah, that's what I thought, heh

21:46 Looking through the noir docs again...

21:48 cshell: did you try referencing it without the public?

21:48 seangrove: cshell: Yeah, I've tried all permutations, but I believe it should be at http://localhost:8080/css/styles.css

21:49 CaptainDerp: Hmm isnt send and swap the same kind of thing but the first is for agents and the second is for atoms?

21:49 ChongLi: looks like noir doesn't have any special handling for this

21:49 they want you to use slurp

21:50 CaptainDerp: it's the same general kind of thing

21:50 cshell: what does the browser return?

21:50 ChongLi: but the semantics of the operation is totally different

21:50 swap! is just comparing the value and swapping it if it wasn't modified

21:50 seangrove: cshell: The server just returns 404, standard noir "we can't find that one" page

21:51 cshell: hmmm, i am able to get my css page at that same address

21:51 ChongLi: send queues your action on a thread pool

21:51 CaptainDerp: ok so what would be the equivilant of (swap! theMap assoc key val)?

21:51 cshell: let me see if I did anything to configure it

21:51 CaptainDerp: oh wait i think i know

21:51 derp

21:51 cshell: seangrove: do you call load-views?

21:52 CaptainDerp: actually nevermind my inital thought was still right

21:52 seangrove: cshell: I did (load-views-ns ...)

21:52 CaptainDerp: ChongLi: what is the equivilant?

21:52 seangrove: One moment, I might have had something else causing a problem..

21:52 Ah, ok

21:52 I was running lein run, and there was some problem with the code, and it wasn't getting reloaded

21:52 So my changes were being ignored

21:53 cshell: Yeah, that can do it

21:53 seangrove: Sorry about that... but thanks cshell and ChongLi

21:53 cshell: I do'nt think there's anythin special you do

21:53 I can't find anything I did

21:54 seangrove: Seems to be working now. Maybe I should hook up lein run/cljsbuild errors to growl somehow

21:54 CaptainDerp: ChongLi: what is the equivilant?

21:55 what would be the equivilant of (swap! theMap assoc key val)?

21:56 i do (send theMap assoc key val) but i get an error if i try an access key later in the same thread

21:56 wait... would send be doing the action asych and i am trying to access the val before it is sent/done?

21:56 /added

21:56 :P

21:56 dnolen: bbloom: ping

21:56 * CaptainDerp loves threads and asych

21:57 bbloom: dnolen: still here

21:57 dnolen: bbloom: you might know this since you worked on the lexical stuff.

21:57 CaptainDerp: hmm i think i am correct

21:57 brehaut: CaptainDerp: still camelCasing? hyphen-names is preferred

21:57 dnolen: bbloom: did you notice that vars created by def don't actually pass along the var map?

21:57 CaptainDerp: brehaut bad habbit :s

21:57 thmzlt: has anyone tried lein2 with drip?

21:58 ChongLi: I'm back

21:58 bbloom: dnolen: clarifying: is this in the JVM reader/compiler again? and by "var map" do you mean metadata on a particular var?

21:58 ChongLi: CaptainDerp: how are you trying to access the key later?

21:59 dnolen: bbloom: no CLJS compiler stuff - def creates an AST w/ :name field but this :name field isn't a var AST, just a symbol.

21:59 CaptainDerp: ChongLi (@the-map key)

21:59 i think i may need send-off instead?

21:59 dnolen: bbloom: emit :def just munges the symbol - so this skips the mapping info step I think.

21:59 ChongLi: try send-off

21:59 dnolen: bbloom: just wanted to confirm since you might have looked at that.

22:00 bbloom: dnolen: ah, i see. yeah, you have to look up the var in @namespaces

22:00 ChongLi: does the function that updates your map do some IO?

22:00 if so, you want send-off

22:00 send is for functions that are CPU limited

22:01 the thing is; no matter what you do you should always be able to dereference the agent to get at the map

22:02 since the map inside the agent is a persistent collection

22:03 and because of how agents are implemented (as a mutable reference type)

22:03 CaptainDerp: i can @ the map but i think i cant get the val for the key

22:03 i am testing at the moment with the simplier setup

22:03 ChongLi: just @ the map

22:04 CaptainDerp: @ map is not the issue

22:04 ChongLi: and see if the key val pair is even in there

22:04 CaptainDerp: that is what i am going to do :)

22:04 just seting up a new test incase it was some other bs

22:04 ChongLi: since agents are asynch you can't expect the value to be in there right after calling send

22:05 CaptainDerp: ya i think that is my issue

22:05 but my 2 second knowledge of send-off made me think it was a possible solution

22:05 i need to block until it is in there

22:06 ChongLi: the difference between send and send-off is how the thread pool is managed

22:06 CaptainDerp: ya

22:06 im getting that now

22:06 ChongLi: to block on an agent

22:06 use await

22:06 CaptainDerp: haha u said it as i found it

22:07 http://clojuredocs.org/clojure_core/1.2.0/clojure.core/await

22:07 thanks again for your help ChongLi

22:08 its fun to be working with threads again

22:08 ChongLi: just doing what I can

22:08 CaptainDerp: javascript can be boring :P

22:08 (but callbacks can be fun)

22:09 ok its all working now

22:09 and should be efficent to some degree

22:10 ChongLi: it's likely not going to compare favourably to something like warp (written in haskell)

22:10 CaptainDerp: i *think* this is a faster/cleaner solution than using a DB for this one thing

22:10 ChongLi: that family of servers is pretty crazy

22:10 CaptainDerp: we are using a clojure web server with a postgres db and a pure js front end

22:11 so far no issue. but we are not concerned about speed too too much

22:11 ChongLi: I hope the data in this map is not important

22:11 CaptainDerp: at the moment

22:11 ChongLi: have you checked out datomic?

22:11 CaptainDerp: ChongLi not super important just should be available <1 second

22:12 hmm no but i like that it supports time-based facts

22:12 ChongLi: http://www.datomic.com/videos.html

22:12 datomic is brilliant

22:12 CaptainDerp: we hate sql at the moment because of its lack of support for time and age based issues

22:12 how old is it

22:13 is it industry ready?

22:13 haha but then again i am saying that in a clojure irc

22:13 :P

22:13 ChongLi: datomic leaves the data storage part to another provider

22:13 CaptainDerp: I will sent the link to my poss

22:13 boss*

22:14 ChongLi: such as a traditional db or something like amazon dynamodb

22:14 wingy: i have a string and want to use it as part of a keyword eg. (def string "foo") and make a keyword out of it eg. :foo/bar

22:14 how is it done?

22:15 ChongLi: #(keyword "foo/bar")

22:15 err

22:15 &(keyword "foo/bar")

22:15 lazybot: ⇒ :foo/bar

22:15 ChongLi: there you go

22:15 oh, sorry

22:15 wingy: ChongLi: hmm i should smash them together first

22:15 ChongLi: yeah probably

22:16 wingy: &(keyword (format "%s/bar" "foo"))

22:16 lazybot: ⇒ :foo/bar

22:16 wingy: yepp thx

22:16 ChongLi: yeah there you go

22:16 mattmoss: clojure is ruining my ability to write C++ code... I keep doing (printf "blah blah")

22:16 ChongLi: haha

22:17 I'm not sure if I'd be able to cope with C++ at this point

22:17 wingy: as long as it's a lisp

22:18 ChongLi: yeah I love scheme and elisp

22:18 have not used CL though

22:18 brehaut: wait what‽ love elisp!

22:18 ChongLi: haha

22:18 what's wrong with elisp?

22:18 it's totally crazy

22:18 Sgeo: ,(symbol "foo" "bar")

22:18 clojurebot: foo/bar

22:19 Sgeo: ,((comp keyword symbol) "foo" "bar")

22:19 clojurebot: :foo/bar

22:19 ChongLi: dynamic scoping!

22:19 I like how gerry sussman considers dynamic scoping to be a bug

22:21 CaptainDerp: Hopfully i will never degrade in my other "good" languages

22:21 god i know so many now

22:21 learned 3 this year alone

22:22 ChongLi: the best part about learning new languages is learning new ways to think about problem solving

22:22 new ways to decompose a problem

22:22 have you gone through SICP?

22:23 CaptainDerp: the text book? no

22:23 ChongLi: I'd recommend going through it (and the lectures) if you can find time

22:24 CaptainDerp: but i do agree with the whole new perspective thing

22:24 ChongLi: it's a real eye-opener

22:24 CaptainDerp: AI languages are awesome that way

22:24 js can be cool with call backs

22:24 but that is it imo

22:24 seangrove: Hmm, I've setup a new cljs app, and it seems to be mostly working, except that the google closure library isn't being compiled into the output javascript

22:24 CaptainDerp: clojure is nice ... mainly because of interop with java (i am still 1 month into clojure)

22:25 seangrove: the compiled cljs starts with 'goog.provide('myns.main')', but of course goog isn't defined yet

22:25 ChongLi: and the persistent data structures and mutable reference types

22:25 the way they're all cleanly handled in a uniform manner

22:26 makes clojure feel like an extremely modern language

22:27 dnolen: bbloom: another thing - there is no difference between resolve-var vs. resolve-existing-var besides the warning side-effect?

22:27 yedi: you know those blog posts "steps to <programming language> enlightment" or "<programming language> learning curve"

22:27 anyone know of any similar ones for clojure?

22:27 dnolen: bbloom: I'm about to consolidate that code, it's driving me insane looking at it.

22:28 bbloom: dnolen: hurray! that's been annoying me too. honestly, i'd prefer the warning be eliminated entirely as a side effect and attached to the AST :-P

22:29 dnolen: there are also several different lookup mechanisms in there, but i'm not convinced they are all necessary

22:29 dnolen: bbloom: http://github.com/clojure/clojurescript/commit/3b0f5355e9631adedbf8ceeef542200c76850616

22:29 bbloom: but that's just a recollection, i don't recall why i thought that

22:30 ChongLi: yedi: I'm not sure

22:30 dnolen: bbloom: yeah, the compiler needs some serious refactoring throughout - I've forgotten what most of this code does ...

22:30 ChongLi: yedi: you can take most of what is said in a blog post about lisp in general

22:30 bbloom: dnolen: there's a little bit too much stuff happening in the single analysis phase

22:31 dnolen: bbloom: maybe if we both make it to Clojure/West we can have a CLJS compiler hackathon.

22:31 bbloom: dnolen: now that analysis doesn't do the gensym stuff, it should be much much much easier to split it into multiple phases

22:31 dnolen: well, like i said, I'm 95% sure i'm moving to NYC in a few months, so we can do it there too, heh

22:32 dnolen: bbloom: oh right! that too :)

22:33 seangrove: Any reason the google closure lib wouldn't be compiled and included at the top of the compiled js files?

22:34 dnolen: seangrove: that seems pretty weird

22:40 ChongLi: this is such an outright slaughter

22:40 poor bears

22:41 ahh there it is

22:41 they're on the board now

22:41 seangrove: This might be a hint - first time I run cljsbuid once, I get a error with a stack trace, but the second time it thinks everything is fine

22:41 Makes sense, nothing's changed, but it can look like it built fine

22:44 Ok, could actually be the domina library

23:20 dnolen: seangrove: if you can reproduce, worth opening up a ticket w/ steps - weird stuff like that should be tracked.

23:32 bbloom: is there a concatonative programming paradigm available in the clojure universe yet? I'm curious to see if somebody came up with something Factor inspired

Logging service provided by n01se.net