#clojure log - Oct 31 2012

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

0:01 flying_rhino: hello guys

0:07 does clojure have hygienic macros?

0:09 tmciver: flying_rhino: I don't have much experience with macros, but I believe the answer is yes, as long as you use gensym.

0:10 flying_rhino: tmciver: thanks

0:10 can s-expressions be used as replacement for xml in clojure?

0:11 tmciver: flying_rhino: how do you mean? As in replacement for configuration files?

0:11 nightfly_: For serialization?

0:11 flying_rhino: both

0:12 both as a replacement for configuration files and selilization.

0:12 tmciver: I think the answer is yes to both. For example, lein uses a clj file for config, and you can prn a sexp in a form that can later be read in by the reader.

0:13 flying_rhino: thanks

0:15 amalloy: it's not a super-valuable question to have answered about clojure, though. you can use sexps for those things in java too, or any other language, but nobody does. it's entirely a cultural question, not one of "can clojure X"

0:16 tmciver: amalloy: well, nobody does because it would be a PITA; but it's easy in clojure.

0:16 flying_rhino: yeah, you can write s-expression parser in any language true. But it is better when language itself supports it

0:16 XML is verbose as hell and major PITA, imho.

0:17 also the fact that lang itself supports it means it is standardized.

0:18 since I think there are several slightly different versions of s-expressions, if I am not mistaken. (I don't think scheme and CL ase same)

0:18 anyway thanks

0:23 technomancy: clojure doesn't have hygenic macros

0:23 the problems hygenic macros are designed to solve aren't present in clojure

0:24 flying_rhino: technomancy: can you elaborate please?

0:25 Iceland_jack: Hygenic macros were created to avoid capturing variables

0:25 clojure's namespace prevents that

0:27 technomancy: specifically building forms using backquote makes accidental symbol capture nearly impossible since backquote adds namespaces to every symbol

0:30 amalloy: my understanding is that racket's hygenic macros make it actually-impossible; anyone know if i'm wrong about that?

0:31 just as a matter of tangential interest

0:31 technomancy: yeah, s/racket/scheme/

0:32 * technomancy attended a nearly-intolerable boston clojure group meetup once where the presenter insisted the difference between practically-impossible and actually-impossible was a huge problem

1:26 flying_rhino: How fast is Clojure compared to Java?

1:27 benchmarks from a few years ago where quite disheartening.

1:29 mjc: was the meeting practically intolerable, or actually intolerable ?

1:29 Iceland_jack: Are you playing the speed game or is Clojure too slow for some application you had in mind flying_rhino?

1:29 Choosing a programming language always has a trade-off

1:30 mjc: yeah, if you're deploying production benchmarks, there may be serious problems

1:30 flying_rhino: since I am contemplating to create aplication that may (or may not) require a lot of speed, it is important to know if clojure might handle it.

1:31 I would hate to be stuck with bad performace if I commit to clojure

1:31 can you consistently get like 80% of Java?

1:31 _tca: well then maybe you should at some point figure out what your application will do so you can figure out the requirements

1:33 flying_rhino: I have it figured out mostly, but I can't tell you exactly. I do know that less than 50% of Java is unaceptable.

1:34 Iceland_jack: xx% of performance in language X from language Y is pretty vague, certain features of Clojure are going to differ more than others

1:34 If you want to be sure you should maybe consider Java

1:36 scottj: flying_rhino: in micro benchmarks there's a pretty big performance penalty for writing idiomatic clojure. normally you can write unidiomatic clojure and get close to java, maybe 80%, maybe 100%, it depends.

1:36 Iceland_jack: Also microbenchmarks don't tell the entire story

1:36 flying_rhino: thanks scottj

1:38 what's penalty if some variables in your code need to be changed often? IE it you use immutability at places where muttability can makes more sense?

1:38 *mutability makes more sense

1:41 for example, the project I have in mind is RTS-like game. Like in AoE, it has every turn last 0.25 seconds. That means generating new state every 0.25 sec. Does it make sense to make something like that in Clojure?

1:42 shachaf: Why not?

1:42 flying_rhino: because I am making new state often, instead of changing existing one.

1:43 which may not be very smart thing to do

1:44 _tca: .25s is an eternity

1:45 flying_rhino: also it has to update hella lot critter data.

1:47 althought I can see benefits of immutability there, too.

1:47 how quickly can GC discard data from previous turn?

1:49 (stuff like that worries me a lot)

1:51 _tca: it obviously depends on how much garbage you generate, but from what your game sounds like you will never even notice it

1:53 flying_rhino: there will be like thousand critters bumbling around creating new state every 0.25 sec. And there are some unique things (like some creatures leaving trail) so there might be lots of garbage.

1:53 well couple hundred, at least

1:53 _tca: thats very little garbage

1:54 mrowe: you should see the average spring web app! ;-)

1:55 _tca: flying_rhino: gc is overall faster and only an issue for games like an FPS where you might get deaths from a 5ms gc pause

1:56 Iceland_jack: But FPS aren't normally written in GC languages anyhow

1:56 _tca: and trust me you aren't making as much garbage as you think

1:57 flying_rhino: some guy created turn based game in clojure. He said that he would never use functional language for real time game. Now, mine game is RTS not FPS and it is turn based that fakes real time (like Age of Empires) so it is differentbut I am worried.

1:57 *different, but

1:58 _tca: I hope you are right

1:59 _tca: thanks

1:59 mjc: that's who I always like to take important decision making advice from.. "some guy"

2:00 flying_rhino: mjc: the fact that he created a game nakes his judgment at least worth something.

2:00 *makes

2:02 another consideration is that I want some critters to leave trail, which will generate a lot of data real fast. Again I probably worry too much. I will create some benchmarks myself to see what makes sense and what doesn't. Thanks.

2:06 there is a lot to take into consideration. How would functional A* look like?

2:09 serious has anyone ever made functional A*?

2:11 dhkl: flying_rhino: You can find a discussion of functional A* in "Joy of Clojure"

2:11 flying_rhino: dhkl: thanks

2:15 frankly I would have felt much better if clojure had at least optional mutalibity. I know immutable is often better and I know that Clojure is sophisticated as hell but I am uneasy. It is like flying super advanced plane with no ejection seats, and everyone insisting that you don't really need those.

2:29 dhkl: flying_rhino, wouldn't an aggresive use of atom in place of other reference types give you more or less the kind of mutability you're looking for?

2:30 flying_rhino: not sure

2:33 mrowe: possibly dump question.. I have a function that takes arguments: [thing & other-things], but it doesn't like being passed a seq as the 2nd argument. do I need to somehow "expand" the seq before passing it?

2:34 scottj: mrowe: (apply your-function thing other-things)

2:35 mrowe: scottj: awesome, thanks :)

2:36 I knew it would be obvious once someone told me ;)

2:36 scottj: mrowe: other options are (defn a ([thing] ...) ([thing other-things] ...)) or (defn a [thing & [other-things]] ...)

3:26 sunkencityryleh: I have a protocol that I have a special function for PersistentList in, but I'd like to define my own subclass of PersistentList instead, just to be sure that nothing accidentally triggers this function. How do I go about that in clojure? Do I just deftype and then create a list from that in the protocol, or can i subclass?

4:39 kral: namaste

4:58 ejackson: whispers of EuroClojure 2013 !

5:05 andrewmcveigh|wo: ejackson: any whispers of where?

5:05 ejackson: i see Germans speaking of it...

5:06 andrewmcveigh|wo: interesting...

5:06 * _ulises secretly hopes it'll be near Frankfurt

5:06 _ulises: we have direct flights to Frankfurt you see

5:07 * andrewmcveigh|wo hopes they have air-conditioning

5:08 ejackson: hehehe

5:08 who'd a suspect you'd need that in England ?

5:10 andrewmcveigh|wo: indeed. Next time I'm packing shorts, even if it is London in May.

5:12 ejackson: :)

5:13 tomoj: I wonder if it would be possible to have the repl's namespace state separate from the namespace state with which load-file happens

5:15 borkdude: Is it possible to say: require/use this namespace x from namespace y?

5:15 instead of from the current namespace

5:17 tomoj: (binding [*ns* (find-ns 'user)] (require '[incanter.core :as incanter]))

5:17 seems to work

5:17 borkdude: ok tnx

5:17 tomoj: but.. doesn't seem like a very good idea generally

5:18 borkdude: tomoj there was someone who wanted to include a set of standard helper namespaces in every one of his namespaces and wanted to write a function for it

5:18 tomoj it didn't seem like an idiomatic approach to me, but just wondered what is the cleanest way to get it done

5:19 tomoj: I guess it's not that bad if the person reading the code has M-.

5:19 for anyone reading the code on github, that sucks

5:19 or reading the code without a jvm

5:20 ejackson: yeah

6:35 alexnixon: tset

7:12 rodnaph: hey, i'm trying to use aleph to create a simple websocket server, which works for a short time but then messages stop coming through the channel - do i need to do something to keep it open? https://github.com/rodnaph/lewis/blob/stats/src/lewis/ws.clj

7:15 clgv: rodnaph: I didnt use aleph yet - but maybe an exception happened on client or server which faulted the channel?

7:16 rodnaph: that's possible. i'm using wrap-reload too, could be causing probs? maybe defonce the channel? is there a way i can check if a channel is "working" ?

7:31 clgv: rodnaph: you could wrap code that is using the channel or called in a thread of the channel (if there is something with aleph) in a try-catch-block and then print every exception to debug your problem

7:38 sunkencityryleh: is there some tool that can be used with clojure to get a list of possible exceptions that can come up when calling a function?

7:52 clgv: sunkencityryleh: no

7:52 sunkencityryleh: or do you mean for interop with java?

7:53 mklappstuhl: clgv: he is gone

7:53 clgv: mklappstuhl: damn, i have those notifications invisible for less spam ;)

8:23 rodnaph: clgv: thanks for the advice i'll try it.

8:28 MasseR: I have a situation where I need to override a side-effectful (streaming) java class method. I want the data from that method concatenated and converted into a clojure sequence. For example: foo.processStream(page1), foo.processStream(page2) etcc. processStream calls at some point some other method which should be overriden. How should I approach this? I tried proxying and it's trivial to override the method (and test the original api) but getting the ...

8:28 ... data out of it escapes me

8:33 luxbock: any idea why find-doc doesn't work in the nREPL of Emacs?

8:34 works fine when I use REPL normally

8:35 MasseR: With java I would probably create a new member variable (List<Map>) which I would fill from the overridden method

8:36 One way would be to set! the list but..

8:46 clgv: MasseR: can you make a gist where you describe your problem with examples? "getting data out" is not very specific ;)

8:47 _ulises: +1

8:52 MasseR: clgv: https://gist.github.com/3986869

8:52 is that enough information?

8:52 clgv: we'll see ;)

8:52 mailheaders: What is it conscerning?

8:53 MasseR: mailheaders: The best way to 'get data out of evented java api'

8:53 clgv: MasseR: so looks like you need a gen-class in that interop scenario. you can have a state variable in gen-class

8:54 MasseR: But the questions is whether it is worth to use clojure for that class. you might be faster with plain java just for that class

8:55 mailheaders: No that is not the question.

8:56 The question is at what level is energy being allocated.

8:57 clgv: trolling? :P

8:57 MasseR: clgv: Shouldn't I then need to 1. gather the data as for example List<Map> and then convert that list into '({})

8:57 s/1.//

8:57 clgv: MasseR: seq can convert java.util.List ^^

8:58 mailheaders: I am trying to tell you they have attacked the human mind.

8:59 clgv: &(let [l (java.util.List.)] (doseq [e (range 10)] (.add l e)) (map inc l))

8:59 lazybot: java.lang.IllegalArgumentException: No matching ctor found for interface java.util.List

8:59 clgv: &(let [l (java.util.LinkedList.)] (doseq [e (range 10)] (.add l e)) (map inc l))

8:59 lazybot: ⇒ (1 2 3 4 5 6 7 8 9 10)

8:59 clgv: MasseR: so you actually dont need to convert it - as you can see above

9:00 mailheaders: The question is what is the nature of the human mind.

9:01 8 Chapters

9:01 MasseR: clgv: Thanks

9:02 mailheaders: Obama is an object code in a psychoanalist system.

9:02 Freenode "caught a case".

9:03 Do you understand what is meant by catching a case.

9:03 Identify the threat contaigen -> quarenteen -> triage -> treatment

9:03 * clgv stops watching mailheaders failing the turing test.

9:04 mailheaders: You failed the turing test.

9:05 At what point do you stop and ask a question.

9:05 At what point should a human mind interact?

9:05 You arent doing it.

9:06 Case and point.

9:06 contaigen identified

9:07 Cubic: Did I miss something?

9:08 mailheaders: I asked a question, and everyone responds with retard comments as usual.

9:08 Buzzword morons.

9:08 Never allowing the conversation to develop.

9:09 Try this again.

9:09 Do you understand what is meant by catching a case?

9:10 Lets see if theres even a spark of intelligence in this channel.

9:13 If oboma is re-elected he is willing to take it all the way to WW III

9:13 Do you understand the implications here?

9:13 clgv: mailheaders: can you please stop spamming with off-topic nonsense?

9:14 mailheaders: What is with peoples obsession with topic on this network?

9:16 Jason Ross says artificial intelligence will not understand metaphor.

9:17 Now does darrpa's analysis of defence papers even come close.

9:17 mklappstuhl: mailheaders: what is your point? This channel is about a specific programming language. If you want to talk about politics you are probably at a better place somewhere else

9:19 * clgv remembers that ignore button in his irc client^^

9:19 mklappstuhl: clgv: There is also /mute I think

9:20 clgv: mklappstuhl: I am not that fluent speaking in IRC ;)

9:22 mailheaders: Song of Soloman is the true turing test.

9:22 mklappstuhl: clgv: Actually it's english with a slash in the beginning :)

9:22 :D

9:22 mailheaders: not yip yapping about java like a barking poodle

9:23 clgv: yeah but it doesnt do everything with a prefixed slash ;)

9:23 mailheaders: clgv: so don't tell me I don't pass the turing test

9:23 I don't see you robots cleaning my house.

9:24 This is what I am talking about misallocation of energy.

9:24 That is the question.

9:24 * mklappstuhl OK > /mute mailheaders

9:26 samrat: could someone help me with this, please: http://www.reddit.com/r/Clojure/comments/12easa/transforming_some_data_contained_in_a_hashmap/

9:27 mailheaders: Can an A.I understand a metaphor of something that cannot be externally observed?

9:27 NO

9:27 Make it easy for you.

9:27 The answer is NO.

9:28 Cubic: Mute doesn't seem to work.

9:28 mailheaders: immutable object

9:29 two eternal constants

9:29 ToBeReplaced: samrat: your solution looks okay to me

9:30 mklappstuhl: Cubic: hm, right. It'S only possible for admins

9:30 ToBeReplaced: i'd try to avoid what you're trying to do... trying to do relational things over maps is a pain

9:31 mailheaders: you are not an admin you are just a drone

9:31 TimMc: mklappstuhl: /ignore mailheaders is what you want

9:31 /ignore -replies mailheaders is even more effective.

9:32 clgv: samrat: you could refactor the data model to have explicit rating maps {:movie "batman" :rating 4.5 :user "Toby"} then it would be an easy (group-by :movie prefs)

9:32 Cubic: I don't think that works either.

9:32 mailheaders: yes drones have the option of sticking their head in the sand like a frieghtened ostrich

9:32 TimMc: Oh, you're using the web client... maybe it doesn't have ignore.

9:32 mklappstuhl: clgv: Looks like I'm not fluent in IRC either :P

9:33 TimMc: I'm using weechat and it doesnt work

9:34 mailheaders: see what i mean about misallocation of energy

9:34 so here you are 10 lines latter chatting about how to ignore chatters, chatter chatter chatter

9:36 learn to use your brain if you have one before learning to use a fancy calculator

9:37 TimMc: Hmm. I guess I shouldn't expect that command to be the same for all clients.

9:37 Cubic: TimMc: I think we'll have to fall back to lo-fi ignore then.

9:38 mailheaders: cracking the mind

9:38 chronno: FWI, "/ignore mailheaders ALL" worked for me

9:38 mailheaders: do you like crackers?

9:38 mklappstuhl: TimMc: I actually thought that the commands are just relayed to the actual irc server

9:40 mailheaders: mklappstuhl: do a tracerout on the server you are connected to

9:40 mpan: I have some data which could be directly encoded as literal maps/vectors/etc. Is there a recommended way to store them to have them accessible from a program?

9:40 It would work to just make them part of the source, but I'm unsure if that's a good idea.

