#clojure log - Jan 12 2014

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

0:00 Tolstoy: Set up a project, serve out an index.html page, then use cljsbuild to play with clojurescript.

0:02 With cljsbuild, I don't think you even need a clojure server side.

0:04 kanja: cljsbuild is something to check out then

0:13 ddellacosta: kanja: definitely *don't* start with pedestal if you want to use cloact. Do something like create a new cljs project with David Nolen's mies template, then add cloact. lein new mies my-project-name

0:15 kanja: @ddellacosta mies? I'll try that - thanks for the tip!

0:16 bitemyapp: kanja: if you want an easy shake-n-bake way to go for Clojure web dev backends check out luminus. It's essentially a template for common-case Ring and Compojure stuff.

0:17 kanja: @bitemyapp Awesome, thanks!

0:21 Tolstoy: I kinda get the feeling that ClojureScript is a nice little secret weapon.

0:22 ddellacosta: kanja: np

0:28 egghead: clj is a very fun web stack these days, most recently i've been playing with liberator, compojure, cljs-http, & om

0:29 cljs http in particular, interacting with http (ring) the same way on client and server is very nice :)

0:30 benzap: so typically, do you write the cljs files the same way you would write a clj file

0:30 and then it generates the proper js file when it's requested?

0:31 egghead: usually you compile a cljs app into a single js file including all deps, with a single entry point

0:32 benzap: so the deps can be just pure javascript?

0:32 like, i could include jquery

0:33 egghead: mhmm, you can and there is a cljs wrapper for making it more idiomatic in clj

0:33 benzap: alright cool

0:33 noonian: but there are better options than jquery in cljs imo

0:33 benzap: i'm just trying to learn clojure for now, but i'm really interested in compjure with clostache

0:34 egghead: noonian: I agree

0:35 benzap: there's always better options than jquery ;)

0:35 egghead: benzap: cljs is built on top of the google closure js library, so there are some nice libs wrapping googles stuff

0:35 benzap: ah ok

0:35 I was wondering why a lot of the examples had goog in it

0:54 ddellacosta: benzap: Self-promotion, but I recommend checking out my article on dom libs here if you want to know more: http://davedellacosta.com/cljs-dom-survey

1:33 bitemyapp: arrdem: ring ring

1:37 arrdem: http://i.imgur.com/oO2SSs1.jpg

1:37 arrdem: rat dota.

3:45 shock_one: Is there something like haskell's flip in clojure, which flips function's parameters? (a -> b -> c) -> b -> a -> c

3:46 noonian_: you could write it pretty easily

3:47 shock_one: I understand, but it would be silly if there is a built-in function.

3:48 noonian_: i don't think there is a built in one

3:49 shock_one: Thank you.

4:32 Guest68185: looking at tarsnap-keymgmt i was thinking of leaving a key on the server with just -w (so if hacked an attacker couldnt delete archives), however does -w give the ability to rewrite/overwrite hence with a tiny bit more work causing the same effect of -d?

4:33 sorry wrong room

4:46 Raynes: ifesdjeen: Hi.

5:46 quizdr: nice

7:21 indiana: hello all

7:21 why println "hello" "world" produce "hello world" - not "helloworld"?

7:22 hyPiRion: because println and print makes spaces between the arguments given

7:23 indiana: how i can print it without whitespaces?

7:23 hyPiRion: use (str ...) first, then println

7:23 so ##(println (str "hello" "world"))

7:23 lazybot: ⇒ helloworld nil

7:23 indiana: thanks man :) i am new in clojure

7:24 hyPiRion: no problems, hope you enjoy it :)

7:26 indiana: do you have any experience with java in web applications? do you like more using clojure for web applications?

7:27 hyPiRion: I haven't used Java for web applications, but I've done some work in Clojure and I think it's good for that purpose.

7:28 indiana: I'm java programmer and i try clojure now. I hope that i will be happy with clojure :)

7:30 hyPiRion: ah. The hardest part from a Java-background is that you'll have to learn how to program without mutation (and the parentheses), but when you finally manage to work with just immutability, it's really satisfying

7:33 locks: hyPiRion: the parens are the same, they’re just on the outside ;)

7:33 immutability is doing my head in though

7:34 being used to Ruby et al

7:35 alew: so I have these nested error checks that go about 7 ifs/if-lets deep

7:35 is there a better way to format it so that they aren't so nested?

7:35 hyPiRion: locks: yeah, that's why I put the parens in parens (heh). They are a bit scary and unknown at first, but when you've worked just a little bit with them, stuff gets so much easier

7:35 alew: every failed check evalulates to a single statement that returns an error message

7:36 hyPiRion: alew: a cond perhaps?

7:37 locks: hyPiRion: I think it was stuart that demonstrated in a talk that Clojure actually had less parens than a Java example

7:37 hyPiRion: granted it was probably a cherry picked example, but it’s always entertaining busting myths

7:38 alew: I also need to have binding lets some ways down

7:38 I'll probably just write a let-cond

7:38 or something

7:39 hyPiRion: ah, bindings.

7:39 alew: would be simple otherwise

7:40 hyPiRion: yeah, I think actually making a cond-let would be fair there.

7:41 alew: someone made this http://clojuredocs.org/clojure_contrib/clojure.contrib.cond/cond-let

7:41 but I want to have conditionals and optional let bindings on each condition

7:41 a cond with both if and if-let options

7:45 hyPiRion: well, hm.

7:46 A cond takes a single branch only. How would a let binding in a cond work?

7:47 alew: like how if-let works

7:47 hyPiRion: alright

7:48 alew: (let-cond (testexpr) "error 1!" [a (non-nil-operation)] "error 2!" :else "success!")

7:48 maybe something like this?

7:49 hyPiRion: I'd guess you would use a in the "error 2!" statement

7:50 alew: if a is nil, then "error 2!" is returned

7:50 otherwise it continues on

7:50 oh yeah, that's weird..

7:50 hrm

7:50 hyPiRion: just (not) the thing

7:51 alew: the a, in this case?

7:51 hyPiRion: well, the (non-nil-operation)

7:55 alew: I guess it's a let-not-cond :P

7:55 beacuse it only evals the statements if the test expression is false

7:58 hyPiRion: well, here's a cond-let anyway https://www.refheap.com/22921

7:58 alew: did you just write this?

7:58 awesome

7:58 hyPiRion: yeah

7:59 alew: oh nice, using the if and if-let

7:59 hyPiRion: it's not that hard if you just know how to utilize the already existing macros

8:00 alew: https://www.refheap.com/22922

8:00 pretty easy to make the cond-let-not

8:01 DerGuteMoritz: uncond-let :-)

8:01 alew: need to add a check for a default case

8:01 doublepluscond-let

8:02 DerGuteMoritz: the default case shouldn't need special handling, it's just :else expr, no?

8:02 hyPiRion: DerGuteMoritz: yeah

8:02 DerGuteMoritz: so a regular if branch

8:02 alew: in this case it does

8:02 because of the switch

8:03 you want to eval the expression for the last clause if it is true

8:03 or I guess you could just pass nil

8:06 I fucking love macros

8:07 DerGuteMoritz: there's nothing cooler than a macro *sing*

8:08 alew: Great book

8:18 well, the uncond-let looks pretty ugly when there are tons of statements in it

9:14 benzap: So I ran the lein help, and it's not being nice

9:15 the examples don't seem to work

9:15 any ideas?

9:27 JoltinJoe: join eclipse

9:29 sandbags: benzap: what does "not being nice" and "don't seem to work" actually mean for you?

9:40 benzap: sandbags: sorry, I should give specifics

9:40 I ran lein help tutorial

9:40 followed the tutorial

9:41 the first part that didn't work was

9:41 (user/clojurefocs pprint)

9:41 while in lein repl

9:41 i called each of the functions before that

9:42 so everything should be imported

9:42 (i think)

9:42 if you grep lein help tutorial at line "user=> (require 'my-stuff.core)"

9:42 you should be where I started executing commands

9:43 it's unclear why it fails

9:43 sandbags: (user/clojuredocs pprint) works for me

9:43 without doing anything else

9:43 benzap: i'm going to try it again, one sec

9:44 sandbags: that "f" in clojurefocs was that a c&p error? or did you type that in the repl?

9:44 benzap: would also like to point out that i'm on emacs

9:44 with windows

9:44 and eshell

9:44 so it might even be my side

9:45 sandbags: but beyond that saying "didn't work" (again above) isn't useful to anyone trying to help you... if things fail please gist exactly what you ran and the output

9:46 benzap: so when I type (user/clojuredocs pprint)

9:46 i get CompilerException java.lang.RuntimeException: No such var: user/clojuredocs, compiling:(C:\Users\benzap\AppData\Local\Temp\form-init9134492706436301542.clj:1)

9:46 is this a dependency?

9:47 sandbags: i'm not sure

9:47 it's not clear to me where the clojuredocs function is coming from

9:47 i definitely have it here

9:48 benzap: that's strange

9:48 the second one I tried that gave me trouble

9:48 sandbags: here's my ~/.lein/profiles.clj => https://gist.github.com/mmower/b531456f82d7f842a9e4

9:48 possibly it's coming out of there somewhere

9:49 benzap: mine doesn't have anything in it

9:49 sandbags: puzzling, i don't see the function in the clojure docs in Dash

9:50 benzap: other than :java-cmd

9:50 and an empty :plugins area

9:50 i'll copy yours and see

9:50 sandbags: i think it might require someone with more clojure experience if that doesn't fix it

9:51 benzap: maybe the second problem is a configruation issue

9:51 i'm trying the uberjar example

9:51 it compiles the uber jar

9:51 I created the ./my/stuff.clj file and put the necessary stuff inside

9:51 called lein uberjar

