#clojure log - Jan 06 2015

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

0:06 luxbock: it doesn't appear to be possible to get the source for functions defined at the REPL

0:06 I thought I could read them from the :file key of the meta data of the function

0:10 rritoch: luxbock: Try (meta (var myfun)) That has the file

0:12 luxbock: rritoch: I can find the file, but it doesn't appear to contain the function definition

0:17 rritoch: I see.. w/ (slurp (:file (meta (resolve (symbol "myfunc"))))), it is one complex construct

0:18 luxbock: rritoch: yeah, I couldn't see anything related to my function definition at all in there

0:19 looking at nREPL docs right now to try to understand everything better

0:36 arrdem: cfleming: rofl thanks for that

2:36 black-bonzo: Hi, I've got a question w.r.t Leiningen - is it possible to detect what kind of build is actually being done (like ":dev", ":production", etc.) and act accordingly?

2:36 jayp912: ,(var foo)

2:36 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:37 jayp912: ,(try (var foobar) (catch Throwable t "caught"))

2:37 clojurebot: jayp912: Gabh mo leithscéal?

2:37 jayp912: What?

2:37 clojurebot: What is 2d6

2:37 black-bonzo: I mean, I'd like to achieve something like "conditional compilation" where, for example, when doing "devolopment" build I'm using one kind of resources (ex. translation files) and when doing "production" using completly different one

2:38 jayp912: I dont know

2:38 You tell me

2:38 Can some one help me? This might be stupid? How do I catch a failing (var x) invocation? (try (var foobar) (catch Throwable t "caught")) doesn't seem to work.

2:40 luxbock: jayp912: I think you'd need to use a macro

2:40 jayp912: black-bonzo: there is #leiningen i believe if you can't get an answere here. I am unable to help sorry.

2:41 luxblock: I am writing a marco where I want to convert the param to a var, but if it fails, I get an uncatchable exception it seems.

2:41 black-bonzo: jayp912: thanks, I'll look around there

2:42 luxbock: jayp912: could you use `resolve`?

2:42 ,(resolve 'foobar)

2:42 clojurebot: nil

2:42 luxbock: ,(resolve 'map)

2:42 clojurebot: #'clojure.core/map

2:43 jayp912: i think that might work lux

2:43 lemme see

2:44 however, i would still like to know how one catches a failing (var x) invocation.

2:44 there has to be a way of course. i just cant seem to get to it now.

2:45 luxbock: jayp912: it's not the var that's failing but its arguments

2:45 jayp912: ,(def foo 1) (var foo)

2:45 clojurebot: #'sandbox/foo

2:45 jayp912: ,(def foo 1) (var foobar)

2:45 clojurebot: #'sandbox/foo

2:46 jayp912: luxbock: dont understand you

2:46 ,(var count)

2:46 clojurebot: #'clojure.core/count

2:46 jayp912: ,(var county)

2:46 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: county in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:47 jayp912: in this case, var fails right?

2:47 i want to catch that

2:47 luxbock: ,(try (map not-defined [1 2 3]) (catch Throwable "Catched"))

2:47 clojurebot: luxbock: It's greek to me.

2:48 luxbock: hmm

2:48 jayp912: Throwable t

2:48 luxbock: ##(try (map not-defined [1 2 3]) (catch Throwable "Catched"))

2:48 lazybot: java.lang.SecurityException: You tripped the alarm! catch is bad!

2:48 luxbock: ,(try (map not-defined [1 2 3]) (catch Throwable t "Catched"))

2:48 clojurebot: luxbock: excusez-moi

2:48 jayp912: ,(try (map not-defined [1 2 3]) (catch Throwable t "Catched"))

2:48 clojurebot: jayp912: Titim gan éirí ort.

2:48 jayp912: haha

2:49 it seems like clojurebot don't like catch

2:49 luxbock: yeah, it works in my REPL

2:49 jayp912: ,(try (throw (Exception. "foo")) (catch Exception e "caught"))

2:49 clojurebot: jayp912: Cool story bro.

2:49 luxbock: anyways it would not catch it

2:49 because the problem is not with map, but with its arguments

2:50 the fact that not-defined is not defined

2:50 jayp912: ahh i see

2:50 cfleming: arrdem: I thought you'd like that.

2:50 jayp912: i get it.

2:50 thanks luxbock

2:50 luxbock: np

4:36 black-bonzo: well, apparently there's hardly anybody in #leiningen, so I'' repeat my question: is it possible to detect what kind of build is actually being done (like ":dev", ":production", etc.) and act accordingly?

5:03 Fender: i am not 100% sure but I think I saw something like that in the environment variables

5:05 check (System/getenv)

5:05 ,(System/getenv)

5:05 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.*")>

5:24 llasram: black-bonzo: That's what Leiningen profiles are for

5:24 But they work they other way around -- instead of having code which detects whether certain profiles are active, you have the profiles just specify what should be different

5:28 black-bonzo: Additional, in my experience, trying to replicate a per-process "environment" state in Clojure is a path to tears

5:29 In a standard Clojure development process you tend to have a single persistent JVM in which you (at the very least) want to both run a dev REPL and unit tests

5:29 black-bonzo: llasram: yes, I know of Leiningen profiles, but actually, I'd like to be able to detect "mode" I'm running in,

5:30 llasram: black-bonzo: My contention is that you really, really in fact do not :-)

5:30 What's the concrete effect that you're trying to achieve?

5:30 black-bonzo: of course, I can do it manually by switching some var (and using macros), but then I've actually got two compilation tools - Leiningen and my sort-of-tool

5:31 llasram: I'm writing an ClojureScript app,

5:32 and depend on mode (dev vs production) I'd like to be able to use different resources (like strip some unnecessary files from production build, etc.)

5:33 llasram: right now, of course, I can have some "toggle" in which I can specify what is my desired mode,

5:34 llasram: Yeah, so each Leiningen profile can have a sepearate set of paths for everything you can specify a a path for -- source, resources, etc

5:34 black-bonzo: but then I'd have to actually manually change my source file (at least in one place - where this "knob" resides) to achieve desired result

5:34 llasram: You just specify dev-only resources in the :dev profile, and/or production-only in :production, etc

5:35 black-bonzo: Then you should. My contention is that the "environment" like you want is state, and in Clojure you need an explicit mechanism to communicate that state

5:35 black-bonzo: llasram: OK, that would work for resources - but what about changing actual behaviour of code (ex. to inline some files in production profile)?

5:37 llasram: I'm not quite following "inline some file" -- that sounds like a build option, which sounds like something which would already be specified in your Leiningen project file anyway?

5:38 black-bonzo: llasram: that's one possibility and maybe the most appropriate - but then I could end up with production build that doesn't actually contain everything I want and, moreover, manually changing some knob in code seems kinda un-elegant

5:41 llasram: I get that it seems less convenient, but IMHO getting rid of implicit state almost always makes things *more* elegant :-)

5:42 As an in-between, you can use Fender's suggestion of environment variables with https://github.com/weavejester/environ

5:43 So you can use environment variables to communicate settings from Leiningen profiles to arbitrary code

6:00 black-bonzo: llasram: by "inlining some file" I meant that in dev mode I can use normal CLJS map but in production, I'd like to be able to "render" it to JSON and "inline" (put to the output .js file) it

6:32 hyPiRion: black-bonzo: did you get an answer to the question you posed in #leiningen?

7:52 the-kenny: Hey! We're trying to make our Clojure application which is using stuartsierra's component-library uberjar-compatible. For some reason 'lein uberjar' is failing with NoClassDefFoundError on com.stuartsierra.component.Lifecycle.

7:53 Our -main is in foo.core which is (:gen-class)'d and :aot'd

7:54 One google result suggested adding (:gen-class) to every component-ns, but that didn't do anything for us.

7:59 martinklepsch: whats a sane way to test async retries? the function to test returns immediately — currently I just do (Thread/sleep 100) and use super small retry intervals but it feels dirty

7:59 https://gist.github.com/martinklepsch/dbcc7702b36b7e879419

8:03 the-kenny: Hm, I found a hacky solution to my problem: Add com.stuartsierra.{component,dependency} to :aot in leiningen. Quite ugly, imo :/

8:17 OscarZ: how many years does it usually take to master paredit?

8:22 mearnsh: if master means fluent usage of paredit-convolute-sexp, i don't know

8:23 but i got most of it comfortable within a few days

8:39 OscarZ: mearnsh, omg.. i think i managed to remove some parentheses :) there is hope..

8:45 mearnsh: hehe it'll soon be second nature

8:45 OscarZ: now i messed up my whole file...

8:46 atankanow: OscarZ: i have the hardest time dealing with accidental parens in paredit

8:46 mearnsh: yeah don't do that

8:46 atankanow: not sure what i'm missing ... most other things i'm fine

8:46 OscarZ: if i have something like ()defn foo x []

8:46 how can i spread the () around the function ?

8:46 atankanow: ctrl + shift + )

8:47 dysfun: how 'heavy' are refs?

8:47 atankanow: does anyone use smartparens insted of paredit?

8:47 *instead

8:47 dysfun: i'm guessing on the read front, presumably a pointer deref or similar

8:48 OscarZ: atankanow, ive tried but nothing happens.. hmm maybe its the keyboard layout.. normally to get ) i need to press shift + 9

8:48 mavbozo: ,(import javax.xml.bind.DatatypeConverter)

8:48 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

8:49 mavbozo: is this one of the right way to create byte array from string?

8:49 ,(byte-array (map byte "mavbozo"))

8:49 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

