#clojure log - Oct 20 2012

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

0:50 l1x: o hai

0:51 is there a way to avoid nil being printed?

0:51 when i lein run my app its happening and i would like to get rid of it by default

0:53 julson: l1x: does your app have a main method?

0:53 l1x: it does

0:54 * adu <3 clojure

0:54 adu: I had a question tho

0:54 why is it so hard to use web noir with clojure 1.4 and lein2?

0:54 frozenlo`: it is?

0:54 julson: l1x: the nil should be the result of the function being called. You could try returning something else...

0:54 adu: its hard

0:55 l1x: julson: i would like to return nothing

0:55 julson: adu: I haven't had issues with that configuration

0:55 frozenlo`: Me neither.

0:55 l1x: yeah i have it running on my laptop too

0:56 julson: l1x: I don't think you can... since functions must return something by definition. Unless you fiddle around with your stdout

0:56 l1x: i see

0:57 it is just annoying that there is not idiomatic answer yet i guess :) it should be possible

0:58 julson: yeah it should be possible.

0:58 you could try something with Java interop

0:59 and create a class with a public static void main method

1:00 adu: how does one use lein-noir with lein2?

1:00 Raynes: `lein new noir myproject

1:00 `

1:00 Don't install anything at all.

1:01 adu: "lein noir new myproject"

1:01 Raynes: No, lein new noir myproject

1:01 julson: Raynes is correct

1:01 if you're using lein2

1:01 adu: really?

1:01 Raynes: I promise.

1:01 julson: yes

1:01 adu: that doesn't make any sense

1:01 Raynes: I wrote leiningen's new task. It makes perfect sense.

1:01 adu: that goes against every documentation at http://webnoir.org/

1:01 julson: that's kinda outdated

1:02 adu: wuh

1:02 then why am I following it

1:02 julson: I think the documentation's for lein1

1:02 l1x: yes

1:02 Raynes: That's because the website documents the current release of noir which was pre-lein2.

1:02 frozenlo`: adu: Raynes wrote a big part of Noir, I would listen to him :P

1:02 adu: ok

1:02 Raynes: frozenlo`: Naw.

1:02 I wrote small pieces and moved other pieces.

1:02 I still couldn't tell you how half of it works.

1:02 adu: AHA

1:03 it is "lein new noir myproject"

1:03 Raynes: webnoir's code examples are generally fine. It's installation instructions and stuff that is confusing.

1:03 I need to talk to ibdknox about getting the 1.3.0 final release out.

1:03 adu: fascinating

1:03 Raynes: So documentation can be updated and stuff.

1:04 adu: thanks :)

1:04 l1x: yeah lowering that barrier helps

1:04 i had to ask it on irc :)))

