#clojure log - Jul 04 2014

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

0:01 dbasch: to be fair the design of Go started 7 years ago, not that it makes a huge difference

0:02 nathan7: dbasch: Yeah, that doesn't change much in my eyes

0:02 serjeem: haskell is like 30 years old :V

0:02 nathan7: jesus, 30 already

0:03 tbaldridge: go is language that stresses CSP that's it's killer feature, all the rest of it is just to make the CSP usable.

0:03 serjeem: "The first version of Haskell ("Haskell 1.0") was defined in 1990" so almost

0:03 nathan7: Rust has CSP too though, so that changes very little for me too

0:03 however, Rust is very strongly focused on safety, especially concurrency safety

0:04 which I'd argue is the stuff that makes any concurrency feature useful

0:04 which directly covers "just to make CSP usable"

0:04 tbaldridge: yeah, but if you listen to Rob Pike, he just got done with a parallel language, and the CSP stuff was mostly addressing problems with that approach

0:05 nathan7: Go feels like what would happen if I built out one of my toy languages and started believing it was a serious project

0:05 platz: haskell was not haskell as you know it 30 years ago; it was pretty useless - monadic IO added more recently

0:05 serjeem: Is there a reason to prefer csp to an actor based model?

0:05 tbaldridge: Yeah, but if you think of Go as "Java with a C syntax minus the VM" it's actually fairly practical.

0:05 nathan7: serjeem: CSP is te more general model

0:05 serjeem: like, an actor is a loop and a channel

0:06 serjeem: given CSP, actors are two lines of code

0:06 tbaldridge: serjeem: my take: https://github.com/halgari/clojure-conj-2013-core.async-examples/blob/master/src/clojure_conj_talk/core.clj#L496

0:06 serjeem: actors complect processes with channels.

0:07 serjeem: sweet! thanks nathan7 and tbaldridge <3

0:07 tbaldridge: async OOP is my favorite way to make snarky comments about the actor model ;-)

0:08 serjeem: (tbaldridge: also thanks for the go macro videos, they were the most effective couple hours of my time learning clj)

0:08 platz: actors are pretty much toys absent the resiliency of the Erlang BEAM system

0:09 tbaldridge: my favorite quote from Alen Kay (father of OOP): "Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind."

