#clojure log - Jun 02 2010

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

0:45 axi: so.. when using gen-class.. only functions listed for :init and :methods belong to the class? nothing else in the file?

0:47 cemerick: axi: and those methods inherited by superclasses or defined by implemented interfaces

0:48 hiredman: ok

0:48 axi: so.. how would I declare class-level variables like in java?

0:48 hiredman: (a double boating accident)

0:49 damn it

0:49 trying out split window irssi

0:50 axi: in one of the functions listed under :gen-class's :methods

0:50 I have code like "(def text (new JTextArea))"

0:51 and i'd like to be able to (. instance text append "bla") etc..

0:51 but that doesn't work, because it looks like it gets destroyed when the function exits..

0:51 so.. I need to give it class scope

0:51 but clojure has no facility for that?

0:51 cemerick: definitions should (almost) never go within fns

0:51 That's defining a new top-level var

0:51 axi: I can't find any examples for what I want to do..

0:52 cemerick: axi: you want to add all of the "class level variables" to a clojure map, and return that as the :state value from the :init fn

0:52 axi: what exactly should be in the init function?

0:53 I see no documentation for it..

0:53 cemerick: look at the docs for gen-class

0:53 axi: I read it 20 times

0:54 Must return [ [superclass-constructor-args] state]

0:54 cemerick: ":init - If supplied, names a function that will be called with the arguments to the constructor. Must return [ [superclass-constructor-args] state]"

0:54 axi: Right now it's (defn -init [] [[] (atom [])])

0:54 what do you propse I add to it?

0:55 cemerick: I don't know what your end goal is, but you can return [[] {:text (JTextArea.))]

0:55 Then you can access the text area with (-> instance .state :text)

0:56 axi: how woudl I access it from an instance of the class?

0:56 (. instance state :text)?

0:56 cemerick: just what I said

0:56 axi: oh, sorry

0:56 cemerick: no, (:text (.state instance))

0:57 which is equivalent to (-> instance .state :text)

0:57 have you gone through the examples @ http://clojure.org/compilation

0:57 ?

0:57 axi: hrm

0:57 java.lang.ExceptionInInitializerError

0:58 looks like (defn -init [] [[] {:text (JTextArea.))]) doesn't work

0:58 cemerick: what's the base cause of the exception?

1:01 axi: other than the missing } and ) in wrong place.. idk

1:01 cemerick: are you subclassing something in the :gen-class?

1:02 axi: no

1:03 cemerick: paste your entire file somewhere, please

1:04 KirinDave: Hey folks

1:04 If I define a deftype in a given namespace, how do I make it from another namespace?

1:04 I go testspace/my-type and it doesn't find anything.

1:05 cemerick: (your.namespace.TypeName. a b)

1:05 axi: yay

1:05 KirinDave: Ahh

1:05 cemerick: Weird I am doing that

1:05 cemerick: axi: progress?

1:05 axi: cemerick, it works

1:05 ty :-)

1:05 cemerick: nice :-)

1:06 axi: it looks like I have a lot of reading to do now though to understand why it works :P

1:06 cemerick: axi: gen-class has a lot of flexibility, but there's complexity that goes along with it. If you can use the newer defrecord/deftype stuff, then do so.

1:06 KirinDave: cemerick: http://idisk.me.com/dfayram/Public/Pictures/Skitch/blogpost.clj-20100601-220457.png

1:07 axi: k, i'll keep that in mind

1:07 KirinDave: Ahh

1:07 cemerick: KirinDave: kooky

1:07 KirinDave: cemerick: Actually, weird

1:07 Removing the constructor period works.

1:08 cemerick: KirinDave: you're using an older snapshot

1:08 KirinDave: I guess that's the trick.

1:08 cemerick: Am I?

1:08 cemerick: Indeed.

1:08 KirinDave: Did types get their funcallability removed?

1:08 cemerick: Yes.

1:08 ~3 weeks ago :-)

1:08 clojurebot: excusez-moi

1:08 KirinDave: Ah!

1:08 I never check my installed version

1:08 because lein always gives me one sealed for freshness

1:09 cemerick: heh

1:09 KirinDave: I'll walk you through maven someday, if you haven't been. :-)

1:09 KirinDave: cemerick: I don't really understand it.

1:09 I mean I get the gist

1:09 but the specifics are greek

1:10 cemerick: it's cake, despite the groaning from the peanut gallery

1:11 KirinDave: Usually I have to surf maven2 by hand to find out if something is in there

1:11 Right there learning how to avoid that would be fantastic

1:12 cemerick: KirinDave: http://mvnrepository.com/ for starters

1:12 KirinDave: cemerick: It seems like sometimes I search for project names there and they don't show up, but they are on maven2

1:13 cemerick: well, that is a third-party mirror

1:13 having a nexus repo (which proxies central and whatever other repos you're interested in) is a good thing

1:13 as is having good tools (i.e. both netbeans and eclipse have in-IDE search that's worked well for me)

1:13 KirinDave: I am taught to fear nexuses by my magi overlords.

1:14 cemerick: But that's where all the power is... :-)

1:14 KirinDave: Yeah.

1:14 Well, you know how it is. With great power comes great fondness for wavy daggers and making apprentices clean up the laboratory.

1:14 cemerick: heh, right

1:14 KirinDave: As much as I want to bang out this blog post tonight, I'd better get to the gym.

1:15 cemerick: bed for me, later :-)

3:04 Borkdude: What is the best dynamic vs. static typing article out there?

3:04 KirinDave: Borkdude: Uh, depends on what you want to justify

3:04 Borkdude: Since many of the best languages take hybrid approaches, the issue is somewhat muddy now

3:05 Borkdude: KirinDave: let's say, for making clear to someone who always programmed Java and cannot imagina a dynamic language would work for a big project

3:07 KirinDave: Borkdude: The most obvious answer is to point to a lot of large projects that use dynamic typing and say, "See?"

3:08 bobo_: if php works in large projects with its crappy typing, every other type system works in a large project

3:08 turbofail: for certain values of "works"

3:08 bobo_: :-)

3:09 Borkdude: bobo_, I don't want to mention PHP :)

3:09 turbofail: though really, any decently run large project is really a composition of a bunch of smaller projects

3:09 Fossi: and for certain values of "large" :D

3:09 turbofail: thus, this whole "size" argument doesn't make a whole lot of sense

3:09 spariev: turbofail: judging by your inck, you do know what are you speaking about :)

3:10 Borkdude: what I like about Clojure is that you can just pick a small fragment and explore it in the REPL, but that isn't a dynamic typing property

3:10 spariev: nick*

3:10 KirinDave: Hmmm.

3:11 Can you use protocols to write a custom tostring for an object?

3:11 turbofail: spariev: all too much

3:13 Borkdude: Does Clojure support pattern matching like: (defn foo ([1] 1) ([2] 2) ([x] (foo (dec x)))? No, but maybe there is smth like this?

3:13 KirinDave: With matchjure

3:13 Which I think is going into contrib, right?

3:14 Yeah, last week it was announced that there'd be clojure.contrib.match

3:14 Borkdude: cool :)

3:16 KirinDave: You can get matchure right now tho.

3:16 Borkdude: KirinDave: does it support a pattern matched defn like I described?

3:16 KirinDave: Yes.

3:17 But it's more like plt-scheme's match-lambda stuff.

3:21 tomoj: what's the deal with ?foo in matchure?

3:21 I can't figure out why it isn't just foo

3:28 Borkdude: gtg

4:23 LauJensen: Morning all

4:23 spariev: morning

4:30 Licenser_: aloa

5:42 SinDoc: How can we make one tail call and one recursive call in the same loop?

5:43 opqdonut: (defn f [x] (loop ... (f something) ... (recur somethingelse)))

5:46 SinDoc: Yeah but what happens to the arguments that loop receives? Loop will be initialized again.

5:47 opqdonut: you'll have to pass them in explicitly

5:47 SinDoc: Yeah, I guess that will work

5:47 opqdonut: you'll probably want to implement it with just plain binary recursion first

5:48 SinDoc: I don't understand why recur complains about a call not being a tail call

5:48 opqdonut: recur is a tool for constructing _loops_

5:48 if you have true recursion, you use the stack

5:48 as I said, start with binary recursion and loopify if it really is necessary for performance