1:04 frozenlo`: Raynes: don't you break 1.3.0-beta! ;-)

1:05 Raynes: :p

1:05 adu: and I was about to switch to joodo :P

1:06 Raynes: wat

1:06 That's a thing?

1:06 Huh, that is a thing.

1:06 I've never heard of that.

1:07 julson: oh wow.

1:07 Raynes: The formatting of his map in his "Leiningen 2" example does not inspire confidence.

1:08 adu: apparently, joodo and noir have the same dependancies, so at first I thought they were interchangable

1:09 Raynes: I mostly just use Compojure these days.

1:09 l1x: my only problem with clojure is the memory usage

1:09 adu: maybe I should try a site that uses only that

1:09 Raynes: Looks like joodo is an 'in addition to' thing vs a replacement thing.

1:09 Which is nice. Libraries > frameworks any day of the week.

1:10 l1x: You can limit it to a certain extent.

1:10 Frozenlock: Raynes: I've heard that a lot. Was Noir getting in the way?

1:10 Raynes: l1x: amalloy and I do that for all of our stuff.

1:10 l1x: Raynes: sure, but it is not enough for me

1:10 adu: both joodo and noir depend on Ring, Compojure, and Hiccup

1:10 l1x: i want to write apps with 5-10Mb memory usage

1:10 Raynes: Then you probably want a non-JVM language.

1:10 l1x: (which is possible even with Ruby for example)

1:10 Raynes: It comes with the territory. Not much you can do to avoid it.

1:11 l1x: i guess you have few options

1:11 Raynes: I have 8GB of RAM now. I want it to use more memory.

1:11 adu: lol

1:11 l1x: Raynes: i got it :)

1:11 in production i use 24G/24core

1:12 but sometimes it is not about who's dick^H^H^Hserver is bigger

1:12 Raynes: Anyways, on a more serious note, you could check out Clojurescript + nodejs. Unfortunately, the nodejs support is moderately buggy. I think the worst bugs have been cleared out though.

1:12 There is also clojurepy if you're into snakes.

1:13 adu: I've heard some terrible things about nodejs

1:13 Raynes: Could do some Haskell.

1:13 l1x: wel well well

1:13 * adu <3 Haskell

1:13 l1x: i could do it with Ruby + eventmachine

1:13 Raynes: You certainly could.

1:13 You could do it in Forth.

1:13 l1x: i prefer Ruby's syntax over JS

1:14 och, actually i was working with Forth :)

1:14 this is how old i am

1:14 Raynes: I prefer Clojure's lack of syntax over most things.

1:14 adu: FYI, I'm not a lisp person, I'm a scheme person, but then after writing a couple scheme interpreters, and half a scheme compiler, I realised that (define (f x)) is bothersome, hence the recent conversion to clojure :)

1:14 l1x: Raynes: sure

1:14 me too

1:14 Raynes: Scheme is a Lisp.

1:14 l1x: but there is no point of spinning up the JVM sometimes

1:14 all i am sayin'

1:15 Raynes: I write Ruby sometimes too.

1:15 https://github.com/Raynes/refh

1:15 julson: speaking of clojurescript. does anyone have a good workflow for using both cljs and clj in one project?

1:15 adu: right, but (defn) is shorter, and separates out the function name, which looks really nice

1:15 Raynes: I needed fast startup speed in this case, so Clojure was out of the question. I might have done clojurescript if the node support wasn't broken to shit at the time.

1:16 l1x: hehe

1:16 knowing clojure also makes your imperative code better, at least this is my experience

1:16 Raynes: I would have wrote it in Haskell, but I've mostly forgot everything I've learned about Haskell.

1:17 Well, I never had any imperative code. I went into Ruby *from* functional languages.

1:18 dfd: can anyone suggest how I stub something out in Midje? I want to avoid actually sending an email (trying to stub out drewr's postal library: https://github.com/drewr/postal)

1:18 Raynes: What does 'stub' mean?

1:19 adu: I've noticed I think that way too, when I want to map something, I think "how to I (map f xs) with a foreach loop?"

1:20 dfd: Raynes: I mean, avoid having the function actually get called when my code-under-test is hitting that library

1:21 Raynes: I'll point you to this old classic too if you aren't familiar with the subject: http://martinfowler.com/articles/mocksArentStubs.html ...worth a read.

1:21 Raynes: Makes sense.

1:22 I thought at first you wanted to comment out a piece of code.

1:23 dfd: Raynes: yeah, it does sound like that! But no, I just want to avoid sending out emails, while testing that I'm calling the mailing function. I understand how to verify it's being called in Midje, but I'm a bit clueless when it comes to stubbing the function out completely at the same time.

1:24 Raynes: dfd: Maybe with-redefs

1:24 (with-redefs [println +] (println 2 3)) = 5

1:25 dfd: Raynes: ooh, that looks promising, thank you!

1:26 Raynes: actually, that looks just right--there is a perfect example at the bottom here using it to test HTTP: http://clojuredocs.org/clojure_core/clojure.core/with-redefs

1:26 Raynes: thanks so much!

1:26 Raynes: You, sir, are very welcome.

1:27 julson: oh wow. I learned something new today. awesome

1:28 Sgeo: with-redefs doesn't work with Java methods, right?

1:29 Raynes: No.

1:30 It works by pointing vars at something new.

1:30 If you want to change a Java method, I suggest poison and a smooth drink to see you off.

1:31 Sgeo: Darn

2:17 wei_: using compojure, what's the easiest way to serve a special page when a mobile user agent is detected?

2:19 Raynes: wei_: You can use middleware that checks the user agent, or if you want to do it in each of your routes, you can just check for the user agent and do whatever.

2:20 wei_: is there a middleware that everyone uses or should I just roll my own?

2:21 Sgeo: Please please please, if someone is trying to access an article on their phone, don't direct them to the mobile front page and utterly ignore where they were trying to go

2:21 http://xkcd.com/869/

2:24 wei_: haha, thanks. I'm planning to serve the same content, but in a different format

2:25 Sgeo: Hmm. I'm not a web dev, but I'm curious, what's wrong with just using CSS to control it?

2:32 wei_: it's a travel planner, a single-page app with a big google map in the center. some of the features don't translate very well to mobile.

2:34 mjc: if you're on a mobile device, you're likely already traveling. the app would be redundant.

2:35 wei_: right. you're usually just referring to your itinerary

2:36 Sgeo: Map could be hidden with CSS though, although I guess not sending it and not sending the code is better

2:43 wei_: come to think of it, it'd be ideal if one could use the mobile app offline. wouldn't it be awesome to build a native app using clojure!

2:44 Sgeo: I think there's something in HTML5 that allows a page to load from cache and do some stuff offline

2:45 I guess you'd be using ClojureScript though

2:45 wei_: still awesome. my main app is mostly in clojurescript

2:47 lpvb: Sgeo: how do you like Clojure compared to haskell?

2:47 Sgeo: lpvb, I still have written less code in Clojure than Haskell, and my preference for Clojure over Haskell is still based mainly on academic thoughts rather than actual usage

2:48 (In particular, macros and ease of changing running code)

2:48 callen: lpvb: I have pragmatic reasons for preferring clojure.

2:48 Sgeo: lpvb, but I do miss some Haskell stuff

2:49 callen: lpvb: rapidity of development, interactive development, just plain prefer a lisp, macros, lein instead of cabal (cabal is a goddamn horror), java libraries are more practical and better tested than Haskell ones, better escape-hatches for leaving the overall paradigm as necessary...

2:49 lpvb: callen: haskell has interactive development

2:49 callen: lpvb: easier to write code you undrstand the behavior of in Clojure than Haskell. The lazy semantics in Haskell can be hell in how prolific they are.

2:49 lpvb: Haskell hasn't 100% embraced them, it's not comparable to clojure at all.

2:50 lpvb: you guys don't find the lack of strong typing to cause tricky type errors?

2:50 callen: hell no.

2:50 Sgeo: callen, pervasive laziness has some benefits. See the fact that Clojure is only getting a way to stop a reduce in 1.5

2:50 callen: Sgeo: I don't care.

2:51 lpvb: I abuse laziness alot

2:51 callen: it's not like python/ruby/java where a type error can occur from the multitude of arbitrary operations and methods that can be wrong in a given context.

2:51 Sgeo: I'd prefer to have static typing, but not convinced about lack of it outweighing the other things

2:51 callen: in a Lisp, most things are list-esque and just work.

2:51 there are fewer avenues for dynamic typing to bite you in Clojure, than in Python/Ruby

2:51 lower degree of dimensionality of access

2:51 lpvb: for instance, I turn whole strings into list of words and grab the first 2 or something and I know the rest of the words won't be operated on

2:51 callen: fewer "traps" too.

2:51 Sgeo: callen, not sure I agree. Maybe you have a function expecting a map with keys :foo :bar and :baz

2:52 You accidentally make something just with :foo and :bar

2:52 Function blows up

2:52 callen: Sgeo: no programming language can save the brain dead.

2:52 Sgeo: clojure's access patterns are still far more consistent and less error prone than Python or Ruby or Tcl.

2:52 lpvb: I like the syntax of clojure and macros, but I'm scared to jump out of the type system safety net

2:52 callen: Tcl is a goddamn horror for writing reliable code 'in the large'

2:52 lpvb: to even bother using it over haskell

2:53 callen: lpvb: there's a type system in clojure, just not one that changes your diaper for you at compile time.

2:53 Sgeo: lpvb, at least, Clojure does have lazy sequences

2:53 callen: lpvb: code accordingly. take advantage of the freedom.

2:54 lpvb: in particular, the pattern in lisps/python/ruby is to prototype the concept with potentially incorrect code until you get the basic idea right, then begin "firming" it up as you go.

2:54 rcg: lpvb, you can always add some "safety net" using test-driven development

2:54 Sgeo: Although I think there should be a collection of macros or functions or something for easily defining lazy data structures and functions to act on them.

2:54 callen: tests are actually empirically more useful for creating reliable code than type systems anyway.

2:54 code reviews are the process-level thing shown to be most useful.

2:55 tests can provide a "bottom" or minimum level of guarantee, and there's an equivalent to Haskell's QuickCheck for Clojure.

2:55 it seriously doesn't matter though.

2:55 the problem with the world isn't that your code isn't perfectly type-checked, it's that it doesn't exist yet.

2:56 solve the problem of writing code that solves problems, worry about perfecting it later.

2:56 brainproxy: isn't someone working on a typed clojure extension thing?

2:56 (maybe that's been mentinoed already...)

2:56 callen: brainproxy: typed racket is a thing too.

2:57 Sgeo: What's worse? A library that doesn't exist, thus prompting someone to write code for their use case, or making a library that has a subtle error, thus causing someone to use it, but it fails horribly for them?

2:57 callen: typed racket is moderately...popular. Relatively speaking.

2:57 brainproxy: sure, the former is proabably informed by the latter

2:57 callen: Sgeo: the problem with most libraries isn't bugs, but sub-optimal design or API.

2:57 Sgeo: bugs can be fixed, fundamentally incorrect approaches are irreconciliable.

2:57 quicker iterations and design-phases such as a lisp can enable are more likely to prevent you from fucking that stage up.

2:58 haskell has a habit of making my code more crystalline and rigid in design than I like.

2:59 in Clojure and Python, if I notice an impedance mismatch between my problem and my code, I'm a lot more likely to just fix it

2:59 brainproxy: i think the merits of being able to have strongly typed components in a clojure library will only become apparent, or perhaps will be proved as not-so-useful, once that extension hits beta and folks start experimenting with it

2:59 callen: whereas in Haskell I am punished with an infinite series of irritating type errors because I flipped like one monad lift around.

2:59 shachaf: Hey, it's robink.

2:59 callen: hey it's shachaf

3:01 ivan: ,((fn [{:keys [a b]}] (+ a b)) {:a 2})

3:01 clojurebot: #<NullPointerException java.lang.NullPointerException>

3:02 ivan: is there a way to :mandatory-keys or somesuch?

3:02 macro hackery with precondition?

3:07 oh right, I want :or

3:08 Sgeo: ,((fn [{:keys [a b]}] a) {:a 2})

3:08 clojurebot: 2

3:09 Sgeo: Hmm, no easy way to tell if a key was provided?

3:09 Reliably, I mean.

3:09 I could use (let [sentinel (Object.)] ...)

3:09 ivan: yeah, that's what I was thinking

3:12 mattmoss: &(assert (contains? {:a 1 :b 2} :c))

3:12 lazybot: java.lang.AssertionError: Assert failed: (contains? {:a 1, :b 2} :c)

3:14 ivan: ,((fn [{:keys [a b] :as opts}] (contains? opts :c)) {:a 2}) ; Sgeo

3:14 clojurebot: false

3:14 Sgeo: Good point

3:16 ivan: Clojure's destructuring really makes me hate everything else

3:17 Sgeo: Haskell's pattern matching?

3:18 ivan: might work, I've barely used Haskell

3:20 shachaf: ivan: Prolog's unification?

3:20 Unification is the future.

3:26 doomlord: what to call this hof:- (?? f [a b c d..])->[(f a b)(f a c)(f a d)..(f b a)(f b c..)] i.e. f invoked on every potential pair from a sequence,

3:28 * Sgeo imagines how to do that

3:29 Sgeo: Some combination of juxt, apply, and permutations

3:29 shachaf: Like a cartesian product?

3:29 Sgeo: Wait, there is a permutations function somewhere, right?

3:29 shachaf: I guess you're not taking the diagonal.

3:29 Sgeo: Wait, not permutations

3:29 * Sgeo is slightly unsure of how to do cartesian product in Clojure besides a for loop

3:29 doomlord: iits easy enough to do imperatively :)

3:29 mindbender1: I hope more light will be thrown on the issue of disentangling at the conj!

3:30 doomlord: i've got an implementation in clojure but not sure its the most elegant

3:30 mindbender1: rhickey promised this!

3:31 doomlord: i need every pair , and every tripple aswell. (i'll stop there but i thought it would be possible to write one generalized, every n-tuple ..)

3:31 hiredman: have you seen partition?

3:31 shachaf: doomlord: (a,a) is a pair. :-)

3:31 hiredman: oh, right

3:31 Sgeo: mindbender1, disentangling/

3:32 doomlord: (not doing the diagonal; and its assumed f a b = f b a)

3:32 mindbender1: especially how the problem of inheritance is solved with clojure as it seems so pervasive among frameworks theses days

3:33 hiredman: mindbender1: the way to disentangle inheritence is to not do it

3:33 shachaf: doomlord: If f a b = f b a, then why are you doing both?

3:33 doomlord: (equiv of (for i=0..n {for j=0..i { result.append(f(i,j))} ))

3:33 not doing both

3:34 mindbender1: hiredman: but it's done greatly in the closure lib

3:34 doomlord: given a list of N, its N(N-1)/2 invocations

3:34 mindbender1: and then clojurescript is built on it

3:34 hiredman: mindbender1: and it is done a lot in the jre, but clojure is built on that

3:35 mindbender1: yes but how then do we label everything

3:35 and know how to interop

3:36 doomlord: currently i'm doing it by mapping ranges with indexing inside but it should be possible to do for lists with no random acess

3:37 mindbender1: especially when it comes to ui components

3:37 hiredman: http://berniesumption.com/software/inheritance-is-evil-and-must-be-destroyed/

3:38 doomlord: (c version for linklist would be, for (a=list; a; a=a->next){ for (b=a->next; b; b=b->next){ doSomething(a,b);}} ) ... i guess thats easy to do recursively, but how to do it for a method that can be parallelized

3:40 ah its nested maplists in lisp i think.. does clojure have one like that..

3:42 Sgeo: Do you mean like for?

3:42 ,(for [a [1 2 3] b [4 5 6]] {:a a :b b})

3:42 clojurebot: ({:a 1, :b 4} {:a 1, :b 5} {:a 1, :b 6} {:a 2, :b 4} {:a 2, :b 5} ...)

3:42 Sgeo: ,(for [a [1 2 3] b [1 2 3]] {:a a :b b})

3:42 clojurebot: ({:a 1, :b 1} {:a 1, :b 2} {:a 1, :b 3} {:a 2, :b 1} {:a 2, :b 2} ...)

3:43 doomlord: not what i was after but that is interesting

3:44 Sgeo: ,(catmap (fn [x] [(dec x) x (inc x)]) [1 2 3 4 5])

3:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: catmap in this context, compiling:(NO_SOURCE_PATH:0)>

3:44 doomlord: ,(for [a [1 2 3]] (for [b (range a)] {:a a :b b}))

3:44 clojurebot: (({:a 1, :b 0}) ({:a 2, :b 0} {:a 2, :b 1}) ({:a 3, :b 0} {:a 3, :b 1} {:a 3, :b 2}))

3:44 Sgeo: ,(mapcat (fn [x] [(dec x) x (inc x)]) [1 2 3 4 5])

3:44 clojurebot: (0 1 2 1 2 ...)

3:44 doomlord: nearly

3:45 yeah i've found "mapcat" from an earlier experiment; i've used that in my current implementation of this(the outer pass is a mapcat)

3:45 Sgeo: Fun fact: You can consider for to effectively be built on mapcat

3:45 doomlord: how so..

3:47 Sgeo: ,(mapcat (fn [x] [{:a x :b 4} {:a x :b 5} {:a x :b 6}]) [1 2 3])

3:47 clojurebot: ({:a 1, :b 4} {:a 1, :b 5} {:a 1, :b 6} {:a 2, :b 4} {:a 2, :b 5} ...)

3:48 Sgeo: If you know Haskell: mapcat is =<< on sequences, and for is do notation on sequences

3:48 doomlord: heh i know a little haskell, i've used >>= but not =<<

3:49 Sgeo: >>= is just =<< with the arguments in the opposite order

3:49 lpvb: Clojure/Scala/Erlang have a lot of real world jobs compared to other functional languages

3:50 Sgeo: Erm, what I said is true, but I think I meant to say that =<< is just >== with the arguments in the opposite order

3:50 >>=

3:50 Oh, I guess for is more like a list comprehension than do notation, due to the implicit return]

3:51 ,(for [] 5)

3:51 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.Exception: Unsupported binding form: >

3:51 doomlord: is there something like commonlisps 'maplist'

3:52 Sgeo: If there is, it isn't Haskelly. It seems to not be ... actually, I thought of a way to do it in a typesafe manner

3:52 doomlord: clojure has a mix of lazy seqs and eager eval?

3:53 Sgeo: Wait, no, it's easily done type-safely, I'm a derp

3:54 doomlord, Clojure itself is strict/eager, but lazy seqs are objects that when seq operations are done on them, they don't do them immediately

3:54 So yes

3:55 doomlord, hmm, maybe trickery with reduce?

3:56 doomlord: to write 'maplist' .. something recursive using 'rest' i guess

3:57 (recur?)

3:57 Sgeo: reduce makes no sense I think

3:58 doomlord: didnt thinkso for this

4:00 ok lisp version,nearly: (maplist(lambda(x)(mapcar(lambda(y)(list (first x)y)) (cdr x))) '(1 2 3)) -> ((1 2)(1 3)(2 3) NIL)

4:01 my current clojure implementeation differs in that it's using maps over ranges so its having to do random access.. whereas the above works on lists

4:01 Raynes: Please, God, spaces.

4:04 Sgeo: Is this acceptable to Clojure, as in, would it work?

4:04 ((somemacro someothermacro) some stuff)

4:04 As in, somemacro is a macro that takes an argument and expands to a macro name

4:05 Raynes: It should, I think.

4:07 Sgeo: Muahaha! Macro composition!

4:07 Raynes: (defmacro somemacro [n] ''n)

4:17 doomlord: (defn maplist[f ls] (if (first ls) (concat (seq (f ls)) (maplist f (rest ls)) ) (list)) )

4:17 (does 'rest' return the same type as seq)

4:18 oops last should be nil not list

4:21 oh and i think i want 'recur' instead ?

5:07 wingy: I have always thought that after the . is a namespace and after the / is a variable

5:08 (type (range 5)) gives me clojure.lang.LazySeq … which apparantely is a class?

5:08 Sgeo: Yes, from what I've heard type is roughly obsolete

5:08 wingy: so I thought shouldn't it be clojure.lang/LazySeq .. or is it a Java convention that is used?

5:08 Sgeo: Java classes aren't stored in vars

5:09 wingy: okay

5:09 makes sense then

5:09 Sgeo: why is type obsolete .. what should i use to determine the type then?

5:10 Sgeo: class

5:10 ,(class (range 5))

5:10 clojurebot: clojure.lang.LazySeq

5:10 wingy: okay

5:10 Sgeo: From what I've heard, type is a throwback from when there was another way to specify a type

5:10 I should note that I'm not an expert

5:10 wingy: class makes more sense .. you hear its a class :)

6:10 devn: ,(class (range 0 0 0))

6:10 clojurebot: clojure.lang.LazySeq

6:10 devn: ,(class (range 0 10 2))

6:10 clojurebot: clojure.lang.LazySeq

6:10 devn: ,(class (range 0 10439843 2))

6:10 clojurebot: clojure.lang.LazySeq

6:22 wingy: http://www.infoq.com/presentations/DSL-Clojure

6:22 makes me think about using Midje instead of clojure.test :)

6:22 and other libraries as dsls like logic

6:32 si14: hi there. Am I right that Noir is the most advanced Clojure web framework at the moment?

6:32 "last commit: 1 month ago" looks kinda scary

6:34 Raynes: One month looks scary...?

6:34 Anyways, the author has been busy with other things lately, so things have been slow. I try to merge pull requests and such when I can.

6:35 That said, I tend to use Compojure.

6:35 Not because Noir is outdated/not good, but because I like Compojure better.

6:35 Neither is more advanced than the other.

6:37 si14: Raynes: isn't Noir based on Compojure?

6:38 Raynes: Noir is built on top of Compojure.

6:38 wingy: which makes Noir more than Compojure .. but perhaps you dont want that kind of abstraction

6:38 si14: ah, I see.

6:38 clojurebot: Pardon?

6:38 Raynes: It adds on a more stateful routing DSL and comes with several useful libraries. I've moved those libraries into a library called lib-noir that you can use from compojure though.

6:39 si14: just wondering what's the state of the art is.

6:39 Raynes: Most people use Compojure, lots of people use Noir. Either is fine.

6:39 ivan: what do you guys think of underscores in numeric literals like 1_000_000_001?

6:40 si14: it's strange that there is no popular (?) combination of Noir/Compojure and ClojureScript.

6:40 Raynes: I think that doesn't work.

6:40 si14: at least for validators it seems essential.

6:40 ivan: right, I kind of wish it did

6:40 (it does in Java 7)

6:40 Raynes: I think it's hideous.

6:40 ivan: well, the comma is already taken

6:41 and it is not i18n

6:41 Raynes: si14: I'm not sure what that 'combination' would look like.

6:41 Most people just have projects with clojurescript, compojure, and lein-cljsbuild.

6:43 si14: Raynes: I don't know, it's wishful thinking. Templates that can be rendered on the server and on the client, universal validators for server and client, stuff like this.

6:44 andrewmcveig: si14: that's fairly easily possible

6:44 si14: you don't need noir for that.

6:45 ivan: http://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html

6:52 si14: andrewmcveig: I know, it's just handy to have stuff already done for you, like Rails.

6:54 ivan: I guess I can always have a macro that does this, but it seems kind of lame: user=> (n "1000 2000 4514")

6:54 100020004514

6:54 andrewmcveig: si14: I suppose it depends on what you're looking for...

6:55 si14: andrewmcveig: stuff that can be done with Rails, basically :)

6:55 andrewmcveig: just like Clojure better

6:56 andrewmcveig: si14: compojure + a few libs do enough for me, but not as much as rails.

6:56 alex_baranosky: can you do this kind of Javascript object properly access via ClojureScript? => a["3"] ?

6:57 I have some JS I was playing around with converting to CLJS, but it has some JSON object that it receives from the server that have keys of "1", "2", "3" etc

6:57 ivan: (aget a "3")

6:58 alex_baranosky: ivan: thanks

7:01 another CLJS question - how do I reference undefined?

7:02 ivan: maybe js/undefined

7:05 alex_baranosky: ivan: will try that

7:05 ivan: there may be function in Closure Library's base.js that does the undefined/null check you want

7:05 undefined is the devil

7:06 alex_baranosky: ivan: that did it

7:06 shachaf: hi ivan

7:06 ivan: hi

7:06 alex_baranosky: where are the good cheat sheets and references online for CLJS?

7:06 shachaf: I think JavaScript undefined is positively nice compared to Haskell undefined.

7:06 The *real* devil is the halting problem.

7:06 ivan: alex_baranosky: there's a beta O'Reilly book but I have no idea what's in it

7:07 alex_baranosky: yeah, I just bought it :)

9:13 bonega: Should nrepl-jack-in set cwd to project root? For me it defaults to $home

9:41 no matter, there was something weird going on

9:53 rod_: hi, i've just started using datomic with compojure - but now all stdout seems to get supressed - is there some logging/options i need to configure? thanks

10:39 i've got a database connection which could change over the lifetime of the program, what's the best way to keep this around - i'm think about using a ref or an atom, is this a good/bad idea?

10:55 cemerick: dnolen: sorry for the patch churn. :-|

10:56 dnolen: cemerick: no problem, that's an interesting bug in the compiler

10:56 cemerick: Yeah. I never thought to look at the generated output.

11:03 dnolen: cemerick: I usually sanity check with by modifying the tests to compile w/ {:optimizations simple :pretty-print true} and look at the generated file.

11:04 cemerick: Noted; I'll aim to do the same until my instincts get better.

11:07 dnolen: cemerick: if it's simple it also easy to check generated js via the REPL w/ (fn [] expr)

13:19 samrat: is anyone using emacs-live with evil-mode? its behaving really annoyingly with nrepl

13:19 Kruppe: samrat: what kind of annoying

13:20 samrat: not moving to the next prompt annoying?

13:33 samrat: Kruppe: yes, how can I fix that?

13:35 Kruppe: samrat: This bugreport talks about it https://bitbucket.org/lyro/evil/issue/209/not-moving-cursor-to-prompt-in-comint-like

13:35 samrat: you can fix it with some advice to the function called when you press return

13:36 samrat: fixed it for me anyways

13:52 ssideris_: are there any examples of mixing clojure and clojurescript i.e. having the *same* code run on the server and the browser?

13:52 I don't know how to set up my project

13:53 erm, nevermind: https://github.com/emezeske/lein-cljsbuild/blob/0.2.9/doc/CROSSOVERS.md

14:53 * Sgeo has some issues with the clojure-doc.org tutorial :/

15:01 Sgeo: Is there a way to define my own binding forms?

15:04 gfredericks: Sgeo: you mean such that let/fn/loop would participate?

15:04 metajack: is there a way to have nrepl.el do a browser repl?

15:04 Sgeo: gfredericks, yes

15:05 metajack: lein cljsbuild repl-listen seems to connect itself but not allow nrepl clients to connect

15:12 gfredericks: Sgeo: I don't think there's any built-in way. The cleanest thing you could do is just define your own let/fn/loop macros and use in your own code

15:13 AtKaaZ: hey does anyone know why https://github.com/Datomic/day-of-datomic recommends to start lein repl 2 with trampoline ?

15:18 can we access clojure's AST at runtime? ie. if we wanted to vizualize the code

15:19 ChongLi: someone else will correct me if I'm wrong, but I think clojure's code is the AST

15:19 that's what it means to be a homoiconic language

15:19 AtKaaZ: it compiles to java bytecode though

15:20 but i need to know if I can access it, read only at least

15:20 ChongLi: the bytecode?

15:20 AtKaaZ: no, the ast

15:20 the clojure code as it is in the ast

15:21 which probably means i see no macros, they'd be already expanded

15:21 ChongLi: like after macroexpand?

15:22 TimMc: ChongLi: There are two problems: 1) The reader changes the surface syntax e.g. #(%) into the deep syntax, and 2) the compiler builds an AST that doesn't always match the deep syntax.

15:22 ChongLi: ah

15:22 shouldn't he able to run some low-level function to get that result?

15:23 AtKaaZ: ChongLi, I think after the eval part of the REPL, each macro use is replaced with the expanded macro

15:23 but not after the R phase

15:23 ChongLi: have you looked at the clojure source code?

15:24 AtKaaZ: not really

15:25 TimMc: AtKaaZ: Eval comprises several steps, one of which is AST building.

15:26 AtKaaZ: TimMc, you mean the AST is not yet existent at the read phase? only at the eval phase? not implying that I know

15:27 TimMc: Read, macro-expand, build AST, compile, run, serialize results, print.

15:28 s/compile/turn into byte-code/

15:28 tgoossens_: I have a lazy sequence that i want to convert to a string. (

15:28 and I am 100% sure that the sequence is finite

15:28 for example

15:28 TimMc: AtKaaZ: Read has to happen before macro-expansion, which has to happen before eval.

15:28 tgoossens_: '(a b c) i want it so print like "a b c"

15:29 AtKaaZ: TimMc, are the first two read/writing the text ?

15:29 gfredericks: foo' wasn't valid syntax in 1.2?

15:29 TimMc: gfredericks: Nope!

15:29 * gfredericks coulda sworn

15:29 gfredericks: so 1.2 has slow maths also?

15:29 TimMc: gfredericks: S11001001 showed me a cool trick with that.

15:29 AtKaaZ: ,foo'

15:29 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo' in this context, compiling:(NO_SOURCE_PATH:0)>

15:30 AtKaaZ: what's that supposed to do? except in case of *'

15:30 Sgeo: ,(clojure.str/join " " '(1 2 3))

15:30 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.str>

15:30 Sgeo: ,(require 'clojure.str)

15:30 clojurebot: #<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/str__init.class or clojure/str.clj on classpath: >

15:30 Sgeo: ,(require 'clojure.string)

15:30 clojurebot: nil

15:30 Sgeo: ,(clojure.string/join " " '(1 2 3))

15:30 clojurebot: "1 2 3"

15:30 Sgeo: Could also ##(apply str '(1 2 3))

15:30 lazybot: ⇒ "123"

15:31 Sgeo: Er, guess not

15:31 AtKaaZ: ,(str '(1 2 3))

15:31 clojurebot: "(1 2 3)"

15:31 Sgeo: Just use clojure.string/join

15:31 AtKaaZ: ,(str (list 1 2 3))

15:31 clojurebot: "(1 2 3)"

15:31 AtKaaZ: yep join =)

15:32 Sgeo: ,(doc interleave)

15:32 clojurebot: "([c1 c2] [c1 c2 & colls]); Returns a lazy seq of the first item in each coll, then the second etc."

15:32 TimMc: ...but don't use interleave here, it's silly.

15:32 Sgeo: ,(doc intersperse)

15:32 clojurebot: Excuse me?

15:32 TimMc: Sgeo: interpose

15:32 Sgeo: ,(doc interpose)

15:32 clojurebot: "([sep coll]); Returns a lazy seq of the elements of coll separated by sep"

15:32 TimMc: not that either

15:33 Sgeo: ,(apply str (interpose " " (map str '(1 2 3))))

15:33 clojurebot: "1 2 3"

15:33 AtKaaZ: lol

15:33 TimMc: gfredericks: ##((first [+' +]) Long/MAX_VALUE 1)

15:33 lazybot: ⇒ 9223372036854775808N

15:33 Sgeo: ,(doc with-out-str)

15:33 clojurebot: "([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

15:33 AtKaaZ: ,(apply str (interpose " " '(1 2 3)))

15:33 clojurebot: "1 2 3"

15:33 tgoossens_: the join worked :)

15:33 Sgeo: ,(with-out-str (apply print '(1 2 3)))

15:33 clojurebot: "1 2 3"

15:34 Sgeo: tgoossens_, yeah. We're just messing around

15:34 tgoossens_: sure thing! thanks for helping. I'll be posting what i'm doing very soon. its something very cool :D

15:35 TimMc: ,(first [+' +])

15:35 clojurebot: #<core$_PLUS__SINGLEQUOTE_ clojure.core$_PLUS__SINGLEQUOTE_@4db3ea55>

15:35 TimMc: ^ do that in v1.2 and you'll get _PLUS_ instead

15:35 and they do the same thing

15:35 Sgeo: ,#'with-out-str

15:35 clojurebot: #'clojure.core/with-out-str

15:36 Sgeo: ,(meta #'with-out-str)

15:36 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name with-out-str, :arglists ([& body]), :added "1.0", ...}

15:36 AtKaaZ: tgoossens_, https://www.youtube.com/watch?v=0SARbwvhupQ

15:36 Sgeo: ,(doc with-meta)

15:36 clojurebot: "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."

15:36 tgoossens_: what is it about?

15:36 ok

15:36 i get it :p

15:37 sorry about that :D

15:37 AtKaaZ: lol, it's about keeping it secret for too long being too bad for you:)

15:37 potentially:)

15:37 Sgeo: AtKaaZ, I tend to blab about what I want to do then never actually do it

15:37 AtKaaZ: Sgeo, same lol

15:38 Sgeo: Although hey, I finally wrote the bot that I told some channel I was going to write... in Tcl, because it was during my recent Tcl phase.

15:38 tgoossens_: i'll keep it open in the background while working

15:38 AtKaaZ: if you like to keep it private until it's ready to be released, that's a video to look at:)

15:38 Sgeo, what does it do?

15:39 ToBeReplaced: anyone have a recommendation for logging ring server requests? https://github.com/pjlegato/ring.middleware.logger looks solid to me, but wondering if there's others out there

15:39 AtKaaZ: Sgeo, this one might be good for you lol(and me) https://www.youtube.com/watch?v=NHopJHSlVo4

15:40 tgoossens_: i'll take a look at it thanks :D

15:47 Wow

15:47 that video (of google IO)

15:47 AtKaaZ: any good?

15:47 tgoossens_: the situations they describe are shockingly similar of what i'm experiencing in my project at university

15:47 AtKaaZ: sweet

15:48 synchronicity ftw:)

15:48 tgoossens_: in fact, they describe the problems we encountered the past few weeks, well... exactly :p

15:48 someone worked on something for 1 week, even when asked did not provide any info of how and what he was doing exactly

15:48 then everything had to come together

15:49 and he wrote redudant stuff

15:49 AtKaaZ: that's exacttly what I was thinking of when I gave you the link:)

15:49 tgoossens_: next week i was going to address that problem to the group. better watch that video entirely :D

15:49 AtKaaZ: but in all fairness you did say "very soon" so it probably doesn't apply to you

15:50 right on

15:50 tgoossens_: yeah. In maximum 1 hour or so (i am writing the blogpost ) :D

15:50 but nevertheless shockingly useful video!

15:50 AtKaaZ: cool

15:52 tgoossens_: it has been one month i've been looking into clojure. It were the most interesting programming days i've got in all time :p

15:53 ok. this is getting interesting: "avoiding the trap"

16:07 ohpauleez: lynaghk is bending open the fifth dimension with core.logic as we speak

16:07 AtKaaZ: what's the 4th one?

16:08 tgoossens_: how can i get this to work: (read-string (clojure.string/escape "(println "test")")) probably messing up with the quotes

16:08 Bronsa: (read-string (clojure.string/escape "(println \"test\")"))

16:09 tgoossens_: thats not really what i need

16:09 i want to do this:

16:09 (read-string "(println "test")") . because this didn't work , i tried with escape

16:09 AtKaaZ: I think maybe you need a macro?

16:10 that will escape things for you

16:10 tgoossens_: so it doesn't evaluate? (not sure never created a macro before)

16:10 Sgeo: I think a reader macro might actually be more stylish here, but Clojure doesn't really have a way to make your own

16:11 AtKaaZ: ,(#(count %&) "(println "test")")

16:11 clojurebot: 3

16:11 Sgeo: It didn't complain about test?

16:11 AtKaaZ: it's the 2nd arg:D

16:12 Bronsa: ,(doc test)

16:12 clojurebot: "([v]); test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception"

16:13 Sgeo: tgoossens_, is there a reason you're putting code in a string like that?

16:13 ,(println '(println "Test"))

16:13 clojurebot: (println Test)

16:14 Sgeo: ,*print-readably*

16:14 clojurebot: true

16:14 Sgeo: ...

16:14 tgoossens_: yes

16:14 but

16:14 i'm just wondering

16:14 if a load in a string

16:14 into

16:14 (from-string)

16:14 ohpauleez: AtKaaZ: The 4th dimension is time

16:14 tgoossens_: and there are already double quoutes in the string

16:14 how i can keep them

16:14 Sgeo: ,(doc from-string)

16:14 clojurebot: excusez-moi

16:15 AtKaaZ: ohpauleez: ok

16:15 tgoossens_: so that later on

16:15 when i want to print it again

16:15 the output

16:15 is again

16:15 Sgeo: "This string has no quotation marks"

16:15 tgoossens_: " (println "test") "

16:15 Sgeo: "This string has one quotation \" mark inside it"

16:15 Shouldn't need to do anything special

16:16 ohpauleez: The fifth one? Well let me tell you - it involves a lot of whiskey and IPAs

16:16 Sgeo: ,(println "(println \"Test\")")

16:16 clojurebot: (println "Test")

16:16 Sgeo: Note that that \" is just how to represent a string in syntax

16:16 The string itself does not contain \

16:16 tgoossens_: yes

16:16 Sgeo: Hmm

16:16 AtKaaZ: ohpauleez: 5th one is all possible combinations 4th dimensions?

16:16 Sgeo: ,#"testing\"testing"

16:16 clojurebot: #"testing\"testing"

16:17 AtKaaZ: ohpauleez: what's IPAs?

16:17 ohpauleez: India Pale Ales

16:18 AtKaaZ: Sgeo, any way to automatically quote?

16:18 Sgeo: AtKaaZ, at the reader level?

16:19 Well, as mentioned before, might be possible to write a macro to do it

16:19 tgoossens_: ok that io video made me think

16:19 AtKaaZ: I thought maybe there's already something like that

16:19 Sgeo: Hmm, I don't need to declare functions in a special way in order for macros to use them, right?

16:19 tgoossens_: i'm not going to get forward if I don't explain what i'm doing

16:19 :p

16:20 Sgeo: AtKaaZ, regex reader macro might do something, maybe?

16:20 tgoossens_: i'll write the blogpost with the half-working code. And then i'll post a link here

16:20 AtKaaZ: Sgeo, possibly, if I had any exp. with it :))

16:22 could the ArityException maybe tell exactly how many args are expected? or there could be those variable arity methods which would make this unlikely?

16:22 variable=multiple

16:23 alex_baranosky: anyone know how to reference 'this' in CLJS?

16:23 Sgeo: AtKaaZ, hmm?

16:23 alex_baranosky, there's a macro for it

16:23 this-as I think

16:24 AtKaaZ: ,(#("%") "!")

16:24 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn>

16:24 AtKaaZ: Sgeo, it says that I passed 1 arg, but maybe it could also say how many args can I pass? like 0 or between min/max 0/0 :))

16:25 in case of multiple arity methods could be min/max 0/3 ie. when I pass 4

16:25 Sgeo: AtKaaZ, don't know, don't complain to me

16:25 alex_baranosky: Sgeo: thanks…. seems a bit wonky

16:25 AtKaaZ: good point, sorry:)

16:25 Sgeo: But that lambda takes 0 args

16:26 xeqi: (fn ([a]) ([a b c]) ([a b c d e]) ([a b c d e f & more]) ; [1,3,5,7+] could get ugly

16:26 AtKaaZ: ,::pst

16:26 clojurebot: :sandbox/pst

16:26 xeqi: * 6+

16:27 hmm guess that collapse down to [1,3,5+]

16:28 AtKaaZ: How do I know in which namespace is (pst) ?

16:28 Sgeo: ,(resolve 'pst)

16:28 clojurebot: #'clojure.repl/pst

16:29 Sgeo: ,(resolve 'nonesuch)

16:29 clojurebot: nil

16:29 AtKaaZ: awesome! thanks Sgeo

16:29 Sgeo: yw

16:29 hyPiRion: whaat

16:29 ,((resolve '+) 1 2)

16:29 clojurebot: 3

16:29 AtKaaZ: for some reason that ns was unloaded or something

16:30 Sgeo: ,(ifn? #'+)

16:30 clojurebot: true

16:30 hyPiRion: ,((resolve (symbol (str "ev" "al"))) '(+ 1 2))

16:30 clojurebot: 3

16:30 hyPiRion: Well, that's not secure.

16:31 xeqi: it isn't?

16:31 Sgeo: ,((resolve (symbol "eval")) '(+ 1 2))

16:31 clojurebot: 3

16:31 Sgeo: ,((resolve (symbol "eval")) '(eval '(+ 1 2)))

16:31 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:32 Sgeo: How is eval a security hole?

16:32 AtKaaZ: ,((resolve (symbol "eval")) '(def ghost1 1))

16:32 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:33 AtKaaZ: ,((resolve (symbol "eval")) '((resolve 'def) ghost1 1))

16:33 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:33 hyPiRion: ,((resolve (symbol "def")) foo 1)

16:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)>

16:33 Sgeo: ,((resolve (symbol "def")) foo bar)

16:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)>

16:33 hyPiRion: durr.

16:33 Sgeo: Oh, right

16:33 AtKaaZ: ,((resolve (symbol "eval")) '((resolve (symbol "def")) ghost1 1))

16:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ghost1 in this context, compiling:(NO_SOURCE_PATH:0)>

16:33 Sgeo: We could make a macro to do it

16:33 AtKaaZ: ,((resolve (symbol "eval")) '((resolve (symbol "def")) 'ghost1 1))

16:33 clojurebot: #<NullPointerException java.lang.NullPointerException>

16:33 Sgeo: We should be able to ... hmm

16:34 AtKaaZ: npe?

16:34 oh right, it's calling it:)

16:34 Sgeo: alter-var-root is accessible

16:34 Set some var to a function, alter the metadata to turn it into a macro.

16:35 Then, with our macro, we could... perhaps use a custom macro to call def directly

16:35 AtKaaZ: nope I was wrong, something else happens

16:35 * Sgeo wonders if def expands to function calls

16:35 Sgeo: It has to, right

16:35 ?

16:35 hyPiRion: no.

16:35 AtKaaZ: java code maybe?

16:35 Sgeo: Darn

16:36 AtKaaZ: special form?

16:36 Sgeo: What's a function that no one cares about?

16:36 We could hijack it

16:36 AtKaaZ: lol

16:36 Sgeo: ,(doc alter-var-root)

16:36 clojurebot: "([v f & args]); Atomically alters the root binding of var v by applying f to its current value plus any args"

16:36 xeqi: trying to do it in such a hard way

16:37 Sgeo: ,(use 'clojure.zip :only 'zip)

16:37 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.Exception: Unsupported option(s) supplied: :only>

16:37 hyPiRion: that's fine.

16:37 Sgeo: ,(use ['clojure.zip :only 'zip])

16:37 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

16:37 Sgeo: ,(use '[clojure.zip :only zip])

16:37 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

16:38 hyPiRion: ,(use '[clojure.string :only [zip] :rename {zip foo}])

16:38 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.IllegalAccessError: zip does not exist>

16:38 hyPiRion: whoops.

16:38 ,(use '[clojure.string :only [join] :rename {join foo}])

16:38 clojurebot: nil

16:38 hyPiRion: ,(foo "," [1 2 3])

16:38 clojurebot: "1,2,3"

16:39 xeqi: ,foo

16:39 clojurebot: #<string$join clojure.string$join@30a491e9>

16:39 Sgeo: Hmm, if a legal macro expands into illegal code, the code won't be run, will it?

16:39 hyPiRion: True

16:40 Sgeo: ,(intern *ns* 'x)

16:40 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:40 Sgeo: ,((resolve (symbol "intern")) *ns* 'foo)

16:40 clojurebot: #<IllegalStateException java.lang.IllegalStateException: foo already refers to: #'clojure.string/join in namespace: sandbox>

16:40 Sgeo: ,((resolve (symbol "intern")) *ns* 'bar)

16:40 clojurebot: #'sandbox/bar

16:40 AtKaaZ: ,(resolve 'def)

16:40 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:40 AtKaaZ: ,(resolve (symbol "def"))

16:40 clojurebot: nil

16:41 Sgeo: AtKaaZ, def is a special form, so has no var associated

16:41 AtKaaZ: thank you for that

16:41 Sgeo: So, what shenanigans should I attach to bar?

16:41 AtKaaZ: that means you can't rename it right?

16:42 Sgeo: The most useful would be a macro that expands into code to do def

16:42 Wait, n

16:42 no

16:42 wingy_: if i make a datomic query and get 10 entity ids .. then i loop through them to realize each one of them .. will datomic make 10 new requests to database?

16:42 Sgeo: Macro that expands into a function call with the given string

16:43 AtKaaZ: CompilerException java.lang.RuntimeException: Can't specify more than 20 params,


16:44 Sgeo: ,((resolve (symbol "alter-var-root")) #'bar (fn [f-str & args] (apply (resolve (symbol f-str)) args)))

16:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: bar in this context, compiling:(NO_SOURCE_PATH:0)>

16:45 Sgeo: Oh come on

16:45 ,((resolve (symbol "intern")) *ns* 'bar)

16:45 clojurebot: #'sandbox/bar

16:45 Sgeo: ,((resolve (symbol "alter-var-root")) #'bar (fn [f-str & args] (apply (resolve (symbol f-str)) args)))

16:45 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.lang.String>

16:46 AtKaaZ: I suppose if you have to have more than 20 params you're doing it wrong:)

16:46 Sgeo: I'm confused

16:46 AtKaaZ, it would be good for concat to take more than 20 params

16:46 Because it could be given a large sequence via apply concat

16:46 AtKaaZ: oh i see

16:47 ,(apply concat '(1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1))

16:47 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

16:47 AtKaaZ: I'm using it wrong, checking:)

16:47 xeqi: ,(apply concat (repeat 30 [1]))

16:47 clojurebot: (1 1 1 1 1 ...)

16:48 AtKaaZ: wow that's neat

16:48 that repeat thingy

16:49 hyPiRion: ,(take 30 (cycle [1]))

16:49 clojurebot: (1 1 1 1 1 ...)

16:49 AtKaaZ: I guess it only complains on defn

16:50 xeqi: (take 30 (iterate identity [1]))

16:50 ,(take 30 (iterate identity [1]))

16:50 clojurebot: ([1] [1] [1] [1] [1] ...)

16:50 xeqi: aww

16:50 hyPiRion: ,(mapcat identity (take 30 (cycle [1])))

16:50 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

16:50 hyPiRion: ,(mapcat identity (take 30 (repeat [1])))

16:50 clojurebot: (1 1 1 1 1 ...)

16:51 AtKaaZ: ooh i see why it works it uses applyTo with 1 parameter

16:52 Sgeo: hyPiRion, that mapcat identity is basically a Haskell join, right?

16:52 AtKaaZ: ,(defn foo [a b c d e f g h i j k l m n o p q r s t u v w x y z] (println z))

16:52 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:53 hyPiRion: Sgeo: It's basically the same as apply concat

16:53 AtKaaZ: ,((resolve (symbol "defn")) foo [a b c d e f g h i j k l m n o p q r s t u v w x y z] (println z))

16:53 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)>

16:54 AtKaaZ: ,(var clojure.core/defn foo 1)

16:54 clojurebot: #'clojure.core/defn

16:54 AtKaaZ: ,(quote clojure.core/defn foo 1)

16:54 clojurebot: clojure.core/defn

16:54 AtKaaZ: that's what they have in common

16:54 extra params ignored

16:54 ForSpareParts: How do I declare a dependency on generic.math-functions in lein?

16:56 xeqi: looks like thats in clojure.algo.generic.math-functions

16:57 *clojure.algo

16:57 ForSpareParts: xeqi, Well, I found this, too: http://richhickey.github.com/clojure-contrib/generic.math-functions-api.html

16:57 lazybot: Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure-contrib/generic.math-functions-api.html and try to stop linking to rich's repo.

16:57 xeqi: blah, I meant algo.generic

16:58 being a "contrib" its in maven, and search.maven.org w/algo.generic gives 0.1.0 as the latest version, so I would expect [org.clojure/clojure.algo "0.1.0"]

16:58 AtKaaZ: ,((var-get (var clojure.core/defn)) foo 1)

16:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0)>

16:59 AtKaaZ: lol I get this instead: ArityException Wrong number of args (2) passed to: core$defn clojure.lang.AFn.throwArity (AFn.java:437)

16:59 tomoj: &((fn [& args] (->> args (iterate next) (take-while identity) (filter (comp #{:foo} first)) first second)) 1 2 :foo 3 4 5 6)

16:59 lazybot: ⇒ 3

16:59 tomoj: gotta be an easier way to write that, right?

16:59 ForSpareParts: xeqi, The API reference says "v1.2" -- is that not what I'd want?

17:00 xeqi: ForSpareParts: that was when it was in monolithic contrib

17:00 ForSpareParts: Oh.

17:00 AtKaaZ: ,var-set

17:00 clojurebot: #<core$var_set clojure.core$var_set@28827875>

17:01 ForSpareParts: xeqi, So, In the future, how do I figure out how to specify a library I want for lein?

17:02 I think I'm not totally clear on the syntax yet -- I don't have much experience with Maven, either.

17:03 tgoossens_: that IO video was really nice

17:04 xeqi: [orgname/libraryname "version"] ; in this case orgname="org.clojure" libraryname="algo.generic" version="0.1.0"

17:04 zackzackzack: I'm trying to pull in some java files and use some classes defined in there. A bunch of exceptions are getting thrown though because the java class relies on some other files. Any ideas about what I am doing wrong?

17:04 ForSpareParts: xeqi, Thanks!

17:07 xeqi: &((fn [& args] (second (drop-while (complement #{:foo}) args))) 1 2 :foo 3 4 5 6)

17:07 lazybot: ⇒ 3

17:07 xeqi: tomoj: ^ ?

17:07 AtKaaZ: ,(with-local-vars [axx 1] (var-set axx (resolve (symbol "defn"))) (@axx 'foo [] 1))

17:07 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IObj>

17:07 tomoj: ah yes, much better, thanks

17:07 AtKaaZ: ,(with-local-vars [axx 1] (var-set axx (resolve (symbol "defn"))) (@axx 'foo [] println))

17:07 clojurebot: (def #< clojure.lang.AFunction$1@5bd8c455> (clojure.core/fn))

17:07 AtKaaZ: weird, I dno what happened lol

17:08 I get this in my repl: IllegalArgumentException First argument to defn must be a symbol

17:08 ,*clojure-version*

17:08 clojurebot: {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"}

17:09 xeqi: if you knew the argument count would be even ##((fn [& args] (:foo (apply hash-map args))) 1 2 :foo 3 4 5)

17:09 lazybot: ⇒ 3

17:11 AtKaaZ: ,(#(with-local-vars [acc 1, cnt %] (while (> @cnt 0) (var-set acc (* @acc @cnt)) (var-set cnt (dec @cnt))) @acc) 10)

17:11 clojurebot: 3628800

17:11 amalloy: xeqi: you need the argument count even *and* foo appearing as an odd-numbered index

17:11 tomoj: neither of which is the case

17:11 AtKaaZ: "imperative-style code" http://clojuredocs.org/clojure_core/clojure.core/with-local-vars

17:12 xeqi: amalloy: ah true, and its prolly better written as a destructure there anyways

17:13 AtKaaZ: did you guys catch that with = on records from the maillist?

17:13 tomoj: actually, fuckit

17:14 I'll just decide there are an even number of args

17:14 xeqi: in that case ##((fn [& {:keys [foo]}] foo) 1 2 :foo 3 4 5)

17:14 lazybot: ⇒ 3

17:16 AtKaaZ: https://groups.google.com/forum/?hl=en&fromgroups=#!topic/clojure/PqTRSIJeTtI

17:16 I tried .equals instead of = and yields different results :)

17:16 for this (= (AA. 1) {:a 1})

17:16 ForSpareParts: I'm still confused about lein -- I added a dependency to project.clj, ran lein deps from my project directory, and it seemed to download, but I still can't load it in my project. Any idea why that would happen?

17:17 AtKaaZ: you're loading it with use?

17:17 xeqi: ForSpareParts: how are you trying to load it?

17:17 tomoj: be sure to restart your repl to pick up the new dep

17:18 ForSpareParts: xeqi, (ns my-namespace (:require lib))

17:18 tomoj, did that.

17:19 AtKaaZ, just with :require, which causes an error. Can't find the library on my classpath.

17:20 AtKaaZ: like (:require [lib]) ?

17:20 is that the same btw?

17:21 ForSpareParts: I'm not totally sure. They seem to have the same effect.

17:21 tgoossens_: Hi

17:21 i finished the blogpost

17:21 AtKaaZ: yes you're right just tested

17:21 tgoossens_: finally you will know what i was trying to do:p

17:21 AtKaaZ: tgoossens_ link?

17:21 tgoossens_: it is far from ready, but nevertheless here it is:

17:21 http://tgoossens.wordpress.com/2012/10/20/funix-enhancing-the-linux-terminal-by-thinking-functional/

17:22 tomoj: ForSpareParts: well, maybe check `lein classpath` for the jar you want. then `jar -tf the.jar` to see what namespaces are actually available

17:22 if the jar is on your classpath, contains foo/bar.clj, and you do (:require foo.bar)... it should work

17:23 Sgeo: Wait, you can do that? o. o

17:23 tgoossens_: i will have to go now. I'll be back tomorrow probably in the irc

17:23 AtKaaZ: is it lein jar or java jar?

17:24 for this `jar -tf the.jar`

17:24 tgoossens_: if you have any remarks or comments please post it on the blog so I can read them :D

17:24 (using the webchat irc right nowà

17:24 Thanks for all the help and see you soon!

17:24 Sgeo: Those quotes should, in principle, still be there

17:24 ,(println (str "hello"))

17:24 clojurebot: hello

17:24 Sgeo: hmm

17:24 xeqi: AtKaaZ: that would be the jar command installed by the jre(jdk?)

17:25 tomoj: AtKaaZ: just "jar"

17:25 xeqi: ,(prn (str "hello"))

17:25 clojurebot: "hello"

17:25 Sgeo: xeqi, ahaa

17:25 AtKaaZ: ok, not in my path but I'll make it so;)

17:25 tomoj: you could also just open the jar in emacs. or of course just check the project docs if you trust them

17:26 ForSpareParts: So, it *looks* like the library is there. If I've installed algo.generic...

17:26 (:require [clojure.algo.generic.math-functions]) would load math-functions for me, right?

17:26 There's a jar on my classpath that contains a clojure/algo/generic/math_functions.clj

17:26 AtKaaZ: does that mean you don't have to prefix them with that namespace?

17:26 xeqi: that should load them

17:27 tomoj: the error says "could not find clojure/algo/generic/math_functions.clj" or whatever?

17:27 xeqi: though you prolly want to include something like :as math

17:27 ForSpareParts: tomoj, Yeah.

17:27 Sgeo: tomoj, in Leiningen, can I put standalone jars in my classpath just by putting them in some directory?

17:27 ForSpareParts: Shit, I think it worked this time.

17:28 tomoj: Sgeo: yeah, but you're not supposed to

17:28 you have to abuse some other option like :source-paths

17:29 xeqi: I think technomancy has been recommending abusing :resource-paths, as its more explicit its the wrong thing

17:29 Sgeo: Don't care.

17:29 The jar in question is generated from JNAerator

17:29 What _is_ the "right thing"?

17:30 xeqi: put the jar in a repo

17:30 tomoj: lein-localrepo is better than :resource-paths but not as good as putting it in clojars (or some other repo)

17:38 can't decide if this is appropriately convenient or inappropriately "clever" https://gist.github.com/7e2a8accb472a1af96a8

17:39 I guess :unique/identity or :unique/value would make the weird pairness of :unique go away, which seems less clever

17:40 ForSpareParts: Does clojure cache the results of functions so that it doesn't have to run them again?

17:41 (for a given set of args, I mean)

17:41 tomoj: ,(doc memoize)

17:41 clojurebot: "([f]); Returns a memoized version of a referentially transparent function. The memoized version of the function keeps a cache of the mapping from arguments to results and, when calls with the same arguments are repeated often, has higher performance at the expense of higher memory use."

17:41 tomoj: (in other words, not unless you ask it to)

17:41 ForSpareParts: tomoj, OK.

17:42 tomoj: since it has no way of knowing whether a particular function is referentially transparent :/

17:42 ForSpareParts: I'm trying to write a function that depends on getting the current time from a new java.util.Date object, but it seems like it keeps using the same one.

17:42 jayunit100: (for [x [0 1] y [0 1]] (print "cell [" x " " y "] \n")) <--- has nils in side of it :(

17:43 tomoj: for?

17:43 clojurebot: for is not a loop

17:43 jayunit100: why would a list comp have nils

17:43 tomoj: you want (doseq [x [0 1] y [0 1]] (println "cell [" x " " y "]"))

17:43 amalloy: jayunit100: because print always returns nil, bro

17:43 jayunit100: ah ooooops yeah.

17:45 hello clojure ! its been a while :)

17:45 * jayunit100 trying to write a purely functional version of life.

17:46 ForSpareParts: I assume you mean the game of life, but I like the idea that you're trying to write a functional version of just.. life.

17:46 awkorama: hi everyone

17:47 Frozenlo`: ForSpareParts: Writing a function of oneself would be recursive, because it would too try to write this function :P

