#clojure log - Jan 19 2013

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

0:39 TimMc: &((partial apply map vector) [[1 2] [3 4]])

0:39 lazybot: ⇒ ([1 3] [2 4])

0:39 TimMc: &((partial apply map vector) [[1 2]])

0:39 lazybot: ⇒ ([1] [2])

0:39 TimMc: &((partial apply map vector) [])

0:39 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$map

0:39 TimMc: :-(

0:47 mikera: &((partial apply map vector) [[]])

0:47 lazybot: ⇒ ()

1:40 TimMc: hyPiRion: It begins... https://github.com/timmc/swearjure/blob/master/src/org/timmc/swearjure.clj

1:43 callen: Raynes: nice work.

1:43 Raynes: callen: What did I do?

1:43 callen: Raynes: Imagine Dragons

1:44 Raynes: callen: Trying to determine how that constitutes nice work.

1:44 * brainproxy dreams of a high-level, über flexible defrecord-like macro (or system of macros) which lets him create Datomic backed types w/o manually mucking around in schemas

1:44 brainproxy: anyone can serve that up on a plate?

1:44 callen: Raynes: caught me in a good mood.

1:45 Raynes: trolling people in #startups, hacking on a side project after pizza and beer with my coworkers. It's a good Friday.

1:45 Raynes: callen: So you're not going to stab me in the face because you hated it, or you're thanking me because you liked it, or...?

1:45 * Raynes still isn't sure.

1:46 callen: all of the above.

1:46 * Raynes explodes into bits and pieces.

2:05 cark: how would you guys go about mesuring time (say in milliseconds) but in a way that would be consistent even when the user fiddles with the system time ?

2:05 I know there is the performance counter... but it seems maybe too precise for my use

2:08 TimMc: cark: By the performance counter, you mean ##(System/nanoTime) ?

2:08 lazybot: ⇒ 33290774680106530

2:08 cark: yes

2:09 TimMc: Well, it's what you've got, right?

2:09 cark: right

2:10 I wonder how precise it is over long durations

2:10 like hours

2:10 a couple hours

2:11 TimMc: This worries me: "No guarantees are made about how frequently values change."

2:11 cark: yes I don't like it =P

2:12 TimMc: I *hope* that means changes in offset between JVM runs.

2:12 cark: Is this for measuring durations within a single JVM run?

2:12 cark: my use case is this : I need to measure time of phone calls, user might be a crook and change the system time in order to pocket the money

2:12 yes

2:13 usually i rely on telephony hardware to provide the duration data, but in this case it's all software

2:14 TimMc: As long as it's all within one JVM run, you should be fine.

2:15 The user would probably have to go to quite some effort to affect the nano timer.

2:16 cark: I'm also a bit warry that it might overflow while i'm measuring a duration

2:16 wary*

2:21 anyways thanks for your input !

2:21 TimMc: cark: http://stackoverflow.com/a/4588037/20772 :-/

2:22 cark: mhh maybe he was at the overflow point

2:23 though it would still be positive with java, as the substraction would ...Err underflow

2:23 mhh

2:23 need to do some testing =)

2:24 TimMc: Subtraction is always safe, you just might get a negative number.

2:25 Relatedly, that's a trick you can use to average two numbers without overflowing on the addition.

2:25 cark: right, i mean if you substract Long.MIN_VALUE - Long-MAX_VALUE

2:25 TimMc: Oh, I see. Right, you could overflow that way.

2:26 s/safe/safe with two numbers of the same signum/ :-P

2:26 I suppose that's not as helpful.

2:26 cark: they say nanoTime might be negative

2:27 hum btw how can I do overflowing math with clojure ?

2:27 andrewdeandrade: question: when entering a multiline expression into the repl, how do i go up one line to change it (because of a typo for example) if I know it is incorrect?

2:28 TimMc: cark: unchecked math?

2:28 cark: ahyes

2:28 andrewdeandrade: something like rlwrap looks like it might be able to do the job but I couldn't figure out how

2:28 TimMc: &(unchecked-add Long/MAX_VALUE Long/MAX_VALUE) ;; cark

2:28 lazybot: ⇒ -2

2:30 cark: ,(unchecked-subtract Long/MIN_VALUE Long/MAX_VALUE)

2:30 clojurebot: 1

2:30 cark: sounds about right

2:31 andrewdeandrade: I would recommand using a real repl, like emacs+nrepl or any other like it

2:33 anyways i'll go for breakfast now, thanks for your input TimMc !

2:34 TimMc: Breakfast... It's 2:22 AM here. >_<

2:35 andrewdeandrade: I don't know of a way to go back and edit previous lines -- I think you're locked in.

2:38 andrewdeandrade: cark: yeah, i'm probably going to end up using emacs... i just wanted to be able to do it with `lein repl` since it's easy to fire up

2:38 TimMc: thx

2:38 very unfortunate, but I guess it's just supposed to be uber bare bones

2:38 TimMc: It happens in nREPL as well.

2:39 andrewdeandrade: emacs can't go back and modify the previous line?

2:39 TimMc: Mmm... nREPL may behave differently under Emacs, yes.

2:46 ChongLi: hmmm evil is pretty cool

4:03 muhoo: i have to deal with a java class that DEMANDS only a [Ljava.net.InetSocketAddress]

4:04 it won't accept an ArrayList of them. it must be a [Ljava.net.InetSocketAddress . any way in clojure to generate one?

4:06 cark: ,doc make-array

4:06 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0)>

4:06 cark: hum

4:13 muhoo: into-array seems to do it

4:19 mikera: anyone here doing matrix / numerics work with clojure?

4:22 kevin234: Are there alternatives using Java exceptions for error handling?

4:23 mikera: why would you want to avoid Java exceptions?

4:23 kevin234: The dependence on a class-based filtering mechanism is not very flexible

4:23 mikera: you can wrap in a macro if you don't like the syntax :-)

4:24 just catch Throwable, then you can filer however you like

4:25 kevin234: Not a bad idea, but maybe there is a framework out there that already does that and wraps it all in some macros?

4:25 mikera: hmm not sure. I have a few macros lying around but nothing like a framework

4:26 kevin234: guess I need to do some googling

4:26 mikera: If you wrote your own Java exception class that held an arbitrary object

4:26 you could have a pretty flexible error handling framework in whatever style you like

4:27 could make a nice little library. though never really felt the need for it myself

4:30 kevin234: mikera: looks like I found basically what we are talking about: https://github.com/scgilardi/slingshot

4:31 mikera: nice! I should have guessed someone has thought of this already

4:43 hyPiRion: TimMc: Oh, I see. Are we able to find eval and friends?

4:45 mmarczyk: kevin234: see also ex-info & ex-data

5:10 kevin234: mmarczyk: thanks, looks good

7:25 borkdude: Since I keep hearing more about Markdown for writing articles lately, is there a nice example of a Markdown source file including Clojure source highlighting?

7:28 xumingmingv: I am interested in this topic too.

7:31 augustl: there are some syntax highlighting engines that parses HTML, so that's a possible route

7:31 and of course the in-browser ones

7:33 antares_: borkdude: clojure-doc.org source

7:33 borkdude: antares_ great, tnx

7:33 antares_: borkdude: github's ``` clojure Markdown extension has been implemented at least in C and Ruby (via bindings)

7:52 borkdude: I tried out Markdown for 5 minutes, ran into this issue quit soon: http://meta.stackoverflow.com/questions/23822/markdown-code-block-problem

7:52 quite

