Re: Common Lisp solved this problem 20 years ago Per Bothner 26 Oct 2005 05:46 UTC
Alan Watson wrote: > Per, would you summarize the syntax and semantics of type declarations > in Kawa, please? <type-spec> --> <integer> | <string> | .... ;; See below for more. <optional-type-spec> --> <empty> | :: <type-spec> ;; An optional typespec is indicated by the symbol ':: <variable-maybe-typed> --> <variable> <optional-type-spec> ;; A variable declaration may have an optional <type-spec.. <simple-formal> --> <variable | (<variable-maybe-typed>) <optional-formal> --> <simple-formal> | (<variable-maybe-typed> <default-value>) <optional-formals> --> <empty> | #!optional <optional-formal>+ <rest-formal> --> <empty> | #!rest <simple-formal> | . <simple-formal> <def formals> --> (<simple-formal> ... <optional-formals> <rest-formal>) ;; Syntax of formal parameters. May have <type-specs>. ;; #!optional and #!rest are used as introduced by DSSSL. ;; Kawa also support #!keyword parameters. <formals> --> <variable> | <def formals> <lambda expression> --> (lambda <formals> <optional-type-spec> <body>) ;; The <optional-type-spec> constrains the result type of <body>. <definition> --> (define <variable-maybe-typed> <expression>) | (define (<variable> <def formals>) <optional-type-spec> <body>) | (begin <definition>*) <do expression> --> (do ((<variable-maybe-typed> <init> <step>) ...) (<test> <expression> ...) <command> ...) <bindings> --> ((<variable-maybe-typed> <init>) ...) <let expression> --> (let <bindings> <body>) | (let <variable> <bindings> <body>) ;; define, let, and do extended with optional <type-sepc>s. (as <type-spec> <value>) ;; Coerces the <value> to the given <type-spec> (instance? <value> <type-spec>) ;; True if <value> is an instance of <type-spec>. ;; In Kawa as and instance? are procedures, but for R6RS I'd ;; make them syntax if we're going to include them, to avoid ;; issues of first-class types. ;; Note it's somewhat clumsy that the order of parameters in as ;; and instance? is reversed ... The syntax for <type-spec> could be extensible, and we could allow for "type expressions". However, in Kawa <type-spec> is currently restricted to an identifier bound to a type or class definition (some of which are pre-defined), or to a Java type-name surrounded by angle-brackets. *Conventionally*, angle brackets are used for type-names, and all Java builtin type and classes are pre-defined. See http://www.gnu.org/software/kawa/Standard-Types.html for standard Scheme types, such as <integer> and <symbol>. Examples using Java types (*not* proposed for R6RS): (let (i :: <int> 10) ...) ;; i is unboxed 32-bit signed int. sbuf :: <java.lang.StringBuffer> ;; Java class name. arr :: <java.lang.String[]> ;; Java reference array. iarr :: <float[][]> ;; Java array of float array. More portable, and based on names in /usr/include/stdint.h might be: <int8> <int16> <int32> <int64> ;; Signed integers <uint8> <uint16> <uint32> <uint64> ;; Unsigned integers (Note that stdint.h has a lot more types for "at leat N bits" amd "fast N bits" etc.) <float32> <float64> ;; floating-point types The syntax can be extended, following Common Lisp, but I don't suggest doing this for R6RS, and it's not implemented in Kawa. Possible examples: (or <type-spec> ...) ;; union type (vector [<element-type-spec> [<size>]]) (function [(<type-spec> ... [#optional etc])] [:: <type-spec>]) etc etc -- --Per Bothner xxxxxx@bothner.com http://per.bothner.com/