#clojure log - Jul 24 2014

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

0:10 deadghost: I just updated my emacs packages

0:10 and might've broken my clojure-mode

0:10 http://i.imgur.com/Ue9xWJn.png

0:11 not sure if the orange namespaces are intentional

0:12 wildnux: I tried (slurp "/proc/acpi/bbswitch")

0:12 but it threw:

0:12 IOException Invalid argument java.io.FileInputStream.available (FileInputStream.java:-2)

0:13 is there a simple way to do 'cat' in repl?

0:16 can anyone tell me why it does not work but this works: (slurp (java.io.FileReader. "/proc/acpi/bbswitch"))

0:18 deadghost: wildnux, there's (:out (clojure.java.shell/sh "cat" "/path/to/file"))

0:18 wildnux: deadghost: nice

0:19 ttasterisco: try (slurp (java.io.FileInputStream. "/proc/acpi/bbswitch"))

0:28 wildnux: what is the naming convention for clojure for two word file name? fooBar.clj, foobar.clj, foo_bar.clj or foo-bar.clj ?

0:28 arrdem: foo-bar isn't valid

0:28 fair warning

0:28 foo-bar as a namespace maps to foo_bar.clj

0:28 common and poorly documented pitfall

0:29 wildnux: arrdem: so how should we name multiword clojure source file?

0:29 arrdem: foo/bar.clj is ideal, foo_bar if you must, alternatively choos a better foo

0:29 wildnux: in Clojure multiword source files are almost unheard of

0:29 * arrdem likes this style

0:30 deadghost: the more you know~~

0:31 seriously http://i.imgur.com/Ue9xWJn.png is that orange ns stuff intentional in emacs clojure-mode?

0:31 wildnux: arrdem: i need to up my naming creativity :D

0:31 deadghost: because it's bugging the hell out of me

0:31 arrdem: wildnux: creative naming is very important to us. please also don't have a top level package. Don't be that guy.

0:31 [clj-my-lib "0.1.0"] gtfo

0:31 [com.foo/shit "0.1.0"] better

0:32 wildnux: arrdem: but that comes from namespace right? not the file name..

0:32 arrdem: also please don't use clj-* it's a wasteland of poor naming although there is some good stuff in there

0:32 wildnux: that's the lein/maven groupid not the package.

0:33 wildnux: remember namespaces map to files 1:1 (if you're going to support require)

0:34 wildnux: arrdem: ah! I see, i will go through some existing projects to see how they do it :)

0:34 good night for now :) thank you

0:34 arrdem: np

2:41 SagiCZ: good morning

2:43 tuft: hello

2:43 SagiCZ: How can i design a function with state?

2:45 augustl: SagiCZ: not sure if there's a generic answer to that, other than "use an atom, a ref, or something else" :)

2:45 SagiCZ: augustl: cant expect a better answer to such a vague question.. thank you though

2:45 pyrtsa: By constructing a closure if you really need one. E.g. (let [state (atom {})] (defn stateful [k v] (swap! assoc state k v)))

2:46 SagiCZ: i read that object is a poor man's closure, but at least i understand how object works

2:47 pyrtsa: Closures aren't really mutable. When mutability is what you want, you'll need to use what augustl suggested as the closed-over variables of the closure.

2:48 SagiCZ: pyrtsa: I would like to avoid refs because they are evil right? I might have to analyze my problem deeper though. Maybe it really isnt possible to solve it without states

2:49 pyrtsa: I tend to avoid refs because I can often manage with (a very few) atoms as the application state. But I keep them detached from the functions (and explicitly pass them as arguments).

2:50 SagiCZ: atoms are better than refs?

2:50 pyrtsa: In other words, functions with state aren't my thing.

2:50 SagiCZ: what if you have creatures living in some world, interacting with it, and you need to store their history, experience, fitness.. ?

2:50 pyrtsa: Atoms are simpler. You'd need refs if you need to coordinate transactions of multiple values. Multiple atoms work independently from each other.

2:51 SagiCZ: pyrtsa: coordinate as in concurrently coordinate?

2:51 pyrtsa: I'd have one atom that's the world's state (possibly with its history).

2:51 SagiCZ: pyrtsa: and an atom can be anything right? map, seq, seq of maps?

2:51 pyrtsa: Coordinate as in do things transactionally.

2:51 Yeah, an atom may contain any single value that you can then replace transactionally.

2:52 SagiCZ: so in the "world state atom" you would have a map of all the creatures with their data as keys?

2:52 pyrtsa: Something like that, yes.

2:52 SagiCZ: sounds reasonable.. i will read up on atoms and refs

2:53 and is there any reason why most of the functions that deal with atoms have exclamation marks in them? swap!!! ?

2:53 (doc swap!)

2:53 clojurebot: eval service is offline

2:54 steffen: Using Compojure, I started my webserver locally with (run-server #'app {:port (Integer. 5000) :join? false}). Now it runs. But how do I restart it? how can I interrupt it?

2:54 i used the repl^^ btw

2:55 pyrtsa: SagiCZ: Because they do side effects (I think).

2:55 SagiCZ: pyrtsa: i see

3:01 justin_smith: steffen: run-server should return a handle you can use to stop said server

3:03 steffen: justin_smith: thank you, I'll try that

3:13 __daniel__: (defn safemap [f x] (if (seq? x) (map f x) (f x))) <-- is there a core function that does this, or something more idiomatic?

3:14 AimHere: That function looks like a category mistake

3:14 __daniel__: i need to map over edn responses, which could be a sequence or a single map

3:14 and assoc/dissoc some values etc

3:15 AimHere: please do teach

3:16 AimHere: Silly joke. Category mistake is an old joke about items being treated in one category when they belong in another one. Your function seems to apply both to sequences of stuff, and to the stuff itself

3:17 Erm, not an old joke, some old logical philosopher's idea

3:17 __daniel__: I've just thought that perhaps i could declare a function with multiple arity and type hints? would that be better?

3:18 nobodyzzz: maybe some flatten tricks is suitable here?

3:19 pyrtsa: Isn't flatten very much a category mistake as well? :)

3:19 AimHere: You could multimethod it, particularly if you end up with more types of stuff to handle

3:19 __daniel__: the seq in question will actually be a monger find-maps query result, and the non-seq a single monger entry (map)

3:19 nobodyzzz: pyrtsa, but no if involved =))

3:20 pyrtsa: I tend to need (apply concat xs) much more than (flatten xs).

3:20 nobodyzzz: There very much is an if inside flatten.

3:21 nobodyzzz: nope, http://grimoire.arrdem.com/1.6.0/clojure.core/flatten/ =)

3:21 __daniel__: can someone give an example of how flatten could help here. my seq is only one level deep

3:21 nobodyzzz: (map f (flatten (list x)))

3:22 __daniel__: nobodyzzz: but wouldnt that return a list with a map in it for the non-seq case?

3:22 i want it to return the map

3:22 pyrtsa: nobodyzzz: I stand corrected. (Though `(filter (complement sequential?) ...)` could count as one.)

3:23 __daniel__: so i'd still need an if to call first on it or something

3:24 nobodyzzz: __daniel__, my code is equivalent of your safemap function

3:24 __daniel__: ,(map inc '(1))

3:24 clojurebot: eval service is offline

3:25 __daniel__: would return (1)

3:25 nobodyzzz: (2)

3:25 __daniel__: sorry

3:25 yes

3:25 :)

3:25 my safemap would return (inc 1) i.e. 2

3:25 wouldnt it?

3:25 nobodyzzz: yeap, my fault

3:26 AimHere: Wouldn't it be worse if your sequence was something like '(1 (2 3))? safemap would run f on 1, then '(2 3)' whereas the flatteny thing would run it on 1, then 2, then 3

3:27 __daniel__: AimHere: i think the only two cases im looking at is a sequence of maps, and a single map

3:27 AimHere: I'm not sure what the problem is with the original, to be honest

3:27 justin_smith: ~flatten

3:28 AimHere: Using flatten at all, is generally unidiomatic in clojure!

3:28 justin_smith: appears factoids are offline too

3:28 AimHere: right, because it usually indicates a design mistake

3:28 (if not creating one)

3:28 __daniel__: it works, just checking its not a strange way of doing it

3:29 just wondering now why monger returns a seq and not a vector of results

3:29 maybe i have to order it first, and itll put it into a vector?

3:29 are mongo queries not ordered?

3:29 so seq? may have to become vector?

3:31 justin_smith: __daniel__: what about coll?

3:31 oh, coll? returns true for hash-maps too

3:31 __daniel__: and sets, not that that is an issue

3:31 i could use coll

3:31 justin_smith: (complement map?)

3:31 __daniel__: oh wait, no

3:32 sorry :)

3:32 justin_smith: &(map (complement map?) [[] '() {}])

3:32 lazybot: ⇒ (true true false)

3:33 Glenjamin: the caller of this function should always know if it has a seq or a single item

3:34 __daniel__: Glenjamin: it does, but how would that help? two functions?

3:34 Glenjamin: just implement the single item conversion

3:34 then if you have a seq, do (map f coll)

3:34 __daniel__: that means repeating the if multiple times, instead of once

3:34 this is called all over the place

3:34 Glenjamin: no, because you don't need the if anymore

3:35 your function alrready knows what it has

3:35 __daniel__: Glenjamin: but how do i decide whether to map or not?

3:35 Glenjamin: if you're calling find-maps, you know you have a seq so you need to map

3:36 unless you have a function which returns either a collection or a single, which is very rare

3:36 justin_smith: Glenjamin: he mentioned monger, sometimes returning a map, sometimes a seq of maps

3:36 Glenjamin: (map make-thing (find-maps db coll))

3:36 justin_smith: Glenjamin: which makes me think monger is a mess

3:36 __daniel__: actually Glenjamin is right

3:37 Glenjamin: (make-thing (find-one db coll))

3:37 __daniel__: find-maps would always return a seq i think

3:37 i knew there was something stupid with this function :)

3:37 category error indeed

3:40 justin_smith: OK, I was going on "i need to map over edn responses, which could be a sequence or a single map"

3:41 Glenjamin: sounds like you need some out-of-band schema information :p

3:41 __daniel__: justin_smith: for some reason i completely overlooked that they are not mixed in the same calling function

3:42 different endpoints

3:42 justin_smith: OK

3:42 Glenjamin: it happens quite a lot, off-by-one on the function extraction :)

3:43 __daniel__: is there a way of mapping over a hashmaps values and calling a function if they are of certain type?

3:44 i have to convert all instances of ObjectId. to str before sending the response, at the moment i have two clumsy ifs

3:44 checking if two keys are present, if they are, do an assoc with str

3:45 Glenjamin: is the key always _id ?

3:45 swi: Hello :) Seems like i not clear understand the clojure program typical flow and think in imperative way. Can someone in pair of words say what clojure typical workflow must be? I.e. program that get from some "input" then process data and then put results to some "output"?

3:45 __daniel__: Glenjamin: one is, the other is user_id

3:45 Glenjamin: ah, right

3:46 you can use reduce-kv walk map key/vals without having to re-create it

3:48 justin_smith: &(into {} (map (fn [[k v]] [k (if (even? v) (inc v) v)]) {:a 0 :b 1 :c 2 :d 3 :e 4}))

3:48 lazybot: ⇒ {:a 1, :c 3, :b 1, :d 3, :e 5}

3:49 justin_smith: swi: often there are multiple stages, and in each one you read the previous stage, and create a new one - each of these is immutible and created without modifying the previous

3:49 and each "stage" will be represented by the apropriate datastructure

3:50 mpenet: prismatic schema question: anyone knows how to validate a set with optional values ? ex: can be #{:a :b} or just #{:a} etc

3:50 without listing all the combos

3:51 justin_smith: swi: often I think in terms of plumbing - knowing a specific transformation I need, then building the pipes to get the input structure it needs, and to connect it to the input the next stage needs

3:51 __daniel__: justin_smith: thanks, thats nice

3:51 swi: justin_smith: and what about functions? Is it common to write something like (func1 (func2(func3....))) at maximum or beat all things at posibly smaller ones and catch results in def ?

3:51 instilled: anybody knows how to attach sources in clojure eclipse project (counterclockwise) to dependencies? i'm running 0.26.0.STABLE001.

3:52 justin_smith: swi: after about three levels of nesting, you turn (f (g (h x))) into (-> x h g f)

3:52 imperman: swi: it's different - from functional ( http://my.safaribooksonline.com/book/programming/clojure/9781430272311/controlling-program-flow/functional_programming_techniques ) to reactive ( http://blog.paralleluniverse.co/2014/02/20/reactive/ )

3:52 justin_smith: but that's a rule of thumb

3:52 swi: also, using def should not be part of your algorithm, ever

3:52 def is for globals, let is for local bindings that may change on each call

3:53 Glenjamin: at the edge of your system, you need to take input and send output, but inside you can just thread values through functions

3:54 justin_smith: Glenjamin: I think I may use the terms input and output idiosyncratically, but I think of functions all having N inputs and 1 output (plumbing metaphor I mentioned earlier)

3:54 mpenet: ok it was #{(s/enum :a :b :c) ...

3:54 Glenjamin: yeah, i was attempting to refer to system IO specifically

3:55 swi: imperman: thanks for link

3:55 Glenjamin: a good clojure program only deals with external IO at the edges, i would say

3:56 justin_smith: Glenjamin: most of the time system IO is implicit at one end or the other of my task (whether that's ring taking requests and making them arguments, and taking return values and making them responses, or the repl) - I rarely find myself thinking about those boundary layers of my system

3:56 swi: justin_smith: my imperative mind refuse to take it like 'How? We must put input results to some buffer, then take from it in loop and proceed and make new data we want and place it in new buffer" :)

3:57 justin_smith: Glenjamin: right, i/o is state, and we know it adds sanity to localize state to one part of our code

3:57 swi: if you go through http://clojure.org/cheatsheet almost everything on that page takes input data, does some transformation, and returns new data

3:59 the buffering / storage issues are taken care of implicitly (and have nice features like structural sharing and laziness that are already implemented at a language level)

4:00 swi: mind you, this leads to a language that is very liberal with memory usage - you'll never want to use clojure in an embedded system. But if RAM is cheap, given clojure, you get a lot of sanity at a low price.

4:01 swi: justin_smith: yes. i understand all of this pretty functions separated, but then begin to write some simple program and find myself out situation where in -main i have call only one function, and that function calls inside for another (or two) and that functions calls etc. Is it allways like this ? I mean that on program entry point one function, that became a big tree of func.calls ?

4:01 justin_smith: well, normal code uses let for intermediate values

4:01 but yeah, deep call trees are pretty normal in clojure

4:02 (that's part of why our stack traces are notoriously insane also)

4:02 swi: and let just a...em local var inside function ?

4:02 mpenet: swi: it's true for any language, when it's not functions its, objects/methods etc

4:02 just easier to follow when it's a simple abstraction

4:02 justin_smith: mpenet: but we nest function calls deeper before you hit the metal, compared to the level of object nesting in sane OO code for example

4:02 hcumberdale: swi: local const :)

4:03 mpenet: justin_smith: arguable, OO can often being quite deep too

4:04 swi: mpenet: well, i mean in imperative code i often use var1 = func1(); var2 = func2(var1) and so on :)