8:50 AWizzArd: dysfun: refs are basically just a (mutable) box around a (typically/possibly immutable) object.

8:50 OscarZ: i might as well type with my feet..

8:50 mavbozo: atankanow, i us smartparens too

8:50 *use*

8:51 dysfun: AWizzArd: what i mean to ask is "is it reasonable to create hundreds of thousands of them when working with large interdependent data?"

8:53 atankanow: OscarZ: I just hold ctrl + shift and hit 0 a few times to slurp the parens forward around the forms i need

8:54 OscarZ: maybe it's a keyboard layout difference like you said

8:54 AWizzArd: dysfun: when this is your usecase, then yes.

8:54 OscarZ: hmm nothing happens.. ill try to change the mapping

8:54 dysfun: cool :)

8:54 AWizzArd: dysfun: when you have objects in memory that have to cooperate, then you possibly want to use refs and the STM implementation.

8:55 In practical real-world apps this job is often forwarded to some external DB system.

8:55 dysfun: yes. it's actually a big nested map, so i was wondering whether i actually just want an atom

8:56 AWizzArd: dysfun: possible

8:56 dysfun: however, remember that you may only read one single time from an atom during a transaction.

8:56 OscarZ: wow.. the parens moved.. but only to the end of row? can i just keep on expanding on next rows ?

8:57 atankanow: OscarZ: yup

8:57 AWizzArd: For a (let [x (atom {:a 1, :b 2})] …) you can not do something such as (+ (:a @x) (:b @x)).

8:58 dysfun: AWizzArd: so what's the practical impact of this? no speculative execution?

8:59 AWizzArd: dysfun: the challenge here is that x might be modified during your execution of +.

8:59 arrdem: 'morning

8:59 AWizzArd: When a and b represent the money in the bank accounts of two people, and a sends money to b, then before and after this transfer the sum a+b should be the same.

9:00 dysfun: oh right, sorry, i see what you mean

9:00 AWizzArd: But it’s possible that the amount of a is read during the + operation, but changed before the end of that operation. The resulting a+b will not be consistent.

9:01 So, when using an atom you are forced to put all your transactions into singular functions. Function calls can not share a transaction state.

9:01 Refs however do, because they can only be modified in (dosync …) blocks, which merge.

9:03 dysfun: right

9:03 i think i see

9:03 AWizzArd: A map from which you want to read more than exactly one time per logical program unit, or to which you want to write, should better be placed in a ref.

9:04 You can play with atoms of course, but you must put all your transaction logic into the function that you pass to swap!.

9:04 Whatever that FN does is safe.

9:05 dysfun: i think that's acceptable in this use case

9:06 OscarZ: yeah i think it was a keymap issue... i took small steps towards sanity

9:18 irctc: does someone know how I can add points to an incantor scatter plot in a different color while maintaining point size

9:19 I have 2 data sets, [x1 y1] [x2 y2]

9:19 I want to display them in a scatter plot, both in different colors

9:56 craigglennie: I have 2 lein projects, project-1 and project-2. project-2 depends on project-1, but I can’t figure out how to get that to work. I know next-to-nothing about JARs or Maven, but I think I need to use lein’s “checkout dependencies”. Does that sound right?

9:56 Do I need to build a jar or anything to get project-2 to be able to import project-1? Or do anything with the class path?

9:57 I had hoped I could just add the namespace to :dependencies and create a symlink to the root of project-1 in the checkouts folder

10:00 luxbock: craigglennie: you can use `lein install` on project-1 and then it should work as a dependency for project-2

10:02 justin_smith: craigglennie: if you look up "lein checkout" there is a system that works with symlinks

10:03 craigglennie: justin_smith: Yes, that’s what I’m trying to use. I think I have it working now - I had missed doing “lein install”, per luxbock

10:05 justin_smith: no, lein install is an alternative to checkouts

10:05 the point of checkouts is you can simply make changes in the checked out project, without having to do another install / restart to see them

10:05 the killer being the fact that you don't see the changes without a full repl restart

10:12 stuartsierra: I think you still have to `lein install` the first time before checkouts will work.

10:12 craigglennie: justin_smith: Oh, that’s what I want. This part of the checkouts doc made me think that I still needed to do “lein install” when it couldn’t find my project. "After you've updated :dependencies, lein will still need to be able to find the library in some repository like clojars or your ~/.m2 directory. If lein complains that it could not find the library artifact, you can install it locally by running lein install in the checkout dependency

10:12 project directory."

10:16 justin_smith: oh, I see

10:16 thanks for the clarification

10:17 gfredericks: ,(rand-nth ())

10:17 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

10:17 gfredericks: &(rand-nth ())

10:17 lazybot: java.lang.IndexOutOfBoundsException

10:17 gfredericks: &(rand-nth nil)

10:17 lazybot: ⇒ nil

10:17 gfredericks: w00t

10:18 Bronsa: ,(nth nil 0)

10:18 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

10:18 Bronsa: &(nth nil 0)

10:18 lazybot: ⇒ nil

10:18 gfredericks: (dec clojurebot)

10:18 lazybot: ⇒ 45

10:18 Bronsa: &(nth () 0)

10:18 lazybot: java.lang.IndexOutOfBoundsException

10:18 Bronsa: weird justin_smith

10:19 justin_smith: ?

10:19 Bronsa: gfredericks* :P

10:19 gfredericks: (inc justin_smith) ;; for being a drop-in replacement for me

10:19 lazybot: ⇒ 165

10:19 craigglennie: stuartsierra: Yup, the first “lein install” seems to be necessary, then it picks up changes after that

10:34 zot: i have a dumb interop question. i'm sure it's obvious, but it's my first time at this, and despite having the interop page open, i can't figure out what i've got wrong here. any clues: https://gist.github.com/anonymous/c3348aaa399d29dae411

10:34 (reflection error included in the gist)

10:35 justin_smith: zot: well, that's not an error, just a warning that it can't resolve that method lookup

10:35 are you sure you have the exact args?

10:35 zot: yes, sorry, that was misspoken. but i like warning free compilation :)

10:35 justin_smith: (because the hinting would prevent that warning otherwise)

10:36 zot: ahhhhhhhh

10:36 justin_smith: anyway, I think the key is hinting the arg

10:36 zot: i get it. i didn't type hint the argument.

10:36 bingo

10:36 thanks!!!

10:36 (inc justin_smith)

10:36 lazybot: ⇒ 166

10:36 justin_smith: you shouldn't even need to hint the object itself, since the creation is unambiguous and in-scope

10:37 np

10:37 zot: yeah, that was leftover from being absurdly pedantic, trying to understand

10:37 CookedGryphon: zot, if you're doing a lot of this try eastwood linter

10:37 zot: i thought the string would be obvious too, but i now see why, as it's generated in a threaded macro

10:38 CookedGryphon: it will give you a much better message for what you have done wrong, and more importantly it will pick up on some instances where a type hint actually isn't doing any good

10:38 zot: CookedGryphon: tnx, will check it out

10:56 CookedGryphon: in core.async, what's the best way to "drain" a channel

10:56 as part of my shutdown process, I want to close a number of channels, but make sure they've processed everything that's queued up first

10:56 so take everything that doesn't park, then close and drop out

11:00 dysfun: is there a drop-in replacement for update-in that accepts numeric indices?

11:01 Glenjamin: ,(update-in {0 1} [0] inc)

11:02 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

11:02 Glenjamin: &(update-in {0 1} [0] inc)

11:02 lazybot: ⇒ {0 2}

11:02 dysfun: sorry, i meant so that i can use it with vectors

11:02 i have a nested data structure with both vectors and maps

11:02 i can figure out how to implement it fairly easily, but it seems like someone must have done it already

11:04 Glenjamin: &(update-in [1 2 3] [1] inc)

11:04 lazybot: ⇒ [1 3 3]

11:04 dysfun: oh. why doesn't the documentation say that then?

11:04 Glenjamin: (doc update-in)

11:04 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")>

11:04 * Glenjamin slaps clojurebot

11:04 Glenjamin: &(doc update-in)

11:04 dysfun: heh

11:04 lazybot: ⇒ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

11:05 Glenjamin: &(associative? [])

11:05 lazybot: ⇒ true

11:05 Glenjamin: it sort-of does :)

11:05 dysfun: oh, right. i took that to mean 'looks like a map'

11:10 csd_: How can I convert an BigInteger to a byte array?

11:17 andyf__: csd_: BigInteger?s toByteArray method looks like it should do the trick: http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#toByteArray()

11:17 Might want to ensure the number is positive if you don?t want to deal with negative 2?s complement representation

11:18 EvanR-work: any idea how to get java docs and possibly java source code to work in fireplace? or just in any easy way besides intellij?

11:18 csd_: andyf__: thank you

11:19 stuartsierra: EvanR-work: clojure.java.javadoc/javadoc ?

11:20 EvanR-work: truly boss

11:22 what about source code?

11:23 stuartsierra: EvanR-work: dunno. Theoretically possible if the source JARs are in a Maven repo, not sure if anyone's written it in an IDE-independent way.

11:27 EvanR-work: the key combo for jump to source works for clojure names but not java, "source not found" so maybe i didnt download the source jars

11:28 ah i see "local maven repo"

11:30 andyf__: When extending a protocol to a class, is there a way to name 'array of primitive double' in the extend form other than (Class/forName "[D") ?

11:31 Glenjamin: it's something like "doubles" iirc

11:31 mdrogalis: Has anyone here used something like http-kit or Netty in a very high performance situation? In terms of number of requests/responses per second.

11:31 andyf__: Glenjamin: That works for metadata type tags, like ^doubles, but not for extend

