#clojure log - Dec 31 2011

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

0:01 adiabatic: thanks!@

0:07 TimMc: adiabatic: When you see "((" you should think, "Whoop, here comes a function call that returns a function!"

0:07 (or a thing that can be used as a function)

0:07 amalloy: i prefer to think "aw yeah, code's about to get awesome"

0:08 adiabatic: yeah, that was an artifact of my, ahem, transitional indentation style

0:08 amalloy: haha

0:08 if you're ashamed about it, you're on the Path

0:17 TimMc: amalloy: (((((((((((((foo))))))))))

0:17 um

0:17 )))

0:17 amalloy: )))

0:18 TimMc: Off-by-one error (I was counting in 3s.)

0:19 amalloy: counting is too hard. it just looked off so i checked in paredit

0:19 TimMc: (((((...))))) probably means you should be using trampoline. :-P

0:23 amalloy: &(class ((((((fn [] (fn [] (fn [] (fn [] (fn [] (fn []))))))))))))

0:23 lazybot: ⇒ sandbox6906$eval9224$fn__9225$fn__9226$fn__9227$fn__9228$fn__9229$fn__9230

0:23 amalloy: is lazybot lagging like mad today, or is it me?

0:26 adiabatic: OK, I think I need another hint. I need to implement count, and I can't use def (otherwise I'd recursively peel off the head of the list until I ran out of list). Subtle hints, anyone? Nothing in http://clojuredocs.org/quickref/Clojure%20Core looks particularly promising for this one

0:26 tomoj: you mean you need an anonymous count?

0:26 well..

0:26 amalloy: zoiks. subtle hint: def is *terrible* for locals; you want to use let, loop, or a recursive function

0:27 adiabatic: "try let instead". got it.

0:27 tomoj: you mean (defn my-count [coll] ...) is allowed?

0:28 amalloy: really recursion is the answer; let and loop are just sugar. you can create any kind of "looping" structure you want with just recursive functions

0:29 adiabatic: (defn my-count [x] (x)) ; You tripped the alarm! def is bad!

0:29 amalloy: (fn my-count [x] x)

0:30 adiabatic: And I'll be able to call my-count from within that anonymous…ish…function?

0:31 amalloy: &((fn my-plus [x y] (if (zero? x) y (my-plus (dec x) (inc y)))) 10 20)

0:31 lazybot: ⇒ 30

0:34 emezeske: l

0:34 wrong terminal!

0:41 JorgeB: Is it possible to safely eval some code as if in a sandbox?

0:52 amalloy: $google clojail flatland

0:52 lazybot: [flatland/clojail - GitHub] https://github.com/flatland/clojail