5:49 SinDoc: I'm porting some algorithms from Scheme

5:50 trust me, you don't wanna mess with tail-calls there

5:50 opqdonut: ok

5:50 SinDoc: Thanks opqdonut I'll give it a try

6:47 * esj is completing his armistice treaty with Maven.

6:48 LauJensen: lets celebrate with some xml!

6:48 esj: its been bloody

8:08 Licenser_: hmm how is the best weay to go when I need to call super in an object in clojure?

8:08 do I have to AOT for that? Since proxy does not seem to allow it :)(

8:08 chouser: you can use proxy-super

8:08 Licenser_: ah sneaky thanks!

8:09 chouser: note that's not thread-safe. :-/

8:09 G0SUB: chouser: is there an equivalent in terms of reify?

8:09 Licenser_: chouser: I do swing right now, nothing is thread save

8:10 chouser: G0SUB: reify doesn't to implementation inheritence, so there's nothing in super to call.

8:10 G0SUB: chouser: ah, right.

8:10 Licenser_: neat this woirks :D

8:11 I have a red swing t ree now!

8:29 spariev: just wondering, what exactly is dispatch performance difference between multimethods and deftypes/defrecords ? is it like orders of magnitude ?

8:30 Licenser_: when I create a new type, can I pass the constructor around as function? or anything else

8:33 I can't write new MyType

8:33 neither can I pass MyType.

8:35 hoeck: Licenser_: you can, but only with reflection

8:36 Licenser_: better wrap your type-ctor in a fn

8:36 Licenser_: hoeck: okay

8:36 It didn

8:36 t work at all for me so I went with a fn already

8:37 hoeck: (clojure.lang.Reflector/invokeConstructor MyType 'a 'b 'c)

8:38 no, its actually ( .... MyType (into-array Object '[a b c]))

8:39 Licenser_: yes bit I can

8:39 't pass MyType

8:39 chouser: much better to write your own ctor fn and pass that around

8:39 Licenser_: figured that, fixed it to do that

8:39 making funky swing trees is hard :P

8:42 hm problem is something else

8:42 if I 'use' a namespace I don't include the types

8:42 that is bleh

8:43 chouser: the types are classes, thus have to be imported instead

8:43 Licenser_: yap but I would have expected when using a namespace it automatically does that :P

9:31 hmm I find the import behaviour of types odd

9:43 patrkris: The nicest way to get all the elements from a vector v specified by the indexes in another vector a?

9:44 chouser: (map v a)

9:47 candera: Definition: "Clojure Factor" - the ratio of the length of some solution to a problem to the optimum one. Mine stands at something like 5. :)

9:49 arkahn: likewise

9:51 _fogus_: Definition: "Chouser Factor" - see "Clojure Factor"

10:03 esj: mine often goes infinite as I try to solve problems that don't actually exist.... ah well

10:08 rhickey: aargh! test_clojure.clj:87

10:11 arkahn: (System/exit 0) ?

10:11 cemerick: rhickey: ?

10:11 is this hunt-for-the-real-line-number time?

10:11 rhickey: cemerick: yes

10:12 cemerick: A perennial favorite. I wonder if there's a real solution.

10:13 (beyond clever stack trace analysis/printing)

10:13 rhickey: cemerick: fix the test library?

10:13 cemerick: rhickey: well, it's a general problem

10:13 rhickey: not really

10:14 cemerick: I'll show you some stack traces from compojure in conjunction with lazily-produced output sometime.

10:16 rhickey: a testing framework should be expecting exceptions in tested code

10:17 it's generating that report, not a stack trace

10:17 Licenser_: hm hmm is there a way to 'filter' a hashmap?

10:17 say 'I only want the keys' X Y Z

10:17 cemerick: Licenser: select-keys

10:18 Licenser_: cemerick: thank you smart person!

10:19 LauJensen: Here's a nice idea for any Clojure-driven site: When referral spam or cross-site scripting attempts show up in the access.log, pass the IP tip iptables DROP list - problem solved forever :)

10:19 cemerick: rhickey: that's just clojure.test you're talking about? I'm seeing pretty good stack traces in a recent failed test. *shrug*

10:20 Licenser_: LauJensen: jes and no, it has to time out

10:20 since dynamic IP's might hurt an innocent person

10:20 I wrote a ruby script for something like that once

10:20 it blocked SSH brute force people

10:20 rhickey: cemerick: the stack trace is fine, but the first hing you see is a line from test, which knows the files but always prints the same line from test_clojure.clj - it's just wrong and useless

10:20 [java] ERROR in (defrecord-object-methods-test) (test_clojure.clj:87)

10:21 cemerick: oh, ok -- yes, clojure-maven-plugin does the same thing

10:25 arkahn: LauJensen: also, punishes people who all share the same public IP(s). I work at a company of thousands of computers and a single compromised machine could trigger a server response for everyone here. But maybe that's acceptable.

10:27 LauJensen: arkahn: I trust people to get an email through to me if they get blocked. For certain nations (a certain nation) Im considering a nation-wide ban, and instead of blacklisting, do white-listing

10:31 eevar2: Licenser_: so you reimplemented fail2ban?

10:32 unless you did it before fail2ban existed, of course

10:32 arkahn: LauJensen: blocking countries based on geo-location was talked about on Slashdot recently. One conclusion was that is was coarse and ineffective with things like botnets that disregard country boundaries. On the one hand, a person thinks 'well I don't need to receive traffic from X' but then a good blackhat wouldn't always originate from the same country (or their own country at all).

10:33 LauJensen: just a thought

10:33 Licenser_: eevar2: I have no clue never heared of fail2ban :P

10:33 eevar2: the main threat is botnets, no?

10:34 LauJensen: arkahn: I think the good blackhats deserve to give it a go. But periodically I spend too much time blocking spam, in comments, in referrels, in emails, you name it. And if some region, country, useragent, whatever turns out to be 99.999% spam, then I think its a pure timesaver just to cut it

10:35 arkahn: LauJensen: if one region makes up that much of the bad behavior, I can see it then.

10:35 eevar2: Licenser_: look it up next time you want to stop ssh brute force attacks, neat software

10:35 i'm sure there are tons of similar apps, tho

10:36 LauJensen: eevar2: When launching a linode, you get ssh attacks almost immediately, change to an alternate port and something like 80% goes away.

10:37 arkahn: LauJensen: if enough people did that with their servers, I bet you'd get greater ISP or government pressure to fix their problems from within ; )

10:37 Licenser_: my latest spam is from china

10:38 arkahn: does (send-off *agent* #'fnname) send off an anonymous agent ... or, er, 'agentify' the function call?

10:38 LauJensen: arkahn: why would you think so ?

10:39 eevar2: LauJensen: but that's security by obscurity! ;) -- i guess it doesn't really hurt as an additional layer of protection, tho

10:39 LauJensen: eevar2: right, the second move is to disallow password auth

10:39 arkahn: LauJensen: if enough servers did that, it would impact business and money, the prime motivator for companies and governments.

10:40 LauJensen: Licenser_: its mad, I get (got) weekly emails saying "We are a China based" and then whatever they were selling that month. Do they honestly expect me to hire them after sending me 50 or so offers?

10:40 arkahn: oh ok, thought you were referring to the alternate port - but I hear you

10:40 I guess we should just get busy and build that 'ring of trust' internet :)

11:19 arkahn: will the next release of clojure be 1.1 or 1.2?

11:20 cemerick: 1.2

11:20 1.1 was released on 12/31/2009

11:20 arkahn: cemerick: *palm-on-forehead*, thanks

11:32 bartj: is there a better way to get the index of a seq which satisfies a function?

11:32 than this:

11:32 (defn get-index [f x] (loop [i 0] (if (f (nth x i)) i (recur (inc i)))))

11:33 chouser: indexes and seqs don't go together very well. Are you sure you need an index?

11:33 bartj: hmm, I need the index of a seq/collection which satisfies a function

11:33 chouser: also, I am curious why you say so

11:34 KirinDave: bartj: Because seqs can often be infinite

11:34 bartj: Which sorta defeats the point of an index. ;)

11:34 bartj: KirinDave: thanks!

11:34 TimMc: bartj: And return nil if not found, I suppose?

11:35 chouser: accessing seqs by index and getting indexes from seqs will always be O(n) -- usually there's a better way.

11:35 bartj: what will you use the index for, once you have it?

11:36 KirinDave: bartj: If you use clojure.contrib.seq-utils, you can use (indexed initial-seq) to lazily annotate every entry with an index. Then you can write your predicate to use the second argument. But listen to chouser, what you're asking might be inherently a bad idea.

11:37 bartj: KirinDave: point noted

11:38 chouser: a function returns a lazy sequence, and I wanted to know the index of the sequence which satisfies a given property

11:39 KirinDave: bartj: Why is the index relevant?

11:39 chouser: yes, I understand. once you have this index, what do you intend to do with it?

11:39 KirinDave: Is it corespondent to a line number, perhaps?

11:39 bartj: KirinDave: honestly, this is a programming problem from Project Euler

11:39 KirinDave: oh.

11:40 Haha, don't publish your times. ;)

11:40 I see what you're doing, but don't expect meteoric performance out of it. )

11:40 chouser: ah, well if the index is the final output, then getting it is of course acceptible.

11:40 KirinDave: chouser: "there was no step 3." :D

11:40 chouser: :-)