9:42 Are there any particular advantages to having a separate file to read and eval vs just having it as a file in the source?

9:42 mailheaders: you guys code anything useful for intelligence gathering?

9:42 clgv: mpan: well then store that data as clojure code in your resources directory (for example)

9:42 mailheaders: i can do beta testing, if you will obey my QA reccomendations

9:42 mpan: I guess what confuses me is I can't draw the distinction between being part of the core of the code vs being data that happens to be code vs... oh hey wait I think I know where this is going

9:43 This is intentional, isn't it?

9:43 clgv: mpan: lisp: code is data, data is code ;)

9:43 mpan: It hadn't quite sunk in so fully before

9:44 clgv: one example for configuration data is leiningen's project.clj

9:44 mpan: Is read-file'd and eval'd?

9:44 clgv: you could take inspiration from it in case it fits your use case

9:44 mpan: I'm not completely sure about my use-case, but it's a school deadline, and decent is better than unfinished

9:45 That's for sure

9:45 Also, what if my file needs to contain multiple "values"?

9:46 Not sure if that's the term I should be using

9:46 clgv: thats more tricky then.

9:46 mpan: but, say, multiple top-level s-exprs

9:46 Cubic: Hm, would that mean that saving i.e. levels in a game as clojure source code would actually be idiomatic?

9:46 mpan: Cubic, sounds like it, interestingly enough

9:46 ToBeReplaced: mpan: there's lots of advantages to having your data stored in other formats, but if using a wide brush, you should avoid that until there's a clear need.

9:46 TimMc: mklappstuhl: Some are local, some are sent to the server.

9:46 clgv: Cubic: why not? you would probably build a highlevel language for it

9:47 mailheaders: talk it up

9:47 just dont put the wide brush under your nose

9:47 mpan: Uh, so what I need is a few rather large vectors of maps of domain-specific-stuff accessible from the program

9:47 clgv: Cubic: something like: (level 1 (wall [10 20] [10 50]) (monster :ork [12 12]) ...)

9:48 mklappstuhl: mpan: what school are you on that you are using clojure?

9:48 mailheaders: yes everyone can make a graven image for themselves

9:48 mpan: This assignment doesn't specify a language requirement, thankfully

9:48 ToBeReplaced: mpan: ex. storing your multiple values in json meets your need, but so would def's in a clojure source file... when you read in the data can vary accordingly

9:48 mailheaders: thats what choice is all about

9:48 Cubic: I've been thinking if there was any point in adding scripting to a clojure program, but I couldn't think of anything. The way I understand it, you can just embed an nREPL server and use that for "scripting".

9:48 mailheaders: eternal life and eternal death

9:49 TimMc: mpan: There's a difference between read and eval. If you're just storing vectors of numbers and strings and such, you only need read, not eval.

9:49 mailheaders: the leader of this network runs a company called death works

9:49 mpan: The insides may be oddly arbitrary beyond just literals

9:49 TimMc: so you can (read-string (slurp "data.clj"))

9:50 mpan: but that part is, I imagine, domain-specific concerns

9:50 mailheaders: what you can do is make your graven image on a 3d printer just join #reprap

9:51 mpan: But is it the case that if I want to use read-string, I want to put this "data" file somewhere outside the usual search path for ns-loading?

9:52 mailheaders: go out and eat texturized soy protien with artificial flavors and let the micro fungus pass the blood brain barrier

9:52 clgv: TimMc: mpan: (read-file "data.clj") even.

9:52 mpan: but data.clj isn't something that the compiler would normally load except that we specifically tell it to?

9:52 mailheaders: then come home and type bullship into your fancy calculator

9:53 and while the fungus eats your brain don't worry wolfram alpha will micromanage your "friends" for you with the new facebook app

9:54 mpan: Well, this is really cool

9:54 Thank you guys, and I think I know what to implement now

9:55 mailheaders: and prostitute robots will come to your house to harvest your reproductive organs for the fetus growing lab

9:55 mklappstuhl: I'm comparing the java and clojure libs for riak right now and the java stuff just makes me wanna cry while the clojure stuff is so beautiful

9:56 clgv: mklappstuhl: sometimes even tough guys need to cry ;)

9:56 Cubic: So, read-string creates a form from a string, and eval then evaluates it?

9:57 mklappstuhl: The company I'm working for is using Java for mostly everything and until now I havn't been able to convince them to give clojure a shot :/

9:58 clgv: &(eval (read-string "(println \"Cubic: yes\")"))

9:58 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

9:58 clgv: ah right, sandbox^^

9:58 mpan: why can't they just enforce eval recursively?

9:58 oh wait, that sounds scary

9:59 clgv: mpan: there is also load-file load-string etc...

9:59 mailheaders: they are not the enforcers

10:00 mpan: I was originally wondering about substituting a "fake" read-string etc which did the usual checks

10:00 but that sounds harder the more I wonder about it

10:00 as in, the same enforcement as stuff at the top-level

10:00 clgv: mpan: I have a dsl which now even uses namespaces for organization

10:01 mpan: clgv: does that mean you have ns swapping in the middle of things?

10:01 mklappstuhl: there's a certain "LISP is lunatic fringe" attitude that needs to be fixed first, unfortunately

10:01 clgv: mpan: huh? I don't know what you mean by that. I meant that I use regular namespaces for the DSL documents as I do in the code of the lib

10:02 mpan: I'm only used to use-cases where you specify a ns at the beginning of a file and stick with it

10:02 circumventing that would come with its own complications?

10:03 clgv: yeah the documents have the namespace at the beginning

10:04 mpan: I was worried about "the ns you are in at the time you load them" but that seems to be an artificial line anyway

10:04 not sure what to call that

10:06 clgv: mpan: well, leiningen creates a temporary namespace and loads the project.clj in there if I remember correctly.

10:08 mpan: if I just load something, it ends up in the current ns? (for cases where such a distinction exists)

10:08 S11001001: mpan: yes

10:08 mpan: I suspect my current use-case doesn't encounter that distinction, though

10:09 I'll probably just wrap the many maps in a larger enclosing map

10:09 Thanks you all!

10:09 AWizzArd: Why is a -main method not public? I noticed that in my test namespaces I can’t call (-main …).

10:10 S11001001: AWizzArd: it's not a method, just an ordinary function, and has as much privacy as you give it

10:10 AWizzArd: in other words, gen-class doesn't change the behavior of def or defn

10:13 AWizzArd: S11001001: I did a defn on -main, not a defn-. So I expected it to be publicly available from other NSes.

10:13 So far I solved this by calling (#'-main …). But still very strange, no?

10:13 S11001001: sure

10:16 AWizzArd: S11001001: btw, do you use Emacs + Leiningen + nrepl?

10:16 S11001001: AWizzArd: yes

10:16 AWizzArd: Did you use Slime before?

10:17 S11001001: yes

10:17 AWizzArd: I noticed that several useful key combinations are gone. For example, „C-c C-c”, to compile the expression under the cursor.

10:18 „C-c M-p” is gone too. Is that cause the Emacs support is still young? Or do you know of any good reasons why all those nice key combinations really should be different?

10:18 TimMc: AWizzArd: Wait, so in your test ns you have (:use foo.core) and then (-main ...) doesn't work?

10:18 clgv: AWizzArd: (defn -main [] ...) leads to a public function "-main" that is public and usable from other namespaces.

10:18 Cubic: C-c C-e does almost the same thing, except cursor has to be at the end of the expression

10:19 clgv: AWizzArd: I have called -main often from REPL for testing purposes

10:19 AWizzArd: TimMc: yes, I :use my main NS, but calling (-main …) doesn’t work.

10:20 Cubic: And I believe C-M-x is exactly the same thing as C-c C-c in slime.

10:20 TimMc: AWizzArd: What Clojure version?

10:20 AWizzArd: TimMc: 1.4

10:20 Cubic: it is good that there is some equivalent. But why a new key combination?

10:20 S11001001: AWizzArd: that nrepl isn't a complete port

10:21 duck1123: AWizzArd: are you sure you're using slime and not nrepl?

10:21 AWizzArd: I guess 99% of all nrepl-Mode users were slime users before, and already learned several key combinations.

10:21 duck1123: yes. That -main thing is in slim.

10:21 +e

10:21 Cubic: AWizzArd: I don't know, I guess they didn't really go for SLIME compatibility. Ask the author of nrepl.el. You can change those bindings if you feel like it.

10:22 TimMc: AWizzArd: Could not reproduce. Can you make a reduced test case?

10:22 duck1123: I keep trying nrepl from time to time, but it hasn't been stable enough for me to switch yet. I also don't like that I have to be in the buffer to use C-c M-n

10:23 MasseR: clgv: Thanks. 46 lines of java later I'm rolling

10:23 clgv: TimMc: http://xkcd.com/583/

10:24 AWizzArd: duck1123: The newest Clojure 1.5 alphas don't work with slime anymore.

10:24 Cubic: duck1123: How would you expect it to behave?

10:25 duck1123: Cubic: With Slime, I can be in another buffer and it'll prompt me for the ns I want to switch to

10:26 AWizzArd: TimMc: I can see if I can produce such a condensed test case.

10:28 Cubic: Is there any way you can force recompilation of a file from the repl? Right now I always have to restart the thing when I make some changes to a file, which is rather annoying

10:29 AWizzArd: Cubic: you could reload the code, and thereby recompile it.

10:29 In Emacs in the code buffer: C-c C-k

10:30 TimMc: What I do now is: lein swank, then start up emacs, slime-connect, then I load my test buffer, which has the :use. When I then check the metadata of -main I see :private true.

10:30 Funnily, if I now open the code file of my core code, and C-c C-k that one, from that moment on -main is no longer private.

10:32 TimMc: you could try the same, first load your test code in Emacs, and indirectly load the file which contains the -main, via :use.

10:37 jcromartie: so the arc challenge...

10:37 devn: lol

10:38 jcromartie: :P

10:38 AWizzArd: jcromartie: what is the arc challenge?

10:38 jcromartie: AWizzArd: it's "how easily can your language do this" http://paulgraham.com/arcchallenge.html

10:38 at the end

10:38 a web form

10:38 with anonymous callbacks

10:39 clgv: AWizzArd: you might have some stale class file lying around. do a "lein clean" and test that again

10:39 TimMc: AWizzArd: I don't have SLIME on that box.

10:41 AWizzArd: clgv: I did a „rm -fr target” and tried again. I still get the „-main is not public” error.

10:41 clgv: AWizzArd: thats weird. this is with clojure 1.5?

10:42 AWizzArd: But still a good idea. This could have been it. Unfortunately the error is still there.

10:42 1.4

10:43 clgv: AWizzArd: I tried with clojure 1.4 overhere. my -main is public.

10:44 the namespace has only (:gen-class) without custom declarations

10:51 balint: hey

10:51 I'm trying to set up cascalog and have run into an error

10:51 when I do 'lein repo' I get this

10:51 Oct 31, 2012 3:27:22 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute

10:51 INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset

10:51 Oct 31, 2012 3:27:22 PM org.apache.http.impl.client.DefaultRequestDirector tryExecute

10:51 it seems like a remote repo might not be available but I'm not sure

10:52 I have the latest leiningen installed (2.0.0-preview10) and other projects do work

10:52 I'm on Java 1.6.0_37 Java HotSpot(TM) 64-Bit Server VM

10:52 jakubH: balint: what is "lein repo" supposed to di? I didn't need that to work with cascalog

10:53 balint: jakubH: sorry, lein reps :)

10:53 deps

10:53 jakubH: lein deps in leiningen 2 doesn't do much/anythig, why are you running it?

10:54 balint: because that's what the cascalog readme tells me to do:

10:54 https://github.com/nathanmarz/cascalog

10:54 algernon: doesn't it say 'repl' ?

10:55 jakubH: I see

10:55 algernon: ah, nvm, I'm a few minutes behind.

10:56 mailheaders: nutcase

10:56 jakubH: for me lein deps does nothing ; the help reads:

10:56 USAGE: lein deps

10:56 Force Leiningen to download the dependencies it needs. This usage is

10:56 deprecated as it should happen automatically on demand.

10:56 anyway the problem you are experiencing indeed may be a rempte repo down

10:56 balint: lein install does the same

10:57 jakubH: I guess you can run lein with some option to print debug info to see which repo hangs

10:57 jcromartie: so yeah this works https://gist.github.com/3987491

10:58 jakubH: (or try lein pom; mvn -X dependencies:resolve)

10:59 sorry, http://maven.apache.org/plugins/maven-dependency-plugin/resolve-mojo.html

11:06 balint: so I should install that maven plugin first to be able to debug

11:06 duck1123: the maven plugin should install itself when you call it

11:07 balint: ok

11:07 duck1123: The only reason he listed that is because mvn -X should give you a bit more info about what is going on

11:18 AWizzArd: Cubic: btw, how can I change the key bindings of the nrepl mode?

11:18 jakubH: right; I would suppose that lein has st like maven's -X but don't know

11:19 balint I just run lein deps on a fresh set up and it worked

11:20 lein version => Leiningen 2.0.0-preview10 on Java 1.6.0_37 Java HotSpot(TM) 64-Bit Server VM

11:20 balint: jakubH: hmm, interesting

