#clojure log - Aug 27 2015

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

0:47 sojacques: Hi guys, I have a little question, is there anything similar to http://tour.golang.org for clojure? A friend of mine is looking for a brief introduction to the language, and I can't really find one that allows you to try as you read

0:47 jeaye: sojacques: The koans allow you to learn interactively.

0:48 But there's not much ceremony around it all, so you need to be a bit quick on your feet.

0:48 sojacques: jeaye: is there any way to do the koans in a browser?

0:49 jeaye: Of course.

0:49 sojacques: oh, there are clojurescript koans for that. Fantastic

0:50 jeaye: Right, that's the one. _Basically_ the same, as far as beginners are concerned.

0:51 sojacques: Thanks a lot, I bookmarked this, it's going to be very convenient to explain my friend what I'm doing all day

0:51 friends*

0:58 seangrove: For a function that expects keyword args, is there a way to just pass a plain map?

1:00 ugh, (apply concat {})

1:06 mange: seangrove: I've seen people use a function like this to do it, (defn mapply [f kwargs] (apply f (apply concat kwargs)))

1:54 amalloy: ~mapply

1:54 clojurebot: You have to do something like (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))), which just goes to show why unrolled keyword args are a bad idea

1:55 amalloy: seangrove: ^

1:57 (inc gfredericks) ; for that, iirc

1:57 lazybot: ⇒ 147

2:28 sveri: ambrosebs: ping

2:58 crocket: How do I convert a data structure into a textual representation readable by clojure?

2:59 neoncontrails: Define "readable"?

3:00 And maybe "data structure" too. What type?

3:07 dstockton: ,(pr-str {:a 1 :b 2})

3:07 clojurebot: "{:a 1, :b 2}"

3:08 dstockton: ,(clojure.edn/read "{:a 1, :b 2}")

3:08 clojurebot: #error {\n :cause "clojure.edn"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.edn"\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.net.URL...

3:17 neoncontrails: How many of you would use Clojure in an interview setting? Strictly curious

3:18 * neoncontrails was told earlier in an interview not to use "map" as it reminded the interviewer of Java HashMaps

3:18 oddcully: haha

3:24 jeaye: What a ridiculous interviewer that must've been.

3:44 crocket: dstockton, thanks

3:44 neoncontrails, ^^

3:44 ,(doc pr-str)

3:44 clojurebot: "([& xs]); pr to a string, returning it"