17:48 awkorama: can anyone help me with following not working? (map [(seq (.. 100N getClass getMethods)) .getName ] )

17:48 Bronsa: what are you trying to do?

17:49 awkorama: just print the names of methods in BigInt

17:49 (nothing useful, just messing around in REPL really)

17:49 Bronsa: ,(map #(.getName %) (-> 100N .getClass .getMethods))

17:49 clojurebot: ("add" "equals" "toString" "hashCode" "byteValue" ...)

17:50 awkorama: so .getName is not a function ?

17:50 Bronsa: nope

17:50 jayunit100: @ForSpareParts ha

17:50 Bronsa: you have to wrap it, methods are not first-class as functions are

17:50 jayunit100: arg my function nested in a let isn't being invoked it seems.

17:51 awkorama: i see, ok thx

17:51 tomoj: seems like clojure.reflect should have method? and field?

17:52 jayunit100: https://gist.github.com/3924931

17:52 doomlord: what is the .something .. an identifier for a method lookup?

17:52 jayunit100: ^^ Any thoughts on why the for in "play" isn't being invoked?

17:52 tomoj: for is not a loop

17:52 you want doseq

17:53 doomlord: for returns a lazy sequence?

17:54 jayunit100: @doomlord hmm

17:54 oh duh and the repl always evils it

17:54 s/evils/evals

17:55 doomlord: tis confusing to use the word 'for' as not a loop imo :) but i can live with that