0:53 tomoj: &{# "hi!"}

0:53 lazybot: java.lang.ClassNotFoundException: hi!

0:53 tomoj: what is that?

0:53 amalloy: &#java.util.Date[]

0:53 lazybot: ⇒ #<Date Fri Dec 30 21:54:39 PST 2011>

0:53 amalloy: &'#java.util.Date[]

0:53 lazybot: java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: Fri Dec 30 21:54:58 PST 2011

0:54 tomoj: new eval syntax in 1.3?

0:54 amalloy: it's the record-literal syntax in 1.3

0:54 tomoj: er.. ah

0:55 oh, here it's actually {(Long. 1) "hi!"}, the test output just had a #

0:55 &{# "java.util.Date"}

0:55 lazybot: java.lang.RuntimeException: Unreadable constructor form starting with "#java.util.Date}"

0:56 JorgeB: amalloy, thanks

0:56 tomoj: hmm

0:57 amalloy: writing clojure.test code with arrows and doto looks hilarious, kinda yoda-ish. (doto (f x) (-> nil? not is))

0:58 tomoj: is the record literal syntax documented anywhere?

1:04 amalloy: ,(case 1 (1 2) "one or two")

1:04 clojurebot: "one or two"

1:04 amalloy: ,(case 1 [1 2] "one or two")

1:04 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: 1>

1:22 adiabatic: do I need to install clojure-contrib-devel via macports to get (use 'clojure.contrib.trace) to work, or is clojure-contrib enough?

1:23 amalloy: don't install clojure-anything from macports

1:23 $google clojure github leiningen readme

1:23 lazybot: [README.md at master from technomancy/leiningen - GitHub] https://github.com/technomancy/leiningen/blob/master/README.md

1:24 amalloy: install that baby and let it handle your dependencies (including clojure and, if you must, contrib) for you

1:43 adiabatic: OK, now I can't get my `clj scratchpad.clj` workflow back yet…

1:45 amalloy: what does that do? compile-and-run that file, then exit? just lein repl, and if you want you can call load-file from there

1:45 adiabatic: I put `:main helloworld.core` in project.clj and now when I do `lein run` I get a ClassNotFoundException: helloworld.core

1:45 Yeah.

1:45 amalloy: sadly clojure currently requires you to AOT-compile a namespace if you want to run it as main

1:46 (ns helloworld.core (:gen-class)) (defn -main [& args] ...) probably works, if you aren't ready to embrace a repl-driven workflow yet

1:49 adiabatic: Never really did in Python. Don't expect it'll grow on me too quickly.

1:51 AFAICT it's great for quick syntax checks, but for repeated errors, I tend to prefer the "up, enter" dance

1:58 there we go

2:15 replaca: Raynes: ayt?

2:15 late at night?

3:49 jackdempsey: hey folks, can anyone point out the obvious mistake here? doing what i thought would be simple learning exercises and i'm already failing

3:49 https://gist.github.com/1543423

3:49 the usage of odd? works as i'd expect, but not the divisible-by…anything basic i'm missing!?

3:53 oh lord. nm. ha.

4:25 gf3: is there something like take-if, or should I use for?

4:26 or drop-if

4:31 ahh I want filter

8:12 foodoo: I'm working on the 4clojure problem 128 (https://www.4clojure.com/problem/128) with my solution http://pastebin.com/n3GPbkhX and it looks like the sandbox doesn't like my code. 4clojure returns: "java.security.PrivilegedActionException: java.lang.ClassCastException [...]" How can I make the sandbox accept my solution?

8:50 Raynes: foodoo: Need to actually know what the error is.

8:50 You'll need to paste the exception.

8:50 foodoo: java.security.PrivilegedActionException: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry (NO_SOURCE_FILE:0)

8:52 Raynes: That doesn't look like a sandbox thing.

8:52 Does it work in your repl?

8:53 foodoo: Raynes: the individual functions do. And also the (-> ...) expressio

8:53 Raynes: What is 'card'? It doesn't seem to be defined.

8:54 foodoo: ah, you are right

8:56 I wrapped the entire thing in a (fn [card] %existing-code%) expression now. But I still get the same error.

8:58 Raynes: foodoo: Wrapping it in (fn [card] ..) and then calling it works in my repl.

8:59 foodoo: Raynes: Yes. I also tested it and it works fine in the repl

9:00 Raynes: Oh, I see.

9:00 That is strange.

9:00 That could possibly be a bug in the sandbox.

9:00 foodoo: Could you create an issue on http://github.com/4clojure/4clojure/issues about it?

9:00 foodoo: sure

9:10 Raynes: done https://github.com/4clojure/4clojure/issues/200

9:11 Raynes: Thanks

10:11 TimMc: amalloy_: Wait, what? There's a record literal syntax?

10:11 Bronsa: since clojure 1.3

10:12 TimMc: Is it part of the public API?

10:12 It's totally not listed on http://clojure.org/reader

10:13 Bronsa: http://dev.clojure.org/display/design/defrecord+improvements

10:22 TimMc: OK, I think I've seen that.

10:28 Vinzent: Hello and happy new year! Where -?> is located now? Is it in new contrib or in clojure itself?

10:33 TimMc: Vinzent: incubator, I think?

10:35 Vinzent: TimMc, yeah, thanks

10:39 TimMc: Fuck it, creating an issue for *read-eval* not being documented in read and read-string.

11:10 Raynes: TimMc: It isn't particularly documented, but it is absolutely on purpose and public.

11:10 TimMc: Raynes: Which, the record syntax?

11:11 Raynes: Oh wait, nevermind.

11:11 Literals.

11:11 I thought you were talking about the factory functions.

11:11 I'm just as surprised as you are about this fancy record syntax.

12:06 lnostdal: there's isa? and similar, but is there a type-checking function suitable in e.g. :pre and :post contexts which will show an error message telling which type (and perhaps printed representation of value) it actually did get instead of what it expected?

12:07 the thing i seem to do over and over is add and remove print statements -- just to figure out what actually was passed

12:13 Vinzent: lnostdal, you can write hook that will prn all input data and add it to the functions you are currently working on

12:14 and for type checks you can use (class x)

12:18 also, 'spy' from the tools.logging may be halpful

12:18 lnostdal: yeah, i already have something like spy

12:18 but adding it, then removing it over and over again ....hm

12:19 clojure needs something like check-type (common lisp)

12:20 TimMc: lnostdal: Add it to a project, require that project everywhere.

12:20 lnostdal: or whatever .. not sure if that did what i mean here actually

12:22 Vinzent: lnostdal, with hooks you don't have to modify code itself, you can just add/remove them from the repl

12:23 lnostdal: what do you mean by hooks?

12:23 Vinzent: https://github.com/technomancy/robert-hooke

12:24 lnostdal: ok, yeah

12:25 better of writing my own type-checker / assert function that does what's needed _when_ something goes wrong .. instead of, here too, having to add hooks .. then figure out a way to make the same scenario play out again

12:25 feels silly .. should be in core already ...meh

12:27 Vinzent: so you want tracing of input data for all functions? or you want static-typed clojure? :)

12:27 TimMc: Probably just better reporting from pre/post.

12:29 lnostdal: ,((fn [x] {:pre [(isa? (type x) clojure.lang.Ref)]} (+ @x 2)) 40)

12:29 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.AssertionError: Assert failed: (isa? (type x) clojure.lang.Ref)>

12:30 lnostdal: yes, TimMc .. something like isa? there .. but it should of course say what it actually _did_ get .. simple really .. :>

12:32 Vinzent: ah, yeah, then I agree

12:32 lnostdal: something like "I got a <long: 40>, but expected a ref." .. then i instantly go "oh right!" .. no need to reeval code, do tests again, or even figure out what the heck some random user did to trigger this -- now long passed, scenario

12:36 Vinzent: yeah, that's true. I don't use pre and post conditions much, so I haven't actually face these problems

12:36 also, it'd be nice to have simpler, in-line syntax for conditions

12:37 something like this http://onclojure.com/2010/03/05/pre-and-post-conditions-a-quest-for-a-nicer-syntax/

12:39 and a mechanism to describe structure of nested collections, something similar to midje's 'just'. E.g. if I want a vector of 2 numbers, I could write (match [number? number?] x)

12:43 y3di: is sam aaron's overtone talk from the 2011 conj on the web?

13:11 Raynes: y3di: Not yet.

13:31 technomancy: amalloy_: "sadly clojure currently requires you to AOT-compile a namespace if you want to run it as main" <- only true of uberjars actually; both "lein run" and "clojure.main -m" will work without gen-class/aot.

13:36 wingie: is there a good book on how to do functional programming in clojure?

13:38 Vinzent: wingie, any clojure book :)

13:39 wingie: Vinzent: is this a good source for learning it? http://clojure.org/

13:39 or should i pick a book instead

13:42 how do i install latest java on mac?

13:43 Vinzent: wingie, I think book would be much better. Also check out http://learn-clojure.com/ - there is a lot of useful links there

13:44 pandeiro: wingie: i am really liking clojure in action, published by manning

13:45 wingie: okay i know ruby and javascript

13:45 have no experience with java .. is it crucial to know java when using clojure?

13:46 would i ever need to touch a java lib?

13:46 or i know a little java (learned the basics some years ago)

13:47 technomancy: wingie: over time you'll need to learn how to read Java (not right away), but writing Java is unnecessary unless you're working with a legacy codebase.

13:47 wingie: technomancy: why would i need to learn how to read java?

13:48 and when

13:48 technomancy: wingie: learning how poorly-documented libraries work or debugging issues with them

13:50 pandeiro: i get a connection refused error now when i try to clojure-jack-in... it seems to fail on open-network-stream... anyone know what that's about?

13:55 weird, if i run lein swank and then use slime-connect, it works on port 4005

13:56 and clojure-jack-in was working fine just yesterday after i replaced 1.3.2 w/ 1.3.3

13:56 Raynes: technomancy: I don't think I've ever needed to read Java code.

13:57 technomancy: it depends on the libraries you use

13:57 it used to be a lot more necessary to know the JDK for I/O

13:57 TimMc: technomancy: Why can't an uberjar just include a launcher class that calls clojure.core with the real main class?

13:57 Is this just a "patches welcome" situation?

13:57 technomancy: you'd need non-transitive AOT

13:58 unless you did runtime resolution, which would work fine

13:58 are you saying it should be a lein feature or what?

13:58 I guess at least documenting as a technique in the tutorial would be good

13:58 but /me is heading off

14:01 TimMc: OK. I'll try to build a JAR that does what I imagine.

14:12 I'm imagining a fake main that calls clojure.main -m

14:20 Well, that was easy.

14:27 pandeiro: alright so my issue was ip6-related

14:27 (just in case my future self is looking this up in Raynes' #clojure logs)

14:29 TimMc: Is there a way I can check whether something was AOT-compiled? e.g. some var.

14:32 Raynes: pandeiro: I don't thing that there is more than one of them.

14:32 s/them/me/

14:33 Oh, wait. Never mind. Grammar nazi fail.

14:35 TimMc: rayneseses

14:36 pandeiro: Raynes: i proofread for a living :)

14:36 Raynes: TimMc: I've been reading up on English conventions since Stuart Sierra threatened to asphyxiate guppies if I ever accidentally say "it's" when I mean "its".

14:37 pandeiro: its and it's is painful to read, but there/their makes me cry

14:38 then i try to tell myself that most people on the internet are not native english speakers

14:38 TimMc: Yeah, just keep telling yourself that.

14:38 Raynes: pandeiro: Yeah, I was under the impression that you needed to use s's when a name is both possessive and ends in a s, but theoatmeal tells me that either way is acceptable.

14:38 TimMc: pandeiro: Do you find that spending time on the internet impairs your grammar-sense?

14:38 pandeiro: TimMc: no it makes it more acute

14:39 Raynes: i am under the impression that s's is NEVER, EVER acceptable

14:39 TimMc: I *never* had problems with their/there/they're in elementary school, but I find myself typo'ing those these days.

14:39 Raynes: pandeiro: I bet that you'd vibrate like a washing machine if you trolled through a VB.NET forum for a while.

14:40 pandeiro: haha let me go do that

14:40 i need a boost

14:50 romanandreg: hey guys, I'm trying to extend some of the clojure libraries (algo.monads in this case), but I don't have any leiningen tools, do you have any wiki or tutorial where they show you how to compile and run test on this projects where the only thing you have is a pom.xml file?

14:51 also, how do I load the library to the repl the same way "lein repl" would do?

15:05 I tried maven, but when I call mvn in the root of the project I get this error:

15:05 [WARNING] Some problems were encountered while building the effective model for org.clojure:algo.monads:jar:0.1.1-SNAPSHOT

15:05 [WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ org.clojure:pom.contrib:0.0.25, /Users/roman/.m2/repository/org/clojure/pom.contrib/0.0.25/pom.contrib-0.0.25.pom, line 119, column 15

15:06 sadly my maven foo is not that great :-(

15:08 TimMc: technomancy: OK, I have a working example of a JIT uberjar using an AOT loader class: https://github.com/timmc/uberjit/blob/master/src/sj/loader.clj

15:12 technomancy: So, I'm imagining Leiningen dropping that loader.clj in with a hardcoded namespace.

15:55 flazz: is it possible to overload count for a custom type?

16:03 TimMc: flazz: Check the source.

16:03 See if there's a multimethod or interface or what have you.

16:03 flazz: TimMc: for count? will do

16:03 thanks

16:04 TimMc: flazz: I think there's a Counted interface for constant-time counts.

16:04 bobhope: Does anyone know how progress on clojure's integration with Fork/Join is going?

16:04 Or when it might be released?

16:06 Also, can anyone explain how agents are scheduled? Like, if you have a system with 10 agents, and one agent has 100 actions pending and the others each have 5 actions pending, and the agent with 100 actions pending runs one action, will the thread that agent was run on continue running actions from that queue until it's exhausted? What if one of those actions causes additional actions to be sent to that agent?

16:11 chouser: bobhope: It's not documented, so don't rely on this always being the case...

16:12 hiredman: bobhope: I think they run roughly fifo, they use an executor under the hood which most likely keeps tasks in a queue

16:12 chouser: but my reading of the code indicates that once an agent is running an action, it won't give up its thread until at the end of an action there are no more actions to run.

16:13 hiredman: *sigh*

16:13 * hiredman fires up emacs

16:13 chouser: heh

16:13 You don't trust my reading of Java code?

16:14 src/jvm/clojure/lang/Agent.java line 155

16:15 hiredman: well, a lot has a changed since the last time I looked Agent.java

16:15 chouser: hm, no, you're right to doubt me

16:16 hiredman: I don't think this ActionQueue thing existed last time I looked at this

16:16 chouser: the execute just re-queues the action

16:16 rather, queues the next action. subsequent actions on the same agent can probably end up on different threads.

16:16 this should be easy to demonstrate.

16:16 Raynes: I have a system with 10 chousers. He basically just schedules things however he likes.

16:16 It works out though.

16:17 chouser: Your chousers work out? I should get one of those.

16:18 hiredman: (send-off (agent :agent) (fn f [_] (send-off *agent* f) (println (.getId (Thread/currentThread)))))

16:18 or something

16:19 chouser: it seems like the possible starvation behaviour would be undesirable, so I would be surprised if that is what agents did

16:20 bobhope: chouser, sorry, i didn't see your response--i'm going to look at the code now

16:20 chouser: yep, you're right.

16:20 (dotimes [_ 20] (send a #(do (Thread/sleep 100) (prn (.getId (Thread/currentThread))) (inc %))))

16:21 when I run that here I get a bunch of actions on one thread, then a bunch on another.

16:21 If my original interpretation of the code were correct, that would be impossible, so I was definitely wrong.

16:21 bobhope: so hiredman was right -- all the actions are fed into executors which manage the scheduling

16:22 bobhope: do you know which executor might be backing it?

16:22 chouser: but regardless, these specifics aren't documented which means future versions of Clojure could do something different.

16:22 clojurebot: Cool story bro.

16:23 hiredman: bobhope: it's a vanilla executor

16:23 bobhope: I'm interested because I have a program with 100k agents or so, and they each have small actions, but I think it makes sense to attempt to run the actions in batches to improve locality

16:23 chouser: bobhope: yup! ##clojure.lang.Agent/pooledExecutor for send and ##clojure.lang.Agent/soloExecutor for send-off

16:24 huh

16:24 ,clojure.lang.Agent/pooledExecutor

16:24 clojurebot: #<ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor@da95c1>

16:24 chouser: ,clojure.lang.Agent/soloExecutor

16:24 clojurebot: #<ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor@2e3cb1>

16:25 hiredman: seems like a lot of agents to me, but I've never really used agents seriously

16:25 bobhope: my problem has a lot of parallelism

16:26 unfortunately, it's pretty fine-grained

16:26 chouser: I wouldn't be surprised if batching improves throughput

16:26 hiredman: well, agents aren't for parallelism

16:27 bobhope: they aren't?

16:27 what are they for?

16:27 hiredman: they are for wrapping a series of async generated states with an identity

16:28 bobhope: I don't understand what that means

16:28 hiredman: ~google rhickey state and identity

16:28 clojurebot: First, out of 1680 results is:

16:28 UI Press | Donald R. Hickey | The War of 1812: A Forgotten Conflict

16:28 http://www.press.uillinois.edu/books/catalog/84xtw3mk9780252060595.html

16:28 hiredman: Uh

16:29 wingie: how can i have REPL up/down key support?

16:29 hiredman: bobhope: if you just want to run tasks in parallel then you don't want agents, you want futures or use executors directly

16:30 agents are a clojure reference type

16:30 bobhope: my problem involves having hundreds of thousands of state elements with data flowing between them

16:30 hiredman: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey this one

16:31 bobhope: it seems like agents are a good abstraction for modeling this problem

16:31 hiredman: ah, so you do need the state to have a consistent identity

16:32 bobhope: the problem I'm solving is really a dataflow problem

16:32 wingie: anyone?

16:32 bobhope: but it has some extra out-of-band state beyond the dataflow itself

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

16:32 wingie: i need up/down key to work :(

16:32 bobhope: wingie, get leiningen

16:33 hiredman, I don't know what you mean by "identity"

16:33 hiredman: wingie: rlwrap

16:33 bobhope: so clojure generally deals with immutable data

16:33 like {:name "bob"}

16:33 bobhope: yep

16:34 hiredman: (let [bob {:name "bob"}] bob)

16:34 bobhope: Oh, you mean identity in the sense that I have a name for something whose data is changing, which is why I need a reference type?

16:34 wingie: wii there is a brew package for leiningen

16:34 hiredman: wingie: use the shell script

16:34 bobhope: wingie, google for leiningen, then click the first link, then read

16:34 hiredman: the data isn't changing, you have a series of unchanging data over time

16:36 but you wrap that unchanging data over time in a single reference (an identity)

16:36 wingie: hiredman: why not brew?

16:36 bobhope: when you say "change", you're referring to mutation?

16:36 hiredman: yes

16:37 the reference types use managed mutation to provide identities

16:37 bobhope: ahh, that's what I wasn't understanding

16:37 wingie: brew installs 1.6.2 which is the latest according to https://raw.github.com/technomancy/leiningen/stable/bin/lein

16:38 so i guess its the same

16:38 bobhope: I was trying to interpret what you were saying under the assumption that I fully understood that clojure's mutation is constrained to reference types

16:38 vocabulary is hard ;)

16:38 hiredman: wingie: it's not, the lein shell script will install it for your user

16:38 wingie: hiredman: ah .. it doesn't matter for me if it installs system wide

16:38 chouser: "identity" means approx the same as "instance of a reference type"

16:39 hiredman: wingie: better not to though

16:39 wingie: hiredman: why?

16:39 amalloy: Raynes, pandeiro: Raynes was right about s's, and the oatmeal was apparently wrong. if a name ends with an s but is not plural, then its possessive ends with s's. for example, the dog owned by someone named Evans is Evans's dog

16:39 bobhope: chouser, now I understand

16:39 Raynes: amalloy: You're about to go to war with a proofreader. Better don your English hat.

16:40 hiredman: wingie: I dunno, just nothing else in the java/clojure ecosystem installs system wide

16:40 amalloy: Raynes: i will bitchslap any "proofreader" who thinks s's is never acceptable

16:40 hiredman: amalloy: different style guides say different things, s's is the more modern choice

16:40 amalloy: hiredman: emacs! :P

16:41 wingie: why is the repl that bad it doesn't have auto completion and forces me to use rlwrap

16:41 haskell's REPL is way better :)

16:41 hiredman: wingie: becuase no one cares

16:41 amalloy: wingie: because rlwrap exists. why waste effort on reimplementing rlwrap?

16:41 wingie: i care!

16:41 bobhope: I usually use vimclojure or slime

16:41 wingie: perhaps im a noone

16:41 hiredman: there is more interesting code to write

16:41 bobhope: It's like a repl, but it's way better

16:42 wingie: ok

16:42 bobhope: since you get the full power of a text editor behind you

16:42 hiredman: you can write code just fine with the existing repl

16:42 good enough

16:42 technomancy: there is reply

16:42 wingie: is it an idea to use leiningen to run clojure files instead of using REPL to learn?

16:43 technomancy: https://github.com/trptcolin/reply

16:43 Raynes: technomancy: Why isn't that in Leiningen yet?

16:43 technomancy: Raynes: it's not really done yet

16:43 it was only started at the conj iirc

16:43 bobhope: wingie, leiningen is a build system that also can configure a repl with readline and set up your classpath for you

16:44 wingie, if you really want to use a pleasant environment, you should choose vim or emacs

16:44 Raynes: technomancy: Neither is Leiningen, but I still use it. :p

16:44 Leiningen is a development environment for the command line.

16:44 bobhope: wingie, and then, you can have incredible power by having your editor be a repl

16:44 technomancy: Raynes: reply is totally on the table for 2.0

16:45 bobhope: so that you can execute the code under the cursor, or see what its macro expansion is

16:45 or look up its documentation or soure

16:45 *source

16:45 wingie: bobhope: im using cloud9ide for my web projects

16:45 Raynes: It's probably best if we avoid terms like "build system".

16:45 wingie: they have clojure support ... thank god

16:45 pandeiro: amalloy: Raynes: touche, seems i am getting old (http://www.chicagomanualofstyle.org/CMS_FAQ/PossessivesandAttributives/PossessivesandAttributives01.html)

16:45 wingie: or let me say clojure highlighting

16:46 i decided to try out clojure instead of haskell because they had clojure highlithing haha =)

16:46 technomancy: Raynes: I like the term "project automation" but I'm not 100% settled on it

16:46 bobhope: wingie, if you want blissful development, you should really consider vim or emacs with the associated clojure integration

16:46 For instance, I just type ,me to macroexpand the block under my cursor

16:46 Raynes: technomancy: I don't really like including "project" in it.

16:46 That implies that it is useless for non-project things.

16:46 yoklov: emacs makes writing lisp code amazing

16:47 bobhope: or ,et to execute the expression under my cursor in the repl

16:47 amalloy: yoklov: writing lisp code is already amazing

16:47 Raynes: pandeiro, amalloy: Nobody was incorrect then, right? Not even theoatmeal.

16:47 wingie: bobhope: yeah vim is powerful

16:47 technomancy: Raynes: well if core would get off their bums and actually provide a launcher, it then lein could get back to just being about projects

16:47 yoklov: That's true, not having paredit-mode is a pain though.

16:47 wingie: its the best console editor ever

16:48 bobhope: wingie, have you used vim?

16:48 pandeiro: Raynes: depends on whose authority the question rests... AP (hence most American mags and newspapers) doesn't allow s's

16:48 wingie: yepp

16:48 bobhope: are you comfortable with it?

16:48 amalloy: i totally agree emacs is great for writing lisp. you're just implying that it's not awesome to write lisp unless you use emacs

16:48 wingie: just during a period .. now im using c9 more

16:48 no .. just a beginner

16:48 yoklov: Oh, I didn't mean to imply that at all

16:48 wingie: using it for simple stuff on the console

16:48 Raynes: pandeiro: Have you ever just considered learning lojban and pretending that you were never a native English speaker?

16:49 wingie: once upon a time i even wanted to learn vimscript because of it=)

16:49 bobhope: wingie, http://naleid.com/blog/2011/12/19/getting-a-clojure-repl-in-vim-with-vimclojure-nailgun-and-leiningen/ was really useful for me

16:49 pandeiro: Raynes: i will consider that, after lisp

16:49 bobhope: it gave me an excellent dev environment for clojure

16:50 wingie: nice thanks

16:58 is Leiningen the defacto build system for Clojure?

17:05 lein is like npm for node/gem for ruby

17:07 yoklov: i think its somwhere between the two things you said (but i'm just learning clojure also)

17:07 somewhere*

17:08 wingie: yoklov: cool

17:08 we should chat :)

17:08 why are you learning clojure?

17:08 and from what langs are you from

17:09 yoklov: other lisps

17:09 wingie: ah

17:09 yoklov: and i guess i also know java but thats... less important haha

17:09 wingie: it would definitely be simpler for you to learn it then

17:09 for what you learning clojure?

17:09 yoklov: maybe, i keep getting stuck and just going back to them though haha.

17:10 better libraries, mostly. Also it feels much more modern.

17:11 I.E. car/cdr/cons was designed in the 60s and feels a bit... dated (tragically, I'm so used to it).

17:12 wingie: isn't clojure from 2009?

17:13 yoklov: Dunno, around then I think. Sequences certainly feel like a better way of doing things though.

17:13 wingie: ah im still very new .. kinda 1 hour... need to start reading a book about it

17:13 yoklov: this is like my 4th or 5th time trying to learn.

17:13 wingie: wow :)

17:14 yoklov: well none of them were very serious and I just get stuck at a point and end up being like "oh i know how to do this in racket (or whatever) i'll just go back to that"

17:15 wingie: :)

17:15 i hope i will like all the ()

17:15 yoklov: oh, you will.

17:15 wingie: it sure will look cool if they were of different colors

17:16 its cool that heroku has support for it

17:16 another reason im learning clojure before haskell

17:16 just in case i have a backend app i can just deploy it

17:16 yoklov: eh, haskell's type system is way more of a hassle than its worth

17:18 wingie: what do you think of lisp?

17:18 someone in that channel told me to not bother learning clojure

17:18 that it wasn't ready yet

17:18 yoklov: they're jealous that lisp is more powerful.

17:18 amro: is there a way to get cleaner backtraces from noir? I'm not interested in seeing clojure.lang.Compiler.analyzeSeq(Compiler.java:6409) etc

17:19 danlarkin: you may not be interested in seeing it... but it's on the stack, sooo

17:20 amro: so what exactly?

17:20 danlarkin: so it's gonna show up in stack traces

17:20 amro: I'm wondering if there's something that cleans it up already, else I'll use a wrapper around lein run that filters it out

17:21 danlarkin: saying you want to clean it up implies you think it's dirty

17:21 but it's just being accurate

17:21 amro: it's noise, my mistake is on the top of the stack

17:21 yoklov: wingie: check your pm's

17:21 danlarkin: those frames *are* actually on the stack

17:21 amro: I know they are

17:24 danlarkin: you may only be interested in the top of the stack right now, but who knows when the whole thing will provide you with insight

17:25 amro: I'm not saying want to nuke it from orbit and ensure it never shows up again anywhere, I'm just asking if there's a way to filter it when I want to filter it

18:11 wingie: no one said i could use leiningen's repl :)

18:11 no need to install anything else

18:12 lein is so slow .. is it because it has to boot up the whole jvm?

18:29 emezeske: wingie: I believe that is why it's slow. I've heard that getting a "client" JVM installed can help a lot

18:39 seancorfield: wingie: I tend to leave a REPL open in a window for a long time (so I don't deal with startup time)

18:39 My REPL in Emacs (via lein swank-clojure) has been open for weeks :)

18:51 wingie: seancorfield: :)

20:22 adiabatic: Still getting the hang of lispy formatting style. How's this? https://gist.github.com/1545877

20:26 amalloy: your indents are weird. i guess you're not using emacs?

20:30 adiabatic: No.

20:31 amalloy: adiabatic: https://gist.github.com/1545887 is some feedback

20:32 adiabatic: I've tried it, but that was back in the days when vim was my go-to editor of choice, and it wasn't So Frigging Awesome that I wanted to switch. I've since moved on to TextMate and now BBEdit.

20:32 thanks!

20:32 amalloy: note also that your current version fails if the input collection is nil: it reports count is 1

20:33 adiabatic: So two-space indents is the strong convention in lispland?

20:33 amalloy: for forms that have a "header" and a "body", yes

20:34 eg, fn has a header where you give it a name and args, then a body. the body is indented by two

20:41 anyway, more important than how many spaces you indent by is that if A is a subform of B, then A is indented more deeply than B. your original version violated that assumption by putting (let [r (rest coll)] ...) farther left than (fn my-count-plus ...), which was its parent

20:44 adiabatic: gotcha

20:50 amalloy: it seems a little weird to me that lisp, this whole family of languages, have all (mostly) settled on one consistent formatting style, while all the young upstarts like C are still arguing among themselves and need company/project style-guides to keep things consistent from developer to developer

20:54 adiabatic: Probably has more to do with the number of different syntaxes and syntax rules in the curly-braces camp.

20:58 would "(cond" get its own line if the first test were really long?

21:05 amalloy: i dunno. clojure's cond is a beast to indent

21:07 because it drops the "unnecessary" parens around each pred-expr pair, there's no easy way for editors to indent it right, and it can be hard for the reader to tell what's a pred and what's an expr

21:07 i wrote a cond+ that lets you write (cond+ test1 expr1 [test2 expr2]), ie put in brackets whenever you think it aids readability

21:13 adiabatic: why is (seq …) better than (= '() …)? Brevity, but anything else?

21:14 Also, in clojure, do I need to worry about my functions being tail-call optimizable?

21:14 hiredman: clojure doesn't do tco

21:14 the empty list doesn't need to be quoted

21:15 ,(= () nil)

21:15 clojurebot: false

21:15 hiredman: ,(= (seq ()) nil)

21:15 clojurebot: true

21:15 hiredman: ,(map empty? [() nil])

21:15 clojurebot: (true true)

21:17 hiredman: ,(filter string? (repeat 10 1))

21:17 clojurebot: ()

21:17 hiredman: ,(seq (filter string? (repeat 10 1)))

21:17 clojurebot: nil

21:27 adiabatic: ,(first ())

21:27 clojurebot: nil

21:30 amalloy: because things which are empty are not always ()

21:32 adiabatic: ,(= () "")

21:32 clojurebot: false

21:32 hiredman: ,(= () (seq ""))

21:32 clojurebot: false

21:32 hiredman: ,(= nil (seq ""))

21:32 amalloy: and if you test against () everyone who reads your code will be like "...what is he testing here?" as compared to when you do (if (seq x)) the reader says "okay, he's seeing if the thing is empty or not"

21:32 clojurebot: true

21:32 hiredman: ,(empty? "")

21:32 clojurebot: true

21:35 adiabatic: ,(if-let [[h & r] ""] 1 0)

21:35 clojurebot: 1

21:35 hiredman: ,(macroexpand '(if-let [[h & r] ""] 1 0))

21:35 clojurebot: (let* [temp__3695__auto__ ""] (if temp__3695__auto__ (clojure.core/let [[h & r] temp__3695__auto__] 1) 0))

21:36 hiredman: ,(if-let [[h & r] (seq "")] 1 0)

21:36 clojurebot: 0

21:51 adiabatic: ,(if-let [[h & r] [1 2 3 4 5]] 7 8)

21:51 clojurebot: 7

21:51 adiabatic: ,(if-let [[h & r] [5]] 7 8)

21:51 clojurebot: 7

21:51 adiabatic: ,(if-let [[h & r] []] 7 8)

21:51 clojurebot: 7

21:51 adiabatic: …hunh.

21:51 * technomancy still thinks seq is a weird predicate

22:19 amalloy: [] is truthy, as is (). what's the problem, adiabatic?

22:20 adiabatic: New problem now. Can I use destructuring assignment on (sorted-set 1 2 3 1)?

22:21 code: https://gist.github.com/1546129 passes 1, fails on 2: http://www.4clojure.com/problem/23

22:21 Complains that nth isn't supported on this type, but *I*'m not using nth…

22:30 wingie: could you say that vector is like an array in other langs?

23:14 technomancy: wingie: sorta

23:15 arrays are usually mutable and fixed-length and often homogeneous, but apart from that they are similar

Logging service provided by n01se.net