11:20 I get this: Could not transfer artifact org.slf4j:slf4j-log4j12:jar:1.4.3 from/to central (http://repo1.maven.org/maven2)

11:20 what's your clojure version?

11:22 oh, that's also defined in the project.clj file so it's probably project-specific?

11:22 duck1123: I see that version in the repo. Perhaps you could try a newer version. http://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12

11:23 jakubH: I just run "lein new my-project" and added [cascalog "1.10.0"]

11:23 to dependencies and the line :profiles { :dev {:dependencies [[org.apache.hadoop/hadoop-core "0.20.2-dev"]]}}

11:27 Where does that slf4j-log4j12 version come from?? Here it is successfully trying to download Retrieving org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.pom (2k)

11:28 are you creating a new project from scratch as described on the cascalog page or have you added some of your own dependencies there?

11:28 balint: creating a new project

11:29 just cloning the cascalog repo from github and running lein repl

11:29 duck1123: If you want to be absolutely sure about your dependencies, you could try using https://github.com/xeqi/lein-pedantic

11:29 balint: (or now lein pom and mvm -X)

11:29 the slf4j comes from log4j, I presume

11:29 that's the only logging related lib in project.clj

11:30 however, it's not listed as a dependency here: http://mvnrepository.com/artifact/log4j/log4j/1.2.16

11:30 duck1123: lein deps :tree or mvn dependency:tree help here

11:31 jakubH: and it is really strange you cannot find the jar in the repo since it is there as duck says (also here http://search.maven.org/#artifactdetails|org.slf4j|slf4j-log4j12|1.4.3|jar)

11:33 pandeiro: i'm getting "Error loading project.clj" with lein-cljsbuild 0.2.9 - but my project.clj is in the project root and looks fine... anyone know what could be up?

11:34 jakubH: balint here is my lein deps :tree http://paste2.org/p/2408055

11:34 pandeiro: huh, same problem with lein deps

11:35 duck1123: pandeiro: mismatched parens?

11:35 pandeiro: ack nvm

11:35 duck1123: missing a val

11:36 duck1123: jakubH: try adding an explicit ref to the log4j adapter, see if that helps

11:37 AWizzArd: S11001001 and TimMc: I have the strong suspicion, that AOT+Leiningen are responsible for that mysterious -main privateness in my test ns.

11:37 duck1123: I wonder if that runtime scope is messing things up somewhere

11:37 balint: duck1123: thank you. the problem is I can't even run mvm dependency:tree

11:38 [ERROR] Failed to execute goal on project cascalog: Could not resolve dependencies for project cascalog:cascalog:jar:1.10.1-SNAPSHOT: Could not transfer artifact org.slf4j:slf4j-log4j12:jar:1.4.3 from/to central (http://repo1.maven.org/maven2): Error transferring file: Connection reset -> [Help 1]

11:38 AWizzArd: When I turn AOT off my -main does not magically turn into a private function.

11:38 TimMc: Fascinating.

11:38 mailheaders: anyone doing anything useful with clojure?

11:38 give me something useful to beta test

11:39 Don't you understand the importance of entropy?

11:39 duck1123: balint: and you don't have any funky firewalls, proxies, or overridden repos to contend with?

11:39 TimMc: llasram: OK, you *may* have convinced me that it's better to use a Java loader stub in lein-otf, mostly because I can't seem to get a Clojure version working. :-P

11:39 AWizzArd: TimMc: it seems because I AOT my NS in the target/ folder I have a compiled version.

11:40 TimMc: AWizzArd: I've had bad luck with lein test + AOT in the past.

11:40 AWizzArd: Now when I C-c C-k (load) the test ns inside emacs it compiles a new version of it, it seems.

11:40 balint: duck1123: no, I don't

11:40 AWizzArd: Now in my test NS I only have to evaluate anything that is in my :use’d original NS. No function call required. Just type something into the repl. And magically -main turns private.

11:40 balint: overridden repos?

11:40 mailheaders: What is your mission?

11:41 AWizzArd: So it seems that evaluating anything from my original NS, which I :use in the test NS, triggers some reloading of files from the disk.

11:41 jakubH: balint to mee it also looks as something with your network or setting; try to do it on some server with clean setup or so st

11:41 I have to go, good luck

11:41 nDuff: mailheaders: If you're interested in looking at Clojure projects, see http://www.clojuresphere.com/; there's a random-order option.

11:41 balint: jakubH: thanks a lot for your help

11:41 I'll sort it out

11:41 duck1123: to you, too

11:41 duck1123: balint: based on the error, I don't think thats the case, but check ~/.m2/settings.xml (may have name wrong)

11:43 balint: duck1123: can't find any *.xml there that might be a config file

11:44 jcromartie: https://gist.github.com/3987491 -- jump to the bottom for the Arc Challenge implementation

11:44 duck1123: balint: Then you're good on that front. Still sounds network related. Can you hit http://repo1.maven.org/maven2/log4j/log4j/1.2.16/log4j-1.2.16.pom

11:44 jcromartie: it's longer

11:44 could get around it with more macros

11:44 balint: duck1123: yes, I can

11:44 mailheaders: What is Cognition Caps?

11:45 nDuff: mailheaders: uhh, its github site says exactly what it is.

11:45 mailheaders: SensitiveDataFilter this is called redacting

11:46 * nDuff tires of feeding the troll

11:46 duck1123: balint: did you try adding [org.slf4j/slf4j-log4j12 "1.4.3" :exclusions [[log4j]]] to your project? (or a higher version)

11:46 mailheaders: nDuff: what the F are you talking about

11:47 did you code any of this nDuff?

11:48 i don't know what goes on in these autistic coders minds but in english naming conventions matter

11:48 nDuff: *plonk*

11:48 mailheaders: whatever useless things you tell your calculator to do if you want a real human to care it has to use proper english naming conventions

11:49 mpan: how is that guy so persistent? I'm beginning to think he's a markov-chain bot

11:49 surely a human has better things to do with their morning

11:49 duck1123: you'd be surprised

11:50 mailheaders: no i have to dump shit on you because all of your code means nothing just donating entropy to a robot

11:50 balint: duck1123: mvm is trying to download http://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.4.3/slf4j-log4j12-1.4.3.jar

11:50 and that's where it fails, can you access it?

11:50 Cubic: I think it's probably a real guy watching 10-20 channels at the same time and writing the same thing to all of them. I think it's a bit too good to be a bot.

11:51 lynaghk: technomancy: okay if I pm re: lein/heroku config issues?

11:51 mpan: I think his conversation sounds approximately like what a markov chain generates

11:51 mailheaders: When i tell you something that makes sense you idiots just make retard comments about bots all of the time

11:51 duck1123: balint: works fine for me. Can you access it outside of lein or mvn?

11:51 mailheaders: your minds are broke off into lala land

11:51 nDuff: mpan: Parts do, but parts _did_ seem human-driven. I'm voting for hybrid.

11:51 mailheaders: becoming a burdon on my society

11:51 mpan: anyway, after a morning of modeling domain data, I feel I need to cut down on my domain scope

11:51 nDuff: anyhow, /ignore is a beautiful thing.

11:52 jcromartie: yay

11:52 zerokarmaleft: balint: can you access the jar directly from http://search.maven.org/#artifactdetails%7Corg.slf4j%7Cslf4j-log4j12%7C1.4.3%7Cjar

11:52 jcromartie: ignore is good

11:52 mpan: instead of simulating foo, I'm just going to simulate foo intersect bar intersect baz

11:52 balint: zerokarmaleft: yes, it works that way

11:52 mpan: far fewer special cases that way, far shallower nesting of data representation required

11:52 zerokarmaleft: balint: in that case, i'd just stuff into the correct place in ~/.m2

11:52 balint: not through curl, though

11:53 mailheaders: type this into google define: redacting

11:53 2nd def

11:53 efficiency

11:53 zerokarmaleft: i've done that on a couple of occasions when lein and mvn can't retrieve them for whatever reason

11:53 mailheaders: We, nor no one, needs a three word run on with capitals.

11:54 Theres nothing beautiful about silliness, are you also going to "print" me a plastic fish with the reprap?

11:59 mpan: if you know something is truthful or nil, is it considered idiomatic to test with a naked if?

11:59 e.g. an element is known to be keyword or nil

12:00 AdmiralBumbleBee: mpan: what else would you expect to do?

12:00 nDuff: mpan: I would do it that way, yes.

12:00 mpan: an if and a nil? would have been my other guess

12:00 mailheaders: AdmiralBumbleBee: you made me laugh

12:01 TimMc: nil-punning is idiomatic, for better or worse :-P

12:01 mpan: I mean, not that this is necessarily a reasonable comparison, but certain analogous things in php are very dangerous

12:01 AdmiralBumbleBee: it is easier to read to use (if (nil? x))

12:02 it's also less susceptible to bugs in the future

12:02 TimMc: AdmiralBumbleBee: I think that's the kind of thing I would have written when I first was starting with Clojure, but now I would just use if.

12:02 duck1123: I'd like to argue that you usually know what type of data you're dealing with in clojure better than php

12:02 AdmiralBumbleBee: but I wouldn't do it :)

12:02 mpan: but then again, php goes as far as to pun strings and numbers, so the danger is not necessarily comparable

12:02 AdmiralBumbleBee: TimMc: yeah, I agree

12:02 balint: zerokarmaleft: sorry, but how do you that?

12:02 AdmiralBumbleBee: I was just being explicit about some advantages of it

12:02 TimMc: I recently ran across some ,,, in some -> clauses that I wrote a while back.

12:03 balint: I only find the jars of the projects themselves in ~/.m2/repository/<projectname>

12:03 duck1123: balint: download the pom and the jar, and put them in a dir in ~/.m2 according to the group/artifact. Look at the others for examples

12:05 or, you could use mvn install:install-file to have mvn do it for you

12:05 AdmiralBumbleBee: I guess using nil? would be somewhat similar to using stuff like if ( 1 == x) in another language

12:06 balint: duck1123: I did but it still wants to download the jar from the remote repo

12:06 duck1123: you have to ask yourself: If a false snuck in here, which branch should it take

12:06 balint: duck1123: thank you anyways

12:06 I need to go, will get this working

12:07 duck1123: balint: you could add :offline? true to your project to skip downloading

12:08 or try setting up a mirror like so https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L202

12:15 samrat: why doesn't (clojure.string/split "id|name|foo|bar" #"|") work? it does work for #":"

12:15 technomancy: lynaghk: sure

12:16 samrat: ,(clojure.string/split "id|name|foo|bar" #"|")

12:16 clojurebot: ["" "i" "d" "|" "n" ...]

12:16 zerokarmaleft: balint: if you're able to d/l the pom and jar, cp them into ~/.m2/repository/org/slf4j-log4j12/1.4.3/

12:17 mpan: ,(clojure.string/split "id|name|foo|bar" #"\|")

12:17 clojurebot: ["id" "name" "foo" "bar"]

12:17 zerokarmaleft: periods in group ids turn into additional subdirectories

12:17 mpan: proper style should probably be

12:17 (if I recall)

12:17 ,(clojure.string/split "id|name|foo|bar" #"\\|")

12:17 clojurebot: ["" "i" "d" "|" "n" ...]

12:18 mpan: whoops, ok use the earlier one

12:18 the other one was just me confusing myself

12:18 samrat: mpan: thanks

12:18 mpan: basically, | is special, it means "match this OR that"

12:19 there's a large set of characters with special meaning

12:19 try http://www.regular-expressions.info/tutorial.html or a similar reference

12:20 S11001001: ,(mapv #(re-pattern (java.util.regex.Pattern/quote %)) ["|" ":"])

12:20 clojurebot: [#"\Q|\E" #"\Q:\E"]

12:20 S11001001: or :)

12:22 mpan: I keep confusing myself when working with multiple levels of escaping

12:22 TimMc: mpan: Luckily, Clojure's regex literal takes one of those levels away.

12:22 mpan: TimMc: see, I forget that fact ALL THE TIME

12:23 because I got used to java regex instantiation

12:23 thus my slip-up above

12:24 TimMc: If we had heredocs, it would all be peachy.

12:25 mpan: how do you envision that would fit in with the reader?

12:25 or just a special case of something that isn't an s-expr?

12:26 zerokarmaleft: duck1123: nice, didn't know about install:install-file

12:27 although the ease of passing maven a laundry list of arguments is roughly the same as navigating .m2

12:27 duck1123: If I'm running a compojure app as a servlet, what do I need to do to have the context removed? I see the context fn, but should I create a handler fn to set up the context from the request, or is there a better way?

12:28 zerokarmaleft: install:install-file comes in handy when you don't have a pom to work from

12:36 mailheaders: cognition caps?

12:36 gensymv: hello is there a good package manager for clojure?

12:36 jcromartie: duck1123: what do you mean "have the context removed"

12:36 mailheaders: cycling caps?

12:36 jcromartie: gensymv: Leiningen

12:36 mailheaders: What are you trying to spread brain damage?

12:36 When riding a bike wear a helmet.

12:37 duck1123: jcromartie: My servlet is served from /foo I want my route /bar to match the path /foo/bar

12:38 gensymv: jcromartie, but i have to create the project.clj file my self for that one.

12:38 jcromartie: gensymv: yes, and no, "lein new" creates a template project with a project.clj file for you

12:38 duck1123: gensymv: leiningen should be everything you need. leiningen uses maven's package system along with clojars which is a repo for clojure projects

12:38 mailheaders: my servlet took a dump on your srvlet

12:39 jcromartie: duck1123: I think "context" is what you want

12:39 or do you mean you want to be able to serve it from any context?

12:39 mailheaders: you selling cycling caps?

12:40 Wow you are the best thing since the band Hanson

12:40 duck1123: jcromartie: I want to be able to serve it from any context. I have the current context assoced into the request, I just need to set it up to read that. I was wondering if there was something pre-baked for that task

12:41 jcromartie: you'd have to write middleware, should be easy

12:41 gensymv: duck1123, can it pull packages directly from clojars?

12:41 duck1123, i am searching something like cabal or pip

12:41 *searching for

12:42 nightfly_: leiningen does what you want...

12:43 And "lein uberjar" is just plain cool

12:44 gensymv: cool, but how?kkj

12:44 jcromartie: duck1123: so you just want to strip the context from the :uri before passing it to your simplified handlers

12:44 duck1123: gensymv: Once you have a project file set up, you specify the deps you need in the :dependencies section and lein will make sure they're available on the classpath. You don't install packages directly

12:44 gensymv: ah.

12:45 duck1123: jcromartie: exactly. Should be simple, but seems like I'm not the first to need it

12:45 clojurebot: Gabh mo leithscéal?

12:45 jcromartie: duck1123: fist I've heard of it but it sounds useful for anybody deploying a Compojure app in a more traditional container

12:47 gensymv: ah i get it. it pulls the packages when i launch the repl/needs to use them.

12:47 that was the confusion i was having

12:47 thanks.

12:54 tgoossens: who has experience with noir?

12:54 TimMc: ~anyone

12:54 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 ..."

12:55 jcromartie: I bet Raynes does...

12:55 :)

12:55 tgoossens: Does anyone have experience with Noir. I consider using it for a web project. And I want to know about its stability and performance.

12:55 jcromartie: best part of IRC: the library author is usually in a channel somewhere

12:55 tgoossens: is that better then? :D

12:56 jcromartie: yeah i noticed that :p

12:56 duck1123: I don't use noir, but I haven't heard any recent complaints about instability

12:59 tgoossens: I'm relatively new to clojure (Using it for one month).

12:59 Wondering

12:59 in java you can make a javadoc for your projects api

12:59 Cubic: What are you trying to use it for? I don't think noir is ready to be the next google backend, but there are several websites using it (including, of course, noirs own homepage).

12:59 tgoossens: how is it done in clojure? Is there a "standard" way to do it?

13:00 technomancy: tgoossens: you can, but it's not very useful

13:00 since all docstrings are available at runtime in the repl

13:00 duck1123: codox is pretty nice https://github.com/weavejester/codox

13:00 tgoossens: technomancy: http://webnoir.org/autodoc/1.3.0/noir.core.html#var-custom-handler

13:00 duck1123: also https://github.com/fogus/marginalia

13:00 zerokarmaleft: or marginalia if you're into literate style docs

13:00 technomancy: just use the repl

13:01 tgoossens: Cubic: It's for a project where I live (Antwerp). If released very probably used by 500 students per school

13:02 Cubic: tgoossens: I doubt you're gonna run into performance or stability problems with 500 users, but don't quote me on that.

13:02 tgoossens: Cubic: I won't :D

13:02 TimMc: technomancy: The REPL is great for targeted doc reading, but it's not great for skimming down a list of available oeprations.

13:03 tgoossens: technomancy: i've been reading about "data vs api" and data IS the api in clojure. But you use metadata to document what you expect as argument?

13:04 However. With destructuring I've found it much simpler to know what i can give to the function

13:04 notice the world "simple" ;)

13:04 technomancy: yeah, there's no hard and fast rule; it comes with time

13:05 I recommend starting with compojure for a web project though

13:05 tgoossens: hmm heard of it never seen.. googling...

13:05 technomancy: can you also say why?

13:06 technomancy: tgoossens: it doesn't make decisions behind your back like noir does and is easier to debug when things behave unexpectedly

13:06 tgoossens: technomancy: hmm descisions like what?

13:06 technomancy: noir makes it difficult to apply middleware in a composable way

13:06 jcromartie: tgoossens: Noir is based on Compojure

13:07 Noir creates things you can't control

13:07 tgoossens: i see

13:07 mpan: what are concrete examples of what noir doesn't let you control?

13:07 jcromartie: basically, Noir adds a "friendly" stateful API on top of Compojure, and lets you create "pages" instead of handlers

13:07 duck1123: use plain compojure+ring till you get the hang of clojure web dev then decide if you need a higher abstraction

13:08 tgoossens: i like the defpage :p

13:08 technomancy: mpan: the one that comes up most often is the difficulty of applying middleware and the fact that routes are tucked away somewhere in an atom

13:08 jcromartie: defpage is OK when that's all you need

13:08 technomancy: rather than being first-class defs

13:08 mpan: like because it has state, you have to do stuff in a defined order?

13:08 jcromartie: and "defpage" is a misnomer

13:09 because it doesn't result in a var you can see

13:09 tgoossens: mpan: i'm quickly scrolling through api examples. Haven't dived into it yet

13:09 jcromartie: it sets up a route somewhere else

13:09 gensymv: so i tried installing core.logic through leiningen, it pulled down jar's from the interwebz but now i cannot open the repl through leiningen

13:10 (it complains about socket errors)

13:10 jcromartie: you can only do GET or POST with defpage

13:10 and you can't do both at the same URL

13:10 gensymv: any ideas?

13:10 tgoossens: ok.

13:10 i'll take a look at compojure then :)

13:10 jcromartie: gensymv: any more specific error?

13:11 gensymv: i'll pastebin it, wait a sec.

13:11 jcromartie: tgoossens: and please hang around, because I'm sure you'll have questions :)

13:12 tgoossens: Oh I wille. I've been hanging around here already way too much :D . I love the quick help :D

13:12 gensymv: oh nvm, apparently it wasn't finished with pulling dependencies -- which is weird.

13:12 jcromartie: tgoossens: first step is to add compojure and ring (for ring.adapter.jetty/run-jetty)

13:13 you'll want [ring "1.1.6"] to get everything

13:13 tgoossens: jcromartie: its just. I've so much work at university that I almost cannot find time to 1) play with clojure 2) also relax :D

13:13 jcromartie: tgoossens: I hear ya

13:13 tgoossens: jcromartie: certainly because at university i'm obligated to do projects in java (only)

13:14 mpan: tgoossens: I also feel like almost all my programming is for university assignments

13:14 tgoossens: all we learn is java, OOP, designpatterns etc etc

13:14 mpan: and afterward, I feel too burned out to do much on my own

13:14 gensymv: this is what it complains about btw. http://bpaste.net/show/T5cV4u2pf8tUgYu1PJ24/

13:14 tgoossens: mpan: i know how you feel

13:14 jcromartie: tgoossens: you should ask your profs about Clojure

13:14 you can AOT compile a Clojure class and hand in a jar

13:14 tgoossens: jcromartie: interesting

13:14 mpan: jcromartie: I have seriously considered that

13:14 tgoossens: jcromartie: That might work

13:14 mpan: but it would be "bending the rules" in an "undersirable" way

13:15 jcromartie: lol

13:15 tgoossens: jcromartie: only, 1) They want to see the source code. 2) they expect it to be OO 3) this year it is a groupswork so my teammates won't ever agree :p

13:15 jcromartie: I only took some CS courses at a community college. Intro to programming, OO analysis and design, data structures… it sucked

13:15 yeah

13:16 all Java, all the time

13:16 tgoossens: At univseristy i think OO is really taught to much like "its the best ever! And if it is not OO, its bad!"

13:16 jcromartie: and no real explanation

13:16 just rote learning

13:16 the "hello world" case for Java is pretty bad

13:17 ToxicFrog: mpan: have you asked the TA/profs? It might be worthwhile to do so.

13:17 gensymv: so, it apparently finished pulling stuff, but i think i broke something.

13:17 tgoossens: but it has only been since september that I came into contact with something else than OO / imperative programming

13:17 gensymv: http://bpaste.net/show/sZVqJ7pJTN7cl7j3O5qE/

13:17 mpan: ToxicFrog: they don't want to grade Clojure... their life is hard enough grading Java

13:17 gensymv: help will be appreciated.

13:17 ToxicFrog: Hell, I got away with doing Compilers with a C/Lua mix and Distributed Systems in Erlang.

13:17 Oh :/

13:18 mpan: a certain class goes as far as to say standard Java library only, no external deps

13:18 jcromartie: I think they should start teaching with Python

13:18 tgoossens: yes

13:18 In fact

13:18 they considered teaching python instead of java in the first bachelor yar

13:18 they didn't :(

13:18 jcromartie: gensymv: what does your project.clj look like?

13:18 mpan: because they have ~50 students per grader, every assignment

13:18 jcromartie: compare: print "Hello, World!"

13:18 mpan: and the poor grader has a life

13:18 jcromartie: vs Java: public class Hello { public static void main(String[] argv) { System.out.println("Hello, World!"); } }

13:19 tgoossens: i know :D

13:19 jcromartie: like, WTF is all of that?

13:19 tgoossens: the first time

13:19 ToxicFrog: tgoossens: could be worse, we're using C for first year, and there's no consistent protocol for teaching students how to operate the debugger either.

13:19 mpan: sure, but if that was the only complaint, it would be a rather small one

13:19 I'm more worried about the complaints that don't go away over time

13:19 tgoossens: ToxicFrog: it can be even worse: I have to write assembly for mips architecture :p

13:19 mpan: sure but that's for a specialized course

13:19 not in general, right?

13:19 gensymv: jcromartie, https://www.refheap.com/paste/6286

13:19 nDuff: tgoossens: That's not so bad at all.

13:19 tgoossens: i know ;)

