[Top][All Lists]

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

Re: type annotations

From: siiky
Subject: Re: type annotations
Date: Mon, 17 Aug 2020 20:29:41 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Thunderbird/80.0

> Thank you, André,
> The examples help. I expect that procedure signatures are the most
> common use of type annotations. They seem to provide the most benefit
> for the level of effort and extra code.

No problem, glad they were helpful to you. I think that procedure type annotations are the most useful, yes. I also use `the` sometimes to make it clear what type something is (and of course get type errors), for example in a `let`:

(let ((x (the fixnum (+ 1 2 3))))

Changing from `fixnum` to, for example, `string` shows an error when compiling.

> In the manual page for types ( ),
> what is the meaning of the period in the definition of VALUETYPE for
> procedures? The first three annotation variants for procedures use the
> period: alone, with « -> », and with « --> ». I find the documentation
> confusing.

(I don't know how familiar with Scheme/CHICKEN you are, so I'll assume not too familiar and try not to leave anything implicit)

Do you mean the single dot (.) or the ellipsis (...) ?

The single dot usually appears as in (x y . zs) to mean "the rest" (or the tail); so in this case zs is a list (possibly empty). If you had a function like (define (foo x y . zs) blablabla), and you were to call (foo 1 2 3 4 5), x would be 1, y 2, and zs (3 4 5). In function definitions the single dot is the same as #!rest.

The ellipsis mean zero or more "things", specifically in syntax-rules macros. These are also used in documentation for this purpose.

Taking one of the ways to specify a procedure type as an example:

(VALUETYPE1 ... [#!optional VALUETYPE2 ...] [#!rest [VALUETYPE2]] -> . RESULTS)

It specifies a procedure with 0 or more positional arguments (VALUETYPE1), zero or more optional arguments (VALUETYPE2), rest arguments of type VALUETYPE2, and zero or more results of type RESULTS (notice the single dot, although I think ellipsis could also be used there). (If you find "zero or more return values" weird (I do), and don't know what they are, take a look at `values`[0])

A more specific example would be (using Haskell notation):

myFunc :: Int -> a -> String -> res


(: myFunc (integer 'a string --> 'res))

And for some other common cases (the #!optional, #!rest, and #!key not being possible in Haskell):

(: fun1 ('t integer #!optional string boolean -> 't))
; a :: t
; b :: Int
; c :: String
; d :: Bool
(define (fun1 a b #!optional c d)
  ; do stuff

(: fun2 ('a 'a --> 'a))
; x :: a
; y :: a
(define (fun2 x y)
  (+ x y))

(: make-person
   (or false string) ; name
   (or false fixnum) ; age
   (or false float)  ; height
   boolean           ; cool?
   -> (struct person))) ; return type
; This would be the type of a constructor for a record created by, for example, `defstruct`, with:
; (defstruct person name age height cool?)
(define (make-person #!key (name #f) (age #f) (height #f) (cool? #f))
  (let ((person (...)))

; Type of the function `map` for homogeneous lists (like in Haskell)
(: map (('a -> 'b) (list-of 'a) -> (list-of 'b))
(define (map f l)
  (if (null? l)
      (cons (f (car l))
            (map f (cdr l)))))

Hopefully this message will look alright... I noticed the other one didn't look exactly as I had intended.


André Sá

reply via email to

[Prev in Thread] Current Thread [Next in Thread]