17:56 Sgeo: This is a good motivation for the Haskell way of doing I/O

17:56 doomlord: i'm not convinced

17:57 haskell's is very interesting but there are other valid approaches imo.

17:57 Sgeo: Yes, but just notice that Clojure's approach here does occasionally cause confusion

17:58 doomlord: monads cause confusion too :)

18:00 tomoj: hah

18:00 doomlord: is the clojure convention just "do" for imperative constructs ? (doseq, dotimes, do... , doto)

18:01 tomoj: some people say "when" also suggests imperative

18:01 doomlord: so far i'm enjoying clojure a little more than haskell.. i like its ability to make adhoc datastructures

18:02 technomancy: are there other languages that provide laziness for seqs only?

18:02 doomlord: clojure is a lot of fun.. and i wish i'd learned lisp 20 years ago

18:02 tomoj: I think I read "because it has an implicit do" oslt, but so does fn..

18:04 technomancy: fn is more general though. when is more specific than if

18:04 doomlord: doseq is more like a loop with (saving you writing out a lambda..) but is there an imperative version of map,(domap?) or do you use 'dorun/doall' on the map.

18:04 tomoj: yeah, I hadn't convinced myself

18:04 technomancy: doomlord: there's mapv, but if you use it for side effects clojurebot will come chastise you once you push your code.

