#clojure log - Dec 07 2010

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

0:13 coldhead: definitely a place for both, cky, but very little room for "here is 10000 lines of code i wrote all by myself, please make it better"

0:14 not that i'm bitter :)

4:04 kjeldahl: I want to like "cake", but there's always some issue about it. I've cloned it and symlinked bin/cake, and it makes a fuzz about missing classlojure . Any clues?

4:18 hiredman: kjeldahl: no reason you have to like or use cake

4:18 kjeldahl: hiredman: Well, it's a lot faster.

4:20 And if a thing is supposed to work, I like to get it working before deciding. But you're right, if lein works and cake doesn't, it's a simple choice.

4:21 Thing is, it's working great on one computer, but not the other. Just trying to piece the puzzle together.

4:34 He he, how's that for a dependency.. Cake works, but only after running "lein deps" in it's source directory. It should probably ship with the required dependencies to make it runnable...

4:39 Logged it as an issue: https://github.com/ninjudd/cake/issues/#issue/85

5:41 harishtella: (clojure + vim + unix) makes me feel like god

5:45 bobo_: required joke: then imageine how you would feel if you used emacs

5:56 bartj: how do I download a jar version from http://clojars.org/clj-json

5:57 I am unable to build it on my machine

5:58 kjeldahl: bartj: List it as a dependency in project.clj (assuming you use lein/cake)?

5:58 bartj: kjeldahl, we have not yet migrated to lein/cake, etc

5:59 kjeldahl: bartj: http://clojars.org/repo/clj-json/clj-json/0.3.1/clj-json-0.3.1.jar

6:04 bartj: kjeldahl, thanks! how on earth did you get that jar?

6:04 kjeldahl: On the front page of clojars.org, select "browse the repository". You're welcome!

6:12 bartj: has anybody built clj-json and used it before?

6:16 LauJensen: kjeldahl: Cake is fantastic and you get great support in #cake.clj from among other ninjudd who has written the majority of the code in it

6:29 Lajla: bartj, are you Dutch too?

6:31 AWizzArd: Any Swing expert here? JTables...

6:33 kjeldahl: LauJensen: Yeah, I figured it must have something since the pros use it. Installing from git however, does not work "out of the box". It needs more stuff, which it does not fetch on it's own.

6:34 LauJensen: kjeldahl: You're supposed to install via gems, to get the latest stable

6:34 bartj: Lajla, no

6:34 kjeldahl: LauJensen: Not according to the docs. git clone is supposed to work as well. But the docs may be wrong.

6:35 LauJensen: kjeldahl: Maybe Im the one who needs an update. Ive used it both in nix and windows via the gem installer/upgrader and it has always worked

6:35 bartj: I remember Lau recommending me to use clj-json

6:35 LauJensen: bartj: Was it good advice?

6:36 Hmm... Actually, it must have been because you were using a greater evil, because normally I would never recommend JSON

6:36 kjeldahl: LauJensen: Maybe ;-) For me, not having to mess with Ruby is another pluss (my background is with perl...).

6:36 LauJensen: kjeldahl: You dont have to mess with anything

6:36 kjeldahl: LauJensen: You're assuming ruby and rubygems is already installed on all systems?

6:36 LauJensen: For me it was "sudo pacman -S ruby && sudo gems install cake"

6:36 kjeldahl: no

6:37 kjeldahl: Doesn't pacman install ruby?

6:38 It's not that I'm not able to install ruby and rubygems (apt-get install in my case), but it seems a bit overkill for installing dependencies for a tool which is supposed to help me manage dependencies.. ;-)

6:38 bartj: LauJensen, I am yet to find out

6:38 the sad part is that clj-json just doesn't cleanly compile :(

6:41 I just want to read json strings lazily

6:41 perhaps, I am being too lazy

6:54 fliebel: morning

7:01 LauJensen: kjeldahl: pacman would install ruby yes, so you should use apt-get. Where lein uses bash, cake uses a little bit of Ruby. It makes sense to use the deployment tools already available for that language

7:02 * raek just realized that having "named anonymous functions" like (fn foo [] ...) can potentially make stacktraces more readable

7:03 raek: ,(fn descriptive-name [x y] (+ x y))

7:03 clojurebot: #<sandbox$eval462$descriptive_name__463 sandbox$eval462$descriptive_name__463@176343e>

7:04 * Lajla just gave raek an e-hug.

7:04 Lajla: Because your name reminds me of raep

7:06 kjeldahl: LauJensen: Yes, I get how it works (now at least). I still think it's wierd. I got the impression that cake could be installed any way suggested on the homepage, but since it isn't "self bootstrapping" that's not really true. Bash is also a dependency, ok, but still more widely available than ruby. Compared to leiningen, which "just works" in more cases...

7:07 LauJensen: kjeldahl: Not if you're on Windows. But anyway, state your case in #cake.clj or raise it as an issue on github please

7:07 raek: or Solaris :)

7:07 kjeldahl: LauJensen: Anyway, I contributed a ticket at least on github. I guess the easiest solution is to state that additional packages are needed if not installed by ruby gems or similar.

7:10 * raek gives Lajla an instance of org.apache.xmlrpc.server.RequestProcessorFactoryFactory.RequestSpecificProcessorFactoryFactory

7:11 raek: have fun.

7:12 Lajla: raek, that's what SHE said.

7:59 AWizzArd: Which pros/cons does definterface vs defprotocol offer?

8:06 cemerick: They both generate an interface, the latter is a protocol. :-P

8:08 fogus`away: definterface allows primitive args and rets

8:21 AWizzArd: Primitives are nice, good.

8:22 I have a function that generates and returns a proxy. How do I typehint instances of it?

8:26 Chousuke: AWizzArd: Typehint it as whatever interfaces the proxy implements.

8:28 AWizzArd: Chousuke: ah good, so I can simply use this 90-char type-hint :)

8:30 Chousuke: unfortunately it seems that a potentially random number is attached to the type name: my.projects.namespace.module.proxy$javax.swing.table.AbstractTableModel$TabelModelHelper$bb684924

8:34 bsteuber: AWizzArd: guess proxy internally uses sth. like gensym - but you shouldn't need the name

8:40 AWizzArd: bsteuber: do you have an idea how I can type-hint my proxies in a way that will be stable through restarts of a jvm?

8:41 When rhickey joins I will ask him if it could make sense to extend 'proxy' taking a type-designator T, so that hinting can be done via: ^T my-proxy

8:41 Chousuke: AWizzArd: You shouldn't typehint the proxy by its class; that's frafile.

8:42 fragile

8:42 AWizzArd: what you want to do is typehint the proxy as whatever its superclass is

8:42 so if you proxy FooClass, Typehint the proxy as FooClass

8:43 AWizzArd: Chousuke: that unfortunately does not work they way I did it. My proxy proxies an AbstractTableModel. That is a class, implementing TableModel. It does not offer a method to delete all rows from a table.

8:43 bsteuber: AWizzArd: yeah just typehint it as AbstractTableModel

8:43 AWizzArd: So I added a definterface that defines 3-4 methods that are useful. My proxy also implements that interface.

8:43 bsteuber: ah

8:43 Chousuke: then you can typehint it as that interface.

8:43 AWizzArd: When I now say: (.clearTable ^AbstractTableModel my-table-model-proxy) <-- it can't find the right thing.

8:44 Yes, I currently do this, and type-hint it as the interface. But in Java or with defrecords this would not be required.

8:44 I can type-hint instances as designated.

8:44 bsteuber: why do you need a type hint anyways?

8:44 Chousuke: neither java nor defrecord can redefine methods on the fly.

8:45 proxy works as it was designed, not having access to its classname for typehinting is a feature :)

8:45 AWizzArd: bsteuber: to remove the type-hint warning that Clojure generates for me. My question in general is the other way around: why not type-hint everything?

8:46 Chousuke: in Java the way would be to have class MyTableModel extends AbstractTableModel { ... }

8:46 And in MyTableModel I could simply define 3-4 helper methods.

8:46 Chousuke: AWizzArd: yes, and that's nowhere as dynamic as proxy is

8:46 +near :P

8:46 any changes require a recompile

8:47 basically you're asking proxy to do things it wasn't designed for

8:47 AWizzArd: Chousuke: can you give me an example of what you mean by 'dynamic'?

8:47 bsteuber: AWizzArd: change a method on the fly

8:47 Chousuke: AWizzArd: you can replace proxy methods with a new implementation at runtime, without having to touch existing code in any way.

8:47 AWizzArd: Chousuke: there is no other lightweight way in Clojure to do this, as defrecord and deftype and reify can only take interfaces, but AbstractTableModel is a class unfortunately.

8:47 fogus`: Someone is wrong on the Internet!