9:51 used their project.clj file

9:52 and when I call java -jar my-stuff**....jar

9:52 it gives me the error...

9:52 oh my

9:52 I actually just solved that problem

9:52 haha

9:53 there's a standalone, and a non-standalone

9:53 i was trying the non, which probably didn't have the necessary dependencies :S

9:54 i'm going to add your plugins and see if pprint works

10:22 Morgawr: I wish I knew scheme so I could port this http://yinwang0.wordpress.com/2013/11/04/scheme-benchmarking/ to clojure

10:23 * Morgawr hinting at some fun project for somebody who's familiar with scheme

10:37 ro_st: dnolen: been playing with om today, finally. very, very cool!

10:37 indiana: do you use https://github.com/weavejester/hiccup in production? What do you think about that?

10:38 ro_st: indiana: we use it in production. works great

10:39 indiana: for view layer in java application?

10:39 ro_st: err no

10:39 for a clojure app

10:39 indiana: i want to use it for view layer in spring mvc application

10:40 ro_st: gosh. good luck

10:40 indiana: thanks

10:45 kzar: Are lighttable plugins explained anywhere yet?

10:50 indiana: ro_st: what is "gosh" shortcut?

11:06 pepijndevos: I forgot. What is the idiom for naming an internal function that does the work for the public one? name* or name' or something else?

11:07 locks: name* according to a podcast I heard the other day

11:07 Bronsa: pepijndevos: name*

11:08 hyPiRion: locks: cognicast or some other podcast?

11:08 pepijndevos: I think Python does _, Haskell does ' so that leaves * for clojure...

11:09 locks: hyPiRion: ruby rogues, I think

11:09 can’t remember how exactly it came into the conversation

11:09 hyPiRion: Hm, I was hoping for a new Clojure podcast =/

11:10 locks: sorry to disappoint

11:22 deadghost: is there a generally recommended beginner clojure book?

11:23 I'm going through http://www.clojurebook.com/ and am only barely following along because I already know some CL and coded some clojure

11:24 something I can recommend to my friends without scaring the bejesus out of them

11:24 logic_prog_: is cljx the right layer to insert type checking / linting code ?

11:24 hansel-han: benzap: braveclojure (website)

11:25 arkh: deadghost: maybe this? I haven't read it but others have had good things to say about itL http://www.braveclojure.com/

11:26 hansel-han: on a similar subject, i've found that clojure is a rewarding language to teach in person

11:26 deadghost: everything is better in person

11:27 especially when you might need to set up emacs

11:27 hansel-han: exactly

11:28 sandbags: deadghost: Clojure in Action was a pretty good starting point for me, after that Joy of Clojure, Programming Clojure, and O'Reilly Clojure Programming were much easier to cope with

11:29 deadghost: did you actually read all five

11:29 hansel-han: yeah, joy of clojure is pretty good.

11:29 xeqi: hyPiRion: what would you want to hear on a new clojure podcast?

11:29 hyPiRion: xeqi: Clojure stuff in general. Anything Clojure, really.

11:30 seubert: is clojure in action outdated?

11:30 xeqi: hyPiRion: have any equivalents from other languages for comparison?

11:30 hyPiRion: I wouldn't mind Cognicast coming out more often either, but I guess there's a limit on how much they can do.

11:30 sandbags: not really, although there is a MEAP 2nd edition

11:30 seubert: ah didn't see that

11:30 hyPiRion: xeqi: Well, there's Mostly Erlang

11:31 sandbags: i'm not sure if CiA (or, indeed, any of those books) are strictly beginner books ... i think any of them would require previous experience

11:31 so depends who your target audience is

11:32 deadghost: sandbags, I'm going through o reilly clojure right now and barely keeping up

11:32 would it be worthwhile to read the other books afterwards

11:32 sandbags: for me, yes

11:33 i've not finished them all, i tend to dip in as i process new bits and pieces

11:33 I find the O'Reilly book had the steepest learning curve

11:33 deadghost: I'm trying to set a rule for myself

11:33 for every hour of reading

11:33 at least 2 hours of coding

11:33 sandbags: i got wrong-footed by the Programming Clojure book, because I expected something like their Programming Ruby

11:33 now i've more experience i am finding it a much better read

11:34 locks: joy of clojure 2ED got an update yesterday fwiw

11:35 deadghost: http://videos.lispcast.com/

11:37 arkh: people talk about how that light turns on in your head - learning a lisp or functional language for the first time (coming from an imperative and OO background). It was that way for me when I was first learning clojure. It's natural now but a little frustrating at the beginning without a teacher of some kind.

11:37 sandbags: for my money Erlang was a much easier functional programming language to get wet in

11:38 deadghost: common lisp: a gentle introduction is one of my favorite books

11:40 I never really bought into OOP so it wasn't a difficult transition

11:40 OOP is just doesn't feel right to me

11:41 and k&r demonstrated that state and side effects can be messy

11:42 biggest hurdle for me was emacs really

11:43 locks: use light table xP

11:43 deadghost: does it have vim keybindings

11:43 locks: yes

11:43 sandbags: yes

11:43 locks: and emacs

11:43 sandbags: it's not vim

11:44 but it has a reasonably useful subset

11:44 and a dash or paredit

11:44 s/or/of/

11:44 corecode: yey emacs

11:44 deadghost: is it worthwhile if I'm already on emacs

11:44 sandbags: depends how much you like and want to use emacs i guess

11:44 locks: it has a bunch of neat tricks under its sleeve

11:45 especially if you do cljs

11:50 hansel-han: How do you develop a mental concept of datomic in such that you can have a mental model of performance impact for adding another query to a view?

11:52 arkh: hansel-han: I think of datomic queries as cheap as long as the data is present in memory over what you'd like to query

11:52 hansel-han: That was a poor question. What happens when you call the same datomic query three times in a row from a peer?

11:52 arkh: hansel-han: if it fits in memory than it will be an in-memory query, no round trip

11:53 (if the data it's querying over fits in memory ...)

11:53 hansel-han: arkh: thanks. that's pretty much what's happening in MySQL/Postgres too, right?

11:53 arkh: without round trips to a "database server", your queries can become smaller and more numerous without the downside of round-trip overhead

11:54 logic_prog: what are the semantics of clojure/spit when a file can not be written (i.e. disk full, invalid file name, file read only)

11:54 http://clojuredocs.org/clojure_core/clojure.core/spit is surprisingly weak on documentation

11:55 hansel-han: Actually, I'm wrong about MySQL/Postgres. You still query the DB and tie it up. It just might have your data in memory.

11:55 arkh: well, outside of round trip issues w/ mysql and postgres, datomic also offers treating query results like traditional data structures you might ordinarily have to create with a traditional db

11:56 andyf: logic_prog: They are the same as the semantics of the underlying Java calls. That is a methamatician's answer, because it is 100% accurate and completely useless by itself :-)

11:56 arkh: so you don't necessarliy have to go through the exercise of copying query results into a data structure you can then use in your program

11:56 logic_prog: andyf, nah, a mthematica would be something like:

11:56 the semantics of spit are eaxctly the same as the semantics of spit

11:56 andyf: But seriously, if you really want to know, start with (source spit) and look up Java methods you find

11:58 arkh: one of the tricky things for me with datomic was how it returns results as a 'set'. Turns out you can finagle fetching results in insert order though

11:59 andyf: logic_prog: And if you feel super-motivated after that, consider beefing up ClojureDocs at least a little bit, even if it is only links to the relevant Java pages that describe the error cases.

11:59 hansel-han: arkh: how? right now i sort-by :thing/uid with code every time

11:59 arkh: the other tricky thing is indexing overhead - with my test data, on a vm (on a laptop) I maxed out at 9000 "rows" per second? I was hoping for more ...

12:00 logic_prog: andyf: nope, definitely not that motivated

12:00 andyf: I think you mistaken me for a future-clojure-contributor

12:00 andyf: logic_prog: CloureDocs is much easier to modify than the process for Clojure contribution.

12:01 arkh: hansel-han: when you do that, you're taking the set and making a sorted-set over it, which is fine if your query result isn't large. The cost of doing that on a large result set can be prohibitive, though

12:01 hansel-han: arkh: agreed. i'm just not sure how else to do it

12:03 cjfrisz: Is marmalade known to corrupt package contents?

12:03 corecode: i'm having difficulties converting from a mutable to immutable mindset

12:03 hansel-han: corecode: example?

12:03 arkh: hansel-han: totally cool if the cost for you isn't too high. I don't think there's a better way to fetch results easily. The other way is to use the lower level stuff like seek-datoms

12:03 corecode: specifically, i want to implement something that is a bit like a graph, with nodes and edges

12:03 cjfrisz: I just tried installing troncle, and troncle.el is full of garbage characters when use the package installer or download it straight off the site

12:04 Evidence suggests that the version on github _isn't_ full of garbage, though

12:04 corecode: when you add a new edge, that will change the data of multiple elements

12:04 some of which might not even be in lexical scope

12:05 arkh: hansel-han: there's a chance I was using datomic incorrectly, too - I probably needed to think of creative ways to do more queries over filtered data instead of one big query over the lot of it

12:06 andyf: corecode: In the immutable mindset, adding a new edge means creating a new graph with that new edge. The old graph is still there without it, too.

12:08 corecode: It can be made more efficient than a complete copy by using structural sharing, which you would get if a graph was, say, a map with one key :nodes having a set of nodes, and another key :edges that was a map from nodes to neighboring nodes. A new graph with a new edge is mostly the same as the old one, except for a new set of nodes for one or two nodes in the :edges map.

12:09 corecode: andyf: sure, but if some code contains a reference to a node, that will diverge

12:09 hansel-han: arkh: i use d/datoms all the time, but i'm not sure what d/seek-datoms actually does from its docstring

12:10 andyf: corecode: So you want a graph where some code can hold a reference to a node, and later when that code gets, say, all edges incident to that node, it gets the latest set of edges, not merely the set that existed when it saved that reference?

12:10 kzar: dnolen: Having a quick look at React + om today and I was curious about something. Would it be possible to have the components built automatically from a HTML template similar to something like AngularJS uses?

12:11 arkh: hansel-han: I haven't used it before but I think it allows you to iteratively retrieve results in index order instead of unpredictable set order

12:11 corecode: andyf: i think so, yes

12:12 kzar: dnolen: Like a complete HTML template with bindings like {{ example }} and have Om create the components and watch a ref or similar with the page's state for changes.

12:12 corecode: andyf: i'm toying with the idea to implement a DSL

12:12 andyf: corecode: That is certainly possible to implement in Clojure, but it does sound like a mutable graph, and looking at your original comment, I think I understand it better now :-)

