#clojure log - Aug 22 2013

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

0:41 dissipate: can someone clarify the 'keywords' section of 'clojure programming' on page 14

0:42 why do namespaces matter for keywords? keywords are scoped to their respective maps, no?

0:44 SegFaultAX: dissipate: Keywords don't really have anything at all to do with maps other than they're commonly used as keys in them.

0:45 dissipate: SegFaultAX, but why do i care what namespace a keyword is in?

0:45 SegFaultAX, doesn't it only matter what i'm looking up the keyword in?

0:45 SegFaultAX: dissipate: Because that namespace might be useful when passing keywords across namespaces.

0:45 You can know where it has come from, for example.

0:46 dissipate: SegFaultAX, hmm, that seems odd to me

0:47 coming from a python background here, i've never thought of namespacing keywords in a dictionary. but perhaps i'm confused by this concept because keywords serve some greater purpose in Clojure?

0:47 SegFaultAX: dissipate: Unnamespaced keywords are by far the most common, but there are some interesting uses for namespaced keywords.

0:48 dissipate: Keywords don't have anything to do with maps.

0:48 Keywords are fast, atomic, interned string-like object whose primary operator is comparison (but they have some other interesting properties too)

0:50 dissipate: SegFaultAX, i see. i don't fully understand, but hopefully i'll figure it out by looking at later examples.

0:50 SegFaultAX: dissipate: Think of keywords as being like Python strings but with constant time comparison.

0:50 Like symbols in other languages.

0:51 dissipate: SegFaultAX, but things other than keywords can be keys in a map?

0:51 SegFaultAX: dissipate: All of clojure's built in data types can be used as keys

0:51 dissipate: They're all immutable

0:51 (Which has a similar property to being hashable in Python)

0:52 If I know the data structure can never change out from under me, I know that I can use it as a key without having to worry about needing to rebuild the hash table.

0:52 dissipate: SegFaultAX, sounds excellent.

0:52 SegFaultAX: dissipate: Very excellent!

0:53 technomancy: I don't know if keywords-as-strings is a great comparison. I like to think of them as first-class names.

0:54 SegFaultAX: I only said they were string like. Which they are, even at an implementation level. (Same goes for symbols)

0:54 And in Python, there is nothing similar, so the analogy stands I guess.

0:54 But generally I agree.

0:55 technomancy: they're string-like only insofar as their printable representation, but that's just an affordance for humans

0:55 dissipate: SegFaultAX, so an atom can be a key in a hash in Clojure?

0:55 SegFaultAX: dissipate: A keyword you mean?

0:56 dissipate: /All/ clojure data structures can be used as keys in hash maps.

0:56 dissipate: SegFaultAX, ok, but i thought that atoms were mutable through some kind of transaction?

0:56 technomancy: all java objects, really

0:57 dissipate: clojure will let you do it, but that doesn't mean you should

0:57 SegFaultAX: dissipate: So you do mean atoms, yea there are some complications there. Don't worry about it for now.

0:57 (inc technomancy)

0:57 lazybot: ⇒ 71

0:58 technomancy: ,(let [a1 (atom :a) a2 (atom :a)] (assoc {a1 1} a2 1))

0:58 clojurebot: {#<Atom@dbbb9f: :a> 1, #<Atom@1fac636: :a> 1}

0:58 dissipate: technomancy, so what happens if i say assign an integer to an atom, use the atom as a key in a hash map, then increment the integer?

0:58 technomancy: ^^

0:58 the value inside the atom isn't a factor in how it's used as a has key

0:59 dissipate: technomancy, but this is frowned upon?

0:59 SegFaultAX: dissipate: Yes.

1:00 dissipate: i can understand that

1:00 mutable objects in python can be keys in dictionaries because python uses the id of the object as the key

1:00 technomancy: you can't have meaningful equality between mutable objects

1:00 SegFaultAX: Cannot*

1:00 technomancy: other than "are these the same location in memory?"

1:01 dissipate: technomancy, right, but you can id an object

1:01 or come up with some ad hoc way of defining equality

1:01 SegFaultAX: dissipate: But that's lame. We'd prefer to define equality of structure, not identity.

1:01 technomancy: dissipate: sure; that's how clojure defines = on anything mutable

1:01 based on its id, not its value

1:02 SegFaultAX: Mmhmm

1:02 technomancy: ~equal rights for functional objects

1:02 clojurebot: excusez-moi

1:02 technomancy: ~egal

1:02 clojurebot: egal is http://home.pipeline.com/~hbaker1/ObjectIdentity.html

1:03 technomancy: ^ that paper covers the logic behind equality

1:03 dissipate: SegFaultAX, technomancy, thanks for the info

1:03 SegFaultAX: dissipate: Anyway the point is that *all of clojure data structures can be used as keys in a map* but for some of them that really makes very little sense.

1:04 technomancy: np

1:04 SegFaultAX: np

1:05 dissipate: SegFaultAX, i see. this whole immutability thing has me drooling. but i can tell that learning clojure is going to be quite a bit of work.

1:07 SegFaultAX: dissipate: Even if you don't use Clojure professionally, it's an amazing language to know and understand.

1:07 dissipate: It can rather dramatically change the way you analyze and reason about programming.

1:08 dissipate: SegFaultAX, i want to use it professionally, but i think that it's going to take me quite awhile to get to that point. :O

1:08 SegFaultAX: I generally think most people would benefit in learning at least 1 functional programming language if they generally work in more imperative languages and vice versa.

1:09 dissipate: SegFaultAX, after reading 'Out of the Tar Pit' and watching videos on the advantages of Clojure, i'm convinced it's a much better language than the 'mainstream' languages

1:10 SegFaultAX: dissipate: Nothing is perfect.

1:11 technomancy: faint praise =)

1:11 dissipate: SegFaultAX, of course not, but side effects are bad and i'm excited to get rid of them as much as i can.

1:12 technomancy: in the #emacs channel there is literally a "faint praise" bot command that says "well, at least it's better than Java"

1:12 dissipate: hehe, Java...

1:12 SegFaultAX: dissipate: Well if you're only interested in purity, Clojure is hardly the best choice.

1:12 dissipate: oh how i am glad i have been able to avoid Java

1:13 SegFaultAX, are you referring to Haskell?

1:13 SegFaultAX: dissipate: I'm referring to many languages that are far less side-effecting than Clojure. Haskell is among them.

1:13 technomancy: Haskell is for hippies; Coq is the path of purity.

1:13 brehaut: technomancy: agda!

1:13 SegFaultAX: Amen.

1:14 dissipate: SegFaultAX, i don't want to completely eliminate side effects. i realize it is quite difficult to program purely functionally for all applications. but if the side effects are controlled say through STM, that's good enough for me.

1:15 technomancy: STM use is actually very rare in clojure

1:15 SegFaultAX: dissipate: Remember that you're running on the JVM (or js in the case of clojurescript) and it's very easy to escape Clojure's limited purity.

1:15 technomancy: it's more that side-effects stand out a lot more

1:15 SegFaultAX: If you're using Java libraries, you're doing it all the time.

1:16 Yup, what technomancy said.

1:17 dissipate: SegFaultAX, how often does that bite you?

1:18 SegFaultAX: dissipate: Me personally? Not often. Most of the Java libraries I interface with are specifically designed to interop with Clojure and so those side effects are hidden from me.

1:18 That doesn't mean they aren't there, though. :)

1:18 dissipate: SegFaultAX, BTW, Haskell seems like a good language as well, but it's not homoiconic and i have heard that certain things with its atoms are quite complicated

1:19 noidi: it's funny, the world at large seems to see Clojure as being about the STM, but the more you program in Clojure, the less you seem to use the reference types

1:19 and especially the coordinated ones

1:19 at least that's my experience

1:19 holo: dissipate, this may sound vain, but it's true for me. one of the things i find less time consuming in functional programming is i spend much less time naming stuff like intermediary vars ^^

1:20 dissipate: noidi, well, it's good to know that noobs can fall back on STM

1:23 holo: i'm testing a ^:private def, and I can't get it to eval. #'myns/my-def => vector? throws: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Var

1:24 how do you test your private vars?

1:25 brehaut: you dont make them private, or you varquote them

1:25 SegFaultAX: noidi: My experience has been largely the same. When I have needed reference types though, they've been amazingly useful.

1:26 holo: brehaut, isn't what i just paste above called varquoting?

1:26 brehaut: it is

1:28 holo: brehaut, it doesn't eval to an ISeq like it would if it was public. that's why i was asking how to make it eval

1:28 brehaut: no of course not, it evals to a var

1:29 holo: brehaut, is there any way to make it eval to an ISeq?

1:29 brehaut: dereference it

1:29 ,clojure.core/is-annotation?

1:29 clojurebot: #<CompilerException java.lang.IllegalStateException: var: clojure.core/is-annotation? is not public, compiling:(NO_SOURCE_PATH:0:0)>

1:29 brehaut: ,#'clojure.core/is-annotation?

1:29 clojurebot: #'clojure.core/is-annotation?

1:29 brehaut: ,@#'clojure.core/is-annotation?

1:29 clojurebot: #<core$is_annotation_QMARK_ clojure.core$is_annotation_QMARK_@1348b49>

1:30 holo: oh! damm it!! i have that in another project.. heh completely forgot that

1:30 brehaut thanks

1:32 dissipate: SegFaultAX, do you use java.util.regex?

1:32 SegFaultAX: dissipate: Sure.

1:32 dissipate: #"" is the Clojure literal.

1:36 callen: dissipate: hello again.

1:37 dissipate: callen, hello

1:37 callen: dissipate: why the change?

1:38 dissipate: callen, the change to clojure?

1:47 seancorfield: ,(re-seq #"[aeiou]." "java.util.regex")

1:47 clojurebot: ("av" "a." "ut" "il" "eg" ...)

1:47 seancorfield: :)

1:50 rhg135: Any idea how to do this https://www.refheap.com/17926 I'm trying to map a function to a certain map key at compile time

1:59 noidi: rhg135, (1) your returning a quoted hash-map call, so the hash-map will be built at run-time, not compile-time, (2) doseq is used for side-effects and returns nil

2:00 rhg135: Right..

2:00 So how could I?

2:01 noidi: wait a sec and I'll whip up an example

2:01 rhg135: I don't like writing macros

2:01 Always problematic

2:04 noidi: rhg135, you should first try to come up with a function that does what you want at runtime

2:04 and only then wrap it in a macro to move the evaluation to compile time

2:04 rhg135: Ok

2:04 Lemme try

2:07 noidi: rhg135, https://www.refheap.com/17927

2:09 rhg135: Any reasons for eval

2:09 ?

2:10 noidi: otherwise km would contain the symbol 'clojure.core/inc instead of the `inc`function

