#clojure log - Dec 13 2011

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

0:09 amalloy: one way that lisp makes it easy to think about your problem is exactly the "notorious" parens. there are no special-cases for special syntax built into the language (eg, java's for loop). instead, everything is just (operator arg arg arg). this means that when you add new domain-oriented constructs, they look *exactly* like the built-ins you're used to reading and writing. at that point the language can "get out of your way" and you only have

0:20 Turtl3boi: huh?

0:21 java's for loop has special syntax?

0:21 companion_cube: yes, for iterators

0:22 amalloy: java's for loop *is* special syntax. for (x = 1; x < 10; x++) {...}

0:22 can you add a similar construct to the language yourself? no; all you can do is write methods and classes

0:23 Turtl3boi: Ahh i see

0:23 well i don't get exactly what you're saying, not until i go see a lisp in action

0:24 amalloy: whereas in lisp, suppose you're writing a card-game player. you can easily define something called each-card such that you can write (each-card [rank suit] (...do something with rank and suit...)) - now it looks like each-card is a language built-in

0:50 Turtl3boi: damn i should've gotten some experience in a Lisp sooner

0:50 but i do suppose Matlab is like that to an extent

3:07 replaca: does anyone with a deeper understanding than I have know why clojure.reflect doesn't seem to work on classes created with deftype?

3:08 is it a class loader problem?

3:22 ahh yes (if anyone cares), you need to specify :reflector (clojure.reflect.JavaReflector. (cloj\

3:22 ure.lang.DynamicClassLoader.))

3:23 (that \ was an articat of cutting and pating from a terminal

3:23 *pasting

3:42 AWizzArd: Moin

3:43 replaca: what would you like to reflect about?

3:51 replaca: AWizzArd: I'm extended autodoc to understand protocols, types and records

3:51 *extending

3:52 but now I need to go to sleep :)

5:58 lnostdal: it's really not possible to "subclass" (i guess sub-deftype, or something) a class defined using deftype? .. i have to copy/paste the body to the new deftype and add protocols to it? .. hmm

5:58 perhaps i'm looking for extend

5:59 ..or something

6:25 bsteuber: lnostdal: yes extend seems the way to go

6:26 if that's too low-level for you feel free to build some macros on top of that

7:59 rads: when you compile clojurescript with advanced optimizations, what exactly gets included with your application code? a clojurescript runtime? google closure?

8:08 Fossi: i'd guess both, if you use them

8:08 the closure compiler only pulls in the parts you use though

8:09 thearthur: not sure how much of the runtime makes it into the final either?

8:11 rads: it seems like a lot of javascript to include if I wanted to use both clojurescript and jquery

8:12 34kb for clojurescript runtime and 31kb for jquery before any application code. is that too much?

8:12 Fossi: depends

8:12 also: who needs jquery anyway? :>

8:13 Borkdude: Has anyone read "Test Driven Development By Example" and has it near him/her?

8:13 rads: Fossi: what do you recommend instead? closure's dom stuff?

8:13 raek: in theory, only the parts of the clojurescript standard library you use should be included, right?

8:14 rads: 34kb seems to be the minimum from my tests

8:14 Fossi: i'd always use closure instead of jquery these days

8:14 rads: how come?

8:14 raek: rads: JQuery cannot be compiled in the advanced mode, so the compiler cannot use remove the parts of JQuery you don't use

8:14 Fossi: it just feels better and has the saner design

8:15 also most jquery plugins are a mess

8:15 lucian: Fossi: have you used it from js?

8:15 Fossi: even the ui stuff is not really nice (weird hidden config options if you extend for example)

8:15 rads: maybe I'll take a look at closure then. I just wanted to use jquery because it's a lot more popular and I'm more familiar with it

8:16 Fossi: it's different

8:16 but i like it better

8:18 raek: but because you can hot-link JQuery from google, it's also very likely that the browser alread has it cached

8:19 lucian: raek: for some cases, that's not an option (phonegap)

8:19 kephale: what graph libraries are folks using?

8:19 cemerick: Does hiccup not provide a way to get a "standard" clojure.xml-style representation given a hiccup-style representation?

8:20 Borkdude: Never mind, I just had to read a bit further.

10:04 jeremyheiler2: Anybody see this? http://blog.8thlight.com/uncle-bob/2011/12/11/The-Barbarians-are-at-the-Gates.html

10:06 samaaron: jeremyheiler2: yep, i read it the other day

10:14 jeremyheiler2: samaaron: Now I am interested in how someone would properly scale Clojure across 1024 CPUs.

10:15 raek: it would be interesting if clojure would run on a platform that performs automatic parallelization

10:16 clojure make concurrency easy excellently, but not parallelism

10:17 jeremyheiler2: raek: maybe with an event-loop similar to node.js?

10:19 raek: jeremyheiler2: one event queue but with one event processing loop per CPU?

10:22 jeremyheiler2: raek: yeah; something like that. essentially allow the CPUs to greedily steal work from whatever processes are running.

10:24 gtrak``: jeremyheiler2, ever heard of amdahl's law?

10:25 raek: for purely functional code, the language runtime could even do that for expression evaluation

10:25 which I think some SML and Haskell implementations does

10:26 gtrak``: are the 1024 cpus NUMA?

10:26 lucian: gtrak``: amdahl's law doesn't entirely apply to event loops, since they already do work in small increments

10:27 gtrak``: i think the limit for cache-coherency is like 128 cores

10:27 lucian: so you'd "just" need a distributed event loop

10:27 gtrak``: well, the real issue with that many cores is memory

10:28 TimMc: gtrak``: Yay persistent data structures.

10:29 gtrak``: TimMc, well, :-)... that might not be all you need. Think of unified memory as requiring a lot of protocol overhead. Message passing becomes more natural than shared memory at some point

10:30 the message passing to sync up state is there whether you want it to be or not, but maybe you can have more control if you do it yourself, that's what I'm trying to say

10:32 so, if avout ends up being a good idea, you could apply a similar model for inter-core state

10:33 but having it transparently might not work as well

10:38 http://en.wikipedia.org/wiki/Non-Uniform_Memory_Access

10:39 it even has the pic :-) http://en.wikipedia.org/wiki/File:AmdahlsLaw.svg

10:41 95% parallizable asymptotes at 20x, clojure helps us to get there more effectively, but there's still a limit

10:42 jeremyheiler2: gtrak``: interesting stuff.

10:42 gtrak``: it's why i'm interested in clojure in the first place :-)

10:46 jeremyheiler2, speaking of event loops, you read the LMAX article?

