[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Common Lisp solved this problem 20 years ago



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
per@xxxxxxxxxxx   http://per.bothner.com/