11:41 bartj: what would be the best way possible way then?

11:41 chouser: in your example, x is a vector?

11:41 bartj: no, a lazy sequence

11:41 chouser: ah, then (nth x i) is a bad idea. Again, that's O(n)

11:41 KirinDave: bartj: It's an approximation of some iterative computation that you've broken into steps.

11:42 TimMc: So... at each step you are generating the next value, then checking a property of it.

11:42 KirinDave: Which euler project?

11:42 chouser: and since it's in a loop, O(n^2)

11:42 KirinDave: chouser: I think he's scanning through linearly as he goes, discarding previous values.

11:42 chouser: I don't think he'd have to fetch.

11:43 Oh wait, your code doesn't do that. :D

11:43 bartj: KirinDave: 25

11:43 TimMc: Seems to me you're better off with a (loop) that recurs on the index and current value.

11:43 chouser: (keep-indexed #(when (f %2) %1) x)

11:44 bartj: TimMc: you mean this: (defn get-index [f x] (loop [i 0] (if (f (nth x i)) i (recur (inc i)))))

11:45 KirinDave: bartj: Chouser is saying you shouldn't use nth.

11:45 bartj: And he's right. Do not use nth.

11:45 TimMc: bartj: Nah, just do your fibonacci calculation in the loop, and your checking.

11:45 Not sure what the point of using a sequence is here.

11:45 hugod: should I be able to add a field to a defrecord at the repl by re-evaluating the defrecord?

11:46 chouser: It's ok, and probably good, to decouple the different parts. A fibonacci seq is reusable.

11:46 TimMc: bartj: You can keep your last two fibonacci numbers around as loop parameters (or whatever they're called) as well as the fibonacci index.

11:46 chouser: hugod: I think so

11:46 TimMc: chouser: Decoupling... good point.

11:47 bartj: Ignore me, chouser knows hwo to do this in a way more appropriate to clojure. :-P

11:47 KirinDave: bartj: So what you want is a sequence of numbers from your indexed sequence that meet some predicate.

11:47 bartj: We can easily add the index with (indexed seq)

11:47 bartj: We want to filter based on your predicate

11:48 chouser: hugod: you can, but existing objects of the record type may behave a bit oddly.

11:48 KirinDave: So to start, say that predicate is your predicate and it's (fn [[index val]] ...)

11:48 Then you'd say (first (filter predicate (indexed (my-lazy-seq))))

11:48 That'll return you a 2-vector, [index value]

11:48 hugod: chouser: doesn't seem to work for me on the latest snapshot - the constructor isn't redefined

11:49 KirinDave: Note that even if your sequence infinite, first only takes the first value

11:49 bartj: KirinDave: is the solution to add an index to the seq?

11:49 KirinDave: bartj: What I described is by far the least code for you to write, and it keeps the O(n) property you wanted.

11:49 Honestly that'll actually be faster than 90% of the entries on euler if it involves fibb numbers, most people don't have O(n) implementations of fibb finders.

11:50 There is a reason there isn't the equivalent of ruby/python's collection.find, because lazy collections already solve the problem.

11:50 chouser: hugod: hm, works here. I'm on 878dea8 from May 28. I'll update

11:51 bartj / KirinDave: did you see my keep-indexed solution?

11:51 er

11:51 hugod: sorry, completely wrong version number.

11:51 bartj: chouser: I am having difficulty understanding what keep-indexed does

11:52 chouser: bartj: it takes a fn and a seq, and calls the fn on each item of the seq until the fn returns something truthy. It then returns that truthy thing.

11:52 KirinDave: chouser: I did. I think the (first (filter ..)) has didactic value here, but yours would be what I use in practice.

11:52 hugod: chouser: I'm on clojure-1.2.0-master-20100602.140300-81, whatever that translates to...

11:53 chouser: sorry, call the fn with the seq item *and its index*

11:53 KirinDave: chouser: I try and keep the predicates simple when people are learning about seq munging.

11:53 chouser: KirinDave: I didn't say anything until you said your solution was least code. :-)

11:53 bartj: chouser: and also returns the seq item and the index?

11:53 KirinDave: chouser: I meant less than his. :D

11:54 bartj: No.

11:54 chouser: bartj: no, keep-indexed returns just the value the your fn returns.

11:54 KirinDave: bartj: It returns a lazy sequence. So like filter, you need to handle it with kid gloves.

11:54 Haha, just call exit in your predicate ;)

11:54 DONE!

11:54 chouser: oh!

11:54 you're right, I needed (first ...) as well. sorry.

11:55 KirinDave: chouser: I like the "call exit in your predicate solution"

11:55 It's so very c-ish

11:55 chouser: :-P

11:55 TimMc: Naw, you should segfault to stop execution.

11:55 KirinDave: ;)

11:55 TimMc: Everyone else is doing it!

12:08 cemerick: has there ever been a broad survey of from where people came to clojure? I seem to remember chouser doing one some time ago, but can't find it now....

12:09 * cemerick starts putting together a survey

12:17 lpetit: cemerick: a long time away from coding java in a client ; then discovering new langages (new for me) : SmallTalk, common lisp, scheme, Haskell. Not finding anyone that could be used in practice. Then find clojure. Stop the search. :-)

12:17 cemerick: lpetit: :-)

12:17 I've got a 5-question google form almost done. This'll be interesting.

12:17 lpetit: s/in a client/at a client/ ?

12:17 sexpbot: lpetit: Format is sed [-<user name>] s/<regexp>/<replacement>/ Try $help sed

12:19 TimMc: ${preposition} a client

12:19 sexpbot: Command not found. No entiendo lo que estás diciendo.

12:20 lpetit: cemerick: one thought out of my mind. I've remarked that I'm not "staying with clojure" for exactly the same reasons I "came to clojure". I discovered that clojure had much to offer than what I thought initially (basically, I thought I had find a way to "rule them all" by having a language with macros. It's only later on I understood the virtues of the way clojure mixes FP and state management)

12:20 cemerick: so maybe you could have a question "wy do you stay with clojure", also ?

12:20 cemerick: that's a complicated question, deserving a complicated answer :-)

12:21 lpetit: :)

12:21 _fogus_: I would love to see a Clojure-centric "Hammer Principle" site

12:21 chouser: lpetit: me too. I came here only for macros+interop

12:22 _fogus_: But that's probably just me

12:22 * cemerick googles "hammer principle" :-P

12:23 _fogus_: cemerick: http://therighttool.hammerprinciple.com/

12:23 Obviously structured differently

12:23 cemerick: ah

12:23 _fogus_: it's also a martial arts concept, apparently

12:23 lpetit: chouser: :) . BTW, just bought your ebook today ;)

12:24 _fogus_: Interestingly, Clojure does very well on the annoying syntax question - http://therighttool.hammerprinciple.com/statements/this-language-has-an-annoying-syntax

12:25 technomancy: _fogus_: because it's only rated by people who actually know the language. =)

12:25 _fogus_: technomancy: I suppose there is a flaw in the "choose the languages you know" aspect. :-)

12:26 * cemerick rips off the language listing from therighttool

12:28 * TimMc complains that cemerick left Malbolge off the survey

