On 5/30/05, Zoran Vasiljevic <[EMAIL PROTECTED]> wrote: > > Am 30.05.2005 um 12:23 schrieb Stephen Deasey: > > > > > The other option is -eightbit:flag syntax. It's not perfect, but it's > > better than nested lists and has ~5 years of usage in the ACS behind > > it. > > > > Another try (I can't just let go) ... > > I do not see much sense in trying to keep the Tcl argument list > format under all costs. Give me a good reason why we should do that? > Anyways, we are about to define a new "proc"-type of command > (ns_proc) aren't we? What is the sense then to force ourselves > to the old format? > > Why don't we *extend* Tcl-proc arg-treatment like this: > > {name typecheck ?default_value?} > > This is *not* Tcl-proc compatible but *is* in the spirit of > the language. The "typecheck" above can/will be definitely > a list of one or more elements, depending on the check itself. > The typecheck is *forced*. You must give a type. If you need > no checking at all use "string" which will cover all possiblities. > By *forcing* the type-check, many of the programming > errors and double-checks in the procedure itself can be saved. > > Also, all people needing no extra checking can always use plain Tcl-proc > calls. Others who'd need checking would use exteneded ns_proc syntax. > This is pretty clear and I see no problems with that at all. > > For example: > ns_parseargs {{-retries int 0} {-blockcopy flag} {device string} > args} > > or > ns_proc dosomething {{-retries int 0} {-blockcopy flag} {device > string}} { > # ... > } > > The most natural Tcl-way is to use lists. We've seen that the > desperate try to keep the Tcl-proc syntax leads to too complicated > nested lists which humans are not easily assembling. > So, this is a plain list which is easy to write and read by humans. > > We can evolve typecheck over time to include more elaborate > tests, but a handful of those (string, int, flag, bool, list) are most > useful and complete for about all the needs I can think of > at the moment. > > What is wrong with that (except that it perhaps does not follow > openacs model)?
ns_proc test {{-flag f}} { if {$flag} { ns_log notice ok } } test -flag t ;# ok test -flag true ;# ok test -flag yes ;# ok test -flag 1 ;# ok The result of the expression passed to Tcl's if is converted to boolean so there's no need to use [string is true $x]. The difference between '-flag' and '-flag t' is two characters -- I don't think it's worth it. As I mentioned before, in general I think it's a bad idea to create boolean flags as it makes it cumbersome to call such a proc where the flag is computed. e.g.: if {$x} { foo -flag ... } else { foo ... } It gets really ugly when there are multiple flags. I added boolean flags to the C implementation as there is already existing code which uses them which could benefit from the arg parsing. Regarding the 'oneof' type, maybe what's actually needed is some syntactic sugar? e.g. something like: proc assert_oneof {varname list} { upvar $varname x if {![lsearch -exact $list $x]} { error "assertion failed: $varname must be one of $list" } } proc test {{x foo}} { assert_oneof x {foo bar baz} ... } The disadvantage of extending the proc syntax as you've suggested above is that users are then forced to always provide a type, even if it's just the 'null' type, string. This kind of type checking is likely to be the exception rather than the rule, but I imagine option parsing will be quite common. The ordering of the default argument has changed which is incompatible with what the programmer expects from standard proc usage, even if the mechanical incompatibility does not matter. The oneof check shows that things will get more complicated than simple 'is int', 'is bool' checks. Min and max range checks on integers would be nice, regexp checks on strings would be cool etc... What about applying more than one check to an arg? There would need to be syntax for it as you can't specify the arg more than once as you can specify multiple assertions. Other languages solve this with assertions or pre-conditions and post-conditions, and that feels more like what we're doing here. Tcl *does* have type checking: an integer argument passed to a proc which is then passed to the expr command will cause a conversion failure if the value is 'foo'. The type checking on the proc argument will just cause the failure earlier (and will result in double-checking). What we're catching here are programmer errors. Checking is more urgently required for malicious attacks. You really want to be able to say something like: ns_queryget -assert int -- life 42 It was always in the back of my mind that we needed some kind of unified checking mechanism to handle both procs and ns_queryget (and forms, as in Vlad's nstk). Rather than shoe-horn the type checking of proc into the proc args, perhaps it would be better to use something more direct like the assertion example above? You could imagine various type of syntactic sugar: assert x oneof {foo bar baz} assert { x int y digit } ... Type checking happens at compile time in many languages which makes them better than assertions, but that doesn't apply here. So, how about assertions?