Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending Range class to Interval Arithmetic #392

Closed
librasteve opened this issue Oct 27, 2023 · 2 comments
Closed

Extending Range class to Interval Arithmetic #392

librasteve opened this issue Oct 27, 2023 · 2 comments
Labels
language Changes to the Raku Programming Language

Comments

@librasteve
Copy link

librasteve commented Oct 27, 2023

There is a proposal from @vrurg to add Range op Range overrides where op is +-*/ in Issue #391

This Issue is to debate the pros and cons of extending the raku language to include these operations (including extensions to ROAST and docs).

[NB. In my opinion, we should NOT extend the raku language in this way and I will be making the case AGAINST and to keep these extensions in module space.]


Here is my understanding of the current design of class Range:

  • Range op Scalar and Scalar op Range operations are provided today for the purpose of Shifting and Scaling intervals
  • these distribute the Scalar to the endpoints of the Range in the same manner that a 2 item Junction distributes it's operations
  • Ranges serve two main purposes: to generate lists of consecutive numbers or strings, and to act as a matcher to check if a number or string is within a certain range.
  • since the proposed change will incorporate a thin slice of Interval Arithmetic into raku for the first time, I would encourage all contributors to ingest the excellent wikipedia page

@librasteve
Copy link
Author

librasteve commented Oct 27, 2023

I make the claim that these Range op Range features will truly take raku core into the Interval Arithmetic arena.

Here is the initial code prototype from the newly minted raku Math::Interval module:

multi infix:</>( Range:D $x, Range:D $y ) is export {

    sub inverse($y) {                       # make inverse, ie. 1/[y1..y2] 
        my (\y1, \y2) = ($y.min, $y.max);
        my \ss = (y1.sign == y2.sign);      # same sign

        given y1, y2  {
            # valid 
            when    !0, !0  &&  ss  { 1/y2 .. 1/y1 }
            when    !0,  0          { -Inf .. 1/y1 }
            when     0, !0          { 1/y2 .. Inf  }

            # error
            when     0,  0          { die "Divisor cannot be Range 0..0. Divide by zero attempt." } 
            when    !0, !0  && !ss  { die "Divisor cannot be Range that spans 0 [multi-intervals are not supported]." }
        }
    }

    $x * inverse($y)
}

As you can see, even this partial implementation steps into a world where division is not as simple as dividing each endpoint by a scalar. This is what I mean when I say that we would be stepping into the (often arcane) Interval Arithmetic arena. The need for non-obvious manipulations like this means that you will need to be well informed by the docs what and why this is going on in your language.

In fact to do this properly would return a disjoint multi-interval instead of the 'spans 0' error mode. It has occurred to me that a Junction of Ranges would maybe be a nice solution for this - but again, more weirdness on the horizon for the typical coder.

While some languages (notably Julia) DO support Interval Arithmetic deeply, I think raku devs should be wary of the resource and time implications of a fully functional deep implementation. Therefore there is a risk that a shallow partial implementation in core will be seen as a weakness of the core language. Better to be in module space where the module can evolve incrementally and does not risk the reputation of the core language.

@librasteve
Copy link
Author

thanks for the fb - guess there are no detractors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language Changes to the Raku Programming Language
Projects
None yet
Development

No branches or pull requests

1 participant