18:05 Sgeo: doomlord, it's not so much that Clojure "lets" you make ad-hoc datastructures as it is that it's idiomatic in Clojure in a way that it's not in Haskell

18:05 amalloy: technomancy: i don't know that i'd say clojure provides laziness but only for sequences. it seems to me that between macros and lambdas it lets you put laziness wherever you need, and eg delay is a built-in non-seq lazy construct

18:05 Sgeo: Haskell culture wants things to be typesafe. But there's no reason you can't just use Maps all the time, in theory

18:05 doomlord: in haskell i find the slightly broken record system irritating

18:05 technomancy: "This emu really thinks your code would be clearer if you used doall instead of mapv." <- http://www.buzzfeed.com/expresident/animals-who-are-extremely-disappointed-in-you

18:06 amalloy: you know what I mean

18:06 out of the box

18:06 amalloy: Sgeo: aren't maps homogenous in type? ie, you can't easily do {:foo 1 :bar "foo"} in a Map

18:07 Sgeo: amalloy, good point. I was thinking more along the lines of a use-case I had a while ago where type-safety in terms of keys and their correct types would have been nice, but difficult to implement

18:07 amalloy, could use Dynamic, iirc

18:07 doomlord: maybe i should make myself a (domap function collection)

18:07 or is that just mapv