11:31 Glenjamin: ah

11:31 :(

11:32 andyf__: probably because doubles is also the name of a function, and extend doesn't have special case code for recognizing such a name.

11:34 llasram: andyf__: I don't believe so; the Class/forName is what I do FWWIW

11:35 justin_smith: mdrogalis: doesn't http-kit use netty under the hood?

11:36 llasram: justin_smith: nope -- just nio

11:36 mdrogalis: justin_smith: Nope

11:36 In any case, I'm just trying to get a feel for how people are making these things top out in terms of performance.

11:36 llasram: It includes netty in the project file in the dev profile, which has injected confusion, but I believe just for benchmarking

11:37 mdrogalis: I hear benchmarks like hundreds of thousands reqs/s, but I don't know how to achieve that.

11:37 justin_smith: llasram: mdrogalis: it has netty as a dep in its project.clj

11:37 andyf__: llasram: Thanks. Looks like a tools.analyzer enhancement request coming up not to warn about those.

11:38 llasram: justin_smith: set... aaand match

11:38 justin_smith: (see previous message)

11:40 justin_smith: llasram: ahh, you're right, it is only used in the tests

11:41 mdrogalis: you get benchmarks like that by serving static data out of memory for a contrived benchmark, with no calculation or allocation of objects :)

11:43 mdrogalis: justin_smith: Ha, makes sense :)

11:43 justin_smith: Yeah, I see https://github.com/ptaoussanis/clojure-web-server-benchmarks

11:44 It's just returning the request as the response.

11:44 Still, closing in on 500k requests/s is nuts.

11:45 justin_smith: yes, it proves that the server itself won't likely be your bottleneck

11:46 the hard part is how to actually do any work and still get decent throughput

11:47 EvanR-work: in this benchmark game, they at least serve a static file http://snapframework.com/blog/2010/11/17/snap-0.3-benchmarks

11:47 mdrogalis: justin_smith: Fact

11:47 EvanR-work: all you can derive from it is that rails is really bad

11:47 justin_smith: EvanR-work: which you load into memory once, and after that you are in the same position as the handler that sends the request back unchanged

11:48 EvanR-work: yeah, one of those cases where the server actually does end up being a bottleneck

11:48 EvanR-work: yes

11:49 the fact that the OS is having your common files in memory for you means the web server better not be getting in the way ;)

11:49 thats an automatic speed boost

11:50 would be nice if given a benchmark you could at least get one nugget of useful information out, about something

11:52 csd_: andyf__: one more question. do you know how I can convert the data in java.util.Base64$Encoder to string? The encodeToString method doesn't work; nor does trying to construct a String as I saw some sample Java code do.

11:54 andyf__: csd_: Not off hand, and not obvious to me from a quick perusal, but maybe someone else can shed some light. Is there a .toString() method?

11:55 csd_: According to the docs, there is an .encodeToString method but when I try to use it, java complains that it can't find it.

11:59 TimMc: Link to doc?

12:00 csd_: https://docs.oracle.com/javase/8/docs/api/java/util/Base64.Encoder.html

12:01 TimMc: You don't want that method anyhow. "by using the encoded byte array and the ISO-8859-1 charset"

12:01 stuartsierra: charset shouldn't matter for a string of ASCII Base64 characters

12:04 (.encodeToString (java.util.Base64/getEncoder) (byte-array [1 2 3 4]))

12:05 You can't construct java.util.Base64$Encoder directly.

12:05 EvanR-work: theres no brain-dead base64 encode decode snaz ?

12:05 TimMc: Oh, it's encoding to base64, right. :-)

12:06 csd_: stuartsierra: I see, I had been using .encode and then trying to convert its result.

12:07 What would someone end up using just .encode for?

12:07 stuartsierra: I see, I had been using .encode and then trying to convert its result.

12:07 What would someone end up using just .encode for?

12:08 stuartsierra: Maybe they want bytes, and returning a string would be an unnecessary conversion to UTF-16.

12:08 csd_: I couldn't even figure out how to extract the bytes out

12:10 EvanR-work: ,(.getBytes "abcd")

12:10 clojurebot: #<byte[] [B@14f34bd8>

12:11 EvanR-work: when dealing with byte arrays, anything to do with strings is going to involve encoding and decoding, perhaps needlessly

12:11 csd_: How would you use that in practice? Just IO?

12:11 EvanR-work: use what

12:11 csd_: the result of (.getBytes "abcd")

12:12 I haven't done much with byte arrays

12:12 EvanR-work: yes some apis expect you to provide a byte array or give you a byte array

12:13 if its text data and you need to process it like text, you basically have no choice but to convert to/from a string

12:14 base64 however encodes a byte array as text that does not need unicode so it could in principle stay as a byte array

12:14 csd_: I find the java interop stuff to be much trickier & more frustrating than pure clojure

12:15 EvanR-work: a byte array is a nice type to have in general, it just happens that means java here instead of pure clojure

12:17 ok i managed to download most of my java source jars with maven, and i managed to browse the code manually with vim (without extracting the jars), and i see a way to use ctags with it by unpacking the sources myself

12:17 and thats all im willing to do for now ;)

12:20 dweave: what is the canonical way to query the state of some running process. Say I have a compojure app that needs to look at some ref in another namespace

12:20 i’m probably not thinking about it in the correct clojure way

12:21 but in OO this would just mean having some stateful object

12:21 Chousuke: just deref it?

12:21 then you can look at it all you want

12:21 weavejester: dweave: I'm not sure what you mean by "query the state of some running process"

12:21 EvanR-work: and control K already freakin does (javadoc x) and i didnt even realize

12:21 ssideris: dweave: but do you really need state?

12:21 EvanR-work: er shift K

12:22 dweave: say i have some realtime app that is stateful. like a real time poll or something

12:22 phillord: CinfojBaj3

12:22 dweave: I need to (deref current-top-category)

12:22 or something like that

12:22 ssideris: phillord: password? ;-)

12:22 dweave: how to i expose current-top-category

12:22 phillord: bugger

12:23 ssideris: dweave: just by having it be public in its namespace

12:23 in other words, just def it

12:23 dweave: ok

12:23 EvanR-work: dweave: a "stateful" app which continuous polls (without doing anything with it unless someone also polls) seems kind of weird

12:23 dweave: well it’s just an example

12:23 people could be voting

12:24 ssideris: dweave: but chances are, in many cases where you think you need state, you actually don't

12:24 EvanR-work: a running process that is serving requests right, this "query its state" is just another kind of request ?

12:24 dweave: EvanR-work what do u suggest then

12:24 EvanR-work: i thought you already had this set up

12:24 dweave: i think ur taking query literally?

12:24 i just want to inspect a variable

12:25 no i don’t have that set up

12:25 EvanR-work: i thought you meant you have a demon or server running

12:25 or thread

12:25 dweave: my actual use case is more complex

12:25 Chousuke: to inspect a variable, you just do it :P

12:25 dweave: and i’m investigating

12:25 Chousuke: there's nothing to it

12:25 granted, you don't want to store all your mutable state in separate refs or atoms.

12:25 arrdem: step 1 - inject an nREPL instance into your app, 2 - boot the app, 3 - connect to the repl, 4 - hack in production

12:26 EvanR-work: for sharing a mutable variable between threads, you can use an atom. but it probably makes more sense to put it all in one atom

12:26 ssideris: dweave: if you absolutely need state, make the variable a public atom, and deref it from any namespace

12:26 Chousuke: in general, the less mutable state you have, the better.

12:26 dweave: agreed

12:27 are there any real applications where there is NO mutable state?

12:27 EvanR-work: yep

12:27 dweave: like what

12:27 a calculator?

12:27 AWizzArd: I would say “no”.

12:27 dweave: i think interaction implies state

12:27 AWizzArd: Hickey himself says that Clojure is not the silver bullet, but instead a useful set of tools.

12:27 dweave: right

12:27 EvanR-work: you implement abstractions on top of something underneath, and the computer has to mutate its registers at some point. you dont have to expose this to yourself or clients of your code

12:28 Chousuke: dweave: not necessarily; if all interactions are independent of others.

12:28 EvanR-work: interaction doesnt imply stateful ness or memory

12:28 TimMc: dweave: In the ideal word, you'd have a big core of logic using immutable data and then a thin wrapper around it that handles any mutation and other side-effects.

12:28 AWizzArd: We need to differentiate between mathematical/theoretical possibilities and real-world applications.

12:28 EvanR-work: the model you are trying to implement might be stateful, either rightfully so or not, and then you just use it

12:28 Chousuke: dweave: like web services or something

12:29 AWizzArd: A big Clojure application without a single atom/agent/ref is hard to imagine. Without any mutable Java objects, such as UI elements or such.

12:29 dweave: TimMc ur talking about the idea of “passing in the state of the world” as a function param right

12:29 Chousuke: you make requests and the output of the request doesn't depend on anything but the request parameters, then any state that you have is incidental, not required.

12:29 +if

12:30 EvanR-work: dweave: thats not the right idea

12:30 AWizzArd: Hickey didn’t provide mutable data structures in Clojure because he believes they are not needed. The opposit is the case. But: making mutation explicit was the goal, and this was reached.

12:31 TimMc: AWizzArd: He did provide them. Refs, vars, atoms...

12:31 AWizzArd: Yes.

12:31 And that was very good.

12:31 I’m arguing that they are used in the real world.

12:31 dweave: EvanR-work not sure what u mean

12:31 TimMc: Namespaces... :-p

12:31 arrdem: TimMc: hehe

