develooper Front page | perl.perl5.porters | Postings from August 2012

Re: fixing smartmatch just hard enough (and when, too)

Thread Previous | Thread Next
From:
Damian Conway
Date:
August 23, 2012 17:31
Subject:
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
CAATtAp7Stk8wx2YB_KVVCpQuA7obOuh+5mxU6aaAa-HvB6bt1w@mail.gmail.com
Jesse Luehrs suggested:

> (especially when is_prime(any(9, 10, 11)) should still work fine for
> any sane or reasonable implementation of any()).

The problem is not the sane and reasonable implemenation of any().
The problem is the sane and reasonable implementation of is_prime().

Junctive arithmetic isn't the same as numeric arithmetic, especially when
you construct nested junctions (as you often need to do).

For example, here's an obvious junctive implementation of is_prime():

    sub is_prime {
        my ($n) = @_;

        return $n == 2 || $n % all(2..$n-1) != 0;
    }

If you call:

     is_prime(any(1,2,3))

and the junction is passed into is_prime(), you would get back:

    any(0,1,0)

because:

    return $n == 2 || $n % all(2..n-1) != 0;

becomes:

    return any(1,2,3) == 2 || $n % all(2..any(1,2,3)-1) != 0;

which short-circuits on the LHS of the ||, and so returns:

    any(0,1,0)

In contrast:

    any( is_prime(1), is_prime(2), is_prime(3) )

obviously produces:

    any(0,1,1)

Of course, in that particular example, the difference doesn't matter,
as both the any's evaluate true.

But what about:

     is_prime( all(2,3) )

If the junction is passed in, is_prime() returns:

    all()  # i.e. false

which is wrong...whereas the "proper" semantics of:

    all( is_prime(2), is_prime(3))

produces:

    all(1,1)  # i.e. true.

So it's perfectly possible to have a sane and reasonable semantics for
junctions and a sane and reasonable semantics for is_prime(), that are
not sane and reasonable when used together.

In fact, that's why junctive arguments are supposed to distribute across
subroutine calls, rather than be passed into them: because subroutines
that are not specifically designed for junctive arguments generally
break when passed junctive arguments (especially conjunctive arguments).
In exactly the same way that subroutines not designed for complex
numbers or surreal numbers, or matrices, or quaternions, generally don't
work correctly when passed those kinds of values. Subroutines are coded
assuming a particular arithmetic model, and data that doesn't follow
those particular rules just won't work right.

Damian

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About