18:07 amalloy: (def domap (comp dorun map))

18:07 doomlord: reading 'do' as imperative is nice and clear

18:07 Raynes: http://www.haskell.org/haskellwiki/Heterogenous_collections

18:08 tomoj: for no good reason I did not expect dorun to be a function

18:08 Raynes: tomoj: The 'do' is a fair enough reason to think it to be a macro.

18:09 amalloy: hey, maybe this time i know enough haskell to understand that wiki entry

18:10 Sgeo: Could probably make a Prelude that just has functions that take and return Dynamic

18:10 doomlord: is there something to return amodified collection, eg (modify {:a 1 :b 2 :c 3 :d 4} {:a 10 :c 30}) ===> {:a 10 :b 2 :c 30 :d 4}

18:10 ohpauleez: tomoj: Thanks for all your help on that CLJS ticket

18:11 Sgeo: ,(doc assoc)

18:11 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

18:11 amalloy: $findfn {:a 1 :b 2 :c 3 :d 4} {:a 10 :c 30} {:a 10 :b 2 :c 30 :d 4}

18:11 lazybot: [clojure.set/union clojure.core/conj clojure.core/into clojure.core/merge]

18:11 doomlord: wow, findfn

18:11 * Raynes files his nails

18:12 amalloy: Raynes: now that you've made it so slow, you have plenty of time to file your nails

18:12 Raynes: s/made it so slow/fixed all my broken dangerous shit/

18:12 technomancy: how could findfn not be slow?

18:12 Sgeo: Raynes, oh, did you fix the hole that other person found?

18:12 amalloy: technomancy: it was outrageously fast when the sandboxing was a little less zealous

18:13 Raynes: technomancy: It used to be fast when the sandboxing sucked.

18:13 technomancy: oh wow, you don't even bother filtering by arity?

18:13 amalloy: nope. just call ALL the things

18:13 doomlord: is there some findfn web app caching everything

18:13 Raynes: No.

18:13 Caching would be pretty darn smart though.

18:14 Turns out we're pretty darn stupid.

18:14 Sgeo: What, as in memoization?

18:14 Raynes: As in caching.

18:14 Sgeo: hmm, what's the difference?

18:14 technomancy: Raynes: what are the odds someone would actually do the same query twice between boots of the bot though?

18:14 Raynes: You could just store it in a db, technomancy.

18:14 doomlord: over the entire community of programmers, over many months..

18:15 Raynes: technomancy: It'd only really need to be refreshed for new versions of Clojure. Even then, not really, since they never change anything.

18:15 doomlord: you could also use it for naming. "i'm after a function that does this; i think it would be called ..."

18:15 TEttinger: $findfn [\a \b \c] "abc"

18:15 lazybot: [clojure.string/join]

18:15 TEttinger: nice

18:16 doomlord: findfn [1 2 3] [3 2 1]

18:16 TEttinger: ,(str \a \b \c)