10:46 jeremyheiler2: gtrak``: i have not

10:47 gtrak``: http://martinfowler.com/articles/lmax.html

10:47 totally badass

10:47 i think the insight here is they took control of the transaction model and made different assumptions than a RDBMS would

10:49 jeremyheiler2: nice, i think i gonna get a coffee and read through this

11:05 pjstadig: not every algorithm can be parallelized

11:05 and even if it can there are limits

11:05 ...aaaand this is something that has been well researched

11:06 yet another thing that we'll benefit from that was solved in the 70's and 80's

11:16 hmm...NUMA...didn't some guy do a youtube video about that? http://www.youtube.com/watch?v=KmtzQCSh6xk :)

11:21 gtrak``: pjstadig, numa numa yay.. he must have been talking about computer architecture

11:25 otremblay: Hi, this is probably not the right place to ask this, but I'm setting up emacs with clojure, and I wondered when I pressed C-x C-e where did my println output go?

11:34 gtrak``: otremblay, probably the swank repl buffer?

11:34 slime repl, i mean

11:35 otremblay: I'm going to try again

11:35 gtrak``: do you have the repl buffer open?

11:36 otremblay: In about 5 seconds I will

11:36 gtrak``: it looks like it's just C-x e, not C-x C-e

11:36 otremblay: Oh

11:36 gtrak``: ah wait, that's a thing, too, nevermind

11:36 C-x C-e evaluate the expression behind the cursor

11:36 otremblay: When I do C-x e, it doesn't do anything, no kbd macro defined

11:37 I get a message in my Message buffer when I do C-x C-e

11:37 in my slime-repl clojure buffer, not a thing

11:37 gtrak``: ah

11:38 otremblay: The command goes through in my code buffer, I get "#'clojure-loc.core/clojure-loc" in my message buffer, but nothing anywhere else.

11:38 No error, no nothing

11:39 gtrak``: is there a println in the code itself?

11:41 otremblay: The code I execute is just (println "lol")

11:42 I honestly can't explain why I used an acronym for the expression of laughter, but I can't see it printed nowhere. No lols for me.

11:42 gtrak``: despair is when you println but there is no println

11:44 otremblay, it shows up for me in the slime repl buffer

11:45 otremblay: Configuration is wrong then. Oh, the indignity.

11:45 Wait

11:46 Oh, no, false hope. It "showed up" right after my slime version number.

11:46 gtrak``: otremblay, make sure you've got clojure-mode on

11:46 otremblay, that's right

11:46 otremblay: How do I do that?

11:46 gtrak``: try it again, and it'll be under that

11:46 otremblay: No, it doesn't work.

11:46 gtrak``: yes it does

11:47 you just said it 'showed up' right after your slime version number

11:47 otremblay: It does when I load slime.

11:47 I have this in my .emacs

11:47 (add-to-list 'load-path "~/opt/clojure-mode")

11:47 (require 'clojure-mode)

11:48 gtrak``: ah

11:48 you can always load clojure-mode manually with M-x clojure-mode

11:50 otremblay: When I compile the code using C-c C-k it shows up in my repl window under the version number

11:51 gtrak``: yea, compiling the namespace runs the init for the namespace, which will run that line

11:51 rather, compile and run are kind of the same thing, though C-c C-k does more

11:52 otremblay: I don't understand why it doesn't throw it in my repl when I C-x C-e

12:04 I think I'll make do with C-c C-k until I'm at least two orders of magnitude more proficient in the use of emacs.

12:10 gfredericks: anybody know if I can turn an aleph channel into an input stream or something?

12:14 duck1123: gfredericks: is this a ChannelBuffer?

12:14 gfredericks: or synchronously slurp a channel...

12:14 duck1123: no, it's not

12:14 duck1123: this is an http server which is receiving a req with a streaming body

12:15 I'm trying to forward the request, so any manner of getting the channel to feed into my synchronous call to clj-http would be acceptable

12:16 I should probably try using aleph client stuff instead of clj-http, but now is not a good time for refactoring...

12:16 duck1123: ok, look in aleph.formats, there's a ton of useful fns there

12:16 gfredericks: k

12:17 holy crap look at all that

12:17 duck1123: Unfortunately, many of them are private on 0.2.0, but that changed in the clj-1.3 branch

12:19 of course, if this is a normal lamina channel, you'll probably want to look at pipelines. (I'm still not very good with pipelines)

12:19 gfredericks: hrm....

12:19 gtrak``: nothing in clojure is really private

12:20 gfredericks: gtrak``: yes but it indicates the intentions of the author

12:20 duck1123: the format functions seem to be only useful after I already have the content

12:21 tomoj: bytes->input-stream ?

12:21 gfredericks: don't have bytes, just have channel

12:21 duck1123: where is this channel coming from?

12:21 gfredericks: bytes are preferable to input-stream actually

12:22 tomoj: map* it?

12:22 gfredericks: aleph wiki says: Streamed requests will have a channel as their body. To check for this, see if (channel? body) returns true.

12:22 tomoj: hmm

12:22 that would be odd

12:22 gfredericks: by which I mean bytes are easier atm, not simpler :)

12:22 This present moment is all about easy.

12:23 duck1123: and you're trying to take that channel and send it over http somewhere else, right?

12:23 gfredericks: yeah, using clj-http

12:23 atm clj-http is expecting a byte-array, which is the only reason that's preferable

12:24 obviously a stream is better performance

12:24 tomoj: does map* not return a new channel?

12:25 tomoj: yeah, it does, but each message will be an input stream. don't think that's what you want..

12:25 duck1123: gfredericks: then you can take that channel and get a lazy seq

12:26 gfredericks: duck1123: yeah? (seq ch)?

12:27 duck1123: lazy-channel-seq

12:27 gfredericks: must read: https://github.com/ztellman/lamina/wiki/Channels

12:28 gfredericks: duck1123: I must!

12:36 dnolen: if anyone is interested in hacking on a CLJS debugger, I've started sketching things out here https://github.com/swannodette/cljs-debug

12:41 samaaron: dnolen: just looking at it now

12:41 very exciting

12:42 dnolen: samaaron: hardly anything there yet :) but hopefully I can get someone else excited enough to help out.

12:42 samaaron: :-)

12:43 i've not used cljs beyond following basic tutorials atm

12:43 dnolen: samaaron: the WRDP (webkit remote debugging protocol) really makes it trivial to build a robust debugger.

12:43 samaaron: but i do have a large project which i'm intending to use it for

12:44 dnolen: samaaron: setting breakpoints in the JS and instrumenting top level forms will be simple - the real challenge will be around getting a sensible sexpr level debugging behavior.

