Documentation
Not logged in

Copyright (C) 2009-2010, Trevor Davel <twylite AT crypt DOT co DOT za>
See the file "LICENSE.txt" (Tcl/Tk License) for information on usage and redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.


control::arglist 1.x

Overview

Enhanced arglist handling with support for optional parameters anywhere in the arglist.

[niceargs] is a proof-of-concept for allowing optional and variadic parameters anywhere in the arglist of a proc, anonymous proc, method, etc. Currently Tcl does not support the case where there are required parameters to the right of optional parameters, nor any parameters to the right of the variadic 'args'.

My original concept is discussed in TIP: Higher-order functions in Tcl, and appears to be similar to Wish #106 in the Tcl 9.0 WishList. This implementation is also compatible with TIP #288 which proposes to allow 'args' anywhere in the formal arguments of a proc.

Ideally the functionality of [niceargs] should be integrated into the Tcl core and applied to all argument handling.

Quick reference

proc dostuff {*}[niceargs {arglist} {body}]
set anonproc [niceargs {arglist} {body}]
apply $anonproc arg1 arg2

Example of use

  package require control::arglist 1.0

  # test a b ?c? ?d? ...
  proc test {a b {c 1} {d 2} {args}} {
    return [list $a $b $c $d $args]
  }
  
  # range ?from? to ?step?
  proc range {*}[niceargs {{from 0} to {step 1}} {
    set out {}
    for {set i $from} {$i < $to} {incr i $step} {
      lappend out $i
    }
    return $out
  }]

  # [proc] replacement that uses an enhanced arglist
  proc eproc {name arglist body} {
    uplevel 1 [list ::proc $name {*}[niceargs $arglist $body]]
  }

  # range ?from? to ?step?  
  eproc range {{from 0} to {step 1}} {
    set out {}
    for {set i $from} {$i < $to} {incr i $step} {
      lappend out $i
    }
    return $out
  }
  
  # hmac hashalg ?truncateBits? key value
  proc hmac {hashalg {truncateBits -1} key value} {
    # hmac implementation goes here
  }
  
  # hmac-sha1-96 key value
  interp alias {} hmac-sha1-96 {} hmac sha1 96

  # mylsearch ?-optname value ...? list pattern
  proc mylsearch {args lst pattern} {
    set opts $args
    # ...
  }

Testing

A comprehensive test suite is available, using the Tcltest framework.

Known issues

None at this time

Performance

A pure-Tcl implementation is reasonably fast due to the use of [switch] and dynamically rewriting the body. Handling args is relatively more expensive though.

  proc testtcl {a b {c 1} {d 2} {args}} {
    return [list $a $b $c $d $args]
  }

  # % time { apply {{} { testtcl a b }} } 100000
  # 1.56 microseconds per iteration
  # % time { apply {{} { testtcl a b c d e }} } 100000
  # 2.03 microseconds per iteration
  proc testnice {*}[niceargs {a {b 2} c args {d 3}} {
    return [list $a $b $c $d $args]
  }]

  # % time { apply {{} { testnice a b }} } 100000
  # 2.19 microseconds per iteration

  ### Handling args is expensive:
  # % time { apply {{} { testnice a b c d e }} } 100000
  # 4.21 microseconds per iteration