4:04 hcumberdale: I can't imagine that call hierarchies are deeper than in "real OOP"

4:04 mpenet: swi: you can do that in clojure

4:04 justin_smith: swi: (let [a (f1) b (f2 a z) c (f3 a b) ...] result)

4:05 swi: damn.. i was sure i missed something with this let :)

4:06 __daniel__: regarding the announcement of transit the other day, can anyone tell me if this is intended to replace application/edn when communicating between front and backend clj/cljs ?

4:06 i understand it's more for communicating with other languages, clojure/clojurescript being seen as more or less the same

4:07 swi: btw, is http://clojurekoans.com/ a good ?

4:07 Glenjamin: yeah, koans are pretty good, as is 4clojure

4:08 swi: thanks a lot for answers, a little hard to turn mind from declarative way :) But it's fun

4:09 s/declarative/imperative/

4:09 justin_smith: swi: on the contrary, clojure is very much declarative

4:10 swi: justin_smith: i mean go from c/python to FP, sorry :)

4:11 justin_smith: right, those are not declarative languages at all

4:12 swi: well, python have only a little of fp elements like map filter and lambda that i like so try to catch a true functinal language :)

4:12 justin_smith: http://en.wikipedia.org/wiki/Declarative_programming

4:13 swi: justin_smith: i correct myself a bit higher

4:13 justin_smith: yeah

4:14 sorry, I actually think the declarative language thing is interesting, and like having an excuse to call attention to it

4:16 swi: justin_smith: it's very interesting, even i never will be use i.e. clojure on my work, it's a good way to train brain, learn new ways in programming and just have fun :)

4:17 __daniel__: swi: why would you never use it at work?

4:18 pro_1: swi: there are many other ways to train brain

4:19 swi: __daniel__: i mean 'if' :) Right know as a real try of language i trying to rewrite one of my script that fetch quotes from yahoo :)

4:19 pro_1: sure, but i want somethng pratical thing too :)

4:20 pro_1: Try Calculus, swi

4:20 __daniel__: pro_1: when has calculus last come in handy for you?

4:21 swi: +1

4:21 pro_1: When I calculated when our school will reach certain population

4:22 Calculus is everywhere in Economics, physics

4:23 __daniel__: that involved extrapolating a line/curve? solving a quadratic equation?

4:23 calculus is everywhere in economics and physics, i rarely find myself needing it in programming

4:24 justin_smith: __daniel__: try DSP

4:24 __daniel__: i suppose if you are modelling economics or game physics, then you would

4:24 justin_smith: sure, there are plenty of uses for calculus

4:25 justin_smith: it's a basis for a bunch of stuff related to compression, frequency domain transformations, even crypto

4:25 hyPiRion: __daniel__: You may need it to show certain data structure properties too, actually

4:25 __daniel__: it depends what you're doing though, i spend a lot of my time moving coloured boxes around a screen

4:25 hyPiRion: not that many people do it, but there's certainly some strange use cases lying around

4:25 pro_1: I was telling ways to train brain

4:26 __daniel__: i studied physics at university, unfortunately very little of it has been practical

4:26 engblom: Calculus is very useful tool in many situations where "normal" people find a problem unsolvable unless you do a brute force. Think about dropping a loop in a program and instead just get the right answer directly.

4:26 pro_1: When you work as physicist, you might require programming too.

4:26 __daniel__: it comes down to my career choices

4:27 engblom: Especially when it is about finding the optimal value satisfying some requirements calculus is very important.

4:27 pro_1: engblom: surely you don't mean calculus is for *normal* people

4:27 mpenet: "might", very often it's limited to mathematica/mathlab

4:28 hyPiRion: pro_1: "normal"

4:28 engblom: Sure you could loop over all values and store them in a list and then search that list for the optimal, but that means a huge performance lost

4:28 * swi remember that calculations with 100x100 matrix in thesis project in university and written with c++ omg

4:28 engblom: pro_1: I think all normal people should know some calculus.

4:29 __daniel__: im just saying that unless you're working in science, it may not be as practical as other things

4:30 including computer science, a lot of programmers end up moving coloured boxes around a browser like i do

4:30 pro_1: Daniel_ unless you are into programming job/study it isn't too practical too

4:30 Heh

4:31 swi: apart computer science there is computer engeenering :)

4:32 __daniel__: anyway, calculus is definitely worth learning, mosaic theory and all that

4:32 any knowledge is good knowledge

4:33 swi: certainly

4:33 __daniel__: http://en.wikipedia.org/wiki/Mosaic_theory_(investments)

4:34 pro_1: When you are learning more and more interdisciplinary; you gonna come up with something good in research

4:34 __daniel__: indeed

4:35 swi: hm, how can i remove old clojure that lein download ?

4:36 justin_smith: swi: are you concerned about disk usage?

4:36 anyway, all the jars lein gets are cached under $HOME/.m2/

4:36 swi: justin_smith: dont like trash :)

4:36 __daniel__: lein clean?

4:37 justin_smith: no, that just cleans your current repo of compilation artifacts

4:37 __daniel__: or does that do something else

4:37 i see

4:37 justin_smith: you can remov ~/.m2/repository/ or some set of directories under that tree

4:38 unless you used lein install, lein will automatically download things to refill it

4:38 so it's a tradeoff of disk usage vs. network bandwidth usage

4:38 swi: justin_smith: i see. a lot of jars there. It's from maven afaiu ?

4:39 justin_smith: swi: it's from wherever people declared their deps to be from. maven central, or clojars are the two huge ones

4:39 swi: i have unlim network, but limited hdd :) only 10g is free and a lot of music must be ripped from my new CD :)

4:39 justin_smith: when you run lein, it tells you where it is downloading from

4:39 swi: justin_smith: btw, where lein repos specified ? i mean defaults

4:39 justin_smith: lein has some default config, but it all depends on project.clj

4:40 swi: ~/.leain/project.clj i wrote my own and there only cider

4:40 justin_smith: swi: I mean the project.clj in each project that gets run

4:40 swi: wait

4:41 justin_smith: do you mean ~/.lein/profiles.clj? that is just something that modifies your project's effective project.clj :)

4:42 swi: i mean when run lein search outside any of lein project it' load a lot of indexes, hell, allmost burn my cpu while do this :) And big ones where maven, not clojars

4:43 justin_smith: yeah, if you run lein outside of a project directory, the behavior will be specified by the defaults plus ~/.lein/profiles.clj

4:44 swi: and that defaults hidden somewhere?

4:46 justin_smith: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L190

4:46 here, I think

4:47 oh, oops "TODO move :repositories here in 3.0"

4:47 anyway, it should be somewhere near there in the source tree

4:48 hyPiRion: swi: what version of Lein are you running? Latest ones have a progress bar for `lein search` (it's quite time consuming first time you run it)

4:48 swi: justin_smith: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L279

4:48 justin_smith: there we go

4:48 maven and clojars

4:48 as we said before

4:48 swi: justin_smith: find it, thanks :) src is the best docs :)

4:49 hyPiRion: Leiningen 2.4.2

4:49 hyPiRion: yes, second search was very fast :)

4:49 hyPiRion: right, then you should have some download/progress bar on lein search

4:49 yay!

4:50 swi: yes, but it' was scary how java eat all cpu :)

4:50 justin_smith: swi: well, I'd blame clojure more than java there

4:51 hyPiRion: I'd blame the work to be done, which is not insignificant. Most of lein search is just calls to java libs.

4:52 Just related to the fact that there are a lot of libraries out there

4:52 swi: at first i was shocked - it's just download damn indexes, why so heavy ?

4:53 mpenet: first run is slow

4:53 it dls + builds a lucene index

4:53 then it should be fine I think

4:53 swi: so the build, not just download. than ok

4:54 mpenet: well indexing is not slow, it's mostly the downloading I'd guess

4:55 swi: how the hell downloading can eat 100% of 2 cpu cores?

4:55 mpenet: I have no clue, didn't read the source, but my bet it's not a single file

4:55 insamniac: what is your download client?

4:56 lein?

4:56 hyPiRion: it's a single file afaik

4:56 mpenet: ah well :]

4:57 insamniac: planned obsolescence. get moar cores.

5:13 swi: insamniac: i think 4 cores is fair enough for downloading allmost everything :) thay can just use curl i.e. to download file :)

5:14 justin_smith: I really doubt lein would be using curl

5:14 visof: helo

5:15 here is my code https://www.refheap.com/88544 and when i'm doing curl -X POST -H "Content-Type: application/json" -d '{"hello" "Visof"}' localhost:3000 i got nothing

5:16 justin_smith: that's not valid json

5:16 visof: but when i change the routes to (POST "/" {body :body} (slurp body)) i got it works

5:17 justin_smith: what do you mean?

5:17 hyPiRion: visof: '{"hello" "Visof"}' → '{"hello": "Visof"}'

5:18 justin_smith: http://jsonlint.com/ try validating it here

5:18 not to say that is guaranteed to be your problem, it was just the first thing I noticed

5:19 visof: hyPiRion: justin_smith i changed it to the valid json but with the same problem i got nothing

5:20 Glenjamin: visof: do you have a ring middleware that parses json in your middlewre stack?

5:27 sveri: Hi, how can convert a string "C" to the char representation in clojure?

5:30 vijaykiran: &&(first "C")

5:30 lazybot: java.lang.RuntimeException: Unable to resolve symbol: & in this context

5:30 vijaykiran: ,(first "C")

5:30 clojurebot: eval service is offline

5:31 vijaykiran: ##(first "C")

5:31 lazybot: ⇒ \C

5:31 vijaykiran: sveri: kind of a hack ^

5:31 hyPiRion: &(first "X")

5:31 lazybot: ⇒ \X

5:31 hyPiRion: ,'foo

5:32 clojurebot: eval service is offline

5:32 sveri: thank you

5:44 visof: Glenjamin: no

5:44 Glenjamin: then that's your issue :)

5:45 visof: Glenjamin: so i need to handle the body as json when parse to the handler?

5:50 Glenjamin: have you checked my code? https://www.refheap.com/88544

5:51 augustl: refheap the slow..

5:53 Glenjamin: https://github.com/ring-clojure/ring-json

7:34 __daniel__: "Currently at 1.6.0; top analysts expect this to be followed by newer versions with still higher numbers" :)

7:41 michaelr525: hey

7:42 __daniel__: hey

7:56 boxed: yogthos: isn’t travis supposed to run on PRs?

7:56 that way I would have avoided this embarrassment :P

7:57 yogthos: boxed: it did, but I figured maybe it was getting confused since the pr itself looked ok

7:58 boxed: in any case no worries, everything is looking good now

7:58 boxed: oh.. hmm.. but it didn’t post in the PR?

7:59 yogthos: boxed: it ended up failing here https://travis-ci.org/yogthos/Selmer/builds/30740182

7:59 boxed: I guess I should've put more trust in it :)

7:59 boxed: anyway, cool that you accepted it! I think this little trivial lib could really help make sure docs are correct

8:00 heh

8:00 yogthos: boxed: I definitely find keeping tests in docs up to date a pain, this very much helps

8:00 boxed: going to be even more useful for my clj-pdf docs :)

8:00 boxed: I added a funny little hack to support your examples too: (def … :…) :P

8:01 yogthos: aha, let me give that a shot!

8:02 yogthos: boxed: I noticed that worked, I didn't expect it to, that's a nice touch

8:02 boxed: hmm.. no assertions in the clj-pdf readme though… so midje-readme can only check that the code runs

8:02 yea I thought so… hoped people wouldn’t get upset about it :P I think it really helps because you see that a lot in example code

8:02 yogthos: boxed: I find that's usually the biggest source of problems, you forget a paren or something

8:03 boxed: yea

8:03 I really should get back to my project about validating indents vs paren in clojure some day… but getting my first child next week so the chances of that are pretty slim

8:04 yogthos: boxed: oh well congrats :)

8:04 boxed: thanks :P

8:05 this little two weeks vacation before has really allowed me to jump into clojure which has been fun

8:05 yogthos: glad to hear it, and thanks for making the lib :)

8:06 boxed: glad someone uses something I made :P

8:06 yogthos: :)

8:06 boxed: still think instar is a potentially more useful lib :P

8:08 yogthos: yeah those kinds of transforms do come up often ;)

8:08 CookedGr1phon: Is there a way to output EDN which will guarantee its round-trippability?

8:09 I don't want to find out at read time that somebody's outputted something which doesn't have an appropriate parallel in edn/read-string

8:11 boxed: CookedGr1phon: the brute force approach would be to try to read it with read-string at write time :P

8:11 CookedGr1phon: hrmmmmm

8:12 boxed: KISS and all that :P

8:12 __daniel__: is that even possible? what might not be round-trippable?

8:13 CookedGr1phon: trying the round trip is unacceptable

8:14 and __daniel__, more or less any java object which sneaks in

8:14 boxed: CookedGr1phon: unacceptable why?

8:14 CookedGr1phon: performance

8:15 boxed: you’ve already tried it?

8:15 CookedGr1phon: the old adage of not optimising until you've profiled doesn't really count when it comes to blindly doing more than twice the work you need to in your inner loop

8:16 I'm logging every event which goes through my system and want to guarantee that it's replayable for debugging/testing in the future

8:17 boxed: well you do need to walk the entire syntax in order to guarantee it’s ok.. any other thing would just be a better-than-nothing guess no?

8:18 CookedGr1phon: well what I'm hoping for is some implementation of pr-str which has an option to fail if it can't serialize rather than fall back

8:18 boxed: ah

8:18 __daniel__: CookedGr1phon: ofc, actually i had a similar issue yesterday with mongo ObjectId.

8:18 swi: Am i understand right: loop and recur allmost allways goes in pair ?

8:19 CookedGr1phon: swi: loops tend to have recurs, but you can recur in functions too

8:20 swi: CookedGr1phon: em... can you give a simple example of recur using without loop ?

8:20 hyPiRion: swi: any (semantically sensible) loop has at least one recur.

8:21 hcumberdale: Does anybody know if loom (graph framework for clojure) contains any kind of cycle detection?

8:22 hyPiRion: swi: ##(let [my-non-neg-even? (fn [n] (cond (zero? n) true (pos? n) (recur (- n 2)) (neg? n) false))] (map my-non-neg-even? [1, 4, 5, 10, 80]))

8:22 lazybot: ⇒ (false true false true true)

8:22 swi: i.e. https://www.refheap.com/88547 why this comes to stackoverflow ?

8:23 CookedGr1phon: swi: because every time you enter teh next getsum, you're adding a stack frame and never returning

8:23 so instead of calling getsum from within getsum, call recur

8:24 swi: CookedGr1phon: then i get "Can only recur from tail position"

8:24 jcromartie: swi: you need to define getsum with two arities

8:24 pyrtsa: Or rather either (reduce + l) or (apply + l)

8:25 swi: If you want to keep it recursive, you should guard the recursion with an (if ...) or (when ...).