8:48 Chousuke: AWizzArd: Then you need to use gen-class

8:48 AWizzArd: bsteuber: would that not be possible with an anon class in Java too?

8:48 Chousuke: yes, though this is not very lightweight anymore. More chatty syntax.

8:48 Chousuke: then write a macro :P

8:49 bsteuber: AWizzArd: can you change a method of an existing anonymous class? I don't think so

8:49 AWizzArd: Ideal would be a defrecord that could also take classes, or even more ideal: not one single Java class implements any method on its own, but *always* from interfaces. Then defrecord would always work. :)

8:50 bsteuber: I currently don't see an application for that. But it may be very well much more chatty in Java to do this (via Bytecode generation *shrugs*).

8:50 Chousuke: I think defrecord allowing classes would break the data/behaviour separation.

8:50 AWizzArd: yes

8:50 Chousuke: so it's out of the question :)

8:50 AWizzArd: Yes

8:50 It makes sense the way it is.

8:51 Only that it not operates well with the VM Clojure is running in.

8:51 Chousuke: I don't see a problem

8:51 AWizzArd: Because Sun chose to add methods to classes that do not come from Interfaces.

8:51 Chousuke: Good java APIs are based on interfaces anyway

8:51 there are bad ones, but you just have to accept that.

8:51 AWizzArd: But many Java APIs are not good ;)

8:52 Chousuke: yeah, and in those cases, just use gen-class :P

8:52 AWizzArd: Although this does not in its current version allow me to add fields as in defrecords?

8:52 I can only have a :state which would be an atom or ref, which is way less performant when accessed.

8:53 Chousuke: it can also be a plain old mutable java object.

8:53 AWizzArd: Chousuke: does defclass allow multiple slots or only one :state slot? I am not sure what the current state of it is.

8:54 Chousuke: I've no idea, I've never actually used it :P

8:54 AWizzArd: Interesting it would be if defclass worked like defrecord in that aspect.

8:59 cemerick: AWizzArd: defrecord and deftype are not intended to be fully-featured interop constructs

9:00 AWizzArd: And this makes sense.

9:00 They are serving a great purpose.

9:00 It is just the design of the main VM Clojure is currently running on which can cause sometimes a bit pain, which would go away if defrecord/deftype actually allowed to extend a class.

9:01 cemerick: a better solution would be that *all* methods that any Java class defines in all cases would be an interface method.

9:01 cemerick: Right; well, that ship has sailed. :-)

9:02 AWizzArd: This would of course bring tons of one-method interfaces into the game, but this would reflect the design style that Rich found to be better, and which he now implemented in Clojure.

9:02 defrecords are just classes providing slots, with all methods coming from interfaces (protocolls). Sun however didn't.

9:03 So, when implementing ones own TableModel one has to chose: AbstractTableModel+proxy or TableModel+defrecord. The latter will require more work, as nothing would be implemented, as in the AbstractTableModel case.

9:06 cemerick: AWizzArd: why is the proxy route insufficient?

9:07 jcromartie: what's the best way to manage 3rd-party jars that can't be added to clojars for licensing reasons?

9:11 cemerick: jcromartie: ideally, have your own nexus or artifactory instance

9:11 jcromartie: I used http://maven.apache.org/plugins/maven-install-plugin/usage.html for a temp fix

9:11 but yeah

9:13 neotyk: Has anyone working version of slime-who-calls?

9:20 Raynes: fliebel: Seems to be fine.

9:21 fliebel: Raynes: Huh?

9:21 Raynes: fliebel: The blog.

9:21 fliebel: I just checked and it's still up.

9:22 fliebel: Raynes: It's a http://www.acidrayne.net/ right?

9:22 Safari can't find the server

9:22 Raynes: No.

9:22 http://blog.raynes.me

9:22 Lajla: Using a mac counts as admission to flaming homosexuality under US law.

9:22 fliebel: Raynes: Then update your github and twitter page ;)

9:26 Raynes: Wordpress, eh? Also, page_id=2 (a.k.a. About) is rather terse compared to the huge posts you write.

9:27 Raynes: What would you prefer I use over wordpress?

9:28 fliebel: Wordpress is great, but something in Clojure would be nice, I guess. :D And if you must use WP, I recommend at least turning on permalinks ;)

9:29 Raynes: I don't really have any inclination to roll a blog in Clojure that wouldn't be even 10% as impressive as a default wordpress blog.

9:29 bobo_: Raynes: steal Lausjensens blogstuff?

9:29 fliebel: Agreed.

9:30 Raynes: I'd rather not.

9:30 I actually don't mind wordpress.

9:30 pppaul: it's a blog, what's the big deal about what it runs under/

9:30 bobo_: i like the github stuff. because im lazy and it jsut worked

9:31 jcromartie: I cheated https://gist.github.com/731839

9:31 pppaul: unless you want to extend it...

9:31 Raynes: I'm in the process of writing a Clojure interface to wordpress and eventually various other engines and after that a desktop blogging client, so I have a reason to stay with Wordpress for now.

9:31 pppaul: sounds good

9:32 fliebel: Raynes: Wordpress is totally cool, but taking the time to configure and customize it does show of ;) You know how to do permalinks?

9:32 Raynes: No, because I never cared about permalinks. I'm very good at google.

9:33 fliebel: Raynes: You prefer ?p=48 over /some-nice-title/?

9:33 Raynes: It's shorter, more twitter-friendly.

9:34 fliebel: Raynes: You can get wp.me urls for every single page.

9:34 Raynes: I don't have to without permalinks.

9:37 fliebel: Raynes: Well, I like the fact that you do it as a consideration rather than just neglecting it. (You know you can set a custom permalink under the title field? so you can have /sexpbot/)

9:38 Raynes: Indeed.

9:40 AWizzArd: bsteuber and Chousuke: I just noticed that when my proxy proxies a class C and an interface I then for instances P of my proxy I can not ^C P or ^I P. So, type-hinting just won't work for such proxies it seems.

9:40 fliebel: Raynes: I just can't stand it thoug… hmmm, do you realize /48/ would be even shorter *and* more stylish?

9:41 jcromartie: fliebel: only ubergeeks and marketing people care about URLs

9:41 fliebel: jcromartie: Count me under geeks

9:41 jcromartie: fliebel: although Raynes' audience is ubergeeks

9:41 Raynes: fliebel: Well, nobody is forcing you to read it.

