#clojure logs

2014-01-12

00:00TolstoySet up a project, serve out an index.html page, then use cljsbuild to play with clojurescript.
00:02TolstoyWith cljsbuild, I don't think you even need a clojure server side.
00:04kanjacljsbuild is something to check out then
00:13ddellacostakanja: 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
00:15kanja@ddellacosta mies? I'll try that - thanks for the tip!
00:16bitemyappkanja: 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.
00:17kanja@bitemyapp Awesome, thanks!
00:21TolstoyI kinda get the feeling that ClojureScript is a nice little secret weapon.
00:22ddellacostakanja: np
00:28eggheadclj is a very fun web stack these days, most recently i've been playing with liberator, compojure, cljs-http, & om
00:29eggheadcljs http in particular, interacting with http (ring) the same way on client and server is very nice :)
00:30benzapso typically, do you write the cljs files the same way you would write a clj file
00:30benzapand then it generates the proper js file when it's requested?
00:31eggheadusually you compile a cljs app into a single js file including all deps, with a single entry point
00:32benzapso the deps can be just pure javascript?
00:32benzaplike, i could include jquery
00:33eggheadmhmm, you can and there is a cljs wrapper for making it more idiomatic in clj
00:33benzapalright cool
00:33noonianbut there are better options than jquery in cljs imo
00:33benzapi'm just trying to learn clojure for now, but i'm really interested in compjure with clostache
00:34eggheadnoonian: I agree
00:35benzapthere's always better options than jquery ;)
00:35eggheadbenzap: cljs is built on top of the google closure js library, so there are some nice libs wrapping googles stuff
00:35benzapah ok
00:35benzapI was wondering why a lot of the examples had goog in it
00:54ddellacostabenzap: 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
01:33bitemyapparrdem: ring ring
01:37bitemyapparrdem: http://i.imgur.com/oO2SSs1.jpg
01:37bitemyapparrdem: rat dota.
03:45shock_oneIs there something like haskell's flip in clojure, which flips function's parameters? (a -> b -> c) -> b -> a -> c
03:46noonian_you could write it pretty easily
03:47shock_oneI understand, but it would be silly if there is a built-in function.
03:48noonian_i don't think there is a built in one
03:49shock_oneThank you.
04:32Guest68185looking 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?
04:33Guest68185sorry wrong room
04:46Raynesifesdjeen: Hi.
05:46quizdrnice
07:21indianahello all
07:21indianawhy println "hello" "world" produce "hello world" - not "helloworld"?
07:22hyPiRionbecause println and print makes spaces between the arguments given
07:23indianahow i can print it without whitespaces?
07:23hyPiRionuse (str ...) first, then println
07:23hyPiRionso ##(println (str "hello" "world"))
07:23lazybot⇒ helloworld nil
07:23indianathanks man :) i am new in clojure
07:24hyPiRionno problems, hope you enjoy it :)
07:26indianado you have any experience with java in web applications? do you like more using clojure for web applications?
07:27hyPiRionI haven't used Java for web applications, but I've done some work in Clojure and I think it's good for that purpose.
07:28indianaI'm java programmer and i try clojure now. I hope that i will be happy with clojure :)
07:30hyPiRionah. 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
07:33lockshyPiRion: the parens are the same, they’re just on the outside ;)
07:33locksimmutability is doing my head in though
07:34locksbeing used to Ruby et al
07:35alewso I have these nested error checks that go about 7 ifs/if-lets deep
07:35alewis there a better way to format it so that they aren't so nested?
07:35hyPiRionlocks: 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
07:35alewevery failed check evalulates to a single statement that returns an error message
07:36hyPiRionalew: a cond perhaps?
07:37lockshyPiRion: I think it was stuart that demonstrated in a talk that Clojure actually had less parens than a Java example
07:37lockshyPiRion: granted it was probably a cherry picked example, but it’s always entertaining busting myths
07:38alewI also need to have binding lets some ways down
07:38alewI'll probably just write a let-cond
07:38alewor something
07:39hyPiRionah, bindings.
07:39alewwould be simple otherwise
07:40hyPiRionyeah, I think actually making a cond-let would be fair there.
07:41alewsomeone made this http://clojuredocs.org/clojure_contrib/clojure.contrib.cond/cond-let
07:41alewbut I want to have conditionals and optional let bindings on each condition
07:41alewa cond with both if and if-let options
07:45hyPiRionwell, hm.
07:46hyPiRionA cond takes a single branch only. How would a let binding in a cond work?
07:47alewlike how if-let works
07:47hyPiRionalright
07:48alew(let-cond (testexpr) "error 1!" [a (non-nil-operation)] "error 2!" :else "success!")
07:48alewmaybe something like this?
07:49hyPiRionI'd guess you would use a in the "error 2!" statement
07:50alewif a is nil, then "error 2!" is returned
07:50alewotherwise it continues on
07:50alewoh yeah, that's weird..
07:50alewhrm
07:50hyPiRionjust (not) the thing
07:51alewthe a, in this case?
07:51hyPiRionwell, the (non-nil-operation)
07:55alewI guess it's a let-not-cond :P
07:55alewbeacuse it only evals the statements if the test expression is false
07:58hyPiRionwell, here's a cond-let anyway https://www.refheap.com/22921
07:58alewdid you just write this?
07:58alewawesome
07:58hyPiRionyeah
07:59alewoh nice, using the if and if-let
07:59hyPiRionit's not that hard if you just know how to utilize the already existing macros
08:00alewhttps://www.refheap.com/22922
08:00alewpretty easy to make the cond-let-not
08:01DerGuteMoritzuncond-let :-)
08:01alewneed to add a check for a default case
08:01alewdoublepluscond-let
08:02DerGuteMoritzthe default case shouldn't need special handling, it's just :else expr, no?
08:02hyPiRionDerGuteMoritz: yeah
08:02DerGuteMoritzso a regular if branch
08:02alewin this case it does
08:02alewbecause of the switch
08:03alewyou want to eval the expression for the last clause if it is true
08:03alewor I guess you could just pass nil
08:06alewI fucking love macros
08:07DerGuteMoritzthere's nothing cooler than a macro *sing*
08:08alewGreat book
08:18alewwell, the uncond-let looks pretty ugly when there are tons of statements in it
09:14benzapSo I ran the lein help, and it's not being nice
09:15benzapthe examples don't seem to work
09:15benzapany ideas?
09:27JoltinJoejoin eclipse
09:29sandbagsbenzap: what does "not being nice" and "don't seem to work" actually mean for you?
09:40benzapsandbags: sorry, I should give specifics
09:40benzapI ran lein help tutorial
09:40benzapfollowed the tutorial
09:41benzapthe first part that didn't work was
09:41benzap(user/clojurefocs pprint)
09:41benzapwhile in lein repl
09:41benzapi called each of the functions before that
09:42benzapso everything should be imported
09:42benzap(i think)
09:42benzapif you grep lein help tutorial at line "user=> (require 'my-stuff.core)"
09:42benzapyou should be where I started executing commands
09:43benzapit's unclear why it fails
09:43sandbags(user/clojuredocs pprint) works for me
09:43sandbagswithout doing anything else
09:43benzapi'm going to try it again, one sec
09:44sandbagsthat "f" in clojurefocs was that a c&p error? or did you type that in the repl?
09:44benzapwould also like to point out that i'm on emacs
09:44benzapwith windows
09:44benzapand eshell
09:44benzapso it might even be my side
09:45sandbagsbut 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
09:46benzapso when I type (user/clojuredocs pprint)
09:46benzapi get CompilerException java.lang.RuntimeException: No such var: user/clojuredocs, compiling:(C:\Users\benzap\AppData\Local\Temp\form-init9134492706436301542.clj:1)
09:46benzapis this a dependency?
09:47sandbagsi'm not sure
09:47sandbagsit's not clear to me where the clojuredocs function is coming from
09:47sandbagsi definitely have it here
09:48benzapthat's strange
09:48benzapthe second one I tried that gave me trouble
09:48sandbagshere's my ~/.lein/profiles.clj => https://gist.github.com/mmower/b531456f82d7f842a9e4
09:48sandbagspossibly it's coming out of there somewhere
09:49benzapmine doesn't have anything in it
09:49sandbagspuzzling, i don't see the function in the clojure docs in Dash
09:50benzapother than :java-cmd
09:50benzapand an empty :plugins area
09:50benzapi'll copy yours and see
09:50sandbagsi think it might require someone with more clojure experience if that doesn't fix it
09:51benzapmaybe the second problem is a configruation issue
09:51benzapi'm trying the uberjar example
09:51benzapit compiles the uber jar
09:51benzapI created the ./my/stuff.clj file and put the necessary stuff inside
09:51benzapcalled lein uberjar
09:51benzapused their project.clj file
09:52benzapand when I call java -jar my-stuff**....jar
09:52benzapit gives me the error...
09:52benzapoh my
09:52benzapI actually just solved that problem
09:52benzaphaha
09:53benzapthere's a standalone, and a non-standalone
09:53benzapi was trying the non, which probably didn't have the necessary dependencies :S
09:54benzapi'm going to add your plugins and see if pprint works
10:22MorgawrI wish I knew scheme so I could port this http://yinwang0.wordpress.com/2013/11/04/scheme-benchmarking/ to clojure
10:37ro_stdnolen: been playing with om today, finally. very, very cool!
10:37indianado you use https://github.com/weavejester/hiccup in production? What do you think about that?
10:38ro_stindiana: we use it in production. works great
10:39indianafor view layer in java application?
10:39ro_sterr no
10:39ro_stfor a clojure app
10:39indianai want to use it for view layer in spring mvc application
10:40ro_stgosh. good luck
10:40indianathanks
10:45kzarAre lighttable plugins explained anywhere yet?
10:50indianaro_st: what is "gosh" shortcut?
11:06pepijndevosI 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:07locksname* according to a podcast I heard the other day
11:07Bronsapepijndevos: name*
11:08hyPiRionlocks: cognicast or some other podcast?
11:08pepijndevosI think Python does _, Haskell does ' so that leaves * for clojure...
11:09lockshyPiRion: ruby rogues, I think
11:09lockscan’t remember how exactly it came into the conversation
11:09hyPiRionHm, I was hoping for a new Clojure podcast =/
11:10lockssorry to disappoint
11:22deadghostis there a generally recommended beginner clojure book?
11:23deadghostI'm going through http://www.clojurebook.com/ and am only barely following along because I already know some CL and coded some clojure
11:24deadghostsomething I can recommend to my friends without scaring the bejesus out of them
11:24logic_prog_is cljx the right layer to insert type checking / linting code ?
11:24hansel-hanbenzap: braveclojure (website)
11:25arkhdeadghost: maybe this? I haven't read it but others have had good things to say about itL http://www.braveclojure.com/
11:26hansel-hanon a similar subject, i've found that clojure is a rewarding language to teach in person
11:26deadghosteverything is better in person
11:27deadghostespecially when you might need to set up emacs
11:27hansel-hanexactly
11:28sandbagsdeadghost: 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:29deadghostdid you actually read all five
11:29hansel-hanyeah, joy of clojure is pretty good.
11:29xeqihyPiRion: what would you want to hear on a new clojure podcast?
11:29hyPiRionxeqi: Clojure stuff in general. Anything Clojure, really.
11:30seubertis clojure in action outdated?
11:30xeqihyPiRion: have any equivalents from other languages for comparison?
11:30hyPiRionI wouldn't mind Cognicast coming out more often either, but I guess there's a limit on how much they can do.
11:30sandbagsnot really, although there is a MEAP 2nd edition
11:30seubertah didn't see that
11:30hyPiRionxeqi: Well, there's Mostly Erlang
11:31sandbagsi'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:31sandbagsso depends who your target audience is
11:32deadghostsandbags, I'm going through o reilly clojure right now and barely keeping up
11:32deadghostwould it be worthwhile to read the other books afterwards
11:32sandbagsfor me, yes
11:33sandbagsi've not finished them all, i tend to dip in as i process new bits and pieces
11:33sandbagsI find the O'Reilly book had the steepest learning curve
11:33deadghostI'm trying to set a rule for myself
11:33deadghostfor every hour of reading
11:33deadghostat least 2 hours of coding
11:33sandbagsi got wrong-footed by the Programming Clojure book, because I expected something like their Programming Ruby
11:33sandbagsnow i've more experience i am finding it a much better read
11:34locksjoy of clojure 2ED got an update yesterday fwiw
11:35locksdeadghost: http://videos.lispcast.com/
11:37arkhpeople 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:37sandbagsfor my money Erlang was a much easier functional programming language to get wet in
11:38deadghostcommon lisp: a gentle introduction is one of my favorite books
11:40deadghostI never really bought into OOP so it wasn't a difficult transition
11:40deadghostOOP is just doesn't feel right to me
11:41deadghostand k&r demonstrated that state and side effects can be messy
11:42deadghostbiggest hurdle for me was emacs really
11:43locksuse light table xP
11:43deadghostdoes it have vim keybindings
11:43locksyes
11:43sandbagsyes
11:43locksand emacs
11:43sandbagsit's not vim
11:44sandbagsbut it has a reasonably useful subset
11:44sandbagsand a dash or paredit
11:44sandbagss/or/of/
11:44corecodeyey emacs
11:44deadghostis it worthwhile if I'm already on emacs
11:44sandbagsdepends how much you like and want to use emacs i guess
11:44locksit has a bunch of neat tricks under its sleeve
11:45locksespecially if you do cljs
11:50hansel-hanHow 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:52arkhhansel-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:52hansel-hanThat was a poor question. What happens when you call the same datomic query three times in a row from a peer?
11:52arkhhansel-han: if it fits in memory than it will be an in-memory query, no round trip
11:53arkh(if the data it's querying over fits in memory ...)
11:53hansel-hanarkh: thanks. that's pretty much what's happening in MySQL/Postgres too, right?
11:53arkhwithout round trips to a "database server", your queries can become smaller and more numerous without the downside of round-trip overhead
11:54logic_progwhat are the semantics of clojure/spit when a file can not be written (i.e. disk full, invalid file name, file read only)
11:54logic_proghttp://clojuredocs.org/clojure_core/clojure.core/spit is surprisingly weak on documentation
11:55hansel-hanActually, I'm wrong about MySQL/Postgres. You still query the DB and tie it up. It just might have your data in memory.
11:55arkhwell, 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:56andyflogic_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:56arkhso 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:56logic_progandyf, nah, a mthematica would be something like:
11:56logic_progthe semantics of spit are eaxctly the same as the semantics of spit
11:56andyfBut seriously, if you really want to know, start with (source spit) and look up Java methods you find
11:58arkhone 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:59andyflogic_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:59hansel-hanarkh: how? right now i sort-by :thing/uid with code every time
11:59arkhthe 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:00logic_progandyf: nope, definitely not that motivated
12:00logic_progandyf: I think you mistaken me for a future-clojure-contributor
12:00andyflogic_prog: CloureDocs is much easier to modify than the process for Clojure contribution.
12:01arkhhansel-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:01hansel-hanarkh: agreed. i'm just not sure how else to do it
12:03cjfriszIs marmalade known to corrupt package contents?
12:03corecodei'm having difficulties converting from a mutable to immutable mindset
12:03hansel-hancorecode: example?
12:03arkhhansel-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:03corecodespecifically, i want to implement something that is a bit like a graph, with nodes and edges
12:03cjfriszI 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:04cjfriszEvidence suggests that the version on github _isn't_ full of garbage, though
12:04corecodewhen you add a new edge, that will change the data of multiple elements
12:04corecodesome of which might not even be in lexical scope
12:05arkhhansel-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:06andyfcorecode: 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:08andyfcorecode: 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:09corecodeandyf: sure, but if some code contains a reference to a node, that will diverge
12:09hansel-hanarkh: i use d/datoms all the time, but i'm not sure what d/seek-datoms actually does from its docstring
12:10andyfcorecode: 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:10kzardnolen: 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:11arkhhansel-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:11corecodeandyf: i think so, yes
12:12kzardnolen: 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:12corecodeandyf: i'm toying with the idea to implement a DSL
12:12andyfcorecode: 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:13corecodeok
12:14andyfcorecode: 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:14arkhhansel-han: see also 'datoms' in the clojure api
12:16kzardnolen: 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:17edwseubert: There's a new edition of Clojure In Action in the works. I have the "advanced access" edition.
12:17edwseubert: Strike that. There's a new ed. of Joy of Clojure in the works. Sorry about that.
12:18edw(Both Manning Publications?)
12:24michaniskinkzar: http://hoplon.io may interest you
12:29seubertedw: looks like there are new editions of both!
12:38jonathanjhello!
12:39jonathanji'm busy working my way through "Clojure for the brave bold and true" exercises
12:39jonathanji'm wondering if someone can suggest how to format this in a more readable manner: http://hastebin.com/lugoviriko.lisp
12:39kzarjonathanj: FYI usual extension is clj
12:40jonathanj*shrug* hastebin made that up, not me
12:40kzarCould you give an example of using the function?
12:41Morgawrwhy the "and"?
12:42jonathanj(validate {:name (not nil?)} {:name "Chuck"})
12:42jonathanjMorgawr: well that's a follow-up question
12:43jonathanjMorgawr: i'd like to and all the results together, ie. all the validators return a truth
12:43jonathanji thought i could do (apply and (map ...)) but apparently not
12:43Morgawryou can't apply and because and is a macro
12:43Morgawrhttp://stackoverflow.com/questions/9218044/in-clojure-how-to-apply-and-to-a-list
12:43Morgawryou can use every?
12:44jonathanjwhere does `every` come from?
12:44jonathanjoh
12:44Morgawrit's 'every?' with the question mark :P
12:45jonathanjhrm, except that the guide hasn't talked about `every?` yet, so i'm wondering what they had in mind
12:46noonian,(doc every?)
12:46clojurebot"([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false."
12:46noonian,(every? int? [1 2 3])
12:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: int? in this context, compiling:(NO_SOURCE_PATH:0:0)>
12:46noonian,(every? integer? [1 2 3])
12:46clojurebottrue
12:46noonian,(every? integer? [1 2 3 4.0])
12:46clojurebotfalse
12:47andyfBronsa: ping
12:47jonathanjso any suggestions on formatting this code more readably then: http://cljbin.com/paste/52d2d492e4b0797b6a30cd3b ?
12:49cjfriszjonathanj: http://cljbin.com/paste/52d2d4fde4b0797b6a30cd3c
12:49cjfriszjonathanj: that's the community-accepted formatting
12:49andyfjonathanj: 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:50andyfjonathanj: What cjfrisz said :)
12:50noonianhmm, why the and?
12:50hansel-hanjonathanj: in general, newline a function's arguments.
12:50noonianhttps://www.refheap.com/22964
12:50cjfriszjonathanj andyf: though I respectfully disagree with the community standard formatting quite often :-)
12:50hansel-hannoonian: that's what i do
12:51ArjunaxHow can I easily figure out (at the REPL), whether something is a function or a macro?
12:51michaniskin(map (fn [[k v]] ...) coll) --> (for [[k v] coll] ...)
12:51noonianjust evaluate it
12:51noonian,+
12:51clojurebot#<core$_PLUS_ clojure.core$_PLUS_@edf7e4>
12:51noonian,and
12:51clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>
12:51jonathanjnoonian: thanks, i think that's nice
12:52noonianmacro's throw an error when evaluated, functions don't because they are first class values
12:52Arjunaxohh okay, cool
12:52noonianjonathanj: thanks :)
12:52Arjunaxthanks
12:52andyfArjunax: also (:macro (meta #'and))
12:53nooniannp
12:53Arjunax:)
12:54jonathanjmichaniskin: thanks
12:54cjfriszjonathanj: If you've got more style questions, here's the style guide https://github.com/bbatsov/clojure-style-guide
12:55jonathanjcjfrisz: thanks
12:57cjfriszjonathanj: I found it pretty thorough, but I'm not a huge fan of all the suggestions
12:57cjfriszI.e. cemerick and I both disagree with the "Align vertically function arguments." point
12:58jonathanjcjfrisz: some guidance like "put the body on a different line to the arguments" made a lot of sense
12:58nooniani try to align arguments unless the some are k/v pairs then i put the pair on one line
12:58kzarjonathanj: http://hastebin.com/qapoforimu.lisp << I had a quick go at writing it
12:58nooniansome exceptions when things are like doto where the first argument is special
12:59hansel-hani 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:59cjfrisznoonian: your way seems to be the majority opinion, but I dislike it as a matter of personal taste
12:59michaniskinthe 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:00cjfrisznoonian: likely because the scheme mode I was given in college did it a different way :-p
13:00nooniancjfrisz: what do you prefer?
13:00kzar,(:jonathanj {:jonathanj "Keys can be used like functions to access values."})
13:00clojurebot"Keys can be used like functions to access values."
13:00michaniskinother than indentation clojure syntax is so simple i don't really care
13:00hansel-hanclojure 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:01cjfrisznoonian: I prefer always using two spaces indented from the enclosing s-expression for arguments on new lines
13:01jonathanjhow can require something like clojure.string from the REPL?
13:01noonianeven if there are some args on the same line as the fn>
13:01michaniskin(use 'clojure.string)
13:01steerio(require '[clojure.string :as s])
13:02cjfrisznoonian: yes
13:02nooniancjfrisz: i do that when put first arg on next line
13:02steeriojonathanj: the difference is that unlike in the (ns) form here you need to quote it
13:02jonathanjthanks
13:02jonathanjsteerio: why is that?
13:02noonianbut thats actually where i'm most inconsistent, sometimes i only use one space when i'm wrapping some forms in something like first
13:02steeriojonathanj: so you can require the result of an expression, i guess.
13:02jonathanjsteerio: i'm still getting to macros, but i don't fully understand why
13:03bbloomcjfrisz: i vertically align arguments when they are *arguments*, but i 2 space indent subforms when they are code blocks
13:04steeriojonathanj: in fact require is a function, so when you call it, parameters get evaluated first
13:04cjfriszbbloom: I only recently realized that's how almost all lispers do it outside of Indiana University
13:04steeriojonathanj: (require clojure.string) would look for the value of a var called clojure.string
13:05bbloomcjfrisz: 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:05bbloomgrr :-P
13:05cjfriszbbloom: I agree by way of thinking just about everything should be 2 space indent :-)
13:05steeriojonathanj: just like, say, (println clojure.string) would
13:05noonianhmm, i like aligning args with ->
13:06hansel-hannot aligning will make code feel like a codeblock to me. imo the first arg to -> isn't that special.
13:06bbloomcjfrisz: the way i like to think of it is that i want to push "goals" to the left margin
13:06noonianits just the first form, only thing special is it doesn't have something threaded in imo
13:06cjfriszAlthough I like 'if,' 'and,' and 'or' to be aligned on the first argument
13:07bbloomcjfrisz: lol precisely the opposite of clojure style
13:07cjfriszbbloom: indeed
13:07cjfriszAgain, I didn't realize I had minority opinion until I started looking at common lisp and racket modes recently
13:08steerioin fact with a language based on S-expressions, we could have it rendered to everyone according to their taste
13:08steerioprovided that they can express that taste programmatically
13:08steeriowhy do we even store it in text?
13:08bbloomsteerio: not really. we still have comments which are not in the AST :-)
13:09steeriobbloom: can be solved easily
13:09andyfnot everyone's tastes can be expressed programmatically
13:09michaniskin(comment "i am a comment!")
13:09bbloom";" should be infix for "add metadata to the preceding form" and ";;" to the next form :-)
13:10steeriomichaniskin: 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:10michaniskinit's also an s expr, which is key for formatting with simple tools
13:11michaniskinonce you depart from sexprs things get complicated
13:11andyfmichaniskin: 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:12michaniskinandyf: true, but #_"i am a comment" is problematic because it's not an sexpr
13:13steerioif i was to invent a non-text source code format, i'd add another form for this, which would be truly ignored
13:13steeriowhenever the reader encounters it, it'd just ignore it
13:13michaniskina reader pass that prepreocesses sexprs
13:13michaniskinlike
13:13steeriothough editors would display ; Foo
13:13michaniskin(#_ "this is a comment")
13:14andyfI 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:15michaniskinwhy do reader macro forms not use sexpr syntax? i must be missing something
13:15bbloomandyf: because humans type things with keyboards
13:16bbloomit's pretty much that simple :-)
13:16michaniskinlike why don't we write (# {1 2 3}) instead of #{1 2 3}
13:16michaniskinthis would be way easier to make tooling around
13:16bbloommichaniskin: why don't we write (string \x \y \z) instead of "xyz" ?
13:17michaniskinbbloom: because strings are not really collections
13:17bbloommichaniskin: at some point, you have to have some syntax
13:17michaniskinit's still syntax because the reader would read that as a set, not a seq
13:17bbloomok fine, why do we write [5 10 15] instead of (read-time-vector 5 10 15]
13:18bbloommichaniskin: go install Mathematica and play with FullForm
13:18bbloomwhat you want has / can be done
13:18michaniskini mean why not in clojure?
13:19hyPiRionbecause it's easier for humans to read.
13:19michaniskini understand that we want [1 2 3] and not (read-time-vector 1 2 3)
13:19bbloomb/c the syntax & reader was developed adhoc with the goal of being LL(1) instead of maintaining canonical tree form
13:19michaniskinbut we have a limited set of punctuation on keyboards
13:20Bronsaandyf: pong
13:20michaniskinso if maps use {} then we need something else, like (# {}) for sets, or #{}
13:20michaniskinwhat i don't understand is what's the problem with (# {})?
13:20michaniskinan extra set of parens and a space?
13:20bbloommichaniskin: it would have to be primitive
13:20bbloommichaniskin: a macro can't do it
13:21michaniskinthe reader would read (# {}) as (clojure.lang.PersistentSet. 1 2 3)
13:21michaniskinor whatever
13:21michaniskinit would read that in as a set
13:21bbloommichaniskin: that doesn't work b/c (some-macro (# 1 2 3)) would get a list instead of a set
13:21michaniskinas it should
13:21andyfBronsa: 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:22michaniskin(# {1 2 3}) would be a set
13:22andyfBronsa: I'm trying to figure out the difference in what gets eval'd in each case, but perhaps you already know.
13:22bbloommichaniskin: you're missing what i'm saying, maybe i'm not explaining clearly
13:22hyPiRionmichaniskin: what's wrong with the current way of writing sets, though?
13:22bbloommichaniskin: it's a phasing issue
13:22michaniskinjust like when you pass #{1 2 3} to a macro, you don't get a symbol # followed by a misformed map
13:23michaniskinbbloom: because source code isn't a tree
13:23michaniskinbbloom: that makes editor tooling complicated
13:23michaniskinbbloom: you now need to invent "false trees"
13:23bbloommichaniskin: no no, it's just that the reader combines two phases
13:23bbloomthere is no "false trees"
13:23bbloomthe syntax is already a tree, but we skip a step w/ the reader
13:23michaniskinbbloom: how do you edit #{1 2 3} structurally?
13:24Bronsaandyf: might be emit-form forgetting to attach some :tag metadata, I'll look into that
13:24michaniskinsay you want to make that into a map
13:24andyfBronsa: Want a ticket with a short example?
13:24bbloommichaniskin: you can easily imagine a new namespace called clojure.syntax
13:24michaniskinbbloom: the editor needs to treat #{1 2 3} as (# [1 2 3]), basically
13:24bbloommichaniskin: 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:24bbloommichaniskin: but then you need to do something the reader does: convert syntax to data types
13:25bbloommichaniskin: that has to happen BEFORE macros
13:25michaniskinbbloom: of course, but now we're reverse engineering the clojure reader, which isn't formally specified
13:25bbloommichaniskin: (mac #{}) will call the function backing mac with a set, not with a list
13:25hyPiRionmichaniskin: who says the editor does? That sounds a bit strange
13:25Bronsaandyf: sure, thanks
13:25bbloommichaniskin: ignore the editor, ignore the clojure implementation of the reader
13:25bbloommichaniskin: a reader in general combines two phases: parsing and evaluation of syntax forms
13:26bbloommichaniskin: you can write a function that walks [:some [:tree] [:like :this] [:set 1 2 3]] and turns :set nodes in to PersistentHashSet objects
13:26bbloommichaniskin: the clojure reader is simply doing that during parsing b/c the compiler has no need for the unresolved tree
13:27michaniskinbbloom: you're missing my point
13:27michaniskinbbloom: 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:28bbloommichaniskin: the macro sees a set b/c that's what a macro is defined to do
13:28bbloommichaniskin: i can invent a new type of "macro" that sees pre-reader-evaluation forms
13:28michaniskinbbloom: same thing with this: (foo (# [1 2 3])). the reader would read (# [1 2 3]) at the call site
13:28michaniskinand foo would see a set
13:29andyfBronsa: Woah. It isn't even deterministic. I get about 50% of the time in a short example. WIll mention in the ticket.
13:30gtrakis there a built in way to get cider to send nrepl a 'complete' message?
13:30bbloommichaniskin: 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:30bbloommichaniskin: eval operates on Any, not on AST
13:31michaniskinbbloom: 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:32coventryHave most people switched over to cider.el at this point?
13:32bbloommichaniskin: lol oh, that's you're argument? you're actually arguing that you'd rather less syntax?
13:32bbloommichaniskin: syntax, it turns out, is useful to humans :-P
13:32michaniskinbbloom: i would prefer (# [1 2 3]), because my editor could then show me #{1 2 3} if that's what i like
13:32michaniskinbbloom: but the editor itself could be far, far simpler
13:33michaniskinespecially since the clojure reader is not formally specified anywhere as far as i know
13:33noonianbut then if our editor doesn't have that support we are soul
13:33michaniskinnoonian: but your editor would, because it wouldn't be black magic
13:33noonianout of luck
13:34michaniskindisplaying quirky syntax is a job for an editor, not a reader, imho
13:34bbloommichaniskin: you're still conflating parsing and reading; syntax and semantics
13:35michaniskinbbloom: lol ok man
13:35bbloommichaniskin: 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:35hyPiRionmichaniskin: 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:37michaniskinhyPiRion: because [] and {} can be edited the same way as (), basically
13:37hyPiRionmichaniskin: so can #{}, unless you've hardcoded that delimiters must be 1 char for start and stop
13:38michaniskinhyPiRion: it's not that simple
13:38michaniskinhyPiRion: consider #{1 |2 3}
13:38michaniskinwhere the point is at the |
13:38Bronsaandyf: ... guess what. I got bitten again by clojure silently ignoring :tag
13:38michaniskini want to delete the 2 and convert the set into a map. how to do?
13:39michaniskinhyPiRion: clearly, that set would need to be structured as (# [1 2 3])
13:39hyPiRionmichaniskin: clearly? I don't see any argument for why that is.
13:39andyfBronsa: Pardon me for a moment while I continue to be stunned at the speed at which you find such things :-)
13:39clojurebotHuh?
13:40noonianwont #{1 2 3} get re-written as (set 1 2 3) or something by the reader?
13:40michaniskinbbloom: the AST is not that you print to the source file, btw. you print things that can be read by the reader
13:40michaniskinbbloom: once you have the AST you've lost reader macro info
13:40Bronsaandyf: http://sprunge.us/aEIV?diff this should do it. Let me double-check for a minute and then I'll push the fix
13:40hyPiRionmichaniskin: #{1 2 3} can just be modified in the same way as a list, vector and map can be.
13:41bbloommichaniskin: (def reader (comp eval-reader-literals parse))
13:41michaniskinhyPiRion: how do you delete the # there?
13:41hyPiRionmichaniskin: same way as you replace a {, [ or (, by removing it
13:41bbloommichaniskin: 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:41andyfBronsa: Would the place you've found this explain the nondeterminism of results, too?
13:42Bronsano idea about that
13:42michaniskinbbloom: your argument is similar to the argument that scala macros are as awesome as clojure macros
13:43bbloommichaniskin: scala's macros are fundamentally different from clojure's macros
13:43bbloommichaniskin: scala macros operate on the AST, clojure's macros operate on Any
13:43michaniskinbbloom: you can have a hyper-complex AST representation, yes, but it isn't better than having sexps
13:43andyfBronsa: 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:44bbloommichaniskin: 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:44Bronsaandyf: oh, that's it then.
13:44Bronsasometimes the type hint is a Symbol, sometimes it's a Class
13:44Bronsawhen it's a Class, the Compiler ignores the hint
13:45bbloommichaniskin: 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:45andyfBut why would it sometimes be a Symbol, and sometimes a Class, when I'm analyzing the same source file?
13:45michaniskinbbloom: so specifically why is #{1 2 3} better than (# [1 2 3])?
13:45bbloommichaniskin: because humans like syntax
13:45michaniskinbbloom: so the parens
13:45michaniskinthat's all i was looking for
13:45Bronsaandyf: oh. in the same form? weird.
13:45steerioand you'd mix reader macros with macro calls
13:46steeriothe two are different animals
13:46michaniskinsteerio: no, you can't name a macro #
13:46steerioi mean if your idea was implemented, which implies that you can
13:46michaniskinsteerio: the two methods are equivalent, i think, operationally
13:46andyfBronsa: 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:46michaniskinit's just a matter of taste, apparently
13:46Bronsa:/
13:46steeriomichaniskin: well no, because your example is a nonexistent form
13:46andyfThe pprint'ing doesn't show whether it is a symbol or a class, so your explanation could still be correct.
13:47bbloommichaniskin: 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:47steerio,(# [1 2 3])
13:47clojurebot#<RuntimeException java.lang.RuntimeException: Reader tag must be a symbol>
13:47andyfor maybe the pprint'ing would distinguish between Symbol and Class?
13:47Bronsaandyf: I'm positive that the bug is caused by that, still no idea why it doesn't happen every time
13:47michaniskinsteerio: i meant if the reader read that as a set
13:47steeriogtg
13:47Bronsano, symbols and classes prints the same unfortunately
13:47michaniskinsteerio: it would require a different reader
13:47steeriothough i'd love to continue this
13:47steeriomaybe sometime
13:48andyfBronsa: The pprint'ed form I see contains this sub-form that causes the reflection warning: (.nth ^clojure.lang.IChunk chunk_4449 o_4451)
13:48Bronsaandyf: can you try and see if it's still non-deterministic if you move the doseq out of the defn?
13:48andyfsure
13:51jonathanjsteerio: ah, good point
13:52andyfBronsa: yes it is still nondeterministic with a doseq at the top level of the source file, not inside a defn
13:53Bronsano idea. I'll investigate a bit
13:56Bronsaandyf: I pushed the fix and updated eastwood to use the new SNAPSHOT
13:57Bronsaandyf: just another theory, can you ensure *warn-on-reflection* is actually true both times?
14:04andyfBronsa: Need to go for a while. Will look into it more later today.
14:05Bronsaok, thanks
14:58pepijndevoswaaaaiiit... > < >= <= only work on numbers? What about other comparables?
15:00pjstadigpepijndevos: surprise!
15:03bbloom,(< [5] [10])
15:03clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number>
15:03bbloomhuh.
15:04bbloom,(compare [5] [10])
15:04clojurebot-1
15:04bbloom,(compare [10] [5])
15:04clojurebot1
15:04bbloompepijndevos: pjstadig: i did not realize :-P
15:05hyPiRion,(= [[10] [5]] (sort [[10] [5]]))
15:05clojurebotfalse
15:05hyPiRion,(= [[5] [10]] (sort [[5] [10]]))
15:05clojurebottrue
15:05pepijndevosnow have a look at subseq, and be amazed.
15:05bbloom,(doc subseq)
15:05clojurebot"([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:06pepijndevos&(subseq (sorted-set \a \b \c \d \d) > /b)
15:06lazybotjava.lang.RuntimeException: Invalid token: /b
15:06pepijndevos&(subseq (sorted-set \a \b \c \d \d) > \b)
15:06lazybot⇒ (\c \d)
15:17bbloomhas anybody tried a breadth-first traversal with clojure.zip ?
15:17bbloomseems quite tricky...
15:23pjstadighmm yeah
15:23pjstadigjust DFS for me
15:39kristofAre takes from async channels guaranteed atomic?
15:39kristofMeaning two processes can't take from the channel and end up with the same item
15:40kristofOr is taking and putting ALSO an asynchronous process and the channel itself decides which consumer gets what item? :)
15:40kristofI'm sorry if there's some fundamental misunderstanding I'm showing, here
15:44arkhkristof: 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:44arkhkristof: a given item could only be take!'n once
15:44kristofarkh: 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:45kristofarkh: Do you think there would be a performance benefit to making channels themselves be asynchronous as well, letting the channel be
15:45kristofwell I guess I'm thinking of actors
15:45kristofthe 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:46kristofBut then the channel itself would not be so lightweight, would it? Hrm. Oh well :)
15:46arkhkristof: but then how are agents already coded? : ) I think it acquires a lock, too
15:47kristofarkh: Do they? Nothing actually accesses an agent's state besides the agent itself, I thought, so locking would be keeping nothing out.
15:47kristofBut I am probably wrong in this regard
15:48arkhkristof: 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:49kristofarkh: 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:50bbloompjstadig: give breadth first a try, turns out it's actually hard :-P
15:50arkhkristof: 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:50bbloompjstadig: http://www.eecs.usma.edu/webs/people/okasaki/icfp00.ps <- general functional breadth-first numbering. not w/ a zipper
15:51kristofSo I guess all real concurrency involving shared state relies on locks at least on some level of abstraction?
15:51bbloompjstadig: very trick
15:51bbloomy
15:51arkhkristof: sorry, I meant like a go block in style but not in code
15:51bbloompjstadig: whoops, bad url
15:51bbloomhttp://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf there
15:52arkhkristof: I though clojure mvcc mostly revolved around speculative locks w/ retries
15:52arkhkristof: even agents - it's just the meat of your code doesn't run until things are verified
15:53kristofbrb while I learn what a speculative lock is
15:59arkhkristof: I should have said "stm" instead of "mvcc" back there
16:00kristofarkh: I'm sorry, I thought those were synonymous.
16:02arkhkristof: 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:02arkhsucceeds. 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:04kristofSo a speculative lock tries, checks, then commits or retries.
16:04arkhkristof: oh .. it looks like STM is the problem category and MVCC is how clojure solves it
16:04kristofAnd STM is just large-scale manipulation of speculative locks.
16:06arkhmvcc 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:06fredyrkristof: arkh: I've found this page very helpful in understanding more about the clojure stm, http://java.ociweb.com/mark/stm/article.html
16:07arkhfredyr: nice!
16:08fredyryou might like this one too: https://github.com/tvcutsem/stm-in-clojure
16:09kristofarkh: 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:10mercwithamouthdoes anyone have any good enfocus projects besides chatter-box on github?
16:15arkhkristof: is there any way to do safe concurrency without some kind of lock/mutex/etc. or forcing changes to be single-threaded?
16:16arkhkristof: it looks like agents are ultimately managed by this: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java
16:16kristofarkh: 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:17arkhkristof: isn't that parallelism instead of concurrency though? : )
16:18kristofarkh: 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:18kristofThen again, isn't an actor's mailbox shared state? ...............
16:19arkhmaybe the mailbox is managed by a single event/dispatch thread .... I know zero about actors!
16:19kristofI'm not smart enough for this :(
16:20arkhI'm having fun trying to stretch what little I know!
16:22kristofarkh: The agent.java code in the tree never imports locking transaction. How did you come to that conclusion?
16:23dgrnbrgHow 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:24eggheadin all my use of clj i've never needed agents
16:24dgrnbrg"Communicate by sending messages over channels" is what i'm thinking, but I feel like that doesn't capture the awesomeness of alt!
16:25kristofegghead: 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:25kristofdgrnbrg: 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:26arkhkristof: 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:26eggheadconsumer producer / pubsub doesn't do justice to core.async :p
16:26dgrnbrgkristof: 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:27dgrnbrgwe 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:28locksI liked how in dnolen’s presentation
16:28eggheadreading 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:29kristofdgrnbrg: 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:29lockshe went from not accepting repeated sequential keys to not accepting repeated keys ever
16:30dgrnbrgkristof: I feel like those aren't compelling features of core.async, since you can do that with threads and java.util.concurrent
16:31dgrnbrgalts! 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:31kristofdgrnbrg: not the state machine stuff?
16:31dgrnbrgthe state machine stuff only exists so that the user-space scheduler can exist
16:31kristofThat's what I was talking about
16:31dgrnbrgsince you can accomplish the same thing with threads + blocking calls, and that scales to thousands of processes
16:32dgrnbrg"processes", aka threads
16:32kristofhmmm
16:32eggheadalts! is really cool because it is explicit non-determinism
16:34eggheadbut >! is not the same sort of thing as regular communication between threads or agents
16:34eggheadit's got transactional semantics
16:35afhammadwhat does it mean when a function is prefixed with ->, for example something/->dothis
16:35arkhI like this project's extension of core.async: https://github.com/tonsky/net.async
16:36AimHereafhammad, -> and ->> are just macros for making code more readable in some cases
16:36dgrnbrgegghead: you can get that using java.util.concurrent.LinkedBlockingQueue, if you want the blocking channel semantics
16:36dgrnbrgegghead: 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:36AimHereafhammad, the idea is that instead of (foo (bar (baz (wibble x))))), you write (-> x (wibble) (baz) (bar) (foo))
16:37AimHereOr something to that effect
16:37eggheaddgrnbrg: ah yes, but now you have blocked threads ;)
16:37afhammadAimHere: is that always the case? what about: services/->Services
16:37egghead*not* the same as how core.async puts threads to sleep inside their state machines
16:37dgrnbrgegghead: threads are quite scalable--a 24 core machine can easily handle thousands of threads
16:38egghead'parking' or w/e
16:38dgrnbrgthe OS is quite effective at parking native threads
16:38AimHereafhammad, ->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:39dnolendgrnbrg: I think the fact that core.async was designed w/ ClojureScript in mind from the start is pretty compelling.
16:39dnolendgrnbrg: but maybe your audience is mostly concerned with server-side affairs
16:39dgrnbrgthey're a mix
16:40dgrnbrgthat is a good point, however--I'm going to mention the JS support, because that is pretty awesome
16:40eggheadi think core.async is a nice async lib, but I think it is a better example of why macros are so cool
16:41eggheadmacros let clojure borrow all the good ideas from other langs :)
16:43edwegghead: <http://poseur.com/java-scheme&gt;.
16:44eggheadedw: :)
16:44edwSome hairy macroage in there.
16:45edwWriting macros is the only intellectual activity where I feel actual, literal nausea when things get real.
16:46edwStaring into the abyss so others needn't.
16:51edwSpeaking 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:39gtrak80% of the way to a cljs autocomplete lib, analogous to clojure.complete :-)
18:40gtrakI'm hoping someone will help me with the emacs part.
18:41bitemyappegghead: macros aren't the only way :)
18:42gtrakthe interaction between nrepl, austin, piggieback, ac-nrepl and clojure-mode is.. a bit hairy.
18:43gtraklike.. I think I'll have to disable ac-nrepl, since it actually evals code instead of just sending over a "complete" op.
18:44bitemyappac-nrepl lags too much for me to use.
18:44gtrakall this effort because I was trying to build something with om and got fed up with looking at github :-)
18:45gtrakbitemyapp: do you have autocomplete through ritz or something else?
18:45gtrakI noticed that's one thing that actually uses a 'complete' nrepl op
18:45gtrakand I'm modeling the ensuing piggieback integration after that.
18:45bitemyappgtrak: I use the dumb Emacs AC. It's annoying.
18:46bitemyappgtrak: uh, in Clojure anyway. I have smarter tooling elsewhere.
18:46gtrakblah blah blah haskell
18:46bitemyappI didn't say it.
18:46gtraknot today :-)
18:46bitemyappall you bro./
18:46clojurebotI don't understand.
18:46bitemyappoh shush up bot.
18:47gtraknot having autocomplete wasn't a problem before, since I wasn't learning a bunch of new libraries.
18:48gtrakor writing my own for everything.
18:48gtrakrather, I _was_ writing my own. Hopefully once this infra is in place, it won't be too hard to get M-. going.
18:49bitemyappgtrak: you know what helps even more for reading code you didn't write?
18:49bitemyappgtrak: I give ya two guesses.
18:49gtrakprinting it?
18:49amalloyeyeglasses
18:49bitemyappgtrak: types.
18:50gtrakhahaha
18:50bitemyappamalloy: only if you want >80 columns.
18:50gtrakI use reading glasses occasionally, different focus lengths helps with eyestrain over the course of a week.
18:50bitemyappgtrak: 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:51gtrakah, that is pretty cool actually, but that means I have to use haskell.
18:52bitemyappthat would appear to be the tradeoff.
18:52gtrakstill, I end up reading all the code of every lib I use, anyway, tooling just helps me jump around quickly.
18:52bitemyappgtrak: oh sure, but the types still help: http://hackage.haskell.org/package/base-4.6.0.1/docs/src/Data-List.html#maximum
18:52bitemyappgtrak: :browse in ghci dumps the types and fn names of the module you passed.
18:53bitemyappgtrak: so it's pretty easy to get a 1,000 km overview that way and then start diving into the code.
18:53gtrakone day :-)
18:53gtrakit's been on my list for about 3 years, never the top item..
18:53bitemyappgtrak: well, if you ever want a jump-start, advice, ideas, etc. - ping me.
18:54bitemyappgtrak: it's a learning process very amenable to hammock time.
18:54gtrakyea, that's a good feeling.
18:56gtrakfor now I'm just trying to hack stuff out as fast as possible in clj/cljs.
18:56gtrakbecause of the 'reach' aspect.
18:58bitemyappgtrak: I gotcha. Reach?
19:00gtrakyea.. 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:01bitemyappgtrak: 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:01gdevwell I've been meaning to reduce my Haskell naivete
19:01bitemyappwish the day job leveraged more of it, but my current project at work is hyper Python-specific.
19:01gtrakthat sounds fun, you're in the west coast, yea?
19:01bitemyappgtrak: Yay Area, I live in SF.
19:01bitemyappgtrak: trying to get the fack out of here.
19:01gtrakyea... the tech scene here is really indy.
19:01gtrakin comparison.
19:01bitemyappindie?
19:01gtrakyea, I guess :-)
19:02gtrakI never try to spell that.
19:02bitemyappI'm just unclear on what it's meant to mean.
19:02gtraklittle, mostly low-profile startups
19:02gdevbitemyapp, have you used Haskell with Datomic?
19:03gtrakbut it's a close-knit group.
19:03edwPhilly 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:04gtrakedw: it's probably not so different, I'd guess philly was bigger.
19:04bitemyappgdev: I'm all-up-ons with Datomic at work but I haven't had time to poke around with hEdn in Haskell yet.
19:04bitemyappgdev: my Haskell projects are mostly PGSQL at the moment because esqueleto is RIDIC.
19:04gtrakbaltimore has the DC influence, a lot of folks commute there and back.
19:04bitemyappgdev: regardless, it'd mean going over a proxy like berossus to talk to Datomic.
19:04gtrakso, clojure realistically will interest someone here, haskell I'd be on my own, I'm afraid.
19:06gdevbitemyapp oh, damn, I was hoping to find something that Clojure-the-language would let you do that Haskell-the-language couldn't ;)
19:06edwgtrak: 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:06gtrakb/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:06bitemyappgtrak: learn it for the epiphany, same reason people learned Lisp for the last couple decades. Offer still stands for my time.
19:06gtrakbitemyapp: I hope to take you up on it sometime.
19:06bitemyappMakes sense re: Hadoop, but I strongly suspect you could still put something together.
19:07bitemyappgdev: nice try! Haskell has best-in-the-industry parser libraries. Something like edn wasn't going to stop anybody.
19:07locksparsec is kinda good
19:07bitemyappattoparsec too.
19:09kanjais there a way with cider to see a specific line of code where an error occurred?
19:09gtrakkanja: stacktraces have file-and-line info generally
19:09kanjaSomething 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:10edwkanja: And if they don't, it may be because you "C-x X-e"'d and didn't "C-c C-k".
19:10gdevbitemyapp, ha, that was my first and last attempt too, life is too short for PLT trolling
19:10amalloykanja: (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:10gtrakit's not easy to jump into java, eclipse has a roundabout way of implementing it, though, involving downloading the source artifacts from maven.
19:11bitemyappgdev: http://www.youtube.com/watch?v=asgiNZrcJ44
19:11kanja@edw - yeah that I did do.
19:12bitemyappgdev: watch with audio.
19:12gdevbitemyapp, yeah that's how I feel lol
19:12kanjabut I'm also getting the error at run time rather than load
19:12kanjaso c-c c-k works, but then (myfun someargument) in cider fails
19:13gdevbitemyapp, 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:14bitemyappgdev: 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:15bitemyappgdev: learning how to pair remotely is a useful skill regardless.
19:15bitemyapppaired with others over the internet for Haskell and for day-job stuff both.
19:16gdevbitemyapp that's true, well just name the time and the project and add me to skype ha
19:16gdevor I'll add you because I bet I can guess your skype name
19:17bitemyappgdev: 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:17bitemyappgdev: you won't.
19:17bitemyappmy skype name is ancient and eldritch, nobody could ever guess it.
19:18bitemyappgdev: I'm not bitemyapp on Skype. I am on github/twitter though.
19:20bitemyappI might need to fix hEdn if it's implemented based on the spec (4) or possibly write my own library (5).
19:25bitemyappI'm always up for plain ole tutorials too.
19:28gdevyeah that might be about my level at the moment
19:29bitemyappgdev: there are some prereqs involved. The idioms in Haskell are varied and rich but require building blocks like mathematics.
19:29bitemyappemphasis "like".
19:30bitemyappgdev: Once 80% of this makes sense http://www.haskell.org/haskellwiki/Typeclassopedia you'll be a long way already.
19:32gdevbitemyapp yeah I have a lot of homework to do
19:35gdevhad a problem so I thought I would log on to IRC, now I have a mountain to climb
20:23logic_progin clojure.core.async, is there a way to say: "close this channel if I have not received anythin gfrom it in 5 minutes" ?
20:23logic_progi.e., there's a timer on the channel
20:23logic_progthen after every message, the timer gets set to (current time + 5 minutes)
20:25amalloylogic_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:26logic_progso I create a _new_ channel on every take-mejssage via <! ?
20:26logic_progthat seems sorta expensive
20:26amalloythe usual caveats apply: i don't actually use core.async, so alts! may not quite the right function
20:26logic_progor are channels that cheap?
20:26amalloysure, why not?
20:26logic_progmaybe I shoud write the code + benchmark it
20:26logic_prograther than use imaginary optimizations
20:27amalloyyeah, i would be quite surprised if making a channel were much more expensive than receiving from one
20:27bitemyappamalloy: sounds fine to me.
20:27amalloylike, 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:28bitemyapplogic_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:28logic_progbitemyapp: you are wise
20:28logic_progi'm procrastinating with these imaginary perfomrnace bottlenecks
20:28amalloya popular pastime
20:28amalloyi prefer to procrastinate by answering questions in #clojure
20:29testclojl
20:29edwThere's beene a lot of yak shaving going on today.
20:29edws/beene/been/
20:29testclojcl
20:29testcloj(map #(into {} [[1 2]]) [:a :b :c]) didn't give result of {1 2, 1 2, 1 2}? instead it throws error
20:29testclojwhy it doesn't work?
20:30amalloy#(into {} [[1 2]]) is a function of zero arguments, and you passed it one
20:30amalloyyou could instead use (constantly {1 2]), for example
20:30edwIt's a function of zero arguments because your #(...) form contains no percent signs.
20:32amalloyit 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:35testclojgreat, thx. this works: (map #(let [a %] into {} [[1 2]]) [:a :b :c])
20:38testcloj 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:40hyPiRiontestcloj: you need to wrap it in a paren first
20:41hyPiRion,(map #(let [a %] (into {} [[1 2]])) [:a :b :c])
20:41clojurebot({1 2} {1 2} {1 2})
20:41hyPiRionvs
20:41hyPiRion,(map #(let [a %] into {} [[1 2]]) [:a :b :c])
20:41clojurebot([[1 2]] [[1 2]] [[1 2]])
20:48testclojThanks hyPiRion, but why wrap in a paren make a differnce? I am a newbie to cljure, might be a stupid quesiotn
20:52bitemyapplogic_prog: careful with words like that, the rabble might get angry and toss you off a cliff.
21:00logic_progI 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:00logic_progi.e. my clojure app authenticates "hey, you have access to object XYZ, go fetch it from y other server"
21:00logic_progthen the other server looks at the certificate for "give me XYZ", authenticates it, and returns it
21:01logic_progwhat is the easiest way to setup this "k/v store" with authentication + expiring urls
21:01bitemyapplogic_prog: so, you want a CMS with an ACL?
21:01logic_progacl = access control list, yes
21:01logic_progcms = contant management system ?
21:01bitemyappcontent
21:01logic_progbasically I want something like riak, or hbase + authentication
21:01logic_progit's for hosting static constant
21:01logic_progi.e. think instangram / snapchat hosting of photos
21:03logic_progideally, this k/v store responds over http
21:05bitemyapplogic_prog: static content? you want riak, not HBase.
21:05bitemyapplogic_prog: HBase is *not* made for static content yo.
21:05bitemyapplogic_prog: Riak with the Bitcask backend specifically.
21:06logic_progsorry, I meant hdfs
21:06logic_progriak + authentication would make me happy
21:06CaptainLexDoes anyone have any shoreleave experience? Is there a way to add middleware to a specific remote?
21:07logic_proghttp://docs.basho.com/riakcs/latest/cookbooks/Authentication/ looks like what I want
21:07logic_progquery string optimiations
21:09Janiczekhi, 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:18arohnerstupid 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:18arohnerare go blocks values? (i.e. if I don't return the go block, will it still work?)
21:19ToBeReplacedjaniczek: 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:20ToBeReplacedarohner: 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:21ToBeReplacedarohner: you don't have to return a ref to the block; it won't be GC'd until its work is done
21:21arohneraha. there's the magic
21:22JaniczekToBeReplaced: thanks, if I won't figure it out, at least this is nice :)
21:28bitemyappddellacosta: Keep coming back to this to see how many of the solutions youy understand: http://www.willamette.edu/~fruehr/haskell/evolution.html
21:28bitemyappddellacosta: it's also just a nice joke.
21:28ddellacostabitemyapp: ha, bookmarked that a few weeks ago
21:28bitemyappwell there you go. :)
21:29ddellacostabitemyapp: 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:29ddellacosta*foldr
21:30bitemyappddellacosta: 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:30bitemyappddellacosta: a learning exercise is translating relatively obvious recursive implementations of tree operations to folds.
21:30ddellacostabitemyapp: I rather like the simplicity and elegance of the recursions, most definitely
21:30bitemyappddellacosta: the compiler can do more to help you out if you use things like foldr though.
21:30ddellacostabitemyapp: gotcha, good to know!
21:31bitemyapprecursion is you basically telling GHC, "I got this."
21:32coventryJaniczek: Use cider-eval-expression-at-point-in-repl from https://github.com/halgari/clojure-conj-2013-core.async-examples#usage
21:39Janiczekcoventry: wow, that is exactly what I had in mind. thanks!
21:47seangroveOh man, if only the cljs compiler were a person, I could throttle it
21:47seangroveSo tired of seeing "java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space" right before trying to push to production
21:53bitemyappseangrove: funny, I get that almost every time I use Scala.
21:53bitemyappthen I remember to jack up my Xmx into the stratosphere.
21:54seangroveLooks like it's a combination of several things, but maybe updating Java will help
21:57seangroveHrm, 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`cbpdoes anyone have a cljs + node lein template around
22:03bitemyapp`cbp: node?
22:03`cbpbitemyapp: yea
22:03bitemyapp`cbp: node?
22:03`cbpwat :(
22:03bitemyappson, I am disappoint.
22:03arrdemthere are things that Javascript should not do...
22:04`cbpi need to make desktop app and im not about to learn swing
22:04bitemyapp`cbp: first you abandon me to randos on DotA2. Now you're using node for anything other than cat pictures?
22:04bitemyappohhhhhhh
22:04bitemyappI has answer.
22:04`cbpbitemyapp: I always invite you on dota :(
22:04`cbpyou seemed away today
22:05bitemyapp`cbp: oh, sorry. I've been hacking today. Still want to play?
22:05`cbpnope :p time to figure out cljs + node
22:05`cbp+ node-webkit
22:05bitemyapp`cbp: http://book.realworldhaskell.org/read/gui-programming-with-gtk-hs.html
22:06bitemyapp`cbp: you could also use Fay with node-webkit >:)
22:06bitemyapparrdem: doters?
22:06arrdembitemyapp: lemme finish figuring out when and where my classes start tomorrow then sure.
22:06bitemyapparrdem: oh exciting. What are you taking?
22:07arrdembitemyapp: the only interesting things are a graduate compilers class and the honors undergrad algos class.
22:08kanjaI'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:11amalloyi don't really believe that's what happens, kanja (conj some-list anything) always works
22:11amalloywhereas (conj some-map any-list) always fails, in the manner you describe
22:12bitemyappkanja can't conj
22:12bitemyappsay it out loud.
22:13kanjahttp://pastebin.com/AZUh0CUM
22:13kanja@alalloy ^
22:14kanjaerr http://pastebin.com/dhdcHgz6 is a little clearer
22:15kanjaUG dur, revered the arguments to the function
22:17bitemyappso, in a blazing show of total predictability, amalloy was right again?
22:18gfredericksclojurebot: amalloy |was| right again in a blazing show of total predictability
22:18clojurebotRoger.
22:19amalloyaw
22:19arrdembitemyapp: well... looks like I'll be able to go work out daily before classes if I stop staying up to 2am.
22:19arrdembitemyapp: decisions decisions.
22:20bitemyapparrdem: I think you can fit both if we just cut it off a game earlier. Doters?
22:21arrdembitemyapp: this is probably true. rebooting.
23:07andyfBronsa: 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:14Bronsaandyf: who knows. I'd say yes.
23:17amalloyandyf: do you have an example of a function that uses a tag like that?
23:18andyfIn 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:19mischanixI asked my girlfriend if she likes Lazy Seqs. She didn't think it was funny.
23:22amalloyshe was probably mad you pronounced seq wrong
23:24mischanixI don't think I'll ever be able to read 'seq' as 'seek'.
23:24andyfamalloy: 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:25andyfamalloy: 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:25amalloyandyf: that's usually a symptom of a careless macro
23:26dbaschI'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:26dbaschdon't know why
23:26amalloyeg, (defmacro foo [x] (with-meta x {:tag Object}))
23:26dbaschgen-class that is
23:27dbaschany thoughts?
23:27amalloyandyf: looks like there's one in the definition of 'case
23:31amalloythat's the only one i can see, in fact
23:31andyfamalloy: Maybe one buried in defrecord somewhere? I'm guessing from some debug print output, haven't seen it yet.
23:32amalloymaybe. it's pretty hard to follow what goes on in deftype
23:34amalloyit looks right, though. on-interface starts as 'MyType, and the code that uses that tag is `(. ~(with-meta target {:tag on-interface}) ...)
23:36andyfI 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:43amalloywow, what on earth is test.generative doing with these :tag forms
23:45testclojanybody 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:46andyfamalloy: 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:46andyf"Question about :tag" from mid-Dec
23:47amalloyandyf: it looks to me like tag->gen has a serious, although probably unrelated, bug as well
23:47amalloythe intent is that you can use arbitrary forms as tags, right, to specify your own generators?
23:48amalloybut...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:48andyfamalloy: I haven't learned, myself. Just passing along pointers to the conversations I've seen.
23:51amalloylast 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:52andyfdirect link to the thread: https://groups.google.com/forum/#!topic/clojure-dev/hRZFuaiB_50