#clojure log - Jan 02 2015

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

0:55 * rritoch Has released the leiningen plugin 'lein-sablecc' version 1.0.0 https://github.com/rritoch/lein-sablecc

1:46 justin_smith: I love debugging after I have had some wine ";; the data generated is ill specified, and the function generating it is a fucking mess"

1:48 rritoch: justin_smith: LOL, was this in a commit for future generations of clojure developers to enjoy?

1:48 justin_smith: nah, it is a comment for me to follow up on when I am thinking more clearly

1:49 rritoch: justin_smith: heh, well I've actually seen a lot of crazy comments over the years. I'm not sure if there is a top 10/100 list somewhere, but your comment would certainly warrent recommendation.

1:51 justin_smith: My favorite comment for non-client projects is ;WTF? , which beyond the standard meaning can mean "What to fix"

1:52 If I'm really annoyed that comment is used on client projects, but luckly it's never made it to a commit, yet.

1:59 rhg135: ;ignore this

2:04 justin_smith: ;; truly the person I was in the past is a sadistic monster torturing me with this absurd code

2:05 rhg135: what was the code?

2:06 justin_smith: rhg135: an attempt to normalize data from a csv so that references to unique ids already existing in the datomic db will be found and upsert merged

2:07 rritoch: http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered

2:07 justin_smith: rhg135: and I clearly was deranged and delusional while trying to design it, the datastructures I was generating didn't even make any sense

2:08 rhg135: souns like most c, justin_smith

2:08 justin_smith: heh, but it's clojure. and now I must fix it

2:08 in the morning, after coffee. Now to drink more wine, and harrass a wooden box covered in metal strings until it screams in pain

2:11 rhg135: I hope u refer to a guitar

2:11 justin_smith: rhg135: viola. Close enough.

2:11 violas are better at screaming though. Guitars require electricity for that sort of thing.

2:11 rhg135: viola or Viola, justin_smith ;)

2:12 justin_smith: ?

2:12 rhg135: ok good

2:13 Also acoustic guitars can wail

2:13 justin_smith: OK.

3:49 wei: trying to figure out why my loggback logger runs on compilation (lein javac).

3:50 it’s failing because it can’t find a java class that’s not compiled yet.

6:34 ercusr: .

6:51 jonathanj: hrm, how does one limit the size of a POST request body to a ring server?

6:51 i found https://github.com/ring-clojure/ring/pull/98 but it's not merged (last updated almost a year ago)

6:53 spradnyesh: i have 500 days, and 1000 files (each about 3-4k lines) for each day. i want to run the *same* clojure program on each of these files. i have 4 octa-core PCs. what is a good way to go about distributing these processes across these cores? cascalog (hadoop + clojure)?

6:54 btw, the clojure program uses 3rd party Java libraries

6:55 basically, the program reads *a* file, uses a 3rd party Java library to do computations, and inserts the results into a DB

7:01 http://stackoverflow.com/questions/27741873/clojure-parallel-processing-using-multiple-computers

7:49 AeroNotix: 1000 files * 4k seems like a single 8 core cpu would blast through that.

7:49 it's a tiny tiny amount of data.

7:49 * 500 as well. Still not much

9:15 jonathanj: it's not clear to me if i can abort a POST in a ring application

