One of the things you can do with Generalized Accessors, is that assignments to any value can be typechecked. You get this "for free" because accessors pair a function with a variable slot, and that function can use typechecking:
Writing the accessor boilerplate is laborious...
checked: accessor lambda [^:value [your! types! here!] <static> actual] [
either value [actual: value.] [actual.] ; terminal dot allows unset vars
]
If you want to be truly generic and support storing actions in the variable, you need slashes:
checked: accessor lambda [^:/value [your! types! here!] <static> actual] [
either value [/actual: value.] [actual.]
]
Not only is that a nuisance to get typechecking, it's also not native code, so you're running that EITHER and its branches.
So we could make it a feature of ACCESSOR, maybe just when you give it a block...and it could do a particularly cheap and special form. I think this is actually the right way to go about it... it would put a "pairing" cell in the variable's location, which would pair up the stored value with a PARAMETER! (which does preoptimized calculations on the typeset:
checked: accessor [your! types! here!]
checked: initial-value
That's all fine and good but seems we need a shorter way to say it...that doesn't repeat the variable name and doesn't have to say ACCESSOR.
We want whatever this is to still get collected as a SET-WORD! (if it is one), so this probably has to be something like:
checked: typed [your! types! here!] initial-value
I don't hate it. Alternate ideas?
Interaction With Syntax For Locals
This would now be able to work:
foo: func [x [text!] <local> y [integer!]] [...]
This would need to be lenient in terms of letting the Y be unset prior to its first assignment. So it can contain nothing at the outset, but any future assignments have to assign integers.
But this would get a bit of a problem if we want to mix it with a form that lets you assign the local:
foo: func [x [text!] <local> y: [integer!]] [...]
That would give you Y with the BLOCK! [integer!] in it. You'd have to say:
foo: func [x [text!] <local> y: typed [integer!] 10] [...]
We could keep the historical "groups to initialize" idea
foo: func [x [text!] <local> y (10)] [...] ; not typechecked
foo: func [x [text!] <local> y [integer!] (10)] [...] ; typechecked
And maybe the idea of making a place to put the type constraints vindicates that syntax for this context.
Typechecking will slow down the code. But it would be running through the same checking mechanisms that functions use. As that code got better, so would this.
There could be some sort of "enable typechecking only in debug mode" property of functions where you could turn it on or off.