3:44 crocket: (pr-str '(3 4 [:a :b]))

3:44 ,(pr-str '(3 4 [:a :b]))

3:44 clojurebot: "(3 4 [:a :b])"

4:02 Leonidas: neoncontrails: what's wrong with HashMaps?

4:02 I feel it's like having an issue with the colour blue.

4:03 neoncontrails: Nothing. It's strictly not implied by use of me

4:03 *map

4:04 Leonidas: Must've been hilarious, did you get the job? :)

4:04 neoncontrails: That's precisely what I thought too. I had fun, but I think if an interviewer wants to ding me for using map, we probably won't get along well anyway

4:05 It was a practice interview actually, so purely fun and games. But the guy was older than me, and more experienced

4:07 wasamasa: age doesn't prevent you from sillies

4:07 neoncontrails: I did get briefly excited nonetheless, like, "Ooh, a chance to talk about how cool map() functions are!"

4:10 It did make me wonder though. How common *is* knowledge of map/reduce/filter?

4:11 Empperi: depends on who you ask

4:11 but if you look at the broad majority of the programmers then not very

4:11 neoncontrails: It's standard at my university; one can't pass SICP without becoming an expert on functional style

4:11 Empperi: I'd say 10% of the programmers doing programming for living know those

4:11 or so

4:11 neoncontrails: !!!

4:11 Empperi: the skills of an average programmer out there is not exactly dashing

4:11 neoncontrails: really only 10%?!

4:12 Empperi: it's just a guess but yeah

4:12 I've done my fair share of code auditing, training etc so I think I have a hunch

4:12 neoncontrails: Well, that can be forgiven, maybe (I don't think I'm a terribly good programmer)

4:13 Empperi: and I've interviewed propably hundreds of people for programming jobs

4:13 neoncontrails: I'm just surprised that it's not common parlance by now... even Java has map now, I heard?

4:13 Empperi: these days most of the guys I interview do know those but that's because I'm at the last interview and rest have been filtered out already (

4:14 yeah java has map, filter, reduce, flatmap and so forth

4:14 in java 8

4:14 the problem is, most of the guys writing java out there don't use java 8 yet

4:14 they can't or are too afraid to upgrade since their code is so brittle

4:15 or their customers are too afraid to allow that

4:15 neoncontrails: ,(filter (fn [interviewer] (knows? interviewer 'filter)) (map interview interviewer))

4:15 clojurebot: #error {\n :cause "Unable to resolve symbol: knows? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: knows? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: knows? in t...

4:15 Empperi: and even if they had java 8 they'd have to know how to use those

4:16 it is wildly different to use java Streams API and build on top of that instead of good ol' mutable variable mess

4:16 neoncontrails: I have only heard mediocre experiences with it

4:16 Empperi: it's quite nice

4:16 certainly a huge improvement to Java

4:17 neoncontrails: For me, the transition from Scheme -> Java 7 was distressing because it lacked both my bread and butter

4:17 Empperi: anyway, there are people out there writing client-server architecture where their server receives commands in a way that their clients write commands to database "command" table and the server polls that

4:18 and clients when they've written that command start polling that same table and wait that specific line is deleted

4:18 and then both read and write happily to the exact same database

4:18 yes, this is from a real software I audited

4:18 neoncontrails: I came to appreciate that map/reduce aren't just making my life easier, that they really shape the way I organize my thinking

4:19 Empperi: the reason they implemented it like that was that they didn't know how to write concurrent software or how to use sockets and they didn't bother to google for ready implementations

4:19 neoncontrails: Ha, yes. I haven't worked in industry yet where these things start to matter

4:20 Empperi: that kind of people really do get paid for doing programming work and they can go on doing their work like that for decades

4:20 neoncontrails: But I hear that when I do have to work with databases, it will be an easier transition from my current way of coding

4:20 oddcully: Empperi: ppl get creative to get over fences

4:20 Empperi: indeed

4:20 they had a slight performance and maintanibility problem and bought consultancy from us

4:20 I wonder why they had these problems...

4:21 neoncontrails: Heh

4:21 oddcully: and slight is needs alot of quoting fingers, right?

4:21 Empperi: yup

4:21 there were hundreds of the clients talking to that "server"

4:21 oddcully: s/is/

4:21 Empperi: all accessing the very same database

4:21 writing stuff there

4:21 they also had strange bugs

4:22 turns out they were using MySQL and it's myisam database

4:22 oddcully: haha

4:22 neoncontrails: This is kind of a loaded question then, but supposing all of these things are true:

4:22 Empperi: myisam does not have proper transactions it works in auto-commit mode

4:22 neoncontrails: That most programmers aren't terribly familiar with functional programming methods

4:23 Empperi: yes, correct

4:23 functional programming has been gaining in popularity in the last 5 years

4:23 neoncontrails: That most employers aren't familiar enough with them to really assess your whiteboard solutions written in a functional style...

4:23 What then?

4:23 Empperi: before that it was rare to find anyone who actually knew that stuff

4:23 neoncontrails: then it means you should look elsewhere :)

4:24 you don't want to go to that company where the interviewer doesn't know what map/filter/reduce does

4:24 you'd die in brain hemorrage there

4:25 neoncontrails: Hahaha. I completely agree, but then I wonder, are the companies that consider FP an asset advertising themselves as such?

4:25 oddcully: check for the reaction: either they feel dumb and will not hire you or they will have a revelation

4:25 Empperi: some are, others arent

4:25 neoncontrails: Where would I find the companies that my problem solving approach fits in, in other words

4:27 Empperi: hard to say, depends on where you live

4:28 neoncontrails: California

4:28 oddcully: an indication also can be companies where the job description does not focus on e.g. one programming languages. like "you know scala, python, ocaml and/or racket"?

4:28 neoncontrails: with roots in both bay area and Southern CA

4:28 oddcully: if a shop is already polyglot it will be alot easier to impress them with new stuff

4:29 neoncontrails: It seems (limited experience) like the language preferences are most often articulated by recruiters

4:30 That the same job might have different criteria depending on whether it's posted by HR or a headhunter

4:31 When I see a language preference and it's through a headhunter, I usually apply anyway, maybe with a note that I'm happy to learn Ruby or whatever

4:32 But I dunno, do you think that it's a red flag when a preference is stated at all?

4:35 Empperi: my company (in Finland) recruits guys who do not know the languages we use

4:35 if he/she is good then he/she will learn our tech stacks

4:38 neoncontrails: That sounds like an extremely good attitude to have

4:38 Crossing fingers that enough companies in CA agree with that :)

4:43 Empperi: there aren't that many people who know Clojure for example in Finland

4:43 we are currently the largest company in Finland doing Clojure seriously

4:43 and even we have only like 10% of our projects using Clojure

4:44 so if we wan't new guys into our Clojure projects we usually need to hire someone who doesn't know it yet

4:44 but who wants to learn

4:45 im_learning: i want to learn

4:46 Empperi: so your nick says lol

4:47 im_learning: yea

4:48 I just wanted to get in touch with one fucntional programming language. confused which to choose, haskell or clojure?

4:49 gilliard: Why not both?

4:49 Empperi: yeah

4:49 they are both functional but in many ways very VERY different

4:49 you'd be better off learning both

4:49 gilliard: The differences will teach you a lot about languages.

4:50 Empperi: the same way one becomes a better Java programmer by learning Clojure one also gets a better Clojure programmer by learning Haskell

4:50 and vice versa

4:50 im_learning: nice point.

4:50 Empperi: the further apart from your comfort zone you go when learning a new language the more you'll learn

4:52 im_learning: I always want to get into serious stuff like this. But the problem is the day-time job? How you guys manage your time to learn these?

4:52 Empperi: well, right now I don't lol

4:52 lambda-smith: im_learning: sacrifice the sleep time

4:52 Empperi: I have a 11 month old daughter who takes all my free time

4:52 wasamasa: free time is overrated

4:52 neoncontrails: That question was on my mind, too, a few weeks ago. I decided to go with Clojure first

4:53 Empperi: but fortunately my employer is very flexible in many ways

4:53 I can learn stuff at work too

4:53 but yeah, do programming at your free time

4:53 oddcully: im_learning: sell your tv

4:54 Empperi: pick up a project you'd like to do and which is simple enough you might actually finish it too

4:54 neoncontrails: A criticism of Clojure, that it's just a thin wrapper around Java, is also somewhat of a benefit in terms of interoperability and ability to use Java's fantastic API features

4:54 Empperi: and write it in language x

4:54 something like a blogging platform

4:55 im_learning: how about solving algorithamic questions in language x?

4:55 Empperi: good way to learn too

4:55 but might not introduce you to the way of thinking in that language

4:56 gilliard: Yeah if I'm picking up a brand new language I'll usually pop over to projecteuler or similar. Especially if I don't get big chunks of time all at once.

4:56 neoncontrails: Well all of the languages will give you a solution, some of the languages will give you a great solution

4:56 Empperi: because well known algorithms are well known anyway

4:56 you'll mostly learn syntax that way

4:56 and that algorithm

4:57 im_learning: so solving problem will help you learn syntax, doing project will help you learn the insight of that language.

4:58 empperi, what kind of projects you do with clojure?

4:58 neoncontrails: doing projects helps you define what the problems are, I think

4:58 which is a bit easier said than done

4:58 Empperi: im_learning: mostly stuff with web ui

4:59 but there's a ton of stuff going under the hood

4:59 enterprise stuff and so forth

4:59 neoncontrails: it's one thing to be handed a little problem, say, "sum of the first 3,000,000 prime numbers"

4:59 Empperi: right now we are building this system with micro-services architecture with elastic search and very complex search queries and terabytes of input data

5:00 neoncontrails: which might be a bit tricky, but it's a totally different difficulty than figuring out the problems that you need to solve to get your app to run on an android phone

5:19 Kneiva: im_learning: I've used my commute time to learn stuff. Like solving these problems: https://www.4clojure.com/ When I got to the harder problems and had to really think about them I could do the thinking while helping my child to fall asleep.

6:10 ToxicFrog: Huh.

6:10 When I try to lein run, it dies trying to download the leiningen jar from S3.

6:11 When I try to download it manually, I get an XML file saying "access denied".

6:11 Is Lein hosed for anyone else?

6:12 Empperi: windows?

6:17 ToxicFrog: Empperi: linux.

6:32 gilliard: I just tried it & "works for me"

6:44 vijaykiran: ToxicFrog: proxy ?

6:44 ToxicFrog: vijaykiran: nope. And it passes the certificate checks fine, it just doesn't subsequently serve me the jar.

6:50 Is it possible that 2.3.1 is just too old?

6:51 Yeah, that's the problem.

6:51 Apparently S3 serves 403 rather than 404 if you try to follow a dead link!

6:51 gilliard: nice

6:52 ToxicFrog: And 'lein upgrade' requires the jar to function, so if you wait too long between upgrades your only option is to download the latest script from github by hand.

6:53 gilliard: How old is 2.3.1?

6:54 ToxicFrog: Two years, apparently. I could have sworn I did a lein upgrade more recently than that.

7:21 kungi: Is there no alter-var-root in clojurescript?

7:25 Empperi: not that long ago there was no vars as you understand them in ClojureScript

7:25 and still they aren't equivalent to what we have in Clojure

7:27 kungi: Empperi: Ok ... Thank you. Then I have to do it properly :-)

7:35 spradnyesh: java interop question: i have:- "class A { public enum B {P, Q, R}}" how do i access A.B.P from clojure? i've done [import A :as A], but accessing A.B.P gives "unable to find static field B.P"

7:37 Empperi: if you have it like that then the enum declaration is instance dependent

7:37 in java terms, this wouldn't work: A.B.P

7:38 this would: new A().B.P

7:38 so same applies to clojure

7:38 spradnyesh: Empperi: ohh yes, sorry missed it

7:38 thanks :)

7:38 Empperi: np

7:42 spradnyesh: Empperi: http://stackoverflow.com/a/663849/4329629 (nested enums are implicitly static). ;; in my case i'm using a external library w/ no 0-arity constructor for A()

7:42 also, i see a "A.B.P" reference in the java source code (of the library)

7:43 but i'm not able to figure out how that translates to clojure world

7:52 found: A$B/P

7:53 search for "nested" in http://blog.jayfields.com/2011/12/clojure-java-interop.html

7:54 actually, for enum, i had to use (com.blah.blah.A$B/P) w/ the function call

8:02 Empperi: ah true

8:02 instance specific enums wouldn't make sense anyway

8:02 now that I think of it

8:03 I just always write static enum when doing java .)

8:19 gilliard: Empperi: I don't have a java dev env handy to try it, but you can put fields in enum values can't you? So an instance-specific enum could be used like that? Although I'm not sure what use it would be IRL.

9:01 justin_smith: spradnyesh: [import A :as A] -- :as isn't valid on imports

9:01 I think an enum in a class would be an inner class, so you want A$B/P

9:02 where P is a static member of B, which is an inner class of A

9:03 spradnyesh: justin_smith: sorry, typo

9:04 justin_smith: yes, that's what i found (see above) A$B/P, but doesn't work w/o fully-qualified-name

9:04 justin_smith: oh, sorry, I didn't see that

9:06 spacepluk: inside the ns form you want (:import x.yz.A) which allows A$B/P instead of x.yz.A$B/P

9:06 but that's about as much shortening as you can get in clojure I think

9:06 sorry, misdirect above

9:06 spacepluk: np :)

