[racket] Contract for methods with optional arguments
If I knew the answer I'd tell you, and hopefully someone else will.
Meanwhile, another way you could look at this: If it becomes too
difficult to write a contract (or documentation) for a function, it
might be good to revise the function.
For example, a function that takes an optional argument that, if
supplied, causes the function to return something as different as
number? instead of (vectorof number?). That feels like a function that
instead wants to be two, more-specialized functions. Probably;
admittedly depends on the context of what you're doing.
p.s. An old, classic example s the C stdlib `realloc( ptr, size )`
function. It reallocates ptr to be size bytes. But wait -- there's
more! If ptr is NULL, then realloc will act like `malloc` and
allocate memory for you. And -- if you order before midnight tonight!
-- passing 0 for size will make it act like `free` and return void.
It's an entire API in one function! Three tools for the price of one!
Call now! :)
This example paraphrased by memory from what I think was "Writing
Solid Code" by Steve Maguire in the mid 90s. His point: `realloc` is
too flexible. Because it accepts anything, you can't write ASSERTs (or
a contract) to catch a misuse by a caller. Of course the
implementation may be some private function like realloc, an
all-in-one tools that accepts anything. But the public realloc should
be a thin wrapper function, just like malloc and free are.
On Sat, Aug 31, 2013 at 7:39 AM, Diego Sevilla Ruiz
<dsevilla at ditec.um.es> wrote:
> Hi all:
>
> I have encountered a situation in which I don't know how to specify
> the contract for a method that:
>
> 1. Has a final optional argument
> 2. The value of the optional argument makes the method change the return
> type of the method.
>
> It is similar to this:
>
> (define/public (get-whatever (pos #f))
> (if (not pos)
> inner-vector-of-int
> (vector-ref inner-vector-of-int pos)))
>
> (that is, if you don't specify a position, return the whole vector, but if
> you specify a position, return that position).
>
> For what I've seen in the documentation, there exists the ->i
> function that allos the specification of named parameters, such as (not
> working but you get the idea):
>
> (->i () ;; mandatory
> ([pos (or/c number? boolean?)]) ;; optional
> [result (pos) (or/c (and/c (=/c #f pos) (vectorof number?))
> (and/c (number? pos) number?))])
>
> (I don't think the result expression is correct, but it expresses what I
> want).
>
> The real problem comes with methods, because I have ->m and ->dm,
> but not ->im (->dm does not allow specifying dependent previous values in
> the result, for example, as far as I know).
>
> So the question is, how to write a method contract for this method?
>
> Thanks in advance,
> diego.
>
> --
> Diego Sevilla Ruiz -- http://ditec.um.es/~dsevilla/ -- dsevilla at um.es _.___
> Dep. Ingeniería y Tecnología de Computadores, Facultad de Informática D|TEC
> Univ.de Murcia,Campus Espinardo,30080 Murcia (SPAIN),Tel.+34868887571
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users