12:32 TimMc: anything you can call setAccessible on...

12:35 EvanR-work: dweave: dividing everything into "mutable variables and side effects" and "not" is missing a great many points, and is based on thinking from the former perspective as a default situation

12:37 dweave: hmm I’ll prob just build this out and see what happens

12:39 justin_smith: AWizzArd: there is actually a formal proof that anything you can calculate with mutable state can also be calculated with immutable state + recursion

12:40 *immutable values

12:40 and, more importantly, the immutable version scales with designs more cleanly

12:41 mutability is still an option where performance demands it

12:41 EvanR-work: in fact your runtime environment is almost certainly using it ;)

12:42 justin_smith: EvanR-work: right, the important part is that we can reason about things as if they were truly immutable

12:42 within some reasonable constraints of the abstraction boundary, of course

12:42 EvanR-work: i refudiate abstraction boundaries as much as possible

12:43 justin_smith: quoting Sarah Palin? I'll have to bow out of this one :)

12:44 EvanR-work: somebody had to invent words at some point ;)

12:44 people probably got shit back then too

12:44 AWizzArd: justin_smith: as I said above, on the one hand there is what is mathematical possible, and on the other hand there are real programs.

12:45 justin_smith: AWizzArd: right, and real programs scale more cleanly with immutable values

12:45 and they are free to use mutation where performance demands it, regardless of the language you are using there is a way to do that

12:48 dweave: justin_smith in any of those models that use mutable values there still has to be some impure part of the system that performs side effects no?

12:48 isn’t that what haskell IO monad does

12:49 u can only keep part(s) of your code pure

12:49 justin_smith: dweave: like I said, you can define immutability within some reasonable boundary of the abstraction

12:49 dweave: ah

12:50 so in this case that abstraction is refs, atoms / identities

12:50 ?

12:50 justin_smith: it's also possible to manipulate the value of any "immutable" data structure via reflection. The point is you don't have to, and if you do things sensibly you have an abstraction that makes reasoning about code much easier.

12:50 dweave: the abstraction is immutable datastructures

12:51 refs, atoms, vars etc. are closer to the fuzzy border

12:51 EvanR-work: in a functional program, you will have cpu registers being regularly clobbered, memory being overwritten when not being used, runtime objects having fields memoized, it doesnt mean your should structure your application this way

12:52 justin_smith: exactly. Your function calls are all gotos in the CPU, that doesn't mean you need to use goto

12:52 well, goto plus some stack and register juggling, of course

12:55 EvanR-work: if a webapp responds to requests differently depending on the current snapshot of a database, it does mean the web apps code must necessarily be an imperative program

12:55 does.. not mean!

12:57 the basic alternative is a possibly recursive function, but all kinds of new ideas are coming out all the time with even better alternatives that still present a functional interface but are more natural to describe what youre trying to model

12:58 the book is not closed on this science yet

13:11 mfikes: Are macros expanded in both the then and else branches of an if? I want to understand why (if true (defrecord A [a] ) (defrecord A [b c])) fails in Clojure and appears to take the 2nd definition in ClojureScript.

13:13 rweir: macros are always expanded

13:15 TimMc: mfikes: Probably because CLojure and Clojurescript have different implementations around defrecord and therefore respond differently when you call defrecord twice.

13:16 mfikes: Both branches of the if are expanded and compiled because the compiler can't know which branches will be taken? :-)

13:16 s/?/./

13:16 mfikes: Yes. Compile-time. Right.

13:17 kenrestivo: what's the most straightforward way to have a high-priority thread?

13:18 mfikes: ClojureScript appears to actually be a little strange with that expression. It makes it so (A. 1 2) is well formed but it returns #cljs.user.A{:a 1}, as if the first definition is really in play.

13:18 rweir: what does the thread do

13:18 kenrestivo: ui stuff

13:18 swing, specifically

13:19 rweir: this feels kinda XY-y

13:20 kenrestivo: in more detail, i have an async/thread that is updating the ui (using seesaw invoke-now). it's too slow. trying to find options to get performance without having to rip out core.async (or seesaw) completely

13:21 the actual ui update is very simple, but the latency between when somethign gets stuffed into that channel and when the ui updates is ridicuolous

13:21 justin_smith: kenrestivo: I assume you already tried moving all non-gui work out of the swing thread?

13:21 mi6x3m-alt: kenrestivo: can you explain to me (in a PM perhaps) the scenario

13:21 justin_smith: ahh, so it's not that the GUI is stalling, it's an issue of latency between the command and the result

13:21 kenrestivo: there's nothing going on in the swing thread except alts!!, waiting for something to come in, and displaying it.

13:22 mi6x3m-alt: kenrestivo: why do you even mention swing then?

13:23 justin_smith: kenrestivo: I doubt that prioritizing the swing thread would speed that up much, if at all. Have you profiled?

13:23 kenrestivo: i've run visualvm. maybe i should spend more quality time with it.

13:24 rweir: what to you mean XY?

13:25 TimMc: ~chainsaw

13:25 clojurebot: excusez-moi

13:31 aperiodic: kenrestivo: XY problem: http://mywiki.wooledge.org/XyProblem

13:32 kenrestivo: yeah, in this case the Y is "let's use clojure on a raspberry pi"

13:34 EvanR-work: Y is make a thread higher priority

13:34 according to that link

13:35 aperiodic: hahaha

13:35 kenrestivo: that too

13:35 EvanR-work: that XY problem is composable. X could be the Y in another instance of XY ;)

13:36 kenrestivo: there are many levels of Y here. the digging has gone deep

13:36 EvanR-work: XY problems are arrows in a category where objects are X/Ys ;)

13:36 kenrestivo: recursive XY

13:36 aperiodic: yeah, I dunno if you're gonna be able to eliminate that latency... I've found cljs in node to be way more performant if you want to target the raspberry pi w/clojure, though you have to do a little more fiddling to get the same development experience

13:37 kenrestivo: it's a bit too late, but i did see some posts on running cljs on node and it seems that'd be better for this project.

13:37 kryft: Hmm, does clj-time 0.9.0 work for others? I get an IllegalArgumentException just from adding it to my project dependencies

13:37 I used clj-time 0.9.0 and clojure 1.6.0

13:37 kenrestivo: so i'm left with trying to desperately flail to get what i've got to work, somehow. not a great position to be in. thanks for the help tho.

13:38 EvanR-work: kryft: got 0.8.0 here, works

13:39 kryft: EvanR-work: Ok, that works. Wonder what's wrong with 0.9.0.

13:39 justin_smith: kryft: sometimes after changing a dependency it's neccessary to run lein clean manually

13:39 kryft: justin_smith: I tried that, but still got the exception

13:39 justin_smith: OK

13:39 kryft: (With 0.9.0; 0.8.0 works)

13:44 TimMc: kenrestivo: How do you even get Java running on a raspberry pi? I tried and lein version took about a minute to complete.

13:45 kenrestivo: takes 10 minutes to launch. with the embedded oracle jvm for arm-hf it runs. a uberjar takes about a minute to launch.

13:45 it was not a smart idea, i think i can accept that at this point.

13:45 justin_smith: in core.async, if a (go (while true (f (<! c))) block gets to the point where c is closed, will it go into a busy loop repeatedly operating on nil, or will it get shut down?

13:45 exaptic: kenrestivo: this might be relevant -- i keep wanting to get started with cljs to target all the great js integration available nowadays http://swannodette.github.io/2014/12/29/nodejs-of-my-dreams/

13:46 kenrestivo: yep, node + cljs seems the way to go.

13:46 exaptic: biggest bummer for me looking at cljs from clj is the lack of numeric tower =\

13:46 kenrestivo: i may try it for another project.

13:52 bacon1989: Interesting how most projects these days are web projects

13:52 I wouldn't be surprised if clojurescript started getting even better support than clojure :p

13:53 justin_smith: bacon1989: it's such a ubiquitous platform

13:57 bacon1989: I think it would be neat if a clojure derivative came out that did native compilation

13:57 with a good ffi

13:57 algal: what about https://github.com/pixie-lang/pixie ?

13:58 bacon1989: algal: been looking at racket

13:58 but yeah, I saw that on reddit a few weeks ago, and was interested

14:00 algal: the choice of RPython is interesting. Hadn't heard of it before.

14:00 bacon1989: isn't that what PyPy uses?

14:01 algal: "I implemented Pixie in RPython, which is a subset of Python that can be compiled to C with the PyPy translation tool-chain." from https://medium.com/indie-programming-languages/indie-languages-interview-pixie-and-timothy-baldridge-cadbc36418dc

14:02 bacon1989: but yeah, i've been using clojurescript, and ran into some performance issues. Nothing major, I could change some things to more native javascript

14:02 but it's still a bummer

14:02 maybe if I update the clojurescript build

14:02 to something more recent

14:04 mi6x3m-alt: is it better to put a let outside or in a testing ?

14:04 (let (testing or the other way around ?

14:05 stuartsierra: mi6x3m-alt: In clojure.test ? `testing` is just documentation, doesn't matter where you put it.

14:05 mi6x3m-alt: stuartsierra: no convetion also?

14:05 stuartsierra: I'd rather put it next to the assertions

14:06 after the let

14:06 stuartsierra: mi6x3m-alt: You can put it anywhere, like I said. You can also put documentation strings directly in `is` assertions.

14:07 mi6x3m-alt: stuartsierra: ok, let me reformulate. given 1 functions to-foo which converts a string to foo and a boolean to foo

14:07 I have 2 deftests

14:07 to-foo-from-str and to-foo-from-boolean

14:07 is it better to have 2 deftests or 1 with testings?

14:08 stuartsierra: "better" is subjective. I tend to use more, smaller deftests. Then you can invoke them individually from the REPL.

14:08 exaptic: depends how you want to organize things i suppose

14:08 mi6x3m-alt: stuartsierra: yeah thought so too

14:08 exaptic: same

14:08 mi6x3m-alt: will stick to the current style with 2 deftests

14:08 stuartsierra: I almost never use `testing`.

14:08 mi6x3m-alt: although they both need some context created with let =/

14:09 stuartsierra: mi6x3m-alt: Then factor that context out into a function and call it in each test.

14:11 mfikes: Is there a way for Clojure code to conditionally implement one of two different definitions of a protocol at runtime? (There is a new CLJS REPL IJavaScriptEnv protocol definition: The -setup method has a new arity. In concrete terms, can one codebase dynamically implement either protocol?)

14:12 mi6x3m-alt: mfikes: mmhmm, read on reify

14:12 it handles protocols

14:12 but doesn't sound like a good idea

14:14 dnolen_: mfikes: there is only 1 arity now, realized it wasn't worth it to have 2

14:14 fikusz: 0.0-2665 has the change

14:14 mfikes: oops that was for you ^

14:15 mfikes: dnolen_: Ahh. So my question is now academic :)

14:15 dnolen_: mfikes: yeah all REPLs just have to take opts

14:16 mfikes: and no to your question. I actually realized it was issue when I tried to load AOTed code that implemented only one of the arities

14:18 mfikes: dnolen_: Ahh. OK. I even tried reify in non-AOTed code and, it was a no-go.

14:18 dnolen_: mfikes: huh interesting, it seemed OK at the REPL, but I might have been imagining that

14:19 mfikes: still looking into updating Weasel or doing an iOS native one?

14:19 mfikes: dnolen_: Yes and yes. :)

14:19 dnolen_: mfikes: nice :)