8:25 hyPiRion: jcromartie: you can't recur on different arities, btw.

8:25 jcromartie: not across arities

8:25 hyPiRion: right

8:27 jcromartie: swi: https://www.refheap.com/88548

8:27 I assume this is an exercise in learning recursion and not trying to write a sum function :)

8:28 boxed: yogthos: well I’m finding a few problems in clj-pfd… and a bug in midje-readme so this seems worthwhile :P

8:28 jcromartie: (def sum (partial apply +))

8:28 yogthos: boxed: most excellent :)

8:28 swi: jcromartie: right, i'm trying to get to recursion idea

8:28 jcromartie: yeah

8:28 well that's a noble cause

8:28 yogthos: boxed: and I gotta jet here, looking forward to a pr in the near future :)

8:28 swi: can't catch it perfectly

8:29 jcromartie: Clojure does it a little differently because "recur" is explicit, whereas in languages like Scheme the tail call optimization is automatic

8:29 boxed: yogthos: shouldn’t be long, I’m at line 912 now :P

8:29 yogthos: boxed: awesome

8:29 swi: jcromartie: hm, so in scheme my definition will be all right ?

8:29 jcromartie: well it's still not tail position

8:30 you need an accumulator to make it tail recursive

8:30 that's what my 2-arity version does

8:30 swi: jcromartie: and loop i.e. allow me to write without two arity

8:31 jcromartie: sure, because you just localize the accumulator to the loop

8:31 swi: so it' just a form of tco, one or another?

8:32 jcromartie: yeah, but it's your responsibility to use "recur" properly

8:33 TCO would really imply that it's automatic

8:33 I think you can say Clojure does not have TCO

8:34 swi: jcromartie: i think i understand better now. Thank you for explanation :)

8:36 hyPiRion: jcromartie: Well, TCL has the tailcall command (like recur), and TCL is considered to have TCO.

8:37 Clojure certainly optimised away the tail call when you use recur – the difference is that you must explicitly say so in constrast to Scheme

8:39 boxed: another way of putting it is that loop-recur is just a fancy goto :P

8:40 hyPiRion: heh, yeah

8:42 swi: hm, seems like scheme only one that have auto-tco ? :)

8:51 mpenet: not really, on top of my head: lua and haskell both do it

8:52 hyPiRion: ocaml, C, C++, etc.

9:00 simon_: Hello. New to clojure, does anyone know of any library where (= (some-lib "http://domain.com" "/a/path") (some-live "http://domain.com/&quot; "a/path") (some-lib "http://domain.com/&quot; "/a/path")) ?

9:01 jcromartie: str

9:01 oh wait

9:01 I see :)

9:01 swi: :)

9:01 jcromartie: java.net.URL

9:01 simon_: Cool, cheers, Ill check it out.

9:02 hyPiRion: oh wait wait wait

9:03 Glenjamin: is URL the one that makes external http calls in its hashCode method?

9:03 deathknight: Have there been any new guides on making a web app with oauth2 within the past two months?

9:03 hyPiRion: Glenjamin: yes, things may be equal or not depending of whether you have internet connectivity

9:03 rweir: haha no way

9:04 Glenjamin: it normalises the IP address by resolving DNS iirc

9:04 jcromartie: deathknight: I use OAuth2 in my Compojure web app

9:04 java.net.URI is more general purpose

9:04 deathknight: jcromartie: did you follow a guide or tutorial to help you? I'd really like to wrap my head around this. I have made oauth2 calls from the command line and copying+pasting info to/from the browser

9:06 jcromartie: yeah just a minute, have to go do something

9:06 deathknight: grazi

9:06 jcromartie: would be happy to share code etc

9:06 deathknight: :D

9:07 jcromartie: now I might say: just use Friend

9:07 but I can at least show you what I have here

9:07 I didn't use friend

9:07 deathknight: awesome

9:11 mthvedt: deathknight: i’ve been cooking up this library, https://github.com/mthvedt/qarth

9:11 take a look and tell me if it’s useful

9:12 deathknight: looking!

9:12 can this be used with facebook graph api? sorry that I'm such a noob

9:13 mthvedt: deathknight: you can use it to grab oauth authorizations for graph

9:13 there aren’t any graph-specific methods or fns

9:13 deathknight: :D

9:15 this looks inredible

9:16 incredible*

9:16 mthvedt: deathknight: thanks

9:16 i’m trying to deploy the latest snapshot but something broke in my conf, give me a few minutes before trying it out :(

9:16 deathknight: :)

9:17 I'm trying to run one of your examples, but lein complains that example is not a task

9:19 mthvedt: deathknight: you’re in the same directory as qarth project.clj? and it’s not working?

9:21 deathknight: woa, interesting. it worked with qarth but it didnt work for clj-facebook-graph

9:26 boxed: mthvedt: I like the new readme!

9:26 mthvedt: boxed: thanks! your feedback was very valuable

9:26 boxed: oh, and the thank you note at the bottom was nice too :P

9:27 I was a bit worried my mail sounded a bit too harsh there :P

9:27 deathknight: when trying to run an example, i get "Could not find artifact org.scribe:scribe:jar:1.3.6 in clojars (https://clojars.org/repo/)"

9:30 mthvedt: shouldn’t lein be pulling that from maven?

9:30 deathknight: couldnt get it from maven either

9:31 also, is my syntax correct here? "$ lein example friend", because that threw "Exception in thread "main" java.io.FileNotFoundException: Could not locate friend__init.class or friend.clj"

9:31 mthvedt: deathknight: scribe 1.3.6 is not in releases :( fixing

9:32 deathknight: :D

9:32 mthvedt: also, lein example qarth.examples.friend is correct. will add to the readme

9:33 deathknight: nice! thank you

9:33 that helps so much

9:33 sorry for throwing my pre-coffee brain that's in a complete fog

9:33 at you

9:34 mthvedt: no problem… usability is very important in a library

9:34 deathknight: clj-facebook-graph has an example.clj file in ~/project-directory/tests/clj-facebook-graph/example.clj...what is the lein command to run that file?

9:34 i've been stumped for 3 days ~_~

9:35 mthvedt: probably something along the lines of lein run -m

9:36 hm, it doesn’t have a main

9:36 i think it’s meant to be run from the REPL

9:37 deathknight: would I do (use 'clj-facebook-graph.example) ?

9:37 mthvedt: probably

9:37 deathknight: $ lein example qarth.examples.friend threw this: http://pastebin.com/B33YPEaF

9:40 mthvedt: deathknight: you need to put some keys in test-resources/keys.edn. i think i mentinoed that in the readme

9:40 deathknight: shit man I apologize

9:40 mthvedt: i didn’t really want to distribute my own oauth keys with qarth :P

9:40 deathknight: :D

9:44 jcromartie: putting OAuth keys in a JAR resource is a bad idae

9:44 idea

9:44 it should be configured from outside of whatever you deploy

9:45 i.e. via environment variables or a config file in /etc/

9:45 of course you can always put the config directory on the classpath when you run it

9:45 mthvedt: jcromartie: the keys are not in jar resources

9:46 jcromartie: oh I see

9:46 test-resources

9:46 :P

9:51 deathknight: still can't load keys.edn no matter the values i fill it with

9:52 ooooh

9:52 ok, so its searching for test-resources/keys.edn

9:52 but the file that exists is test-resources/keys-example.dn :)

9:52 .edn*

9:54 mthvedt: i should probably change that to keys.edn. the minor problem is that git won’t let you ignore tracked files, risking people commiting their keys accidentally.

9:54 you can configure ignoring tracked files on a per-clone basis

9:55 swi: hmmm... how can i make recur call from anon-function ?

9:55 Glenjamin: mthvedt: if these are test fixtures, could the test runner generate them if missing?

9:55 swi: and anon-function does not have any argument

9:56 clgv: swi: with "recur" as usual

9:56 justin_smith: swi: how would you plan on making recur terminate if there is not argument that changes?

9:57 *is no

9:57 mthvedt: glenjamin: well, i think you need valid oauth keys for facebook, github, &c

9:57 which one would want to keep to one’s self

9:57 Glenjamin: oh right

9:57 i see

9:57 i assumed that this was for some sort of server :)

9:58 swi: justin_smith: well, i mean not using recur but make recursion function.

9:58 lazy function.. without end :)

9:58 mthvedt: gpg-agent has stopped working after i put in the wrong password :(

9:59 jcromartie: I have to say I really don't like it when libraries require me to have certain files in the filesystem or on the classpath

9:59 I'd rather be able to configure it from any source

9:59 mthvedt: jcromartie: these are purely for testing

9:59 Glenjamin: i tend to use env vars: FACEBOOK_AUTH_SECRET for eg

9:59 justin_smith: &(take 4 (repeatedly #(+ (rand) (rand)))) ; swi - is this what you have in mind?

9:59 lazybot: ⇒ (1.115337555838034 1.4810516083741536 0.5165425022186816 0.48732042702698797)

9:59 mthvedt: qarth makes no assumptions about where the files are, just the test examples load that one file

10:01 swi: justin_smith: yep. and seems i figure out. I need to write not #(...) but (fn somename .... ), right ? so that i can call function by it's name inside

10:02 justin_smith: right, but unless you are producing a lazy sequence (as repeatedly does) you will usually want some argument that controls the recursion

10:03 swi: justin_smith: i'm using lazy-cat there :)

10:03 justin_smith: well there you go, cool

10:04 but calling repeatedly on a function of no args is preferable to doing a manual recursion and lazy-cat with no args

10:05 clgv: swi: calling by name will eat up your stack which is sometimes not preferred (overflow). hence just use "recur"

10:05 justin_smith: clgv: not with lazy-cat

10:06 clgv: justin_smith: lazy-cat? where?

10:06 justin_smith: oh that last post

10:06 justin_smith: well it's actually no recursion then ;)

10:07 swi: damn :( not working

10:08 (fn foo [] ...) is right for empty argument function ?

10:09 hyPiRion: yes

10:09 clgv: swi: you'll probably get to your goal faster if you describe your problem and provide some input output examples

10:10 hyPiRion: But calling (fn foo [] ...) only makes sense if you use global mutable state

10:10 deathknight: mthvedt: upon running an example, I get this: http://pastebin.com/U7cGB1Ma. it hangs there and the server doesnt start up

10:10 hyPiRion: using, rather

10:10 simon_: Pardon my ignorance, but is there any easy way to do something like for k, v in {"a": "b", "1": "2"}.iteritems(): [k,v] (python, returns two lists ['a', 'b'] and ['1', '2'])

10:11 clgv: simon_: `for` or `reduce-kv`

10:11 swi: clgv: well, i need to make function returning first N fibonacci numbers :) i know how defn such a functionm but i must put in as anon-function

10:12 justin_smith: swi: then, each iteration should take the previous two numbers as an argument

10:12 clgv: swi: then you need at least a parameter "n" right? ;)

10:12 justin_smith: swi: in fp, you really want all your state to be in the function args

10:12 mthvedt: deathknight: it’s worrisome that the server doesn’t start. i’m not sure what’s up with the slf4j error, but that just has to do with logging and it won’t stop the server from starting

10:13 simon_: Cheers clgv

10:13 deathknight: is it because I switched the scribe dependency to [clj-scribe "0.3.1"]?

10:15 swi: justin_smith: clgv yeees... i think i understand where i was wrong :)

10:15 mthvedt: gpg-agent has stopped working completely after i put in the wrong passphrase too many times, because it thinks ctrl-c is an attempt to put in a passphrase

10:16 i have no idea how to fix whatever happened

10:16 deathknight: lol

10:21 clgv: mthvedt: kill gpg-agent and restart it?

10:33 deathknight: mthvedt: just recloned the project. when running $ lein example qarth.examples.friend_multi, I get "Exception in thread "main" java.lang.Exception: Cannot find anything to run for: [..]/friend_multi"

10:35 mthvedt: deathknight: try lein example qarth.examples.friend-multi

10:35 remember that clojure switches _ and -

10:36 deathknight: oo

10:36 danke mucho

10:37 sweet jinglies it works

10:38 mthvedt: deathknight: huzzah!

10:52 arrdem: trptcolin: ping

10:52 'mornin all btw

10:53 trptcolin: arrdem: sup :)

10:53 that was fast

10:53 arrdem: trptcolin: IRC driven F/OSS dev ftw

10:53 swi: &((fn [a] (take a ((fn f [x] (lazy-cat x (map + (rest (f x)) (f x)))) [1 1]))) 10 )

10:53 lazybot: ⇒ (1 1 2 3 5 8 13 21 34 55)

10:53 swi: fuuuuuh

10:53 arrdem: trptcolin: TL;DR _DASH_ is a workaround for Jekyll insanity

10:54 jcromartie: anybody seen cgrand?

10:54 http://enlive.cgrand.net/syntax.html

10:54 arrdem: trptcolin: Jekyll claims that /-foo/ isn't a valid dir for whatever reason, so I just went ahead and munged it.

10:54 justin_smith: swi: cool, now do it with memoize :)

10:55 trptcolin: arrdem: yeah, sorry, i’m not too worried about that part - mainly about (a) text-only (no html - which afaik may exist somewhere i don’t know about) and (b) doing search without a js runtime

10:56 dumb client (`slurp`) can just do a GET

10:56 arrdem: trptcolin: so... getting examples as text only is something I have zero support for ATM. There's a branch, I think it's feature/ssg or something, in which I'm experimenting with reworking Grimoire around a trivial Ring/Compojure server rather than Jekyll.

10:57 trptcolin: gotcha. but that’s something you’re open to doing?

10:57 or having someone else do?

10:58 arrdem: due to summer classes I don't have a ton of time ATM, so Grimoire is gonna languish until I no longer feel bad about neglecting my GSoC project, but yeah transitioning to a "real" server and offering a text API is something I'm open too.

10:58 trptcolin: i don’t have the bandwidth to take it on right now but might be able to find someone to lean on around my work :)

