This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: type declaration best practices?
- From: Per Bothner <per at bothner dot com>
- To: Helmut Eller <eller dot helmut at gmail dot com>
- Cc: kawa at sources dot redhat dot com
- Date: Wed, 13 Jan 2010 00:54:52 -0800
- Subject: Re: type declaration best practices?
- References: <FF51B6B0-46D4-4C37-B521-831014EB4B73@theptrgroup.com> <4AFCA0F9.3060300@bothner.com> <m2my2q3nho.fsf@gmail.com> <4AFD109E.7090307@bothner.com> <4B4AC54C.1020208@bothner.com> <m2tyut9hpc.fsf@gmail.com>
On 01/11/2010 12:19 AM, Helmut Eller wrote:
* Per Bothner [2010-01-11 07:29+0100] writes:
For function declarations, I'm dithering between:
(1)
(define (string-ref (str ::string) (k ::int)) ::char
(invoke str 'charAt k))
...
Comments?
In (1) the colons seem redundant except for the return type.
Agreed, that is a blemish. I'm still undecided ...
So how would (future) type annotations fit in? I think by
coming after the :: as in:
(define x ::(@NonNull)string (...))
Keywords could also be used like:
(define x :: string annotation: NonNull value)
or perhaps
(define x (string annotation: NonNull) value)
The first syntax seems to imply that NonNull is an
anotation on the declaration x, rather than as
intended an annotation on the type string.
The second syntax seems to imply that the type-specifier
string
is the same as the type specifier
(string)
which may be undesirable. Plus there are some issues about
how you handle parameterized type specifiers - perhaps
(list integer)
and how you handle multiple type annotations as well as
type annotations with parameters.
That's why I'm leaning towards a syntax for ANNOTATION
that would be:
(@ANNOTATION_TYPE KEYWORD: VALUE ...)
and TYPE-SPECIFIER would be:
:: TYPE-ANNOTATION ... TYPE-EXPRESSION
I.e. :: followed by 0 or more type-annotations, followed
by the type-name or type-expression.
There could be a rule that if define has 3 arguments the second are
annotations. And as shortcut, if the second argument is a symbol it's a
type:
(define x int 10)
would be the same as now (define x :: int 10)
One problem is do:
(do ((i a b)) ...)
Does this mean a is a type specifier for i, and i is initialized to b,
or does it mean that a is the initial value and b the update expression?
I agree the traditional "Schemy" way to handle things like specifiers
would be to use parenthesis grouping, and in general positional syntax.
Unfortunately, I think that way of doing things is inflexible,
error-prone, and hard to read. Using keywords and syntactic cues is
usually preferable, at least if one can keep it from being too verbose.
Unfortunately, it's a difficult problem, and the need for compatibility
with existing code makes it harder.
--
--Per Bothner
per@bothner.com http://per.bothner.com/