9:42 * fliebel gives up, stops talking off-topic stuff and gets back to work

9:42 Lajla: fliebel, now you have admitted your famling homosexuality.

9:42 Now what?

9:42 Admit it, you support Assange

9:42 in his crimes against the freedom of the US

9:44 fliebel: Lajla: Any interesting Clojure gotchas recently? ;)

9:44 Lajla: fliebel, you should know by now that I would never sell my soul to the darkside of lack of TCO.

9:46 fliebel: Lajla: Total Cost of Ownership?

9:47 Lajla: fliebel, tail call optimization

10:03 garytr25: hmm, wouldn't you rather know when tail call is happening explicitly?

10:05 lyonscf: Hey guys

10:06 edw: garytr25: No. As someone who comes from a Scheme background, Clojure's (understandable) lack of TCO is like dealing with someone you love believing in astrology.

10:07 garytr25: you should love them for who they are, not who you want them to be :-)

10:08 edw: Right, that's why I really like Clojure, but I'll like her a lot more when she quits smoking.

10:09 lyonscf: What's the best way to traverse a map?

10:09 Well, it's a map of maps

10:10 fliebel: Hm, what's that function called that is like map for nested sequences?

10:10 lyonscf: so I want to iterate over each element and take a couple of vals out of it and put it into a new list of maps

10:10 fliebel: lyonscf: A map is just like a seq of key-value paris when traversing.

10:10 edw: (map identity (sequence {:a 1 :b 2 :c 3}))

10:11 fliebel: zip?

10:14 Raynes: fliebel: clojure.walk/postwalk?

10:14 lyonscf: edw: could you perhaps break that down for me.

10:15 tonyl: &(map identity {:a 1 :b 2 :c 3})

10:15 ,(map identity {:a 1 :b 2 :c 3})

10:16 clojurebot: ([:a 1] [:b 2] [:c 3])

10:16 tonyl: $google sexpbot

10:16 fliebel: Raynes: Probably, but I thought it was in core.

10:16 Raynes: tonyl: sexpbot is down for a little bug fixing.

10:16 tonyl: Raynes: :( ok

10:22 Raynes: tonyl: I try to do this sort of thing late at night when everyone is asleep, but I actually slept through the night last night.

10:23 tonyl: no worries, I take my sleeping seriously as of lately

10:26 jcromartie: how do I create a Java vVector from a Clojure vector?

10:26 Vector

10:27 chouser: you're sure you need to?

10:27 jcromartie: I'm creating a JTree

10:27 and I figure the simplest route is the constructor that takes a vector of nodes

10:27 before I go making a proxy

10:28 chouser: Clojure vectors are java.util.RandomAccess, java.util.Collection...

10:29 but if you need to, ## (doto (java.util.Vector.) (.addAll [1 2 3 4]))

10:29 sexpbot: ⟹ #<Vector [1, 2, 3, 4]>

10:30 jcromartie: hm

10:30 looks like to-array will work, there's an array constructor

10:47 edw: When I `lein repl' I get "Warning: problem requiring hooks: java.lang.IllegalAccessError: extract-javac-tasks is not public (javac.clj:1)". On Ubuntu 10.04 w/ Sun's JDK. Any ideas?

11:34 Bahman: Hi all!

11:35 tonyl: hello Bahman

11:37 Bahman: Hi tonyl!

11:43 Raynes: &(+ 1 (- 2 (* 3 (/ 4.0 10))))

11:43 sexpbot: ⟹ 1.7999999999999998

11:43 Raynes: Yay!

11:43 * Raynes runs off to do more productive things.

11:43 fliebel: Raynes: What was that about?

11:43 tonyl: sexpbot is up

11:43 fliebel: Yay indeed!

11:44 garytr25: (+ 1 2 3)

11:44 clojurebot: *suffusion of yellow*

11:44 garytr25: &(+ 1 2 3)

11:44 sexpbot: ⟹ 6

11:44 garytr25: nice!

11:45 edw: What's that first character sexpbot emits? A right-pointing arrow? A double-lined right-pointing arrow?

11:46 garytr25: yea

11:46 (fn [] (+ 2 3 4))

11:46 &(fn [] (+ 2 3 4))

11:46 sexpbot: ⟹ #<sandbox6366$eval8383$fn__8384 sandbox6366$eval8383$fn__8384@8c0d5d>

11:47 garytr25: &((fn [] (+ 2 3 4)))

11:47 sexpbot: ⟹ 9

11:47 garytr25: neato

11:47 &(def x 5)

11:47 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

11:47 garytr25: haha ok

11:49 lucian: try let :)

11:52 garytr25: &(let [x 5] ((fn [y] (+ y 1)) x))

11:52 sexpbot: ⟹ 6

11:53 fliebel: Can anyone tell me how I can make a protocol extend a final java class? Or anything else for that matter. stuartsierra said it to be possible, but I can't find anything about "protocol inheritance"

11:53 http://groups.google.com/group/clojure/browse_thread/thread/0241042e15696cc9/256f6d4f55dd41a0#256f6d4f55dd41a0

11:57 kotarak: fliebel: (extend-type YouFinalClass YourProtocol (funA ...) (funB...))

11:58 fliebel: there is no "protocol inheritance" but you can mix in functionality with mapos

11:58 -o

11:58 tonyl: this might help http://clojure.org/Protocols

11:59 fliebel: kotarak: But it think extend makes my final class support my protocol, while I need my protocol to be based on the final class.

11:59 kotarak: fliebel: exactly. You can't extend final class with more functionality. Or any non-final class for that matter...

12:00 fliebel: you have to patch your clojure version and make Atom non-final. Just as Alyssa suggested.

12:01 fliebel: kotarak: Then I don't get the point of Stuarts's response. What does he want me to do?

12:01 kotarak: fliebel: he wants you to write a protocol. Extend it to atoms and your stuff. Then it can serve as a common API.

12:02 fliebel: I'm not looking to make atoms.fly, if that is what I can do with extend. I need to implement the Atom "interface" rather.

12:03 tonyl: you need a type for implementation

12:03 declare a type with the base protocol being the Atom interface and extend the methods

12:03 kotarak: fliebel: something like this: (defprotocol PAtom (swap! ...) (reset! ...)) and then do (ns your.namespace (:refer-clojure :exclude (swap! reset!)) (:use name.space.containing.protocol))

12:03 hiredman: I think that is a bad idea, better make new similar reference types

12:05 fliebel: Alright, so I can replace or supplement Atom, but not implement it.

12:06 kotarak: fliebel: you can do (extend-type clojure.lang.Atom PAtom (swap! [this f & args] (apply clojure.core/swap! this f args)) (reset! [this v] (clojure.core/reset! this v)))

12:07 fliebel: then also atoms support your API

12:10 fliebel: huh… so I can 'replace' the methods of Atom to do what I want? That feels so much like monkeypatching…

12:11 fogus`: fliebel: In what way? Atom is not changed.

12:11 chouser: no, you'd just be using your own functions instead

12:12 fliebel: chouser: So I'm like shadowing Atom?

12:13 chouser: fliebel: kotarak is showing you how to explicitly manipulate your namespace so that the names 'swap!' and 'reset!' refer to your own protocol functions instead of the clojure.core/functions

12:14 completely different functions in different namespaces

12:14 not quite shadowing because you have to explicitly exclude clojure.core's functions from being put in your namespace.

12:14 fliebel: chouser: Yea, that sounds better. Just make my own multimethod swap! that does either core swap or custom swap, depending on type.

12:15 chouser: right, that's what he was showing you, only with a protocol instead of multimethod

12:15 fliebel: oh, right :) hm, I'll reread