13:20 ToxicFrog: IME most of them don't start understanding programming (as opposed to "how to cobble together a working program in C") until near the end of second year when they're getting exposed to python and java as well.

13:20 jcromartie: gensymv: you are missing Clojure itself!

13:20 nDuff: tgoossens: MIPS is probably one of the better architectures to work with for that purpose.

13:20 tgoossens: i know

13:20 ToxicFrog: We use the 68k for our asm course.

13:20 nDuff: tgoossens: ...granted, as former maintainer of gxSPIM, I might be a little biased. :)

13:20 jcromartie: gensymv: in a Leiningen project, the language is a library (pretty cool if you ask me…)

13:20 ToxicFrog: I've never used MIPS, just 68k and 386.

13:20 jcromartie: gensymv: add [org.clojure/clojure "1.4.0"]

13:20 tgoossens: nDuff: and I have nothing against programming in assembler, as long as it is for learning how under the hood it works

13:21 nDuff: *nodnod*.

13:21 tgoossens: (kinda)

13:21 gensymv: jcromartie, lol.

13:21 thanksş

13:22 tgoossens: i still have 2,5 years to go at univ. And as far as I know. It will all be in sense of OO

13:22 nDuff: ...well -- I've actually heard a pretty compelling argument that SH is a better learning architecture

13:22 but it hasn't been around nearly as long.

13:22 (the SH manuals are annotated with C to implement each instruction in a simulator).

13:22 gensymv: jcromartie, that did the trick.

13:22 jcromartie, thanks pal.

13:23 one more question, if i clone the repo and create the project.clj file with the sole dependency of clojure itself, will it directly internalize the library?

13:24 jcromartie: gensymv: not sure what you mean

13:24 "internalize"?

13:25 gensymv: https://github.com/clojure/core.logic

13:25 tgoossens: Anyone used clojure already for android development? Might be interesting i think

13:25 technomancy: tgoossens: it's not anywhere close to ready from what I hear

13:25 gensymv: if i clone this repo, create a project.clj file and "lein install"

13:25 it will do the same thing right?

13:30 tgoossens: Functional programming an sich existed already a loong time ago. Why do you think it hasn't been as popular as OO. It has probably to do with identity, which is a great way for modelling stuff i think. But that argument is invalid now, clojure has identity (in a much cooler way)

13:30 cemerick: tgoossens: I've recently heard people being waved away from scala for android dev because of classloader and JIT issues. Those problems affect Clojure even more.

13:31 tgoossens: how come?

13:31 mpan: how much of that is bypassable by aot compilation?

13:32 I mean, being a different VM is meh :/

13:33 tgoossens: I also think that. in functional programming. The idea of "pure functions" scare people: "How are we supposed to have interaction with the outside world then?"

13:34 cemerick: tgoossens: My understanding is that even simpler things like protocol dispatch (which is optimized to the 9's by hotspot et al.) are impaired in dalvik

13:34 mpan: AOT is mandatory for anything approaching sane android dev as far as I've heard

13:35 dnolen: cemerick: still hoping people give ClojureScript a shot on Android w/ V8, from the sound of it on Raspberry Pi ClojureScript runs circles around Clojure JVM

13:36 cemerick: but that doesn't address points of dynamism like protocols, multimethods, proxies, etc. Scala's runtime has none of those features, so doesn't suffer from the poor JIT.

13:36 hah, sweet

13:36 dnolen: if and when I do mobile, that's the route I'll be taking

13:37 mpan: I hear a lot of mobile native dev folks complaining about anything involving HTML 5, but then again, they are hardly impartial

13:37 cemerick: we can't blame Clojure for its perf on the Pi though; that's more of an architectural issue between V8 vs. JVM.

13:37 dnolen: JavaScriptCore is quite fast too from what I can tell. Would be happy to see a lighter alternative to PHMs for ClojureScript - that's the slowest datastructure by far. Perhaps cgrand new map type will perform better?

13:38 cemerick: yes implementation details ;)

13:38 cemerick: mpan: Sure, if you've got cash to burn on additional devs for 2±1 platforms. *shrug*

13:39 mpan: well, a particularly poignant example was a certain CTO from a certain company whose success depended on convincing their clients to get native apps done for each platform

13:40 he accused me of being an HTML 5 apologist at a job fair and whatnot

13:40 I really shouldn't say these things under my own name :(

13:40 tgoossens: gotta catch a train

13:40 we speak again!

13:40 mpan: have fun

13:40 Baldanders`: @tgoosens Well, I think there are some reasonable reasons to want to be sure that you can break out of pure FP without too much inconvenience for certain kinds of things. Even if they can be modeled purely it's not always convenient or practical.

13:41 err- well, maybe I will talk with you about it some other time ;).

13:41 tgoossens: :)

13:41 cemerick: mpan: If mobile dev were my thing, I'd be HTML5-only just to avoid native platform sharecropping.

13:41 tgoossens: long story short:

13:41 multi paradigm rules

13:41 mpan: "sharecropping"? Sorry, I don't follow your metaphor

13:42 jcromartie: eh, I've tried the HTML5-instead-of-native thing, and it's just not for me

13:42 I'm sure HTML will get there

13:42 but right now native is really far ahead

13:42 like, really *really* far ahead

13:43 and it's totally unfair since native can pull in HTML in a view wherever it is useful, while the reverse is not true

13:43 mpan: phonegap etc try hard to get some semblance of the reverse

13:43 cemerick: mpan: app store approval + 30% cuts is not a favorable market IMO

13:44 jcromartie: mpan: they are wasting their time, honestly

13:44 mpan: on top of saturation, I suppose

13:44 app store saturation is scary

13:44 jcromartie: I was at a mobile conference, and everybody that was presenting about PhoneGap and similar techniques were selling something

13:44 all of the actual app developers were using and advocating native

13:45 mpan: of course, native has momentum

13:45 lynaghk: cemerick, dnolen: we're working on a ClojureScript weather app for iPhone. Pref is a bit lacking---not sure how much is the JS situation and how much is attributable to CLJS.

13:46 dnolen: lynaghk: via JavaScript

13:46 lynaghk: dnolen: yeah.

13:46 dnolen: lynaghk: er, via JavaScriptCore or via WebView?

13:46 lynaghk: Cordova, which I believe is using a WebView.

13:46 dnolen: lynaghk: yeah, I don't you'll get any JIT love there.

13:48 lynaghk: dnolen: yeah. We haven't done any perf tuning yet. Do you know offhand if it's possible to mash up JavaScriptCore while using a DOM?

13:49 jcromartie: Just point me to a 5-star, top-selling Cordova/PhoneGap app.

13:49 :P

13:53 lynaghk: jcromartie: maybe. We've done custom apps for enterprise folks using Cordova. Sells one copy, but the net is better than most app store apps =P

13:53 cemerick: jcromartie: what, you don't have a clojurec app available for download yet? ;-)

13:54 devn: howdy all

13:57 mpan: lynaghk: any public examples of an app using those libraries?

13:57 oh whoops

13:57 :(

13:57 dnolen: lynaghk: it always good to get information about the bottlenecks, I did just add SourceMap V3 support to CLJS, perhaps can help w/ profiling if you're using a WebKit view in your app?

14:04 Negdayen: I played around with clojurescript in android dev using a web view for a bit. For me, the bottleneck were the javascript-java interop calls. Nothing clojurescript can really do about though, ofc.

14:05 bonega: Negdayen: Have a look at Phonegap

14:05 Baldanders`: I have a question about Clojure idioms. Let's say I have a predicate function that just calls another function that can return some truthy value or nil. Is it more idiomatic to use a when, and return the value returned by that function, to use a when and return true from that branch, or to use an if and return true or false?

14:07 Negdayen: Well, I had considered phonegap--but.. for what I was doing, it wouldn't have really helped I think. I was doing somethign rather crazy and did no expect performant results in the first place--OpenGL rendering. Lol.

14:07 technomancy: Baldanders`: don't use an if with true/false in its branches

14:07 Baldanders`: if you have to return a boolean, use the boolean function

14:08 IMO it's OK to have a predicate that doesn't necessarily return a boolean, but that's debatable.

14:09 Baldanders`: OK- so is it better to just return the result of calling that function (in which case the function I am writing exists only to give it a better name) or to return true from a when?

14:09 bonega: Negdayen: ah, I thought you were refering to some sort of api-problem, not the performance

14:09 alexnixon: Baldanders: the clojure library coding standards says "NB predicates return booleans"

14:09 Baldanders`: oh, I see

14:10 technomancy: Baldanders`: yeah, opinions vary. I really hate seeing when used for return values though.

14:10 if the function is part of your public API then it's probably worth calling boolean though

14:10 Baldanders`: OK- I am kind of used to CL, where the nil/false distinction doesn't exist.

14:11 technomancy: for internal functions I wouldn't bother; the question mark in the name is enough

14:11 Negdayen: Well, id o think the performance problem was in the api--marshalling and unmarshalling JSON data across to java OpenGL calls was terribly, terribly slow.

14:11 as one can imagine. :P

14:11 alexnixon: see clojure.core/not-empty for a good example - it returns truthy if a collection is not empty and falsey if it is, but it doesn't return a boolean and so is not a predicate (it doesn't have a ? suffix)

14:12 technomancy: Baldanders`: nil isn't the problem; the problem is someone could conceivably do something with the a truthy return value.

14:12 I would say it's their fault if they do that; the name clearly indicates it's a predicate, and if they use it as not-a-predicate that's a bug in their

14:12 code

14:12 but opinions vary

14:13 Negdayen: I was thinking perhaps there might be a way to perform the callins via the NDK and V8 or some other. But, I am not experienced in that area at all. Not sure if that would be a possiblity.

14:14 mpan: Hm, I'm wondering about something from earlier. It's turning out that my data is a bunch of defs in a clj file. Would there be a difference in using it via require vs using it via load-file?

14:15 jcromartie: mpan: why is your data a bunch of defs

14:15 mpan: because I'm lazy and this is the only place I'm going to use it

14:15 dnolen: Negdayen: that's a pretty interesting ClojureScript use story

14:16 mpan: so I'd rather avoid jumping through the encoding-as-some-serialization-format hoop

14:16 I admit, this isn't quite what I was originally imagining

14:16 technomancy: mpan: just put it in a map and use load-file

14:16 jcromartie: and by "some serialization format" you mean "prn" won't work?

14:17 mpan: but semantically? is there any difference with putting it in a map and doing a require?

14:17 jcromartie: yes there's a big difference

14:17 require doesn't return anything

14:17 technomancy: require won't work unless you have a namespace

14:17 mpan: oh, uh yes I do have a namespace

14:17 there's a ns declaration at the top of the file, rather

14:18 jcromartie: mpan: sounds like you just have a typical clojure code file

14:18 mpan: except this is "application data"

14:18 jkkramer: put the data in a file in resources/ and then use read or read-string or similar to pull it in

14:18 technomancy: what jkkramer said

14:19 mpan: all right

14:19 thank you all

14:24 duck1123: if you're using useful, useful.config/read-config might be good for you

14:30 jweiss: huh, i'm just finding out (the hard way) that "thread local bindings" don't quite mean just that. if you spin off a thread within the binding form (eg in a future), that thread sees the same binding as the original thread. I assumed it would see only the root binding.

14:30 mpan: I've found "useful" but where do I find the docs for it?

14:31 AdmiralBumbleBee: mpan: docstring

14:32 mpan: ah thanks!

14:32 duck1123: like many clojure projects, just check out the source. :(

14:32 AdmiralBumbleBee: the docstrings in useful are very well written IMO

14:32 embarrassingly so when you compare to clojure.core

14:33 pandeiro: anyone get "Invalid number of options" when trying to use cljsbuild's notify-command feature?

14:34 hiredman: jweiss: that used to be the case

14:35 jweiss: post 1.3 bindings get conveyed to futures and agents

14:35 gensymv: is there a way to make leiningen auto add the locally installed libraries to the classpath (outside the project)

14:35 hiredman: it kind of stinks

14:36 jweiss: i guess it's fine, i was writing log files (what I thought was) "per thread"

14:36 but was getting jumbled output and couldn't figure out why

14:36 piranha: can I do the same in clojure as 'import some.ns.*' in java? I.e. import every (java) class from namespace?

14:37 duck1123: gensymv: "lein classpath" will print out the classpath for the project. You can start there, but why are you trying to do this?

14:37 nDuff: hiredman: ...it does? I've been using bound-fn* unnecessarily, then.

14:38 * nDuff learned something new.

14:38 gensymv: duck1123, i installed a library by listing it as a dependency of a dummy project, now i cannot use the library in repl outside that project

14:39 nDuff: gensymv: ...so, existing in the Maven cache isn't generally considered "installed"

14:39 gensymv: ...think of it more as "cached"

14:39 gensymv: nDuff, hm i can see the corresponding jar file in .m2/repository/BLAR

14:40 duck1123: without a project, lein repl only has access to the dependencies it needs itself

14:40 gensymv: ah.

14:40 Baldanders`: @technomancy: sorry for the delayed response- got called away. But that makes sense, and is maybe part of what made me feel a little unclean about just returning the result of calling the function. Thanks.

14:41 gensymv: is there a way to work around that?

14:41 duck1123: that's why it's best to always work in the context of a project, even if that project is only for one-off playing. Sooner or later you'll want to add a new dep

14:41 nDuff: gensymv: ...I _always_ work in projects. You can use pomegranite to install things at runtime, but you need to be in a project to have even that.