9:13 justin_smith: actually, I think you can (import A$B) and fix his problem ... seems he left though

9:24 pseudonymous: Is there an easy way to build a lazy sequence of function calls which I can evaluate at some later point ? (I'm trying to create a form for short-circuit evaluation of incoming requests)

9:27 snowell: pseudonymous: You could quote the calls (turning them into lists) and then (eval) them at said later point

9:27 For all I know, this is a terrible idea/practice, so use with caution ;)

9:28 pseudonymous: snowell: that's also the only idea I have right now. But it just seems as if there's something with these lazy sequences that may work .. ?

9:30 justin_smith: pseudonymous: laziness might be less controlled than you need - it isn't recommended to mix laziness and side effects - what about using delay and @ to force the delay?

9:31 ,(def d (delay (do (prinln "forced") :d)))

9:31 clojurebot: #error {\n :cause "Unable to resolve symbol: prinln in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: prinln in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: prinln in t...

9:31 justin_smith: ,(def d (delay (do (println "forced") :d)))

9:31 clojurebot: #'sandbox/d

9:31 justin_smith: ,d

9:31 clojurebot: #object[clojure.lang.Delay 0x2304a617 {:status :pending, :val nil}]

9:31 justin_smith: ,@d

9:31 clojurebot: forced\n:d

9:31 justin_smith: ,@d

9:31 clojurebot: :d

9:31 justin_smith: you have very precise control with delays

9:33 pseudonymous: justin_smith: I basically only intend to use it as a way of getting OR-like functionality - at the first error check which returns non-nil, I want to abort and return the formatted error to the user (thereby not evaluating the other checks) - there's no alteration of program state per se

9:33 (But I guess I could wrap each check in a delay clause, it just seems a bit verbose)

9:37 snowell: pseudonymous: Could you use core.async and have it wait via (alts!) for a message to come over a specific channel?

9:37 Or go through the error checks with (some->)

10:01 gfredericks: amalloy_: I suspect ~mapply came from TimMc

10:01 ~TimMc is the mapply prophet

10:01 clojurebot: You don't have to tell me twice.

10:50 TimMc: can confirm

11:07 justin_smith: pseudonymous: sounds like you just want every? then

11:08 or maybe every-pred actually

11:11 akabander: So... I need to build a distributed app that will communicate with other instances over a network message bus. Must be a fairly typical pattern. Any suggestions for where to start investigations?

11:12 noncom: akabander: the aleph networking library?

11:12 in clojure we have stack traces lost in macros... why is this? will there ever be a better handling of this? is it possible at all?

