Version 0 of Named Arguments Using Dicts

Updated 2017-10-23 19:52:05 by hypnotoad

The concept of Named Arguments as Dictionaries is to provide an extensible means to extend argument definitions to include rules and allow them to be given in any order, without introducing a major syntax change to proc.

The Tcl implementation is reasonably trivial:

package provide nproc 0.1

proc ::dictargs argdef {
  if {[catch {dict keys $argdef} argnames]} {
    puts $argnames
    error "Argument definition is not a well formed dict"
  }
  set result {}
  append result {if {[llength $args]==1} {set dictargs [lindex $args 0]} else {set dictargs $args}} \n
  foreach {field info} $argdef {
    set argbody [list if {[dict exists $dictargs {@field@}]} {set {@field@} [dict get $dictargs {@field@}]}]
    set map [list @field@ $field]
    if {[dict exists $info mandatory]} {
      lappend argbody else {error "@field@ is required"}
    } elseif {[dict exists $info default]} {
      lappend map @dvalue@ [dict get $info default]
      lappend argbody else {set {@field@} {@dvalue@}}
    }
    append result [string map $map $argbody] \n
  }
  return $result
}
if {[info command ::_proc] eq {}} {
rename ::proc ::_proc
_proc ::proc {name arglist body} {
  set result {}
  if {[lindex [lindex $arglist end] 0] eq "dictargs"} {
    append result [::dictargs [lindex [lindex $arglist end] 1]]
    set arglist [lrange $arglist 0 end-1]
    lappend arglist args
  }
  append result $body
  ::_proc $name $arglist $result
}
}

###
# Named Procedures as new command
###
proc ::nproc {name argdef body} {
  set result {}
  append result [::dictargs $argdef] \n
  append result $body
  ::proc $name args $result
}

And here are some examples of play testing the new rules:

proc standard {subject sender {dictargs {
  mtime {}
  body  {}
}}} {
  set auto_reply [subst {To: $sender
Subject: Re: $subject

Dear $sender,
Thank you for writing us about $subject}]
  if {[dict exists $dictargs mtime]} {
    append auto_reply " on [clock format [clock scan $mtime]]"
  }
  puts $auto_reply
}

puts [info args standard]
puts [info body standard]


# Example
nproc newstyle {
  subject {mandatory 1}
  sender  {mandatory 1}
  mtime   {}
  body {}
} {
  set auto_reply [subst {To: $sender
Subject: Re: $subject

Dear $sender,
Thank you for writing us about $subject}]
  if {[dict exists $dictargs mtime]} {
    append auto_reply " on [clock format [clock scan $mtime]]"
  }
  puts $auto_reply
}

standard {Hi there} {[email protected]} body {Extra garbage}
newstyle subject {Hi there} sender {[email protected]} body {Extra garbage} mtime [clock format [clock seconds]]