8:03 antares_: borkdude: indentation for code was superceded by the ``` extension (which you can use e.g. if you are writing docs)

8:07 borkdude: antares_ ok

8:24 nz-: technomancy: i missed that one

8:25 ops, cut&paste error

9:35 bizarrefish: Lo, all

9:37 hyPiRion: hello

9:46 pure_loulou: hello :))

9:47 i want to get values form a list so i can use theme as values, example '(1 2 3) ----> 1 2 3

9:47 i want to get values form a list so i can use theme as arguments, example '(1 2 3) ----> 1 2 3

9:47 can i?

9:47 Chousuke: (apply function list)

9:48 ,(apply + 1 2 3 '(4 5 6))

9:48 clojurebot: 21

9:48 Chousuke: the arguments before the final sequence are optional

9:48 pure_loulou: ... wait for me to think :)

9:50 bizarrefish: ,(apply print ["this" "is" "an" "argument" "list"])

9:50 clojurebot: this is an argument list

9:51 pure_loulou: i want to make '(1 2 3) ---> 1 2 3

9:51 like @ in macros

9:51 bizarrefish: Is there some kind of high performance code generation lib for clojure? I know there are assemblers(well, at least one - lithium), and there's clojurescript, I'm talking about more the C kind of level

9:52 Example: (defspeedyprogram [speedyargs] #_(some numbercrunching written in a subset of clojure))

9:53 pure_loulou: '(1 2 3 4 5) that's just a sequence, what do you want to get? one of the elements from it?

9:54 If you just want an element, use nth

9:54 ,(nth '(1 2 3 4 5 6) 2)

9:54 clojurebot: 3

9:55 bizarrefish: For random access, though, you normally want to be using a vector [] rather than a list () . If you use a vector, you've got a neat syntax you can use to get at the elements: ([1 2 3 4 5] 2)

9:55 ,(let [my-vector [1 2 3 4 5]] (my-vector 2))

9:55 clojurebot: 3

9:59 pure_loulou: i want to get all the elements

9:59 and use them to call a function

10:00 bizarrefish: pure_loulou: That's what 'apply' is for. ,(doc apply)

10:00 ,(doc apply)

10:00 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

10:00 AimHere: ,(apply inc '(1 2 3 4 5))

10:00 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (5) passed to: core$inc>

10:00 AimHere: Oops

10:00 ,(apply * '(1 2 3 4 5))

10:00 clojurebot: 120

10:00 pure_loulou: ok guys i will try ,thx :) i am newbie

10:00 bizarrefish: ,(apply print '(1 2 3 4 5))

10:00 clojurebot: 1 2 3 4 5

10:01 hyPiRion: "(apply + [1 2 3 4])" is the same as "(+ 1 2 3 4)"

10:01 bizarrefish: pure_loulou: righto, good luck dude

10:01 hyPiRion: pure_loulou: Don't be afraid of asking :)

10:01 AimHere: Sadly, to confuse things, there are clojure function-like objects (like macros and Java methods) that can't be applied like that

10:02 hyPiRion: AimHere: Let's not talk about that now :p

10:02 AimHere: I figured pure_loulou might have to be aware that there might be things later on that bite him. If it happens he can ask

10:02 TimMc: hyPiRion: No, I can't get eval.

10:02 pure_loulou: (fun '(1 2 3)) ----> 1 2 3 ; as arguments

10:03 bizarrefish: AimHere: I'm sure he'll find out one way or another :P

10:03 pure_loulou: (apply fun '(1 2 3))

10:03 That does the same as: (fun 1 2 3)

10:04 hyPiRion: TimMc: Ahh. The compiler idea is neat though. With what we have, we should be able to generate working scripts for stuff

10:04 pure_loulou: you right i think

10:04 thx

10:05 hyPiRion: e.g. "(defn foo [a b c] (+ a b c)) (println (foo 1 2 3))" could be swearjurized

10:05 Sgeo_: swearjurized?

10:10 TimMc: ~rest

10:10 clojurebot: rest never returns a unicorn

10:10 TimMc: ~rest

10:10 clojurebot: rest is easy to write without alphanumerics: https://www.refheap.com/paste/5980

10:10 TimMc: Sgeo_: ^

10:11 hyPiRion: ~swearjure

10:11 clojurebot: Cool story bro.

10:11 hyPiRion: ~swearjure

10:11 clojurebot: Huh?

10:11 hyPiRion: humm

10:11 ~Swearjure

10:11 clojurebot: Gabh mo leithscéal?

10:11 hyPiRion: clojurebot: Swearjure is http://hypirion.com/swearjure

10:11 clojurebot: c'est bon!

10:15 Sgeo_: ah

10:15 clojure-newb: hey guys.. this is an emacs question really but I'm trying to learn the favourite productivity editor for clojure debs… in nrepl (via nrepl-jack-in) I get started typing and then just get kicked out with a message 'Buffer is read-only:#<buffer *nrepl-error*>… this was when I started typing (println) just now, any ideas ?

10:16 I'm using emacs-live

10:17 TimMc: hyPiRion: Hmm, can we do (boolean ...) in swearjure?

10:17 hyPiRion: TimMc: Hmm

10:18 TimMc: boolean takes nil and false to one value and everything else to another -- should be doable with a map.

10:18 zilti: Is there some kind of successor to ibdknox' fetch lib?

10:19 hyPiRion: TimMc: Can we do nil?

10:19 as in "nil"

10:19 TimMc: I'm sure...

10:19 hyPiRion: ,({} (+))

10:19 clojurebot: nil

10:19 hyPiRion: Oh, sweet.

10:19 Sgeo_: clojure-newb, there should be another buffer for the REPL itself, I think

10:20 *nrepl-error* is a buffer that errors go on

10:20 TimMc: hyPiRion: I've implemented if=, and this will let me generalize to if + =

10:20 clojure-newb: Sgeo_:I was in the *nrepl* buffer, I had already evaluated an in-ms command successfully

10:20 but then as I continued typing (prin… I just got kicked out

10:20 strange… figure there may be some shortcut key getting picked up ?

10:22 hyPiRion: ,(#{1 2} 3 4)

10:22 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: PersistentHashSet>

10:22 hyPiRion: boo.

10:22 TimMc: Interesting.

10:22 Oh, makes sense.

10:23 clojure-newb: Sgeo_: maybe my workflow is wrong… I start emacs, load a file, split vertically, nrepl-jack-in and then use in-ms to get to where I want to go

10:24 Sgeo_: Are you sure nothing's throwing an error?

10:24 I don't think in-ms exists

10:24 clojure-newb: sorry… typo.. in-ns

10:25 Sgeo_: Check what buffer you're in once you jack in, then check what buffer you're in once you in-ns

10:25 hyPiRion: ,(let [ts #(= %& %&), fs #(= `%& %&), nils #({} %&) boolean #((`{~(= + -) ~fs, ~({} +) ~nils} % ts))] (map boolean [nil false true 1 [1 2 3]]))

10:25 clojurebot: (nil false true true true)

10:25 hyPiRion: TimMc: ^

10:25 clojure-newb: Sgeo_: will try, thanks

10:25 Sgeo_: yw

10:31 TimMc: &({(= :+ :-) (= :+ :-), ({} :+) ({} :+)} false (= :*))

10:31 lazybot: ⇒ false

10:31 TimMc: &({(= :+ :-) (= :+ :-), ({} :+) ({} :+)} 17 (= :*))

10:31 lazybot: ⇒ true

