#clojure log - Nov 25 2013

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

0:15 jjjddd0: Hi all, can anyone tell me what htis does:

0:15 {#'*out* out}

0:17 coventry: jjjddd0: Play around with it in the repl.

0:18 ,(let [out 'foo] ({#'*out* out} #'*out*))

0:18 clojurebot: foo

0:18 jjjddd0: its hard to google for macros sometimes, {# yields no results

0:18 is there a goto list somewhere ?

0:18 allenj12: hey what would be the best data structure if i wanted nested keywords so live {:john {:name --- :age --- :address { :street ...}}} etc...

0:19 a hash-map-map?

0:19 justin_smith: jjjddd0: the docs for the reader help. all the reader macros are mentioned there http://clojure.org/reader

0:19 also, there is http://symbolhound.com/ for looking up programming language symbols other engines don't index

0:20 http://symbolhound.com/?q=%23%27+clojure for example (that is a search for #')

0:21 jjjddd0: justin_smith: that one isnt in the reader macros list

0:21 bitemyapp: justin_smith: oh man, that is nice.

0:21 justin_smith: jjjddd0: it is, it is listed as Var-quote

0:21 bitemyapp: justin_smith: you have no idea how nice this will be for Haskell

0:22 justin_smith: jjjddd0: from there you would follow up to look up var

0:22 jjjddd0: oooh I see

0:22 should've been looking for #' not {#

0:22 thanks

0:22 justin_smith: np

0:23 bitemyapp: jjjddd0: { ... } is just a map yo.

0:23 justin_smith: jjjddd0: yeah, that {#'x x} would be read as {} with #'x and x inside may not be the easiest thing to intuit at first

0:23 jjjddd0: yep got that now

0:24 justin_smith: but the rule is that # precedes the thing it qualifies

0:24 bitemyapp: jjjddd0: like #inst "2013-03-03"

0:24 jjjddd0: but so.. what is it doing ? that's abit confusing

0:24 justin_smith: it introduces a reader macro

0:25 something that transforms the input as it is read, before it is evaluated

0:25 jjjddd0: creating a map with a var as a key and it's value set to... ?

0:25 justin_smith: jjjddd0: yeah, that is odd - perhaps it has a special behavior if you ask it to do something with #'*out*

0:25 *out* is always the default place for printing functions

0:26 jjjddd0: it's here line 11:

0:26 https://github.com/Raynes/tryclojure/blob/master/src/tryclojure/models/eval.clj

0:26 justin_smith: so clearly it is a situation where something is saying if this thing is bound to our current output port, than return out (whatever that is bound to)

0:27 jjjddd0: i see, it's overidding a var '*out*' with a custom output stream

0:27 justin_smith: probably something like that, yeah

0:28 though usually you would do that by just binding *out*

0:28 jjjddd0: because *out* is a standard var in clojure right ?

0:29 clever

0:29 justin_smith: yeah, it is the magic default place that print goes, if you rebind it, that changes where print prints to

0:29 (and the other functions that call print, of course)

0:29 jjjddd0: thanks for your help all

0:29 justin_smith: np

0:31 Raynes: justin_smith: Thanks for providing free customer support for my projects.

0:32 justin_smith: lol

0:32 Raynes: You're a pal.

0:32 justin_smith: I'm just a compulsive pedant, love a chance to try to teach something

0:32 especially if it is short term, no commitment :)

0:33 Raynes: You and amalloy should have babies.

0:38 bitemyapp: man babies. ma-bies.

1:30 bellkev: Is there any kind of convention clojure programmers follow for ordering there function inputs so that it's easier to compose them with "threading"? I've noticed that sometimes when I "thread" it happens that "thread-last" works better and other times normal threading works, but it's annoying that it seems kind of arbitrary depending on the input order...

1:31 justin_smith: a sequence should go last, an indexed collection should go second

1:32 in general

1:32 err, first arg, second place in the form

1:34 bellkev: This is the example that I started trying to write with thread-first, though "Oh, shit, this won't work", and then thought "Oh, this will work with thread-last..."

1:34 https://gist.github.com/bellkev/7637204

1:35 It feels like a total coincidence that it worked though :P

1:35 justin_smith: you generate a collection, and pass it through each function

1:35 collection args canonically go last

1:36 *sequential collection

1:36 bellkev: Ah, that makes sense

1:36 Now that you put it that way I feel better

1:38 justin_smith: there is also as-> for more flexibility

1:38 bellkev: I was kind of thinking of the string in the split term as being "collectiony", but now I can see it as a "collection generator" and a "collection collapsor" or whatever

1:38 justin_smith: though it requires explicitly marking where the arg comes in

1:39 bellkev: Interesting, I'll have to look into that...

1:41 justin_smith: ,(as-> 1 $ (+ $ 3) (if (> $ 2) $ (* $ $)) (inc $))

1:41 clojurebot: 5

1:41 justin_smith: also allows multiple references to the passed value, as you see

1:47 bellkev: So, it's kind of like a little miniature 'let', but with less syntax and without the implicit 'do'?

1:47 And for only one variable-ish thing?

1:47 justin_smith: yeah

1:48 if you macroexpand it that is exactly what it is

1:48 bellkev: okay, that seems handy

1:48 justin_smith: it is a handy way to express some stuff, yeah

1:48 and when you name it $ it is almost like you are doing perl or something

2:32 blur3d: if I have a list of hash maps, does clojure have a way to pull out certain keys? kind of like a ruby active record pluck

2:33 using select-keys works, but was wondering if something was already in core

2:33 (map #(select-keys % keys) coll)

2:33 TEttinger: blur3d, sure. what condition do you want the keys under? do you mean values or keys?

2:33 justin_smith: ,(map #(select-keys % [:a :b :c]) [{:a 0 :b 1 :c 2 :d 3} {:a 1}])

2:33 clojurebot: ({:c 2, :b 1, :a 0} {:a 1})

2:34 TEttinger: (inc justin_smith)

2:34 lazybot: ⇒ 13

2:35 blur3d: yeah, that works fine - I was just wondering if it was common enough to be in core under something like pluck [coll keys]

2:35 justin_smith: no, it would be a one liner if you want to write it

2:35 blur3d: kk, cheers

2:35 justin_smith: the general clojure philosophy is to have a small number of functions that compose well and all use the same datatypes

3:03 sveri: hi everyone, let the IDE wars begin, which IDE do you use for clojure development on windows? A friend of mine tried to convince me to use emacs now for one week, but we still dont have everything running as we would like :(

3:06 justin_smith: not a windows user, but I have gotten emacs working on windows before

3:06 I saw a demo of cursive that was pretty impressive

3:06 I bet that works fine on windows

3:07 http://cursiveclojure.com/

3:07 sveri: hm, i tried cursive, it opened the clojure files, but i could not get the tests running

3:15 any cursive users here? is it already possible to run unit tests with cursive? or am i trying something that doesnt work yet?

3:20 justin_smith: sveri: it has a repl, you can load the namespaces that define the tests and use (test/run-tests)

3:20 though I would be surprised if it did not have a shortcut for that

3:21 sveri: justin_smith: i just cannot find one :D

3:21 however, i found the repl

3:21 justin_smith: as in, you haven't written any tests yet?

3:22 or, you haven't found the "run tests" button

3:22 sveri: i haven't found the "run tests" button, the tests are there already

4:25 davidbe`: I've a question on how to connect to an Oracle db: when running a query, I get an error that there's no suitable driver found for jdbc:oracle:thin:@<path-to-db>:1521:dwh. This url should work, using SQuierreL SQL, I can connect. I guess it has to do with requiring/using ojdbc6.jar... How can I solve this?

4:26 Or should I add ojdbc6.jar to project.clj?

4:33 clgv: davidbe`: you usually need to add the driver jar to the classpath of your application on the jvm

4:34 davidbe`: in a Clojure project adding it to project.clj when using leininingen is the way to go

4:34 davidbe`: I'm not that familiar with Java and beginning with clojure... where do I place ojdbc6.jar and how to add it to project.clj?

4:36 I've put it first in ./src (lein classpath mentions it)

4:36 jowag: davidbe`: http://stackoverflow.com/questions/9898499/oracle-jdbc-ojdbc6-jar-as-a-maven-dependency

4:38 and http://stackoverflow.com/questions/18249901/clojure-lein-cant-find-oracle-jdbc-driver

4:40 davidbe`: jowag: thanks, I'm checking it out. 10 minutes ago, stackoverflow was down. Lucky it's up again!

4:53 clgv: davidbe`: with leiningen you usually do not place a jar anywhere. you specify the jar as a maven-style dependency in the the project.clj and leiningen downloads it for you

4:59 TEttinger: (inc clgv)

4:59 lazybot: ⇒ 9

4:59 TEttinger: (inc jowag)

4:59 lazybot: ⇒ 1

5:00 clgv: TEttinger: thx - you cant have too much karma these days ;)

5:01 TEttinger: $karma TEttinger

5:01 lazybot: TEttinger has karma 6.

5:02 TEttinger: $karma technomancy for fun

5:02 lazybot: technomancy has karma 86.

5:09 davidbe`: clgv: but how for ojdbc6.jar?

5:11 clgv: davidbe`: what is there project site?

5:11 davidbe`: I've been going through the pages jowag was giving me, but it meant the installation of maven (I'm new to jvm...) and now it errors because there is no POM in this directory...

5:11 dsrx: (dec dsrx)

5:11 lazybot: You can't adjust your own karma.

5:11 davidbe`: ojdbc6.jar is the driver for Oracle DB

5:11 jowag: are you using leiningen?

5:12 davidbe`: jowag: yes

5:12 jowag: lein is using maven underneath

5:12 davidbe`: jowag: ow...

5:12 searching the internet doesn't give me a clear example/help. It always says that ojdbc6.jar should be in your classpath

5:13 that's it, no more. I'm clueless :)

5:13 clgv: davidbe`: it seems that oracle does not publish this driver as maven artifact, right?

5:14 jowag: try this, add this repo in your project.clj, :repositories [["codelds" "https://code.lds.org/nexus/content/groups/main-repo"]]

5:14 davidbe`: clgv: sorry, I cannot answer that. I don't know how maven works...

5:14 Jarda: does the repl have some specia case for (float) printing

5:14 jowag: and then add [com.oracle/ojdbc6 ""] as a dependency in project.clj

5:14 clgv: davidbe`: ok I found it. add [ojdbc/ojdbc "14"] to your project.clj in the dependecies part

5:15 Jarda: because in dev repl (float (read-string "19.9")) prints 19.9

5:15 but in production the same code inside a ring-app produces 19.899999618530273

5:16 davidbe`: clgv: that gives "could not find artifact ojdbc [..] in central"

5:16 clgv: oh well I have no clue which is the right dependency. there is also the following on maven: [com.oracle/ojdbc14 ""]

5:17 but it seems those are only pom-files which isnt useful...

5:18 go with jowags hint there is a jar in the repo he mentions

5:20 davidbe`: clgv, jowag: okay, I'll look into that. Thanks already!

5:22 clgv: devidbe`: your project.clj needs the :repositories entry and the vector with oracle ojdbc dependency like here: https://www.refheap.com/21231

5:22 davidbe`: ^^

5:29 davidbe`: clgv: we have a winner =)

5:30 edbond: help please with cljs - http://stackoverflow.com/questions/20189860/export-deftype-methods

5:31 davidbe`: clgv: thank you! I'm only wondering, with some experience with Ruby's gem and Haskell's cabal, how one can find the jar's you need in Java-world!? Those centralized repos give less headaches :)

5:32 cYmen: Could somebody help me spot the error in this: https://www.refheap.com/21233

5:32 It's a 4clojure problems.

5:32 -s

5:32 Probably some sort of type equality thing because the result looks correct.

5:33 TEttinger: davidbe`, that's exactly what maven central is

5:33 there's also clojars

5:34 http://search.maven.org/

5:34 https://clojars.org/

5:35 edbond: cYmen, it's infinite, there is no exit

5:35 TEttinger: cYmen: ##(doc map-indexed)

5:35 lazybot: ⇒ "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

5:36 cYmen: edbond: ah, thanks

5:36 edbond: one can use reduce too

5:38 TEttinger: ,(= (#(map-indexed (fn [idx item] [item idx]) %) [:a :b :c]) [[:a 0] [:b 1] [:c 2]]) ;; map-indexed is highly useful

5:38 clojurebot: true

5:39 jowag: edbond: do not exprt deftype, export some function which will create what you need, e.g. create new instance of your type

5:39 davidbe`: TEttinger: thanks for the info. Yes, I understood clojars also as a central repo. It is though strange to add another repo for an oracle driver, which is not uncommon.

5:39 TEttinger: that may not work on the others, I haven't tried! but you should try to do it with reduce for completeness, cYmen

5:39 yeah

5:40 edbond: jowag, I can export function but that deftype object doesn't have handleShow. I think it's renamed

5:40 TEttinger: davidbe`, it seems to be there. http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22ojdbc14%22

5:41 jowag: edbond: in that case, try putting ^:export before handleShow, inside deftype

5:41 TEttinger: oh you need 6 I guess?

5:41 davidbe`: TEttinger: yes

5:41 TEttinger: is that a very old version?

5:42 edbond: jowag, I tried ^:export, generated .js doesn't have 'handleShow'. Seems export can't be applied there.

5:43 I thought externs can help but it ignores them too

5:43 davidbe`: TEttinger: bit too old. Problem is solved for now, I was only wondering why it wasn't that easy (lazy-me :-)

5:43 TEttinger: heh

5:44 well lein is wonderful, it easily handles quite a lot of hassle inherited from java land

5:44 "lein uberjar" is great

5:48 edbond: cYmen, here is reduce version

5:48 ,(reduce (fn [[i coll] el] (vector (inc i) (conj coll [el (inc i)]))) [0 []] [:a :b :c])

5:48 clojurebot: [3 [[:a 1] [:b 2] [:c 3]]]

5:49 edbond: off-by-1 )

5:49 and map accepts many collections

5:49 ,(mapv (fn [a b] [a b]) [:a :b :c] (range))

5:49 clojurebot: [[:a 0] [:b 1] [:c 2]]

5:49 edbond: map-indexed of course if the winner. know your core :)

5:51 cYmen: heh

5:53 TEttinger: what's kinda crazy is that mapv is relatively recent -- 1.4 I think?

5:53 http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/mapv yep

5:57 clgv: edbond: in case you need a map anyway ##(zipmap [:a :b :c] (range))

5:57 lazybot: ⇒ {:c 2, :b 1, :a 0}

6:08 cYmen: What is the difference between map and mapv? Does mapv pass the arguments as a set?

6:09 Ember-: @(doc mapv)

6:10 ##(doc mapv)

6:10 lazybot: ⇒ "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remai... https://www.refheap.com/21235

6:10 Ember-: ##(doc map)

6:10 lazybot: ⇒ "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. An... https://www.refheap.com/21236

6:10 Ember-: cYmen: see the "Returns a <here>"

6:11 there is a dramatic difference, mapv returns an eagerly initialized vector, map returns a lazy sequence

6:25 cYmen: Totally missed that..

6:25 thanks

6:26 * ucb waves

7:07 johiddini: Hi - compojure/ring question. I have a compojure app, works great in development, but now I want to properly deploy it. How can I run my uberjar as a service that starts when my EC2 instance does, and automatically restarts if it crashes? I'm not an ops guy so maybe I'm missing the obvious.

7:26 dnolen: edbond: not supported but not hard to add - http://dev.clojure.org/jira/browse/CLJS-698

7:27 edbond: dnolen, thanks, will take a look.

8:19 kilen: Any idea why this explodes? http://bit.ly/18j7bel (refheap), it seems trivial and the first version should be equivalent to the 2nd.

8:26 ambrosebs: kilen: why is it [coll] instead of coll in the loop binder?

8:28 kilen: ambrosebs: so that I don't have to wrap the initial collection in a vec in the color, it's serves as a stack

8:28 s/color/caller

8:29 I culled this from a larger function, so lacks context.

8:31 nonuby: why does this whole the exception instead of closing channel in a finally for example https://github.com/clojure/core.async/blob/76317035d386ce2a1d98c2c349da9b898b480c55/src/main/clojure/clojure/core/async.clj#L382

8:31 whole --> swallow

8:34 kilen: ambrosebs: yeah, that's the problem, but I thought it was legal to put an expression on the rhs of a binding. strange.

8:35 mattmoss: nonuby: I suspect that, since (f) is in another thread, there is no easy way to handle that exception.

8:36 Sorry, ignore that, I misunderstood your question.

8:38 ambrosebs: kilen: sure it's legal. You just wrapped coll in a vector, I don't know where the NPE comes from though.

8:42 kilen: ambrosebs: oh f, i captured rest instead of calling it rst. boo.

8:43 ambrosebs: kilen: :)

8:52 dnolen: piranha: so does React actually work with advanced compilation? If so I'm curious why renaming is an issue?

8:55 wakeup: hi

8:55 mdrogalis: Morning.

8:55 wakeup: Anyone using cloverage here? I can't get the -n and -t options to work

8:56 I am trying to run cloverage on a chosen testsuite only.

9:19 dabd: could someone please help me out using clojure.walk? https://gist.github.com/dabd/7641881

9:22 justin_smith: dabd: postwalk does not work on anything other than generic types

9:22 coventry: dabd: But I believe clojure.walk2 does.

9:22 justin_smith: because it needs to know how to create an empty thing and put transformed contents in it

9:22 coventry: https://github.com/stuartsierra/clojure.walk2

9:23 justin_smith: I think walk2 will be in the next clojure.core

9:23 our caribou version is the only version of walk2 you can get from maven, last I checked

9:23 oddly

9:23 coventry: justin_smith: Yes, troncle is still depending on it. :-)

9:23 justin_smith: oh yeah, we had that conversation

9:24 coventry: I guess you would have to extend walk2.Walkable to your record type for it to work properly.

9:24 Huh, there's already an extension for IRecord.

9:24 justin_smith: dabd: hopefully clojure.walk2 fixes your issue, otherwise, this was another thing to add to the "you probably don't want to use defrecord" list

9:24 rabidsnail: How do I unescape html character entities? Googling just points to a bunch of templating libraries.

9:25 justin_smith: coventry: cool, so that should fix his issue then

9:25 arcatan: i wonder if walk2 preserves metadata

9:25 coventry: arcatan: Pretty sure it doesn't.

9:25 arcatan: It's easy to add that to the transformation functions, though.

9:26 dabd: justin_smith: what should i use instead of defrecord to define nodes in a tree that can contain complex data?

9:26 coventry: http://clojure-log.n01se.net/date/2013-11-24.html#18:13

9:27 rabidsnail: I mean I guess I could use apache commons to do it, but that doesn't seem very clojurey.

9:27 justin_smith: coventry: yup, that's where we talk about the list I would be adding to

9:28 rabidsnail: I think the ring handler that handles URL params may do this?

9:28 wakeup: -.- why is simply running cloverage.coverage/-main in my project so hard?

9:28 rabidsnail: justin_smith: I'm not using ring (this isn't a web app)

9:29 justin_smith: but web libraries are good at handling data formatted for the web

9:29 rabidsnail: justin_smith: I'm pulling data from the twitter api

9:29 justin_smith: it is a web app: a web client app :)

9:29 dabd: coventry: i am not using defrecord to represent the tree.

9:30 just the nodes

9:31 coventry: dabd: Can you represent the node data using the standard clojure data structures?

9:31 justin_smith: rabidsnail: and speaking of being a web client, clj-http.client does format coercion

9:31 https://github.com/dakrone/clj-http

9:33 rabidsnail: justin_smith: to use that I would have to write my own twitter api client, though

9:33 justin_smith: it is probably using a class from apache to do the URL transform though

9:33 dabd: coventry: of course a simple map would work. It seems like defrecord, deftype and protocols get messy. So when should I use a simple map instead of defrecord

9:33 rabidsnail: (wrong layer of abstraction)

9:33 yeah, I'll probably just use apache commons

9:34 coventry: dabd: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

9:35 See the "No" "No" path.

9:36 dabd: coventry: thanks. seems useful

9:36 coventry: NP.

9:49 allenj12: is there an easy way to read in txt files word by word? so maybe something like "hello john" to ["hello", "john"]

9:52 dbusnenko: (.split (slurp "file.txt") " ")

9:52 justin_smith: (clojure.string/split (slurp "project.clj") #"[ \n\t] ")

9:52 I forget the generic "split by white space" regex

9:53 Mendor|s1r: "\\s+"

9:53 justin_smith: thanks

9:54 allenj12: alright thanks!

9:54 justin_smith: Mendor|s1r: that seemed to do the opposite, so I need to negate it

9:55 bja: capital S is everything except whitespace

9:55 lowercase S is all whitespace characters

9:55 so \\s+ vs \\S+

9:55 justin_smith: oh, it was "\s+"

9:55 not "\\s+"

9:55 that did it

9:55 bja: err, yeah. java requries the escaped \

9:56 (not clojure)

9:56 justin_smith: (clojure.string/split (slurp "project.clj") #"\s+")

9:56 that works

10:03 piranha: dnolen: it actually does work, almost does :)

10:04 dnolen: the thing is that they have this list of tags they create on DOM, and if you use them as DOM.td, advanced mode will rename them to Q.x or something like that :)

10:04 I guess I should just add an extern which lists all those tags and be done with it, their names are not that long

10:04 casper_: (+ 1 1)

10:04 clojurebot: 2

10:05 coventry: (inc 10)

10:05 lazybot: ⇒ 0

10:06 coventry: Does clojurebot have "+" hardcoded?

10:07 dnolen: piranha: I'm confused why the renaming is a problem, isn't everything compiled together?

10:07 Mendor|s1r: ,(inc 10)

10:07 clojurebot: 11

10:07 Mendor|s1r: too many bots :)

10:07 dnolen: piranha: React and your CLJS code?

10:07 coventry: Mendor|s1r: The remarkable thing about casper_'s message is that it wasn't preceded by any kind of unquote.

10:08 piranha: dnolen: ok, so it's a problem only in single case

10:08 Mendor|s1r: coventry: oh, I'm blind :)

10:08 piranha: dnolen: the thing is that DOM.div, DOM.p and other functions in React are created in runtime from an array (['div', 'p']), so they don't get renamed

10:08 gfredericks: Why does the core.typed wiki describe a function as "an ordered intersection of arities"? wouldn't union make more sense?

10:09 piranha: dnolen: but they get renamed in a client code, which is a problem :)

10:09 dnolen: piranha: ah, so those are dynamic properties? Why don't they just make them static?

10:10 coventry: gfredericks: What's the formal correspondance between an arity and a set?

10:10 piranha: dnolen: 'code size' :D

10:10 dnolen: piranha: huh?

10:10 gfredericks: coventry: I don't know

10:10 dnolen: piranha: I can't see how it make a significant difference, and would be good for Closure dead code elimination

10:11 TimMc: &((juxt (fn ([] :nullary-a) ([& _] :varity-a)) (fn ([& _] :varity-b) ([] :nullary-b))))

10:11 lazybot: ⇒ [:nullary-a :nullary-b]

10:12 TimMc: I don't see what order has to do withit either.

10:12 piranha: dnolen: yeah... well they discussed that my patch ( https://github.com/facebook/react/pull/420/files ) added half a kb of code...

10:12 gfredericks: TimMc: well in core.typed you might have several types for one arity

10:12 though again that sounds like a union to me

10:13 piranha: oh, it actually is other way around, it does rename

10:13 ah, damn, I really forgot this thing

10:13 :))

10:13 dnolen: the thing is that closure compiler does not rename them in my code! because I use [:div "something"]

10:14 I was thinking about switching pump to (div "something"), that would fix the problem

10:14 justin_smith: (inc 10)

10:14 lazybot: ⇒ 1

10:14 justin_smith: lol

10:16 piranha: ah

10:16 dnolen: I've got it other way around again :)

10:16 the problem was that it renamed all the tags and you got <xf></xf> in your DOM :))))))))

10:16 dnolen: I'm sorry for the confusion, it took a while to switch my brain back :)

10:20 dnolen: piranha: right, I'm chimed in on your pull request - from what I've seen React looks like one of the best libs to integrate into a CLJS project

10:20 would be sad to reinvent

10:20 piranha: thanks for the explanations

10:21 piranha: yeah, react is great

10:22 dnolen: it actually seems quite similar to hoplon for me, but I think alandipert doesn't agree with me; it still could be used as a backend renderer just to skip writing all this reconciliation again

10:23 I would love React to be separated in libraries, but still, idea is really good - having 'render' as an idempotent function makes writing an app much simpler

10:37 gfredericks: I feel like it would be useful for robert.hooke to have an around function that's like add-hook but only gives you the original function with the args already applied

10:38 joegallo_: to save the characters of applying them yourself?

10:39 that is, so you could (f) rather than (apply f args)?

10:42 gfredericks: exactly

10:42 and make it clear that you don't care about the args or intend to change them

10:52 justin_smith: gfredericks: any relation to (defmacro thunkify [form] `(fn [] ~form))

10:52 gfredericks: justin_smith: I don't believe so; robert.hooke is about monkey-patching vars

10:54 justin_smith: well the hook could provide you the thunkified version of the call

10:54 is what I am saying

11:03 TimMc: Raynes: A coworker found this. I don't know what it is, but it really should be accessible by a lazybot $wat command: https://github.com/gf3/WAT/blob/master/wat.json

11:17 dabd: this is a very basic question about trees and s-expresions. I want to represent the tree shown first here https://gist.github.com/dabd/7643940 but the clojure zipper will produce a structure like shown at the end of the file. How can I represent the first tree using a zipper?

11:18 TimMc: What have you tried?

11:18 Oh, misread, sorry.

11:21 kilen: This fails to work: (map Integer/parseInt ["4"]) ,is there sugar or must I wrap it in a fn?

11:22 TimMc: dabd: I think each vector needs to specify *three* nodes -- left branch, node value, and right branch.

11:22 justin_smith: kilen: there is (map #(Integer/parseInt %) ["4"]) - probably the best you'll get

11:22 dabd: my trees are not necessarily binary

11:23 justin_smith: kilen: the issue is that a static class is not a first class object, and the language would have to become much more complex to make it act like it is

11:23 coventry: ,(macroexpand '(Integer/parseInt "4"))

11:23 justin_smith: *static class method

11:23 clojurebot: (. Integer parseInt "4")

11:24 dabd: for example this clojuredoc zipper example is working with a tree that is not binary http://clojuredocs.org/clojure_core/clojure.zip/zipper

11:27 kilen: justin_smith: how strange, where does that macro come from? is invocation a macro??

11:27 lazybot: kilen: What are you, crazy? Of course not!

11:27 kilen: nice

11:28 justin_smith: kilen: it is a shorthand for fn

11:28 ,(macroexpand '#(str %))

11:28 clojurebot: (fn* [p1__57#] (str p1__57#))

11:29 kilen: justin_smith: but isn't fn a special form? I don't follow.

11:29 justin_smith: fn is not a special form, it is a macro

11:29 coventry: fn* is a special form.

11:29 justin_smith: #() is a macro that expands to fn* which is a special form, yes

11:30 kilen: justin_smith: Then (doc fn) is a filthy liar

11:30 justin_smith: weird - I may be wrong

11:31 coventry: Yep, it's lying.

11:31 justin_smith: it manually adds :special-form to its metadata

11:31 which is odd?

11:31 coventry: There are a couple of other forms on http://clojure.org/special_forms which also aren't special. loop and let, at least, IIRC

11:32 justin_smith: because they are wrappers around the special form, and they are there to do the arg destructuring, right?

11:32 coventry: But actually, the documentation is more useful the way it is without going into this distinction.

11:32 kilen: Seriously, this would never happen in scheme. *ducks*

11:32 justin_smith: no, it would not happen in scheme. and my boss would never deploy scheme in production :)

11:33 kilen: justin_smith: ok, so #() is shorthand for fn, and fn is a macro. how does macro expansion work for (foo bar)? I don't see the fn

11:34 justin_smith: foo is a var pointing at a first class function

11:34 the problem is you can't just have a var pointing to a first class static method on a class

11:34 coventry: I suggest reading the code for riddley.walk/macroexpand if you really want to get into this.

11:34 justin_smith: because a first class static method on a class is not a thing :)

11:34 we are adapting to the limits of the jvm here

11:35 kilen: coventry: thanks, will clone

11:36 justin_smith: if we wanted to be able to use static methods on classes as if they were first class things, the clojure interpreter would be more convoluted. I like that the design was kept simple.

11:36 coventry: It's basically clojure's macroexpand machinery, reimplemented in clojure.

11:36 TimMc: dabd: I've not used zippers; how do they store node values, or do they only have data at the leaves?

11:37 dabd: timmc: looks like the answer for what i'm trying to do is here http://grokbase.com/t/gg/clojure/12afy2cz9p/how-to-represent-trees-for-use-with-zippers

11:37 coventry: Hmm, actually, I don't know that it's going to show how Integer/parseInt is handled. I think it defers to clojure's macroexpand for that. You might need to look at HostExpr in Compiler.java.

11:37 dabd: vector-zip will treat all vectors as branches so to explicitly represent the nodes i need to do something like caspar is showing. I'm going to try it

11:40 kilen: justin_smith: let me see If I got this right, all symbols pointing to a function get expanded via the fn macro which has special sauce for static methods, is that right?

11:40 justin_smith: kilen: err, no

11:40 a function is an object

11:40 so a var can have it as a value

11:40 a static method is not an object

11:41 so you cannot put it in another container in the jvm

11:41 there is no such concept, it is not a first class thing

11:41 it belongs to the class

11:41 and the class is not neccessarily a callable thing

11:42 so the jvm has its own ontology of classes vs. fields / methods, and rather than jumping through hoops and having special cases to make everything act first class, clojure is just like "well, this is java, do it the java way"

11:42 any normal clojure thing will generate objects, which are first class, and you can use in the usual handy convenient ways

11:43 kilen: I accept that, I'm now trying to understand how the macro which converts the invocation into java interop form gets invoked

11:43 justin_smith: the macro creates an fn

11:43 an fn is a callable object

11:43 TimMc: dabd: Yeah, looks like vector-zip isn't what you want at all, then.

11:43 justin_smith: inside, it invokes a static method

11:44 it is a workaround for the fact that a static method is not something you can pass around as a first class thing

11:44 you wrap it in something that is

11:45 and you dream of a sane design where things that should be first class functions actually are

11:45 kilen: justin_smith: I'll try again to explain what's puzzling me. as macros go, I know that (someMacro quux) gets expands as the body of someMacro

11:46 justin_smith: right

11:46 this happens at the moment of compilation, when the code is loaded

11:46 kilen: I don't understand how (NotaMacroAtAll-JavaStaticMethod) gets expand by any macro at all. there's no macro there., it looks like any other invocation.

11:47 ahh

11:47 so the expansion (. foo bar) is the body of the fn that was created by expansion at compilation time?

11:47 justin_smith: it is inside the body of the fn

11:47 but yes

11:48 kilen: close enough

11:48 yay we made it! thanks :)

11:48 justin_smith: np

11:48 so how about (. )

11:49 I don't know how to examine that in the repl at all

11:49 must be a reader macro or special form?

11:49 coventry: It is a special form.

11:49 justin_smith: I just realized I can't ask for its class, but yeah, I can call doc on it

11:50 "they all expand into calls to the dot operator at macroxpansion time"

11:50 coventry: I don't actually know where (Integer/parseInt ...) gets turned into (. Integer parseInt ...), though. I don't think HostExpr is the place, either, and it's not the reader.

11:50 ,(read-string "(Integer/parseInt \"4\")")

11:50 justin_smith: http://clojure.org/java_interop#dot this is where the doc for . led me

11:50 clojurebot: (Integer/parseInt "4")

11:51 bbloom: coventry: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L803

11:54 coventry: bbloom: Thanks. That's not where the expansion happens, though. It's (predictably enough, I guess) in macroexpand1. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6517

11:54 bbloom: ah sorry, answered the wrong question :-)

11:54 TimMc: &(macroexpand '(.foo bar))

11:54 lazybot: ⇒ (. bar foo)

11:54 TimMc: &`(.foo bar) ;; to demonstrate that it's not read-time

11:54 lazybot: ⇒ (.foo clojure.core/bar)

11:55 dnolen: somewhat less half baked CLJS for for making mutable JS object comform to a epochal time model - now with more refined ideas about handling nested objects - https://gist.github.com/swannodette/7644500

11:55 justin_smith: TimMc: yeah, . seems to be the bottom of things for normal inside clojure stuff - you need to start messing with the compiler to get lower than that

11:55 dnolen: would be easy to write a macro to make an EpochHTMLElement or EpochCanvas

11:55 nDuff: blegh.

11:55 * nDuff thinks about learning OCaml

11:56 nDuff: ...still been playing around with using core.logic for recognizing bytecode-level optimizations

11:56 bbloom: dnolen: the "next epoch" stuff reminds me that i need to find time to elaborate on https://github.com/brandonbloom/exstate/blob/master/src/exstate/core.clj

11:57 TimMc: &(macroexpand `(~(symbol "") 1 2 3))

11:57 lazybot: java.lang.StringIndexOutOfBoundsException: String index out of range: 0

11:57 nDuff: ...but most of the available libraries providing single-assignment intermediate representations for java bytecode either (1) have outright horrifying implementations [think: mess of singletons and mutable state], (2) aren't reversible back to java bytecode, or (3) aren't implemented in Java.

11:58 TimMc: nDuff: Aren't reversible?

11:58 As in, have no possible representation, or are just really hard to reverse?

11:58 nDuff: TimMc: well, don't have implementations presently available for reverse transformations.

11:59 TimMc: not that it isn't possible, just it isn't done; and I'm trying to keep things narrowly-scoped.

11:59 TimMc: I was thinking about writing (or convincing someone else to write) a learning reverser.

11:59 nDuff: (Wala is the particular toolchain for which that's the case)

11:59 TimMc: You'd feed it a bunch of input-output pairs for a transformation and it would build a model for the reverse.

12:04 technomancy: nDuff: doooo eeeet

12:05 dnolen: bbloom: oh a lib to deal w/ external state?

12:05 jcromartie: when I'm working with records and protocols in the REPL via CIDER, and I use C-c C-k to load a file, then trying to call any protocol function on a previously-created record fails with "No implementation of method:"

12:05 bbloom: dnolen: yeah

12:06 dnolen: i discussed the idea in here a few months ago when i first implemented that prototype

12:06 nDuff: technomancy: ...write a wala IR -> JVM bytecode compiler? Eh, maybe for 1.0; for 0.1, I'm probably going to hold my nose and use Soot; I'd rather prove the concept before sinking time into improving the tools used to implement.

12:06 bbloom: dnolen: the premise is to view the outside world is a filesystem w/ synchronous reads and asynchronous writes. where all external services are mounted at some route & the routing tables are cheap and immutable

12:08 jcromartie: it happens if I use (require ... :reload) too

12:08 technomancy: nDuff: I meant the for ocaml

12:08 jcromartie: I understand what's going on but I wonder how I can avoid it

12:08 nDuff: technomancy: ahh.

12:08 jcromartie: other than avoiding interactive development with protocols and records

12:08 technomancy: jcromartie: pretty much

12:08 jcromartie: bah

12:08 that sucks

12:08 well at least this part doesn't change much

12:09 bbloom: dnolen: kinda plan9 + datomic inspired

12:13 dnolen: https://gist.github.com/swannodette/7644500, add back -update!, if a value has children you can't -update! it

12:15 bbloom: I think there's an interesting opportunity here with what I've got to do batching and doing a read will fuse?

12:15 will ponder that

12:15 bbloom: dnolen: what do you mean by "fuse"?

12:16 dnolen: bbloom: actually apply the batched operations

12:17 bbloom: in your code? i don't see any batching...

12:17 i still don't really understand it tho

12:18 dnolen: bbloom: nothing there yet - talking out loud :)

12:18 bbloom: i'm still not really convinced that this is a big issue

12:18 java interop isn't any fun b/c you need to create tons of config objects w/ builder APIs and all that nonsense

12:19 javascript interop sucks b/c you need to do the same thing

12:19 only it double sucks b/c the "builder API" has nice data notation in JS

12:19 :-P

12:19 it *feels* close to have a clj map and a js obj and be like "why can't i just make this magically work?"

12:19 dnolen: bbloom: yeah I just agree at all w/ your take on the response

12:19 (js-obj "foo" "bar")

12:20 {foo: "bar"}

12:20 not saving many characters here

12:20 "just don't agree"

12:20 bbloom: heh, ok, was about to ask

12:20 i don't think it's about saving characters

12:20 it's about some warm fuzzy feeling

12:20 dnolen: bbloom: don't get me wrong I think #js literal idea is a fine one

12:21 and that would make people a little bit happier but really

12:21 justin_smith: if it's just about comfort, just ripping the bandaid off is the best policy

12:21 dnolen: #js {"foo" "bar"} vs. (js-obj "foo" "bar")

12:21 come on

12:21 bbloom: doThing(with, args, {like: "this", and: "that"}) is just much more pleasant than (js/doThing with args (js-obj "like" "this" "and" "that"))

12:21 dnolen: bbloom: marginal

12:21 bbloom: dnolen: yeah man, it's marginal to you and me

12:21 dnolen: b/c we understand that it's surface beauty

12:21 dnolen: but people care about that weird shit

12:21 hence: ruby.

12:22 why use a map when you can spend a bunch of time metaprogramming a fancy english-ish configuration API that essentially boils down to a map?

12:23 rasmusto: ~map

12:23 bbloom: i don't have proof, but i'm pretty sure athsetics drives much of the clj->js desire

12:23 clojurebot: map is laziness

12:23 bbloom: that's not to say there isn't value in making the process smootehr

12:23 there certainly is

12:24 especially b/c json is so popular in js libs, where wacky class hierarchies and absurd DSLs are so popular in java and ruby respectively

12:24 the popularity of json means that there is real opportunity for a solution that may actually be broadly applicable

12:26 i think an even bigger win than a #js literal would be a dot-like form tuned for js calling conventions, much like coffeescript's splat & keyword args and whatnot

12:27 dnolen: bbloom: #js literal maybe, sugary stuff not gonna happen, people write their macros for that stuff.

12:28 bbloom: dnolen: yeah, but that's what i'm saying: i think the complaints are about sugar

12:29 nDuff: technomancy: Hmm. Do you have experience w/ any options for running OCaml on the JVM? Even if I'm using the IR implemented in OCaml, I'd rather not give up core.logic or have to serialize/deserialize everything crossing the boundary.

12:29 dnolen: bbloom: perhaps, but I'm skeptical that's the only reason

12:29 bbloom: nDuff: not to speak for technomancy, but i think the only reason he bothered with ocaml was to avoid the JVM :-P

12:30 technomancy: no, he's right

12:30 I wasn't actually paying attention to what you were doing; just happened to pattern match on that one particular word. sorry =)

12:31 nDuff: heh, np.

12:35 danneu: What does this error usually mean? namespace 'eraser.core' not found after loading '/eraser/core'

12:35 TimMc: It might mean you have a typo in either the ns or the file path.

12:35 hiredman: it means you have the wrong name in your ns form, or don't have an ns form

12:35 TimMc: or an underscore/hyphen confusion.

12:36 danneu: My test autorunner enters this state after a few autoruns lately. Otherwise the suite runs entirely a few times.

12:36 good opportunity to try midje

12:40 coventry: There are some drawbacks to midje. http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/

12:44 TimMc: coventry: What drawbacks?

12:44 gfredericks: TimMc: you might have to rewrite your tests in clojure.test

12:44 TimMc: I skimmed the blog post, but it didn't seem relevant to that.

12:45 danneu: i read a blog post a while back about some effort towards a core.test rewrite or big refactor.

12:45 TimMc: Oh, I see -- missed the directionality.

12:45 But it doesn't mention *why* they didn't like midje.

12:45 bbloom: TimMc: it only uses the word "idiomatic"

12:46 or rather "unidiomatic"

12:46 myguidingstar: hi all, what are the best practices to mock/test file io?

12:46 danneu: kibit called their test suite unidiomatic so they're working towards kibit compliance

12:47 kdd

12:47 * TimMc submits a PR to kibit that emits "Not giving TimMc money is unidiomatic."

12:47 justin_smith: lol

12:47 bbloom: myguidingstar: for the O part, you can use with-out-str

12:48 myguidingstar: for the I part, you can use http://docs.oracle.com/javase/7/docs/api/java/io/StringReader.html

12:48 justin_smith: ,(with-in-str ":hello" (read))

12:48 clojurebot: :hello

12:48 justin_smith: why not with-in-str?

12:48 oh because you are not usually reading from *in* of course

12:49 bbloom: justin_smith: i had no idea that existed

12:49 technomancy: guns: hey, I was going to tweet about the new slamhound release; do you have a twitter account I could include?

12:49 coventry: TimMc: Too much magic. While that post is explicitly about rewriting, the tone most of the way through it is "here's some more magic which makes midje tests and the results of running them hard to reason about."

12:49 guns: technomancy: oh wait!

12:49 technomancy: It's not quite released...

12:49 Trying to shove a last bugfix out the door

12:49 technomancy: oh, haha. sure

12:49 guns: I didn't push the 1.5.0 git tag for that reason

12:50 technomancy: no worries

12:50 justin_smith: coventry: yeah, I looked at midge and it failed my "does it exist to emulate ruby" sniff test

12:50 TimMc: ouch :-P

12:51 My experience has simply been that composing can be a more difficult with Midje.

12:51 technomancy: it reminded me a bit of CL's LOOP macro

12:51 justin_smith: It is that whole magic thing. Accepting greatly increased complexity in return for minor conveniences.

12:52 danneu: i've been using jaycfields' http://jayfields.com/expectations/ for months. `(expect :a (first [:a :b :c]))`

12:52 TimMc: I'd like to see some of the prerequisites stuff pulled out into a separate utility, for instance.

12:52 technomancy: making up "english-like" syntax instead of using lisp calling conventions

12:52 or "non-structured" rather than "english-like" I guess

12:54 llasram: Macros make it easy for internal DSLs to be arbitrarily different from the host language

12:54 I don't think the problem is that it's "English-like," but that it's no longer the host language

12:55 There are lots of good ideas in Midje, but I've definitely found the cognitive load of effectively writing your tests in a different language than your code to be more than I want to absorb

12:57 hiredman: is halfway between clojure.test and cucumber really a destination?

12:57 danneu: my last job was at a rails shop and it's easy to underestimate the load of having to write `assert User.new(name: "Chuck").valid?` as `subject.should be_valid`

12:57 hiredman: (given many don't actually like cucumber)

12:59 danneu: my favorite ruby test lib is https://github.com/sconover/wrong - `assert { <ruby code> }`. and it analyzes the code to show helpful fail messages

13:02 which is something i think every clojure lib already does

13:03 coventry: Bwahaha

13:04 Oh, you mean testing libs.

13:05 danneu: well, if there's a cooler way to interpret the things i write, i don't want to stop you.

13:17 eigenlicht: /join #c

13:17 nobody saw that, ok

13:18 tbaldridge: clojurebot sees everything

13:20 mdrogalis: ~omnipresent

13:20 clojurebot: Excuse me?

13:20 rasmusto: ~omnipresence

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

13:22 justin_smith: ~πανταχού

13:22 clojurebot: Titim gan éirí ort.

13:22 justin_smith: ~πανταχού

13:22 clojurebot: Excuse me?

13:22 justin_smith: (that is the greek word for omnipresence, btw)

13:23 wakeup: gotta love emacs unicode support

13:24 rasmusto: oh i cant see it

13:24 justin_smith: I just pasted it in from google where I looked it up, heh

13:24 sadly, emacs does not do zalgo text properly

13:24 * rasmusto blames hipster bitmap fonts

13:24 justin_smith: the sacrifices I make for this platform

13:24 wakeup: zalgo?

13:24 eigenlicht: or word processing

13:24 justin_smith: wakeup: http://knowyourmeme.com/memes/zalgo

13:25 there is a unicode text trick for zalgo

13:25 a classic example: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags

13:25 top answer is fucking hilarious

13:25 wakeup: rasmusto: emacs mixes bitmap fonts with ttf fonts for fallback

13:26 H̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ

13:26 doesn't reallly work in emacs

13:26 justin_smith: nope

13:26 works in the browser

13:26 wakeup: bt the characters itself are displayed correctly

13:26 justin_smith: dunno if any text-editor proper would support it

13:26 yeah

13:26 wakeup: just positioning is off

13:26 justin_smith: it just doesn't do the layering

13:26 wakeup: hard to navigate if it would

13:26 rasmusto: wakeup: i should try to get putty-tray to do that w/ comic sans

13:27 justin_smith: yeah, that is likely the reason

13:27 wakeup: rasmusto: if comic sans has a big set of glyphs which I doupt

13:27 rasmusto: wakeup: (wingdings fallback)

13:27 wakeup: haha

13:31 Me going wild with math glyphs in lisp code: http://imgur.com/BaWzdBq

13:32 justin_smith: wakeup: do you have a low resolution screen, or really good eyesight?

13:33 wakeup: justin_smith: 1280x1024

13:34 justin_smith: I forget that most of the world is not at super high screen resolutions sometimes

13:34 wakeup: good eyesigh on short distances

13:34 ;)

13:34 Yeah the monitor I use is really old, but really really good

13:34 pristine truecolors and all

13:35 rasmusto: wakeup: im rocking an lgl246wp-bn at home, it's pretty solid

13:35 but the backlight is dimming on the left side :<

13:35 justin_smith: nice. Where I work everyone has a mac cinema display as their secondary monitor

13:35 wakeup: The next monitor I buy has to have a feature that reduces or eliminates the fly-poop

13:35 or whatever it is flies leave

13:35 EIZO :)

13:35 seangrove: wakeup: Are those font-locks, or actual characters in the source?

13:36 wakeup: seangrove: actual characters in utf-8

13:36 justin_smith: emacs makes symbol entry pretty easy: C-x 8 <return> snowman <return>

13:36 wakeup: seangrove: http://repo.or.cz/w/flub.git/blob/HEAD:/bachelor-cs/set-theory.lisp

13:36 justin_smith: and of course you can put favorites on a simpler keybinding

13:37 wakeup: I have an xmodmap keybingings for math characters

13:37 seangrove: wakeup: More a fan of font-lock replacements in emacs, personally

13:37 justin_smith: seangrove: that is definitely kinder to collaborators and downstream users

13:37 seangrove: But maybe that's just me being crazy, definitely could be.

13:37 danneu: Is there a lein plugin that auto-runs appropriate core.test suite on file save?

13:37 guns: You can also use readline bindings to write utf-8 in a shell

13:38 ❤ utf-8

13:38 seangrove: justin_smith: That's my concern, but maybe it's crazy to expect collaborators who can do the whole clojure/lisp thing but can't handle utf chars

13:38 wakeup:

13:38 snowman!

13:38 justin_smith: wakeup: every unicode is available by name that way

13:38 and if you enter a * glob and tab it shows cantidates

13:38 like check out *cat*

13:39 seangrove: wakeup: Wouldn't mind seeing some code with all the symbols :)

13:39 justin_smith: 😹 <- "CAT FACE WITH TEARS OF JOY" is the name of that codepoint

13:39 wakeup: justin_smith, seangrove: It's not like this is production source, this was an experiment for myself, I think programs in ASCII aren't a bad thing!

13:40 seangrove: wakeup: Yeah, that's no problem at all of course. Definitely fun for doing things on your own!

13:40 coventry: Holy cow. http://cppgm.org/about.html "Students of this online course each single-handedly develop their own original C++ compiler, standard library, and toolchain"

13:41 seangrove: Wow, C++ grandmaster.

13:41 * seangrove imagines what one would look like

13:41 * seangrove shudders

13:41 wakeup: lol

13:41 justin_smith: in fact, weird unicode in names is a nice substitute for the ___***name***___ convention to indicate things you probably don't want to fuck with

13:42 ie. the fact it is weird to enter in may increase the amount of time spent deciding whether one should really refer to it

13:43 seangrove: 😼

13:43 TimMc: justin_smith: Such as brehaut's favorite, a suffix to mark side-effecting predicates: ‽

13:43 justin_smith: that would be a good name for an internal namespace for example

13:43 * seangrove just found M-x insert-char

13:44 justin_smith: seangrove: that is the C-x 8 <return> I was referencing above

13:44 seangrove: justin_smith: Ah, got it

13:44 justin_smith: there is also M-x describe-char

13:45 if you want to know which thing that does not print properly is at point

13:45 for example

13:45 or if you see a sigil and want to know its name

13:45 TimMc: Totally works.

13:45 justin_smith: CAT FACE WITH WRY SMILE

13:46 come to think of it, I use C-x 8 <return> often enough, I should totally give it a C-c binding

13:47 TimMc: https://www.refheap.com/21243

13:49 justin_smith: (global-set-key (kbd "C-.") #'insert-char) (global-set-key (kbd "C-,") #'describe-char)

13:49 works a charm

13:50 llasram: I need to update my key-bindings... I'm still using `ucs-insert`, which apparently now is just an alias for `insert-char`

13:51 justin_smith: "ucs-insert is an alias for `insert-char' in `mule-cmds.el'."

13:51 thats what M-x describe-function tells me

13:51 llasram: justin_smith: I think that's basically what I just said...?

13:52 justin_smith: just verifying

13:52 gf3: TimMc: re: wat.json

13:52 llasram: kk :-)

13:52 gf3: TimMc: Those are all real-life WTF comments people have made, mostly on IRC

13:52 justin_smith: llasram: I misunderstood what you meant by "apperently"

13:53 llasram: 😼

13:54 jcromartie: so I have a rather simple set of protocols here for data model change transactors and transactions

13:54 I know, just use Datomic right?

13:54 but just humor me

13:56 (defprotocol ATransactor (transact [x transaction] "Update state and persist transaction"))

13:56 really it just calls (defprotocol ATransaction (run [x state] "Apply this transaction to the data model state"))

13:56 but for a file-based transactor it would write the transaction to a log and return the new state

13:56 mikerod: clojure.reflect/type-reflect is called in an AOT-compiled src/main directory; it fails with ClassNotFoundException when the class is from a `defrecord` that is not AOT-compiled in a src/test directory; anyone have insight into what could be happening?

13:56 jcromartie: for a SQL transactor it would insert a row, etc.

13:57 hiredman: mikerod: have you loaded the defrecord definition?

13:57 justin_smith: mikerod: I would lein clean and restart to rule out the most trivial possible cause of the problem

13:57 jcromartie: so the question is

13:57 llasram: mikerod: IIRC, type-reflect grabs the thread context class loader, which doesn't know about e.g. defrecords added to the Clojure dynamic classloader stack

13:57 jcromartie: what about side effects

13:58 mikerod: hiredman: yes the definition is loaded

13:58 jcromartie: you could call a transaction on a transactor and cause it to be stored but somehow ignore the result

13:58 so I think the transactor needs to be stateful

13:58 llasram: mikerod: Here's a work-around I submitted to a similar problem in clara-rules: https://github.com/rbrush/clara-rules/pull/8/files

13:58 mikerod: hiredman: and I reproduce this in a REPL setting, probably because the reflect lib is grabbing the correct classloader stack

13:58 llasram: this is along the lines of what I am thinking

13:58 llasram: mikerod: It doesn't entirely work, because it only grabs the base loader. To allow re-compilation, you need to make sure you're grabbing the current loader

13:59 hiredman: that seems unlikely

13:59 mikerod: llasram: that's funny you show this patch, because this is the same lines of code that I am fighting with in Clara

13:59 hiredman: it looks like the default java reflector tries to read class bytecode

13:59 llasram: mikerod: haha

13:59 mikerod: I was reading the reflector clojure stuff, and I can't see why a dynamically loaded defrecord would not be visible to it

14:00 llasram: mikerod: I haven't used been back to clara since that patch. Not sure if it got reverted etc

14:01 hiredman: mikerod: if you create your own java classloader using the value of the var clojure.lang.Compiler/LOADER it should work

14:01 mikerod: llasram: your changes are in the version I am looking at/working with. I was setting up some tests where I generate some dynamic defrecords, and clojure.reflect/type-reflect is giving me the ClassNotFoundException

14:01 hiredman: it takes the value of the context classloader at load time, which seems kind of gross

14:02 llasram: hiredman: Ah, yeah -- I think that's the problem

14:02 mikerod: oh

14:02 hiredman: have you considered just using reflection?

14:02 mikerod: I was thinking there was something going on here with grabbing the load-time classloader

14:02 which, I guess is then unaware of any new classes being added later

14:02 llasram: There's a clojure.lang.RT method makeClassLoader, which I think is the Right Way To Do It (tm)

14:03 I think the fix is to use that method, and call it each time you invoke type-reflect

14:03 hiredman: I am not a huge fan of clojure.reflect, largely because it seems sort of half baked with things like this

14:04 mikerod: so you'd call type-reflect with a new :reflector each time?

14:04 to keep it "fresh"

14:04 hiredman: yeah, I am a bit skeptical on clojure.reflect, especially after this one

14:04 llasram: mikerod: I believe so. I'm not entirely certain even that will work

14:04 I think hiredman's suggestion of just directly reflecting on the class might be way to go

14:04 mikerod: indeed

14:05 TimMc: gf3: Do you use that file for anything>

14:06 gf3: TimMc: Oh yeah, we've got an IRC bot that spits those out randomly when people say "wat"

14:06 wat

14:06 b-ot: gf3: Blog wat: http://grenzgenial.com/post/2414488498/javascript-and-the-brain-why-javascript-is-the-future

14:06 ToxicFrog: Oh boy

14:08 gfredericks: where does core.typed store the annotations for vars in clojure.core?

14:09 seangrove: Luckily this blog-wat post isn't loading. Probably good.

14:10 Ah, guess it's here now http://grenzgenial.tumblr.com/post/2414488498/javascript-and-the-brain-why-javascript-is-the-future

14:10 TimMc: Aha.

14:10 wat

14:10 b-ot: TimMc: I am having a jsp that contains a jquery tab and inside tab i am having a custom search component on clicking the component a grid will open and it will act as an overlay and i used this plugin to close the grid if the user clicks outside the gridis working perfectly in all other element click other than jquery tab selection component

14:10 TimMc: Nice.

14:11 justin_smith: wat

14:11 b-ot: justin_smith: can i use document.write to call a json

14:11 seangrove: "a) No types: types are stupid. "

14:12 Seems like a fairly straigthforward answer

14:12 hiredman: gfredericks: there is a #typed-clojure channel where you may have better luck asking such things

14:12 gfredericks: hiredman: I am going to go there

14:12 seangrove: json is a string, and strings do not implement IFn, so no.

14:12 gfredericks: hiredman: thx

14:12 justin_smith: seangrove are you talking to b-ot?

14:13 seangrove: justin_smith: Just speaking to the wider point ;)

14:13 hiredman: gfredericks: sure, I am in there too, and interested in seeing the answer

14:13 justin_smith: wat

14:13 b-ot: justin_smith: javascript:(unescape); lead you to function unescape() { [native code] } Native Code, eh? I wonder if '%69%6C%6F%76%65%6D%6F%6F' has anything to do with a Native Code...

14:14 hiredman: gfredericks: depending what you mean by "stored" there is a source file called something like base_env.clj which I think is where the types are declared, but I am not sure where in memory stuff is stored

14:14 gfredericks: hiredman: oh I think that's all I meant

14:15 hiredman: well

14:15 https://github.com/clojure/core.typed/blob/master/src/main/clojure/clojure/core/typed/base_env.clj#L1073

14:16 seangrove: justin_smith: The collection of quotes is incredibly difficult to parse...

14:16 Seems to highlight some problems with human communication and thought processes...

14:28 sdvhbhszo8yhwtu: YOU MAY BE WATCHED






14:28 trptcolin: such caps lock. noble consonants in username. wow.

14:28 TimMc: Oh, we got this one over on foonetic as well.

14:28 seangrove: True, true.

14:32 sdvhbhszo8yhwtu: YOU MAY BE WATCHED





14:32 kilon_: o_O

14:33 :D

14:33 seancorfield: heh... thank you!

14:33 kilon_: i love your style

14:33 technomancy: pew pew pew

14:33 pisketti: preemptive strike

14:39 TimMc: When someone takes op, I imagine them glowing slightly.

14:43 technomancy: when someone who joins takes op because they forgot to turn it off before parting I imagine trumpeter fanfare

14:44 * justin_smith makes a hook in emacs erc mode that changes "*** ChanServ (ChanServ@services.) has changed mode for #clojure to +o technomancy" to "technomancy: I'm chargin' mah lazerz"

14:45 shaunxcode: is it crazy talk to use the channel returned by a go block as a way of early return e.g (def ch (go ... (if x (>! ch early-result) normal-path))

14:46 joegallo_: technomancy's ops are over 9000!!!! http://tinyurl.com/p6cwmdz

14:46 hiredman: shaunxcode: you can't, you don't have access to the returned channel inside the go block

14:47 shaunxcode: it may actually work in a def like, due to def, but it won't work with locals

14:47 shaunxcode: hiredman: in that example I do though (I have this working I was just wondering if it would appear odd)

14:47 edoloughlin: I find that using logging statements breaks a clean functional style (e.g., using 'do' everywhere). Is there an idiomatic way of doing this that I just don't know about?

14:48 dnolen: shaunxcode: I also don't see how that example demonstrates early return

14:48 hiredman: shaunxcode: try it with a let

14:48 technomancy: edoloughlin: for quick debugging I often use (doto x prn)

14:48 (if it's not going to get checked in)

14:49 edoloughlin: I'm looking for something more permanent. I.e., logging calls to a REST API. I want to be able to generate long-term logs.

14:50 ...without making my code look ugly.

14:51 justin_smith: edoloughlin: there are things like spy in many logging libs that return what the original form returned, while logging the form and its result

14:51 edoloughlin: justing_smith: thanks. That might be a good starting point.

14:52 TimMc: edoloughlin: I have written "check" (a doto + when-not) that I use to log which part of an if expression's conditional is failing.

14:52 hiredman: shaunxcode: the way def ends up working, you can refer to the thing being def'ed in the value of the def, as long as the def actually happens before you try and get the value

14:52 edoloughlin: I'm looking to do application-level logging. E.g., "user X created resource Y"

14:53 hiredman: which basically means if you def a function and the value of the var (that def creates) is not refenced until you try and run the function

14:53 so your (def … (go …)) is actually a race condition

14:54 has def interned the channel returned by the go block as the value of the var by the time the running go block on the threadpool or whatever has gotten to the dereference of the var

14:54 edoloughlin: Anyone know if http://www.clojure-toolbox.com/ is still a good catchall for libs, or is there something more current?

14:56 shaunxcode: hiredman: good call - trying it in let block made it clear.

14:57 hiredman: shaunxcode: I dunno what your background is, but people coming from scheme often try to use def as a synonym for let, like define in scheme, but clojure's def is definitely not like scheme's define

14:58 clojure's def only operates on the global environment, nothing lexical about it at all

14:58 gfredericks: I've been wanting a robert-hooke based lib for logging around vars

15:17 bitemyapp: gfredericks: uhm, I did that with blackwater.

15:17 gfredericks: but for SQL and pretty colors.

15:17 gfredericks: you could whip up what you want in a jiffy yo.

15:25 Apage43: juffowup

15:27 bitemyapp: Apage43: ?

15:28 Apage43: who knows

15:28 llasram: Time to start hacking Apage43's accounts I think

15:30 Apage43: it's never that time. That time ruins my day

15:30 bitemyapp: gfredericks: please don't mention things I like without elaborating :(

15:32 gfredericks: bitemyapp: I get stalled thinking about it because I don't know how much it should be coupled with a structured logging lib

15:33 seangrove: gfredericks: channel all the things, decoupling.

15:33 gfredericks: huh?

15:34 seangrove: gfredericks: Just thinking about a robert-hook logging-oriented library with core.async channel-based apis

15:34 Should be pretty simple with a structure like that to pipe it into other libraries.

15:34 gfredericks: seangrove: the question in my mind is whether the var-hooking lib can log data or should assume it can only log strings

15:35 seangrove: Ah, that's what you meant by 'structured'

15:35 Well-made point.

15:36 justin_smith: optional arg for a formatter, that can choose to print readably or whatever else? default just being calling str on the args?

15:36 gfredericks: I wouldn't want to use it if I had to do that every time I wanted to log something

15:37 I've gotten so used to structured logging that I can't fathom going back, but I don't know of a decent public lib for it

15:41 seangrove: bitemyapp: Drinks or dinner tonight somewhere on Market? Thinking orbit-room or armory club if you're inclined.

15:43 hiredman: pedestal has a little logging api

15:44 rkneufeld: hiredman: my ears are ringing. Whose using pedestal's logging library where!?

15:44 hiredman: no one, I am just throwing it out there as opensource clojure code with structured logging

15:45 https://github.com/pedestal/pedestal/blob/master/app/src/io/pedestal/app/util/log.clj

15:45 rkneufeld: Cool. FWIW: It's pretty spartan, and definitely needs a bit of work

15:45 stuartsierra: In retrospect, I think my addition of a new logging API in Pedestal was probably a mistake.

15:45 hiredman: sure, but with what little I have done with it, it seems vastly superior to, for example, what we currently use at work (which is not structured at all)

15:46 seangrove: rkneufeld: What do you think of pedestal for a chat app for an introductory run-through? Worth it, or overblown?

15:46 stuartsierra: But I'd like to have a standard API for structured log messages, unlike clojure.tools.logging which is mostly string-based.

15:46 rkneufeld: Timbre looks kind of neat: https://github.com/ptaoussanis/timbre. And we have a recipe on it in the cookbook: https://github.com/clojure-cookbook/clojure-cookbook/blob/master/deployment-and-distribution/logging-with-timbre/logging-with-timbre.asciidoc

15:46 hiredman: stuartsierra: a start would be spinning pedestal's out in to a library

15:47 gfredericks: stuartsierra: I've been able to use c.t.l with structured

15:47 seangrove: I've noticed some of the ui patterns I've independently been working towards seem to be pretty well baked into pedestal, so it's piqued my interests recently.

15:47 gfredericks: with log4j all it takes is a custom Layout class

15:47 stuartsierra: hiredman: Yes, it's on the (infinitely long) queue.

15:47 kilen: What's the idiom for caaddr-like helpers? firstfirstrestrest doesn't quite capture it.

15:47 seangrove: kilen: hahahahaha

15:48 Love that idea :)

15:48 gfredericks: kilen: I think we mostly use destructuring instead

15:48 seangrove: ffrrest

15:48 llasram: kilen: destructuring

15:48 rkneufeld: seangrove: Hmm, I think it would depend on the level of your audience. Admittedly, the introductory material can be a little rough aside from going through the bulk of the app-tutorial (pretty big).

15:49 seangrove: rkneufeld: Yeah, made it about half-way through, but haven't completed it. On reflection, I think porting kandanapp over to pedestal could be a worthwhile learning experience

15:50 kilen: gfredericks, llasram: is there sugar I'm on aware of? that only works in a binding context, no? what would (count (caaddr foo)) translate to?

15:50 llasram: kilen: You do a destructuring bind wherever you get `foo` from in the first place, or you do the destructuring bind on `foo` before calling `count`

15:52 kilen: llasram: say it's a retval of some function, can I do it outside a let or function argument decleration? if not, it's far less convenient

15:52 llasram: kilen: Why don't you refheap/gist up an example?

15:55 ath0: cd do

15:58 justin_smith: kilen: yes, you can destructure in a let, loop, doseq, for...

15:59 ,(let [[a b c] (range)] b)

15:59 clojurebot: 1

16:01 justin_smith: there is also get-in

16:02 llasram: I would waaaay rather see destructuring in code than a call like `(get-in [0 1 1 1 0] foo)`

16:02 justin_smith: ,(get-in [:a :b :c [:d :e [:f :g :h]]] [3 2 1])

16:02 clojurebot: :g

16:02 b-ot: justin_smith: Sorry, I can't find anything on [:d+:e+[:f+:g+:h]]]+[3+2+1])

16:02 justin_smith: wat

16:02 b-ot: justin_smith: How can I replace a php include navigation with jQuery?

16:03 kilen: justin_smith: nice, that's much better then (first (first (rest))

16:03 llasram: Huh -- is b-ot also listing on ^, ?

16:03 justin_smith: only works on vectors though

16:04 but agreed with llasram that a destrucuring is usually better

16:05 get-in becomes nice when you are doing partial walks, so constructing or manipulating the sequence of keys to step into

16:06 kilen: justin_smith: still, you have to add a let in there to destructure, it doesn't fit well with a series of steps you might translate into a -> form

16:07 justin_smith: unless you write a helper that does the destructuring

16:07 well, no, you don't need a let, an fn would suffice

16:08 hiredman: ,(doc as->)

16:08 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

16:10 teslanick: ,(source as->)

16:10 clojurebot: Source not found\n

16:10 justin_smith: yeah, the source is easier than the doc string for me :)

16:11 teslanick: I usually like to see how the non-special-forms bits are implemented. It helps me understand the docstring.

16:11 kilen: hiredman: iiuc that combins let with ->, it doesn't help destructure an intermediate result

16:12 justin_smith: (defmacro as-> [expr name & forms] `(let [~name ~expr ~@(interleave (repeat name) forms)] ~name))


16:12 kilen: so just (def caddr (comp first rest rest)) basically if that's what you need. fair enough,

16:12 hiredman: ,(-> {:a 1} (as-> {:keys [a]} (+ a)))

16:12 clojurebot: {:keys [nil]}

16:12 justin_smith: yeah it constructs all the lhs in the let, so it does not help destructure

16:12 hiredman: clojurebot: jerk

16:12 clojurebot: you cut me deep, man.

16:12 llasram: kilen: Also `nth`

16:13 kilen: llasram: only for vectors, no?

16:13 hiredman: kilen: I think whatever is missing here, is you don't have deep nesting of lists in clojure like you do in other lisps

16:13 llasram: (inc hiredman)

16:13 lazybot: ⇒ 28

16:13 hiredman: kilen: in clojure you don't use alists, you use maps

16:13 llasram: ,(nth '(0 1 2 3) 2)

16:13 clojurebot: 2

16:13 kilen: hiredman: that actually makes a lot of sense

16:14 llasram: yeah, you can't erase silly things you say on irc unfortunately

16:14 llasram: kilen: Not with that attitude you can't!

16:15 kilen: llasram: ok

16:16 llasram: Become a supervillian and erase all our minds / kill us all

16:16 It just takes a positive attitude

16:17 kilen: I am still curious about any specific example you have, unless maps vs alists has turned it into a non-issue

16:20 kilen: llasram: how about (first (rest (helper foo)) as the retval expression of a function? the style advice on maps is helpful though.

16:20 llasram: kilen: `second` is (comp first rest), so the stdlib has you covered that far

16:22 kilen: I think it does come down to style, which may be a two-way street w/ what Clojure provides. If I'm using a vector as a positional "record," I'll usually turn it into a map at 3 fields.

16:23 In part I'm sure because that makes it easier to access portions of the structure

16:24 kilen: llasram: yeah, I tend to end up with lots of first first in code, I'm going to try switching to maps. thanks.

16:37 dotemacs: Hi, I can see that clj-pdf can be used to generate a new PDF file, but what about editing an existing PDF file, do you know of a good package for that ? Thanks

16:39 bitemyapp: dotemacs: editing PDFs other tools generated is often messy and source-specific

16:40 dotemacs: there isn't a good high-level way to do so, you're going to be hacking it up yourself.

16:40 its just the way PDF works.

16:41 justin_smith: if clj-postscript existed we could run clojure in pdfs

16:41 I guess new fangled pdfs have javascript too

16:41 bitemyapp: justin_smith: horrific.

16:42 justin_smith: yeah, I know

16:42 seangrove: Wish there was a nicer syntax for fields

16:42 justin_smith: the fact that they are emphatically not passive documents but a full but unreadable programming language is actually what I don't like about pdfs

16:43 kilen: dotemacs: you might be able to use qpdf to convert that into a text processing task. it's a pdf -> text -> pdf structure editor, I've used it before, not with clojure though.

16:43 bbloom: justin_smith: wasn't that like 2005? old news :_P

16:43 llasram: Actually, the PDF subset of PS drops Turning-completeness. The original idea was that it was essentially an entirely pre-rendered PostScript

16:43 seangrove: (map (juxt #(.-name %) #(.-value %)) (prim-seq (.-attributes el))) Isn't very nice.

16:43 bbloom: justin_smith: still horrific, however

16:43 dotemacs: bitemyapp: im involved in a project that is already doing that, where PDF forms have to be filled in which works fine using pdftk (CLI tool), the only part that is missing is crossing out certain form fields with thick black lines. So if there was something which could just add thick black lines...

16:43 justin_smith: bbloom: it was after I learned how to use pdf, so it is new fangled :)

16:44 dotemacs: kilen: thanks, but the PDF document needs to stay PDF, it's just the insertion of thick lines in certain forms that I need to add

16:44 justin_smith: dotemacs: that's at most 20 characters of postscript code

16:44 though pdf is terrible and I am sad you have to use it

16:44 dotemacs: justin_smith: ok, i'll look into that, never tried postscript coding before :)

16:45 justin_smith: I don't know if coding it directly is wise, most use a tool that inserts a shape or object into pdf by generating postscript

16:45 kilen: dotemacs: like I said, it's a "structure editor" the text representation is just an IR, you should see if it fits your needs. it's not a pdf->text converter.

16:45 bitemyapp: dotemacs: you're going to hack it up yourself.

16:46 dotemacs: kilen: thanks, looking into qpdf now

16:46 justin_smith: the issue is that pdf is not a declarative page, it is a turing complete language that outputs a page, which makes generalized editing tools a big task

16:47 though putting an arbitrary shape on top of what is there is comparatively doable

16:47 kilen: dotemacs: it's a analysis-synthesis type deal

16:47 llasram: PDF w/o JS is *not* Turing-complete

16:48 justin_smith: llasram: ? postscript is a programming language, and it is turing complete

16:48 pdf is a container for postscript

16:48 it is related to forth

16:48 llasram: justin_smith: Yes to the former, no to the latter

16:48 justin_smith: it has variables and loops yo

16:48 it is turing complete

16:48 llasram: PDF objects may contain a subset of PS w/o control structures

16:49 justin_smith: oh, pdf does not allow the entirety of postscript?

16:49 llasram: No

16:50 bbloom: it's a venn diagram

16:50 llasram: There's a lot of cruft (JS) in later version of PDF, but IMHO the base spec is pretty sane

16:53 bitemyapp: dotemacs: supposedly cemerick has a PDF extraction library, I am hunting down the name.

16:54 justin_smith: the amount of papers on turing completeness that are in pdf format (and marked as such in surrounding text) makes the turing completeness (or not) of pdf a hard thing to google

16:54 llasram: haha

16:54 coventry: bitemyapp: PDF Text Stream http://snowtide.com/

16:55 dotemacs: bitemyapp: doesn't that just extract text from a PDF file? This link that coventry posted, cemerick's lib

16:55 bitemyapp: coventry: oh is that what pays for cemerick's 100% time?

16:56 llasram: justin_smith: I only worked with PDFs at a low-level for a little while, so I may be mistaken, but my memory/experience is that it essentially contains the result of running a source PS "program"

16:56 bbloom: i dunno if it actually covers his 100% time or not, but i just assume that anything PDF related makes absurd amounts of money for no apparent reason

16:56 i call that "PDF money"

16:56 brehaut: llasram: that + a whole lot of crazy since

16:57 bitemyapp: http://www.pdftextstream.com

16:57 cemerick: dotemacs: Yes, PDFTextStream is strictly provides extraction functionality. Sounds like you need "editing", which is a whole different ball o' wax.

16:57 llasram: There's a joke in there somewhere about printing money (since many printers use PDFs as their transfer format)

16:57 printers == printing companies

16:58 justin_smith: and have hard coded stuff to detect money even? or is that an urban legend

16:58 llasram: Oh, no idea on that one

16:58 bitemyapp: justin_smith: scanners and photoshop detect money yes.

16:58 kilen: dotemacs: if what you're trying to do is graphical, you could try cairo+poppler to load, draw and render back to pdf.

16:58 llasram: I hadn't heard that urban legend :-)

16:58 bitemyapp: printers do not, they don't need to.

16:58 lumafi: yeah, it's true

16:58 http://en.wikipedia.org/wiki/EURion_constellation

16:58 justin_smith: bitemyapp: oh, ok, it is on the input end

16:58 cemerick: llasram: PDF uses a non-turing-complete subset of PS

16:59 bitemyapp: justin_smith: you can't use a conventional printer to make counterfeit bills so it doesn't even matter, plus they'd get marked.

16:59 dotemacs: cemerick: thanks

16:59 kilen: thanks, i'll look into it

16:59 llasram: cemerick: Glad to have my memories confirmed :-)

17:00 justin_smith: bitemyapp: yeah, that unique yellow pattern each printer does, which is why you need a color cartridge to have some ink even to print black and white

17:00 bitemyapp: That is probably partly why.

17:01 PDF is a good example of why you should eschew turing completeness/excess power whenever possible

17:03 justin_smith: because it does it well, or because it does it poorly?

17:05 bitemyapp: justin_smith: you want to use as little power as possible to solve a given problem.

17:05 justin_smith: if a regular syntax would suffice, use that. If a context free grammar would suffice, use that.

17:05 justin_smith: PDF's turing completeness is a horrendous problem.

17:05 brehaut: bitemyapp: thank the IRS apparently :P

17:05 bitemyapp: contrast processing PDF with HTML.

17:05 justin_smith: why the IRS?

17:06 brehaut: they apparently funded a lot of development of PDF with specific features that they wanted

17:06 a lot of it was apparently to do with adding 'rich document' shenanigans (big frinstance ecmascript)

17:07 bitemyapp: the solution is to create rules of the standard for implementers, not embed a VM. :P

17:07 if word docx can suffice with XML, there's no reason PDFs needed to be turing complete.

17:07 brehaut: bitemyapp: ah, the CSS solution ;)

17:07 justin_smith: so it was like powell motors and "the homer" automobile

17:07 cemerick: bitemyapp: it's not turing-complete. The Javascript you can embed in it, on the other hand...

17:07 coventry: brehaut: Any keywords which would be useful in searching for that story? ("IRS pdf" turns up a lot of false positives. :-)

17:07 bitemyapp: brehaut: that's roughly how most PDF generators work anyway, like HTML and CSS, and CSSes problems are specific to its implementation not its nature.

17:08 brehaut: coventry: no idea sorry; i got the info from chatting with an internet friend who worked at adobe at the time on PDF stuff

17:09 bitemyapp: cemerick: I'm pretty sure the PostScript derivative in PDFs is turing complete.

17:09 brehaut: coventry: feel free to take it as 2nd hand apocryphal

17:09 technomancy: coventry: hey, can you remind me of what issues you ran into trying to build troncle based on nrepl-discover that lead you to embed your own stuff?

17:09 bitemyapp: cemerick: it would be very hard for you to prove otherwise.

17:09 technomancy: was it just the region-as-text?

17:10 bbloom: http://www.adobe.com/devnet/pdf/pdf_reference.html have fun guys

17:11 oh, right you need to BUY the reference from ISO

17:11 insert look of disapproval here

17:12 bitemyapp: http://www.citationsoftware.com/faqPS_vs_PDF.htm

17:12 it says PDF doesn't have looping or conditional constructs, making it not turing complete.

17:12 After having seen the SKI combinator implemented in CSS, I would take that as a challenge.

17:13 bbloom: lol ok you have to link me to that ski/css thing

17:13 bitemyapp: sorry, Rule 110

17:14 bbloom: have you seen the Rule 110 implementatio?

17:14 implementation*

17:14 turbofail: i don't think there is any substitution mechanism in PDF either

17:14 cemerick: bitemyapp: do you really want to blow your time thinking about the guts of PDF, etc?

17:14 bitemyapp: I saw SKI pop up somewhere weird not too long ago, but I don't think it was CSS

17:14 cemerick: Let me answer that for you: no, no you don't.

17:15 bbloom: in any case, turing completeness is pretty much completely irrelevant to the rule of least power

17:15 bitemyapp: http://beza1e1.tuxen.de/articles/accidentally_turing_complete.html

17:15 bbloom: it's not irrelevant at all.

17:15 bbloom: people create *accidentally* turing complete interpreters pretty much by default

17:16 bitemyapp: Django templates aren't turing complete because they terminate.

17:16 at least at the compile-time level.

17:16 runtime is more complicated because runtime is whatever your language is.

17:17 the looping and conditional constructs don't mean much because it's data, not codata.

17:17 unless you injected a non-terminating generator, in which case you're an asshole.

17:18 bbloom: in order to choose something with the "least" power, you have to both assume power is a singular dimension and then define it

17:18 technomancy: cemerick: do you think nrepl needs to be more descriptive around content negotiation?

17:18 bbloom: turing completeness is not a useful notion for practically any practical application of the least power principal, since practically anything you ever do is still going to deal with *very large* data as opposed to infinite codata

17:19 so you're gonna need timeouts and other error handling anyway

17:19 the fact that you CAN write an infinite loop is pretty much moot if i can just generate arbitrarily large inputs

17:20 bitemyapp: that's not the point of eschewing turing completeness whenever possinle

17:20 possible*

17:20 the point isn't even halting in-and-of-itself although it can be useful, it's the programmatic processing of the data/code.

17:21 There's more to code-writing-code than human generated macros.

17:21 brehaut: bbloom: what is codata

17:21 bitemyapp: brehaut: http://blog.sigfpe.com/2007/07/data-and-codata.html

17:22 coventry: technomancy: Region-as-text, full-source-as-text (or at least line/column position of region, that's what I'm using it for at the moment), plus most crucially the ability for elisp to call into the discovered functions. Having nrepl-discovered clj output useful stack traces is also incredibly valuable for development. In a sense that was what triggered the rewrite: it was more for my own understanding, I just kept pulling stuff out

17:22 until I had that working, then I kept going until it just does what I need. So I'm not rejecting nrepl-discover wholesale, but I'm anticipating that for troncle I'm going to need more than it offers.

17:22 bbloom: bitemyapp: i agree that's about programatic processing of the data/code -- which is precisely why turing completeness is not a relevant design characteristic when evaluating usefulness for processing

17:23 being able to build a turing machine in my DSL makes me say "heh, neat" not "omg! my DSL is too powerful!"

17:24 bitemyapp: turing completeness affects your ability to deterministically process the input.

17:24 bbloom: only if you're assuming i need to execute the input to do anything useful with it

17:24 bitemyapp: I am positive that fact hasn't escaped you, so I'm going to assume you're being contrarian for the sake of it, to the detriment of anybody trying to learn something here.

17:26 bbloom: i don't subscribe to the rule of least power. instead of trying to minimize power, i try to maximize leverage, which, often, coincides with lesser power

17:26 benedikt: does require have something similar to :once with use ?

17:29 coventry: benedikt: Do you mean :only?

17:29 benedikt: d'oh. yes.

17:30 bbloom: bitemyapp: consider compilers. turing completeness is a given for a general purpose language, but some languages are more or less amenable to static analysis. the same is true of any data representation that may or may not happen to be turing complete

17:31 bitemyapp: the question is: what type of analysis do you need to perform? how can you design a language or data representation that helps you accomplish those goals?

17:31 coventry: benedikt: See :refer in the (require) docstring, and the (refer) docstring.

17:32 benedikt: ah, thanks

17:35 etiquette: is it considered rude to ask for help with an open and new stack overflow question?

17:37 kilen: benedikt: try it, the worst that can happen is that technomancy will charge his lazers. again.

17:41 bitemyapp: benedikt: having a well detailed Stack Overflow question pasted with a brief explanation/title in channel is an improvement over the sort of questions we usually get.

17:41 "does anyone use Clojure to process things?"

17:41 "does anyone use Clojure to do Clojure-y or web things?"

17:41 "I'm not going to ask my question until I get a population census of who uses this tool to accomplish the exact same thing my question is about"

17:42 technomancy: benedikt: I promise to only be slightly offended that you didn't pick #clojure as your first place to turn

17:42 owengalenjones: does anyone have an opinion on whether it's bad form to have a default multi-method implementation that is 8 lines long rather than say defining a function and just calling it in the default implementation?

17:42 kilen: I'm about to dive into core.logic, I've used blackbox SAT solvers before, how's core.logic different?

17:42 hiredman: what is a sat box solver?

17:43 bitemyapp: hiredman: http://en.wikipedia.org/wiki/Boolean_satisfiability_problem

17:43 hiredman: are you familiar with minikanren?

17:43 kilen: No, that's what I'm asking.

17:45 hiredman: minikanren is,uh, I guess breadth first search over a tree of possible solutions, with eaching disjunction(conde in core.logic, "or" in normal speak) being a branch

17:45 benedikt: technomancy: :)

17:45 hiredman: not branch, a branching

17:45 kilen: You can use a modeling language to generate a formulation for a SAT problem, feed it to a solver and get an answer. that seems kinda like what core.logic does, so is there a difference?

17:45 benedikt: technomancy: to be fair, i was here asking some days ago about it, with less details

17:45 bitemyapp: benedikt: what's the question anyway?

17:46 benedikt: http://stackoverflow.com/questions/20203047/classnotfoundexception-and-classcastexception-with-lein-droid # The question

17:46 bitemyapp: oh, android question. yep, I'm out.

17:46 benedikt: gg gl hf

17:47 benedikt: bitemyapp: i'm new to this wizardry as well

17:47 technomancy: benedikt: hardly anyone using clojure on android these days afaict

17:47 dnolen: kilen: SAT solvers are very specific type of powerful tool, core.logic is more an like an general embedded programming paradigm, with easy escape hatches back into functional programming.

17:47 benedikt: technomancy: i just felt like it

17:47 technomancy: beneditk: don't imagine you'd get much help outside a mailing list

17:48 dnolen: kilen: there is a strong connection between constraint logic programming and SAT solving methods - but this only recently well understood as far as I can tell - and we haven't treaded there yet.

17:48 hiredman: yeah, I found http://www.soi.city.ac.uk/~jacob/solver/flops.pdf, and looking over it, it seems to suggest SAT solvers are restricted to boolean expressions?

17:48 kilen: dnolen: so are the solvable problems in one a subset of the other? are they for different things?

17:48 dnolen: kilen: many problems solvable in either, SAT methods better in some cases, constraint solving better in others

17:49 trptcolin: benedikt: those last errors look similar to a lein issue: https://github.com/technomancy/leiningen/issues/1376

17:49 dnolen: kilen: but the killer thing about core.logic (which still needs work) is the level of integration with Clojure data structures

17:49 kilen: not really possible with off the shelf constraint solvers or SAT solvers

17:49 trptcolin: as for the initial ones, you don't have access to all the usual JVM stuff on android (see http://developer.android.com/reference/packages.html - javax.json.* is not there)

17:49 benedikt: trptcolin: thanks

17:49 dnolen: kilen: or even JVM based Prologs

17:51 benedikt: trptcolin: is it simply the case that clojure on android isn't a great idea?

17:52 technomancy: benedikt: I don't know if it's a great idea, but you definitely need to be prepared to shave a big pile of yaks

17:52 benedikt: technomancy: so not a great idea for a project to learn clojure?

17:52 kilen: dnolen: Thanks.

17:53 trptcolin: yup. http://www.deepbluelambda.org/2011/02/ was the last i'd heard about work towards it

17:53 technomancy: benedikt: not so much

17:53 trptcolin: [the yup was to what technomancy said]

17:53 bitemyapp: benedikt: not at all.

17:53 technomancy: benedikt: I think to make progress on those lines you'd need to already be a clojure expert *and* and android expert

17:53 alandipert: otoh, a good project to master clojure :-)

17:54 benedikt: technomancy: i have no intentions of being an android master

17:54 alandipert: :)

17:55 i'll switch to using ring and the other web things

17:57 bitemyapp: benedikt: http://www.luminusweb.net

17:57 coventry: Ooh, that clojars latest-release trick in the lein-droid readme is nice.

17:58 benedikt: bitemyapp: nice. is this what replaced noir?

17:58 bitemyapp: coventry: you really don't look at any of my libraries do you? https://github.com/bitemyapp/revise/

17:58 benedikt: 'ish, the approach is different. It's pedagogical.

17:59 dnolen: in other news core.logic CLJS runs zebrao in ~8ms on my MBA 1.7ghz under V8, I suspect when the protocol indirection elimination via type inference lands we can probably shave off another 1-2ms.

17:59 benedikt: bitemyapp: sounds like a similar idea to bottle in the python world

17:59 coventry: bitemyapp: I looked at it before this. :-) https://github.com/bitemyapp/revise/commit/846e4737b737863fcbe0e99a21b8cf35daf30b6b

17:59 bitemyapp: Apage43: trolling Ptacek about his Golang use on Twitter.

17:59 coventry: how did you fail to notice the svg? :P

17:59 ohhhhh

18:00 coventry: it has error handling now.

18:00 dnolen: near order of magnitude perf improvement in a year and a half ain't bad :)

18:00 coventry: bitemyapp: It will definitely be on my radar when I need a database. :-)

18:00 Apage43: bitemyapp: oh boy

18:01 bitemyapp: coventry: if you need a different database, ping me.

18:02 [Neurotic]: Hey all - trying to work this out - Does clojure.edn/read look at data_readers.clj for tags? I can't seem to make it work (using the :readers opt is fine, but trying out both ways)

18:03 hiredman: [Neurotic]: data_reader.clj is read once when the clojure runtime is loaded

18:03 [Neurotic]: hiredman: I'm not currently running this in a REPL, so that doesn't seem to be the issue

18:03 Although... is that an implicit "yes edn/read does look at data_readers.clj" ?

18:04 hiredman: [Neurotic]: is it?

18:04 [Neurotic]: it doesn't look like it

18:05 ah, it does

18:05 it just grabs it in the java :(

18:06 [Neurotic]: Okay, so if it does, don't suppose someone would have an example of defining an EDN tag in it? I can't seem to make it work

18:07 hiredman: https://github.com/hiredman/bytes

18:07 [Neurotic]: I looked at that... but that's not an EDN tag, is it?

18:07 bitemyapp: Apage43: he is now intrigued by Haskell.

18:07 mission success.

18:07 Apage43: I watched it play out in real time

18:07 bitemyapp: Eggscellent.

18:07 Apage43: so you, too, are intrigued by Haskell.

18:07 The fire rises!

18:07 joshhead: I was just reading up on some Clojure history, following links from this post: http://clojure.com/blog/2012/02/17/clojure-governance.html

18:08 I see references to the first Clojure talk at LispNYC, but the links are broken. Allegedly there was an audio recording, does anybody know where to find it?

18:08 Apage43: you're keeping going huh

18:09 [Neurotic]: oh, I think it's me.. I think I worked out my issue

18:10 hiredman: [Neurotic]: actually the edn reader grabs the value of *default-data-readers* not *data-readers*, and data_readers.clj only sets *data-readers*

18:10 [Neurotic]: hiredman: aaah

18:11 hiredman: thanks for looking into that - that explains why it wasn't doing anything

18:11 bitemyapp: Apage43: hahaha, he actually RT'd that one.

18:11 I'm proud of that tweet.

18:14 [Neurotic]: hiredman: that makes sense against the docs for edn/read :readers - "When not supplied, only the default-data-readers will be used"

18:14 hiredman: thanks for your help

18:16 hiredman: I forget that new things have docstrings to read

18:18 [Neurotic]: Just so I'm clear then - data_readers.clj is really about changing the clojure reader - most likely for custom things like the base64 link above

18:20 emaphis: I just intalled clojure-mode and cider in emacs from marmalade. When I cider-jack-in, I get this error: "java.lang.IllegalAccessError: pp does not exist". Anybody have any idea what I screwed up? I can't find anything on google.

18:20 hiredman: it is sort of complicated, but yes, I think part of the genesis of the edn reader as a distinct thing was to provide a more explicit interface to reading things, since magic can happen with the clojure reader which could be bad if you are receiving random data from the internet

18:20 emaphis: do you have something in a user.clj or similar?

18:21 emaphis: my guess would be some code somwhere expects someone to already have done a (require '[clojure.pprint :as pp])

18:21 emaphis: hiredman: im a noob. where do I find user.clj?

18:21 hiredman: emaphis: well, then it is unlikely that you have one

18:21 amalloy: hiredman: no, that error message comes from (:require [foo :refer [pp]]), i'm pretty sure

18:21 not from trying to write foo/pp

18:22 [Neurotic]: hiredman: yeah, that makes a lot of sense. Don't want executing code in EDN ;) Cool. Thanks!

18:22 hiredman: Oh

18:22 ,(pp 1)

18:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: pp in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:22 amalloy: ,(require '[clojure.set :refer [pp]))

18:22 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

18:22 amalloy: ,(require '[clojure.set :refer [pp]])

18:22 clojurebot: #<IllegalAccessError java.lang.IllegalAccessError: pp does not exist>

18:22 hiredman: ,(refer 'clojure.core 'pp)

18:22 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: pp>

18:22 hiredman: yep

18:23 amalloy: so i'd guess a version mismatch in some library, like maybe clojure.edn exports a pp?

18:23 emaphis: so clojurebot has the same problem. :-)

18:23 hiredman: emaphis: some something is looking for a `pp` in a namespace where it doesn't exist

18:24 emaphis: Ok. I hunt for it. thanks. I'm not too worried, I have a working repl.

18:37 hiredman: when I connect to an already running "lein repl" I don't get the "PP" error. (just for reference).

18:44 akurilin: Has anybody here integrated results of lex/bison into a clojure app before?

18:44 dnolen: should make playing around with and looking at CLJS AST considerably more fun - http://github.com/clojure/clojurescript/commit/badffafde00a29f85e256906bd1ffb0c54a0786c

18:46 hiredman: Heh

18:46 yep

18:50 bitemyapp: akurilin: InstaParse doesn't suit your needs?

18:50 akurilin: https://github.com/Engelberg/instaparse

18:52 akurilin: bitemyapp, I'm not completely familiar with the tooling out there. I was thinking of lex/bison since I used them before and since I'm not really experienced in this domain, it'd make finding questions to my answers much easier

18:52 bitemyapp, if it's something really fancy, I'll have no idea what to do with myself.

18:52 bitemyapp: akurilin: Instaparse is really simple to use.

18:52 akurilin: stop being afraid of leverage. Check out Instaparse.

18:53 akurilin: you're using Clojure *for* the leverage, if you eschew all the benefits thereof you're missing the point.

18:53 akurilin: whole swaths of users started programming Haskell just so they could use Parsec, which is related to Instaparse.

18:54 akurilin: bitemyapp, do people find the historical tools so painful they'd rather go through that?

18:56 bitemyapp, anyhow, appreciate the referral, will check it out

18:57 bitemyapp: akurilin: you've never used lex or bison before I see.

18:57 akurilin: I've seen people lose their sanity with those tools.

18:58 akurilin: bitemyapp, I thought lex was ok, but it was for a toy language

18:58 bitemyapp, I guess I just don't know any better ;)

19:00 bitemyapp: akurilin: Instaparse is goddamn magical.

19:10 arohner: I like the CircleCI ads, one just showed up on comonad.com

19:10 arohner: bitemyapp: cool! thanks

19:11 bitemyapp: arohner: did you see my update to Brambling?

19:11 I don't recall if we discussed it or not.

19:11 technomancy: yeah some of those illustrations are classic

19:11 arohner: incremental migrations?

19:11 bitemyapp: arohner: yeah, 30 million datoms ~2.2 minutes on a crappy instance.

19:11 arohner: that's incremental, but not live, right?

19:11 bitemyapp: arohner: divide by 4-10x, then multiply by roughly the datoms your data model would turn into.

19:12 arohner: because you're still switching DBs?

19:12 bitemyapp: arohner: well, by live you probably mean differential migrations.

19:12 there's never-ever going to be a live migration faculty with Datomic that Datomic doesn't itself implement

19:12 arohner: by 'live' I mean 'no downtime'

19:12 bitemyapp: and they're only going to implement very simple use-cases, not whole database transformations like what brambling does.

19:12 differential migrations can do "catch-up" migrations to minimize swap time.

19:13 but the hand-over you'd be managing yourself.

19:13 if you're using core.async or a queue internally in your applications you can pause the queries long enough to flip over though.

19:14 arohner: if you're serious about using Datomic in production then it might be worth your time to spitball some of this with myself or the Datomic guys.

19:14 if not, then let me know and I'll stop bugging you.

19:14 I just knew you were one of the people that expressed an interest.

19:14 arohner: I am interested, but we don't have our eval key yet

19:14 and it'll probably be someone else on the team handling the migration to datomic

19:15 bitemyapp: arohner: are they on IRC? can they be?

19:15 I'd be happy to discuss it with them and offer advice/help/pointers if they'd like.

19:17 it's irritating the degree to which I end up imitating destructuring in Python. :as and all.

19:18 arohner: bitemyapp: they're not on IRC yet. I'll tell them to bug you when they're ready :-)

19:18 and when I know who's going to do it...

19:19 bitemyapp: arohner: sure sure. Cheers.

19:24 Apage43: anagram thing is more interesting sorted by length of word than by size of set

19:24 (->> "/usr/share/dict/words" slurp clojure.string/split-lines (group-by frequencies) vals (filter #(> (count %) 2)) (sort-by (comp count first)) (take-last 100) pprint)

19:25 ["importancy" "patronymic" "pyromantic"]

19:25 bitemyapp: important father-derived fire-crazies

19:25 devn: anyone here using caribou?

19:26 bitemyapp: devn: justin_smith is the resident expert dev/user.

19:26 Apage43: ["petrography" "pterography" "typographer"]

19:26 bitemyapp: devn: yogthos and I have admired their work from afar :)

19:26 devn: there is a reference to schmetterling which seems to imply that you need to clone the external repo

19:26 is that correct?

19:26 justin_smith: devn: schemetterling is a standalone app

19:26 devn: just checking :)

19:27 i got it working by cloning it and connecting to it

19:27 bitemyapp: justin_smith: ...does that work modulo locals clearing?

19:27 justin_smith: it isn't part of caribou - you can connect it to anything running under the jdk

19:27 devn: just thought maybe it was batteries included

19:27 bitemyapp: also how did I not hear about this earlier?!


19:28 this is really nice if it actually works

19:28 justin_smith: bitemyapp: yeah, as far as I know. The one problem really is that it gives you a repl in the context of the stack, and if you get an exception there the whole thing is toast

19:28 so run code in the contact of the exception stack judiciously

19:28 hopefully we will find a way to handle it gracefully in the app

19:29 bitemyapp: justin_smith: why isn't this an nrepl plugin?

19:29 justin_smith: we wanted something our non-expert devs could just connect to their process

19:29 with as little friction as possible

19:30 bitemyapp: but...nrepl is the standard protocol... ;_;

19:30 justin_smith: but maybe we could do that with an nrepl plugin

19:30 bitemyapp: please?

19:30 justin_smith: we are using standard jvm debugging sockets

19:30 bitemyapp: then emacs/vim/etc could use it.

19:31 technomancy: linky?

19:31 justin_smith: https://github.com/prismofeverything/schmetterling

19:31 devn: justin_smith: an overview of things/libs caribou works with would be nice

19:31 justin_smith: devn: yeah it would

19:31 devn: i mean even just in terms of "officially supported"

19:31 like schmetterling

19:31 clojurebot: Excuse me?

19:32 devn: because the project.clj contains things like caribou.foo

19:32 which doesn't expose them directly

19:32 dependencies and 3rd party lib integration i guess is what im saying

19:32 justin_smith: either way, nice job on caribou so far

19:32 justin_smith: bitemyapp: we were also aiming for total non-integration with editors, because there is a lot of diversity of editors used in our environment, easier to have something universal (the browser) than adapt to vim, emacs, sublime...

19:32 devn: thanks, I am just a bit player

19:32 devn: justin_smith: i especially liked that the default page was RESPONSIVE

19:33 bitemyapp: nrepl...is universal...

19:33 technomancy: I don't know how you'd initiate a connection with nrepl

19:33 bitemyapp: technomancy: idea being to tunnel the JDK stuff to nrepl

19:33 devn: M-x nrepl,, 44444

19:33 technomancy: but yeah, nrepl solves the whole diversity problem neatly

19:33 devn: where does the port number come from?

19:34 devn: in the startup sequence, and also in the config IIRC

19:34 ive barely used caribou at this point

19:34 justin_smith: I think it may just be our lack of knowledge / experience with the internals of nrepl that kept it from being used.

19:34 devn: i init'd an app, ran it, and connected nrepl to it through that port

19:34 justin_smith: in default caribou the port is set in boot.clj, but can be overridden in resources/config/<environment>.clj

19:35 technomancy: you'd want it to be accessible from your existing nrepl session

19:35 hiredman: well, the jvm exposes the debugging info over sockets, so you would need another layer translating it in to something like nrepl

19:35 which, well, meh

19:35 bitemyapp: does nobody care that the whole point of nrepl was to make it so every editor/environment could leverage the same tools?

19:35 hiredman: you might make something like an repl proxy, that proxies and nrepl and tunnels the debugging stuff over nrepl

19:35 justin_smith: schmetterling just uses a fork of the cdt lib to interact with the debug socket

19:35 hiredman: yeah

19:36 technomancy: bitemyapp: it seems like an obvious thing once you figure out the session issues

19:37 hiredman: justin_smith: it does look really neat

19:37 justin_smith: the other issue is a repl is a push ui - you type something in and it gets sent. Schmetterling was envisioned to both push and pull - it pops up your stack trace from the other process, then you can send commands from the context of a stack level

19:37 perhaps we could make that work with an nrepl though

19:37 hiredman: thanks, mostly prismofeverything's work, I just helped whiteboard it

19:37 technomancy: justin_smith: nrepl handlers can send unsolicited messages

19:38 justin_smith: so maybe we can embed this in a repl

19:38 technomancy: yeah, this needs to happen =)

19:38 justin_smith: we looked into using ritz and just got lost - either we were too dumb or it was too complex

19:38 bitemyapp: this is the debugger I've been waiting for, for awhile.

19:38 justin_smith: or some combo

19:38 technomancy: or alternatively someone needs to make ritz work for mortals

19:38 bitemyapp: justin_smith: I didn't like Ritz either, that's why I would really like this to be adapted for nrepl.

19:38 technomancy: not requiring two JVMs is great though

19:38 bitemyapp: I got Ritz to work, it's just not very helpful.

19:38 justin_smith: pull requests would gladly be considered :)

19:39 bitemyapp: it's not a PR to schemetterling

19:39 it's a separate project entirely

19:39 that schmetterling could turn into a wrapper for.

19:39 technomancy: yeah, extraction is needed

19:39 justin_smith: well in the core is that fork of cdt, that could be the common basis, but you would likely want to extend it

19:40 https://github.com/prismofeverything/cdt

19:40 akhudek: Given a map m, are the results of keys and vals guaranteed to be in the same order (such that each key corresponds to each val)?

19:40 bitemyapp: akhudek: maps aren't ordered unless they're a sorted map.

19:41 justin_smith: akhudek: the key/val relations are fixed

19:41 bitemyapp: that question is baffling.

19:41 justin_smith: do you mean does (zipmap (keys m) (vals m)) always = m ?

19:41 akhudek: justin_smith: exactly

19:41 technomancy: bitemyapp: no it's not

19:41 it's a common question that gets asked here all the time

19:42 bitemyapp: technomancy: I didn't parse out keys and vals are functions.

19:42 technomancy: ah, ok; sure

19:44 justin_smith: ,(into #{} (repeatedly 10000 #(let [m (zipmap (repeatedly 30 rand) (range))] (= m (zipmap (keys m) (vals m))))))

19:44 clojurebot: #{true}

19:44 justin_smith: empirically, it worked the first 10000 tries

19:44 technomancy: it's explicitly stated somewhere on clojure.org iirc, but it needs to be in the docstrings

19:44 akhudek: justin_smith: it does seem true, but I never like to make assumptions unless they are really guaranteed.

19:45 justin_smith: akhudek: that's smart

19:45 bitemyapp: akhudek: you must've used C in a past life.

19:45 akhudek: technomancy: I also wish the cost complexity various operations were easier to find in docs

19:45 justin_smith: bitemyapp: with that attitude you could hardly write a single C program that does anything interesting

19:45 akhudek: bitemyapp: is it that obvious?

19:46 bitemyapp: akhudek: I know the fear too. I used to hack in C.

19:46 justin_smith: I somehow made my way, but C taught me some real paranoid about what "truth" is, and what "is" means.

19:47 technomancy: "An experienced programmer is one who looks both ways before crossing a one way street"

19:47 Apage43: I'm hacking on some C++ *right now*. There is no meaning in this place.

19:47 bitemyapp: technomancy: I actually do that in Chinatown all the time.

19:47 technomancy: throw UnexpectedVehicleException

19:48 Apage43: Unexpected vehicle throws you!

19:48 bitemyapp: Today on TwitteR: People with syphilis get mad at me for making fun of their favorite language.

19:48 justin_smith: and in the hospital they attempt to set the breakpoints after the crash

19:48 it is much like debugging

19:49 that was a terrible pun

19:49 (dec justin_smith)

19:49 lazybot: You can't adjust your own karma.

19:50 technomancy: hehe

19:50 bitemyapp: (dec justin_smith)

19:50 lazybot: ⇒ 12

19:53 akhudek: technomancy: I can't actually find any mention of the order of keys and vals on clojure.org. :-( Pretty sure I read it somewhere too though. If I can find a source I'll add a comment about it on clojuredocs.

19:53 technomancy: akhudek: maybe it was on the dev.clojure.org wiki instead

19:54 or it could have been a mailing list. anyway, I'm 100% sure it's guaranteed.

19:54 akhudek: technomancy: ok, I'll just add a comment on it then

19:56 Apage43: (keys) returns a KeySeq, which is a wrapper around seq'ing the map that returns just the key portion of each item

19:56 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L133-L162

19:57 they're both in the order you get when you (seq) it

19:57 bitemyapp: so there's no order to the seq itself, but they're paired up evenly?

19:57 akhudek: Apage43: thanks

19:57 bitemyapp: that's right

19:57 bitemyapp: it appears that requires relying on an implementation detail, but it's good to know.

19:57 justin_smith: if you want to guarantee they match, there is always doing a reduce on the map and destructuring yourself

19:58 that way you only need to create the seq once too

19:58 Apage43: bitemyapp: as long as you aren't crazy and don't make a map type where (seq)'ing the same value twice gives you a different order

19:58 justin_smith: (or would keys and vals both use the same seq?)

19:58 bitemyapp: Apage43 leading the way on reading the code. Best way to learn. :)

19:58 Apage43: as go *intentionally* does

19:58 bitemyapp: Apage43: that's perverse :|

19:58 Apage43: yeah, go randomizes order of iteration over maps

19:59 devn: justin_smith: i stepped away, but in any event: caribou is definitely a nice contribution, and something of a middle ground between pedestal and "roll your own".

19:59 thanks for your work

19:59 i'll be giving it a more in-depth try over the next week or so.

19:59 justin_smith: devn: np, I will pass that along, thanks

20:00 pedastal looks cool, I mean to try it. But we need something where the frontend is not clojure, because we don't hire frontend for clojure skill, we hire them because they can make a designer's psd happen as a responsive page

20:01 devn: depends on what you mean by designer

20:01 but if by designer you mean front end developer with design skills, then i agree

20:01 justin_smith: people who use photoshop to make a pretty picture of a web page

20:01 devn: oh, im sorry, i misread

20:01 yeah i think we agree

20:02 that was always a goal of Clojurescript One, too

20:02 to make it easy for designers and people who were primarily front end devs to collaborate

20:03 justin_smith: well what I meant is that the frontend devs know js / css / html - we don't want to make them use a clojure oriented stack, and pedastal seemed to be pushing that way (maybe I am wrong?)

20:04 though some of them have been trying clojurescript and enjoying it for the occasional project

20:05 devn: i have more coworkers who are currently using clojurescript than clojure

20:05 i know the state of clojure survey begs to differ

20:05 justin_smith: interesting

20:05 devn: but i think they're just not as connected to the community at the moment

20:05 justin_smith: I know if I had to do frontend, I would totally do it in clojurescript if I could

20:05 devn: so maybe they aren't being heard as loudly

20:06 on all of the JS projects i've worked on recently we had lots of things in play to basically simulate clojurescript

20:06 like using google closure to get require and provide, etc.

20:06 justin_smith: more than just underscore style fp features?

20:06 devn: strong desire to use a functional style, desire for namespaces, desire for namespaces

20:07 and desire for namespaces ;)

20:08 underscore is a gateway drug to FP, and then they find clojurescript and say: "oh! this is even better!"

20:09 joshhead: I do frontend JS work, we don't use any clojurescript but boy I'd like to

20:09 devn: people with nice functional style using underscore were given recognition for writing nice code, so other people noticed and decided to try to do it as well

20:09 when they come to clojurescript they see group-by, map, reduce, etc. and they immediately get it

20:10 joshhead: I've got Fogus's Functional JavaScript, am hoping that it makes way for more functional style so that clojurescript seems like less of a leap

20:10 I actually showed some ClojureScript to a few coworkers, they said it looked more useful than CoffeeScript

20:11 devn: i've been surprised. people who have always had some aptitude for lisps, have written their own, etc. were more taken by what clojurescript provided than clojure as a core language

20:11 dnolen: joshhead: heh

20:11 devn: mainly because they see how practical it is, and it makes them feel like they're not in a completely foreign land/language

20:12 because they *know* javascript

20:12 so they don't feel completely novice in clojurescript

20:12 clojurescript is a good gateway drug

20:13 i think dnolen's posts have been inspiring a lot of people to check it out since it's so damn easy nowadays, too

20:14 gotta run, but keep on truckin' :)

21:01 bitemyapp: arrdem: I bought an Xbone: http://i.imgur.com/k4NWp0u.png

21:09 arrdem: bitemyapp: your timing in pinging me as I M-x erc remains spooky

21:11 bitemyapp: arrdem: that's better than being puffnfresh. I barely let the poor bastard sleep.

21:35 ambrosebs: gfredericks: it's an ordered intersection function type because a function is *all* of its arity types.

21:35 gfredericks: a (Fn [Number -> Number] [Boolean -> Boolean]) can be safely coersed to [Boolean -> Boolean]

21:35 gfredericks: but a (U [Number -> Number] [Boolean -> Boolean]) cannot.

21:44 fakedrake: hello

21:44 ambrosebs: TimMc, gfredericks: they are "ordered" intersections because (Fn [Long -> Long] [Number -> Number]) is different to (Fn [Number -> Number] [Long -> Long]). If you pass a Long, the former returns a Long and the latter a Number.

21:45 the intersection (I Number Boolean) is unordered currently FWIW.

21:48 fakedrake: i want to write a macro that will make a special case of defn, namely more than 3 or 4 of my functions will be able to be take their arguments and also no credentials for anon login, a login object or username + password eg (defn foo "maybe doc" ([a cr] code) ([a] (foo a (anon-login) ([a u p] foo a u p))))

21:48 that should be (login-defn foo "maybe doc" [a cr] code)

21:49 The problem is to me the docstring which may or may not be there

21:49 ambrosebs: fakedrake: have you considered keyword arguments?

21:50 fakedrake: ambrosebs: hmm, good idea

21:51 ambrosebs: fakedrake: once you start wrapping defn like that, you're stuck with extensibility. What if you want a 4th parameter?

21:51 fakedrake: but still i will have to define them every time

21:51 ambrosebs: i probably will

21:52 hmm

21:57 Ill just rewrite a couple of lines each time

21:59 amalloy: fakedrake: you can also do that as an actual functional wrapper. eg, (defn wrap-logins [f] (fn ([a cr] (f a cr)) ([a] (f a (anon))) ([a u p] (f a (login (u p))))), (def foo (wrap-login (fn [a cr] code)))

21:59 it avoids many of the problems of doing it as a macro

22:02 although i do sorta recommend standardizing on one kind of credentials that all functions take, rather than accepting this freeform "creds or user/pass or nothing"

22:03 and then you can just add one layer of abstraction somewhere, like one function that takes the freeform mess and converts it to what the rest of the system wants

22:06 fakedrake: amalloy: i did the keys thing

22:06 SegFaultAX: I like the way warden does it (which friend kinda tries to copy)

22:07 fakedrake: but now i want this map to be passed on to other functions, Is there a counterpart for `apply' only for dictionary -> keyword args ?

22:07 hiredman: welcome to a world of pain

22:07 fakedrake: instead of seq -> positional

22:07 hiredman: not to contribute anything useful

22:09 fakedrake: how does this look: (apply fn-with-rc-key-arg "ha" (flatten (seq {:rc 1})))

22:09 ?

22:10 bitemyapp: flatten lol, prepare for shitstorm.

22:10 fakedrake: :( flatten was my favourite

22:10 :P

22:11 SegFaultAX: fakedrake: flatten is very often considered a code smell or otherwise a hint that something has gone wrong.

22:11 Not always, but often enough that it's worth pointing out.

22:11 fakedrake: aha

22:11 thnx

22:11 justin_smith: if one of your keyword args had a colleciton as a value

22:11 SegFaultAX: As in this case, it's pretty smelly.

22:11 justin_smith: which is not actually uncommon

22:11 flatten would fuck that up

22:11 SegFaultAX: Yup

22:13 fakedrake: thnx

22:13 is there an alaogue to elisp's `let*' ?

22:14 justin_smith: ,(mapcat identity {:a [0 1] :b 2})

22:14 clojurebot: (:a [0 1] :b 2)

22:14 justin_smith: an alternative

22:14 amalloy: fakedrake: let

22:14 justin_smith: preserves substructure

22:14 fakedrake: indeed i did not realize xD

22:24 lazy-cat looks awesome!

22:26 amalloy: fakedrake: it's unlikely you want lazy-cat - concat is a better "default", and the difference between them is fairly subtle

22:28 actually i don't think i've ever used lazy-cat? that surprises me a little now i think about it

22:28 fakedrake: amalloy: I get a lazy sequence of vectors from `map' and i want a defn to return a lazy sequence of the elements of the vectors

22:28 amalloy: fakedrake: (apply concat vs)

22:28 or, really, use mapcat instead of map

22:29 fakedrake: didnt know about that one

22:29 amalloy: ~flatten

22:29 fakedrake: amalloy: nice!

22:29 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

22:29 fakedrake: thnx!

22:29 amalloy: happens to mention this solution already, so it would have been a helpful reply to your earlier attempt to use flatten

22:30 fakedrake: amalloy: indeed

22:33 Raynes: amalloy: HEIL NOFLATTEN

23:10 bellkev: Hey folks, I'm working on a tool to enable the generation of AWS CloudFormation templates using a Clojure-based syntax kind of like leiningen's project.clj. I'm working on how the syntax should look to be most clojurey, and I wonder if anyone has some input: https://gist.github.com/bellkev/7653342

23:22 fakedrake: I am getting this strange error 'Exception in thread "main" java.lang.IllegalArgumentException: Parameter declaration uq. should be a vector' when running lein test, is it familiar to anyone?

23:22 http://pastebin.com/DHcqrkKv

23:22 here is the whole thing

23:23 coventry: fakedrake: You may be missing a parameter list in a defn.

23:23 Probably in reddit_crawler.core_test.

23:24 And there's probably "uq" wheer the parameter list should be.

23:25 fakedrake: coventry: i dont think i have a defun with uq as a parameter

23:25 let me double check

23:25 ah it was a typo

23:25 coventry: thanx!

23:26 coventry: np

23:40 gfredericks: ambrosebs: that is terribly interesting, thanks

23:41 ambrosebs: gfredericks: I think they're first described in www.ccs.neu.edu/racket/pubs/padl12-stff.pdf‎

23:41 4.1

23:41 Fn is case-> in Typed Racket

23:47 coventry: > Seems weird that there is no update fn corresponding to update-in as assoc corresponds to assoc-in. Am I missing something?

23:49 dnolen: core.logic 0.8.5 going out, old stateful defrel stuff is finally dead, good riddance https://github.com/clojure/core.logic

23:50 seancorfield: coventry: what would update do?

23:53 ambrosebs: dnolen: nice!

23:56 coventry: seancorfield: Hmm, I was thinking of something like (defn update [map f key] (assoc map key (f (map key)))), but actually that gets messy when you have multiple kv pairs and args you want to pass f. I guess I see why there's no such thing.

23:57 amalloy: coventry: right. does it take multiple k/v pairs, or does it take &args for the f function?

Logging service provided by n01se.net