12:45 samaaron: what's the impedance mismatch between JS and CLJS?

12:45 within the context of the dubugger

12:45 dnolen: samaaron: in CLJS you have macros - how we debug those? do we debug the macroexpanding source?

12:46 samaaron: simple CLJS sexprs map to multiple JS statements, how map multiple JS steps to a simple CLJS one?

12:46 stuff like that

12:47 ideally it would be very robust for user. you only deal w/ stepping through sexprs

12:47 samaaron: cool

12:47 dnolen: you can ask to macroexpand an expression and step through macroexpanded source.

12:47 samaaron: i guess that's always the issue with a hosted language

12:48 dnolen: samaaron: yeah, I'm optimistic though, we have a very easy to use analyzer

12:48 samaaron: you have to be able to interprete errors/operations in the host and understand how they correlate to operations in the hosted language

12:48 dnolen: samaaron: yup.

12:50 technomancy: anyone want to take a look at http://dev.clojure.org/jira/browse/CLJ-879 and possibly +1 it?

12:52 samaaron: technomancy: what's the lein way of overriding jar deps with local projects in folders?

12:52 can I do it without using symlinks or changing my project.clj?

12:52 technomancy: samaaron: it's called checkout dependencies; I think it's covered in the readme or tutorial

12:53 typically symlinks are used, but there's no reason you couldn't place the original directory right in the checkouts/ dir

12:53 samaaron: oh

12:53 i don't want to do either of those really

12:53 with cake i could just add projects to my classpath in a config file

12:53 technomancy: why not?

12:54 samaaron: because i'd have to teach my .gitignore about my checkout deps

12:54 whereas with cake i just teach .gitignore globally about .cake dirs

12:54 TimMc: just the checkouts dir

12:54 technomancy: yeah, it's just a single line in gitignore

12:54 samaaron: oh ok, so i have a checkouts dir, but then i have to put symlinks in that?

12:54 technomancy: right

12:55 it should already be in the gitignore of a fresh project

12:55 samaaron: sure, but that sounds like more effort than the cake approach

12:55 TimMc: ...

12:56 technomancy: if it sounds like a nontrivial amount of effort you may be misunderstanding =)

12:56 samaaron: actually i might just be being unecessarily frictionful

12:56 :-)

12:56 solussd: how do I require the clojure.math library in my source file?

12:56 samaaron: so if i created a checkouts dir, woudl lein just pick it up automatically and favour that over any jar in the lib dir?

12:57 technomancy: samaaron: it reads the project.clj file from each dir in checkouts/ and places the :source-path and :resources-path on the classpath ahead of all jars

12:57 samaaron: oh, but i don't want to edit the project.clj with dev stuff

12:58 because i check that into a repo that everyone else including non-dev people use

12:58 TimMc: samaaron: No editing involved.

12:58 samaaron: oh sorry, i misunderstood

12:58 technomancy: sure if there's no :source-path etc, it will use the defaults

13:00 samaaron: technomancy: so if i placed the source of a subproject in my checkouts dir of a parent project, it would take precidence over the jar of the same project in the lib directory of the parent project without having to add :source-path and :resources-path statements to any project.clj file?

13:01 technomancy: right

13:01 samaaron: perfect

13:01 technomancy: I should look into revamping the checkout deps docs; people always get confused over them.

13:02 though it's usually from people who think that adding checkout deps means they should drop it from project.clj.

13:02 samaaron: ah, sure

13:02 i guess people don't know which would take priority

13:02 so drop it from project.clj to make sure

13:03 TimMc: technomancy: What happens when they do that?

13:03 technomancy: TimMc: it works for them, but not for anyone else

13:03 TimMc: Nice.

13:03 samaaron: :-)

13:03 technomancy: samaaron: aha, so clarifying the precedence should help in that case.

13:03 samaaron: technomancy: definitely

13:04 TimMc: technomancy: Is there any way to tell someone is doing that? Like checking the group.artifact?

13:04 s/\./\//

13:04 technomancy: TimMc: hmm... yeah, issuing a warning would be possible I suppose

13:05 TimMc: `lein lint` :-)

13:05 technomancy: I'd rather make it clearer in the docs, but maybe misunderstanding is inevitable

13:05 yeah

13:06 https://github.com/technomancy/leiningen/commit/26be8a23fee3eef865ebe956c3ce1d6353172c03

13:36 samaaron: dnolen: is WRDP supported in Chrome?

13:40 dnolen: samaaron: I've only got it to work in the Chromium builds

13:40 samaaron: perhaps it might work with Safari?

13:40 dnolen: samaaron: I'm planning on creating exact instructions soon on how to play w/ the repo

13:41 samaaron: or at least the Webkit nightlies?

13:41 dnolen: samaaron: yes it should, but I haven't figured out how to get it to work yet.

13:41 samaaron: :-)

13:41 why not? it's not like you do much with your spare time...

13:42 ;-)

13:42 dnolen: heh

13:42 samaaron: to be honest i'm flabberghasted by the amount of stuff you hack on

13:42 it's extraordinary

13:42 you could probably hack up overtone in a few weekends :-)

13:43 dnolen: samaaron: ha! no way, overtone is like 3 years of work :)

13:44 samaaron: did you see that someone used overtone to make a simple sequencer in their first night of hacking?

13:44 dnolen: no but that's great, it's really cool to see it taking off.

13:45 samaaron: and someone else sequenced Prokofiev's Troika with full bell synthesis in one gist: https://gist.github.com/1467356/886db6ce94fc393877629620659f3af81739ac1b

13:45 insanely cool

13:49 dnolen: wow

13:50 samaaron: stuff like that totally makes my day

13:51 right, home time :-)

14:00 seancorfield: quick emacs Q: I want to this Pig mode https://github.com/motus/pig-mode/blob/master/pig-mode.el but I'm not sure where to put the file - what's "site-list"?

14:01 s/want to/want to add/

14:01 technomancy: seancorfield: try M-x package-install-file first; if that doesn't work you'll need a manual install

14:02 seancorfield: pig isn't on the package list (hence that question :)

14:04 misread that... site-lisp... is there a standard place i'll find that? somewhere inside ~/.emacs.d ?

14:06 technomancy: it just means put it on your load-path somewhere

14:06 ~/.emacs.d is fine

14:06 clojurebot: In Ordnung

14:06 technomancy: ...

14:07 Bronsa: lol

14:07 technomancy: clojurebot: forget /.emacs.d |is| fine

14:07 clojurebot: I forgot that /.emacs.d is fine