10:58 swi: justin_smith: :`( memoize? i'm allmost break my head writing this.. what is memoize ?

10:58 trptcolin: arrdem: awesome

10:58 arrdem: http://grimoire.arrdem.com/1.6.0/clojure.core/memoize

10:59 rkneufeld: Hey arrdem: Have you ever heard of Dash.app on Mac? I was thinking about what it might be like to generate a docset from grimoire to have on my machine.

10:59 swi: arrdem: justin_smith em... i can't use def or defn :)

10:59 arrdem: trptcolin: the one thing I'm trying to do in that experimental branch is FS as a DB. I really really want to keep the existing "contribute via github" model because I don't like working with real databases and having to add worthwhile auth and appropriate editing pages is just gonna be a boatload of overhead.

10:59 justin_smith: swi: you can memoize an fn

11:00 trptcolin: arrdem: cool. i’ll probably wire up whichever of grimoire & clojuredocs has a text-only API first to REPLy

11:01 arrdem: trptcolin: clojuredocs already has a not crap text API. that's actually how I got almost all my examples :P

11:01 trptcolin: oh?

11:01 justin_smith: &(map (memoize (fn [x] (do (println "element" x) x))) [:a :a :b :b :b :a]) swi

11:01 lazybot: ⇒ (element :aelement :b:a :a :b :b :b :a)

11:01 clgv: $seen cgrand

11:01 lazybot: cgrand was last seen quitting 4 weeks ago.

11:01 Glenjamin: rkneufeld: it should be trivial to make a dash docset from grimoire

11:01 arrdem: trptcolin: http://api.clojuredocs.org/

11:01 Glenjamin: i've been meaning to try, but haven't yet

11:02 arrdem: rkneufeld: have you read my blog post about the "augmented documentation" strategy I'm taking with Grimoire?

11:02 rkneufeld: Glenjamin: no promises, but I'm going to take a look at the format some time today

11:02 trptcolin: oh you mean json?

11:02 i mean pure text, dumped out as it will be printed

11:02 rkneufeld: arrdem: I've read some of your stuff, not sure if I hit that post though.

11:02 swi: justin_smith: eeemm.. is it fit here http://www.4clojure.com/problem/26#prob-title?

11:02 Glenjamin: http://kapeli.com/docsets#dashDocset seems to make it sound easy

11:02 arrdem: trptcolin: the json API has the code examples string encoded.

11:02 trptcolin: i know

11:02 but dependencies

11:02 arrdem: ah. gotcha.

11:03 yeah that's something Grimoire's API is gonna try and do...

11:03 both be self-hosting bacause dogfooding and provide raw text

11:03 still trying to figure out highlighting.

11:03 trptcolin: cool yeah, think netflix-style API where the server throws down exactly what clients need

11:04 arrdem: rkneufeld: if you want to try and take the Grimore generator and retarget it to build a Dash dataset I'm totally chill with that and I'll help such as I can, but right now screen scraping Grimore is more effort than it's worth and there's no API.

11:05 rkneufeld: arrdem: Will do.

11:05 Glenjamin: if i do it first i'll throw up a PR/issue saying what i did :)

11:06 lduros: hi, I'd like to know what's the current state of native android app development and whether it's viable to use clojure to write quality apps and whether there are production examples

11:06 arrdem: rkneufeld: I'm a little uncomfortable with this because I'm explicitly trying to host an uncondoned but useful superset of the official docs. see andyf's thalia. also type signatures and soforth.

11:06 not that I've had the time let alone codebase stability to start copy editing yet..

11:06 lduros: there's a page that dates back from 2011 talking about it: http://dev.clojure.org/display/design/Android+Support

11:06 Glenjamin: arrdem: uncomfortable with which bit?

11:07 arrdem: Glenjamin: being further officiated by virtue of being "the" Clojure dash documentation set :P

11:07 rkneufeld: arrdem: There actually is an official(?) one alreayd.

11:07 Glenjamin: there's already "the" set in dash, which uses the clojure.github.io one

11:07 rkneufeld: But Grimoire is far more useful to me

11:07 arrdem: okay. that's totally legit

11:08 * arrdem resumes attempting to hitch his ox to the cart

11:08 swi: justin_smith: i will try next day :) thank a lot for help :)

11:18 clgv: arrdem: do you plan to write blog posts about the aot emitter while developing it?

11:19 arrdem: clgv: that's been on my todo list for a while... there'll definitely be a post, probably a paper and maybe a clojure/conj talk about it. right now just trying to get the damn thing working...

11:20 clgv: arrdem: good :) I just thought that maby experiences during development could also be informative for others ;)

11:20 *maybe

11:26 arrdem: do you know how complete tools.emitter.jvm is?

11:26 arrdem: clgv: tejvm will do everything except write init classes and classfiles.

11:29 I have code to do the latter, the former is really a bug that needs to get fixed at some point.

11:42 gill_: anyone using loom?

11:42 arrdem: have before, what's up?

11:42 gill_: how would I graph a sequence? all the examples are not in a seq

11:43 arrdem: what does that mean? are you asking if you can have an arbitrary sequence as the children of a DAG node?

11:43 s/DAG/DG/g

11:44 gill_: like (graph [1 2] [2 3] [0 1] [3 0]) is let's say the example. I want to do (graph ([1 2] [2 3]))

11:44 passing in a seq returns something I do not expect

11:45 arrdem: (graph '([1 2] [2 3])) should be (apply graph '([1 2] [2 3])) which is (graph [1 2] [2 3])

11:45 gill_: oh okay

11:45 that makes sense

11:45 it'd be more ideal to just have graph accept a seq, thanks :D

11:46 arrdem: eh... apply has no performance overhead in this case, so there's no reason to complicate the function logic and change the API to support it..

11:52 ghadishayban: Got some much better invokedynamic performance last night

11:52 arrdem: RFC: api.grimoire.arrdem.com or grimoire.arrdem.com/api/?

11:52 ghadishayban: do you have official numbers yet? :P

11:53 Glenjamin: api.

11:53 ghadishayban: should be able to release some stuff to play around with

11:53 by monday

11:53 Glenjamin: i thought you were doing oxcart stuff :p

11:53 arrdem: sweet!

11:53 teslanick: api.grimoire..

11:53 ghadishayban: I'm avoiding claiming number

11:53 s

11:53 arrdem: fair

11:54 ghadishayban: but obviously I won't release anything I believe is slower than -master

11:54 vars and keyword invokes are there already

11:54 fighting performance on proto invokes

11:55 it's pretty amazing, Rich put in two fast paths on the bytecode

11:55 mthvedt: deathknight: have you been integrating qarth into the facebook thing you were working on?

11:56 arrdem: api... it is

11:56 deathknight: I havent gotten to that yet mthvedt

11:56 Im reviewing shell scripts for the first time >.<

11:56 ghadishayban: the obvious one is invoking the interface on a target object if it has one, and then falling back to looking up through the var+cache

11:58 but there is a fastpath for objects whose class just got looked up

11:58 mthvedt: deathknight: the examples work fine for you?

11:58 ghadishayban: i added both of those fastpaths, the MethodHandle combinators are pretty slick

11:58 deathknight: havent been able to give it a real go yet mthvedt

11:58 mthvedt: ok no

11:58 np

11:58 deathknight: i'll be sure to be in contact when I do!!!

11:59 i;d love to help out in any way to this awesome project

11:59 mthvedt: deathknight: thanks

12:01 debating whether to ANN...

12:01 deathknight: ann?

12:01 arrdem: [ANN] my-osum-project 0.1.0

12:06 mthvedt: i basically only had one user (two now), so i’m reluctant to release, but no other obvious way forward

12:06 i’ll get a burrito then decide

12:09 gzmask: hello everyone :) does any of you know a good static site generator?

12:10 arrdem: there are a couple for Clojure... none that I can say I've used (yet) tho...

12:11 rkneufeld: Glenjamin: et all, would user docs of other contrib libraries be something you'd like too see in the future?

12:11 gzmask: I am on the verge of using a static generator or just use cljs :{

12:11 technomancy: gzmask: static site generators don't really take advantage of the strengths of clojure

12:12 gzmask: what's the best bet if I just want a quick way to make a github cv/blog?

12:13 technomancy: I have like a hundred lines of ruby for mine

12:13 arrdem: Jekyll is good for a quick "close enough" one-off... that's what I use for my blog

12:14 it works OK for minimal customization, but once you really want to do more than dated posts and a few hand coded static pages it breaks down pretty hard.

12:14 technomancy: which is a great way to prevent yourself from wasting a lot of time on your blog

12:15 TimMc: technomancy: Time much better spent on writing blogging software, yes.

12:16 arrdem: Jekyll will give you syntax highlighting and some other stuff that you could otherwise waste a _lot_ of time getting working more or less out of the box. Jelly Bootstrap is also really nice and packages comments, analytics and some other good stuff as well as some reasonable community themes.

12:16 gzmask: It's very difficult for me to restrain from playing with blogging software too

12:17 technomancy: syntax highlighting is pretty easy if you blog from emacs

12:18 M-x htmlize-region

12:18 arrdem: fair

12:19 gzmask: is that if using Emacs might as well just write vanilla html? I am a vim user, but I tried Evil-mode and it's nice.

12:21 technomancy: gzmask: yeah, I write in HTML with a splash of ruby to insert common headers/footers and generate listings. markdown is another popular choice

12:22 gzmask: sounds like you made yourself a generator ;)

12:23 technomancy: as long as it's under 200 lines I don't have a problem with ruby

12:25 gzmask: I wish I can be as practical as you. I pretty much force myself to use clojure for everything these days. And I know this is not right.

12:26 technomancy: well I wrote this before Clojure was released

12:26 http://p.hagelb.org/Rakefile.html

12:33 gzmask: arrdem: is Jekyll-Bootstrap stand-alone or it requires jekyll?

12:34 arrdem: gzmask: it's a bunch of template files for Jekyll.

12:34 Glenjamin: arrdem: I think codox etc do a good job of third party libs

12:35 Adding 3rd parties to grimoire would make them seem blessed in some way, and possibly add undesired maintenance overhead

12:35 I think

12:35 arrdem: yeah. I'm willing to compete with Clojuredocs for documenting clojure/core since it's relatively inactive ATM, but I think that there's kinda no good reason to take on cross-clj.

12:40 johnwalker: can you have an atom of sets in om?

12:40 i know lists aren't allowed

12:40 ambrosebs: is there a consistent way to great a new instance of a deftype with the same fields as an old one?

12:40 is there a consistent way to create a new instance of a deftype with the same fields as an old one?

12:41 awwaiid: johnwalker: what do you mean lists aren't allowed?

12:41 technomancy: arrdem: would people set up their own grimoire instances for their own libs?

12:41 clgv: ambrosebs: havent seen anything like it. is there a usecase for deftypes with only final field?

12:42 awwaiid: johnwalker: (def x (atom '(a b c d))) works fine for me

12:42 arrdem: technomancy: https://github.com/arrdem/grimoire/issues/28

12:42 johnwalker: awwaiid: in the context of om

12:42 technomancy: arrdem: dead link to crossclj

12:43 awwaiid: johnwalker: ahhh

12:43 arrdem: technomancy: wha? where?

12:43 oh. in the issue.

12:43 Bronsa: arrdem: it's .info

12:43 arrdem: Bronsa: yeah just realized that.

12:43 ambrosebs: clgv: weighing up my options in proxying a deftype to validate it, where the fields themselves can't be immediately checked, like a function argument

12:44 deftypes are final, so proxying itself is out

12:44 clgv: oh ok

12:44 arrdem: fixed.

12:45 clgv: so you actually want a proxy with additional fields?

12:45 ambrosebs: I don't know if I want additional fields, I want the same fields but they should be wrapped in runtime checks

12:46 it would be great if (instance? Foo x) was still preserved too

12:46 but deftype being final pretty much nullifies any chance of that, afaik

12:47 clgv: ah ok. I thought that was a concret use case but you are probably working on that for core.typed?

12:47 ambrosebs: I really do want a proxy tho, since I also want to wrap its methods in checks :(

12:47 right, the use case is using untyped code from typed code, and preserving type assumptions at runtime

12:48 and then blaming the correct party when hell breaks loose

12:48 Typed Racket basically redefines the struct I think

12:49 clgv: humm well, it would be easy to accomplish with arbitrary class generation. we need that macro ;)

12:50 I have some use cases for that as well ;)

12:50 ambrosebs: what do you mean?

12:51 clgv: I mean a macro like reify, deftype but which does allow you to create arbitray java classes (super classes if needed, interfaces, fields ...)

12:52 your wrapper would be easily implemented with that

12:53 ambrosebs: genclass?

12:53 one issue is of course, if I redefine the deftype, all current instances are now outdated.

12:54 clgv: I thought you just define a wrapper?

12:54 well another option would be the aspect oriented approach, where they modify the bytecode of the class

12:55 e.g. what they do in AspectJ

12:55 ambrosebs: I want a wrapper with the same name and attributes.

12:55 effectively

12:56 yes perhaps that's my next bet

12:56 clgv: ambrosebs: should be possible with the asm lib thats included in clojure

12:57 ambrosebs: oh? not familiar with either

12:57 arrdem: objectweb's asm lib is how clojure does bytecode generation...

12:57 ambrosebs: yes I know that much, not any more tho

12:57 thanks for the pointer

12:59 I'm not sure what I want to actually achieve now..

13:00 I guess I want to proxy a deftype, with the ability to override methods, and preserve (instance? Foo x)

13:01 a subclass I guess

13:02 clgv: ambrosebs: having to learn the asm lib will be a significant effort, I guess

13:02 ambrosebs: I'm sure

13:03 but I already agreed to give a conference talk on this..

13:03 shit

13:03 ;)

13:03 one way to motivate

13:03 clgv: yeah well, I know how that feels ;)

13:04 best conferences are those that demand full papers since you can be sure you have the finished content when the slides need to be created ;)

13:07 ambrosebs: I'm planning to write a paper the conference after this, does that count?

13:07 no time, should look at asm

13:09 clgv: I guess not ;)

13:11 verma: when I specify externs in cljsbuild configs the paths are relative to my project's root right?

13:18 oh, its a compiler parameter :P

13:25 ghadishayban: woo last known bug squashed on invokedynamic protocol calls...

13:26 I can successfully run & compile our largest app at work on invokedynamic

13:28 clgv: ghadishayban: github link?

13:28 ghadishayban: you mean using invokedynamic for clojure variables?

13:30 ambrosebs: ghadishayban: congrats!

13:30 tbaldridge: nice!

13:30 Bronsa: ghadishayban: sounds exciting

13:56 SagiCZ1: (doc def)

13:56 clojurebot: eval service is offline

13:57 arrdem: http://grimoire.arrdem.com/1.6.0/clojure.repl/doc

13:58 dmillett: Try tracking accumulated file/line commits (churn) from the command line for a git repository? See 'git-commit-churn' (https://github.com/dmillett/bash-help)

14:01 hiredman: I always forget clojurebot routes services through an openvpn that is vesa mounted on the back of one of my monitors

14:07 dbasch: after a few months of nothing but clojure, coding in ruby feels like typing with my knuckles

14:07 johnwalker: lol

14:09 arrdem: i saw that grimoire got integrated into cider

14:09 is there any way to get the examples in there also?

14:09 arrdem: johnwalker: https://github.com/arrdem/grimoire/issues/53

14:09 johnwalker: nniiiiiiice

14:10 (inc arrdem)

14:10 lazybot: ⇒ 34

14:22 arrdem: trptcolin: are you trying to grab a header delimited, terminal appropriate string here?

14:23 trptcolin: yep

14:23 arrdem: herm. yeah as specified there's no way to do that in a single get.


14:24 trptcolin: right i couldn’t tell if e.g. `/$VERSION/$NAMESPACE/$SYMBOL/` would use “Accept: text/plain” or if they’d actually be different URLs

14:25 arrdem: odds are I won't be arsed to build something sufficiently bright to check headers :P

14:25 I think a different file is probably for the best...

14:25 it'll just be a server-side concatination of all the other API resources anyway.

14:25 trptcolin: i think the accept header idea is the “right” way to do it but i don’t personally care as long as there’s a way to (slurp URL_HERE) and get the info

14:26 arrdem: hum...

14:26 lemme see if there's something I can do to nginx such that I can support the text/plain using only static files. If so I'll do that, otherwise I'll do a standalone file.

14:28 trptcolin: bbloom: really, pencils you have to sharpen?

14:29 bbloom: trptcolin: many good ideas have been had during pencil sharping

14:29 trptcolin: although maybe that’s the trick to why CS was so awesome in the 60s & 70s

14:29 :)

14:29 arrdem: trptcolin: looks like if you hit /foo/ with Type: text/plain, it'll hit index.txt rather than index.html.

14:30 so yeah I'll just add that Type: text/plain shall work on the normal symbol root path, and if you ask for text/plain you'll get it.

14:52 Ro_: hello, is there an open source datomic clone?

14:52 TimMc: No.

14:53 * tbaldridge makes some popcorn

14:53 TimMc: I mean, there might be some other datalog type stuff out there, but you're not going to find Datomic-the-free-version.

14:54 technomancy: you could write one

14:55 Ro_: :)

14:57 technomancy, I am thinking about it :)

14:57 technomancy: cool

14:58 Ro_: The only thing I need to know, what about patents, Do they have it on Datomic?

14:58 bbloom: Ro_: shhh

14:58 the last thing you want to do is inquire about patents

14:59 knowingly violating patents is worse

14:59 mdrogalis: Licensing battle: Part 2

14:59 * mdrogalis sounds the gong

14:59 * tbaldridge makes more popcorn

14:59 * arrdem popcorn

14:59 mdrogalis: tbaldridge: Please step into the ring. Ding Ding!

14:59 technomancy: Ro_: rule one of software: it violates patents.

14:59 there are no exceptions.

14:59 tbaldridge: mdrogalis: not going close to this discussion ;-)

15:00 Ro_: So you are saying it is kind of OK?

15:00 justin_smith: https://www.youtube.com/watch?v=AvDvTnTGjgQ

15:00 mdrogalis: tbaldridge: Smart man :P

15:01 technomancy: hey, at least this time it's not idle complaining

15:01 justin_smith: m'kendiepoppetycorn

15:01 tbaldridge: (inc technomancy)

15:01 lazybot: ⇒ 125

15:01 tbaldridge: I'm interested in seeing where it would go just from a programmer standpoint.

15:02 I mean it only took Rich and Co about 2 years to write Datomic...

15:02 pmonks: (inc justin_smith) ; for swedish chef awesomesauce

15:02 lazybot: ⇒ 52

15:02 bbloom: Ro_: http://patents.stackexchange.com/questions/475/does-looking-at-prior-art-searches-pose-a-risk-for-engineers

15:02 arrdem: (inc justin_smith) bork bork bork bork

15:03 (inc justin_smith) ; bork bork bork

15:03 lazybot: ⇒ 53

15:03 bbloom: weee treble damages

15:03 dbasch: (dec patents)

15:03 lazybot: ⇒ -2

15:03 tbaldridge: dbasch: you can't do that, dec is patented

15:04 dbasch: (inc sue-me)

15:04 lazybot: ⇒ 1

15:04 tbaldridge: anyone else remember this gem? https://www.techdirt.com/articles/20110102/15363912492/ibm-files-patent-patent-trolling-it-may-be-too-late.shtml

15:04 * arrdem consults his rulebook for the dice count when rolling "treble damage"

15:04 justin_smith: technomancy: "Third, sometimes parties are sued for inducing infringement -- i.e., encouraging someone else to infringe." uhoh

15:05 dbasch: some country should sue the US for infringing their patent on patent laws

15:05 arrdem: "Cognitect vs. #Cloure et. all"

15:05 justin_smith: heh

15:05 * bbloom tugs on collar

15:06 Ro_: P.S. I am not from US ;)

15:07 technomancy: Ro_: lucky you!

15:07 dbasch: Ro_: oh, then you’re never going to get sued by a US company. US companies are extremely mindful of borders.

15:07 arrdem: lol

15:07 Ro_: So I am kind of "safe" :D

15:08 aperiodic: and there are certainly no trade agreements extending the domain of the US's patent & IP systems

15:08 turbofail: careful, sarcasm is patented now too

15:08 bbloom: dbasch: maybe they don't have sarcasm in his country

15:09 Ro_: I know there was such a talk, but could you tell me once more: why Rich Hickey did not enforce Datomic opensource?

15:09 TimMc: What if their country has defined "patents" as "a type of fish"? That should protect them.

15:09 dbasch: bbloom: I just exported it then :)

15:10 technomancy: Let's weaponize sarcasm.

15:10 SagiCZ1: justin_smith: hey there

15:10 justin_smith: SagiCZ1: https://38.media.tumblr.com/cc047915ad3d725e2d96e09cc1f5433f/tumblr_n83ikzjgiV1qak4ico1_400.gif

15:10 TimMc: dbasch: *gasp* You're in contravention of the Export Administration Regulations!

15:10 bbloom: technomancy: https://www.youtube.com/watch?v=hsW9DO1k5-s

15:10 dbasch: TimMc: no, it’s only 32-bit sarcasm. I wouldn’t do 128-bit on irc.

15:10 SagiCZ1: justin_smith: ouch

15:10 TimMc: ah, phew

15:10 arrdem: dbasch: dude utf8 supports multiword sarcasm

15:11 Ro_: Every time I come to Clojure channel I am glad that the Clojure community is so nice :)

15:11 tbaldridge: Ro_: I'm trying to find you a point in a talk where Rich answers that

15:11 Ro_: ok, thx

15:12 arrdem: #clojure is pretty good about grousing politely

15:12 justin_smith: arrdem: you take that back, jackass

15:12 arrdem: (dec justin_smith)

15:12 lazybot: ⇒ 52

15:12 arrdem: (dec so)

15:12 lazybot: ⇒ -32

15:13 SagiCZ1: justin_smith: I am originally java programmer and I have a problem expressing myself in functional language.. how do you go about preserving states when you need to? Example: Let's have a group of creatures who interact with their environment and save some data about it, or just save the history of their actions right? How would I save that and access? For now, each creature is represented by one function object i guess.. Can I avoid

15:13 tbaldridge: Ro_: http://youtu.be/FOQVWdG5e2s?t=38m38s

15:13 technomancy: one of these days so is going to change his nick and we're not going to notice; we'll just keep on dec-ing him out of tradition.

15:13 http://p.hagelb.org/tradition.jpg

15:14 justin_smith: SagiCZ1: a common pattern is to make a function that takes "state" as its argument, then returns an updated version of the state. The hard part is not preserving the state (it is immutible after all), it is about propagating the updated one.

15:14 * arrdem votes so for the first person to break -100

15:14 * tbaldridge writes a bot for that

15:15 SagiCZ1: justin_smith: yeah, i guess what i meant by "preserving" should be called "updating" .. so passing it in and out.. interesting

15:15 justin_smith: SagiCZ1: also, pragmatically we have things like atoms and ref with safe update behaviors

15:16 SagiCZ1: justin_smith: and what is the communities stance on them? are they necessary evil for corner cases or normal part of everyday use?

15:16 justin_smith: but that is needed only rarely (maybe in one place in a huge lib), mostly you can use function arguments / return values to propagate

15:16 Ro_: technomancy: Rich does answer the question :D

15:16 SagiCZ1: justin_smith: so that answers that

15:16 justin_smith: I am sure other developers here will weigh in on how often they use an atom or agent or whatever to coordinate state

15:16 SagiCZ1: feel free to chip in guys

15:17 TimMc: arrdem: So, you really find it so bad? For me it's only so-so.

15:17 arrdem: har har har

15:17 tbaldridge: atom almost all the time, I haven't used agents since core.async came out

15:17 TimMc: /nick har

15:17 justin_smith: SagiCZ1: another thing to consider is that if in some library you define an atom that holds library state, you are limiting the user to only one state for the library in their entire app - if it is an argument that is propagated, they can use the library in different places without interference

15:18 * arrdem realizes so isn't here anymore

15:18 tbaldridge: but yeah, arguments over atoms

15:18 brunov: SagiCZ1: for an illustration of what justin_smith just said, take a look at how Clara handles its session state in an immutable manner https://github.com/rbrush/clara-rules

15:18 technomancy: Ro_: is it because his efforts to fund-raise through donations went badly?

15:18 TimMc: SagiCZ1: refs are amazing but basically no one uses them. :-)

15:18 brunov: each function accepts a state object as first argument and returns a modified version

15:18 TimMc: They're a gateway drug.

15:20 arrdem: is there a writeup somewhere of compojure's route formatting? I'm not seeing one right off.

15:20 SagiCZ1: justin_smith: remember how i talked about "creatures" lets say I each of them runs some calculations and I want each "creature" to have its own thread. Is it still achievable without refs, or I need them to collect the "creatures" data? I hope you its not too abstract.

15:20 Ro_: technomancy: Nope.

15:20 justin_smith: SagiCZ1: this sounds very similar to how agents work

15:21 Ro_: technomancy: Rich "I have a kind in college"

15:21 justin_smith: SagiCZ1: with an agent, you start it out with a value, then you send it functions that update that value

15:21 Ro_: :)

15:21 SagiCZ1: justin_smith: "agent" would be even more precise name for my creatures, because they would be trading agents.. so agents are a thing in clojure

15:22 justin_smith: SagiCZ1: but there are multiple ways to do this. Each creature could be a core.async go block that reads perterbations from a channel, and responds by sending messages to other creatures via channels

15:22 TimMc: SagiCZ1: Careful, "agent" is an overloaded word.

15:22 justin_smith: SagiCZ1: or all the creatures could be in a map, with another map describing their relationships or interactions

15:22 SagiCZ1: TimMc: Yes I realize that

15:22 Ro_: Do you know any papers on Datomic which could help me to clone the "stuff"?

15:23 SagiCZ1: justin_smith: one thing someone recommended earlier was to hold a map with the creatures as keys and their data as values and update that map somehow (it would be ref map)

15:23 justin_smith: SagiCZ1: with the map representation, you would have a state updater that walks through and propagates one "tick" of updates for all creatures

15:23 would not have to be a ref map

15:23 it could be a function that takes the creature map as input, and returns an updated map

15:24 katratxo: Ro_: http://tonsky.me/blog/unofficial-guide-to-datomic-internals/

15:24 SagiCZ1: justin_smith: and can multiple alter the same map at once? (if they are in different threads)

15:24 justin_smith: the storage could be in a ref, could just be a question of passing the map back into the function again, could be persisted to a db or edn file...

15:24 Ro_: ty

15:25 justin_smith: SagiCZ1: the map is immutible, if you want parallel processing you could split up the processing per key in the updater function, or make it a reference type (atom, ref, datomic data, whatever) and then coordinate the updates

15:25 even with a mutable reference type, the map inside is immutible, because maps just are

15:26 SagiCZ1: justin_smith: I see.. well I won't pretend to know exactly how to do that, but I am glad to hear that its very possible. I will learn more about clojure first though.

15:28 bbloom: ,((fn [x] {:pre (pos? x)} x) -5) ; ouch

15:28 clojurebot: -5

15:28 justin_smith: SagiCZ1: one of Rich Hickey's clojure talks is about simulating a colony of ants via parallel updates

15:28 bbloom: ,((fn [x] {:pre [(pos? x)]} x) -5)

15:28 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (pos? x)>

15:28 SagiCZ1: justin_smith: yeah i was impressed by that

15:28 bbloom: i guess both pos? and x are true....

15:29 justin_smith: bbloom: yeah, that hit me a few times before I knew what I was doing

15:29 SagiCZ1: justin_smith: easy concurrency is why I chose clojure for my project over java

15:29 * bbloom is making a damn patch

15:29 schmee: heyo, I have a quick question about sockets

15:29 I connect to a server and then spawn a thread with that socket to listens to messages from the server

15:29 justin_smith: bbloom: what would the patch do? complain if the pre arg is not a callable?

15:30 PigDude: mmm i'm getting chicken korma from the indian place by me while i work on some korma stuff

15:30 schmee: but calling `read` on the reader just keeps spitting out nil, is there any way to make it block until it receives a message?

15:30 bbloom: justin_smith: require the conditions be a vector

15:30 justin_smith: bbloom: cool

15:33 hiredman: schmee: read on a Reader cannot return nil

15:33 http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html#read%28%29

15:35 unless by read you mean clojure.core/read which works on pushbackreaders, and can return nil, and certainly does block

15:37 schmee: hiredman: strange... here's the function in question: https://gist.github.com/schmee/522e29e355428a627fe2

15:38 hiredman: I would expect that to throw an exception

15:39 schmee: I spawn the thread with `(doto (Thread. #(listen sock)) (.start))

15:39 `

15:39 justin_smith: yeah, read on an io/reader always fails when I do it (it is only thanks to my stupidity that I have tried it so often)

15:39 hyPiRion: schmee: you're using read, you want .read.

15:39 hiredman: ,(doc read)

15:39 clojurebot: "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in*. Note that read can execute code (controlled by *read-eval*), and as such should be used only with trusted sources. For data structure interop use clojure.edn/read"

15:40 hiredman: ^- takes a pushbackreader and reads a clojure form

15:40 schmee: depending on your setup stacktraces maybe being printed to random places where you might not be looking

15:41 schmee: hiredman: can I wrap it in a try catch or something?

15:41 hiredman: sure

15:42 consider using a future instead of manually starting a thread

15:42 bbloom: justin_smith: http://dev.clojure.org/jira/browse/CLJ-1473

15:43 schmee: hiredman: I will, I was going to ask here when I'm finished with code if it can be made more "clojure-y" :)

15:44 thanks everyone for the suggestions, I'll try them out!

15:44 justin_smith: bbloom: nice

15:47 schmee: regarding idiomatic clojure, instead of while / checking an atom, you could loop/recur with a check that looks for your termination condition

15:47 since the atom is bound in that let block, you clearly are not using it to detect a condition coming from another thread

15:49 schmee: I'll do that, thanks. I've just randomly copypasted the conditions in a lot of places since I don't need them atm, so it probably doesn't work the way it should :P

15:49 pandeiro: anyone have experience testing reactjs apps using clj-webdriver? i am new to selenium and not sure if DOM tests operate against a page's initial HTML or the actual DOM environment in memory

15:50 gzmask: is there any interesting clojurescript eco-system news website out there?

15:50 dbasch: justin_smith schmee: in that snippet there is no termination condition, the atom is completely unnecessary

15:51 the “running” binding, for that matter

15:51 justin_smith: dbasch: indeed, but I assumed in some future version there would be a termination condition

15:51 schmee: yep

15:52 justin_smith: and I think conditional recur is more idiomatic than an atom as sentinel

15:52 dbasch: justin_smith: of course

15:53 mmitchel_: is there a way to convert a record into a plain hash-map?

15:54 hiredman: (into {} ...)

15:54 mmitchel_: ahh perfect

15:54 thanks hiredman

15:56 mkrlearner: Quoting doesn't work for ^ symbol. Any specific reason for that?

15:56 user> '(1 2 3 a b c ^) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221)

15:56 justin_smith: ^ is read time

15:57 mkrlearner: I want a list of mathematical symbols like +, -, *, /, ^ (for power), and I am not able to make one :(

15:58 tbaldridge: mkrlearner: ^ is a special symbol that attaches metadata

15:58 , (meta ^{:doc "foo"} {})

15:58 clojurebot: {:doc "foo"}

15:59 justin_smith: ,(symbol "^") it's possible to put it in a symbol, but it's hacky and not very usable

15:59 clojurebot: ^

15:59 Zekka: Have you considered **?

15:59 mkrlearner: I am changing it to ** right now.

15:59 tbaldridge: or pow

16:00 SagiCZ1: tbaldridge: what are metadata for?

16:00 tbaldridge: SagiCZ1: lots of stuff, for example line numbers and the like

16:00 ,(meta '(+ 1 2))

16:00 clojurebot: nil

16:00 mkrlearner: Yeah I get it. I thought quote would take lower precedence than metadata.

16:00 tbaldridge: or not in that example

16:01 ,(meta #'conj)

16:01 clojurebot: {:ns #<Namespace clojure.core>, :name conj, :added "1.0", :file "clojure/core.clj", :static true, ...}

16:01 tbaldridge: ,(keys (meta #'conj))

16:01 clojurebot: (:ns :name :added :file :static ...)

16:01 justin_smith: SagiCZ1: we use it to attach documentation to vars, to differentiate macros from functions, to mark the type as a guide to the compiler... all sorts of things

16:01 tbaldridge: bleh, nevermind, but lots of stuff in there

16:02 mkrlearner: metadata is the only way to add additional info to a data-structure without compromising its equality semantics.

16:04 SagiCZ1: justin_smith: thanks :)

16:04 btw.. i wanted to register my nick to freenode.. it for some reason added "1" to it.. why?

16:09 arrdem: anyone care to recommend mustache or some other HTML string templating engine?

16:10 * tbaldridge makes a 3rd batch of popcorn

16:10 arrdem: tbaldridge: quiet you

16:10 schmee: any way to reset the REPL without restarting it? to get rid of all the state

16:10 tbaldridge: arrdem: just start a emacs/vim war while your at it...

16:10 :-D

16:10 technomancy: wasn't templating the original bitemyapp rant topic before he learned haskell?

16:10 TimMc: tbaldridge: Nonsense, it's ed vs. nano.

16:10 arrdem: technomancy: yep, and it was the last rant I got from him before we stopped hanging out.

16:11 TimMc: technomancy: I used to rant about it too. Then I finally figured out how to use enlive.

16:11 * tbaldridge wonders what Haskell template engines look like

16:11 technomancy: I've only used hiccup, and I love it, but I understand there are situations for which it's inappropriate

16:12 arrdem: I've just already got a boatload of liquid template files which are near mustache and I'd rather not retype all of them in hiccup which is otherwise my Clojure HTML preference.

16:12 hyPiRion: technomancy: I'm pretty sure he learned Haskell before that

16:12 technomancy: well, before haskell destroyed him anyway

16:12 arrdem: well there's already a liquid implementation for Clojure...

16:12 augustl: is there a way to do int r; while ((r = doARead()) != 1) { thing.update(bfr, 0, r) } in clojure?

16:12 * arrdem ponders his luck

16:16 hyPiRion: augustl: (loop [r (doARead)] (when (not= 1 r) (. thing (update bfr 0 r)) (recur (doARead)))) ?

16:16 augustl: it's a bit annoying to have to repeat the doARead :)

16:18 hyPiRion: (doseq [r (take-while (comp not neg?) (repeatedly #(doARead)))] (. thing (update bfr 0 r)))

16:18 TimMc: heh

16:20 teslanick: I wonder...

16:20 ,(apropos #".*")

16:20 clojurebot: (primitives-classnames +' decimal? restart-agent sort-by ...)

16:21 teslanick: Awesome! Just discovered apropos, didn't think clojurebot would let me use it for some reason.

16:26 technomancy: thank goodness for *print-length*

16:27 justin_smith: teslanick: there is also (all-ns) and (ns-publics 'some-ns)

16:40 arrdem: tbaldridge: Grimoire had better count against my GSoC work :P

16:54 verma: are the clojure stickers here [1] opaque? [1] http://clojure.org/swag

16:55 anyone have them?

16:55 hiredman: they are

16:57 (assuming they are the same stickers they hand out at the conj)

16:57 verma: aw man, I want the mac's apple light to go through the sticker, like translucent would be awesome

16:57 technomancy: lein stickers are translucent

16:57 just sayin'

16:58 verma: technomancy, are there available somewhere? or where did you get them made?

16:59 oh accepted patch gets you a sticker :)

16:59 technomancy: verma: if you make a contribution to lein that's accepted, you can get a sticker.

16:59 I forgot where I got them

16:59 * arrdem digs for the old template update he PR'd

16:59 justin_smith: technomancy: I know you don't mean it that way, but that just sounds so gradeschool condescending

17:00 technomancy: hah

17:00 justin_smith: "oh, a patch? for me? have a sticker" headpat

17:00 llasram: Well, maybe if the sticker were automatic

17:00 hyPiRion: justin_smith: Would a golden star be better?

17:00 augustl: hyPiRion: ah, nice one (almost 1 hour ago)

17:00 llasram: But since you then have to ask for the sticker... It's more like "Here's patch. So.... sticker? Eh?"

17:00 ghadishayban: I love this UnwarrantedOptimismException http://hg.openjdk.java.net/jdk9/jdk9/nashorn/file/49d7a2a66ae6/src/jdk/nashorn/internal/runtime/UnwarrantedOptimismException.java

17:01 technomancy: llasram: so... require a mailing address before accepting any patches? =) where have I heard that before?

17:01 llasram: lol

17:02 verma: I can get clojure stickers made right, no problems with that, I would think

17:02 hiredman: this channel is not really the place to ask

17:03 TimMc: verma: There is probably a trademark or copyright on that logo.

17:03 hiredman: there is

17:03 verma: TimMc, hmmm

17:03 llasram: tradecopymarkright

17:03 technomancy: possibly even a patent

17:03 arrdem: that Grimoire and a bunch of other Clojure resources infringe on..

17:05 hiredman: бизнес methods for logo design

17:06 TimMc: technomancy: "A method for combining yin-yang and lambda symbols."

17:14 augustl: I can't seem to figure out how to call http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#readAttributes%28java.nio.file.Path,%20java.lang.Class,%20java.nio.file.LinkOption...%29

17:15 (Files/readAttributes (.toPath pic-file) BasicFileAttributes) fails with java.lang.IllegalArgumentException: No matching method: readAttributes

17:15 hiredman: … means array

17:15 Fare: what's the simplest way to test whether an object is a Java byte array [B ?

17:16 augustl: hiredman: so I need to pass an empty array?§

17:16 hiredman: no

17:16 yes

17:16 augustl: :)

17:16 hiredman: is what I meant

17:16 :)

17:16 trptcolin: Fare: (= (Class/forName "[B") …)

17:17 Fare: I can (= (type x) (type (byte-array []))) but that's somewhat ugly

17:17 trptcolin, thanks

17:17 same thing, I suppose

17:17 your being slightly cleaner

17:17 justin_smith: ,(= "[B" (.getName (class (byte-array (map byte [0 1 2])))))

17:17 clojurebot: true

17:18 Fare: justin_smith, I think that's slightly worse, actually

17:18 augustl: hiredman: (Files/readAttributes (.toPath pic-file) BasicFileAttributes (make-array LinkOption 0)) works wonders :)

17:18 * Fare caches (Class/forname "[B") in a ref, and there I go.

17:19 dbasch: Fare: a ref? that’s ugliest

17:19 Fare: BTW, what does declare do? Apparently not enough for me, possibly because I'm passing the forward-referenced function as parameter while buidling a data structure

17:19 (the data structure being a monadic parser)

17:20 in the end, I ended up coding my own variant of declare, that binds the ref to a function that consults the ref at a later time to the the actual value

17:21 mthvedt: Fare: declare makes an unbound var

17:22 Fare: OK

17:22 mthvedt: not quite understanding why one would need an “earlier” late binding

17:23 Fare: (declare-forward f) (def g (wrap f)) (def f (wrap-differently g))

17:23 dbasch: Fare: do you really mean ref or do you mean var?

17:23 Fare: dbasch: I'm not sure

17:23 dbasch: Fare: if you’re not sure, you probably mean var

17:23 Fare: probably mean var

17:24 yes, I use var-get

17:24 (defmacro def-forward [& names] `(do ~@(map #(do `(defn ~% [~'σ] ((var-get #'~%) ~'σ))) names)))

17:24 (they are all functions of one argument)

17:25 (monadic parsers)

17:34 hugod: In an om render function, can you render multiple nodes, or just a single node (with children)?

17:36 mthvedt: fare: you’re binding vars to fns that get themselves?

17:36 how does that work

17:36 Fare: mthvedt, the function is defined later.

17:37 the early binding is to use the late binding

17:37 mthvedt: so you’re referencing the fn earlier, but calling it later?

17:37 Fare: yes

17:38 danielcompton: so top level packages are frowned upon?

17:38 justin_smith: danielcompton: yeah, definitely

17:38 Fare: maybe I could simplify in (declare f) (def f [n] (f n)) ? or would that be simplified in a recur?

17:41 mthvedt: fare: clojure looks up bindings each time a var is invoked

17:41 it relies on the JVM to optimize away most of the lookups

17:44 Fare: so, maybe `(do (declare ~f) (def ~f (fn [~'x#] (~f ~'x#)) ?

17:45 mthvedt: i think that would work

17:45 you don’t need to quote unquote the x#

17:45 in fact just make it a defn

17:46 danielcompton: justin_smith: ztellman gets to be the exception?

17:46 ztellman_: I get to be what?

17:46 talios: 'lo danielcompton

17:46 danielcompton: top level package

17:46 bbloom: Fare: you know you can give functions names without def, right?

17:46 danielcompton: publisher

17:47 hiredman: danielcompton: what do you mean by top level package?

17:47 ztellman_: oh, top-level packages are bad because they're not easily consumable by other stuff

17:47 Fare: bbloom, and pass them as parameters to other functions?

17:47 ztellman_: though the new Clojure Java API stuff pretty much sidesteps that

17:47 bbloom: Fare: yeah

17:47 danielcompton: from http://i.imgur.com/Ue9xWJn.png

17:48 bbloom: ,((fn add [x y] (if (zero? x) y (recur (dec x) (inc y)))) 5 10)

17:48 clojurebot: 15

17:48 danielcompton: arrdem commented about top level packages, I assumed he meant 'judo-notes.handler'

17:48 Isn't that a top level package?

17:48 technomancy: no

17:48 bbloom: ,((fn f [] f))

17:48 clojurebot: #<sandbox$eval51$f__52 sandbox$eval51$f__52@a0187c>

17:48 bbloom: Fare: see?

17:48 hiredman: danielcompton: please use a pastebin for sharing text instead of screenshots

17:49 danielcompton: hiredman: I was copying a screenshot published last night in the #clojure channel

17:49 hiredman: :/

17:49 bbloom: what declare really does is it puts an "unbound" var entry in to the mutable namespace map... then when the compiler sees some symbol x, it first looks up x in locals, then if not found, looks it up in the namespace mappings

17:49 in the former case, a vm stack operation is generated

17:49 hiredman: danielcompton: I have no idea what he was refering to by top level package there

17:49 bbloom: in the latter, an invoke is generated to deref on the var

17:50 mthvedt: bbloom: i think he wants to have the var bound to a fn he can pass in to some parser combinators, and that fn looks up the “real” binding later

17:50 Fare: mthvedt, yes

17:50 danielcompton: ztellman_: is lamina a top level package for example?

17:50 ztellman_: danielcompton: no

17:51 bbloom: Fare: to what end? mutual recursion? or something else?

17:51 ztellman_: unless we're using a different definition

17:51 Fare: yes, my tweaked definition works.

17:51 ztellman_: it's lamina.core, lamina.executor, etc

17:51 hiredman: danielcompton: I recommend not using the namespace part stuff like (judo-notes [model :as model]) and just do [judo-notes.model :as model], and use [] instead of () for requires

17:51 ztellman_: my primitive-math library, though, is just 'primitive-math'

17:51 Fare: yes, mutual recursion between two grammar non-terminals

17:51 bbloom: Fare: and is each non-terminal defined as a top level?

17:51 Fare: each non-terminal has a corresponding monadic parser

17:51 yes

17:51 danielcompton: hiredman: it wasn't my code but thanks

17:52 mthvedt: bbloom: parser combinators are usually defined with higher-order fns

17:52 you have fns that make fns that mutually recurse

17:52 bbloom: mthvedt: right, but i'm not sure where he needs the mutual recursion

17:52 hiredman: danielcompton: there is nothing that is called a "package" in clojure so when you say "top level package" everyone has to guess what you mean by package

17:52 mthvedt: it’s a general case for parser combinators

17:52 hiredman: danielcompton: in this case ztellman is guessing you mean namespaces

17:52 ztellman: it's what namespaces are called in Java

17:52 hiredman: toplevel is also a problem, because there is no explicit hierarchy in clojure namespaces

17:53 bbloom: Fare: is your grammar open for extension? or closed?

17:53 mthvedt: a parser generator that can’t conveniently mutually recurse would be kind of gimped

17:53 bbloom: Fare: ie is the set of non-terminals known and finite?

17:53 hiredman: er

17:53 Fare: closed for now, but I'm wondering about the best way to make it extensible later

17:53 hiredman: implicit I guess

17:53 bbloom: so if it's closed, you can just use letfn

17:53 hiredman: anyway, they are non-hierarchical

17:53 bbloom: but you won't get any vars for use from the outside

17:54 Fare: I can't use letfn when most definitions are not (defn foo [x] ...) but (def foo (&combine bar baz))

17:54 hiredman: ztellman: it is a similar construct in java, common lisp also has a similar kind of thing called a package

17:54 bbloom: Fare: ah ok, yeah, there's no general letrec construct

17:54 danielcompton: hiredman: I'm referring to arrdem's comment in http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-07-23.txt at 22:28:22

17:54 I was reading through the logs this morning and was trying to understand what he eant by that

17:55 hiredman: danielcompton: he is talking about maven depedency coordinates

17:55 Fare: I suppose I could eta-convert to avoid some of that... but that's about the same result, isn't it? This way I only eta-convert 9 forward-referenced functions.

17:55 hiredman: danielcompton: which are totally different from clojure namespaces

17:55 Fare: but yeah, to make it extensible, I might need to eta-convert everything, at which point a simple a simple (declare ...) would be enough

17:55 bbloom: Fare: you just need to forward declare one function from every mutually recursive group

17:56 hiredman: danielcompton: and are not packages either, the coordinates are made up of a [group-id/artifact-id version-string]

17:56 bbloom: Fare: do you want an extensible set of non-terminals, or do you want an individual non-terminal to be extensible?

17:56 ie add an alternative to some production

17:56 hiredman: in lein/clojure it is pretty common to use the same thing for both group-id and artifact-id so lein shortens that to just [artifact-id version-string]

17:56 mthvedt: i like the general solution—it is simple and avoids annoying refactoring later

17:57 Fare: bbloom, yup, I only have 9 forward references out of ~79 named non-terminals

17:57 danielcompton: hiredman: thanks. Next question, is it ok to write projects without a fully qualified namespace, e.g. rummy instead of net.danielcompton/rummy

17:57 hiredman: *?

17:57 hiredman: that is not a namespace

17:58 danielcompton: sorry, I mean project naming

17:58 hiredman: sure

17:58 Fare: I think that for now I'm considering leaving the grammar not extensible, and have the same extension points as macropy

17:58 bbloom: Fare: you can "extend" a previous var something like this: (def foo (...)) .... (def foo (add-alternative @#'foo bar))

17:58 hiredman: I assume you are talking about what you pass to lein new when creating a project

17:59 Fare: (though with a different ast structure: the official python ast looks really really misdesigned)

17:59 bbloom: Fare: the @#' is just (deref (var ...))

17:59 which lets you capture the old value

17:59 hiredman: lein new foo/bar will create a new project with the group-id foo and the artifact-id bar, and will generate a namespace foo.bar in the file src/foo/bar.clj

18:00 lein new foo will create a new project with the group-id foo and the artifact-id foo, and will generate a namespace foo.core in the file src/foo/core.clj

18:00 mthvedt: fare: curious, what are you building? are you using a library?

18:00 bbloom: Fare: but if it were me, i may consider not defining non-terminals as vars, but rather as keywords

18:00 Fare: bbloom, yes, but currently I need to recompile the entire grammar every time I do a change, because the uses of a non-terminal in a combinator defining another non-terminal are eagerly bound.

18:00 hiredman: now generally it is frowned on the have single segment namespaces like (ns foo) which is what everyone assumed you were asking about when you asked about top level packages

18:00 Fare: mthvedt, I've made very light use of algo.monads

18:01 hiredman: ~namespaces

18:01 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

18:01 Fare: but ended up only using variants of the state monad, with my own extensions

18:01 technomancy: danielcompton: don't use common nouns for unqualified project names

18:01 bbloom: Fare: you can simply write #'foo to get late binding... vars are callable!

18:01 ,(defn foo [] :old)

18:02 clojurebot: #'sandbox/foo

18:02 hiredman: I have bought domains on impluse because it seemed like they would be a cool group-id for a project

18:02 danielcompton: technomancy: that's what I was trying to work out. So something like lamina would be ok, but light would be frowned upon?

18:02 bbloom: ,(def a (comp vector foo))

18:02 clojurebot: #'sandbox/a

18:02 bbloom: ,(def b (comp vector #'foo))

18:02 clojurebot: #'sandbox/b

18:02 bbloom: ,(a)

18:02 clojurebot: [:old]

18:02 bbloom: ,(b)

18:02 clojurebot: [:old]

18:02 bbloom: ,(defn foo [] :new)

18:02 clojurebot: #'sandbox/foo

18:02 technomancy: danielcompton: right; you're just trying to avoid something that someone else is likely to use as a name

18:02 bbloom: ,(a)

18:02 clojurebot: [:old]

18:02 bbloom: ,(b)

18:02 clojurebot: [:new]

18:02 bbloom: Fare: ^^

18:03 danielcompton: technomancy: and when in doubt, fully qualify?

18:03 technomancy: sure

18:03 bbloom: Fare: alternatively, you could define only a single var which contains a data restructure representing the entire grammar, then use keywords as identities instead of symbols/vars

18:04 so (&compose :foo :bar) instead of (&compose #'foo #'bar)

18:04 the evaluator would just do a lookup for the production lazily

18:05 Fare: bbloom: I would need to eta-convert all my non-terminal combinations, but that's doable

18:05 hiredman: https://github.com/hiredman/raft/blob/master/project.clj has a sweet group-id

18:05 mthvedt: bbloom: that’s basically what i did for https://github.com/mthvedt/clearley

18:05 it’s kind of heavyweight however

18:05 Fare: yes, I could make my combinators explicitly late-bind...

18:06 mthvedt: actually, i lied

18:06 that’s not really what i did

18:06 nevermind

18:10 gf3: getting this error on the default hello world generate by dnolen_'s mie, any ideas? → https://www.refheap.com/3d45d51132c42c4c6761f1f66

18:11 dnolen_: gf3: you need to be on JDK7 at least

18:11 gf3: dnolen_: ahh ok thx

18:12 Fare: so... is there an existing clojure project that would accept silly contributions such as a python parser? I'm having a hard time convincing my boss to convince my VP to underwrite a new project release just for that

18:13 technomancy: Fare: I can create a dummy project and accept pull requests if you like =)

18:13 Fare: technomancy, that might help :-/

18:13 a bit borderline, though

18:14 technomancy: really what you need to do is create a web service that can do this for you

18:14 Fare: :-)

18:14 does anyone here see a use for a python parser?

18:15 danielcompton: Fare: I was wanting to call python libraries from Clojure

18:16 Fare: danielcompton, not the same, unless you also reimplement enough of python...

18:16 danielcompton: Fare: that way madness lies

18:16 Fare: if you want a full python, you're better off calling jython

18:16 on the other hand, if you, like me, are implementing a python dialect...

18:21 (inc bbloom)

18:21 lazybot: ⇒ 38

18:22 {blake}: I'm getting an error trying to use cljs. I type "lein cljsbuild once" and get "java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Associative".

18:22 clojurescript 2268, lein-cljsbuild 1.0.03

18:22 (I sorta figure it's a version error but I can't see it. That's the latest everything.)

18:24 imperman: {blake}: What about :plugins [[lein-cljsbuild "1.0.3"]] in project?

18:24 Fare: (defmacro def-forward [& names] `(do ~@(map #(do `(do (declare ~%) (def ~% #'~%))) names)))

18:24 imperman: {blake}: https://github.com/emezeske/lein-cljsbuild

18:24 {blake}: Yep. (copying and pasting: :plugins [[lein-cljsbuild "1.0.3"]]

18:25 imperman: {blake}: also The lein-cljsbuild plugin works with Leiningen version 2.1.2 or higher.

18:25 {blake}: It's lein 2.3.4.

18:25 imperman: {balke}: hmm...

18:25 {blake}: imperman, Yeah, I went there first. But I've obviously missed something. (I've never had a problem with it before.)

18:26 Fare: I'm not sure I understand what #' does anymore... oh, it's just like calling a symbol in CL... it's actually calling a symbol in clojure.

18:27 duh

18:27 mthvedt: fare: not quite, #’ gets the var bound to a symbol

18:27 clojure bindings go symbol -> var -> value

18:27 {blake}: Huh, the example in cjlsbuild works, with no clojure/clojurescript dependency.

18:28 imperman: {blake}: What about this: In addition, you should add an explicit ClojureScript dependency to your project, like this:

18:28 :dependencies [[org.clojure/clojurescript "0.0-XXXX"]]

18:28 lein-cljsbuild will add a dependency to your project if it doesn't already contain one, but that functionality will not remain for long. The latest version of lein-cljsbuild currently requires a minimum of ClojureScript 0.0-2197.?

18:28 mthvedt: i don’t think common lisp has that

18:28 imperman: {blake}: I don't know exactly. Only try to understand :)

18:29 Fare: oh, #'foo is a var, not a symbol

18:29 ttasterisco: #'foo is the same as (var foo)

18:30 {blake}: OK, I found it.

18:30 Fare: so, vars are callable, and calling them do a late binding

18:30 {blake}: I was using an example that had ":cljsbuild {:builds []})" in it. And that don't work no more.

18:30 Fare: the symbol is not callable, but the var is.

18:30 {blake}: Thanks, imperman!

18:30 (inc imperman)

18:30 lazybot: ⇒ 1

18:31 imperman: {blake}: Oh, good :)

18:31 Fare: mucho cleaner than whatever I was doing.

18:31 I'm glad I asked.

18:46 * Fare realizes he is using domonad out of clojure.algo.monads, and replaces it with his own specialized 5-line macro.

18:46 Fare: worth removing a dependency

19:00 ok, is it worth creating a library for that ~120 line parser combinator thingie?

19:02 ttasterisco: hm, does Korma not have a way to set the isolation level of a transaction?

19:04 Fare: Korma? As in Chicken Korma?

19:09 ttasterisco: Fare: yes

19:09 with hash brownies

19:19 Fare: #(brownies)

19:24 mthvedt: ,(.hashCode “brownies")

19:24 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

19:24 ered: i think it put smart quotes on there

19:24 ,(.hashCode "brownies")

19:24 clojurebot: 384041441

19:24 ered: yeah

19:26 mthvedt: ,(.hashCode "brownies")

19:26 clojurebot: 384041441

19:26 mthvedt: stupid os x

19:31 danielcompton: Is there a more elegant way of writing https://gist.github.com/danielcompton/df8f59e49626d8ce5d73#file-jmx-queries-clj-L9-L11 ?

19:32 I want to test if attr = a certain value, returning a different value if true and attr if false

19:33 justin_smith: ,(replace {["*"] :new-value} [["*"]])

19:33 clojurebot: [:new-value]

19:33 justin_smith: it's a bit hacky because replace only works on collections - wait...

19:34 ,(get {["*"] :new-value} ["*"] ["*"])

19:34 clojurebot: :new-value

19:34 justin_smith: dunno if that is any clearer (you would use attr for the last two values in that form of course)

19:48 zilti: Is it the case that it's impossible to launch a Clojure application without reflection?

19:49 justin_smith: zilti: I don't know, but out of curiosity, why would launching one require reflection? reflection used in the clojure compiler?

19:50 zilti: justin_smith: I'm creating a WebStart application and wanted to make it unsigned. But despite getting no reflection warnings during compilation (and I have :gen-class set, too) I get an error on launch because of reflection

19:52 justin_smith: http://icyrock.com/blog/2012/04/clojure-seesaw-and-java-web-start-with-leiningen/ this mention that seesaw reflects

19:52 *mentions

19:53 zilti: I'm not using seesaw, I'm using JavaFX. And as I said, I don't get any reflection warnings, not even in any libraries

19:54 justin_smith: OK - I wouldn't be too surprised if clojure does some reflection that isn't caught by warn-on-reflection, but as you see I am no expert in this. Interesting though.

19:54 TEttinger: zilti, check for primitive math

19:54 $google ztellman primitive math

19:54 lazybot: [ztellman/primitive-math · GitHub] https://github.com/ztellman/primitive-math

19:55 TEttinger: Unfortunately, while Clojure will warn you when reflection is required to invoke a function, it will not warn you when reflection is required to perform math

19:55 zilti: TEttinger: Thanks, I'll try that

19:56 TEttinger: primitive-math won't fix it automatically, it will throw a lot of warnings at compile time when it finds reflection on math so you can fix them

19:57 the number is usually very high at first, the warning count

19:57 it goes down quickly the more you fix

19:59 danielcompton: justin_smith: thanks, that's helpful, though it also looks a bit weird

20:04 zilti: justin_smith: Ugh. It seems core.async uses libs which use reflection at two points. Bad luck for me.

20:05 justin_smith: zilti: may be worth a github issue

20:05 (or whatever they use to track bugs / feature requests)

20:06 zilti: justin_smith: Jup. Gonna make that Clojure JIRA smoke.

20:07 core.memoize and data.priority_map use reflection and both are used by core.async

20:07 TEttinger: core.memoize probably needs it

20:08 zilti: "Reflection warning, clojure/core/memoize.clj:72:23 - reference to field cache can't be resolved." sounds more like a bug.

20:08 TEttinger: no, that one is just a reflection warning -- it can't tell the type of cache

20:09 how would it, anyway? memoize is kinda beyond my grasp

20:09 zilti: Yes, I had these in my code too, in my case they were fixed by simple type hints

20:10 justin_smith: TEttinger: it should suffice to have a typehint in the right place that the argument implements the apropriate memoization protocol

20:10 TEttinger: it is already implemented in terms of protocols, so the hinting should be strightforward

20:10 TEttinger: zilti, yeah, JIRA it is then. if it is in memoize.clj you should be able to patch it locally and install it in your maven repo

20:12 pandeiro: should the [:repl-options :init-ns] be automatically loaded on `lein repl`? my repl is starting at the ns, but w/o any of its vars -- is that the normal behavior?

20:28 blur3d: pandeiro: you can try using the user namespace, as it automatically loads in lein repl (I haven’t actually tested this tho)

20:29 fifosine: I don't understand the function definition of get at http://clojuredocs.org/clojure_core/clojure.core/get

20:29 It looks like it just calls itself?

20:30 pandeiro: blur3d: thanks turns out i had mismatching ns/filepath issues (i really need to write the emacs function that automates this..)

20:30 justin_smith: fifosine: where is the definition you are referring to?

20:30 zilti: fifosine: Look at the "inline" part

20:30 hiredman: ,(macroexpand '(clojure.lang.RT/get {} 1))

20:30 clojurebot: (. clojure.lang.RT get {} 1)

20:30 hiredman: http://clojure.org/java_interop#Java%20Interop-The%20Dot%20special%20form

20:31 blur3d: justin_smith: I came across this today https://freeboard.io/ - it’s similar to the dashboard I am working on and it’s also open-source. But not clojurescript alas… still some ideas tho

20:32 fifosine: zilti: I'm confused, what's the difference between inline and the actual code?

20:32 hiredman: the day has come when those have arrived who have never use the . and new special forms directly

20:32 justin_smith: blur3d: it's never been easier to become a supervillian

20:32 hiredman: fifosine: see my link

20:32 blur3d: justin_smith: https://www.geckoboard.com/ is more of what I am after… but the key difference is I want it to be dynamic at runtime - aka. it creates itself based on data

20:33 justin_smith: yeah.. I think thats the best part of html… viewable source

20:34 zilti: fifosine: Well, it's some fancy macro-stuff-callable-as-function. But I just noticed afterwards that it says the same as the actual code.

20:35 fifosine: hiredman: How would I go about extending the hashmap data structure in order to override the way get works?

20:35 hiredman: fifosine: you mean change the exist hashmap? you can't, you have to build a new hashmap type

20:35 justin_smith: ,(macroexpand '(. clojure.lang.RT (get {} 1))) hiredman: but this is what we see on clojuredocs, and that is a tricker syntax

20:35 clojurebot: (. clojure.lang.RT (get {} 1))

20:36 hiredman: justin_smith: the page I linked to explains *all* the interop syntax

20:36 fifosine: hiredman: That's what I mean, how would I go about building a new hashmap type?

20:36 hiredman: ,(supers (class (hash-map))

20:36 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

20:36 hiredman: ,(supers (class (hash-map)))

20:36 clojurebot: #{clojure.lang.AFn clojure.lang.Associative java.lang.Runnable clojure.lang.APersistentMap clojure.lang.IMeta ...}

20:36 justin_smith: hiredman: right, just pointing out (you had pasted a more intuitive syntax in your macroexpand above)

20:36 hiredman: you make something that implmenets all of that

20:37 depending on what you actually want you can pick and choose some smaller set of interfaces to implement

20:37 fifosine: hiredman: Ok, is implementing those interfaces sufficient for a data structure comprable of a hashmap?

20:38 hiredman: you can support get by implementing ILookup

20:38 fifosine: what do you mean comparable?

20:38 fifosine: Does a hashmap have any functionality that is not defined in any one of those interfaces?

20:40 hiredman: Is there no way to, the way we can override in Java, override the get method of a hashmap in clojure? Implementing all those interfaces would be more work than would make it worth

20:40 hiredman: IPersistentMap is the main map interface, clojure map literals actually start out as array maps and if they get large enough that got swapped for hashmaps transparently becuase of that interface

20:41 fifosine: sure, I'd suggest not creating a new map type

20:41 why do you want to?

20:42 fifosine: I want a map where every key *and its reverse* map to a value

20:42 hiredman: so, like, two maps?

20:42 fifosine: Right, but half the size

20:42 nathan7: well, you can have that

20:42 O(n) lookups in one direction, O(1) in the other

20:42 hiredman: I really doubt that

20:43 (the half the size bit)

20:43 nathan7: you just need to sacrifice time for space

20:43 fifosine: hiredman: What is it that you doubt?

20:43 nathan7: It's a space vs time tradeoff.

20:44 fifosine: nathan7: I agree, but wouldn't it require overwriting the get method in hashmap so that we can call reverse?

20:44 nathan7: fifosine: Write yourself a wrapper that implements the right interface that tacks onto a normal hashmap

20:44 hiredman: fifosine: that won't work anway

20:44 fifosine: What do you mean by "tacks"? Is that different from extends?

20:44 hiredman: Why?

20:45 nathan7: fifosine: so you have two IMap objects — one is the one storing stuff, the other is a wrapper for the former

20:45 hiredman: fifosine: I guess it could

20:45 nathan7: to tack onto, to stick onto

20:45 hiredman: fifosine: why not just write a my-reverse-get-function ?

20:45 nathan7: hiredman: well, you could provide that as a my-reverse-map object

20:46 fifosine: hiredman: Because it needs to be generalized for all map-types.

20:46 nathan7: (reify IMap …)

20:46 hiredman: (if (contains? m k) (get m k) (get m (reverse k)))

20:46 nathan7: IPersistentMap, even

20:46 hiredman: works on any IPersistentMap, and any java.util.Map I suspect

20:46 nathan7: wait

20:46 fifosine: nathan7: What are you listing? Interfaces to implement?

20:47 nathan7: well, it's IPersistentMap I guess

20:47 I think I misunderstood your requirements though

20:47 fifosine: ,(supers (class (hash-map)))

20:47 clojurebot: #{java.lang.Runnable clojure.lang.IMeta clojure.lang.Associative clojure.lang.Counted clojure.lang.IPersistentCollection ...}

20:47 nathan7: fifosine: I was assuming you meant something that does key->value and value->key lookup

20:47 fifosine: no

20:47 nathan7: you want key->value and (reverse key)->value, in one object

20:47 hiredman: ,(defn magic-get [m k] (if (contains? m k) (get m k) (get m (reverse k))))

20:47 clojurebot: #'sandbox/magic-get

20:47 fifosine: yes, but we shouldn't have to store (reverse key)

20:48 hiredman: ,(magic-get {"foo" "bar"} "foo")

20:48 clojurebot: "bar"

20:48 hiredman: ,(magic-get {"foo" "bar"} "oof")

20:48 clojurebot: nil

20:48 hiredman: oh

20:48 fifosine: lool

20:48 hiredman: str reverse of course

20:48 ,(defn magic-get [m k] (if (contains? m k) (get m k) (get m (apply str (reverse k)))))

20:48 clojurebot: #'sandbox/magic-get

20:48 hiredman: str reverse of course

20:48 ,(magic-get {"foo" "bar"} "oof")

20:48 clojurebot: "bar"

20:48 hiredman: ,(magic-get (doto (java.util.Map.) (.add "foo" "bar")) "oof")

20:48 clojurebot: #<CompilerException java.lang.IllegalArgumentException: No matching ctor found for interface java.util.Map, compiling:(NO_SOURCE_PATH:0:0)>

20:48 hiredman: ,(magic-get (doto (java.util.HashMap.) (.add "foo" "bar")) "oof")

20:49 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: add for class java.util.HashMap>

20:49 hiredman: ,(magic-get (doto (java.util.HashMap.) (.put "foo" "bar")) "oof")

20:49 clojurebot: "bar"

20:49 hiredman: gah

20:49 so I guess I haven't used java.util.Maps in a while

20:49 fifosine: hiredman: Nonetheless, I don't want to have to use magic-get

20:52 nathan7: fifosine: then reify!

20:52 fifosine: nathan7: What do I reify? hashmap? Or its interfaces?

20:53 nathan7: fifosine: ILookup

20:53 fifosine: at the very least

20:53 fifosine: nathan7: So I have to reimplement all un-edited hashmap methods?

20:53 nathan7: fifosine: Yes.

20:53 fifosine: that's crazy

20:54 nathan7: well, you can forward many of them to your actual hashmap

20:54 that backs it

20:54 fifosine: ah ok, guess that's true

20:54 still would extend not help?

20:54 http://clojuredocs.org/clojure_core/clojure.core/extend

20:54 nathan7: how would it

20:54 what are you going to extend

20:55 for one, none of these things are protocols

20:55 they're interfaces

20:55 extend works with protocols

20:55 fifosine: PersistentHashmap?

20:55 nathan7: is that a protocol now?

20:55 fifosine: Idk, I'm guessing

20:56 nathan7: it can't be

20:56 because of how things are implemented

20:56 fifosine: What is it then?

20:56 nathan7: It's nonexistent

20:56 IPersistentHashMap is a Java interface

20:57 fifosine: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java

20:57 nathan7: oh, yes, that's a class

20:57 implementing the actual thing

20:57 fifosine: Can I not extend that?

20:57 nathan7: but that's not what you want

20:57 fifosine: no?

20:57 clojurebot: no is tufflax: there was a question somewhere in there, the answer

20:57 nathan7: fifosine: extend the class with what protocol?

20:57 fifosine: extend allows you to extend a class with a protocol.

20:57 fifosine: ugh, I must be terribly confused

20:57 nathan7: fifosine: You could define a MagicGet protocol.

20:57 fifosine: MagicGettable, whatever

20:58 fifosine: and have a magic-get protocol method

20:58 fifosine: get, however, operates on things implementing ILookup

20:58 fifosine: and assoc operates on things implementing Associative (also an interface, despite lack of I)

20:59 fifosine: just ILookup and Associative are probably all you want to implement

21:00 fifosine: I'd hate to have a map that's not fully a map though

21:00 nathan7: Then implement IPersistentMap

21:00 which means implementing Iterable, Associative and Counted

21:01 I'm bloody tempted to write your thing for you just so you'd understand

21:03 fifosine: nathan7: I'm reading this http://tech.puredanger.com/2011/08/12/subclassing-in-clojure/

21:03 nathan7: heck, here we go

21:03 fifosine: Looking like gen-class will do it

21:08 nathan7: Yea, gen-class with :exposes-methods

21:12 nathan7: fifosine: http://sprunge.us/NBYU

21:12 fifosine: this is a start

21:14 fifosine: #{empty without containsKey assoc assocEx seq entryAt equiv valAt count cons forEach iterator spliterator}

21:14 fifosine: the methods you'd have to implement

21:14 fifosine: could even have implemented valAt in terms of entryAt

21:35 zilti: Huh? Lein uberjar puts libraries from others than just the default profile into the jar?

21:36 fifosine: (defn my-map [](proxy [clojure.lang.PersistentHashMap] [nil 0 nil false nil]

21:36 #_=> (valAt [key] 1)))

21:37 mi scuse

21:42 zilti: Ok I've got the exact error because of the reflection now: https://www.refheap.com/88562 What can I do about that?

21:44 TEttinger: that does not appear to be a reflection error at first glance

21:44 it looks like you're reading a local file when you do not have permission from the OS/user

21:45 zilti: TEttinger: The .jar doesn't read any files at all, so that can't be it

21:46 TEttinger: so you're just trying to do webstart and it isn't working?

21:46 or something else?

21:46 zilti: TEttinger: Exactly

21:46 TEttinger: I wasn't aware that webstart was different from normal desktop java

21:47 zilti: TEttinger: Well it runs unsigned applications in the sandbox, so there's that

21:48 fifosine: Anyone know why this returns nil? https://www.refheap.com/88564

21:57 ttasterisco: fifosine: because it can't find any key in the map?

21:57 you're trying to find a key named (2 1) ?

21:58 nathan7: fifosine: the reverse* fn in my code

21:58 fifosine: read it.

21:58 fifosine: (defn reverse* [x] (into (empty x) (reverse x)))

21:58 fifosine: you want it to be the same collection type

21:59 fifosine: (reverse [1 2 3]) is the *seq* (1 2 3)

21:59 err

21:59 (3 2 1)

21:59 what you want is (reverse* [1 2 3]), giving you [3 2 1], a *vector*

21:59 fifosine: If you look at the link, the key is a list

21:59 and I ask for the reverse of the list

22:00 ttasterisco: what does (println (assoc (rev-key-map) key "nice")) show?

22:01 fifosine: "nice"

22:02 ,(defn rev-key-map []

22:02 (proxy [clojure.lang.PersistentHashMap] [nil 0 nil false nil]

22:02 (valAt [key]

22:02 (or (proxy-super valAt key)

22:02 (proxy-super valAt (reverse key))))))

22:02 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

22:02 fifosine: w/e

22:02 ttasterisco: {#<core$key clojure.core$key@24ff5d3f> nice}

22:03 ,(defn rev-key-map [] (proxy [clojure.lang.PersistentHashMap] [nil 0 nil false nil] (valAt [key] (or (proxy-super valAt key) (proxy-super valAt (reverse key))))))

22:03 clojurebot: #'sandbox/rev-key-map

22:04 fifosine: ,(let [key (list 1 2)] (get (assoc (rev-key-map) key "nice") key))

22:04 clojurebot: "nice"

22:04 fifosine: but

22:04 ,(let [key (list 1 2)] (get (assoc (rev-key-map) key "nice") (reverse key)))

22:04 clojurebot: nil

22:04 ttasterisco: [19:00] <fifosine> ttasterisco: {#<core$key clojure.core$key@24ff5d3f> nice}

22:05 that's not "nice"

22:05 that's a map with a key and nice

22:05 gfredericks: ,(type (rev-key-map))

22:05 clojurebot: sandbox.proxy$clojure.lang.PersistentHashMap$ff19274a

22:05 ttasterisco: ,(let [key (list 1 2)] (println (keys (assoc (rev-key-map) key "nice"))))

22:05 clojurebot: ((1 2))\n

22:05 gfredericks: ,(type (assoc (rev-key-map) 1 2))

22:05 clojurebot: clojure.lang.PersistentHashMap

22:05 ttasterisco: that's the key in the map

22:05 gfredericks: ttasterisco: ^ it reverts to a regular map after assoc

22:06 fifosine: Ah-ha!

22:06 shit

22:06 gfredericks: ztellman has a lib for making custom map types without too much trouble

22:06 * nathan7 mutters things about reify

22:07 ttasterisco: ,(doc transient)

22:07 clojurebot: "([coll]); Returns a new, transient version of the collection, in constant time."

22:14 gfredericks: ,(doc var)

22:14 clojurebot: Gabh mo leithscéal?

22:14 gfredericks: ,(doc comment)

22:14 clojurebot: "([& body]); Ignores body, yields nil"

22:14 gfredericks: ,(comment doc)

22:14 clojurebot: nil

22:15 danielszmulewicz: 'lein new app my-app' doesn't create a user.clj under a dev directory. I always thought it did. Did it change recently?

22:21 technomancy: no, it's never done that

22:21 wildnux: hi, if i have a function (valid-arg? ) which takes a string and returns the string if it is valid else returns nil, what is the idomatic way of checking 3 arguments for a function? eg: (defn [f s t] (map valid-arg? [f s t]) gives (str1 str2 str3)

22:22 how do i write (defn checkthree [f s t] ..) so that it returns (f s t) if all are valid else returns nil

22:25 danielszmulewicz: technomancy: Oh, OK. I understand, I need to add the :dev profile in project.clj and create the file manually, right?

22:37 fitzoh: Trying to figure out what I’m doing wrong inserting multiple values with jdbc. this works: (j/insert! db :table nil (first lines) (second lines))

22:37 this doesn’t: (apply #(j/insert! db :table nil %) lines))

22:37 what am I missing?

22:42 ttasterisco: you're passing a collection to insert! in the 2nd case, while in the first case you're passing lines as separate args?

22:43 trptcolin: fitzoh: your anonymous fn only takes 1 arg but apply is making you pass more (assuming lines has > 1 element)

22:43 fitzoh: I thought that the apply “unwrapped” the collections into multiple args

22:45 trptcolin: you can delete the `#(` and the `)` and it should work

22:45 ttasterisco: ,(doc apply)

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

22:46 ttasterisco: what trptcolin said

22:47 fitzoh: ah, makes sense

22:47 thanks for the help

22:49 trptcolin: np

23:40 kelseygi: hi i am kind of stuck trying to create a predicate based on a vector of strings

23:40 (defn reply?

23:40 (some-fn (map (partial #(.startsWith %1 %2)) prefixes)))

23:40 i'm getting Parameter declaration some-fn should be a vector

23:43 ttasterisco: you're missing a [] with the args after reply?

23:43 kelseygi: sorry, prefixes refers to an arg

23:43 er to a vector of strings

23:44 ttasterisco: (defn reply? [some-fn prefixes] (some-fn (map (partial #(.startsWith %1 %2)) prefixes))) ?

23:45 why are you using partial with the anonymous function?

23:45 ,(defn reply? [some-fn prefixes] (some-fn (map #(.startsWith %1 %2) prefixes)))

23:45 clojurebot: #'sandbox/reply?

23:47 ghadishayban: core.async "subway turnstile" https://gist.github.com/ghadishayban/7018dbc353216801b318

23:49 ttasterisco: ,(defn reply? [some-fn pf1 pf2] (some-fn (map #(.startsWith %1 %2) pf1 pf2)))

23:49 clojurebot: #'sandbox/reply?

23:49 ghadishayban: i can't decide if metaphors help or hurt most of the time

23:50 ttasterisco: ,(reply? vec ["aaa" "bbb" "ccc" "ddd"] ["ddd" "bbb" "ccc" "aaa"])

23:50 clojurebot: [false true true false]

23:50 ghadishayban: they probably help if it's in a description, but not symbol names

23:56 literater: having what looks to be a dependency issue with lobos. new to clojure, unsure how to resolve. i'e had issues getting korma to work so i set org.clojure/java.jdbc to latest in my project.clj. now korma works but i get a "#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *db* in this context, compiling:(lobos/connectivity/jdbc_2.clj:14:1)>"

Logging service provided by n01se.net