[racket] Plot is voracious

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Wed May 21 13:25:14 EDT 2014

Or

#:catch-these-exns-plot! [catch-exn? void]

Jay

On Wed, May 21, 2014 at 11:22 AM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> How about adding yet another argument to plot #:errors-go-to-nan or
> something like that, such that plot's default behavior is to let the
> errors thru, but that, if you turn that flag on, then it just swallows
> all errors?
>
> Robby
>
> On Wed, May 21, 2014 at 12:18 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> Division by zero and other math domain errors, primarily. There are two good
>> reasons to ignore these.
>>
>> 1. Plotting is for visualizing functions. Users shouldn't have to ensure to
>> Plot that the function they're plotting is total when all they want is to
>> *see* it, not use it for some critical calculation.
>>
>> More concretely, raising all exceptions means that this:
>>
>>   (plot3d (surface3d / -1 1 -1 1))
>>
>> has to be this instead:
>>
>>   (plot3d (surface3d
>>            (λ (x y) (with-handlers ([exn?  (λ (e) +nan.0)])
>>                       (/ x y)))
>>            -1 1 -1 1))
>>
>> or it has to use an explicit domain test (i.e. test (= y 0)). That's a lot
>> of work just to visualize the division function.
>>
>> 2. Plotting necessarily approximates. Plot's behavior should be as
>> consistent as possible regardless of exactly how it approximates.
>>
>> Currently, plotting the division function in any subdomain or with any
>> sampling interval just works. Suppose Plot allowed errors to be raised. Then
>> this would plot just fine:
>>
>>   (plot3d (surface3d / -2 1 -2 1))
>>
>> because sampling 41 points (the default) within [-2,1] skips over 0. But
>> this would raise an error:
>>
>>   (plot3d (list (surface3d / -2 1 -2 1)
>>                 (surface3d + -1 2 -1 2)))
>>
>> because the bounds are extended to [-2,2]x[-2,2] accommodate the `+` surface
>> renderer, so 0 would be sampled.
>>
>> ----
>>
>> In a sense, what I really want is impossible. With any exception-swallowing
>> rule I make, someone could write a function that raises an exception that
>> Plot eats when it shouldn't, or re-raises when it shouldn't. Someone could
>> try plotting a function that, for some reason, tries to compute (gamma 0) if
>> a `vector-ref` goes out of bounds.
>>
>> But I think it could behave properly in the most common cases if it were
>> possible to tell the difference between the errors raised by (gamma 0) and
>> (vector-ref vs (length vs)). Right now, there's no way to do that.
>>
>> Neil ⊥
>>
>>
>> On 05/21/2014 10:16 AM, Robby Findler wrote:
>>>
>>> I meant to suggest that plot should raise any error that a function it
>>> calls raises. Is there something wrong with doing that?
>>>
>>> Robby
>>>
>>> On Wed, May 21, 2014 at 11:09 AM, Neil Toronto <neil.toronto at gmail.com>
>>> wrote:
>>>>
>>>> Referencing an identifier before its definition raises an
>>>> `exn:fail:contract:variable`. So that would put Plot in the weird
>>>> position
>>>> of having to distinguish different kinds of contract errors, but not by
>>>> using subtypes or any other simple rule.
>>>>
>>>> Maybe we should have an `exn:fail:contract:math` or
>>>> `exn:fail:contract:domain` or `exn:fail:contract:argument` and make
>>>> `exn:fail:contract:divide-by-zero` a subtype of it. I'd gladly change
>>>> Plot
>>>> to ignore just those, and change the math library to raise more specific
>>>> errors.
>>>>
>>>> (log 0) raises an `exn:fail:contract:divide-by-zero`, which is a
>>>> terminology
>>>> stretch that suggests we need a bit of refactoring anyway.
>>>>
>>>> Neil ⊥
>>>>
>>>>
>>>> On 05/21/2014 09:51 AM, Robby Findler wrote:
>>>>>
>>>>>
>>>>> IMO, plot should raise that exception.
>>>>>
>>>>> Robby
>>>>>
>>>>> On Wed, May 21, 2014 at 10:37 AM, Laurent <laurent.orseau at gmail.com>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> ... it eats everything! (particularly exceptions)
>>>>>> For example, it is perfectly happy with the following:
>>>>>>
>>>>>> % racket
>>>>>> Welcome to Racket v6.0.1.7.
>>>>>>>
>>>>>>>
>>>>>>> (require plot)
>>>>>>> (plot (function (lambda(x)(+ x n)))
>>>>>>
>>>>>>
>>>>>>     #:x-min 0 #:x-max 10 #:y-min 0 #:y-max 10)
>>>>>> (object:2d-plot-snip% ...)
>>>>>>
>>>>>> ... although n is clearly undefined. Presumably this is to avoid
>>>>>> breaking
>>>>>> on
>>>>>> math errors like `(/ 0)` ?
>>>>>>
>>>>>> Would it make sense to have an `exn:fail:arithmetic` exception struct
>>>>>> so
>>>>>> that `function` would only catch those?
>>>>>>
>>>>>> Laurent
>>>>>>
>>>>>>
>>>>>> ____________________
>>>>>>     Racket Users list:
>>>>>>     http://lists.racket-lang.org/users
>>>>>>
>>>>> ____________________
>>>>>     Racket Users list:
>>>>>     http://lists.racket-lang.org/users
>>>>>
>>>>
>>>> ____________________
>>>>   Racket Users list:
>>>>   http://lists.racket-lang.org/users
>>
>>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.