11:13 justin_smith: ,(def even-pos (every-pred #(do (print "even ") (even? %)) #(do (print "pos ") (pos? %))))

11:13 clojurebot: #'sandbox/even-pos

11:13 justin_smith: ,(even-pos -1)

11:13 clojurebot: even false

11:13 justin_smith: ,(even-pos 2)

11:13 clojurebot: even pos true

11:13 Bronsa: noncom: stack traces lost in macros?

11:13 justin_smith: pseudonymous: that's "lazy" in the way you want

11:13 akabander: noncom: Thanks, checking it out

11:14 justin_smith: akabander: I've had decent luck with kafka after a pretty steep ramping up

11:14 noncom: Bronsa: if i generate a fn in a macros then if there is an exception in this fn, the exception just points at the macros.. no way to get inside the generated fn

11:15 Bronsa: noncom: do you have an example? I'm not sure I understand

11:17 noncom: Bronsa: umm, not at the moment. let me then first factor a clear example and then show you. maybe not today. this problem bothers me for a long time but i never fixed it. i will work to resolve this confusion by frist focusing on creating a simple reproduceable example

11:19 justin_smith: noncom: one thing that makes stack traces that contain anonymous functions much easier to read is to "name" your anonymous functions (fn some-descriptive-name-here [] ...) - the name will be part of the generated class name for that anon-fn

11:19 noncom: the examples in my original program are big and depend on many things so i cannot just present them, it will be hard to follow

11:19 justin_smith: yes! a good advice. i tend to give names to them when i come acros the ones i did not yet name :)

11:21 seangrove: Bronsa: Is it a monumental task to bring t.a.js up to date with cljs master?

11:23 ps: Hello all, I’m trying to run some tests with ‘lein cljsbuild test’ using phantomjs. When all tests pass, everything is ok, but if a test fail, phantomjs returns a non zero code, while the invocation of the parent ‘lein cljsbuild test’ returns 0 (no error). I assume lot of people do cljs tests in phantomjs and may be someone knows about a workaround or something I miss

11:25 Bronsa: seangrove: sorry I was afk yesterday -- the issue you were having was caused by tajs not supporting new cljs version yeah

11:25 seangrove: not the smallest of tasks I'm afraid

11:27 akabander: noncom: I may go with jeromq

11:27 noncom: akabander: yeah, the mq family of libs seems cool, though i never used it

11:28 akabander: noncom: it definitely seems to be robustly featured. Brings a bit of complexity, but I think I'll need some of the flexibility down the road.

11:29 noncom: akabander: i've heard only good words in address of zeromq, and jeromq seems to be a java replica

11:29 so yeah, that's bright! :)

11:32 seangrove: Bronsa: No problem being afk, of course!

11:32 Bronsa: And yes, I suspected that between Dec 2014 and Aug 2015 there might have been some big changes, heh

11:36 Bronsa: Well, for what it's worth, it'd be great to have :)

11:36 Bronsa: seangrove: especially with cljs going bootstrapped

11:41 seangrove: Bronsa: especially great, or especially big changes?

11:42 Bronsa: The bootstrapped/live-editing aspect is actually what I'm going for here https://www.dropbox.com/s/pvpgprg5kzq8sy4/dato_live_editing_2.mp4?dl=0 - I need t.a.js to properly persist the forms server-side

11:44 kavkaz: How come if I do (group-by identity (range 10)) I get a sequence which is not in order? I tried playing around with the force evaluation functions but I'm not too familiar with them

11:44 And to be honest don't quite know what's happening

11:45 justin_smith: kavkaz: group-by creates a hash-map, hash-maps are not ordered

11:45 seangrove: t.a.js to figure out the var/def deps graph for the location of the inserts (while minimizing movement to be git-friendly) and additions to the ns-form, and clj-fmt to keep the changes to a minimum, regardless of where the change is coming from (emacs, vim, browser)

11:48 Bronsa: seangrove: especially bug changes

11:48 big*

11:53 kavkaz: justin_smith: Ah okay. I found that it retains the order of the sequence usually, but not with range

11:54 Well, for any sequence I input by hand and feed it, it retains the order, but not range for example

11:54 justin_smith: kavkaz: normally = for small inputs

11:55 kavkaz: justin_smith: Ah, I see.

11:55 justin_smith: kavkaz: small hash-maps use a different implementation, one that will preserve order

11:55 kavkaz: Makes a lot of sense now

11:55 justin_smith: they automatically switch to a non-order-preserving version after hitting a certain size

11:56 kavkaz: Interesting, I'll find another way to do what I need to do. Thanks for your help justin_smith

11:56 sdegutis: Is defonce lazy?

11:56 justin_smith: kavkaz: maybe you want a sorted-map?

11:56 sdegutis: ,(do (defonce foo (prn :foo)) nil)

11:57 clojurebot: :foo\n

11:57 sdegutis: aww

11:57 justin_smith: ,(into (sorted-map) (group-by identity (range 100)))

11:57 clojurebot: {0 [0], 1 [1], 2 [2], 3 [3], 4 [4], ...}

11:57 sdegutis: time for memoize

11:57 kavkaz: justin_smith: hmm, I'll take a look at that.

11:57 justin_smith: sorted-map will sort by the keys

11:58 rasmusto: ,(sorted-set 1 2 3)

11:58 clojurebot: #{1 2 3}

11:58 rasmusto: ,(set [1 2 3])

11:58 clojurebot: #{1 3 2}

11:58 rasmusto: that annoys me (the arity difference)

11:58 justin_smith: ,(hash-set 1 2 3)

11:58 clojurebot: #{1 3 2}

11:58 justin_smith: rasmusto: comparing the wrong function :)

11:58 rasmusto: ah, there's my answer

12:23 seangrove: Bronsa: I suppose the priority is pretty low for t.a.js? Perhaps you could make some tickets to guide bringing it up to date? I'd like to build some stuff on it for an upcoming talk in Nov.

12:27 rasmusto: is there a tool that will find all hash-sets in my code? (besides `grep set`)

12:28 Olajyd: Hi, Bronsa

12:29 Bronsa: seangrove: the big issue with tajs is that the cljs.core macros do a lot of non-trivial interop with cljs.analyzer and cljs.compiler, in tajs we need to replace that with a custom file that uses t.a internally rather than cljs.analyzer

12:29 seangrove: Ouch, that does sound tough

12:29 justin_smith: rasmusto: maybe jvisualvm could show you via profiling? or yourkit, I hear that's even better

12:29 Bronsa: seangrove: meaning that tajs is bound to support specific versions of cljs and requires constant maintenance to keep it up to date with cljs

12:30 and I simply don't have the time to keep up with dnolen

12:30 Olajyd: hi

12:30 rasmusto: yeah, I've used jvisualvm before. Maybe its overkill for what I need.

12:31 I'll use some old-fashioned visual inspection for now

12:31 Olajyd: Bronsa, I have a challenge that has been keeping me busy and cant seem to figur it out

12:34 Bronsa: Olajyd: don't ask me specifically for general help, please, ask the channel

12:34 Olajyd: ok

12:34 Bronsa: I'll help if I know how or if I have time to do so

12:42 Olajyd: Given sample rows [[“1” “2” “3”][“4” ”” “5”][“6” “” “7”][“8” “9” “10”][“2” “” “3”]] write a function that will return a pair of rows using the last non empty column (here it is col 1), ie [[[“1” “2” “3”] [“1” “2” “3”]] [[“1” “2” “3”] [“4” “” “5”]] [[“1” “2” “3”] [“6” “” “7”]] [[“1” “2” “3”] [“8” “9” “10”

12:42 [[“8” “9” “10”] [“2” “” “3”]]] :)

12:43 oddcully: am i having a deja vu?

12:44 Olajyd: oddcully :), hardly

12:44 :)

12:45 oddcully, you remember the problem right, I’m told to solve it by creating a pair like this

12:53 justin_smith: ,(rest (reductions (fn [prev cur] (map #(or (not-empty %) %2) cur prev)) [nil nil nil] [["1" "2" "3"]["4" "" "5"]["6" "" "7"]["8" "9" "10"]["2" "" "3"]]))

12:53 clojurebot: (("1" "2" "3") ("4" "2" "5") ("6" "2" "7") ("8" "9" "10") ("2" "9" "3"))

12:54 justin_smith: oh I think I misunderstood

12:57 kwladyka: Olajyd, i don't know what you want achive, why are there this ugly chars?

12:57 justin_smith: kwladyka: certain osx clients do that

12:57 kwladyka: "smart quotes"

12:57 expez: Bronsa: any way to get tools.reader and specify the platform? e.g. read like I'm the cljs reader and then reader like I'm the clj reader?

12:58 Olajyd: Kwladyka, I tried avoiding this smart quotes but they just keep comint up

12:58 *coming

12:58 kwladyka: Olajyd, it makes it so unreadable :)

12:58 akabander: Try using irssi in a console window?

12:59 kwladyka: Olajyd, anyway what do you want achieve if not what justin_smith show?

12:59 akabander: You need a non-GUI client that doesn't try to insert "smart quotes" (dumb feature).

13:00 Bronsa: expez: you men for feature expressions?

13:00 mean*

13:00 expez: Bronsa: yes, dealing with cljc files in refactor-nrepl is proving to more tricky than I had hoped

13:01 Olajyd: kwladyka, I started learning clojure like a month ago and my assignment for the day is `Write a function that Fill in an empty column from the last non-empty value` given a sample row like I gave earlier on

13:02 kwladyka: Olajyd, is it what justin_smith did?

13:03 Olajyd: oddcully and some others gave a solution using `reductions` and I tendered it as a soluttion but, wasn’t accepted

13:03 kwladyka, oh nope :)

13:04 Bronsa: expez: there are a bunch of endpoints that you need to configure to read cljs sources

13:04 kwladyka: Olajyd, Is it from 4clojure.com ?

13:04 Bronsa: expez: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/analyzer.cljc#L2591 is a good example

13:04 justin_smith: oh wait

13:05 Olajyd: so thing I need to make them as a pair like a tuple kind of

13:05 justin_smith: ,(rest (reductions (fn [prev cur] (if (every? not-empty cur) cur prev)) [nil nil nil] [["1" "2" "3"]["4" "" "5"]["6" "" "7"]["8" "9" "10"]["2" "" "3"]]))

13:06 (["1" "2" "3"] ["1" "2" "3"] ["1" "2" "3"] ["8" "9" "10"] ["8" "9" "10"])

13:06 clojurebot: (["1" "2" "3"] ["1" "2" "3"] ["1" "2" "3"] ["8" "9" "10"] ["8" "9" "10"])

13:06 justin_smith: oops

13:08 Olajyd: such that the first element in the pair vector (tuple), is the vector that is the last non epmty row (based on col 1) and the second pair vector is the normal row with empty or non-empty col :)

13:08 Bronsa: Olajyd: how do you expect to learn clojure if you ask others to do your assignments though?

13:08 luxbock: I want to serialize a sorted-map with a custom comparison fn as EDN so that I can use it with both Clojure and CLJS, so I'm wrapping it in a record, giving it a print-method that reads it through its own constructor fn

13:09 so now I'm re-implementing all the protocols/interfaces that Clojure maps use

13:09 does this seem reasonable?

13:09 Olajyd: I’ve tried an approach already Bronsa, I used an atom to keep track of previous state

13:11 Bronsa: Olajyd: reduce already keeps track of previous state for you

13:11 expez: Bronsa: That looks great. Are you keeping this behavior? If I do :features #{:cljs} with the regular reader I still get the clj branch if there are multiple branches.

13:11 Bronsa: expez: by regular reader you mean LispReader.java?

13:11 Olajyd: Besides, I want to knw how it can be done right, I could have used stackoverflow u knw, but I want to learn, right :)

13:11 oddcully: luxbock: wouldn't that mean that you would have to eval the fn?

13:12 expez: Bronsa: yes

13:12 Bronsa: expez: if that's the case that would be a serious bug, seems unlikely tbh

13:13 oddcully: luxbock: or in other words: could i manipulate the edn to make your code execute evil things?

13:13 luxbock: oddcully: what do you mean by eval the fn? my plan is to add a tag to data_readers.cljc so that it should work the same in Clojure and CLJS

13:13 Bronsa: expez: oh wow you're right wtf

13:14 wow

13:14 ,(read-string {:read-cond :allow :features #{:cljs}} "#?(:cljs 1 :clj 2)")

13:14 clojurebot: 1

13:14 Bronsa: ,(read-string {:read-cond :allow :features #{:cljs}} "#?(:clj 1 :cljs 2)")

13:14 clojurebot: 1

13:14 Bronsa: this is seriously broken

13:14 puredanger: ^

13:14 expez: Bronsa: Could you please keep this as an optional behavior? The default is retarded for use in tooling.

13:14 Bronsa: expez: no i mean LispReader is broken

13:14 luxbock: oddcully: I don't think it would be an issue

13:14 Bronsa: expez: tools.reader implements the expected behaviour

13:15 expez: Bronsa: They featured it, IIRC. The platform conditional is always present.

13:15 luxbock: the data the function receives is always trusted

13:16 expez: Bronsa: However, note that the Clojure reader will always inject the platform feature :clj as well. For platform-agnostic reading, see tools.reader.

13:16 Bronsa: http://clojure.org/reader#The%20Reader--Reader%20Conditionals

13:17 Bronsa: wow

13:17 puredanger: The reader in Clojure is not intended to be platform-generic

13:17 Bronsa: I see

13:17 puredanger: Tools.reader is

13:17 Bronsa: I guess it kinda makes sense

13:18 LispReader doesn't have the configurable endpoints necessary to correctly read cljs

13:18 puredanger: Nor should it

13:20 Bronsa: the order-dependant behaviour might be confusing though

13:22 puredanger: It's like cond - the first successful test is chosen

13:23 That's why it's reader cond-itionals

13:23 Bronsa: puredanger: yeah, I meant the cond-like behaviour + the implicit feature

13:24 puredanger: I think expliciting that :clj is an implicit :feature in the read/read-string docstring would help

13:24 puredanger: I agree the implicit feature is potentially confusing. The original version was not like that and I don't love it.

13:25 blake_: OK, so, I'm using Monger to read some data, and I'm using find-maps which is lazy. As I'm traversing the find-maps result, the lazy chunking kicks in, and one of the records in my block is causing an exception. I mentioned this last week, but I'm still unclear what to do about it. Not just here, but generally. How do I figure out what record, or perhaps more importantly, who do I catch the exception and proceed while only skipping the bad record?

13:25 Pupeno: With ring/compojure, how can I have an object that is not being used by more than one thread at a time but that it's being re-used over time? http://stackoverflow.com/questions/32255188/ensuring-single-threadness-of-an-object-with-ring-and-compojure

13:28 expez: puredanger: what was the rationale for constraining the reader in this manner?

13:28 blake_: Pupeno: Wouldn't keeping them in atoms do the trick? Atoms are thread safe.

13:28 blake_: Although I guess that doesn't prevent one thread from sharing with another.

13:29 Pupeno: blake_: atoms are to share data between threads, the opposite of what I want to do.

13:29 blake_: a dynamic var is the closest to want I want, but I'm not sure *when* I should set it.

13:30 Bronsa: expez: LispReader is strictly a clojure reader, it technically can't read cljs

13:30 expez: aha

13:30 Bronsa: expez: main (probably only) issue is stuff that requires namespace awareness

13:30 like ::foo or `bar

13:30 blake_: Pupeno: How do you know when the thread is done with the engine?

13:31 Bronsa: tools.reader has configurable endpoints for that, LispReader is hardcoded for clj

13:31 Pupeno: blake_: I don't and that's what I want, when the thread is re-used, I want the engine to be re-used.

13:32 blake_: Pupeno: Oh! Well, couldn't you just map the thread to an engine?

13:33 Pupeno: blake_: that's more or less what I want to achieve.

13:34 blake_: Pupeno: I guess I'm not getting what this would take beyond a regular map. (assoc engine-map thread engine)?

13:34 Maybe make engine-map an atom?

13:35 Why wouldn't that do it?

13:35 Pupeno: blake_: how do engines ever get removed when a thread is killed?

13:37 blake_: Pupeno: When you kill the thread, you take it out of the engine-map?

13:37 Pupeno: I am not killing the threads, the threads are managed by Jetty or HTTPKit or whatever environment is running my app.

13:38 I am not creating them either.

13:42 blake_: I feel like I'm missing a big piece here.

13:43 Pupeno: Jetty, HTTPKit, Aleph, whatever web server thingy will create threads, processes, re-use threads, whatever. I don't know. I have to ensure that no scriptengine is ever used by more than one thread at the same time and I want to re-use them because they are expensive and I'm happy to have one per thread so that locking is not a problem.

14:20 blake_: Pupeno: Maybe use get-thread-bindings?

14:21 No, I guess that wouldn't help.

14:21 Pupeno: :)

14:25 amalloy: Pupeno: you want a thread-local probably

14:26 you can use java's ThreadLocal manually, or flatland/useful has a macro wrapping it

14:26 Pupeno: amalloy: what do you mean by that exactly?

14:26 amalloy: ah, ok.

14:37 blake_: So...yeah...exception caused somewhere in chunking and I'm trying to figure out how to trap/skip the errant record. Anyone?

15:33 snowell: Say I have an atom pointing to a collection [1 2 3]

15:33 And I want it to be [2 3 4]

15:33 Is there a way to swap! the map function there, or can I only do (reset a (map inc @a))?

15:34 swap! only seems to work if the function takes the current value as the first arg

15:34 s/reset/reset!

15:34 Bronsa: ,(def a (atom [1 2 3]))

15:34 clojurebot: #'sandbox/a

15:34 Bronsa: ,(swap! a (partial mapv inc))

15:34 clojurebot: [2 3 4]

15:34 snowell: Holy crap. It's so beautiful

15:34 (inc Bronsa)

15:34 lazybot: ⇒ 120

15:35 snowell: I never remember partial :D

15:35 tatut: I'm partial to the #(mapv inc %) form (excuse the pun)

15:36 amalloy: snowell: even if you never remember partial, you can always reorder arguments by just using an intermediary lambda as a middle man

15:36 (which is what tatut is suggesting)

15:36 snowell: Yeah, which I thought of doing

15:37 But when swap! works it always just looks nicer

15:37 tatut: ,(swap! a #(mapc inc %))

15:37 clojurebot: #error {\n :cause "Unable to resolve symbol: mapc in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: mapc in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: mapc in this co...

15:37 tatut: ,(swap! a #(mapv inc %))

15:37 clojurebot: [3 4 5]

15:37 tatut: typo

15:37 snowell: Thanks everyone

15:37 (inc tatut)

15:37 lazybot: ⇒ 2

15:39 amalloy: snowell: well yes, you absolutely must use swap!. i was not recommending you use reset!

15:52 ectric: so if I develop an app with luminus using +jetty, then use lein ring uberwar and throw it on tomcat (elastic beanstalk), how does that work? is there a jetty server running in tomcat? or if i used +immutant, an immutant server?

15:57 justin_smith: ectric: jetty is a local replacement for what tomcat does

15:57 both are containers that can run your war

15:58 jetty is used in-process - you don't even start a separate container, but it loads up your code the same way tomcat would when deploying

16:00 ectric: justin_smith: sorry, i'm the whole java tomcat ecosystem is pretty foreign to me. so in that case, when i upload my war for my app to tomcat, it is still basically using the embedded jetty server?

16:00 justin_smith: *new to the java ecosystem

16:00 justin_smith: ectric: no, not at all

16:00 ectric: justin_smith: so it is ignored, and tomcat is used

16:00 justin_smith: ectric: locally, you put something in a plastic bag, on the server it goes in a canvas bag

16:00 bot hare just bags

16:00 ectric: on the server, jetty isn't present

16:01 ectric: tomcat and jetty are containers, the intention is that you can just pick one and it will work

16:01 you don't want more than one, you just use the one that is convenient for a given environment

16:02 so on a server you want tomcat (log rotation, hot reload, hosting multiple apps, diagnostics, advanced configuration options) and locally you want jetty (simple, few options, few features, just enough to run your app)

16:02 or maybe you don't want tomcat, it's a choice

16:03 expez: Is there a blogpost around describing how to use the new cljs analyzer.api?

16:03 ectric: justin_smith: ok, that makes a lot of sense thanks.. but like in my app core's -main function, i call a function that ultimately calls like jetty run server. is that somehow stripped out with lein ring uberwar?

16:03 ttt_fff: does clojure's 'schema' from prismatic provide anything like haskell's GADTS + typeclasses ?

16:03 justin_smith: ectric: tomact never calls your main

16:04 ectric: justin_smith: ahhh. what does it call/how does the thing get started?

16:04 justin_smith: ectric: lein-ring generates the code that tomcat can call to launch your app

16:04 ectric: based on your telling lein-ring what your handler is, etc.

16:05 ectric: justin_smith: that was the piece I was missing! makes sense now.

16:05 justin_smith: thanks a lot for the explanation

16:05 justin_smith: np!

16:06 ectric: justin_smith: is tomcat considered pretty good?

16:07 justin_smith: ectric: it has some features people like, but it's also a bit of a behemoth

16:08 ectric: justin_smith: gotcha

16:09 justin_smith: for example I have used it sometimes just because it's what elastic beanstalk builds on, and it was convenient to use elastic beanstalk

16:12 ectric: ya, that's why i'm using it. elastic beanstalk seemed like the easiest way to get my luminus app hosted - and it has been easy

16:25 mikerod: Bronsa: seancorfield I have been hitting up against this complicated issue with AOT vs JIT and clj 1.7.0 changes

16:25 I've tracked through all of the Jira history and google groups to be sure I'm up to speed

16:25 I understand most of it besides this last point "it should not ship AOT versions of other libraries that folks might also be using via JIT "

16:26 I understand it as the danger is having both AOT compiled lib class mixed with the lib coming in as just clj files

16:26 However, wouldn't the compiler prefer loading the class files to the clj files if the class file has a modified time > clj file?

16:27 I can't seem to see the way that I'd get a forced reload of the clj file to cause the conflict with the pre-existing AOT class files

16:28 I understand the 1.7.0 choice of clj class loading to prefer the in-memory version. I just don't see how the JIT happens at all in the presence of the AOTed files

16:28 puredanger: are you using deftypes?

16:28 mikerod: puredanger: yes this was a deftype one

16:28 I'm hitting the "Caused by: java.lang.ClassCastException: schema.utils.SimpleVCell cannot be cast to schema.utils.PSimpleCell"

16:28 there was some people complaining about this one when the 1.7.0 stuff was coming along

16:29 puredanger: I believe the issue is with deftype constructors (which load via the new bytecode) vs other means of loading, which load via Class.forName() through the DynamicClassLoader which takes into account the cached classes

16:29 mikerod: but I didn't see any concrete answers. It was highly related to the CLJ-1639 and CLJ-979 chain of Jiras though I'm fairly sure

16:29 puredanger: http://dev.clojure.org/jira/browse/CLJ-1741

16:30 mikerod: I've read this Jira and thought it was related as well.

16:30 My main confusion is how am I even getting a dynamic loader class along with the AOT/static loaded class if the namespace isn't being forcefully reloaded?

16:31 I see that the modify time of the class files __init are all later than the schema clj files on the classpath

16:31 so I can't see how the compiler would choose to recompile those files to cause this "duplicate" class definition for the deftype

16:32 I understand the issue with `compile` not checking the `loaded-libs` too

16:33 I'm not calling `compile` anywhere explicitly or something like that though. I'm actually kicking off the compilation chain via a `require`

16:33 puredanger: there are multiple use cases (that present errors in similar ways) through either AOT or reloading

16:34 mikerod: hmm.. ok

16:35 puredanger: sorry, I don't have any of this in my head so it's taking a bit to boot my brain :)

16:35 mikerod: I'm still baffled at how I can even get two versions of these deftype classes. It should only be compiled once. (brain hurts)

16:35 No problem. This is a complicated trail of issues to sort through indeed.

16:35 hiredman: mikerod: many times these issues come down to code load order, if you import a deftype before requiring the namespace that generates it and that kind of thing

16:35 puredanger: well like in CLJ-1741 you end up with two versions because a constructor constructs via one classloader and a class literal is loaded via a different one

16:36 the deftype constructor uses the new bytecode which uses the context classloader, which is typically not a DCL, so won't check the cache

16:37 hiredman: the loader order stuff will manifest as the project code failing to load if you don't aot

16:38 puredanger: the changes in 1.7 make class loading more universal across many paths to always be cache-aware (but the new bytecode case falls outside that)

16:38 so it's not even that a recompile is occurring, but just that two classloaders loaded the identical class (which the jvm treats as two different classes)

16:43 have you tried separating the deftype definition into a different namespace than where it is used? that seems to cut down on the most problematic scenarios

16:44 mikerod: puredanger: At what point do two separate loaders load the class?

16:44 puredanger: no, I think I'm going to remove the AOT entirely because it seems dangerous. It was a lib we don't control - Prismatic schema

16:44 puredanger: instantiating a deftype instance and loading a class literal

16:44 mikerod: I was just trying to get some understanding of this issue

16:44 and I couldn't understand where 2 loaders are trying to load the same class

16:44 that is interesting

16:45 I will try playing around with that to understand how those paths go

16:46 My particular case really is a fallout of CLJ-322 I think

16:46 puredanger: yes, that is the root cause of much pain

16:46 mikerod: that AOT'ing your own stuff causes all your deps to be AOT'ed and included as well

16:46 that is a sneaky issue

16:46 makes AOT hard to work with

16:46 puredanger: the solutions are widely varying if you follow that ticket and the related design pages

16:46 mikerod: especially if I get this double-loader for a class issue with deftype :P

16:46 puredanger: I think clearly fully-transitive AOT is almost never what you want

16:47 mikerod: puredanger: yeah, I haven't delved into that entire Jira yet, I intended to get to that next up

16:47 puredanger: it has tendrils. I have spent many hours reading through all of it and the solution is still not clear to me.

16:48 in Clojure, the granularity of compile is a single ns but in your typical build it is "some or all of my project code"

16:48 those two levels have some impedance mismatch in goals

16:49 it's tricky to describe to the low-level compile function: "just do this much, no more"

16:49 Bronsa: mikerod: sorry, been a while since I hacked that part of Clojure, can't really help without a minimal reproducible case

16:49 mikerod: yeah, I can understand that leading to a sticky situation

16:49 Bronsa: fair enough, I certainly don't have one of those

16:50 My case sounds about the same as when core.typed included AOT version of core.cache

16:50 and that was breaking when a lib used core.typed and had the non-AOT core.cache on the path

16:50 that's why I related it directly to that Jira and was curious

16:50 Bronsa: the unfortunate situation is that there is a disconnect between logic in the classloader, the compiler and the "compiling functions" in clojure.core

16:50 mikerod: I may have enough to go off of now to try to understand what the compiler is doing in my particular case

16:51 Bronsa: they handle compiling, loading and reloading in similar but slightly different ways that are not really compatible all the time

16:51 puredanger: I have compile to believe that having the output directory of the compile function on your input classpath is evil (despite that being stated as a requirement)

16:51 mikerod: yeah, I've been reading (and rereading) through a stack of Jiras around this a while to follow along with where things are

16:52 Bronsa: clojurebot: puredanger has compiled to believe

16:52 clojurebot: Pardon?

16:52 Bronsa: :(

16:52 puredanger: heh, come to believe

16:52 mikerod: haha

16:52 Bronsa: puredanger: I agree with that argument btw

16:52 puredanger: when compilation generates classes, it should have effects on the runtime state

16:52 Bronsa: it shouldn't* ?

16:52 puredanger: but its outputs should not affect the input classpath

16:53 Bronsa: ah, right

16:53 mikerod: that makes sense

16:53 puredanger: when multiple compiles have in a row in "wrong" orders, they currently trip each other up

16:54 I went back and read all the irc history when Rich was putting this in and things he was trying to do at the time and the realities of where we are now are simply different

16:54 Bronsa: puredanger: seems like a simple solution would be to change the docs around that and fix the tooling then?

16:55 puredanger: there are no simple solutions re AOT :)

16:55 I think there are also needs to be a good solution to 322 which is likely to also affect tooling

16:56 but then I think there are still reload use cases with issues (like where this conversation started)

16:57 that needs more research. imho, I do not think we should add more tracking state to the runtime, which is the direction of many of the patches.

16:59 I'm curious how things would change if, for example, deftype constructors didn't use "new", or if we set the context classloader to a different loader around the use of "new"

17:01 Bronsa: puredanger: we can't really change the classloader used by new

17:01 puredanger: sure you can

17:01 it'll use the context classloader

17:04 * Bronsa goes spelunking the jvm spec

17:06 Bronsa: puredanger: it seems to me that once the classfile is loaded by the system classloader instead of DCL, `new` instructions will instantiate the classes resolved by that same classloader, no matter what the context classloader is

17:06 puredanger: at least I think it does :)

17:07 mikerod: I think this is outside of my understanding on how the new is used in the deftype now

17:07 I thought the stack would just have whatever class reference you were going to be new'ing

17:08 guess it is time for me to do more reading in that dept

17:10 amalloy: my understanding is the same as Bronsa's, but i am not really an expert on the topic

17:10 puredanger: I believe there is no reason that we cannot control the classloader used to load anything we're doing in Clojure

17:11 Bronsa: puredanger: say class C causes loading of class D

17:11 and we load C from a classfile

17:11 we have no way of having D be loaded from our DCL

17:11 the jvm will use whatever classloader it was used to load C to load D

17:11 puredanger: is C code we created the bytecode for?

17:12 if so, then can't we create different bytecode?

17:12 Bronsa: puredanger: I'm assuming we're in a situation where we want to load C from disk and D from memory

17:13 puredanger: sure, we just can't use `new` instructions

17:13 puredanger: well that's what I'm saying

17:13 Bronsa: ah, missed that then :)

17:14 I actually thought of trying that a while ago but I was worried about the performance implications of using Class/forName+newInstance vs new

17:17 puredanger: like I said - needs research

17:17 it might be faster than you think

17:22 iirc there is a buried way to construct things for serialization too that's kind of sneaky

17:40 sdegutis: What are the benefits and drawbacks of putting :aot :all at the root of your project map in project.clj?

17:44 I imagine it would terribly mess with dynamic code reloading at runtime right?

17:45 But are there other hidden disadvantages, such as vars not having metadata available at runtime?

19:24 hiredman: ob

Logging service provided by n01se.net