2:10 ('inc 123)

2:10 ,('inc 123)

2:10 clojurebot: nil

2:10 noidi: wat

2:11 ah, symbols are functions that look themselves up in the map given as an argument, or return nil if the input is not a map

2:11 that's confusing as hell

2:13 technically you could skip eval for m if it only has literal values

2:13 rhg135: K,just it kind of hurts to see eval now

2:14 So ingrained lol

2:20 noidi: rhg135, it's all eval'd sooner or later anyway :)

2:20 rhg135: Ik

2:21 Ill use it

2:24 How about instead taking a map followed by kv pairs?

2:25 noidi: rhg135, then just change the arglists from [m km] to [m & {:as km}]

2:26 rhg135: I did and got null

2:28 noidi: rhg135, ah, sorry, change the _macro's_ arglist to that

2:28 rhg135: I did

2:28 noidi: this works for me https://www.refheap.com/17929

2:29 if you change the function's arglist as well, you won't be able to just call it with the map that the macro receives (because it's expecting key value pairs and not a map)

2:30 rhg135: Ah

2:30 SegFaultAX: That code is horrifying.

2:30 rhg135: Can you show how you called it?

2:31 noidi: rhg135, (apply-to-map {:foo 1, :bar 2} :foo inc, :bar #(* 2 %)) ;= {:foo 2, :bar 4}

2:32 SegFaultAX, how would you do it?

2:32 SegFaultAX: noidi: Why does it need to happen at compile time?

2:32 rhg135: Slow computers :(

2:33 noidi: SegFaultAX, I don't know: [08:29] < rhg135> Any idea how to do this https://www.refheap.com/17926 I'm trying to map a function to a certain map key at compile time

2:33 SegFaultAX: :(

2:33 rhg135: I compile it on a way faster one

2:34 SegFaultAX: If your target machine is so slow it can't run a few basic functions, you need to re-evaluate your hardware ;)

2:34 rhg135: It's not my he, it's my target

2:34 Mobile devices

2:35 Not phones

2:35 Slower

2:38 noidi: my bad it does work

2:40 SegFaultAX is right, functions are better and if its too slow too bad

2:44 No, I meant I want it to produce ex (hash-map :key (f value))

2:45 SegFaultAX: (defmacro apply-map [m & {:as km}] `(-> ~m ~@(for [[k v] km] `(update-in [~k] ~v))))

2:47 rhg135: ?

2:47 SegFaultAX: rhg135: You asked how I'd do it.

2:47 rhg135: I didn't

2:47 SegFaultAX: Oh, maybe noidi did

2:47 rhg135: He did

2:48 SegFaultAX: Anyway, no eval necessary.

2:49 rhg135: Uh

2:49 LONGER=more code

2:49 More complex

2:50 SegFaultAX: I don't think so.

2:51 It turns (apply-map M :k1 f1 :k2 f2) into (-> M (update-in [:k1] f1) (update-in [:k2] f2))

2:51 rhg135: But I asked the wrong q.

2:51 :/

2:52 SegFaultAX: rhg135: Oh what was the original problem statement?

2:52 I thought it was something like that.

2:53 rhg135: No, I meant I want it to produce ex (hash-map :key (f value))

2:53 SegFaultAX: Oh that's way less fun. :(

2:54 rhg135: Same args

2:54 SegFaultAX: noidi: Anyway ^

2:57 noidi: SegFaultAX, those updates are not evaluated at compile time

3:01 SegFaultAX: noidi: Then drop the outer ` if that's what you want.

3:01 But Ew. ;)

3:03 Oh well I guess that won't work. But anyway, you get the idea.

3:10 rhg135: I know it's unusual, that's why I am stuck

3:16 ordnungswidrig: moin alle

3:39 supersym: github died?

3:40 rhg135: Again?

3:40 Raynes: It went down like thunder this time.

3:41 I can't even push.

3:42 The status page should really just have a picture of http://th01.deviantart.net/fs71/PRE/f/2010/142/b/2/Molten_Planet_by_Cushendun.png right now.

3:45 supersym: hehe

3:46 well a canyon at least is somewhat appropriate

3:46 rhg135: Yup

3:47 glosoli: Hey folks I am using httpkit with ring and compojure, any suggestions how could I server byte array from database as pdf ?

3:48 supersym: doesn

3:48 damn cat...

3:48 doesn't clj-pdf do something in that direction too?

3:49 Raynes: supersym: http://www.youtube.com/watch?v=mXPeLctgvQI

3:49 supersym: can't check... except google returns since github is dead :D

3:50 glosoli: dam n github is down

3:50 again

3:50 supersym: Raynes: long time since I've seen that movie,...great fun tho

3:56 Raynes: It returns!

7:23 supersym: damn..pedestal is a tough cookie now and then

7:23 so many nested colls make me dizzy ><

7:35 ker2x: http://www.youtube.com/watch?v=2WLgzCkhN2g this video is super awsome

7:35 you probably saw it already, it's on clojuretv

7:39 clojure is slowly coming to my workplace

7:40 vijaykiran: ker2x: where's your workspace ?

7:40 ker2x: ebuzzing, in france

7:41 well, the technical staff is in france

7:41 vijaykiran: cool

7:41 glosoli: Hmm how does one make a collection of strings that could be inserted in Postgres as varchars array

7:46 Anderkent: glosoli: depends on what API you're using. On the jdbc level it's `(.createArrayOf sql-connection "varchar" string-array)`, then put that into a query

7:46 with something that abstracts higher you might have to fall back on raw string queries if there's no array api

7:47 glosoli: Anderkent: thanks sir, that's exactly what I needed

8:08 ker2x: anyone use online mind mapper ? any suggestion ?

8:17 noncom: how do i make my function so that i could introduce arbitrary previously undefined symbols in its call? Like (ns) and (let) forms allow for passing and writing symbols that don't trigger the compiler's "unknown symbol" error?

8:18 hyPiRion: noncom: that would require a macro, not a function

8:18 noncom: so it is only possible for a macro?

8:18 hyPiRion: yes

8:18 noncom: and i could pass such symbols to any macro i define?

8:19 hyPiRion: yes

8:19 noncom: ok, thank you. that thing was really bugging me for some time..

8:19 hyPiRion: but use macros sparsingly, and only if you have to

8:19 (They're bug introducers)

8:20 noncom: yes, i try to avoid them and if i have to use them, i try them to be one-liners or something simple

8:20 macros are err*r-porne because of the humans not able to think well?

8:21 i mean, is there anything wrong with the compiler? like in scala they do not recommend extending case classes simply because compiler bugs on it and they not gonna fix it

8:22 Anderkent: they're just harder to write correctly

8:22 and the compiler is not that good at telling you what exactly is wrong with your macro

8:22 also they give you more power, which you usually don't need, and are harder to reason about

8:23 noncom: well at least the compier does not bug on them.. very good! and yes, i totally understand that about reasoning and unforseeing stuff.. it could become like C #defines hell

8:23 hyPiRion: noncom: well, mostly because of humans, but also because, as Anderkent said, the compiler can't give good feedback whenever you've misused one

8:24 The compiler can't (unfortunately) infer what you want to do and just say you need to fix X or Y.

8:26 noncom: during runtime, can i get something similar to macros by forging clojure forms by assembling `(list)s of symbols?

8:26 (just a theoretical interest, i not gonna do that i think :)

8:27 emil0r: i have a small problem with the clojurescript compiler (using cljsbuild). i seemingly can't use hashmaps. the code generated is cljs.core.PersistentArrayMap.fromArray(["\uFDD0:id","\uFDD0:blah"], true) and throws an error. any obvious mistake I have made?

8:28 noncom: emil0r: there should be no such problem. can you post a refheap with your code?

8:28 hyPiRion: noncom: eval

8:29 but do that on your own risk (both perf. and security wise)

8:29 noncom: emil0r: my best guess is that you mix js and clojurescript datastruct types. they are different afaik and there are cljs->js and js->cljs core funcs in cljs

8:30 but httwo seeing the code

8:30 Anderkent: Does anyone understand how to interpret jvm memory usage? I have newrelic graphs showing 'used heap' at 200MB, but 'comitted heap' growing up to 600mb for no apparent reason. (it's a problem because heroku)

8:31 noncom: eval is like a gun. it is good to know you have it, but actualy using it is something to consider really well

8:31 emil0r: http://pastebin.com/PynsSDcr

8:31 noncom: i'm just doing an eval on {:id :blah}

8:31 that's it

8:32 .fromArrays work though

8:33 in so far that it gives something back :)

8:34 noncom: emil0r: hmmm.. never used eval in cljs for that. if you want to read a datastruct from a string i would consider utilizing the edn reader... idk if it is avail for cljs.. or try js->cljs ?

8:35 emil0r: i came across the problem when i tried to use crate.core/html. such as (crate.core/html [:p.woot {:id :blah} "Hey"])

8:36 used cljsbuild before and never had a problem, so i'm stumped

8:36 and crate

8:36 noncom: Anderkent: http://stackoverflow.com/questions/206847/exact-state-of-committed-memory-in-java and http://stackoverflow.com/questions/14642962/high-committed-memory-but-small-heap-size

8:37 the latter one is for .net but maybe relates...

8:38 http://stackoverflow.com/questions/10357611/what-is-tomcat-memory-heap-committed

8:38 Anderkent: yeah, I know what it is (thanks to these links in part), what I'm looking for is someone who understands why it's so high - i'm running jvm with -Xmx320m, it really shouldnt ever need a 600mb heap

8:38 noncom: no real good explanatioonthough

8:40 Anderkent: does your app use NIO buffers or JNI?

8:40 Anderkent: whatever jetty uses :D I doubt that's where the problem is. Why?

8:41 noncom: sometimes the underlying native resources or buffers don't get released and litter the memory. i witnessed that problem 2-o-times

8:41 Anderkent: right. But that would show in physical (non-jvm-managed) memory, not the committed heap.

8:41 good thinking though :P

8:42 hyPiRion: yeah, that shouldn't kill the heap

8:42 Anderkent: it's not even that the heap is dying

8:42 it's just that it's using 700mb of physical memory while only using 200 out of 650 for the heap

8:42 hyPiRion: well, then I am completely right then

8:42 :p

8:42 Anderkent: and heroku doesnt like it if you eat its memory

8:43 hyPiRion: oh right, that's because of the JVM itself. The JVM likes to eat memory, but not free it up once it doesn't need it anymore.

8:43 noncom: and if you run that on your computer? same readings? can you factor out what parts of the program cause the rise?

8:43 Anderkent: yeah. Do you know if there's any way of telling it 'never grab more than X physical memory'?

8:43 other than trying to trick it into thinking there's only 500mb on the machine, I guess

8:43 Ember-: -Xmx=512 or something like that

8:44 Anderkent: nah, that's only for the actual heap, and I already have -Xmx=320m

8:44 hyPiRion: Ember-: that was what he tried to do, afaik

8:44 Ember-: check java command line arguments

8:44 Anderkent: it's still committing 600mb for the heap

8:44 but never letting it use more than 320 out of that :P

8:44 the problem is heroku doesnt care if the OS is overcommitting and not actually using any extra physical memory

8:45 Ember-: -XX:MaxDirectMemorySize=256M mayve?

8:45 maybe

8:45 noncom: is there the same problem on your PC?

8:45 Anderkent: ah! that sounds right

8:45 noncom: hard to say, i couldnt reproduce that easily

8:45 Ember-: hmm, doesn't look like correct

8:46 hyPiRion: Anderkent: well yeah, it's not exactly overcommitting. The JVM will use that space, and no other program can

8:46 noncom: if direct memory adjustment helps, then you have some memory leak either in NIO or JNI

8:46 Ember-: yeah, that isn't the correct config

8:46 Anderkent: hyPiRion: if the os is overcommitting, then the jvm will think it can use that space, but no actual pages will be allocated until it tries

8:46 noncom: I don't think it actually *uses* that memory

8:46 hyPiRion: hrm.

8:46 Ember-: that seems to affect how much memory native code ran from java can use memory

8:46 and I can't write

8:47 anyways, code with 'native' keyword

8:47 Anderkent: right

8:47 Ember-: how about MaxPermSize ?

8:47 Anderkent: that's only for the perm gen

8:47 Ember-: yes

8:48 I know

8:48 noncom: maybe heroku have their own options for the jvm screwed up?

8:48 Ember-: java normally gives up the memory if OS asks it do so

8:48 if it is not using it that is

8:48 but at heroku what you said this isn't happening

8:48 hyPiRion: I'd probably just ulimit it. That's the easy way.

8:48 Anderkent: alas, the OS will not ask it to, because it thinks it has 1.5G of space... but 1G of that is terribly slow swap

8:48 Ember-: wierd stuff

8:49 ah, well swap :)

8:49 I'm too used to having 8 or 16 gigs of mem :P

8:49 Anderkent: hyPiRion: ulimit -m doesnt work on ubuntu I think, and -v is not what I want

8:50 I can't use -v because jvm allocates a *lot* of virtual memory that's never actually physically accessed

8:51 hyPiRion: hrm, add in -Xss512k and check what happens

8:51 (reduces stack sizes)

8:52 Anderkent: already did that. But again I don't think that takes space from the heap pool

8:52 my overhead on top of heap is ~120mb or so, which is totally fine.

8:52 hyPiRion: hrmm

8:52 * hyPiRion gives up.

8:52 Anderkent: yeah :P

8:52 hyPiRion: I've tried to fix that earlier, and I always struggle with it

8:53 noncom: last post: https://forums.oracle.com/thread/2236644

8:54 all point to that being an anomaly though

8:54 Anderkent: thanks anyway :)_

8:55 noncom: maybe you could also make some use of this: http://download.java.net/jdk7/archive/b123/docs/api/java/lang/management/MemoryUsage.html

8:55 Anderkent: I guess this is the point where I fetch openjdk sources

8:55 noncom: ooh.. that should be a big load

8:58 fbernier: Hey, I hacked my first "real-world" Clojure project yesterday. If anyone have some time to give feedback on the code/style/whatever it would be nice.

8:58 https://github.com/fbernier/taz-clj

9:00 mdrogalis: Pretty good fbernier

9:00 Probably don't need to type-hint so much, but good stuff.

9:01 fbernier: mdrogalis: Thanks, I think I type-hinted only what "lein check" was complaining about though.

9:02 mdrogalis: I've never heard of Lein check. What's it do?

9:02 ordnungswidrig: fbernier: very good. I'd suggest that convert-to-image would return a lazy seq of images to avoid repeated loading and parsing of the pdy

9:02 ...of the pdf

9:02 fbernier: mdrogalis: "Check syntax and warn on reflection."

9:03 mdrogalis: I see. Nice.

9:05 ordnungswidrig: fbernier: in converter.clj like that (map #(.convertToImage (.. document getDocumentCatalog getAllPages (get %))) (range (.getNumberOfPages document))

9:05 fbernier: ordnungswidrig: For now it serves one image for one HTTP request ... so I open the file, render a single page, and close it. I'd need to keep the PDF in memory whithout really knowing if another HTTP request for this HTTP request will come any time soon.

9:06 ordnungswidrig: fbernier: ah, I see.

9:06 fbernier: but suggestions on improving this are welcome.

9:06 for this PDF*

9:11 ciphergoth: Clojure "promises" don't have a "then" method yet, right? http://dev.clojure.org/display/design/Promises

9:12 is there a way to achieve the same thing I'm not seeing?

9:12 iwo: hey, does anyone know an alternative strategy to with-redefs that could be used safely in an application?

9:12 stuartsierra: ciphergoth: That's correct, promises do not currently support callbacks.

9:12 core.async offers an alternative way to achieve that.

9:12 iwo: i notice that with-redefs is not thread-local, but i'm using it to dynamically re-bind a function that i need to customize

9:13 the fact that the rebind is global (not thread-local) makes me reticent to use it in production

9:13 mpenet: ciphergoth: also look at lamina result-channel (probably closer to what you are looking for)

9:13 ciphergoth: well since I'm using alpha that seems plausible!

9:13 iwo: but since the var is not dynamic, i'm unsure if there's any way to customize the behaviour without with-redefs

9:14 stuartsierra: iwo: There isn't.

9:15 ciphergoth: Lamina channels seem pretty different from promises!

9:16 mpenet: result-channels are essentialy promises

9:16 not channels

9:18 ciphergoth: mpenet: ah OK! I found this page, bit it wasn't as helpful as I'd hoped... https://github.com/ztellman/lamina/wiki/Result-Channels

9:18 mpenet: yeah I know, it vanished

9:18 :/

9:49 zapu: I'm trying to learn clojure and I'm playing with 'resolve' right now. (resolve (symbol ".toString")) doesnt work for me, I suspect member access might be somewhat special. What am I missing?

9:49 klrr: any recommendation of a book ? got some FP experience

9:50 stuartsierra: zapu: Yes, resolve only works on Vars and classes, not methods.

9:50 Java methods are not first-class objects.

9:50 zapu: oh, I see

9:50 yeah, that would make sense. but I can pass them around wrapped in anonymous functions if I ever need to, right?

9:51 Ember-: in java 8 btw that is going to change, after java 8 methods are first class and can be referenced directly

9:51 which is nice

9:51 stuartsierra: zapu: yes, to pass methods as arguments you have to wrap them in Clojure functions.

9:51 hyPiRion: is that a JVM change or Java change?

9:51 Anderkent: zapu: you can also just use memfn to pass around a method call: (map (memfn toString) objects)

9:51 Ember-: hyPiRion: imho jvm

9:51 zapu: thank you :)

9:52 Ember-: because it would be inefficient otherwise

9:52 RiGGeR: it will have to result in a jvm change, too

9:52 stuartsierra: memfn is slightly deprecated in favor of #(.toString %)

9:52 Ember-: anyway, with java 8 you write stuff like myList.filter(Something#uberMethod);

9:53 you -> can <- write

9:53 should help clojure's java interop too

9:53 hyPiRion: Hm, that could speed up aot compiled code with type annotations I guess

9:53 Ember-: too bad they pushed the release of java 8 to 2014

9:54 chrisrossi: so in java 8 you can do? method = someObject.someMethod

9:54 result = method()

9:54 ?

9:54 Ember-: hmm, of *that* I'm not 100% certain

9:54 klrr: should i use openJDK or oracle JVM?

9:55 Ember-: would have to check with current beta build

9:55 anyway, method references are ok

9:55 stuartsierra: klrr: Not that much difference as of JDK 7.

9:55 RiGGeR: http://www.jcp.org/en/jsr/detail?id=337

9:56 klrr: okey, which is quickest to install on ubuntu?

9:56 Ember-: having to write java in this project since customer explicitly said NO for clojure :/

9:56 ToxicFrog: klrr: IMO, whichever's easier to install. I've been using openjdk without trouble.

9:56 Ember-: really missing clojure

9:56 ToxicFrog: klrr: openjdk, definitely.

9:56 klrr: okey

9:56 blrm: klrr: openjdk should be in the ubuntu repos

9:57 hyPiRion: should actually be installed on ubuntu by default, isn't that the case?

9:57 klrr: is the package called "openjdk", also, do i need any other packages?

9:57 RiGGeR: and you don't have to login to oracle to dl

9:57 manutter: sudo apt-get install openjdk-7-jdk

9:57 Just did that myself the other day

9:57 Anderkent: klrr: just watch out for ubuntus fucks up around openjdk. If you're gonna use ssl from java, you want to fix https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776

9:57 ToxicFrog: "openjdk-7-jdk" is the package you want, then just run lein and it'll grab the other stuff it needs (clojure etc) as needed.

9:58 blrm: hyPiRion: might just have a jre by default?

9:58 hyPiRion: blrm: ah

9:58 klrr: Anderkent: thanks for pointing out

9:58 hyPiRion: might have to do `sudo update-alternatives --config java`, then

10:00 klrr: got it installed now, was much easier than i expected

10:00 well

10:01 Anderkent: yeah, having a package manager is a real boon

10:01 looking at you osx

10:01 klrr: at least i got repl running

10:01 Anderkent: klrr: from that point onwards everything should be handled by lein for you, assuming pure jvm dependencies

10:02 klrr: i got lein installed

10:02 hyPiRion: then life is good and you got everything (except an editor, maybe)

10:02 klrr: how do i make so that lein can find clojure?

10:03 Anderkent: klrr: lein includes clojure in its uberjar, so you shouldnt have to do anything

10:04 if you mean for your projects, you specify which version of clojure you want in project.clj, and lein automagically gives it to you

10:04 ToxicFrog: klrr: it should do it automatically. All you need is a JVM and a net connection.

10:04 hyPiRion: and downloads other clojure versions if you specify those in the dependencies

10:04 Anderkent: (to get a project.clj do `lein new project-name`)

10:04 klrr: okey

10:04 then it was clojure sources i downloaded xD

10:04 ToxicFrog: Yeah, you should never* be installing clojure by hand. Let lein handle it.

10:04 klrr: coming from haskell that works differently since its distributed as a compiler

10:04 ToxicFrog: *rarely, and definitely not when starting out

10:05 Anderkent: yeah, the lein/maven ecosystem takes a bit of time to get used to, but the benefits are great

10:07 klrr: so how does stuff work? in haskell you basically compile stuff using the compiler, and that's it, then it ofc got cabal which is built around that, and the repl exist too. but in clojure i did not install a compiler yet, or is it what i got from lein? how do i use the compiler?

10:08 hyPiRion: klrr: Clojure is a Java library, so all you need is a Java version to run Clojure. Lein handles compiling for you

10:08 blrm: klrr: clojure is basically a library, so when you make a new project with lein, it adds the library as a dependency to the project for you.

10:09 hyPiRion: If you want to create an application, you can do `lein new app my-app`, then `cd my-app`. To build into a standalone, do `lein uberjar` (runs it with `java -jar target/my-app-0.1.0-SNAPSHOT-standalone.jar`)

10:09 blrm: klrr: running "lein new foobar" will create a clojure project. cd into that and run lein repl, and boom

10:09 hyPiRion: Yes, you can change the name of the standalone.

10:09 klrr: okey

10:09 thanks :)

10:10 hyPiRion: klrr: and if you hit any problems, we'll still be here :)

10:10 stuartsierra: Clojure is not a platform in and of itself, it uses the Java platform. This sets it apart from languages like Haskell which are their own platforms.

10:12 klrr: so, theoratically clojure could use for example haskell and GHC as its platform? :D

10:13 Anderkent: klrr: your files are basically dynamically linked. Clojure/java packages are bundled in jars, which mvn/lein will fetch for you. Then when you request a class jvm scans the classpath (including all the jars that lein put there) for the .class or .clj file that provides it

10:13 klrr: yes, but many clojure libs do 'native' interop that's only valid with java

10:13 klrr: okey

10:13 Anderkent: there's already cljs which is clojure on the javascript engine, and pure clojure libraries work on it(usually)

10:13 klrr: so most libraries are wrappers over java libs?

10:14 Anderkent: not quite, but many libraries depend on libraries that depend on java, etc.

10:14 blrm: klrr: some are, but there are a number of pure clojure libraries too

10:14 klrr: okey

10:14 after ive ran lein new foobar, what is the use of resources ?

10:15 nvm

10:15 Anderkent: resources are files that will be available to your code no matter where it runs. Usually you put non-code stuff that your code needs (like config files)

10:15 hyPiRion: klrr: it is for files you want to bundle with programs or libraries, which aren't code. I wouldn't worry too much about it for now

10:15 klrr: got a bigger problem i gotta takle :P atm brb

10:16 okey, thanks

10:19 titubear: join #go-lang

10:19 hah

10:19 Anderkent: traitor

10:19 klrr: golang? which of them, the new limbo language or the original one?

10:20 titubear: more like a traitor the other way

10:20 klrr: god

10:20 titubear: since it's go-nuts anyway

10:20 klrr: #go-lang got a dead guy in it

10:20 :s

10:20 no kidding

10:20 titubear: but my work is favoring clojure and I like looking back at lisp style programming

10:21 running through the elisp tutorial was one of my early programming experiences.

10:21 klrr: haskell is my first lang, tried to learn other languages before that though :)

10:23 hyPiRion: klrr: wow, that's very cool. You'll feel many other languages (possibly including Clojure) will be more... ancient, is perhaps the right word.

10:23 Chousuke: you'll just miss fmap terribly :P

10:24 among a couple other things in particular

10:24 Anderkent: haskell was my first real language too :P

10:24 noncom: in clojruescript can imported ns names coincide with local var names?

10:24 looking at the compiled source i think it mixes them

10:25 ?

10:25 klrr: haskell is ancient too

10:25 20 years or sth

10:25 titubear: BASIC, PERL and C for me... if it wasn't all caps, what was the point?

10:26 noncom: or maybe my bad

10:26 titubear yeah i remember that :)

10:26 in school we had QBASIC

10:26 from MICROSOFT

10:26 running under MSDOS

10:27 titubear: noncom: yea, well, that and logo was a good one early on

10:27 blrm: Chousuke: have you tried the fluokitten library? I haven't used it for anything, but it looks interesting

10:27 dnolen: noncom: you can always shadow referred names w/ locals

10:27 noncom: no different from Clojure

10:29 mgaare: klrr: clojure is 54 years old ;)

10:30 RiGGeR: the lambda calculus is 80 ?

10:30 noncom: dnolen: i meant not referred names but the namespaces names themselves.. however i think that there was error in my code..

10:30 RiGGeR: i think that all that stuff is simply an extension to the writing.... when writing appeared?

10:30 you remember they say that anient people were writing programs on walls

10:30 s/anient/ancient

10:31 mostly hunting simulators

10:31 RiGGeR: hahahaaa, awesome way to look at it

10:31 noncom: :)

10:32 Chousuke: blrm: lacks static typing though

10:33 rhg135: hey i was wondering if there was a fuse api for clojure and if not a good java one to use/wrap

10:33 Chousuke: In part the reason fmap is such a great thing in haskell is that it is expressive and convenient like a dynamically typed function but maintains safety.

10:33 klrr: mgaare: it is? i thought it was more morden than haskell

10:33 modern*

10:34 Chousuke: klrr: just "Haskell" is not specific enough to talk about modernity

10:35 Haskell as it is implemented in GHC is very nearly bleeding edge

10:35 with some dependently typed languages going a bit further into uncharted territory.

10:35 mgaare: klrr: clojure is a lisp dialect, and lisp was from 1959

10:35 hyPiRion: Chousuke: Agda mostly, or are there more?

10:36 Chousuke: Agda and Idris come to mind

10:36 hyPiRion: Hm, haven't heard about Idris, thanks for that one

10:37 Chousuke: It seems very interesting. Fairly new, but seemingly attempts to be practical in a way Agda doesn't.

10:37 klrr: mgaare: i know, but clojure is a NEW lisp right?

10:37 Chousuke: true, there's modern extensions etc.

10:37 mgaare: klrr: bah, that's an implementation detail ;)

10:37 (but yes, from 2007)

10:38 Chousuke: It still amuses me when I see papers going "Look at this cool new thing! We implemented it in GHC"

10:39 noncom: rhg135: which exactly "fuse" ?

10:39 lots-o-software use that name..

10:39 rhg135: filesystem in user space

10:40 noncom: rhg135: a google search on "fuse filesystem java" gives good results

10:41 rhg135: so no recomendations?

10:41 noncom: (i never used that thing, so no expect for me to know that well)

10:42 no personal recommendation for me, but if i were you, i would look into https://code.google.com/p/javafuse/wiki/README and other references given by the search since there i see people with similar requests

10:42 s/for/from

10:43 rhg135: ok, ill look around

10:43 noncom: rhg135: here's something else: https://launchpad.net/jnetfs

10:44 rhg135: this grammar hurts my eyes

10:44 dont think i trust their coding

10:45 klrr: hmm, vimclojure-easy says im supposed to run "lein vimclojure", but lein complains that nothing named "vimclojure" exist

10:45 Anderkent: klrr: I'd recommend using fireplace instead of vimclojure

10:45 http://clojure-doc.org/articles/tutorials/vim_fireplace.html

10:46 i don't think anyone's keeping vimclojure up to date anymore

10:46 klrr: never mind got it working

10:46 `cbp: cant trust chinese software, no proper english in their docstrings!

10:46 klrr: Anderkent: the link is dead but ill google that later :)

10:46 rhg135: fireplace works fine

10:46 Anderkent: that link works for me :O

10:46 oh well, try https://github.com/tpope/vim-fireplace

10:46 rhg135: let me tell you a story, it involves a korean company

10:47 it ended tragically

10:49 klrr: well i just want syntax highlight anyway so vimclojure will work fine :)

10:49 rhg135: -static

10:49 or 7.4

11:07 gvickers: Anyone know of a better way to run functions from (ns-publics) than parsing the output and eval-ing the function? That works but it feels rather messy.

11:08 Anderkent: gvickers: vars are callable, so just ((get (ns-publics *ns*) 'fn-name))

11:10 gvickers: https://www.refheap.com/17942 . I assume there's a reason you use (ns-publics) and not just resolve.

11:11 gvickers: I have a collection of namespaces that are unknown at compile time with an expected set of functions in each. I need to check if they exist and call the functions expected in each namespace

11:12 atankanow: is there any performance difference between using ->> to thread a list through a series of map calls to transform data VS one map call with a compound function that does all of the transformation?

11:13 rhg135: i think i settled on https://github.com/EtiennePerot/fuse-jna but how do i use it in lein?

11:14 gvickers: Anderkent: thanks that worked a lot better than my intial solution.

11:14 Anderkent: atankanow: there might be, but the question is do you care? (most of the time the answer should be 'no' :P)

11:15 * nDuff watches the cljs-in-cljs talk, and somewhat regrets having missed clojure/west

11:15 atankanow: <Anderkent> I don't care about the performance that much ... but i love the ->> macro and wanted to make sure i wasn't abusing it =)

11:17 ToxicFrog: atankanow: series-of-maps is probably less performant, but much more readable.

11:18 Anderkent: rhg135: it seems it's not a mavenized project, so you'd have to write a pom to it then push it out to clojars to use it with lein the 'right way'

11:19 ah wait, it has native dependencies

11:19 rhg135: sigh, has nobody ever used fuse in clojure before

11:19 Anderkent: then I guess you just need to download it and include it in your sources

11:20 lein isn't very good with native stuff :)

11:20 rhg135: that ik

11:20 atankanow: ToxicFrog: I definitely agree about the readability ... i feel very comfortable deconstructing algorithms in a series of transformations

11:30 rhg135: how would i include it just add to classpath?

11:43 caracal_: I'm having a weird compilation error in clojurescript. Anyone willing to listen and hopefully give me some idea of how to solve it?

11:45 justin_smith: I'm no clojurescript expert, but I may still be able to help. What's the error?

11:46 codonnell: So I've modeled a really simple app on the modern-cljs tutorial.

11:46 It's just a form with a calculation attached to the submit button.

11:47 However, if I remove the brepl from compilation and click my submit button, I just get "page not found"

11:47 The same thing happens if brepl is included and I compile with advanced compression.

11:48 I set prettyprint to true and checked out the compiled javascript file, and I cannot for the life of me find a difference between the version that works and the one that doesn't.

11:49 justin_smith: part of the what the google closure compiler does is remove unneeded dependencies - could it be that it is erroneously thinking some of your generated javascript is unused?

11:50 this is something I have watched someone address, but not done myself, sadly

11:52 codonnell: That is possible. I'm going to take a second look and compare working and nonworking compiled javascript.

11:54 ro_st: codonnell: also be worth inspecting the network traffic when you click submit

11:54 justin_smith: we were group-programming in a workshop, I seem to recall manually adding the generated js as includes - there may be a better way to do that

11:54 ro_st: page not found is a 404. what url/http verb is being attempted?

11:54 codonnell: I just have it on localhost for the moment.

11:54 The submit button shouldn't actually change which page I'm on. Its action should be to execute a javascript function.

11:55 ro_st: it's likely that it's causing your browser to redirect thanks to e.preventDefault(); not being used

11:57 codonnell: hmmm

11:57 Any idea how I could fix that?

11:58 ro_st: quickest would be to stick onclick="return false;" directly on the html of the button

11:58 or to not use a button inside a form

11:58 unless you're trying to do form validation?

11:58 codonnell: No, I'm not. I literally just started using clojurescript yesterday. I'm mimicking a technique from the modern-cljs tutorial.

11:59 Of course, it works with the tutorial code. I just spent an hour futilely trying to find the difference.

12:00 Thanks for the tip, by the way.

12:02 ro_st: sure thing :-)

12:02 codonnell: Adding onclick="return false;" does prevent the page from redirecting, but unfortunately my function is still not attached to the form submission.

12:03 ro_st: how are you binding the handler?

12:04 codonnell: One sec, I'll make a pastebin.

12:04 My code is quite short.

12:06 http://pastebin.com/VM2K6pdG

12:06 ro_st: would you mind pasting the calculate fn too?

12:07 codonnell: Sure thing.

12:08 http://pastebin.com/bPmcnfrz

12:10 ro_st: codonnell: drop a (.log js/console theForm) in just above the set!

12:10 does it print something to the console?

12:11 codonnell: theForm isn't defined up there. How about (.log js/console (by-id "draftForm"))

12:12 ro_st: i'm talking about inside the let form

12:12 codonnell: oh ok

12:12 ro_st: after you have theForm bound

12:13 codonnell: aha!

12:13 I should have thought to open up the console.

12:13 ro_st: i have to run, i'm afraid. happy hunting :-)

12:14 codonnell: Alright, well thanks for your help. :)

12:14 ro_st: hth :-)

12:40 bkirkbride: tbaldridge: ping

12:40 tbaldridge: bkirkbride: ack

12:41 bkirkbride: tbaldridge: so I took your advice to use go blocks for glue only

12:41 tbaldridge: but I'm dealing with some synchronous systems and wanted to pick your brain on how best to interface with them

12:42 tbaldridge: ok, what's the issue?

12:43 bkirkbride: tbaldridge: The two options I see are to wrap the sync calls with async versions or make some more generic abstraction that does that on the fly using channels

12:44 tbaldridge: bkirkbride: my current line of thinking (there are some that disagree) is to wrap sync code in one or more (thread) blocks and then communicate using channels. (hang on for a gist...)

12:46 bkirkbride: tbaldridge: that's close to my thinking, but I'm creating pools with a bounded number of threads ahead of time. Here's a gist: https://gist.github.com/bkirkbri/6309498

12:46 tbaldridge: https://gist.github.com/halgari/6309500

12:46 yep, they're pretty much the same, your's is more generic

12:46 bkirkbride: tbaldridge: I decided NOT to embed a function in the thread block, as that seemed more like an actor. Instead you send a [return-channel thunk] message to the "worker"

12:47 tbaldridge: and depends on how you want to divide up the work. Embedding the function may be nice when you want to limit the number of requests to something. For example, a database may need to be restricted to 4 calls in flight at a time.

12:48 bkirkbride: tbaldridge: Right. Sending the thunk allows worker pools to be used for more than one thing. But you probably want the bounds to be linked to the function(ality) anyhow.

12:50 tbaldridge: Send thunks means leveraging closures more directly than sending args to a baked-in fn.

12:50 tbaldridge: In any case, I'm glad to be on the right track. Before chatting with you the other day I was doing the sync work in the go blocks.

12:51 tbaldridge: bkirkbride: yeah, that's not a good idea :-)

12:52 bkirkbride: if you want to do some research on this topic, take a look at Netflix Hystrix. I think there should be a way to use this sort of thing from core.async. https://github.com/Netflix/Hystrix/wiki

12:53 bkirkbride: tbaldridge: Nice. I've seen it but not considered it for use with core.async.

12:53 tbaldridge: Another common pattern I'm trying to abstract is collection (reduction) of a bunch of work you've sent out.

12:53 tbaldridge: bkirkbride: basically it wraps retries/circuit breakers, etc. I haven't figured out what the interop would be like with core.async, but I think it'd be a cool research project.

12:54 bkirkbride: like (join chan1 chan2 chan3) => [result1 result2 result3] ?

12:54 bkirkbride: tbaldridge: Right, I'm using my own breaker stuff right now. It's pretty easy to roll an atom-based implementation that aborts lazy seqs, etc.

12:55 tbaldridge: Well, originally I was creating a channel for each async task sent to a pool and then alt! over those channels, check response, remove from alt! set, repeat

12:56 tbaldridge: But now I'm leaning toward a single result channel that returns messages with the result and what work produced it.

12:57 tbaldridge: A little more abstract than your join example. More like a channel reducer that handles errors and timeouts too.

12:57 tbaldridge: Error channels and timeout channels that is.

13:00 tbaldridge: bkirkbride: yeah, I haven't done enough of that sort of thing to offer much of a suggestion. I'm still trying to figure out the best way to do that sort of thing myself.

13:01 bkirkbride: tbaldridge: Cool, I'll be sure to share anything that works out for me.

13:01 tbaldridge: bkirkbride: cool! I'd love to hear about it.

13:25 schmir: my google foo fails me. how can I get the jdk/jre version I'm running on from within a clojure program?

13:25 s/foo/fu/

13:25 ToxicFrog: schmir: this isn't a clojure-specific question, so [java get jvm version] or similar is probably the query you want

13:26 tbaldridge: ,(System/getProperty "java.vm.version")

13:26 clojurebot: #<SecurityException java.lang.SecurityException: denied>

13:26 schmir: ToxicFrog: you google-fu is much better than mine..

13:26 thanks everyone

13:26 tbaldridge: well that'd work if clojurebot wasn't so stingy

13:26 rlb: schmir: you're lookingf for System Properties.

13:26 (probably)

13:26 http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

13:27 ToxicFrog: ,(System/getProperty "java.version")

13:27 clojurebot: #<SecurityException java.lang.SecurityException: denied>

13:42 dnolen: bbloom: feel free to flesh out the optimizing expression semantics page when you get a chance - specifically I want to hear how the transformation pass will work. Your example from yesterday isn't enough since that just unwraps if, but we will need to unnest lets too.

13:48 hiredman: if you do alpha conversion you can merge lets

13:51 bbloom: dnolen: link?

13:51 dnolen: hiredman: yes, that the kind of thing I want to see written up :)

13:52 bbloom: confluence is refusing to load the nav bar for me

13:52 dnolen: bbloom: http://dev.clojure.org/display/design/Optimizing+Expression+Semantics

13:53 bbloom: dnolen: how about i add some comments & you incorporate them in to whatever format you like?

13:54 seriously atlassian…. Error formatting macro: pagetree: java.lang.NullPointerException

13:54 jira AND confluence are pretty much unusable

13:55 dnolen: http://dev.clojure.org/pages/diffpagesbyversion.action?pageId=8192615&originalVersion=3&revisedVersion=14

13:55 why should i bother contributing design notes if you're just gonna replace them wholesale?

13:56 dnolen: bbloom: your design note aren't design notes which I alluded to yesterday

13:56 bbloom: you wrote up some high level plan with no specific goal

13:57 bbloom: or an overly abstract one, now I'm asking to talk specifically how your solution can address this specific problem

13:58 bbloom: dnolen: *sigh* sorry man, i can't be bothered to play "guess what david nolen wants to hear". you and i both understand the problem & my proposed solution. if there are specific questions you have, i'm happy to answer them. but i'm done posting to the design wiki. it has never proven fruitful

13:59 dnolen: bbloom: just because you and I understand doesn't mean other people don't

13:59 bbloom: nor does it mean we'll remember 2 months down the line when the proposed solution end up being more complicated then we originally though for N reasons

14:00 bbloom: I'm up big changes, but I'm for thinking about how they apply to actual problems and documenting it

14:00 bbloom: dnolen: my proposal is an A-normal form transformation. This is *textbook compiler stuff*. I've already done a proof of concept & the only major problem i ran in to was gensyms in analysis, which i fixed

14:01 dnolen: bbloom: which no one knows about, nor did I follow it closely - so what?

14:02 bbloom: I didn't see any benchmarks, I didn't see any source output comparisons, I just some links to Github

14:02 bbloom: dnolen: so i'm happy to contribute a patch & i'm happy to jump through a few hoops to do so, but if you want a design page, you're gonna have to write it. i'm happy to provide feedback

14:03 dnolen: there are two separate issues: 1) future proofing the AST & API, which i've written design pages about in the past. no progress has been made 2) adding compiler passes, which has also been discussed before but is dependent on #1

14:04 http://dev.clojure.org/display/design/Formalize+AST

14:04 http://dev.clojure.org/display/design/AST+children

14:04 i wrote some notes for you about the compiler API, you deleted those

14:04 dnolen: bbloom: because you keep moving too far out ahead w/ slowing down

14:05 bbloom: both of your "design" note pages don't even outline *real* problems

14:06 bbloom: dnolen: what is the purpose of these pages? to convince you? to document our efforts for other observers? nobody ever comments on these pages

14:06 nobody is paying attention to them

14:06 dnolen: bbloom: why should people pay to pages about problems they don't have?

14:06 bbloom: i'm happy to volunteer non-trivial amounts of my time, but i want my time to be productive

14:06 seangrov`: bbloom: I've been reading through them while trying to understand some problems with the analyzer and compiler

14:07 It hasn't been super useful though, on reflection

14:07 dnolen: bbloom: ^

14:07 bbloom: dnolen: ^

14:07 :-P

14:07 bhauman: dnolen: bbloom: seangrov`: my next post http://rigsomelight.com/2013/08/22/channels-of-channels-dots-game-refactor.html

14:08 bbloom: dnolen: forgive me for being disillusioned, but afaict, you're the only person actively committing to cljs & your criteria for progress seems arbitrary and short-sighted

14:08 dnolen: bbloom: anyways, we have a real problem that needs actual solving with passes that isn't solved by GClosure anymore

14:08 bbloom: dnolen: sure, so you understand the problem, you document it if you feel that's valuable

14:08 i'll contribute code, since i feel that's valuable

14:08 i'm not trying to be a dick, i'm just trying to maximize the utility of my time

14:09 dnolen: bbloom: as am I since I'm going to have to go through your patches

14:09 bbloom: which are generally the most invasive and tend to break shit

14:10 bbloom: dnolen: b/c you want squashed patches. in my branches, they are very fine grained commits that are quite easy to understand

14:10 dnolen: as for breaking shit, yeah, *shrug* we find the issues & we fix them. i'm not super concerned w/ master being broken. i understand that you are, so i'm happy to do extra work to test & validate before applying. i've done so in the past many times & include the tests or benchmarks you ask for

14:12 am i being unreasonable?

14:13 dnolen: bbloom: look, if you can't slow down to explain your solution to *me* and document for *others* I don't see what the point is of pursuing your solution which I'm open to doing. Otherwise I'll simply solve the problem in a local way. My time is as precious as yours.

14:14 bbloom: there's no rush :)

14:15 bbloom: dnolen: my proposed solution is a translation to A-normal form. I can provide you with references as to why that is useful and i can answer specific questions about the impact to CLJS' compiler in particular. If you want to codify my comments in to a design page, you are free to do so

14:16 seancorfield: comment from the peanut gallery: as more people start to use CLJS, keeping releases stable - and keeping master stable - will become increasingly important

14:16 bbloom: seancorfield: trivial solution: unstable branch

14:16 seancorfield: it's just not a problem

14:16 :-P

14:16 callen: I think the problem is that there isn't a stable branch atm

14:16 bbloom: of course releases should be stable

14:16 for once, i agree w/ callen

14:17 callen: and unless the developers choose to split one out, it's a little unreasonable to expect people to fork and manually cut stable releases into the fork.

14:17 seancorfield: we're starting to look at AngularJS + ClojureScript so I'd want to keep master stable, just like dnolen, which means anything "big" needs to go on a branch

14:17 bbloom: dnolen: i can provide a proof of concept patch & you and i can work together to minimize impact

14:17 seancorfield: I'm just commenting on the discussion around keeping master stable

14:18 dnolen: bbloom: anyways feel free to write up your thoughts whenever you like if you actually want it to move forward. I'm not planning on leading this, but I also want to know what the specific plan is for this specific optimization. IRC is not documentation of your thought process.

14:18 bbloom: dnolen: i provided documentation of my thought process… you didn't like it… lol

14:18 dnolen: bbloom: unframed to the specific problem.

14:18 glosoli: hmm is there some decent way in VIM to find the usage of the function between the project ?

14:20 dnolen: bbloom: this is a better page even though it hasn't gone anywhere if you need an example http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances

14:20 bbloom: dnolen: my proposal addresses a number of concerns. looking back at my revision of that page, i wrote: "Eliminates (function() {})() forms that GClosure unreliably optimizes"

14:20 that's the specific problem, is it not?

14:21 i'm not sure why the ceremony is required

14:21 dnolen: bbloom: w/o saying where such an optimization might matter - which I do over and over again.

14:22 `cbp: if I exclude clojure.java.jdbc from korma and use the latest instead will korma break? korma uses 0.2.3 and the latest is 0.3.0

14:22 bbloom: dnolen: but then you replaced *all* of my notes with an unskimmable wall of prose

14:23 dnolen: bbloom: I don't skimmable is meaningfully valuable for potentially significant compiler changes.

14:25 bbloom: dnolen: look, it's really simple: I *was* happy to type up some notes & *am still* happy to answer questions about design, notes, patches, everything. I *never was* happy to conform to some arbitrary archetype of a design document. And now, after a year of trying to jump through design hoops, I am *no longer* happy to write up notes

14:25 dnolen: if that means you're just gonna do a local fix & further complicate the code generator. *shrug* fine by me i guess

14:26 I feel that I've been extremely patient, but my patience has run out.

14:26 dnolen: bbloom: imagine I have only passing familiarity with ANF and alpha conversion for merging lets (which is true). but I have to look at the patch and push the changes through, test it, and in the future debug it.

14:26 seangrov`: dnolen: "This map should map each constant's original form to a unique identifier, possibly some human readable prefix like `cljs$constant$vector$` plus a short ID of some kind." => is this supposed to end up looking like #<Atom@3f86f612: {:else "cljs$constant$vector$else" :a "cljs$constant$vector$a"}> ?

14:26 ker2x: humm, hey, there isn't an openCL lib for clojure hidden somewhere ? :(

14:27 SegFaultAX: bbloom: I missed the start of the convo, what are y'all talkin about?

14:27 bbloom: SegFaultAX: check the logs

14:27 dnolen: i pointed you towards two references on ANF & can point you towards more. No amount of notes I could write would ever equal to the mountains of reference materials on compiler design

14:28 dnolen: this page explains it very susinctly w/ working example code http://matt.might.net/articles/a-normalization/

14:28 `cbp: is korma no longer maintained?

14:29 ker2x: something like that https://github.com/ztellman/calx/ but not dead ?

14:29 seangrov`: bbloom: Maybe a blog post would be a better place to post "design docs" for you, a bit less mutable by others

14:29 That way they're there for reference, and won't be swept away in a single change

14:31 bbloom: seangrov`: writing blog posts or any polished prose for that matter takes *a long time*

14:32 seangrov`: bullet points take minutes, discussion can take an hour, a proper quality design doc or blog post can take me a whole day

14:32 seangrov`: if i've got a day to give to CLJS, i'd rather have it result in a patch

14:32 seangrov`: bbloom: Well, just the fact that you can point to it for reference and not have it wiped away

14:32 bbloom: seangrov`: there is revision control :-P

14:32 seangrov`: Post bullet points, but maybe rely on someone else to port them to the wiki

14:33 bbloom: seangrov`: i did post bullpoints… dnolen's "port" involved cmd+a, backspace

14:33 dnolen: i'm sorry man. you know i want to help

14:33 callen: `cbp: it's maintained'ish.

14:34 `cbp: what's wrong?

14:34 dnolen: bbloom: yes, yes, all this I plan to read. But just because I read it doesn't mean I'll understand immediately how you intend to use it unnest if and unnest the resulting lets. That's like me waving my hand saying "just use core.async it'll be easy to make an autocompleter"

