#clojure logs

2008-07-28

01:47mebaran151if I have a function in the form of (fn [x] (+ x 1)) or something, is it possible to get its quoted form back
01:50hoeckmebaran151: please explain, do you mean its backquoted form or the functions source code?
01:51mebaran151I meant the src of function
01:51mebaran151what does the backquote do?
01:51mebaran151(I'm still learning Lisp)
01:52shoovera single quote could give you the code as a list: '(fn [x] (+ x 1))
01:52hoeckbackquote and un-backquote are basically abbrevations for list and for eval
01:52shooverand if you put that into a variable with let, you could later eval it
01:53hoeckyou could, but thats considered bad style
01:55shooverok. I was thinking if you did need the code as a list and you also needed it to evaluate, that would be one way. Is there another way you're thinking of?
01:55hoeckmebaran151: instead of writing (list 'a b c 'd) you can write `(a ~b ~c d)
01:56mebaran151I just want to be able to get at the underlying src of a compiled of function just in case
01:56mebaran151I'm writing a little object persistence layer in clojure I've named Oscar, and this might come in handy
01:58mebaran151(Oscar searches creates and removes) or (Object store: creation and retrieval)
01:58hoeckshoover: i guess if you write something like a repl, this is okay
01:59mebaran151I'd basically like to quote an already eval'ed function, but maybe clojure throws away such minor points
01:59hoeckmebaran151: cool, i had the same idea, storing a functions source code (as string) in its metadata
02:00mebaran151the metadata is coming in very handy
02:00shooverClojure emits the source as debugging information during compilation, but I'm not sure how you could access that.
02:00mebaran151it's where I keep all of oscars internal state
02:01hoeckthen it would be nice to browse the source like in delphi or slime
02:01mebaran151yeah that could be nice
02:01mebaran151I thought lisp was all about that whole getting the syntax tree back
02:01mebaran151but I guess the tree has to be cut down at some point
02:02shooverThe tree is available to you in macros, but once those are resolved to function calls, Clojure compiles everything down to Java classes.
02:03mebaran151I see
02:04shooverhttp://clojure.org/lisp goes into it a little bit
02:05shoover... at least the part about how macros get to see the tree and transform it
02:06mebaran151I sort of get macros
02:06shooverThat sort of makes 2 of us :)
02:08mebaran151so here's my idea for an object persistence store in lisp and I'm wondering if you guys have any feedback on the general idea of the design
02:09mebaran151my basic unit is the hash: I derive a database template from it, recursing to define nested templates under it
02:09mebaran151these templates define how I later run the insert statements and do joins and what not
02:10mebaran151I'm trying to make up for the fact I don't have classes to play with, so the next time I try to save an object, it looks in a central ref'ed var and attempts to match the hash given by its keys
02:14shooverWhat would one of these templates look like?
02:15shooverAlso, are you talking about clojure HashMaps or computing a hash using some hash function?
02:17hoeckand what kind of objects do you store, clojure data-structures or any kind of (clojure) object?
02:19mebaran151I'm starting just with hashes
02:19mebaran151the templates are pretty simple
02:20shoovermebaran151: This sounds interesting, but I gotta run. I will be glad to check the log later to see the answers to these questions
02:20mebaran151just a list of mappings of functions to keys to attributes and relationships
02:20mebaran151where I'm stuck is modeling intra db relationships
02:21mebaran151(serializing and retrieving single use hashes is easy)
02:24hoeckmebaran151: what do you mean with 'hashes'?
02:24mebaran151I mean hashmaps
02:24mebaran151I started with ruby where they're called hashes
02:24hoeckahh, okay
02:24mebaran151I'd like to eventually do any clojure object
02:25mebaran151the goal would be that I provide sane templates to get you started but a user could smack it around if they wanted via customizing the archetype I slyly stored in the metadata, which I have to admit, was an inspired invention
02:27mebaran151I always hated how rigid activerecord felt, but I Hibernate never had any dynamicness, and besides, neither project has as great a name as Oscar
02:29hoeck:) i've never used any (object) persistence system, so can you explain to me what are the templates for and how such a persistence system works??
02:31hoecki was always pretty satisfied with lisps loading their own code and data (at least in a small scale)
02:32mebaran151well I'm expecting a lot of objects on this scale
02:32mebaran151in this app
02:34mebaran151I basically am planning to allow designers to specify a template against which their objects will be persisted: within the template you would provide either symbols or functions which I would run over the hash and their results would be inputted properly in the database
02:35mebaran151(hash in this case meaning hashmap)
02:38mebaran151it would record which keys were of interest and whether to serialize them to the filesystem or to sql
02:40hoecki see, have you any simple use-case for explanation to me?
02:40mebaran151well you have a lot of users
02:40mebaran151each has a profile per se
02:41mebaran151and can have a profile picture
02:41mebaran151you wouldn't want to put the profile picture in the database
02:41mebaran151so that's a simiple nested requirement
02:42mebaran151you should have a table for the flat information about users like his name and hashed password, andprobably have a separate table for profile data while keeping his jpg in a hash somewhere on the file system
02:43hoeckahh, cool, i got it!
02:43mebaran151*jpg in a file somewhere on the file system
02:43mebaran151now let's get a bit more complex
02:44mebaran151users have profiles in whcih they can customize the fields, like add favorite soups or something
02:44mebaran151building a new column for that would be sort of silly, esp if only one user ever declared himself to have a favorite soup
02:44mebaran151so that part of the hash is probably best serialized to the file system
02:46mebaran151that's why I think a hybrid approach is best for a dynamic language like lisp where some objects might not look exactly like the rest
02:48mebaran151this profile might also be modeled as sequence of sections or something
02:48hoeckwhat is the non-hybrid approach?
02:48mebaran151just using SQL for everything
02:50jykrdhi
02:50mebaran151I'll be back in a moment
02:50hoeckjykrd: hi
02:52jykrdSo I'm using (take n (repeatedly (fn [] (. (new BufferedReader (new InputStreamReader (. *param* getInputStream))) readLine))) to pull in lines
02:52jykrdbut I don't want to use take n
02:53jykrdI want it to keep on taking values until it his a nil, and then stop
02:53hoeckthen use (take-while identity ..)
02:54jykrdwhat does the identity part mean?
02:54hoeckidentity is a function
02:54hoeck(identity 1) -> 1
02:54hoeck(identity nil) -> nil
02:54jykrdright, so basically take-while (not-returning-nill)
02:54hoeckand serves in take-while as a predicate
02:54hoeckexactly
02:55jykrdoh, so actually write identity
02:56hoeckyou could also write it more verbose (take-while (fn [element] (not (= nil element))) ...)
02:57jykrdright
02:57jykrdidentity sounds easier
02:58jykrdI'm getting strange results here now
02:59jykrdi do this to make processes:
02:59jykrd(import '(java.io BufferedReader IOException InputStreamReader))
02:59jykrd(defn $ [p] (.. Runtime getRuntime (exec (str p))))
02:59jykrdthen this to get input on it:
02:59jykrd(defn $in [n obj]
02:59jykrd (dorun (map println (take-while identity
02:59jykrd (repeatedly (fn [] (.
02:59jykrd (new BufferedReader (new InputStreamReader (.
02:59jykrd obj getInputStream))) readLine)))))))
02:59jykrd(sorry 'bout the flood)
03:00jykrdand when I do a ($in 10 ($ "ps -ef")) I get strange results
03:00jykrddoing it repeatedly returns different sections of the results
03:00hoeckyou can use lisppaste for bigger code chunks
03:00jykrdrather than all of it, but perhaps the output has escape characters?
03:01hoecki guess its because you create a new BufferedReader each time you request a line
03:02jykrdhmm
03:02jykrdok, so I could chop it into smaller functions
03:04hoeckor put the reader creation into a let
03:08hoeck(let [r (new BufferedReader (new InputStreamReader ..))] (take-while identity (repeatedly #(.readline r))))
03:09jykrdyup
03:10jykrdthat works
03:10jykrdgood eye
03:11jykrdso #() is short for (fn [] ())
03:12hoeckyes
03:12jykrdall this new syntax
03:12hoeckyes, kind of
03:13jykrdand .method
03:13jykrdthats new to me
03:13jykrdI remember it was talked about
03:13hoeckare you using svn or a release from the clojure site?
03:13jykrdsite
03:14jykrdbut that all works
03:14hoeckin svn there is also (Object. ..) instead of (new Object ..)
03:14hoecki think its in the release too
03:18jykrdyea, that works here
03:19jykrdso I've got it to do system commands.. so I might be able to do some system scripting clojure once I figure it out :)
03:23jykrdwhat to make though.. maybe yet another backup tool
03:26hoeckjykrd: fetching clojure sources would be cool :)
03:27hoeckjykrd: but on shell-level, it wouldn't be too portable
03:32jykrdhoeck: yea, I guess that's why there isn't much system scripting done with java or it's derivitives
03:34hoecki'm going to work, bye
03:34jykrdlater, thanks for the help
03:35hoecknp
03:38jykrdlisppaste*
03:38jykrdlisppaste8
08:05rhickeyjykrd: you might want to check out line-seq
08:17jykrdrhickey: ok
08:47jykrdYea, that's smoother
08:48rhickeyfind-doc is your friend - e.g. (find-doc "line")
08:50jykrdWhy is is that, if i wrap the line-seq with a (map println(...)), then it puts a nil on the front of each line?
08:51Chouserjykrd: println returns nil, which the repl prints
08:51rhickeymap is functional and lazy and println is a side effect. To get side-effects to happen you need some form of 'do' - (dorun (map ...
08:51jykrdoh
08:52jykrdohhoh
08:53jykrdI never knew. That's been getting me for a while. That should go somewhere in the wiki.
08:53rhickeymap returns a sequence of the values of the function you call, which as Chouser said, is nil in this case. You really don't care about those values, only about the side effects
10:05cemerickChouser: I'm suddenly feeling very uneasy about the underscore name mangling
10:05Chouserreally? why's that?
10:08cemerickIt's a totally workable approach technically, but putting myself in the shoes of someone who doesn't necessarily know what gen-class is or how it works, it looks like a serious wart.
10:09Chouserhm. I have actually drifted the other direction. When actually looking at the example namespace I cobbled together, I thought the underscores looked quite nice.
10:09cemerickYou'd like to be able to point someone at a namespace, and say, "here's the implementation of the same-named class", period. With this, the most common FAQ will be, "What's with all of the underscores?" "Oh, don't worry about that."
10:09rhickeyWhen thinking about the namespace relationships last night, I thought perhaps ClassName-methodname might be best
10:09Chouser...with the possible exception of underscores when calling the functions directly.
10:09cemerickrhickey: you mean a namespace per method?
10:11rhickeyif you are gen-ing org.myns.Foo, under the Java rules the package is org.myns, and thus the Clojure namespace should be org.myns too. This would make it easy to gen and implement several fns in a single file
10:12Chouserhm!
10:13Chouserseveral classes in a single file?
10:13cemerickrhickey: That's actually something like what I was thinking of over the weekend, except instead of ClassName-methodname, have a map of method names and fn's def-ed to each ClassName,
10:13rhickeyso make a org/myns/myns.clj with Foo-doThis, Foo-doThat fns. org.myns.Bar could be defined in the same file, or have org/myns/myns load Foo.clj and Bar.clj is you want them separate
10:14rhickeycemerick: using a map requires a special defing form
10:15ChouserFoo-doThis is still probably more terse than "public static final doThis"
10:16cemerickrhickey: Not sure I follow; wouldn't it be simply (def ClassFoo {:toString (fn [this] "blah")}), etc?
10:18rhickeycemerick: if you do that then redefining/testing single functions becomes ungainly, and you lose dynamic per-thread rebinding of methods
10:19rhickeyone of the cool things about gen-class is that Java classes inherit Clojure goodness, like that rebinding capability, or transactionality if state is a Ref
10:21cemerickI'd say that rebinding probably isn't a very common use-case in connection with gen-class impls -- and, if someone wanted to support that, it'd be a piece of cake to have the real impl of a function in a val (which can be rebound) that is invoked from within the class impl map.
10:22rhickeyJava methods can also be multimethods
10:23rhickeycemerick: true, it's hard to know what the use-cases are yet. Per-context logging is particularly useful
10:24cemericksure, and the class impl map could dispatch to a multimethod elsewhere, too. My only point is that, right now, getting the simplest stuff done via gen-class requires just as much work/mental overhead/understanding of gen-class as the the most ambitious stuff.
10:25rhickeyif these uses become common you'll have to write 2 functions, the second of which will have ad-hoc names
10:25rhickeyspeaking of names, the anonymous fns in the map won't have useful ones during debugging
10:27rhickeyI guess it seems to me like you could have a (defimplementation ClassFoo .. that looks like what you want but generates real named fns
10:27cemerickvia the ClassFoo-methodfoo naming pattern, you mean?
10:27rhickeyright
10:29rhickeyall I see the map saving you is repeating the ClassFoo- prefix, at the cost of making the class definition atomic, and thus not very Clojure-like
10:29cemerickYeah, that seems like it'd be OK.
10:30cemerickWell, in the nexus of Java and Clojure (gen-class), I'm happy to sacrifice a little bit of clojure-ness in order to minimize the appearance of magic. Perhaps we can have our cake and eat it too, though.
10:32cemerickYeah, I'll +1 the ClassFoo-methodname notion, with the defimpl macro.
10:34lisppaste8rhickey pasted "method def options" at http://paste.lisp.org/display/64357
10:37lisppaste8rhickey annotated #64357 with "defimpl" at http://paste.lisp.org/display/64357#1
10:40rhickeya nice thing about the defimpl macro is you needn't put everything in there, if you have a couple of multimethod methods you can define just them a la carte
10:40hoecki would prefer the (defn Foo-doThis [] ..) form
10:40rhickeyhoeck: me too, defimpl is optional
10:41rhickeybut I can understand its appeal
10:44hoeckmaybe it is because of my long exposition to emacs-lisp, where usually function-names have a common beginning
10:58ChouserCould defimpl could be rolled into genclass?
10:59rhickeyChouser: I think it's important to remember the dual static/dynamic nature of genclass.
10:59ChouserI guess it would then have to do namespace magic as well, but you'd get something that feels more like a "normal" class definition.
10:59rhickeyor do you mean put the macro into genclass.clj?
10:59Chouserno, you understood me.
10:59rhickeyChouser: normal class definitions suck, as they are static
11:00ChouserI understand, but it would actually be normal, just give the illusion. If that's something you're specifically trying to avoid, then so be it.
11:00Chousers/would actually/wouldn't actually/
11:01rhickeyI think it would be a shame if you had to rebuild your Java when you changed your Clojure implementation code
11:01rhickeymaybe others disagree
11:02rhickeyI like generating a servlet stub once and forgetting about Java
11:02Chouseryes, I agree. Well, that is I'm entirely willing to agree. I'm not arguing against that, as you could still use the (def Foo-doThis) form for rebinding.
11:02Chouserah, nevermind, I see what you're saying.
11:03Chouserthere's a usage style difference here between gen-and-save-class and gen-and-load-class.
11:04ChouserFor the -load- case, I wouldn't at all mind having the definitions optionally embedded in the gen-class statement.
11:04rhickeygen-and-load-class has such marginal utility, IMO
11:05ChouserIn fact it's be nice to not have to switch around namespaces and such. Dynamic re-binding would still be supported, but having the "canonical" version of your implementation in your gen-class statement wouldn't hurt anything.
11:05rhickeymost of the time you genclass it's because some Java code needs to know the names
11:06Chouserwith gen-and-save-class it makes a lot of sense to have it in a separate -gen.clj file that you very much leave alone, and would want any implementation inside.
11:06cemerickwe use gen-and-load-class specifically to make it possible to at least co-locate the gen-class definition near the impl
11:07cemerick(see the save-gen-class macro in my genbean post from Friday)
11:07rhickeywhat I foresaw, which may not have come to pass, was that gen-class wouldn't normally be enumerating the members, given that they come from superclasses or interfaces
11:08rhickey(gen-and-save-class FooServlet :extends HttpServlet)
11:08Chouserwhen a gen-interface exists, that may become more true.
11:08rhickeywhy would I want to stick method defs in that?
11:09Chouserhm, it looks like my one real-world use of gen-class is a gen-and-load-class that could probably now be replaced with proxy, since super-calls are now supported there.
11:10ChouserMaybe my experiences are much help in this conversation. :-)
11:10Chouseraren't
11:10Chousersheesh
11:10cemerickrhickey: well, you'd certainly want to add methods to class definition -- not in a HttpServlet context, but elsewhere, that's very desirable
11:10cemerickwhether the impl defs are inline with the gen-class is another story
11:12rhickeycemerick: I understand that when they are not inline, you have to repeat the method names, like in c++ headers/source
11:12cemerickrhickey: very tangentially to this conversation, I'd urge you to not over-focus on the web development use-cases. I don't think you have to date, but how to hook into a servlet container is a very narrow context.
11:13rhickeycemerick: I'm not, enclojure is the biggest consumer of genclass from my perspective - many of the features, including adding members, came from their use cases
11:15cemerickName repetition sucks, but dislocation of source code sucks more. That's why we have save-gen-class, and that's also why I'm sure I'll be writing something similar so one form can utilize defimpl and spin off a gen-and-save-class class at build time.
11:15rhickeyOTOH, having done C++/Java/C# for 20 years, I often miss headers when in C#/Java, especially from a build dependency standpoint. Thus I'd emphasize interfaces whenever adding member so you get decoupling from implementation changes
11:16rhickeycemerick: agreed, but they are 2 different things. save-gen-class doesn't need the impls inline
11:17cemerickrhickey: true, but that's only the case because of how gen-class works. All of our gen-class usages at the moment are 100% static, so I'd be perfectly happy dropping impls into it.
11:17cemerickI'd emphasize "at the moment" :-)
11:18rhickeyok, let me think about it
11:18cemerickFWIW, that's very, very low on my personal wish list. Nailing down the namespace/lib/gen-class-naming issues within the current architecture is far more important, IMO.
11:22rhickeycemerick: I think the org.myns.Foo -> org/myns/myns.clj with Foo-doThis, Foo-doThat conforms to the new system, and Steve seems to be moving along with lib
11:23rhickeyjust need to do the genclass changes
11:24cemerickrhickey: Sounds good, thanks. I've not kept up with Steve's progress in svn, though; been distracted elsewhere.
11:25cemerickwe're still holding at r937 until that's stabilized
11:25Chousergenclass's arguments would remain unchanged, right? Just the namespace name and function names would change?
11:28rhickeyChouser: right. I'm thinking now the file name should still org/myns/Foo.clj, but the code in it will be in org.myns. This way you can still get per-class load-on-demand
11:29rhickeyChouser: I think you can just change your patch from _ to ClassName-
11:29Chouseryou want to do the changes this time, or do you want to wait again for me to fumble my way through?
11:29Chouserah. I'll try it.
11:30cemerickrhickey: would it be bad for the load-on-demand to load /org/myns/myns.clj and /org/myns/Foo.clj? Having both options work automatically would be a plus, I think.
11:30rhickeyI'm finishing up multimethod dispatch-value preferences
11:31rhickeycemerick: what happens when you genclass multiple classes in the same ns, independently?
11:32rhickeywould load myns.clj more than once
11:32cemerickrhickey: ah, I'm presuming that lib is available
11:33rhickeycemerick: yes, lib will be rolled into Clojure soon, then genclass will use it
11:34cemericknifty
11:50Chouserhuh. The class doesn't exist yet, so I can't ask it for its simpleName. I guess I'll just chop off everything thru the last "."
11:50rhickeyChouser: right
12:02Chouserrhickey: as a general rule, do you prefer diff/patch files, or whole replacement files?
12:04rhickeyChouser: diff files as attachments are best
12:04Chouserok
12:05cemerick(def a (new java.util.ArrayList<String>)) => error; is there a different incantation for referring to parameterized classes, or is this not yet supported?
12:05Chouserno need to provide the param class
12:05Chouser(java.util.ArrayList.)
12:06cemerickright, no reification
12:07cemerickI've been targeting 1.4 forever; I need to adjust my expectations :-P
12:18Chouserhttp://n01se.net/paste/cIN?pretty=no -- genclass-classname.patch
12:23Chouserexample usage: http://n01se.net/paste/9g3J
12:59rhickeyChouser: cool, thanks! I don't understand:
12:59rhickey; the follow would fail because when we have a namespace and class
12:59rhickey; named the same, the "/" syntax is ambiguous?
12:59rhickey;(prn (net.n01se.TestObj/makeone 9))
12:59Chouseroh, those are left over from the last patch. I haven't tested them with this one.
13:00Chouserindeed, that works now.
13:01rhickeycould you please post patch to group, with diff as attachment? (can't take contribs from pastes) - thanks
13:01Chousersure, just a sec.
13:12Chousersent
13:15ChouserIt's interesting that this removes the class/method vs. namespace/function ambiguity.
13:15rhickeyyes
13:15Chousersince now its package/simpleclass-function for the latter case.
13:29rhickeyChouser: patch applied, thanks
13:30Chouserof course just as you said that I was realizing I failed to update the doc string.
13:31rhickeyah
13:37Chouserwould you prefer to have your existing test code in (comment) at the end? or mine, or nothing?
13:38rhickeysomething that works would be good :) mine doesn't
13:47Chouserwell, I posted a patch to be applied on top of the old one. Of course feel free to edit to your preference.
13:53rhickeyChouser: that's up, thanks again
13:53Chousersure, sorry for the stutter. :-)
13:53rhickey:)
13:55Chousersounds like a good life
13:57rhickeyactually, the multimethod enhancements are huge, once people figure out what they can do with them
13:59ChouserI believe you. It's fascinating to me how many things are (apparently) lumped into the OO class and hierarchy model that I had never conciously separated.
13:59ChouserClojure seems to be aggressively deconstructing OO.
13:59rhickey:)
14:00rhickeyCL's generic functions were an eye opener for me, after so many years of the C++ system
14:00Chouserwhy should the namespace be a class? why should the class of the first argument be the only dispatch criteria? Why should the heirarchy control inheritence?
14:02ChouserI worked for a couple year in a C++ codebase that had custom-built a sort of runtime-resolved two-argument multi-method system. The implementation was unimpressive, but the idea fascinated me.
14:02ChouserSo when I read onlisp, I was ready for CLOS. I still haven't used it (or Clojure multimethods) yet.
14:03rhickeyNow I think objects are a trivialization that is holding us back, and many new languages are content to stick with the same-old worldview
14:04ChouserBut anyway, this is a good system. If having folks writing two-line patches to genclass or architecting lib.clj frees you up to keep thinking through the tricky stuff, then we all win.
14:04rhickeyGreenspun's 10th is true, once the systems get large you need the flexibility of Lisp, and end up implementing it ad-hoc
14:05ChouserI don't know how it'll help you feed your family though. I hope they all like ice cream.
14:06rhickeyChouser: thanks
14:08ChouserQt is sort of an attempt to fix some of the problems metnioned in that paper.
14:09rhickeyYes, RougueWave, boost et al all moved the idea forward in subsequent years
14:10ChouserBut it's amazing the amount of work they've done to implement signals/slots in C++. A somewhat naive implementation in a dynamic language like JavaScript took only a couple dozen lines.
14:11rhickeyChouser: exactly
14:59kotarakis it possible to assign doc strings to multimethods?
15:04Chouser(defmulti #^{:doc "foo does foo stuff"} foo identity)
15:05kotarakBut what, when the docs actually depend on the defmethod part?
15:05Chouserah. hm.
15:06ChouserHow would you look up the doc on a defmethod?
15:06rhickeykotarak: there should be a generic way to describe what a multimethod does. A multimethod is an open set, so it better represent an abstraction of some sort. Individual methods should all be implementations of that abstraction.
15:07rhickeyi.e. the same way you can read the docs for an interface and use it
15:07kotarakI thought about something like: (defmulti foo) (defmethod foo :a "bla" ...) (defmethod foo :b "blub" ...) (doc foo) -> ":a:\n bla\n:b:\n blub"...
15:09kotarakrhickey: the problem comes from my monad adventures. There you have a bind function, which takes a monad and a function which does something to the monad returning another monad. But how this is actually established depends on the actual monad.
15:10kotarakBut maybe I should do it differently.
15:10kotarakJust because this is done like that in Haskell, it's not necessarily a good idea to do it like that in Clojure.
15:11rhickeya user of a multimethod needs for there to be a single logical abstraction behind it - they shouldn't need to know or care what the methods are
15:14ericthorsenchouser: Sorry to have to ask...but where are the archives of this chat room?
15:15Chousernot a problem: http://clojure-log.n01se.net/
15:17rhickeyThat should probably go in the login banner on the IRC - logged at: ...
15:17ericthorsenthx
18:51shooverAlong the lines of lisp features and thinking differently than mainstream languages, I'm curious if there's any interest in a CL-like condition/restart system to allow error handling directives to be established at a higher level without unwinding the stack.
18:51shoover I know at times my C# methods get bloated in order to wrap all the error situations (or I have to pass additional arguments down the stack). Is it too complicated, too slow, does anyone need it?
18:52slavashoover: restarts are very handy and lead to a whole new way of thinking about error handling
18:57shooverslava: It definitely seems that way. On the other hand, with CL's handler-case, handler-bind, restart-case, invoke-restart, and unwind-protect, there's more to get the mind around than good old try/catch. I'm wondering if those who have used restarts find them that useful in practice.
18:57slavaI do
18:57slavaI wouldn't want to do serious programming in a language without them.
18:58shooverWow, that's a strong statement. You must not use a lot of languages for serious programming!
19:05rhickeyThe recommended pattern for Clojure is to dynamically bind a handler fn at a higher level - the lower level code can call it in order to get alternative values etc, the handler can possibly handle, or throw if no alternative
19:06rhickeyone way to look at the CL condition system is as a special purpose set of dynamic functions in a language that otherwise doesn't have them
19:07rhickeydynamic functions + exceptions let you build whatever you want
19:07slavathe real benefit of having conditions comes when they're actually used pervasively by the standard library
19:09rhickeymaybe, I don't know that there is enough evidence to support that, and that conditions are needed to supply those benefits
19:10rhickeyany high/low level coordination has to be pretty carefully orchestrated, I think it is more likely to work when you own both levels
19:20shooverrhickey: Interesting, thanks. I'll chew on this. All else aside, binding a dynamic function is easier to remember how to use.
19:40shooverOf course, now that you mention it it comes flooding back that dynamic vars were made for this context. If someone wanted the handler-bind, invoke-restart terminology I think it could be built on binding and find-var
19:43rhickeyshoover: right, and defns end up in vars already, so no find needed. A fn need only say: if I get stuck I'm going to call handle-unparseable-input if it is bound, and use its return if not nil, and ignore if nil.
19:45Chousergen-interface would really be gen-and-save-interface and gen-and-load-interface?
19:45Chouseror "would also have" I guess.
19:47rhickeyChouser: I'm trying to imagine a scenario for gen-and-load, who could be the consumer of such an interface?
19:47rhickeybut generally, yes, a code generator and then helpers that use the code, like gen-class
19:48Chousergen-and-load still creates the named class, just not the class file. So any combination of proxy and gen-and-load-class could use it.
19:49rhickeyChouser: I guess more generally, if you proxied/loaded an interface you just made up, who could use it?
19:50rhickeythe logic for gen-and-load-class was that other Clojure code could new instances by name
19:50rhickeyinterfaces are contracts between independent pieces of code
20:33Chouserdoes gen-interface need to supported nested types?
20:33ChouserI assume it should at least support constants.
20:52rhickeyChouser: no, interface constants are not something I want to support, nor nested
21:53hashendgameI'm trying to write a def- macro that is identical to def, but adds :private true to the metadata (similar, I think, to defn- vs defn). My best attempt is at http://pastebin.ca/1085831 , but (def- woot 3) gives me a "second arg to def must be a Symbol" error.
21:56ChouserI think you want the with-meta to happen when your macro is called, rather than being put into the expansion.
21:56Chouserdid you look at how defn- is defined in boot.clj?
22:00hashendgameI am now. Looks like the with-meta gets evaluated at call time.
22:04hashendgamehttp://pastebin.ca/1085839 has a working version, for those interested.
22:05hashendgamethanks Chouser
22:05Chousersure, glad you got it working.
22:35Chouserusing real classes and getInternalName for :extends means all your interface classes must be *loaded* before you can gen your derived class?
22:39rhickeyIt seems so
23:21Chouserbut by using a real classes you can take advantage of imported class names.