#clojure log - Dec 20 2014

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

2:04 abaranosky: anyone out there who's used Reagent?

2:05 I'm trying to get the simple-component from the reagent docs to work and I'm getting the JS equivalent of a null pointer exception

2:05 I wonder if somehow I've got the wrong version of React under the hood

2:05 js/React shows a react version of "0.9.0"

2:06 I'm using reagent "0.5.0-alpha"

2:13 dang noone's aroudn?

3:05 TEttinger2: ugh, I'm in a debugging nightmare with lazybot

3:06 I can get $google to work, some of the time

3:06 but only if the first result of the search uses https

3:06 and I have no idea how with-open and clojure.java.io/reader interoperate

4:22 expez: abaranosky: reagent appears to target react 0.12.2

5:11 borkdude: is lib-noir still the go to library for handling sessions in web applications in clojure

5:11 haven't looked at this for a while

5:15 what was that website again where you can check how many projects depend on some library

5:58 hyPiRion: borkdude: crossclj?

6:17 m1dnight_: Might be a stupid question, but is clojure an interpreted language?

6:17 (I know java is jit'ed, but in a sense it's still a compile dlanguage, no?)

6:18 expez: m1dnight_: all clojure code is compiled

6:18 Bronsa: m1dnight_: yes, clojure is compiled to jvm bytecode

6:18 m1dnight_: oh okay :)

6:18 thanks

7:00 jonathanj: is there a form of -> that returns early if a subform returns nil?

7:01 (-> [] first inc) => nil / (-> [1] first inc) => 2

7:02 expez: jonathanj: some->

7:03 jonathanj: expez: fantastic! thank you!

7:38 borkdude: hyPiRion yes, how can you see in that website how much and by what a lib is used?

7:40 hyPiRion: good question

7:40 I thought it did, but it doesn't seem like it

7:40 clojars have download stats though, but it doesn't list reverse deps

9:02 crispin: hey guys

9:03 how do I use non-clojars/maven source for dependencies and lein plugins in leiningen?

9:03 say I need a lein plugin. latest version is 0.1. But the github master branch has bugfixes I want to use

9:03 how do I specify this dependency so it doesnt download it, but uses some local path

9:04 same question with dependencies and plugins

9:04 expez: crispin: https://github.com/kumarshantanu/lein-localrepo

9:05 crispin: ah cheers expez! will try

9:19 noncom|3: what is the best and latest and coolest doc/reading on transducers and explanation on how to use them ?

9:41 zand: Anyone else getting a "nth not supported" error when using 'lein new template' command?

9:42 I tried a couple of different reagent templates and I'm getting the same result

9:42 using lein 2.5.0

9:42 noncom|3: zand: nope, never

9:42 that must be an error in the template?

9:43 zand: yes, possible - weird though that I'm getting the same error on different templates

9:43 any hints on debugging lein templates? :-)

9:44 noncom|3: what exactly is this template?

9:44 zand: https://github.com/reagent-project/reagent-template

9:44 noncom|3: if it is installed with a 3rd party lib, i guess you must check that out

9:45 zand: it's the default reagent template for lein

9:45 noncom|3: well, it is obvious that nth is being used on something that is not an ordered sequence

9:46 other than that,.. it is hard to say..

9:46 what is the exact stack trace?

9:47 zand: http://pastebin.com/8ug0nbDH

9:48 it would be great if clojure stack traces referred to a line in clojure code :-/

9:49 noncom|3: well, it actually does hre

9:49 *here

9:49 leiningen.core.project$dependency_map.invoke (project.clj:77)

9:49 it cant process the deps

9:50 zand: isn't that what source maps solves?

9:50 noncom|3: not sure what you're talking about..

9:51 btw: java.lang.UnsupportedOperationException: nth not supported on this type: Symbol

9:51 zand: when you say "it can't process the deps" I was assuming that you meant clojure can't figure out the line of the error from the clojure sources

9:52 noncom|3: no, i meant it cannot process the dependencies vector of the app/template

9:52 cannot resolve the project dependencies

9:52 for them are a symbol, not a []

9:52 for some reason..

9:53 zand: ok, well it's a hint to start looking. I love clojure but it's a serious step backwards in the debugging dept vs other languages where you get the link in your sources.

9:54 *line in your source files

9:54 noncom|3: zand: well usually it does

9:55 here it does too

9:55 the thing is that the error occures in leiningen, not in the template itself

9:55 template is data here

9:55 *but*

9:55 too bad that it does not print out the data that caused the error

9:57 zand: so when it mentions the line where the error happens (project.clj:77) is that the project.clj of the template?

9:58 noncom|3: zand: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L77

9:58 no. the error is *in leiningen*

9:58 so the stack trace is that of leiningen

9:58 zand: ah, ok - thanks for the clarification

9:59 noncom|3: zand: you can recompile leiningen with added debug output for that function :D

9:59 and seeee what data exactly causes hte issue

9:59 zand: thanks - I'll check that out...

10:01 noncom|3: zand: i'd say that the "dep" thing that comes inside the function is not a [] as it is expected to be, but symbol

10:01 zand: don't you merge the tamplate with any of your own configs?

10:02 zand: not usually - in practice you usually do something like : "lein new <template-name> <your-project-name>" and it sets up the project for you based on the template

10:04 noncom|3: zand: so, then the error is in the template - probably it does not meet the spec

10:04 try removing the {{{}}} elements from it..

10:05 can't help more though :)

10:05 zand: that's what i'm guessing - grepping the template for 'dependency-map' brings up nothing...

10:06 oh well, I'll open a ticket on the template and keep hacking away on it in the meantime.

