Expanding the Expansion prefix - example 1

FM This page is to illustrate some of the proposals made in the expanding the expansion prefix page. Please refer to this page to know what this subject is about. This changes could be done in TCL 10.0, since TCL 9.0 is already out.

Here I use some prefixes as they could be configured :

  • In the proc command : proc {NAME_PREFIX}ProcName {ARG_PREFIX}Arg_list {BODY_PREFIX}Body
    • {NAME_PREFIX} will indicate the type of return value of ProcName
    • {ARG_PREFIX} will indicate a specific parser for the argument list (here, we will just imagine an {typed_args} prefix that allows us to specify the type of each arguments and checks for their type correctness)
    • {BODY_PREFIX} indicate how to interpret the body (here, we will just use the {=} prefix to denote that the body has to be taken as a mathematical expression).
  • In the expr command :
    • I had imagined a multiline expression parser, where each expressions are separate by semi-colonn ; (like in TIP 282)
    • I had configure a construct : {type}var = value to assign value to the variable var along the type type
    • I had used an definition of list in expr, saying that, (1,2,3) is in expr what [list 1 2 3] is in Tcl knowing that « 1,2,3 » is the argument list of a function.
    • I had define the {*} expansion prefix operator to return an expr list. aka : min({*}{1 2 3}) is equivalent to min(1,2,3)
    • I had nested a {type} prefix with expansion prefix {*}, so that {{type}*}(a,b) is made equivalent to {type}a, {type}b
    • I had generalized the assignation operator so that a,b = 1,2 is equivalent to a=1;b=2 (it's a kind of lassign in expr).
    • I had nested two expansion operators {{*}*} to denote double-expansion, so that {{*}*}((1,2),(3,4)) gives ({*}(1,2),{*}(3,4)), then (1,2,3,4)

Then, we can write :

# matrix determinant
proc {double}determinant {typed_args}{
    {matrix[3x3]}M
} {=}{
    {{double}*}(a, b, c, d, e, f, g, h, i) = {{*}*}$M;
    $a*$e*$i + $b*$f*$g + $c*$d*$h \
        - ($g*$e*$c + $i*$d*$b + $h*$f*$a)
}

# vectorial product
proc {vec[3]}v_prod {typed_args}{
    {vec[3]}A
    {vec[3]}D
} {=}{
    {{double}*}(a,b,c) = {*}$A;
    {{double}*}(d,e,f) = {*}$D;
    ($b*$f-$e*$c, $c*$d-$f*$a, $a*$e-$d*$b)
}

# dot product
proc {double}dot_product {typed_args}{
    {vec[3]}A
    {vec[3]}B
} {=}{
    {{double}*}(a1, a2, a3) = {*}$A;
    {{double}*}(b1, b2, b3) = {*}$B;
    $a1*$b1 + $a2*$b2 + $a3*$b3
}

# tensorial product
proc {matrix[3x3]}tensorial_product {typed_args}{
    {vec[3]}A
    {vec[3]}B
} {=}{
    {{double}*}(a1, a2, a3) = {*}$A;
    {{double}*}(b1, b2, b3) = {*}$B;

    (($a1*$b1, $a1*$b2, $a1*$b3),
     ($a2*$b1, $a2*$b2, $a2*$b3),
     ($a3*$b1, $a3*$b2, $a3*$b3))
}

# Lie product
proc {matrix[3x3]}lie_product {typed_args}{
    {vec[3]}A
    {vec[3]}B
} {=}{
    {{double}*}(a1, a2, a3) = {*}$A;
    {{double}*}(b1, b2, b3) = {*}$B;

    ((        0        , $b1*$a2 - $a1*$b2, $b1*$a3 - $a1*$b3),
     ($a1*$b2 - $b1*$a2,         0        , $b2*$a3 - $a2*$b3),
     ($a1*$b3 - $b1*$a2, $a2*$b3 - $b2*$a3,         0         ))             
}

Is that not a lot more clear an synthetic that all what we can write currently ?