12:13 corecode: ok

12:14 andyf: corecode: If you are asking "should I implement my graph as mutable or immutable", then that is a harder question to answer. Not sure I could help you a lot answering it.

12:14 arkh: hansel-han: see also 'datoms' in the clojure api

12:16 kzar: dnolen: Then you could just create a HTML template in a style that's common in other frameworks, maintain a ref with the page's state and have Om worry about the binding. It would be super easy to use and it would be more of a drop in replacement. As it is I can't use it for now, I think convincing guys to rewrite HTML templates in Lisp would not go down well. (That said I could be completely missing the point.)

12:17 edw: seubert: There's a new edition of Clojure In Action in the works. I have the "advanced access" edition.

12:17 seubert: Strike that. There's a new ed. of Joy of Clojure in the works. Sorry about that.

12:18 (Both Manning Publications?)

12:24 michaniskin: kzar: http://hoplon.io may interest you

12:29 * kzar has a look

12:29 seubert: edw: looks like there are new editions of both!

12:38 jonathanj: hello!

12:39 i'm busy working my way through "Clojure for the brave bold and true" exercises

12:39 i'm wondering if someone can suggest how to format this in a more readable manner: http://hastebin.com/lugoviriko.lisp

12:39 kzar: jonathanj: FYI usual extension is clj

12:40 jonathanj: *shrug* hastebin made that up, not me

12:40 kzar: Could you give an example of using the function?

12:41 Morgawr: why the "and"?

12:42 jonathanj: (validate {:name (not nil?)} {:name "Chuck"})

12:42 Morgawr: well that's a follow-up question

12:43 Morgawr: i'd like to and all the results together, ie. all the validators return a truth

12:43 i thought i could do (apply and (map ...)) but apparently not

12:43 Morgawr: you can't apply and because and is a macro

12:43 http://stackoverflow.com/questions/9218044/in-clojure-how-to-apply-and-to-a-list

12:43 you can use every?

12:44 jonathanj: where does `every` come from?

12:44 oh

12:44 Morgawr: it's 'every?' with the question mark :P

12:45 jonathanj: hrm, except that the guide hasn't talked about `every?` yet, so i'm wondering what they had in mind

12:46 noonian: ,(doc every?)

12:46 clojurebot: "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false."

12:46 noonian: ,(every? int? [1 2 3])

12:46 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: int? in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:46 noonian: ,(every? integer? [1 2 3])

12:46 clojurebot: true

12:46 noonian: ,(every? integer? [1 2 3 4.0])

12:46 clojurebot: false

12:47 andyf: Bronsa: ping

12:47 jonathanj: so any suggestions on formatting this code more readably then: http://cljbin.com/paste/52d2d492e4b0797b6a30cd3b ?

12:49 cjfrisz: jonathanj: http://cljbin.com/paste/52d2d4fde4b0797b6a30cd3c

12:49 jonathanj: that's the community-accepted formatting

12:49 andyf: jonathanj: There is room for personal taste here, but in that code I would probably put the (fn ...) args on the same line as (fn, but the body of the function on the next line. Then the same with the record, auto-indented by whatever editor you use that has auto-indenting

12:50 jonathanj: What cjfrisz said :)

12:50 noonian: hmm, why the and?

12:50 hansel-han: jonathanj: in general, newline a function's arguments.

12:50 noonian: https://www.refheap.com/22964

12:50 cjfrisz: jonathanj andyf: though I respectfully disagree with the community standard formatting quite often :-)

12:50 hansel-han: noonian: that's what i do

12:51 Arjunax: How can I easily figure out (at the REPL), whether something is a function or a macro?

12:51 michaniskin: (map (fn [[k v]] ...) coll) --> (for [[k v] coll] ...)

12:51 noonian: just evaluate it

12:51 ,+

12:51 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@edf7e4>

12:51 noonian: ,and

12:51 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

12:51 jonathanj: noonian: thanks, i think that's nice

12:52 noonian: macro's throw an error when evaluated, functions don't because they are first class values

12:52 Arjunax: ohh okay, cool

12:52 noonian: jonathanj: thanks :)

12:52 Arjunax: thanks

12:52 andyf: Arjunax: also (:macro (meta #'and))

12:53 noonian: np

12:53 Arjunax: :)

12:54 jonathanj: michaniskin: thanks

12:54 cjfrisz: jonathanj: If you've got more style questions, here's the style guide https://github.com/bbatsov/clojure-style-guide

12:55 jonathanj: cjfrisz: thanks

12:57 cjfrisz: jonathanj: I found it pretty thorough, but I'm not a huge fan of all the suggestions

12:57 I.e. cemerick and I both disagree with the "Align vertically function arguments." point

12:58 jonathanj: cjfrisz: some guidance like "put the body on a different line to the arguments" made a lot of sense

12:58 noonian: i try to align arguments unless the some are k/v pairs then i put the pair on one line

12:58 kzar: jonathanj: http://hastebin.com/qapoforimu.lisp << I had a quick go at writing it

12:58 noonian: some exceptions when things are like doto where the first argument is special

12:59 hansel-han: i think in most cases, if you don't align fn arguments vertically, then it's jarring because you're putting emphasis on the first argument (like that filter example)

12:59 cjfrisz: noonian: your way seems to be the majority opinion, but I dislike it as a matter of personal taste

12:59 michaniskin: the only thing about formatting that is a no-go for me is when indentation isn't right, like when eclipse is misconfigured and produces mixed tabs/spaces

13:00 cjfrisz: noonian: likely because the scheme mode I was given in college did it a different way :-p

13:00 noonian: cjfrisz: what do you prefer?

13:00 kzar: ,(:jonathanj {:jonathanj "Keys can be used like functions to access values."})

13:00 clojurebot: "Keys can be used like functions to access values."

13:00 michaniskin: other than indentation clojure syntax is so simple i don't really care

13:00 hansel-han: clojure is my first lisp and the indentation of other lisp code that i come across often feels arbitrary. like every programmer just does whatever.

13:01 cjfrisz: noonian: I prefer always using two spaces indented from the enclosing s-expression for arguments on new lines

13:01 jonathanj: how can require something like clojure.string from the REPL?

13:01 noonian: even if there are some args on the same line as the fn>

13:01 michaniskin: (use 'clojure.string)

13:01 steerio: (require '[clojure.string :as s])

13:02 cjfrisz: noonian: yes

13:02 noonian: cjfrisz: i do that when put first arg on next line

13:02 steerio: jonathanj: the difference is that unlike in the (ns) form here you need to quote it

13:02 jonathanj: thanks

13:02 steerio: why is that?

13:02 noonian: but thats actually where i'm most inconsistent, sometimes i only use one space when i'm wrapping some forms in something like first

13:02 steerio: jonathanj: so you can require the result of an expression, i guess.

13:02 jonathanj: steerio: i'm still getting to macros, but i don't fully understand why

13:03 bbloom: cjfrisz: i vertically align arguments when they are *arguments*, but i 2 space indent subforms when they are code blocks

13:04 steerio: jonathanj: in fact require is a function, so when you call it, parameters get evaluated first

13:04 cjfrisz: bbloom: I only recently realized that's how almost all lispers do it outside of Indiana University

13:04 steerio: jonathanj: (require clojure.string) would look for the value of a var called clojure.string

13:05 bbloom: cjfrisz: the real issue is the threading macros! i feel that is a 2 space indent situation, but every damn indenter everywhere aligns args to -> and ->>

13:05 grr :-P

13:05 cjfrisz: bbloom: I agree by way of thinking just about everything should be 2 space indent :-)

13:05 steerio: jonathanj: just like, say, (println clojure.string) would

13:05 noonian: hmm, i like aligning args with ->

13:06 hansel-han: not aligning will make code feel like a codeblock to me. imo the first arg to -> isn't that special.

13:06 bbloom: cjfrisz: the way i like to think of it is that i want to push "goals" to the left margin

13:06 noonian: its just the first form, only thing special is it doesn't have something threaded in imo

13:06 cjfrisz: Although I like 'if,' 'and,' and 'or' to be aligned on the first argument

13:07 bbloom: cjfrisz: lol precisely the opposite of clojure style

13:07 cjfrisz: bbloom: indeed

13:07 Again, I didn't realize I had minority opinion until I started looking at common lisp and racket modes recently

13:08 steerio: in fact with a language based on S-expressions, we could have it rendered to everyone according to their taste

13:08 provided that they can express that taste programmatically

13:08 why do we even store it in text?

13:08 bbloom: steerio: not really. we still have comments which are not in the AST :-)

13:09 steerio: bbloom: can be solved easily

13:09 andyf: not everyone's tastes can be expressed programmatically

13:09 michaniskin: (comment "i am a comment!")

13:09 bbloom: ";" should be infix for "add metadata to the preceding form" and ";;" to the next form :-)