10:06 thanks for your help!

10:16 looks like it might be a lien bug after all...

10:17 doing 'lein repl' from the cli gives the same error with a fresh install of lein

10:41 noncom|3: zand rather strange

10:42 i dont think lein is *that* bugged

10:42 maybe you have some user profiles..

11:05 luxbock: how does one type hint a double-array?

11:05 was it just ^"[D"?

11:06 I only remember there was something weird about it

11:06 errr there's ^doubles

11:10 gfredericks: yeah that other syntax probably is only needed for nested arrays or something

11:14 TEttinger: gfredericks, correct

11:14 $google metadata and the medusa

11:14 lazybot: [Building a Sustainable Metadata Workflow for Audio ... - IFLA Library] http://library.ifla.org/94/1/124-edge-en.pdf

11:14 TEttinger: who fixed lazybot?

11:15 http://www.learningclojure.com/2010/09/macros-and-type-hints-metadata-and.html

11:17 also, http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html

11:19 double[][] in java becomes [[D in bytecode, which clojure can type hint as ^"[[D"

11:20 m1dnight_: guys, could somebody help me out with a macro? I want to write one that takes 0 or more arguments but it fails on me

11:20 atm I have e.g., (defmacro f [& args] `(println ~args))

11:20 (f) works, but (f 1) does not

11:21 TEttinger: ,(defmacro f [& args] `(println ~@args))

11:21 clojurebot: #'sandbox/f

11:21 TEttinger: ,(f 1)

11:21 clojurebot: 1\n

11:21 TEttinger: ,(f)

11:21 clojurebot: \n

11:21 m1dnight_: oh

11:21 TEttinger: ,(f 1 2 3)

11:21 clojurebot: 1 2 3\n

11:21 TEttinger: yay, my first macro

11:21 (that works)

11:22 m1dnight_: oh great that works

11:22 thanks! :)

11:22 TEttinger: no prob

11:22 m1dnight_: (inc TEttinger)

11:22 lazybot: ⇒ 33

11:31 emaczen: what server does 'lein ring server' actually run?

11:31 weavejester: emaczen: Jetty, the Ring default

11:51 luxbock: can I transmit deftype'd classes over transit-clj/cljs?

12:03 dnolen_: luxbock: sure you just need to install handlers for those types

12:04 luxbock: dnolen_: are handlers defined in *data-readers*?

12:05 dnolen_: luxbock: Transit documentation covers this - nothing to do w/ data literals

12:06 luxbock: dnolen_: alright thanks

12:06 dnolen_: luxbock: https://github.com/cognitect/transit-js/wiki/Getting-Started

12:07 luxbock: how I wish someone had ported potemkin over to CLJS :)

12:32 m1dnight_: Is it possible to write my own exception FooException in Clojure, that has a field? Atm I'm using ExceptoinInfo but it's a bit cluttered

12:32 Or am I best to do this in java?

12:33 I can't find any decent documentation on how to do it

12:40 bbloom: m1dnight_: if you genuinely need a field for jvm interop, just use java

12:41 simply add a .java file to your src directory and you're good

12:59 dnolen_: luxbock: realized transit-cljs docs were in a bad state compared to transit-js, fixed https://github.com/cognitect/transit-cljs/wiki/Getting-Started

13:16 andyf: Bronsa: I don?t see any :resolved-op metadata for ns forms. Is that because ns is a special case, perhaps?

13:16 Bronsa: is it? I can't rememberr

13:16 andyf: I'll check in a second and let you nkow

13:16 andyf: It might not be, and this is a bug or missing case in t.a(.j).

13:17 Bronsa: andyf: http://sprunge.us/SQQI?clj

13:18 andyf: Looks good there. I'll keep checking and let you know if I figure it out.

13:18 Bronsa: andyf: just tried without #'trim and it's still there

13:19 andyf: Maybe try a bigger ns form that causes fix for Gilardi scenario to kick in?

13:19 Or that one might already...

13:19 Bronsa: ah, right

13:19 using analyze+eval I don't see resolve-op indeed

13:20 andyf: I do see resolved-op for many forms, but I haven't characterized which ones yes and which ones no.

13:20 Bronsa: yeah I see what's going wrong now

13:21 give me a minute and I'll commit a fix

13:21 andyf: Any chance Clojure/West in Portland, Oregon at a date to be announced would fit into your schedule?

13:21 probably depends on the date, but curious.

13:24 Bronsa: andyf: check now

13:24 andyf: ok