14:34 callen: `cbp: I would make the point that Korma essentially "just works" and doesn't need a flurry of activity to be healthy.

14:34 bbloom: dnolen: if you read it, you'll discover that what ANF does *precisely* is to un-nest things like ifs in to lets

14:35 dnolen: bbloom: but you need to merge the lets too

14:35 hiredman: thanks for the comments :)

14:35 bbloom: dnolen: no, you don't

14:35 dnolen: bbloom: you do

14:36 bbloom: dnolen: why do you need to merge lets? i mean you can, but why do you have to?

14:36 dnolen: (and true false true) -> (let [x (let ... (let ...))] (if ...)) with the transform you suggested yerterday

14:36 all those lets become functions

14:37 hiredman: dnolen: you only hoist if the expression is non-atomic, which is open to redefinition, but I don't think booleans are non-atomic by any definition

14:37 bbloom: dnolen: the compiler will turn all that in to local assignments, which is the point of the ANF transform. you can merge the lets to make the intermediate form look nicer, but for a non-parallel let, that's sugar

14:38 dnolen: letfn is parallel, but clojure's let could (and probably should) be defined in terms of a single binding

14:38 dnolen: i've proposed this before too: a macro should UNflatten all of the lets

14:38 dnolen: hiredman: in the above example booleans of course can will be more complex expressions like function invokes

14:39 bbloom: dnolen: have you read that post yet?

14:40 dnolen: most of your questions will be answered if you reflect on that post for a while

14:41 dnolen: in particular, you should note the "Output language"

14:41 hiredman: dnolen: sure

14:41 bbloom: dnolen: the first argument to an 'if form is an atomic expression

14:42 callen: "ztellman: A reminder that there's a 50% chance of collision on a 32-bit hash with only 77k values. Don't use hashes for comparison/equality checks."

14:42 ztellman: yup

14:42 source, if people care: http://en.wikipedia.org/wiki/Birthday_attack

14:43 bbloom: dnolen: hiredman: regarding alpha conversion - my proof of concept currently uses gensyms, but it could use de bruijn indexes instead with a very small change. we already do hacky alpha conversion in the code generator b/c js has broken lexical scoping

14:43 would be a good idea to do alpha conversion as a pass in the future, since that transformation is important for other backends

14:44 alpha conversion can also leave the original symbol name as a prefix of the generated name, so that it's easier to match them up later

14:52 dnolen: hiredman: the problem is we always need to hoist - in order to avoid emitting complex test expression which always gets wrapped in a JS function

14:53 bbloom: I'm squinting a the post, I get the high level picture but I don't see how it handles the nested let case.

14:53 callen: ztellman: related to the Birthday Paradox?

14:54 anybody here doing Clojure Cup?

14:54 ztellman: callen: birthday problem, I think, not sure what's paradoxical about it

14:54 but yeah

14:54 callen: ztellman: ah yes you're right. I think it's one of those probability things that are slippery for people.

14:54 hiredman: dnolen: it doesn't, but combined with alpha conversion it does, because when you alpha convert, you have unique names, so you can merge the lets

14:54 callen: like the Monty Hall thing.

14:54 bbloom: dnolen: before we discuss what you mean by "nested let case" can we first agree that clojure's let is serial, not parallel? ie, (let [x 1 y 2] z) is sugar for (let1 x 1 (let1 y 2 z))

14:55 ztellman: callen: yeah, I knew about it, but still somehow glossed over it when I was writing the compare function

14:55 dnolen: bbloom: yep

14:55 bbloom: dnolen: ok so with that in mind. what is the problem with nested lets?

14:55 callen: ztellman: you don't mind that I propagate interesting/amusing tweets to this channel do you?

14:55 dnolen: bbloom: (let [x (let ...)] ..) the second let is an expression context will be wrapped in function by the comipler

14:56 ztellman: callen: no, why would i?

14:56 bbloom: dnolen: currently, yes. after an ANF transform, that would be not necessary

14:56 dnolen: bbloom: so what would ANF convert that into, this is what I don't see :)

14:56 bbloom: and the blog post isn't making it any clearer for me

14:56 callen: ztellman: I don't know, some people get proprietary about their missives.

14:57 bbloom: dnolen: if you look at the output language, you'll seee there are 3 types of "expressions" aexp, cexp, and exp

14:57 an aexp is totally atomic

14:57 a cexpr can be compound, but can't be another let

14:58 the inner let would be hoisted out, and assigned a name

14:58 if that involved another inner expression, this would happen recursively

14:58 such is the nature of the transform

14:59 Bronsa: (let [a (let [a 1] a)] a) => (let [a1 1 a2 a1] a2) ?

14:59 bbloom: as a result, if you *also* do alpha conversion (which we do), then you can remove all of those (function() { … })(); generators that check (= context :expr) in the code generator

14:59 dnolen: yeah, Bronsa has it right

15:00 notice how the inner a was named to a1, then assigned that inner binding value

15:00 it makes order of evaluation explicit

15:00 it's also halfway to an SSA transform

15:00 ker2x: anyone tested G-WAN webserver ?

15:00 Bronsa: fwiw i already do alpha conversion in CinC (but no anf) and it makes writing passes so much easier

15:01 hiredman: as an aside https://github.com/hiredman/qwerty does both alpha conversion and anf, but the anf is sort of ad-hoc

15:01 bbloom: (inc Bronsa)

15:01 lazybot: ⇒ 8

15:01 bbloom: (inc hiredman) ; you too budy

15:01 lazybot: ⇒ 25

15:01 bbloom: (dec bbloom) ; for misspelling buddy

15:01 lazybot: You can't adjust your own karma.

15:02 bbloom: whew.

15:03 dnolen: bbloom: it's hard for me to confirm what's going on in Matt Might's blog pos since it doesn't work on trivial examples

15:03 (normalize-program '(let ((x (let ((y 1)) y))) x)) => '(let (let ((y 1)) (let ((g1534 (x y))) (g1534))) x)

15:05 * bbloom is thankful for vectors as binding syntax in clojure

15:06 bbloom: dnolen: you running the racket example?

15:07 dnolen: bbloom: yep

15:07 bbloom: er which one?

15:07 dnolen: I just copied and pasted the the code at the bottom of the post

15:08 bbloom: grumble grumble rlwrap

15:09 dnolen: your arguments are invalid

15:09 dnolen: a let is not an allowable top level form

15:09 wrap it in (list ..)

15:09 dnolen: bbloom: heh, I'm not making an argument :) just fumbling along trying to understand the post

15:10 bbloom: dnolen: lol i didn't mean your debate argument, i meant your function arguments

15:10 haha

15:10 i'm also not making an argument, i was genuinely debugging :-)

15:10 heh, that's pretty funny

15:11 dnolen: bbloom: ok gotta switch gears, but I'll look into this, it's making sense - I'll do the dirty work of keeping the confluence page in sync and ping you again for comments.

15:11 bbloom: dnolen: if you look at normalize-program, you'll see that it matches empty lists, define forms, and lists

15:12 seangrov`: dnolen: Quick confirmation before you switch gears?

15:12 dnolen: seangrov`: what's up?

15:13 seangrov`: dnolen: "This map should map each constant's original form to a unique identifier, possibly some human readable prefix like `cljs$constant$vector$` plus a short ID of some kind." => is this supposed to end up looking like #<Atom@3f86f612: {:else "cljs$constant$vector$else" :a "cljs$constant$vector$a"}> ?

15:14 dnolen: seangrov`: I would probably just store an id? no strings, we should probably do the id emitter as some kind of function to keep it flexible for now

15:15 seangrov`: Is the id just a unique integer? Or another keyword?

15:15 dnolen: seangrov`: it's fine if integer for now

15:16 seangrov`: So #<Atom@3f86f612: {:else 1 :a 2}>, with the integers/ids being generated from a function

15:17 dnolen: seangrov`: something like that, could probably just be the id generator used by gensym

15:17 seangrov`: Ok, perfect, thanks

15:17 dnolen: seangrov`: also, you know there is an existing Keyword type right?

15:18 seangrov`: here https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L2048 right?

15:18 dnolen: seangrov`: yep, it needs to fleshed out into something more like this http://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L382

15:18 `cbp: callen: i had some jdbc queries which depend on 0.3.0 which i wanted to copypaste but korma gets 0.2.3 or something and the queries wouldn't work so I ended translating everything in korma to jdbc and removing korma

15:19 seangrov`: dnolen: Yeah, I think I have that done locally, looking at the Symbol deftype and the clj-jvm Keyword implementation

15:19 `cbp: callen: I could have tried to exclude jdbc from korma but that would've prolly broken it

15:20 dnolen: seangrov`: you should also look how we emit Symbol - we precompute all the properties at compile time.

15:21 seangrov`: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L170

15:21 dnolen: seangrov`: yep

15:23 seangrov`: Ok, so do the analyzer bit to track keywords first, then finish the deftype, and then the compiler emit phase?

15:23 egghead: dnolen: when you pass in 'sel' to alts! in your most recent blog post -- how does that work? I've only seen alts used on a list of chans, not on a chan and a vector of chans

15:24 I see in the docs: "can be either a channel to take from or a vector of"

15:24 [channel-to-put-to val-to-put],

15:24 but alts! doesn't put at all but takes, doesn't it?

15:25 `cbp: callen: also selmer question, the template cache only checks if 1 file has changed. So if you render "home.html" but "home.html" extends "base.html" and you change the latter, the cache won't notice the change. Should there be support for that?

15:25 callen: `cbp: I think you can exclude and replace deps, but just submit a pulll request man.

