#clojure log - Dec 28 2013

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

0:25 yedi_: what does the `@` represent in `@(d/transact conn schema-tx)`

0:26 justin_smith: @ is a reader macro for deref

0:27 (macroexpand-1 '@thing)

0:27 ,(macroexpand-1 '@thing)

0:27 clojurebot: (clojure.core/deref thing)

0:27 amalloy: justin_smith: you don't need to macroexpand reader macros

0:27 ,'@thing

0:27 clojurebot: (clojure.core/deref thing)

0:27 justin_smith: amalloy: nice, thanks

0:28 amalloy: since of course it's the reader expanding it

0:28 justin_smith: d'oh, I could have figured that out, of course

0:30 Arafangion: Out of curiosity, what's the overheads of using clojure on android?

0:30 justin_smith: the sanity drain of dealing with a weird jvm

0:31 Arafangion: Is it turely that weird?

0:31 *truely

0:31 justin_smith: in all seriousness, like any other clojure use case, depends on what you need it to do and your coding style

0:31 Arafangion: I want to write a tiny application, the language is probably irrelevant, in all seriousness.

0:32 So if the overheads for a minimal clojure support library is say, 50KB, then I'd consider it very minimal.

0:32 justin_smith: I have yet to hear any success story about clojure on android, but ymmv and it could be I only heard the whiners

0:32 Arafangion: The whiners can whine... If nothing else, clojure apparently works on javascript.

0:33 justin_smith: space overhead should be identical, because android is not a separate build target

0:33 Arafangion: Yeah, just wondering what that space overhead is.

0:33 justin_smith: though you could mitigate it with gen-class and compiling in such a way as not to include sources (which is not the default)

0:33 Arafangion: Hmm.

0:34 justin_smith: I mean identical to the normal overhead with a desktop jvm

0:34 clojure is not lightweight in ram usage by any means

0:34 Arafangion: RAM is a separate concern.

0:34 justin_smith: add to that persistance / immutibility and their added space usage

0:34 OK

0:34 Arafangion: I mean, RAM is a concern, but it's separate.

0:34 justin_smith: I meant "space" above, including ram and deployed size

0:35 Arafangion: I'm mostly concerned with "download size".

0:35 justin_smith: right - in that case you may actually want to avoid gen-class and only ship sources for libs. But clojure still can't do tree shaking, so it will be a large deploy.

0:36 Arafangion: No tree shaking, curious. (Seems to be a new term for "stripping"?).

0:36 justin_smith: kind of

0:36 since clojure has eval in it, and no way to explicitly say you won't use it

0:36 nothing can be ruled out as runtime accessible

0:37 Arafangion: So, the overhead of my application, naively, would be the size of the clojure jar itself.

0:37 justin_smith: not in an automated way at least

0:37 plus libs you use

0:37 yeah

0:37 Arafangion: Naturally.

0:37 Hmm, so between ~900K and 3.5M. Tiny by modern standards.

0:37 But not tiny by android standards.

0:38 justin_smith: and my app deploys are typically significantly larger than that. But I am not shipping something comparable to an android app at all

0:38 Arafangion: Indeed. Still, 900K is probably tolerable.

0:38 justin_smith: Arafangion: it almost seems to imply a shared clojure base app that could be used for other apps would be called for

0:39 Arafangion: That's very difficult in practice.

0:39 justin_smith: once you have clojure, the individual app could be very small

0:39 maybe an app that just ships clojure plus the code to download and bootstrap your 10k of code

0:39 Arafangion: That shared clojure app would have to be 'frozen'.

0:39 (my term)

0:39 Hmm, actually that is an idea, depending on how dynamic dalvik is.

0:40 But avoiding the need to bootstrap and do additional downloads is something I'd like.

0:40 justin_smith: if alembic can be made to run on dalvik, you could take that and run with it

0:40 Arafangion: http://www.alembic.io/ <-- That?

0:40 justin_smith: and, actually, if you could bundle your app as source, you wouldn't need to hack class path, you could just use load

0:40 though that's pretty ghetto

0:41 Arafangion: Yeah, I'd rather compile.

0:41 justin_smith: load compiles

0:41 there is no non-compiled jvm clojure mode

0:41 Arafangion: I'm considering either some scheme dialect, or javascript, for my app. (With is a trivial library/database app, but it's a nice example to try ideas in)

0:41 justin_smith: https://github.com/pallet/alembic <- this

0:42 Arafangion: Thanks

0:42 justin_smith: I love clojure, but honestly it will be easier to get a small bundled deploy size with a scheme or javascript

0:43 Arafangion: I'm seriously considering doing most things in just javascript - I should know the langauge anyway (I can hack it as it is, but I don't truely know it).

0:43 Although there's a number of hates I have with it.

0:44 justin_smith: you could use a clojurescript dev environment and target a js that runs on android

0:44 Arafangion: js easily runs on android.

0:45 But even that would still entail some overhead... But there are tools available to strip that down.

0:46 justin_smith: jvm clojure has no tree shaking, but clojurescript may (via goog)

0:47 ryanf: is there a commonly used way to make stuff (e.g. tests) start faster using something like nailgun?

0:47 justin_smith: ryanf: you can run tests in a repl

0:47 ryanf: there's an ancient lein-nailgun plugin but I think it's incompatible with current leiningen and it doesn't look like anyone ever used it

0:47 yeah, I know, I'm using cljs though and it's really rickety

