syntax woe with typed Racket 'let'

50 views
Skip to first unread message

Hendrik Boom

unread,
May 30, 2020, 1:32:36 PM5/30/20
to Racket Users
I'm sorry to keep pestering this list, but I'm out of my depth with the
detailed syntax (and semantics) of typed Racket. But I'm doggedly
ploughing on.

I'm having trouble with the 'let' line in the 'pointer-to' function listed later:

(let ([vt : Ffi-type (cast ((inst hash-ref Ffi-type Ffi-type) type-to-vector type #f) Ffi-type)])

Yes, there's an unbalanced parenthesis because this sin't the end of the let-expression.

The error message is

let: expected type-annotated identifier
parsing context:
while parsing annotated-binding
while parsing optionally type-annotated binding in: (vt : Ffi-type (cast ((inst hash-ref Ffi-type Ffi-type) type-to-vector type #f) Ffi-type))

I can't see the error. 'vt : Ffi-type' looks like a type-annotated
identifier to me. And it seems to have the right number of parentheses
in front of it, followed by an expression whose vlue is to be bound to
'vt'.

Here's the function it's part of:


(define (pointer-to [type : T-Type] . [args : T-Size]) : T-Type ; TODO: rename args to size-args
(if (and (equal? args '(1)) (not (eq? type '_void)))
(mode-dependent-type
`(_ptr i ,type) `(_ptr o ,type))
(case type
((_void) '_pointer/intptr)
((_byte _uint8) (mode-dependent-type
'_string*/utf-8
(if (null? args)
'_bytes
`(_bytes o ,@ args))))
(else
(let ([vt : Ffi-type (cast ((inst hash-ref Ffi-type Ffi-type) type-to-vector type #f) Ffi-type)])
(if vt
(mode-dependent-type
`(,vt i)
(if (null? args)
vt
`(,vt o ,@ args)))
(mode-dependent-type
`(_vector i ,type)
(if (null? args)
'_pointer
`(_vector o ,type ,@ args)))))))))

Sam Tobin-Hochstadt

unread,
Jun 1, 2020, 10:58:25 AM6/1/20
to Racket Users
Do you perhaps have some other binding shadowing the binding of `:`
from Typed Racket? That produces the error message you get when I try
it.

Sam
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20200530173230.bsrp5skkc35ot34h%40topoi.pooq.com.

Hendrik Boom

unread,
Jun 1, 2020, 3:09:20 PM6/1/20
to Racket Users
On Mon, Jun 01, 2020 at 10:58:09AM -0400, Sam Tobin-Hochstadt wrote:
> Do you perhaps have some other binding shadowing the binding of `:`
> from Typed Racket? That produces the error message you get when I try
> it.

Not intentionally. I'll have to look carefully for possible candidates.
Or ask DrRacket to jump to a binding occurrence.

Did that: It wouldn't find a bining instance while that colon was
there, but complained about the syntax error I was sompaining about.
But when I removed the type specification from the let-clause and
introuced a colon elsewhere in the function as an extra parameter in
another expression, it would find the binding. It turned out that the
binding occurrence was the colon in the tail-parameter [args : T-Size].

So I have to ask, what *is* the proper way to indicate that the
function can be called with many more parameters, which are to be
made available as a list?

Thank you for the hint.

-- hendrik
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2BYkANXdevMc%3DiSTFaWnpzU-6ofNWF2qJtWyR-f6ES2gLg%40mail.gmail.com.

Sam Tobin-Hochstadt

unread,
Jun 1, 2020, 3:48:12 PM6/1/20
to Racket Users
The syntax looks like this:

(define (f [x : Number] . [y : String *]) : Number (+ x (length y)))

See the documentation for `define` in Typed Racket here:
https://docs.racket-lang.org/ts-reference/special-forms.html?q=define#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._define%29%29
in particular the `rst` production.

Sam
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20200601190913.hxaqlgfm7y6prm5p%40topoi.pooq.com.

Shu-Hung You

unread,
Jun 1, 2020, 11:29:38 PM6/1/20
to Hendrik Boom, Racket Users
FWIW, because `.` is just cons, the program
(define (F [X : T1] . [Y : T2]) 'e)
is being read as:
(define (F [X : T1] Y : T2) 'e)
I guess that's the reason for having an extra '*' in the syntax.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2Bb%3DqGddyCB1FgOOiMZYG5c%3DBg9%3DV0kAVmPTE6riTNaAcA%40mail.gmail.com.

Hendrik Boom

unread,
Jun 2, 2020, 12:03:36 AM6/2/20
to Racket Users
On Mon, Jun 01, 2020 at 10:28:55PM -0500, Shu-Hung You wrote:
> FWIW, because `.` is just cons, the program
> (define (F [X : T1] . [Y : T2]) 'e)
> is being read as:
> (define (F [X : T1] Y : T2) 'e)
> I guess that's the reason for having an extra '*' in the syntax.

Indeed. It works for untyped Racket, but in typed Racket that notation
would become quite ambiguous.

-- hendrik

Philip McGrath

unread,
Jun 2, 2020, 11:00:54 AM6/2/20
to Sam Tobin-Hochstadt, Racket Users
On Mon, Jun 1, 2020 at 3:48 PM Sam Tobin-Hochstadt <sa...@cs.indiana.edu> wrote:
(define (f [x : Number] . [y : String *]) : Number (+ x (length y)))

 Another way to write this, which I often prefer, is:
(: f (-> Number String * Number))
(define (f x . y)
  (+ x (length y)))
Reply all
Reply to author
Forward
0 new messages