From: Will Duquette Date: April 29, 2004 8:12:01 PM PDT To: snit@lists.wjduquette.com Subject: Snit Reconsidered #2: Delegation Syntax The syntax of Snit's "delegate" statement is intentionally designed to read like English. For example, delegate method insert to myTextWidget delegate method * to myTextWidget except {dump dlineinfo} delegate method append to myTextWidget as {insert end} I've begun to think that this is a mistake, especially now that I'm using a Mac and have been exposed to AppleScript. I've heard of write-only languages; AppleScript is the closest thing I've ever seen to a read-only language. But be that as it may, my real complaint about the current syntax is that it's hard to extend in any obvious way without become impossible. Now, everyone agrees that Snit's delegation model is the coolest thing about it. It seems to me that in Snit 1.0 we should be looking for ways to delegate more flexibly, to more kinds of objects. And to do that we need an extensible syntax. What I propose to do is move from the current English-like syntax to a more typical Tcl option/value syntax, e.g., delegate method .... For example, # Delegate a method to a component delegate method insert -methodof myTextWidget # Delegate all but two methods to a component delegate method * -methodof myTextWidget -exclude {dump dlineinfo} # Delegate a method to a component as a different method delegate method append -methodof myTextWidget -asmethod {insert end} These are equivalent to the statements given above. But also, # Delegate a method to a component as the component itself delegate method textpane -component myTextWidget This is equivalent to Snit's "expose" statement, which really should have been part of "delegate". The "textpane" method maps not to a method of myTextWidget but to myTextWidget itself. Thus, given an object of this type I can say $wid textpane get 1.0 end $wid textpane delete 1.0 end and so forth. Now consider this case: suppose you're using a database extension. It can manage several databases, each with its own name. However, the database name isn't an object; it's just a handle you pass as the first element of all of the database commands, e.g., set mydb [dbcreate] db $mydb add ... db $mydb get ... db $mydb delete ... In short, it's the usual procedural way of implementing an OO API. At present, Snit can't delegate to that. But it *could*: # Delegate a method to a component that's a managed object. delegate method get -component mydb -as {db %c get} What we're saying is, we translate method "get" to a database command by substituting the component's command name into the -as pattern where the %c is. That gives us great freedom. If we had a program which contained a canvas widget, for example, we could conceivably write objects that delegated methods to objects within the canvas itself. These same kinds of considerations apply to the "delegate option" statement. The canvas and text widgets have sub-objects which have configure and cget methods; we should be able to delegate to them as well. Questions For Discussion * Can you think of any other ways we might like to delegate methods or options that Snit doesn't currently support? * Do you think switching to an option/value syntax is an improvement? Or do you think it's a mistake. * If you think switching to an option/value syntax is an improvement, do you like the particular suggestions I made above? Can we do better? Feel free to brainstorm. Remember, we're bound by the vision of Snit as Object Glue that I posted a couple of days ago, not by what Snit does at the moment. Will ------------------------------------------------------------- will -at- wjduquette.com | Catch our weblog, http://foothills.wjduquette.com | The View from the Foothills