10:31 TimMc: &({(= :+ :-) (= :+ :-), ({} :+) ({} :+)} nil (= :*))

10:31 lazybot: ⇒ nil

10:31 TimMc: Hmm, not quite.

10:31 &({(= :+ :-) (= :+ :-), ({} :+) (= :+ :-)} nil (= :*))

10:31 lazybot: ⇒ false

10:32 TimMc: I don't really need a boolean function.

10:33 AimHere: Can you do map in your daft swearjure?

10:34 As in the function map, because then and should be easy

10:34 TimMc: I think hyPiRion got that working, yes.

10:34 AimHere: Well map and reduce

10:34 Because you can just map over {(= * *) (*) (= * +) (+)} or something and then add it all up

10:35 TimMc: Heh, nice!

10:35 AimHere: That only works for true and false, rather than truthy and falsy

10:35 TimMc: It doesn't do short-circuiting, of course.

10:45 hyPiRion: Roadmap for the compiler: https://github.com/timmc/swearjure/blob/master/src/org/timmc/swearjure.clj#L4

10:49 Hmm, I need to walk a tree of code and replace certain forms. Is there a tree-walking thing for that?

10:51 hyPiRion: AimHere: I got mapv

10:54 And yeah TimMc, boolean wasn't working. It was just mapping truthy values to true.

10:54 * my boolean attempty

10:55 Anderkent: TimMc: do you need to understand the code or are you just treating it as nested lists?

10:55 TimMc: Nested lists, maps, vectors, maybe even records.

10:56 Hmm... I do need to understand it a little bit.

10:56 Anderkent: Right. You can take a look at how cloverage does code instrumentation - i don't think there's anything out of the box that can walk code sanely

10:56 https://github.com/lshift/cloverage/blob/master/cloverage/src/cloverage/instrument.clj

10:56 TimMc: I want to find certain (very simple) patterns in the code and replace them.

10:56 Thanks! I'll take a look.

10:58 Ideally I'd say (walk form dispatch-fn), where dispatch-fn is handed a node and asked for a replacer-fn, which could be nil.

10:58 clojurebot: Roger.

10:58 TimMc: clojurebot: You suck.

10:58 clojurebot: It's greek to me.

10:58 TimMc: This would be a neat lib, but it feels like it should exist...

11:00 For now I'm just using with-redefs on gensym to make my tests easier, but later I'll need something production-capable and more complicated.

11:00 (I'll need to find and replace function calls.)

11:02 Anderkent: TimMc: right. That's on our todo list for cloverage - but I mostly work on it in my free time nowadays (since it fulfills the primary purpose decently already). instrument/wrap knows how to recurse into forms, extracting it out to something more generic shouldn't be too hard

11:02 TimMc: Anderkent: I'd be happy to drop work on this swearjure silliness and build a lib for that.

11:04 Haha, whoops -- gensym isn't a great thing to redef.

11:04 hyPiRion: TimMc: Grats on breaking Clojure :p

11:04 Anderkent: TimMc: feel free, cloverage is epl :) Unfortunately there's a bit of code-coverage logic mixed with code-walking logic in instrument. Feel free to ask any questions here or via github

11:05 qz: what is preferred way to call a function for every item in a seq? i do not care about results, so maybe there's something better than map..

11:05 Anderkent: qz: doseq

11:05 ah wait not quite I suppose

11:05 hyPiRion: (alter-var-root #'gensym memoize)

11:05 Smartest thing ever.

11:05 TimMc: hyPiRion: Glorious.

11:06 Anderkent: doseq sounds good.

11:06 Anderkent: ,(doc dorun)

11:06 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

11:06 TimMc: &(doseq [x (range 3)] (println x))

11:06 lazybot: ⇒ 0 1 2 nil

11:06 Anderkent: yeah I think doseq is the way to go

11:06 qz: Anderkent: aha, thanks

11:06 Anderkent: I was looking for something with the map syntax

11:07 qz: Anderkent: i thought there's something like map but that doesnt care about result, like .each vs .map in ruby

11:08 Anderkent: qz: yeah doseq does that in the general case.

11:11 TimMc: qz: Another difference is that doseq is eager and map is lazy.

11:12 &(map println (range))

11:12 lazybot: java.lang.OutOfMemoryError: Java heap space

11:12 qz: TimMc: yeah, i need eager evaluation

11:12 TimMc: Hmm... that depends on how lazybot builds a response, I guess.

11:12 Raynes: &(let [foo (map println (range))])

11:13 lazybot: ⇒ nil

11:13 qz: also, what's preferred way to create locals in a function? def or let?

11:13 Raynes: let.

11:13 Anderkent: qz: let. def declares global vars

11:13 Raynes: Not only is def not the preferred way, it is never used for that purpose ever at all.

11:13 rkz: what are people using for oauth2? clj-oauth2? looks like it's not merged pull reqs for 5 months

11:13 qz: i see, thanks. i'm total newb to clojure..

11:15 TimMc: qz: In scheme, define can be used to create locals, which trips a lot of people up who are used to that. :-)

11:16 qz: TimMc: wish i knew scheme, this is my first lisp-like language.. :)

11:16 cark: qz : the parenthesis are a give away : (let [a 12] (func a)) .. it clearly shows that a is used in the scope of the let form

11:18 Anderkent: rkz: which clj-oauth2 are you looking at? The canonical one seems lively

11:19 qz: cark: yeah, i see..

11:19 rkz: Anderkent: looking at https://github.com/DerGuteMoritz/clj-oauth2 but i see that's not the one on clojars?

11:20 Anderkent: https://github.com/clj-oauth2/clj-oauth2 seems to be the one to use

11:54 TimMc: Anderkent: I'd like this tree-walking function to accept a single dispatch fn, which can either instruct the walker to A) replace the node using a returned fn, B) stop descending into this node, or C) keep descending.

11:55 Anderkent: I was going to use nil to indicate "keep descending, I'm not interested in this node", but I don't have a way to ask it to stop -- and keywords can be valid fns.

11:56 Anderkent: TimMc: isn't just returning the form unchanged sufficient to stop?

11:57 TimMc: Ah... right. :-)

11:57 Anderkent: or do you want to recurse into the returned node?

11:57 TimMc: Return identity.

11:57 Anderkent: yep :)

11:57 TimMc: Nope, any replacer fn will have to recurse to the walker again if it wants to process children.

11:57 Anderkent: yeah, that makes sense

11:58 TimMc: That gives it a choice of whether to pre-process or post-process, for instance.

11:58 Anderkent: you run into stack depth issues though if it would be a common case

11:59 actually nvm

11:59 :P

11:59 TimMc: I guess we don't know how deep this data structure might be.

12:01 Anderkent: unlikely to be an issue, and since the walker would probably be recursing as well you're not losing anything by having it done in the replacer

12:01 TimMc: Well, the walker could use trampolining or maintain its own stack (I think...).

12:01 Explicit recursions back to the walker would be unavoidable stack allocations.

12:02 Anderkent: well, the need for that depends on your input type... If you're working on human produced code, don't bother

12:02 generated code might be more problematic since it can be arbitrary deep

12:05 well, I'll be off now. If you work on this based on cloverage, do contact when you have any questions - my github's https://github.com/JacekLach

12:05 TimMc: Cool, thanks.

12:05 djwonk: is it considered good/bad/otherwise to define a function in a custom namespace that shadows a core function?

12:06 TimMc: djwonk: It can be confusing, although the :refer-clojure in the ns will alert callers to be on the lookout.