14:42 gensymv: hm, thanks.

14:42 piranha: or at least is there any way to import package (as opposed to importing class), so that I won't have to enumerate every class name I need in :import declaration?

14:42 jweiss: piranha: i'm not aware of any way to require a bunch of ns' at once

14:42 oh you are referring to actually importing java classes

14:43 piranha: right

14:43 I found answer that I can't, but I can't found if I can import package

14:43 duck1123: There used to be a ns+ macro I had seen, but IIRC it suffered from a bootstrapping problem

14:43 piranha: I have like 40 classes...

14:43 it won't be fun to list them twice :-))

14:44 jweiss: piranha: i'm not aware of any way, unless you want to get ugly and use reflection to get a list of classes, and call import on all of them.

14:46 piranha: jweiss: well... that's not nice :)

14:47 jweiss: I thought maybe I can do something like (:require [my.java.package :as pkg]), but it seems to be not working

14:47 jweiss: no, require is for clojure ns's only

14:47 duck1123: so you're directly referring to 40 classes in your namespace?

14:47 piranha: duck1123: well I'm not yet, I'm just writing it

14:47 ok, let's get more specific then :)

14:47 https://github.com/sirthias/pegdown/blob/master/src/main/java/org/pegdown/ToHtmlSerializer.java

14:48 here is a Visitor for some markdown parser

14:48 I need to have specific rendering of markdown (not in html), so I have to write my own

14:48 I thought I'm going to have a function with long (case (type node) ast/RootNode ... ast/OtherNode ...), etc

14:49 but it seems I have to list every class in my :import statement, which looks quite ugly

14:49 maybe approach with case is ugly btw, but I don't know if I can have fast function dispatch on class

14:50 jweiss: why not just do a map lookup?

14:50 jcromartie: piranha: can you shell out to the Perl script?

14:50 piranha: jcromartie: nope, I need to have normal ast :-)

14:50 jcromartie: lol

14:51 piranha: jweiss: like {RootNode process-root OtherNode process-other}?

14:51 jweiss: yeah, assuming those are all functions already

14:52 piranha: well, they are not, but I'll write them, heh

14:52 that's an option... anyway, this means I have to list every name in :import

14:52 jweiss: you could just list the whole package name and not import anything.

14:53 in fact, if you used a map you could just leave off the package name and add it to all the keys afterward

14:53 but that is getting a bit fancy

14:53 piranha: haha, but that's an option!

14:53 TimMc: piranha: If you do an ls on the directory you could get a list of classes and just dump that in your ns block.

14:53 piranha: TimMc: right ;)

14:53 it's just that editing will require 2 places

14:54 duck1123: That is one hell of an interface, btw

14:54 piranha: though whatever, not a big deal, I shouldn't be changing that often :)

14:54 duck1123: not exactly my dream, heh :-)

14:54 but then, it seems like the best markdown parser for jvm (it's supported, has ast and documented, unlike others)

14:55 jkkramer: a macro could expand a list of class names into appropriate dispatching code

14:56 TimMc: jkkramer: What, generating an (import ...)?

14:56 Oh, nvm, I see.

14:57 jkkramer: no, just '[RootNode, BulletListNode, …] => macro => whatever form your dispatcher takes (case statements, map, protocol impls, …)

14:57 piranha: hm, right!

14:57 jkkramer: this is lisp, after all

14:57 write some code to write the code for you

14:58 jweiss: (inc jkkramer)

14:58 lazybot: ⇒ 4

14:58 piranha: well, thank you, I have to switch to different mindset, too much javascript is not doing anything good to my brain it seems

15:00 Baldanders`: I've said it before, but, IMHO, everything would have been a lot better if Netscape had just embedded Scheme in Navigator, instead of coming up with a scheme-inspired language meant for people used to C.

15:00 TimMc: And people would have used it, since they wouldn't have a choice.

15:01 Baldanders`: exactly ;)

15:01 Javascript is every bit as offbeat as Scheme, actually.

15:01 jcromartie: Baldanders`: Imagine how bad ExpertsExchange would be if it were full of half-wit Scheme coders

15:01 Baldanders`: or was, at least.

15:01 devn: Am I a bad person for not wanting to switch to nREPL yet?

15:02 nDuff: devn: Not bad, necessarily, but... I was wary, and switched recently, and I'm pretty darned happy.

15:02 devn: What about references? Like "Who calls..."?

15:02 That stuff is not implemented, right?

15:02 piranha: indeed, I'm using JavaScript not because I like the language, but because of environment. I would write for browsers even if they had Cobol inside %)

15:03 Baldanders`: Hmm- I'm not sure it's better to have a bunch of half-wits using a half-baked language. Though, to be fair, Javascript is pretty neat in places.

15:03 hiredman: devn: we still use swank/slime for our work projects, I've used nrepl for some personal projects, and ux for swank/slime is still better

15:04 so I can't blaim anyone for sticking with swank/slime

15:04 piranha: Baldanders`: can't imagine where it's nicer than any other language I'm using. In places it's sometimes as good as they are, but neat? No, no, it's painful :))

15:06 jweiss: from what i've read about nrepl it's improving at an impressive rate. some of the open issues sounded annoying so i haven't switched yet

15:06 pandeiro: i can't get cljsbuild to include other ns within my src-cljs/ when i specify builds by subdirectory within src-cljs/*

15:07 Baldanders`: Well, it was my first exposure to protype-based stuff, hich I have since come to quite like for some things (though that has been done better elsewhere.) And it has real closures. And it is fairly lispy, if broken in a lot of ways. I am writing a lot of C these days, and I'd rather be writing js, if it had the charactersitics C has that js lacks.

15:13 technomancy: devn: who-calls in swank-clojure is pretty broken IIRC

15:14 the main thing that's missing is the debug repl and inspector

15:14 so I still fall back to slime if I have to work with a bunch of Java classes and need to peek at their methods

15:16 hiredman: the way nrepl endlessly creates *nrepl<n>* buffers is really a drag

15:16 ticking: am I the only one constantly writing (range start Double/POSITIVE_INFINITY) ^^?

15:16 hiredman: (nrepl.el)

15:16 piranha: Baldanders`: ah, ok, sure, I was comparing JS to languages I write in, and that's mostly Python, so it's hard to love it :)

15:17 bbloom: ticking: what do you use it for?

15:18 ticking: bbloom numbering pages, creating test sequences, indexing stuff ^^

15:19 bbloom why create a bound list when I can create an infinite one and just take n ^^

15:19 bbloom: ticking: hm yeah, it's kinda unfortunate that there isn't some function that is as easy to use as .. and ... syntax in other languages

15:19 ticking: bbloom my point exactly ^^ (range n …) would be super handy ^^

15:20 jkkramer: ,(take 10 (iterate inc 0)) ;a bit shorter

15:20 clojurebot: (0 1 2 3 4 ...)

15:20 Iceland_jack: ,(take 10 (range))

15:20 clojurebot: (0 1 2 3 4 ...)

15:20 jkkramer: right, assuming your start is 0

15:20 Iceland_jack: ,(take 10 (range 4))

15:20 clojurebot: (0 1 2 3)

15:20 bbloom: jkkramer: yeah, but range has nice chunking properties, etc

15:20 Iceland_jack: damnit, egg on my face

15:21 ticking: jkkramer right, but its not as nice for somebody not familiar with the code

15:21 bbloom yeah chunking is awesome ^^

15:21 jkkramer: see also: map-indexed