14:16 ljos: I was just wondering, what is the rational for having the doc-string before the arg-list in a function declaration and not after? I think it looks tidier with it after, but there might be a good explenation for why?

14:17 arohner: ljos: because if you have a fn with multiple arities, where should the docstring go?

14:17 (defn foo "a doc string" ([x] (+ x 2)) ([x y] (+ x y))

14:18 Bronsa: why not?

14:18 oh

14:18 that's right

14:20 ljos: That looks like a good explenation, but the two are distinct. In the event of multiple arities it should be before, but when the arity is 1 it should be after. It looks cleaner imo.

14:20 Though I see that that might cause confusion.

14:21 technomancy: better to be consistent

14:26 ljos: I agree with that usually, but in this case I just think it makes it less readable when you have arity 1, and in my experience most functions have arity of 1. What I could imagine though is the possibility to choose where to put the meta-data yourself by using the tag in the outmost body. Like this: (defn foo [x] ^:doc "A doc string" (+ x x))

14:31 tmciver: cleanliness is in the eye of the beholder. Consistency is cleaner to me.

14:35 technomancy: http://neptune.cocollage.com/people/jmeowmeow/items/6252/

14:35 just saw that come up on the screen at the coffee shop I'm at.

14:35 looks like midje has a new logo?

14:37 ljos: What I mean by consistent and cleaner is that when I the docstring after the arg-list I just have to look at the first line to know how to access the function, but with the other I will not know if I have to look at the first or the second. But I agree it is more consistent; and consistancy is usually better.

14:38 duck1123: personally, I prefer my arg lists to almost always be on their own line. (with the exception of very short fns)

14:40 ljos: Either way it is still cleaner. In my case you will always know that it is the next argument in the defn that is the arg list, but not so in how it is now since there might be a docstring or not.

14:41 duck1123: but if you have multiple arities, then the next element is a list, so it's not that easy already

14:42 (defn foo "calculate foo" ([] 0) ([x] x))

14:43 ljos: That is true, but with multiple arities you already have the problem with finding the arg-list.

14:44 amalloy: since we're on the topic of defns, am i the only one who thinks it's crazy that defn (a) allows attr-map at all, and (b) allows it before-or-after the docstring? does this feature predate an easy way to attach reader metadata?

14:45 technomancy: I'm guessing yes on the latter.

14:47 hiredman: technomancy: I don't think it does

14:51 TimMc: amalloy: Why is it crazy to allow attr-map? (You mean (defn foo ^{:foo :bar} [x] x), right?)

14:51 amalloy: TimMc: no, i mean (defn foo {:foo :bar} [x] )

14:51 hiredman: maybe it predates the implicit copying of symbol-name meta onto the var meta?

14:52 TimMc: Oh, I see -- no caret, of course.

14:52 amalloy: it just seems so weird to me that you would add this feature if it were already possible&easy with metadata

14:53 TimMc: And apparently the attr-map can go after the body too.

14:53 amalloy: no way, really?

14:54 TimMc: yep, in the explicit-arities verison

14:54 amalloy: i know you can have per-arity attr-maps, but those are after the arglist, not the body

14:54 TimMc: &(doc defn)

14:54 lazybot: ⇒ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"

14:55 TimMc: The second form allows (defn foo ([x] x) {:foo :bar}) -- just tested it.

14:56 amalloy: gratuitous inconsistency!

14:56 TimMc: Where does it allow it before the docstring?

14:56 amalloy: TimMc: am i wrong? i thought it did

14:56 TimMc: I tried adding 3 attr-maps and it didn't work.

14:57 amalloy: apparently i'm wrong. fair enough

14:57 TimMc: Still pretty weird.

14:57 amalloy: TimMc: you could squeeze in ~23 attr-maps in a multi-arity function :P

14:58 TimMc: I don't see how to add attr-maps per-arity.

14:58 amalloy: man am i wrong about this too? i thought the point was to have different preconditions for different arglists

14:59 TimMc: Good point.

14:59 amalloy: ah, yes

14:59 http://clojure.org/special_forms#fn

15:01 ambrosebs: I brought up the attr map after the body with rhickey, he was saying he thought it would be nice if you had a ton of metadata so it didn't dominate the start of the fn. But it's a little known and unused feature

15:01 technomancy: in 1.7.8: "git diff learned --function-context option to show the whole function as context that was affected by a change" <- I wonder if this is extensible or just assumes an ALGOL-like.

15:01 Raynes: ambrosebs: Your logic tutorial thing is directed at people with no prior experience with logic programming, right?

15:02 ambrosebs: Raynes: yes, I tried

15:02 TimMc: (defn foo "doc" {:a 2} ([x] {:b 4} x) {:c 3}) <- but :b never makes it into (meta #'foo), of course

15:02 Raynes: ambrosebs: Then thank you and I'll read it later. I'm tired of not having any clue what the big deal is.

15:02 `fogus: TimMc: It wouldn't. That's a pre/post map

15:03 Turtl3boi: what is the definition of "meta data"

15:03 TimMc: Can it contain arbitrary keys/values?

15:03 Raynes: `fogus: I've decided to call our little marginalia console app 'marg'. Is that appropriate?

15:04 `fogus: I figured the command would be 'marg', so naming the project itself that made sense.

15:04 ambrosebs: Raynes: also check out the Lojic series on clojure.org by stuartsierra

15:05 `fogus: TimMc: The pre/post map? Yes, it's a regular map. The :pre/:post keys are privileged, the rest go bai

15:05 TimMc: aha

15:05 `fogus: Raynes: Marg++

15:05 Raynes: I did. It was fun, but a little too brief and I didn't really get the "oh, so that's the point" feeling from it.

15:05 More posts will probably fix that.

15:05 arohner: Turtl3boi: metadata is extra data you can attach to a value that doesn't change its value

15:06 Turtl3boi: is this something for the compiler usually

15:06 TimMc: In practice, yes.

15:06 You attach metadata to the lists and vectors and maps that make up your code's structure.

15:06 ambrosebs: Raynes: that's the trick. It's hard to convince people this stuff is useful without first doing the hard yards

15:07 gfredericks: Turtl3boi: ##(= [1 2 3] (with-meta [1 2 3] {:foo "bar"}))

15:07 lazybot: ⇒ true

15:08 Turtl3boi: what is that? like a #define?

15:08 Raynes: ambrosebs: I think the problem is that when you're so passionate about a certain technology, it can become difficult to explain why it is so great to other people. I sometimes get a "why don't they just get it naturally!" feeling sometimes.

15:08 gfredericks: Turtl3boi: no ## is what lazybot uses for inline eval

15:09 Turtl3boi: so what's going on there? are you attaching metadata to [1 2 3]

15:09 gfredericks: Turtl3boi: so I was just getting it to evaluate (= [1 2 3] (with-meta [1 2 3] {:foo "bar"}))

15:09 yep

15:09 Turtl3boi: what's the metadata in this case? the {:foo "bar"} ?

15:09 gfredericks: yep

15:09 ,((juxt meta first) (with-meta [1 2 3] {:foo "bar"}))

15:09 Turtl3boi: now tell me WHY you would want to do that in this case

15:09 clojurebot: [{:foo "bar"} 1]

15:10 TimMc: ,(instance? clojure.lang.IMeta [1 2 3])

15:10 clojurebot: true

15:10 gfredericks: Turtl3boi: no reason :) I was just demonstrating that it doesn't change the value

15:10 ambrosebs: Raynes: I'm usually lost for words when people ask. I wrote that tutorial while I was learning logic programming, so I'd hope I covered the common misunderstandings

15:11 arohner: Turtl3boi: metadata is used for a lot of fun things. docstrings are metadata, the debug information about file and line number are metadata

15:11 and it's left open so users can discover new uses for it

15:11 Raynes: ambrosebs: It should be great. As long as there are no more than 2 uses of the word 'cheeky' in it. Are all aussies attached so attached to that word? :P

15:11 ambrosebs: :D

15:11 Raynes: Minus one attached. Donating that one to charity.

15:12 TimMc: either one?

15:12 I guess it makes sense either way.

15:13 amalloy: TimMc: Raynes tries to write fault-tolerant IRC messages

15:14 Raynes: Fault tolerance! Speaking of that, Tentacles has that now. Doesn't throw exceptions every time Github flips you off anymore.

15:14 And oauth2 support, given arohner.

15:14 <3

15:14 `fogus: Raynes: Thanks for taking marg BTW.

15:15 s/taking/tackling/

15:15 Raynes: If people don't start writing tentacles crap soon, I might just explode.

15:15 `fogus: I'm taking it to the bank.

15:15 ambrosebs: chaching

15:16 Raynes: `fogus: Without needing to copy run-marginalia, it's like a 6 line application. I'm just lazy. Should have had it done by now.

15:17 daniel: https://gist.github.com/1473695 can anyone see why im getting this error?

15:20 ambrosebs: this will probably interest a few here (if you know haskell, think protocol=typeclass) https://github.com/frenchy64/typed-clojure/blob/813e8c0e0b7b1beec522bbc70e90034111a8b674/src/typed_clojure/test.clj#L11

15:20 brehaut: whoa

15:20 `fogus: Raynes: Understood. 6 lines of code. 635 lines of marg docs!

15:21 brehaut: ambrosebs: is all that working‽

15:21 ambrosebs: experimenting with syntax of course, but I have got a very simple type checker working

15:21 no

15:22 TimMc: daniel: Where is that error originating?

15:22 dnolen: ambrosebs: nice

15:22 pjstadig: `fogus: i ran into a bug in unk yesterday

15:23 at least i think it's a bug

15:23 daniel: TimMc: when i try to open /:id/login in my browser, seems to originate from the (defpartial login line

15:23 pjstadig: not sure how to handle it mid transition to contrib

15:23 daniel: I have another partial which is giving me a different error: Wrong number of args (2) passed to: notepad$lock - (class clojure.lang.ArityException)

15:23 (defpartial lock [{:keys [id password]}]

15:24 (2 args) is what it should be

15:25 `fogus: pjstadig: A ticket at http://dev.clojure.org/jira/browse/CMEMOIZE would be great

15:26 brehaut: what is this clojurescript analyzer that typed-clojure's readme mentions?

15:26 TimMc: daniel: Well, login expects a map, but (login id) is probably not passing it one.

15:26 nickmbailey: is there an idiomatic way to take a map of properties and convert it to 'setProp' calls on a java option for interop?

15:27 ambrosebs: https://github.com/frenchy64/typed-clojure/blob/874ab3f5ab62a15f0cafa1006f8c5b3c00eec7d1/src/clojure_analyzer/compiler.clj

15:27 I've converted the CLJS compiler (analyzer portion) to work on CLojure code

15:27 example usage: https://github.com/frenchy64/typed-clojure/blob/874ab3f5ab62a15f0cafa1006f8c5b3c00eec7d1/src/clojure_analyzer/docstrings.clj

15:28 not all things work, but enough to get some work done

15:28 nickmbailey: like {:prop1 100 :prop2 200} -> (doto (new Object) (.setProp1 100) (.setProp2 200))?

15:28 TimMc: nickmbailey: Basically, convert to bean accessors?

15:28 daniel: TimMc: same error if i change to (defpartial login [id]

15:28 nickmbailey: bean setters yeah

15:28 brehaut: (map munge params) <- lol

15:29 nickmbailey: dammit i have to leave for a sec but thanks in advance for any advice

15:29 ambrosebs: brehaut: heh, (def munge identity)

15:29 brehaut: haha

15:30 ambrosebs: the whole thing is a bit of a hack of course

15:30 (my conversion)

15:30 I'll start a serious attempt soon

15:31 brehaut: ambrosebs: what information does the analyzer produce?

15:32 oh. dont worry, i just found analyze and its docstring

15:32 ambrosebs: it's lots of fun to play with

15:35 pjstadig: `fogus: http://dev.clojure.org/jira/browse/CMEMOIZE-3

15:37 daniel: it seems like my error is due to the form-to helper, i have another partial which works fine

15:37 also uses a map of :keys

15:45 TimMc: daniel: "Named" indicates something is calling (name ...), perhaps for a map key or a field name. "Character" means maybe a string is getting turned into a seq.

15:52 daniel: TimMc: think i've found the problem, i need to pass form-to a vector

15:52 thanks

15:52 `fogus: member:pjstadig: Thanks! Even better would be to assume that the underlying cache is an associative structure. So maybe it's enough to get the snapshot via (into {} (.cache @cache))

15:53 pjstadig: ^^^

15:54 pjstadig: `fogus: oh right, yeah that would be better

15:55 `fogus: But, yes. Patches welcomed. :-)

15:59 pjstadig: `fogus: actually wouldn't (into {} x) treat x as a seq, maybe just returning (.cache @cache) is all that's needed if the underlying cache can be assumed to be associative?

15:59 pyr: `fogus: I see that you mention AsyncCacheProtocol in the core.cache 0.5.0 announcement

15:59 pjstadig: i guess we have to deref the delays though

16:03 `fogus: pjstadig: We can return the cache directly if it's immutable I suppose, but they might not all be.

16:03 pyr: Indeed

16:03 gotta run gentle-persons

16:04 bai now

16:11 daniel: can anyone enlighten me on this error? Key must be integer - (class java.lang.IllegalArgumentException)

16:13 nevermind, i think im passing around anull value somewhere

16:15 amalloy: daniel: you will get about twenty times as much help with errors if you gist an actual stacktrace instead of excerpting the part you think might be relevant

16:16 for this particular error it's easy though: you're looking up an index in a vector, and the index isn't an integer

16:16 &(get [1 2 3] 1)

16:16 lazybot: ⇒ 2

16:16 amalloy: &(get [1 2 3] "test")

16:16 lazybot: ⇒ nil

16:16 amalloy: &([1 2 3] "test")

16:16 lazybot: java.lang.IllegalArgumentException: Key must be integer

16:32 Turtl3boi: OH "Lisp" stands for "List processing"

16:32 daniel: amalloy: thanks

16:33 Somelauw: john mccarty died this year in october

16:33 He was the inventor of lisp

16:34 TimMc: daniel: Ah, so your string *was* getting seq called on it, and then name was getting called on the first char.

16:34 Turtl3boi: awww man

16:34 i didn't even know that

16:35 Somelauw: I didn't saw it in any newspapers and learned it by actually visiting wikipedia.

16:36 daniel: well they were busy reporting on Steve Jobs

16:37 Turtl3boi: well i should've known more about the Lisp language

16:37 amalloy: re mccarthy: https://twitter.com/#!/danbernier/status/128599665737338882

16:39 (point being, i guess, that the CS "media" was pretty busy at the time)

16:40 Somelauw: What!? Is Ritchie dead as well?

16:40 amalloy: yes

16:40 october was a sad month

17:25 lobotomy: argh, how the heck is binding supposed to work

17:26 is it not supposed to cascade down function calls? or is there something else wrong here

17:27 cgray: in compojure, is it possible to have a route like "/foo/:bar" and have that get called when the url is "/foo/bar.baz"?

17:28 i.e., have dots in the url

17:30 aha, it looks like you can with ["/foo/:bar" #"[a-zA-Z0-9\.]*"] or so

17:31 oops ["/foo/:bar" :bar #"[a-zA-Z0-9\.]*"]

17:32 amalloy: cgray: fwiw, the \ in \. there is irrelevant

17:32 cgray: amalloy: thanks

17:33 and I guess it should be + instead of * at the end, so that the empty string isn't accepted

17:33 amalloy: actually that whole regex is #"[\w.]+"

17:33 i think? you can put \w inside character classes, right?

17:34 nickik: some emacs hacker around?

17:34 amalloy: &(re-seq #"[\w.]+" "words. more words.")

17:34 lazybot: ⇒ ("words." "more" "words.")

17:34 amalloy: ~anyone

17:34 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

17:38 cgray: can the percent symbol not go in a character class?

17:39 lobotomy: on binding: why doesn't the following code work? -> http://pastebin.com/NZegZQSw

17:39 cgray: &(re-seq #"[\w.+-\%]+" "words.+with-pluses%")

17:39 lazybot: java.util.regex.PatternSyntaxException: Illegal character range near index 7[\w.+-\%]+ ^

17:39 cgray: needed another \

17:39 amalloy: cgray: \%, really? take all the \s out of your regexes :P

17:39 cgray: amalloy: didn't work that way

17:40 amalloy: well \\% is certifiably crazy if you just want to allow %. it's identical to % except that it also allows backslashes

17:41 it's the - that's causing you problems

17:41 cgray: damn it

17:41 amalloy: #[-\w.+%]

17:41 #"[-\w.+%]"

17:41 cgray: yep, you're right

17:41 _ulises: ahoy

17:42 lobotomy: (also, how the hell do i disable the pause in emacs after slime returns an error)

17:42 amalloy: lobotomy: i think it's fair to say that the odds of anyone reading-and-executing all that code and telling you what's wrong is roughly 0%.

17:43 _ulises: lobotomy: ref. 1st question, that's quite some code, which bit doesn't work?

17:43 oh, heh

17:43 lobotomy: the last 15 lines are the relevant ones

17:43 amalloy: but you're probably experiencing issues related to the interaction between laziness and binding

17:43 yes, definitely

17:43 lobotomy: binding works when i do one thing, when i do multiple things it doesn't

17:44 if i put the for inside a binding, that also doesn't work

17:44 amalloy: no, it works when you do N things, but you are doing 0 things. for returns a lazy sequence

17:44 weavejester: cgray: The latest RC of Compojure supports "." in keywords.

17:44 By default

17:44 lobotomy: even though all the things work individually

17:44 amalloy: by the time elements of that lazy sequence are evaluated, the binding is no longer in place

17:44 lobotomy: my theory is that whoever coded up this stuff is even less capable with clojure than i am

17:45 amalloy: no, it's just you

17:45 cgray: weavejester: good to know, though I am hacking on 4clojure, so I guess it's up to the team if they want to use the RC

17:45 _ulises: nice theory

17:45 lobotomy: i mean, that isn't my code

17:45 except for the last 15 or so lines

17:45 amalloy: cgray: the only issue is in the last 15 or so lines

17:46 cgray: what are you adding?

17:46 cgray: amalloy: openid support

17:46 amalloy: er, lobotomy: the only issue is in the last 15 or so lines

17:46 nice, thanks

17:46 lobotomy: so you mean i can't use for in the code?

17:46 cgray: amalloy: thank me when it's done :P

17:46 lobotomy: what do i do then, use doseq instead?

17:46 amalloy: lobotomy: you need to understand how lazy sequences and binding interact. once you understand that, you can use for whenever you want

17:47 lobotomy: well, how do they interact?

17:47 amalloy: for immediately returns a lazy sequence. by the time elements of that lazy sequence are evaluated, the binding is no longer in place

17:47 lobotomy: yes, i got that

17:47 amalloy: it's the difference between lexical scope and dynamic scope

17:48 &(let [f (binding [*clojure-version* 10] (fn [] *clojure-version*))] (f))

17:48 lazybot: java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!

17:48 amalloy: ,(let [f (binding [*clojure-version* 10] (fn [] *clojure-version*))] (f))

17:48 clojurebot: {:major 1, :minor 3, :incremental 0, :qualifier nil}

17:49 amalloy: ,(let [f (let [*clojure-version* 10] (fn [] *clojure-version*))] (f))

17:49 clojurebot: 10

17:49 lobotomy: now that i've understood that, how do i get for to work?

17:50 amalloy: any number of ways. you could wrap a doall around the body of try-things

17:51 you could have try-things capture *game-info* lexically, and then rebind it dynamically at each iteration of the for

17:58 Somelauw: Something that really annoys me is that all lisp dialects have a different order in which to supply the arguments to reduce.

18:06 amalloy: Somelauw: really? what do scheme and CL use?

18:09 fwiw, haskell uses the same order clojure does, for both foldl and foldr

18:10 brehaut: it happens to be the most useful order for partial application

18:11 Somelauw: amalloy: scheme does (foldl cons '() '(1 2 3))

18:11 '(3 2 1)

18:11 amalloy: that's the same order as clojure?

18:11 Somelauw: CL does (reduce #'cons '(1 2 3))

18:11 ((1 . 2) . 3)

18:12 clojure does lisp order, but clojure can't use cons that way

18:12 brehaut: ,(reduce conj () '(1 2 3))

18:12 clojurebot: (3 2 1)

18:12 Somelauw: (reduce list [] [1 2 3])

18:12 ((([] 1) 2) 3)

18:12 brehaut: i think you mean that the reduce function takes the arguments in reverse order

18:12 weavejester: If I want to remove a piece of data from a vector whilst maintaining its order...

18:13 amalloy: weavejester: don't use a vector :P

18:13 weavejester: Is there a better way than just (vec (remove (partial = blah) d))

18:13 amalloy: What would I use instead?

18:13 kephale: cant you use ordered.set?

18:13 weavejester: There's an ordered set?

18:13 amalloy: nah, ordered.set is pretty bad at disjoins too

18:13 weavejester: i implemented one; it keeps a backing set and vector internally

18:14 weavejester: I'm not worried about performance; it's more an example.

18:14 amalloy: updates both, reads from one or the other, depending whether you want ordering or membership test

18:14 weavejester: i don't think a good data structure for what you want really exists ready-made (in clojure)

18:15 a vector would be fine for an example, though using seqs probably makes more sense if you're going to be doing much removing

18:15 weavejester: amalloy: So is (vec (remove (partial = item) coll)) the best way of writing it, do you think?

18:15 Somelauw: The code for cl was wrong, it should be: (reduce #'cons '(1 2 3) :initial-value '())

18:15 (((NIL . 1) . 2) . 3)

18:16 amalloy: weavejester: well, unless you have duplicates in the list

18:16 weavejester: amalloy: Fortunately nope

18:17 amalloy: if you wanted to be careful about that case you could write ##(let [v [1 2 3 1 2 3] [before [x after]] (split-with (complement #{3}) v)] (vec (concat before after)))

18:17 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

18:18 amalloy: or...apparently not actually that, but something close?

18:18 Somelauw: And clojure and scheme don't use the same order. conj just takes the arguments in opposite order than cons.

18:19 brehaut: Somelauw: _reduce_ takes the functions in the same order, the function to reduce takes them in reverse order

18:19 _ulises: amalloy: would you mind explaining to me the interaction between lazy seqs and bindings? I've been bitten before with binding and threading so I wouldn't mind understanding a bit more about the interplay there. Alternatively, I'm happy with an RTFM and a pointer :)

18:20 amalloy: if you've already read my explanation to lobotomy i'm not really up to something more detailed

18:20 &(let [v [1 2 3 1 2 3] [before [x & after]] (split-with (complement #{3}) v)] (vec (concat before after))) ;; forgot the &

18:20 lazybot: ⇒ [1 2 1 2 3]

18:20 _ulises: ok, no worries, thanks anyway :)

18:31 lobotomy: i went with doall, seems to work and is simple enough for now

18:38 cgray: amalloy: if you want to play with the openid code, have a look at the openid branch in my github https://github.com/chrismgray/4clojure/tree/openid ... I think it's getting pretty complete

18:38 sdeobald: Does anyone know if clojure.math.expt has found a new home yet in 1.3?

18:43 amalloy: cgray: if you're interested in getting feedback or a dialog about your changes, you can open a pull request. if the feature isn't "done" yet, then just make a note that you don't want it actually pulled. pull requests are great for review/discussion, because they're a centralized place to have a discussion

18:49 * gfredericks spent 45 seconds trying to interpret the phrase "explanation to lobotomy"

19:14 cgray: amalloy: ok, will do

20:19 wiseen: is there a logging library (like tools.logging) for clojurescript ?

20:22 cgray: wiseen: I don't know tools.logging, but for simple logging, you can use (.log js/console foo)

20:25 wiseen: cgray, will that work cross browser ?

20:25 by work I mean not fail :)

20:27 cgray: wiseen: I think so

20:27 it works on chrome and firefox

20:28 amalloy: i think console.log is part of the js spec (and a part that is actually implemented by everyone)

20:33 dnolen: cgray: console.log will not work on < IE 8, if that matters.

20:34 cgray: dnolen: it doesn't to me, it might to wiseen :)

20:36 wiseen: will just add dummy log-error and log-info to my lib

20:36 so I can turn it off/on when I want

20:57 TimMc: It's only available if you have a debugging tool, AFAIK.

20:58 IE 8 and Chrome come with dev tools by default.

21:25 gtrak```: I think it is (abstract (singleton ((proxy factory) bean)))

21:25 after much deliberation

21:48 jhirn: This may be unorthodox, but is it possible to bind the result of a :when test to return in a list comprehension.

21:48 EX; (for [x xs :when (fn x y)] [x (fn x y)])

21:49 licenser: jhirn: map it beforehand?

21:50 (for [[x r] (map (fm [x] [x (f xs)) xs) :when r] [x r])

21:50 or along the line

21:50 jhirn: Let me see if that works for my case

21:51 licenser: not when you just copy since I messed yup f and fn ^^

21:51 also I forgot your y

21:51 jhirn: =) I'll interpolate

21:51 licenser: fine fein :)

21:51 *pets on the head and tosses a cookie* good programmer, what a goooood programmer

21:51 * licenser runs and hides

21:56 jhirn: Still working on it, pulling a function out atm

21:57 licenser: ^^

21:57 * licenser brb's

21:57 dnolen: ambrosebs: starting to dig into the CLJS analyzer, it's pretty nice how much is already there. do you use the cljs.compiler/namespaces atom at all?

22:06 jhirn: So this is my actual comprehension. I'm not convinced it has to be a comprehension but this is the wall my head is currently cozy with.

22:06 (for [original-filename (:deleted-files files)

22:06 :when (moved-file-location original-filename (:new-files files)) ]

22:06 [original-filename, (moved-file-location original-filename (:new-files files))])

22:09 brehaut: jhirn: i think (keep (fn [original-filename] (when-let [loc (moved-file-location original-filename (:new-files files))] [original-filename loc])) (:deleted-files files))

22:09 is equivalent

22:10 jhirn: it passes the test, thanks.

22:11 brehaut: jhirn: you might find :let useful in your comprehension version too

22:11 jhirn: ah.... can you combine :let and :when?

22:12 brehaut: ,(for [a (range 10) :let [b (* a 3)] :when (odd? b)] b)

22:12 clojurebot: (3 9 15 21 27)

22:15 jhirn: That is exactly what was I was looking for brehaut!

22:15 Many thx.

22:21 reiddraper: Any ideas why defrecord and deftype don't take docstrings? Or am I missing something?

22:28 melipone: hi! what's the best way to find an element in a collection in clojure?

22:28 brehaut: reiddraper: presumably because they generate classes, and classes come from javaland and thus cant have meta data

22:28 melipone: it depends on the collection

22:28 melipone: msg brehaut how about '(a b c d e f) and I want to find the position of d?

22:29 brehaut: melipone: its uncommon to use a list for a list in clojure, you probably mean a vector or a seq?

22:29 melipone: brehaut: yes

22:30 brehaut: (that was terribly imprecise english)

22:31 melipone: LOL

22:31 brehaut: so with a vector you can do

22:31 ,(.indexOf [1 2 3 4] 3)

22:31 clojurebot: 2

22:31 melipone: oh, I can do that?

22:31 reiddraper: brehaut: that makes sense, thanks

22:32 melipone: thanks, I thought that indexOf was only for strings

22:32 but strings are vectors too ...

22:32 brehaut: melipone: clojure's collections implement the appropriate java collections api methods

22:32 melipone: strings are assuredly not vectors

22:33 but both are able to be coerced into sequences

22:35 melipone: i dont know how you would find the index of something in sequence though

22:35 huh. apparently .indexOf works again

22:35 melipone: in both cases i would expect it to be an O(N) operation

22:40 melipone: the other comment is that if you are using either a seq or a vector and wanting the index of things, you are probably using the wrong datastructure

22:48 amalloy: brehaut: java.util.List has .indexOf - vectors and seqs implement that, but maps don't

22:49 brehaut: amalloy: yeah i realised that vectors didnt, i wasnt aware that seqs did

22:49 amalloy: List being, basically, "an ordered Collection"

22:51 gtrak```: TimMc, glad we got that cleared up :-)

22:52 amalloy: but i'd like to echo brehaut's last point: if you're trying to look up something's index in a collection, you're probably using either a bad algorithm or a bad data structure. i tried to make that point myself but apparently wasn't connected to irc at the time :P

23:01 melipone: amalloy: what should I be using then?

23:01 amalloy: impossible to answer in isolation

23:17 reiddraper: is autodoc popular outside of clojure.org? It seems that people have been putting their own releases on clojars because there haven't been official releases in forever

23:28 technomancy_: reiddraper: yeah, there are issues with autodoc. most people seem to prefer marginalia.

23:29 reiddraper: technomancy_: thanks, i think marginalia is awesome, and was hoping to have both types of documentation. oh well

23:31 technomancy_: I never really saw the point; having docstrings available at runtime always seemed a lot more convenient than reading HTML

23:31 unless you need to send a link to someone, I guess

23:32 reiddraper: technomancy_: the point of marg or autodoc?

23:32 technomancy_: mostly autodoc, but I guess the same point applies to marginalia

23:33 marginalia is a bit different since it's all on one page though, which you don't get with reading source

23:33 reiddraper: I think there is something to having the "public" api in one place, which is what i was hoping to get from autodoc

23:34 technomancy_: do you use slime?

23:34 reiddraper: nope

23:34 vim user

23:36 either way having html docs is nice for new users who haven't even necessarily got a repl open with your project, just starting to see if it's well documented, etc.

23:36 technomancy_: yeah, I guess so

23:39 reiddraper: technomancy_: otherwise why would heroku have html docs :)

23:40 technomancy_: welllll...

23:40 reiddraper: hehe

23:40 technomancy_: documenting an application is very different from documenting a library

23:40 lots of docs here: https://github.com/technomancy/leiningen/tree/master/doc

23:41 tmciver: I've got a project with a print method and when I use it I get a warning that 'print already refers to clojure.core/print' which is fine. But when I (use :reload my-ns) I get an IllegalStateException. What should I do about that?

23:41 dnolen: anyone got opinions about this ClojureScript enhancement? https://github.com/clojure/clojurescript/compare/master...analyzer-plus, it brings back some of the functionality that was lost from Vars and Namespaces not being reified in ClojureScript.

23:42 reiddraper: technomancy_: and those are another great type of documentation. I sort of like the idea that there are three types of documentation. 1. high level tutorial or narrative type. 2. public api ala clojure.org 3. code comments

23:43 technomancy_: reiddraper: yeah, I just think most of the time reading comments from the files themselves is more convenient than a web page

23:46 reiddraper: technomancy_: sure, fair enough

23:51 ambrosebs: dnolen: what exactly is it doing?

23:51 dnolen: ambrosebs: storing the line numbers of all defs

23:51 ambrosebs: that's normally done on vars in Clojure

23:51 ambrosebs: ah cool

23:52 dnolen: ambrosebs: but really it's more than just about line numbers, cljs.compiler/namespaces becomes the place to go after running cljs.compiler/analyze-file

23:53 technomancy_: ambrosebs: curious what the rationale for not using type hints for typed-clojure is

23:53 ambrosebs: technomancy_: heh, actually still juggling. It's starting to look like an ok idea

23:54 technomancy_: ambrosebs: if it were me I would have just taken it for granted, so it's good that you're thinking it through. =)

23:55 ambrosebs: technomancy_: seemed funny to me to use a compiler "hint" as static type information

23:55 but it's clean

23:55 and has type information :)

23:56 technomancy_: yeah, I can see how you wouldn't want to complect "here's something to help you avoid reflection" with "help me tell if this program is correct" but I don't really see them diverging at all in practice

23:57 ambrosebs: exactly, I just need a little more convincing

23:58 technomancy_: technically right now types that don't match the hint are not bugs by definition, but it's hard to imagine real cases where they are intended.

23:58 best-case is they're harmless.

23:59 ambrosebs: yes

Logging service provided by n01se.net