18:16 clojurebot: "abc"

18:16 doomlord: $findfn [1 2 3] [3 2 1]

18:16 lazybot: [clojure.core/rseq clojure.core/reverse]

18:16 TEttinger: wonder why it didn't find str

18:16 amalloy: Sgeo, Raynes: is Dynamic something that could be (or is) implemented in haskell, or does it have to be done in the bowels of the type system or compiler?

18:16 TEttinger: because str isn't a solution

18:16 doomlord: shame it isn't printing the query here in the irc channel

18:16 tomoj: $findfn \a \b \c "abc"

18:16 amalloy: &(str [\a \b \c])

18:16 lazybot: ⇒ "[\\a \\b \\c]"

18:16 TEttinger: ohhh

18:17 lazybot: [clojure.core/str]

18:17 technomancy: Raynes: so Emacs mailer uses something like "phil@i-did-not-set-a-mail-host-please-tickle-me" for your From: field if you don't configure it

18:17 TEttinger: I didn't know the syntax that findfn needed

18:17 technomancy: Raynes: maybe lein-newnew could do something similar?

18:17 Raynes: technomancy: I have no idea what we're talking about.

18:17 Sgeo: amalloy, I think it makes use of a typeclass called Typeable. I _think_ it exists in pure Haskell but actually making instances typically uses a language extension

18:17 I may be wrong

18:17 technomancy: Raynes: the annoyance of *.core

18:17 amalloy: technomancy: he's trying to get rid of foo.core

18:18 though i can see how without twitter context you'd think he's looking for a tickle buddy

18:18 Sgeo: but for your own datatypes you'd typically use deriving Typeable with the appropriate language extension

18:18 Raynes: I'm lost.

18:19 doomlord: so do we just need some massive brute force datacentre and we submit "write-fn [.sample input,outputs pairs..] :suggest_name "foo" " and it generates the programs for us, and picks the empirically proven most popular names..

18:19 amalloy: just tickle him like his email address suggests. the clojure fanfic boards would catch fire

18:19 Sgeo: amalloy, although it also relies on unsafeCoerce iirc, so partly depends on your opinion of whether that counts as Haskell

18:19 technomancy: lol

18:19 Raynes: cemerick tweeted about how he hates *.core and everyone chimed in with ideas of how to stem the tide of badly-named namespace

18:19 Raynes: Oh!

18:19 I'm so sick of the *.core arguments.

18:20 Sgeo: amalloy, http://hackage.haskell.org/packages/archive/base/

18:20 Raynes: Maybe if it had ever caused me a problem I'd care *a little*, but...

18:20 technomancy: Raynes: think of all the poor saps who don't use uniquify

18:20 Sgeo: uniquify?

18:20 technomancy: seventeen indistinguishable core.clj buffers open

18:20 amalloy: hah

18:21 i remember those days

18:21 Raynes: technomancy: Let's run up to the stage during Bodil's talk and be like "Yo, imma let you finish, but *.core is the best convention of ALL TIME!"

18:21 technomancy: Sgeo: http://www.emacswiki.org/emacs/uniquify

18:21 amalloy: personally i'm more interested in getting clojure programmers to pick namespaces that are even a little bit globally unique

18:22 * Sgeo would like it if globally unique wasn't something that was so necessary

18:22 doomlord: $findfn [3 [1 2 3 4 5 6]] [[1 2 3][4 5 6]]

18:22 lazybot: []

18:22 Sgeo: As in, being able to rename namespaces at the Clojure level, so something that was in foo.bar/baz is relocated to somethingelse/baz, not just aliased

18:23 doomlord: $findfn [2 [1 2 3 4 5 6]] [[1 2] [3 4] [5 6]]

18:23 lazybot: []

18:23 technomancy: Sgeo: one of these days we're going to hack that up at seajure

18:23 content-addressable namespaces

18:23 a la nix

18:24 Sgeo: Awesome

18:24 amalloy: doomlord: drop the []s

18:24 doomlord: how does it distinguish input from output

18:24 $findfn 2 [1 2 3 4 5 6] [[1 2] [3 4] [5 6]]

18:24 amalloy: output comes last

18:24 lazybot: [clojure.core/partition-all clojure.core/partition]

18:25 doomlord: this is awesome

18:26 ivan: $findfn 0 1

18:26 doomlord: $findfn [1 2 3][4 5 6] [[1 4][2 5][3 6]]