13:10 steerio: michaniskin: exactly. if it's namespaced, there shall be no problems. it'd never be actually executed, the compiler would ignore it, editors would render them as s ; Foo

13:10 michaniskin: it's also an s expr, which is key for formatting with simple tools

13:11 once you depart from sexprs things get complicated

13:11 andyf: michaniskin: At least in current Clojure versions, (comment) blocks return nil, so depending upon where you put them they can change the meaning of your program

13:12 michaniskin: andyf: true, but #_"i am a comment" is problematic because it's not an sexpr

13:13 steerio: if i was to invent a non-text source code format, i'd add another form for this, which would be truly ignored

13:13 whenever the reader encounters it, it'd just ignore it

13:13 michaniskin: a reader pass that prepreocesses sexprs

13:13 like

13:13 steerio: though editors would display ; Foo

13:13 michaniskin: (#_ "this is a comment")

13:14 andyf: I wonder why this often-reinvented idea has never taken off? Seems like there would be a reason. Perhaps simply "not enough benefit for the initial switch-over trouble"?

13:15 michaniskin: why do reader macro forms not use sexpr syntax? i must be missing something

13:15 bbloom: andyf: because humans type things with keyboards

13:16 it's pretty much that simple :-)

13:16 michaniskin: like why don't we write (# {1 2 3}) instead of #{1 2 3}

13:16 this would be way easier to make tooling around

13:16 bbloom: michaniskin: why don't we write (string \x \y \z) instead of "xyz" ?

13:17 michaniskin: bbloom: because strings are not really collections

13:17 bbloom: michaniskin: at some point, you have to have some syntax

13:17 michaniskin: it's still syntax because the reader would read that as a set, not a seq

13:17 bbloom: ok fine, why do we write [5 10 15] instead of (read-time-vector 5 10 15]

13:18 michaniskin: go install Mathematica and play with FullForm

13:18 what you want has / can be done

13:18 michaniskin: i mean why not in clojure?

13:19 hyPiRion: because it's easier for humans to read.

13:19 michaniskin: i understand that we want [1 2 3] and not (read-time-vector 1 2 3)

13:19 bbloom: b/c the syntax & reader was developed adhoc with the goal of being LL(1) instead of maintaining canonical tree form

13:19 michaniskin: but we have a limited set of punctuation on keyboards

13:20 Bronsa: andyf: pong

13:20 michaniskin: so if maps use {} then we need something else, like (# {}) for sets, or #{}

13:20 what i don't understand is what's the problem with (# {})?

13:20 an extra set of parens and a space?

13:20 bbloom: michaniskin: it would have to be primitive

13:20 michaniskin: a macro can't do it

13:21 michaniskin: the reader would read (# {}) as (clojure.lang.PersistentSet. 1 2 3)

13:21 or whatever

13:21 it would read that in as a set

13:21 bbloom: michaniskin: that doesn't work b/c (some-macro (# 1 2 3)) would get a list instead of a set

13:21 michaniskin: as it should

13:21 andyf: Bronsa: Just noticing some Eastwood behavior I hadn't investigated fully before, and see if you knew the issue. When a source file has (set! *warn-on-reflection* true), I often see reflection warnings from Eastwood when it evals forms that macro-expand to things containing (.nth ...), like a doseq macro. 'lein check' gives no reflection warnings, though.

13:22 michaniskin: (# {1 2 3}) would be a set

13:22 andyf: Bronsa: I'm trying to figure out the difference in what gets eval'd in each case, but perhaps you already know.

13:22 bbloom: michaniskin: you're missing what i'm saying, maybe i'm not explaining clearly

13:22 hyPiRion: michaniskin: what's wrong with the current way of writing sets, though?

13:22 bbloom: michaniskin: it's a phasing issue

13:22 michaniskin: just like when you pass #{1 2 3} to a macro, you don't get a symbol # followed by a misformed map

13:23 bbloom: because source code isn't a tree

13:23 bbloom: that makes editor tooling complicated

13:23 bbloom: you now need to invent "false trees"

13:23 bbloom: michaniskin: no no, it's just that the reader combines two phases

13:23 there is no "false trees"

13:23 the syntax is already a tree, but we skip a step w/ the reader

13:23 michaniskin: bbloom: how do you edit #{1 2 3} structurally?

13:24 Bronsa: andyf: might be emit-form forgetting to attach some :tag metadata, I'll look into that

13:24 michaniskin: say you want to make that into a map

13:24 andyf: Bronsa: Want a ticket with a short example?

13:24 bbloom: michaniskin: you can easily imagine a new namespace called clojure.syntax

13:24 michaniskin: bbloom: the editor needs to treat #{1 2 3} as (# [1 2 3]), basically

13:24 bbloom: michaniskin: and you can write a parser that produces a tree of lists where things like #{1 2 3} get translated to (clojure.syntax/set 1 2 3)

13:24 michaniskin: but then you need to do something the reader does: convert syntax to data types

13:25 michaniskin: that has to happen BEFORE macros

13:25 michaniskin: bbloom: of course, but now we're reverse engineering the clojure reader, which isn't formally specified

13:25 bbloom: michaniskin: (mac #{}) will call the function backing mac with a set, not with a list

13:25 hyPiRion: michaniskin: who says the editor does? That sounds a bit strange

13:25 Bronsa: andyf: sure, thanks

13:25 bbloom: michaniskin: ignore the editor, ignore the clojure implementation of the reader

13:25 michaniskin: a reader in general combines two phases: parsing and evaluation of syntax forms

13:26 michaniskin: you can write a function that walks [:some [:tree] [:like :this] [:set 1 2 3]] and turns :set nodes in to PersistentHashSet objects

13:26 michaniskin: the clojure reader is simply doing that during parsing b/c the compiler has no need for the unresolved tree

13:27 michaniskin: bbloom: you're missing my point

13:27 bbloom: suppose foo is a macro, right? somewhere you call (foo #{1 2}). what does foo see? a set. why? because the reader read the #{1 2 3} form at the call site

13:28 bbloom: michaniskin: the macro sees a set b/c that's what a macro is defined to do

13:28 michaniskin: i can invent a new type of "macro" that sees pre-reader-evaluation forms

13:28 michaniskin: bbloom: same thing with this: (foo (# [1 2 3])). the reader would read (# [1 2 3]) at the call site

13:28 and foo would see a set

13:29 andyf: Bronsa: Woah. It isn't even deterministic. I get about 50% of the time in a short example. WIll mention in the ticket.

13:30 gtrak: is there a built in way to get cider to send nrepl a 'complete' message?

13:30 bbloom: michaniskin: if it helps to think in terms of types, you've got an AST tree type and an Any type. A "parser" returns AST. A reader returns "Any". Macros are functions of Any -> Any. You could create "syntax macros" that operate on AST -> AST

13:30 michaniskin: eval operates on Any, not on AST

13:31 michaniskin: bbloom: you could do any number of things. my question was what's wrong with (# [1 2 3]) syntax instead of #{1 2 3}, operationally? i don't buy the argument that one set of parens is a burden

13:32 coventry: Have most people switched over to cider.el at this point?

13:32 bbloom: michaniskin: lol oh, that's you're argument? you're actually arguing that you'd rather less syntax?

13:32 michaniskin: syntax, it turns out, is useful to humans :-P

13:32 michaniskin: bbloom: i would prefer (# [1 2 3]), because my editor could then show me #{1 2 3} if that's what i like

13:32 bbloom: but the editor itself could be far, far simpler

13:33 especially since the clojure reader is not formally specified anywhere as far as i know

13:33 noonian: but then if our editor doesn't have that support we are soul

13:33 michaniskin: noonian: but your editor would, because it wouldn't be black magic

13:33 noonian: out of luck

13:34 michaniskin: displaying quirky syntax is a job for an editor, not a reader, imho

13:34 bbloom: michaniskin: you're still conflating parsing and reading; syntax and semantics

13:35 michaniskin: bbloom: lol ok man

13:35 bbloom: michaniskin: i don't see how having a more uniform grammar would help your editor in any interesting way if your editor is already operating at the AST level

13:35 hyPiRion: michaniskin: then I don't get why you don't have issues with [] and {}. With only one set of delimiters to consider, an editor will be vastly more simple.

13:37 michaniskin: hyPiRion: because [] and {} can be edited the same way as (), basically

13:37 hyPiRion: michaniskin: so can #{}, unless you've hardcoded that delimiters must be 1 char for start and stop

13:38 michaniskin: hyPiRion: it's not that simple

13:38 hyPiRion: consider #{1 |2 3}

13:38 where the point is at the |

13:38 Bronsa: andyf: ... guess what. I got bitten again by clojure silently ignoring :tag

13:38 michaniskin: i want to delete the 2 and convert the set into a map. how to do?

13:39 hyPiRion: clearly, that set would need to be structured as (# [1 2 3])

13:39 hyPiRion: michaniskin: clearly? I don't see any argument for why that is.

13:39 andyf: Bronsa: Pardon me for a moment while I continue to be stunned at the speed at which you find such things :-)

13:39 clojurebot: Huh?

13:40 noonian: wont #{1 2 3} get re-written as (set 1 2 3) or something by the reader?

13:40 michaniskin: bbloom: the AST is not that you print to the source file, btw. you print things that can be read by the reader

13:40 bbloom: once you have the AST you've lost reader macro info

13:40 Bronsa: andyf: http://sprunge.us/aEIV?diff this should do it. Let me double-check for a minute and then I'll push the fix

13:40 hyPiRion: michaniskin: #{1 2 3} can just be modified in the same way as a list, vector and map can be.

13:41 bbloom: michaniskin: (def reader (comp eval-reader-literals parse))

13:41 michaniskin: hyPiRion: how do you delete the # there?

13:41 hyPiRion: michaniskin: same way as you replace a {, [ or (, by removing it

13:41 bbloom: michaniskin: no, that's not true. that's only true of clojure's current reader b/c clojure's compiler doesn't need that info & so they combined the parser & parse-time evaluator

13:41 andyf: Bronsa: Would the place you've found this explain the nondeterminism of results, too?

13:42 Bronsa: no idea about that

13:42 michaniskin: bbloom: your argument is similar to the argument that scala macros are as awesome as clojure macros

13:43 bbloom: michaniskin: scala's macros are fundamentally different from clojure's macros

13:43 michaniskin: scala macros operate on the AST, clojure's macros operate on Any

13:43 michaniskin: bbloom: you can have a hyper-complex AST representation, yes, but it isn't better than having sexps

13:43 andyf: Bronsa: OK, in my debugging I have pprint'ed every form given to clojure.core/eval in Eastwood's analyze-file, with metadata included, and I have two runs where one gives the warning, and the other does not, but the pprint'ed forms are identical.

13:44 bbloom: michaniskin: you've having two arguments at once: 1) editing at the text level is hard regex fu and 2) something about sexps all the way down

13:44 Bronsa: andyf: oh, that's it then.

13:44 sometimes the type hint is a Symbol, sometimes it's a Class

13:44 when it's a Class, the Compiler ignores the hint

13:45 bbloom: michaniskin: i'm saying 1) regex fu works just fine for me in vim land, but you can operate at the AST level if you want to make that easy & in that case, the syntax doesn't matter 2) you can have sexps all the way down if you just separate parsing from evaluating. see Mathematica

13:45 andyf: But why would it sometimes be a Symbol, and sometimes a Class, when I'm analyzing the same source file?

13:45 michaniskin: bbloom: so specifically why is #{1 2 3} better than (# [1 2 3])?

13:45 bbloom: michaniskin: because humans like syntax

13:45 michaniskin: bbloom: so the parens

13:45 that's all i was looking for

13:45 Bronsa: andyf: oh. in the same form? weird.

13:45 steerio: and you'd mix reader macros with macro calls

13:46 the two are different animals

13:46 michaniskin: steerio: no, you can't name a macro #

13:46 steerio: i mean if your idea was implemented, which implies that you can

13:46 michaniskin: steerio: the two methods are equivalent, i think, operationally

13:46 andyf: Bronsa: Yeah, I made the one-file project described in the latest TANAL ticket, ran Eastwood multiple times with the extra pprint'ing just before eval, and gotten identical results on 2 runs except for the Reflection warning in one, none in the other.

13:46 michaniskin: it's just a matter of taste, apparently

13:46 Bronsa: :/

13:46 steerio: michaniskin: well no, because your example is a nonexistent form

13:46 andyf: The pprint'ing doesn't show whether it is a symbol or a class, so your explanation could still be correct.

13:47 bbloom: michaniskin: yes, the parens... but that's why i lead by saying something like (clojure.syntax/string \x \y \z), hell even then (clojure.syntax/string (clojure.syntax\char .....

13:47 steerio: ,(# [1 2 3])

13:47 clojurebot: #<RuntimeException java.lang.RuntimeException: Reader tag must be a symbol>

13:47 andyf: or maybe the pprint'ing would distinguish between Symbol and Class?

13:47 Bronsa: andyf: I'm positive that the bug is caused by that, still no idea why it doesn't happen every time

13:47 michaniskin: steerio: i meant if the reader read that as a set

13:47 steerio: gtg

13:47 Bronsa: no, symbols and classes prints the same unfortunately

13:47 michaniskin: steerio: it would require a different reader

13:47 steerio: though i'd love to continue this

13:47 maybe sometime

13:48 andyf: Bronsa: The pprint'ed form I see contains this sub-form that causes the reflection warning: (.nth ^clojure.lang.IChunk chunk_4449 o_4451)

13:48 Bronsa: andyf: can you try and see if it's still non-deterministic if you move the doseq out of the defn?

13:48 andyf: sure

13:51 jonathanj: steerio: ah, good point

13:52 andyf: Bronsa: yes it is still nondeterministic with a doseq at the top level of the source file, not inside a defn

13:53 Bronsa: no idea. I'll investigate a bit

13:56 andyf: I pushed the fix and updated eastwood to use the new SNAPSHOT

13:57 andyf: just another theory, can you ensure *warn-on-reflection* is actually true both times?

14:04 andyf: Bronsa: Need to go for a while. Will look into it more later today.

14:05 Bronsa: ok, thanks

14:58 pepijndevos: waaaaiiit... > < >= <= only work on numbers? What about other comparables?

15:00 pjstadig: pepijndevos: surprise!

15:03 bbloom: ,(< [5] [10])

15:03 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>

15:03 bbloom: huh.

15:04 ,(compare [5] [10])

15:04 clojurebot: -1

15:04 bbloom: ,(compare [10] [5])

15:04 clojurebot: 1

15:04 bbloom: pepijndevos: pjstadig: i did not realize :-P

15:05 hyPiRion: ,(= [[10] [5]] (sort [[10] [5]]))

15:05 clojurebot: false

15:05 hyPiRion: ,(= [[5] [10]] (sort [[5] [10]]))

15:05 clojurebot: true

15:05 pepijndevos: now have a look at subseq, and be amazed.

15:05 bbloom: ,(doc subseq)

15:05 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

15:06 pepijndevos: &(subseq (sorted-set \a \b \c \d \d) > /b)

15:06 lazybot: java.lang.RuntimeException: Invalid token: /b

15:06 pepijndevos: &(subseq (sorted-set \a \b \c \d \d) > \b)

15:06 lazybot: ⇒ (\c \d)

15:17 bbloom: has anybody tried a breadth-first traversal with clojure.zip ?

15:17 seems quite tricky...

15:23 pjstadig: hmm yeah

15:23 just DFS for me

15:39 kristof: Are takes from async channels guaranteed atomic?

15:39 Meaning two processes can't take from the channel and end up with the same item

15:40 Or is taking and putting ALSO an asynchronous process and the channel itself decides which consumer gets what item? :)

15:40 I'm sorry if there's some fundamental misunderstanding I'm showing, here

15:44 arkh: kristof: it looks like those operations are made atomic through explicit locks, e.g. https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/channels.clj

15:44 kristof: a given item could only be take!'n once

15:44 kristof: arkh: I thought you were going to link to Rich Hickey's buffer code because I thought that would be where the logic lies but I suppose not

15:45 arkh: Do you think there would be a performance benefit to making channels themselves be asynchronous as well, letting the channel be

15:45 well I guess I'm thinking of actors

15:45 the channel could be an agent that sends the next item to the process (whose name is known to the agent already) and so no explicit locking is necessary at all

15:46 But then the channel itself would not be so lightweight, would it? Hrm. Oh well :)

15:46 arkh: kristof: but then how are agents already coded? : ) I think it acquires a lock, too

15:47 kristof: arkh: Do they? Nothing actually accesses an agent's state besides the agent itself, I thought, so locking would be keeping nothing out.

15:47 But I am probably wrong in this regard

15:48 arkh: kristof: as far as whether it'd be more efficient to put that into an async process (like a go block, etc.) I think that takes me out of my depth - I'd just be speculating

15:49 kristof: arkh: Huh? Go blocks use channels, so implementing channels in terms of go blocks doesn't make much sense. :) Anyway, I'm out of my depth, too, I was just wondering about the implementation of channels

15:50 bbloom: pjstadig: give breadth first a try, turns out it's actually hard :-P

15:50 arkh: kristof: I could be wrong but I believe concurrent operations on agents are aligned single-file through through speculative lock, simliar to atoms, i.e. attempt exclusive access to a given thing and then verify nothing else tried to do the same. The difference between and atom and an agent is what happens in the code after the lock is verified to be ok

15:50 bbloom: pjstadig: http://www.eecs.usma.edu/webs/people/okasaki/icfp00.ps <- general functional breadth-first numbering. not w/ a zipper

15:51 kristof: So I guess all real concurrency involving shared state relies on locks at least on some level of abstraction?

15:51 bbloom: pjstadig: very trick

15:51 y

15:51 arkh: kristof: sorry, I meant like a go block in style but not in code

15:51 bbloom: pjstadig: whoops, bad url

15:51 http://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf there

15:52 arkh: kristof: I though clojure mvcc mostly revolved around speculative locks w/ retries

15:52 kristof: even agents - it's just the meat of your code doesn't run until things are verified

15:53 kristof: brb while I learn what a speculative lock is

15:59 arkh: kristof: I should have said "stm" instead of "mvcc" back there

16:00 kristof: arkh: I'm sorry, I thought those were synonymous.

16:02 arkh: kristof: in a general sense, a speculative lock is one where code attempts to make a change to something (presumbaly shared and) mutable and it checks to make sure nothing else changed it at the same time. If not, the change (or transaction) is committed, if something else modified it concurrently, then the operation or transaction is retried until it

16:02 succeeds. Technically clojure won't retry forever and will error out if there happens to be too much contention. I've never seen that though - I doubt it's common!

16:04 kristof: So a speculative lock tries, checks, then commits or retries.

16:04 arkh: kristof: oh .. it looks like STM is the problem category and MVCC is how clojure solves it

16:04 kristof: And STM is just large-scale manipulation of speculative locks.

16:06 arkh: mvcc seems to be about speculative locks and keeping old values of ref types around until such time as nothing refers to the value and it'll be gc'ed

16:06 fredyr: kristof: arkh: I've found this page very helpful in understanding more about the clojure stm, http://java.ociweb.com/mark/stm/article.html

16:07 arkh: fredyr: nice!

16:08 fredyr: you might like this one too: https://github.com/tvcutsem/stm-in-clojure

16:09 kristof: arkh: According to the link fredyr just sent, there's nothing inherently about actors that needs to include locks in the implementation, which is what I suspected. I will look up the implementation of agents in Clojure, though, and find out.

16:10 mercwithamouth: does anyone have any good enfocus projects besides chatter-box on github?

16:15 arkh: kristof: is there any way to do safe concurrency without some kind of lock/mutex/etc. or forcing changes to be single-threaded?

16:16 kristof: it looks like agents are ultimately managed by this: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java

16:16 kristof: arkh: Concurrency is only unsafe when there's shared state between threads. An actor, as far as I can tell, always operates within a single thread, so there's never any unsafeness.

16:17 arkh: kristof: isn't that parallelism instead of concurrency though? : )

16:18 kristof: arkh: Maybe, if you want to look at it that way. But then that's the reason why actors are so cool: because you're not ever forced to deal with shared state.

16:18 Then again, isn't an actor's mailbox shared state? ...............

16:19 arkh: maybe the mailbox is managed by a single event/dispatch thread .... I know zero about actors!

16:19 kristof: I'm not smart enough for this :(

16:20 arkh: I'm having fun trying to stretch what little I know!

16:22 kristof: arkh: The agent.java code in the tree never imports locking transaction. How did you come to that conclusion?

16:23 dgrnbrg: How can I express core async in one pithy sentence to an audience that learned about the epochal model of time 1 slide before? (for http://flausenhaus.org/lambda/ )

16:24 egghead: in all my use of clj i've never needed agents

16:24 dgrnbrg: "Communicate by sending messages over channels" is what i'm thinking, but I feel like that doesn't capture the awesomeness of alt!

16:25 kristof: egghead: Timothy Baldridge said last night (or the night before) that he's never really used STM in a way that it didn't get replaced by core.async code or agents when he refactored. To each their own, but some people like transactions!

16:25 dgrnbrg: Epochal model of time doesn't really have much to do with understanding core.async in my opinion. The best way to put it would be to use the consumer/producer analogy.

16:26 arkh: kristof: taking an agent operation like 'send', for example, ends up calling .dispatch on clojure.lang.Agent. dispatch calls dispatchAction which, at the beginning of its operation, calls LockingTransaction.getRunning()

16:26 egghead: consumer producer / pubsub doesn't do justice to core.async :p

16:26 dgrnbrg: kristof: I know that the epochal model of time doesn't have much to do with core.async, which is why I'm not sure how to express it

16:27 we don't really have time to go over core.async in the class, but I'd like to be like "yo, this is a powerful, cool model, and here's a 30 second teaser"

16:28 locks: I liked how in dnolen’s presentation

16:28 egghead: reading and writing to channels kind of captures what it is to be async, time independent, but you get to write it as if it were sync :)

16:29 kristof: dgrnbrg: There are really two cool parts to core.async in my opinion. The first is the ability to take two processes and let them run at the same time and talk to each other. The second cool thing is the go macro, which takes benign sequential looking code and smashes it all together into a state machine.

16:29 locks: he went from not accepting repeated sequential keys to not accepting repeated keys ever

16:30 dgrnbrg: kristof: I feel like those aren't compelling features of core.async, since you can do that with threads and java.util.concurrent

16:31 alts! and user-space threading are the novel parts of core.async, but they're not so easy to explain unless you've written code without them

16:31 kristof: dgrnbrg: not the state machine stuff?

16:31 dgrnbrg: the state machine stuff only exists so that the user-space scheduler can exist

16:31 kristof: That's what I was talking about

16:31 dgrnbrg: since you can accomplish the same thing with threads + blocking calls, and that scales to thousands of processes

16:32 "processes", aka threads

16:32 kristof: hmmm

16:32 egghead: alts! is really cool because it is explicit non-determinism

16:34 but >! is not the same sort of thing as regular communication between threads or agents

16:34 it's got transactional semantics

16:35 afhammad: what does it mean when a function is prefixed with ->, for example something/->dothis

16:35 arkh: I like this project's extension of core.async: https://github.com/tonsky/net.async

16:36 AimHere: afhammad, -> and ->> are just macros for making code more readable in some cases

16:36 dgrnbrg: egghead: you can get that using java.util.concurrent.LinkedBlockingQueue, if you want the blocking channel semantics

16:36 egghead: and you can get a more powerful version of an unbuffered channel using an exchanger: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html

16:36 AimHere: afhammad, the idea is that instead of (foo (bar (baz (wibble x))))), you write (-> x (wibble) (baz) (bar) (foo))

16:37 Or something to that effect

16:37 egghead: dgrnbrg: ah yes, but now you have blocked threads ;)

16:37 afhammad: AimHere: is that always the case? what about: services/->Services

16:37 egghead: *not* the same as how core.async puts threads to sleep inside their state machines

16:37 dgrnbrg: egghead: threads are quite scalable--a 24 core machine can easily handle thousands of threads

16:38 egghead: 'parking' or w/e

16:38 dgrnbrg: the OS is quite effective at parking native threads

16:38 AimHere: afhammad, ->Services is a different symbol from -> and so I don't know what that's all about, probably defined in the project somewhere else

16:39 dnolen: dgrnbrg: I think the fact that core.async was designed w/ ClojureScript in mind from the start is pretty compelling.

16:39 dgrnbrg: but maybe your audience is mostly concerned with server-side affairs

16:39 dgrnbrg: they're a mix

16:40 that is a good point, however--I'm going to mention the JS support, because that is pretty awesome

16:40 egghead: i think core.async is a nice async lib, but I think it is a better example of why macros are so cool

16:41 macros let clojure borrow all the good ideas from other langs :)

16:43 edw: egghead: <http://poseur.com/java-scheme>.

16:44 egghead: edw: :)

16:44 edw: Some hairy macroage in there.

16:45 Writing macros is the only intellectual activity where I feel actual, literal nausea when things get real.

16:46 Staring into the abyss so others needn't.

16:51 Speaking of... May need a macro to introduce arbitrary search depth for a cascalog graph app. Hand-writing n-level transitivity is ugly and tedious.

18:39 gtrak: 80% of the way to a cljs autocomplete lib, analogous to clojure.complete :-)

18:40 I'm hoping someone will help me with the emacs part.

18:41 bitemyapp: egghead: macros aren't the only way :)

18:42 gtrak: the interaction between nrepl, austin, piggieback, ac-nrepl and clojure-mode is.. a bit hairy.

18:43 like.. I think I'll have to disable ac-nrepl, since it actually evals code instead of just sending over a "complete" op.

18:44 bitemyapp: ac-nrepl lags too much for me to use.

18:44 gtrak: all this effort because I was trying to build something with om and got fed up with looking at github :-)

18:45 bitemyapp: do you have autocomplete through ritz or something else?

18:45 I noticed that's one thing that actually uses a 'complete' nrepl op

18:45 and I'm modeling the ensuing piggieback integration after that.

18:45 bitemyapp: gtrak: I use the dumb Emacs AC. It's annoying.

18:46 gtrak: uh, in Clojure anyway. I have smarter tooling elsewhere.

18:46 * bitemyapp scowls

18:46 gtrak: blah blah blah haskell

18:46 bitemyapp: I didn't say it.

18:46 gtrak: not today :-)

18:46 bitemyapp: all you bro./

18:46 clojurebot: I don't understand.

18:46 bitemyapp: oh shush up bot.

18:47 gtrak: not having autocomplete wasn't a problem before, since I wasn't learning a bunch of new libraries.

18:48 or writing my own for everything.

18:48 rather, I _was_ writing my own. Hopefully once this infra is in place, it won't be too hard to get M-. going.

18:49 bitemyapp: gtrak: you know what helps even more for reading code you didn't write?

18:49 gtrak: I give ya two guesses.

18:49 gtrak: printing it?

18:49 amalloy: eyeglasses

18:49 bitemyapp: gtrak: types.

18:50 gtrak: hahaha

18:50 bitemyapp: amalloy: only if you want >80 columns.

18:50 gtrak: I use reading glasses occasionally, different focus lengths helps with eyestrain over the course of a week.

18:50 bitemyapp: gtrak: but 4rlz though. Made up that type signature of the fly: http://www.haskell.org/hoogle/?hoogle=Ord+a+%3D%3E+%5Ba%5D+-%3E+a

18:51 gtrak: ah, that is pretty cool actually, but that means I have to use haskell.

18:52 bitemyapp: that would appear to be the tradeoff.

18:52 gtrak: still, I end up reading all the code of every lib I use, anyway, tooling just helps me jump around quickly.

18:52 bitemyapp: gtrak: oh sure, but the types still help: http://hackage.haskell.org/package/base-

18:52 gtrak: :browse in ghci dumps the types and fn names of the module you passed.

18:53 gtrak: so it's pretty easy to get a 1,000 km overview that way and then start diving into the code.

18:53 gtrak: one day :-)

18:53 it's been on my list for about 3 years, never the top item..

18:53 bitemyapp: gtrak: well, if you ever want a jump-start, advice, ideas, etc. - ping me.

18:54 gtrak: it's a learning process very amenable to hammock time.

18:54 gtrak: yea, that's a good feeling.

18:56 for now I'm just trying to hack stuff out as fast as possible in clj/cljs.

18:56 because of the 'reach' aspect.

18:58 bitemyapp: gtrak: I gotcha. Reach?

19:00 gtrak: yea.. baltimore's mobile/web/rails folks mostly, with some java for govt contractors, we just started a real clojure meetup, which is still pretty esoteric, but it's getting better. With cljs, I can hopefully show up at hackathons and impress :-).

19:01 bitemyapp: gtrak: I've been doing a mixture of tool building, benchmarking, dev-ops automation, and web stuff in Haskell with Fay on the frontend for JS.

19:01 gdev: well I've been meaning to reduce my Haskell naivete

19:01 bitemyapp: wish the day job leveraged more of it, but my current project at work is hyper Python-specific.

19:01 gtrak: that sounds fun, you're in the west coast, yea?

19:01 bitemyapp: gtrak: Yay Area, I live in SF.

19:01 gtrak: trying to get the fack out of here.

19:01 gtrak: yea... the tech scene here is really indy.

19:01 in comparison.

19:01 bitemyapp: indie?

19:01 gtrak: yea, I guess :-)