15:22 Baldanders`: Sure- Python is fairly lispy too, though less so than js, IMHO. I've mainly written Python and C for the last couple of years. But there are a few placews where I think js might be better: Python's scoping rules are very weird, IMHO, an it would be nice to have real closures in Python.

15:22 Iceland_jack: ,(take 10 (map #(+ 4 %) (range))) ; runs

15:22 clojurebot: (4 5 6 7 8 ...)

15:24 ticking: Iceland_jack yeah problem is readability and performance there ^^

15:24 dnolen: Iceland_jack: that's actually pretty good, since you can preserve chunking

15:24 ticking: I don't see how performance is really an issue here

15:25 ticking: dnolen two additions instead of one

15:25 holo: hi

15:25 dnolen: ticking: I'm sure the cost will be dominated by other things.

15:26 it's not like chunking magically eliminates allocation overheads

15:26 ticking: dnolen yeah but why would you do chunking (which prevents one fn evaluation per value) just to reintroduce one function evaluation per value

15:26 jkkramer: you could also write your own range function… (defn range-from [start] (range start Double/POSITIVE_INFINITY 1))

15:26 ticking: jkkramer that is basically what (range) does

15:27 jkkramer: only if you start from 0

15:27 dnolen: ticking: no, chunking doesn't eliminate fn evaluation - it eliminates allocation overhead, processing on 32 elements at time

15:27 ticking: jkkramer yeah but I'd probably prefer haskell like style a la 1 …

15:28 Iceland_jack: ticking: how would that fit the Lisp syntax?

15:28 ticking: Iceland_jack what lisp syntax ;) (range 1 …)

15:29 * Iceland_jack cries a bit

15:29 ticking: Iceland_jack lisp is all about macros

15:29 Iceland_jack: Since when?

15:29 ticking: Iceland_jack DSLs to be more precise

15:29 Iceland_jack: I stand by my question

15:30 jkkramer: (def ... Double/POSITIVE_INFINITY)

15:30 ticking: dnolen which you still reintroduce by calling that function on every element

15:30 dnolen: ticking: no

15:31 ticking: Iceland_jack since it got macros^^ why would you have oatmeal with toenails clipped in it if not for the flexibility ^^

15:31 boodle: /shell setenv TERM=screen-256color

15:31 Iceland_jack: I don't think this conversation will be fruitful

15:32 dnolen: ticking: same as reducers. fns invocations on every element don't magically disappear

15:32 ticking: jkkramer yeah that'd do the trick ^^ but I was wondering how many other people use infinite lists starting at non defaults

15:33 ejackson: how is it the reduce works on java arrays, they are not classes so how is the CollReduce protocol extended to them ?

15:33 dnolen: ticking: which why thinking adding one more arith operation will be a significant cost makes no sense

15:33 jkkramer: ticking: that was tongue in cheek suggestion, don't do that

15:33 * ejackson confused by internals he doesn't grok

15:33 ticking: dnolen yeah what I meant was that with 1.0 seqs every first involved a fn being resolved and now it's only every 32th element

15:34 jkkramer I know I won't but I'd be a funny solution nevertheless that emulates that with a minimum line of code ;D

15:34 Iceland_jack whats lisps flexible syntax for you about then?

15:35 Iceland_jack: Not interested

15:36 dnolen: ticking: not sure what you mean about "fn being resolved"

15:37 ticking: dnolen if my understanding of the implementation is correct the lazy-seq macro wraps every subsequent call to the body in a separate fn

15:37 which gets then called by first

15:39 dnolen: ticking: yes but what does that have to do with a "fn being resolved" in the case of chunked seq? if you mean that the allocation overhead is decreased because you get 32 transformed elements at time w/ chunked seqs ... ok.

15:42 ticking: dnolen, yeah I'm intrigued by this so I'm currently running some criterion benchs ^^I'd be delighted to be utterly wong :D

15:43 amalloy: ejackson: reduce is extended to c.l.ArraySeq

15:44 ejackson: amalloy: thanks. Now what is an ArraySeq (I'm reading the code for it now)

15:44 amalloy: &(class (seq (into-array [:a :b :c])))

15:44 lazybot: ⇒ clojure.lang.ArraySeq

15:45 amalloy: it's just an implementation detail of how arrays are seq'd over

15:45 ejackson: aaah I see

15:45 hmm... i was hoping to use reducers with arrays and avoid boxing

15:45 but (seq (into-array ...)) will just box it up again

15:45 or is there something subtle to avoid that ?

15:46 dnolen: ejackson: reducers don't support primitive pipelines yet

15:46 ejackson: alas !

15:46 thanks dnolen, amalloy clears it up for me

15:46 amalloy: ejackson: yeah, it won't work for primitives. it avoids consing up stuff for traversing the array, but for getting stuff out...

15:48 holo: with '({:check ['email1']} {:check ['email2']}) i want to obtain {:check (email1 email2)} . didn't have any success with apply/reduce + merge-with

15:49 ejackson: primitive type hinting the functions within the reducers does improve performance

15:49 amalloy: really? i doubt that

15:49 ejackson: 1 sec, i'll gist it

15:49 amalloy: i mean, maybe it improves the performance of your arithmetic inside the function, but you'd get that from a hinted let-binding

15:50 and it won't improve the performance of calling, which is where the boxing happens

15:51 TimMc: holo: ##(let [in [{:check ["foo"]} {:check ["bar"]}]] (apply merge-with (partial apply conj) in))

15:51 lazybot: ⇒ {:check ["foo" "bar"]}

15:51 ejackson: amalloy: https://gist.github.com/3989381

15:51 amalloy: ejackson: you have a 1.5 repl handy, right? mind trying out (reduce + (take 1e6 (cycle (concat '(1) [2])))) for me? looking at the code near ArraySeq makes me think it will stackoverflow

15:51 ejackson: amalloy: sure, lemme try

15:52 no overflow

15:52 amalloy: ejackson: right, here you're speeding up the call to Math/round by avoiding reflection, not the call to your function. https://gist.github.com/3989391 ought to be just as fast

15:53 ejackson: even at 1e8 it doesn't overflow

15:54 amalloy:aaah I see its that call

15:54 thanks that clarifies it

15:54 amalloy: TimMc: (= (partial apply conj) (with-slowness into))

15:57 piranha: can I somehow view a function source in repl? This function is anonymous, so I can't do (:source (meta #'fn-name)).

15:58 amalloy: no

15:58 ivan: serializable-fn?

15:58 clojurebot: serializable-fn is a hack for preserving source of a compiled function: https://github.com/technomancy/serializable-fn

15:59 ejackson: amalloy: thanks again.

16:00 TimMc: amalloy: haha, fair

16:01 duck1123: If I have some clojure code that I need to access from a JSP page, what would be the best way to include it? I originally wrote it as a compojure app, but I need it to be run in the context of our JSP template

16:02 I got it working as an iframe, but I'm not happy with that solution

16:02 hiredman: call it like however you call java core via jsp

16:03 holo: TimMc, i don't know why i didn't try this variation: (apply merge-with into (list {:check ['email1']} {:check ['email2']})) but it also works as yours. your (partial apply conj) melt my brain :>

16:04 ##(apply merge-with into (list {:check ['email1']} {:check ['email2']}))

16:04 lazybot: ⇒ {:check [email1' email2']}

16:04 TimMc: holo: into is better.

16:05 holo: TimMc, that ' is weird

16:05 TimMc: holo: You know that ' isn't valid for string quoting in CLojure, right?

16:05 &(class 'foo)

16:05 lazybot: ⇒ clojure.lang.Symbol

16:05 hiredman: <%= clojure.lang.RT.load("my/ns/name"); ((clojure.lang.IFn)clojure.lang.RT.var("my.ns.name", "a-fun")).invoke("foo"); %> or something

16:05 TimMc: &(class "foo")

16:05 lazybot: ⇒ java.lang.String

16:05 hiredman: I don't know anything about jsp

16:05 holo: TimMc, ok, that's explained. probably forgot about it. thanks!

16:06 devinus: when was swank deprecated

16:07 hiredman: actually, I don't think you need the IFn cast for Vars like that

16:07 as long as RT.var has a real return type

16:07 ticking: dnolen https://gist.github.com/3989455 interesting result ^^ I didn't think (iterate inc 4) would be so slow

16:09 technomancy: devinus: development on it ceased 8-10 months ago, but it was only made official 2-3 months ago

16:09 amalloy: i can't understand why (reduce + (take 1e6 (cycle (concat '(1) [2])))) doesn't cause a stack overflow with the new reducers stuff. it seems like internal-reduce should get called, and since the type of the underlying seq changes every time (back and forth between Cons and ChunkedCons) it should keep doing a non-tail call to internal-reduce again

16:10 callen: why is oauth so horrible?

16:11 ticking: dnolen 30% slower is indeed not bad, still overhead but not nearly as bad as I had assumed

16:12 dnolen: ticking: yep

16:13 hiredman: ,(type (cycle (concat '(1) [2])))

16:13 clojurebot: clojure.lang.LazySeq

16:13 hiredman: ,(type (rest (cycle (concat '(1) [2]))))

16:13 clojurebot: clojure.lang.LazySeq

16:13 hiredman: ,(type (rest (rest (cycle (concat '(1) [2])))))

16:13 clojurebot: clojure.lang.LazySeq

16:14 hiredman: the (lazy-seq ...) around the boyd of cycle (at least, maybe concat too?) makes it always a LazySeq

16:16 duck1123: callen: Have you read this? http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/

16:17 dnolen: ticking: iterate creates a real lazy seq, no chunking

16:18 ticking: so seq allocation overhead for every step

16:19 ticking: dnolen right, I didn't think that seq allocation is so much more expensive than function application

16:19 dnolen: ticking: like way way way way way way more expensive

16:19 ticking: dnolen hrhrhr :D

16:19 dnolen: ticking: ;)

16:20 amalloy: hiredman: only because you're calling rest instead of next

16:20 piranha: argh, I have some cyclic dependency in my clojure file

16:20 how do I resolve the problem that functions doesn't seem to be able to refer to each other?

16:20 amalloy: if you check (type (seq ....)) rather than (type ...), you get the classes changing. and since internal-reduce is checking (class (seq ...)), seems like it should bounce

16:20 ticking: piranha you can use a forwards declaration

16:21 piranha: thanks, will read about it

16:21 ticking: piranha sec, code follows ^^

16:21 piranha: aha, (declare ...) ? :)

16:21 ticking: piranha yeah exactly ^^

16:21 piranha: ticking: thanks!

16:21 ticking: piranha np ^^

16:24 goracio: hi there

16:25 hiredman: amalloy: interesting, if you put a println in the interal reduce impl it just shows Cons as the class all the time

16:25 amalloy: i must be putting my println in wrong, because i can't get any printlns to show up :P

16:26 goracio: i wonder if there is something close to cramp.in in clojure ?

16:27 mpan: which bot handles findfn, and what syntax should I be whispering it?

16:28 amalloy: $findfn 1 2 3

16:28 lazybot: [clojure.core/bit-or clojure.core/bit-xor clojure.core/+ clojure.core/unchecked-add clojure.core/+' clojure.core/unchecked-add-int]

16:28 mpan: thanks!

16:30 hiredman: ,(type (seq (next (cycle (concat '(1) [2])))))

16:30 clojurebot: clojure.lang.ChunkedCons

16:32 amalloy: &(map class (take 10 (iterate next (cycle (concat '(1) [2])))))

16:32 lazybot: ⇒ (clojure.lang.LazySeq clojure.lang.ChunkedCons clojure.lang.Cons clojure.lang.ChunkedCons clojure.lang.Cons clojure.lang.ChunkedCons clojure.lang.Cons clojure.lang.ChunkedCons clojure.lang.Cons clojure.lang.ChunkedCons)

16:34 goracio: so any thoughts about that ?

16:35 dnolen: goracio: sounds like someone needs to build something like it :)

16:36 spligak: goracio, have you looked at aleph? may proved to be a foundation for something similar.

16:37 *prove, even

16:37 rbxbx: dnolen did you make it out okay with sandy?

16:37 goracio: dnolen: definitely :))

16:38 dnolen: rbxbx: I did, lost internet for a few hours was about it

16:39 goracio: spligak: thanks will look at it

16:39 mpan: Are { } literals always array-based maps? Is this potentially a performance issue if I've got a constant medium-sized lookup-table?

16:39 rbxbx: dnolen fairly non-traumatic. Good to hear :)

16:40 jlewis: is there a way to check to see if a .clj file is being run as a "script"? a la python's if __name__ == "__main__"

16:42 dnolen: rbxbx: thankfully yes

16:43 ticking: jlewis you mean if it is run as a main or called from a library?

16:43 jlewis or rather as a library

16:46 devinus: technomancy: reinstalling emacs starter-kit, i'm not getting paredit on by default anymore, was that changed?

16:49 feeling less productive already :P

16:50 TimMc: &(class (read-string (pr-str (into {} (for [x (range 8)] [x x])))))

16:50 lazybot: ⇒ clojure.lang.PersistentArrayMap

16:50 TimMc: &(class (read-string (pr-str (into {} (for [x (range 9)] [x x])))))

16:50 lazybot: ⇒ clojure.lang.PersistentHashMap

16:51 TimMc: mpan: It looks like only very small map literals are currently backed by flat arrays.

16:52 zackzackzack: How can I extend a object such that I can do (ob :a) or (:a ob) and have it return property a of the object?

16:54 rbxbx: zackzackzack you'd have to implement the function interface

16:54 hiredman: those are two different things

16:54 for (ob :a) ob is being called as a function

16:54 for (:a ob) :a is being called as a function

16:54 mpan: TimMc: thanks!

16:54 AimHere: If you create the object with defrecord, isn't the (:a ob) function already in place?

16:54 Chousuke: yes

16:55 hiredman: for an object to be callable as a function it needs to implement clojure.lang.IFn

16:55 Chousuke: using keywords as accessors works for anything associative

16:55 dnolen: zackzackzack: not if you don't control the type, IFn and ILookup are interfaces in Clojure JVM

16:55 zackzackzack: Sweet

16:55 hiredman: when keywords like :a are called as a function they look themselves up in the argument via a number of different interfaces

16:55 the easiest to implement is ILookup

16:55 zackzackzack: dnolen: that is what I was looking for I think

16:57 Let's say I am extending a java class called Element then

16:57 Would it just be

16:57 (extend-type Element Ifn (invoke [this keyword] (code code code)))

16:58 dnolen: zackzackzack: as I said above, you can't do that

16:58 zackzackzack: in Clojure JVM, it's possible in ClojureScript where IFn & ILookup are protocols not interfaces.

16:59 zackzackzack: Hmmm. That puts a crimp in my style for the moment then.

16:59 jlewis: ticking: i suppose - I'm trying to write a small program that will work regardless of whether I execute clj my-program.clj or compile it as usual and execute with java

17:01 zackzackzack: What if Element isn't a class but rather an interface?

17:02 dnolen: zackzackzack: still won't work. depending on what you want to do you could wrap Element in your own type that provides the interface you want.

17:04 ticking: jlewis afaik that should be the default, clojure is always compiled unlike python

17:07 nDuff: ...unless you use things like gen-class (which only works with AOT compilation)

17:07 ticking: nDuff oh yeah right ^^

17:11 Cheiron: Hi, I have a lib in .ivy2 and I want lein to pick it up. is it possible?

17:14 nDuff: Cheiron: Short answer is "no" -- I use Gradle, not Leiningen, only on account of the lack of Ivy support.

17:14 (and Gradle is really darned miserable in comparison)

17:15 Cheiron: gradle provides the functionality of lein and allow to fetch dependency from .ivy2?

17:15 nDuff: Not all the functionality of lein, but it _is_ a build tool, and with the Clojuresque plugin, it can be used as a sorta-crappy-halfway substitute.

17:15 Raynes: You poor people.

17:16 * nDuff regrets that he didn't start here several years earlier -- not _only_ for the missed stock options, but also because he missed his chance to make it a Maven shop.

17:17 frio: nyargh nDuff

17:17 we use ant and ivy here on our java stuff

17:17 Cheiron: I see, but can for testing purposes. can I use gradle for my clojure project to fetch a dependency from .ivy2?

17:17 frio: huge, complex, wrong

17:17 i feel your pain

17:20 nDuff: Cheiron: Yes, it can be done.

17:22 Cheiron: what about this? https://github.com/lrenn/vine

17:23 nDuff: *shrug*. Last time I looked, it didn't meet my needs -- but I don't remember why that was.

17:30 solussd: could someone tell me why this code creates a bound var "groups-collection" in my repl, but not when compiling with 'lein compile'? https://www.refheap.com/paste/e13402dc488d8b458c7528e6b The last function call fails with "clojure.lang.Var$Unbound cannot be cast to clojure.lang.Named"

17:33 hiredman: ,(doc contains?)

17:33 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

17:33 hiredman: that macro is pretty horrible

17:34 a. contains? doesn't work the way you think it does

17:34 b. single clause ifs

17:34 c. def's inside an if

17:34 d. evaluates types multiple times

17:35 e. evaluates types as a function call multiple times

17:35 etc

17:36 I would be more surprised if anything worked at all ever there

17:38 I have this absurd idea of printing it out and taking a red pen to it

17:39 apwalk_: reading a file in clojure, using io/file, io/reader, and line-seq; the first character is a utf-16 byte-order-mark (BOM) \uFEFF. viewing the same file in vim's hex mode, the first char is a utf-8 BOM, EF BB BF.

17:40 solussd: hiredman: shit.. I dont even think it works that way… I'm just being stupid. thanks, I see the bug

17:40 hiredman: and yeah, horrible.. it evolved that way, I'm sure it'll grow out of it. :)

17:41 hiredman: though, it is happening at compile-time, so… maybe I dont care if it's inefficient. :D

17:42 hiredman: apwalk_: when you create a reader it will assume you want whatever the file.encoding property is unless you tell it otherwise, but I am not sure how that would effect boms

17:42 piranha: what's the right way to insert an element in a vector? I'm doing (apply conj [] (first v) item (rest v)), but this doesn't seem nice to me.

17:43 hiredman: don't

17:43 dnolen: piranha: vectors don't support efficient insertion. so there's not really a "right" way.

17:43 piranha: dnolen: ok, I see... well, I have to anyway, so I suppose I'll just use this approach

17:43 nDuff: piranha: Look at how Clojure's queues work.

17:44 piranha: nDuff: ok

17:44 apwalk_: hiredman: thank you, a promising direction to look.

17:44 nDuff: piranha: ...they have a list on one end, and a vector on the other, so you can efficiently modify both sides.

17:44 piranha: that kind of joint structure might be appropriate for your case.

17:45 piranha: heh, well, I have to generate a data structure for a library, so I'm not sure. Anyway, I'll look at them, thanks!

17:45 akhudek: do LazySeq's have the same complexity garauntees as lists?

17:45 nDuff: piranha: ...I take it you're only ever inserting at the 2nd position, as in your example?

17:45 piranha: yes

17:45 nDuff: piranha: then why not store the item in the 1st position somewhere completely different?

17:45 piranha: that frees you to use a separate, efficient-head-insertion object for position 1

17:46 piranha: nDuff: I'm thinking exactly about that right now :-)

17:46 well, I'm thinking more along the lines that I could put nil there and just replace it in future...

17:46 if I need that

17:46 nDuff: piranha: What's the point of the head item anyhow?

17:46 dnolen: akhudek: some small things are different, you can call count on lists efficiently for example.

17:47 nDuff: (err, the separate, before-the-insertion-point head item)

17:47 ibdknox: dnolen: as of this commit (https://github.com/clojure/clojurescript/commit/aea65a69384b05b0b79b94fdd9daee936ab68d5e) I don't get any useful return value when defining functions in cljs - is there some trick I'm missing?

17:47 dnolen: I just get back nil now

17:47 piranha: nDuff: hm, well, I'm generating data for clj-pdf, and format is [:element {:styles :here} items items items]

17:47 and I have to update styles after having some element

17:48 nDuff: piranha: ...so that's not an insert at all, then. You can update an indexed item in a vector quite efficiently.

17:48 piranha: nDuff: right, I just didn't have style there at all (it's optional)

17:48 dnolen: ibdknox: yeah sorry about that. that commit is going to get reverted.

17:48 akhudek: dnolen: first, next, and conj should all be O(1) though, is that correct? Sometimes I wish there were a clojure complexity cheat sheet!

17:48 piranha: after reading responses I decided that I'll just put empty map everywhere :))

17:48 dnolen: akhudek: someone made one I think

17:48 nDuff: piranha: *nod*; that's what I'd do too.

17:49 ibdknox: dnolen: ah, okidoke :)

17:49 piranha: thanks!

17:49 ibdknox: dnolen: exciting things coming next week ;)

17:49 amalloy: akhudek: there's no meaningful answer to that for first/next on a lazyseq

17:49 dnolen: ibdknox: there's been some changes to the analyzer that broke the compiler, will get the fix in by Friday and ping stuart for a release.

17:49 amalloy: &(time (first (lazy-seq [1 2 3])))

17:49 lazybot: ⇒ "Elapsed time: 4.749026 msecs" 1

17:50 amalloy: &(time (first (lazy-seq (Thread/sleep 1000) [1 2 3])))

17:50 lazybot: ⇒ "Elapsed time: 1024.083699 msecs" 1

17:50 ibdknox: dnolen: great thanks! In fun news, Light Table is now *entirely* cljs :)

17:50 dnolen: ibdknox: whoa really? Like Node.js on the backend?

17:51 ibdknox: dnolen: yessir

17:51 dnolen: ibdknox: craziness

17:51 akhudek: amalloy: of course, that makes sense as the implementation could be anything. I suppose I'm more interested in what happens with seqs produced by map

17:52 ibdknox: dnolen: this next update is probably the biggest one we'll ever do. From here on out things can be much more incremental. I completely rewrote it on top of node embedded in chromium

17:52 dnolen: ibdknox: wow

17:52 amalloy: akhudek: same response applies. (map #(do (Thread/sleep 1000) %) coll) is slow, other functions might be fast

17:52 ibdknox: dnolen: it looks totally different now too and should be much more useful to everyone :)

17:53 akhudek: hm, ok, thanks.

17:56 goracio: defsocket anyone :) ?

17:58 dnolen: akhudek: conj is O(1) for lazy seqs since you don't have to examine the lazy seq

17:58 ibdknox: exciting!

17:59 ivan: ibdknox: can you just run the whole thing inside chrome with no node, using web file APIs?

18:00 amalloy: &(time (conj (map #(do (Thread/sleep 1000) %) (range 5)) 1))

18:00 lazybot: ⇒ "Elapsed time: 5025.124192 msecs" (1 0 1 2 3 4)

18:00 ibdknox: ivan: no, though the layer that interacts with node is small enough for us to replace if we want it to be hostable in the future

18:00 ivan: I see

18:00 amalloy: dnolen: for no particular reason that i can see, conj on lazy-seq calls .seq()

18:00 ibdknox: ivan: gotta get it useful first :)

18:01 it's to the point now where I do all my work in it, I don't really open vim unless I manage to hork the environment doing something stupid :)

18:02 dnolen: amalloy: yeah we avoid that in CLJS if we have an ISeq

18:03 ibdknox: so building with Chromium has been positive?

18:04 ibdknox: after a lot of stumbling around I found a project that is carrying the work forward by Intel, oddly enough. The transition to this setup has been hugely beneficial.

18:04 Raynes: ibdknox: Oh man, I'm excited.

18:04 dnolen: ibdknox: what project?

18:04 ibdknox: it'll be a real app on all the platforms, it allowed me to organize the internals much more intelligently, and removed the JVM dependency

18:05 dnolen: https://github.com/rogerwang/node-webkit

18:05 Raynes: new branding, the t-shirt designs, a new website, and a completely new LT :)

18:05 dnolen: ibdknox: so a JS API for plugins?


18:06 ibdknox: dnolen: I need to wrap the CLJS stuff, but yep

18:06 dnolen: with full access to node too

18:07 dnolen: I also made some really neat discoveries on how to make an infinitely customizable runtime-self-modifiable system in a reasonable way

18:07 TimMc: infinitely customizable in a reasonable way = controlled monkey patching, or what?

18:08 goracio: ibdknox: so when update will be available ?

18:08 ibdknox: next week

18:08 mpan: oh nice

18:09 ibdknox: TimMc: it draws from the component-entity-system model of game development

18:09 TimMc: functionality is contained in behaviors that are given to objects

18:09 dnolen: ibdknox: that's cool, look forward to a technical post about that.

18:09 TimMc: I don't know about that, so I'll wait for the blog post. :-P

18:10 dnolen: ibdknox: I suspect there's a lot of stuff to learn from LT about building UIs w/ a FP lang

18:10 ibdknox: and I'm assuming a fairly simple way to build extensions with CLJS if that's desired?

18:10 ibdknox: dnolen: potentially - there's still a lot for me to learn

18:11 dnolen: yeah it's trivial to add things to LT

18:11 dnolen: sweet!

18:12 ibdknox: learned a lot about the limits of things like jquery too lol

18:12 I had to ditch it

18:12 mpan: what did you use instead?

18:12 ibdknox: it was leaking unbelievable amounts of memory

18:12 dnolen: ibdknox: heh

18:13 ibdknox: I only have to support chromium right now, so I wrote a little jquery replacement (turns out I've been a very primitive jquery user, so this amounted to around 100 lines of cljs)

18:13 brehaut: ibdknox: one of my friends works on jscore; he has not so complementary things to say about jquery's memory usage :P

18:13 ibdknox: brehaut: I shit you not, in 1.5 min I could get it to leak 35mb

18:13 it just wasn't meant to do what I was doing with it

18:13 brehaut: i am entirely unsurprised

18:14 ibdknox: the problem is that it caches things rather unintelligently

18:14 so while nodes were getting cleaned up, if an event was bound anywhere on a parent *all* children ended up cached

18:14 unless you use jquery to remove them, they last forever

18:15 I looked at a heap to find out after 20 minutes I had 200k nodes in memory :p

18:15 dnolen: ibdknox: oof, via event delegation right?

18:15 ibdknox: I wasn't even doing delegation :( It was normal old binding

18:16 dnolen: ibdknox: hmm interesting. in anycase, nothing like getting rid of massive dependency w/ a hundred lines of code you actually understand.

18:17 ibdknox: yeah, I wasted a day trying to figure out wtf was going on inside jquery

18:17 that code is a mess

18:17 brehaut: haha

18:17 thats the understatement of the day

18:17 im slightly horrified at the amount of code that exists in jquery to support a terrible flat namespace

18:18 and then try to fix the stupid that that brings

18:18 ibdknox: I went from unbounded memory growth to a constant 7-15mb of total memory usage

18:18 brehaut: nice!

18:19 ibdknox: dnolen: at the conj I'd be curious to hear what it would take to make the CLJS compiler work completely on node

18:22 for kicks and giggles, here's the entirety of the dom lib I'm using: https://www.refheap.com/paste/6297

18:22 but that's all cheating, since I have the latest chromium only :)

18:23 dnolen: ibdknox: a medium. need a CLJS LineNumberingPushbackReader, a macroexpander. Then some perf issues which may be surmountable w/ some fast path code / better datastructure - multimethod performance, PHM performance

18:23 a medium project I mean.

18:24 oh and symbols that support metadata

18:25 Bronsa: dnolen: https://github.com/Bronsa/blind/blob/master/src/blind/reader.clj#L11-96

18:25 ibdknox: the symbols thing you could cheat by doing some sort of lookup

18:26 oo, look at athat

18:26 lol

18:26 dnolen: Bronsa: ah right, yeah I saw that. Should port that to CLJS :)

18:26 Bronsa: should just be a matter of s/unsynchronized-mutable/mutable

18:26 ibdknox: dropping the java dep would be huge for me

18:27 Bronsa: oh, and replacing string method calls

18:27 dnolen: could really use Feature Expressions

18:28 * hiredman goes to see if anything has changed on the wiki

18:31 ibdknox: hiredman: wiki?

18:31 spligak: I have a handful of functions that all take the same first argument. Looking to provide a helper function to act as a context which would provide the initial argument automatically.

18:31 hiredman: ibdknox: dev.clojure.org/display/design/Feature+Expressions

18:31 spligak: Any particular construct I should look at?

18:32 Digging into macros a bit, but I feel this may be a solved problem.

18:32 hiredman: dnolen: idea what the path from the wiki to jira to master for feature expressions is?

18:33 any

18:33 simonadameit: hi

18:34 dnolen: hiredman: continuing to bug Clojure/core? :) Stuart Halloway seems interested so that's a good sign. Perhaps collectively push to get it into 1.6.0

18:34 simonadameit: i have trouble understanding the state of clojure.contrib

18:34 how do i use something from contrib?

18:34 hiredman: ~where did contrib go?

18:34 clojurebot: well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

18:35 simonadameit: hiredman: thanks

18:36 dnolen: hiredman: if anything Clojure/core should be very interested in it as their building a lot of CLJS projects these days - sharing code between Clojure / CLJS is ridiculous

18:38 hiredman: you mean "relevance, who has a бизнес relationship (employee, partner, consulting) with a large portion of clojure/core is building a lot of cljs projects these days" ?

18:38 dnolen: hiredman: right

18:41 casperc: Is there any way to find out if a record implements a given method?

18:45 nDuff: casperc: see satisfies?

18:45 (for the protocol the method is part of)

18:46 dnolen: be warned that satisfies? is insanely slow on types that don't acutally satisfy the protocol.

18:46 in Clojure, not CLJS

18:46 sorry I mean instances of types

18:47 casperc: ah thanks, that might be it

18:47 nDuff: casperc: What's the use case? Might make more sense to provide a default implementation for Object that returns nil or such.

18:48 ibdknox: what would people be most interested in hearing about for my talk at the Conj?

18:48 * nDuff tries to remember -- think there's a more graceful method to do a default than an Object implementation

18:49 dnolen: nDuff: an Object implementation is the way to provide a default.

18:49 casperc: I just want to avoid an exception when calling a method which might not be implemented, but come to think of it I might want to split it up into more protocols to avoid this problem

18:49 dnolen: casperc: good idea

18:50 simonadameit: is there a way to reevaluate the classpath in a running lein repl?

18:50 i added a new dependency and dont want to close my repl

18:50 dnolen: ibdknox: I'm curious about the CLJS architecture, but it might be good to talk about how compelling it would be to have a self hosted CLJS too.

18:50 technomancy: simonadameit: you can do it if you have pomegranate loaded, but it's not well-supported

18:51 dnolen: ibdknox: for me self-hosting isn't about running complete Clojure environment in the browser, rather a way to get Clojure running self-hosted in environments where JVM is just too big / heavy

18:52 magius_pendragon: hey everyone, I've just recently started playing with clojure. I read through the tutorial and have been working through tutorials for jmonkeyengine. On the latest one though, I'm getting a class not found error on the namespace. The first line of the file is the ns macro, with the name of the namespace... the file is named after the last bit, and the namespace appears in my project.clj file. Any ideas what I'm missing?

18:52 ibdknox: dnolen: yeah I don't care about eval in this case

18:52 lynaghk: ibdknox: I'd be interested in hearing about architectural patterns you've used to scale up a cljs codebase

18:52 ibdknox: dnolen: I mean that would be nice, but whatever

18:52 dnolen: lynaghk: +1

18:53 ibdknox: dnolen: but the idea that I could compile my cljs from this node process means I wouldn't need crazy interprocess communication just to modify the thing

18:53 technomancy: magius_pendragon: namespaces usually don't match artifact names from project.clj

18:53 ibdknox: lynaghk: interestingly I think I've created a cljs app platform by accident :)

18:54 magius_pendragon: technomancy: Erm, maybe I didn't describe it right? The namespace matches the :main directive in the project file

18:55 lynaghk: ibdknox: yeah, I've done that two or three times myself =P

18:55 magius_pendragon: technomancy: I've been using the same project for various tutorials, each of which has it's own main. I've just been swapping out which one I passed to :main. It worked for the first 2, but the third one's messing up.

18:55 technomancy: magius_pendragon: just ignore :main for now while you try to get it working in the repl

18:55 hiredman: magius_pendragon: dashes or underscores in the namespace name?

18:56 magius_pendragon: hiredman: dashes

18:56 hiredman: magius_pendragon: and dashes in the file name?

18:56 magius_pendragon: hiredman: yes

18:56 hiredman: ~filename

18:56 clojurebot: your filename should match your namespace declaration, but with - channged to _ e.g. (ns foo.bar-baz) => foo/bar_baz.clj

18:57 magius_pendragon: hiredman: that accidently matches :p

18:57 hiredman: ~accident

18:57 clojurebot: Excuse me?

18:58 technomancy: ~the ns macro

18:58 clojurebot: (def transpose (partial apply map vector))

18:58 technomancy: boo

18:58 magius_pendragon: probably worth reading this too: http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

18:58 simonadameit: technomancy: thanks

18:59 magius_pendragon: lol to clarify: When I started, I named the project hello_jme3 not thinking about the - vs _. The ns currently in question is hello-jme3.assets, and in src/hello_jme3 there's a file called assets.clj

18:59 and I'm getting a class not found on hello-jme3.assets

19:01 hiredman: magius_pendragon: well there you go

19:01 magius_pendragon: hiredman: ?

19:01 hiredman: hello_jme3.assets will be the class name (asusming you are gen-classing)

19:02 magius_pendragon: ... it's worked for all the other ones? and didn't the bot just say to replace - with _ in filenames?

19:03 hiredman: magius_pendragon: hard is really hard to say without more info (a pastebin of your code)

19:03 magius_pendragon: yeah, was just about to do that

19:04 hiredman: magius_pendragon: you don't get a class with the name of your namespace unless you ask for one

19:05 give the class not found exception, it seems like you are expecting to have such a class somewhere

19:05 given

19:06 magius_pendragon: source file: http://paste.lisp.org/display/133470 project.clj: http://paste.lisp.org/display/133471

19:07 hiredman: should be -main not main-

19:07 wei_: what's the best way to get a timestamp in clojurescript? new Date().getTime()?

19:07 hiredman: can you pastebin the exact exception you are getting?

19:07 mpan: What's a strategy for writing something that would ordinarily be recursive (not necessarily tail position, could be multiple sub-calls) but would exceed allowable stack depth?

19:08 hiredman: my guess is it isn't actually about the class being missing, but about the class not having a main method

19:08 magius_pendragon: hiredman: that fixed that issue, and threw another one.

19:09 so yeah, pay more attention to that next time

19:09 wei_: to answer my above question, (.getTime (js/Date.)) seems to work.

19:09 magius_pendragon: mpan: can always make it tail recursive. Don't know if that's standard though.

19:09 hiredman: you really should also always include (:gen-class) in the ns form for the :main namespace if you are launching via java

19:10 mpan: magius_pendragon: short of playing a human compiler?

19:10 magius_pendragon: hiredman: umm... I'm launching via lein run. Is that launching via java?

19:10 hiredman: magius_pendragon: no, so no reason there

19:10 magius_pendragon: mpan: I just started learning yesterday ;) was just the first thing that came to mind. Will shut now :)

19:10 lynaghk: Is it possible to have ring/compojure reject POSTs larger than a certain size?

19:11 mpan: magius_pendragon: your suggestion is a good on (in the sense of effectiveness) but not one I would enjoy (in the sense of human burden)

19:11 good one*

19:11 magius_pendragon: mpan: yeah, figured as much. It's a pain

19:11 hiredman: mpan: it sort of depends what you are doing, if it is tree shaped you can turn it in to a lazy seq and then walk the lazy seq

19:11 mpan: uh, ok concrete example: depth first search of a graph

19:12 you could impose a tree-shape over it, I suppose

19:12 hiredman: oh yeah, definitely

19:12 magius_pendragon: mpan: acyclic?

19:12 mpan: suppose not

19:12 magius_pendragon: mpan: graph is only a tree if it's acyclic. But in either case, you can actually throw away the stack in DFS if you don't mind possibly infinite searches on cyclic graphs

19:13 mpan: uh, I meant to say, for the general graph, you just need to hit all the nodes so you could traverse an acyclic overlay

19:13 hiredman: what you do is make the search return a lazy seq

19:14 so if you are at node X with children a b c, the result of searching X is (concat (search a) (search b) (search c))

19:14 Apage43: if it's a tree, and you're going depth first tree-seq already has you covered

19:14 mpan: hiredman: that feels like manual stack-keeping :/

19:15 magius_pendragon: mpan: hiredman's solution isn't, though I was about to propose manual stack :p

19:15 mpan: it isn't, but -- and I'm not sure how to explain -- it has that feel as if it was

19:15 hiredman: mpan: actually it is manual list monading

19:16 mpan: I guess the property of recursion that I like and would like to maintain is: it allows you to reason extremely locally and defer the rest

19:17 which the lazy seq way is, but then I'm not sure what about it I feel uncomfortable with

19:17 magius_pendragon: mpan: you could do CPS instead

19:17 if that feels more recursive to you

19:17 mpan: that would be the answer I'm scared of

19:17 magius_pendragon: lol

19:18 mpan: I only began to understand it the other day and I'm so uncomfortable around it

19:18 hiredman: I have a very naive datalog https://github.com/hiredman/datalog/blob/master/src/datalog/core.clj which does search like this, it is also how (in a more sophisticated incarnation) core.logic does searching

19:19 mpan: not sure search was quite the right example though

19:20 magius_pendragon: search is a fine example if it's what you're working on...

19:20 less good if it isn't

19:20 mpan: no I mean in the sense of

19:20 maybe I said the wrong example

19:20 there's a certain property of problems I'm trying to capture like

19:20 you don't know now where you need to go later

19:21 maybe somewhere midway, you change to one of some number of strategies, depending on what you see there

19:21 hiredman: sure

19:21 mpan: or is that a good candidate for transforming into a tail-recursive "iteration" with explicit state passing?

19:22 magius_pendragon: mpan: depends on the strategies

19:22 hiredman: sounds a lot like core.logic

19:22 mpan: looking that up at the moment

19:23 hiredman: (or datalog)

19:23 I don't mean it sounds like a problem you would solve with core.logic, it sounds like the implementation of core.logic

19:23 magius_pendragon: mpan: if your strategy is really simple (like dfs) manual state-passing or manual tail-call via cps is not terrible. hiredman's solution works well either way, since it just generates the DFS traversal, and then you iterate over that and pick out whatever you need.

19:24 hiredman: http://www.clojure.net/2012/03/26/Messin-with-core.logic/ might be a good read

19:24 magius_pendragon: hiredman: though, come to think of it, lazy list approach might break down in the case of infinite loops, since you'd never get to the rest of the list...

19:25 though, that's more of a problem with DFS than it is with the lazy list approach

19:25 hiredman: "Combining these three components in the proper way you get an engine that searches a space shaped like a tree."

19:25 mpan: uh, maybe an example of the sort of problem I'm asking about is

19:25 imagine you wanted to find an element of pascal's triangle but memoization didn't exist

19:25 hiredman: magius_pendragon: there are different ways to deal with that

19:25 magius_pendragon: hiredman: yeah, such as don't use DFS :P

19:26 hiredman: mpan: I seem to recall there just being a nice formula you can use

19:26 forget searching anything

19:26 magius_pendragon: mpan: yeah, pascals triangle is just the binomial coefficient formulae

19:26 mpan: I'm trying to come up with a small example and admittedly it is contrived

19:26 so we would need to pretend all the reasonably efficient shortcuts didn't exist

19:27 I'm sorry. I don't know a better example

19:27 like the property I'm trying to capture is: the call-graph branches, and it does so potentially depending on what it sees currently

19:28 magius_pendragon: ooh static analysis

19:28 are you trying to build the call graph dynamically, or do you already ahve it?

19:28 hiredman: mpan: a branch is just an (if ...), you can put them whereever you like

19:29 magius_pendragon: oh wow, totally reading the wrong way into that

19:29 oops

19:29 mpan: sorry, I meant to say: the program is recursive in such a way that, if you examined its call graph, it branches profusely and makes local decisions

19:30 magius_pendragon: mpan: actually reminds me more of A* at the moment than anything else

19:30 mpan: like, the function has some number of cases, most of which are compound expressions of multiple recursive calls

19:30 magius_pendragon: hm

19:30 mpan: magius_pendragon: yea, I think that's an example

19:30 magius_pendragon: not anymore

19:31 mpan: A* uses a heuristic to get around compond expressions of recursive calls :p

19:31 mpan: hiredman: what I meant to say about the branching is just that, prior to examining a node, you don't know which set of recursive calls you need

19:32 hiredman: mpan: sure, no problem

19:32 you search function does case analysis on each node and can do whatever

19:32 your

19:33 magius_pendragon: hiredman: if he's not doing search, that just became a lot trickier to do

19:33 mpan: imperatively, there would be some per-node accumulation

19:33 hiredman: magius_pendragon: not really, either way you traverse nodes

19:34 mpan: so you don't know what "search b" should do until you're fully done with "search a", and in that sense perhaps it isn't really search

19:34 and "search b" in the imperative version has the results/intermediates of "search a"

19:34 magius_pendragon: hiredman: how's mutual recursion handled in clojure? or isn't it?

19:34 hiredman: mpan: right, so that is impossible to do lazily then, but not significantly different

19:35 magius_pendragon: depends what you want

19:35 mpan: magius_pendragon: the tail position case you can use trampolines

19:35 magius_pendragon: hiredman: well, I was just thinking mpan's case started sounding like mutual recursion

19:35 hiredman: it is

19:36 magius_pendragon: cuz i've run into that sort of setup doing an interpreter

19:36 hiredman: and my datalog impl I pasted does that too

19:36 mpan: that's a really interesting way to think about it

19:36 magius_pendragon: mpan: which?

19:36 mpan: yea, I think it definitely can be re-expressed as mutual recursion

19:37 or, well, extending mutual recursion to multiple calls

19:37 magius_pendragon: mpan: you're the one whos aid search a needed search b :p

19:37 hiredman: (let [ar (search a) br (search b ar) cr (search c ar br)] (concat ar br cr))

19:37 mpan: I fear I'm misusing terminology again :(

19:38 magius_pendragon: mpan: well, I think I follow you, so if you're misuing terms we're both lost

19:38 mpan: wow, some day a future employer is going to run across these logs, and I am going to be so embarrassed

19:40 I'm trying to construct a small-enough example

19:42 https://www.refheap.com/paste/6302

19:42 I think that's a small example of the sort of program I'm wondering about

19:43 suppose the call stack would overflow evaluating it like that

19:43 magius_pendragon: mpan: well, that example's broken

19:43 since (f x) will call (f x) if (q? x)

19:43 and infinitely recurse

19:44 on the same element

19:44 mpan: sorry I broke it in multiple places

19:44 https://www.refheap.com/paste/6303 fixed, I hope

19:48 the things I wanted to make the example have were: multiple control paths depending on state and multiple recursive calls in a given path

19:49 and in some sense, x is the (potentially arbitrary) accumulator of info about what has been seen so far

19:50 but also x contains the (potentially arbitrary) info about what's left to "work" with, for whatever "work" something of this form might need to do

19:56 dnolen: mpan: as hiredman said, does sounds a bit like a logic programming framework - something prolog / datalog like seems well suited for this kind approach to solving problems.

19:57 mpan: Those are quite new to me. I will look into them.

19:58 Thank you guys so much for bearing with me while I figured out the properties of what I was trying to express! Thank you all so much for your help!

19:59 magius_pendragon: I'm out, thanks hiredman

20:05 tomoj: consider a macro which accepts a fn body. is it possible to correctly resolve all symbols in the body with respect to the namespace in which the macro is called?

20:05 without macroexpand-all and a special form walker

20:06 hyPiRion: ,`(~'+ 1 2)

20:07 clojurebot: (+ 1 2)

20:07 hyPiRion: Or do you want to inject a specific body?

20:07 Like, the macro takes in a body, and spits out a result.

20:10 tomoj: https://www.refheap.com/paste/beafe1fe33732526f5616f3f7

20:11 meredydd: Hey, could someone suggest why I'm getting "Attempting to call unbound fn" errors when I AOT compile my code

20:11 but it's OK if I start it pointing at the .clj on the command-line?

20:11 nDuff: meredydd: Have a reproducer?

20:12 meredydd: Sadly not yet, nduff

20:12 Wanted to check whether it was a known issue before I start bisecting away my entire damn codebase.

20:13 hyPiRion: tomoj: Humm

20:13 tomoj: I have a macro that defines a datomic db fn, automatically pulling in the current ns's requires/imports. but if you want to call a fn in the current ns, you have to fully qualify

20:13 hyPiRion: ,((let [bar :foo] (bound-fn [] bar)))

20:13 clojurebot: :foo

20:13 amalloy: you're probably attempting to call clojure functions from java without initializing the clojure runtime, meredydd

20:14 hyPiRion: Wait, that's not correct.

20:14 hiredman: tomoj: I have a macro impl of syntax quote that does something like that

20:14 tomoj: oh, sweet

20:14 for query as well?

20:14 er, dunno if you're using it for datomic

20:14 hiredman: https://github.com/hiredman/syntax-quote/blob/master/src/syntax_quote/core.clj

20:19 tomoj: seems like you have to gensym to avoid resolution?

20:19 which makes sense, not sure what I want is even possible

20:21 &'./foo

20:21 lazybot: ⇒ ./foo

20:24 hiredman: tomoj: you could do something more complicated in the same general shape

20:24 meredydd: amalloy, nope - that's got a call trace straight back from the .clj file specified by lein's :main parameter

20:25 hiredman: tomoj: e.g. if resolve doesn't return anything from the current ns, assume it is a local

20:25 tomoj: yeah, for example I think it would be nice to take that and make it not resolve variables in datomic queries

20:25 meredydd: I am, however, belatedly realising that 'lein clean; lein run' might be a good first step. It's taking a while.

20:26 hiredman: or something more syntax aware that knows where rvalues appear

20:27 which quickly moves in to static analysis

20:27 tomoj: yeah :(

20:32 meredydd: Oh, interesting.

20:32 OK, new problem.

20:33 I forward-refer variables from another namespace

20:33 hiredman: don't do that

20:34 meredydd: (ns my-namespace) ... (ns other-namespace) (def some-var) (ns back-to-my-ns) (refer 'other-namespace : only 'some-var)

20:34 All right, what's the Approved Way To Do It?

20:34 amalloy: define namespaces that aren't circular

20:34 hiredman: don't do that

20:35 meredydd: Helpful, hiredman.

20:35 amalloy, what's the recommended pattern when you want a circular call graph?

20:36 Do I need to have static start-up code throw fn pointers into the ns? Cause that just feels nasty.

20:37 amalloy: you can either put them in the same namespace, with a declare or a letfn, or you can add some layer of indirection

20:37 eg to have a->b->a, you can add an extra "what to call" arg to b, and have a pass itself

20:37 hiredman: you can have any shape call graph you want, but namespaces are a tree

20:38 meredydd: Ick.

20:40 tomoj: I guess it would be cool if there were an analogue to ::foo for symbols

20:40 meredydd: tomoj, isn't that what ` does?

20:40 tomoj: not really

20:41 I don't want it quoted, just resolved

20:42 amalloy: tomoj: i think ::foo already causes enough problems, doesn't it? by coupling the reading of forms with their evaluation

20:43 hiredman: amalloy: huh?

20:43 tomoj: yeah I can see that

20:43 hiredman: tomoj: what is different about how :: works for keywords and ` works for symbols?

20:44 amalloy: hiredman: you can't read the string ::foo into a keyword reliably (ie, always get the same result). relatedly, ::foo/bar has caused actual problems for static analyzers that try to read your code; they can't read it without evaluating it

20:44 tomoj: &(map read-string ["::+" "`+"])

20:44 lazybot: ⇒ (:sandbox7657/+ (quote clojure.core/+))

20:45 hiredman: amalloy: that is not truee ::foo/bar can be read without evaluating ::foo/bar, but you need to know the read environment as setup by the ns form to resolve it properly

20:45 tomoj: &(read-string "::foo/bar")

20:45 lazybot: java.lang.RuntimeException: Invalid token: ::foo/bar

20:46 amalloy: hiredman: perhaps i was unclear. you're right that, to read x, you don't need to eval x. but you might need to eval y (the ns form) first

20:46 hiredman: tomoj: I see, current ns vs. resolve

20:46 tomoj: well, that's not important to me

20:46 just that there's a quote on the right

20:46 (there might as well be one on the left since for keywords it doesn't matter, but..)

20:46 amalloy: so you can't read all of a project's code without evaling at least some of it

20:47 tomoj: I don't actually think it's a good idea to add something to the reader to address my problem :)

20:47 hiredman: amalloy: unless you have have an analyzer for ns forms, and they only manipulate namespaces via ns forms

20:47 amalloy: sure. obviously there's nothing magic about eval, and you could write all the pieces of it you need to

20:48 leonardoborges: hey guys! :) anyone using quil?

20:48 amalloy: but every other readable clojure construct (i think? barring reader tags anyway) can be read from a string without knowing anything else about the program

20:48 hiredman: that is part of the reason ns exists, and why it should be used in preference to putting in-ns, require, use, etc where ever

20:49 ns is forms are easier to deal with statically without walking over all the code and evaluating it

20:49 leonardoborges: I got a handler in :mouse-clicked that calls (no-loop) if an atom called 'running' is true. If it's false, it tries to call (start-loop). Problem is, once (no-loop) is called, the mouse handler never gets triggered again.

20:49 hiredman: a nice declarative style

20:52 amalloy: actually didn't reader tags get a default reader recently?

20:53 tomoj: yep :)

