|
From: Florent M. <flo...@gm...> - 2025-12-30 10:28:10
|
Hi everybody, hi Colin,
I had some writing on the wiki about "Type" in Tcl (since 2012). I like this idea because :
- it can enforce the semantic correctness of the code.
- it may allow some optimisations impossible for now.
I published there a package "typedlist", which is simply a class of objects that contains a list and a type.
It helps me to make some scripts that I couldn't achieve without type (for instance, a megawidget package).
As I did a diploma, in my professionnal area (planing building projects),
I have been always thinking about how to modelise the things of the reality I had under my eyes.
Persons, Societies, Tools, Machines, materials, Seller, Supplier, Client...
Of course, but sadly, Tcl was of no help here... Strings doesn't exist in the reality.
Ok, now, we have Tcl_oo package. But, to use it, we need to generate the model a priori.
It's difficult when you are in the heart of action, when scripting has its full value.
I would like to be able to define a type "on the fly", to have a real dynamic typing.
Since then, I published also other ideas, one of it is to use an extended "braced-prefix" concept.
A braced-prefix before a word, when this word is in a position of variable, would indicate that the declared variable has a type.
For instance : % set {list}L {}
Would set the variable L as a list (ie of &tclListType)
You can check the wiki pages below to get more.
https://wiki.tcl-lang.org/page/Proposal+of+syntax%2C+expressiveness+and+semantic+improvements+with+annotations
https://wiki.tcl-lang.org/page/Expanding+the+Expansion+Prefix
https://wiki.tcl-lang.org/page/Expanding+the+Expansion+prefix++%2D+example+1
But a braced-prefix word would indicate only a typed value, it has to be seen as a meta-data word. It's only when a word is in a position to be interpreted as a variable that its braced-prefix will be interpreted as a type.
In other cases, the braced-prefixe is just a tag set on a word, that can be used to modulate an algorithm.
First, I thought about introducing a TCL_TOKEN_PREFIX for the parsing STEP
Second, I thought about a &tclMetaType object which can hold two references, one to the prefix, one to the suffix,
the internalRep beeing of twoPtr. The bytes representation of the &tclMetaType object should be inherited from the suffix object only,
the prefix object beeing only its meta value. To denotes a type, this &tclMetaType object should be tested by any proc where it expects a variable name (set, append, lappend,...etc)
Then, the name of the variable is the suffix, while the braced-prefix is its type.
Third, I thought about how to define types. How to compose it ?
I went to check in OCAML. It distinguishes between "sum type" (union), and "product type" (struct)
So I was thinking about using prefixes to denotes these :
{+} prefix denotes sum type (union)
{x} prefix denotes product type (struct)
Ex:
type scheme Person {x}{
{+}{
{string}full
{string}nic
}name
{dict}tel
{dict}mel
}
set {Person}P {{name}full}$fullname {tel}[dict create home ... office ...] {mel}[dict create home ... office ...]
Again, things get complicated :
Some unions are "carots an potatoes", they can hold distincts concepts.
But we can think about unions which hold distinct representation of the same concept (ex: cartesian or polar complex number).
We would need another braced-prefix to denote that. I was thinking about {|} :
% type scheme complex {|}{
{{x}{
{num}real
{num}imaginary
}}cartesian
{{x}{
{num}modulus
{num}arguments
}}polar
}
% set {Complex(polar)}Z {modulus}2 {argument}[expr {acos(-1)/4}]
Forth, types could need parameters also. I was thinking about enclosing this into parenthesis.
... etc
A lot of things to take into account !
Fifth, the types should be recorded somewhere in the interpreter.
I thought about new hash table in the namespace structures. Here had stoped my inquiry.
Because I don't know how to use hashtables in Tcl.
I didn't think yet on how to connect the variable name and the variable type.
It should need a new VAR_TYPED definition.
About the return value of a proc :
We can keep the proc routine, but refine its interface :
proc {returnType}MyProc {argProtocol}arguments {bodyProtocol}Body
Here,
{returnType} brace-prefix is the type of value returned
{argProtocol} brace-prefix denotes an extended way of declaring arguments : There could be many braced-prefix for args (named arguments, typed arguments, ...)
{bodyProtocol} brace-prefix denotes the "language" to use when compiling the body.
There could be many also : {=} for math expression syntax, {c} for critcl, {bc} for bytecode, {asm} ...
proc {int}add {typedArgs}{
{int}i
{int}j
} {=}{
$i+$j
}
Intertingly, the etymology of Protcol means "glued in front".
So a braced-prefix, which is "glued in front" of a word, appear to be just like, literaly, a protocol...
The protocol of a variable can is a type.
Every command can expect also many protocols on its arguments.
For instance, the protocol of a body proc indicate how to compile it.
Cordialy
-------------------------------------------------------
Dear All,
In trying to answer sebres's criticism of the compiled code efficiency
in my tip 676 implementation, I wrote some kludgy, ad-hoc compile-time
type-checking. This allows me to skip doing a run-time check that a
value is numeric when it comes from a command that always gives numeric
results. I'm now wondering if a more general type-checking facility for
Tcl could be worth exploring.
My kludge could be extended to specify the return types and argument
types for those built-in commands where this is possible. E.g.
`llength` requires a list argument and returns an integer. A variant of
`proc` could be introduced where one can specify argument and return types.
Also we could have a facility to declare a variable with a fixed type in
a similar way to how Tip 677 allows declaring a variable to be
constant. A typed variable would have to be initialised with a legal
value of that type, and could only be modified to another value which
can be converted to that same type.
Then, for example, an arithmetic expression whose variables were all
known to be doubles could be evaluated without all the type-checking and
conversion logic which is currently needed, perhaps giving a significant
speedup. It should also be possible to do better error reporting, e.g.
if the increment passed to `incr` has been declared as double, this
error can be reported at compile time. Such errors could be picked up
if and when the code is compiled, even if that specific command is not
executed. This would address another of the perennial complaints
against Tcl.
Any thoughts, too un-Tcl-ish perhaps???
Season's Greetings,
Colin.
-----------------------------------------
|