0:47 justin_smith: reload the code being tested (and the test if needed, and (test/run-test <optional ns arg>)

0:47 ryanf: I haven't had much luck finding a sane workflow for running tests in a repl and loading updated code

0:48 technomancy: if you don't run your tests in the repl (which you should but whatever) there's always grenchman

0:48 ryanf: oh, plus I'm using the node cljs repl, because I'm targeting node

0:48 justin_smith: (do (require my.ns :reload) (test/run-tests))

0:48 ryanf: technomancy: thanks for the pointer

0:48 justin_smith: yeah, I can't help with the cljs testing

0:48 ryanf: justin_smith: the cljs repl doesn't even support require :(

0:49 Arafangion: ryanf: If there is no test framework, I highly suggest that when you decide to roll your own, you look around for some existing test frameworks other platforms have, and reproduce the best one.

0:49 ryanf: As there are some fantastic, but non-obvious solutions.

0:49 ryanf: oh, I'm not doing that. I'm using this https://github.com/cemerick/clojurescript.test

0:49 I got it working pretty well if I don't mind running "lein cljsbuild test" every time, but I unfortunately do mind that

0:50 I just spent a while trying to get interactive test running working with https://github.com/bodil/cljs-noderepl, but haven't found a sane way to reload test code in that repl yet

0:50 but one might exist that I just haven't figured out yet

0:50 justin_smith: is there really no require in the cljs repl?

0:51 ryanf: as far as I can tell, there isn't

0:52 also looking at that node repl the wrong way makes it raise an unrecoverable exception, which requires restarting the whole thing, so that's fun :)

1:02 bitemyapp: arrdem: another soul claimed!

1:02 arrdem: up fer doters?

1:06 nmws: whats the easiest way to wrap a java class into clojure? for e.g. a Java class has 10 methods, and I want to create 10 clojure functions that correspond to those methods

1:25 TEttinger: nmws: are you translating in some way? like ArrayLists <-> Vectors?

1:25 otherwise, you can just use the java class

1:26 ,(.nextDouble (java.util.Random.))

1:26 clojurebot: 0.290021386697762

1:34 sritchie: magnars: around?

1:34 had a Q about optimus

1:38 TEttinger: sritchie, the expensive keyboards?

1:38 sritchie: haha, no, his front end optimization lib

1:41 magnars: sritchie: hi mate! I'm with my daughter right now. If you open an issue on GitHub, I'll get back to you as soon as I can.

1:41 sritchie: okay, for sure

1:45 yedi_: so im trying to use the console with datomic free: bin/console -p 8080 rhymer datomic:mem://rhymer

1:46 i get this error: Removing storage with unsupported protocol: rhymer = datomic:mem://rhymer

1:46 this is my application code so far: https://github.com/yedi/rhyme-finder/blob/master/src/clj/rhyme_finder/app/db.clj

1:46 am i missing something?

1:58 TEttinger: ok, I can't remember how to reload a ns in lein repl

1:59 and since I can't remember the words, I don't know what to search for...

2:09 seancorf`: do you mean (require 'some.namespace :reload) ?

2:10 or something more specific?

2:28 magnars: yedi_: your code looks right. My guess is that console doesn't work with in-memory datomic from another process?

2:28 TEttinger: seancorfield, yeah that's it

2:28 sritchie: magnars: https://github.com/magnars/optimus/issues/8

2:28 boom

2:28 magnars: sritchie: I'll take a look! :)

2:28 yedi_: magnars: yea, that's what i realized

2:28 ty tho

2:28 sritchie: maybe just a misunderstanding of mine, but css urls don't seem to be getting rewritten with the hash-based prefix

2:28 magnars: or any base url

2:28 magnars: thanks!

2:43 TEttinger: hm, how do I tell whether a file by a given name exists or not?

2:44 arrdem: if you have a URI for the file then I think you can stat it with the File api...

2:44 that's probably the best way.

2:44 TEttinger: it's local, I'll take a look

2:46 yep, .exists

2:51 yedi: whats the complement to `read-string`? (tryna convert clojure data/edn to a string)

2:51 magnars: str

2:52 sritchie: I answered your issue with a question

2:52 yedi: wow

2:52 derp

2:52 sritchie: magnars: maybe I have them in the wrong order

2:53 magnars: sritchie: order shouldn't matter - at least I've been trying hard to avoid that pitfall.

2:54 sritchie: responded

2:54 with the optimizations - it's working great for the actual css file,

2:54 magnars: I added some printlns to replace-css-urls,

2:54 and (replacement-fn file url) returned the url, unchanged

2:55 magnars: the tests don't seem to show a cache-busting rewrite? Just rewriting of relative URLs

2:55 magnars: sritchie: I think you must be looking at the load-css-asset code, because the cache-busting is in add-cache-busted-expires-headers

2:56 sritchie: https://github.com/magnars/optimus/blob/master/test/optimus/optimizations/add_cache_busted_expires_headers_test.clj#L50-L72

2:59 sritchie: let's see...

3:00 magnars: okay, found the bug

3:00 magnars: excellent

3:00 sritchie: magnars: it seems that if I have a resource included twice -

3:00 the first time, referenced by the css, then again as the image by itself

3:00 (concat (css-bundle) (image-assets))

3:01 if there's a duplicate, the css rewriting stops working

3:01 magnars: Doh. Good detective work. If you update the issue, I'll take reproduce and fix that this evening.

3:02 sritchie: okay, great

3:02 thanks, awesome

3:02 magnars: In the meantime, removing the images referenced in CSS from (image-assets) should work around the bug.

3:02 sritchie: yeah, I'll move them over to the CSS folder for now

3:02 since I just slurp up all images

3:02 loving the lib

3:02 magnars: Glad to hear that :-)

3:05 TEttinger: yedi, pr-str is the real equivalent, since str doesn't always produce re-readable output (you can make str print anything by changing a type's .toString method)

3:05 pr-str is more equivalent, but still not perfect

3:05 I did use it to make save files, and clojure worked on the first try

3:05 (just now)

3:13 sritchie: magnars: strange… even if I move those images out, if I include that image bundle as well, the rewrite fails

3:13 TEttinger: yedi, if you want to stringify arrays, it's more tricky, but I got it working with these lines https://github.com/tommyettinger/dungeon-kingpin/blob/master/src/dk/DKGame.clj#L21-L23 for char, bool, and double arrays

3:13 sritchie: no matter the location, including the following line kills the rewrite: (assets/load-assets "public" [#"/img/.+\.(png|jpg|gif|ico)$"])

3:14 including this line, though, has no effect: (assets/load-assets "public" [#"/cljs/.+\.js$"])

3:14 TEttinger: try .+?

3:15 hm

3:15 ,(clojure.string/replace "/img/hooray.gif" #"/img/.+\.(png|jpg|gif|ico)$" "yay")

3:15 clojurebot: "yay"

3:15 TEttinger: so that regexp will match

3:16 sritchie: ah, false alarm

3:16 I think I forgot a reload on the latest iter

3:16 TEttinger: phew

3:17 yedi: TEttinger: ahh thanks, yea (str) was just printing out "LazySeq blah blah blah" but pr-str did the trick

3:18 TEttinger: that print-dup thing I linked at my github -- it needs a binding to work, but you don't need to set print-dup usually for clojure data

3:18 edn should be pr-str and read-string capable

3:19 yedi: TEttinger: hows that game goin a long btw

3:20 TEttinger: great, I am very pleased that savefiles work on the first try

3:20 using that method I mentioned, pr-str and slurp

3:29 yedi: so im using emacs + nrepl. my handler.clj keeps failing to load (C-c C-l) because of this error: java.lang.Exception: namespace 'rhyme-finder.core' not found

3:29 when i try to load rhymefinder's core.clj, it says its own ns can't be found

3:30 i then (in-ns 'rhyme-finder.core) i try reloading, and it loads fine

3:30 then reloadin handler.clj also works

3:30 does anyone know why handler.clj would fail to load successfully at first?

3:31 i also get this error when starting the repl: #<CompilerException java.lang.ClassNotFoundException: clojure.walk, compiling:(rhyme_finder/core.clj:23:5)>

3:31 (but the repl still starts)

3:31 TEttinger: oh, it could be the - in the ns

3:31 that causes problems sometimes

3:32 see how it says compiling:(rhyme_finder/core.clj:23:5)

3:32 with an _

3:33 yedi: i thought that was how it was supposed to work? the - in the namespace gets converted to _ when lookin up the file

3:33 TEttinger: but if you have rhyme_finder and rhyme-finder as ns paths...

3:34 it may be expecting to be found as rhyme_finder even though your ns calls it rhyme-finder

3:34 I think it's kinda not a recommended practice?

3:34 but I could be wrong

3:35 yedi: yea, the folder name is called rhyme_finder though, so it should be able to find that path

3:35 TEttinger: right, nvm http://stackoverflow.com/a/8923092

3:46 yedi: here are the relevant files: https://gist.github.com/yedi/8157428

3:47 logic_prog: where can I read about what characeters are valid function name ?

3:47 I want to do apl style programming, so I can do shit like ($! /% (!! 20))

3:47 and it'll get me the first 20 prime numbers

3:47 yedi: the compiler exception before the repl starts seems to complain about this line: https://gist.github.com/yedi/8157428#file-rhyme_finder-slash-core-clj-L23

3:55 TEttinger: logic_prog, http://www.hypirion.com/musings/swearjure ?

3:56 logic_prog, so in that, !! is iota in APL?

3:56 logic_prog: TEttinger: the above is not valid apl code

3:56 I just made it up

3:56 TEttinger: ok

3:56 logic_prog: not like anyone can tell :-)

3:56 sweajure looks ifasicnating

3:56 TEttinger: it uses no numbers!

3:56 logic_prog: especially given they made this professional pdf to present it

3:56 TEttinger: hyPiRion is here

3:56 he's a pro

3:57 but yeah, the APL chars are valid names

3:57 logic_prog: hyPiRion: we meet again

3:58 i'm thinking of using unicode characters

3:58 (apply concat ...) is too long

3:58 I want this to look like (A B ...)

3:58 where A, B are unicode cahracters

3:58 clojurebot: Pardon?

3:58 yedi: ughhh... TEttinger i figured it out: https://gist.github.com/yedi/8157428/revisions

3:59 for some reason that fixes it

3:59 TEttinger: heh

3:59 http://www.unicode.org/charts/PDF/U2300.pdf

4:04 logic_prog: à is now apply

4:05 TEttinger: ["?" "⌈" "⌊" "⍴" "∼" "∣" "⍳" "⋆" "−" "+" "×" "÷" "," "⌹" "○" "⍟" "⌽" "⊖" "⍋" "⍒" "⍎" "⍕" "⍉" "!" "+" "−" "×" "÷" "⋆" "○" "?" "∈" "⌈" "⌊" "⍴" "↑" "↓" "⊥" "⊤" "∣" "," "\" "/" "⍳" "⌹" "⌽" "⊖" "⍟" "⍕" "⍉" "!" "<" "≤" "=" "≥" ">" "≠" "∨" "∧" "⍱" "⍲"]

4:06 those are the chars used in APL

4:06 IBM APL anyway

4:06 Arafangion: I seem to have missed the era of special-purpose keyboards.

4:08 logic_prog: TEttinger: someday, people will look back, and say, it was on Dec 28, 2013 that clojure went back to 1970s technology

4:08 TEttinger: ["?" "⌈" "⌊" "⍴" "∼" "∣" "⍳" "⋆" "−" "+" "×" "÷" "," "⌹" "○" "⍟" "⌽" "⊖" "⍋" "⍒" "⍎" "⍕" "⍉" "!" "+" "−" "×" "÷" "⋆" "○" "?" "∈" "⌈" "⌊" "⍴" "↑" "↓" "⊥" "⊤" "∣" "," "\" "/" "⍳" "⌹" "⌽" "⊖" "⍟" "⍕" "⍉" "!" "<" "≤" "=" "≥" ">" "≠" "∨" "∧" "⍱" "⍲" "/" "⌿" "\" "⍀" "." "∘"] ; the real list

4:09 but APL is very oriented towards arrays, there's no seq abstraction

4:10 I kinda think the best part of APL is not that everything is so short, but that everything can be expressed ever more cleverly

4:11 APL has tons of stuff (operators) that changes the behavior of other functions or operators

4:12 J calls them adverbs

4:13 logic_prog: yeah

4:13 and also the notion that all functions are either 1 arg of 2 args

4:13 which removes the need for ()'s

4:13 more important question:

4:13 on http://symbolcodes.tlt.psu.edu/bylanguage/mathchart.html#fractions ... what is a good representation of "apply" and "reduce" and "map"

4:15 TEttinger: it has to be a fraction?

4:16 logic_prog: no no

4:16 any symbol

4:17 i was just so desperate I was looking throuhg all of them, even fractions

4:17 right now, (apply concat (map :blah lst))

4:17 reduces to ($a $c ($m :blah lst))

4:17 TEttinger: apply is one to many, map is many to many, reduce is many to one

4:17 logic_prog: ??

4:17 lazybot: logic_prog: Uh, no. Why would you even ask?

4:17 TEttinger: find some symbols for those

4:19 ≾ apply

4:22 ≻ reduce ≈ map ≊ mapv

4:23 progo: those abbreviations make it easy to go over 80 characters per line :S

4:24 TEttinger: yeah, the unicode thing

4:24 but clojure has no such restriction

4:26 Arafangion: TEttinger: Why is unicode so desirable?

4:27 TEttinger: it isn't, just wondering how to do APL stuff for clojure

4:27 of course the words are better

4:27 Arafangion: TEttinger: (Your IDE could easily convert words to symbols at the UI level, similar to how emacs can do http://www.emacswiki.org/emacs/PrettyLambda )

4:28 * Arafangion personally uses pretty-lambadada, but for python coding.

4:30 ddima: logic_prog: do you want to make sure nobody else can understand the code? ;)

4:32 logic_prog: ddima: I work alone

4:34 those who say perl is unreadable has not seem bad clojure :-)

4:35 ddima: would be nice if there was a site "badclojure" or something with examples ;)

4:37 Arafangion: Bad code can be written in any language. :)

4:38 ryanf: how do people feel about speclj?

4:43 nones: how big overhead give agents?

4:43 can I make 10.000 agents?

4:44 logic_prog: agents, afaik, are very chepa

4:47 TEttinger: bitemyapp: http://www.reddit.com/r/Coffee/comments/1abp48/question_i_swear_i_am_not_gonna_do_this_but_if/c8w18bw now I'm curious

4:47 logic_prog: in emacs, what is the most dumbass way to have a certain keyword colored differetly?

4:47 for example, I want the word "foo" to be red always

5:03 ddellacosta: ryanf: regarding how I feel about speclj, Stuart Halloway explains it well here: http://vimeo.com/77199361

5:23 yedi: someone should write "the seasoned reasoned schemer"

5:24 oh they were written by the same dude... makes more sense now

5:36 TEttinger: the seasoned roasted schemer

5:38 arcatan: are there any other -easoned words?

5:38 TEttinger: treasoned

5:51 dyreshark: weasoned http://www.merriam-webster.com/dictionary/weason

6:59 nones: is there ways to use in struct own property?

6:59 eg.: (struct smth :arr [7 8 9] :length ???)

7:00 roland_: hi in datomic, could you use a rule within another rule?

7:01 jcromartie: seriously, screw protocols and records for use as "objects"

7:01 if your records are long lived

7:01 recompiling means recreating records before you see new behavior

7:01 bleh

7:02 nones: what are you trying to achieve

7:02 AFAIK structmaps are all but dead

7:02 nones: I have this struct:

7:03 (defstruct unit :points :width :height)

7:03 I init unit:

7:05 (struct unit :points (case type

7:05 :medic [[0 1 0]

7:05 [1 1 1]

7:05 [0 1 0]

7:05 [1 1 1]]

7:05 :spy [[1]])

7:05 :width

7:05 :height

7:05 )

7:05 jcromartie: can width and height be a function of the points

7:05 ?

7:05 or are they not necessarily related?

7:05 and why are you using a defstruct instead of just a map

7:06 babilen: (or record)

7:06 nones: width and height are constants

7:07 jcromartie: constants?

7:07 nones: they calculated only in init

7:11 jcromartie: OK so anyway, what's your question? I am not sure

7:11 nones: it looks like you're making a game?

7:12 nones: jcromartie: yes, you right

7:12 jcromartie: cool! always happy to see game dev in Clojure

7:13 now, how well it works is yet to be determined :)

7:14 nones: I want set width and height depending on points 2d array

7:19 ok, I decided to go other way

7:21 jcromartie: nones: are you sure you need to cache those values?

7:21 rather than use a function?

7:21 is this a real-time game

7:22 like, high framerate? with lots of lookups of the height/width of these things?

7:22 there are lots of ways you could optimize it: if there are just a few possible point vectors, then you could just memoize the height and width functions

7:23 (def height (memoize (fn [points] (count points))))

8:20 augustl: dnolen: hey :) Any idea how well Om performs in IE9? Is mori reasonably fast? Is it still fast with setTimeout 16 instead of requestAnimationFrame?

8:54 xsyn: The pedestal docs and the pedestal tutorial look very different from each other

8:57 jcromartie: how do you name your reference types?

8:58 like, an atom shouldn't be called "state"

8:58 but that's the temptation

9:03 or naming futures that represent simple values

9:40 pepijndevos: Would it be possible to "rebase" a hash trie?

9:53 jcromartie: I wish Emacs clojure-mode had better logic for string fill, like it does for comments

9:54 comments work flawlessly, but strings end up applying fill to the surrounding code

9:54 especially awkward with doc strings

9:54 roland_: jcromartie: clojure-fill-docstring

9:55 jcromartie: damn

9:55 thanks!

9:56 I guess I could rebind that to M-q

9:56 roland_: np :-) i remember when i was desperately looking for it

9:56 jcromartie: I dont see the need for standard fill mode anywhere in Clojure code

9:56 roland_: i had at one time stuck to using comments intead of docstrings

9:56 jcromartie: but then what about comments… huh

9:57 nonrecursive: roland_: thank you! that's driven me nuts

10:04 pepijndevos: How does Clojures maps compare to b-trees with 32 leave nodes?

10:05 peterdon`: >>>/quit

10:10 xk

10:16 hyPiRion: pepijndevos: way faster on average

10:16 but it doesn't really make sense to compare maps to vector-like structures

10:17 pepijndevos: hyPiRion, you can turn any vector into a map by hashing the key and using as an index :)

