#clojure log - Dec 18 2011

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

0:00 accel: how many animals do I need to sacrifice to ensure that in the comman dline, I can press <UPARROW> instead of typing (load-file "main.clj") every time? right now, UPARROW gives me ^[[A or something like that

0:01 dmansen: how are you launching your REPL?

0:02 accel: java clojure.main

0:02 I'm on OSX


0:02 *deers in the area run away in fear*

0:02 *elephants bow down in awe*

0:02 *Scar looks on from the distance and snickers.*

0:02 dmansen: yeah, you gotta wrap that in jline

0:02 lemme look this up

0:02 accel: jline: command not found

0:03 dmansen: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_JLine

0:03 gotta grab the jar and such

0:03 accel: noted; thanks

0:04 dmansen: using leiningen is also nice and easier - i'd recommend that

0:04 http://riddell.us/ClojureSwankLeiningenWithEmacsOnLinux.html

0:04 lazybot: The riddell.us tutorials are much more highly-ranked on Google than they deserve to be. They're old and way too complicated. If you're trying to install Clojure...don't! Instead, install Leiningen (https://github.com/technomancy/leiningen/tree/stable) and let it manage Clojure for you.

0:04 dmansen: oh

0:04 am i being outdated? hahah

0:04 accel: I have this philosophy in life:

0:05 I should learn how to crawl before I jump into a F15

0:05 still playing with the repl / java paths for now

0:05 dmansen: it's not a bad idea

0:05 jline will make it bearable

0:08 accel: i have to admit

0:08 java has the best libraries ever

0:08 dmansen: i hate to admit that as well, but it's the truth

0:08 accel: i've been writing this application since earlier today

0:08 and every library I needed

0:08 at my finger tip

0:09 dmansen: the clojure interop makes it so nice

0:09 accel: no ./configure && make && curse at incompatible versions

0:09 dmansen: the missing link

0:09 accel: shit just works

0:09 it's amazing

0:09 dmansen: that's why they say "joy of clojure"

0:09 it's really fun

0:12 devn: anyone here use parsatron?

0:14 amalloy: jline is terrible. if you really can't bear to spend two minutes installing lein, then use readline; jline is not an enjoyable substitute

0:15 rlwrap <whatever command you were running before>

0:16 devn: (run (between (char \() (char \)) (>> (char \+) (char \space) (many1 (letter)) (char \space) (many1 (letter)))) "(+ test case)")

0:16 accel: what is clojure's repelacemnt of "begin" ?

0:17 devn: (run (between (char \() (char \)) (many1 (any-char))) "(+ test case)")

0:17 i wonder why one passes and the other succeeds...

0:17 accel: like, ruby begin?

0:17 duck1123: accel: if you mean begin as in begin escue end, try

0:17 devn: ^-

0:17 duck1123: try and catch to be presise

0:17 devn: and finally

0:18 * amalloy will bet a dollar he means scheme 'begin, and wants 'do

0:18 dmansen: i think that too

0:18 first thing i thought

0:18 devn: ,(do (+ 1 1) (/ 1 3))

0:18 clojurebot: 1/3

0:18 amalloy: $findfn 'stuff 'more-stuff 'result 'result

0:18 lazybot: [clojure.core/get clojure.core/trampoline]

0:19 amalloy: oh right, do isn't a function, so he doesn't try it

0:19 trampoline, though. good joke, lazybot

0:19 jsnikeris: anyone know why the latest release of ClojureQL (1.0.2) isn't in Clojars?

0:20 amalloy: if it's not in clojars, it's not the latest release?

0:20 devn: jsnikeris: i haven't a clue

0:21 accel: amalloy: you win; it's "do"

0:21 duck1123: good try

0:22 devn: what, no honorable mention?

0:22 amalloy: seriously though, jsnikeris, if it's no in clojars it isn't released. if you're getting the version number from their github project.clj, then presumably that's the version that's being worked on

0:23 jsnikeris: strangely the github page's README.md says the most recent release is 1.0.2, but clojureql.org states 1.0.0

0:23 amalloy: though actually i see even their readme says to use that version

0:24 jsnikeris: well, lau probably owns clojureql.org, and he hasn't done any clojure for quite some time

0:24 jsnikeris: ah OK

0:24 amalloy: bendlas is maintaining cql; you should probably ask him on github what the deal is

0:24 since the readme shouldn't suggest a version that doesn't exist

0:25 * devn misses Lau

0:25 duck1123: whatever happened to him?

0:25 jsnikeris: I was under the impression that Lau just did a complete rewrite of clojureql

0:26 amalloy: "just" about a year ago

0:27 devn: http://zef.me/2637/on-language-design-my-problem-with-clojureql

0:27 Update: Since this post, ClojureQL has been completely redesigned, my criticism in this post no longer applies.

0:27 jsnikeris: ah gotcha

0:27 devn: jsnikeris: have you checked out sqlkorma>

0:27 jsnikeris: I have not

0:28 devn: http://sqlkorma.com/

0:28 technomancy_: duck1123: he got on rich's bad side

0:28 accel: goofing around has been fun and all that

0:28 but now I neex ot get serous

0:28 duck1123: korma is very nice and a natural way to do sql in clojure

0:28 accel: and split my clojure prog

0:28 across multiple files

0:28 fielcabral: Hi I just cloned ClojureScript and run script/bootstrap. Should it be possible to run (require '[goog.string :as gstring]) in the REPL provided by script/repljs?

0:28 accel: can someone sugest some docummnentation?

0:28 ihodes: hmmm. trying to figure out the best way to do this. so I have this LinkedBlockingQueue, and I have a function that wants to `add` to it as long as it can in one thread, and in another thread i want to pop from it and do something with that value, indefinitely. what's a good way of doing this? just dispatching the producer function to another thread?

0:29 devn: accel: about using namespaces?

0:29 accel: is that what seprate files are called?

0:29 namespaces?

0:29 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

0:29 devn: http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

0:29 amalloy: ihodes: sounds like ##(doc seque)

0:29 lazybot: ⇒ "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent... https://gist.github.com/1492466

0:30 devn: amalloy: you write some beautiful clojure on 4clojure

0:30 jsnikeris: devn: I kind of like how stays close to the relational model

0:30 devn: im "following" you on there now, redoing old problems

0:30 amalloy: devn: thanks! which problem were you looking at just now

0:30 devn: jsnikeris: *nod* -- it's very well done

0:31 accel: devn: require looks awesome

0:31 amalloy: (side note: some of my solutions look like total crap because i input someone else's solution to repro a bug they were having)

0:31 devn: amalloy: it was a series of them. I'm helping a friend learn clojure so i've been re-solving problems with him

0:31 we're following you and there are some beauties

0:31 jsnikeris: devn: should have had a clojureql in that last comment

0:31 amalloy: i think my favorite is Beauty Is Symmetry

0:32 devn: amalloy: which number is that?

0:32 accel: is "use" equiv to "require blah :as '' " ?

0:32 ihodes: amalloy: that would work... nice. thanks. still things in 1.0 i don't know about...sigh.

0:32 accel: i.e. require :as <empty string>

0:33 amalloy: devn: 50-something, i think

0:33 $google 4clojure beauty symmetry

0:33 lazybot: [96. Beauty is Symmetry - 4clojure] http://4clojure.com/problem/96

0:33 amalloy: factor of 2. not bad

0:33 devn: accel: no. (:require [foo.core :as f]) would mean that throughout your program you (f/fn args) in order to call foo.core/* functions

0:33 accel: if you (:use [foo.core]), you would (fn args)

0:34 accel: but using means it can overwrite a local definition of (fn).

0:34 amalloy: accel: yes, it's a lot like requiring as the empty string, if that were possible

0:35 ihodes: amalloy: except it's returning a seq, which means i can't really peek/pop/.take

0:35 devn: amalloy: am i confusing his question again with something in scheme?

0:35 require :as is not the same as :use -- when you say 'yes', what are you referring to?

0:35 amalloy: ihodes: you don't need to, just map or doseq your side-effecty function over the seq produced by seque; it will block as long as necessary

0:36 devn: he asked if :use is kinda like :require with an empty prefix

0:36 devn: d'oh, i see now. :X

0:37 i assumed it was the old use/require question.

0:39 amalloy: heh, 96 is interesting indeed

0:39 ihodes: amalloy: excellent!

0:40 choffstein: Can anyone help me with a weird error I am getting? https://gist.github.com/1492480

0:40 I don't understand why I am getting the ArityException I am with my assoc usage

0:42 amalloy: incanter probably defines another function called assoc that behaves differently

0:42 choffstein: …that would make sense

0:42 and this is why I shouldn't code at night

0:43 amalloy: also, those flattens are horrible

0:43 ~flatten

0:43 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

0:43 choffstein: …but they do exactly what I want :D

0:44 devn: amalloy_: everything was going along just fine until i hit the vectors

0:48 fielcabral: "require" question for ClojureScript: Can I (require '[goog.string :as gstring]) in ClojureScript's script/repljs REPL? (https://gist.github.com/1492486)

1:23 accel: A = code works. B = A, except a function foo is moved into another namespace. B does not work (i.e. in the GUI, I end up drawing a blank box instead of drawing pictures). Java does not throw any errors (everything is properly imported). I can't figure out what's going on -- unless there's some library I'm used, which is loaded twice, and their internal state is conflictgin?

1:33 technomancy_: you guys

1:33 I am very excited

1:33 clj-stacktrace in swank.

1:33 dmansen: hey

1:33 technomancy_: squeeeeeeeeee

1:33 dmansen: nice work =)

1:33 dmansen: i have really enjoyed modifying this

1:34 i should be going to bed, but this is a lot of fun

1:34 technomancy_: I'll let it simmer a while and then cut a release maybe at the end of the week if no issues are reported.

1:34 dmansen: excellent

1:35 technomancy_: I love it when you're expecting something to be this big burden, and then when it's done you discover it was much simpler than you were expecting.

1:35 even better when someone else does it for you =)

1:35 but I better head off too; see you later.

1:35 thanks

1:35 leo2007: technomancy_: what does clj-stacktrace for swank do?

1:36 dmansen: it makes the stacktraces print prettier

1:40 accel: DAMN IT

1:40 I found my BUG :-)

1:40 suppose foo/dog.clj depends on foo/cat.clj

1:40 (load-file "foo.dog.clj") does NOT reload "foo/cat.clj"

1:41 even if "foo/cat.clj" has changed

1:41 how do I tell clojure to do a

1:41 (load-file-and=-load-all-dependences-that-have-changed "foo/dog.clj") ?

1:54 alright

1:54 so on the web

1:55 I keep on finding documentation on defrecord

1:55 however, I want mutable fields

1:55 is there a good example of how to use deftype

1:55 (and setting the fileds) anywhere?

2:01 alright; so I have

2:01 duck1123: accel: for the first question of the reloading, try adding a :reload-all flag in your require block

2:01 as for the "i want mutable fields" you probably don't actually

2:01 accel: (deftype Bar [a b c d e]); (def b (Bar 1 2 3 4 5)); now, how do I set field :c of b ?

2:02 duck1123: you're probably right; what do I wnat instead?

2:02 duck1123: well, if you go with defrecord, you have a type that has all the powers of a map

2:03 so (let [b (Bar. 1 2 3 4 5)] (assoc b :c 17)

2:04 accel: duck1123: (:require crfx.util)

2:04 where do I stick the :reload-all ?

2:04 duck1123: (:require foo.dog :reload-all)

2:04 accel: duck1123: alright; I am convinced I have no idea what I am talking about.

2:05 here's the situation: I need to store some data structure

2:05 this data structured needs to store lots of GUI elements

2:05 I need to call functions w/ side effects on these GUI elements

2:05 duck1123: reload all is kinda tricky, and I tend to avoid it really, but that's only because saving a file and sending it to the swank session is an automatic pattern for me

2:06 devn: atom(s)?

2:06 duck1123: are these gui elements java classes that need special care?

2:06 clojurebot: succ 0 is 1

2:06 accel: they're java classes

2:06 I don't know if they need special care

2:07 you know

2:07 devn: accel: it helps if you can tell everyone your general goal. there are many ways to write the same program.

2:07 accel: this sounds like prmature optimization

2:07 I'm writing a WYSIWYG document editor

2:07 duck1123: well, in most cases, you make it so that whenever you need to make a change, you have your function return a new copy of the structure

2:07 accel: when a user presses a key, some internalt state is updated

2:08 duck1123: this gets tricy with mutable java objects

2:08 accel: when this state is updated, I need to call repaint on a bunch of GUI elements

2:08 STMs _only_ roll back clojure state (i.e. Refs), and does not "time-wrap/un-execute" java code right?

2:09 duck1123: I don't get into gui, but I know there are several libraries that make this sort of thien easier in clojure, have you looked at them?

2:09 accel: not yet

2:09 this isn't a full GUI

2:09 I need only to keep two java Graphics2D elements updated

2:09 devn: I think duck1123 is right to suggest that as a next step. Learn how other people do it. When you say WYSIWIG it sounds like a GUI to me.

2:09 duck1123: right, Clojure's stm can't undo a mutable java poperation

2:10 devn: Text editors aren't simple. It's worth looking at existing solutions to the problem.

2:10 Finding the analgous problem and its solution is valuable.

2:11 duck1123: from what I've heard, the java gui libraries really went out of their way to make it a PITA for clojure

2:12 ihodes: amalloy: seque isn't going to work, i need a way to .take from the queue...

2:12 devn: duck1123: we can make them suck less with concerted effort.

2:12 ihodes: is there a way to send my producer to another thread and just have it add to the agent, unless i tell it to stop? agent?

2:13 duck1123: accel: this might get you started https://github.com/search?type=Repositories&language=Clojure&q=swing

2:14 accel: i got it figured out

2:14 I want agents + watchers

2:14 duck1123: will look into it; thanks

2:14 err, we are blaming java for not taking into account the needs of a programming langauge that did not exist at the time java was being built?

2:15 duck1123: absolutely! That;s no excuse

2:16 amalloy: java developers will go so far as inventing a time machine to increase the getter/setter proliferation

2:16 duck1123: some would argue that some core features of Java don't take into account the needs of Java

2:17 accel: code in a STM block may be re-executed

2:17 for an agent, does the function that I pass to it

2:17 get guaranteed to be executed exactly once?

2:17 amalloy: accel: would you ming using some punctuation instead of gratuitous newlines? it rather clutters up the channel

2:18 and i believe it's guaranteed to execute at most once. you can't guarantee it ever executes, because some prior action may fail, clogging the pipe

2:21 duck1123: There's something about if you send inside a dosync, then it only gets sent wen it finishes, but then there's something about "only with a ref" that I got wrong before. Can't find the relevant docs

2:22 Will atoms ever trigger a retry?

2:22 accel: amalloy: Understood. Will try to be better in the future.

2:23 devn: duck1123: As with all reference types, the intended use of atom is to hold one of Clojure's immutable data structures. And, similar to ref's alter and agent's send, you change the value by applying a function to the old value. This is done in an atomic manner by swap! Internally, swap! reads the current value, applies the function to it, and attempts to compare-and-set it in. Since another thread may have changed the value in the intervening time, it may ...

2:23 ... have to retry, and does so in a spin loop.

2:24 duck1123: http://clojure.org/atoms

2:24 accel: So clojure does NOT do any time of scheduling to ensure that only one of these modify-functions on an agent is executed at a given time?

2:24 duck1123: devn: right, I was just reading that. I'm just trying to understand the "only with refs" part I was corrected on

2:26 amalloy: accel: certainly it does. that's the point of agents. but duck1123 was asking about atoms

2:26 devn: duck1123: where at?

2:27 accel: atoms, refs, and agents are different animals.

2:28 http://techbehindtech.com/2010/06/05/simple-matrix-refs-atom-agents-clojure/

2:30 accel: devn: lol; thanks

2:30 in terms of GUI/repainting. I'm looking at http://java.ociweb.com/mark/clojure/ClojureSnake.html <-- why does this code not proxy an obejct + override it's paint() function?

2:31 devn: accel: Aaron Bedra and Stu Halloway's update to "Programming Clojure" has a demonstratrion of the snake program.

2:33 accel: looking at their code; it seems like they're doing it the "wrong" way; i.e. they have a main loop, where they draw everything + -then sleep for 30 milliseconds

2:33 I was under the belief this is NOT the correct way to do things.

2:34 devn: accel: we invent the correct way by doing it correctly

2:34 accel: devn: you believe snake.clj's way of handling repaints + nteractivity is the right way?

2:34 duck1123: I think that's more the shortcut way, where doing anything better was outside the scope

2:35 devn: accel: i do not believe in ultimate correctness.

2:35 i believe in a general form of correctness that takes into account the nature of the problem and the goal of its solution

2:36 amalloy: accel: i believe that is a very common pattern for game code, where you just want a canvas to draw on however you like whenever you like

2:36 if you want to make a menu with lots of nice clicky buttons, this isn't the way to do it; but that's not what they're doing

2:38 devn: http://ique.github.com/bebot/ is interesting

2:38 duck1123: make your code read from a lamina channel and take that data and draw your form. then you could enqueue transitions from other threads

2:38 devn: what about avout?

2:39 duck1123: ok, so you can enqueue from any machine in his cluster?

2:40 accel: amalloy: good call, I believe most OpenGL apps are writen in a similar manner.

2:40 devn: accel: i was talking to someone the other day. they were very concerned with being "right" immediately.

2:40 duck1123: I've been excited about the possibility of avout + lamina, but I haven't hade the time yet

2:41 devn: duck1123: i got a few friends at work to install zookeeper and we had a bit of fun

2:41 it's very cool

2:42 accel: I thin this is what I wanted to read: http://pragprog.com/magazines/2010-11/getting-clojure.

2:45 duck1123: devn: I think when I do get around to using avout for my one project, I'll use the mongo backend as I'm already using it as my datastore.

3:08 accel: (def curline (agent "")) ; (send curline (fn (x) x)) <-- why does this code result in an error?

3:09 user=> (def curline (agent "")) (send curline (fn (x) x))

3:09 #'user/curline

3:09 CompilerException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol, compiling:(NO_SOURCE_PATH:7)

3:09 what is wrong with this?

3:10 I'm sending it the identity function

3:10 and yet it can't do anything with it?

3:12 I want [x], damn it :-)

3:13 amalloy: accel: you want ##(doc identity)

3:13 lazybot: ⇒ "([x]); Returns its argument."

3:14 amalloy: although what the hell, why are you sending an agent identity?

3:15 accel: amalloy: i simplfied my code to a minimal failure case

3:15 despite the sutpidity I have demosntrated so far, I do not send agents the identity function :-)

3:29 duck1123: I just finished documenting Ciste's routing mechanism. Anyone willing to provide feedback? https://github.com/duck1123/ciste

3:29 I really need to break this into a Wiki

3:56 accel: i do not know if this is the right window to ask: I am using Clojure on OSX Lion. Is there anyway to make one of my awt/swring windows _transparent_ ? I don't need rounded corners; I only need transparent.

4:02 kumarshantanu: accel: http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/

4:04 You must be on JDK 1.6.10 or higher, on Lion latest as of now is 1.6.29

4:05 accel: ~$ java -version

4:05 java version "1.6.0_29"

4:05 clojurebot: http://java.sun.com/docs/books/tutorial/java/index.html

4:05 accel: kumarshantanu: thanks!

4:06 devn: (inc kumarshantanu)

4:07 accel: (dec accel)

4:07 lazybot: You can't adjust your own karma.

4:07 accel: (read accel)

4:07 lazybot: help

4:07 lazybot: You're going to need to tell me what you want help with.

4:07 accel: lazybot: help karma

4:07 lazybot: accel: Checks the karma of the person you specify.

4:08 accel: (karma accel)

4:08 karma accel

4:08 lazybot: karma accel

4:08 lazybot: accel has karma 0.

4:09 duck1123: accel: if you want to play with clojurebot, it'll respond over /query

4:09 Raynes: duck1123: That isn't clojurebot.

4:09 But he will also respond over /query.

4:09 duck1123: If you ever call lazybot clojurebot again, he might just end you.

4:09 duck1123: lol

4:10 Raynes: Keep laughing. You'll get yours.

4:10 amalloy: Raynes: usually i tell people to knock it off and use /msg, but lazybot keeps separate karmas per channel (and /msg is a separate channel)

4:10 accel: it's alright; I'll stop :-)

4:11 Raynes: accel: FYI, you didn't really do anything over the top or bother anyone. We were just mentioning the query capability so that you didn't. :)

4:11 We still <3 you.

4:12 amalloy: Raynes: anyway, lazybot is here for the entertainment of #clojure denizens, right???

4:12 lazybot: amalloy: How could that be wrong?

4:13 Raynes: Not to mention that it is 3AM, 1AM, and 2AM and variations thereof in the US, so all the people with lives are asleep.

4:13 keith__: :(

4:14 Raynes: On the other hand, all the cool people are awake.

4:14 keith__: :)

4:21 accel: is it bad style to use _ instead of - in clojure code?

4:21 somehow, I find foo_bar easier to read than foo-bar

4:23 keith__: it's a lisp convention

4:23 I think they just like to gloat about how no one else can do it though

4:23 accel: does _ have special meaning in clojure?

4:23 keith__: only when used alone

4:23 as a function argument

4:23 accel: as in ignore thi sargument?

4:23 keith__: it discards the parg

4:23 ya

4:24 amalloy: _ has no special meaning in any context

4:25 &((fn [_] (inc _)) 10)

4:25 lazybot: ⇒ 11

4:26 amalloy: i mean, in a language with macros, any macro could give _ special meaning, of course. but none of the built-ins do

4:26 keith__: &((fn [_ _] _) 1 2)

4:26 lazybot: ⇒ 2

4:26 keith__: &((fn [a a] a) 1 2)

4:26 lazybot: ⇒ 2

4:26 keith__: oh I guess not

4:33 accel: is there any clojure data type (i.e. deftype, defrecord) where I also specify the types of the members?

4:35 duck1123: accel: chances are, you don't really need it

4:36 what are you looking to gain by specifying the types of the members?

4:36 accel: easier to debug

4:36 coming over from haskell

4:39 duck1123: yeah, clojure is a very different beast from haskell when it comes to types. In clojure, it's generally recommended to code against abstractions and use those abstractions to build the bigger picture.

4:40 amalloy: duck1123: i don't think the second sentence is really relevant

4:40 accel: what do ou mean "code vs abstractions" ?

4:41 are these abstractions enforced by anything?

4:41 amalloy: accel: clojure just has a much looser philosophy about typing

4:41 trying to apply haskell habits is good, but when the language is obviously discouraging you, try to adapt instead of cram the square peg into the round hole

4:42 accel: lol

4:42 what is the right way to build a DOM tree

4:42 all of whose members are either FooNode, BarNode, CatNode, or DogNode ?

4:42 amalloy: don't do that. just build a tree whose members are all Nodes

4:43 accel: I want to then write code that does patern matches on FooNode/BarNode/CatNode/DogNode

4:43 amalloy: clojure's pattern-matching facilities are much weaker than haskell's

4:44 accel: Are there cool things we can do with amcros to make up for it?

4:44 amalloy: the general approach is to make each node a hashmap containing whatever type information you need (which is less than you think, really)

4:45 well, of course

4:46 one problem is pattern-matching is a closed system: if you later add a BlamNode, all the pattern-matching sites need to change

4:47 duck1123: that's when multimethods are great

4:47 amalloy: but you're approaching every problem as "I'm building a Haskell program using Clojure, and this line of code doesn't work; how can I do this Haskell thing?"

4:49 instead, embrace the tools that clojure emphasizes, like ubiquitous and easy hashmaps

4:49 accel: amalloy: Not everything. I'm not asking for monads + algebraic data types. I used to use scheme; and I do like the ease of detecting errors via types.

4:49 amalloy: i do too; i've dabbled with haskell and wish we had algebraic data types and optional static typing. but it's not there (yet: you can add it yourself in a library if you have a few months to spare and are a genius)

4:49 kumarshantanu: accel: you may like to check out Jim Duvey's experiment with monads

4:50 accel: I have 72 hours to spare. I am not a genius.

4:50 kumarshantanu: will look into it

4:52 amalloy: accel: you can get basically a generalization of typeclasses, by using multimethods

6:14 triyo: is there a shorthand for something like (or [] [1 2 3]). So thats if vector is empty use the right hand side as the default

6:22 licenser: ,(dropwhile empty? [[] [1 2 3]])

6:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: dropwhile in this context, compiling:(NO_SOURCE_PATH:0)>

6:23 licenser: ,(drop-while empty? [[] [1 2 3]])

6:23 clojurebot: ([1 2 3])

6:23 licenser: there we go :)

6:24 triyo: Cool, that'll do

6:25 amalloy: &(or (not-empty []) [1 2 3])

6:25 lazybot: ⇒ [1 2 3]

6:25 licenser: &(or (not-empty [1]) [1 2 3])

6:25 lazybot: ⇒ [1]

6:26 licenser: neat

6:26 triyo: Hmm, I'm being stupid here guys. Sorry. I forgot the mention that the first list is the optional arg of a function. Thought that returns an empty [] if no optional args are set mean while its actually a nil.

6:27 so in that case its actually (or nil [1 2 3 4])

6:27 licenser: ,(or nil [1 2 3 4])

6:27 clojurebot: [1 2 3 4]

6:27 licenser: that is working great so no need for any of the trickery ;)

6:28 triyo: exactly :)

6:29 Never make assumption

6:29 So I did a quick test in repl

6:29 licenser: triyo: no making assumptions is OK as long as you are right in the end :P

6:29 triyo: ,((fn [a b & c] c) 1 2)

6:29 clojurebot: nil

6:29 triyo: ((fn [a b & c] c) 1 2 3)

6:30 ,((fn [a b & c] c) 1 2 3)

6:30 clojurebot: (3)

6:30 licenser: &((fn [a b & c] c) 1 2 3)

6:30 lazybot: ⇒ (3)

6:30 triyo: licenser: thanks for the words of wisdom. ;-)

6:31 licenser: ^^

6:31 that's what I am here for sharing my experience of years and years being a smartass

6:35 triyo: always appreciated :)

6:58 osa1: does clojure have a function like python's dir, which lists vars, functions, etc. in a namespace?

7:10 kawas44: osa1: (require '[clojure.repl :as rpl]) (* then load your namespace *) (rpl/dir <your namespace>)

7:11 osa1: kawas44: thanks. do you know something like repl/dir but for java classes? to browse methods etc.

7:15 kawas44: osa1: the same question was asked yesterday but I dont have the log :)

7:16 osa1: for consultation you can play with (javadoc <your class>) # see clojure.java.javadoc

7:17 osa1: for prog use you can play with (bean <your obj or class>)

7:17 osa1: kawas44: looks like I don't have clojure.java.javadoc (clojure 1.3)

7:19 kawas44: osa1: javadoc is just an helper function to open your browser on java api pages try: (javadoc String)

7:20 osa1: to have more function you should load the namespace (use 'clojure.java.javadoc)

7:22 osa1: kawas44: javadoc is not what I want actually, I want to work on just REPL and a clean buffer

7:23 kawas44: osa1: as I said you can play with (bean obj)

7:24 osa1: kawas44: is there a pretty-printer for output of (bean obj) ?

7:29 kawas44: osa1: sorry I dont know of one, maybe in a lib, but your can filter the output on keys your are interested in :)

7:53 osa1: If you manage to get repl-utils lib, I think "show" may do what you want : http://clojure.github.com/clojure-contrib/branch-master/repl-utils-api.html#clojure.contrib.repl-utils/show

7:59 terom: ~logs

7:59 clojurebot: logs is http://clojure-log.n01se.net/

9:13 dmansen: hmm. just noticed that my swank-clojure indentation code doesn't work well when you go to other frames..

9:13 i guess i should fix that

10:24 wmealing: hi, i'm playing with fedora 16's "yum install clojure", the repl doesn't seem to work how i'd think. i expected an "up arrow" to go to the previous input.. am I doing it wrong ? what should I be doing ?

10:28 I expected tab and auto complete to work too..

10:44 jline trickery with a shell script. seems to do most of what i want.

10:46 cemerick: wmealing: Clojure is a JVM *library*, and so is generally a mismatch for OS-level package managers. *shrug*

10:47 wmealing: yeah, and java not having a repl and all.

10:47 at least not to my knowledge.

10:48 cemerick: Well, Java != JVM. And a Java REPL makes as much sense as a "C REPL"

10:49 though both things do exist :-P

10:52 wmealing: today i learned.

12:15 TimMc: cemerick: I use a very shitty Java REPL every day at work.

12:15 cemerick: beanshell, perhaps?

12:16 TimMc: It's an Eclipse View called "Display".

12:16 cemerick: heh, sure

12:16 My loyal, fucked up little friend. :-P

12:17 TimMc: That's an excellent description.

12:18 Although I might temper the loyal part -- every once in a while it decides it doesn't wanna.

12:18 cemerick: I've abused it enough by making it do things you really shouldn't do that I can't fault it too terribly.

12:19 TimMc: wmealing: If you use Leiningen's REPL, make sure to install rlwrap.

12:19 It will give you the readline support you want.

12:20 But yeah, grab Leiningen and run `lein repl` inside or outside of a project directory.

12:44 mrevil: if I'm debugging and I wanted to print the class name of an object how would I do it?

12:45 miniyuki: mrevil: (println (class o)) ?

12:46 TimMc: $findfn 5.6 Double

12:46 lazybot: [clojure.core/class clojure.core/type]

12:47 mrevil: miniyuki: that was it. thanks

12:57 rplevy: DerGuteMoritz: I'm looking at clj-oauth2 and trying to figure out if this library has a different or the same purpose as clj-oauth

12:58 the reason is I noticed clj-facebook-graph is not upgraded to 1.3 yet

12:59 DerGuteMoritz: rplevy: clj-oauth implements OAuth 1.0, at least last time I checked

12:59 rplevy: I see

12:59 DerGuteMoritz: thus clj-oauth2 because it implements OAuth 2.0 :-)

12:59 rplevy: so I'm going to upgrade clj-oauth2 to 1.3

13:00 DerGuteMoritz: rplevy: cool, feel free to send a pull request

13:00 rplevy: ok, great, thanks

13:01 jsnikeris: Is it always preferable to use "(:require [a.b.c :as c])" over use?

13:01 DerGuteMoritz: jsnikeris: I'd say it's a matter of taste and clarity

13:02 jsnikeris: e.g. when the namespace you are importing contains some very generic names such as `get' it's clearer to use a prefix

13:02 jsnikeris: I'm looking at the the sqlkorma library, and it seems like it would be cumbersome to genearte queries if I always had to write (sql/select users (sql/with address) (sql/fields [:firstname]))

13:02 DerGuteMoritz: lright

13:03 jsnikeris: those are pretty generic names though

13:03 DerGuteMoritz: if you are going to use a certain library a lot in your code I would use `use'

13:03 consider it a DSL then :-)

13:03 jsnikeris: right

13:03 DerGuteMoritz: if you only use it in one or two places, then I'd go for the prefix

13:03 jsnikeris: gotcha

13:03 DerGuteMoritz: but there is no hard rule to rely on

13:04 jsnikeris: ya, I mean I can see both sides of the argument

13:04 w/ require it makes it clear where fns are coming from

13:04 DerGuteMoritz: that's right

13:04 unless you choose a bogus prefix, of course :-D

13:05 jsnikeris: heh, but even then you can look to see what namespace that prefix corresponds to

13:05 terom: Also consider using :only in combination with :use so that it's clear what you're really using.

13:06 Vinzent: +1 for that; i use require only when there is conflicts with clojure.core functions

13:06 DerGuteMoritz: that's also a good idea sometimes, indeed

13:09 jjcomer: Does anyone happen to know where you can download the source code from Rich's Clojure Concurrency presentation? Here is the link: http://blip.tv/clojure/clojure-concurrency-819147

13:09 jsnikeris: seems like it could be tedious to manage your 'use only' declarations though

13:10 Vinzent: although, I can see the merits in using that style

13:11 I think that's actually the best strategy

13:12 'use only' by default, and if there are conflicts, 'require as'

13:12 does clojure-mode provide any help for managing one's ns declaration?

13:13 Vinzent: jsnikeris, as far as i know, it does not; but you should check https://github.com/technomancy/slamhound

13:15 Although, I haven't tried that. In fact, it's pretty easy to manage declarations by hand

13:17 jsnikeris: Vinzent: slamhound looks like it does what I want

13:17 Vinzent: thanks!

13:21 Vinzent: np

13:26 RazWelles: How's the CLR implementation of clojure in terms of maturity?

13:33 travisjeffery: i want to define a function takes parameters name and direction given in a hashmap, how do I deconstruct them properly if I call the function like: (my-func {:name "NAME" :direction "DIRECTION"})

13:41 mrevil: given two sequences '(1 2 3) and '(a b c) is there an easy way to get '( '(1 a) '(2 b) '(3 b)) so that i can use it with doseq?

13:42 cemerick: (map vector [1 2 3]

13:42 ,(map vector [1 2 3] '[a b c])

13:42 clojurebot: ([1 a] [2 b] [3 c])

13:42 Bronsa: ,(partition 2 (interleave '(a b c) '(1 2 3)))

13:42 clojurebot: ((a 1) (b 2) (c 3))

13:42 dmansen: hmm, i'm very close to having this colorization done for swank-clojure

13:43 i just need to somehow indicate to swank that my advice around slime is enabled or not

13:44 Vinzent: also ##(zipmap [1 2 3] '(a b c)) is basically the same

13:44 lazybot: ⇒ {3 c, 2 b, 1 a}

13:45 Vinzent: if ordering isn't important

13:46 jjcomer: what about ##(map-indexed (fn [a b] [(inc a) b]) [:a :b :c :d :e])

13:46 lazybot: ⇒ ([1 :a] [2 :b] [3 :c] [4 :d] [5 :e])

13:46 travisjeffery: if i deconstruct arguments to a function how can i bind the entire match as well?

13:47 mrevil: ty!

13:47 Vinzent: travisjeffery, [[a b c] :as coll]

13:48 travisjeffery: Vinzent: Thanks!

13:49 Vinzent: travisjeffery, oh, wait, or is it [a b c :as coll]?

13:58 scottj: dmansen: colorization done for swank-clojure?

14:03 dmansen: scottj: almost

14:04 it's all working, i just have to make sure it doesn't use the coloring if this particular advice isn't loaded

14:04 scottj: dmansen: I meant what do you mean by that?

14:04 coloring in autodoc, in inspector?

14:04 dmansen: oh oh

14:04 stack traces

14:05 scottj: hmm, is that a special lib, I don't see any color in sbcl sldb that I don't see in clojure

14:06 dmansen: it looks like this, the colors come from the clj-stacktrace package:

14:06 http://t.co/srsMjNvc

14:07 scottj: oh I see

14:30 gf3: sjl: ohai!

14:50 * gfredericks just did "M-x shell" and "lein repl"

14:52 priv_cooper: I am curious, what blogs do you all like to read?

14:53 Trying to refill my rss reader

14:54 Vinzent: priv_cooper, http://nakkaya.com

14:55 priv_cooper: I am new to lisp's, currently loving clojure. Just re-coded my personal website in clojure. Working through sicp and learning more clojure.

14:56 Vinzent: Is this your blog?

14:57 Vinzent: priv_cooper, no, but it's very cool :)

14:58 technomancy_: dmansen: you could have it triggered by a defproject key

14:58 cemerick: priv_cooper: you could do worse than to add Planet Clojure. :-)

14:58 technomancy_: and then the jack-in task could assoc in that key since it knows the colorization advice is active

14:59 jsnikeris: technomancy_: hey, I'm trying to get slamhound.el working with Emacs < 24

15:00 technomancy_: jsnikeris: hm; yeah that is not very well-tested

15:00 even on 24, the pretty-printing is kind of crappy

15:00 jsnikeris: technomancy_: So I'm looking at slamhound-prettify-subclause, and it looks like it's just removing extra spaces and newlines from a '[net.cgrand.enlive-html :only [html-content]]'

15:01 technomancy_: yeah, I don't think I got to the point of attempting to keep lines under 80 columns

15:01 jsnikeris: technomancy_: are there some times where the slamhound clojure code returns extra spaces?

15:01 technomancy_: yes, it'll insert line breaks in odd places

15:01 because it just uses clojure.pprint

15:02 jsnikeris: technomancy_: ah, ok. my examples must not have shown that yet

15:02 technomancy_: I think this little tool is great btw

15:02 technomancy_: jsnikeris: I had tons of fun writing it

15:02 except for the prettification part; that is a huge pain

15:02 jsnikeris: technomancy_: do you still use it to manage your namespaces?

15:03 technomancy_: I don't use it much, mostly because of the prettification issue

15:03 also because I've started to do more things like (:require [cheshire.core :as json])

15:03 and slamhound assumes the :as must be the same as the last segment

15:03 jsnikeris: right

15:04 hmm

15:04 technomancy_: partly that's a problem with cheshire; having .core in the namespace name is lame. but that's a fact of life.

15:04 miniyuki: what would you recommend Midje or Lazytest?

15:04 jsnikeris: I suppose slamhound could take hints from an existing ns definition

15:04 technomancy_: yeah. I can't think of a way to portably declare "these are the nonstandard require mappings this project uses", but leveraging what's already there is probably as good as you can get.

15:05 if you'd like to take a crack at it, I'd love to take a patch

15:05 I documented the internals fairly thoroughly here: http://technomancy.us/148

15:06 jsnikeris: technomancy_: yah, I'll take a look at it after I get the prettification working on Emacs < 24

15:08 technomancy_: I'm not too familiar w/ how clojure-mode works, but would it make more sense for the ns formatting stuff to exist there?

15:08 then you slamhound could just call indent

15:08 technomancy_: jsnikeris: yeah, that would make a lot of sense

15:08 anything that can be done statically (without communicating with a running clojure process) can go in clojure-mode

15:09 but I am also totally unfamiliar with its indentation functionality

15:09 jsnikeris: I'm guessing that you can only specify rules for indenting one line at a time

15:10 technomancy_: there's some level of backtracking logic

15:10 jsnikeris: OK

15:10 but if you've got the whole namespace on a single line, you probably couldn't specify a rule that would split it up and indent it properly

15:12 technomancy_: actually you might be able to make it work as a reduce over a seq of forms -> a vector of strings in clojure

15:13 maybe doing it from elisp is the wrong approach?

15:13 dunno

15:15 jsnikeris: technomancy_: well I'd suppose people would be interested in formatting their ns declarations in a standard way even if they're not interested in automatically building them up

15:16 technomancy_: if that is the case, then the namespace formatting stuff should live in clojure-mode, while the namespace generating stuff should live in slamhound

15:17 technomancy_: I'm going to try my hand at a namespace formatter

15:17 dmansen: technomancy_: wish i had read all this a few minutes ago

15:17 priv_cooper: cemerick: Thanks!

15:18 dmansen: i've been trying to figure out how to send a command to emacs that will return whether or not that advice is defined

15:18 it feels like i'm close, but i really don't understand the slime protocol that well

15:24 technomancy_: dmansen: it doesn't have to check for the advice itself necessarily

15:24 the file that has the defadvice could provide something, and then you could just check featurep

15:24 dmansen: oh sure

15:25 i just don't know how to communicate between the processes :)

15:25 i don't know if i should be sending an :eval message, :emacs-return, or what

15:31 technomancy_: yeah, it may be simpler to set something in the jack-in task instead

15:32 dmansen: ohhhh i see what you mean. that does sound much easier

15:41 fielcabral: Hi. Does the repljs REPL in ClojureScript allow you to call require?

15:42 Hi. Does the repljs REPL in ClojureScript allow you to call require?

15:45 dnolen: fielcabral: if you mean call require as a function, I don't think that works yet.

15:48 y3di: in order to use the jvm, do we need to get a liscense from Oracle to avoid being sued? how exactly does that work?

15:49 fielcabral: Can anybody see this? Pigs fly

15:50 cemerick: y3di: why in the world would you think that's necessary?

15:51 y3di: no idea... lol so i guess not

15:53 technomancy_: you only need a license to fork it

15:56 fielcabral: test

15:58 y3di: whats the difference between an api and a dsl?

16:00 technomancy_: "dsl" is just a trendy way to say "an api that makes sense"

16:01 y3di: haha ok

16:03 fielcabral: /help SET

16:06 test

16:10 fielcabral_: MSG NickServ IDENTIFY fielcabral 62TJn47kHm6Zt4KNuh4eGNS6AY23Cr9h

16:10 dmansen: technomancy_: wow, that's the best way i've heard of distinguishing that

16:11 fielcabral__: MSG NickServ IDENTIFY fielcabral 62TJn47kHm6Zt4KNuh4eGNS6AY23Cr9h

16:11 cemerick: fielcabral__: um, might want to not use that password.

16:13 gfredericks: yeah, it's clearly insecure. Doesn't even have any special characters.

16:14 fielcabral: test

16:58 gtrak_m: Pretty impressed clojure has a repl on android and python does not

17:02 babilen: gtrak_m: https://code.google.com/p/android-scripting/ (it does)

17:03 gtrak_m: Ah

17:03 dmansen: okay...FINALLY

17:04 technomancy_: i have it working...it feels a bit ugly right now though

17:04 samaaron: i'm trying to implement IFn within defrecord - has anyone tried this before?

17:07 dmansen: i stored *color-support?* in a ref, but i don't know if that's necessary

17:07 kotarak: samaaron: (defrecord Foo [x] IFn (invoke [this y] (+ x y))) Doesn't sound too scary, no?

17:08 samaaron: kotarak: sure, if you only want to support one args in your fn

17:08 but if you want to support varargs it seems you ahve to implement all the different invoke arities

17:08 unless i'm doing something silly

17:08 kotarak: samaaron: another example http://clj-me.cgrand.net/2011/10/17/valued-functions/

17:08 Ah. varargs.

17:08 cemerick: samaaron: There was a macro kicking around that would stub out IFn as necessary.

17:09 samaaron: cemerick: yeah, that's what i was just about to start writing

17:09 cemerick: Alternatively, you can proxy AFn *very* easily.

17:09 gtrak_m: Is the array parity more than one arg?

17:09 Arity *

17:09 samaaron: cemerick: if I proxy AFn, how easy would it be for me to also implement IObj?

17:10 cemerick: Not very.

17:10 samaaron: yeah, that's the position i'm in

17:10 we already have a proxy version of our 'callable-map'

17:10 but i can't add metadata to it

17:10 and we wrote it years ago

17:11 i think i'll just implement all the different invoke arities

17:11 i only have to do it once

17:12 gtrak_m: Ah damn, it's 20 plus the array

17:12 samaaron: gtrak_m :-)

17:12 cemerick: samaaron: The universe demands that you produce a macro and gist it. For the children. ;-)

17:12 samaaron: cemerick: haha, ok. The younglings shall be considered

17:15 kotarak: samaaron cemerick Why is IObj difficult to proxy with AFn? http://paste.pocoo.org/show/522730/

17:15 I'm confused.

17:17 cemerick: Ohhh! I misread samaaron's msg as "how *hard* would it be" :-P

17:17 samaaron: it's very *easy*, not very hard, to implement IObj with proxy.

17:19 samaaron: cemerick: ah ok

17:20 i wonder if we should just stick with our proxy impl then

17:20 btw, what's the difference between AFn and IFn?

17:20 fridim_: Sorry to interrupt, I'm disicovoring clojure, but that is strange to me : user=> (* 12323123213 1231231231312) => ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374) I thougt, clojure was a lisp :P

17:20 kotarak: samaaron: AFn is base class IFn is the interface

17:21 fridim_: discovering*

17:21 samaaron: you can easily tell I never got too dirty with Java :-)

17:22 brehaut: fridim_: its a lisp that has to respect the JVMs tradeoffs as best it can

17:22 kotarak: ,(* 12323123213 1231231231312)

17:22 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

17:22 kotarak: ,(*12323123213 1231231231312N)

17:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *12323123213 in this context, compiling:(NO_SOURCE_PATH:0)>

17:22 brehaut: ,(*' 12323123213 1231231231312)

17:22 clojurebot: 15172614167151479645456N

17:22 dmansen: hm, i thought clojure automatically promoted things to bigint?

17:22 ah

17:22 samaaron: ok, so why would you proxy AFn rather than IFn?

17:22 kotarak: ,(* 12323123213 1231231231312N)

17:22 clojurebot: 15172614167151479645456N

17:23 brehaut: fridim_: ^ use the star prime op to have auto bignumming

17:23 kotarak: samaaron: Because AFn implements stuff like applyTo, but IFn does not?

17:24 cemerick: dmansen, fridim_: http://dev.clojure.org/display/doc/Enhanced+Primitive+Support

17:24 kotarak: samaaron: I haven't looked to close at the source of AFn. But usually stuff like this is the reason.

17:24 fridim_: ok, thanks

17:24 cemerick: actually, http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics is a better page

17:24 fridim_: either +M or *'

17:25 samaaron: kotarak: interesting, thanks. I just worry that perhaps the default implementations won't work if I don't populate the object properly or override all the fns myself

17:25 kotarak: samaaron: Good question.

17:25 cemerick: technomancy_: when you write "Invoke M-x clojure-jack-in from a project" does that mean "with a file in the desired project open in the current buffer"?

17:27 samaaron: dmansen: so do i need to do anythign special to get emacs to do the right things with the ansi codes?

17:28 dmansen: although a bigger issue was when I switched to 1.3.4-SNAPSHOT of swank-clojure it blew up my emacs

17:28 1.4.0-SNAPSHOT doesn't do that, so i'm sticking with that for the time being

17:30 dmansen: samaaron: did you get the clj-stacktrace changes i pushed?

17:31 i had to modify that as well

17:31 samaaron: dmansen: i'd never heard of clj-stacktrace before your tweet

17:31 dmansen: haha

17:31 actually, if you're just using the 1.3.x branch you shouldn't have to

17:31 the color stuff isn't merged in yet

17:32 samaaron: dmansen: so i'm using the 1.4.x branch as 1.3.x dies spectacularly for me

17:32 dmansen: do you have the error?

17:32 samaaron: dmansen: not sure where to find it. Emacs crashed.

17:32 dmansen: it CRASHED emacs? completely?

17:32 wow

17:32 samaaron: yup

17:32 dmansen: i have not seen that one

17:33 emacs 24?

17:33 samaaron: yup

17:33 i believe it's somethign to do with my auto complete plugin

17:33 it was when auto-completing a java namespace when it died

17:34 dmansen: interesting

17:34 i'm not sure...

17:34 were you at the repl? or a trace

17:34 samaaron: dmansen: i was in a clojure buffer just hacking away

17:35 what's the difference between the 1.3.x branch and 1.4.x?

17:35 dmansen: where are you seeing 1.4.x? i don't see that branch

17:35 my stuff got merged directly into 1.3.x

17:36 samaaron: i just specify it in my global project.clj file in ~/.cake/

17:36 and pull it as a global dep

17:36 it must be in a maven repo somewhere

17:36 dmansen: i'm a bit confused. but my stuff isn't in maven yet

17:36 so it's not me

17:36 * dmansen washes hands

17:37 samaaron: :-)

17:37 i think all this swank/slime/emacs stuff is just fragile magic

17:37 dmansen: technomancy_ said he might try to do a release later this week possibly

17:37 oh man, try messing with the debugger. it's such a strange, meta experience

17:37 the debugger breaks, and...you can't debug it, cause you broke it

17:37 samaaron: haha

17:38 dmansen: it was a bit painful

17:38 samaaron: i think i need to switch to lein to get the debugger working properly

17:38 dmansen: ahhh yeah i'm using lein

17:38 haven't tried cake yet

17:38 samaaron: don't bother - lein is the future

17:45 amalloy: yeah, there was a mailing-list thread some time ago about having a defrecord implement IFn by delegating to one of its fields

17:45 accel: good morning ladies and gentlemen

17:46 it's now ~ 3pm and I start coding again

17:46 clojure is a language, where I can spend 10 hours writing 95 lines of code

17:46 yet feel it was completely productive for a day's worth of work. :-)

17:47 dmansen: i spent ALL DAY doing the same thing

17:47 modify 4 lines, change a ton of stuff - i love it

17:48 accel: Programming in Clojure is like modifying DNA. Change 1% of the code, and one jump from monkey to ape.

17:48 duck1123: it's always so sad, because when you're done hacking on something in clojure, you're left with a handful of functions that are so basic and straightforward that you're left wondering what you did all day.

17:49 samaaron: amalloy: yeah, i have a version of defrecord which implements *some* of IFn, although I can't get 20+ args to use apply automatically

17:49 accel: This is proof that P != NP. It takes exponential work to output a polynomial size program.

17:49 dmansen: i have to go to work tomorrow and write PHP

17:49 that's the real sadness

17:50 weavejester: I kinda find that as I become more practised at programming, the solutions I come up with become simpler, rather than more complex.

17:50 dmansen: absolutely.

17:50 my usual flow is: write a bunch of code to get it working, then revisit and cut it down as much as possible

17:50 it always goes along this curve

17:51 amalloy: samaaron: gist or something?

17:52 accel: holy shit

17:53 I think I just understood how the zippers work. :-)

17:53 fridim_: <dmansen> i have to go to work tomorrow and write PHP

17:53 samaaron: amalloy: https://gist.github.com/1494730

17:53 fridim_: haha

17:53 accel: Once you write it out as "list of" [ntype, left, node, right], ; then moving up/down the tree reallyd oes look like a zipper.

17:53 dmansen: fridim_: i really despise it.

17:53 accel: dmansen: Where do you work?

17:53 dmansen: www.rjmetrics.com

17:54 amalloy: oh, i thought you had the macro already

17:54 samaaron: you go do something more interesting, i'll sketch out the macro for you

17:55 samaaron: amalloy: the macro is something i could do - what i'm unable to do is to get that to work for: (def f (Foo. (fn [& args] (println "args: " args)))) (apply f [1 2 3 4 5 6 7])

17:56 hold on

17:56 my example was incorrect

17:56 I can't get it to work for this: (f 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22)

17:56 perhaps that's a clojure error though, not a record error

17:57 amalloy: no, that should work

17:57 samaaron: although this doesn't work either: (apply f [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22])

17:58 whereas (apply f [1 2 3]) works if i've implemented invoke with three args

17:58 weavejester: Hmm, leiningen plugins only seem to work if added as a dev-dependency, not as a dependency

17:59 amalloy: samaaron: well your gisted implementation of applyTo is wrong

18:00 or, i guess it might work as-is. but (applyTo impl args) seems better than (applyTo this args)

18:01 yeah, and that fix makes it work, when i try it

18:02 samaaron: amalloy: ahh, that's just me being silly

18:03 weavejester: technomancy_: Is it deliberate that lein plugins only work when included in dev-dependencies?

18:05 samaaron: amalloy: so taht fixes it for applying to a large list of params, but not for (f 1 2 3 .. 22)

18:07 i guess that's just something clojure doesn't allow

18:07 amalloy: samaaron: but it does, because you can call + that way

18:07 oh, that might just be because + gets inlined. let me check

18:08 &(let [p +] (p 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24))

18:08 lazybot: ⇒ 300

18:08 samaaron: amalloy: it gets reduced down

18:08 but the sig is [x y & more] so clojure must be doing somethign to map the long param list to that impl

18:09 amalloy: samaaron: well, of course that's the implementation of + once it receives a bunch of args. but the difficulty you're having is in getting your function to receive a bunch of args to begin with

18:09 samaaron: exactly

18:10 amalloy: samaaron: oh, i think i see what's going on

18:10 samaaron: so (defn bar [& more] (println more)) works as expected

18:10 amalloy: samaaron: look at the IFn interface

18:11 samaaron: Object... args)

18:11 is it something to do with that?

18:11 amalloy: yes

18:11 samaaron: what does that mean?

18:12 amalloy: well, the relevant part is that if you pass it 21+ args, then applyToHelper will call that version, passing it the first 20 args explicitly and then an array of the rest of the args

18:12 and since you didn't implement that...

18:12 or rather, not applyToHelper

18:13 but rt, or the compiler, or someone

18:13 samaaron: i don't really get how this applies to applyToHelper

18:13 ah ok

18:14 amalloy: so you need to emit another body that takes 21 args and forwards all those to the impl

18:15 samaaron: amalloy: so that totally works

18:15 although i still don't quite see why

18:15 what does Object... mean?

18:16 amalloy: it's silly jvm lingo for Object[]

18:16 samaaron: ah ok

18:16 amalloy: java lingo, i guess. at the bytecode level it's an Object[], but calling it Object... instead lets java programmers pretend it takes varargs

18:16 samaaron: hahaha

19:08 mbac: AWESOME

19:08 PLEAC accepted our clojure submission

19:08 http://pleac.sourceforge.net/pleac_clojure/index.html

19:09 15.29% complete, already ahead of C, forth, R, factor, smalltalk, obj-c, and go

19:09 i'm coordinating development at my github https://github.com/mbacarella/pleac-clojure

19:10 it's easier than trying to send piecemeal submissions to the pleac people

19:10 feel free to fork it if you want, but i'm happy to just throw you commit access and do the work of merging it into PLEAC

19:12 accel: #_ is so cool.

19:13 it's especially cool in situations where ; would not work, since on the given line, the number of ()'s are not balanced; but #_ just knocks out the next sexp

19:16 what is the right pattern/macro in clojure to use to dispatch on tagged lists or def-types ?

19:17 brehaut: accel: if you need both? multimethods ?

19:28 ibdknox: I'm seeing very strange behavior with UTF8: when I set an atom to a unicode char in the repl, and have it print inside of a ring handler, it prints the char as ?

19:28 any thoughts?

19:29 if I simply print it at the repl (not in the context of ring) it prints correctly.

19:29 jkkramer: ibdknox: printing to where? the repl or to a webpage?

19:29 ibdknox: either

19:30 mindbender: how to I exit clojure repl in emacs without errors

19:30 jkkramer: you using embedded jetty?

19:30 mindbender: *do

19:30 ibdknox: jkkramer: yes

19:30 jkkramer: headers are correctly set

19:30 jkkramer: ibdknox: including charset=utf8 in content-type?

19:30 ibdknox: yes

19:30 it actually prints the value to the console wrong

19:30 jkkramer: (in actual http header, not in html)

19:31 hmm

19:31 ibdknox: which indicates to me that there's some sort of java-level thread setting that is screwed up in the context of jetty

19:33 jkkramer: I had trouble getting jetty to output using the right charset, which I solved with a middleware hack. not sure if it would help in your case, though

19:35 jweiss: how do I do set! on my own vars in the repl? Seems to only work within a binding form. is there another way to change a thread-local value permanently?

19:36 cemerick: ibdknox: Make sure your jvm has UTF8 set as its default encoding.

19:36 ibdknox: cemerick: how do I do that?

19:36 duck1123: jweiss: if you're just playing around in the repl, why not just re-def them

19:36 brehaut: yay default encodings :(

19:37 ibdknox: the thing that's weird though

19:37 is that in the same repl that is running the jetty instance, it works

19:37 cemerick: ibdknox: either make sure your OS has it set as its default (either via LANG or LOCALE or something), or make sure the JVM is started with -Dfile.encoding=UTF-8

19:37 jweiss: duck1123: ultimately it's going to be multithreaded, so it won't just be done in the repl

19:38 duck1123: jweiss: alter-var-root, but if you know you're going to be updating this value, why not use a reference type

19:39 jweiss: alter-var-root and atoms, etc are not thread-local. i want a thread-local value

19:39 i just want to set it permanently, not just within a binding form

19:41 at the repl, i don't want to recalculate the value every time i send an expression to be read

19:44 ibdknox: weavejester: ping?

19:45 gtrak_m: jweiss, if it's threadlocal it's not permanent. That doesn't make sense

19:48 duck1123: gtrak_m: I think he means for the life of the thread

19:48 jweiss: gtrak_m: (set! *print-meta* true) for all practical purposes, that is permanent

19:48 just asking if i can get similar behavior in the repl with my own vars

19:48 duck1123: but that's not thread local, which is the big difference

19:49 jweiss: sounds like the answer is no

19:49 duck1123: i believe it is

19:49 you can't call set! unless it's already thread local

19:49 at least, it doesn't work for me unless it's within a binding form

19:50 i assumed *print-meta* must be in a binding form in which the entire repl runs

19:50 gtrak_m: But the thread goes back in a pool most likely. Seems like unintended behavior could happen

19:50 jweiss: the repl is multithreaded? didn't know that

19:51 gtrak_m: You don't need to set! if you're binding already

19:51 jweiss: gtrak_m: i know that

19:52 gtrak_m: Just make the var dynamic

19:52 jweiss: i just want to permanently change a thread-local value until either i change it again or the thread ends

19:53 actually i'd be happy just to set a thread local value the shadows the root binding, permanently, in the repl

19:53 i know that's not necessary for the repl

19:54 gtrak_m: Why not just def?

19:54 jweiss: but it is for my runtime code, and i'd like to test the code in the repl that i'm actually going to use

19:54 i guess i can use 2 different forms - binding for running my program and def at the repl

19:54 but i was hoping there was one waya that would work in both places

19:54 samaaron: cemerick: for the children: https://gist.github.com/1494980

19:56 gtrak_m: Jweiss just split the function into one that does the binding and an internal version?

19:57 cemerick: samaaron: hah; I'll have to say that that one's "complected" ;-)

19:57 samaaron: cemerick: for sure, I never claimed to be a macro whizz

19:57 jweiss: gtrak_m: ok, i thought there might be a straightforward way

19:58 gtrak_m: You know how lots of fns in core have fn* versions

19:58 samaaron: i'd happily take any advice in simplifying it

19:58 i tried pulling out some of the fns into the letfn bindings

20:00 cemerick: samaaron: so that knocks out the record as a lookup fn; is that intentional?

20:00 samaaron: cemerick: what do you mean "knocks out"?

20:01 ah, you mean clobbers the original behaviour?

20:01 cemerick: right

20:01 samaaron: yeah, totally - the old behaviour is boring - we need new spice!

20:02 well, these things are meant to be used as fns first and maps second

20:02 cemerick: OK, I see what you're aiming at then

20:02 The function you pass to CallableMap. should implement all the arities you care about.

20:02 samaaron: cemerick: exactly, and we don't know that ahead of time

20:02 perhaps this is the wrong kind of datastructure

20:03 but in overtone we already use something like this quite a bit

20:03 perhaps the map should just be metadata...

20:03 and the fn just be a pure fn

20:05 cemerick: Maybe, hard to say without knowing the usage.

20:06 samaaron: for example, when you create a synth, we return a map which contains all the info for that synth, and the map also serves as a fn to trigger the synth

20:06 rather than having to pass it to a trigger fn

20:07 which feels pretty good from a user perspective

20:07 cemerick: How often is the data in the map accessed? And, does it ever figure into equality comparisons or used in a map?

20:08 samaaron: currently rarely accessed

20:08 and never used in equality comparisons or used as keys in a map

20:11 cemerick: So, I'd say metadata on a function *sounds* reasonable. You have to think about whether that is semantically appropriate though.

20:12 samaaron: when might our unwieldy callable-map approach seam appropriate to you?

20:12 s/seam/seem/

20:12 cemerick: meh

20:12 samaaron: b

20:12 cemerick: I've gone down that road and been burned in various circumstances.

20:13 samaaron: do you have any handy blog post brimming with wisdom gained from such circumstances?

20:13 cemerick: e.g. passing the fn/map around generically, getting odd results, and it being tough to track down why (was trying to use it as a function or a map when the "wrong" implementation was primary)

20:14 heh, no

20:14 samaaron: yeah, that's a good point

20:14 cemerick: If you *can* characterize the synths as functions with some metadata, that certainly seems cleaner on all fronts. *shrug*

20:15 samaaron: yeah, that's definitely worth considering prior to 1.0

20:15 might involve some gutting out

20:15 which is always a good thing (generally)

20:17 cemerick: In that case, you really do want a lower-level macro that emits a reify for each synth.

20:18 (or a deftype if the synths are top-level forms)

20:20 samaaron: cemerick: can you expand on your reify example?

20:25 cemerick: samaaron: I'll see if I can put together a macro in a bit.

20:25 samaaron: cemerick: that would be lovely

20:25 i'm going to bed now though :-)

20:27 cemerick: samaaron: feel free to bug me tomorrow if I haven't gotten to it yet :-)

20:27 samaaron: cemerick: will do :-)

20:28 technomancy_: cemerick: that's right re: clojure-jack-in from "inside the project"

20:28 cemerick: technomancy_: thanks :-)

20:28 technomancy_: dumped the apropos thing for an inspector demo BTW

20:29 technomancy_: sounds good

20:30 weavejester: that's right re: dev-deps and plugins. it will probably change in 2.0 to make plugins distinct from dev-deps though

20:33 xrl: I'm using noir to build an application and one important dependency appears to be incomplete. the hiccup.form-helpers is missing. when I do an "ls" on classes/hiccup there is no reference to "form_helpers"

20:33 any ideas?

20:34 I'm using an up to date hiccup

20:34 ibdknox: xrl: what happens when you try to require it?

20:41 xrl: ibdknox: so from the repl I'm trying (use 'hiccup.form-builder) and I get a FileNotFound exception

20:41 ibdknox: form-builder?

20:41 xrl: err

20:42 I was trying form-helper earlier... it has an S

20:42 ibdknox: :)

20:42 xrl: thanks for the help :)

20:49 cemerick: technomancy_: re: lein deps being invoked automatically — when was that added?

20:49 that doesn't appear to be true, at least for getting a repl on a new project…

20:51 ttaxus: How does "contains?" work? (contains? '("jhbadger") "jhbadger") returns false, so I obviously am using it wrong

20:51 TimMc: ttaxus: indeed

20:51 ibdknox: ,(doc contains?)

20:51 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

20:51 TimMc: clojurebot: contains?

20:51 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains

20:51 ibdknox: or filter

20:52 ttaxus: thanks!

20:53 TimMc: ttaxus: It's a poorly-named function.

20:56 quizme: how do you get a subset of k-v pairs from a hashmap given a vector of keys ?

20:58 select-keys

20:58 nm

20:59 weavejester: technomancy_: Ah, okay. So currently, if one is using lein to manage a production deployment (as with Heroku), you can't use plugins.

21:00 technomancy_: So how far is Leiningen 2.0 off? :)

21:06 technomancy_: weavejester: are you thinking of lein ring?

21:06 weavejester: technomancy_: Yup

21:07 technomancy_: I was thinking I could make "lein ring server" act as a production server as well as a dev server.

21:08 technomancy_: weavejester: better to use "lein run" or "lein trampoline run" although there is a workaround

21:08 weavejester: technomancy_: Hmm, well, if I use "lein ring server" then I don't have to bother setting up an adapter

21:08 technomancy_: cemerick: an empty lib/ dir has triggered deps for quite some time, but having a simple change to the :dependencies vector trigger deps is new in 1.6.2

21:09 weavejester: because it bundles jetty for you?

21:10 weavejester: technomancy_: Yes, and because I don't have to write something like: (run-jetty app {:port (Integer. (System/getenv "PORT"))}) etc.

21:10 technomancy_: it's only a couple lines to handle jetty yourself; I think there are benefits to being explicit

21:10 weavejester: But "lein ring server" is pretty explicit too

21:10 And I'd rather specify my handler in one place, the project.clj file, than two

21:11 technomancy_: weavejester: I need to take off; happy to discuss it further tomorrow

21:11 weavejester: It feels like I'm duplicating logic that could be in a standard library.

21:11 technomancy_: No problem :)

21:36 technomancy_: the tl;dr is that the idea of using leiningen in production is very new (~6 months) and that a lot of the design of plugins and such reflect the idea that it's a tool only used in development

22:04 tmciver: Where can I find the JavaDocs or source for clojure.lang?

22:05 brehaut: tmciver: https://github.com/clojure/clojure/blob/master/src/

22:06 tmciver: Thanks brehaut

22:27 TimMc: You're not going to find javadocs, though -- Clojure/Core is allergic to docs or something.

22:57 simard: hum wasn't it possible with clojure 1.3 to use a record's constructor as a function ? say, in a map.

22:58 (map my-record a-list)

23:00 brehaut: simard: map->recordname

23:00 ithink

23:00 simard: its not the constructor anyway, its an autogenerated function

23:01 simard: http://dev.clojure.org/display/design/defrecord+improvements is perhaps a good place to look?

23:05 simard: sounds good, thank you

23:07 perhaps I should be using maps and multimethods for now..

23:08 hum. no. ok this works now.

Logging service provided by n01se.net