12:30 * _fogus_ hopes cemerick puts Potion on the list

12:31 cemerick: heh

12:31 it's alphabetized and I can't change the order, so it's done :-P

12:31 when I do State of Clojure, Winter 2010, I'll take suggestions

12:33 bsteuber: does anyone know how to write EOF or make (read) stop somehow using slime?

12:49 cemerick: Can I get a smattering of problem domains to add to the survey? e.g. Math / analytics, gaming, web development, network programming, etc etc

12:51 chouser: device drivers, process scheduling, memory cache hit optimization

12:52 er, wait.

12:52 cemerick: dammit, chouser, do you have a native Clojure backend that you're not sharing? :-P

12:52 chouser: :-)

12:52 p;/-p;/9ik,m786890p-------------------~

12:52 cemerick: sly, cheeky bastard chouser is ;-)

12:53 bartj: __fogus__: Regarding that link - http://therighttool.hammerprinciple.com/languages/clojure, shouldn't "Ranked highly in" and "Ranked Low in" mean "advantages" / "disadvantages"?

12:54 __fogus__: if yes, how come verbosity is shown as a disadvantage!

12:59 KirinDave / chouser: thanks for the help before, I had to rush out before...

13:04 Licenser_: does anyone know how I can force a swing jtree to update a certain path/node or itself entirely?

13:04 TimMc: bartj: The problem is that not all statements can be classified cleanly as "positive" or "negative".

13:09 cemerick: OK, any thoughts before I post this?

13:09 http://spreadsheets.google.com/embeddedform?formkey=dDVXY0ZfWlNfdXl0TW43S3dJcTFvU1E6MQ

13:11 LaPingvino: hello

13:12 TimMc: cemerick: "if using at work" needs a third option

13:12 cemerick: TimMc: which is?

13:12 TimMc: Should be "Are you using Clojure at work? : No ; Yes, endorsed ; Yes, secretly"

13:12 Most browsers do not let users unclick a radio button set.

13:13 cemerick: yeah, OK