10:18 xsyn: ugh pedestal confuses me

10:18 pepijndevos: But ok, a clojure vecctor pretty much uses the same underlying structure as a map, lot lets use that.

10:19 I know that CouchDB uses an append-only B+ tree with structural sharing for storage

10:19 That sounds an awefull lot like clojure vectors. So why a B tree if the clojure thing is faster?

10:20 Probably something with disk seek time?

10:23 hyPiRion, ?

10:25 gfredericks: (merge #{} #{}) ;; any guesses what this returns?

10:26 hyPiRion: pepijndevos: hmm, that's interesting. I would guess the B+-tree is inferior speed wise, but there may be some serialisation issues

10:26 disk seek time shouldn't be a concern

10:26 ,(merge #{} #{}) ;; Gogo clojurebot

10:26 clojurebot: #{#{}}

10:27 gfredericks: yaaay dynamic types amirite

10:27 pepijndevos: wat

10:27 hyPiRion: gfredericks: haha, it's using the ##(conj {:foo :b} {:bar :a}) trick

10:27 lazybot: ⇒ {:bar :a, :foo :b}

10:27 gfredericks: of course what I wanted was either into or clojure.set/union

10:27 hyPiRion: yeah I know I hate that trick

10:27 pepijndevos: waat

10:28 hyPiRion: One of the few things stranger than when-first

10:28 pepijndevos: waaat

10:28 I though Clojure made sense...

10:29 gfredericks: conj has this weird inexplicable edge case

10:29 ,(conj {1 2 3 4} {5 6 7 8})

10:29 clojurebot: {7 8, 5 6, 1 2, 3 4}

10:30 gfredericks: I have never heard an argument that that^ shouldn't throw an exception

10:30 but it seems to have been at least mildly intentional

10:30 hyPiRion: that's like, stranger than edge cases from IEEE-754

10:30 pepijndevos: $source conj

10:30 gfredericks: I actually haven't heard any comment on it at all from anybody on the core team even

10:30 lazybot: conj is http://is.gd/U6MjEm

10:30 gfredericks: pepijndevos: it's probably buried inside the cons method on APersistentMap

10:31 pepijndevos: I thought so...

10:31 gfredericks: presumably it is too late to change now

10:31 hyPiRion: gfredericks: we can riot on the next conj

10:31 pepijndevos: clojure.lang.RT always

10:31 gfredericks: I wonder if they are opposed to changes like that for 2.0

10:32 pepijndevos: So the question is what cons for a map does

10:33 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L24

10:33 gfredericks: pepijndevos: cons for any collection usually adds an "item" to that collection; for maps it only makes sense that you should be able to add a mapentry

10:33 pepijndevos: yes, but a map is a mapentry?

10:33 gfredericks: a quasi-map-entry at least

10:33 no

10:33 that's the edge case

10:33 cons on maps also accepts a map

10:34 and merges them

10:34 pepijndevos: ...

10:34 Ok, so what about the other 2?

10:34 gfredericks: the other 2?

10:34 pepijndevos: #source merge

10:34 $source merge

10:35 lazybot: merge is http://is.gd/8qKYI3

10:35 pepijndevos: yea, merging 2 sets and when-first

10:35 also points back to cons

10:36 gfredericks: merge is because of cons

10:36 pepijndevos: yea, so it's just ##(.cons #{} #{})

10:36 lazybot: ⇒ #{#{}}

10:41 hyPiRion: pepijndevos: Yeah, the B+-tree in CouchDB uses removal, in which case a persistent vector is slower

10:41 It just does so internally

10:45 pepijndevos: hyPiRion, removal?

10:46 Like, removing elements is slower from a vector?

10:47 hyPiRion: pepijndevos: yes, when they're in the middle of the vector

10:47 pepijndevos: Why?

10:47 clojurebot: Why is startup slow is busy compiling the `for` macroexpansion

10:48 hyPiRion: because a B+-tree nodes can be half the maximum size, whereas vectors must be the exact size

10:49 pepijndevos: oh. hmm, thinking about that...

10:50 yes, that sounds right. But that doesn't apply to hash maps. And in dtabases and filesystems you're using a b-tree to look up keys, right?

10:51 Vlad4Justice: pepijndevos, hai pop.

10:51 Vind jij Pim Fortuyn ook de grootste Nederlander?

10:51 pepijndevos: Vlad4Justice, offtopic

10:52 Vlad4Justice: pepijndevos, mag hier.

10:52 Lenient kanaal, ik zit hier al 5 jaar en ben nog nooit geband, kan je nagaan.

10:52 En ik maak grappen over de holocaust

10:52 Op #haskell was ik er meteen uitgeknald na de eerste holocaust grap

10:52 pepijndevos: at least talk english so others can enjoy the jokes

10:52 Vlad4Justice: It is true

10:52 everyone should be privy of holocaust humour

10:53 All those jews would've surely died for nought if not everyone could enjoy the finest holocaust jokes.

10:54 pepijndevos: hyPiRion, or I'm misunderstanding something about how databases and filesystems work.

10:55 I seem to remember maps use some clever bit twidling to have sparse child references packed together.

10:55 hyPiRion: pepijndevos: true, doesn't apply to maps. No idea what CouchDB does, but it has an element removal function.

10:56 pepijndevos: Maybe I should ask in #couchdb

10:57 hyPiRion: hmm, yeah, sounds like an idea

10:58 pepijndevos: What is the name of the thing that vector uses?

10:59 hyPiRion: structural sharing? path copying?

11:01 pepijndevos: map uses HAMT, and wikipedia says "A HAMT is an array mapped trie where the keys are first hashed [...]"

11:03 hyPiRion, anyway, thanks for thinking along :)

11:04 hyPiRion: np

11:18 jcromartie: woah, I thought records were equal when their fields were equal?

11:19 is this more AOT bullshit or something?

11:19 hyPiRion: maybe, or that the fields aren't equal

11:20 jcromartie: they absolutely are

11:20 it's just when I print and read the record

11:21 look at this weirdness https://gist.github.com/anonymous/57fbb6f1637b30a2075d

11:21 e and e' are def'ed earlier as a record and (read-string (pr-str e)) respectively

11:22 the class even appears to be the same

11:22 but it's not

11:22 same name? different class?

11:22 AOT

11:24 I am really frustrated with the way records and protocols have completely screwed me over in the REPL

11:26 yup

11:26 so get this

11:27 since I have a -main, I have to AOT that namespace, which in turn AOTs the namespace that has a record type that is used to serialize events in the system

11:27 if I recompile my model which contains that defrecord, then the whole thing breaks when I do a certain sanity check for the serializability of events

11:27 yay

11:33 roland_: jcromartie: why is (class e) not equal (class e')

11:34 jcromartie: roland_: that's awfully confusing isn't it?

11:34 they are not the same class

11:34 they have the same name

11:35 but I assume one is the AOT class and one is recompiled

11:35 roland_: same fqn yea

11:35 how is that possible if they are loaded with the same classloader?

11:35 jcromartie: ,(instance? java.io.Serializable (fn []))

11:35 clojurebot: true

11:35 jcromartie: lies

11:35 LIES

11:36 technomancy: yeah, sothis is why I don't use records

11:37 hyPiRion: jcromartie: whoa, nice find

11:38 jcromartie: technomancy: I'm starting to believe you

11:38 :)

11:39 gfredericks: clojurebot: so this is why I don't use records

11:39 clojurebot: You don't have to tell me twice.

11:39 jcromartie: I know records were designed for where type-based-dispatch polymorphism is the only way to make it fast

11:40 gfredericks: records are what happened when deftype and APersistentMap had a baby

11:41 jcromartie: my wife is hunting our 3 year old with a nerf gun… it's disturbing

11:47 I'm also beginning to like the sound of a single global database connection

11:55 sritchie: any enlive gurus around?

11:59 zerokarmaleft: can friend wrap a set of routes with authentication?

12:00 i.e. (friend/authenticated some-big-defroutes)

12:00 roland_: more like (friend/authenticate routes config)

12:01 zerokarmaleft: roland_: isn't that just to enable the middleware?

12:01 roland_: oh yea

12:02 but you can enable the middleware on a selection of routes

12:03 and the for each handler, you have friend/authenticated ...

12:03 zerokarmaleft: yea, that's what I'm doing currently, I was just seeing if I could DRY out the friend/authenticated wrapping of the body of each handler

12:04 roland_: oh ok. I see, i just use a macro :-)

12:06 hyPiRion: $karma zerokarmaleft

12:06 lazybot: zerokarmaleft has karma 1.

12:07 hyPiRion: the nickname lies

12:07 dsrx: $karma dsrx

12:07 lazybot: dsrx has karma 0.