12:45 garytr25: &(let [[x y] '(5 6)] ((fn [z a] (+ z a 1)) x y))

12:45 sexpbot: ⟹ 12

12:48 amalloy: garytr25: ##((fn [[z a]] (+ z a 1)) '(5 6))) works too if you're just exploring destructuring

12:48 sexpbot: ⟹ 12

12:49 garytr25: nice

12:57 amalloy: and also, '(5 6) is somewhat un-idiomatic; i'd usually use [5 6]. but (let [[x y] [5 6]]) kinda looks less magical, so if you want to be awed go with the quote :)

13:24 garytr25: programs work best when they look the most magical

13:24 Licenser: now I've a hard decision: I have a idea for a program (web apploication) and am not sure if I should try to write it in erlang or clojure

13:26 amalloy: Licenser: it seems like, by asking this question in #clojure, you've predetermined what answer you'd like to get

13:26 Licenser: amalloy: yes that is why I am tricky and also asked in #erlang :P

13:27 now I can paralellize my decision making process

13:27 and since both erlang and clojure are good for paralell stuff I think it fits

13:27 amalloy: Licenser: see what #fortran thinks

13:27 garytr25: clojure doesn't do message passing stuff like erlang

13:28 Licenser: amalloy: good idea

13:28 garytr25: you might have to do more work to scale it up?

13:29 Licenser: garytr25: yes that is a + for erlang

13:30 raek: garytr25: don't forget to take a look at the goodies in java.util.concurrent

13:30 ehr, Licenser: I mean

13:30 garytr25: sorry

13:31 Licenser: raek: *nods* I know that clojure does very well with concurrency

13:31 my problem is I want to learn more aout both languages but am not sure which to choose here

13:32 raek: I'm preparing a mini-talk for the local clojure meeting about that stuff

13:32 Licenser: raek: web dev or concurrency?

13:33 raek: just want to make sure that people do not ignore the java stuff that clojure treats as "fully working, no extra wrappers required"

13:33 Licenser: concurrency. but my last one was about web dev

13:34 Licenser: raek: happen to have slides to look at? :P

13:34 hmm I could make a compromise and use both

13:35 making it even more complicated

13:35 raek: very very mini... so no slides

13:36 https://github.com/raek/lcug-guestbook

13:37 Licenser: kk

13:37 was just curiose

13:37 I get to cry since I can't use lein on my work PC fracking proxy's!

13:41 okay the guys in #fortran were the most convincing - time to learn fortran

13:44 * amalloy takes a bow

13:48 garytr25: i've heard you can write fortran in any language

13:52 bartj: I have a 10GB json file...any tips on how to go about reading it lazily?

13:53 fliebel: bartj: Write a json zipper? Hmm… Or strip the root element and read the sub elements.

13:53 hiredman: a single json object?

13:54 you can't read a single json object lazily

13:54 chouser: really?

13:54 hiredman: [ … 10 gigs … ]

13:55 the object goes from [ to ]

13:55 thats readinga clojure form lazily

13:55 Licenser: you could query the contens laziely

13:55 chouser: yeah, but that could be represented as a lazy seq

13:55 fliebel: hiredman: Make it a zipper, and you can only read [ and then go depth first and such...

13:55 hiredman: fliebel: but thats not structured data

13:56 cemerick: json array elements could be read lazily, but object (maps), not so much.

13:56 hiredman: making a zipper out of a sequence of characters makes very little sense

13:56 bartj: my first idea was to use (read-json...) but that returns a PersistentArrayMap which doesn't implement ISeq (I think)

13:56 cemerick: I guess you could do k/v pairs *shrug*

13:57 fliebel: cemerick: everytime do do z/down you only need to read up ot the next [ or { if I'm correct.

13:58 cemerick: fliebel: pairing zippers with IO seems like a disastrous idea…

13:58 bartj: jackson lists "streaming" as a feature, you could give it a try: http://jackson.codehaus.org/

13:59 joly: zipper would be on the JSON parse tree, which reads more characters from IO as needed?

13:59 fliebel: cemerick: Why? Do zippers need to be side-effect free? What about the xml zipper?

13:59 cemerick: holy crud, a 418-class JSON parser :-O

14:00 bartj: cemerick, it didn't cleanly build on the first try...so kind of looking for alternatives

14:00 cemerick: bartj: it's widely-used -- isn't it in central or some other repo?

14:01 hiredman: jackson does smile too

14:01 cemerick: fliebel: c.c.zip-filter.xml, you mean? It operates over a fully-realized XML data structure.

14:01 hiredman: clj-json is built on jackson

14:07 bartj: thank you all for the flurry of enthusiastic replies

14:07 I think I am going to jackson a shot once again

14:07 *give

14:07 chouser: c.c.lazy-xml lazily parses xml. It can be done.

14:08 I can't think why it couldn't be done for JSON similarly

14:10 fliebel: chouser: I agree :)

14:11 chouser: if you wanted the json objects and arrays to be represented by vanilla collections, that would be a problem

14:12 but something that implements java.util.Map and something else that implements java.util.RandomAccess to represent objects and array respectively could certainly consume the input stream lazily

14:12 fliebel: chouser: So what do you propose?

14:12 chouser: What about lazy seqs or zippers?

14:13 chouser: lazy-xml ignores the problem that you end up with the whole thing in memory if you read all the way to the end

14:13 if that's a problem you'd have to do something more clever there.

14:13 fliebel: chouser: Even if you doseq?

14:14 chouser: lazy-xml returns lazy externally immutable objects, like lazy-seq, that cache their values to allow random access

14:14 wrapping those in a zipper works just fine

14:15 and walking that zipper with zip-filter also works fine. :-)

14:15 fliebel: awesome

14:16 chouser: but I have no recommendation for JSON, just suggesting it should be possible

14:19 fliebel: I remember someone mentioning a 2-way parser language, with something called lenses, anyone knows?

14:20 ah http://www.seas.upenn.edu/~harmony/

14:23 Before you can say 'supercalifragilisticexpialidocious' and after I finish a dozen other projects, I'll come up with an awesome lazy bidirectional Clojure parser framework.

14:26 cemerick: my point before re: zippers and IO was that, esp. in a situation where you've got a large data source involved, you will inadvertently allocate and retain indeterminately.

14:27 i.e. z/left may cause you to hoover up a gig of data, and worse, not release your prior loc's contents

14:29 fliebel: cemerick: I'm not sure I get your point.

14:30 amalloy: fliebel: if you use a zipper to wrap some laziness around your IO, you'll have a hard time understanding/predicting what zipper operations will cause IO

14:30 fliebel: True, they might return instantly, or take a long time.

14:31 amalloy: fliebel: more importantly, zippers are complicated and i wouldn't be sure how much data they kept in memory

14:32 fliebel: But any lazy implementation of JSON is unpredictible in the amount of IO that is involved per item.

14:33 cemerick: fliebel: The point is that you don't have a choice as to what is retained by a zipper.

14:33 If you're really working with large datasets, that's a problem.

14:34 fliebel: right...

14:35 cemerick: I'm not saying that zippers over e.g. lazy-xml don't work, but I'd be nervous about using them in cases where the laziness is there for a "good" reason.

14:36 fliebel: So what you're saying is that it's fine for doing lazy stuff, but not fro being lazy for the sake of not having 10gb of ram :)

14:37 amalloy: fliebel: have you considered tracking down the sadist who wrote a 10GB json file?

14:39 cemerick: amalloy: these things happen…

14:39 brehaut: usually from big slow moving corporations who arent tech companies

14:40 * brehaut is not bitter. honest

14:44 cemerick: I'm not sure being a "tech company" helps any if you've got to move NN gigs of data from here to there.

14:45 brehaut: cemerick: sure. but non-tech companies can turn NN megs of data into NN gigs of data

14:45 cemerick: ah; yeah, that can happen :-)