13:13 TimMc: (Also, people will abandon a survey if they think they can't answer one of the questions & think it is required.)

13:14 cemerick: thanks, changed

13:15 any other feedback? Going once, going twice...

13:17 TimMc: hrm

13:17 mabes: cemerick: it might be interesting to take an editor survey as well..

13:17 TimMc: Wording on primary langauge is a little weird.

13:17 Previous primary, or last language used on a project?

13:20 cemerick: mabes: yeah, good.

13:20 Probably the last question I'll add. Don't want the thing to fall over.

13:21 bartj: cemerick: is it possible to have a "grid" of check boxes instead of a very long list for the question - "If Clojure disappeared tomorrow, what would you use as a "replacement"?"

13:21 cemerick: bartj: I looked, and it doesn't appear to be possible.

13:22 it'll be the last question, so as to not scare people away

13:23 mabes: cemerick: it might be interesting/worthwhile to distinguish web application development from web services development... I'm willing to bet more people use clojure more for APIs than for sites.

13:24 bartj: cemerick: perhaps include a question on the documentation? not sure what though...since blogs serve as the most important "documentation" right now for me.

13:26 cemerick: mabes: those are some fine hairs to split, insofar as a lot of people do both

13:27 mabes: yeah, it is probably fine as is

13:28 pedroteixeira: hello, anyone knows if there is a version of compojure works with clojure+contrib 1.2-master?

13:28 bartj: most of the questions seem inclined towards - "where" are you using Clojure? not sure if the title is apt...

13:29 jfields: if I'm in a function is there a way to print the name of the function that called me? (or the entire call stack?)

13:29 cemerick: bartj: that's a little bit of the point, no? Where is clojure being used, and where did its users come from, etc.

13:32 mabes: jfields: perhaps trace could help: http://richhickey.github.com/clojure-contrib/trace-api.html

13:32 rhickey: , (map str (.getStackTrace (Thread/currentThread)))

13:32 clojurebot: ("java.lang.Thread.getStackTrace(Thread.java:1426)" "sandbox$eval__8474.invoke(NO_SOURCE_FILE:0)" "clojure.lang.Compiler.eval(Compiler.java:5343)" "clojure.lang.Compiler.eval(Compiler.java:5311)" "clojure.core$eval__4350.invoke(core.clj:2364)" "hiredman.sandbox$cond_eval__4040.invoke(sandbox.clj:76)" "hiredman.sandbox$eval_in_box_helper__4065.invoke(sandbox.clj:112)" "hiredman.sandbox$eval_in_box__4070$thunk__4073.invoke(s

13:33 mabes: or that :)

13:33 jfields: rhickey, mabes: thanks

13:36 rhickey: jfields: in nested clojure calls, .getClass of the stack trace element is pretty useful:

13:36 (defn foo [] (map #(.getClassName %) (.getStackTrace (Thread/currentThread))))

13:36 (defn bar [] (foo))

13:36 (defn baz [] (bar))

13:36 (baz)

13:36 ("java.lang.Thread" "user$foo" "user$bar" "user$baz" "user$eval128" ...)

13:37 jfields: rhickey, cool. that was what I was looking for. thanks.

13:38 rhickey: np

13:42 riddochc: rhickey: has my contributor agreement arrived?

13:43 rhickey: riddochc: haven't looked at the box in a few days, will soon

13:47 bartj: cemerick: Tracing your Clojure Beginnings - A Survey

13:49 riddochc: rhickey: Then it's probably there. Thanks. I look forward to helping out with stuff.

13:53 KirinDave: pedroteixeira: It doesn't work?

13:57 pedroteixeira: KirinDave: thanks.. it is actually congomongo the problem. thought was compojure. testing between over 5 forks out there in clojars now :)

13:57 KirinDave: pedroteixeira: Just use the main one.

13:58 Don't mess around with the forks, they're often weird

13:58 jfields: (I'm working with some legacy code...) Is there a way to access private fields of a java object instance?

13:59 pedroteixeira: KirinDave: my team members (used to java) are finding it difficult to choose which version to pick from clojars. the problem is congomongo and the new contrib json now.

14:00 KirinDave: the main congomongo does not accept "sort" in the fetch function.. only rads` seem to.

14:00 TimMc: cemerick: Is the survey "public" now?

14:00 cemerick: TimMc: yes: http://twitter.com/cemerick/statuses/15267220072

14:00 and posted to the google group

14:02 hugod: cemerick: can we see the results?

14:03 cemerick: hugod: I figured I'd keep them wrapped until I close the form. Seems like it's just begging for gaming.

14:03 hugod: :)

14:03 cemerick: like, all three emacs users writing scripts to drive up the counts! ;-)

14:03 :-D

14:03 mabes: jfields: I've never needed to do that, but I believe that is what wall-hack-field and wall-hack-method are for: http://richhickey.github.com/clojure-contrib/java-utils-api.html

14:04 ,(doc wall-hack-field)

14:04 clojurebot: "clojure.contrib.java-utils/wall-hack-field;[[class-name field-name obj]]; Access to private or protected field."

14:05 TimMc: Awesome name.

14:07 jfields: mabes: thanks

14:08 bartj: cemerick: "state of clojure" form duly filled in

14:09 cemerick: bartj: thanks much :-)

14:10 mabes, jfields: the wall-hack fns there are actually deprecated I believe, moved here: http://richhickey.github.com/clojure-contrib/reflect-api.html

14:11 mabes: yeah, so depending on what version of clojure you are on.. for 1.1 use java-utils, but for 1.2 use the ones in reflect

14:11 well, version of c..c

14:12 * riddochc takes the survey, and is stuck on what to say for the most glaring problem.

14:12 jfields: cemerick, mabes: cool, thanks

14:13 chouser: ,(first "\n")

14:13 clojurebot: \newline

14:13 chouser: ,(second "\newline")

14:13 clojurebot: \e

14:14 chouser: riddochc: how about that for "most glaring"? :-)

14:15 LauJensen: cemerick: I think question #3 should be "In which domains are you using Clojure", correct?

14:15 riddochc: chouser: Yeah, that one's pretty weird.

14:15 * riddochc finishes the survey.

14:16 riddochc: Back later. Have fun clojuring.

14:18 cemerick: LauJensen: Yup, that'd be more correct. Will fix.

14:18 rhickey: cemerick: where are the results?

14:21 cemerick: rhickey: I figured I'd keep them closed for a while, anyway -- seems like a starting gun for gaming things

14:21 rhickey: cemerick: ok

14:23 zakwilson: http://gist.github.com/418631 <-- I'm having trouble getting full performance out of a quad-core machine. I got some interesting feedback on the google group, but no closer to my code running faster on four cores than two.

14:24 bartj: is it possible to have some sort of rating system for libraries on clojars like search.cpan.org for perl modules

14:25 KirinDave: bartj: maven?

14:27 bartj: KirinDave: eg: http://search.cpan.org/search?q=xml;s=0 (I almost immediately know to use XML::Twig for parsing xml files) based on the rating

14:33 zakwilson: I'm not sure how to answer some of these Clojure survey questions when I'm working on something that I intend to make a startup out of, but currently isn't anything that formal.

14:35 * zakwilson is calling that "use at work".

14:40 cemerick: zakwilson: yeah, I'd call that "at work", commercial product/service

14:41 islon: is there raw strings in clojure? or do i have to escape every double quote?

14:42 * zakwilson called it that in part because at-work/primary-language/in-the-open responses could be good for Clojure's future.

14:44 TimMc: zakwilson: But be honest...

14:46 chouser: islon: escape all double-quotes, unfortunately

14:46 or read it from a file of course

14:47 cemerick: mmm, a perennial wish-list item

14:47 islon: ok, i'll use a file

14:47 TimMc: Are there LISPs with heredocs?

14:48 islon: a reader macro would be good

14:58 cemerick: TimMc: I'm sure there's a CL reader macro somewhere for them. c.c.strint is the closest there is here.

14:59 rubydiamond: hi guys..

14:59 is Clojure, an object oriented programing language

15:00 I read Clojure is not Object Oriented ..

15:00 rys: lol

15:00 cemerick: rubydiamond: this is a subject of great debate :-)

15:01 you can create Java objects from clojure, and you can define new Java classes in clojure

15:01 rubydiamond: cemerick: but that is not clojure right

15:01 cemerick: rubydiamond: sure, it is

15:01 (defrecord Foo [a b]) defines a new class with two fields

15:02 rubydiamond: cemerick: but Clojure is functional language right

15:02 rys: I think the ability to interact with Java doesn't make it an OO language by any means. You could choose never to do so, by design

15:02 nDuff: rubydiamond, LISPs are traditionally so flexible you can define your choice of object systems within them.

15:02 rubydiamond, ...and this is no different with Clojure.

15:02 cemerick: rubydiamond: indeed

15:02 rubydiamond: rys: that's what I meant

15:02 cemerick: rubydiamond: it's probably most important to not get tied up in the semantics of "object oriented" and "functional", etc.

15:03 rubydiamond: omg, defrecord for class

15:03 cemerick: or deftype or gen-class -- each with different capabilities and interop knobs

15:04 nDuff: rubydiamond, ...see for instance CLOS, the Common LISP Object System. I'd argue that whether the existance of CLOS makes the question of whether Common LISP is object oriented irrelevant; you can write OO code with it, or you can choose not to do so, as appropriate for your situation.

15:05 rubydiamond: btw if I know Lisp.. does it mean.. that I can learn Clojure faster

15:06 _fogus_: Was it chouser who said, "Clojure is not object-oriented, but oriented around objects"?

15:06 cemerick: that's nice

15:06 rubydiamond: you'll certainly have a leg up on a lot of concepts

15:06 chouser: yes, but not enough faster to warrant learning Common Lisp, unless you have some other reason to do so.

15:08 rubydiamond: chouser: "Clojure is not object-oriented, but oriented around objects" lol

15:17 rys: I guess it is short sighted to equate OO with imperative programming against mutable state

15:17 zakwilson: I'd point everyone toward SICP, which uses Scheme if they haven't already worked through it. Of course, SICP + Clojure will take longer than Clojure by itself.

15:17 Allan Kay would consider that a mistake, rys.

15:17 rys: Yeah

15:18 I hang my head for the 'lol'

15:19 mebaran151: well OO is usually just about mutable state

15:19 zakwilson: His idea of what OO means has more to do with message passing than anything else. Clojure's reference types support a form of it.

15:19 mebaran151: at least simula 1 style

15:22 zakwilson: None of this matters much though. Clojure is what it is, regardless of what you call it.

15:22 cemerick: yeah, like I said, it's probably most important to not get tied up in the semantics

15:45 hugod: chouser: I found my defrecord problem - an aot class file in the classpath - defrecord silently fails in this case

15:45 chouser: hm.

15:52 islon: to the guy who made the clojure.contrib.sql: why not create a "with-query-result" or "with-single-result" to return a single result? its a pretty common pattern

16:14 mebaran151: Did anyone ever do real OO style programming with just closures in Clojure?

16:15 Licenser: cookies!

16:15 mebaran151: where instance variables were stored as locals?

16:16 I played with writing a couple macros, that now seem to have been subsumed into defrecord. Other than Java interop, what would have been the disadvantages of representing as objects in terms of functions?

16:16 lancepantz: i've seen it done in other lisps, but not clojure

16:17 mebaran151: that's probably because other lisps didn't have easy built-in hashtables

16:17 KirinDave: mebaran151: They don't?

16:18 mebaran151: I'm assuming, because very function compiled to a class, this method probably woudl be just as fast as defrecord and deftype, except with much worse names and therefore worse dispatching

16:18 not with builtin syntax, like in Clojure

16:18 KirinDave: mebaran151: The protocol-based dispatch is much faster than the generic dispatch.

16:18 mebaran151: Yeha, well most code did use that syntax tho

16:19 it just wasn't in the standard.

16:19 I think nearly everyone did something like: http://frank.kank.net/essays/hash.html

16:19 We don't get reader macros in clojure, unfortunately.

16:20 mebaran151: oh I didn't know

16:20 KirinDave: Yeah

16:20 Scheme and Common Lisp allow for reader macros

16:20 mebaran151: I don't know about scheme, but I know sbcl had defstruct

16:20 KirinDave: So basically you can really have any syntax you wan

16:20 You could make an algol reader macro ;)

16:21 So I think it's also true in sbcl

16:21 mebaran151: I never actually was able to use any lisps for serious programming before, so the most I did was dabble before Clojure

16:21 KirinDave: But defrecord/deftype are making distinct types to dispatch upon.

16:21 If you use a function to do it, that works, but it doesn't have any type system stuff and thus loses a bit.

16:21 mebaran151: well assuming you didn't redefine it at the REPL, would you dispatch on a function type, though the name is really nasty?

16:22 KirinDave: But that wouldn't be terribly helpful to the compiler.

16:22 mebaran151: and maybe write some macros to work with it like a java object

16:22 KirinDave: Both SBCL and Clojure can do a hell of a lot more if you use defined objects rather than fns or hash tbales.

16:22 The compiler and jits can actually make things equivalent to offset in C in the best case. SBCL frequently does this

16:22 mebaran151: I'm not saying it should be done, I'm just saying it was theoretically possible

16:22 KirinDave: Yes

16:22 Have you read the scheme paper?

16:23 mebaran151: which?

16:23 KirinDave: The original sussman one, i think

16:23 Closures and Objects are equivalent

16:23 But offer different perspectives with different optimization potential

16:23 mebaran151: I think I learned the style from the SICP, and was reminded from some blog post in recent memoryy

16:24 well you could never make mutable closures right?

16:24 Licenser: aloa my lispy friends!

16:24 mebaran151: locals have to stay local

16:24 KirinDave: I don't understand your question

16:25 And you could make mutable closures in clojure

16:25 mebaran151: in standard oop, usually field mutation is take for granted

16:25 KirinDave: It need not be

16:25 But yes, in common lisp fields in a clojure are mutable.

16:26 Setf will rebind a local just as well

16:26 mebaran151: in a closure?

16:26 ah I didn't know not

16:26 *that

16:26 KirinDave: There is a book, "let over lambda"

16:26 You should check it out.

16:26 if you can successfully finish 2 chapters in that book, ANY two, you will be a better lispologist than most people.

16:27 gregh: I have that book, it's kinda neat

16:27 KirinDave: it's the most insanely dense macro book imaginable

16:30 mebaran151: I really do a need a good macro-fu book

16:30 KirinDave: That book is the fu book

16:31 mebaran151: one of my coworkers is a macro machine, but he came from computational ling, so it was expected

16:31 _fogus_: LOL is amazing

16:31 It will melt your mind

16:31 mebaran151: I often has to spend a lot of unpacking his stuff

16:32 heh, skimming, it looks like a real tome of a macro book

16:36 tomoj: LOL is a book/

16:36 ?

16:37 mebaran151: http://letoverlambda.com/index.cl << it's got an ISBN

16:41 Licenser: _fogus_: I bought JoC the other day :) great book!

16:41 tomoj: and VIP codes? O_o

17:11 raek: when is it idiomatic to use 'rest' and 'next'?

17:12 arohner: raek: when you need to

17:12 raek: sorry for the sarcastic answer. Do you think you're in a situation where it's un-idiomatic?

17:12 islon: next: when testing (if (next coll) stuff other-stuff)

17:12 raek: what I wonder is which should I use?

17:12 islon: next is test-friendly (returns nil on an empty list)

17:13 raek: yes, I know about next calling seq on the result

17:13 so it becomes nil if it empty

17:14 islon: (next [1]) => nil

17:14 raek: I've seen next being used outside tests

17:15 but that was in clojure.core

17:15 maybe rich just replaced all rest calls with next calls when these things changed

17:16 could one consider 'rest' to be the standard choise when nil-on-empty doesn't matter?

17:18 programble: anyone else interested in CSS support in Hiccup?

17:22 ysph: programble: a clojure CCS lib would no doubt be useful, what's the reasoning behind including it within hiccup? just that html and css are strongly coupled?

17:22 programble: yes

17:23 http://github.com/programble/hiccup

17:23 i added in CSS rendering

17:23 and it seems a little too small to stand as its own project

17:23 its only about 20 lines of code

17:30 onkara: hi Guys ... I am having hard time configuring clojure REPL shell with command history and tab completion functionality

17:30 could anyone please point me to a resource that can help with this ... FYI i am on ubuntu-lucid

17:31 hiredman: dunno about tab complete, but rlwrap will get you history

17:31 onkara: and whats the best way to save the code snippets (that have been tested in a shell) to a file

17:32 cemerick: onkara: most good environments (emacs/slime, netbeans/enclojure, and eclipse/ccw) all provide completion

17:33 programble: emacs/slime is great

17:33 arkahn: we need the clojure equivalent of ipython ; )

17:34 technomancy: I think the CLI integration is bad on purpose in order to convince you to get your editor set up more quickly.

17:35 arkahn: it's not a bug, it's a feature, huh? ; )

17:36 onkara: cemerick: ccw is counter clock wise plugin the one hosted at code.google.com ???

17:36 programble: emacs/slime/swank ftw

17:37 Licenser: I'd like to ask if someone could look at some small function ( http://gist.github.com/423027 ) it is meant to find the key that changed in a hash-map (so the lowest when there are multiple changes that holds all of them)

17:37 I know it's not optimized I am just looking for correctness or total stupidity

17:40 KirinDave: Licenser: For starters, do arg validation in pre and post

17:41 Licenser: It'll be way clearer

17:42 TimMc: CCW is pretty grungy.

17:42 KirinDave: Licenser: Secondly, wouldn't a quick first check be to compute the hashcode for each of the maps and compare? You could save a lot of work.

17:44 hiredman: I think pre and post conditions only run when a certain var is bound

17:44 KirinDave: hiredman: ?

17:47 hiredman: clojurebot: git commit 0ac482878a1dd520cbee2faa0f5f6ab1082ffa76

17:47 clojurebot: git 0ac482878a1dd520cbee2faa0f5f6ab1082ffa76

17:47 clojurebot: :pre and :post conditions as metadata on arglist, or map following arglist conditions are predicate exprs in a vector return value of fn is bound to % for :post (defn foo [x y] {:pre [(even? x) (< x y)] :post [(> % 3)]} (* x y)) add *assert*, default true, when not true asserts are no-ops *assert* is bound in repl

17:48 hiredman: so if you always want to validate you can't use :pre and :post

17:48 Licenser: KirinDave: I think = does the hash code stuff

17:48 and I'm not sure what you mean with arg validation

17:49 hiredman: (I'm assuming you mean :pre and :post when you said pre and post)

17:49 ataggart: (defn constrained-sqr [x]

17:49 {:pre [(pos? x)]

17:49 :post [(> % 16), (< % 225)]}

17:49 (* x x))

17:49 Licenser: but I don't want the function break when it is not a map

17:50 ataggart: from http://clojure.org/special_forms

17:50 hiredman: ataggart: yes, and those will only run if *assert* is true

17:50 which it is at the repl, but not other places

17:51 ska2342: Hello. Can someone tell me how I can access the docstring of a method defined in a defprotocol? I only see the doc metadata in the map that is the protocol itself. I'd expect `doc' to just work.

17:52 hiredman: huh

17:53 looks like the default value of *assert* is true

17:53 or root I should say

17:54 ataggart: hiredman: the deeper question is whether such checks are properly assertions or input validation. For the latter a different mechanic would be used

17:55 assertions should be disableable (is that a word?)

17:55 hiredman: well, input validation ittself is a loaded term

17:55 ataggart: true

18:16 cemerick: onkara: yes, ccw is counterclockwise @ google code

18:17 timcharper: can lazy seqs eagerly load in a separate thread ?

18:17 (do they?)

18:18 building a somewhat-long stream pipeline, and would be super sweet if each step of the pipeline could be processed simultaneously

18:20 technomancy: timcharper: you could use futures, but it's not transparent.

18:21 timcharper: ok, willing to abstract here

18:21 how would I go about abstracting a lazy seq to eager load using futures ?

18:22 technomancy: timcharper: just wrap your calculation in (future [...]) and deref it when you want to use it. easy peasy.

18:23 timcharper: ah... so that won't cause the whole lazy seq to load all at once because lazy-seq only reads a few ahead ?

18:23 mebaran151: any tips on setting up a slime environment that can connect to both sbcl and clojure proper?

18:24 timcharper: mebaran151: A) first, use technomancy's starter kit. B) add the proper swank dep to your project using lein

18:25 oh... A2) install swank-clojure from ELPA (via m-x package-list-packages)

18:34 technomancy: so with the future wrapping, not only will each step of my pipeline be processed in parallel, but each iteration of each step will be processed in parallel, right ?

18:35 (my understanding of clojure leads me to that conclusion)

18:35 technomancy: timcharper: think of a future as an agent that you can only set once

18:35 rather than an identity with a series of values over time.

18:35 timcharper: and, one, according to my benchmarks, is much faster than agents

18:36 technomancy: how you consume a seq of futures will determine how things are processed.

18:36 timcharper: awesome, that's a neat trick. Thank you

18:39 onkara: CCW rocks

18:48 cemerick: onkara: oh? What's the best part so far?

18:56 mebaran151: timcharper: I've got a working clojure env with lein swank (and swank-clojure from elpa is officially unsupported based on the net's whisperings)