14:25 mfikes: dnolen_: For reference, here is a gist showing the attempt to conditionally reify the old interface and the associated exception: https://gist.github.com/mfikes/06bad1d73057405bd50e

14:37 jjttjj: dnolen_: hey I know this is extremely low priority but just wondering if there's anything else I need to do for my patch here: http://dev.clojure.org/jira/browse/CLJS-936 I'm now on the official contributers list

14:38 dnolen_: jjttjj: nothing to do, thanks for the bump applying now

14:39 jjttjj: dnolen_: awesome, thanks!

14:43 irctc: hey guys! I wrote a function that finds where numbers go from increasing to decreasing in a collection, but its kinda hard to read. Is there a better way to do this? http://pastebin.com/dqb0fST2

14:44 dnolen_: jjttjj: it is done, your plus another patch brings us to 100 contributors to CLJS - not bad!

14:45 irctc: dnolen_: woah thanks for everything you do for clojurescript

14:45 justin_smith: irctc: instead of first + reduce why not use reduced?

14:45 mfikes: Wow. 100 contributors. Nice.

14:46 irctc: justin_smith: hmm ill look into reduced

14:46 justin_smith: irctc: (reduced x) will return x from reduce

14:46 it's pretty simple

14:47 irctc: justin_smith: oh I see

14:48 amalloy: justin_smith: how does reduced help irctc with that function?

14:49 it looks like the reduce is building up a 3-tuple, the first item of which is a list that gets larger

14:50 the real improvement, if i'm reading this right, would be to not use reduce at all, but instead write a recursive function using lazy-seq to produce results on demand

14:52 irctc: amalloy: yeah a lazy sequence of critical points sounds like what I want. I'll try rewriting it with lazy-seq

14:52 amalloy: justin_smith Thanks a bunch!

