Re: define-typed: checking values on proc entry and exit
Zelphir Kaltstahl <[email protected]>
| Newsgroups | gmane.lisp.guile.user |
|---|---|
| Message-ID | <[email protected]> |
On 10.05.24 15:47, Dr. Arne Babenhauserheide wrote: > Hi, > > in #guile on IRC¹, old talked about Typed Racket so I thought whether > that could be done with define-syntax-rule. So I created define-typed. > This is also on my website², but I wanted to share and discuss it here. > > I follow the format by [sph-sc], a Scheme to C compiler. It declares > types after the function definition like this: > > ┌──── > │ (define (hello typed-world) (string? string?) > │ typed-world) > └──── > > ┌──── > │ (define-syntax-rule (define-typed (procname args ...) (ret? types ...) body ...) > │ (begin > │ (define (procname args ...) > │ ;; define a helper pro > │ (define (helper) > │ body ...) > │ ;; use a typecheck prefix for the arguments > │ (map (λ (type? argument) > │ (unless (type? argument) > │ (error "type error ~a ~a" type? argument))) > │ (list types ...) (list args ...) ) > │ ;; get the result > │ (let ((res (helper))) > │ ;; typecheck the result > │ (unless (ret? res) > │ (error "type error: return value ~a does not match ~a" > │ res ret?)) > │ ;; return the result > │ res)) > │ ;; add procedure properties > │ (let ((helper (lambda (args ...) body ...))) > │ (set-procedure-properties! procname (procedure-properties helper)) > │ ;; preserve the name > │ (set-procedure-property! procname 'name 'procname)))) > └──── > > This supports most features of regular define like docstrings, procedure > properties, and so forth. > > ┌──── > │ (define-typed (hello typed-world) (string? string?) > │ typed-world) > │ (hello "typed") > │ ;; => "typed" > │ (hello 1337) > │ ;; => type error ~a ~a #<procedure string? (_)> 1337 > │ (define-typed (hello typed-world) (string? string?) > │ "typed" > │ #((props)) > │ typed-world) > │ (procedure-properties hello) > │ ;; => ((name . hello) (documentation . "typed") (props)) > └──── > > This should automate some of the guards of [Optimizing Guile Scheme], so > the compiler can optimize more (i.e. if you check for `real?') but keep > in mind that these checks are not free: only typecheck outside tight > loops. > > They provide a type boundary instead of forcing explicit static typing. > > Also you can do more advanced checks by providing your own test > procedures and validating your API more elegantly, but these then won’t > help the compiler produce faster code. > > But keep in mind that this does not actually provide static program > analysis like while-you-write type checks. It’s simply [syntactic sugar] > for a boundary through which only allowed values can pass. Thanks to > program flow analysis by the just-in-time compiler, it can make your > code faster, but that’s not guaranteed. It may be useful for your next > API definition. > > My question now: do you have an idea for a better name than > define-typed? > > > [sph-sc] <https://github.com/sph-mn/sph-sc> > > [Optimizing Guile Scheme] > <https://dthompson.us/posts/optimizing-guile-scheme.html> > > [syntactic sugar] > <http://www.phyast.pitt.edu/~micheles/scheme/scheme12.html#are-macros-just-syntactic-sugar> > > > ¹ https://web.libera.chat/?nick=Wisp|?#guile > ² https://www.draketo.de/software/guile-snippets#define-typed > > > Best wishes, > Arne Hello Arne, You might also be interested in my repository for function contracts using CK macros: https://codeberg.org/ZelphirKaltstahl/guile-examples/src/commit/0e231c289596cb4c445efb30168105914a8539a5/macros/contracts I hope I can check out your macro soon and hope to be able to understand it : ) Regards, Zelphir -- repositories: https://notabug.org/ZelphirKaltstahl