9:32 hellofunk: ,(into [] '(1 2 3 4))

9:32 clojurebot: [1 2 3 4]

9:32 hellofunk: ,`[~@(1 2 3 4)]

9:32 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

9:33 hellofunk: ,`[~@'(1 2 3 4)]

9:33 clojurebot: [1 2 3 4]

9:33 perplexa: eeew

9:33 hellofunk: i'm finding that i like syntax unquote splicing quite a bit and am using it instead of into quite often. bad thing?

9:35 perplexa: hellofunk: it massiely decreases readability and makes unnecessary use of macros ;p

9:37 i have no idea about technical aspects such as laziness though ;p

9:37 hellofunk: perplexa: well technically what i have provided is not a macro

9:38 perplexa: hellofunk: ~@ is a macro.

9:38 ,(macroexpand '~@'(1 2 3 4))

9:38 clojurebot: (clojure.core/unquote-splicing (quote (1 2 3 4)))

9:39 hellofunk: perplexa: a reader macro, no?

9:40 perplexa: hellofunk: yes, but how does that make it better or any different?

9:40 what's with your aversion against into?

9:41 check out https://github.com/bbatsov/clojure-style-guide

9:42 hellofunk: perplexa: my example was trivial, but usually a combination of into and concat can be consisely handled by a single reader macro

9:43 perplexa: there's no need for a macro when a function does the same

9:44 hellofunk: just getting opinions, i see it more as a matter of taste, there are quite a lot of examples i come across in production code where these macros were used rather than functions

9:45 perplexa: hellofunk: doesn't mean it's good ;P

9:45 hellofunk: perplexa: for example

9:45 ,(into [] (concat [1 2 3 4] [5 6 7 8]))

9:45 clojurebot: [1 2 3 4 5 ...]

9:45 perplexa: don't get me started on the pile of dirt our php frontend team leaves everywhere :D

9:45 hellofunk: vs:

9:45 ,`[1 2 3 4 ~@[5 6 7 8]]

9:45 clojurebot: [1 2 3 4 5 ...]

9:46 perplexa: yeah definitely the first one ;)

9:46 hellofunk: perplexa: i used to agree with you until i starting seeing the second more and more

9:46 perplexa: maybe wait for some other people to pop up here :)

9:47 i'm rather a clj newb ;x

9:47 but i'm sure somebody has some good reasons for the first one ;p

9:47 hellofunk: perplexa: I suppose it is worth noting that a reader macro would not invoke runtime function call so could be faster

9:53 dysfun: it's also less useful

9:53 i can't imagine a situation where i'd find it useful

9:54 supersym: perplexa: I have the joy of working PHP/Magento now... :( It hates you so much

9:55 perplexa: supersym: i learned oop with magento 0.8 - no docs whatsoever, was much fun to reverse all their badly written code :)

9:55 supersym: I find it extremely hard NOT to create messy code with PHP though

9:55 perplexa: not even inline docu

9:55 supersym: yeah... everything has to be a scavanger hunt

9:56 I am loving my 'ack' atm

9:57 also zen coding the XML files saves some pain etc but coming back from clojure, I don't think its that good for my motivation until there is a clj->php of decent quality sometime, I'll hate it with a passion

9:59 not every clojure library does provide (inline) documentation, some are just notoriously hard to grasp or just outside of reach (of me) at a given point... but at least its not mutable soup where this is actually the norm

9:59 meaning most don't actually need to extra comments... PHP projects sure do though

10:16 ah... my login problem of course: cookie domain

10:21 EvanR-work: is there a string split which simply splits on a single char or a simple string delimiter

10:28 mdrogalis: ,(clojure.string/split "a,b,c" #",")

10:28 clojurebot: ["a" "b" "c"]

10:28 mdrogalis: EvanR-work: ?^ Should just be able to do that.

10:29 EvanR-work: right, but i tracked down a performance problem to this

10:29 im doing 5 levels of splitting on not that much, to get a [[[[[string]]]]], it takes too long

10:31 mdrogalis: EvanR-work: Maybe pull out partition-by since Strings are colls?

10:32 EvanR-work: :Doc partition-by

10:33 worth a shot

11:33 justin_smith: coll opps are going to be slower than string ops, for almost anything

11:34 vanila: hi

11:34 gfredericks: ~coll opps |are going to be| slower than string ops, for almost anything

11:34 clojurebot: Ack. Ack.

11:43 arrdem: does the clojurescript compiler expose anything like ns-publics on the JVM side?

11:45 Bronsa: arrdem: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L1675

11:48 arrdem: Bronsa: thanks

12:59 djames: I'm using gen-class with a JavaFX class. It appears a static initializer is being run by `lein compile`. I don't see why this is necessary for compilation.

12:59 ^ to extend a JavaFX class

13:00 I noticed CLJ-1315 addressed the issue of static initializers for import statements. I wonder if the same should apply to gen-class.

13:00 http://dev.clojure.org/jira/browse/CLJ-1315

13:11 akkad: djames did you use to live in Austin?

13:13 djames: akkad: yes. do we know each other?

13:38 AWizzArd: What is the max number of elements in a PersistentVector? 2^32 ?

13:39 stuartsierra: I expect it's much higher than that.

13:40 I think Java arrays have a limit of 2^31

13:40 [blake|: 2^33 at least...

13:40 stuartsierra: I think you'll run out of memory before you hit any hard limit in PersistentVector.

13:44 [blake|: Well...if PersistentList uses an int for its count, it would have to be limited to 2^31-1, as the Java int, no?

13:46 stuartsierra: oh yeah, looks like it does use an `int` https://github.com/clojure/clojure/blob/05af4b52a474bc60d2eb931e388b302c14edc884/src/jvm/clojure/lang/PersistentVector.java#L40

13:51 gfredericks: ~2^31-1 |ought to be| enough for anyone

13:51 clojurebot: Ack. Ack.

13:54 andyf: 2^31 ought not to be enough for everyone. No way. Rage against the limitation created when memory was more expensive.

13:55 AWizzArd: Vectors use this bit mechanism under the hood, and it is set to 32.

13:56 So I thought in the highest level there are just 2 bits.

13:56 Next level contains 4 arrays of size 32.

13:57 Next 32x more, next 32 more, and so on, until in level 7 there would be 2^32 arrays, each pointing on an object stored in the Vector.

13:59 On a 64 bit machine the arrays of 5 cells on the lowest level alone would already consume 32 GB of RAM, the references to the objects (which themselves would eat much more than this).

14:00 Someone here who has access to a machine with 300 GB of RAM? :-)

14:01 akkad: yeah I build a big swapfile to my 1TB SSD

14:02 AWizzArd: I might test out of curiosity how much time it takes to actually insert 4 billion objects on an EC2 instance. Amazon gives us in its r3.8xlarge instance 244 GB RAM for 41 cents per hour.

14:02 They talk about 63000 MB/s memory bandwidth. Nice.

14:15 justin_smith: AWizzArd: next question of course is how quickly you could generate enough objects to take up that much space

14:15 I guess you could just have a big vector where every element is nil for starters though

14:19 AWizzArd: Yes, nil or possibly a fixed object, say, a String. And all point to the same.

14:26 wei: why does “lein javac” also try to compile my clojure sources?

14:26 am i doing it wrong

14:30 justin_smith: Like the compile and deps tasks, this should be invoked automatically when needed and shouldn't ever need to be run by hand.

14:30 (quoting "lein help javac")

14:31 wei: so my problem is when running my app with “lein run”, I get a ClassNotFoundException on one of my java sources

14:33 I specified the java sources with :java-source-paths ["src/java"]

14:51 djames: wei: actually, I'm having the same problem perhaps

14:51 I would expect `lein javac` would compile the classes before the clojure compilation needs them

14:55 wei: are you using dev/user.clj? I'm reading this https://github.com/technomancy/leiningen/issues/1477 -- it may be the cause of my problem.

15:05 wei: removing a :dev profile that pointed to dev/user.clj addressed my problem. I also started a thread on the mailing list: https://groups.google.com/forum/#!topic/clojure/4ytDn6OHabI

15:09 stuartsierra: djames: Simple workaround: don't use dev/user.clj. Call it something else like "dev.clj" and load it when you start your REPL.

15:11 djames: stuartsierra: thanks. is there something magic about "dev/user.clj" in particular? profiles?

15:11 stuartsierra: djames: user.clj is magic to *Clojure* — it's always loaded on startup.

15:12 djames: stuartsierra: much appreciated. there are, I think, 3 leiningen tickets about this :)

15:13 stuartsierra: Since it's in Clojure, it's not something that Leiningen can fix. The solution is just not to put compilation-sensitive code in user.clj

15:15 djames: stuartsierra: right, I linked 4 of the leiningen tickets together with a comment.

15:15 stuartsierra: djames: thanks

15:16 craigglennie: Why doesn’t this work? Shouldn’t it destructure the key and value from each hash-map in the list? (map (fn [[x y]] {y x}) [{:a :b} {:c :d}])

15:17 justin_smith: craigglennie: that's not how hash-maps destructure

15:17 ,(map (fn [[[x y]]] {y x}) [{:a :b} {:c :d}])

15:18 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap>

15:18 justin_smith: erm...

15:18 I guess you can't destructure the entries on a hash-map

15:19 craigglennie: anyway, your issue there is this: ##(seq {:a :b})

15:19 lazybot: ⇒ ([:a :b])

15:19 justin_smith: note that each k/v pair becomes a vector

15:19 &(seq {:a :b :c :d})

15:19 lazybot: ⇒ ([:c :d] [:a :b])

15:21 craigglennie: justin_smith: Where does seq come into it? Is it called as part of destructuring?

15:21 djames: craigglennie: I've got a pretty exhaustive list of destructuring examples here: https://github.com/xpe/clj-destruct/blob/master/src/destruct/core.clj

15:22 justin_smith: craigglennie: unless you know the key you are destructuring for a map, your ownly destructuring option is to destructure a sequence

15:22 *only

15:23 craigglennie: justin_smith: Okay… so it is a bit confusing that this works: (map (fn [[x y]] {y x}) {:a :b})

15:23 And the other way doesn't

15:23 justin_smith: craigglennie: map calls seq on its arg

15:24 craigglennie: Oh, okay

15:24 I think I get it

15:24 justin_smith: so you are destructuring not the map, but the individual entry (a key and a value as a vector)

15:25 &

15:25 lazybot: java.lang.RuntimeException: EOF while reading

15:25 craigglennie: That makes sense… (seq {:a :b}) returns [:a :b] which can be destructured, but (seq [{:a :b]) returns [{:a :b}] and the inner value is still a hash-map, which can’t be destructured

15:25 justin_smith: &

15:25 lazybot: java.lang.RuntimeException: EOF while reading

15:25 justin_smith: no, (seq {:a :b}) does not return [:a :b] it returns [[:a :b]]

15:26 &(vector? (first {:a :b}))

15:26 lazybot: ⇒ true

15:26 craigglennie: oh, yes

15:27 AWizzArd: amalloy: do you happen to know what the max number of elements in a PersistentVector is?

15:27 amalloy: &(Integer/MAX_VALUE)

15:27 lazybot: ⇒ 2147483647

15:27 amalloy: probably

15:28 AWizzArd: I “calculated” 2^32

15:28 jackjack: Hi, i have a Lucene frontend that uses clojure expressions while scoring, and for that i am compiling the query expressions once and caching them (just using Map<Object,IFn> for every (IFn) clojure.lang.Compiler.load(new StringReader(raw))

15:28 amalloy: nah, should be 2^31-1

15:28 jackjack: i was wandering if this is the proper way to do that, or should i do clojure.eval from java?

15:28 amalloy: count will rollover to be negative, and then lots of bad stuff will happen

15:29 AWizzArd: possible, possible

15:29 I remember there are 7 layers. And vectors use 5 bits as bitmask.

15:30 6*5 bits => 30. So the highest level could have 2 more bits, and that’s 32.

15:32 amalloy: even if that's "possible" in terms of bit arithmetic, there's a lot of code in the implementation that depends on count that will break if it's negative

15:32 eg, seq checks whether count is positive and returns null otherwise

15:32 AWizzArd: Yes.

15:33 Besides that, for practical reasons this is an unlikely scenario anyway.

15:33 Just out of curiosity I’m interested :-)

15:34 amalloy: yes, i thought of making a vector of 2^31 elements to see how it behaves, but with the boxing overhead i probably don't have enough memory, and i'd get bored waiting for it too

15:34 AWizzArd: Even with the 2^31 variant the lowest nodes would consume 16 GB of RAM for the references to the objects alone.

15:40 gfredericks: ,(.nextProbablePrime (biginteger (rand-int Integer/MAX_VALUE)))

15:40 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

15:40 gfredericks: &(.nextProbablePrime (biginteger (rand-int Integer/MAX_VALUE)))

15:40 lazybot: ⇒ 557350501

15:40 gfredericks: (inc 557350501) ;; I like primes

15:40 lazybot: ⇒ 1

15:40 Kristien: that's a weird incrementing

15:41 gfredericks: clojure has this weird feature where if you increment a prime you always get 1

15:41 Kristien: (inc 2)

15:41 lazybot: ⇒ 1

15:41 Kristien: (source inc)

15:41 lazybot stop being lazy

15:42 justin_smith: Kristien: lazybot 's inc command is not clojure's inc

15:42 Kristien: Right. :P

15:42 (inc 2)

15:42 lazybot: ⇒ 2

15:42 Kristien: It increments a global map value.

15:43 justin_smith: it increments a number stored in mongodb, or creates one if it was not there before

15:43 Kristien: sounds overkill

15:43 justin_smith: oh?

15:44 Kristien: to use mongodb for it

15:44 or is mongodb also used for other things?

15:44 justin_smith: it needs some sort of persistent storage, or else how would amalloy get over 200 karma?

15:44 (identity amalloy)

15:44 lazybot: amalloy has karma 210.

15:44 Kristien: Could just read/write a map from/to disk with edn.

15:45 justin_smith: Kristien: that isn't thread safe

15:45 Kristien: It is if you synchronise it.

15:45 justin_smith: and would require rewriting an entire file to change a single value

15:45 databases have already solved these issues

15:46 Kristien: I have once made a similar application it was pretty fun.

15:47 But it stored fails or wins instead of integers. :P

15:47 s/or/and/

15:47 jackjack: do you know if clojure.lang.Compiler.load(string) is thread safe?

15:48 justin_smith: jackjack: not as far as I know, no

15:48 EvanR-work: what does it mean for a function to not be thread safe in this case?

15:48 jackjack: thanks!

15:49 justin_smith: how about the IFns returned from it?

15:49 justin_smith: EvanR-work: if two threads load files that define the same vars, it's a race condition

15:50 jackjack: EvanR-work: i meant can i invoke that from multiple threads, with different strings, and use the results in multiple threads as well

15:50 justin_smith: jackjack: functions are immutable, the vars are mutable though and can get into an inconsistent state

15:50 EvanR-work: ok, theres global bindings

15:50 jackjack: sorry my web irc client is acting weird

15:51 justin_smith: my argument is just string that is a (fn [])

15:51 justin_smith: OK, if you don't mutate any vars, then it should be fine, since functions are immutable

15:52 jackjack: my question was more about if Compiler.load itself has somekind of state that i have to protect

15:52 but if not, it should be ok

15:52 thanks

15:53 justin_smith: I would be very surprised if Compiler.load itself was not thread safe.

15:55 EvanR-work: are facts such as these documented in some standard place

15:55 if standard function x is or is not thread safe

16:01 stuartsierra: In Clojure generally you can assume everything is thread safe unless documented otherwise. In Java, the opposite.

16:01 "thread safe" is kind of vague anyway

16:02 A more useful question is, "Is this object safe to use simultaneously from multiple threads?"

16:02 jackjack: \o/ glad i picked clojure :)

16:03 stuartsierra: Most stuff in the Clojure runtime (namespaces, vars) uses AtomicReference or ConcurrentHashMap under the hood, so the answer is usually yes.

16:04 jackjack: stuartsierra: i was just playing around, when i noticed that .invoke() on clj IFn invoked 5 million times adds surprisingly small overhead on my scoring (it was 140ms without it and 220 with it), this includes doing some local bindings and some bit processing

16:04 in the end i was very happy, but just wasnt sure i was compiling the expression the correct way

16:04 thanks for the info

16:05 chouser: doc proxy-super

16:05 I forget how to use the bots

16:06 nuwanda_: ,(doc proxy-super)

16:06 clojurebot: "([meth & args]); Use to call a superclass method in the body of a proxy method. Note, expansion captures 'this"

16:08 chouser: Hm, I thought the docstring there made it clear how thread-unsafe it is.

16:09 Anyway, it's not thread safe.

16:10 jackjack: chouser: what is not thread safe?

16:11 proxy-super?

16:11 chouser: right

17:08 warz: hi all. im setting on Cursive, on IntelliJ. i've imported my lein project, and it's asking for an SDK. is this the JDK?

17:12 AWizzArd: warz: yes

17:13 tbaldridge: ping

17:51 Frozenlock: Anyone knows how to wrap-params with bidi?

17:51 *use

17:53 EvanR-work: is there a way to determine which import a particular class in my code is coming from

17:53 (fireplace)

17:54 justin_smith: the printed form of the class should include the full package name

17:55 EvanR-work: ok i see it in the import list

18:21 dnolen_: Just shipped ClojureScript 0.0-2644 https://groups.google.com/forum/#!topic/clojure/mRAED4TFlCM

18:21 greatly enhanced REPLs across the board

18:23 EvanR-work: how to convert a string into a byte array?

18:23 justin_smith: .getBytes

18:23 ,(into [] (.getBytes "hello"))

18:23 clojurebot: [104 101 108 108 111]

18:24 EvanR-work: ,(into [] (.getBytes "日本語"))

18:24 clojurebot: [-26 -105 -91 -26 -100 ...]

18:24 EvanR-work: seems legit

18:24 justin_smith: the into [] is just so it prints readably for demo purposes of course

18:25 .getBytes returns a byte-array

18:25 EvanR-work: yeah i guess i was counting on positive numbers to check the encoding

18:25 but i recall java byte type is signed

18:25 justin_smith: yeah, the jvm doesn't have any unsigned anything

18:26 EvanR-work: so what encoding does it use?

18:26 justin_smith: it's almost utf-16 - but getBytes takes an encoding argument

18:26 I'd ask it for utf8

18:26 EvanR-work: thank god

18:26 justin_smith: ,(.getBytes "hello" "UTF-8")

18:26 EvanR-work: (encoding argument)

18:26 clojurebot: #<byte[] [B@45207ff0>

18:28 gfredericks: ,(count (.getBytes "hello"))

18:28 clojurebot: 5

18:28 gfredericks: ,(count (.getBytes "hello♥"))

18:28 clojurebot: 8

18:29 EvanR-work: sane default

18:29 gfredericks: ,(count "hello♥")

18:29 clojurebot: 6

18:29 gfredericks: ,(count (.getBytes "hello♥" "UTF-8"))

18:29 clojurebot: 8

18:29 gfredericks: ,(seq (.getBytes "♥"))

18:29 clojurebot: (-30 -103 -91)

18:30 gfredericks: man I dunno nuthin bout unicode

18:30 EvanR-work: showing the utf8 bytes as negative does not help understanding

18:30 crack_user: hello

18:31 fast question, someone knows how can I install a package in clojure to play in repl?

18:31 justin_smith: crack_user: lein try

18:31 crack_user: the package in question is core.async

18:31 gfredericks: clojurebot: the package in question is core.async

18:31 clojurebot: In Ordnung

18:31 justin_smith: or you can use pallet/alembic to load just about any dep at runtime

18:32 but lein try is easy enough

18:32 crack_user: $lein try

18:32 'try' is not a task. See 'lein help'.

18:32 EvanR-work: what does "almost utf16" mean?

18:32 gfredericks: combined with lein-shorthand all I have to do is (./add-dep [some/thing "0.0.0"])

18:33 justin_smith: crack_user:

18:33 crack_user: I think I am lost the point here

18:33 amalloy: i just saw (defmacro foo [x y] `(get ~x ~y)), and it made me think of a silly simple puzzle. obviously in this case, foo could just be a function: (defn foo [x y] (get x y)), but can you think of some f such that (defmacro foo [x y] `(f ~x ~y)) would work and (defn foo [x y] (f x y)) wouldn't?

18:34 justin_smith: sorry, tried to paste something, weird client setup issues - lein try is a lein plugin you can find on github

18:34 $google lein try

18:34 lazybot: [rkneufeld/lein-try · GitHub] https://github.com/rkneufeld/lein-try

18:35 crack_user: justin_smith: ok I will check that

18:36 andyf: EvanR-work: You can make a simple function to show bytes as unsigned if it makes them easier for you to read, e.g. (defn unsigned-byte-val [x] (if (< x 0) (+ x 256) x))

18:37 EvanR-work: they would be easier to read as hex

18:37 even mod 256 shouldnt require me to type that much

18:37 andyf: So (format "%02x" ...) them if you like

18:37 EvanR-work: good to know

18:38 [0x1f 0x1f]

18:38 ,[0x1f 0x1f]

18:38 clojurebot: [31 31]

18:38 crack_user: justin_smith: it works, but I guess I am cheating the process here

18:38 justin_smith: crack_user: cheating? I don't know about that. Of course you should eventually make a proper project, but there is not harm in one off repls to try things.

18:38 [blake|: What about Clojure makes it unsuitable for Android where Java is just fine? Is it loading the compiler/etc?

18:39 akkad: xb

18:39 andyf: EvanR-work: I do not know why justin_smith said "almost UTF-16". getBytes should return a sequence of bytes that is encoded in UTF-8, UTF-16, etc. exactly, not almost. Unless it has bugs.

18:39 EvanR-work: yeah the bugs part is what i was wondering about

18:39 justin_smith: [blake|: it really depends on the device, clojure uses more resources (and is very liberal with its RAM usage)

18:39 amalloy: andyf, EvanR-work: ##(format "%x" (byte -110))

18:39 lazybot: ⇒ "92"

18:39 amalloy: oh, i see you already said that while i was testing that it works

18:39 [blake|: justin_smith: Gotcha.

18:40 justin_smith: andyf: I meant as in the internal representation used by the vm

18:40 andyf: then it became clear he wanted to know what format he could get from it of course

18:40 andyf: justin_smith: Why do you qualify with "almost"?

18:40 crack_user: justin_smith: this is because I can not properly require a package in the repl?

18:40 justin_smith: andyf: what the jvm uses isn't quite utf-16 - one moment, let me get my cite

18:41 EvanR-work: yes that part is much less interesting (unless of course its buggy)

18:41 amalloy: hey neat: ##(format "%#02x" (byte 10))

18:41 lazybot: ⇒ "0xa"

18:41 andyf: EvanR-work: I am not aware of any bugs with getBytes, but I haven't looked hard, either.

18:41 amalloy: &(format "%#02X" (byte 10))

18:41 lazybot: ⇒ "0XA"

18:41 amalloy: hah, it upcases the X too. that's kinda annoying

18:42 justin_smith: andyf: my bad, it is utf-16 internally, but a "modified utf8" in some other contexts.

18:43 andyf: justin_smith: Thanks for checking. I was pretty sure it was utf-16 internally always.

18:45 justin_smith: andyf: java switched from UCS-2 to UTF-16 with J2SE 5.0

18:47 andyf: makes sense. UTF-16 had no reason to be created yet when Java began.

18:48 justin_smith: and I also just learned that "modified utf8" has a specific definition, relating to BOM handling

18:48 weird

18:51 amalloy: man, i learned it back when it was UCS-2, and i just can't erase that factoid even though it is obviously impossible

18:51 [blake|: I'm trying to save a field as a blob in Monger and not having any luck. It doesn't help that all the GitHUb URLs contain "blob", though.

18:52 andyf: Clojurebot: brainwash amalloy to the ways of UTF-16 by spamming him every 24 hours

18:52 [blake|: It's not great that "Monsters vs Aliens" has a General Monger and Bob the Blob, either. >:-{

18:53 justin_smith: haha

18:53 amalloy: amalloy: java |uses| UTF-16

18:53 You don't have to tell me twice.

18:53 andyf: lol

18:53 gfredericks: clojurebot: scala |uses| UTF-17

18:53 clojurebot: 'Sea, mhuise.

18:54 justin_smith: lol

18:54 andyf: and UTF-17 has mutable and immutable interfaces

18:54 EvanR-work: UTF-16++

18:54 gfredericks: (inc andyf)

18:54 lazybot: ⇒ 21

18:54 amalloy: i wanted to say "Ik berjikp" but i couldn't remember how clojurebot spells that

18:55 gfredericks: andyf: I've always like the idea of numbers being mutable

18:55 amalloy: "Ik begrijp", apparently

18:55 gfredericks: amalloy: functionally identical

18:55 andyf: gfredericks: Because you like to make Plato spin in his grave?

18:56 amalloy: clojurebot: Ik begrijp is not easy to spell

18:56 clojurebot: Alles klar

18:56 justin_smith: gfredericks: I had to google and double check, but I am really glad scala falls short of that measure of insanity

18:56 gfredericks: Mutable Platonic Forms

18:56 andyf: gfredericks: It will be a little while yet, but I'm finally on the way to implementing specially-formatted comments in Eastwood that disable specific warnings.

18:56 justin_smith: gfredericks: play-doh-nic forms?

18:57 gfredericks: andyf: justin_smith: https://github.com/gfredericks/flexnum

18:57 andyf: w00t w00t

18:57 andyf: I went with the specially formatted comments, because I can sleep at night knowing they will never affect generated code.

18:57 until some other tool starts using comments for code generation

18:58 EvanR-work: gfredericks: im now having ruby flashbacks

18:58 amalloy: andyf: what's wrong with the obvious approach of like (defmacro eastwood-annotation [annotation form] form)?

18:58 gfredericks: EvanR-work: should I put a trigger warning in the README?

18:59 andyf: ultimately anything can affect anything; you can't get away from it

18:59 andyf: amalloy: Probably nothing, except the need to define that macro wherever you need it, or require/use a lib

18:59 gfredericks: amalloy: I had always thought metadata was the obvious not-yet-thought-out solution

19:00 pre-hammock

19:00 amalloy: man, maybe it is. i just don't really reach for metadata often (ever)

19:00 andyf: I don't claim my hammock has the same qualities as Messr Hickey's, but once I figured out how to modify tools.reader to remember the contents of comments and every other form, with source code locations, I was happy.

19:01 gfredericks: amalloy: definitely doesn't have the import drawbacks andyf just mentioned

19:02 wei: djames: your solution re: compiling java sources works for me, thanks!!!

19:02 sorry for the late response. I stepped out for a bit

19:02 gfredericks: amalloy: feels like metadata is great for not having to use magic-comments in particular

19:02 like, in lots of scenarios, not just eastwood

19:02 djames: wei: did you see the suggestions from Stuart Sierra and the mailing list post?

19:03 amalloy: gfredericks: i have a vague worry about macros that inspect metadata and blow up when there's something there they don't like

19:03 andyf: gfredericks: magic-comments have the potential benefit over metadata of annotating things that can't have metadta

19:03 amalloy: and also that

19:03 andyf: Not sure if I'll ever use that, though.

19:03 djames: in short, it is still possible to use dev/user.clj if you are careful about what it requires

19:03 wei: ^

19:04 gfredericks: andyf: magic comments via ;; don't obviously annotate anything in particular though

19:04 andyf: I just need to qualify magic-comments for Eastwood with a prefix like "This-comment-is-special-to-Eastwood-so-keep-your-hands-off-if-you-aren't-Eastwood: "

19:04 gfredericks: I don't want to put a keyword on its own line just so I can put a ;; on the previous line

19:05 andyf: that sounds like exactly why metadata can have namespaced keywords :P

19:05 amalloy: gfredericks: you can't annotate keywords with metadata anyway

19:05 justin_smith: gfredericks: clearly the solution is a magic comment written in a morse code realized using zero width whitespace and BOM

19:05 gfredericks: amalloy: yeah that's why I used that

19:06 andyf: My current implementation is "a magic comment always annotates the next expression in the source code"

19:06 gfredericks: amalloy: keywords are the only thing that can't take meta that I can imagine worth linting

19:06 andyf: whether that next expression is a keyword, number, parenthesized expression, etc.

19:06 gfredericks: and probably only the "this keyword looks like a typo" linter

19:07 amalloy: gfredericks: (+ 1 ^:eastwood/should-be-zero 0)

19:07 then the linter can let you know if you accidentally put in a non-zero number

19:07 gfredericks: amalloy: oh yeah well that's a good example actually

19:07 amalloy: no wait

19:07 isn't the linter really applying to the whole (+ ) expr?

19:07 a 0 by itself is not suspicious

19:08 amalloy: gfredericks: it's a totally nonsense linter anyway

19:08 wei: djames: not clear on what user.clj is for anyways. i just added a support namespace that basically does the same thing

19:08 andyf: I'm not sure the ability to annotate individual keywords, numbers, etc. is something that Eastwood will actually take advantage of, but we'll see.

19:08 gfredericks: amalloy: dunno adding zero seems worth linting, aside from infrequency concerns

19:08 amalloy: i was suggesting a new linter for checking that the only thing you annotate with :eastwood/should-be-zero is 0, not that all 0s are annotated

19:09 djames: wei: it is just a convenient way to have functions available in the user namespace (that's how I see it). why it loads first is unclear to me, as a design decision.

19:09 gfredericks: user.clj is usefully for haxing in specific situations

19:11 andyf: Is anyone aware of any Clojure-verse tools that use magic comments yet?

19:11 gfredericks: my new project called eastwood-the-linting-tool-that-andy-fingerhut-made-not-garys-thing does

19:13 andyf: we should probably coordinate on magic comment syntax, then :)

19:14 We can divide it in half. You take all of them whose UTF-16 encoding starts with a bit of 1.

19:14 gfredericks: I'll take all the comments whose SHA512 hashes start with 1

19:14 andyf: much better

19:14 djames: andyf: I couldn't think of anything, but I started digging re: clojure and magic comments. Found this: http://gorilla-repl.org/start.html

19:14 gfredericks: in UTF-17

19:15 does lein-oneoff use magic comments?

19:15 for dependencies?

19:15 maybe it was a #_ comment

19:15 andyf: djames: Thanks. I do recall seeing an example save file for a gorilla repl document before, and noticed that, but had forgotten.

19:15 wei: djames: I need the helper functions in my uberjar, anyways. i don’t think user.clj is included

19:16 djames: wei: if you are curious about uberjars, dependencies, and profiles, it helps to dig around in the lein source code

19:16 I often forget what gets pulled in :)

19:19 andyf: Future non-documentation: "In order to prevent accidentally writing a comment that affects Eastwood behavior, all magic comments that Eastwood pays special attention to must be written in the form of Clojure code Quines, containing the string "lint-config", and have a SHA512 equal to 0"

19:19 gfredericks: the whole sha?

19:20 andyf: Well, to keep the probability of accidents low, you know

19:20 For all practical purposes, that feature is already implemented :)

19:21 Submit a bug report for this feature and win the awe and amazement of coders everywhere.

19:24 djames: Are there other libraries like this -- perhaps more widely used? https://github.com/konrad-garus/yaclot

19:25 I like that the library above uses `convert` in a way roughly similar to `into`.

19:44 kenrestivo: i'd look in crossclj.info . that's been by far the best resource i've found for evaluating libraries

20:09 dnolen_: http://swannodette.github.io/2015/01/02/the-essence-of-clojurescript-redux/

21:40 djames: If I was designing a code base with a bunch of vars (from def and defn) and wanted to encourage/allow redefinition of any of them, is it best that I mark them as dynamic?

21:41 This would not be a typical application ... one that encouraged extensibility (like Emacs for example) and trusted users to do whatever.

21:41 justin_smith: djames: better to explicitly pass the state rather than redefine top level vars I think

21:42 would you want the vars to take on unique per-thread values?

21:42 djames: justin_smith: I figure the end user might want to redefine anything (at their peril of course)

21:42 I don't think I care about per-thread bindings

21:43 justin_smith: well, don't make it dynamic if you don't care about per-thread bindings

21:44 djames: justin_smith: I get that binding makes a thread-local binding

21:44 what's the mechanism by which redoing a `def` would work?

21:44 justin_smith: alter-var-root

21:44 djames: because, if I understand it correctly, all threads will pick up the new value

21:44 justin_smith: or just calling dif again

21:44 *def

21:45 djames: justin_smith: right, but under the hood, what guarantees should I expect about threads accessing the root binding?

21:45 the root binding is checked with every access if I remember correctly

21:45 (with every var access)

21:45 justin_smith: unless you capture the value (via let or whatever)

21:46 djames: so IF (a big IF) I'm worried that different threads might read different versions of the var value (as it is changing), then I might be in trouble?

21:47 it that is the case, I should use a "proper" reference type (I'm speaking out loud here)

21:47 justin_smith: it will be altered atomically, but if you need any sort of consistancy between threads, yeah that's messy

21:47 djames: justin_smith: cool, thanks for discussing. I seem to pick up new and interesting angles on things that I never wondered about before on here

22:29 justin_smith: lein do clean, check, eastwood, test, run

22:32 gfredericks: :aliases {"dccetr" ["do" "clean," "check," "eastwood," "test," "run"]}

22:33 justin_smith: that's a good idea

22:33 gfredericks: I like those kinds of aliases they're easy to remember and never collide

22:34 justin_smith: gfredericks: I could translate it phonetically to "lein decatur"

22:34 gfredericks: but then someone would need to come up with "lein urbana" and "lein chicago" to top that

Logging service provided by n01se.net