19:02 I never try to spell that.

19:02 bitemyapp: I'm just unclear on what it's meant to mean.

19:02 gtrak: little, mostly low-profile startups

19:02 gdev: bitemyapp, have you used Haskell with Datomic?

19:03 gtrak: but it's a close-knit group.

19:03 edw: Philly is like that: a lot of small companies that call themselves start-ups but are actually just basically mom-and-pop internet companies run by twenty/thirty-something hipsters.

19:04 gtrak: edw: it's probably not so different, I'd guess philly was bigger.

19:04 bitemyapp: gdev: I'm all-up-ons with Datomic at work but I haven't had time to poke around with hEdn in Haskell yet.

19:04 gdev: my Haskell projects are mostly PGSQL at the moment because esqueleto is RIDIC.

19:04 gtrak: baltimore has the DC influence, a lot of folks commute there and back.

19:04 bitemyapp: gdev: regardless, it'd mean going over a proxy like berossus to talk to Datomic.

19:04 gtrak: so, clojure realistically will interest someone here, haskell I'd be on my own, I'm afraid.

19:06 gdev: bitemyapp oh, damn, I was hoping to find something that Clojure-the-language would let you do that Haskell-the-language couldn't ;)

19:06 edw: gtrak: Philly may be similar in that the 212-215 and 202-215 thing is practical. And the 215 has banks and pharmas. So there's the bimodal distribution of companies split betweem the aforementioned and people sucking corporate cock.

