I am experimenting a bit with Snit, to see how it could be used to
wrap certain numerical/mathematical/...
functions and provide a more convenient interface.
Two things I am wondering about are:
- Is it possible to define new methods for a particular Snit object
(after it has been created)?
- Is it possible to redefine an existing method?
The reason I ask, is that it would be very convenient to have, say, a
type that offers
one or more integration options and then define the function to be
integrated per object.
Something like:
snit::type numeric {
method integral {a b} {
}
method f {x} { puts "This is a dummy!" }
}
numeric create func
func define f {expr {$x*exp(-$x)}}
puts "Integral: [func integral 1 3]"
Making a new class/type for each function you want to integrate would
be inconvenient.
Regards,
Arjen
HTH
Helmut Giese
Aha, so that is what a "mixin" is - I knew the term from the
discussion on the various OO systems, but I am fairly unfamiliar
with OO as such.
Well, it is useful to see how XOTcl would deal with this. Thanks
for the tip.
Regards,
Arjen
You technically can, but it's not something Snit supports well (see below).
> - Is it possible to redefine an existing method?
>
> The reason I ask, is that it would be very convenient to have, say, a
> type that offers
> one or more integration options and then define the function to be
> integrated per object.
> Something like:
>
> snit::type numeric {
> method integral {a b} {
> }
> method f {x} { puts "This is a dummy!" }
> }
>
> numeric create func
> func define f {expr {$x*exp(-$x)}}
>
> puts "Integral: [func integral 1 3]"
>
> Making a new class/type for each function you want to integrate would
> be inconvenient.
You can define procs in the relevant namespace to achieve this. (You can
also use lambdas).
package require Tcl 8.5 ;# required
package require snit 2.2 ;# may work with earlier
# A function environment
snit::type funcenv {
constructor {} {
# Make things nice for expr
namespace eval $selfns\::tcl::mathfunc \
[list namespace path $selfns]
}
# Define a function:
# env define f x y ... = expression
method define {name args} {
set body [list expr [lindex $args end]]
set params [lrange $args 0 end-2]
proc $selfns\::tcl::mathfunc::$name $params $body
return $name
}
method apply {f args} {
$selfns\::tcl::mathfunc::$f {*}$args
}
}
snit::type numeric {
component env
delegate method define to env
delegate method * to env using "%c apply %M"
constructor {} {
install env using funcenv $self.env
}
method interal {a b} { ... }
}
numeric create func
func define f x = {$x*exp(-$x)}
func f 1
func define g x = {$x-f($x)}
func define pi = acos(-1)
...
In many ways this is a nice solution -- the funcenv is a nice general
abstraction for function symbols. On the other hand, the delegation is
rather magical and I suspect the rewrite required involves some
performance impact. I will wikify this shortly.
-- Neil
Actually, for the given example, mixins are not needed. In XOTcl
allows to define object specific methods via "proc".
Class numeric
numeric method integral {a b} {
}
numeric create func
func proc f {x} {expr {$x*exp(-$x)}}
Mixins can be defined in XOTcl per-class (for all instances of a
class) or per-object. Mixins are used to add/remove dynamically a set
of methods to classes or objects. It is certainly possible to define
mixins with only one method ("f" in the example). Mixins are in
particular useful when the same set of methods should be modeled
together and added to several e.g. objects without the need to
duplicate code.
G. Neumann, U. Zdun: Enhancing Object-Based System Composition
through Per-Object Mixins, in: Proceedings of Asia-Pacific Software
Engineering Conference (APSEC), Takamatsu, Japan, December, 1999
http://nm.wu-wien.ac.at/research/publications/xotcl-mixin.pdf
G. Neumann, U. Zdun: Implementing Object-Specific Design Patterns
Using Per-Object Mixins, in: Proceedings of NOSA`99, Second Nordic
Workshop on Software Architecture, Ronneby, Sweden, August, 1999 .
http://nm.wu-wien.ac.at/research/publications/xotcl-objpattern.pdf
Concerning your first questions:
- In XOTcl it is possible to define new methods on the object and
class level at any time (i.e. after creation)
- in XOTcl it is possible to redefine existing methods both on the
object or on the class level at any time.
Just tested your solution in a small and very simple example and it
works nicely.
Thanks (also for the two references)
Regards,
Arjen