18:56 I'd like to run some of these examples in let over lambda, but I need SBCL to do so

18:57 vIkSiT: did technomancy post about that somewhere?

18:59 mebaran151: I remember the old days when I could just run m-x slime to get a clojure repl, but modern emacs doesn't like this; slime-connect works fine though

19:03 timcharper: mebaran151: I am using swank-clojure 1.1.0 and clojure-mode 1.7.1. slime-connect works great for both clojure 1.2 and 1.1.

19:03 mebaran151: when I had swank-clojure installed C-c C-k didn't work

19:04 complained about bad arities: I was advised to move to swank-clojure 1.2.0 and launch slime via lein swank

19:04 timcharper: strange... works here

19:04 mebaran151: are you using slime-connect or plain slime?

19:04 timcharper: slime-connect

19:04 mebaran151: slime-connect probably works, because your project is loading a modern swank implementation

19:05 timcharper: for clojure 1.1, I am using this: [leiningen/lein-swank "1.0.0-SNAPSHOT"]

19:05 mebaran151: try just M-x swank-clojure-project

19:05 timcharper: I use that too

19:05 mebaran151: hmm, I got weird Java errors

19:05 timcharper: hmmmm

19:05 mebaran151: oh yeah, what version of slime do you run?

19:05 timcharper: 20091016