20:53 bbloom: amalloy: yeah http://dev.clojure.org/jira/browse/CLJ-927

20:59 meredydd: I'm still getting my head around the namespace-DAG thing. Could someone give me a hand by explaining how, for example, one would go about implementing an MVC-type application with an interactive view (eg Swing)?

20:59 The view needs to pull levers on the controller (eg on button-push), and the controller needs to pull levers on the view (eg new data to display)

21:00 (and by "would" I mean "should, idiomatically")

21:00 Apage43: Extract the levers

21:01 meredydd: And do what with them, Apage43 ?

21:02 Have an atom in, say, the view, that holds a map of levers for the controller?

21:02 Apage43: put them together in a third, unrelated place

21:03 you have your view, and your controller, and a third guy "app definition" that says, here's my view, here's my controller, let me pull out some stuff from each and stick 'em in the right places on the other

21:03 meredydd: right

21:03 Apage43: things being callbacks or something of the sort

21:03 meredydd: But what form should that "sticking them in" take?

21:03 Atoms? Mutating top-level values of vars?

21:03 Apage43: well for a thing that's displaying data, an atom isn't bad

21:04 meredydd: I feel like there's something I'm not getting here...

21:04 An atom to hold the function?

21:04 Apage43: the data.

21:04 meredydd: That's not the problem.

