From 8b838c0b22e95460e48ab812c7b57a4718852bbf Mon Sep 17 00:00:00 2001 From: Sergiu Ivanov Date: Sun, 20 Mar 2022 19:34:48 +0100 Subject: [PATCH] Introduce pseudovariadic functions. --- scribblings/functions.scrbl | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/scribblings/functions.scrbl b/scribblings/functions.scrbl index 7766dda..c3a943c 100644 --- a/scribblings/functions.scrbl +++ b/scribblings/functions.scrbl @@ -18,7 +18,37 @@ Boolean functions, etc.). [sandbox-memory-limit 50]) (make-evaluator 'typed/racket #:requires '((submod "functions.rkt" typed))))) -@section{Tabulating functions} +@section{Pseudovariadic functions} + +Functions for @seclink["tabulating"]{tabulating functions} take as an argument +a function to tabulate or a list of functions to tabulate. Writing the type of +such functions in Typed Racket and generalizing on the number of the arguments +is hard, and using functions with such types seems even harder. +The @seclink["tabulating"]{following section} contains some examples, +illustrating among other things the difficulties of typing +tabulating functions. + +The type of @racket[apply] does not help in this situation, because Typed +Racket treats @racket[apply] in +@hyperlink["https://racket.discourse.group/t/replicating-the-type-of-apply/770/3"]{a +special way}. This means that a user-defined function with the same type as +@racket[apply] and directly calling it will not work in the same way. + +@examples[#:eval functions-evaluator +apply +(define myapply apply) +myapply +(apply (λ (x y) (and x y)) '(#t #f)) +(eval:error (myapply (λ (x y) (and x y)) '(#t #f))) +] + +One way to work around this issue is to write functions which disguise as +variadic functions of type @racket[(-> a * b)], but which throw an exception +when they receive a number of arguments different from a given constant value. +Such functions are called @italic{pseudovariadic functions} in +this documentation. + +@section[#:tag "tabulating"]{Tabulating functions} @defproc[(tabulate [func (-> a ... b)] [doms (List (Listof a) ... a)])