12:08 zerokarmaleft: hyPiRion: :(

12:52 deadghost: I just realized code golf is programming sudoku

12:54 dnolen: augustl: I'd imagine Om works fine on anything that React works fine on

12:54 augustl: as far as persistent data structure perf, I can't imagine it being a problem on IE9 in many cases

13:01 Raynes: Guys. I might switch back to Emacs.

13:02 Just thought you all should know.

13:02 yedi: Raynes: what r u using

13:02 Raynes: I've been using Vim for quite a while.

13:02 I tend to switch between editors a lot.

13:03 The motivation for switching back to Emacs is mostly because it is annoying to use Vim for everything *but* Haskell.

13:03 And Vim is horrific for Haskell.

13:06 deadghost: I've been using evil and it's been great

13:08 Raynes: deadghost: Yeah, I'm a fan. I used Emacs with evil mode for a long time.

13:09 deadghost: any reason for using vim as opposed to emacs + evil?

13:13 Raynes: deadghost: At the time it was just because I was bored with staring at Emacs all day and wanted to switch things up a bit.

13:15 pdk: what's wrong with vim's haskell support

13:16 Raynes: pdk: Horrible indentation, primarily.

13:16 pdk: are haskell's indentation rules that complicated

13:16 i mean with lisp it's already more complex than say indenting c/c++

13:18 Raynes: Lisp's indentation 'rules' are aesthetic. Haskell has significant whitespace and frequently 15 different ways to indent the same expression, some of which could make it mean different things.

13:18 deadghost: oh god what

13:18 augustl: dnolen: cool, thanks

13:18 deadghost: I didn't know that

13:19 Raynes: Vim just doesn't handle this sort of thing well, but someone could certainly write a better plugin. They just don't because Emacs is already good at it.

13:20 deadghost: emacs makes it easier by giving letting you toggle through possible indentations with tab.

13:21 miltondsilva: hi, I'm using emacs and I cant get 2 space indent working for all sexps in clojure-mode. I tried using (setq clojure-defun-style-default-indent t) but when I type (some-very-long-function-name arg1... it doesnt get indented as showned in the wiki (https://github.com/clojure-emacs/clojure-mode)under "whereas turning on the "always 2 spaces" option yields this:". Any ideias on how to solve this?

13:23 also, in the scracth buffer indentation is also not "pretty printed" (2 space always) and the major mode is different lisp instead of clojure

13:24 with defun it works okay but other sexps it aligns with the first char of the first argument

13:25 dsrx: the scratch buffer, afaik, is in lisp mode (emacs lisp) by default

13:26 "defun" is an emacs lisp form, not a clojure one

13:29 miltondsilva: yes. I know. My problem is with the clojure indentation but I'm saying that in other lisp modes it also doesnt work as I expected.

13:30 that could provide usefull information for people that tried to help me ;)

13:33 roland_: anyone able to dangerouslySetInnerHTML with om?

13:33 deadghost: hmmm ehhhhhhh can I use a function literal with no function in it?

13:33 for example #(%2) instead of #(do %2)

13:34 arrdem: ,(#(%3) 0 1 2)

13:34 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

13:35 arrdem: deadghost: you should really be using first/second rather than trying to be cute like that..

13:35 deadghost: arrdem, I'm playing code golf on 4clojure

13:35 and it's telling me to be cute by not using last

13:36 jonasen: Bronsa: why do you macroexpand here? https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer.clj#L190

13:36 deadghost: so I'm using reduce #(do %2) instead

13:36 and trying to shorten it

13:36 arrdem: hum... I don't think of anything.

13:36 yedi: man, datalog / logic programming is so sexy

13:42 roland_: oh so #js tag isnt recursivve

13:43 scottj: roland_: yeah, was a bit bummed by that

13:43 roland_: scottj: interesting

13:43 scottj: (I'm guessing there's a good reason though)

13:44 roland_: yes, it would otherwise be impossible to embed clojure objects in a js object

13:44 scottj: well, if that were less common couldn't you use metadata to escape the #js?

13:44 Bronsa: jonasen: tools.analyzer.jvm's macroexpand-1 macroexpands Integer/MAX_VALUE in (.- Integer MAX_VALUE) for example, so that we only need to handle the host "." form and not the foo/bar form

13:45 roland_: scottj:how will that work?

13:45 scottj: roland_: no idea ;)

13:46 roland_: me thinking that that would require you to include deep paths in the metadata for escaping, which can easily become painful :)

13:47 yedi: i have this datalog query that returns nothing, i'm tryna get a poem's analysis by the poem's title: https://gist.github.com/yedi/8162720

13:48 when i put the query into the console, it works fine. but using it from my app code here doesn't work

13:50 i think it has something to do with the fact the query data structure is quoted before being sent to (d/q)

13:50 though im not sure why that's necessary since i though vectors evaluated to themselves anyways

13:55 nvm, figured it out

13:56 devn: hola

13:56 where is monitor-enter and monitor-exit defined?

13:56 ,#'clojure.core/monitor-enter

13:56 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: clojure.core/monitor-enter in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:56 Bronsa: they are special forms, not var

13:57 devn: d'oh

13:57 thanks Bronsa

13:58 funny that I don't think I've ever really used them, same with ,#'clojure.core/locking

13:58 but i guess the clojure.org description basically says don't use them, so not a huge surprise there

14:24 nmws: I've read a lot about agents (Clojure Programming book, online etc.) but I'm still struggling to get a fully worked out example in my head

14:27 Raynes: arrdem: All of them! ALL of them!!!!

14:27 (none of them, actually)

14:27 arrdem: Raynes: oh good. bullet doged.

14:27 Raynes: arrdem: Well, except for nrepl since I had to switch over to cider.