14:45 brehaut: through liberal application of new buzzwords they dont understand :)

14:46 i learnt a lot about python's itertools and lazy evaluation working with that

14:58 rata_: hi all

14:58 has anybody used counted-sorted-sets to store maps?

14:58 chouser: do you know of a good comparison fn for storing maps in counted-sorted-sets?

14:59 chouser: depends on how you want it sorted, I suppose

15:02 rata_: chouser: I don't really want it sorted... I'm just concerned with fast nth, disj and conj

15:03 (nth is for rand-nth)

15:03 chouser: oh. hm... so like hash, but guaranteed unique. bleh.

15:06 rata_: mmm... do you mean using hash like (compare (hash m1) (hash m2))?

15:12 chouser: ^

15:14 dnolen: hmm man I really want real TCO. There isn't a good guide on how to convert mutually recursive tail fn calls into a lazy sequence is there?

15:14 hiredman: dnolen: trampoline is kind of nice

15:14 chouser: rata_: right, but hash isn't guaranteed unique

15:15 cky: dnolen: I'd say you should use SRFI 41, but, that's for Scheme only. :-P

15:15 hiredman: I also would love some TCO

15:15 dnolen: hiredman: yeah but it's too slow.

15:15 hiredman: infact, just this morning I said "all these jsrs and no tco"

15:16 dnolen: hiredman: I've been hacking away at this miniKanren impl, and it's pretty sweet. But it's incorrect, it has stack overflow errors on certain orderings because the Scheme impl assumes TCO.

15:16 hiredman: :/

15:16 cky: hiredman: http://blogs.sun.com/jrose/entry/tail_calls_in_the_vm

15:16 hiredman: I know

15:17 cky: hiredman: (This is all in the future tense, as far as I know.)

15:17 hiredman: by "all these jsrs" I was refering to the ones listed for java 7 and 8

15:17 cky: hiredman: Heh.

15:19 dnolen: for example is this safe? https://gist.github.com/732343

15:19 if so I think I can do what I want.

15:20 Chousuke: looks safe to me

15:20 dnolen: *sweeeeeeeeeeeet*

15:20 Chousuke: the functions always return before the recursion happens.

15:20 dnolen: god bless rhickey

15:29 chouser: does java have a foreach?

15:29 brehaut: chouser: something like it since 1.5 i think

15:30 cemerick: for (String s : someIterable<String>) { … }

15:30 chouser: cemerick: thank you!

15:34 cky: Java's for-each loops aren't as cool as for-each in real languages, though. For example, you can't iterate through multiple iterables simultaneously.