13:24 Bronsa: andyf: yeah depends on the date, but.. I hardly see having time this year :(

13:25 andyf: understood. School makes time precious, I'm sure.

13:26 Bronsa: i mean, I can probably take a week off. I'll see when the date gets announced

13:27 andyf: I'd guess the program committee would be interested in most talk submissions you would think of, which can help a lot on the cost.

13:32 That worked for the ns forms, at least, from quick spot checking. Thanks,

13:35 ... and when I say "can help a lot with the cost", I would guess they might even be willing to spring for the entire cost including travel, for you.

13:40 I think I understand at least some of the reasons why, but it is amazing the number of places like this :resolved-op you have added that mutability during compilation is significant.

13:41 given the emphasis on immutability elsewhere.

13:41 Bronsa: andyf: gotcha, I'll think about it :) tbh I'd love to come to one of the clj confs

13:41 andyf: huh? I don't understand

13:42 andyf: I mean, one of the reasons you added :resolved-op is because trying to resolve vars at the end of analyzing a file could change the result, because Vars are mutable, yes?

13:42 Bronsa: yeah

13:42 well

13:42 the namespace system

13:42 andyf: Yeah, I suppose most of the things I am thinking of come down to mutability there.

13:43 Bronsa: that's the only piece of global mutable state that t.a.jvm uses (is forced to use)

13:43 and yeah, that complicates things a bit

13:44 I've actually added support for an immutable namespace system but it's still undocumented and I'm not sure how much useful it will actually be given clojure's semantics

13:45 andyf: I know others, I think Mike Anderson, and perhaps arrdem, may be interested.

13:46 Bronsa: you *can* snapshot the ns env at a point in time & have multiple deterministic-ish analysis of the same form but for this to work, you have to assume that no interning happens during analysis other than via def

13:46 which is not something we can assume in the general case

13:47 puredanger: Clojure/west will be Apr 20-22 in Portland

13:48 dnolen_: puredanger: woot!

13:48 puredanger: We will make a wider announcement in the new year

13:49 Back at the Gerding theater where we were 2 yrs ago

13:50 andyf: cool beans

13:59 Bronsa: new resolved-op key should be on all forms in :raw-forms, not just the first, yes?

14:00 Bronsa: andyf: correct

14:02 andyf: well, *now* it will, pull the last commit :P I forgot about inlines

14:19 dnolen_: Om 0.8.0-beta4 out, back in sync with React 0.12.2

14:25 bbloom: dnolen_: thanks for the nolocal fix!

15:05 dnolen_: bbloom: np

15:06 also landed an interesting change where you can override rAF in Om, perhaps people doing testing might find it useful

15:39 ticking: what if the default printing for stacktraces would only print the clojure parts and core.stacktracke could be used to print everything?

16:01 amalloy: ticking: the default should not be to omit information. it leads to people showing up in #clojure and saying "here is my stacktrace, what is wrong", with the answer being "your stacktrace is wrong"

16:02 ticking: amalloy: one of the biggest complaints I heat though, is that the stacktraces are very hard to understand

16:02 most of the time you're not interested in the java layers in between, and most of the time you don't do interop

16:04 Bronsa: ticking: I honestly think that most of the people that complain that clj stacktraces are hard to understand, don't even try to read them. They just look at this long verbose stacktrace and assume it impossible to figure out what's going wrong reading it

16:04 ticking: clojure could focus a bit more on usability, especially because it seems that most people that come to clojure are non-lisp people, that are used to nicer error messages

16:04 amalloy: (inc Bronsa)

16:04 lazybot: ⇒ 80

16:04 amalloy: ticking: if you try to make the easy case easier, by printing neutered stacktraces, you make the hard case impossible

16:05 ticking: Bronsa: yeah, but that doesn't mean that they have a very bad noise to signal ratio

16:05 amalloy: clojure embraces the JVM; you can't just pretend you're not on it

16:05 what are you supposed to do if there's an exception in some java code? just have the stacktrace stop at the deepest part that's clojure? that's awful

16:06 ticking: amalloy: yeah because that is where the error most likely occured

16:06 amalloy: most of the exceptions in clojure programs might get thrown in java parts, but they originate from logic flaws in the clojure layers

16:07 amalloy: ticking: if my programming language starts deciding to hide debugging information based on what "likely happened", it's time for me to switch programming languages

16:07 Bronsa: ticking: I'd blame the issue of hard-to-understand error messages on the garbage-in garbage-out attitute & lack of validatio on clojure core code rather than on "bad stacktraces"

16:07 ticking: amalloy: that why I said, that the information should be available from clojure.stacktrack/print-stacktrace

16:08 amalloy: ticking: but the beginners you're trying to protect by changing the default don't even know clojure.stacktrace exists

16:08 you can't make up for bad beginner defaults with a library that gets back the stuff you took away

16:09 ticking: its not a library, it's buildin

16:09 and even advanced clojure people get thrown off by the exceptions from time to time

16:10 amalloy: i'm not going to argue this anymore. i get tired of people proposing to "simplify" stacktraces

16:10 ticking: if people come up with this repeatedly, maybe they've got a point

16:11 signal to noise is important, it is better to give a comprehensible incomplete overview first, that gives you a good idea where to go deeper than hand you a giant incomprehensible mess

16:11 amalloy: ticking: people also repeatedly come up with the brilliant idea to use indentation instead of parentheses

16:11 Bronsa: ticking: people come up regularly with proposals of removing parents from lisp. doesn't mean that's a good idea

16:12 parens*

16:12 amalloy: Bronsa: if we removed parents, lisp programmers would all be as cool as batman

16:13 ticking: amalloy Bronsa: so far I've seen no cases of indentation that are better than parens, but I've seen plenty of languages that have better stacktraces

16:13 even ones on the jvm

16:17 andyf: ticking: There are at least a few libraries that attempt to make them shorter and Clojure-specific, but I don't recall all of them.

16:17 ticking: andyf: prone is quite nice when doing ring https://github.com/magnars/prone

16:19 andyf: In Clojure itself, I believe the issue has been raised at least a few times, but I think the statement has been made that removing things too early in the implementation discards potentially useful information, so modifying them is left as a job for IDEs or libraries.

16:20 dnolen_: ticking: Clojure already has shorter pretty printed stack traces by default - no one uses it

16:20 ticking: (clojure.repl/pst e) does this

16:25 ticking: dnolen_: interesting, but even with /pst it consists of 90% repl implementation functions unrelated to the problem

16:29 amalloy Bronsa: lol, maybe you have to change languages already ;p because by default it seems that Exceptions have only their last frame printed :D

16:29 Bronsa: ticking: I use slime, I always get the full stacktrace

16:30 ticking: Bronsa: yeah, but I wans't really meaning tooling, tools should do whatever they want, all the html based editors could have trace folding which would be nice, but I meant in the repl, because that is where people first come into contact

16:31 Bronsa: ticking: the repl is tooling

16:31 ticking: Bronsa: but amalloy s argument doesn't hold there

16:31 printing a nice trace for exceptions would be an improvement over one liners

16:31 https://gist.github.com/ticking/c69e77ec33cf7a7855d0

16:32 Bronsa dnolen_ amalloy: currently you get nothing or everything in the repl. Either just the root cause which is pretty useless, or a trace that contains 90% implementation detail of the repl

16:34 Bronsa: ticking: I was never making a case for how good the default behaviour of the clojure repl is. I never use the default clojure repl. I only talked about clojure stacktraces

16:34 dnolen_: ticking: nothing in a Clojure stacktrace is useless - the opinion of people that have to use Clojure in anger is not on your side.

16:35 ticking: that it's not friendly for beginners is of course totally true - but friendlier Clojure environment can fix this

16:36 ticking: dnolen_: yeah but so far the only argument I've seen is: "we shouldn't omit information", which doesn't apply for exceptions because they only print like "NullPointerException clojure.lang.Numbers.ops (Numbers.java:961)" anyways

16:37 so having only the "relevant" clojure parts printed instead would't remove anything

16:37 one could even print the root cause and afterwards print the clojure fns but I think this would make a lot of people happy and shut up a lot of critics that start the repl, get a useless error and go rant on their blog

16:40 dnolen_: but I'll just go back to fixing gorilla repl's exception printing and lobbying for making it the default repl :P

16:40 dnolen_: ticking: or repl-y could do this since most people run `lein repl` - sounds like you have some patches in your future :)