19:06 mebaran151: new slime isn't as good as nicely aged slime

19:06 there we go

19:06 now we've got something

19:06 I'm on 20100404

19:06 timcharper: hmmm, I'm seeing I can upgrade. Now that you say it's no bueno, tempted to not

19:07 mebaran151: I had to because I upgraded my workstation

19:07 installed some new Linux love

19:07 Ubuntu Lucid!

19:08 timcharper: hurray for bleeding edges!

19:08 mebaran151: yeah, the upgrade is a little nasty

19:08 timcharper: lol

19:08 mebaran151: new swank though has some cool functions like breakpointing with local variables

19:08 which I like alot

19:08 (swank.core/break) is my friend

19:08 timcharper: _REALLLY_

19:09 that rocks! you don't have to patch clojure for it to work?

19:09 mebaran151: only Clojure 1.2

19:09 has the magic sauce I think

19:09 timcharper: will have to give that a spin. Lack of debugging tools has been somewhat of a sore-spot for clojure

19:09 mebaran151: well it's still not like netbeans, where I'd click a line

19:10 timcharper: does netbeans work though?

19:10 mebaran151: but a real breakpoint line with locals inspection is nice

19:10 timcharper: (I couldn't get it to)

19:10 mebaran151: when netbeans works it works pretty well

19:10 KirinDave: Blog article I'm about to post about clojure and prototypes

19:10 https://gist.github.com/raw/2349be16daab2a02cba6/4a2f3b463b95b97ae696b5083309f81c235376ec/post-draft.txt

19:10 mebaran151: I was on 6.8 before I got addicted to paredit

19:11 timcharper: paredit is great

19:11 mebaran151: the repl was nice and friendly, and java completion _mostly_ worked

19:12 timcharper: have you installed highlight-parens for emacs ?

19:12 mebaran151: yeah I think I have

19:12 timcharper: I really like it

19:12 the end

19:12 mebaran151: but not rainbow-parens

19:12 that was ugly

19:12 well clojure netbeans had highlight parens built in

19:12 decent formatting

19:13 but it was finicky and would often die for reasons I could never resolve

19:13 timcharper: (I use highlight-parens and customized it to be rainbow... looks decent)

19:13 tomoj: whoa.. never saw highlight-parens before. cool!

19:13 timcharper: '(hl-paren-colors (quote ("#ff2244" "#ff7700" "#ffff00" "#00ff00" "#2266ff" "#00aaff" "#ff00ff" "black")))

19:14 mebaran151: I think that Emacs needs a major update, though it's the best editor I've used yet

19:14 it knows how to get out of your way

19:14 it's kind of sad the best editor we have comes from the 70's

19:15 especially for mulitdocument editing, I think it could do better (though I don't know emacs lisp well enough to fix anything)

19:15 timcharper: emacs-lisp, in my opinion, is a terror

19:16 (I've written a few emacs extensions)

19:16 mebaran151: I've often though it might be cool to write an emacs clone in Java and Swing

19:16 *thought

19:16 timcharper: yeah... and clojure ?

19:16 mebaran151: something you could script a little more sanely in Clojure

19:16 yeah, and Clojure

19:17 maybe mostly Clojure, but Swing components are so so brittle

19:17 timcharper: I think an emacs rewrite in clojure would be the coolest thing since sliced bread

19:17 mebaran151: well it wouldn't run emacslisp, because that would be annoying

19:17 timcharper: heh.. it might include an emacs-lisp emulator

19:18 to help with the transition

19:18 KirinDave: It'd be a bad idea

19:18 mebaran151: Clojure really needs a programming envirionment written in Clojure

19:18 timcharper: emacs-lisp is really primitive, it'd be easy to implement an interpreter

19:18 KirinDave: Elisp's biggest limitation is that it thinks about editor things with a very dated model

19:18 buffers, frames, etc

19:18 mebaran151: KirinDave: exactly

19:19 timcharper: KirinDave: But why couldn't you map it?

19:19 tomoj: what's a better model?

19:19 mebaran151: it has no concept of buttons or controls that could make things a lot easier

19:19 tomoj: buttons? pff

19:19 like, ones that you hit with the mouse, I assume?

19:19 mebaran151: or interactive text within text

19:20 timcharper: mebaran151: it has a concept of overlays that have click actions

19:20 mebaran151: oh overlays are interesting

19:20 but not just click, I'm talking about demarcating regions of text and rendering different things appropriately

19:21 tomoj: doesn't emacs demarcate regions of text and render different things appropriately?

19:21 mebaran151: kind of

19:21 vIkSiT: KirinDave, do you have a non raw version of that blogpost?

19:21 mebaran151: I mean everything is in nice terminal 1980's style

19:21 you couldn't exactly create a pretty IDE with Emacs :)

19:21 tomoj: I wonder if I really like it that way

19:22 I certainly _feel_ like I wouldn't want the clojure-scriptable editor to be a pretty IDE

19:22 but maybe emacs has just brainwashed me

19:22 timcharper: yes: I prefer a scriptable editor that has IDE-like components. Editor first.

19:22 mebaran151: that's probalby the only thing TextMate got right

19:22 timcharper: by IDE-like components I mean extensions

19:23 TextMate got many things right

19:23 mebaran151: I was also thinking of a IDE that edited code rather than files

19:23 kidn of like smalltalk

19:23 that could perhaps just export the project

19:23 into something that lein or maven would jar up

19:24 instead of representing everything in terms of files, it would work in terms of a program graph, and you'd manipulate that tree, like a pervasive version of paredit

19:25 you could do ns refactors and stuff like that

19:25 timcharper: and then all of your source control systems would work marvelously with it

19:26 mebaran151: well save would be bound to export as files

19:26 tomoj: I don't see the point in ignoring the code<->file mapping while editing, especially since it's a pretty simple mapping in clojure

19:26 vIkSiT: hmm has anyone here used defrecord?

19:27 mebaran151: for one thing makes merging harder

19:27 vIkSiT: http://paste.lisp.org/display/111083

19:27 How do I get my push function to return a record of type FStack?

19:27 timcharper: I think a Text Editor that can understand the language syntax (as with lisps) is a better way to go.

19:27 tomoj: yeah

19:28 I think we need a cleaner compiler

19:29 mebaran151: I think most version control systems suck because they don't understand what they're comparing

19:29 it's bytes to bytes

19:29 where as if they were merging syntax trees, lots of things might make more sense

19:29 timcharper: is there any reason you couldn't extend a source control system to understand syntax trees when resolving conflicts?

19:29 tomoj: but can't we merge syntax trees anyway without pretending code isn't in files?

19:30 mebaran151: timcharper: I once decided I'd hack mercurial: I failed

19:30 tomoj: merging syntax trees sounds pretty dangerous to me

19:30 timcharper: if you have a specialized source control system, it will be great for that code, but generally suck for everything else

19:30 mebaran151: tomoj: merging syntax trees sounds like the lisp macro way of handling merges

19:30 where as straight merging is more like a C preprocessor

19:30 that blindly smashes text

19:30 tomoj: except I think it's very likely the merge results will usually not make any sense

19:31 mebaran151: why would it make any more or less sense than a merge that worked on bytes?

19:31 technomancy: once threads get merged to mainline, Emacs bytecode could be a semi-reasonable Clojure compilation target. way easier than a rewrite.

19:31 tomoj: merging diverging histories of a lisp form correctly (so that the lisp program actually does something useful) seems like a problem for humans

19:31 * technomancy wanders off

19:32 mebaran151: tomoj: I at least think the diff program might be easier to work with

19:32 I find myself usually blindly clicking my way through merges

19:32 timcharper: mebaran151: agreed: the suggested merges would be easier to understand. But I still think you can use an underlying SCM, such as git, to achieve such an end. git-merge-tool, for example, allows you to specify a custom merge resolution tool

19:32 mebaran151: getting a bad file, and then taking the old file, merging it by hand by copy and paste, and resubmitting that file as the Final one

19:33 timcharper: it could be done with the current flexibility of git

19:33 tomoj: it bugs me that mvn clojure:swank tries to compile stuff

19:33 timcharper: tomoj: try lein swank ?

19:34 tomoj: :P

19:34 timcharper: (git was originally meant to be a platform which you could use to develop an SCM)

19:34 mebaran151: timcharper: I'm not git expert: we usually use mercurial over where I work

19:34 timcharper: several emerged, and then one of them became standard

19:35 mebaran151: so sorry...

19:35 mebaran151: because of some windows developer guys; git used to be hell to make run on Windows

19:35 timcharper: :)

19:35 mebaran151: hg is pretty good, actually

19:35 timcharper: (I kid, I kid... I know

19:35 )

19:35 mebaran151: heh

19:35 timcharper: I started out with git and have devoted time to learning it inside out. I really love it, but understand it has it's warts.

19:36 mebaran151: still, an editor shouldn't need to use files for everything

19:36 you could emulate that behavior with a sufficiently clever version of save as

19:37 one should save a project rather than a file

19:39 Licenser: what is wrong with this code:

19:39 ,(update-in {1 2 3 4} [] assoc 3 5)

19:39 clojurebot: {nil {3 5}, 1 2, 3 4}

19:39 tomoj: vIkSiT: still stuck?

19:39 Licenser: shouldn't that be {1 2 3 5}

19:39 mebaran151: if you kept track of the version of entities rather than of tiles

19:39 vIkSiT: tomoj, yea :)

19:39 mebaran151: you could mix and match the old and the new

19:39 tomoj: you have "Fstack." instead of "FStack."

19:40 mebaran151: maybe even pull up old versions for a visit to see what got broken

19:41 tomoj: Licenser: what exactly are you trying to do?

19:41 if you want {1 2 3 4} -> {1 2 3 5}, why not just (assoc m 3 5) ?

19:41 Licenser: update a map by a given path that does not work if the path is empty

19:41 I think that is a bug in update-in

19:41 unless there is some special thought of that

19:41 vIkSiT: tomoj, *ARGH*

19:41 tomoj: yeah, seems like it should error out

19:41 vIkSiT: thanks :)