15:35 (Which is something I often find a use case for, and for which I've ended up having to write manual loops instead).

16:11 jaley: hi everyone. can macros be overloaded on arity too?

16:12 dakrone: jaley: yep

16:13 jaley: dakrone: thought so... and is it a sensible way to support optional arguments?

16:14 dakrone: depends, you could use '& args' also

16:14 jaley: dakrone: yeah but it'll be nicer for the call if the optional arg goes in the middle... :/

16:15 cemerick: jaley: keyword args to the rescue?

16:15 dakrone: why? normally options args go at the end

16:15 yea, or pass a map

16:15 jaley: dakrone, cemerick: i'm aiming for (with-response r body) and (with-response r validator-fn? body)

16:16 dakrone: at least i think it'd be nicer if the body part was always at the end, as it's potentially long?

16:16 tonyl: you can use arity with that

16:16 2 args or 3 args

16:17 dakrone: for that, arity seems easiest

16:17 jaley: tonyl: right, that was my thinking, but for some reason by 2 arg version calling the 3 arg barfs with "wrong number of args (3) ...

16:17 tonyl: what is the implementation that you have?

16:18 amalloy: jaley: probably wrong syntax for arity overloading?

16:18 jaley: amalloy, tonyl: right i suspect so, but i wasn't sure if what i was doing was even the right approach so i wanted to check :-)

16:18 amalloy: (defmacro stuff ([a b] b) ([a b c] (+ c b)))

16:18 dakrone: jaley: (defmacro foo ([a] a) ([a b] [a b]))

16:19 amalloy: your error sounds like you did something more like (defmacro stuff [a b] b [a b c] (+ c b))

16:19 jaley: let me pastebin it, i'll be 1 minute...

16:21 broken: http://pastebin.ca/2013238

16:24 fliebel: How many lines of code do you usually (re)produce in one day? I find it much harder to estimate time than LoC for a task. I was wondering if LoC is something reasonably constant. Inspired by a quote that all coders average at around 10 lines of code per day, where good coders spend more time thinking and bad coders on trial and error.

16:24 amalloy: jaley: the 2-arg version needs a `

16:25 brehaut: fliebel: i dont think you can ever turn LoC into a meaningful metric

16:25 jaley: amalloy: d'oh! thank you!

16:26 zztr: fiebel: +1 what brehaut said

16:26 amalloy: brehaut: it is a meaningful metric for, eg, estimating how big a hard drive to put on your vc server...:)

16:26 brehaut: amalloy: hah

16:27 tonyl: is there a way to know if a form is a macro?

16:27 amalloy: &(meta #'or)

16:27 sexpbot: ⟹ {:macro true, :ns #<Namespace clojure.core>, :name or, :file "clojure/core.clj", :line 705, :arglists ([] [x] [x & next]), :added "1.0", :doc "Evaluates exprs one at a time, from left to right. If a form\n returns a logical true value, or returns that value and does... http://gist.github.com/732440

16:27 Raynes: &(meta for)

16:27 sexpbot: java.lang.Exception: Can't take value of a macro: #'clojure.core/for

16:27 Raynes: &(meta #'for)

16:27 sexpbot: ⟹ {:macro true, :ns #<Namespace clojure.core>, :name for, :file "clojure/core.clj", :line 3582, :arglists ([seq-exprs body-expr]), :added "1.0", :doc "List comprehension. Takes a vector of one or more\n binding-form/collection-expr pairs, each followed by zero or mor... http://gist.github.com/732442

16:27 amalloy: Raynes: too slow

16:27 Raynes: amalloy: Damn. I was too slow.

16:28 And again.

16:28 tonyl: ##(:macro (meta #'for))

16:28 sexpbot: ⟹ true

16:28 amalloy: &(-> for var meta :macro)

16:28 sexpbot: ⟹ true

16:28 Raynes: Mine is shorter.

16:29 Arguable more readable. Wanna fight about it?

16:29 tonyl: thanks, I didn't know there was metadata for that

16:29 Raynes: tonyl: A lot of core stuff even has line numbers in metadata.

16:29 That's how the $source command works.

16:30 tonyl: wow nice to know

16:30 amalloy: Raynes: defn/defmacro include line numbers in the meta automatically

16:31 Raynes: amalloy: I assumed. Too bad def doesn't.

16:31 fliebel: So source just fetches those lines? I thought it'd be something with getting the actual datastructure that was used to produce it.

16:32 Raynes: fliebel: Naw, source just looks at the metadata and links to the line on Github.

16:32 amalloy: $source source

16:32 sexpbot: Source not found.

16:32 fliebel: Raynes: Oh, I was thinking about ##(source source)

16:32 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

16:32 Raynes: fliebel: Oh, right.

16:33 amalloy: &(use '[clojure.repl :only [source]])

16:33 sexpbot: ⟹ nil

16:33 amalloy: $source source

16:33 sexpbot: Source not found.

16:33 amalloy: &(source source)

16:33 sexpbot: ⟹ Source not found nil

16:33 amalloy: bah

16:33 fliebel: source uses source-fn, which in turn does not have a source

16:35 https://github.com/richhickey/clojure/blob/master/src/clj/clojure/repl.clj#L21

16:37 amalloy: &(-> clojure.repl/source-fn var meta ((juxt :file :line :source))

16:37 sexpbot: java.lang.Exception: EOF while reading

16:37 amalloy: &(-> clojure.repl/source-fn var meta ((juxt :file :line :source)))

16:37 sexpbot: ⟹ ["clojure/repl.clj" 21 nil]

16:37 amalloy: &(-> clojure.repl/source var meta ((juxt :file :line :source)))

16:37 sexpbot: ⟹ ["clojure/repl.clj" 43 nil]

16:38 amalloy: well, i guess it makes sense that the source isn't directly in the meta. i just don't understand why (source) can find source but not source-fn, when they both have line numbers

16:43 fliebel: I don't think I understand source-fn. How does it figure out how many lines to read? It seems to read up to :line, but then I get lost in Java pushback readers and stuff.

16:46 amalloy: fliebel: it uses the built-in (read) function to read a single sexp, and as a side effect writes each character it reads to the stringbuilder. then it throws away the sexp it read and returns the string

16:47 fliebel: amalloy: Ah, the ambiguity! I'm not sure I have found the Clojure read amongst the java.io read methods.

16:48 Ah there it is...

16:48 amalloy: https://github.com/richhickey/clojure/blob/master/src/clj/clojure/repl.clj#L40

16:49 hiredman: that is a clever idea, but the implementation isn't so solid

16:50 amalloy: hiredman: the implementation of source-fn? i agree on both counts

16:50 hiredman: proxy and pbr and then wrap it in another pbr?

16:50 proxy a

16:51 fliebel: And a lot of mutable Java stuff. Not sure it hurts that much in this case though.

16:52 amalloy: fliebel: bet you $N (for some small N) that it leads to the output of (source) having trailing spaces on occasion

16:53 fliebel: amalloy: Why would that happen?

16:53 Would be fun to try… map over ns-publics, bind *out* to a string writer, call source-fn and see if it ends with a space.

16:53 amalloy: the pbr that appends to the stringbuilder can't know if the input stream gets pushed back. it's already appended to the string

16:54 on thinking about it it probably is fine because (read) will never actually have to push back in order to read, but maybe there's some weird structure of source lines that would cause it

17:00 bortreb: how do I efficiently subsample a vector?

17:01 amalloy: bortreb: not sure what you mean by subsample. are you looking for ##(subvec [1 2 3 4 5] 2 4)?

17:01 sexpbot: ⟹ [3 4]

17:01 bortreb: like, if I have a 25,000 vector and I take every 10th one to get a 2,500 vector

17:02 fliebel: amalloy: ##(not-every? identity (map #(.endsWith (or (source-fn (key %)) "") " ") (ns-publics 'clojure.core)))

17:02 sexpbot: java.lang.SecurityException: You tripped the alarm! ns-publics is bad!

17:02 amalloy: bortreb: take-nth probably isn't efficient since it falls back on treating the vec as a seq

17:04 jdrannbauer: ,(hash-map :a :b :a :c)

17:04 clojurebot: java.lang.IllegalArgumentException: Duplicate key: :a

17:05 amalloy: &(vec (take-while identity (map [1 2 3 4 5 6 7 8 9] (take-nth 2 (range)))))

17:05 sexpbot: java.lang.IndexOutOfBoundsException

17:05 jdrannbauer: Hmmmmm... Anyone know why the docs suggest that I can supply duplicate keys to hash-map but it throws an exception if I do?

17:06 amalloy: &(doc hash-map)

17:06 sexpbot: ⟹ "([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings."

17:06 amalloy: jdrannbauer: where are the docs that make you think you can do this?

17:07 jdrannbauer: Good question. Saw it at this url: http://clojuredocs.org/clojure_core/clojure.core/hash-map. usually a good reference.

17:07 amalloy: bortreb: anyway i think the answer will be vaguely like what i did above. use the vector as a function, and call it with the indexes you want

17:07 bortreb: ah

17:07 amalloy: just make sure you don't call it with bad indexes

17:08 bortreb: it's just (vec (map v (range 0 (count v) n))) to so subsampling because count is fast

17:09 amalloy: jdrannbauer: whoa that must be old

17:09 bortreb: oh, sure

17:09 jdrannbauer: Ah! Cool. Too new to clojure to have noticed. Thanks for the heads up!

17:11 amalloy: Is there a sugary way to do what I am looking for? I want to convert [:a "b" :a "c"] to {:a "c"}

17:11 amalloy: jdrannbauer: ##(into {} [:a "b" :a "c"])

17:11 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

17:11 amalloy: jdrannbauer: ##(into {} (partition 2 [:a "b" :a "c"]))

17:12 sexpbot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

17:12 amalloy: bahhhhh

17:12 hiredman: ,(apply hash-map [:a "b" :a "c"])

17:12 clojurebot: java.lang.IllegalArgumentException: Duplicate key: :a

17:12 hiredman: no kidding

17:12 chouser: ,(into {} (map vec (partition 2 [:a "b" :a "c"])))

17:12 clojurebot: {:a "c"}

17:12 chouser: meh

17:12 amalloy: ah right, map vec. thanks chouser

17:12 fliebel: chouser: I'm to slow, was about to try that.

17:13 chouser: I wouldn't call it sugary

17:14 ,(let [v [:a "b" :a "c"]] (zipmap (take-nth 2 v) (take-nth 2 (next v))))

17:14 clojurebot: {:a "c"}

17:14 jdrannbauer: Thanks everybody. Not as sugary as I was hoping but does exactly what I need.

17:15 fliebel: something like this.. but it doesnt work yet,,, maybe I'm stilll fast enough (reduce into {} (partition 2 [:a 1 :a 2]))

17:15 jdrannbauer: chouser: oooh, that's pretty cool.

17:16 jarpiain: bortreb: you could do something like this if you need the vector interface: https://gist.github.com/732529

17:23 jaley: can anyone explain the *-suffix naming convention?

17:24 cemerick: foo* often indicates a helper fn for a "public" foo fn or macro, or a function that is a variation of a primary foo implementation

17:25 jaley: cemerick: thanks!

17:31 hd: I fail to use "mvn clojure:swank" on windows vista, although I'm using the newest versions clojure-maven-plugin:1.3.8-SNAPSHOT and swank-clojure:1.3.0-SNAPSHOT

17:32 The error is the same as here http://goo.gl/moVYc

17:33 Exception in thread "main" clojure.lang.LispReader$ReaderException: java.lang.Exception: Invalid token: C:

17:34 Can anybody help?

17:35 cemerick: hd: I'd post to that thread and ask Mark to clarify where you can find the proper fix (it doesn't look like he explicitly states where a staged release is).

17:36 hd: I downloaded it from github and installed it from source, but got the same error.

17:36 cemerick: an even better reason to post. Squeaky wheel, and all that. :-)

17:36 hd: [INFO] --- clojure-maven-plugin:1.3.8-SNAPSHOT:swank (default-cli) @ m2doc ---

17:36 Exception in thread "main" clojure.lang.LispReader$ReaderException: java.lang.Exception: Invalid token: C:

17:36 at clojure.lang.LispReader.read(LispReader.java:180)

17:36

18:35 amalloy: chouser: ##(apply assoc {} [:a 1 :a 2])

18:35 sexpbot: ⟹ {:a 2}

18:35 amalloy: looks like the sugar jdrannbauer was looking for before he left

18:48 jave: has anyone got a clojure 1.2.0 applet working, in openjdk?

18:59 pdk: how many folks use slime here

18:59 dumb q dealing with how to actually send it restarts when it gets an error

19:00 shachaf: pdk: You'll probably have much better success if you ask it than if you ask about asking it.

19:00 pdk: probably :p

19:01 say if i do M-x slime to start slime

19:01 then in *inferior-lisp* buffer i try putting in something that causes an error like (thisfunctiondoesn'texist)

19:02 bortreb: how can I make my objects defined with defrecord print in their own special way?

19:02 pdk: then i dunno how to actually input one of the restarts it lists through the buffer so i just sit there :p

19:02 clicking on a restart in the list it gives seems obvious but apparently not, etc

19:02 tonyl: b

19:03 pdk: !

19:03 tonyl: bortreb: implementing the Object.toString method, i think that is how it is

19:03 pdk: cool beans tonyl

19:03 so i can just hit the top row numbers to use the restart of that number too

19:03 tonyl: pressed enter too soon wih t

19:03 pdk: though how does it handle entering a restart by name

19:04 tonyl: i don't use slime, sorry i am not

19:04 m

19:04 u

19:04 pdk: b surprisingly enough did something though so it's unintentional help :p

19:04 * tonyl aaaagh something is wrong with my keyword

19:04 tonyl: lol

19:06 bortreb: tonyl: thanks! I just forgot to recompile my namespace

19:08 er, actually that doesn't work after all

19:10 you apparently need to also define the print-method and print-dup multimethods for your defrecord type

19:10 then it works fine

19:10 tonyl: uh interesting

20:35 islon: does anyone know hot to remove all nils from a seq?

20:35 *know how to

20:35 brehaut: ,(filter identity [1 2 nil nil 3 nil])

20:35 clojurebot: (1 2 3)

20:36 islon: thanks

20:36 brehaut: no worries

20:37 oh

20:37 that also filters out falses

20:37 how about

20:37 ,(remove nil? [nil 1 2 3 nil 4])

20:37 clojurebot: (1 2 3 4)

20:37 brehaut: thats way smarter

20:38 islon: yes, my list can't contains falses anyway

20:39 jcromartie: anybody ever notice some weird buffering issues with lein repl?

20:39 like, with lots of output, sometimes it hangs and I have to type something in before I get the rest of it

20:39 technomancy: jcromartie: there were flushing bugs in 1.3; 1.4 is better

20:40 jcromartie: k

20:41 amalloy: &(keep identity [nil 1 false 2])

20:41 sexpbot: ⟹ (1 false 2)

20:41 amalloy: brehaut, islon: ^^

20:41 brehaut: amalloy: nice

20:42 islon: good

20:42 amalloy: &(keep last [[1 2] [1 false] []])

20:42 sexpbot: ⟹ (2 false)

20:42 amalloy: keep is a nice little combo of map/filter

20:50 islon: does anyone knows the function that return the intersection of two seqs?

20:55 jcromartie: islon: have you checked out clojure.set?

20:56 &(clojure.set/intersection #{1 2 3} #{2 3 4})

20:56 sexpbot: ⟹ #{2 3}

20:56 islon: jcromartie: thanks, i used clojure.set/difference

21:01 aligole: hey guys

21:03 anybody here knows how I can overload/ override + to be able to add a number to a list of lists of numbers like (+ 3 ((1 2) (3 4))

21:04 jcromartie: why?

21:04 clojurebot: http://clojure.org/rationale

21:04 jcromartie: thanks, clizzin_

21:04 clojurebot:

21:04 clojurebot: #<ClassCastException java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;>

21:04 jcromartie: durrrrrrrrrr

21:04 aligole: (+ 3 ((1 2) (3 4))

21:06 raek: do you have a minute?

21:08 jcromartie: you asked me? "why"

21:08 jcromartie: yeah

21:08 aduric: Hi, anyone have any experience with clj-plaza?

21:08 aligole: sorry

21:08 jcromartie: I'm not sure what you want to do

21:09 clizzin_: jcromartie: haha, i was wondering why someone said my name in here

21:09 jcromartie: heh

21:10 aligole: I'm trying to implement a Matlab like thing! and I need to have and add function for matrices

21:11 i can write function to do this but it would be more convenient if + could be used to add numbers to all the nubmbers in a list

21:12 aduric: Anyone know what the error: "[java.lang.IllegalArgumentException] No implementation of method" usually means?

21:12 islon: ,(map + [1 2 3 4] [3 5 6 7])

21:12 clojurebot: (4 7 9 11)

21:12 aligole: ,(map + [1] [3 5 6 7])

21:12 clojurebot: (4)

21:12 jcromartie: aligole: I think that part of the rationale of Clojure is to avoid monkey-patching built-in functions

21:12 aligole: not what I need

21:13 jcromartie: so overriding + is not a good idea

21:13 unless you wanted to make a special context for it

21:13 like a macro that replaces + with your own function

21:13 which is what people do to build sub-languages

21:14 aligole: that sounds about right, I may need to do that, so I need to define a macro with the same name "+"

21:15 cool, let me try it

21:15 amalloy: aligole: no, just a function named + will be sufficient

21:15 jcromartie: no

21:15 I mean sure

21:15 you can redefine + in a namespace

21:15 amalloy: jcromartie was, i think, suggesting you define a macro (replace-pluses)

21:16 jcromartie: I'm not really suggesting it...

21:16 aligole: :)

21:16 jcromartie: first I'd suggest using something other than +

21:16 because + means +

21:16 :)

21:16 amalloy: heh, yes

21:16 jcromartie: like vec+

21:16 that's clearer

21:16 I mean

21:16 matrix+

21:17 amalloy: jcromartie: i think he actually wants something like scalar+, for adding a scalar to a matrix, but that's his problem

21:17 jcromartie: yeah

21:17 yeah if you were going to define a matrix math library, you'd name them in that context

21:19 aligole: I like to use + for all adding purposes, I don't see why it is not a good idea. and yes I am making a limited matrix library

21:20 Clojure's promis is to let you modify the language to your needs, isn't it?

21:20 hiredman: aligole: nope

21:20 brehaut: aligole: thats a really imprecise statement in a lisp

21:21 aligole: hiredman: WHAT?! why not? isn't it a LISP? I've done this in arc before very easy it was!

21:21 hiredman: clojure.core/+ is for fast adding of numbers, if you want a generic addition operator, there is one in contrib

21:21 right, and look where that got arc...

21:21 jcromartie: heh

21:22 aligole: oh, I didn't know, where in contrib?

21:22 jcromartie: aligole: by all means, define + in your matrix math lib

21:22 you can exclude + from the namespace

21:22 but I think you'll get tired of writing clojure.core/+

21:23 amalloy: &(require '[clojure.core :as [c]])

21:23 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Symbol

21:23 amalloy: &(require '[clojure.core :as c])

21:23 sexpbot: ⟹ nil

21:23 amalloy: &(c/+ 1 2 3)

21:23 sexpbot: ⟹ 6

21:23 amalloy: jcromartie, aligole: ^^

21:24 aligole: cool

21:24 jcromartie: wait... sexpbot maintains state for you?

21:24 &(def x 1)

21:24 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

21:24 jcromartie: oh

21:24 aligole: but still I am confused, why I can't have a generic +

21:25 hiredman: do you remember where in contrib is that generic +

21:29 amalloy: generic-math?

21:30 vIkSiT: hi all

21:30 aligole: there is a generic + in generic/arithmatic.clj as well

21:30 vIkSiT: When doing a lein compile, I find that it gets stuck at the "compiling namespace" step

21:30 is there a way to see what might be going wrong?

21:30 (some sort of a verbose mode, perhaps)?

21:31 danlarkin: vIkSiT: how long have you waited?

21:31 vIkSiT: quite some time (ran it for almost 20 minutes)

21:32 danlarkin: oh gosh, okay that's certainly long enough

21:32 vIkSiT: hehe yeah, i lein compiled and was doing something else

21:32 lein compile works fine on another project

21:32 top shows 2 java processes taking 5.3 and 5.2% mem respectively

21:34 also the lib/ size is only 5M, whereas lein works fine for a project with 18M of libraries

21:34 aligole: hiredman, amalloy, jcromartie: http://clojure.org/multimethods

21:35 vIkSiT: danlarkin, ideas?

21:35 brehaut: aligole: multimethods are the exception, not the rule. (partly because dispatch is slower than static fns)

21:36 danlarkin: vIkSiT: nope :( could be a bug, I suggest reporting it

21:37 amalloy: aligole: https://github.com/clojure/clojure-contrib/blob/master/modules/generic/src/main/clojure/clojure/contrib/generic/arithmetic.clj

21:39 aligole: brehaut: I agree if performance is the first priority, but in my case it is not,

21:40 amalloy: thanks, just was reading that

21:40 brehaut: aligole: sure, then it'll work fine

21:41 vIkSiT: dakrone, aaah. quick question - how does one compile a (future) function in a file?

21:41 I had a variable called (def f (future (myfn params)))

21:41 er i meant danlarkin*

21:42 danlarkin: what do you mean how do you compile it

21:42 vIkSiT: danlarkin, in the sense - i've got the def within my file, and the function it wraps around basically tails a file (and waits on it).

21:43 i'm guessing the compilation process initiated this

21:43 my question is - how would i lein compile code which contains a (future) fn call like this?

21:44 danlarkin: are you sure you need to be compiling in the first place?

21:44 I know that's not your question, but I'm obligated to ask

21:44 vIkSiT: danlarkin, well, i need to create a JAR for my program so i can deploy it :)

21:45 danlarkin, is there another way btw? (apart from starting a REPL, not sure thats advisable in production)

21:45 danlarkin: you don't need to complie clojure to deploy it in a jar

21:45 vIkSiT: hmm

21:46 but lein jar had the same issue

21:46 does lein jar evaluate the code, perhaps?

21:47 danlarkin: yeah your problem is the def

21:48 I assume

21:49 vIkSiT: I could ping technomancy and check as well..

21:52 amalloy: vIkSiT: (defs) are necessarily evaluated at compile time, otherwise (defn foo [] x), which expands to (def foo (fn [] x)), wouldn't do anything when you compile

21:52 vIkSiT: amalloy, indeed

21:53 amalloy: to prevent this from happening, you need (defn make-f [] (future (myfn params)))

21:53 then when you want to do something with it, call (make-f) to get out a logger

21:55 and make sure that make-f isn't called in the global scope. call it from (-main) or whatever

21:55 vIkSiT: amalloy, ah

21:55 good idea - let me try that!

21:58 amalloy: vIkSiT: a pretty general strategy when you don't want something evaluated is to put it into a function :P

21:58 vIkSiT: amalloy, is -main the only function not eval'd?

21:58 amalloy: vIkSiT: they're all evaled

21:58 vIkSiT: amalloy, hehe

21:58 amalloy: but they're only called if you call them

21:58 vIkSiT: ah but a def when evald will have invoked the future fn..

21:58 right

21:58 amalloy: no

21:59 well yes, a def

21:59 which is why, as i said, you can't make it a top-level thing. shove it inside a function

21:59 &(future (println 1))

21:59 sexpbot: ⟹ #<core$future_call$reify__5500@3c2bdf: nil>

21:59 amalloy: &(fn [] (future (println 1)))

21:59 sexpbot: ⟹ #<sandbox6366$eval8635$fn__8636 sandbox6366$eval8635$fn__8636@b579ac>

22:00 amalloy: only one of those two things will have printed to the stdout on sexpbot's server

22:00 vIkSiT: right

22:00 the first one

22:00 amalloy: right. same is true if you'd lein jar/compile'd it

22:00 vIkSiT: gotcha

22:01 whew. it works :)

22:02 amalloy: hurrah. if it didn't, i'd have to re-evaluate my perspective on reality

22:02 vIkSiT: haha

22:04 couple of questions about reading params from the CLI. right now, I've just defd two global vars (def a) and (def b), and then i read the values from the CLI and (def them from within the -main function

22:04 is this general practice in terms of keeping global state?

22:04 (for instance, if i want to read/write to a configuration file)

22:06 tomoj: would be nice to be able to switch between configuration profiles easily

22:07 oh, just place a file and read it I guess

22:07 amalloy: vIkSiT: (def *args* (atom {:a 10, :b 20})) (defn -main [] (swap! *args* assoc :a (read) :b (read))) is the hacky approach i would use

22:07 having just one var with all the args appeals to me

22:08 vIkSiT: ah

22:08 makes sense

22:08 brehaut: vIkSiT: using a (couple of) vars are fine if you dont expect them to change

22:08 vIkSiT: but if you can just pass the appropriate values through to the real program from -main that is nicer (IMO)

22:09 vIkSiT: agreed

22:09 tomoj: I think I'll just put some clojure forms in a file and read them

22:09 jcromartie: is there something weird about defmulti that the dispatch function isn't updated when reloading a namespace?

22:09 vIkSiT: but i'm trying to interop with an existing java program

22:11 amalloy: jcromartie: the old defmethods will stay attched to the original defmulti; to attach them to the new one you'll need to reload the defmethods too

22:11 not sure if that's the problem you're having

22:11 jcromartie: the defmulti and defmethods are all in the same ns

22:12 amalloy: jcromartie: actually this sounds a lot like a problem i had, now that you mention it. i never figured it out; let me know if you do

22:36 scottj: Is there a fn for (concat (butlast coll) (f (last coll)))?

22:37 this is where a smalltalk method finder would come in useful.

22:44 amalloy: scottj: i don't think there is, and it would have to be pretty slow. maybe you can modify what you've done to get you to the state where you want this function?

22:58 pdk: little pop quiz

22:58 if i'm evaling stuff with slime and i write something that would lead to an infinite loop

22:59 what would you do to kick it in the pants and make it cancel that so you can eval other stuff and get printouts again

23:00 scottj: you can try C-c C-c ad infinitum but you'll probably have to kill java proc and restart it.

23:00 pdk: now i'd need to know how to hook emacs and slime to the new java proc i make without restarting those too :p

23:01 so i could keep working seamlessly like nothing happened after the inferior lisp is restarted

23:01 in the case of working on a file in slime mode at least

23:03 scottj: if you use lein swank you just have to M-x slime-connect

23:04 alias les='lein swank & sleep 5; emacs-client -e "(slime-connect 4005)"'

Logging service provided by n01se.net