[plt-dev] coding ideas from JaneStreet

From: Sam Tobin-Hochstadt (samth at ccs.neu.edu)
Date: Tue Apr 13 12:54:42 EDT 2010

On Tue, Apr 13, 2010 at 12:42 PM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> On Tue, Apr 13, 2010 at 10:47 AM, Sam Tobin-Hochstadt <samth at ccs.neu.edu> wrote:
>> On Tue, Apr 13, 2010 at 9:08 AM, Robby Findler
>> <robby at eecs.northwestern.edu> wrote:
>>> On Tue, Apr 13, 2010 at 7:15 AM, Sam Tobin-Hochstadt <samth at ccs.neu.edu> wrote:
>>>> On Tue, Apr 13, 2010 at 4:42 AM, Paulo J. Matos <pocmatos at gmail.com> wrote:
>>>>>
>>>>> Awesome, this one of my favourite features missing in Scheme. Hopefully
>>>>> we will see this soon in TS, Sam?
>>>>
>>>> Yes, we will hopefully soon see the form Eli describes.  But it won't
>>>> give you exhaustiveness checking in general for `match', that's much
>>>> harder.
>>>
>>> I'm still looking into this, but my initial reading of the paper
>>> behind the current match implementation [1] seems to suggest that the
>>> compilation process can detect when it has to insert "else" clauses
>>> which should be at least a good start on this problem, no?
>>
>> `match' always inserts an else clause.  The only way to write a
>> guaranteed exhaustiveness in Scheme in general is to write a catch-all
>> pattern yourself.  I don't think `match' should warn if you don't do
>> that, since programmers will in general know more about the
>> exhaustiveness of their patterns than `match' can.  For example,
>> should there be a warning for this code?
>>
>> #lang scheme
>>
>> (define/contract (f x)
>>   ((or/c number? string?) . -> . number?)
>>   (match x
>>     [(? number?) ...]
>>     [(? string?) ...]))
>
> No. If match can't tell it isn't exhaustive, it should be quiet; so it
> can just assume that predicates cover everything (and insert an error
> to be sure) This one, on the other hand:
>
> (match x
>  [`(x ,(? number?)) ...]
>  [`(,_ ,(? string?)) ...]
>
> should signal an error or warning or something since the
> non-two-element-list case is not covered.

What if we change the contract to:

((list/c any/c any/c) . -> . any/c)

Now the error case is unreachable, but `match' doesn't know that.
This also suggests that almost every single use of `match-let' should
trigger a warning.

Ultimately, I think the choices are between a warning that is issued
almost always (except when there's a catchall clause), and a warning
that basically never happens, leading people to false confidence in
the completeness of their patterns.  Neither of those seem like good
points in the design space.  Instead, if you want coverage checking,
you should use a more restrictive pattern matcher, such as `cases'
from the PLAI library.
-- 
sam th
samth at ccs.neu.edu


Posted on the dev mailing list.