21:05 Apage43: you can ask atoms to call a fn when they change

21:05 meredydd: although actually, that could be sticky too

21:06 a) The view is going to want to perform actions that aren't entirely expressible by changing the value of an atom

21:06 b) How do you inject the atoms in the first place?

21:06 Even if using atoms is OK, the "app definition" still has to tell the controller "modify this atom" and the view "display this atom"

21:06 after they've loaded

21:07 which means modifying some state inside them, yes?

21:07 How do you represent *that* state (which isn't really state, except during start-up) neatly?

21:07 Apage43: you could pass the atom to the view and controller's "constructors"

21:07 meredydd: Yes, and what do those "constructors" do?

21:08 Apage43: I don't know

21:08 meredydd: Damn, because that's what I don't know either.

21:08 Apage43: I mean, they're your doohickeys.

21:08 meredydd: yes, yes

21:09 But fundamentally, they've just been given the atom they need to push new values to.

21:09 Where do they put it?

21:09 Ssay I'm the controller, and the app-initialiser has just called my constructor, with the atom I should update to call the view.

21:10 sorry. With the atom I should update in order to update the view.

21:10 What do I do with it? Do I change the top-level value of a var (ew)?

21:10 Do I have an atom to store the atom (ew)?

21:10 Apage43: well what is the thing your constructor is making

21:10 meredydd: This is the part I'm not getting.

21:10 Apage43: I mean, say it's a button

21:10 meredydd: Well, it's a "view".

21:11 Apage43: well you were talking about controllers just now

21:11 meredydd: Oh, sorry, yes.

21:11 Apage43: (fn make-button-thingy [counter-atom] (proxy [ButtonClass] [] (onClicked [] (swap! counter-atom inc))))

21:12 I don't remember swing

21:12 meredydd: eh, that's all right.

21:12 Apage43: so that's a pretend guy

21:12 meredydd: I get what you're saying.

21:14 Fundamentally, it sounds like what you're saying is "write all your code that might need to use another component inside a constructor function that's wired together by a third party"

21:14 Accurate summary? Or not getting it?

21:15 bbloom: meredydd: GUIs are an area where all the viable toolkits are fundamentally object oriented

21:15 Apage43: Yeah, I think so. More generally the idea is that the things that are actually "components" should really need to know about each other, at least, concretely, and that you build a system by composing them.

21:16 s/really need to/not really need to

21:16 I accidentally a word

21:16 bbloom: meredydd: you just kinda need to suck it up and deal with state, unless you've got time to invest into an open research problem of alternate GUI approachs

21:17 amalloy: bbloom: i don't think that's the question he's asking at all. also, functional reactive GUIs?

21:17 meredydd: Apage43, Yeah, I get that ideal

21:17 bbloom: amalloy: they are discussing where to put their mutable state... sadly, the answer is "everywhere"

21:18 meredydd: Apage43: and it's a nice ideal, but one that, as I understand it, doesn't play nice with (eg) MVC, or anything where components have a peer relationship

21:18 amalloy: no they're not. they're discussing how to get two things to talk to each other circularly

21:18 gilliepit: working through a partial args problem, looking for a sanity check on this: https://gist.github.com/3990998 -- I feel like I might be able to break this down into a macro, but is this at all the right approach?

21:18 * meredydd nods at amalloy

21:18 amalloy: they've sidetracked a little into deciding they need a hundred atoms, which i think is wrong, but it's not the central point

21:18 bbloom: heh

21:19 meredydd: amalloy, Oh please, save me from the "hundred atoms", because I really don't want that to be the answer.

21:20 Frozenlo`: How could I get only "json" from this?: (re-find #"\.(.+)$" "word.json") --> [".json" "json"]

21:20 meredydd: The atom thing was really a distraction, anyway. I'm actually having that problem with functions

21:21 Frozenlo`: I want to get the extansion, not the dot with it.

21:21 meredydd: Eg the email interface to this system needs to be called by the controller (when things happen that need email notifications) and call the controller (when new emails come in and require an action)

21:21 WuHoUnited: is there any god way in clojure to indicate that a parameter to a function MUST implement a protocol? Is the best option to use preconditions, or does the idea in general run counter to clojure

21:22 gfredericks: docstring for documentation

21:22 amalloy: meredydd: for one thing that's not really true; the model could be a function that returns a blocking lazy sequence of changes, and the controller blocks waiting for it

21:22 meredydd: Frozenlo`: (let [[_ extension] (re-matches #".*\.(.+)" "word.json")] extension) should do it

21:22 gfredericks: preconditions if you want checks

21:23 WuHoUnited: type hints aren't actually enforced right?

21:23 meredydd: amalloy, Fair enough, although this is an event-driven system so this will require some abuse of the events to turn them into "wake up a thread" events, and that would introduce a sequential bottleneck, and and and...

21:24 tomoj: event-driven seems pretty hopeless in clojure right now

21:24 Frozenlo`: meredydd: I find it weird... there's no way to make a regexp and select only a part of it?

21:25 meredydd: amalloy, I'm not above things like taking incoming events and putting them into a queue that will wake up a listener. If that will produce a good design, I'm interested.

21:25 (And I can see how that looks more functional on the other end - although it rapidly becomes imperative again when it spits an email-shaped event out the other side, but I can live with that.)

21:25 amalloy: i'm not really an expert in events or mvc, in clojure or any language

21:26 but for example you can (defn controller [state] (fn [model] ...)) (defn model [state] (fn [controller] ...))

21:26 meredydd: Frozenlo`, There is - these functions effectively return multiple values, and you can pick out the bits you want.

21:28 amalloy, yep. That's the approach I was trying to summarise when I said "write all your code that might need to use another component inside a constructor function that's wired together by a third party"

21:30 And it looks like that might be the way to go. Still feels like a lot of effort, but might be livable with.

21:47 bbloom: it's been a while since i wrote some ruby and ran into a damn-near-un-debuggable usage of method_missing or const_missing

21:48 now i'm reading through some weird javascript that uses getters and setters with the get and set keywords

21:48 holy hell is it impossible to debug this thing!

21:48 functions that look like mutable fields! i want to cry

22:00 gfredericks: bbloom: oh I was so disturbed when I heard those were added

22:00 clojurescript came just in time

22:07 mattmoss: I guess this isn't as bad as I thought, but... https://gist.github.com/3991188

22:07 Wondering if there is a more succinct way to express that.

22:12 tomoj: &(keep (fn [[a b]] (if (even? b) a)) (map vector [1 2 3] [4 5 6]))

22:12 lazybot: ⇒ (1 3)

22:12 tomoj: it's too bad keep doesn't have variable arity

22:13 then it could be (keep #(if (even? %2) %1) [1 2 3] [4 5 6])

22:13 amalloy: unless one of the elements of a is nil :P

22:14 anyway, another solution: (for [[a b] (map list as bs) :when b] a)

22:15 tomoj: oya

22:16 mattmoss: Well, in my case, a will never have nil, but good concern in general.

22:18 &(for [[a b] (map list '(1 2 3) '(:a :b :c)) :when (even? a)] b)

22:18 lazybot: ⇒ (:b)

22:25 mattmoss: &(map #(when %1 %2) (map even? (range 5)) (:a :b :c :d :e))

22:25 lazybot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a

22:25 mattmoss: &(map #(when %1 %2) (map even? (range 5)) '(:a :b :c :d :e))

22:25 lazybot: ⇒ (:a nil :c nil :e)

22:26 mattmoss: &(keep #(when %1 %2) (map even? (range 5)) '(:a :b :c :d :e))

22:26 lazybot: clojure.lang.ArityException: Wrong number of args (3) passed to: core$keep

22:26 mattmoss: oh, ah, variable arity thing

Logging service provided by n01se.net