19:06 gtrak: b/c the higher-skilled ruby folks are starting to be more open-minded, and I see hadoop and big-data influencing things, which implies JVM.

19:06 bitemyapp: gtrak: learn it for the epiphany, same reason people learned Lisp for the last couple decades. Offer still stands for my time.

19:06 gtrak: bitemyapp: I hope to take you up on it sometime.

19:06 bitemyapp: Makes sense re: Hadoop, but I strongly suspect you could still put something together.

19:07 gdev: nice try! Haskell has best-in-the-industry parser libraries. Something like edn wasn't going to stop anybody.

19:07 locks: parsec is kinda good

19:07 bitemyapp: attoparsec too.

19:09 kanja: is there a way with cider to see a specific line of code where an error occurred?

19:09 gtrak: kanja: stacktraces have file-and-line info generally

19:09 kanja: Something like "ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:437)" is informative, but it would be great if I could jump right to the fn call that caused the error

19:10 edw: kanja: And if they don't, it may be because you "C-x X-e"'d and didn't "C-c C-k".

19:10 gdev: bitemyapp, ha, that was my first and last attempt too, life is too short for PLT trolling

19:10 amalloy: kanja: (1) the full stacktrace already contains that information, if you'd pasted it to refheap or something; (2) you have code that looks like (x) when you just want x