0:09 nathan7: (defmacro actor [message-sym & body] `(let [ch# (chan)] (go-loop [~message-sym (<! ch#)] ~@body (recur (<! ch#))) ch#))

0:09 tbaldridge: Alan Kay

0:10 * tbaldridge begs forgiveness from the PL gods

0:10 nathan7: tbaldridge: the man who can take most modern programming concepts and go "well actually, I came up with that, and …"

0:11 platz: " Pop culture is all about identity and feeling like you're participating. It has nothing to do with cooperation, the past or the future — it's living in the present. I think the same is true of most people who write code for money." - Kay

0:11 nathan7: almost ended up working at a consultancy with him and various other legends on the board

0:11 was kind of bummed that my would-be employer wanted like a three-month termination period

0:12 pretty weird company anyway, their dev team is in South Africa, and they just wanted to hire me over here in Amsterdam

0:13 mainly run by one guy with *that* kind of maniacal cackle

1:00 Fare: I'm still not sure why I need all these subdirectories

1:14 where is the format of project.clj documented? do I need to put test and src in separate directories? What if I don't?

1:17 noidi: I think this is the most comprehensive documentation for it https://github.com/technomancy/leiningen/blob/master/sample.project.clj

1:17 Fare: noidi: I was reading that

1:18 noidi: one reason to keep src and test separate is that src gets packaged into a jar while test doesn't

1:18 there's no reason to ship your tests to the users of a library

1:21 Fare: how does lein know which files in the project to compile / load and in which order?

1:24 noidi: it tells Clojure to compile the main namespace, and Clojure checks the (:require ...) bits in its ns form to find its dependencies and compiles them as well

2:23 rurumate: sorry fell asleep

2:34 tjahan: hello, good book to start learning clojure?

2:41 ddellacosta_: tjahan: lots of folks recommend Clojure Programming as a good starting book: http://www.clojurebook.com/

2:42 tjahan: The Joy of Clojure is really great too, but a bit denser and move a bit more quickly, in my opinion: http://www.manning.com/fogus2/

2:44 tjahan: ddellacosta_, thank you

2:44 ddellacosta_: tjahan: np

3:09 _kardan: Forgive me if my tired brain is confusing me. I have a string which represents a Prismatic schema e.g. "UserType" but now I want to use that string in the validation e.i. do (s/validate UserType user). Any ideas?

3:10 nathan7: _kardan: have a map of { schema-name schema }?

3:13 _kardan: So I get events from a queue and then need to dispatch different validations based on "types". Maybe I just need to understand what you explained (brain need coffee..)

3:25 thanks nathan7 - as suspected I was confused :-)

3:26 nathan7: _kardan: 20 hours in and still bright out here, apparently [=

4:19 ckuttruff: evening all; was looking at the following thread regarding relative path references with leiningen: http://stackoverflow.com/a/15884225/1566623 . Does anyone happen to know if it's possible to get all files within a directory specified within the resource-paths option?

4:20 so if you specify ":resource-paths ["foo"]" and want all the files foo/*.txt ... is there a way to specify that using java io API?

4:56 mpenet: When packaged as a jar? I think there are only gory solutions to this (using JarFile for instance)

7:59 perplexa: heya

8:01 when i have a vector ["a","b","c","d"] and i have a string like "/%1/%2/%3/%4", how would i replace the variables in the string with the indexes found in vector? ie. /b/c/d/%4/

8:01 is there an easy solution or do i have to iterate over the string? ;x

8:03 borkdude: Does Scala have a clojurescript + core.async (in the javascript variant) equivalent?

8:09 Fare: perplexa, with apply?

8:10 adding an extra argument to be 1-based rather than 0?

8:10 silasdavis: I'm probably missing something simple but I'm trying to pull in: http://search.maven.org/#artifactdetails%7Corg.apache.storm%7Cstorm%7C0.9.2-incubating%7Cpom

8:10 with ... :profiles {:dev {:dependencies [[org.apache.storm/storm "0.9.2-incubating"]]}}

8:11 perplexa: Fare: wat

8:12 i don't want it to be 1-based btw

8:13 silasdavis: in my project.clj, but it can't find it in http://repo1.maven.org/maven2/

8:13 perplexa: but i think apply is the right way :)

8:13 silasdavis: is that a reliable mirror or am I missing something?

8:15 mpenet: perplexa: you could just use clojure.string/replace

8:15 perplexa: mpenet: but how would i make it look up the strings dynamically? :)

8:16 mpenet: ,(let [x ["a" "b" "c" "d"]] (clojure.string/replace "/%1/%2/%3/%4" #"%([0-9]+)" (fn [[_ idx]] (str (nth x (dec (Long/parseLong idx)))))))

8:16 clojurebot: "/a/b/c/d"

8:16 mpenet: not super nice but it does the job

8:16 perplexa: heh

8:16 (inc mpenet)

8:16 lazybot: ⇒ 3

8:16 perplexa: awesome

8:16 mpenet: :]

8:16 perplexa: also thanks for destroying my self-esteem ;p

8:16 Fare: not super nice? It's *very* nice

8:17 (inc mpenet)

8:17 lazybot: ⇒ 4

8:17 mpenet: you could do something with reduce and map-indexed

8:17 * Fare learned to use monads for writing a lexer

8:17 martinklepsch: when using timbre, does it log occuring exceptions without me needing to explicitly feed them to timbre?

8:18 perplexa: mpenet: yeah i was just looking into reduce

8:20 silasdavis: martinklepsch, no you'd need to catch them and log yourself

8:21 martinklepsch: silasdavis, if exceptions would occur within an nrepl-server I started would it be enough to wrap the nrepl/start-server in the catch statement?

8:23 silasdavis: martinklepsch, yeah if you want to catch everything you can just wrap the entry point, but beware errors that occur in child threads won't surface necessarily

8:28 martinklepsch: hm, I run many threads. maybe I'm overseeing: the more general problem is that I have a long running pmap job and sometimes it crashes inbetween. but since I started the process in the nrepl server (which I detached after starting) I wont see the exception

8:39 kungi: Hello!

8:56 silasdavis: martinklepsch, you may want to implement the parallelism yourself

8:57 and you can catch the errors

8:58 razum2um: how can i redefine function in other ns and use old version inside? (i.e like calling "super" inside with-redefs)

8:59 martinklepsch: silasdavis, hm I mainly used pmap because I didn't want into implement it myself

9:00 silasdavis: pmap just steps through a lazy sequence of map #(future (f %)) coll

9:00 often pmap isn't want you want... some people avoid on principle

9:01 Janiczek_: Can you somehow run Eastwood on ClojureScript?

9:01 mpenet: ~pmap

9:01 clojurebot: pmap is not what you want

9:01 mpenet: :)

9:01 hyPiRion: silasdavis: no, it doesn't even do that. It does it semi-chunked, but in a strange way

9:02 martinklepsch: ok so what do I want? I'm basically parsing 100s of big xml files and saving them into a DB (db is bottleneck I believe)

9:03 koreth_: Is there a built-in function to expand all non-namespaced symbols to include namespaces like the reader does? That is, to turn '(inc 1) into '(clojure.core/inc 1) using the current *ns* and other bindings?

9:03 dbasch: ~pmap

9:03 clojurebot: pmap is not what you want

9:04 martinklepsch: :D

9:04 hyPiRion: martinklepsch: I'm trying to find a library which is a bit more efficient. Give me a second.

9:06 silasdavis: martinklepsch, crude but potentially workable

9:06 ,(mapcat (comp (partial map deref) (partial map #(future (inc %)))) (partition 10 (range 100)))

9:06 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

9:06 silasdavis: ah

9:06 hyPiRion: martinklepsch: https://github.com/TheClimateCorporation/claypoole there

9:07 dbasch: if the db is the bottleneck, it probably won't help to launch hundreds of threads

9:07 silasdavis: anyway, your partition n is the batch size is the number of simultaneous function applications you think your system can handle at at a time

9:07 dbasch: you could have a queue with a small number of threads, deref the first one and then add to the queue

9:07 s/threads/futures

9:08 hyPiRion: So you can say (cp/pmap (+ 2 (cp/ncpus)) f input) and get it to work as you'd expect an eager version of pmap would work

9:09 aroemers: koreth_: syntax-quote not enough?

9:10 martinklepsch: I don't have a problem with pmaps lazinesss

9:10 koreth_: aroemers: The expression is in an EDN file, not in my source code.

9:12 martinklepsch: hyPiRion, except for the last point the stuff claypool does doesn't seem to be something I need

9:12 silasdavis: martinklepsch, so my suggestion will probably do what you want

9:12 martinklepsch: "We would like to be able to do an unordered pmap, so that we can start handling the first response as fast as possible."

9:12 silasdavis: replace inc with your parsing function, and stick a finger in the air to set the n in (partition n files)

9:14 martinklepsch: silasdavis, would you mind elaborating how this differs from pmap?

9:14 silasdavis: if your inputs are similarly costly it should give reasonably parallelism

9:14 martinklepsch: silasdavis, seems pretty similar to how I thought/assumed it would work

9:14 silasdavis: oh you can log your exceptions

9:14 martinklepsch: silasdavis, ah right!

9:14 silasdavis: it is pretty similar

9:15 actually you could do that already

9:16 mpenet: martinklepsch: you could use core async, a list of channels in a go block and you loop then call alt!! on the list

9:16 martinklepsch: mpenet, yeah wondered about that too but didn't really investigate it yet

9:16 mpenet: something similar to the example here https://github.com/mpenet/alia#async-using-clojurecoreasync

9:17 you'd get the first realized no matter the ordering

9:17 and so on

9:18 chans would be c.c.async/thread

9:29 benzap: was wondering, does (load-string) evaluate stuff within the current namespace?

9:30 or maybe I have a problem specific to the :as clause, I have a required namespace :as foo, and I can't access foo/bar from load-string

9:32 dbasch: benzap: what error do you get?

9:33 benzap: I have a (:require [foo.bar.state :as state]), and i'm calling (load-string "(state/get-device-id)") --> No such namespace: state, compiling:(null:1:1)

9:34 it works fine if I (use 'foo.bar.state)(get-device-id)

9:34 and then subsequent calls are fine

9:35 to (get-device-id)

9:36 dbasch: why are you using load-string?

9:37 benzap: i'm exposing my clojure environment to a remote web client

9:37 like a repl

9:37 dbasch: does it work without the load-string?

9:37 benzap: ya

9:38 dbasch: you can still use the fully qualified namespace, does that work?

9:39 benzap: if I use an actual repl on my code, and eval, the state/device-get-id works

9:39 *get-device-id

9:40 dbasch: I mean (load-string "(foo.bar.state/get-…

9:41 benzap: ya

11:34 zilti: Is there a way to "shut down" core.async? It seems to block leiningen plugins. Adding a shutdown hook which closes the channel unfortunately doesn't help.

12:21 tbaldridge: zilti: sometimes shutdown-agents can help with that

12:21 the function in clojure.core

12:58 Fare: what's a nice short prefix for all my lexer functions? I used lex- but that's ugly. m- was weakly suggested by my using monads. I was thinking "?" or "!" or "%" as a prefix.

12:59 or maybe some unicode character?

12:59 $ ?

12:59 bbloom: Fare: why not stick them in a lexer namespace and drop the prefix?

13:00 Fare: bbloom: (1) I'm not sure how to avoid with clojure core symbols, and (2) I still wanted to distinguish them somehow.

13:01 avoid clash

13:01 bbloom: Fare: in your ns form, put (:refer-clojure :exclude [whatever will clash])

13:01 then you can also put (:require [clojure.core as :clj]) or something like that, if you need to use them stilll you can use clj/whatever

13:02 Fare: do will clash

13:02 bbloom: on the consuming side of it, you can choose an alias (:require [mylib.lexer :as yourprefixofchoicehere])

13:02 Fare: argh. yes, the specials are annoying

13:06 * Fare settles for "%" as a prefix

13:06 bbloom: Fare: seems like not a great choice, given the fact that % is used for syntax in #(...) forms

13:06 Fare: oh

13:07 is % followed by non-numeric also used specially?

13:07 things like %do

13:07 bbloom: https://github.com/edn-format/edn#symbols

13:07 Fare: What about & ?

13:07 bbloom: % and & are both 100% valid symbols, but they are used specially by various core syntax

13:08 Fare: I mean as a prefix, not as standalone

13:08 bbloom: as far as i know, they are only used as complete, unqualified symbols, with the exception of &env and &form which are anaphoric in defmacro

13:08 Fare: bbloom, that page seems to imply that unicode characters are no good, but I've been using greek letters all over the place

13:09 bbloom: Fare: 1) that page defines edn, which is a subset of clojure syntax

13:09 Fare: ok

13:09 bbloom: 2) clojure is notoriously permissive in what it accepts

13:09 ,(symbol "including wildly invalid shit like spaces")

13:09 Fare: is it bad form to use greek letters as variable names?

13:09 clojurebot: including wildly invalid shit like spaces

13:10 bbloom: Fare: i haven't seen any greek letters in clojure code except when done at the display layer in emacs

13:11 ie fn -> a lambda, but fn gets stored in the file

13:11 Fare: my state variables are all named σ

13:11 and my type-parametric variables are named α and α

13:11 β

13:12 amalloy: Fare: if you don't intend anyone else to ever edit your code, feel free

13:12 Fare: amalloy, what's wrong with those variable names?

13:12 amalloy: but most people are not set up to type greek letters trivially, so they will just tell you to go to hell. i would change them all back to ascii symbols if the code were ever my responsibility

13:13 bbloom: agreed w/ amalloy

13:13 Fare: C-u C-\ t e x RET \ l a m b d a

13:13 clojurebot: No entiendo

13:14 bbloom: i even wish the usual suspects like + and * had ascii equivs... i really enjoy FullForm[...] in mathematica

13:14 amalloy: even as an emacs user that sounds like a pointless hassle. imagine how useless it sounds to anyone else

13:14 Fare: anyway renaming later is a trivial search-and-replace away

13:14 I'll keep it that way for now

13:14 amalloy: sure. do what you want in code nobody else has to use

13:15 Fare: I'm reminded of that japanese lisp where everything was in Kanji.

13:15 amalloy: and it reads fine, as long as you don't use the letter B next to your betas

13:16 Fare: anyway, it's not like they need to type the greek letters to use the code — exported functionality is all ascii

13:16 ddellacosta_: omg, Japanese lisp sounds terrible

13:17 Fare: which brings me back to prefix for my monadic functions and macros

13:17 I'm thinking "&" instead of "%" as the prefix

13:17 if only "&" alone is special, then I should be fine, isn't it?

13:17 bbloom: nothing will blow up

13:18 Fare: thanks

13:19 amalloy: &foo is sorta conventionally used for stuff introduced anaphorically, by some people anyway. it's not seen very often, because anaphora aren't that common

13:19 lazybot: java.lang.RuntimeException: Unable to resolve symbol: foo in this context

13:19 bbloom: nice. somebody else got bit by lazybot's overzealous metacharacter

13:19 amalloy: you could maybe use uh...$foo instead? or *foo, so everyone knows it's a function pointer

13:19 bbloom: happens to me all the time, for some reason

13:19 bbloom: & me to as you know ;-)

13:19 lazybot: java.lang.RuntimeException: Unable to resolve symbol: me in this context

13:20 Fare: I'm no big fan of anaphora — I removed them all from ASDF when I took it over.

13:20 amalloy: and it's hardly overzealous; clojurebot's the same way with comma, just nobody accidentally puts that one first

13:20 bbloom: , but i was taught a comma always comes before a, but

13:20 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: but in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:22 Fare: when lexing, is a symbol without namespace the proper data structure to intern identifiers to? Seems to me that it is.

13:25 bbloom: that's reasonable, assuming the identifiers you're parsing are a subset of symbols

13:25 it's worth noting that symbols are not interned, their contained strings are

13:25 keywords are however interned

13:25 if memory usage and equality speed were a concern

13:26 Fare: should I intern my identifiers as keywords?

13:27 bbloom: really depends on what you're doing

13:27 Fare: not sure yet

13:27 bbloom: just leaving them as strings are perfectly fine too

13:27 Fare: I'm at the lexing phase still

13:28 implementing a language by ultimately turning it into clojure forms, is I suppose what I'm doing

13:29 bbloom: in that case, if you expect a 1-to-1 relationship between source code identifiers and object code identifiers, symbols seems like a good choice

13:34 Fare: bbloom: probably, though some identifiers may have to be massaged, especially so to prevent clashes

13:34 I suppose that when it comes to compiling those forms, I'll have to do some namespace magic

13:37 (I love how purity of my monads make backtracking trivial)

13:51 sritchie: hey all - is anyone here using lein-cljsbuild with :optimizations :none in development mode?

13:51 I can’t figure out which files to include in my generated HTML to make this work

13:51 it’s easy with :whitespace optimizations, since only one file is generated

13:52 this example uses whitespace, for example...

13:52 https://github.com/magomimmo/modern-cljs/blob/master/project.clj

13:52 I just can’t find anyone using :none

13:53 bbloom: sritchie: you should only need to include the google closure base.js file & then your root output js file

13:53 the dev mode stuff in base.js will inject script tags for all the other files

13:53 sritchie: bbloom: interesting, I’ve got those two,

13:54 and I’m getting “paddleguru is not defined"

13:54 bbloom: do I need to make sure any specific routes are open so that the relative paths in base.js work?

13:55 bbloom: sritchie: check the network tab in your browser's inspector

13:55 404s or 503s or whatever should make it clear

13:55 Fare: what's the simplest way to concatenate two strings?

13:55 bbloom: ,(doc str)

13:55 clojurebot: "([] [x] [x & ys]); With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args."

13:55 Fare: duh. thanks!

13:55 bbloom: ,(str "like" "this")

13:55 clojurebot: "likethis"

13:56 Fare: Is there a simpler variant for #(do true) ?

13:56 sritchie: bbloom: none of ‘em

13:56 let me check the load order...

13:56 bbloom: (doc constantly)

13:56 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

13:56 sritchie: yeah, goog/base.js loads fine, then generated.js loads as well

13:58 bbloom: ,(#(do true) "this will fail b/c the #(...) generates a nullary function in this case")

13:58 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval93/fn--94>

13:58 bbloom: ,((constantly true) "but this will work" :just-fine)

13:58 clojurebot: true

13:58 sritchie: bbloom: the goog.addDependency calls execute with no problem, too

13:59 bbloom: sritchie: you're now beyond my help. i've struggled much w/ cljsbuild etc, ultimately i gave up and did some custom build kludgery in a custom ring handler

13:59 sritchie: frankly, the tooling for cljs is a complexity disaster

13:59 Fare: is there an escape sequence for (char 7) in clojure?

13:59 sritchie: thanks for the help… man, what a bummer

13:59 yeah

13:59 without this it’s 15 seconds to build

13:59 for every change

13:59 bbloom: Fare: https://github.com/edn-format/edn#characters

14:00 sritchie: finally trying to make this work, and fail time

14:00 arohner: sritchie: are your generated files in the resource path

14:00 sritchie: yeah

14:00 bbloom: ,\u0007

14:00 clojurebot: \

14:00 sritchie: arohner: I may not be exposing them

14:00 well, yeah, I am

14:00 arohner: they need to be in a path where ring/wrap-resource can find them

14:00 sritchie: since they load fine

14:00 no 404s

14:01 arohner: so what problem are you seeing?

14:01 bbloom: Fare: see also http://clojure.org/reader

14:01 sritchie: base.js and my generated.js load with no errors, but none of the cljs namespaces, my namespaces, or my dependencies’ namespaces are loaded

14:01 so I immediately get a “paddleguru is not defined"

14:01 when I try to load some cljs

14:01 arohner: the Om docs mention needing to use goog.require

14:02 <script type="text/javascript">goog.require("main.core");</script>

14:02 (I assume you're using om?)

14:02 sritchie: no, I’m not yet, anyway

14:03 goog.require(‘paddleguru.util’);

14:03 Error: Cannot write "https://local.paddleguru.com/cljs/dev/goog/string/string.js" after document load

14:03 bbloom: Fare: generally, the clojure.org docs are very good & especially clear for CL folks. worth reading through them in their entirety

14:04 sritchie: arohner: or when I try to require clojure.string;

14:04 Error: Cannot write "https://local.paddleguru.com/cljs/dev/goog/../paddleguru/util.js" after document load

14:04 technomancy: "very good"?

14:04 sritchie: arohner: does that work for you?

14:04 bbloom: technomancy: yes. i think they are excellent for their intended audience

14:04 technomancy: bbloom: hm; ok.

14:04 arohner: I'm using :whitespace, and I don't need the goog.require, for unknown reasons

14:05 technomancy: bbloom: they're shit for introductory material

14:05 bbloom: technomancy: when i was learning clojure, i found them to be by far the best bang for buck

14:05 sritchie: arohner: yeah, whitespace is just unbelievably slow

14:05 18 seconds per compile

14:05 arohner: yeah :-(

14:05 bbloom: technomancy: sure, but there's lots of other introductory material places. Fare knows common lisp quite well

14:05 technomancy: which seems to be the most common kind of audience likely to visit clojure.org

14:05 sritchie: coventry had this issue, looks like: http://clojure-log.n01se.net/date/2014-04-19.html

14:05 bbloom: technomancy: he should have no trouble getting lots of valuable info from the clojure.org docs

14:05 sritchie: arohner: so is everyone just suffering through this stuff?

14:06 bbloom: technomancy: i mean, noooooow. but when clojure was new? language geeks, lispers, etc

14:06 technomancy: bbloom: oh I see; didn't have the context

14:06 arohner: sritchie: IDK. I didn't realize :none was so much faster

14:06 I also use the cljs repl a lot

14:06 sritchie: yeah, less than a second

14:06 arohner: my bigger problems w/ CLJS compliation is the lack of tracking which files need to be recompiled

14:06 sritchie: yeah, I do too, but austin is really unreliable for me

14:07 and cemerick is profoundly uninterested in working on it anymore

14:07 arohner: that, and recompiling both :dev and :prod when I start in dev mode

14:07 sritchie: oh, that’s odd

14:07 that doesn’t happen for me

14:07 bbloom: sritchie: i found that https://github.com/tomjakubowski/weasel was much easier to get working

14:07 sritchie: “lein cljsbuild auto dev”, yeah?

14:08 oh shiz

14:08 nice

14:08 arohner: I have the cljsbuild :hook in my project.clj. I'm threatening to take it out because it slows down startup so much

14:08 sritchie: yeah, take it out for sure

14:08 bbloom: i really dislike cljsbuild

14:08 sritchie: arohner: I can show you what I do

14:08 (defn with-generated [& tasks] (apply vector "do" "cljx," "cljsbuild" "once" "dev," tasks))

14:09 I have that in my project.clj

14:09 arohner: nice

14:09 sritchie: then this: :aliases {"launch" ~(with-generated "repl”), "test" ~(with-generated "test")}

14:09 so “lein launch” generates everything, “lein repl” is clean

14:09 but “lein test” always goes the generation

14:10 arohner: I like it

14:11 sritchie: dnolen_ was making fun of me for using :whitespace instead of none,

14:11 but it seems that no one is actually using :none :)

14:12 since it’s such a pain in the ass

14:20 rkneufeld: Anyone remember what that recent clojure-test runner was that had really nice diffs?

14:20 I remember reading an article about it lately, but can't track it down.

14:22 Found it. It was "humane-test-output" from http://jakemccrary.com/blog/2014/06/22/comparing-clojure-testing-libraries-output/

14:24 Fare: does clojure have a function to map character names to name, without loading the Java ICU4J library?

14:39 can I have a case with multiple values?

14:39 amalloy: Fare: you mean like a function f such that (= (f \≇) "NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO")?

14:39 and if you mean the case macro: yes, read the docstring for case

14:41 dnolen_: arohner: if you have a reproducible case of that I would like to know, I haven't encountered that unless you're talking about cold start

14:41 bbloom: Fare: which you can get in your repl with the doc macro

14:41 dnolen_: sritchie: I never dev w/ anything but :none, everything else is way to slow for dev

14:42 sritchie: also the only compilation mode where source maps are truly accurate

14:42 sritchie: dnolen_: how do you include the generated files?

14:42 in your HTML?

14:42 sritchie: goog.require(‘paddleguru.util’);

14:42 [12:01pm] sritchie: Error: Cannot write "https://local.paddleguru.com/cljs/dev/goog/string/string.js" after document load

14:42 I get that error when I try to require anything;

14:42 and without requiring, of course, nothing’s available

14:42 dnolen_: sritchie: never seen that before

14:42 sritchie: that happens when I try to require any cljs namespace

14:43 dnolen_: sritchie: no idea, are you sure this isn't a server config issue?

14:43 sritchie: no, it very well could be -

14:43 Fare: amalloy: apparently I can crash the clojure 1.6.0 compiler with my case statement :-/

14:43 sritchie: I just haven’t found a single example config that uses :none. I’m guessing it’s some goof with the way I’m exposing static routes

14:43 dnolen_: sritchie: anyway I've gotten :none to work w/o and without webserver

14:44 sritchie: and in fact sunk a lot of time making sure it does work :)

14:45 Fare: if I include \1 in the list of octal characters in that case, it blows up with java.lang.NegativeArraySizeException, compiling:(/tmp/form-init6222044222718782545.clj:2:3)

14:45 at clojure.lang.Compiler.analyzeSeq (Compiler.java:6651)

14:45 sritchie: dnolen_: I believe it, and the sub second compile times make me want to get there too

14:45 I’ll play around with the routes

14:45 in the meantime, weasel is hugely helpful: https://github.com/tomjakubowski/weasel

14:45 dnolen_: sritchie: I'd be surprised if modern-cljs doesn't cover this

14:45 sritchie: it doesn't

14:45 they use whitespace

14:45 dnolen_: huh weird, someone should fix that

14:46 sritchie: yeah, everyone I could find in here is using whitespace as well -

14:46 * Fare hunts for a reduced test case

14:46 sritchie: I’ll push an example if I can figure out what’s goofed over here

14:46 dnolen_: sritchie: https://github.com/KitchenTableCoders/immutable-stack/blob/master/contacts/project.clj

14:47 sritchie: older deps but that should work even w/ newer deps

14:47 if it doesn't I'd like to know about it

14:47 sritchie: nice, looking for the html generation...

14:47 ah, I see index.html

14:47 dnolen_: sritchie: no html generation in this case, just static

14:47 shouldn't really matter though

14:48 sritchie: thanks for that link

14:51 TimMc: Fare: Compile errors are indistinguishable from compiler crashes. :-(

14:57 ToxicFrog: TimMc: yep :(

14:58 sritchie: bbloom: this is huge - thanks so much for pointing out weasel!

14:58 this is WAY more reliable.

14:58 bbloom: sritchie: awesome

14:58 (inc weasel)

14:58 lazybot: ⇒ 1

15:09 benzap: anyone know where I can find the implementation of the defn macro?

15:09 i'm trying to write a new macro that defines a function, but assigns it to some sortof handler

15:09 need some direction

15:10 Fare: down to one line: (defn err1 [c] (domonad sequence-m [_ (case c \U c (\0 \2 \3 \4 \5 \6 \7) c \1 c)] c))

15:18 expanded a bit: (defn err2 [c] (case* c 0 0 nil {55 [\7 c], 85 [\U c], 54 [\6 c], 48 [\0 c], 50 [\2 c], 51 [\3 c], 53 [\5 c], 52 [\4 c], 49 [\1 c]} :compact :hash-equiv nil))

15:21 where do I report such compiler failures?

15:21 benzap: macroexpand ?

15:21 avshalom: Hi All, I am looking for an "Everyman's List of What's new in Clojure 1.6"

15:22 nkoza: benzap: (source defn)

15:24 benzap: well damn, it's not implemented as a macro

15:25 Bronsa: benzap: it is

15:26 benzap: it doesn't use defmacro because it's definied later in the bootstrap process

15:26 benzap: So the way it's implementing itself resembles that of a macro

15:27 Bronsa: benzap: it's manually marked as a macro a couple of lines after its definition

15:27 (. (var defn) setMacro)

15:27 or something like that

15:28 benzap: it's implementing itself in a rather strange way

15:28 keeps redefining the local variables in a let, i've never seen that before

15:28 dnolen_: avshalom: https://github.com/clojure/clojure/blob/master/changes.md

15:30 Bronsa: Fare: it looks like this problem is caused when the gensym'd symbol is not type hinted as Object

15:30 Fare: so probably algo.monads loses some metadata

15:30 Fare: Bronsa: I didn't understand your explanation :-(

15:31 bbloom: Bronsa: why would you hint something as Object?

15:31 Bronsa: bbloom: clojure.core/case does, and apparently for a reason

15:31 I was never able to understand why

15:31 bbloom: Bronsa: weird

15:31 clojure.core/case is crazy

15:32 Bronsa: well maybe now I'll get it.

15:32 Fare: e.g. try your last expression but with (case* ^Object c

15:34 avshalom: dnolen_: i was blushing after asking the question and seeing that link. Thanks.

15:34 dnolen_: avshalom: np

15:34 Fare: Bronsa, doesn't help me

15:35 what makes it magically compile is removing the \1 case

15:35 or the clojure.tools.macro/with-symbol-macros macro

15:36 or any of the numeric cases

15:36 Bronsa: Fare: bbloom uhm disregard all I've said wrt ^Object, I misread my repl output

15:37 Fare: if I remove one of the numeric cases, it works

15:37 bbloom: Bronsa: already done. that seemed too crazy for me to bother comprehending

15:37 Fare: reduced case so far: (fn [c] (clojure.tools.macro/with-symbol-macros (case c \U c (\0 \1 \2 \3 \4 \5 \6 \7) c) c))

15:38 what does that with-symbol-macros do?

15:38 Bronsa: bbloom: what I can't explain is that on my repl that case expression works, but if type in the macroexpansion it stops working

15:38 & the only difference seems to be the ^Object hinting

15:38 lazybot: java.lang.RuntimeException: Unable to resolve symbol: the in this context

15:39 bbloom: Bronsa: yeah, that sounds like a metadata or subtle type issue

15:39 Bronsa: what does print-dup show?

15:39 or *print-meta*

15:39 Fare: should I send a message to the mailing-list?

15:40 bbloom: Fare: in the meantime, use `condp =` instead of case

15:40 Fare: bbloom: thanks

15:40 bbloom: Fare: case is just an optimization for table dispatch, condp = will do the same thing as linear ordered choice

15:40 Bronsa: ah

15:40 wait

15:41 I think I got it

15:47 Fare: Bronsa, yes?

15:47 I was ready to click the send button for my bug report...

15:48 Bronsa: Fare: I'm trying to prove my guess

15:48 Fare: ok

15:48 I will refrain from sending...

15:48 Bronsa: Fare: no, no go ahead, it's still probably a bug

15:54 Fare: bbloom got it

15:54 bbloom: Bronsa: i got what?

15:54 Bronsa: no, I got it

15:55 bbloom: Bronsa: whoa whoa, you can't take this away from me!

15:55 (what is is? :-P)

15:55 Bronsa: the issue is that the emitted map {48 [\0 'c] ..}

15:55 is a sorted map

15:55 bbloom: fucking sorted maps.

15:55 Bronsa: when you read that back, it's a normal unsorted map

15:55 bbloom: grumble grumble. the default printing behavior for sorted maps is atrociously broken

15:55 Bronsa: bbloom: I never liked that sorted maps prints as normal maps

15:55 bbloom: it's terrible

15:55 Bronsa: yeah

15:57 bbloom: so why is the printed representation an issue here?

15:57 is fare explicitly calling macroexpand or something?

15:57 the jvm clojure macro system has cross-stage persistence of objects that don't have printable forms

15:58 scheme on the other hand only requires that forms with external representations be persistable across stages

15:58 Bronsa: bbloom: except it doesn't really work for sorted maps

15:59 bbloom: http://sprunge.us/IHHh

15:59 bbloom: hmm i wonder why

15:59 maybe a bogus map? test in there somewhere?

15:59 Bronsa: I already opened a bug for that months ago

15:59 bbloom: ,(defmacro m [] (Object.))

15:59 clojurebot: #'sandbox/m

15:59 bbloom: ,(class (m))

15:59 clojurebot: #<CompilerException java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: java.lang.Object@14aeb29, compiling:(NO_SOURCE_PATH:0:0)>

15:59 bbloom: ah no

15:59 now i remember

16:00 you need to define print-dup for your form to get cross stage persistence when compiling

16:00 ,(macroexpand '(m))

16:00 clojurebot: #<Object java.lang.Object@e64543>

16:00 bbloom: see?

16:01 Bronsa: bbloom: http://dev.clojure.org/jira/browse/CLJ-1093

16:01 I haven't found any good fix for this

16:01 there are a couple of proposed patches but they're more workarounds than fixes

16:02 bbloom: lots of gross broken edge cases where clojure's syntax and its bolted on type system collide :-/

16:02 Bronsa: yeah

16:02 what's worse is that it's not only going to break sorted maps

16:02 bbloom: the original :type metadata idea was cute, but it became pretty obvious that type tags were useful for creating separate equality classes

16:03 Bronsa: every deftype that's also an IPersistentMap will be transformed in a PAM/PHM in this case

16:03 to*

16:04 uhm no, that's not true

16:04 synkte: Is let lazy?

16:04 i.e. local variables only created when the expression is evaluated?

16:04 Bronsa: luckly all deftypes get emitted using their /create static method so there's not that issue

16:05 bbloom: synkte: no, the only thing that is lazy are seqs

16:06 synkte: and the traditional control operators, like if

16:06 Bronsa: but aren't empty seqs special cased?

16:06 Bronsa: since the interned value can be used

16:06 clojurebot: Titim gan éirí ort.

16:06 bbloom: some of the create methods work on empty and some fail

16:06 (i discovered while working on eclj)

16:06 Bronsa: yep

16:07 print-dup is broken on IPersistenCollections

16:07 synkte: bbloom: Interesting, I'm trying to test a sql insert method using let binding the create, and then searching for the entry in the database with a query binding in the same let statement, and the query is returning nothing

16:07 Bronsa: it assumes all IPersistentCollections have a /create method

16:07 which is not true

16:07 synkte: so I can compare that it actually inserted

16:07 bbloom: synkte: there are infinite things that could be wrong w/ that. can't help w/o seeing code

16:09 synkte: bbloom: http://pastebin.com/YMrUP723

16:09 The create and find functions work

16:09 tested already

16:11 bbloom: synkte: what type of objects do they return?

16:11 synkte: bbloom: Both are lazyseq

16:12 bbloom: synkte: *shrug* you didn't provide enough code to actually debug. i suggest you create a minimal self-contained reproduction, and i'm sure you'll find the issue along the way

16:16 synkte: bbloom: Ah, id is being set to nil

16:16 bbloom: I'm an idiot haha

16:16 bbloom: Thanks :)

16:18 noncom: i have been examining DotLisp, the previous creation of Rich Hickey. the bootstraping file, which defines the most part of the language is full of macros definitions, not function definitions

16:18 i have read that it is better to avoid macros if not completely necessary

16:18 so the question is: why is it 100% made of macros ?

16:18 Fare: ok, how do I debug a stack overflow?

16:18 amalloy: the language core usually has a lot of unusual work to do

16:18 noncom: is this because speed concerns? do macros save a funcall ?

16:19 amalloy: Fare: look at the stacktrace, gist the stacktrace, ...

16:19 noncom: Fare: it depends.. but you can show us..

16:19 Fare: I must be recursing without a proper stop condition... but where?

16:19 noncom: show us stack trace :)

16:19 Fare: it just tells me StackOverflowError clojure.lang.PersistentArrayMap.assoc (PersistentArrayMap.java:189)

16:20 noncom: and the code ?

16:20 Fare: it's hundreds of lines

16:20 noncom: :(

16:20 Fare: that depend on other libraries

16:20 amalloy: Fare: the built-in repl hides stacktraces from you for some misguided reason

16:20 are you using cider, or what?

16:20 Fare: cider

16:20 amalloy: you can (.printStackTrace *e)

16:20 dbasch: Fare: (pst *e)

16:21 amalloy: dbasch: clojure.repl isn't auto-referred in cider afaik.

16:21 dbasch: amalloy: true, I have it in my user.clj

16:21 noncom: amalloy: so, yes, the core has to do strange stuff, but why macros, why not functions ? the only reason i can think of is that macros save a funcall and some resolutions..

16:22 *in runtime

16:22 amalloy: because it's building the whole dang language. you use macros to introduce new linguistic constructs; probably a lot of those end up needing to be macros in dotlisp, i dunno

16:22 Fare: I don't get to the print stack trace... the stack overflows.

16:22 amalloy: Fare: yes, and after it does that, in your repl *e is bound to the exception

16:22 so you can write (.printStackTrace *e)

16:22 dbasch: Fare: refheap?

16:23 noncom: amalloy: i see..

16:23 Fare: it prints nil

16:23 noncom: i use counterclockwise for eclipse, it always shows the trace, idk for other tools.. but there must be some unversal way

16:23 dbasch: Fare: how about (clojure.repl/pst *e)

16:24 Fare: works better, thanks!

16:25 noncom: so macros are used to represent linguistical constructs, but how would you say what functions are for?

16:25 i am just interesrted in theory behind that

16:25 and implications

16:26 gfredericks: functions are for computations?

16:26 bbloom: noncom: if you're interested in theory, start here: https://en.wikipedia.org/wiki/Evaluation_strategy

16:28 noncom: i just never before really thought about what is their nominal difference beside that one of them executes at startup and the other one in runtime..

16:28 thanks for the link! looks like a cool explanations for the general thing!

16:28 dbasch: noncom: suppose you want something like (do-not-evaluate (/ 1 0))

16:28 noncom: could do-not-evaluate be a function?

16:28 noncom: aha, macros will prevent immediate evaluation..

16:29 it could be a fund only if i quote the arg.. but that is rarely good, so macros do not eval args..

16:29 evaluation strategy! :)

16:34 Fare: just because it compiles doesn't make case work... falling back to condp

16:35 yup, there was more brokenness in case. Sigh.

16:41 sent a bug report to the clojure@ mailing list

16:41 oh, it's moderated (thus far)

16:53 ivan: is there a Clojure code reformatter (that handles all the edge cases like https://github.com/odyssomay/sublime-lispindent/issues/7 ) that I could integrate into Sublime Text?

16:57 perhaps over the network; doesn't have to be in Python

16:59 amalloy: ivan: for just indentation, you can fire up emacs in batch mode and ask it to indent for you. if you want something to also decide when to indent newlines that's impossible because it's a matter of taste and style

16:59 ivan: amalloy: thanks. I'll take a look at what Emacs' formatter does

17:10 sritchie: does anyone here have any good tooling on managing trees of utility dependencies in JVM land?

17:10 thinking of this -

17:10 if I split out schemas and utils into their own libraries, if I want to add to util, I need to

17:10 add the code, bump util’s version, release util, bump my main project’s version of util, run tests, bump my project’s version

17:11 lein-voom starts to address this problem; curious to know if anyone’s used it to automate this process

17:47 dnolen_: hey, do you know of a react hosted behind https?

17:48 looks like https://fb.me/react-0.9.0.js redirects to non-https

17:48 causing chrome to block it

17:48 I can just download it, I guess

17:50 ah, here we go

17:50 https://cdnjs.cloudflare.com/ajax/libs/react/0.9.0/react.min.js

18:24 cbp: how do i get a stactrace from clojurescript?

18:25 stacktrace even

18:25 is there some sort of magical pst function somewhere?

18:26 Fare: you debug with clojure, then port to cljs?

18:26 cbp: you funny Fare

18:26 bbloom: actually, the cljs debugging story is pretty decent

18:27 turn off optimizations & turn on source maps

18:27 cbp: bbloom: theyre both on

18:27 bbloom: in your browser, turn on "break on unhandled exception"

18:27 in chrome you gotta click that stupid little icon for it on the script tab

18:28 irctc: Anybody know if there's a debian/Unbuntu with Leinigen 2.0 in? - So I can use my package manager to manage it?

18:30 cbp: bbloom: Is it "pause on exceptions" on the sources tab?

18:31 bbloom: yeah

18:31 cbp: well will you look at that

18:31 if I had known this 2 months ago

18:32 bbloom: further proof that browsers are just crappy IDEs and IDEs just crappy operating systems

18:37 annapawlicka: bbloom: that's one useful tip! i'm glad i read that

18:38 bbloom: amazing just how un-learnable most UIs are...

18:39 it's utterly brain dead that loading the dev console doesn't have any impact on the system menubar

18:39 at least when stuff is in the menu bar, you can scan through textual descriptions of the possible operations available to you

19:06 annapawlicka: yeah, you would think this is a given

19:46 Fare: what's the standard way of getting a string's length? (.length s) ?

19:53 Jaood: ,(count "foo")

19:53 clojurebot: 3

19:58 Jaood: Fare: ^^ - I guess that's the standard (using polymorphic functions)

20:21 gfredericks: does anybody make use of the version field of their project.clj for applications?

20:22 I can't think of a use for it

20:34 amalloy: gfredericks: so that when something goes wrong in production, the version number on the uberjar tells you what code is running

20:40 gfredericks: amalloy: I do that via a plugin & jenkins config; I can't imagine wanting to do it manually in the project.clj file.

20:41 I guess lein-release works by editing the file...hmm.

20:42 amalloy: *shrug* you asked if there's a use for it. maybe your way is better, but this way is useful

20:59 technomancy: gfredericks: lots of people use it for bug reporting

21:01 gfredericks: technomancy: I get the value of knowing the version of your application that's running; I just didn't think line 1 of the project.clj file was the easiest way to get that feature

21:02 compared to e.g. a lein plugin

21:04 technomancy: gfredericks: oh, like literally reading it out of the file?

21:05 yeah, not so much. lein 2.4.2 actually includes a pom.properties file during development time so you can check a single source that works in dev and production

21:05 gfredericks: no not literally reading it out of the properties file, but literally putting it there

21:06 e.g., my project.clj line one is (defproject woohoo "0.1.0-DUMMY-VERSION"

21:06 and I use a lein plugin that inserts my git sha into the uberjar name

21:07 technomancy: the sha is already in the uberjar, but maybe the filename is a more convenient place to read it from

21:08 gfredericks: sure

21:08 my point is that line 1 of project.clj does not change

21:10 technomancy: yeah, manually maintaining it for an application might not be worth the trouble

21:11 but you don't have to maintain it with lein-release; you just have to tell it whether you're doing a bugfix/minor/major bump

21:16 Fare: what's the correct way to parse a number in clojure?

21:17 particularly so floating point numbers

21:17 Bird|otherbox: Fare: as in numeric string -> int or float? why, it's the exact same method any Java programmer would call

21:18 (Integer/parseInt "42")

21:19 ivan: Fare: depends on if you want doubles or integers for integer strings

21:20 Fare: and for the neophyte Java programmer, that would be, what, NumberFormat.getInstance(Locale.POSIX).parse(string) ?

21:20 ivan: I suppose I want (a) doubles, and (b) bignums

21:20 Bird|otherbox: Fare: that's actually a direct call to Integer.parseInt

21:20 ivan: ,(Double/parseDouble "123.123123123123")

21:20 clojurebot: 123.123123123123

21:20 Fare: Bird|otherbox, I believe for my Integers, I want bignums.

21:21 ivan: Clojure BigInt or Java BigInteger?

21:22 Fare: probably Clojure

21:23 ivan: ,(require '[clojure.edn :as edn])

21:23 clojurebot: nil

21:23 ivan: ,(type (edn/read-string "123123123123123123123"))

21:23 clojurebot: clojure.lang.BigInt

21:23 ivan: ,(type (edn/read-string "0.012312312412434"))

21:23 clojurebot: java.lang.Double

21:24 ivan: of course, that can read a bunch of other things as well, so you might want a regexp check as in http://stackoverflow.com/questions/2640169/whats-the-easiest-way-to-parse-numbers-in-clojure

21:38 blur3d: Hey guys, are there any good resources on javascript/nodejs and clojurescript interop? I’ve been finding it hard to get the interop working.

21:46 blaenk: hey, I'm kind of confused about aleph and http-kit, specifically, where they fit. my understanding is that aleph would replace ring, but http-kit is a server. so theoretically one could run aleph on http-kit? is there a reason to?

21:52 yeah I guess I'm mainly looking for the difference between aleph and http-kit

22:00 blur3d: blaenk: I am no authority on it, but I tried using aleph and hated that is uses lamina

22:00 blaenk: thanks blur3d, why's that bad?

22:00 oh I see what it is

22:01 blur3d: Well for one, it made debugging really hard… the lamina outputs are not helpful

22:01 I’ve been using http-kit for simple web servers and also making use of websockets and found it to be great

22:02 I could be using it completely wrong, but lamina seems to be outdated by core.async (although core.async is very new and may not fit your needs)

22:04 blaenk: yeah I'm new to clojure but when I saw the page for lamina it reminded me of core.async, though I haven't learned it yet

22:04 blur3d: well, core.async has a very nice API

22:04 it’s not to hard to learn

22:05 and I’ve found it easy to debug and test

22:06 I was trying to use aleph for UDP - but take a look at https://github.com/ztellman/aleph/pull/96

22:06 a pull request that fixes an api inconsistancy with the rest of the code and the docs from Jun 4, 2013 - and not yet pulled

22:07 blaenk: woah

22:07 blur3d: so yeah, I can’t recommend using it

22:09 I haven’t had to scale things using httpkit, but this looks promising http://http-kit.org/600k-concurrent-connection-http-kit.html

22:15 egosum: is there a name for a function which accepts a list of functions, and returns a function which, when called, calls all the passed functions?

22:15 (with no arguments)

22:17 these would be side-effectual functions, clearly

22:18 gfredericks: and then returns nil?

22:18 egosum: sure

22:19 gfredericks: ,(doc pcalls)

22:19 clojurebot: "([& fns]); Executes the no-arg fns in parallel, returning a lazy sequence of their values"

22:19 gfredericks: hm

22:19 call it docalls

22:19 no wait

22:19 blur3d: ,(doc comp)

22:19 clojurebot: "([] [f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

22:20 gfredericks: docomp :)

22:20 dobind?

22:20 egosum: hah, i like docomp

22:20 blur3d: I’ve never used it, but I think it’s what you're after

22:20 egosum: i was thinking doall, but that clashes

22:20 gfredericks: blur3d: no comp is functional

22:21 egosum: blur3d: comp composes functions--passes the output of one to the other etc

22:21 returns the final value

22:22 blur3d: oh, you want them called separately

22:22 gfredericks: ,(defn docomp [fns] #(doseq [f fns] (f)))

22:22 clojurebot: #'sandbox/docomp

22:22 egosum: gfredericks: yeah that's the idea--this isn't for clojure, just looking for a name

22:22 figured y'all might have some ideas :)

22:23 gfredericks: ,(defmacro don't [& _])

22:24 clojurebot: #'sandbox/don't

22:25 gfredericks: ,(don't worry)

22:25 clojurebot: nil

22:30 blur3d: does anyone know any good resources for javascript clojurescript interop, I’m finding it hard to get my head around

22:31 gfredericks: (.foo bar) ;; bar.foo()

22:31 (.-foo bar) ;; bar.foo

22:32 blur3d: what about something like this http://pastebin.com/SMN3b8C6

22:34 sdegutis: egosum: lol

22:35 clever

22:35 bbloom: (js/SerializePort "/whatever" #js {:baudrate 57600})

22:36 actually, don't do the js/SerialPort bit, just do (def SerialPort (.-SerialPort (js/require "serialport")))

22:36 although i'm sure there's something much better for interop w/ the node module system

22:36 but as far as i know, node.js support for cljs is kinda experimental

22:38 blur3d: yeah, i’ve been getting horrible errors trying to use it

22:38 but some had bug reports of over a year ago

22:38 I was hoping to write a web-app using node-webkit and clojurescript that can communicate with arduinos (microcontrollers)

22:39 bbloom: there's no champion for cljs on node actively contributing that i know of

22:40 blur3d: I just found some chrome apis, which node-webit may support, so I might be able to do it all in js

22:40 Jaood: cljs hardly has a maintainer

22:40 blur3d: but I was hoping for TCP support

22:40 hmm, it’s all so much better then using javascript

22:41 bbloom: Jaood: i don't really think that's fair to david, he dedicates a lot of time to it

22:42 blur3d: clojurescript gets once a month releases, so it is making progress

22:43 using react and om is also really amazing

22:45 Jaood: bbloom: oh, didn't mean to take on him, his work on cljs is awesome, just meant that cljs could doesn't have many contributors and no one is working on it full time

22:46 bbloom: I wonder if Hicker lost interest on it?

22:46 Hickey

22:46 bbloom: Jaood: the thing is that the compiler itself is already quite solid, there is no need for a full time maintainer

22:46 the biggest shortcomings are in external tools

22:47 Jaood: bbloom: I see, is the interop quite solid too?

22:47 bbloom: Jaood: with javascript, yes

22:48 with node, no, not really

22:48 blur3d: what kind of tools would help?

22:48 bbloom: since there's really no good reason to interop with node.js as far as i can tell

22:48 blur3d: yeah, I haven’t had any javascript issues

22:48 Jaood: blur3d: I guess be tooling he means user experience

22:48 s/be/by/

22:48 bbloom: yes, ux

22:48 blur3d: I just needed to use sockets, and I was hoping not to have to use nodejs

22:49 bbloom: blur3d: surely java has sockets, right?

22:49 (i know it does)

22:49 blur3d: yeah, but I want to embed in node-webkit

22:49 Jaood: blur3d: yeah, why not use the jvm?

22:49 oh

22:50 blur3d: I have it working now using clojure as a server, but I was hoping to embed a mini server into node-wekbit

22:50 bbloom: ...why?

22:50 blur3d: and that would mean using nodejs… at least for TCP/WS

22:51 Basically, I have been working on make a visualisation library for Arduinos (microcontrollers), so people can easily see what they are doing in real-time - with current values and graphs, etc

22:52 I want to support Serial, TCP, UDP and WS communication (so you can be wireless)

22:52 and then show all the data using clojurescript

22:53 Fare: ok, my python lexer is complete in 458 lines of monadic clojure code.

22:53 blur3d: and since making people go to localhost:4567 sucks, I was hoping to embed it inside node-webkit

22:53 and have it portable for windows/linux/osx

22:53 Fare: (plus 166 for a line/column position library)

22:54 Jaood: blur3d: lighttable is a node-webkit app, maybe you can get some ideas from there

22:54 blur3d: yeah, I’ve been slowly reading its code - also the github atom editor

22:55 the problem is that browser serial/tcp/udp/ws support sucks, and I’ll likely need a mini proxy server that communicates between the arduino and the clojurescript app

23:00 Fare: and now, for monadic parsing!

23:02 Jaood: blur3d: I hate to say if you don't want to do it C maybe Go would be less of a headache there?

23:03 or racket

23:03 blur3d: Well, nodejs might work fine for it

23:03 I’m just not sure yet of the limitations of nodejs and node-webkit

23:03 technomancy: with a few tweaks racket can feel a bit like a lightweight clj

23:04 blur3d: could I package racket in a node-webkit app?

23:05 Jaood: blur3d: no, but it has a built-in http server and lets creates executables for your three platforms

23:05 *you

23:05 blur3d: I guess technically I could use a nodejs loaded to name anything run… but it just gets complex managing all the processes

23:05 ok, I’ll take a look

23:05 a nodejs loader’ to make’

23:09 Jaood: technomancy: true, seems like a nice replacement for clj where you don't need/want the baggage of the jvm

23:12 blur3d: are there any good racket books?

23:12 Jaood: blur3d: many

23:12 blur3d: Realm of Racket

23:13 blur3d: here is a preview of what I am trying to setup https://imgur.com/dBVDBon - basically a realtime dashboard for arduinos

23:13 ok, thanks

23:13 Fare: the clojure code is about half the size of the java code, but does more. It's also much slower :-/

23:15 Jaood: Fare: I guess that normal? :P

23:15 bbloom: Fare: how much slower?

23:15 Fare: what more is it doing?

23:17 blur3d: I have a quick question for people - how many languages would you say that you are reasonable fimiliar with (aka. able to write a minimal app)?

23:18 seancorfield: Probably a dozen, maybe two dozen... but I'm a bit of a language whore so I suspect I'm unusual...

23:18 Fare: bbloom: it's hard to time, since it's not hooked to the same things. I'll try to time it, eventually. It's lexing various additional things that the Java variant of that code I have was not processing, such as floating-point numbers.

23:18 On the other hand, my error messages suck beyond measure

23:18 blur3d: I’ve spent a fair amount of time learning more then I can count - and it can get hard to recall the right functions and such

23:19 bbloom: Fare: you mentioned your lexers were monadic? or just the parser?

23:20 blur3d: I’d say I am comfortable with using around a dozen, but am familiar with a lot more (excluding windows)

23:20 Fare: I didn't write the new parser yet, only the lexer. There is an existing codebase in Java that I want to bypass using clojure so I can experiment more easily.

23:20 the parser is next.

23:20 there I expect to be at least 3-5 times smaller than the java code.

23:22 bbloom: Fare: you mentioned backtracking earlier... what backtracking is happening in the lexer?

23:22 Fare: I'm following the official grammar quite closely, and not trying to optimize in terms of look-ahead

23:22 bbloom: what state does the lexer have in general? how is it encoded?

23:22 Fare: for instance, I try to parse a float, and if that fails I try to parse an integer

23:22 seancorfield: blur3d: yeah, I'm rusty with some of things I haven't used for several years... but I've done professional, production work in C, C++, Java, CFML, COBOL, FORTRAN, Groovy, Scala, Clojure, several assemblers... I used to do a lot of Prolog, some APL...

23:23 bbloom: what does the lexer produce? a lazy seq?

23:23 Fare: [in out indent-stack delimiter-stack]

23:23 bbloom: what are in and out?

23:23 Jaood: seancorfield: oh man, you are old school ;)

23:23 Fare: in is a sequence of [char line column], out is a sequence of [token-type data position-info]

23:23 indent-stack is a list of integers, delimiter-stack is a list of expected closing delimiters.

23:24 bbloom: Fare: what is the out sequence? a vector? and you're conj-ing on to it?

23:24 Jaood: seancorfield: do you still use Scala?

23:24 Fare: out is a list, that gets reversed in the end.

23:24 bbloom: Fare: arg.

23:24 don't do that

23:24 make it a vector

23:24 use conj instead of cons

23:24 Fare: I use conj on a list

23:24 bbloom: it won't need to be reversed at the end

23:24 vectors have fast append

23:24 Fare: reversing is O(n), conj'ing to a vec is O(n log n)

23:25 bbloom: Fare: try it, should be a 2 line change

23:25 conj-ing on to the tail is amortized O(1)

23:25 Fare: I don't see why pessimize the program... it's already pretty dismal, performance-wise

23:26 bbloom: there's a tail array in the root node

23:26 Fare: it's used only once, anyway

23:27 bbloom: you were complaning it's slow. i'd be willing to bet that's a reasonably good win :-)

23:27 Fare: I'm hoping to getting it released some time this year, but meh.

23:28 bbloom: what is slow is all the allocation and all the wrapping/unwrapping of the state along the monadic style.

23:28 also, the backtracking through exceptions.

23:28 bbloom: Fare: oh absolutely, that's by far the slowest

23:29 i'm confused why a lexer has backtracking though, heh

23:29 or a stack for that matter

23:29 seems more like a parser to me....

23:29 Fare: because it was simpler to write that way — the source code is much more modular

23:30 bbloom: ok

23:30 Fare: e.g. (def &exponent-float (&bind (&or &point-float (&intpart ())) &exponent))

23:30 that's pretty much straight out of the spec — except with left-to-right reordering so the longest is tried first.

23:31 hence the expensive backtracking

23:31 if/when I decide to optimize for speed, I could modify the monad so the backtracking doesn't rely on exceptions.

23:32 but really, having an implementation that closely follows the spec is great.

23:32 bbloom: for sure

23:33 Fare: unlike the java implementation I'm trying to replace, that is just butt ugly.

23:34 for now, I'm just experimenting, speed is not essential

23:36 (a lexer is just a parser that outputs a sequence of tokens)

23:39 bbloom: Fare: generally a lexer also implies a regular language

23:40 ie one that can be parsed with a finite state machine

23:40 rather than a pushdown machine

23:41 Fare: well, in python, you need an indentation stack and a delimiter stack to properly lex

23:41 so exit the finite state machine

23:42 also, I'm not sure how to parse those numeric literals without backtracking, it sounds awful to me.

23:42 seancorfield: Jaood: I no longer use Scala professionally... At work we switched from Scala to Clojure about three years ago...

23:42 bbloom: ah, the joys of parsing languages whose grammars are retroactively formalized from their primary C-based recursive descent parser

23:42 weee

23:42 Fare: 01234 -- looks octal? only if it's not followed by . or e

23:43 seancorfield: I don't think I have Scala installed anywhere now... possibly on my Windows tablet but not on my main work machine (Mac Desktop)

23:43 Fare: switching from Scala to Clojure? Why?

23:43 seancorfield: time to go watch TV etc... probably back on later...

23:44 Fare: I posted to the Clojure mailing list about it ages ago and it caught fire on HN (unfortunately!)

23:44 lots of reasons :)

23:45 Fare: https://groups.google.com/forum/#!topic/clojure/sY-QBsBo8KA ?

Logging service provided by n01se.net