15:25 everybody has to pitch in for these things to be maintained :(

15:25 t-goossens: in leiningen project file how do I add a class to classpath (like: com.mysql.jdbc.Driver)

15:26 callen: `cbp: that's a good question, I'd brought it up before but I don't think it was addressed.

15:26 dnolen: egghead: sel is a chan

15:26 egghead: aaaah

15:27 dnolen: egghead: it chan of the selector chan which has had other operations applied over it

15:27 egghead: r/filter and r/map are not sequence filter/map

15:27 egghead: ya I was confused by the names map and filter, didn't realize they were the sort of map-chan filter-chan things from your async-tests utils

15:27 cheers, thanks

15:27 callen: `cbp: the official policy is:

15:27 `cbp: use dev mode if you need to disable caching.

15:28 ToBeReplaced: t-goossens: you need the artifact that contains the class... in your case, I think you add ["mysql-connector-java" "5.1.6"] to your :dependencies

15:28 t-goossens: like that

15:28 ok

15:28 thanks

15:28 for some reason i remember something like (:import)

15:28 ToBeReplaced: or mysql/mysql-connector-java

15:28 t-goossens: but maybe that is something else..

15:28 `cbp: callen: yeah that's probably enough

15:29 callen: for my use case anyway

15:29 ToBeReplaced: that's how you import the class in a clojure ns form -- that's different from telling your project it needs to use that artifact

15:29 t-goossens: basically it is one namespace that needs it

15:31 callen: `cbp: (cache-off!)

15:33 hiredman: :import only lets you use a class using the shorter version of the name

15:33 .win 5

15:33 boblarrick: Google keeps leading me to functions in contrib like deep-merge or dissoc-in, what is the recommended way to use that stuff now? How do I get those in my project?

15:47 llasram: boblarrick: Most of the utility stuff in contrib which didn't make it honestly just isn't that useful. Fortunately most of them are tiny, so you can just copy-paste them if you can't live without them

15:48 boblarrick: Or you can check out the non-contrib utility libraries like flatland/useful

15:49 dissipate: does anyone here use a scripting language like python to compliment clojure? or can clojure replace python/ruby/perl?

15:50 callen: dissipate: bit of both.

15:50 nDuff: dissipate: in my experience, the set of projects for which each is the right tool tends to be surprisingly disjoint.

15:50 dissipate: callen, bit of both? would you use clojure to whip up a recipe for the command line?

15:50 nDuff: ...well, not entirely. There's a case I recently used Python's Trellis for which Pedestal was also very competitive.

15:50 * technomancy is using ocaml for small things the JVM sucks at

15:51 dissipate: nDuff, i'm not talking about a project, i'm talking about just whipping up a script

15:51 bbloom: technomancy: nice

15:52 callen: dissipate: depends on what it is.

15:52 I've got a script written in Clojure running right now.

15:52 but it's also more complicated than a typical 1-liner.

15:53 nDuff: dissipate: usually, if I'm "just whipping up a script", my tool of choice is shell.

15:54 boblarrick: llasram: yeah i'm copy/pasting now, wondered if that was considered shady or what

15:54 cemerick: nDuff: every time I do that, I end up writing in 40 different languages

15:54 shdwprince: nDuff: found shell very painfull when writing something above 2-3 lines

15:55 patchwork: dissipate: Clojure is not a scripting language and requires spinning up a JVM to run anything

15:55 nDuff: cemerick: If one knows bash well, it's rarely necessary to use awk/perl/whatnot from it.

15:55 patchwork: stick to bash for one off simple command line tasks

15:55 cemerick: nDuff: I'll have to take your word for it :-)

15:56 dissipate: patchwork, so it seems clojure is more suited to application development, not scripting

15:56 nDuff: shdwprince: people who write scripts by guess-and-test have trouble. It's a language, and has to be learned like any other to be used effectively. (Actually, needs _more_ care to use effectively, since there are so many non-obvious pitfalls).

15:56 patchwork: nDuff: bash is awesome for stringing programs together, not so much for writing them… !

15:56 I love bash for having programs as function calls

15:56 ltw: Anyone got any strong opinions on function naming practice when you're essentially renaming a function to swap the args around?

15:56 patchwork: but I would still rather write the programs bash calls in something besides bash

15:57 dissipate: patchwork, what about python?

15:57 mgaare: actually I think using clojure for simple scripts is very good for your health

15:57 patchwork: dissipate: It is like any compiled language that way

15:57 nDuff: patchwork: I have a bash library that provides, in effect, higher-order-functions with lexical scoping.

15:57 ToxicFrog: Lein repl really needs a (reload)

15:58 patchwork: dissipate: python is fine for simple tasks, not so much for applications (GIL)

15:58 nDuff: patchwork: If you want to make an argument about where bash is and isn't the right tool, we can do that, but I'd prefer to do it at a point when we both have the time to make our arguments in full and provide counterexamples.

15:58 mgaare: every time you go to run a small clojure script, get up and get a drink of water. Super helathy

15:58 patchwork: nDuff: That sounds interesting. Link?

15:58 nDuff: patchwork: unreleased.

15:58 mgaare: ToxicFrog: see clojure.tools.namespace

15:58 nDuff: patchwork: I'd *like* to release it, but property-of-employer, etc.

15:58 patchwork: big parts are inspired by the execlineb language, by the way, if you want to look at that.

15:58 patchwork: nDuff: bummer. So much good code in private repos

15:58 ltw: ToxicFrog: is that a complete ns reload, complete with requires, or just the ns contents?

15:59 dissipate: patchwork, i'd pick python over java for a large application though. not sure if that is saying much.

15:59 patchwork: nDuff: I don't deny you can write anything in bash, there are just less error-prone options nowadays for writing full programs

16:00 dissipate: mgaare, not sure if serious. :P

16:00 ToxicFrog: mgaare: will do

16:00 patchwork: dissipate: Everything is a tradeoff. You clearly prioritize developer sanity over general performance

16:01 nDuff: patchwork: Depends on what you mean by "error-prone". The exception-handling story isn't so great -- I had to roll my own tools -- but if you're just referring to the pitfalls inherent in using the language badly, well, the answer is not to do it badly. :)

16:01 ToxicFrog: ltw: I think complete with requires? Basically I want to be able to change some part of the project and reload it without needing to shut down and restart the repl (20+ seconds)

16:01 mgaare: dissipate: only a little bit. Although the lifestyle of programmers often leads to chronic dehydration, so it could be a good practice :D

16:01 dissipate: patchwork, that i do. BTW, there are ways around the GIL, namely interprocess communication. my main beef with python is it's imperative with side effects.

16:01 mgaare: ToxicFrog: clojure.tools.namespace will do code reloading. If you change your dependencies in project.clj, it won't pick those up though

16:01 ltw: the (refresh) in mgaare's suggestions of clojure.tools.namespace seems a good fit.

16:01 technomancy: my rule for bash scripts: your first bug you get from weak typing counts as a warning; once you hit your second you have to throw it away

16:02 patchwork: dissipate: Right, running many pythons in parallel. Kind of like brute-force threading

16:02 technomancy: unless you actually have no choice (/me makes a sad, resigned motion towards bin/lein)

16:02 ToxicFrog: mgaare: that's good enough for me, thanks.

16:02 benkay: mgaare wine bottles fixed my hydration problem. 750 mL, 2x/day. throat size makes it super easy to drink large volumes while walking or w/e.

16:02 dissipate: patchwork, and what would you recommend for a multi-threaded friendly scripting language?

16:02 nDuff: technomancy: Heh. It's more the unintuitive automatic behavior (string-splitting on expansion, unescaping on read, etc) that requires effort to turn off that I see messing folks up. :)

16:02 tbaldridge: patchwork: the libraries in python are super nice for that sort of thing. basically fork with a function argument.

16:03 nDuff: ...that, and people trying to copy old, bad code that uses scalars where one should use arrays.

16:03 patchwork: dissipate: I don't know one : ) In that case just keep a clojure repl open, use that is your shell so to speak

16:03 clojure to me hits the sweet spot of being expressive and performant

16:03 that no other language I've used can match

16:04 tbaldridge: Haven't used it in a couple years! Used to use it all the time ~5 years ago, but I assume things have come along since then

16:04 mgaare: benkay: yeah, I think Tim Ferriss does that too

16:04 benkay: mgaare: now that I think about it I got the trick from him.

16:04 shdwprince: dissipate: maybe when you need powerfull thread system in scripting language, you doing it wrong?

16:05 benkay: 500 mL is a great wakeup while the coffee brews

16:05 ToxicFrog: patchwork: if only it didn't take so long to warm up :(

16:05 patchwork: ToxicFrog: Just never close your repl!

16:05 dissipate: patchwork, but then i have to have 2 languages in my code base. 1 language for my scripts (say python) and then clojure for my application code.

16:05 ToxicFrog: dissipate: lua has a nice message-passing library (Lanes) and a cluster computing library (Luapilot), but the package management situation is kind of not good.

16:05 mgaare: benkay: I still haven't gotten in a good morning water habit. shame shame on me

16:06 shdwprince: dissipate: you want to stick one one language for all purposes?

16:06 patchwork: dissipate: That is why I am saying, if you keep a repl open you get around the startup time, and can use it just like a scripting language

16:06 dissipate: shdwprince, so you are saying i would never want to run a script that does scientific calculations?

16:06 benkay: mgaare: wine bottles. wine bottles errywhere :)

16:06 patchwork: But also, right tool for the job and all that

16:07 shdwprince: dissipate: some libs for math in python writted and optimised on very low level

16:07 callen: shdwprince: the same libraries exist on the JVM...

16:07 mgaare: Didn't I read somewhere about something that lets you keep a hot jvm running to alleviate the startup time concerns for this kind of scripting?

16:07 shdwprince: dissipate: i say about if you really need perfomance you should'nt use scripts

16:07 rlb: mgaare: nailgun

16:07 dissipate: shdwprince, and yes, i would like to reduce complexity by not having multiple languages

16:07 rlb: (or similar?)

16:08 patchwork: shdwprince callen: Right, everyone is still using the same old fortran for matrices!

16:08 mgaare: rlb: yeah that sounds right.

16:08 patchwork: Just find blas in whatever language you are using. Done

16:08 Apage43: nailgun is a single JVM

16:08 there's also drip

16:08 https://github.com/flatland/drip

16:08 dissipate: patchwork, do you use the repl as your CLI?

16:09 patchwork: dissipate: Increasingly yes

16:09 technomancy: nailgun is extra-complicated for the sake of Java

16:09 patchwork: abstraction is great

16:09 Apage43: which keeps an -extra- JVM handy, with your classpath already set up

16:09 shdwprince: dissipate: there is many languages for very different purposes, you can't stick at one that will be very good in all

16:09 mgaare: oh wow, it's like double-clutch jvm

16:09 stuartsierra: ha :)

16:10 dissipate: shdwprince, well, that's an epic fail

16:11 stuartsierra: In case it was unclear, I was laughing at mgaare's "double-clutch jvm"

16:12 hiredman: ,(some nil? [])

16:12 clojurebot: nil

16:13 hyPiRion: ,((juxt keep some) nil? [nil])

16:13 clojurebot: [(true) true]

16:13 mgaare: ;)

16:13 patchwork: stuartsierra: Thanks for clarifying. I thought you were laughing at everything

16:13 ToxicFrog: zipmap \o/

16:14 stuartsierra: patchwork: Sometimes I do. It's how I stay sane. :)

16:14 Also, I wrote tools.namespace so that I could use a single REPL as a persistent process.

16:15 I only restart the JVM once or twice a day now.

16:16 xeqi: stuartsierra: whats missing to get that to 0 ?

16:17 stuartsierra: xeqi: Never making a mistake in my code. :)

16:17 mgaare: I use tools.namespace too, but PEBKAC issues cause restarts sometimes :D

16:56 noncom: are there any recommendations on organizing global program architecture with core.async?

16:57 stuartsierra: noncom: Step 1: wait until it's finished. :)

16:58 noncom: ahaha

16:59 stuartsierra: More seriously, there are good examples in docs / talks about Go.

16:59 tbaldridge: I'm not sure what people are waiting for to mark it as "finished". The client API hasn't changed...well since it was first written.

17:00 stuartsierra: Well, I'd like a little more testing before I base my "global program architecture" on it. :)

17:00 And we'll be confused about how to pronounce <!! forever.

17:01 futile: I wonder if it can be made into a more "pluggable" API, so that you don't have to architect your app around it, but the other way around.

17:01 mgaare: maybe pronounce it "failed bank robbery"

17:02 stuartsierra: mgaare: Not as good as "double-clutch JVM" :P

17:02 futile: Not that I know the first thing about its API.. I just know that when I hear that phrase, it usually indicates an API that sits under your code instead of on top of it. And I guess that's often a good thing, as clojure.core does that.

17:02 tbaldridge: futile: that's kindof like asking a compiler to magically add parallelism to your code.

17:03 ToxicFrog: openmp~

17:03 tbaldridge: ToxicFrog: even that takes code annotations most of the time

17:03 ToxicFrog: tbaldridge: yes, I wasn't actually serious

17:03 hiredman: b

17:03 mgaare: stuartsierra: hm... actually "gun control" would be better. for "less bang bang"

17:03 dnolen: tbaldridge: I think people are probably waiting for non snapshot release - is there anything blocking a 0.1.0? It would be nice to get Read/WritePort in there

17:03 hyPiRion: and it's not just like saying #pragma omp parallel for either, sadly

17:04 stuartsierra: mgaare: Now that's a good one.

17:04 hyPiRion: Well it is, but you need to find good sizeable chunks, not throw them around everywhere

17:04 tbaldridge: dnolen: We'd have to talk to Rich about that, but I know I handled most of the ones we discussed last Monday.

17:05 hyPiRion: but pmap makes everything faster! It's the magic fairy dust of the Clojure world!

17:05 hyPiRion: tbaldridge: ha

17:05 tbaldridge: I tend to call <!! "blocking take" and <! "take" or "parking take"

17:06 t-goossens: can clojure.java.jdbc library give me a list of all tables in a database. I can't seem to find sometihng in the api

17:06 stuartsierra: I'm going to go with mgaare's "gun control"

17:06 tbaldridge: but I know that doesn't really help anyone else.

17:07 ToBeReplaced: tbaldridge: dnolen: i'm in that camp -- i have some std blocking queue code set aside to test a port to core.async when it hits a non-snapshot

17:07 stuartsierra: Or maybe "angry bunny."

17:07 tbaldridge: stuartsierra: so what do we call >!! ? May I suggest we call it "guns for everyone" or perhaps just call it "Texas"?

17:07 ToBeReplaced: t-goossens: it can't; the information you want is database dependent, so you should use "query" with the right meta table

17:08 mgaare: tbaldridge: "Texas" sounds like a winner

17:08 stuartsierra: tbaldridge: "Texas" is too political, "America" would work.

17:08 tbaldridge: nah... "Murica"

17:08 mgaare: haha

17:08 maybe "NRA"

17:09 hyPiRion: "Now, if we do a 'Murica call here, this part will block until some other goroutine performs a gun control."

17:09 Well, it should be the other way around really

17:09 'Murica should run free and lose until someone performs a gun control?

17:09 *loose

17:09 stuartsierra: :)

17:09 tbaldridge: ROFL!

17:09 "It's the yin/yang of programming, you can't have one without the other"

17:16 noncom: i see...

17:17 frp paradigms seem fit

17:22 i am doing a little gui framework on html canvas, is core.async ready for such a task? i think yes.. but what you say?

17:23 currently it is without core.async but i want to swap the architecture

17:24 seangrov`: Almost certainly worth an experiment

17:26 dissipate: a gui framework?

17:26 oh hell no

17:26 noncom: hate framewox?

17:27 dissipate: noncom, gui framework just screams OO framework to me

17:28 noncom: agreed, that is my mindset too.

17:28 dissipate: noncom, you have a TextBox widget that you add...

17:28 nDuff: dissipate: eh. seesaw, f'rinstance, is downright beautiful.

17:29 ...whether you call it a "framework"... *shrug*.

17:29 noncom: but as seangrov` said i want to consider an experiment, but first asking for encouragement i guess

17:29 dissipate: noncom, are your widgets going to be immutable?

17:30 mgaare: noncom: we're using async quite a bit here. not for gui, but for io related things. I encourage!

17:30 noncom: dissipate: i am yet to decide.. i guess i will have a kind of mvc structure.

17:31 tbaldridge: noncom: don't assume that OO patterns will work with core.async (e.g. MVC)

17:31 noncom: also, read all you can about Pedestal's UI model. It's not perfect, but it's one of the best I've seen in a long time.

17:32 futile: Why is (some #{el} coll) the only core fn to test if a seq contains a given element?

17:32 dissipate: noncom, immutable data structures in MVC? hmm. see that's a bit strange to me.

17:32 noncom: yeah, i'm not going to reimplement OO, or at least i'll try.. :).. i will read on pedestal too, thanks for the reference..

17:33 futile: I guess I'm wondering why there's no (contains? el coll)

17:33 dissipate: noncom, that means that when you want to resize the textbox widget, you don't resize the existing one, you remove the existing one, produce a new one of the proper size and put it back in place of the old one.

17:33 noncom: futile: contains? will check for index inbounds

17:33 futile: right

17:34 noncom: dissipate: good point. but actually here i come to a question: what is a textbox widget in fp? and when i try to think of it, the widget disappears in my head

17:35 i see functions and the flow of data

17:35 that flow can be altered by other funcs

17:35 ..

17:35 dissipate: noncom, that's exactly why i said it smacks of OOP

17:35 noncom: i am still trying to grasp all that

17:35 dissipate: noncom, in fact, there is no other use case that smacks more of OOP than GUI frameworks

17:36 noncom: yeah, guis are tricky :)

17:36 looks like a challenge :)

17:36 dnolen: noncom: I'd rather see an event layer over Canvas

17:36 noncom: you should also check out my blog posts on the subject

17:36 justin_smith: in dataflow a text box widget is a container that data flows into (from the user), that does nothing until triggered (the trigger propagating the data it has accumulated to be functionally processed)

17:37 buckets and spouts

17:37 dissipate: justin_smith, but it's immutable?

17:37 justin_smith: no, because the user manipulates its contents

17:38 dissipate: justin_smith, there in lies the problem

17:38 justin_smith: but the change of state is isolated to the contents + the triggering of functions based on them at a precise time

17:38 (rather than being entangled all through the logic as state usually is)

17:38 dissipate: justin_smith, ok, so then you have side effects

17:38 justin_smith: you need that for state, yes

17:38 and for UI you need state

17:39 the key is to minimize its incidence and scope

17:39 noncom: dnolen: i read your posts! very inspiring and interesting! but what you say on events now? js events or you mean core.async?

17:39 dissipate: theoretically you don't, but personally i would probably go insane if i had to do a GUI in pure FP

17:40 justin_smith: ok, you need something that acts like state, and for that it just makes sense to use sensibly managed mutable state

17:41 dnolen: noncom: just that it would be nice to have some approach to an event layer over canvas

17:41 noncom: you could use a shadow canvas

17:41 noncom: dissipate: i think that OOP complects textbox widgets (bear me).. there are no textbox widgets in reality.. most of the flow functions are universal archetypes, which, being decoupled from implementation are very reusable

17:41 dnolen: noncom: drawing operations could be surrounded in a block where you paint to that surface so it's a particular shade

17:41 noncom: then when mouse event happen you can check the shadow canvas

17:42 noncom: and emit an identifier

17:42 so you can have sane generic event handling for canvas like you do w/ DOM

17:42 noncom: far more useful than a GUI toolkit over canvas IMO

17:46 noncom: dnolen: oh i see

17:47 that technique is widely used in games

17:47 dnolen: noncom: it's kind of thing you see can reinvented over and over again

17:47 noncom: yep

17:47 noncom: but would also just make canvas more friendly

17:47 noncom: you could reuse all your HTML based logic in Canvas

17:49 noncom: definitely my interest grows more

17:50 * `cbp makes a note in his todo list

17:51 noncom: i will explore all the advices and thoughts of who responded and experiment. i will share the results if i make something sane!

18:01 powrtoc: What's the best method for getting a clojurescript browser repl working with emacs?

18:02 glosoli: I would like the same info but VIM related

18:02 lol

18:02 dnolen: powrtoc: follow the instructions carefully that are in the repo, then do the same with lein cljsbuild

18:05 glosoli: Hmm anyone familiar with ring ? I don't seem to get the way Session storage works in it, shouldn't session entries appear to be viewable by browser session viewer ?

18:05 `cbp: is there a better idiom for (->> xs (map (future..)) (doall) (map deref) (doall)) ? =P

18:06 justin_smith: glosoli: the browser gets a token, used to look up the actual session data in memory

18:06 powrtoc: dnolen: so you use inferior lisp mode?

18:06 dnolen: powrtoc: yep

18:06 justin_smith: glosoli: that is the default, at least

18:06 dnolen: powrtoc: fancier things are possible with piggieback and austin but I haven't bothered

18:07 glosoli: justin_smith: just to be completely sure, in which memory ?

18:07 powrtoc: dnolen: with an inferior-lisp-program set to something like "lein cljsbuild repl-listen"?

18:08 dnolen: powrtoc: yep

18:08 justin_smith: glosoli: server

18:08 mikkelg: hey folks! having trouble require'ing core.async:

18:08 CompilerException java.lang.RuntimeException: Unable to resolve symbol: pprint in this context, compiling:(clojure/core/async/impl/ioc_macros.clj:23)

18:09 justin_smith: glosoli: you can request a cookie store that is stored for client browser, but that is not the default

18:09 mikkelg: I don't get it, since if I clone core.async and compile the file, it works fine

18:09 glosoli: justin_smith: aaa thanks for taking time to explain!:) confusion is gone

18:09 pbostrom: powrtoc: piggieback is another option https://github.com/cemerick/piggieback

18:10 powrtoc: pbostrom: thanks... I'm looking at it just now...

18:11 on the subject of cljsbuild, is there a more up to date version that uses clojure 1.5.1 and the latest clojurescript release?

18:12 dnolen: powrtoc: no just but it doesn't really matter - just specify your version of Clojure and ClojureScript

18:13 powrtoc: dnolen: cool... that's what I've been doing

18:13 dissipate: noncom, explain how a textbox resize would occur in your GUI framework

18:19 Morgawr: ibdknox: I've been playing around with light table 0.5 since I saw it's a new release, however I can't find the option to enable vim mode D:

18:20 glosoli: Morgawr: where is it???

18:20 lazybot: glosoli: Yes, 100% for sure.

18:20 noncom: dissipate: that is an interesting topic i'd like to discuss, but i MUST go sleep now :D it night here. next time we talk and maybe find something interesting, probably tomorrow..

18:21 Morgawr: glosoli: where is what?

18:21 glosoli: 0

18:21 0.5

18:21 dissipate: clojure programmers sleep? wow

18:21 Morgawr: glosoli: http://www.lighttable.com/

18:21 glosoli: Morgawr it isn't

18:22 Morgawr: glosoli: yes it is, it's version 0.5

18:22 noncom: ahahaa, :) we hibernate

18:22 glosoli: Morgawr: Binary version 0.5.1..

18:22 Morgawr: It's not LightTable 0.5

18:23 Morgawr: Hmm I take back My words.... sorry man, must have cached links or something

18:24 Morgawr: glosoli: haha it's ok ;)

18:24 glosoli: Morgawr: I really do get only the older version on download... damn

18:28 noonian: light table updates itself automatically doesn't it?

18:29 glosoli: noonian: not this time

18:29 This new version is awesome

18:30 Rainbow Parenthesis included man

18:30 THat's cool

18:32 noonian: awesome, I'll check out the new version then

18:33 glosoli: noonian: It's so damn nice and minimalistic, !!

18:33 Morgawr: yeah the new version is awesome

18:33 just gotta find out how to enable vim mode

18:34 * futile checks out light table

18:34 glosoli: Morgawr: and change font lol

18:35 Morgawr: font isn't that bad ;)

18:36 glosoli: Morgawr: Yeah, vim mode would be great though, it's somewhere hidden

18:37 Morgawr: let me know if you find out how to enable it

18:37 glosoli: Morgawr: likewise

18:40 futile: does LightTable have structural editing yet?

18:41 callen: futile: you mean paredit?

18:42 futile: If you do - no and it won't until the plugin functionality comes out.

18:42 futile: callen: paredit is just one implementation of structural editing

18:42 ok

18:43 * futile wanders off

18:43 glosoli: Kinda weird, CodeMirror got updated, and no way in gui to enable vim mode

18:43 hmm

18:48 Morgawr: it is in behaviours

18:49 noonian: is the feature to change the skin between light, dark, and minimal gone?

18:49 glosoli: Seems like everything has been moved to behaviours

18:49 Not sure how to get list of the ones available yet

18:50 noonian: I like being able to bring up the workspace with 1 keyboard shortcut as opposed to 2 or a click

18:51 Morgawr: glosoli: I don't know how behaviors work, I'll look it up, thanks

18:52 glosoli: Morgawr: neither do I xD

18:52 noonian: nice, can change skin (and other behaviors presumably) with the user behaviors config file

18:52 glosoli: noonian: yet not sure how to get available ones

18:52 noonian: start typing behaviors in the command pane to access them

18:52 light, dark, and minimal all seem to work, but minimal make the config file itself impossible to read

18:53 glosoli: noonian: can you explain more

18:53 noonian: it shows you 2 autocompletions of light and dark when you start typing in the string quotations

18:54 glosoli: I see now

18:54 need to find a way to enable vim mode lol

18:54 noonian: I type ctrl + space bar to bring up the command pane on the right, then start typing behaviors and it will bring up 3 options, to reload behaviors, and user, workspace, and default behaviors

18:54 if you hit the user behaviors it has some initial code that you can edit

18:55 glosoli: noonian: yeah, though there should be something like "available behaviours" because Default ones does not list all of them for sure

18:55 Morgawr: holy crap this is amazing

18:55 the themes and everything

18:55 noonian: oh cool, I hadn't checkout out the defaults, just the user ones theres way more stuff in there

18:56 glosoli: Morgawr: yeah lol

18:57 Morgawr VI MODE!!!!

18:57 works lol

18:57 Morgawr: :D

18:58 glosoli: Fonts!! man I am loving

18:59 Morgawr: Nice I even got to set line height, this is good

19:37 ddellacosta: ping cemerick

19:38 `cbp: ztellman: ping

19:40 callen: `cbp: ping

19:40 `cbp: callen: hihi

19:40 callen: `cbp: seemed like what the cool kids were doing.

19:40 `cbp: I just had a question about websockets in aleph :P

19:42 callen: ddellacosta: what about you? :D

19:42 ddellacosta: callen: howdy

19:42 callen: ddellacosta: hi! Have a question?

19:43 ztellman: `cbp: shoot

19:43 ddellacosta: oh, I wanted to ask cemerick about austin, specifically the use-case where you load it up in your *own* app *not* within the same repl session you have your app running from (which is the default example in the austin docs)

19:44 callen: if you have any suggestions, I'm definitely all ears, but I figured it was relatively…niche. heh

19:44 `cbp: ztellman: can I use ring/compojure and route a websocket?

19:44 ztellman: `cbp: yeah, it looks like a normal request to ring, if you wrap the handler in wrap-ring-handler at the outer context

19:45 then you wrap the websocket handler in wrap-aleph-handler at the innermost context

19:45 there's an example of this in the wiki

19:45 `cbp: ok thanks a bunch

19:48 callen: ddellacosta: asking in the open, even if you suspect only one person can answer is useful for a few reasons. It'll let people (like me) know what tools are being used, what people are interested in, and somebody willing to read the code could still help out.

19:48 ddellacosta: when I know one person can realistically answer it, I ask the question and then ping/cc afterward.

19:48 also some people have watches set on the name of projects they care about, although I suspect that's a minority.

19:48 ddellacosta: callen: fair enough…it was a tough call with this one, as I think this is a pretty esoteric thing at this point. But, point taken!

19:49 I will take that approach.

19:49 callen: ddellacosta: thanks for hearing me out, I know I ask things that can seem strange. :)