19:10 gtrak: it's not easy to jump into java, eclipse has a roundabout way of implementing it, though, involving downloading the source artifacts from maven.

19:11 bitemyapp: gdev: http://www.youtube.com/watch?v=asgiNZrcJ44

19:11 kanja: @edw - yeah that I did do.

19:12 bitemyapp: gdev: watch with audio.

19:12 gdev: bitemyapp, yeah that's how I feel lol

19:12 kanja: but I'm also getting the error at run time rather than load

19:12 so c-c c-k works, but then (myfun someargument) in cider fails

19:12 * bitemyapp moonwalks out of scene and into hacking

19:13 gdev: bitemyapp, if I'm ever in your area or if you're ever in San Antonio I'll totally pair with you on some Haskell hacking

19:14 bitemyapp: gdev: Sure! I'm more likely to be in Austin or Seattle when I'm not in SF in the near future though. I've paired with others over the internet successfully though.

19:15 gdev: learning how to pair remotely is a useful skill regardless.

19:15 paired with others over the internet for Haskell and for day-job stuff both.

19:16 gdev: bitemyapp that's true, well just name the time and the project and add me to skype ha

19:16 or I'll add you because I bet I can guess your skype name

19:17 bitemyapp: gdev: I've got a *list*. I'm working on rewriting bitemyapp.com (1) so that I can post a benchmarking project (2). I've also got grom (3) and other projects.

19:17 gdev: you won't.

19:17 my skype name is ancient and eldritch, nobody could ever guess it.

19:18 gdev: I'm not bitemyapp on Skype. I am on github/twitter though.

19:20 I might need to fix hEdn if it's implemented based on the spec (4) or possibly write my own library (5).

19:25 I'm always up for plain ole tutorials too.

19:28 gdev: yeah that might be about my level at the moment

19:29 bitemyapp: gdev: there are some prereqs involved. The idioms in Haskell are varied and rich but require building blocks like mathematics.

19:29 emphasis "like".

19:30 gdev: Once 80% of this makes sense http://www.haskell.org/haskellwiki/Typeclassopedia you'll be a long way already.

19:32 gdev: bitemyapp yeah I have a lot of homework to do

19:35 had a problem so I thought I would log on to IRC, now I have a mountain to climb

20:23 logic_prog: in clojure.core.async, is there a way to say: "close this channel if I have not received anythin gfrom it in 5 minutes" ?

20:23 i.e., there's a timer on the channel

20:23 then after every message, the timer gets set to (current time + 5 minutes)

20:25 amalloy: logic_prog: every time you try to take from it, use alts! to also take from a 5-minute timeout channel, right? and close the main channel if you got a message from the timeout instead?

20:26 logic_prog: so I create a _new_ channel on every take-mejssage via <! ?

20:26 that seems sorta expensive

20:26 amalloy: the usual caveats apply: i don't actually use core.async, so alts! may not quite the right function

20:26 logic_prog: or are channels that cheap?

20:26 amalloy: sure, why not?

20:26 logic_prog: maybe I shoud write the code + benchmark it

20:26 rather than use imaginary optimizations

20:27 amalloy: yeah, i would be quite surprised if making a channel were much more expensive than receiving from one

20:27 bitemyapp: amalloy: sounds fine to me.

20:27 amalloy: like, in js the code for creating a timeout channel has got to be something like: allocate a Channel object; setTimeout(5000, function () {write to the channel})

20:28 bitemyapp: logic_prog: don't pre-optimize or anticipate from a position of obscurity. Proceed with the clean and simple thing and wait for performance problems to arise.

20:28 logic_prog: bitemyapp: you are wise

20:28 i'm procrastinating with these imaginary perfomrnace bottlenecks

20:28 amalloy: a popular pastime

20:28 i prefer to procrastinate by answering questions in #clojure

20:29 testcloj: l

20:29 edw: There's beene a lot of yak shaving going on today.

20:29 s/beene/been/

20:29 testcloj: cl