19:41 Licenser: tomoj:

19:42 ,(get-in {1 2 3 4} [])

19:42 clojurebot: {1 2, 3 4}

19:42 Licenser: acts as expected

19:42 tomoj: that's not really what I would expect

19:42 well, yeah, I guess it makes sense

19:43 Licenser: seen the source for update-in?

19:43 Licenser: nope

19:43 tomoj: it is assumed that you will pass at least one key

19:43 Licenser: hmm

19:43 tomoj: it destructures the path like [k & ks]

19:44 and checks whether ks is nil or not to decide whether to recur

19:44 but for you, k is nil, so

19:45 Licenser: hmm yes but it is kind of not intuitive

19:45 in my eyes at least

19:45 tomoj: doing anything at all with [] seems unintuitive to me

19:45 you think it should pass the whole map to your function, I guess?

19:46 again I guess that does make sense.. :)

19:46 just never thought about it before

19:50 vIkSiT: hmm how would a purely functional pop work?

19:50 (w.r.t stack)

19:51 should it return the value of the popped element, or should it return the changed stack?

19:51 tomoj: you need two functions

19:51 (or return both, but..)

19:51 vIkSiT: like a "top" and "pop"?

19:51 tomoj: yes, like first and next :P

19:52 vIkSiT: hehe but how do you return *two* things?

19:52 tomoj: in a vector or something

19:52 but that's ugly

19:52 vIkSiT: urgh, thats ugly

19:52 tomoj: lists are already stacks, aren't they?

19:52 vIkSiT: hmm

19:53 yes they should be

19:53 Licenser: tomoj: it is about when you don't have a fixed path you want but one that is passed or constructed

19:53 vIkSiT: and the behavior there is to return the (rest coll)

19:53 tomoj: Licenser: yeah, it just took me a while to understand, but I think you're right

19:53 Licenser: tomoj: or at least make get-in behave the same :P

19:53 tomoj: vIkSiT: but we also have first

19:53 Licenser: because it is really confusing otherwise

19:55 tomoj: vIkSiT: push pop peek, maybe?

19:55 vIkSiT: yes, I've got push, pop working

19:55 now to figure out peek

19:55 as in, for the other two I can do (swap! my-stack push val) and (swap! my-stack pop)

19:56 wrapped the stack around an atom

19:56 but peek is read only

19:56 mebaran151: you know, vectors already implement peek pop and push (under conj)

19:56 tomoj: is this just an exercise in protocols/records? just curious

19:56 vIkSiT: and If I use swap there, its going to override my stack with the top value!

19:56 mebaran151: it might be weird you start from the bottom, but I don't see any problem with that

19:57 tomoj: vIkSiT: just peek before you swap, then

19:57 vIkSiT: oh yes, its an exercise.. I'm going through Okasaki's purely functional data structures

19:57 tomoj: ah, cool, then

19:57 are inductive graphs in there, I wonder?

20:01 wouldn't it be cool if there were an easy way to proxy all of an interface's methods to a field of a deftype?

20:02 hiredman: if you have your queue in a ref, then you can compose multiple operations peek/pop/etc in a transaction

20:02 tomoj: macro

20:03 oh

20:04 tomoj: oh, with an atom, I guess there is no way to peek+pop atomically?

20:05 (unless you do something silly like a function which returns a vector tuple with the first/next..)

20:06 vIkSiT: ah, I guess I could convert that to a ref

20:19 if only Okasaki used lisp to implement the structures in his book :)

20:19 tomoj: what is it, haskell? ML?

20:22 vIkSiT: both actually

20:23 print version has ML, and addendum with Haskell code

20:24 tomoj: ah

20:24 yeah the paper about inductive graphs I found is haskell, too

20:24 pain to translate

20:25 vIkSiT: I've had to jump into SML for that

21:23 lancepantz: anyone know of a function in core that is similar to filter, but will return two collections, one for which the predicate is true, the other false?

21:26 looks like group-by is what i want

21:31 AntonyBlakey: anyone know why this:

21:31 (defmacro action-guard [name]

21:31 (let [method-name (symbol (str "can-" name))]

21:31 `(do

21:31 (defmulti ~method-name (fn [ctx# module#] (-> module# :workflow :state)))

21:31 (defmethod ~method-name [ctx# module#] false))))

21:31 (doseq [x '[edit reassign submit approve reject reedit delete]] (action-guard x))

21:31 fails with: "Unable to resolve symbol: ctx__3472__auto__ in this context" in the doseq ?

21:33 (regardless of the missing :default dispatch value on the defmethod)

21:43 Ah, stupid me. :default in the wrong spot in the defmethod.

21:54 ataggart: lancepantz: split-with

22:09 arohner: in compojure 0.3, there was a function url-params. Does anyone know where that went in ring / compojure 0.4-land?

22:11 Raynes: arohner: What did it do?

22:12 dsantiago: arohner, I think it is not in 0.4, but it should probably be in hiccup.page-helpers.

22:12 arohner: Raynes: it constructed the URL parameters for a link, given a map i.e. (url-params "google.com" {:a 1 :b 2})) => "google.com?a=1&b=2"

22:13 dsantiago: I'd email James Reeves and say you want it. :)

22:13 AntonyBlakey: There was a library published recently with generic url-construction facilities

22:14 arohner: AntonyBlakey: do you know the name of it?

22:14 AntonyBlakey: just looking in planet clojure

22:15 Raynes: arohner: I wrote a function for that a few days go and put it in clojure-http-client. It's small, and I believe Phil renamed it to add-url-params or something similar. You can steal it if you'd like.

22:15 AntonyBlakey: http://github.com/paraseba/resource-url

22:15 arohner: Raynes: thanks. I'll probably just pull the fn out of compojure 0.3.2 and publish a patch for hiccup

22:16 Raynes: Not sure it belongs in hiccup. Maybe you should ask weevy why he removed it and throw it into ring or something.

22:17 arohner: AntonyBlakey: interesting. thanks

22:18 dsantiago: Yeah, in my experience some things were just lost in the reorganization. He's been pretty responsive about putting things back in.

22:18 I'm not really sure why you want that function, if not to generate a URL for a link. It was in page-helpers in 0.3.

23:22 redalastor: I'm looking for the name of a function I know exists. It takes a function and value, applies the function to the value and applies the function again to the result of that, lather, rinse, repeat.

23:29 tomoj: iterate?

23:29 redalastor: Yes!

23:29 Thanks

Logging service provided by n01se.net