14:54 [blake|: How, in hiccup, do I get a tag that has no value? I.e., if I want to set a class, I do <<:class "whatever">> but for something like readonly? I can't just put in <<:readonly>> because it's in a map!

14:55 amalloy: [blake|: i think the canonical thing for these toggle-style attributes is to use <a readonly="readonly">, <input checked="checked"> ...

14:56 the shorthand of <a readonly> is a legacy thing, i *think*

14:56 incidentally, irctc, the asymmetry between <= and > makes me think you don't do quite what the docstring says

14:56 because increasing and decreasing should be perfectly symmetrical

14:57 [blake|: irc2c?

14:57 OH. Sorry, you're talking to someone else, and I thought you were using one of those "hep" Internet abbreviations.

14:59 kenrestivo: hep?

14:59 amalloy: kenrestivo: an adjective to describe hepcats

15:00 [blake|: kenrestivo: "Hep", yeah, happening, with it, now...yeah, amalloy has it.

15:00 amalloy: i thought it was quite apropos here, because it's old-fashioned slang to show how out of touch [blake| is with modern internet slang

15:01 [blake|: I'm an "L7".

15:20 TimMc: That's crazy, daddy-o.

15:20 [blake|: Damn beatniks.

15:22 moquist: It's hilarious that "hep" is the new "hip", since "hip" used to be the new "hep".

15:24 TimMc: Alex and I have been reading the Autobiography of Malcolm X and it's fun to hear him describe way he talked in the 1930s.

15:25 moquist: http://en.wikipedia.org/wiki/Hip_%28slang%29#Development <-- in case anyone is curious. Some great lyrics there from Harry "The Hipster" Gibson, circa 1947.

15:25 [blake|: Wait, has "hep" become the new "hip"? That means my irony is fail! (Of course, if you're ironic long enough, you come around to being sincere again. It's groovy.)

15:27 TimMc: #groovy is thataway ->

15:31 That article doesn't give a consistent explanation of hip vs. hep and their etymology.

15:50 [blake|: Wikipedia, man. It's heavy.

15:50 SagiCZ1: i am using the regular JDK that comes from Oracle.. is there anything I could do to make the GC deterministic?

15:52 [blake|: SagiCZ1: JRockit? http://www.oracle.com/technetwork/middleware/jrockit/overview/index-101826.html

15:52 SagiCZ1: [blake|: yeah i was wondering if there was some magic option for the regular jdk that could achieve at least something similar

15:53 amalloy: SagiCZ1: what is your actual goal? a deterministic GC sounds like an XY problem

15:53 [blake|: SagiCZ1: My guess would be no. Usually GC determinism is a Big Deal. Even a Can't Be Done.

15:54 SagiCZ1: amalloy: maybe the gc is not an issue at all.. i just need to send periodic heartbeats over usb very often at a stable period.. currently i am trying to get it down to 5 ms, but every fifth or so message gets held up in java for 20 ms.. i have no idea why so i wondered if it could be gc

15:55 amalloy: you're trying to write a device driver in java or something?

15:55 i mean, yes that probably is gc, and no you probably can't do anything about it

15:55 SagiCZ1: amalloy: is the gc triggered even when the heap is not even close to getting full?

15:55 why

15:56 amalloy: *shrug* the GC works in mysterious ways

15:56 SagiCZ1: :)

15:57 [blake|: Some GCs I've worked with could be tweaked.

15:57 SagiCZ1: btw it is something that probably should be implemeneted as a driver but I wondered if it could be avoided since I don't know how to make drivers

15:57 TimMc: OCaml.

15:58 justin_smith: SagiCZ1: it is possible to make a gc that is more deterministic (though lower throughput) - basically you sacrifice your average time for minimizing worst-case time

15:58 I don't think java really does that though

15:58 SagiCZ1: the strange thing is, that VisualVM shows no GC activity.. i think it might be getting held up by some other mechanism

15:59 justin_smith: could be the OS

15:59 SagiCZ1: yeah

15:59 justin_smith: could be caching

15:59 SagiCZ1: or some buffer

15:59 justin_smith: that is, cache line fill time

16:02 SagiCZ1: i think java can achieve something very close to real time, i just dont know how yet

16:03 [blake|: SagiCZ1: OTOH, device drivers aren't that hard. Just whip out your C compiler and go!

16:04 SagiCZ1: [blake|: the problem is that the potential user could be very reluctant to install drivers vs just running an executable jar with my app.. and bugs in drivers equal BSOD

16:04 cfleming: mfikes: I'm interested to hear about your Weasel/iOS REPL plans

16:05 [blake|: SagiCZ1: Well, sure, it's not for the faint-hearted. =P

16:06 SagiCZ1: i think drivers can achieve better speed because they have higher priority in the system scheduler..

16:06 tbaldridge: SagiCZ1: or if C scares you write that bit in Python, at least then you get the deterministic behavior of a reference counting GC.

16:06 [blake|: Yeah, although you can't necessarily count on the 5ms thing there, either, right? Not on Windows, anyway.

16:07 SagiCZ1: [blake|: dont usb mice get some pretty stunning refresh rate? not sure about the numbers though

16:07 tbaldridge: python scares me more than c!

16:07 tbaldridge: SagiCZ1: 5ms is actually a ton of time. tons of games run at 120 fps, which is about 8ms. And think of all the time spent rendering a single frame on a pc

16:08 SagiCZ1: tbaldridge: yeah.. i would actually be pretty happy about some stable 20 ms.. i think it has to be achievable within java

16:08 tbaldridge: you are most likely creating more garbage than you think, and that's triggering a GC pause

16:08 sure, theres about 200 gc tuning switches for the JVM, one of them should due the trick ;-)

16:09 SagiCZ1: tbaldridge: yeah that was my first guess

16:09 EvanR-work: whats the "best" clojure web server / app thing

16:09 tbaldridge: EvanR-work: define "best"

16:10 EvanR-work: simple, reliable, free

16:10 pick three

16:10 jackhill: Hi, is there a comparison of clojure with kawa and ABCL? i.e. why should I choose clojure over Scheme or Common Lisp?

16:10 hiredman: why?

16:10 clojurebot: hiredman: because you can't handle the truth!

16:10 hiredman: clojurebot: jerk

16:10 clojurebot: you cut me deep, man.

16:11 hiredman: clojurebot: rationale?

16:11 clojurebot: rationale is http://clojure.org/rationale

16:11 EvanR-work: clojurebot: my wife left me

16:11 clojurebot: It's greek to me.

16:11 augustl: what are good ways to deploy a java -jar file for a clojure webapp on an ubuntu server? :)

16:11 jackhill: hiredman: thanks

16:11 tbaldridge: EvanR-work: well it depends. Something like ring, is certainly simple, but also limited in some aspects. Other platforms like http-kit or pedestal have more features and flexability, but are prehaps a bit more complex.

16:11 jackhill: have you seen "Are we there yet?"

16:12 jackhill: also a good rationale to clojure: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

16:12 EvanR-work: tbaldridge: so something like sinatra, it lets you handle the response, and customize aspects of the response if necessary, but sane defaults

16:13 jackhill: tbaldridge: I have not seen "Are we there yet?" Thanks!

16:14 tbaldridge: EvanR-work: I've been told ring is pretty close to sinatra.

16:14 or at least close to a Clojure version of sinatra

16:14 stuartsierra: Including copying its flaws.

16:14 tbaldridge: :-D

16:15 EvanR-work: did it copy rack? no? then its good

16:15 justin_smith: augustl: it can be as simple as scp the jar to the server, stop any process with an extant PID file (removing said file) then launch your jar, creating a PID file

16:15 stuartsierra: jackhill: some of the earliest presentations by Rich Hickey cover differences from other Lisps.

16:15 justin_smith: augustl: of course there are various wrappers for making an arbitrary program a "service" under ubuntu

16:15 stuartsierra: jackhill: Search for "Clojure for Lisp Programmers" maybe

16:15 augustl: justin_smith: sounds like I should look into how to create my own services

16:15 jackhill: stuartsierra: will do :)

16:16 justin_smith: augustl: it's pretty straightforward - in that case you would upload, then restart the service (pointing it to the latest jar of course)

16:16 augustl: justin_smith: sounds good, thanks for the pointer :)

16:16 stuartsierra: jackhill: The big difference is ABCL and Kawa are trying to emulate their respective platforms on top of the JVM, so there's a bit of a mismatch with things like types and interop. Clojure is "native" to the JVM.

16:17 EvanR-work: "Ring is a Clojure web applications library inspired by ... rack."

16:17 :\

16:17 tbaldridge: EvanR-work: so like I said, depends how you define "best". By my standards, pedestal is the best. But your standards may differ.

16:17 stuartsierra: augustl: JSVC (Apache Commons Daemon) may be useful

16:19 jackhill: stuartsierra: In fact, I started looking around at languages becasue I was interested in Java interop, so that's good to keep in mind.

16:19 EvanR-work: pedestal looks cool

16:21 mi6x3m-alt: jackhill: you've come to clojure, look no more!

16:22 jackhill: :) Data immutability is also very attractive

16:23 mi6x3m-alt: yes, it's an important achievement of humanity

16:27 mfikes: cfleming: I was thinking of a simple JavaScriptCore REPL that works much like the Node.js REPL (standalone, TCP comm, loading dependency JS files off disk). That would make it easy to fire up a REPL when you want to suss out something with JavaScriptCore. But, figuring out the alternative comm channel: USB / iOS WebKit debugging might a more fruitful avenue of pursuit.

16:28 cfleming: mfikes: Ok, sounds interesting. I'm slowly investigating the debugging in the background, and hoping to get to it in the next couple of weeks

16:28 mfikes: I'll let you know when you can be a guinea pig :-)

16:29 mfikes: cfleming: That'd be cool to work on :)

16:30 cfleming: I suppose the USB debug protocol might lead to more capability if it affords you the opportunity to do things like set JavaScript breakpoints, etc.

16:35 cfleming: mfikes: definitely. Plus that allows code to be swapped while the VM is paused, so when you're paused at a breakpoint your REPL will still work, local state will be saved and then you'll be able to continue with the new code

16:35 mfikes: It'll potentially be nicer than debugging Java at that point.

16:43 mfikes: cfleming: OK. I'll read up on that protocol so I know more about it.

16:43 SagiCZ1: tbaldridge: ok, it was just my code, java is fully capable of being pretty accurate under 5 ms.. i just need some timer that wont acumulate the error and i am good to go

16:46 doritostains: I'm using cider 0.9.0alpha with cider-nprepl 0.9.0-snapshot and emacs seems to start a server fine but the repl buffer doesn't have a prompt. Anyone having a similar problem? This just started happening today. I just updated my packages and prelude

16:55 postpunkjustin: doritostains: I had a similar problem yesterday, I just fixed it by downgrading to 0.8.2

16:55 AeroNotix: doritostains: welcome to CIDER where everything breaks and nobody cares.

16:55 Use older version, 0.8 is known-good.

16:56 I tentatively have upgraded to the latest CIDER{-nrepl} and I seeing no problems. However, I suspect that it's a ticking time bomb and it's waiting until I'm knee deep in a deadline straddling bugfix to break.

16:57 llasram: AeroNotix: If you care, the project seems to be very opening PRs, and has a growing test suite

16:57 s,opening,open to,

16:57 The transition to the middleware-based implementation was made more painful by the lack of a pre-existing suite of tests

16:58 AeroNotix: It really was

16:58 llasram: But I think things are looking much rosier going forward

16:58 amalloy: llasram: "very opening PRs" - such doge

16:58 llasram: amalloy: yes yes :-p -- I have a bad habit of changing my planned sentences faster than I can type

16:59 rhg135: good to know im not the only one

17:07 AeroNotix: llasram: yeah, the middleware transition was terrible. I wish it didn't need to happen so swiftly.

17:07 Also, I remember the 0.6 was so amazing I was comparing its quality to SLIME.

17:07 so it kind of set me up to really dislike the quality in later releases.

17:07 And FWIW, I opened issues with all bugs I encountered and discussed those which other people had made before me.

17:10 coventry`: I'm having trouble getting started with some java interop. I think it's just clojure rustiness. Any suggestions for how to get these clojure instructions working? https://www.refheap.com/95732

17:11 SagiCZ1: coventry`: did you accidentely post something else?

17:11 mi6x3m-alt: coventry`: (OpCode/e_op_code_NOP)

17:11 SagiCZ1: no sorry im blind

17:11 mi6x3m-alt: coventry`: if you want to call it that is

17:11 amalloy: coventry`: your clojure looks fine

17:11 mi6x3m-alt: otherwise the message is correct

17:11 and the static field is missing

17:11 amalloy: i'd say your javadocs don't match the version of the library you have

17:13 coventry`: Hmm, I'm pulling the types for the AT_Block call straight out of the source code which I think I just cloned: https://github.com/BurstProject/burstcoin/blob/master/src/java/nxt/at/AT_Block.java#L22

17:14 mi6x3m-alt: e_op_code_NOP is a data field: https://github.com/BurstProject/burstcoin/blob/master/src/java/nxt/at/OpCode.java#L13

17:15 mi6x3m-alt: coventry`: not public

17:15 amalloy: oh, true indeed mi6x3m-alt

17:15 all of those members are not public

17:16 mi6x3m-alt: you can force them through reflection but the inter-op is not helping you there

17:16 csd_: Is there an easy way to xor 1 byte into each byte of a hexadecimal number?

17:16 justin_smith: csd_: the size of the number matters more than the printed representation, but yes

17:17 size of the number's datatype that is

17:17 csd_: its BigInteger sized

17:17 justin_smith: that's trickier, but I would do it in a reduce

17:17 coventry`: mi6x3m-alt: Thanks... As a public class, I should be able to access AT_Block's constructor, though, right?

17:18 mi6x3m-alt: csd_: create a BigInteger from the byte by shifting and adding

17:18 csd_: someone in #java recommended BitSet but I don't see how I would use it

17:18 mi6x3m-alt: coventry`: no, it's not public

17:18 csd_: I feel like I'm using the wrong language for doing byte operations

17:19 mi6x3m-alt: csd_: take your byte x

17:19 justin_smith: csd_: so for every byte of the BigInteger (until you run out of bytes in the number) you want to xor each one with a specific byte

17:19 mi6x3m-alt: your goal is to create a big int each byte of which is x

17:20 justin_smith: csd_: you can't just construct a BigInteger to xor against by repeating the byte, because BigIntegers have arbitrary size

17:20 mi6x3m-alt: well he can if he knows the size of the other number

17:21 csd_: Initially i have a string representation of a hex number that I want to operate on. I don't care if it's biginteger that contains it

17:21 justin_smith: csd_: do you know the max size? that would make it much easier

17:21 kenrestivo: my woes appear to be due to my swing thread exiting... on the target, but not when running in nrepl in development. i see an @(promise) in my future

17:22 csd_: 34 bytes

17:23 although i'd like to be able to generalize to larger if needed

17:24 hiredman: /win 15

17:28 TEttinger: \lose 1

17:28 coventry`: mi6x3m-alt, amalloy: Thanks, mystery solved.

17:28 arrdem: (inc TEttinger)

17:28 lazybot: ⇒ 37

17:28 kevinfish: I'm having trouble understanding http://clojurescriptkoans.com/#functions/9 Can someone help?

17:31 mi6x3m-alt: csd_: can you determine the number of bits of the number

17:31 csd_: mi6x3m-alt: I'm attempting http://cryptopals.com/sets/1/challenges/3/

17:36 justin_smith: csd_: seeing the actual problem, your best bet is to take two chars at a time from that string, turn them into a byte, and then track the frequencies of the unique bytes you get

17:36 (and compare those frequencies to the frequencies of letters used in english, etc.)

17:36 csd_: justin_smith: yes i did that. but i want to take the one-byte key and XOR it on the entire string

17:37 justin_smith: csd_: why? just xor each byte (each pair of chars in the string)

17:37 so work along the string, xor each pair of chars as hex byte, and output as char

17:37 no need to create one big number, and then xor each of its bytes

17:38 csd_: I suppose you're right. I just was looking for a function i could apply using `map`

17:38 justin_smith: csd_: bit-xor

17:38 csd_: except that doesnt work on bigint

17:39 justin_smith: csd_: why would you need a bigint at any point here?

17:39 just map across each pair of chars, turning each pair into a number, then xor it

17:39 csd_: ok

17:40 justin_smith: kevinfish: since that's a koan, I'll ask: what function would take \x -> x*x as an argument and return 25?

17:40 csd_: thanks justin

17:41 kevinfish: justin_smith: #(5)?

17:41 justin_smith: kevinfish: I that's close, but it is not a function

17:41 remember it has to take an arg

17:41 that arg being (fn [x] (* x x))

17:42 and then it has to do something with that argument

17:42 kevinfish: so something like: #(% 5)?

17:42 justin_smith: kevinfish: I think that is precisely the answer

17:42 kevinfish: lol, ok. bizarro :)

17:43 justin_smith: yes, it's a contrived example

17:43 but hopefully it made some kind of point about first class functions

17:43 kevinfish: yes, braintwister. Thanks.

17:44 andyf: llasram: Regarding my question about extend-protocol earlier, Bronsa reminded me of this ticket:

17:44 jjttjj: kevinfish: i think maybe it's expecting something more like (fn [f] (f 5)) ?

17:44 justin_smith: jjttjj: that's what #(% 5) is

17:44 and #(% 5) is accepted as the correct answer

17:45 kevinfish: jjttjj: that would have been more of a noob way to do it, yes.

17:45 andyf: llasram: http://dev.clojure.org/jira/browse/CLJ-1308

17:45 justin_smith: in fact ##(quote #(% 5))

17:45 lazybot: ⇒ (fn* [p1__45305#] (p1__45305# 5))

17:45 justin_smith: it expands to that, modulo some weird naming

17:48 jjttjj: oh woops I missed that, just saw the #(5)

17:49 nontrivialleaf: question: is this an appropriate location to ask newbie questions about the language?

17:50 amalloy: yes

17:50 SagiCZ1: nontrivialleaf: definetely.. or at least i do it all the time

17:51 nontrivialleaf: hah! this form freezes my repl. It must be running infinitely, but I'm very unsure as to what the issue is: (for [x (iterate dec 100) :when (> x 0)] x)

17:51 gfredericks: you probably want :while

17:52 instead of :when

17:52 with :when you're filtering the infinite sequence

17:52 zirkonit: good day, gents

17:52 nontrivialleaf: oh

17:52 gfredericks: which takes forever understandably

17:52 nontrivialleaf: yes that makes things work

17:52 thank you ^_^

17:53 gfredericks: np

17:53 amalloy: nontrivialleaf: see also (range 100 0 -1)

17:58 gfredericks: ,(nth (iterate shuffle (range 100 0 -1)) 1000)

17:58 clojurebot: [48 58 68 6 2 ...]

17:59 gfredericks: clojurebot: iterate shuffle is your friend

17:59 clojurebot: 'Sea, mhuise.

17:59 nontrivialleaf: I'm confused on which functions/macros return lazy seqs

17:59 i know I can search docs

17:59 coventry`: Is there a way to execute clojure code in the context of a package, to simplify access to its package-private fields and methods?

17:59 SagiCZ1: nontrivialleaf: it is usuallyi n the doc

17:59 amalloy: nontrivialleaf: most of them

17:59 SagiCZ1: nontrivialleaf: the rule of the thumb is that if the algorithm CAN return lazy seq, it will

18:00 nontrivialleaf: hmm

18:00 SagiCZ1: ,(type (take 5 (range 10)))

18:00 clojurebot: clojure.lang.LazySeq

18:00 SagiCZ1: ,(type (shuffle (range 10)))

18:00 clojurebot: clojure.lang.PersistentVector

18:00 nontrivialleaf: ,(println "testing")

18:00 clojurebot: testing\n

18:00 nontrivialleaf: nice

18:08 just to be clear: in this example (nth (iterate shuffle (range 100 0 -1)) 1000), iterate returns a lazy seq to nth, whereas in (type (shuffle (range 10))), shuffle actually evaluates

18:08 correct?

18:19 alandipert: nontrivialleaf, iterate returns a lazy sequence that nth will consume eagerly. shuffle is eager too, because it returns a vector

18:19 gfredericks: nontrivialleaf: also to be clear (iterate shuffle ...) is totally useless

18:19 because it shuffles more than once

18:20 amalloy: gfredericks: what if i know how my shuffle algorithm works, and i know i'll get the cards i want on the tenth shuffle?

18:20 (because the RNG is bad too)

18:21 gfredericks: amalloy: if you know what cards you want then just make those cards directly

18:22 nontrivialleaf: ah your missing a key point, it has to *look* random so he can trick his friends into playing

18:22 gfredericks: and clojure's RNG isn't seedable anyhow so it's all wild west

18:22 nontrivialleaf: *you're

18:26 justin_smith: gfredericks: well, the jvm rng is available

18:28 gfredericks: justin_smith: eh?

18:28 you mean just using a j.u.R directly?

18:29 justin_smith: gfredericks: there is a seedable rng that clojure doesn't use, it is available via interop

18:29 right

18:29 gfredericks: yeah the "clojure doesn't use" part is all I meant

18:29 justin_smith: someone should make a seedable rand-nth / shuffle

18:29 gfredericks: I did

18:30 https://github.com/gfredericks/four/blob/master/src/four/stateful.clj

18:30 also I made a jira ticket and a patch

18:30 justin_smith: oh, of course you did

18:30 gfredericks: go vote on it http://dev.clojure.org/jira/browse/CLJ-1452

18:31 amalloy: gfredericks: alex changed priority from minor to critical? that surprises me

18:33 gfredericks: I know that was an amusing jump

18:34 I'm sure it's based on some internal interpretation of "critical"

18:34 amalloy: hahahaha

18:34 "he is criticizing the dang random numbers, can't the guy ever take a break, why's he so critical"

18:34 gfredericks: lol

18:35 Kristien: gfredericks: I almost got my shor implementation working

18:35 gfredericks: Kristien: that sounds exciting

18:36 mearnsh: i'd like to see that Kristien

18:36 machty: clojure noob here: i believe i have a grasp on how clojure minimizes the copying/duplication of immutable data between operations, but i'm wondering if any of the same tricks that apply to sequences can also apply to objects?

18:36 by objects i mean maps

18:36 nontrivialleaf: i think map is a seq

18:36 hiredman: nope

18:37 amalloy: machty: for large maps, yes this is done

18:37 rhg135: PersistentHashMap.java is open source

18:37 amalloy: rhg135: open but not very legible

18:38 rhg135: legible may be subjective, amalloy

19:09 gtrak: machty: maybe this isn't the place to ask, but you curious about clojure for ember's sake? I recognize you from the react slide-deck. Been futzing with immutable.js in an ember codebase for a bit already.

19:32 aaelony: I enjoy using the repl to load and explore an unfamiliar clojure library. However I've never done this with a library that uses Stuart Sierra's Component library. Are there guidelines or recommendations on stepping into details of nested components and their OO-like start methods?

19:45 thearthur: aaelony: I don't think so, other than call the start

19:47 aaelony: thearthur: I'd like to see intermediate results of things that are called from start, but finding it somewhat opaque to discover the correct types of the arguments to pass in to subsequent functions. Also, I'm a little unclear if/why/whether alter-var-root is needed to poke around from the repl...

19:53 thearthur: aaelony: I agree ;-) suppose it's kind of a lifestyle choice :-/

19:53 sorry if thats not really useful

19:54 aaelony: thearthur: well, if anyone has stories of refactoring a component lib, I'm interested in hearing about it...

21:08 fairuz: ,(-> {:name "Foo" :age 12} ((fn [x] (info x))))

21:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: info in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:09 fairuz: How can I simplify this?

21:09 I want to put an anonymous fn inside a -> chain

21:10 msassak: fairuz (#(do-something 123))

21:10 nullptr: fairuz: (-> {:name "Foo" :age 12} info)

21:10 thearthur: ,(let [info count] (-> {:name "Foo" :age 12} info)))

21:10 clojurebot: 2

21:10 amalloy: there's no great way to do it, fairuz. yours is the simplest workaround, if we presume that your actual lambda isn't just a wrapper around info

21:11 fairuz: nullptr: info is just a dummy function, it can be a several lines of code

21:11 gfredericks: fairuz: (-> {:name "Foo" :age 12} (as-> x (info x)))

21:11 can be nicer sometimes

21:11 fairuz: amalloy: Ok, just wondering if there's any tricks around :)

21:11 thearthur: then amalloy is right. using as-> can sometimes make it look a little better

21:15 amalloy: ,(let [{:as x} nil, {:as y} []] [x y])

21:15 clojurebot: [nil []]

21:15 amalloy: ,(let [{:as x} nil, {:as y} [], {:as z} ()] [x y z])

21:15 clojurebot: [nil [] {}]

21:16 amalloy: kinda interesting that only seqs get converted to a map; nil and [] stay the same

21:16 gfredericks: ,(let [{x 0} [42]] x)

21:16 clojurebot: 42

21:16 gfredericks: huh.

21:17 amalloy: ah, right, that's why

21:17 because vectors already have keys

21:17 gfredericks: yeah I realized a second later that explained your thing too

21:17 I'm not convinced this vectors-as-maps thing is worth it

21:18 I guess if you're really really really using a vector then it's kind of map-like

21:18 amalloy: gfredericks: you mean vectors shouldn't destructure like maps with integer keys, or get shouldn't work on them?

21:18 gfredericks: so maybe the real thing is that I don't normally use vectors as vectors

21:18 amalloy: I meant get, assoc, dissoc, IFn

21:19 fairuz: amalloy: thearthur: gfredericks: msassak: nullptr: thanks for the response. :)

21:19 amalloy: well, dissoc already doesn't

21:20 gfredericks: ,(dissoc [1 2 3] 2)

21:20 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap>

21:20 gfredericks: w00h00!

21:20 that's kind of good I guess

21:20 amalloy: gfredericks: you want them to preserve their indexed-access features, but with different function names than maps have?

21:21 because being able to assoc on a vector is pretty important; if you take that away you need to add it somewhere else with a new name

21:21 gfredericks: amalloy: just being indexed doesn't make them maplike -- e.g., perhaps the new whatchamacallum vectors will allow prepending as well

21:22 which amounts to a giant keyshift

21:22 now that I think about that I'm having a hard time imagining those things replacing clojure's current vectors

21:23 amalloy: gfredericks: are you talking about zach's small vectors or something else? i don't follow the mailing lists anymore

21:27 gfredericks: amalloy: no the bagwell things

21:28 https://github.com/clojure/core.rrb-vector

21:28 amalloy: are those actually on track for replacement?

21:28 gfredericks: just something I heard rich speculate wrt clojure 2.0

21:28 a while ago

21:29 amalloy: mmm. it seems to me like they'd be fine; who cares if (v' 10) used to be (v 5)?

21:29 gfredericks: I guess if assoc continues to work on the exact same keyset

21:30 e.g., you probably wouldn't want (assoc v -1 x) to do something

21:30 amalloy: i don't really want (assoc v (count v) x) to do anything either, but we can't always get what we want :P

21:30 gfredericks: so as long as you treat them like maps they keep being maplike

21:31 and only use that one magical assoc-point; yeah I agree that one is weird and could go away

21:31 you kind of have to know you're doing it so you may as well use conj

21:34 amalloy: the only use case i can think of for the magical assoc point is someone wrote this cool function like (fn [x ...] (reduce (fn [acc y] (assoc acc ...)) x ...))

21:35 and you really really want to use it for a vector, so you arrange to give it pairs like [0 x] [1 y] ...

21:35 which all seems rather far-fetched

22:16 verma: if I want to append an item to a seq (list or a vec), I gotta do (concat lst [item]) ?

22:18 lasergoat: if you need it to go on the end and you don't know what it is, then yeah

22:18 amalloy: verma: http://stackoverflow.com/q/5734435/625403

22:18 lasergoat: my general advice is to know which one you have

22:19 (meaning a vec or list)

22:20 amalloy: indeed, that's my advice in that SO question too

22:20 verma: amalloy: thanks, lasergoat: its argument to a function, so its most likely a list, I could always vec it and then go from there

22:20 arguments*

22:20 kenrestivo: the nightmare continues. doing some binary search, it seems my swing/seesaw stuff broke horribly once i cut over to using the components system to start it up

22:20 verma: (fn [a & rest] ...)

22:21 lasergoat: verma: rest is definitely a vector

22:21 verma: lasergoat: oh? :/

22:21 kenrestivo: reading seesaw docs, it seems to imply that all datastructures used in the ui need to be updated on the ui thread. that can't happen, i've got atoms and agents and state modified through async channels.

22:21 amalloy: lasergoat: whaaaaaat

22:21 that is one million percent untrue

22:22 kenrestivo: i wonder now if i'm the only freak trying to use swing/seesaw as a write-only thing? i.e. there are no incoming ui events. it's used only for display.

22:22 amalloy: kenrestivo: your async channels need to use SwingUtilities/invokeLater or whatever

22:22 kenrestivo: i am doing that.

22:22 lasergoat: *not. definitely *not* a vector

22:22 justin_smith: kenrestivo: if you are only displaying, and not allowing any twiddling from the user, wouldn't pushing updates to an html page be much easier?

22:23 amalloy: &(apply (fn [& rest] (class rest)) [1])

22:23 lazybot: ⇒ clojure.lang.PersistentVector$ChunkedSeq

22:23 kenrestivo: justin_smith: i thought of that. writing a little c daemon that just takes updates in and writes to a window with GTK

22:23 amalloy: okay, just checking. it's indeed always a seq there

22:23 lasergoat: ,((fn [a & rest] (vector? rest)) 1 2 3)

22:23 clojurebot: false

22:23 kenrestivo: could even launch it with conch and spew it events on stdin

22:24 lasergoat: amalloy: i thought i'd said not and when you said it was untrue i ran back to my repl to prove and came to see that i'd screwed up

22:24 amalloy: well, i guess you can actually make it a vector if you are an evil madman

22:24 with like (apply f (reify IPersistentVector ... ISeq ...))

22:25 but best not to have any evil madmen aroun

22:25 kenrestivo: EVIL VECTOR MADMEN running round instead of an (s) on their chest it says (vec)

22:26 of course, the real name of the evil vector madmen, when not in costume, is "victor"

22:26 lasergoat: verma: in all seriousness, you generally don't need to worry about perf on & args, unless you do some crazy (apply) to it, so i'd just say (vec) like you were planning to

22:27 verma: lasergoat: I actually want to do an apply to it, not sure if its crazy, writing a macro which turns node.js style functions into nice clojure-y looking functions (js/fs.exstsSync) -> (fs/exists-sync?)

22:28 lasergoat: by crazy apply i meant with some giant data array

22:28 verma: lasergoat: no definitely not, will always be as manageable and sane as a function argument list should/need to be.

22:29 lasergoat, amalloy : thanks for your help

22:29 kenrestivo: (apply + (range))

22:29 lasergoat: if you have like, a normal number of arguments, you should be able to do whatever you want

22:29 amalloy: i want to fly to the moon. can we arrange that? i only have a slightly higher number of arguments than normal

22:29 lasergoat: i know fns are java callables, but if i have a java function that takes, say, a Callable<int>, can i still pass in my fn? i haven't tried it, but it strikes me that it wouldn't work?

22:30 amalloy: lasergoat: there's no such thing as a Callable<int>

22:30 justin_smith: lasergoat: that's a generic right?

22:30 amalloy: do you mean Callable<Integer>?

22:30 lasergoat: sorry, yes

22:30 amalloy: then yes, your function works fine

22:30 lasergoat: justin_smith: yeah

22:30 justin_smith: generics are a fiction of javac

22:30 amalloy: generics are a fiction of javac

22:30 justin_smith: so you can use them just fine

22:30 woah! jynx amalloy

22:30 amalloy: justin_smith: jerk

22:30 justin_smith: haha

22:31 lasergoat: haha

22:31 justin_smith: I can't believe we got the exact phrasing

22:31 amalloy: it's a popular phrasing

22:31 justin_smith: :P

22:31 kenrestivo: it's a fail-safe channel with redundancy

22:31 lasergoat: oh, so the underlying bytecode doesn't care, it's just a rule the java compiler enforces between pieces of java code?

22:31 interesting, thanks

22:32 justin_smith: amalloy: I just googled the exact phrase - got two hits on the #clojure log and that's it

22:32 haha

22:32 amalloy: justin_smith: "fiction of javac" first used in this channel by the man himself, rhickey

22:32 the real logs show it being said 6 times

22:33 rhickey, cemerick, technomancy, stuartsierra (referring to checked exceptions), you, me

22:34 i thought i'd said it before this myself

22:34 weird that i apparently haven't

22:34 kenrestivo: band name: "fiction of javac"

22:35 verma: not sure what it means

22:37 justin_smith: verma: generics don't exist in any form in the bytecode, they are a constraint enforced by javac, and clojure does not use javac

22:37 same deal with checked exceptions: javac enforces them, they have no representation in the bytecode

22:37 verma: oh, I see

22:37 lasergoat: which sort of makes sense, now that i think about it

22:38 i think in .NET generics are byte-code level things, though

22:40 justin_smith: lasergoat: I think that's easier to do that way when you plan on generics from the beginning, I don't think that was the case with java

22:40 and java has a high priority on backward compatibility

22:40 lasergoat: justin_smith: right

22:41 justin_smith: .net didn't have them at first either, but they're much quicker to break things, and they have second-move advantage

22:41 *mover

23:25 luxbock: are side-effectful transducers kosher? I tried Googling about them but couldn't find anything

23:34 amalloy: luxbock: look up the source for the transducer for `take`

23:45 lasergoat: take has like internal state, but i'm guessing the questions is whether you should update databases or launch rockets with transducers

23:47 i asked a similar question on #clojurescript, and while the answer was "generally no", after playing with them for a while, i decided that having side effects in my transducer was exactly as bad as having them anywhere else

23:47 in other words: bad, but not something special about transducers

Logging service provided by n01se.net