16:41 ticking: dnolen_: yeah reply would be a good point for this :), that's why I was asking what people would think of this. No use in an unwelecome patch

16:42 kenrestivo: i'm trying to bend schema to my will. i need a map that has one but not more than one of a required key. i.e. {:foo x :baz y} or {:bar x :baz y} but not {:foo x :bar x :baz y} no matter where i stick the s/either, i get protocol :explain exceptions

16:43 dnolen_: ticking: I don't think anybody is against making things easier for newcomers

16:43 kenrestivo: or :walker exceptions

16:44 ticking: dnolen_: yeah, I'll whip something up for gorilla and backport it to reply :)

17:08 craigglennie: Is there a single function to extend a list? Equivalent to ##(flatten (conj [1 2] [3 4]))

17:08 lazybot: ⇒ (1 2 3 4)

17:08 craigglennie: Or is that the way to do it?

17:08 Bronsa: ,(concat [1 2] [3 4])

17:08 clojurebot: (1 2 3 4)

17:09 craigglennie: awesome, thanks Bronsa

17:09 danielglauser: ,(assoc concat [[0 1] [2 3]])

17:09 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/assoc--4105>

17:10 danielglauser: ,(apply concat [[0 1] [2 3]])

17:10 clojurebot: (0 1 2 3)

17:10 Bronsa: danielglauser: you mean apply?

17:10 danielglauser: :)

17:10 Bronsa: heh, looks like so

17:10 danielglauser: craigglennie: A slightly different but similar case

17:13 alexbara`: I'm reading the Om source code. I see a funciton or macro called "specify!" but I cannot find where this is defined, either in Om or in Clojurescript. Anyone know where "specify!" comes from? Or at least what it does?

17:14 craigglennie: danielglauser: there doesn’t seem to be any reason to use apply? concat already works without it. You could do this, though: ##(apply conj [1 2] [3 4])

17:14 lazybot: ⇒ [1 2 3 4]

17:14 dnolen_: alexbara`: not a function, it's a macro

17:15 alexbara`: dnolen_: where is it defined? I couldn't find it by rgrepping

17:15 dnolen_: alexbara`: unique to ClojureScript as it's probably too difficult to implement efficiently on the JVM at the moment