19:50 ddellacosta: I have a habit of researching tools I see people having a lot of trouble with. Usually either to fix them or to learn them myself.

19:50 that's why I use CCW and LT periodically.

19:50 ddellacosta: callen: no problem. It doesn't take much effort to think about how to use IRC to help the community better share ideas, which I think is the thrust of your argument.

19:50 callen: ddellacosta: yep, you've got it exactly. :)

19:50 ddellacosta: callen: :-)

19:57 clj-json vs. cheshire?

19:57 ztellman: cheshire's faster

19:57 ddellacosta: both based on Jackson from what I can tell

19:57 okay

19:57 ztellman: and actively maintained

19:58 I thought there was a deprecation notice on clj-json

19:58 is there not?

19:58 mischov: There's a clj-json?

19:58 ddellacosta: ztellman: thanks. Yeah, I'm getting some weirdness now with clj-json, and was wondering if I should switch

19:58 ztellman: I don't see it on the git page: https://github.com/mmcgrana/clj-json

19:59 ah, but yeah, the last pushed version was from Nov. 2012: https://clojars.org/clj-json/versions/0.5.3

19:59 alrighty then.

20:00 callen: ddellacosta: most people use Cheshire.

20:00 I should write a lein task that lets you compare the clojars pushing and github history of two libraries.

20:01 and tells you which one it thinks you should use.

20:01 ddellacosta: callen: thanks, good to know. This is not a project I started, so I'm learning about some libs I haven't really used in the past, clj-json among them. I used cheshire on something else. We're moving most of this to edn anyways so it's moot I guess...

20:01 callen: that would indeed be a handy lein task.

20:02 * callen adds to to-do list

20:05 malyn: Is Cheshire preferred over data.json? I have been using the latter...

20:05 ddellacosta: apropos of nothing: testing for user-agents on the server-side makes me irrationally angry.

20:06 ztellman: malyn: Cheshire is faster, and I'm not sure if other than correctness there's another dimension that can be used to compare json libraries

20:06 malyn: ztellman: Yeah, good point.

20:08 hiredman: ztellman: there are other features I would like a json lib to have, but as far as I can tell none of them have restartable encoding in to a fixed size buffer

20:08 TimMc: callen: How will it distinguish "abandoned" and "done"? By checking the issues?

20:10 ddellacosta: so, big diff is that data.json is pure Clojure, huh? Interesting

20:11 hiredman: ddellacosta: I would say the big difference is cheshire uses jackson which has had a lot of engineering time thrown at it

20:12 ddellacosta: hiredman: right, so it would make sense that it would speed things up a bit.

20:13 ztellman: also is probably more robust to any edge cases that exist in the spec

20:13 though that's hard to measure

20:13 hiredman: there was a talk done by an ebay engineer about comparisons they did of serialization formats in terms of speed, if I recall correctly jackson was competitive with binary formats

20:14 TimMc: However, Jackson will do some stupid things in the name of optimization, such as giving you Shorts instead of Longs when it can. :-(

20:16 ztellman: TimMc: is it truncating numbers?

20:16 majormajormajorm: hello

20:16 ztellman: why is that stupid?

20:17 hiredman: http://www.infoq.com/presentations/Dealing-with-Performance-Challenges-Optimized-Data-Formats

20:17 TimMc: ztellman: It gives you the smallest possible representation of Number.

20:17 ztellman: dunno why that's bad

20:18 ddellacosta: isn't that what you want if you can do it without losing information?

20:18 hiredman: you'd prefer doubles?

20:18 TimMc: I don't recall the specifics, but it has caused some problems at works.

20:18 *work

20:19 You know how there are all these Clojure programs that do all integer stuff with Longs?

20:19 ztellman: little l longs

20:19 otherwise it's just Object

20:19 and is auto-coerced

20:19 TimMc: I guess it's not so much "stupid" as "violates the principle of least surprise".

20:21 hiredman: I've seen bugs where some json libraries pedantically put a .0 at the end of all numbers, which cause other libraries to give you some kind of floating point number instead of some kind of integer, which broke equality checks, etc

20:25 powrtoc: any idea why I'm getting same origin policy issues with my clojurescript browser repl, when accessing the page http://localhost:8080/ ?

20:26 TimMc: hiredman: Well, that's definitely objectively worse...

20:29 hiredman: computers are basically terrible at dealing with numbers

20:30 it is sad because people say things like "computers are idiot savants, only good for dealing with numbers"

20:30 "only good at" I guess

20:30 AimHere: Both are perfectly grammatical

20:30 hiredman: I'm pretty sure most introductions to binary arithmetic say something like that at some point

20:31 callen: TimMc: my to-do list? It's sorted. If something is done, it gets removed.

20:32 TimMc: callen: No, silly, the thing that compares libraries.

20:32 AimHere: Is it that the computers are bad at processing numbers or that they're bad at presenting the numbers to people? I'd say that the former is probably wrong and the latter is probably right

20:33 callen: TimMc: yeah, abandoned/done from unresponded to issues. It'll be comparative and explain the reasoning.

20:33 TimMc: so it'll say, "library A has a lot of commits, so it might just be stable, but there are a couple of github issues that haven't been closed or responded to in ${X} months"

20:34 TimMc: "Library B has fewer commits, but it's more active. Also the contributors curse frequently."

20:34 incidentally, Raynes has a shake-n-bake library I can use for the GH integration :)

20:34 TimMc: "Also, the library author's username uses wAcKyCaSe so they are probably still snorting pixie sticks."

20:34 callen: TimMc: I snorted audibly, thank you.

20:37 mischov: "The library name would be a real word if you switched the ju for su. Do not trust."

20:38 Rather.. "Do not encourage."

20:39 callen: "Author has '420' in their username and hasn't replaced the broken Leiningen default project test. Nuke from orbit"

20:40 "lein-kibit reported 524 issues with the project, author may have used this project to learn Clojure"

20:51 TimMc: "Triple snail detected. Author is either too clever or insufficiently so."

20:52 callen: TimMc: @@@?

20:52 TimMc: yeah

20:52 callen: TimMc: that's like the c2 wiki, "triple-star programmer"

20:54 hyPiRion: It's worse when you see (nth (iterate deref ...) n).

20:55 callen: hyPiRion: ...where did you see this?

20:55 hyPiRion: I haven't. I haven't even seen double snails yet. I'm just pointing it out

20:56 TimMc: You've never used @@ in anger?

20:56 brehaut: that syntax looks just as shocked as is apropriate

20:58 TimMc: I see @@#' in tests all the time.

20:58 But tests are a different category of code, I guess.

20:59 hyPiRion: whirr, I rarely put global state in vars

21:01 TimMc: grep @@ -nRI --include=*.clj repos/

21:02 pprint has a bunch of @@

21:02 callen: TimMc: I haven't used @@ in non-test code.

