Skip to content

Support SRFI 253 / relax type annotation syntax #150

Description

@aartaka

Hello! I want to see SRFI 253 supported in Bigloo, and I’m ready to implement it myself. In fact, I tried that. I thought that type annotations consist of three separatable parts: symbol, type annotation indicator (::,) and the type itself. This is the way it works on Kawa, where I successfully used that syntax to bring in SRFI 253 types:

(define-syntax %lambda-checked
     (syntax-rules (::
                    number? complex? real? rational? exact-integer? integer? inexact?
                    symbol? keyword? list? pair? string? char?
                    vector? procedure? input-port? output-port?

                    number complex real rational integer double
                    symbol keyword list pair string character
                    vector procedure input-port output-port)
       ((_ name (body ...) (args ...) (checks ...))
        (lambda (args ...)
          checks ...
          body ...))
       ((_ name body (args ...) (checks ...) (arg number?) . rest)
        ;; See this ::?
        (%lambda-checked name body (args ... arg :: number) (checks ...) . rest))
       #|...|#
       ((_ name body (args ...) (checks ...) (arg output-port?) . rest)
        (%lambda-checked name body (args ... arg :: output-port) (checks ...) . rest))
       ((_ name body (args ...) (checks ...) (arg pred) . rest)
        (%lambda-checked
         name body
         (args ... arg) (checks ... (check-arg pred arg name)) . rest))
       ((_ name body (args ...) (checks ...) arg . rest)
        (%lambda-checked
         name body
         (args ... arg) (checks ...) . rest))
       ((_ (body ...) (args ...) (checks ...) . last)
        (lambda (args ... . last)
          checks ...
          body ...))))

However, trying to reproduce this approach, I discovered that Bigloo treats type-annotated symbols as inseparable entities, and separating them turns them into three independent symbols instead. So this macro doesn't work:

(define-syntax %define-checked
  (syntax-rules (=> :: check-impl?
                    procedure? pair? null? list? integer? exact-integer?
                    inexact? real? boolean?
                    string? char? vector? output-port? input-port? symbol? keyword?

                    obj procedure pair nil pair-nil bignum real bbool bstring
                    bchar vector output-port input-port symbol keyword)
    ((_ name (=> (returns ...) body ...) (args ...) (checks ...))
     (define (name args ...)
       checks ...
       body ...))
    ((_ name (body ...) (args ...) (checks ...))
     (define (name args ...)
       checks ...
       body ...))
    ((_ name body (args ...) (checks ...) (arg procedure?) . rest)
     (%define-checked name body (args ... arg :: procedure) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg pair?) . rest)
     (%define-checked name body (args ... arg :: pair) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg null?) . rest)
     (%define-checked name body (args ... arg :: nil) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg list?) . rest)
     (%define-checked name body (args ... arg :: pair-nil) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg integer?) . rest)
     (%define-checked name body (args ... arg :: bignum) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg exact-integer?) . rest)
     (%define-checked name body (args ... arg :: bignum) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg inexact?) . rest)
     (%define-checked name body (args ... arg :: real) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg real?) . rest)
     (%define-checked name body (args ... arg :: real) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg boolean?) . rest)
     (%define-checked name body (args ... arg :: bbool) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg string?) . rest)
     (%define-checked name body (args ... arg :: bstring) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg char?) . rest)
     (%define-checked name body (args ... arg :: bchar) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg vector?) . rest)
     (%define-checked name body (args ... arg :: vector) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg output-port?) . rest)
     (%define-checked name body (args ... arg :: output-port) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg input-port?) . rest)
     (%define-checked name body (args ... arg :: input-port) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg symbol?) . rest)
     (%define-checked name body (args ... arg :: symbol) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg keyword?) . rest)
     (%define-checked name body (args ... arg :: keyword) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg (check-impl? type)) . rest)
     (%define-checked name body (args ... arg :: type) (checks ...) . rest))
    ((_ name body (args ...) (checks ...) (arg pred) . rest)
     (%define-checked
      name body
      (args ... arg :: obj) (checks ... (check-arg pred arg name)) . rest))
    ((_ name body (args ...) (checks ...) arg . rest)
     (%define-checked
      name body
      (args ... arg) (checks ...) . rest))))

Any pointers on how I might generate type annotations in macros? Does that require a change in Bigloo parser? Is that feasible?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions