#clojure log - May 24 2015

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

0:03 justin_smith: beat it at what?

0:03 performance? never

0:03 adoption? it would take an immense amount of work, mostly PR

0:03 developer productivity? they already win on that metric

0:05 crocket: justin_smith, haskell performance could be indistinguishable from C++ performance.

0:05 for most practical purposes.

0:06 justin_smith: that's not the same as haskell every outperforming c++

0:06 crocket: Will haskell GPU programming become simple?

0:06 justin_smith: *ever

0:06 crocket: Will haskell GPU programming become simple without losing performance?

0:07 epichero: crocket... if you want functional GPU programming try http://fsharp.org/use/gpu/

0:07 crocket: F#

0:08 epichero: yes, Alea GPU

0:08 crocket: If F# can do it, then other languages, too..

0:08 epichero: you could also probably use clojure clr

0:09 justin_smith: epichero: sure, but even for that, the first step is turning your code into matrix operations, and often that's the hard part, and it's language agnostic

0:09 crocket: justin_smith, It is going to require you to think in terms of matrix.

0:09 justin_smith: I mean if you are doing a media encoder / decoder / renderer / DSP yeah it'll be easy to use, because what you are doing is matrixes

0:09 crocket: If you know how to think in matrix, then it's not that difficult.

0:09 matrices

0:09 justin_smith: crocket: sure, but most of the stuff we do now, that is too slow, isn't matrix problems

0:10 crocket: justin_smith, Can you give me specific examples of slow things?

0:10 justin_smith: unless you are doing DSP, media work, etc.

0:10 leiningen startup time

0:10 clojure boot time

0:10 crocket: well...

0:10 justin_smith: good luck turning those into matrix operations

0:10 crocket: boot time is one-time cost.

0:10 epichero: having toolchain support is important for things like this but tbh i'm not invested in this topic

0:11 crocket: After starting up, it is fast...

0:12 justin_smith: crocket: OK, eval is slow

0:12 crocket: Doesn't clojure compile once and just use the bytecodes?

0:13 justin_smith: yes, but you can use the compiler at runtime, which we avoid, because it is slow

0:13 *compile

0:13 crocket: Why don't you compile it in advance?

0:14 justin_smith: crocket: we do, but if eval wasn't slow, we wouldn't need to. See fexprs (runtime macros). A feature clojure won't have for performance reasons, (maybe other reasons too)

0:14 crocket: I'm nost saying cuda is useless, but if you keep track of the things you wait for your computer to do, many of them simply are not reducable to matrix operations

0:15 the javascript engine in my browser, waiting for tools like leiningen to execute some task, these are the sorts of things I notice waiting on.

0:15 crocket: justin_smith, I was thinking about machine learning applications.

0:16 Why does your browser wait for leiningen?

0:17 Does ClojureScript launch leiningen on web browsers?

0:18 justin_smith: crocket: those are two examples of what is actually too slow on my computer

0:19 I don't use machine learning at the moment, if I was using it, I would look into cuda, yes

0:20 crocket: I really don't want to use C++...

0:20 C++ is complex

0:21 justin_smith: making clojure perform 1/10th as fast as c++ (usually the limit) is also quite complex

0:21 crocket: 1/10th is harsh.

0:21 justin_smith: performance requires work and expertise, if you are interested in high performance computing, it's a whole field, but it's not easy

0:21 crocket: I though it was close to 1/3rd.

0:21 justin_smith: 1/10th the speed of c++ is amazing

0:21 if js could get that fast they would be bragging

0:22 crocket: If most of your operations run on cuda, clojure wouldn't be 1/10th as fast as C++.

0:22 Because clojure isn't the bottleneck.

0:23 justin_smith: 1/10th is a fudge. idiomatic clojure at its best is about 1/10th the speed of java, in most cases to go faster than that it is easier to write a java class. java can approach 1/3 the speed of c++ or maybe slightly better for some problems

0:23 crocket: Most machine learning applications run on cuda.

0:23 justin_smith: crocket: clojure is a huge bottleneck

0:23 crocket: justin_smith, I think you can outsource performance-sensitive tasks to java or C++ from clojure.

0:24 vectorz-clj and clatrix do that.

0:24 justin_smith: crocket: as I mentioned, you end up using cuda as a sub-language or a domain specific language, at that point it hardly matters whether the host is c++, clojure, assembly, python - the operations available and their semantics don't change at all

0:24 crocket: yes, any language can shell out to something faster, but that isn't free.

0:25 crocket: justin_smith, In case of vectorz-clj, is it almost free.

0:25 justin_smith: I'm not saying you shouldn't try to do high performance clojure (I got an excellent book on the topic, I highly recommend it), but high performance clojure isn't easy, and often the easiest thing for the last mile is just write some java

0:25 crocket: wel

0:27 justin_smith: crocket: and vectorz-clj isn't free. To get the best performance you give up on immutability, which is likely clojure's single most important feature.

0:30 even more so with haskell's usage of cuda - you end up in a subdomain that lacks lazy evaluation, monadic control of side effects, and immutability, and has almost zero useful type system. It's effectivly C with a weird syntax at that point regardless of the language you think you are using. Which is a large part of why people using those facilities are just programming in C or C++.

0:47 crocket: justin_smith, You give up on immutability in tiny corner cases....

0:47 Which can still be manageable.

0:48 In most parts of your AI program, performance is not that important.

0:48 Extreme performance is needed in tiny areas.

0:49 Rather than giving up the productivity of clojure and haskell, you just use them.

3:56 dfletcher: hi file-seq is giving me the whole tree. similar func that gives just one dir level? or hum, filter this list I guess?

4:18 hum well that's rather unsatisfying http://pastebin.com/PvurL4Au .. works though I suppose.

4:34 crocket: It's important to distinguish parallelism from distribution. Distributed computing is a specialization of parallel computing where the processors don't reside in the same computer and where tasks are distributed to computers over a network. It'd be like Lady Gaga asking Beyoncé, "Please text this guy while I drink."

4:35 A quote from braveclojure.com

4:38 entity: I have coded this ery simple REPL , but for some reason, it won't let me redefine global bindings: http://pastie.org/10204590

4:39 and I can't figure out why not :(

4:39 crocket: Please text this guy while I drink.

4:40 entity: not helpful

4:42 I'm open to suggestions as to how to correctly implement a REPL into my app that imports a couple namespaces at startup

5:15 [mad]: hi

6:30 crocket: Are macros expanded after compilation?

6:32 jack0: Does anyone know how to setup leningen on windows?

6:36 crocket: jack0, It's leiningen.

6:46 amalloy: entity: you can't use def in namespace a to replace a var in namespace b

6:48 eg, try this in clojure's built-in repl, and you get the same result: (intern (create-ns 'test.foo) 'x 1) (refer 'test.foo) (def x 2)

7:10 crocket: (defn-

7:10 ,(defn- screw-you [] true)

7:10 clojurebot: #'sandbox/screw-you

7:10 crocket: ,(defn screw-you [] true)

7:10 clojurebot: #'sandbox/screw-you

7:10 crocket: ,(defn screw-you [] true)

7:10 clojurebot: #'sandbox/screw-you

7:16 Kneiva: ,(let [op (first '(+ 1 2)) rst (rest '(+ 1 2))] (apply op rst))

7:16 clojurebot: 2

7:16 Kneiva: What's happening here? ^

7:18 crocket: (+ 1 2) happened.

7:18 clojurebot: 3

7:18 crocket: Kneiva, Do not try to complicate.

7:18 It just means (+ 1 2)

7:18 ,(rest '(+ 1 2))

7:18 clojurebot: (1 2)

7:19 crocket: ,(doc apply)

7:19 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

7:19 Kneiva: But the result is 2 not 3...

7:23 crocket: Kneiva, I think you just found a bug.

7:23 A clojure bug

7:24 clojer: I have Midje running on autotest in an Emacs cider repl but after a source update it's still showing old test results. Any ideas?

7:25 crocket: Kneiva, The result was (apply '+ '(1 2))

7:26 wink: yeah

7:26 (type +) != (type (first '(+ 1 2))

7:26 the former is clojure.core$_PLUS_$

7:26 the latter is Symbol

7:26 crocket: Why does (apply '+ '(1 2)) return 2?

7:28 How do I get the value that '+ refers to?

7:30 wink: that's a good question

7:32 Kneiva: ,(resolve '+)

7:32 clojurebot: #'clojure.core/+

7:33 Kneiva: but applying something to '+ (or any symbol) seems a bit strange

7:33 wink: maybe quote helps?

7:34 you might find help when reading stuff about macros

7:34 but otherwise, no idea :)

7:37 Kneiva: ,(doc symbol)

7:37 clojurebot: "([name] [ns name]); Returns a Symbol with the given namespace and name."

7:37 crocket: ,(let [op (first (eval '(+ 1 2))) rst (rest '(+ 1 2))] (apply op rst))

7:37 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.lang.RT first "RT.java" 654]\n [clojure.core$first__4107 ...

7:37 crocket: ,(let [op (eval (first '(+ 1 2))) rst (rest '(+ 1 2))] (apply op rst))

7:37 clojurebot: 3

7:38 crocket: Kneiva, ^^

7:38 evaluate the symbol to the function

7:38 evaluate the symbol to get the function

7:39 OrbitalKitten: ,(let [op (first '(+ 1 2)) rst (rest '(+ 1 2))] (apply (resolve op) rst))

7:39 clojurebot: 3

7:39 OrbitalKitten: that doesn't explain how apply to a Symbol returns the second argument

7:39 Kneiva: Yeah, but that won't work since I'm doing 4clojure and it doesn't allow evaluate =)

7:40 crocket: ok

7:40 I think the behavior of apply is undefined when the first argument is a symbol.

7:41 Probably, apply just uses 'second' when it is passed a symbol in the first parameter.

7:41 ,(second [1 2])

7:41 clojurebot: 2

7:41 crocket: ,(apply '+ 2)

7:41 clojurebot: #error {\n :cause "Don't know how to create ISeq from: java.lang.Long"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: java.lang.Long"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.core$seq__4125 invoke "core.clj" 135]\n [clojure.core$app...

7:41 crocket: ,(apply '+ [2])

7:41 clojurebot: nil

7:41 crocket: ,(second [2])

7:41 clojurebot: nil

7:44 Kneiva: ok. maybe apply shouldn't accept symbols

7:45 OrbitalKitten: oh

7:46 so

7:46 Symbol implements IFn

7:47 and extends AFn which provides an invoke method

7:47 public Object invoke(Object obj, Object notFound) {

7:47 return RT.get(obj, this, notFound);

7:47 }

7:48 Hence returning the 'second' argument

7:48 Kneiva: ah

7:54 luxbock: ,('foo {'foo :bar})

7:54 clojurebot: :bar

7:54 luxbock: ,('foo {'bar :bar} :not-found)

7:54 clojurebot: :not-found

8:01 TMA: ,(apply '+ [{'+ 1} :nf])

8:01 clojurebot: 1

8:07 kaiyin: hi. could anyone help me with this? http://stackoverflow.com/questions/30418232/contextual-eval-in-clojure/30423110?noredirect=1#comment48931815_30423110

8:09 wink: Kneiva: you could try aliasing "add" to +

8:56 gfredericks: kaiyin: looking at your modification, I would guess the two are only equivalent when the values in your context map are literals

8:56 which they are in this example, since they're numbers

8:56 kaiyin: yeah.

8:57 gfredericks: ,(def literal-expr 42)

8:57 clojurebot: #'sandbox/literal-expr

8:58 gfredericks: ,(def other-expr '(* 2 3 7))

8:58 clojurebot: #'sandbox/other-expr

8:58 gfredericks: ,`(let [v1 `'~literal-expr, v2 `'~other-expr] ...)

8:58 clojurebot: (clojure.core/let [sandbox/v1 (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list sandbox/literal-expr))) sandbox/v2 (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list sandbox/other-expr)))] ...)

8:58 gfredericks: hah ew

8:59 ,`(let [v1 ~`'~literal-expr, v2 ~`'~other-expr] ...)

8:59 clojurebot: (clojure.core/let [sandbox/v1 (quote 42) sandbox/v2 (quote (* 2 3 7))] ...)

8:59 gfredericks: ,`(let [v1 ~`'~literal-expr, v2 ~`'~other-expr v3 ~`~literal-expr v4 ~`~other-expr] ...)

8:59 clojurebot: (clojure.core/let [sandbox/v1 (quote 42) sandbox/v2 (quote (* 2 3 7)) sandbox/v3 ...] ...)

8:59 gfredericks: well clojurebot is not helping

8:59 anyhow

8:59 kaiyin: is there still something you need help with?

9:00 kaiyin: gfredericks: nothing specific, I am just trying to get a better understanding of the quote/unquote business.

9:01 gfredericks: it's easy to play with at a repl without calling eval or using macros

9:01 kaiyin: gfredericks: I have added more examples to the question, could you have a look again? http://stackoverflow.com/questions/30418232/contextual-eval-in-clojure

9:06 gfredericks: kaiyin: so when you say "gets the job done" you mean that (pprint (contextual-eval '{a (* 2 3) b (inc 11)} '(+ a b))) returns 17?

9:06 or 18 rather

9:07 kaiyin: yeah, 18

9:07 gfredericks: I guess the key point here is that it's not obvious whether that's correct or not

9:07 depends on the requirements for the function

9:07 which depends either on what the book is aiming at or what you're interested in writing

9:08 it's totally plausible to have a function like this where you *don't* want the values in the map to be evaluated

9:08 in fact I would expect that to be a more plausible use case than the other way

9:08 which is probably why JoC has theirs the way it is

9:17 kaiyin: gfredericks: using `'v might actually cause serious trouble here, please see the SO question again (edited).

9:18 gfredericks: kaiyin: that's consistent with what I'm saying

9:18 kaiyin: the trouble is just the function being implemented one way and the user expecting the other

9:19 kaiyin: if you instead call it like: (pprint (contextual-eval {'a (inc 3) 'b (* 3 4)} '(+ a b)))

9:19 then it should work

9:24 kaiyin: ,(eval (clojure.core/let [a '(* 2 3) b '(inc 11)] (+ a b)))

9:25 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "C...

9:25 kaiyin: ,(eval (let [a '6 b '12] (+ a b)))

9:25 clojurebot: 18

9:26 kaiyin: strange. why isn't '(* 2 3) evaluated?

9:26 gfredericks: the '6 isn't evaluated either

9:27 putting a ' in front of something is exactly to prevent it from being evaluated

9:27 also note that your eval call in these examples is redundant

9:27 ,(let [a '(* 2 3) b '(inc 11)] (+ a b))

9:27 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [sandbox$eval73 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "C...

9:27 gfredericks: ,(let [a '6 b '12] (+ a b))

9:27 clojurebot: 18

9:28 kaiyin: ,(eval `(let [a '6 b '12] (+ a b)))

9:28 clojurebot: #error {\n :cause "Can't let qualified name: sandbox/a"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't let qualified name: sandbox/a, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.RuntimeException\n :message "Can't let qualified name: sandbox/a"\n :at [clojure.lang.U...

9:28 gfredericks: kaiyin: this might help http://www.infoq.com/presentations/macros-clojure-west-2013

9:29 kaiyin: cool.

9:32 gfredericks: kaiyin: also it looks like your repl prints things out using the "'" and "~" characters?

9:33 that's not how most repls work; I'm not sure if that ends up being more or less confusing though

9:33 might be worth comparing to a normal repl

9:36 kaiyin: ok, I am using a repl in cursive.

9:36 will try it in lein repl.

9:36 clojurebot: It's greek to me.

9:38 gfredericks: I would've guessed cursive :) it's colin being fancy I bet

9:39 kaiyin: gfredericks: I don't observe any difference in lein repl, though.

9:41 gfredericks: kaiyin: compare entering "''x" in each

9:41 my guess is your cursive repl prints "'x"

9:41 whereas:

9:41 , ''x

9:41 clojurebot: (quote x)

9:41 gfredericks: also try "~x"

9:41 or '~x rather

9:41 , '~x

9:42 clojurebot: (clojure.core/unquote x)

9:52 kaiyin: gfredericks: ah, that is rather pprint being fancy.