21:04 TimMc: Sam Neubart wrote something interesting with a delay in an atom -- that involves an @@.

21:05 callen: TimMc: that sounds nifty - what for?

21:05 TimMc: Found it, "the Lock-less Monster": https://gist.github.com/samn/5843422

21:07 callen: TimMc: how apropos, I just got done writing code in Python to manage an OAuth access token lifecycle.

21:07 of course, since it's Python, I'm fucked anyway.

21:08 TimMc: I don't think it's quite perfect, though.

21:08 mmarczyk: bbloom: is there somewhere I could have a look at your ANF pass? (if I understood correctly that you have a poc)

21:09 callen: TimMc: even still, gives me something to think about.

21:09 at present I'm using a global mutable variable and a timestamp expiry to manage it in Python.

21:09 I can't say I'm entirely happy about that.

21:10 TimMc: I added a comment to the gist that explains what I think could go wrong.

21:10 callen: oh, and an accessor fn wrapper that manages cycling out and replacing expired values.

21:10 ztellman: can I get the opinion of someone who's familiar with the internals of apply? bbloom, looking at you

21:11 assuming you're around

21:11 callen: on a quasi-related note, is bbloom's RestFn patch going to get merged?

21:11 ztellman: who knows

21:11 callen: that would make some code of mine XX% faster.

21:11 which would be, you know, cool.

21:12 ztellman: just noticed that in applyToHelper, we're calling RT.boundedLength: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFn.java#L154

21:12 and boundedLength doesn't check if the ISeq is Counted

21:12 so we're doing two passes through the first ~20 elements, always

21:12 I can't think of why this is necessary, but maybe I'm missing something?

21:23 callen: Are there any recommended Datomic schema/query libraries other than the default one?

21:24 mmarczyk: callen: not saying anything about "recommended" (by whom?), but https://github.com/rkneufeld/conformity is worth a look

21:25 callen: mmarczyk: thank you, I've been poking around for libraries to de-fang some of the prickliness of datalog for a coworker of mine who is going to be learning Clojure as they learn Datomic as well. wanted to make it a little less intimidating.

21:25 this is also the first Clojure project at this company >:)

21:26 mmarczyk: oh, cool -- sounds fun

21:27 callen: devn: ping - need to ask you about datomic-simple.

21:29 muhoo: hiredman: computers are good at turning electricity on and off, which makes them good at 1's and 0's. everything else, less so, depending on the software.

21:29 so i guess all numbers other than 1 and 0, gets to be a gray area :-)

21:32 mmarczyk: ztellman: I guess typically required arity is pretty small and so it's only 2-3 elements that are iterated over; otherwise no reason that I see fwiw, though it would have to return something like max(i + c.count(), limit + 1) in the counted case I suppose? (also, apply with extra args -- prepended to final seq -- uses cons for prepending, so not counted -- probably not a major consideration though?)

21:32 dnolen: ping

21:33 ztellman: mmarczyk: agreed, but if you're applying a vector or something it's much faster and much less allocation

21:33 mmarczyk: ztellman: right, I'd expect that

21:33 (much faster, I mean)

21:34 benkay: callen where do you work?

21:34 callen: benkay: the place with the really expensive rent.

21:35 benkay: callen: i'm more curious about which company is dabbling in clojure

21:35 company/companies

21:35 company is/companies are (argh grammar)

21:36 callen: benkay: I'm in the bay area, there are a goodly number of companies dabbling in Clojure out here.

21:47 muhoo: callen: brooklyn has SF beat on rent

21:47 callen: muhoo: are you sure? I lived in Brooklyn a few years ago on $450 a month.

21:48 we had a pretty huge two bedroom big enough for four people

21:49 ztellman: way to take the air out of ibdknox's wings.

21:49 ztellman: callen: I was genuinely curious, I haven't been keeping up

21:49 I use so little of what emacs can do, that's pretty much the one barrier

21:50 callen: ztellman: last I heard, paredit happens whenever plugins do.

21:50 ie, community should implement it themselves.

21:50 benkay: PDX has most everywhere beat on dev salaries ;)

21:51 callen: benkay: on being low?

21:51 benkay: yup.

21:51 callen: I always wondered why that was the case.

21:51 benkay: because dev salaries = f(rent)

21:51 well, proportionate, but i don't know that character offhand.

21:52 callen: benkay: I prefer to min-max by working in SF and living like a peasant so I can save money and escape California someday.

21:52 benkay: callen: having spent a few years scraping by in NYC i've determined that (for me at least) QoL trumps most other considerations

21:53 not about to sacrifice current experience of life for probabalistic future payoff

21:53 callen: benkay: I have a problem finding companies that suit my personality outside of the bay area.

21:53 benkay: callen: what is your personality and what kinds of companies suit it?

21:54 callen: benkay: startups, companies with little/no hierarchy.

21:54 benkay: I'm the sort of person that would rather be kept up on what business/product priorities are and do the job of translating that to software myself.

21:55 benkay: callen: well obvs you want a job at the new Salesforce plant out in the burbs then ;)

21:56 callen: I don't really know anything about Salesforce as a company, so I can't tell if you're being sarcastic.

21:56 I'm very happy where I'm at right now though.

21:56 benkay: very sarcastic.

21:56 callen: I'm in a nice little hive of anarchy. :)

21:56 benkay: read "plant" as "software manufacturing facility"

21:57 callen: said anarchy is how I'm able to test Clojure and Datomic for a project.

21:57 hiredman: abstract software factory factory

21:57 benkay: awesome!

21:57 TimMc: hiredman: Would that be... a... startup incubator?

21:58 callen: TimMc: I think that's accurate.

21:59 hiredman: I dunno, too abstract for me

21:59 callen: I hated incubating.

21:59 T'was only good for the office space.

22:00 benkay: i've never understood the practice from the incubee's perspective.

22:00 i'll do my own networking, tyvm.

22:01 callen: benkay: we really really needed free office space.

22:01 benkay: really really equity sacrifice needed?

22:02 muhoo: huh, i read this lock-less-monster thing, and i'm wonder, why not memoize instead?

22:02 benkay: callen: because lol move to portland and bike to each other's houses. (only sort of joking)

22:02 callen: muhoo: expiry + auto-refresh?

22:02 benkay: we were all living in apartments together and car pooling to the incubator.

22:03 there were like 5 people, one of whom was an illegal immigrant, living in 2 two bedroom apartments.

22:03 we rotated who had to sleep on the couch.

22:03 benkay: callen: holy smokes!

22:03 callen: I'm only just now moving out of one of those apartments to SF.

22:03 benkay: callen: how much did those apartments cost?

22:05 eh, irrelevant I suppose.

22:05 callen: benkay: $2000 apiece

22:05 * benkay falls over

22:05 callen: and that's in the cheapest neighborhood in mountain view.

22:05 SF is worse.

22:05 benkay: dude.

22:06 callen: if my company ever opens a non-California office, I'm *out*.

22:06 benkay: well duh you pegged your salary at those Yay Area numbers...

22:06 `cbp: haha thats more than i make!

22:07 callen: benkay: *grins sheepishly*

22:07 muhoo: http://gothamist.com/2013/08/08/skyrocketing_brooklyn_rents_close_i.php

22:08 callen: http://sfist.com/2013/03/07/map_average_rent_for_1br_in_san_fra.php

22:08 benkay: el oh el oh ******* el

22:08 muhoo: sf is still marginally cheaper

22:08 benkay: i am renting a 3 br victorian in downtown portland for 1650

22:08 callen: muhoo: only if you include all the neighborhoods nobody wants to live in.

22:08 benkay: with a park across the street

22:08 callen: benkay: there's only two neighborhoods (both remote) in SF with average single bedroom apartment rents lower than $1650.

22:09 more typical is more like $2200-3000 for a single bedroom in SF

22:09 gdev: callen, if you ever move to Chicago I have a townhouse you can rent out for 1k

22:09 callen: gdev: Chicago wouldn't be my first pick if I can finally escape Cali.

22:09 TimMc: My wife had a $400 room in Somerville, about 4 miles from downtown Boston.

22:09 muhoo: yep. a few people i know have since decamped to west oakland

22:09 callen: I'd probably go SEA, PDX, or AUS

22:10 TimMc: Now, that's pretty cheap for the area -- but $650-700 is still pretty low.

22:10 gdev: is AUS australia or austin?

22:10 benkay: SEA is a bland sea of suburbia

22:10 with awful traffic.

22:10 * `cbp googles for pasadena average rents and starts crying

22:12 TimMc: I think I'd like to see a map showing the ratio of salaries in some profession to cost of food.

22:12 food/housing

22:12 muhoo: my great dream is to buy some land out in coastal mendo or humboldt, put a trailer on it, and flip off the rest of the world

22:13 i just need one hit startup first :-)

22:14 callen: gdev: Austin

22:14 TimMc: well that's the problem, a lot of consumption for some people is flexible, for others it isn't. Having a family a lot.

22:16 gdev: callen, really? I live in san antonio and drive up to Austin for clojure meetups, i don't see the appeal

22:16 muhoo: you can baseline it though. food and housing can be apples to apples for 1 person, then some relatively constant-ish factor to multiply it by per kid

22:16 gfredericks: austin is the seattle of texas?

22:16 callen: gdev: I'm sort of a gun nut. Texas appeals.

22:17 muhoo: callen: somalia then?

22:17 TimMc: callen: Soooo... not MA, then? :-P

22:18 callen: TimMc: I'd pick Somalia before MA.

22:18 rlb: gfredericks: possibly more like portland than seattle.

22:18 afaict

22:18 muhoo: i hear you can buy them on the street, drive around with 50cal in the bed of your toyota pickup

22:21 ToxicFrog: Is there an idiomatic clojure equivalent to chaining the Maybe monad in haskell?

22:21 E.g. I have (->> input foo bar baz moby); any of those operations may return nil.

22:21 If they do, I want the result of the entire (->>) to be nil rather than NullPointerException.

22:22 arohner: ToxicFrog: some->> ?

22:25 ToxicFrog: arohner: that is exactly what I was looking for! Thanks.

22:27 holo: where is as-str?

22:28 ,(as-str :foo :bar) ; => "foobar"

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

22:29 benkay: str?

22:30 holo: ,(str (name :foo) (name :bar)) ; not so compact

22:30 clojurebot: "foobar"

22:32 brehaut: ,((comp (partial apply str) (partial map name) list) :foo :bar)

22:32 clojurebot: "foobar"

22:32 `cbp: (defn as-str [ks] (->> ks (map name) (apply str))) there you go

22:32 brehaut: (def as-str (comp (partial apply str) (partial map name) list))

22:33 `cbp: showoff

22:34 brehaut: if i was showing off, i'd have got a juxt in there ;)

22:34 `cbp: i was just wondering how to do that

22:34 TimMc: ToxicFrog: clojure.incubator/-?> I think.

22:34 brehaut: replace the map with an apply juxt repeat

22:35 ToxicFrog: TimMc: already solved, I wanted some->>

22:35 amalloy: brehaut: extra fun: replace your map with mapcat

22:35 brehaut: ha

22:36 TimMc: OK, but that's new in 1.5.

22:37 (Important if you're writing a lib.)

22:37 TEttinger: ##(reductions + (repeat 20 0.1)) always nice to know that double precision sucks

22:37 lazybot: ⇒ (0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999 1.0999999999999999 1.2 1.3 1.4000000000000001 1.5000000000000002 1.6000000000000003 1.7000000000000004 1.8000000000000005 1.9000000000000006 2.0000000000000004)

22:37 TEttinger: ##(reductions + (repeat 20 0.1M)) works fine though, thanks clojure

22:37 lazybot: ⇒ (0.1M 0.2M 0.3M 0.4M 0.5M 0.6M 0.7M 0.8M 0.9M 1.0M 1.1M 1.2M 1.3M 1.4M 1.5M 1.6M 1.7M 1.8M 1.9M 2.0M)

22:39 holo: you are awesome.. i was just wondering where it was hehe

22:39 futile: oh hey holo whats new

22:40 holo: hey futile.. same old same old

22:40 futile: right on, right on

22:42 `cbp: copy paste code from chrome into emacs, C-c C-k, nrepl blows up and emacs goes "we cant figure out the coding system" =(

23:09 gdev: `cbp, I can't get it to blow up =o

23:09 what am i doing wrong?

23:10 `cbp: gdev: you're a) prolly not using windows and b) prolly pasting code with no non-english characters =P

23:11 or c) not being delusional like me and trying to encode emacs files with utf-8

23:13 gdev: are you using emacs 23 or 24?

23:14 `cbp: 24

23:14 gdev: what version of windows ?

23:14 `cbp: 7 64-bit

23:16 gdev: okay, so i've tried to reproduce your environment. i have w7 laptop with emacs 24 and i'm pasting non-english chars from chrome to emacs with cc ck...wish me luck

23:16 what site are you copy-pastashing from?

23:17 `cbp: gdev gmail

23:17 muhoo: waaaay off topic, but i figured i'd ask: anyone else in the bay area seeing t-mobile data toggling on and off in an endless loop?

23:17 `cbp: so much effort just for some fireworks

23:19 bbloom: mmarczyk: let me dig that up for you

23:19 `cbp: gdev: If emacs' coding-preference (or whatever) is set to utf-8 you should get some ugly weird \### chars instead of non-english characters when you copy paste from windows onto emacs

23:20 bbloom: mmarczyk: https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L68-L186

23:21 $mail ztellman sorry i missed you, let me know if you still need help w/ the apply stuff later

23:21 lazybot: Message saved.

23:22 `cbp: keyboard/locale might have to do with it too idk, maybe windows assumes everything is damn ascii or stupid latin-1

23:22 tl;dr: cant wait to buy a mac

23:23 amacdougall: Not to be that guy, but use Linux!

23:24 I'm on a Thinkpad running Xubuntu, and although there were some kinks to work out over time, it's been over a year and I'm quite satisfied.

23:24 `cbp: I would but I apparently suck, and can't build emacs because it segfaults randomly hehe

23:24 amacdougall: That's really weird, but why do you have to build it from source?

23:25 `cbp: It seemed like the only option at the time

23:25 rlb: `cbp: just install the emacs binary -- they're provided for windows now...

23:25 amacdougall: Just use a really mainstream distribution and use its package manager.

23:26 rlb: `cbp: http://ftp.gnu.org/gnu/emacs/windows/

23:26 `cbp: rlb: my emacs segfaults on ubuntu not windows

23:26 amacdougall: rlb: I think he meant that it segfaults when he builds it on Linux, so he's using Windows. (?)

23:26 rlb: ok, so that is strange -- which emacs emacs23 or emacs24?

23:26 (and have you tested without a .emacs?)

23:27 i.e. emacs -Q or similar

23:29 `cbp: I tried a lot of things for a long time, but it's been a long while and I don't remember

Logging service provided by n01se.net