17:15 alexbara`: cljs/core.clj

17:15 danielglauser: craigglennie: I suspect that a list of lists is a more common situation.

17:16 abaranosky: dnolen_: aha, my rgrep was looking in *cljs ... I'm still not 100% used to how cljs puts the macros into *.clj files :D Thanks for pointing me in the right direction

17:24 tom39291: Can anyone suggest a book to introduce clojure? I'm a professional Scala developer, also experienced in Java and Haskell

17:25 Clojure for the brave and true looks good, especially since it introduces Emacs too.

17:26 danielszmulewicz: tom39291: I worked my way with the Joy of Clojure.

17:28 mearnsh: JoC +1

17:29 dnolen_: tom39291: Joy of Clojure probably the best intro if you're experienced with Scala/Haskell. Other books don't assume much functional background.

17:29 tom39291: Great. Sounds like what I'm after. Thanks for the recommendations.

17:31 danielszmulewicz: I'm playing with boot-clj. I like what I see.

17:31 A lot.

17:32 michaniskin: danielszmulewicz: if you have issues or suggestions etc we're hanging out in #hoplon

17:34 danielszmulewicz: michaniskin: OK, will do. Looks quite stable. I missed the cider repl and middleware the first time I launched a boot repl, but quickly found the wiki with relevant information. Nice.

17:34 michaniskin: awesome

17:36 andyf: Bronsa: For jvm interop forms, there is no plan to have :resolved-op ? (and maybe no need?)

17:37 Bronsa: andyf: no need

17:38 andyf: I guess those are either fully namespace qualified for static methods/fields, or they are instance methods and should have no class names?

17:40 Bronsa: andyf: right

17:40 danielszmulewicz: michaniskin: The philosophy behind it is just awesome. You trade the declarative nature of traditional build tools with the power of Lambda. To die for. I wonder how fast you'll convert Leiningen users to grok and use it.

17:41 michaniskin: LAMBDA: The Ultimate Declarative :)

17:41 danielszmulewicz: michaniskin: Do people grok it?

17:41 michaniskin: aka: Lisp Can Do It!

17:41 i think it's easier to get by example maybe?

17:41 i just did a video the other day: https://www.youtube.com/watch?v=d0XQD89enjE

17:42 kenrestivo: eastwood is very helpful. i.e. merge with only one map... oops forgot to put in the second one...

17:42 michaniskin: i live code like 90% of what boot can do

17:42 hit all the main concepts anyway

17:42 danielszmulewicz: Yes, that's how I got sucked in. But what is your impression of people's reaction after being exposed to it?

17:43 michaniskin: if i can show someone in person they will love it

17:43 but i am not a good technical writer so i think a lot is lost there

17:44 danielszmulewicz: michaniskin: The blog post with example is good.

17:44 andyf: kenrestivo: Glad you are finding it useful. Working on enhancements to it right now.

17:44 Bronsa: (inc andyf)

17:44 lazybot: ⇒ 15

17:44 Bronsa: (inc eastwood)

17:44 lazybot: ⇒ 5

17:45 michaniskin: danielszmulewicz: all the concepts in boot are interrelated, like lisp, so it's tricky to explain sometimes

17:45 danielszmulewicz: michaniskin: Yes, it's been forever there. I mean, I remember when boot v1 was announced.

17:46 michaniskin: Being so neat, it deserves better exposure & acceptance.

17:46 michaniskin: boot1 was hobbled because we didn't know how to make pods work back then

17:47 now that we've figured that out it's smooth sailing :)

17:47 danielszmulewicz: michaniskin: Building its own homepage was a smart move.

17:47 michaniskin: I can see it coming together.

17:47 michaniskin: alandipert and i work at adzerk, and they're really cool about supporting open source

17:48 adzerk actually paid for the website and whatnot

17:48 sveri: Hi, anyone using cursive here? I have this form [:h3 "foo" [:h4 "bar"]]. What is the structural editing command to separate these both into this: [:h3 "foo"] [:h4 "bar"]?

17:49 ticking: sveri: should be barf forward

17:50 sveri: ticking: indeed, thanx, thats it :-)

17:50 cfleming: sveri: Yup, barf forward, under Edit->Structural Editing

17:50 ticking: Alt + A, ,

17:50 danielszmulewicz: michaniskin: It's really a competing alternative to Leiningen, and since Leiningen is almost standard these days, it is going to be an uphill battle. I'm curious how this will turn out.

17:51 ticking: seems like the lisp curse has finally struck

17:52 andyf: ticking: Because both Leiningen and boot exist?

17:52 ticking: yeah kinda

17:52 andyf: ticking: There used to be Leiningen and Cake, and those merged.

17:52 ticking: andyf: yeah, that was a happy day :D

17:52 sveri: Hehe, a friend of mine who started using clojure together with me always went for building its own thing until I pointed him to existing libraries which did things better

17:53 andyf: Leiningen did not eliminate Maven, or makefiles, or the use of other build tools. It *nearly* eliminated them, but not completely.

17:53 michaniskin: danielszmulewicz: we can use leiningen tasks in most cases, we run them in pods, like https://github.com/adzerk/boot-beanstalk

17:53 ticking: andyf: I really like build, but I love that I can point newbies to one canonical build tool

17:53 'boot

17:53 Bronsa: ticking: having alternatives is good when you need them

17:53 andyf: See compile/package/deploy section of the survey results here if you are curious: https://cognitect.wufoo.com/reports/state-of-clojure-2014-results/

17:54 ticking: yeah I agree, I just don't ever want to tell people getting started "well you could use this... or this.. they are both good but different"

17:54 sveri: ticking: what do you tell ppl in java land? there are at least three majore players: ant, maven and gradle

17:55 ticking: sveri: yeah and how many people do you tell to use java?

17:55 sveri: ticking: :D

17:55 ticking: at work everyone is using it

17:56 ticking: sveri: yeah but the build tool situation is still a mess

17:56 kenrestivo: after investing almost 3 years now in rendering all of leiningen's quirks into muscle memory, any alternative would have to be beyond amazing to get me to spend the mental overhead to learn it and unlearn lein

17:56 sveri: ticking: gradle is pretty cool, not as cool as leiningen (didn't try boot), but hey, at least you can get things done in a relatively short time

17:57 kenrestivo: well not all of its quirks, but all the ones i've run into (mostly in the realm of cljs)

17:57 danielszmulewicz: kenrestivo: that's the situation for most of us. The thing is, boot-clj might be very well be that amazing thing.

17:57 michaniskin: sveri: boot is to leiningen as gradle is to maven

17:58 sveri: michaniskin: I try it in my next project, did plan to do that anyway

17:58 michaniskin: awesome, let us know how it works for you :)

17:59 kenrestivo: as it is, it took me much longer than i thought it would to wrap my brain around stuart sierra's components lib. but i think i've got a fair amount of its quirks rendered into muscle memory by now too.

18:00 took 3 projects to really get comfortable with it.

18:00 danielszmulewicz: kenrestivo: A propos Stuart Sierra's components lib, have a look at https://github.com/danielsz/system

18:00 michaniskin: kenrestivo: boot is actually also a good replacement for components

18:00 so you can in theory nuke two things with one bomb

18:00 kenrestivo: great, another thign to unlearn :-/

18:01 ticking: tbh I don't get boot it does too many things

18:01 danielszmulewicz: michaniskin: Ok, that's your next blog post.

18:01 michaniskin: haha, yes, after docker

18:01 ticking: why does it manage resources in scripts, when there is alembic?

18:01 kenrestivo: getting to be an old guy, i can't do 180-degree turns on a dime anymore.

18:02 michaniskin: ticking: alembic doesn't support the extreme classloader isolation we needed

18:02 it uses classlojure for that, which isn't enough

18:02 ticking: michaniskin: yeah but why not fix it then?

18:03 michaniskin: it can't be fixed because it's running in clojure. boot fixes it by shipping a java executable, and doing the isolation in java before any clojure runtimes are loaded into any classloaders

18:03 ticking: michaniskin: ah I see, too bad :(

18:04 michaniskin: basically the classloader isolation and dependency resolution needs to happen outside of any clojure classloader hierarchy

18:04 ticking: michaniskin: so the set-env! part is parsed statically and then removed?

18:04 michaniskin: no, set-env! is just a function

18:04 there is no static munging in boot

18:04 Deraen: I did some quick testing today and converted one of my work projects to boot (it took like 15minutes, as I simple boot project already) and I found that lein pdo less watch, cljx watch, figwheel + lein repl uses 6 jvms and 6000MB memory (some jvm opts might help) while one boot task doing the same things uses 800MB and 1 JVM

18:04 ticking: michaniskin: ah so the classloader setup is done before, I see

18:04 kenrestivo: danielszmulewicz: i looked at your system lib, stuart's components, trapperkeeper, frodo, jig, modular, leaven, pisto... and ended up going with components becuase it seemed the simplest and easiest to understand.

18:05 michaniskin: ticking: the machinery for doing the classloader stuff is implemented in a java class that is in the topmost classloader, above any clojure classloader

18:06 this means that you can actually call methods on that class from clojure

18:06 ticking: interesting, thanks for the explanation :)

18:06 michaniskin: it's a class with just static methods

18:06 danielszmulewicz: kenrestivo: Nice. Just to be clear, system is just a set of readymade components. It builds on SS's lib and brings no other abstractions. Just a repo of ready-to-go components.

18:12 sveri: michaniskin: while you are here, I just looked through the homeüage and wiki. Is there an example somewhere which includes cljx / cljs / and clj with relaoding features for development and adapted config for production?

18:13 Deraen: sveri: https://github.com/Deraen/saapas/blob/master/build.boot

18:14 michaniskin: sveri: sure, there is a cljx task that's not in the blog post, but it can be composed with what's in the post easily: http://adzerk.com/blog/2014/11/clojurescript-builds-rebooted/

18:14 oops, what Deraen said :)

18:14 sveri: Deraen: michaniskin thank you both, I bookmark this and go through it :-)

18:14 michaniskin: saapas is the current state of the art there

18:16 sveri: how about test-refresh for clojure.test?

18:17 michaniskin: sveri: alandipert made a test task the other day actually, one sec

18:17 https://github.com/adzerk/boot-test

18:18 you can do like `boot watch test` for example

18:18 sveri: michaniskin: awesome, thank you

18:18 michaniskin: it actually runs your tests in a pod

18:18 a new pod each time

18:18 so you don't need to worry about reloading namespaces etc

18:18 each time is a fresh clojure runtime

18:19 sveri: tasty tasty, maybe I will reconfigure my current project

18:19 I am to curious right now

18:19 michaniskin: alan was doing some stuff the other day

18:19 like building the project incrementally, running tests, when tests pass building snapshot jar and deploying to maven local

18:20 playing different sounds when tests pass/fail

18:20 sveri: hehe

18:20 michaniskin: he built that whole pipeline in a single command line

18:20 just composing boot tasks in different ways

18:22 sveri: :-) bed is calling for now, thanks again

18:25 michaniskin: np :)

18:25 ticking_: sveri: silly germans, always tired

20:15 cfleming: michaniskin: Congrats on boot, it looks really cool

20:15 michaniskin: I need to add support to Cursive for it, it's on my list

20:16 michaniskin: boot actually looks like a good candidate to migrate the Cursive build (currently Ant) to

20:16 michaniskin: cfleming: awesome, we can help wherever possible

20:16 kenrestivo: methinks you're going to find yourself setting up a #boot channel

20:16 cfleming: michaniskin: Cool, I won't get to it for a while but there are already users asking for it

20:17 michaniskin: cfleming: i think we can do cool things vis ide integration using pods

20:17 because it's cheap to spin up a new pod as an alternative to reloading namepsaces

20:17 cfleming: michaniskin: Yeah, I need to look into your classloader magic, I might need something similar for Cursive extensions

20:17 michaniskin: we have an optimized pod-pool thing for that

20:18 cfleming: michaniskin: Interesting, it does seem like there'd be some interesting use cases for that.

20:18 michaniskin: tcrawley's shimdandy project is what you want there, for sure

20:18 A+ would use again :)

20:18 especially since cursive is launched from a java process, which is what you really need to get classloader isolation working properly

20:19 you can't really do it from inside clojure's classloader

20:19 or i should say, i spent like 3 months trying and couldn't do it :)

20:19 cfleming: michaniskin: Interesting. What I actually really want for plugins is to be able to control which classloader Clojure code gets loaded into, but that doesn't seem to be possible.

20:20 michaniskin: cfleming: they can if you use pods

20:20 cfleming: michaniskin: i.e. what i don't want is to replicate the clojure runtime for each plugin

20:20 michaniskin: why not?

20:20 it's not expensive really

20:20 cfleming: michaniskin: Because that's a lot of classes in a long-running process

20:21 michaniskin: maybe 10-20M of memory is the size of it

20:21 boot uses way less memory than lein because of pods

20:21 cfleming: There's also startup time, which is a problem in IDEs

20:21 michaniskin: we have a pod pool thing for that

20:21 that keeps a pool of pods warmed up with clojure.core loaded

20:21 ready for action

20:22 cfleming: Right, but I'm talking about initial IDE startup when the plugins are loaded

20:22 michaniskin: boot starts a pod for each task usually

20:22 i mean tasks generally start pods of their own

20:22 but they do so in a future

20:22 so they all start concurrently

20:23 boot starts a minimum of i think 3 or 4 pods

20:23 cfleming: michaniskin: Ok, I don't have that much control over IntelliJ's plugin loading unfortunately

20:23 michaniskin: just to get to hello world

20:23 but i can run boot in < 1.2 on my machine

20:23 i mean 1.2s

20:23 cfleming: Anyway, pods seem like a really interesting idea for things like spinning up tests and new REPLs

20:24 michaniskin: i'm interested in making a new kind of repl

20:24 more like a resident editor than a repl

20:24 where you have a file that is reevaluated every time it changes

20:24 and you see the output

20:25 cfleming: Sounds like lighttable

20:25 michaniskin: so each time you change it it is evaluated in a new pod

20:25 cfleming: I see, interesting

20:25 michaniskin: yeah but no namespace reloading or mutable namespace business

20:25 but for that to work you need a good model for like "session state"

20:26 basically a database of local state that is persisted across compiled

20:26 cfleming: How good is the JVM at reclaiming classes loaded into discarded pods?

20:26 michaniskin: *compiles

20:26 it's fine, but for java 7 there is the permgen issue which is serious for clojure

20:26 so you need to use the jvm options that permit permgen class unloading

20:26 but with those options it runs great on 1.7

20:27 1.8 has no problems at all, because they removed that

20:27 i mean if you make a lot of pods you either need to use a pod-pool or call the destroy-pod function yourself

20:27 because the pod classloader needs to be closed and clojure agents need to be stopped

20:28 or it'll hang around for a while eating memory

20:28 but we regularly run tests in anonymous one-time-use pods with no memory issues

20:29 in a watcher loop

20:30 cfleming: https://github.com/boot-clj/boot/wiki/JVM-Options#permgen-errors

20:37 cfleming: michaniskin: Ok, thanks. I'll think about some use cases for pods - I suspect they might be quite useful.

20:37 michaniskin: haha they're entertaining for sure

20:38 cfleming: shimdandy looks very nice, actually

20:38 michaniskin: cfleming: for an idea: https://github.com/adzerk/boot-logservice

20:38 that solves the datomic peer sfl4j conflict problem

20:38 by isolating your logger implementation in a pod

20:39 so your project has no looger implementation dependency to conflict with the one datomic pulls in

20:39 *logger

20:39 cfleming: Nice

20:58 brucehauman: michaniskin: you still here?

20:59 michaniskin: hello brucehauman :)

20:59 brucehauman: hey man, I am diggin where you are going with boot :)

20:59 michaniskin: thanks! i dig your domes, man!

20:59 brucehauman: michaniskin: thanks!

21:00 michaniskin: i just moved to durham, and i want to build one

21:00 brucehauman: michaniskin: Well let me know if you have questions.

21:00 michaniskin: I was planning on getting out that way sometime

21:01 michaniskin: i'm still looking for a site

21:01 mildfate: hey all, what's the difference between the last two examples here? https://github.com/ring-clojure/ring/wiki/Creating-responses

21:01 michaniskin: hoping to find a shack in the woods :)

21:01 brucehauman: its not as hard as you would imagine

21:02 a shack in the woods is the way to go

21:02 mildfate: in what cases would I want to return a file vs an input-stream or vice versa? I guess another, more fundamental question is, what does it mean to return an input stream?

21:02 michaniskin: if you are in this area i invite you to drink beers

21:02 brucehauman: i’d love that

21:03 michaniskin: mildfate: input-streams are stateful, is one difference

21:03 weaveje__: mildfate: An inputstream can come from any I/O source, not just a file.

21:03 brucehauman: michaniskin: hey I wanted to let you know about a clojurescript build library I made that you might find helpful

21:03 michaniskin: brucehauman: sweet, what is it?

21:03 weavejester: mildfate: A file has more information than an input stream. e.g. you know it's size and last modified date.

21:04 brucehauman: michaniskin: https://github.com/bhauman/clojurescript-build

21:04 mildfate: weaveje__: I think of an input stream as something that requires you to ask content of it. Does the client's browser continue to "ask" the input stream for content?

21:04 michaniskin: brucehauman: cool, i like it!

21:04 brucehauman: it’s a lib that alolows incremental ClojureScript rebuild when clj files are changed

21:05 michaniskin: this will be useful to use in the boot-cljs task i think

21:05 brucehauman: yeah thats why I brought it up :)

21:05 michaniskin: eventually i think we'll go a little farther than that, using pods

21:05 like with pods we won't need to reload namespaces

21:05 we can just do it whenever any clj file changes at all

21:06 because like a clj file with just functions in it might change the behavior of a macro in another clj file

21:06 if the macro calls those functions

21:06 weavejester: mildfate: An input stream is a stream of data that can be read. It's piped directly to the client.

21:06 brucehauman: yeah I account for that

21:06 michaniskin: brucehauman: whoa, really?

21:07 brucehauman: michaniskin: yep :)

21:07 weavejester: mildfate: From the browser's perspective, there's no difference between a File body or an InputStream body.

21:07 michaniskin: i must read codes :)

21:07 mildfate: weavejester: Ok. In what cases would I use an InputStream instead of converting it into, say, a string and sending that?

21:08 weavejester: mildfate: If the stream is large or of an indeterminate length.

21:08 mildfate: weavejester: Ok, I gotcha

21:08 If I'm creating the inputstream on the fly or something

21:09 michaniskin: brucehauman: do you know if cljs analyzer state can be written to disk and used in a new compiler yet?

21:09 it was like half implemented last time i checked

21:09 brucehauman: michaniskin: there are atoms in there I think

21:10 michaniskin: bummer

21:10 brucehauman: michaniskin: maybe I’m wrong about that

21:10 mildfate: weavejester: So I'm reading the Ring wiki atm, do you recommend any specific framework that builds upon Ring?

21:11 brucehauman: michaniskin: it might be posssible, that would be awseom

21:11 weavejester: mildfate: The luminus template is a good place to get started.

21:11 michaniskin: brucehauman: yeah it's a key thing for what we want to do with pods

21:11 mildfate: weavejester: I thought Luminus was just a collection of libraries?

21:11 michaniskin: we want to avoid reloading namespaces, instead just using a fresh pod

21:11 weavejester: mildfate: http://www.luminusweb.net/

21:12 michaniskin: because reloading multimethods and protocols is sketchy

21:12 weavejester: mildfate: It's a project template

21:12 mildfate: ok

21:12 weavejester: mildfate: That's probably the closest thing there is to a "framework" in Clojure.

21:13 A framework is pretty much just a template + libraries.

21:13 brucehauman: michaniskin: ofr each compile? and thats fast?

21:14 michaniskin: brucehauman: well only when clj files change, but yeah it's super fast

21:14 the only thing that takes time is loading clojure.core really, so we keep pods warmed up in reserve ready to go

21:16 brucehauman: I’m compiling every few seconds in figwheel sometimes. That seems intense.

21:16 michaniskin: each time a clj file changes we could use your tool to mark the js files that need to be recompiled and stuff, and then do the cljs compile in a fresh pod with the saved analyzer state from the pervious pod

21:17 it's not a noticeable delay at all, we use it all the time for running tests tdd style

21:17 brucehauman: but maybe thats my perception laging whats actually possible

21:17 michaniskin: tests run each time in a fresh pod and the pod is discarded after

21:18 also the garden task does it

21:18 incremental compiles with garden don't take longer than without pods

21:18 it's like .30s to do the garden compile for a normal site

21:18 including spin-up of the new pod and whatnot

21:21 bhauman: got bumped offline for a sec

21:23 michaniskin: yeah I wanted to let you know that I decoupled figwheel from lein and cljsbuild so if you want to use it, its possible

21:23 michaniskin: bhauman: that's awesome, we'll be using it, i'm sure

21:24 bhauman: michaniskin: it has its own watcher though

21:24 but you can get around it

21:24 https://github.com/bhauman/lein-figwheel/blob/master/sidecar/src/figwheel_sidecar/auto_builder.clj#L38

21:46 Deraen: Perhaps we can also use figwheel client for boot-reload (or boot-figwheel), the new HUD is nice :)

21:49 mildfate: is there a getting started page somewhere for lib-noir?

22:03 xnil_: mildfate: lib-nope

22:04 uris77: I have a rather basic question about sessions in ring. When I authenticate with an OAuth provider, I normally need to manually make another request to get the user's profile. I'd like to keep some of that information in the session without needing to make a network request for the profile everytime a secure handler is accessed.

22:04 Currently, I have a middleware that adds the profile to the session in the request, but it feels wrong having to do a network request everytime.

22:08 mildfate: what are the advantages of dealing with routing in the frontend with javascript versus in the backend?

22:08 I'm trying to understand why I might use routing libraries in clojurescript vs compojure

22:09 uris77: routing in the front-end is for rich frontend applications

22:09 the frontend routes don't always correspond to the backend-routes

22:10 and for some views (or routes) you don't make a request to the server, you just hide or show parts of the view. The front-end routes provide ways to access those views through a url.

22:10 it is a common practice when building SPAs

23:04 crack_user: what is the advantage of transducer over classic function composition?

23:11 kenrestivo: generalization across channels, sequences, etc?

23:13 crack_user: I cannot do that before transducers?

23:14 I am new in clojure and I am trying hard to understand some parts

23:20 kenrestivo: if i were new i'm not sure i'd be starting with trandsducers :-)

23:20 there's a couple good talks by rich hickey on trandsducers that explain them though.

23:21 ok, core.async question: why would this https://www.refheap.com/95230 be a No implementation of method: :admix* of protocol ?

23:22 my goal here is to have a sub that takes a *set* of topics off of a bus, not just one. i was told to use mixes... and that seems to be failing.

23:24 * kenrestivo feels like using core.async might have been a bit too cutting-edge of a strategy here

23:29 bhauman: the first argument to admix needs to be a mix right?

23:30 mix creates and returns a “mix” so that would be the first arg to admix

23:39 kenrestivo: aha, thanks. i'd gotten confused with sub, which is side-effecting, and admix, which is side-effecting. mix returns the mix, it doesn't turn the channel presented as an arg into a mix

23:40 i really wish the side-effecting functions in async were! appropriately! screaming!

23:42 i.e. it'd be nice if admix was admix! and sub was sub!, but from now on i'll remember that mix is not mix!

Logging service provided by n01se.net