9:52 justin_smith: ,(clojure.pprint/pprint '~x)

9:52 clojurebot: #error {\n :cause "clojure.pprint"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.pprint"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.n...

9:53 justin_smith: (require 'clojure.pprint)

9:53 ,(require 'clojure.pprint)

9:53 clojurebot: nil

9:53 justin_smith: ,(clojure.pprint/pprint '~x)

9:53 clojurebot: ~x\n

9:53 justin_smith: yup, pprint

9:54 kaiyin: ,(eval '(clojure.core/let [a (quote 6) b (quote 12)] (+ a b)))

9:54 clojurebot: 18

9:55 kaiyin: ,(eval '(clojure.core/let [a (quote (* 2 3)) b (quote (inc 11))] (+ a b)))

9:55 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers add "Numbers.java" 128]}]\n :trace\n [[clojure.lang.Numbers add "Numbers.java" 128]\n [sandbox$eval123 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "...

9:55 kaiyin: now, the question is why the form 1 get evaled ok, but not form 2.

9:55 gfredericks: man I would not have guessed

9:56 justin_smith: ,(type '1)

9:56 gfredericks: ,(+ (quote 6) (quote 12))

9:56 clojurebot: 18

9:56 java.lang.Long

9:56 gfredericks: kaiyin: ^ that's why

9:56 justin_smith: ,(type '(inc 1))

9:56 clojurebot: clojure.lang.PersistentList

9:56 justin_smith: that's the issue

9:56 kaiyin: so '6 is implicitly coerced into a long?

9:57 justin_smith: '6 is a long, there is no coersion

9:57 gfredericks: sorta

9:57 it has to be evaluated first :)

9:57 it's read as a list, then eval'd to a long, then sometimes evaled again where it stays a long

9:58 there's a lot of confusion when trying to work these things out because the repl itself does an extra eval

9:58 justin_smith: rEpl

9:58 gfredericks: ,(clojure.pprint/pprint ''''x)

9:58 clojurebot: '''x\n

9:58 gfredericks: ^ note the transition from "''''x" to "'''x"

9:59 ,(clojure.pprint/pprint (eval ''''x))

9:59 clojurebot: ''x\n

9:59 gfredericks: ,(clojure.pprint/pprint (eval (eval ''''x)))

9:59 clojurebot: 'x\n

9:59 gfredericks: each evaluation loses a '

9:59 kaiyin: hm, i see.

9:59 gfredericks: but one of them gets lost right away because of the repl evaling implicitly

10:00 the other cause of confusion is that most literals, including numbers, eval to themselves

10:00 ,4

10:00 clojurebot: 4

10:00 gfredericks: ,(eval 4)

10:00 clojurebot: 4

10:00 gfredericks: ,(eval (eval 4))

10:00 clojurebot: 4

10:00 gfredericks: etc.

10:00 so you could be evaluating something more times than you thought and not notice

10:07 crocket: By measuring the time it takes to multiply two 100x100 matrices, core.matrix performs at the same level as vectorz-clj.

10:07 Did I measure the time wrong?

10:09 justin_smith: the reliable way to microbenchmark clojure performance is to use criterium

10:13 crocket: How do I make sure core.matrix is used if project.clj contains both core.matrix and vectorz-clj?

10:14 justin_smith: core.matrix is not an implementation, it's a protocol that a matrix library can implement

10:15 crocket: I was talking about :persistent-vector implementation.

10:15 The default implementation.

10:16 justin_smith: it should be tied to the type, thus the code that creates the matrix

10:25 crocket: Jesus

10:25 Holy Christ

10:26 vectorz-clj is as performant as clatrix when it comes to multiplication of two 100x100 matrices.

10:26 Almost same performance

10:26 indistinguishable

10:26 Yay

12:10 luxbock: crocket: there's also: http://neanderthal.uncomplicate.org/

12:10 http://neanderthal.uncomplicate.org/articles/benchmarks.html

12:39 gfredericks: good morning

12:57 justin_smith: good morning

13:45 mmeix: good evening from Austria

13:45 short question:

13:45 justin_smith: mmeix: it was afternoon in gfredericks' timezone when he said that

13:45 mmeix: ah ok -)

13:46 TimMc: g'mornin'

13:46 mmeix: so:

13:46 ,(apply min [1 2])

13:46 clojurebot: 1

13:46 mmeix: ok

13:46 how to guard again:

13:46 ,(apply min [])

13:46 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: core/min"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/min"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 399]\n [clojure.lang.AFn applyToHelper "AFn.java" 152]\n [clojure.lang....

13:47 mmeix: the vector might come in as empty

13:47 TimMc: mmeix: You could call empty? on the collection to check.

13:47 mmeix: ok, easy enough

13:47 thanks

13:48 justin_smith: ,(min-key identity [])

13:48 clojurebot: []

13:48 justin_smith: ,(apply min-key identity [])

13:48 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/min-key"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/min-key"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 412]\n [clojure.lang.AFn applyToHelper "AFn.java" 154]\n [cloju...

13:48 justin_smith: same issue, just checking

13:49 mmeix: would this be a use case for :pre ?

13:49 (and does :pre work as expected in clojurescript?)

13:57 gfredericks: justin_smith no it wasn't

14:01 kaiyin: in lein repl, using files that have been modified after repl started causes an error: CompilerException java.lang.Exception: namespace '...' not found

14:01 how do you solved this?

14:02 justin_smith: kaiyin: (require 'some.ns :reload)

14:07 and that error specifically happens if there was an error when you first loaded the namespace. The require mechanism thinks it's been fulfilled, but the code didn't get loaded.

14:08 augustl: is it possible to merge component system-maps?

14:09 justin_smith: augustl: the system using other components can merge their maps, that's easy to do

14:09 augustl: justin_smith: using clojure.core/merge?

14:10 justin_smith: well, all the maps come in as keys under one map

14:10 augustl: justin_smith: should I merge the raw map before calling system-map on them?

14:10 justin_smith: no, I'm saying one of the components can merge them before using them

14:11 merging them on that level would ruin one of the main points of using component

14:12 which is explicitly declaring access between dependencies. If you could merge the system maps, the dependency graph wouldn't make sense.

14:12 augustl: justin_smith: I'll re-read what you said after eating some food, my brain is running on low gear :)

14:22 TimMc: mmeix: Probably not, unless you just want an AssertionError instead of an ArityException.

14:23 mmeix: ok, so it's better to think through all cases and build branches into a function

14:24 (if I cannot guarantee, that a coll could come in empty)

14:24 thanks!

14:40 kaiyin: Isn't this a bug, allowing function name to be nil? https://github.com/joyofclojure/book-source/blob/959578a5514e8a2d1d2da7e7f8ed84c517f5c9cb/first-edition/src/joy/contracts.clj#L11

14:41 ,(fn nil [x] (inc x))

14:41 clojurebot: #error {\n :cause "Parameter declaration should be a vector"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Parameter declaration should be a vector, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.IllegalArgumentException\n :message "Parameter declaration should ...

14:41 kaiyin: ,(fn f [x] (inc x))

14:41 clojurebot: #object[sandbox$eval47$f__48 0x495d0dbf "sandbox$eval47$f__48@495d0dbf"]

14:55 jack0: how clojure.xml/parse work?

14:55 TimMc: kaiyan, that does seem odd even though you're no longer in the room.

15:06 justin_smith: ,(list* 'fn nil '[[](a b c)))

15:06 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

15:06 justin_smith: ,(list* 'fn nil '[[](a b c))

15:06 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

15:06 justin_smith: ,(list* 'fn nil '[[](a b c)])

15:06 clojurebot: (fn nil [] (a b c))

15:07 gfredericks: ,(eval (list* 'fn nil '[[](a b c)]))

15:07 clojurebot: #error {\n :cause "Parameter declaration should be a vector"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Parameter declaration should be a vector, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.IllegalArgumentException\n :message "Parameter declaration should ...

15:07 justin_smith: maybe it worked with some ancient clojure version?

15:18 gfredericks: yeah that was my first guess

16:37 augustl: justin_smith: hmm, food didn't help :) Do you have a concrete example?

16:48 amalloy: &(fn nil [] 1)

16:48 lazybot: java.lang.IllegalArgumentException: Parameter declaration should be a vector

16:50 amalloy: maybe it never worked, but they didn't test it that way. the only exampe in that gist supplies the optional name param

17:40 kaiyin: anyone here who is also good at R? http://stackoverflow.com/questions/30428610/compute-in-a-new-thread-and-refer-to-results-later-in-r

18:46 cfleming: gfredericks: I haven't read that whole thread, but am I correct in thinking that the fanciness wasn't mine in the end?

19:01 justin_smith: cfleming: it was pprint

19:01 cfleming: justin_smith: Ok, thanks.

19:32 justin_smith: augustl: so the normal thing is that you use system-using to declare which components access data from other components

19:32 augustl: you can merge the incoming components with (reduce merge (vals this)) in your start method

19:32 or (reduce merge (vals component)) to use the name usually provided in the examples

19:33 augustl: but there is a benefit to isolating the dependencies (including the fact that components might have duplicate resources like :channel or :server)

20:23 gfredericks: ~the fanciness |was not| cfleming's in the end

20:23 clojurebot: Alles klar

20:23 cfleming: gfredericks: I mean, I'm pretty fancy

20:25 gfredericks: But not as fancy as pprint, as it turns out

20:26 gfredericks: ~cfleming |has| a fanciness level strictly between println and pprint

20:26 clojurebot: 'Sea, mhuise.

20:26 cfleming: clojurebot gets wiser by the day

20:26 gfredericks: in particular his fanciness is normalled called "cflprint"

20:27 normally*

20:27 which is pronounced "siffle-print"

20:28 cfleming: I like that.

20:29 gfredericks: the implementation of cflprint is left as an exercise for the reader

20:31 set theory notation doesn't have disj do they

20:31 they just have $X \setminus \{x\}$

20:36 so let's say my :user profile is

20:36 [{...} :foo]

20:36 should it be possible to use `with-profile -foo ...` to obtain just the {...} part?

21:02 justin_smith: gfredericks: are you using a weird pseudo syntax there?

21:05 Seylerius: I can't seem to actually load the clojure cheatsheet's link to the / function

21:06 gfredericks: justin_smith: latex?

21:06 justin_smith: or the profile stuff?

21:06 justin_smith: gfredericks: the :user profile

21:06 Seylerius: It's giving me a 404.

21:06 gfredericks: justin_smith: no, profiles can be vectors

21:07 justin_smith: a vector of maps and names of other profiles

21:07 justin_smith: doesn't look like any profile I have used, so I wondered

21:07 OK, cool, feature I've never used

21:07 gfredericks: justin_smith: I use it pretty heavily https://github.com/gfredericks/dotfiles/blob/master/.lein/profiles.clj.symlink

21:07 helps keep things organized

21:08 justin_smith: Seylerius: http://conj.io/store/v1/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/%2F/ conj.io (grimoire) version

21:09 gfredericks: cool, it uses a bunch of stuff I haven't tried, I'll need to try some of that

21:09 gfredericks: was thinking of making a lein alias for my coworkers that would launch figwheel and "less auto" automatically

21:18 Seylerius: What's the simplest way to turn [1 2 3 4 5 6 7 8 9] into [1 1 1 2 2 2 3 3 3]?

21:18 I feel like quot is close, but it'll just round to the nearest, when I need up.

21:19 justin_smith: ,(apply concat (map (partial repeat 3) [1 2 3 4 5 6 7 8]))

21:19 clojurebot: (1 1 1 2 2 ...)

21:19 justin_smith: oh, wrong pattern

21:20 ,(map (comp inc (partial rem 3)) [1 2 3 4 5 6 7 8 9])

21:20 Seylerius: More precisely, I'm passing &&(range 1 10) into a function,

21:20 clojurebot: (1 2 1 4 4 ...)

21:20 justin_smith: err...

21:21 Seylerius: (I thought && woke up lazybot...)

21:21 It must be ##

21:21 justin_smith: ,(map (comp inc #(rem % 3)) [1 2 3 4 5 6 7 8 9])

21:21 clojurebot: (2 3 1 2 3 ...)

21:21 justin_smith: ugh

21:21 Seylerius: Right.

21:21 justin_smith: ,(map (comp inc #(quot % 3)) [1 2 3 4 5 6 7 8 9])

21:21 clojurebot: (1 1 2 2 2 ...)

21:21 justin_smith: still not it

21:22 &(map (comp inc #(quot % 3) dec) [1 2 3 4 5 6 7 8 9])

21:22 lazybot: ⇒ (1 1 1 2 2 2 3 3 3)

21:22 Seylerius: ,(map #(quot % 3) (range 9))

21:22 clojurebot: (0 0 0 1 1 ...)

21:22 justin_smith: so you want dec, quot, inc

21:23 Seylerius: That oughta do it, thanks.

21:23 Widgets in a seesaw container should retain order, right?

21:24 justin_smith: Seylerius: some containers have rules for how they place things

21:24 I don't know what the default is though

21:41 drojas: Hi, is anyone here familiar with core.match?

21:57 TEttinger: ,(map (comp inc int (partial * 0.333333)) [1 2 3 4 5 6 7 8 9])

21:57 clojurebot: (1 1 1 2 2 ...)

21:58 justin_smith: TEttinger: heh, that's another way to do it

21:58 TEttinger: or!

21:58 ,(map (comp inc int (partial * 1/3)) [1 2 3 4 5 6 7 8 9])

21:58 clojurebot: (1 1 2 2 2 ...)

21:58 TEttinger: oooh!

21:58 different

21:58 justin_smith: those tricksy decimals

21:58 gfredericks: there might be a continuous function for this

22:01 TEttinger: gfredericks: continuous for the 1 1 1 2 2 2 ... problem?

22:01 gfredericks: yeah

22:02 TEttinger: so what would 3.5 be?

22:19 gfredericks: (f 3.5)?

22:21 TEttinger: 1 2 3 4 5 6 => 1 1 1 2 2 2

22:22 2 2.5 3 3.5 4 4.5 => ???

22:22 lazybot: TEttinger: Oh, absolutely.

22:24 gfredericks: TEttinger: gimme a minute

22:34 TEttinger: this is fun

22:34 ,(map #(inc (read-string (apply str (drop-last (format "3r%03d" (Integer. (Integer/toString (dec %) 3))))))) [1 2 3 4 5 6 7 8 9])

22:34 clojurebot: (1 1 1 2 2 ...)

22:34 TEttinger: I wish dealing with non-binary, non-decimal, non-hex bases was easier

22:35 this one converts it to a string of ternary digits and discards the least significant trit

22:39 gfredericks: ,(defn triples [x] (let [f #(/ (- (Math/sin (* Math/PI (+ % (/ 7.0 4)) (/ 2.0 3))) (Math/sin (* 7 (/ Math/PI 6)))) 1.5)] (+ (/ x 3) (* (/ 2.0 3) (f (+ 1 x))) (* (/ 1.0 3) (f x)))))

22:39 clojurebot: #'sandbox/triples

22:39 gfredericks: ,(map triples [1 2 3 4 5 6])

22:39 clojurebot: (0.9999999999999994 1.0000000000000002 0.9999999999999993 1.9999999999999991 2.000000000000001 ...)

22:39 gfredericks: ,(map triples [2 2.5 3 3.5 4 4.5])

22:39 clojurebot: (1.0000000000000002 0.8333333333333331 0.9999999999999993 1.4999999999999996 1.9999999999999991 ...)

22:39 gfredericks: pardon my floats

22:40 TEttinger: ^

22:40 TEttinger: &(let [base 36] (map #(inc (read-string (apply str (drop-last (format "%dr%03d" base (Integer. (Integer/toString (dec %) base))))))) (range 1 100)))

22:40 lazybot: java.lang.NumberFormatException: For input string: "a"

22:40 TEttinger: aw

22:44 cryptack: anyone have a mac and experienced problems with tab completion when using lien's repl?

22:44 TEttinger: &(let [base 36] (map #(inc (read-string (apply str "0" (drop-last (Integer/toString (dec %) base))))) (range 1 100)))

22:44 lazybot: ⇒ (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3)

22:44 TEttinger: nice

22:44 cryptack: for whatever reason, it works just fine on Windows, but when attempting on OS X it doesn't provide any completion

22:45 TEttinger: cryptack, is your mac using macports' version of lein?

22:45 it may be very outdated

22:45 &(let [base 17] (map #(inc (read-string (apply str "0" (drop-last (Integer/toString (dec %) base))))) (range 1 100)))

22:45 lazybot: ⇒ (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6)

22:46 cryptack: TEttinger: no, it was installed via brew

22:47 TEttinger: if you run the command: lein version

22:47 what does that print?

22:47 (possible there's something wrong with the jline or whatever wrapper it uses)

22:47 cryptack: TEttinger: Leiningen 2.5.1 on Java 1.8.0_45 Java HotSpot(TM) 64-Bit Server VM

22:47 TEttinger: that's about as new as it gets

22:48 cryptack: yeah, it seems pretty strange to me

22:49 and I'm very new to clojure/lien so I'm not even certain where to start to look into it

22:49 TEttinger: I'd try re-self-installing. you can rename the jar that lein downloads when it installs, that's where the whole program is except for the launcher script 'lein', then running 'lein selfinstall' or it might be 'lein self-install'

22:49 let me see where that jar is on mac

22:49 cryptack: ok

22:52 TEttinger: ok, run: lein self-install

22:53 that will tell you where the jar is; delete or preferably rename it, then run 'lein self-install' again

22:58 MichaelGreeves: i find 4 year old girls sexually attractive

23:05 currentoor: Hey does anyone have a break point repl that works inside a webserver?

23:05 Sort of like the pry gem that you can use in rails?

23:06 TEttinger: currentoor: cursive does have a breakpoint debugger

23:07 currentoor: but I'd have to use intellij for that right?

23:07 cfleming: currentoor: Right.

23:07 currentoor: I was thinking of something that I could use in the terminal

23:07 editor agnostic

23:08 cfleming: currentoor: You could check out clj-debugger

23:09 currentoor: hmm thanks!

23:16 smokeink: hello ! has anyone got an emacs configuration for opening local "/usr/share/doc/java8-openjdk/api/" javadoc in w3m inside emacs?

23:34 bluesnow: Why does (remove #{5 7 false} (cons false (range 10))) return (false 0 1 2 3 4 6 8 9)?

23:35 Shouldn't the predicate evaluate to true on false, since false is a member of the set?

23:35 I thought that false would be removed from the result

23:37 TimMc: bluesnow: ##(map #{1 2 nil true false} [1 2 nil true false "hello"])

23:37 lazybot: ⇒ (1 2 nil true false nil)

23:37 bluesnow: oh never mind, I see what's happening. the set is used as a function to look up false, false is returned, and evals to false

23:38 yeah, thanks

23:38 TimMc: Sets return the element if they contain it. Sometimes this is not what you wanted.

23:38 bluesnow: yep

23:38 have to use contains? for this case

23:59 TimMc: &(map (partial contains? #{1 2 nil true false}) [1 2 nil true false "hello"])

23:59 lazybot: ⇒ (true true true true true false)

Logging service provided by n01se.net