18:26 lazybot: [clojure.core/unchecked-inc-int clojure.core/unchecked-inc clojure.core/inc clojure.core/inc']

18:26 []

18:26 Sgeo: Wait, it will pass its argument through unchecked-inc-int?

18:27 hmm

18:27 ivan: $findfn '([1 2 3][4 5 6]) [[1 4][2 5][3 6]]

18:27 doomlord: findfn cloud app could collect people's queries and list the most popular ones as function documentation

18:27 lazybot: []

18:29 doomlord: findfn (partial -) [3 2 1 4] 1

18:29 ivan: $findfn 9223372036854775807 -9223372036854775808

18:29 lazybot: [clojure.core/unchecked-inc clojure.core/bit-not]

18:30 doomlord: $findfn (partial count) ["foo" "bar "baaaz" "fo"] "baaaz"

18:30 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$partial

18:30 doomlord: $findfn #(count %) ["foo" "bar "baaaz" "fo"] "baaaz"

18:30 lazybot: []

18:31 doomlord: thats one i was trying to write - given a 'score' function, find the element of a collection who has the largest 'score'

18:31 TEttinger: I am a little confused about leiningen mixed with maven

18:31 amalloy: &(doc max-key)

18:31 clojurebot: defmulti doc is ugly

18:31 lazybot: ⇒ "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

18:31 TEttinger: technomancy: http://nifty-gui.lessvoid.com/archives/459 lists how to have a maven project with these jars in it

18:32 but how would I carry that over to clojure with lein?

18:34 doomlord: (apply max-key #(count %) ["foo" "baar" "bz"])

18:34 ,(apply max-key #(count %) ["foo" "baar" "bz"])

18:34 clojurebot: "baar"

18:34 doomlord: awesome, thats very useful

18:35 any pther

18:35 any other lanuages have a similar standard function?

18:35 hyPiRion: ,(apply max-key count ["foo" "baar" "bz"])

18:35 clojurebot: "baar"

18:35 hyPiRion: (just fyi)

18:36 doomlord: neater ok.

18:37 $findfn count ["foo" "baar" "bz"] ["bz" "foo" "baar"]

18:38 lazybot: []

18:38 doomlord: (want: "sort-key")

18:38 metellus: ,(apply sort-by count ["foo" "baar" "bz"])

18:38 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core$sort-by>

18:39 metellus: ,(sort-by count ["foo" "baar" "bz"])

18:39 clojurebot: ("bz" "foo" "baar")

18:39 doomlord: ok cool.

18:39 amalloy: now that one, i don't know why lazybot didn't find

18:39 metellus: $findfn count ["foo" "baar" "bz"] ("bz" "foo" "baar")

18:39 lazybot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

18:39 doomlord: maybe it has a timeout (halting problem)

18:39 metellus: $findfn count ["foo" "baar" "bz"] '("bz" "foo" "baar")

18:39 lazybot: []

18:41 doomlord: does haskell benefit from having immutability assumptions in its collector in ways that jvm languages can't.. or does the jvm pay more dividends from popularity and hence amount of attention its implmeentations have got

18:41 (or maybe the jvm has enough to benefit from immutabiltiy asumptions)

18:44 technomancy: doomlord: not really; the main place JVM legacy messes you up vs haskell is when doing type inference

18:46 supposedly the HM type inference algorithm is incompatible with subclassing or something

18:46 TEttinger: site's down

18:46 doomlord: ah that sucks, type inference is awesome

18:46 Sgeo: What does Scala do?

18:46 technomancy: other types of inference are possible, but they're generally not as good

18:47 Sgeo: Oh, have limited inferencing?

18:47 technomancy: Sgeo: inference for locals and subclass methods only IIRC

18:47 TEttinger: technomancy: which site, http://nifty-gui.lessvoid.com/archives/459 ?

18:47 technomancy: TEttingeryeah

18:47 TEttinger: just loaded it from her

18:47 e

18:47 doomlord: does clr handle it bbetter

18:48 technomancy: doomlord: F# does better than scala from what I understand, but I haven't looked at it in detail

18:48 doomlord: i'd assume immutability helps type inferencing quite a bit vs other lisps

18:49 want: power of lisp macros, clojures style of adhoc structures, *and* reliable type inferencing :)

19:01 oskarth: If I am moving code from one ns to another and get "already refers to..." errors in nREPL, how do I get nREPL to lose the old definitions / force update?

19:03 tomoj: one manual way is (ns-unmap *ns* 'the-var)

19:04 oskarth: ns-unmap, thank you :)

19:07 dgrnbrg: Hey clojure users, I just wrote a println/trace oriented debugging library for Clojure: https://github.com/dgrnbrg/spyscope

19:08 It's thoroughly documented, and it provides a lot of filtering and tracing functionality in very few keystrokes

19:10 it supports many usage patterns in multithreaded debugging, such as including fragments of filtered stack traces and storing the interleaving of the traces.

19:11 it also is done with reader tags and extra metadata, which means you type as few characters as possible

19:11 amalloy: dgrnbrg: i find that last claim highly dubious

19:12 for example, #spy/d x is already more typing than (? x), which is what i use

19:12 dgrnbrg: amalloy: you could alias it to #?, which would be fewer characters (and I think that's legal)...

19:13 amalloy: well (a) it's not actually fewer characters with paredit, and (b) you're not supposed to use non-namespaced reader tags, as i'm sure you know

19:13 dgrnbrg: amalloy: that's why it has a 3 letter namespace :)

19:13 amalloy: i know

19:14 dgrnbrg: my paredit would require an extra keystroke to slurp the x

19:14 amalloy: no way. M-( ?

19:14 dgrnbrg: i use paredit.vim :)

19:14 and evil-paredit-compat.el

19:14 wingy_: with datomic free i dont get durability right?

19:15 dgrnbrg: but, amalloy, does your library have the filtering/querying/understanding really messy logs functionality?

19:16 amalloy: not really. it just prints the expression and then the value. but i carefully objected only to the repeated claim of "as few characters as possible"

19:17 rlb: TimMc: so I suppose it might just be that incanter just doesn't work over ssh -X/Y right now.

19:17 s/just doesn't/doesn't/

19:18 dgrnbrg: amalloy: I'm just trying to get some eyeballs ;)

19:19 I think that what I wrote is very useful, and removes a lot of annoyance from long debugging sessions of multithreaded applications, where it's hard to see what's going on, and at some point you've got some many tracing statements it's like "wtf does :failed 323 mean in the stdout mess!?"

19:19 tomoj: wingy_: you get durability with transactor-local storage

19:21 wingy_: tomoj: didnt know it writes to the disk

19:21 cool

19:22 hyPiRion: dgrnbrg: So you're using reader tags to remove the amount of parens?

19:23 dgrnbrg: hyPiRion: I often find that i first want to see what a value is, and then I realize over time that I need more and more information about it, especially as I start displaying related values as well

19:23 So you can first just use the reader tag to get basic info

19:23 and then you can keep requesting more and more info and narrowing your search as you gain problem insight

19:23 and the printed lines have enough context to grep, filter, and detemine how to remove the traces

19:24 hyPiRion: Hmm, interesting.

19:25 tomoj: I wonder how much slower the free storage is than dynamodb

19:25 dgrnbrg: it's what I came up with when I tried to write a tool that followed my natural, lazy, least-effort-first debugging style

19:26 I'd like to add cross-thread data analysis, so that it could track data flowing through code and reference types, but even without that, just making coherent traces is a big improvement

19:27 hyPiRion: Hmm, you should add some settable debug-flag which toggles debugging off and on.

19:27 eflynn: wow lot of people in here

19:27 hyPiRion: Since I'm lazy and wouldn't bother to remove my debugging stuff after a debugging session.

19:28 dgrnbrg: hyPiRion: wouldn't you use git checkout/reset to clean up the code prior to commit/release?


19:29 how would you imagine that working--a configurable regex that filters which namespaces have any effect at the moment?

19:31 hyPiRion: dgrnbrg: Well, it was just a random though I had after long nights with #define DEBUG in c.

19:31 s/though/thought/

19:31 Maybe I should use a logging tool for that instead, and turn the logging off.

19:32 dgrnbrg: yeah, this is less for logging and more for debugging sessions

19:35 hyPiRion: anyway, it seems like something I'm doing quite a lot but haven't bothered to make a lib out of. I'll probably use it if I'm in need of debugging.

19:35 dgrnbrg: awesome! that was my thought exactly, but i got fed up with not having the lib, esp for mutlithreaded stuff

19:37 Sgeo: I'm starting to see the benefit of Clojure's approach to namespacing symbols over Common Lisp's approach: It's why it's not terrible that Clojure is a Lisp-1 with CL-style macros, because the symbols that are used within, say, a let won't be the same as the symbols that are the result of quasiquoting

19:37 ,`+

19:37 clojurebot: clojure.core/+

19:37 tomoj: I wonder why symbols can't start with numbers

19:37 Sgeo: Using that in a let that let's + won't conflict

19:37 ,(= '+ 'clojure.core/+)

19:37 clojurebot: false

19:38 Sgeo: ,(let [+ 5] (clojure.core/+ 10 +))

19:38 clojurebot: 15

19:41 under_my_shoes: :)

19:51 TEttinger: technomancy, maybe in more general terms, can you use a maven repo (not sure of the exact terminology) from leiningen, in a lein-only project?

19:52 the line that had me confused a bit, more than the rest,

19:52 For Maven simply add our sf.net Nifty Maven Repo to your pom.xml:

19:52 and I have never added repos for leiningen before

19:59 wingy_: TEttinger: long time no see .. you were one of the LiveScript users?

19:59 amalloy: $google leiningen sample project.clj

19:59 lazybot: [leiningen/sample.project.clj at master · technomancy/leiningen ...] https://github.com/technomancy/leiningen/blob/master/sample.project.clj

19:59 amalloy: TEttinger: ^

20:00 TEttinger: wingy_, still considering it

20:00 thanks amalloy

20:01 wingy_, if I am not mistaken so is Sorella

20:02 and right now I am looking to develop something along the lines of "a nice GUI"

20:02 wingy_: TEttinger: i thought you were already using it for dev

20:02 TEttinger: no, I don't know enough JS to get by

20:03 I want to get Nifty GUI to work with Clojure for now, failing that I will try LiveScript with AppJS

20:18 tomoj: $findfn :foo :bar :foo

20:19 lazybot: [clojure.core/doto clojure.core/or]

20:19 xeqi: were either of those what you were looking for?

20:19 tomoj: neither of them are fns

20:20 I bet useful has this

20:20 xeqi: &((comp first list) :foo :bar)

20:20 lazybot: ⇒ :foo

20:21 tomoj: guess not

20:21 ah, that'll work

20:25 Sgeo: ,((const :foo) :bar)

20:25 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: const in this context, compiling:(NO_SOURCE_PATH:0)>

20:25 Sgeo: ,((constantly :foo) :bar)

20:25 clojurebot: :foo

20:25 Sgeo: Sorry, too much Haskell ;)

20:25 Although I guess that's not what you want

20:25 tomoj: if it were curried

20:25 Sgeo: ,(apply first :foo :bar)

20:25 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

20:26 Sgeo: ,(apply first [:foo :bar])

20:26 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$first>

20:26 Sgeo: ...derp

20:26 devn: herp

20:26 muhoo: m'gerp

20:26 devn: ermagerb

20:26 tomoj: devn: you know how to rebase?

20:27 devn: tomoj: i knew someone was going to tell me "you fucking noob"

20:27 tomoj: nah, rebase is scary

20:27 devn: not that you're saying it that way, i just have always dealt in pull requests

20:27 so the patch flow is a bit foreign to me

20:28 i did git am --keep-cr -s < patch.diff

20:28 it failed to apply cleanly

20:28 i sort of expected a merge-esque situation but didn't see one

20:28 so i ended up just redoing the patch, committing, generating the new patch

20:28 tomoj: well one option is to go to a spot where the patch applies fine, apply it, then do `git rebase origin/master` and fix the conflicts

20:28 then add and commit

20:29 devn: tomoj: gotcha. that makes sense.

20:29 tomoj: dunno if that puts you as committer but it definitely will leave author alone

20:29 devn: tomoj: how active are you on the dev jira?

20:29 tomoj: and commit date

20:30 not much on clj, somewhat on cljs

20:30 devn: tomoj: i feel like im doing stuff wrong -- ive read through the guide for submitting patches with the workflow and what-not

20:30 but i can't shake the feeling im Doing It Wrong

20:32 tomoj: i just did a few things on there, so I suppose I'll find out the hard way whether I get it or not

20:33 tomoj: there's so much low-hanging fruit and tedious work that can be done. I'd like to help some people in the meetup I run to get comfortable helping out with some of that tedium, just want to make sure I don't make a mess

20:48 doomlord: $findfn [10 1 9 100 2] [1 100]

20:48 lazybot: []

20:48 doomlord: $findfn [10 1 9 100 2] [1]

20:49 lazybot: []

20:49 doomlord: $findfn 10 1 9 100 2 [1]

20:49 lazybot: []

20:49 doomlord: $findfn 10 1 9 100 2 100

20:49 lazybot: [clojure.core/bit-xor clojure.core/max]

20:49 doomlord: $findfn 10 1 9 100 2 [1 100]

20:50 lazybot: []

20:50 amalloy: hah. bit-xor. what a lovely accident

20:51 tomoj: &((juxt min max) 10 1 9 100 2)

20:51 lazybot: ⇒ [1 100]

20:51 doomlord: damn there was me trying to write that with maps /reduces

20:51 (defn reduce-juxt..) (reduce-juxt min max [10 1 9 2])

20:52 ,(apply (juxt min max) [9 10 2 7 4])

20:52 clojurebot: [2 10]

21:04 ivan: any longbottom news?

21:08 tomoj: :(

21:08 the tracing thing someone wrote above made me long for longbottom

21:53 Frozenlo`: Question for seesaw users: Whenever I use the 'dialog' function, it shows a dialog. However the dialog doesn't have a presence on the task bar, so if I put another window in front of it, I can forget it's there. Is there a way to add it to the taskbar?

22:09 Sgeo: Would be nice if it was easy to make a macro that intercepts function calls

22:09 * Sgeo can think of a few million uses for such a thing

22:11 tomoj: it intercepts every single function call?

22:12 xeqi: Sgeo: similar to https://github.com/technomancy/robert-hooke ?

22:12 yedi: is there a #clojure chat log?

22:12 tomoj: logs?

22:12 clojurebot: logs is http://clojure-log.n01se.net/

22:12 tomoj: clojurebot: botsnack

22:12 clojurebot: botsnack is scoobysnack

22:14 Sgeo: xeqi, except adding a hook to all function calls, not just ones I know about

22:18 gfredericks: I think it's conceivable to redefine fn

22:19 but probably a lot of clojure.core at least would get loaded before that happens

22:22 amalloy: Sgeo: i don't think you would enjoy the spooky action-at-a-distance strewn throughout your program

22:22 Sgeo: amalloy, well, just the function calls lexically contained within some macro

22:23 tomoj: why redefine fn? just walk the body

22:23 amalloy: "just"

22:24 Sgeo: Yes, I know it can be done by walking the body, but it also requires understanding special forms. It's certainly doable, I think, but a library to make it easy would be nice

22:24 amalloy: Sgeo: so write that library. nobody else is going to

22:51 Apage43: oh man

22:51 I may have caught myself overusing a pattern

23:14 amalloy: Apage43: what pattern?

23:16 Apage43: (let [acc (transient [])] (walk/{pre/post}walk (fn [el] (when some-pred (conj! acc el)) el)) (persistent! acc))

23:16 er, where the last arg to walk is some big ugly hierarchichal structure

23:17 and I'm just searching it for pieces that match a predicate

23:17 amalloy: so...(filter some-pred (tree-seq coll))?

23:18 or i guess tree-seq wants more args

23:19 (filter some-pred (tree-seq coll? seq coll)) iirc

23:19 Apage43: seq? identity looks usable for most of the places I'd use that pattern with postwalk

23:19 sometimes I use it with prewalk too though,

23:20 hm

23:20 but it's lazy, which is really nice

23:20 amalloy: Apage43: your function is brutally wrong anyway

23:20 that conj! is not guaranteed to do what you want; transients are not supposed to be bashed in place

23:21 Apage43: oh?

23:22 amalloy: they're permitted to mutate themselves, not guaranteed

23:22 it so happens that in the current version of clojure, vectors always do (i think). but maps don't, and in a future version vectors may not

23:22 Apage43: ah. I'm just getting lucky then, oops.

23:22 amalloy: even if it were guaranteed, there's no reason to introduce mutability here; using an atom would be less wrong but just as unpleasant

23:24 after all, you're computing the results of a pure function on a data structure. recursion is enough

23:25 Apage43: tree-seq is almost what I want

23:25 I'll prolly write something based off it

23:28 I need to also have the option to go breadth-first, but that's it really

23:30 callen: ~(read-string "(+ 1 42)")

23:30 clojurebot: read-string |is| as unsafe as eval unless *read-eval* is bound to false.

23:30 callen: IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote clojure.lang.Var$Unbound.throwArity (Var.java:43)

23:30 kay, what did I do that is stupid?

23:31 amalloy: you tried to unquote inside of a non-quoted context

23:32 callen: amalloy: it returns (+ 1 42), how do I force eval on that?

23:32 amalloy: don't

23:32 or call eval, if you want

23:32 callen: don't say that, I'm just trying to learn.

23:32 what exactly is it returning? a quoted form?

23:32 amalloy: a list

23:32 callen: this isn't production code, I'm following along with cemerick's book.

23:33 amalloy: containing the symbol +, and the numbers 1 and 42

23:33 callen: that makes sense just fine, but how do I do the equivalent of ()'ing it, if it's not quoted to begin with?

23:34 amalloy: ()'ing it doesn't mean anything, so i don't know what the equivalent of that is

23:34 callen: amalloy: how do I get the returned list to evaluate and return its result?

23:34 just eval?

23:35 amalloy: eval. that's what eval is

23:35 callen: that worked, but I was suspicious of it.

23:35 amalloy: thank you.

Logging service provided by n01se.net