12:06 It's only really a problem if someone :uses the ns, such as from the REPL.

12:07 djwonk: TimMc: all and all, probably safer to avoid the name collisions, then? unless there is some compelling reason

12:07 TimMc: Yeah.

12:08 djwonk: ok, thanks

12:08 TimMc: You can also get some really entertaining bugs if you shadow a core fn with a local, but that doesn't mess up other people's namespaces.

12:09 I keep catching myself using 'name as a local...

12:09 djwonk: TimMc: that sounds like a great way to make life interesting

12:10 Anderkent: djwonk: you may also get some AOT compilation issues if the shadowed function is used in something like gen-class

12:10 TimMc: ORLY?

12:11 djwonk: I was hoping to keep function names short. So instead of policy/policy-name I was hoping for policy/name

12:11 Anderkent: TimMc: it's only when you dont refer-clojure :exclude [whatever-clashes]

12:11 TimMc: Anderkent: So it only happens when you ignore compiler warnings? I'm fine with that.

12:12 djwonk: ~(doc refer-clojure)

12:12 clojurebot: defmulti doc is ugly

12:13 Anderkent: I think I had that issue with drift-db I believe : https://github.com/macourtney/drift-db/pull/2

12:13 djwonk: it's a key on the ns macro

12:13 djwonk: Anderkent: I'll check it out

12:14 ,(doc refer-clojure)

12:14 clojurebot: "([& filters]); Same as (refer 'clojure.core <filters>)"

12:14 TimMc: ,(refer-clojure :exclude '[name])

12:14 clojurebot: nil

12:14 TimMc: ,name

12:14 clojurebot: #<core$name clojure.core$name@6e56103e>

12:15 TimMc: The :exclude thing only works on clojure.core when used in the ns block.

12:16 Anderkent: TimMc: that's assuming you have a ns block. If you don't it will work (i.e. it will work the first time clojure.core is referred into the ns)

12:16 TimMc: Hmmm.

12:16 djwonk: Anderkent TimMc thanks that saves me some warnings

12:24 TimMc: &(map #(when-let [[f & r] %] [f r]) [nil () [1]])

12:24 lazybot: ⇒ (nil [nil nil] [1 nil])

12:37 tomoj: (ns foo (:import-clojure))

12:37 that's basically the default in clojurescript, right?

12:39 jamiei_: amalloy_ bbloom: Thanks for both of your help a couple of days ago with my ns clause problem. Whichever of you suggested the mis-declared defn was absolutely correct. :)

12:40 pure_loulou: hello :)

12:40 TimMc: &(empty (range))

12:40 lazybot: ⇒ ()

12:40 pure_loulou: do you know how to make '(1 2 3) to (1 2 3)

12:41 djwonk: pure_loulou: not sure what you mean. `(1 2 3) evaluates to (1 2 3)

12:41 i meant single tick, not `

12:42 TimMc: pure_loulou: What's this for?

12:42 pure_loulou: i know wait to ask better thx :)

12:42 macros is confusing... at first

12:43 djwonk: pure_loulou: you are making a macro?

12:43 mike_17: hi room, have a clarification in enlive. Is (h/select nodes [:a.link-rss]) and (h/select nodes [:a (h/attr= :class "link-rss")]) the same thing?

12:43 pure_loulou: yes

12:47 mike_17: I have a class with a name containing space, how can I select it using enlive - I tried some thing like (h/select nodes [:a (h/attr= :class "link rss")]) , but it doesn't work, do you guys know of any way to do it

12:48 djwonk: mike_17: I haven't used enlive

12:48 TimMc: mike_17: Classnames don't contain spaces. Try .link.rss

12:49 tomoj: if you had a data structure that implemented both IPersistentVector and IPersistentMap.. that would be bad?

12:49 djwonk: mike_17: right, you defined two classes, separated by a space

12:50 mike_17: any enlive experts here?

12:50 sorry didn't saw the response

12:51 djwonk: mike_17: just to clarify, in your HTML source, if you do class="link rss" you are really applying two CSS classes

12:51 tomoj: I guess it's just that people don't consider the case that (and (map? x) (vector? x)) when using map? and vector?

12:51 TimMc: tomoj: I think they're incompatible.

12:52 What happens if I (assoc ... 0 :whoops)?

12:52 djwonk: tomoj: do you want an ordered map?

12:52 tomoj: I have that, from flatland

12:52 djwonk: that preserves insertion order? some other kind of order?

12:52 tomoj: insertion order, yes

12:52 those can implement IPersistentStack

12:52 but they can't implement ITransientStack cus there isn't such a thing

12:53 pop! is in ITransientVector

12:53 but really, they _could_ implement IPersistentVector too, yes?

12:53 mike_17: TimMc: let me try that , djwonk: yes you are right - let me also see if there are ways to match two :class values

12:53 djwonk: mike_17: keep it simple if you can. match one unless you have to match two

12:54 tomoj: TimMc: assoc just calls .assoc, IPersistentVector also has .assocN

12:54 so the .assoc would expect keys, .assocN indices

12:54 dunno what would break

12:55 djwonk: tomoj: oh! you are using flatland. ok, well you are way ahead of me

12:55 tomoj: I just implemented IPersistentStack and then noticed the transients

12:56 admittedly I don't have any use case for pop! or IPersistentVector :)

12:58 TimMc: oh, right, someone might see (vector? x) and then assume they can sensibly (assoc x 0 :whoops)

12:58 since there's an informal correspondence between the assoc and assocN of a vector

12:58 and its ILookup and Indexed

12:59 at least there is nth there

12:59 why not assoc-nth?

13:00 because there were no data structures that could do both differently?

13:01 hyPiRion: tomoj: assoc-nth? How does that make sense?

13:01 mike_17: djwonk: I could select them by just using .rss class, however it selects all rss tags, I wanted to filter only the .rss class tags which contains "info" in their url , I am doing this - (h/select mcnodes [:a.rss (h/attr-contains :href "info")])

13:02 hyPiRion: Wouldn't assoc be enough? I mean, I can't think of any data structure where both assoc and assoc-nth would make sense.

13:02 mike_17: but it does it work, I could list all the :a.rss tags and see that some contains the string "info" in their url

13:03 is this the right way to use (h/attr-contains) ?

13:04 TimMc: Doubtful. Space-separated attributes like classes need special handling.

13:04 Have you tried :a.link.rss ?

13:06 mk: what does Compiler.load() do that Compiler.eval() does not?

13:07 djwonk: mike_17: I haven't used enlive but … what TimMc sounds worth trying

13:08 i see that [] in enlive means 'and' / intersection, so I'm sure you'll get it with some expermentation

13:09 the battery is low, so I'll see y'all later

13:09 tomoj: hyPiRion: uh. an ordered map. see above :)

13:09 mike_17: TimMc: : nope, I could just select all the :a tags with "rss" class as [:a.rss], now I have to filter only the links having "info" in the :href attribute ie < a href="../../info/xyz.asp" class="link rss"/>, I tried [:a.rss (h/attr-contains :href "info")] but it doesn't work

13:10 TimMc: mike_17: Did you try :a.link.rss as I suggested?

13:10 mike_17: let me try that as well

13:11 hyPiRion: tomoj: When is that practical? I can't currently see any semantics where it would be useful, but I'm open to suggestions

13:12 TimMc: Anderkent|away: OK, I think this is all I need for my own project -- does it work for your as well? https://github.com/timmc/arborist/blob/master/test/org/timmc/arborist_test.clj

13:15 mike_17: TimMc: man, it works, thx a lot... now I am filtering the nodes that only contain "info" in :href, I am doing this outside (h/select) at present using (filter #(re-find #"info"(:href (:attrs a)), is there a better way by including it as a part of selector itself?

13:15 TimMc: Not sure, I haven't played with Enlive in a bit.

13:17 mike_17: ok np

13:19 mk: what must I do to read and eval clojure from java?

13:21 I used Compiler.load(StringReader...), but this does not give me the form. Now I'm using LispReader.read(...), but this is giving me "Can't change/establish root binding of: *ns* with set"

13:22 Sorry, it's not load that throws that, but Compiler.eval(). I don't think I understand how and why thread-local is being used here

13:23 TimMc: mk: The goal is to read serialized Clojure data off of disk?

13:25 mk: I want a toy repl that can read a clojure file (or string) as if clojure was reading it itself

13:26 TimMc: Why aren't you using clojure's own REPL libs then?

13:26 mk: so for example, I don't want to be put into a user namespace, and I'd like it to handle (ns) properly

13:27 hyPiRion: mk: Reading the clojure repl implementation should help immensely

13:27 mk: TimMc: have not discovered them via google, I suppose

13:29 TimMc: mk: https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L186

13:29 mk: hyPiRion: I think I have it (Repl.java?), however it puts me in the user namespace and initializes the 123* variables

13:29 TimMc: And there's nREPL as well.

13:30 hyPiRion: mk: https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj

13:31 mk: I mean, what I want to try messing with in the end is loading a line form by form and inspecting what the objects look like in eclipse debug

13:32 I've been looking at http://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/Repl.java?r=1160

13:46 tomoj: when do you ever actually need to put nil in a map?

13:47 bbloom: tomoj: when nil means something :-P

13:47 Raynes: &(contains? {:foo nil} :foo)

13:47 lazybot: ⇒ true

13:47 Raynes: &(contains? {} :foo)

13:47 lazybot: ⇒ false

13:48 bbloom: i have a tree of maps that represents an index and sometimes an intermediate value in the index can be nil

13:52 mk: what is an unbound function?

13:53 TimMc: unbound var, you mean?

13:53 (declare foo) should do it.

14:23 tomoj: bbloom: ah, right, of course

14:24 it's great that you can't have a nil attribute value in datomic

14:34 TimMc: I want to map over the contents of a collection and give back something of the same type -- in the same order.

14:34 (Obviously sets and maps are exempt from that last bit.)

14:36 &(map #(into (empty %) (map inc %)) '[[0 1 2] (0 1 2)])

14:36 lazybot: ⇒ ([1 2 3] (3 2 1))

14:39 mk: TimMc: this is conj at work. You might look at the source at http://clojuredocs.org/clojure_core/clojure.core/into and see if you can get rid of conj

14:43 tomoj: &(map (partial clojure.walk/walk inc identity) [[1 2 3] '(1 2 3)])

14:43 lazybot: ⇒ ([2 3 4] (2 3 4))

14:43 mk: http://pastebin.com/TrxZpc9k "Attempting to call unbound fn". Why? This is java, but I'm just trying to replicate Compiler.load https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7031

14:47 what would it mean for the fn to be unbound in that case? It's defined after an (ns).

14:47 yogthos: tomoj: I think this would be better no? (clojure.walk/prewalk #(if (number? %) (inc %) %) [[1 2 3] '(1 2 3)])

14:48 mk: yogthos: no because you don't want it to be silent if you accidentally try to use it to increment strings, you want it to blow

14:48 yogthos: mk: ah

14:55 TimMc: I think I'll just bail on any sequential? that isn't a list? or a seq? -- client code can handle this itself.

14:55 (or a vector?)

14:55 Bronsa: coll?

14:55 clojurebot: seqs and colls is http://www.brainonfire.net/files/seqs-and-colls/main.html

15:02 mk: my issue was that LispReader reads forms one at a time: it read and evaluated the (ns) form, but did not read the (defn) form, so of course the function had not been bound when I tried invoke

15:11 amalloy: TimMc: clojure.walk/walk?

15:11 or use fmap

15:12 which is in old-contrib somewhere, and maybe ported to new?

15:12 TimMc: amalloy: clojure.walk didn't do what I wanted.

15:12 Anyway, I got it working.

15:13 ferd: I cannot make wrap-json-response (from ring-json) work with my compojure routes... A quick look tells me they might not be compatible, given that a Compojure route handler does a "render" at the end, and that happens before wrap-json-response. Am I missing something obvious?

15:14 amalloy: yes

15:14 render happens inside the heart of ring, long after all your handler code has happened - wrap-json has had plenty of time to work

15:17 ferd: you meant "render happens inside the heart of *compojure*" right?

15:21 amalloy: it might. i think it's ring, though

15:21 ferd: mind that I'm talking about the json *response*... wrap-json-body works find 'cause it handles the request before compojure

15:23 on the way back though, my compojure handler "renders" the response... so it messes with my clojure map before wrap-json-response gets a chance

15:24 weavejester: ferd: You need to do something like (response {:foo "bar"}) for it to work

15:24 Or {:body {:foo "bar"}}

15:25 ferd: weavejester: thanks will try

15:25 was thinking of a way to: (unextend-protocol Renderable APersistentMap) ;-)

15:27 weavejester: working, thanks agian

15:27 *again

15:28 weavejester: No problem

15:28 It's a little annoying to have to do (response {:foo "bar"}) instead of {:foo "bar"}

15:28 But without that you wouldn't be able to do redirects or any other kind of response.

15:29 And rather than guess what map is a response and what map isn't, it's better to just make sure the JSON map is in the response body

15:30 ferd: got it

15:33 actually... it's not working yet :-\

15:37 TimMc: Anderkent|away: I released [org.timmc/arborist "1.0.0"]. Let me know if you end up using it.

15:43 ferd: weavejester: found the problem... in some cases I'm returning a Seq... and wrap-json-response explicitly checks for vec? or map?. Why is that check in there?

15:43 weavejester: ferd: Because seqs already mean something in Ring.

15:45 ferd: :-(

15:47 gfredericks: what do seqs mean in ring?

15:47 weavejester: gfredericks: They're used for lazy responses

15:48 gfredericks: So if you specify a lazy seq as the body of a response, it will be streamed to the client as it is consumed.

15:49 ferd: weavejester: thanks again and again. looks like I might go back to my "to-json" function for response

15:49 gfredericks: so wrap-json-response tries to allow both json data structures and lazy other things

15:50 weavejester: gfredericks: wrap-json-response tries to play nice with base Ring, so it only interprets data structures in the body that have no meaning to Ring.

15:51 But thinking about it, perhaps I should make it an option instead.

15:51 Lazy seqs are not often used as response bodies, and one could just wrap the JSON middleware around a subset of routes.

15:53 ferd: weavejester: I like that

15:54 gfredericks: yeah, I don't like the idea of an API distinguishing between vectors and seqs if it can be avoided

15:56 c.c/rationalize seems like magic

15:57 bbloom: how do people ever do anything useful when all their data types don't have a sane notion of equality?

15:57 ferd: gfredericks: didn't know about it. Reminds me of old times with my hp48

15:57 gfredericks: I just don't know how it does what it does. I suppose the magic is in BigDecimal/valueOf

15:58 it must be a bunch of fudging

15:58 ,(rationalize (/ 1.0 3))

15:58 clojurebot: 3333333333333333/10000000000000000

15:58 gfredericks: ah ha nevermind it's not magic

15:58 Anderkent|away: TimMc: you don't want to use `list?` for code

15:58 ,(list? `(1 2 3))

15:58 clojurebot: false

16:00 Anderkent|away: other than that I'd have to think a bit whether using that would make my code cleaner :P

16:02 frozenlock: Just before I start coding, did anyone made the github-like next/back animation for clj/cljs? https://github.com/blog/760-the-tree-slider

16:04 TimMc: Anderkent: I check for both seq? and list?, actually.

16:09 Anderkent: Hm. Okay, I s'pose. I'd like it more if there was lazy-seq? and Cons'es were handled eagerly, but oh well

16:10 as to use for cloverage, after consideration I don't think there'd be much point - I'd find myself doing a transform on every step and manually calling the recursion.

16:18 TimMc: *nod*

16:19 gfredericks: TimMc: I expect seq? is always true when list? is true

16:19 at least for the normal types

16:20 TimMc: Interesting point about Cons vs. lazy-seq? -- I'll have to think about that.

16:38 pure_loulou: hello :)

16:42 (bindings [ x_from_macro value_from_macro ] ...) i tried to make it work but i had some problems

16:42 xybre: I'm seeing talk of JSdoc type hinting for a Clojure->JS compiler.. does this have anything to do with ClojureScript and the [#^String s] notation?

16:42 * xybre so lost right now

16:42 gfredericks: pure_loulou: maybe give a gist of an actual example?

16:43 pure_loulou: I can't tell what you mean from that line

16:43 pure_loulou: ok :)

16:43 i wanted to evaluate a random boolean formula like (and a b),with local vars

16:43 i didnt know the formula

16:44 gfredericks: you want to temporarily redefine a macro?

16:44 pure_loulou: i had problems doing it

16:45 i stuck i am newbie

16:45 gfredericks: lots of subtleties here; some context would help

16:45 ,(let [and +] (and 1 2 3))

16:45 clojurebot: 6

16:46 pure_loulou: i wanted to evaluate a random boolean formula,

16:47 so i used for the symbols local vars

16:47 and i macro to determine the random bindings

16:47 gfredericks: you have a formula like (and a b (or c d)) and you want to give a,b,c, and d random values?

16:48 pure_loulou: yes

16:48 xybre: (not= "Clojure Compiler for JS" "ClojureScript") => yes/no?

16:50 bbloom: xybre: yes, clojurescript is currently a subset of clojure

16:50 gfredericks: pure_loulou: well I imagine you can use the normal values of and/or; is this formula literally nothing but and, or, and variables?

16:50 bbloom: xybre: it's the runtime subset, specifically

16:50 pure_loulou: i wanted to evaluate a random formula,for random values

16:51 gfredericks: pure_loulou: I'm thinking wrapping the formula in a let where you assign the values, and then evaling it

16:51 first step is to figure out what variables it has

16:51 xybre: So, Clojure just has a source to source JS compiler?

16:52 pure_loulou: that will need a let difined from a macro i think

16:53 dynamic let

16:53 dnolen: xybre: yes

16:53 gfredericks: pure_loulou: you shouldn't need a macro if you're using eval directly; I'll have some code in a seond

16:54 pure_loulou: ok :)

16:54 xybre: Okay, that makes sense.

16:54 And the Clojure compiler has support for comments that alter code functionality like: /** @type {String} */?

16:55 dnolen: xybre: the missing non-concurrency related bits will likely get worked in as we head to towards optional bootstrapping.

16:56 bbloom: xybre: the cljs compiler emits a minimal set of Google Closure type hints, etc

16:56 gfredericks: pure_loulou: https://www.refheap.com/paste/8791

16:56 bbloom: xybre: basically only what's needed for compilation, like @constructor

16:56 gfredericks: pure_loulou: the eval approach assumes you don't have the formula until runtime. if you have it at codetime then presumably you could use a macro, yes

16:58 dnolen: xybre: there are no hooks for optional type checking via GClosure.

16:59 pure_loulou: gredericks thx alot i will read your code

16:59 gfredericks: pure_loulou: probably should have wrapped line 3 in distinct or set, but it shouldn't change how the code works

17:00 xybre: Thanks bbloom and dnolen, I can tell I need to read more, there's a lot going on that I'm not familiar with yet :)

17:01 bbloom: xybre: the cljs compiler code, despite being a bit messy, is actually quite straightforward and understandable. you can probably just jump right into to analayzer.clj and then take a look at compiler.clj

17:01 pure_loulou: i have some troubles with symbols like ' ` @ , but i started a week ago

17:01 thx i will retry

17:02 * xybre clones the clojure repo to take a look

17:03 bbloom: xybre: it's in the clojurescript repo

17:04 xybre: bbloom: oh I misread, but coincidentally I just cloned the clojurescript repo too

17:07 bbloom: i really like the signature of add-watch and remove-watch

17:07 (add-watch reference key fn) and (remove-watch reference key)

17:08 b/c most addListener things are basically key==fn

17:08 but ::foo or some meaningful key is just so much easier to remove later

17:08 the other option i like is having the listen function return the unlisten function

17:09 b/c then you don't need two bits of info to remove the listener

17:09 gfredericks: robert.hooke uses the key approach, but makes it optional; you can pass in the function itself to remove

17:10 the keyless version just defers to the keyed version with key==fn

17:10 bbloom: can you always do that? or only if you omit the key

17:10 yeah, that's what i thought

17:10 gfredericks: the only case I can recall of a function being used as a map key intentionally

17:11 bbloom: *shrug* i've done it a few times

17:51 technomancy: since you warned about signing up talks with unfinished code: i now consider it done-enough-to-release, but i'll permit it to continue baking until my talk :-)

17:54 gfredericks: bbloom: I intend to go the heck to that talk

17:55 bbloom: gfredericks: i'm glad people are interested :-)

18:05 seangrove: Just as a bit of a crazy whim, I'd like to be able to mark a function with metadata like ^:transparent/pure, and have the compiler give me warnings if I referenced any variables that weren't passed in as arguments (checking outside atoms, etc.) or if the function made function calls to other functions and didn't pass any arguments to it (probably relying on state)

18:06 Seems like that shouldn't be impossibly hard as a compiler pass in cljs if I'm able to load a module to analyze the AST info?

18:06 Just idly speculating, not likely to jump on this any time soon at all

18:07 gfredericks: seangrove: not caring about the false positives?

18:08 seangrove: gfredericks: False positives from what?

18:08 gfredericks: seangrove: e.g., calling functions that do rely on state even though you passed them arguments

18:09 your checks would say that's a pure thing to do even if it isn't

18:09 seangrove: Ah, yes

18:09 The metadata would be something like "please check this function for basic signs of not being X"

18:10 It'd be nice as a code style linter

18:12 amalloy: i think the difficulty of that problem is somewhere between "solving the halting problem" and "reimplementing clojure"

18:13 even a half-assed solution that barely works is going to be a lot harder than you thing

18:23 technomancy: amalloy: I bet typed clojure could do it with some tweaking

18:26 bbloom: the real issue is that consuming memory is a side effect ;-)

18:26 it's the whole thing with transients: if a tree falls in the forrest and whatnot

18:27 if i use an atom in my observably pure function, i don't want my function being marked impure

18:27 technomancy: easy enough to just allow for metadata to override inference errors

18:28 bbloom: sure

18:28 i've wondered what an "associative" type system would look like

18:28 rather than saying "the type of X is Y" it would be like "well, X implements method F and has linear runtime in terms of (count Y)"

18:29 but those facts also need to be labeled as inferred, asserted, or provable :-)

18:30 seems like an area of research for some codeq fans!

18:39 aaelony: hmmm, I'm processing large files and i'm tempted to use promises when I encounter incomplete lines. Typically, an incomplete line will have 2 or 3 lines that make it whole later in the lazy-seq, and at that point the promises would be realized and delivered. curious as to what people would suggest...

18:39 seangrove: bbloom: Well, it's be nice to know where I have implicit state I could (possibly) clean up

18:40 bbloom: aaelony: i recently discovered that this is what the haskell people call a "finite state transducer"

18:40 aaelony: https://github.com/brandonbloom/fipp/blob/master/src/bbloom/fipp/transduce.clj#L26-39

18:41 aaelony: bbloom: thanks, I'll look that up. I'm sure it's a fairly common problem, likely with some design pattern around it

18:41 awesome, thanks for the link :)

18:41 bbloom: that's with reducers, but it's even easier to do with a lazy seq

18:41 aaelony: I'll likely need reducers too

18:42 bbloom: so if you don't care about losing laziness, reduce into a vector

18:42 aaelony: I'm thinking of using partition-all on a large lazy-seq and wrapping each partition in a future

18:42 I'll look to match the incomplete only within a partition since the incompletes are relatively rare and the partitions will be large

18:43 bbloom: hmm, that'd be a good trick, then you just apply concat on those ?

18:43 aaelony: I don't know concat that well, but perhaps that's the angle I need...

18:44 bbloom: you could probably skip the futures all together if you buffer during transformation

18:44 amalloy: why would you wrap the partitions of partition-by in a future? they're not lazy

18:44 aaelony: basically applying a fancy regex to a string in each line, and further exploding information out

18:44 bbloom: that's what the "finite state transducer" is about. it's a map or reduce or similar transformation that proceeds linearly and preserves some state in the machinery of it... ie a buffer

18:44 aaelony: I'd like to parallelize as much as possible

18:45 …and make it as fast as possible

18:45 amalloy: so why not write (@(future +) @(future 10) @(future 9))? wrapping a value that's already computed in a future doesn't do you any good

18:46 aaelony: amalloy: not sure I understand what you mean. my thought was to wrap a function that does a bunch of stuff on a line or set of lines in a future

18:46 amalloy: you said, wrap each partition of partition-by in a future

18:47 aaelony: partition-all

18:47 amalloy: which sounds like you mean you want the partitions to be computed in a different thread

18:47 aaelony: yes, that's right

18:47 amalloy: if you have some function, which you want to run in parallel on a different thread per partition, that's fine and works

18:47 but computing the partitions themselves in a future is not possible

18:47 aaelony: the former

18:48 the only reason to partition at all is to get some leverage out of parallelization

18:49 bbloom: aaelony: make it work... THEN make it fast :-)

18:49 aaelony: I think I need partition-all because I don't want to lose the partitions that don't have all the elements in the last partition

18:50 bbloom: heheh, true. It's about half of both right now ;)

18:50 actually, quite fast, but need to add the processing of incompletes into the mix

18:51 i think its faster than hadoop, so far…

18:51 but haven't tested enough

18:57 rkz: anyone know how to get something like python's pdb.set_trace() to work? I tried (debug-repl) in a route handler but it doesn't pause execution

18:58 or general debugging in nrepl, cdt doesn't seem to work

19:05 scottj: rkz: maybe look at ritz

19:10 rkz: looks good

19:10 thanks

19:32 tomoj: &((juxt identity class) (gensym :foo))

19:34 djwonk: what's the clojure helper library for finding functions based on input and output?

19:38 Anderkent: djwonk: findfn

19:39 djwonk: Anderkent: right! thanks

19:59 majyk: I'm a Clojure n00b and I'm trying to write a naive directory tree walker using recur and I'm getting an error saying that recur is not in the tail position. I've Googled but I cannot figure out why what I've written is wrong. Can anyone help me? https://gist.github.com/4576052

20:00 I know there is support in clojure.java.io to assist in walking a directory tree but I'm trying to learn how to write a recursive function

20:00 bbloom: majyk: tail position does not mean "at the end of the function" it means that no evaluation occurs after it

20:00 in this case, that doseq wraps the recur

20:00 majyk: ah okay

20:01 bbloom: majyk: the purpose of recur is to have the compiler enforce that you won't use any stack space for a recursive or iterative algorithm

20:01 but in this case you DO want to use stack space: you need to come back to go on to the next branch of the walk

20:01 so instead of (recur file) you can (walk file) to get a non-tail-recursive algorithm

20:02 seangrove: Is there a function that given a hash-map and a list of keys, returns a new map identical to the original *except* for keys specified in the list?

20:02 Something like (without {:a 10 :b 100 :c 4 :d "a"} [:a :c :d]) => {:b 100}

20:03 majyk: bbloom, thank you. I'm going to try this

20:04 bbloom: majyk: if you want to learn about tail recursion, change your let statement to be a loop and include an explicit stack: (loop [stack '() f (File. dir)] ...)

20:04 majyk: then use recur with two arguments

20:04 majyk: bbloom, okay thank you. I'll dig into to this.

20:05 amalloy: seangrove: ...apply dissoc?

20:05 seangrove: ,(apply dissoc {:a 10 :b 100 :c 4 :d "a"} [:a :c :d])

20:05 clojurebot: {:b 100}

20:05 seangrove: amalloy: Err, sorry, that should've been pretty clear

20:07 and thanks

20:29 bbloom: the syntax of tagged literals just *feels wrong*... it's the only unary prefix operator that has a space between the operator and the operand

20:29 #foo/bar{:x 1} seems reasonable for maps, but #foo/bar :keyword just seems wrong

20:30 but that's not even valid tagged literal syntax for the map, since the lack of space implies it's a record

20:30 hmm i guess metadata is a unary operation.... ^:foo :bar

20:31 *shrug* still feels a tag weird

21:15 tomoj: throw+ is nuts

21:16 I never really experienced "if you do weird shit, unfamiliar people trying to read it will be very confused"

21:17 first thing I did in a port to ex-info was remove the +, then I tried to understand what was inside the throw+, forgetting about the +

21:20 bbloom: tomoj: slingshot?

21:21 tomoj: yeah

21:21 I just noticed it actually throws ExceptionInfo now

21:21 and that gets a map of the environment, which is neat

21:22 bbloom: tomoj: seems pretty odd to me that it has it's own pattern matching facility

21:22 tomoj: and that throw+ bundles format and sets up a binding for %

21:23 I guess you can just (throw+ map str) if you want

21:24 bbloom: i don't think a single one of my clojure projects ever catches an exception....

22:00 technomancy: bbloom: the plan at one point was to integrate core.match

22:00 it's not really pattern matching so much as a flexible predicate specification

22:00 but I agree that the ability to throw arbitrary objects is kinda nuts

22:01 bbloom: seems like one should just *always* throw a map and that all unnamespaced keys be reserved for use by the system

22:02 n_b: I'm getting a Java OutOfHeap error with the following code when attempting to partition the 'fna var: https://www.refheap.com/paste/8799 ; I assume that it's realising the entire file into a string that's causing it?

22:03 bbloom: n_b: how large is the file?

22:03 n_b: about ~3.5MB

22:03 bbloom: n_b: how large is your heap? :-)

22:04 but yeah, that's likely the issue... you're not just allocating 3.5MB

22:04 n_b: Yea, that's what I expected

22:04 bbloom: you're also allocating a string per line segment and then a sequence and some other junk

22:04 shouldn't be TOO big, but apparently it is

22:05 n_b: Really I'd like to write it in a way that's as lazy as possible

22:05 bbloom: check your heap size & if it's low, try setting the jvm-opts

22:05 amalloy: he's holding onto the head of the whole thing for no reason. you could easily do this totally lazily

22:05 bbloom: sorry, yeah dur, clearly amalloy is right (again)

22:05 n_b: just do it all within the the reader context, right amalloy?

22:05 amalloy: i don't know that i can write it just from looking at this code though, because find-open-frames is nonsense. what is it supposed to do?

22:05 yes

22:07 Bronsa: kjhlkjhl

22:07 whops. wrong buffer.

22:09 n_b: It's meant to find the long nucleotides within a genome, which are comprised of 3-char sequences and end when the pattern "TAA" is hit

22:10 so the input file is a very, very long sequence of strings like "CATTAAAGGACACGCT"

22:11 so this can be easily done recursively I suppose

22:19 amalloy: and each line's length is divisible by three?

22:44 alex_baranosky: technomancy: a site I've had up on Heroku for a long time, but which I haven't gone to in months doesn't seem to work anymore. Did something about Heroku change that would cause an old Noir site to no longer work?

23:11 technomancy: works fine now

23:11 must have been idling

23:12 ludston: .(range 0.1 1 0.1)

23:13 @(range 0.1 1 0.1)

23:13 &(range 0.1 1 0.1)

23:14 LazyBot is dead?

23:14 mattmoss: lazybot appears to be awol

23:15 ludston: ,(range 0.1 1 0.1)

23:15 clojurebot: (0.1 0.2 0.30000000000000004 0.4 0.5 ...)

23:15 mattmoss: Yay floating-point!

23:15 ludston: Is this a bug, or is that expected?

23:15 mattmoss: Maybe, and mayhaps?

23:16 mikera: expected

23:16 doubles can't express 0.3 exactly

23:16 mattmoss: Many numbers cannot be represented exactly in FP. 0.3 would appear to be one such

23:16 ,0.3

23:16 clojurebot: 0.3

23:16 mattmoss: ,(+ 0.1 0.2)

23:17 clojurebot: 0.30000000000000004

23:17 ludston: ,(= (range 0.1 0.4 0.1) '(0.1 0.2 0.3 0.4))

23:17 clojurebot: false

23:17 ludston: (= 0.3 (+ 0.1 0.2))

23:17 ,(= 0.3 (+ 0.1 0.2))

23:17 clojurebot: false

23:17 ludston: :(

23:17 mattmoss: Yeah, don't do that.

23:18 ludston: That's extremely annoying.

23:18 technomancy: floats are inexact

23:18 mattmoss: Floating-point operations will introduce rounding error.

23:19 technomancy: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

23:19 mattmoss: ,(< (- (+ 0.1 0.2) 0.3) 0.00001)

23:19 clojurebot: true

23:20 ludston: I get the theory behind it, but it's annoying that it's so easy to run into.

23:20 mattmoss: Easy to avoid, too.

23:20 ludston: ,(double 0.3)

23:20 clojurebot: 0.3

23:21 ludston: ,(double (+ 0.1 0.2))

23:21 clojurebot: 0.30000000000000004

23:21 mattmoss: ,(- (+ 0.1 0.2) 0.3)

23:21 clojurebot: 5.551115123125783E-17

23:21 xeqi: ,(range 0.1M 1 0.1)

23:21 clojurebot: (0.1M 0.2 0.30000000000000004 0.4 0.5 ...)

23:22 xeqi: ,(range 0.1M 1 0.1M)

23:22 clojurebot: (0.1M 0.2M 0.3M 0.4M 0.5M ...)

23:22 ludston: I guess I can live with it.

23:22 Thanks xeqi

23:23 mattmoss: ,(+ 0.1M 0.5M)

23:23 clojurebot: 0.6M

23:23 mattmoss: eh

23:23 xeqi: thats making them BigDecimal, so you'll lose speed but gain precision

23:24 mattmoss: And gain size, methinks?

23:26 ludston: mattmoss: size?

23:30 mikera: bigdecimals use quite a bit of memory IIRC

23:32 mattmoss: ludston: double is 8 bytes, bigdecimal is... ?

23:34 amalloy: bigdecimal is willing to use all the RAM and swap on your computer

23:34 mikera: variable, but probably at least 80 bytes

23:34 when you count the overhead of all the things it contains

23:36 amalloy: you're likely to be much better off just getting used to the various tradeoffs of floating points, ints, etc, rather than trying to pretend computers can do infinite-precision arithmetic

23:41 ludston: Common lisp can do infinite-precision arithmetic without any obvious drawback

23:41 gdev: okay

23:42 mattmoss: lolz no

23:43 technomancy: hehe

23:43 mattmoss: That's like saying I can shove the universe and a bag of chips into my CPU with no noticeable effect.

23:43 ChongLi: for some value of obvious I guess

23:43 technomancy: is that another way of saying they aren't up-front about the fact that it's much, much, slower?

23:43 ChongLi: if you aren't looking at the clock, the drawbacks are hard to see

23:44 mattmoss: Maybe clipers never work with floats, so they never notice? Don't know... never done clisp myself.

23:44 *clispers

23:44 ChongLi: wouldn't it be great if we had computers that could work on real numbers in constant time and space?

23:44 ahhh

23:45 mattmoss: We can dream...

23:45 amalloy: clisp> (float (/ 1 3)) ;;; 0.33333334

23:45 senorflor: Woot--just registered for Clojure/West and .cljs training! Will there be a swag-bag with instant infinite-precision arithmetic? I hear that's proposed for Java 8.

23:46 ludston: ChongLi: Real numbers in constant time and space, as in "104/105" with o(1) cpu?

23:46 mattmoss: Really? I need to be there.

23:46 ChongLi: ludston: as in pi with O(1)

23:46 technomancy: amalloy: [1] for certain values of infinite

23:46 mattmoss: The rational 104/105?

23:47 ludston: mattmoss: Yes

23:47 mattmoss: ,104/105

23:47 clojurebot: 104/105

23:47 mattmoss: Awesome.

23:47 Point being,... Not a great example to demonstrate the constant time of REALs with a RATIONAL.

23:48 See ChongLi ^^^

23:52 amalloy: rationals are real too :P

23:52 mattmoss: But... they're also... imaginary? o_O

23:53 * mattmoss collapses into a quantum cheeseburger joint.

23:54 * muhoo lights the quantum cheeseburger joint

23:54 mattmoss: Someone type pi!

23:54 ludston: pi

23:54 mattmoss: π

23:54 ChongLi: pi!

23:54 mattmoss: Oooo, pi factorial? Hmm.

23:54 ludston: I'm not sure you can do that...

23:54 xeqi: i

23:54 ChongLi: it's what he asked for!

23:55 mattmoss: That and a side of fries.

23:55 xeqi: √-1

23:57 mattmoss: Egads, that's north!

23:57 I should stop doing things after 10pm...

23:58 e^iπ + 1

23:58 ,exp

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

23:59 mattmoss: ,clojure.contrib.math/expt

23:59 clojurebot: #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.math, compiling:(NO_SOURCE_PATH:0)>

Logging service provided by n01se.net