14:27 arrdem: I think I still have crap kicking around that (require 'nrepl)s

14:27 yerp.

14:31 jonasen: Bronsa: got it. Thanks

15:08 technomancy: https://twitter.com/ClojureMarkov

15:11 hiredman: Bronsa: I saw your datomic tweet, looks neat, have you done anything with core.logic on the analysis tree? I think with core.logic you could do queries over the tree without flattening it out as entities first (although doing that first may be a good idea anyway)

15:12 dsrx: hmm, won't be too long until ClojureMarkov retweets some of my thoughts about clojure :)

15:13 arrdem: technomancy: is that a bot that finds other bots using "clojure" or what...

15:14 seems really good at picking out the spambots :P

15:14 technomancy: it's not a bot; they're hand-curated

15:14 spam only

15:20 Clome: is there a naming convention for constants? Like (my-method MY-CONSTANT) or (my-method my-constant)

15:20 clojurebot: It's greek to me.

15:20 technomancy: Clome: the convention for constant is (def whatever 12)

15:21 you use lower case with dashes

15:21 Clome: is there a way to define keywords? like (def :my-constant 4) ?

15:21 insamniac: waitwhat

15:21 technomancy: no, keywords always evaluate to themselves

15:22 Clome: damn

15:22 technomancy: that's kind of the whole point of keywords

15:22 insamniac: don't worry, you're not the only person scratching their head

15:22 i'm a clojure nub too

15:22 Bronsa: hiredman: not yet -- I haven't really played with core.logic much. That's something that I want to do but I need to find some time first. Might even consider rewriting some passes using core.logic if it proves to be fast enough/easier, but I need to get familiar with it first.

15:23 technomancy: I've seen some CONSTANT in core.async impl code, made my eyes bleed.

15:23 Clome: i am not scratching my head, i just would like a better way to define constants, so i get dont confuse them with variables.

15:23 technomancy: oh dear

15:24 arrdem: Clome: ... why would that ever be an issue?

15:24 hiredman: Clome: what variables?

15:24 technomancy: there are no variables

15:24 so that should make it easy

15:24 pdk: you could have a map from keywords to associated values

15:24 {:my-constant 4}

15:24 then look up that map for the value you want for :my-constnat

15:24 constant

15:24 arrdem: pdk: if you ever write production code like that I will find you

15:25 Clome: pdk thats slow

15:25 insamniac: lulz

15:25 Clome: i need speed

15:25 pdk: why not just name them const-constantname then

15:25 insamniac: that was going to be my suggestion too

15:25 pdk: or stick a - on them

15:25 Clome: (lwjgl/gl-create-shader lwjgl/gl-vertex-shader) vs (lwjgl/gl-create-shader :gl-vertex-shader), look how nicer the second example is, too bad it has drawbacks

15:26 insamniac: mole hill

15:27 rovar: what about a set of aliases?

15:27 that someone would just :refer :all

15:27 so it would be (lwjgl/gl-create-shader gl-vertex-shader)

15:27 put your constants/aliases in a separate namespace

15:30 Clome: rovar: namespace prefix is not an issue, I would like to use clojure constructs so i get proper highlining

15:32 Would people get mad if you use a custom neming convetion for constants? like MY-CONSTANT or _my-constant or should I just leave it normal my-constant. Feedback please?

15:32 hiredman: people have given you feedback, you just don't like it

15:33 arrdem: (inc hiredman)

15:33 lazybot: ⇒ 31

15:33 gfredericks: whoever was saying yesterday that _ as the first arg in a protocol impl is smelly

15:33 I disagree

15:34 mainly because the deftype/defrecord fields are accessible directly

15:34 hiredman: gfredericks: sure, it happens a lot in my experience

15:34 gfredericks: hiredman: yeah mine too; I just hadn't thought of that exact point at the time it was being discussed

15:34 hiredman: gfredericks: or if you are using reify

15:35 gfredericks: good old reify

15:41 Clome: hiredman: It is not that I do not like them. I like pdk`s suggestion about the prefixes "constant" or "-", just do not know if people using clojure do this type of stuff or just leave it normal. Would have liked more opinions but w/e, I will stick with normal naming convention.

15:42 dsrx: (def ^:const my-constant 42) ?

15:42 i mean, that won't prevent it from being redefined...

15:43 but at least it's inlined, and the metadata is a good hint to not redefine it

15:44 hiredman: dsrx: I would recommend against using someone new to clojure using :const

15:44 Bronsa: dsrx: once it gets inlines, even if you redefine it, you won't notice the value change

15:48 gfredericks: i.e., the semantics of code reloading get more complicated

15:53 yedi: saddest thing about cljs is how many js libs require jquery

16:00 brainproxy: is it possible to "dual license" a Clojure project under EPL with option of a commercial license? seems like the EPL doesn't prohibit that, but wondering if there are examples of companies/developers doing so?

16:01 Clome: drsx: nice, I will probably use that, I have read on stackoverflow that it is much faster cuz it skips all indirect calls to that constant, if I understood it correctly it just replaces it at compile itme.

16:02 gfredericks: do you mean that if I define it with ^:const I won`t be able to redefine it at runtime?

16:02 rovar: brainproxy: you are welcome to release your commercial product under whatever licence you like as long as you wrote it

16:03 arrdem: Clome: correct. By using ^:const you are giving the compiler permission to play tricks with your constant value, because you are swearing that you won't change it ever. That's what Bronsa and gfredericks were on about.

16:04 and when you start telling the compiler lies....

16:06 Clome: awesome, thanks

16:08 arrdem: anyone got a cond-> example kicking around?

16:09 Morgawr: arrdem: I don't have code lying around but maybe this can be of help http://stackoverflow.com/questions/13830194/clojure-new-cond-macro

16:10 gfredericks: arrdem: I use cond-> all the time for any kind of conditional modification

16:10 it's less repetition than (if (foo) (bar x) x)

16:10 and less readable to beginners!

16:10 [1]brian: i remember something on hacker news about a Clojure editor plugin/library used to transform Clojure code into idiomatic form, does anyone know what i'm talking about?

16:11 arrdem: gfredericks: right. I've recently fallen in love with as-> and I just tried to use cond-> with limited success, hence the question.

16:11 roland_: ,(cond-> [] (even? 2) (conj :even) (odd? 3) (conj :odd))

16:11 clojurebot: [:even :odd]

16:12 jkj_: gfredericks: !

16:12 arrdem: gfredericks: I thought that the condition got ->'d with the value too, hence my confusion.

16:12 jkj_: i thing like that exists

16:12 amaze, wow

16:12 gfredericks: arrdem: ah right; I want that too sometimes; I wrote such a thing and pasted it in here once

16:13 it must have been a one-liner

16:13 arrdem: gfredericks: feh. I'd bet so.

16:14 roland_: as-> is awesome as well

16:14 gfredericks: oh I think I called it cond->->, so that's searchable

16:14 * gfredericks goes grepping

16:14 * arrdem is sad that his IRC logs aren't comprehensive

16:15 jkj_: amazing. cond-> will shorten my code a lot

16:15 arrdem: jkj_: now check out as-> and be more amaze

16:15 gfredericks: quoting myself:

16:15 (defmacro cond->-> [x & pairs] (if-let [[c form & more] (seq pairs)] `(let [x# ~x] (cond->-> (if (-> x# ~c) (-> x# ~form) x#) ~@more)) x))

16:15 arrdem: $(do rant about lack of maintained paste library)

16:15 Morgawr: mmm... can someone provide an example of as->? I just found out about it and I can't quite understand how it works (seems cool)

16:16 amalloy: gfredericks: fwiw the seq there isn't strictly needed

16:16 roland_: ,(as-> 3 a (+ a 4))

16:16 clojurebot: 7

16:16 arrdem: ,(as-> 1 foo (inc foo) (+ 1 foo) (+ foo 5))

16:16 clojurebot: 8

16:16 Morgawr: ah!

16:16 gfredericks: ,(as-> 42 <> [<> <> :foo <> (+ <> <>)]) ; unhelpful example

16:16 clojurebot: [42 42 :foo 42 84]

16:16 Morgawr: amazing! thanks

16:16 gfredericks: amalloy: I think I wondered that and didn't know if there was a guarantee about it

16:16 Morgawr: gfredericks: most helpful of all haha

16:16 arrdem: Morgawr: the win of as-> is when you don't have a clear first or last parameter that you always want to thread too.

16:17 gfredericks: I acutally have a -<n> macro kicking around that used <>.....

16:17 jkj_: amaze!

16:17 gfredericks: I'm always using as-> when I'm threading a thing that ends up being the second of 3 args to reduce

16:17 Morgawr: so it's pretty much like doing (let a (-> initial_value f1 f2 f3)) ?

16:17 arrdem: Morgawr: bingo.

16:17 gfredericks: arrdem: yeah I can't use anything besides <> after seeing the swiss arrows lib

16:18 Morgawr: man, this will prettify my code a lot, I always do some stupid stuff like (#(f1 p1 % p2)) when my parameter is the second one in a threading macro

16:18 jkj_: i use (-> (#(... % ...)) fubar things... or nested (->> (-> crapness

16:18 Morgawr: ^

16:18 arrdem: gfredericks: I've had swiss arrows in my profile forever but I've never found them compellingly useful.

16:18 jkj_: i see waking up today wasn't for nothing

16:18 gfredericks: arrdem: I don't think I ever used it. but I loved <>

16:18 <_> would be interesting too

16:18 arrdem: lol

16:19 gfredericks: or ___

16:19 * arrdem wanders off to investigate how many smiley faces he can come up with that would be valid symbols

16:20 decaf: (javadoc) tries to load docs in a swing frame. google doesn't help

16:20 gfredericks: ,(as-> 1.5 $1.50 (* 3 $1.50))

16:20 clojurebot: #<CompilerException java.lang.ClassFormatError: Illegal field name "$1.50" in class sandbox$eval122, compiling:(NO_SOURCE_PATH:0:0)>

16:20 decaf: cause I want to set browser in java, not java plugin in browser

16:20 arrdem: ,(let [ಠ_ಠ 3] ಠ_ಠ)

16:20 clojurebot: 3

16:20 arrdem: gfredericks: ^

16:22 gfredericks: unicode is like cheating

16:23 arrdem: I use the tex input mode in all my markdown files, and I have an emacs macro that shortens fn to the \lambda symbol

16:23 decaf: terminus has no 0CA0 and I don't care

16:23 arrdem: it's really confusing every time I start writing clojure because somewhere I'll try to write (\lambda [a b ]... ) and then catch myself

16:25 gws: [1]brian: could you be referring to https://github.com/jonase/kibit

16:25 [1]brian: yep found it. thanks

16:31 pepijndevos: Is there a way to serialize Clojure data maintaining structural sharing?

16:32 like (deserialize (serialize [universe (assoc universe :foo :bar)])) and not end up with 2 universes.

16:34 arrdem: hum... is there a unicode lparen/rparen?

16:35 pepijndevos: Is the ascii one not good enough?

16:36 gws: arrdem: http://stackoverflow.com/questions/13535172/list-of-all-unicodes-open-close-brackets


16:36 arrdem: (ing gws)

16:36 (inc gws)

16:36 lazybot: ⇒ 5

16:37 arrdem: ❨^.^❩

16:37 ,(let [❨^.^❩ 4 ಠ_ಠ 3] (* ❨^.^❩ ಠ_ಠ))

16:37 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

16:37 arrdem: fack

16:38 that was almost really goo

16:38 d

16:39 gfredericks: find a unicode carrot

16:39 pepijndevos: What's the cool thing to write TCP servers in these days?

16:39 gfredericks: carot

16:39 tarot

16:40 gws: caret

16:40 * gfredericks gives up

16:40 gfredericks: pepijndevos: netcat

16:40 arrdem: cljcat!

16:40 gws: pepijndevos: node.js

16:40 pepijndevos: (use 'netcat)

16:40 gws: lol

16:41 pepijndevos: I suppose Aleph would be a decent choise, but I'm suprised noone did a Netty + core.async thing the day it was released.

16:41 gfredericks: netcat is a nerdy superhero

16:41 arrdem: just remember to set $LEIN_IRONIC_JURE kids

16:41 gfredericks: arrdem: of course I export it in my .bashrc

16:41 technomancy: pepijndevos: raw Java ServerSockets are fine too for most things

16:42 you don't have to turn your program flow inside-out just because you're choosing raw TCP over HTTP, that is

16:43 pepijndevos: ?

16:43 inside out?

16:43 technomancy: pepijndevos: async vs threads I mean

16:43 pepijndevos: Oh I see

16:45 technomancy: I understand why it's necessary sometimes, but the assumption of "I want tcp sockets; better use aleph" leads to newbies getting thrown into the middle of stuff that's a lot more complicated than it needs to be

16:45 just throwing that out there

16:48 pepijndevos: technomancy, yea, for most thinks a simple thead and a socket is more than enough

16:49 technomancy: you and I know that, but with all the buzz and conf talks about core.async I wonder if newcomers are getting a different message

16:49 pepijndevos: It's definitely fun to play with core.async

16:50 technomancy: boring sockets don't make the HN front page

16:50 arrdem: lol

16:50 pepijndevos: I should try

16:51 "developer writes server using theads and sockets"

16:51 technomancy: "look how it's only 80% as many lines of code!"

16:52 pepijndevos: but then I'd actuallly have to do something. For hello world, the boilerplate dominates the async/sync difference

17:05 CaptainLex: I have a few hashes of the form {:foo a :bar b} {:foo a :bar c} and I would like to combine them into a single hash of the form {:a [b,c]}. This doesn't quite seem like a job for map.

17:06 But it sounds exceedingly fnal

17:06 JasonFelice: I keep wanting there to be a function in clojure.core where (= '([1 2 3 4] [2 3 4] [3 4] [4]) (f [1 2 3 4]))

17:07 TEttinger: CaptainLex, seems like an odd result value

17:07 JasonFelice: CaptainLex: merge-with

17:07 Oh, I didn't read the whole thing. Not merge-with.

17:08 CaptainLex: TEttinger: Well, the specific case is a bunch of hashes with dates and time; I'd like to combine then into a hash where times are keyed to their dates

17:08 So really you'd have a hash at the end that looks like {:a [b,c] :d [e,f,g]} etc

17:08 JasonFelice: CaptainLex: clojure.set/index does something similar, maybe that's useful.

17:09 TEttinger: so CaptainLex, you want the :foo and :bar stripped out right?

17:10 CaptainLex: TEttinger: Well, as long as I'm grouping times by date, I'm neutral as to whether :foo and :bar are still present

17:10 TEttinger: ok, uh I just woke up, do you have any sample data and sample results?

17:11 CaptainLex: Hahah yeah, lemme mock something up

17:13 {:date 2013/12/28 :time 19:30}

17:13 {:date 2013/12/28 :time 21:30}

17:13 {:date 2014/1/1 :time 19:30}

17:13 {:date 2014/1/1 :time 21:30}


17:13 =>


17:13 [{:date 2013/12/28 :time [19:30, 21:30]}, {:date 2014/1/1 :time [19:30, 21:30}] ;;Something like this

17:14 arrdem: ~paste

17:14 clojurebot: paste is not gist.github.com

17:14 CaptainLex: Woops

17:14 arrdem: eez cool, just something to be aware of.

17:14 ~refheap

17:14 clojurebot: https://www.refheap.com/

17:14 arrdem: is also acceptable

17:15 CaptainLex: https://www.refheap.com/22267 :{

17:15 :P*

17:15 arrdem: CaptainLex: danke :D

17:15 sritchie: magnars: hey, thanks for the help

17:15 upgrading now

17:16 CaptainLex: I can see broadly how this works, but actually implementing it in the language is trickier

17:16 magnars: sritchie: my pleasure! I want optimus to be a really solid piece of software. So thanks for reporting issues :)

17:16 arrdem: CaptainLex: I suspect that you're gonna want some combination of reduce, contains and conj.

17:17 sritchie: magnars: I think your new issue covers it, but just to make sure,

17:17 I actually wasn't seeing a base URL for contextless paths

17:18 magnars: with a base-url of "https://cdn.paddleguru.com", for example, and an asset of "/img/logo.png", the images inside the CSS wouldn't get the base, though the CSS file itself would

17:19 magnars: sritchie: no, adding a :base-url to an asset won't fix its contents. Or the contents of any referencing assets either. If you want the :base-url in CSS files, you need to replace its :contents "manually" in the transformation function. However, it isn't necessary to do that if your :base-url doesn't have a context-path. In your case, even tho the CSS doesn't

17:19 explicitly link to http://cdn.paddleguru.com - the images will still be served from there when referenced with absolute URLs.

17:21 sritchie: absolute URLs meaning, "/img/logo.ong"?

17:21 png*

17:21 that's the part I'm not clear on, on why it's not necessary without the context pathj

17:21 magnars: yes - when the CSS is served from paddleguru, any absolute URLs in the CSS will also be served from there

17:21 sritchie: oh, interesting

17:22 so the context bug doesn't affect me, then. accidental sleuthing

17:22 magnars: boom, awesome

17:22 magnars: excellent! :)

17:27 TEttinger: CaptainLex:

17:27 ,(apply merge-with #(flatten (conj [%1] %2)) (mapv (fn [m] {(:date m) (:time m)}) [{:date "2013/12/28" :time "19:30"} {:date "2013/12/28" :time "19:31"} {:date "2013/12/28" :time "21:30"} {:date "2014/1/1" :time "19:30"} {:date "2014/1/1" :time "21:30"}]))

17:27 clojurebot: {"2014/1/1" ("19:30" "21:30"), "2013/12/28" ("19:30" "19:31" "21:30")}

17:27 TEttinger: not the right format, quite yet

17:28 CaptainLex: TEttinger: Thank you! :D I'll poke around with it :)

17:28 TEttinger: no prob

17:28 good wake-up task

17:30 ,(mapv (fn [[k v]] {:date k :time (vec v)}) (apply merge-with #(flatten (conj [%1] %2)) (mapv (fn [m] {(:date m) (:time m)}) [{:date "2013/12/28" :time "19:30"} {:date "2013/12/28" :time "19:31"} {:date "2013/12/28" :time "21:30"} {:date "2014/1/1" :time "19:30"} {:date "2014/1/1" :time "21:30"}])))

17:30 clojurebot: [{:date "2014/1/1", :time ["19:30" "21:30"]} {:date "2013/12/28", :time ["19:30" "19:31" "21:30"]}]

17:30 sritchie: magnars: actually, seeing java.lang.Exception: Two assets have the same path "/cljs/reset-codes.js", but are not equal.

17:31 magnars: It's a good thing it put that in there then.

17:31 I wonder how they differ. That might be relevant information. :P

17:31 sritchie: magnars: well, there's only one file, actually

17:31 with that names

17:31 name*

17:32 magnars: Somehow there's ended up with two assets with that path loaded. You could do a filter in the list of assets and see?

17:33 sritchie: okay, trying that out

17:34 probably one's inside a bundle

17:34 and the other's not

17:35 magnars: That sounds very likely.

17:35 Bundled files are still available on the original paths, so there's no need to include them twice.

17:35 I could add a specific error message for that case.

17:35 sritchie: let's see

17:38 magnars: so, here's what it is

17:38 magnars: I've got a bundle with some files, which I had thought was just a particular grouping of those files -

17:38 and then another call to (assets/load-assets "public" [#"/cljs/.+\.js$"])

17:39 magnars: but I don't quite understand why the contents would be different.

17:40 magnars: The contents are the same - it's the :bundle property that's triggering the error.

17:40 There's also the case that you might want to have one file in two different bundles.

17:40 sritchie: yup

17:40 magnars: So while the exception has brought to light an issue, I'm not entirely sure what to think of it yet.

17:41 sritchie: could you ignore the bundle property in the equality check?

17:41 logic_prog: is there a way to tell "lein cljsbuild auto" that "whenever you rebuild, kill existing chrome, fire up a new chrome, and have it load up url __BLAH__ " ?

17:41 magnars: sritchie: I can do that for now.

17:45 sritchie: magnars: https://github.com/magnars/optimus/pull/10

17:45 magnars: this is where type classes for custom equality comes in handy

17:46 magnars: Indeed. But I don't think this is the solution going forward - since it will now collapse down to just one asset - losing any different :bundle definitions.

17:47 I can merge your PR to fix your issue now, but it will have to be handled differently soon.

17:48 sritchie: yeah, that makes sense. I wonder if I should change it to pick the asset with a bundle definition, if either has one

17:48 magnars: sritchie: How about instead, I make sure assets are distinct on the juxt of :path and :bundle ?

17:48 sritchie: that works for me

17:48 magnars: ok, I'll get on that

17:49 sritchie: mine's buggy anyway, since if the non-bundled version comes first, you lose the bundle information

17:50 magnars: yeah, could be solved by doing a merge in the reduction tho

17:57 sritchie: 0.13.2 released

17:57 sritchie: trying now

18:02 okay, works great

18:02 thank you sir

18:02 magnars: Good to hear :-)

18:04 arrdem: (inc magnars) ;; good mantainer points!

18:04 lazybot: ⇒ 1

18:04 magnars: My first point! Thank you arrdem :)

18:08 sritchie: magnars: it looks like Chrome actually does require a cache-control header

18:08 even though it's the same as the expires, technically

18:08 magnars: sritchie: That is weird, since I removed the Cache-Control header on information from Google :)

18:09 sritchie: I'll plop it back in again - not exactly the end of the world sending two headers that may or may not be overlapping / superflous.

18:10 sritchie: I think cache-control overrides expires, but apparently chrome needs the former

18:10 gotta inc as well

18:10 (inc magnars)

18:10 lazybot: ⇒ 2

18:10 sritchie: crazy inc rate

18:11 arrdem: if we project his karam out with linear approximation, in less than 24hrs he'll have the most in-channel karma!

18:11 magnars: :)

18:13 sritchie: Cache-Control is back in again in 0.13.3

18:13 sritchie: haha, amazing

18:13 trying now

18:14 optimus has been live at paddleguru.com for a while now, btw -

18:14 if you want to see where we're using this stuff

18:14 magnars: oh, very cool :)

18:17 sritchie: okay, looks great. chrome is still having trouble caching this one js resource when I revisit a page, but the headers all look good

18:23 magnars: sritchie: Now that Optimus adds Last-Modified headers, it should work well with ring.middleware.not-modified. I haven't gotten around to testing it yet tho. Will do so shortly. Anyhow, that might improve the situation you mention, since Chrome at least should only get a 304 Not Modified.

18:35 sritchie: Tested now, and that worked very well. Added example of how to respond with 304 Not Modified to the README. It's pretty much a no-brainer. :-) https://github.com/magnars/optimus

18:40 sritchie: magnars: works great

18:40 magnars: ugh, chrome just won't look in its cache for this one bundle

18:40 weird

18:41 magnars: the ways of the optimizer are mysterious to mere mortals

18:45 mocker: Instead of practicing 4clojure problems I started reworking 4clojure.el to allow me to submit authenticated answers

18:45 * mocker is easily distracted.

18:49 volchok60: :quit

18:49 quit:

18:50 hyPiRion: /quit it is

18:50 mrcheeks: heh

18:50 magnars: mocker: oh, if I could do 4clojure problems in my Emacs and submit authenticated answers, that would increase my joy of 4clojure by quite a bit. Should I be watching this repo, or somewhere else? https://github.com/joshuarh/4clojure.el

18:51 mocker: That's the one, I'll submit a pull request when I finish it up.

18:51 magnars: nice!

18:51 mocker: But, submitted my first authenticated solution earlier!

18:51 :)

18:51 magnars: :)

18:52 mocker: Just couldn't imagine having to copy and paste all the time, that would annoy to no end.

18:53 magnars: Yeah, unbearable.

18:53 akurilin: bitemyapp: man, you have a serious mix going on there on Spotify \m/

19:01 hiredman: /win 15

19:15 TEttinger: ok, if a java lib I use was compiled on JDK 7, but I use leiningen's :javac-options ["-target" "1.6" "-source" "1.6"], it won't recompile the library and I'll still be targeting 1.7, right?

19:15 hyPiRion: no

19:16 if the library itself was compiled with 1.7, it won't be recompiled down to 1.6

19:16 TEttinger: because I'm getting an incompatible version error when someone runs my program on a mac with 1.6

19:16 hiredman: sure

19:17 because the library you use is 1.7 only

19:17 TEttinger: so should I rebuild the lib? I think JDK 7 uninstalled my JDK 6

19:17 hiredman: TEttinger: *shrug*

19:18 hyPiRion: TEttinger: You don't need to use JDK 6 for it, as long as you pass in those parameters

19:18 Although it is a good idea to check that it runs on 1.6

19:18 TEttinger: it doesn't

19:18 hiredman: that assumes the library doesn't use any 1.7 features

19:18 TEttinger: it doesn't

19:20 how would I check what version a maven jar was compiled for?

19:42 Clome: is there a function that applies a function on each element of a collection? I have tried (apply) but it seems like the function you are pasing to it needs to suport any number of arguments. I would like (apply fn coll) where it iterates over the coll and applies fn to each element, and fn is only able to accept one argument. Is there one, or do i have to implement it?

19:44 magnars: Clome: are you looking for map?

19:45 TEttinger: Clome, yeah map or mapv

19:45 (doc map)

19:45 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

19:45 TEttinger: ,(map inc [1 2 3])

19:45 clojurebot: (2 3 4)

19:49 TEttinger: Clome, I'm kinda surprised whatever resource you're using to learn clojure didn't cover map, it's one of the most-used functions in clojure

19:49 Clome: I will try map even though I dont need a collection back, all I need is to apply some side effects to the arguments and return nil.

19:49 TEttinger: oh, you mean reduce?

19:49 JanxSpirit: trying to use noir.response.json and getting java.lang.RuntimeException: No such var: clojure.core/noir.response

19:49 Clome: I know about map

19:50 logic_prog_: in cljs, what is the closest thing to clojure.core.format ?

19:50 TEttinger: well uh

19:50 JanxSpirit: I can't see to figure out the correct import

19:50 logic_prog_: wait, clojure.core.format is probably nil

19:50 JanxSpirit: newb here obviously

19:50 TEttinger: there's doseq, which is meant for side effects and returns nul

19:50 nil

19:50 logic_prog_: in cljs, what is the closest thing to format ?

19:51 TEttinger: (doc doseq)

19:51 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

19:51 TEttinger: not very helpful that doc

19:51 JanxSpirit: I did (:require [noir.response])

19:52 and then (GET "/json" [] (json {:result "this is json"}))

19:52 am I requiring wrong?

19:53 TEttinger: ,(doseq [e (repeatedly 5 #(java.util.Random.))] (print (.nextDouble e) " "))

19:53 clojurebot: 0.2754962034583899 0.5572356845394634 0.010696014221999728 0.7035002207066564 0.7873626149862337

19:54 TEttinger: Clome, does that help? repeatedly in there creates some mutable java objects, and it does side effects in the body

19:54 Clome: TEttinger: thanks, doseq is what I was looking for

19:55 TEttinger: Clome, I had trouble for a while with dorun, doall, and doseq... usually doseq is more-often used

19:56 JanxSpirit: any advice?

19:57 TEttinger: JanxSpirit, that's in your ns part right?

19:57 the :requie

19:57 JanxSpirit: it is, yes

19:58 TEttinger: so, yes I think you are requiring wrong, maybe

19:59 JanxSpirit: I can pete it all somewhere if you're willing to take a look

19:59 TEttinger: yeah, gist or refheap, sure

19:59 JanxSpirit: I feel like Ive tried a lot of ways

19:59 TEttinger: I think a parenthesis may be in the wrong place

20:01 JanxSpirit: https://www.refheap.com/22274

20:01 Clome: TEttinger: do you maybe know how to extract the index out? Or is there another special form for this?

20:01 JanxSpirit: that's the current incarnation

20:01 I've been thrashing ofr a bit and tried a variety of things though

20:07 also sorry for my typing - broke my arm the other day and am one handed

20:09 Tettinger anything glaring there?

20:11 TEttinger: sorry just got back

20:11 Clome, to get indices, it's probably better to use map-indexed

20:12 JanxSpirit, yes

20:12 your ns is never closed

20:12 or it is closed at the end of the file, which is wrong

20:12 JanxSpirit: doh!

20:13 TEttinger: [tango-luminus.util :as util]) should be [tango-luminus.util :as util]))

20:13 yep!

20:13 JanxSpirit: think I just introduced that

20:13 ok now I'm getting one I saw earlier

20:13 empty already refers to: #'noir.response/empty in namespace: tango-luminus.routes.home

20:13 TEttinger: ah!

20:13 ddima: TEttinger: javap -version

20:13 TEttinger: you should generally require as

20:13 thanks ddima

20:14 JanxSpirit: thought Lighttable would ding me for the parens...

20:14 ddima: my connection died and i didnt notice, so thus the delay ;)

20:14 JanxSpirit: ok I'll try that

20:15 no love on require as

20:15 still same error about empty

20:17 TEttinger: JanxSpirit, I mean

20:17 (:require [noir.response :as n-r]) and refer to empty as n-r/empty

20:18 or whatever name you choose

20:20 other names from noir.response would need to be similarly changed

20:21 JanxSpirit: tettinger I don't use empty is the thing

20:21 TEttinger: yes

20:21 clojurebot: yes isn't is

20:21 TEttinger: but there is a var empty in both files, and you are including both if you require without :as

20:23 JanxSpirit: here's my current - still the same error: https://www.refheap.com/22276

20:24 TEttinger: uhhhh I have no idea. try lein clean

20:24 I have to go, dinner with family

20:25 JanxSpirit: thanks for the help

20:27 yedi: why does take! require a function to pass the value to?

20:28 JanxSpirit: tettinger lein clean did it - thanks again!

20:30 TEttinger: yay

20:37 Clome: Guys, what are you using for logging, timbre?

20:43 yedi: dat feel when you can't figure out why the cljs compiler is hanging...

21:09 rovar: is there a way to execute something in one namespace from another?

21:11 i know I could change a namespace.. so I guess I could just call in-ns .. not sure how to pop back out of it..

21:16 Cr8: rovar: what is the desired effect of executing the code in a different ns

21:18 rovar: Cr8: I am making a collaborative MUD. I am experimenting with each room having its own verbs (fns) in their own contexts

21:19 Cr8: ah

21:19 (binding [*ns* (create-ns 'the-namespace)] (eval '(code-to-eval-in-ns)))

21:19 create-ns will return the existing ns if one exists

21:19 rovar: ah so that's what the binding call does..

21:20 Cr8: binding rebinds dynamic vars and then pops the binding at the end

21:20 rovar: very cool..

21:21 I am considering making all functions pure by requirement, then just taking their results and re-binding them back into the global state..

21:21 so just executing everything in one of several sandboxes.

21:22 Cr8: I mean, unless folks are actually typing clojure code

21:22 are they?

21:22 rovar: they could be

21:22 Cr8: mm

21:22 okay

21:23 rovar: everyone that wishes to can contribute verbs to some scope

21:23 only admins will be allowed to contribute to the global scope..

21:23 or write functions at the room scope which shadow those at the global scope..

21:23 basically it's more of a multi-user lisp repl than a MUD..

21:24 the effect I hope is something in-between...

21:25 logic_prog: cljx is fucking awesome

21:25 not only does it make code sharing between clj + cljs easier

21:25 it even makes using macros in cljs easier

21:25 cljx is fucking awesome

21:25 rovar: I hope to learn cljx soon

21:26 v4n: Is it considered appropiate to use def as long as it is defined outside local scopes (e.g. namespaces)?

21:27 Or should def be overall avoided outside any REPL experimenting?

21:27 rovar: def at the namespace level seems fine..

21:27 sometimes its necessary.

21:27 gfredericks: v4n: you mean as opposed to defn?

21:28 it's a weird question because pretty much everything is a def

21:28 v4n: I mean in the first pages of programming with clojure, it is mentioned to avoid using def.

21:29 So I am curious is if the warning is REPL and scope specific or for the overall language.

21:30 rovar: v4n: I think you should use let wherever possible, but if you want something to be available between function calls, its your only choice

21:31 dnolen: k Om is now a lot more draconian about forcing users to consider concurrency issues - a big improvement in my opinion

21:31 v4n: rovar: Makes sense

21:43 gfredericks: v4n: oh yeah; 99% of defs are constants or point-free function definitions or dynamic vars

21:53 ivan: yedi: maybe your cljs compiler has put your JVM into an endless GC loop due to not enough heap space?

21:54 yedi: connecting visualvm to it might help

21:54 yedi: ivan: no longer an issue, though i have no idea what fixed it

21:54 thanks though

21:56 grandy_: hey just wondering if someone would mind doing a quick code review of some clojure i just wrote to "join" two CSV files... it's less than 20 lines of code

21:57 i'm curious for someone to point out all the obvious things that are stupid or non-idiomatic about it

21:58 arrdem: grandy_: drop a paste. if it's sketchy someone will loudly object :P

21:58 grandy_: https://gist.github.com/anonymous/055c885f955723401590

21:59 i'm sure there is a ton wrong/stupid about it so don't hold back

22:00 Arafangion: I don't know any clojure, but that's not a streaming implementation, isn't it?

22:00 grandy_: Arafangion: correct

22:00 Arafangion: It reads all from one file, then all from the other file, and then joins it?

22:01 grandy_: Arafangion: yep

22:01 Arafangion: I'd object to that! ;)

22:01 grandy_: Arafangion: it's possible the rows in the files might be in a different order

22:02 Arafangion: Well it's readable for someone who doesn't have lisp coding experience.

22:02 grandy_: Arafangion: hah not sure if that's a good thing or not

22:02 Arafangion: (Other than tiny emacs configuration files)

22:02 arrdem: I mean... you could read all of one file, then read the other file by lines and merge on the 2nd file..

22:02 grandy_: arrdem: true

22:03 arrdem: and there's nothing blatantly bad about it...

22:03 Arafangion: arrdem: Not sure if that would be an advantage unless you could also stream on the output.

22:03 grandy_: it seems that it would be possible to just join additional files using reduce

22:03 arrdem: Arafangion: File.writeline?

22:04 Arafangion: arrdem: While streaming? Doesn't he have to re-order the whole CSV first?

22:04 arrdem: Arafangion: why? as long as he can match ID pairs from one file to the other he can totally stream the output

22:04 Arafangion: So he'd have to read at least one of those files in their entirety.

22:05 arrdem: Arafangion: I mean he's already reading both files in their entirety.

22:05 at the same time...

22:06 Arafangion: note the (doall) in open-csv.

22:08 Arafangion: arrdem: Yes, he could do it there, and I guess streaming one file would represent an advantage, but it's still reading the other file in the entirety so that he can match up ID's?)

22:09 bitemyapp: arrdem: you need more risque french electro-pop in your life.

22:09 grandy_: any thoughts on naming or function argument structure?

22:10 bitemyapp: grandy_: order function arguments by increasing variance.

22:10 grandy_: name the functions in a verby sort of way.

22:10 grandy_: bitemyapp: thanks!

22:11 have i missed some much more elegant way to do anything this program does?

22:13 Arafangion: grandy_: Some might find using lambda's more elegant, but as it stands, your defn's do some clearly defined task.

22:14 TEttinger: rovar, clojail might be handy for your purposes

22:15 yedi: any cljs core.async afficionados wanna do a code review: https://github.com/yedi/rhyme-finder/blob/master/src/cljs/rhyme_finder/rhymer.cljs#L36

22:16 grandy_: Arafangion: ok makes sense, thought about using lambdas in a few cases actually but wasn't convinced it would improve readability

22:17 rovar: TEttinger: I am using it :)

22:17 CaptainLex: TEttinger: I just noticed you provided a complete solution! o_o Thank you so much!

22:17 grandy_: thanks everyone for the advice

22:17 TEttinger: haha sorry I should have said your nick

22:17 Arafangion: grandy_: Personally, it violates the do-one-thing principles.

22:17 TEttinger: no prob, CaptainLex

22:18 rovar: TEttinger: the trick is figuring out how and when to execute un-sandboxed..

22:18 grandy_: Arafangion: what does?

22:19 rovar: e.g. all actual IO has to occur outside of the sandbox, so I have compute the results of functions inside a sandbox and then send the results in un-sandboxed code

22:19 [1]brian: what are your tricks to a faster jvm startup time for Leiningen, guys?

22:19 rovar: but I also need to update the available verbs within a namespace from outside the sandboex..

22:19 [1]brian: i experimented with drip without much success

22:21 Clome: anyone here using mirc clinet? If so how do you hide all the notifications in the chat windows, I would like to see only the messages.

22:34 Arafangion: grandy_: Ideally, each function should do one clear, distinct task.

22:34 grandy_: However, detractors point out that by putting everything into one function, one can more easily see the "shape" of how the code operates.

22:35 grandy_: But I'm new to clojure, haven't even downloaded it. (Actually, I've downlaoded it, that's it).

22:46 marcopolo`: Is there a way yet to handle libraries with different dependency versions? akin to this question: https://groups.google.com/forum/#!topic/clojure/q93CQSQ6Aeo

22:49 ivan: marcopolo`: if the API changed, you basically have to fix all callers to work with the new version, or fix the library to support both the old and new API

22:56 rovar: is there a map that is not lazy?

22:56 I know there is doseq, but I'd prefer map semantics

22:56 less typing in this case..

22:56 ah.. dorun

23:00 dnolen: rovar: doall is a bit more idiomatic if you want to force a lazy seq, also reducers are not lazy.

23:00 rovar: dnolen: I don't care about the results, so not storing the seq in mem is fine..

23:09 TEttinger: rovar: mapv is not lazy

23:11 rovar: huh

23:12 I find shift-up/down very convenient to switch between panes in emacs

23:13 except for the fact that alt-up/down deletes a chunk of my code

23:15 arrdem: rovar: minor inconvenience that

23:15 bitemyapp: links or it didn't happen

23:16 bitemyapp: also buying my 10/22 tomorrow :D

23:16 bitemyapp: arrdem: awesome :)

23:16 arrdem: http://www.youtube.com/watch?v=Y99UqvgCmE8

23:16 Raynes: ^^

23:17 Raynes: bitemyapp: Oh boy do I have something for you!

23:17 bitemyapp: https://www.youtube.com/watch?v=tolm-07if3c :p

23:18 bitemyapp: Anyways, yes, I very much like girlpop :p

23:19 rovar: Raynes: speaking of youtube. I just watched your clojureconj talk on clojail. Very helpful

23:19 clojail is proving to be quite useful..

23:19 Raynes: rovar: It probably wasn't, actually. I basically rewrote the whole darn thing after that talk. :P

23:19 Around technomancy's lovely serializable-fns.

23:20 rovar: the sfns seem to be a small part of it..

23:20 Raynes: That's a lie. The talk is still useful.

23:20 rovar: an important part..

23:20 Raynes: Just that the API has changed a bit and stuff.

23:20 rovar: I'm using the sfns too

23:20 arrdem: Raynes: what am I watching...

23:20 Raynes: arrdem: SHUT UP AND LET ME GO

23:20 !

23:20 rovar: I just pulled the code out of try-clojure as it seemed to apply to what I'm doing..

23:20 arrdem: (ban! Raynes)

23:21 Raynes: didn't work.

23:21 bitemyapp: hum. I am satisfied this template library will work I think.

23:21 Raynes: rovar: Aye. I'm happy you enjoyed the talk. And my blue hair.

23:21 I hope you enjoyed my blue hair.

23:21 bitemyapp: Raynes: not enough gallic women in this music video you sent me.

23:21 Raynes: It'd be a shameful waste of dye otherwise.

23:21 bitemyapp: Tradeoffs, man.

23:21 arrdem: bitemyapp: "such doge" is on the other team..

23:22 bitemyapp: Raynes: dat text

23:23 rovar: this video is sexually suggestive

23:23 bitemyapp: arrdem: you're in DotA2?

23:23 arrdem: bitemyapp: da

23:23 bitemyapp: arrdem: gut. Grinding out dem games?

23:24 arrdem: bitemyapp: I needed more flaming golems in my life

23:24 bitemyapp: arrdem: also found a group that generally runs 4 and 5 man teams. Might be able to peel people off that to fill out a team periodically.

23:24 arrdem: bitemyapp: so far I'm 3/0 in tonight's pug games..

23:24 bitemyapp: Eggscellent.

23:24 arrdem: hero?

23:24 rovar: I played the tutorial of Dota2 after someone here suggested that I try it

23:24 need to get back to that..

23:24 too busy clojuring

23:25 bitemyapp: rovar: I'm off in MonadIO Typeable1 la-la land.

23:25 dem unsafe unitypes. yissss

23:26 rovar: bitemyapp: haskell?

23:26 bitemyapp: rovar: yeah. I'm seeing how many pragmas I can mix before this code blows up in my face.

23:26 Haskell is a good mad-scientist language.

23:26 rovar: heh

23:27 bitemyapp: I actually already figured out how to make this unsafe coerce stuff segfault.

23:27 Now trying to figure out if I can trick the compiler into letting me escape the IO monad. Probably not.

23:27 rovar: it's unsafe coerce, that's not a challenge, try to make the pure stuff segfault

23:28 unsafeExecIO

23:28 err unsafeRunIO

23:28 I really did not enjoy wrangling monads in haskell, which is why I quit coding in it

23:29 bitemyapp: rovar: I don't even know what unsafeRunIO is.

23:29 rovar: is that ST or IO?

23:29 rovar: one monad.. super awesome.. the problem is that any integrated app, like a web app, ends up requiring me to intermix 8 different IO monads

23:29 bitemyapp: rovar: I don't really mind the monads because I only use them as much as I want.

23:29 rovar: there's really no good way to do that..

23:29 it should be in IO

23:29 it does what you hope it might, run your IO monad and give you a result.. I might be misremembering the name..

23:30 bitemyapp: rovar: a web app is what I'm tinkering with. My only real complaint at the moment is that the wacky template library thinks it needs IO for rendering a flat string.

23:30 that's a pretty understandable decision, given that in the typical case you'd be reading the filesystem.

23:31 rovar: I can't find it on hackage or hoogle.

23:31 rovar: I haven't experienced the pain you're talking about just yet. Mixing the template lib with Scotty hasn't been an issue yet.

23:31 rovar: IO.Unsafe unsafePerformIO and unsafeInterleaveIO

23:31 bitemyapp: rovar: next up is persistence. What stack were you using? HAppS?

23:31 gerd dermert hayoo.

23:32 arrdem: bitemyapp: I'm killing lifestealer with my fatal bonds. wat.

23:33 rovar: I've mucked with both Snap and Yesod extensively

23:33 I actually contributed to AcidState a loooong time ago when it was part of HAppStack

23:33 I also wrote the original MongoDB drivers for Haskell

23:33 then 10Gen hired a haskell guy who went and made them monadtastic

23:34 bitemyapp: arrdem: ...

23:34 rovar: yeah, I like Haskell a lot, I just think the monad stuff merits restraint.

23:34 rovar: rovar, back to work, slave.

23:34 oh.. i had a real question

23:34 with paredit

23:35 how does one insert a function call into an existing set of parens?

23:35 it's not optional, man.

23:35 bitemyapp: rovar: I have a problem I was working on that turned into an absolute horror in the absence of types so I decided a rewrite merited giving Haskell a shot at making my problem nicer.

23:35 rovar: that's really cool that you worked on that stuff. Yesod seems like a sure-fire path to monad Hell though. That's why I stay closer to WAI.

23:35 I might try Happstack or Snap but I'm not really going to benefit from a "framework" for what I'm doing.

23:37 what's not optional?

23:37 rovar: http://stackoverflow.com/questions/14170403/using-paredit-to-wrap-existing-expression

23:37 rovar: http://clojure.jr0cket.co.uk/perfect-environment/paredit-guide

23:37 <3

23:37 monads

23:37 if you can keep your application away from IO as long as possible, you win

23:39 TEttinger: Raynes, bitemyapp, have some weird j-pop music video https://www.youtube.com/watch?v=yzC4hFK5P3g

23:40 bitemyapp: rovar: I have a pure subset of my code and that's where I need the type system the most anyway.

23:40 I don't really care that much about tracking effects in a web app.

23:40 rovar: that guide I found is actually quite nice..

23:40 alt-(

23:40 is the bees shit

23:40 it has already changed my life for the better

23:40 in the last 1.5 minutes that I discovered it

23:41 bitemyapp: TEttinger: dafuq

23:42 TEttinger: i kno rite

23:42 bitemyapp: it probably says something that my work desktop didn't even have Java installed.

23:43 TEttinger: enjoying this, thanks!

23:43 still don't know what the fuck is going on though.

23:43 TEttinger: I guess J-pop isn't into music videos with a narrative?

23:43 TEttinger: haha

23:43 it's some kind of cultural critique on that kind of girl that likes eldritch horrors

23:43 you know, japan stuff

23:44 arrdem: why do I click on the links in here...

23:44 TEttinger: arrdem, I'm telling you, it could be much worse

23:46 bitemyapp: TEttinger: wait what

23:46 TEttinger: the artist herself said she likes grotesque things

23:46 why would...what...why...oh god what is going on I don't know how to internet

23:46 this is more confusing than that weird MonadIO thing earlier.

23:46 TEttinger: hahaha

23:47 bitemyapp: rovar: also what in the shit is MonadIO for?

23:47 TEttinger: it's multi-layered, like an onion or reality

23:47 arrdem: Kpop, it's weirder than monands!

23:47 bitemyapp: I had to make a type expression for IO ByteString to get it to shut the fuck up about multiple possible specific instances of MonadIO - why would you even vary the monadic type?

23:47 seriously, why?

23:48 do people make specialized IO monads to run their code in?

23:48 :|

23:48 brain a'splode.

23:48 rovar: bitemyapp: it lets you lift common (typeclass implemented) monads into the IO monad

23:48 bitemyapp: yes, it makes their life easier in the short run to do so

23:48 and harder (IMO) in the long run

23:49 bitemyapp: rovar: well I could tell they were lazy when I saw all the Typeable1 flying around.

23:50 Saw that and said, "ah well fuck it then"

23:50 rovar: it allows you to do things such as make params implicit for functions that mutate that param

23:50 bitemyapp: rovar: isn't the vanilla State monad like that?

23:50 I bumped into a use of StateT that was like that.

23:50 rovar: for instance, lets say you have a database client, it obviously needs to run in IO because it needs TCP. So you could put it into an IO monad, and the param to your function and its return value will be the database client object.

23:50 bitemyapp: I think in this case Hastache was using MonadIO to genericize their access against the fs.

23:51 Could be (very) wrong tho.

23:51 rovar: yeah but isn't that like...a closure?

23:51 you could just make the db-client a curried first argument, couldn't you?

23:51 rovar: closures are the only state you have in haskell :)

23:52 you kind of can, but it still needs to run in the IO monad

23:52 bitemyapp: well I knew that

23:52 just saying that I don't see a need for auto-baking the implicit param into it when currying would suffice.

23:52 unless the implicit param needs to be magically auto-swappable.

23:52 Would that be the point in this case or is it something else?

23:52 rovar: actually.. you might not be able to, .. because the return of your function is a mutated db client object, which you need to pass to your next call..

23:53 hence the whole reason for monads :)

23:53 bitemyapp: hum. yes.

23:53 rovar: they've created these things called monad wrappers, which help generalize all of your IO monads into a single one, but its still a pain, IMO

23:54 Yesod's main "loop" was a StateT of like 8 monads

23:54 bitemyapp: LOL

23:54 rovar: yeah, that's partly why I don't use Yesod :P

23:54 TEttinger: Yesod?

23:54 rovar: then I gouged out my eyes

23:54 bitemyapp: rovar: I can at least understand WAI and Scotty.

23:54 rovar: scotty is great

23:54 bitemyapp: because uh, you know, fuck *that* noise.

23:54 rovar: I am big fan

23:55 if you're doing math in a RESTful interface, Scotty will be your friend :)

23:55 bitemyapp: rovar: well I'm exposing an analytics service over REST.

23:55 rovar: me, I'm writing a collaborative MUD against a graph database, NFW I'm doing this in haskell.

23:55 bitemyapp: rovar: why "math"?

23:55 rovar: i just meant pure code

23:56 all math is pure code and pure code is math

23:56 true story

23:56 bitemyapp: rovar: I don't see why a collaborative MUD couldn't be done in Haskell :P

23:56 rovar: also why a graph db?

23:56 rovar: in my case I'm generating queries against ElasticSearch.

23:56 rovar: most maps are shaped like graphs

23:56 seemed like a good idea

23:56 TEttinger: indeed

23:56 most pathfinding algos work well on graphs too

23:56 rovar: Titanium is actually very nice so far

23:57 TEttinger: it's almost as if they were made for graphs..

23:57 TEttinger: haha

23:58 my decidedly not-M-U-yes-D game uses dijkstra for pathfinding and AI

23:58 I have yet to do a proper version over a graph, mine uses arrays

23:59 bitemyapp: TEttinger: probably faster anyway :P

23:59 arrdem: 4/0...

23:59 TEttinger: bitemyapp, err just remembered, it actually uses transient vectors

Logging service provided by n01se.net