20:29 (map #(into {} [[1 2]]) [:a :b :c]) didn't give result of {1 2, 1 2, 1 2}? instead it throws error

20:29 why it doesn't work?

20:30 amalloy: #(into {} [[1 2]]) is a function of zero arguments, and you passed it one

20:30 you could instead use (constantly {1 2]), for example

20:30 edw: It's a function of zero arguments because your #(...) form contains no percent signs.

20:32 amalloy: it also looks sorta like you imagine this starting with an empty map and mutating it three times, rather than starting with three distinct empty maps and conjing to each (not mutating)

20:35 testcloj: great, thx. this works: (map #(let [a %] into {} [[1 2]]) [:a :b :c])

20:38 but the result is [[1 2]] [[1 2]] [[1 2]] instead of {1 2} {1 2} {1 2} , since I used into {}, the result should have a map, correct?

20:40 hyPiRion: testcloj: you need to wrap it in a paren first

20:41 ,(map #(let [a %] (into {} [[1 2]])) [:a :b :c])

20:41 clojurebot: ({1 2} {1 2} {1 2})

20:41 hyPiRion: vs

20:41 ,(map #(let [a %] into {} [[1 2]]) [:a :b :c])

20:41 clojurebot: ([[1 2]] [[1 2]] [[1 2]])

20:48 testcloj: Thanks hyPiRion, but why wrap in a paren make a differnce? I am a newbie to cljure, might be a stupid quesiotn

20:52 bitemyapp: logic_prog: careful with words like that, the rabble might get angry and toss you off a cliff.

21:00 logic_prog: I need to setup something (probably not using clojure, but it's part of a clojure web app) to do a key/value store which supports (1) authentication and (2) expiring urls

21:00 i.e. my clojure app authenticates "hey, you have access to object XYZ, go fetch it from y other server"

21:00 then the other server looks at the certificate for "give me XYZ", authenticates it, and returns it

21:01 what is the easiest way to setup this "k/v store" with authentication + expiring urls

21:01 bitemyapp: logic_prog: so, you want a CMS with an ACL?

21:01 logic_prog: acl = access control list, yes

21:01 cms = contant management system ?

21:01 bitemyapp: content

21:01 logic_prog: basically I want something like riak, or hbase + authentication

21:01 it's for hosting static constant

21:01 i.e. think instangram / snapchat hosting of photos

21:03 ideally, this k/v store responds over http

21:05 bitemyapp: logic_prog: static content? you want riak, not HBase.

21:05 logic_prog: HBase is *not* made for static content yo.

21:05 logic_prog: Riak with the Bitcask backend specifically.

21:06 logic_prog: sorry, I meant hdfs

21:06 riak + authentication would make me happy

21:06 CaptainLex: Does anyone have any shoreleave experience? Is there a way to add middleware to a specific remote?

21:07 logic_prog: http://docs.basho.com/riakcs/latest/cookbooks/Authentication/ looks like what I want

21:07 query string optimiations

21:09 Janiczek: hi, when using Emacs + CIDER (nREPL), is it somehow possible to print the results of C-M-x (interactive eval) to the repl and not to the "Messages" statusbar row at the bottom? possibly with the evaluated form, so that it behaves as if I copy-pasted it to the REPL? (sorry for the probably wrong naming of things)

21:18 arohner: stupid core.async question. I want to give someone a channel, and take messages from it and do stuff with them. It makes perfect sense to me using threads, but how does that work with go blocks?

21:18 are go blocks values? (i.e. if I don't return the go block, will it still work?)

21:19 ToBeReplaced: janiczek: i don't know it well enough to give you a definitive answer. however, you could always type *1 in the repl after (C-Z, *1 Enter)

21:20 arohner: go blocks return channels that yield the result of the body -- you could create a channel, pass it to a producer, then go or go-loop all you want

21:21 arohner: you don't have to return a ref to the block; it won't be GC'd until its work is done

21:21 arohner: aha. there's the magic

21:22 Janiczek: ToBeReplaced: thanks, if I won't figure it out, at least this is nice :)

21:28 bitemyapp: ddellacosta: Keep coming back to this to see how many of the solutions youy understand: http://www.willamette.edu/~fruehr/haskell/evolution.html

21:28 ddellacosta: it's also just a nice joke.

21:28 ddellacosta: bitemyapp: ha, bookmarked that a few weeks ago

21:28 bitemyapp: well there you go. :)

21:29 ddellacosta: bitemyapp: I think because of my Clojure experience, I started on the folder, and then used the more Haskell-y recursive solutions. But some of the later ones are mind-blowing to me.

21:29 *foldr

21:30 bitemyapp: ddellacosta: folds/catamorphisms are generally the wiser way to go. Recursions are seen as relatively low-level but they yield some beautiful code in some cases.

21:30 ddellacosta: a learning exercise is translating relatively obvious recursive implementations of tree operations to folds.

21:30 ddellacosta: bitemyapp: I rather like the simplicity and elegance of the recursions, most definitely

21:30 bitemyapp: ddellacosta: the compiler can do more to help you out if you use things like foldr though.

21:30 ddellacosta: bitemyapp: gotcha, good to know!

21:31 bitemyapp: recursion is you basically telling GHC, "I got this."

21:32 coventry: Janiczek: Use cider-eval-expression-at-point-in-repl from https://github.com/halgari/clojure-conj-2013-core.async-examples#usage

21:39 Janiczek: coventry: wow, that is exactly what I had in mind. thanks!

21:47 seangrove: Oh man, if only the cljs compiler were a person, I could throttle it

21:47 So tired of seeing "java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space" right before trying to push to production

21:53 bitemyapp: seangrove: funny, I get that almost every time I use Scala.

21:53 then I remember to jack up my Xmx into the stratosphere.

21:54 seangrove: Looks like it's a combination of several things, but maybe updating Java will help

21:57 Hrm, added :jvm-opts ^:replace ["-Xms1024m" "-Xmx1024m" "-server"] to the project and it passed this time. Let's see if it break again in the next hour...

22:02 `cbp: does anyone have a cljs + node lein template around

22:03 bitemyapp: `cbp: node?

22:03 `cbp: bitemyapp: yea

22:03 bitemyapp: `cbp: node?

22:03 `cbp: wat :(

22:03 bitemyapp: son, I am disappoint.

22:03 arrdem: there are things that Javascript should not do...

22:04 `cbp: i need to make desktop app and im not about to learn swing

22:04 bitemyapp: `cbp: first you abandon me to randos on DotA2. Now you're using node for anything other than cat pictures?

22:04 ohhhhhhh

22:04 * arrdem cracks up

22:04 bitemyapp: I has answer.

22:04 `cbp: bitemyapp: I always invite you on dota :(

22:04 you seemed away today

22:05 bitemyapp: `cbp: oh, sorry. I've been hacking today. Still want to play?

22:05 `cbp: nope :p time to figure out cljs + node

22:05 + node-webkit

22:05 bitemyapp: `cbp: http://book.realworldhaskell.org/read/gui-programming-with-gtk-hs.html

22:06 `cbp: you could also use Fay with node-webkit >:)

22:06 arrdem: doters?

22:06 arrdem: bitemyapp: lemme finish figuring out when and where my classes start tomorrow then sure.

22:06 bitemyapp: arrdem: oh exciting. What are you taking?

22:07 arrdem: bitemyapp: the only interesting things are a graduate compilers class and the honors undergrad algos class.

22:08 kanja: I've got a single item list that contains a map and a map and I want to join the two together - why do I get "ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry clojure.lang.APersistentMap.cons (APersistentMap.java:42)" when calling (conj mapList map) and not (conj map mapList)

22:11 amalloy: i don't really believe that's what happens, kanja (conj some-list anything) always works

22:11 whereas (conj some-map any-list) always fails, in the manner you describe

22:12 bitemyapp: kanja can't conj

22:12 say it out loud.

22:13 kanja: http://pastebin.com/AZUh0CUM

22:13 @alalloy ^

22:14 err http://pastebin.com/dhdcHgz6 is a little clearer

22:15 UG dur, revered the arguments to the function

22:17 bitemyapp: so, in a blazing show of total predictability, amalloy was right again?

22:18 gfredericks: clojurebot: amalloy |was| right again in a blazing show of total predictability

22:18 clojurebot: Roger.

22:19 amalloy: aw

22:19 arrdem: bitemyapp: well... looks like I'll be able to go work out daily before classes if I stop staying up to 2am.

22:19 bitemyapp: decisions decisions.

22:19 * bitemyapp cracks knuckles

22:20 bitemyapp: arrdem: I think you can fit both if we just cut it off a game earlier. Doters?

22:21 arrdem: bitemyapp: this is probably true. rebooting.

23:07 andyf: Bronsa: Clojure itself uses tags of type java.lang.Class, according to my testing. Does that imply it is a bug that tagOf() returns null when given such a tag?

23:14 Bronsa: andyf: who knows. I'd say yes.

23:17 amalloy: andyf: do you have an example of a function that uses a tag like that?

23:18 andyf: In Clojure, I think just about any tag like ^long will do, but give me a minute and I will point at a particular one.

23:19 mischanix: I asked my girlfriend if she likes Lazy Seqs. She didn't think it was funny.

23:22 amalloy: she was probably mad you pronounced seq wrong

23:24 mischanix: I don't think I'll ever be able to read 'seq' as 'seek'.

23:24 andyf: amalloy: I may have been a bit hasty. There are tags ^Object where 'Object' is a java.lang.Class while compiling Clojure itself, and test.generative uses some S-expressions as tags, but not long that I can see.

23:25 amalloy: My extra debug print doesn't give me file name or line #s, so it will take a while longer to track down where those ^Object tags are.

23:25 amalloy: andyf: that's usually a symptom of a careless macro

23:26 dbasch: I'm trying to extend a java class that has a protected constructor with no arguments via hen-class, and I get this error "Exception in thread "main" java.lang.NoSuchMethodError: com.google.bitcoin.core.NetworkParameters: method <init>()V not found"

23:26 don't know why

23:26 amalloy: eg, (defmacro foo [x] (with-meta x {:tag Object}))

23:26 dbasch: gen-class that is

23:27 any thoughts?

23:27 amalloy: andyf: looks like there's one in the definition of 'case

23:31 that's the only one i can see, in fact

23:31 andyf: amalloy: Maybe one buried in defrecord somewhere? I'm guessing from some debug print output, haven't seen it yet.

23:32 amalloy: maybe. it's pretty hard to follow what goes on in deftype

23:34 it looks right, though. on-interface starts as 'MyType, and the code that uses that tag is `(. ~(with-meta target {:tag on-interface}) ...)

23:36 andyf: I believe all of the cases I saw when compiling the latest Clojure occurred in defrecord, or in test.generative tags-that-are-general-forms

23:43 amalloy: wow, what on earth is test.generative doing with these :tag forms

23:45 testcloj: anybody did the question of http://www.4clojure.com/problem/156? one of it is (= (__ 0 [:a :b :c]) {:a 0 :b 0 :c 0}), I can't figure it out after thinking it for a long time

23:46 andyf: amalloy: Nicola started a thread on clojure-dev asking about that, and created a ticket to eliminate the property where such tags are visible 'outside' of test.generative

23:46 "Question about :tag" from mid-Dec

23:47 amalloy: andyf: it looks to me like tag->gen has a serious, although probably unrelated, bug as well

23:47 the intent is that you can use arbitrary forms as tags, right, to specify your own generators?

23:48 but...it removes all quotes from those forms before evaluating them. if i tag it like ^{:tag (repeat 10 'a)}, it mangles that into (repeat 10 a)

23:48 andyf: amalloy: I haven't learned, myself. Just passing along pointers to the conversations I've seen.

23:51 amalloy: last june the rss feeds for the clojure and clojure-dev mailing lists stopped working in my email client, so i haven't really read anything since then. on the whole that's worked out fairly well for me, but it does mean i haven't seen that conversation :P

23:52 andyf: direct link to the thread: https://groups.google.com/forum/#!topic/clojure-dev/hRZFuaiB_50

Logging service provided by n01se.net