This package defines a new command object type "feather::curried" and a command "feather::curry" to create objects of that type.
[feather::curry]
feather::curry <command> ?<args> ...?
command argument
specifies the command to invoke when the curried object is invoked and the
args are the arguments to pass to command.
Currying of curried objects is optimised to improve the performance. Rather than embed curried objects inside one another they are expanded out.
Currying creates a command which takes N-k arguments by encapsulating a command
which takes N arguments with k arguments. This is similar to how
[list] is used to build up callback scripts.
fileevent $channel readable [list AsyncRead $channel] button .b$i -label "Button $i" -command [list InvokeButton $i]
The curried object has the following advantages over the list approach.
[eval].
[eval].
Creating an object command is very easy. Obviously as you have no control over the name that the object gets this will not work when the name is important, e.g. for widgets.
namespace eval objects {
proc ctor {args} {
# Create and initialise some instance data.
# $self 'points' to the instance data.
return [feather::curry [namespace current]::methods $self]
}
proc methods {self method args} {
# Use $self to access the instance data.
switch -- $method {
"print" {
puts "$args"
}
}
}
}
set object [objects::ctor x y z]
$object print 2 3
Doing functional programming.
proc square {x} {
expr {$x * $x}
}
proc composer {f g x} {
$f [$g $x]
}
proc compose {f g} {
# returns a function equivalent to [$f [$g $x]]
return [feather::curry composer $f $g]
}
set quad [compose square square]
It supports the following interfaces.