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/