Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread TSa

HaloO,

Larry Wall wrote:

That seems a bit ugly though.  Another way would be to define ± as
simple half-open Range and then overload comparison:

multi sub infix:==(Num $x,Range $r) {
$x == any($r.minmax);
}


This is strange. Having 1 == 1..3 and 3 == 1..3 as true is
not what I expect. I think for consistency with lists and
arrays a range should numify to the length of the list it
represents. That is, we have 'a'..'z' == 26 and 4..6 == 3.

Thinking of string ranges, how would infix ± treat these?
'm' ± 3 === 'j'..'p' seems reasonable albeit not overly
useful. The overload infix:±:(Str,Ratio) will hardly work.

BTW, here is a correct implementation of relative error
range creation:

   multi infix:± (Num $x, Ratio $r -- Range of Num)
   {
   if $x == 0
   {
  # range instead of plain 0 to comply with sig
  return 0..0;
   }
   elsif $x  0
   {
  return $x * (1 + $r) ..^ $x * (1 - $r);
   }
   else
   {
  return $x * (1 - $r) ..^ $x * (1 + $r);
   }
   }

The interesting thing is that 0 comes out as a special number
that is exact as far as relative error goes. Note that it can't
be subsumed by the other cases because that would produce 0..^0
which fails for 0 ~~ 0..^0 since that means 0 = 0  0 which
is false.

Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread TSa

HaloO,

Jon Lang wrote:

@a[50%] # accesses the middle item in the list, since Whatever is
set to the length of the list.


I don't understand what you mean with setting Whatever. Whatever is
a type that mostly behaves like Num and is used for overloaded
postcircumfix:[ ]:(Array @self: Whatever $i). So *-1 just casts
the -1. Postfix % would do the same for Ratio. Then one can overload
postcircumfix[ ]:(Array @self: Ratio $r) and multiply $r with the
size of the array to calculate the index. BTW, this indexing reminds
me of the way how textures are indexd in OpenGL. With that in mind
the index ratio could also interpolate between entries of a texture
array.



Concerning - $val, $err { [..^] $val - $err, $val + $err } vs -
$val, $err { any $val - $err, $val + $err }: I'm not sold on the
notion that Huffman coding might imply that ± should go with the
former.  Perhaps an argument can be made for it; but I suspect that
the relative commonness of the two uses is extremely similar (which,
per Huffman coding, would imply that their names should have similar
lengths).  Whichever one we go with, we have a conundrum: if we use ±
as the name of the latter, the conundrum is that the only other
intuitive name for the former that has thus far been proposed (i.e.,
within) is too long; if we use ± as the name for the former, the
conundrum is that no other intuitive name has been proposed for the
latter.

So: what we need are proposals for short, understandable names for
each operator.  Suggestions?


I think the junctive alternative is of little use. A numeric Range has
its primary purpose as the rhs of a smartmatch that checks numbers. We
have no proper range arithmetic that renders the semantics of
approximated exact numbers.


So here comes some rant about Num as the type that in contrast to Rat
carries an approximation error and an approximation closure that can be
called to decrease the error. That is e.g. sqrt(2) returns such a thing
that can be called again to continue the iteration. Numeric equality
checks would then not only compare the approximate values but also the
identity of the iteration closure. Whereas ~~ would check if the lhs
number's interval falls into the range of the rhs which is build from
the current approximation and the error. The approximation closure is
never invoked by ~~. Infix ± would then not create a range but a Num
with explicit error. That is, it is syntactic sugar for

$y.error = 0.001;
$x ~~ $y;

where I think the error should always be the relative error. Hmm, or the
relative error is indicated by the Ratio type. This gives the following
ways to write literal Nums:

my $x = 10 ± 0.01; # absolute error, no approximation closure
my $y = 10 ± 0.1%; # same with relative error

10.001 == $x; # false because undecidable
10.001 ~~ $x; # true

The falsity of == is due to the fact that 10.001 is exact and therefore
the errors aren't the same. That is 10 ± 0.1 == 10 ± 0.01 is false
because their is no approximation closure to decrease the error on the
lhs. Num equality is a rare event! 9 ± 0.1  10 ± 0.1 is easily true
because 9.1  9.9. Even 10 ± 0.1 == 10 ± 0.1 could be false, so that
only exact values and values with the identical approximation closure
can be equal.  Assuming that the basic arithmetic operations are exact
because they use the Rat type the approximation system should manage to
have sqrt(2) / 2 == 1 / sqrt(2). I think that succeeds because the Rat
returned by sqrt(2) is the same, division preserves the relative error
and the approximation closure is the same.

The problem with the approximation closure is that it becomes more and
more complex during calculations. So we need to cut it off e.g. so that
it is at most one level deep. Also the error is than fixed at the level
of the input.

Another question is if we define some arithmetic on these closures
so that asin(sin(2)) == 2 exactly. I think this is doable by e.g. an
'is inverse' trait on code objects. This would allow asin to extract
the integer 2 from the sin approximation closure and return it. Pi
would be the identity of an approximation closure and it is not required
from an implementation to render sin($x) == sin($x + 2*pi) even though
it is imaginable if $x contains a Num that has pi as approximation
closure so that an exact modulo can be put into the approximation 
closure of sin's return value.



Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Daniel Ruoso
Em Qui, 2009-02-26 às 17:01 +0100, TSa escreveu:
  $y.error = 0.001;
  $x ~~ $y;

Looking at this I just started wondering... why wouldn't that be made
with:

  my $y = 10 but Imprecise(5%);
  $x ~~ $y;

daniel



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Jon Lang
TSa wrote:
 HaloO,

 Jon Lang wrote:

   �...@a[50%] # accesses the middle item in the list, since Whatever is
 set to the length of the list.

 I don't understand what you mean with setting Whatever. Whatever is
 a type that mostly behaves like Num and is used for overloaded
 postcircumfix:[ ]:(Array @self: Whatever $i). So *-1 just casts
 the -1. Postfix % would do the same for Ratio. Then one can overload
 postcircumfix[ ]:(Array @self: Ratio $r) and multiply $r with the
 size of the array to calculate the index. BTW, this indexing reminds
 me of the way how textures are indexd in OpenGL. With that in mind
 the index ratio could also interpolate between entries of a texture
 array.

I'm not certain about the exact mechanism to use; all I know for
certain is that I want a kind of dwimmery with postfix:% that
returns a percentage of some other value when it's reasonably easy to
decide what that other value should be, and a percentage of the number
one otherwise.  Perhaps that _is_ best handled by means of a Ratio
type (or whatever), perhaps not.  If so, I think that Rat (as in a
Rational Number) should be kept distinct from Ratio (as in a
portion of something else).  Perhaps the latter should be called a
Portion rather than a Ratio.

 So here comes some rant about Num as the type that in contrast to Rat
 carries an approximation error and an approximation closure that can be
 called to decrease the error. That is e.g. sqrt(2) returns such a thing
 that can be called again to continue the iteration. Numeric equality
 checks would then not only compare the approximate values but also the
 identity of the iteration closure. Whereas ~~ would check if the lhs
 number's interval falls into the range of the rhs which is build from
 the current approximation and the error. The approximation closure is
 never invoked by ~~. Infix ± would then not create a range but a Num
 with explicit error.

I'm not sold on the notion that Num should represent a range of values
(and I use range here in its mathematical sense of any number
that's between the given lower and upper bounds, as opposed to its
Perlish sense of a discrete list of numbers).  However, I _do_ like
the idea of distinguishing between is exactly equal to and is
approximately equal to; and tracking the margin of error would be
essential to getting the latter option to work.

 Another question is if we define some arithmetic on these closures
 so that asin(sin(2)) == 2 exactly.

I don't know how relevant this is; but this sounds like the sort of
optimization that pure functional programming allows for - that is, if
the compiler ever sees a call like asin(sin($x)), it might optimize
the code by just putting $x in there directly, and bypassing both the
sin and asin calls - but only because both sin and asin are pure
functions (i.e., they don't produce any side effects).

As well, I have a certain fondness for the idea of lazy evaluation of
mathematical functions (and pure functions in general), on the premise
that whenever you actually carry out an operation such as sqrt or sin,
you potentially introduce some error into the value with which you're
working; and if you postpone the calculation long enough, you may find
that you don't need to perform it at all (such as in the
aforementioned asin(sin(2)) example).

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Jon Lang
Daniel Ruoso wrote:
 Em Qui, 2009-02-26 às 17:01 +0100, TSa escreveu:
      $y.error = 0.001;
      $x ~~ $y;

 Looking at this I just started wondering... why wouldn't that be made
 with:

  my $y = 10 but Imprecise(5%);
  $x ~~ $y;

That's not bad; I like it.

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Brandon S. Allbery KF8NH

On 2009 Feb 26, at 13:00, Jon Lang wrote:

I'm not sold on the notion that Num should represent a range of values


Arguably a range is the only sane meaning of a floating point number.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Doug McNutt

I don't know how relevant this is; but this sounds like the sort of
optimization that pure functional programming allows for - that is, if
the compiler ever sees a call like asin(sin($x)), it might optimize
the code by just putting $x in there directly, and bypassing both the
sin and asin calls - but only because both sin and asin are pure
functions (i.e., they don't produce any side effects).


Don't get too hung up on that example.

If $x is 2*pi,  asin(sin($x)) would return 0.0 and not 2*pi.
--

-- From the U S of A, the only socialist country that refuses to admit it. --


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Jon Lang
Jon Lang wrote:
 TSa wrote:
 Jon Lang wrote:

   �...@a[50%] # accesses the middle item in the list, since Whatever is
 set to the length of the list.

 I don't understand what you mean with setting Whatever. Whatever is
 a type that mostly behaves like Num and is used for overloaded
 postcircumfix:[ ]:(Array @self: Whatever $i). So *-1 just casts
 the -1. Postfix % would do the same for Ratio. Then one can overload
 postcircumfix[ ]:(Array @self: Ratio $r) and multiply $r with the
 size of the array to calculate the index. BTW, this indexing reminds
 me of the way how textures are indexd in OpenGL. With that in mind
 the index ratio could also interpolate between entries of a texture
 array.

 I'm not certain about the exact mechanism to use; all I know for
 certain is that I want a kind of dwimmery with postfix:% that
 returns a percentage of some other value when it's reasonably easy to
 decide what that other value should be, and a percentage of the number
 one otherwise.  Perhaps that _is_ best handled by means of a Ratio
 type (or whatever), perhaps not.  If so, I think that Rat (as in a
 Rational Number) should be kept distinct from Ratio (as in a
 portion of something else).  Perhaps the latter should be called a
 Portion rather than a Ratio.

Another possible approach would be to define postfix:% as returning
a code block:

  sub postfix:%(Num $x) generates { $x / 100 * ($_ \\ 1.0) }

This would allow it to partake of nearly all of the same dwimmery of
which Whatever can partake, save for the purely Whatever stuff.

Brandon S. Allbery wrote:
 Jon Lang wrote:
 I'm not sold on the notion that Num should represent a range of values

 Arguably a range is the only sane meaning of a floating point number.

Perhaps; but a Num is not necessarily a floating point number - at
least, it shouldn't always be.

Doug McNutt wrote:
 Jon Lang wrote:
 I don't know how relevant this is; but this sounds like the sort of
 optimization that pure functional programming allows for - that is, if
 the compiler ever sees a call like asin(sin($x)), it might optimize
 the code by just putting $x in there directly, and bypassing both the
 sin and asin calls - but only because both sin and asin are pure
 functions (i.e., they don't produce any side effects).

 Don't get too hung up on that example.

 If $x is 2*pi,  asin(sin($x)) would return 0.0 and not 2*pi.

True enough: asin is not the inverse function of sin, although it's
probably as close as you can get.  And even there, some sort of
compiler optimization could potentially be done, replacing the
composition of asin and sin (both of which have the potential to
intensify error) with a normalization of the value into the -pi ..^ pi
range (which might also introduce error).

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Brandon S. Allbery KF8NH

On Feb 26, 2009, at 14:27 , Jon Lang wrote:

Jon Lang wrote:
Brandon S. Allbery wrote:

Jon Lang wrote:
I'm not sold on the notion that Num should represent a range of  
values


Arguably a range is the only sane meaning of a floating point number.


Perhaps; but a Num is not necessarily a floating point number - at
least, it shouldn't always be.


But that's not the point; it's can be that matters, not must be.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




Re: Comparing inexact values (was Re: Temporal changes)

2009-02-26 Thread Jon Lang
Martin D Kealey wrote:
 On Thu, 26 Feb 2009, Jon Lang wrote:
 asin is not the inverse function of sin, although it's probably as close
 as you can get.  And even there, some sort of compiler optimization could
 potentially be done, replacing the composition of asin and sin (both of
 which have the potential to intensify error) with a normalization of the
 value into the -pi ..^ pi range (which might also introduce error).

 Hmmm ... the normal mathematical range of arc-sine is (-π,+π], rather than
 [-π,+π), especially where complex numbers are concerned: arg(-1) == +π.
 (Well, so much for consistently using lower half-open ranges.)

...you're right.  Sorry; my error.

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-25 Thread TSa

HaloO,

Doug McNutt wrote:

Thinking about what I actually do. . .

A near equal test of a float ought to be a fractional error based on the 
current value of the float.


$x  tested for between $a*(1.0 + $errorfraction) and $a*(1.0 - 
$errorfraction)


I strongly agree that checking relative errors in floating point
algorithms is ubiquitous and thus the creation of relative
ranges deserves a dedicated operator. So I wanted to make the
heretic proposal to use % for that. That is

$x % $y;

to actually mean

$x * (1 - $y/100) ..^ $x * (1 + $y/100);

I think that this reads good for numeric matches:

if $x ~~ $y % 5 { say within five percent }

even though postfix % and infix ± read even better:

   if $x ~~ $y ± 5% { say within five percent }

and so I'm proposing to add these and 'within' as ASCII fallback
for ±.

The intended semantics could be achieved with postfix % returning
a Ratio type for which infix ± has an overloaded version that
creates a relative range as given above. Other operators that
don't have overloads for Ratio use it as a Num. This is much
easier than the closure generation with subsequent currying as
proposed by Larry elsewhere in this thread. This nicely allows

   $x += 5%;

to mean

   $x += $x * 0.05;

But defining the corresponding overloads of infix + is tricky
for infix:+:(Ratio,Num) because it could mean to increase the
Ratio and return a Ratio or ignore the Ratio type and return a
plain Num. I think the latter is saner.

BTW, in numerics one usually needs small values so we could have
a .ppm postfix operator that also returns a Ratio, albeit one
that is smaller by a factor of 1. Alternatively a triple
application of % gives the same ratio. And of course we should
have ‰ (promille) and ‱ (permyriad) as well. And when we are at
it .ppb and .ppt are common as well. At least Wikipedia has them.
There one also finds that ratios are expressed with the SI prefixes
like nano without a unit or U for uno. But I guess at the latest
this all belongs into a Ratio (standard?) module.

Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-25 Thread Mark J. Reed
I think the use of % for the modulus operator is too deeply ingrained
to repurpose its infix incarnation.

I do quite like the magical postfix %, but I wonder how far it should
go beyond ±:

$x += 5%;   # becomes $x += ($x * .05)?  Or maybe $x *= 1.05  ?
$x * 5%;   # becomes $x * .05 ?


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-25 Thread Jon Lang
Mark J. Reed wrote:
 I do quite like the magical postfix %, but I wonder how far it should
 go beyond ±:

 $x += 5%;   # becomes $x += ($x * .05)?  Or maybe $x *= 1.05  ?
 $x * 5%;   # becomes $x * .05 ?

If it works with ±, it ought to work with + and -.  Rule of thumb: if
there's no easy way to answer 5% of what? then default to 5% of
1.0, or 0.05.  +, -, and ± would need to be set up to provide the
necessary answer for of what? by means of setting Whatever; and by
basing it on Whatever, you have other options, such as:

@a[50%] # accesses the middle item in the list, since Whatever is
set to the length of the list.

--

Concerning - $val, $err { [..^] $val - $err, $val + $err } vs -
$val, $err { any $val - $err, $val + $err }: I'm not sold on the
notion that Huffman coding might imply that ± should go with the
former.  Perhaps an argument can be made for it; but I suspect that
the relative commonness of the two uses is extremely similar (which,
per Huffman coding, would imply that their names should have similar
lengths).  Whichever one we go with, we have a conundrum: if we use ±
as the name of the latter, the conundrum is that the only other
intuitive name for the former that has thus far been proposed (i.e.,
within) is too long; if we use ± as the name for the former, the
conundrum is that no other intuitive name has been proposed for the
latter.

So: what we need are proposals for short, understandable names for
each operator.  Suggestions?

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-25 Thread Doug McNutt

At 13:58 -0500 2/25/09, Mark J. Reed wrote:

I do quite like the magical postfix %, but I wonder how far it should
go beyond ±:

$x += 5%;   # becomes $x += ($x * .05)?  Or maybe $x *= 1.05  ?
$x * 5%;   # becomes $x * .05 ?


For ratio-like comparisons for effective equality of floats some
thought might be given to operating on the mantissa part of the IEEE
float. For normalized floats it's possible to get nearly equal tests
by simply truncating the mantissa at some number of bits and
comparing the floats as longs for equality. I suspect most technical
users would have no problem in specifying a number of significant
bits. They certainly can do it with decimal digits. Rounding from 52
to, say, 16 bits ought to be easy in binary.

But then with everyone using processors with  floating point hardware
the efficiency might not be important.

--
-- Marriage and kilo are troubled words. Turmoil results when
centuries-old usage is altered in specialized jargon --.


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-25 Thread Larry Wall
On Wed, Feb 25, 2009 at 02:34:50PM -0800, Jon Lang wrote:
: Mark J. Reed wrote:
:  I do quite like the magical postfix %, but I wonder how far it should
:  go beyond ±:
: 
:  $x += 5%;   # becomes $x += ($x * .05)?  Or maybe $x *= 1.05  ?
:  $x * 5%;   # becomes $x * .05 ?
: 
: If it works with ±, it ought to work with + and -.  Rule of thumb: if
: there's no easy way to answer 5% of what? then default to 5% of
: 1.0, or 0.05.  +, -, and ± would need to be set up to provide the
: necessary answer for of what? by means of setting Whatever; and by
: basing it on Whatever, you have other options, such as:
: 
: @a[50%] # accesses the middle item in the list, since Whatever is
: set to the length of the list.

Coolness.

: Concerning - $val, $err { [..^] $val - $err, $val + $err } vs -
: $val, $err { any $val - $err, $val + $err }: I'm not sold on the
: notion that Huffman coding might imply that ± should go with the
: former.  Perhaps an argument can be made for it; but I suspect that
: the relative commonness of the two uses is extremely similar (which,
: per Huffman coding, would imply that their names should have similar
: lengths).  Whichever one we go with, we have a conundrum: if we use ±
: as the name of the latter, the conundrum is that the only other
: intuitive name for the former that has thus far been proposed (i.e.,
: within) is too long; if we use ± as the name for the former, the
: conundrum is that no other intuitive name has been proposed for the
: latter.
: 
: So: what we need are proposals for short, understandable names for
: each operator.  Suggestions?

I'm not sure we should give up on unification so soon.  Hmm.

Here's another approach.  Suppose we define

$a ± $b

to mean something

$a ..^ $b :interval

and :interval causes the Range object to return $a and $b in list
context.  Then, since any() supplies list context, we could write

if $x == any($a ± $b) {...}

That seems a bit ugly though.  Another way would be to define ± as
simple half-open Range and then overload comparison:

multi sub infix:==(Num $x,Range $r) {
$x == any($r.minmax);
}

Of course, that would potentially introduce a failure mode where
people say == when they mean ~~, or vice versa.  Maybe that wouldn't
be a big problem in practice.

Larry


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Larry Wall
On Mon, Feb 23, 2009 at 11:54:44PM -0600, Chris Dolan wrote:
 On Feb 23, 2009, at 11:16 PM, Larry Wall wrote:

 if $x ~~ $y ± $epsilon {...}

 where infix:± turns the single value into a range for the  
 smartmatch.


 That's very cool.  However, my first impression is that $y ± $epsilon 
 maps more naturally to any($y-$epsilon, $y+$epsilon) than to a range.

I'm using ±  more in the engineering sense than the mathematical sense.
Maybe there's some way to finesse it to mean both, though I suspect
any such scheme would make it difficult to catch brainos.  If there's
a subtle distinction between

if $x ~~ $y ± $epsilon {...}

and

if $x == $y ± $epsilon {...}

then it will be sure to trip people up.

It would be possible to make it a method:

if $x ~~ $y.within($epsilon)

but that does late binding, too late to give info to the optimizer.
The adverbial solution might or might not have the same problem.
In any case, adverbs on operators tend to be a design smell.

So it might be better as a (very tight?) operator, regardless of
the spelling:

$x ~~ $y within $epsilon

For what it's worth, ± does happen to be in Latin-1, and therefore
officially fair game for Standard Perl.  By the way, the mathematical
definition can be derived from the engineering definition with

if $x == ($x ± $epsilon).minmax.any

The problem with defining it the other direction is that junctions
tend to lose ordering information of their eigenstates, and we can't
just flip mins and maxes when we feel like it, or degenerate null
ranges get broken.

Larry


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread TSa (Thomas Sandlaß)
On Tuesday, 24. February 2009 17:59:31 Larry Wall wrote:
 So it might be better as a (very tight?) operator, regardless of
 the spelling:

 $x ~~ $y within $epsilon

This is a pretty add-on to smartmatch but I still think
we are wasting a valueable slot in the smartmatch table
by making numeric $x ~~ $y simply mean $x == $y. What
is the benefit?


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Geoffrey Broadwell
On Tue, 2009-02-24 at 12:31 -0800, Jon Lang wrote:
   $y ± 5  # same as ($y - 5) | ($y + 5)
   $y within 5 # same as ($y - 5) .. ($y + 5)

Oh, that's just beautiful.


-'f




Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Jon Lang
Daniel Ruoso wrote:
 What about...

  if $x ~~ [..] $x ± $epsilon {...}

 That would mean that $x ± $epsilon in list context returned each value,
 where in scalar context returned a junction, so the reduction operator
 could do its job...

(I'm assuming that you meant something like if $y ~~ [..] $x ±
$epsilon {...}, since matching a value to a range that's centered on
that value is tautological.)

Junctions should not return individual values in list context, since
it's possible for one or more of said values to _be_ lists.  That
said, I believe that it _is_ possible to ask a Junction to return a
set of its various values (note: set; not list).  Still, we're already
at a point where:

  if $y ~~ $x within $epsilon {...}

uses the same number of characters and is more legible.  _And_ doesn't
have any further complications to resolve.

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Daniel Ruoso
Em Ter, 2009-02-24 às 13:34 -0800, Jon Lang escreveu:
 Daniel Ruoso wrote:
   if $y ~~ [..] $x ± $epsilon {...}
 Junctions should not return individual values in list context,

It is not the junction that is returning the individual values, but the
infix:± operator...

daniel



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Jon Lang
TSa wrote:
 Larry Wall wrote:
 So it might be better as a (very tight?) operator, regardless of
 the spelling:

     $x ~~ $y within $epsilon

 This is a pretty add-on to smartmatch but I still think
 we are wasting a valueable slot in the smartmatch table
 by making numeric $x ~~ $y simply mean $x == $y. What
 is the benefit?

Larry's suggestion wasn't about ~~ vs. ==; it was about within as an
infix operator vs. within as a method or an adverb.

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Jon Lang
On Tue, Feb 24, 2009 at 1:39 PM, Daniel Ruoso dan...@ruoso.com wrote:
 Em Ter, 2009-02-24 às 13:34 -0800, Jon Lang escreveu:
 Daniel Ruoso wrote:
   if $y ~~ [..] $x ± $epsilon {...}
 Junctions should not return individual values in list context,

 It is not the junction that is returning the individual values, but the
 infix:± operator...

Hmm... true point.  Thinking through it some more, I'm reminded of an
early proposal to do something similar with square roots in
particular, and with non-integer exponents in general.  e.g., sqrt(4)
=== ±2.  IIRC, the decision was made that such a capability would
work best as part of an advanced math-oriented module, and that things
should be arranged such that sqrt($x).[0] in that advanced module
would be equivalent to sqrt($x) in Perl's default setting.  That would
mean that sqrt(4) would have to produce (+2, -2) in list context,
rather than (-2, +2) - which, in turn, would mean that ±2 should do
likewise.  And however prefix:± works, infix:± should follow suit,
returning addition first and subtraction second.

Which would further mean that you should use the reversal metaoperator as well:

  if $y ~~ [R..] $x ± $epsilon {...}

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Doug McNutt

Thinking about what I actually do. . .

A near equal test of a float ought to be a fractional error based on 
the current value of the float.


$x  tested for between $a*(1.0 + $errorfraction) and $a*(1.0 - $errorfraction)

If you're dealing with propagation of errors during processing of 
data the fractional error is usually the one that's important. 
Finances might be different  but floating dollars have their own set 
of problems relating to representation of decimal fractions.

--

-- A fair tax is one that you pay but I don't --


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Jon Lang
Doug McNutt wrote:
 Thinking about what I actually do. . .

 A near equal test of a float ought to be a fractional error based on the
 current value of the float.

 $x  tested for between $a*(1.0 + $errorfraction) and $a*(1.0 -
 $errorfraction)

 If you're dealing with propagation of errors during processing of data the
 fractional error is usually the one that's important. Finances might be
 different  but floating dollars have their own set of problems relating to
 representation of decimal fractions.

Half-baked idea here: could we somehow use some dwimmery akin to
Whatever magic to provide some meaning to a postfix:% operator?
Something so that you could say:

  $x within 5%

And it would translate it to:

  $x within 0.05 * $x

?

Something along the lines of:

1. infix:within sets Whatever to its lhs while evaluating its rhs
2. postfix:% returns the requested percentage of Whatever; if
Whatever is undefined, return the requested percentage of 1.

-- 
Jonathan Dataweaver Lang


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Larry Wall
On Tue, Feb 24, 2009 at 04:54:35PM -0800, Jon Lang wrote:
: Half-baked idea here: could we somehow use some dwimmery akin to
: Whatever magic to provide some meaning to a postfix:% operator?
: Something so that you could say:
: 
:   $x within 5%
: 
: And it would translate it to:
: 
:   $x within 0.05 * $x
: 
: ?
: 
: Something along the lines of:
: 
: 1. infix:within sets Whatever to its lhs while evaluating its rhs
: 2. postfix:% returns the requested percentage of Whatever; if
: Whatever is undefined, return the requested percentage of 1.

The semantic magic is trivial; what we'd say is that if Cwithin has
a 1-ary closure for its right argument, it calls that with its left
argument to calculate the epsilon.  The syntactic magic is another
matter.  We could easily define postfix:% that just translates 5% to
{ 0.05 * $_ }, but we'd have to weigh that against the infix use of %.
So basically it could be done, but we'd have to require whitespace
on the infix:% form.

Interestingly, though, assuming we have multies for Code:($) as well
as as Whatever, things like $x * 5% would also work automatically.
Which we'll probably have anyway, if we want things like

grep (* % 3) == 1, @list

to work.  It basically looks like Whatever is mutating into a
mechanism for currying 1-ary functions, though of course it won't
work if you try to curry infix:.. with it, or any other operator
that treats Whatever idiosyncratically.  You'd basically have to
know which operators Do What You Mean, which could be construed as an
arbitrary list.  Makes me wonder if this is one of those new mistakes
we're trying to make with Perl 6.  :)

But my gut-level feel is that, although this is a feature that
you can easily shoot your foot off with, the actual code comes
out quite readable.  And I think people can pretty easily learn
the default transformation of (* op 42) to { $_ op 42 }.  On the other
hand, * is so hardwired in to our consciences as wildcarding and
quantifying that constructs like abc xx * also look natural.

So I'm gambling that this is a new mistake we want to make.  The
alternative would be to create a different way of writing simple
closures, but we already have that in { $_ op 42 } if you want it.

I do very much like the fact that, unlike in Haskell, you curry
with an explicit placeholder, not by leaving things out.  (Of course,
this is a requirement in Perl anyway because its parser depends
heavily on term/infix alternation.)

Larry


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Martin D Kealey
On Tue, 24 Feb 2009, Jon Lang wrote:
   $y ± 5  # same as ($y - 5) | ($y + 5)
   $y within 5 # same as ($y - 5) .. ($y + 5)

I suspect that we're running against Huffman here, given the likely
usage -- ranges *should* be used at pretty much every floating point
equality test, whereas any(-x,+x) would mostly be useful for
expressing solutions to polynomials.

Perhaps we could define infix:± as a range generator and prefix:± as a
set generator:

  $y + ±5   # same as ($y - 5) | ($y + 5) (also same as $y - ±5)
  $y ± 5# same as ($y - 5) .. ($y + 5)

-Martin


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread Martin D Kealey
On Wed, 25 Feb 2009, I wrote:
   $y + ±5   # same as ($y - 5) | ($y + 5)   (also same as $y - ±5)
   $y ± 5# same as ($y - 5) .. ($y + 5)

A further question: should such ranges be [closed], (open) or [half-open)?

I would argue for half-open because then exactly one of a set of consecutive
ranges will match; back to the original question, I'd only expect one match
from:

$time ~~ $date-yesterday
$time ~~ $date-today
$time ~~ $date-tomorrow

even if $time falls precisely on midnight.

-Martin


Comparing inexact values (was Re: Temporal changes)

2009-02-23 Thread David Green

On 2009-Feb-23, at 10:09 am, TSa wrote:

I also think that time and numbers in general should be treated in
a fuzzy way by smart match.


My thought is to have == take a :within adverb, at least for imprecise  
types like Num, that could be used to specify how close values need to  
come in order to be considered equal.


So instead of:
if abs($x-$y)$epsilon { ... }

you could say:
if $x==$y :within($epsilon) { ... }

which makes your tests for equality look like tests for equality.

I'd even suggest that the :within be mandatory, to guarantee that the  
coder is aware that $x==$y is probably not DWIM.  Of course, there  
should also be an easy way to set epsilon across a scope, like:


use Num :precision(0);# force exact matches in this block



-David



Re: Comparing inexact values (was Re: Temporal changes)

2009-02-23 Thread Larry Wall
On Mon, Feb 23, 2009 at 09:08:39PM -0700, David Green wrote:
 On 2009-Feb-23, at 10:09 am, TSa wrote:
 I also think that time and numbers in general should be treated in
 a fuzzy way by smart match.

 My thought is to have == take a :within adverb, at least for imprecise  
 types like Num, that could be used to specify how close values need to  
 come in order to be considered equal.

 So instead of:
 if abs($x-$y)$epsilon { ... }

 you could say:
 if $x==$y :within($epsilon) { ... }

 which makes your tests for equality look like tests for equality.

 I'd even suggest that the :within be mandatory, to guarantee that the  
 coder is aware that $x==$y is probably not DWIM.  Of course, there  
 should also be an easy way to set epsilon across a scope, like:

 use Num :precision(0);# force exact matches in this block

Or just:

if $x ~~ $y ± $epsilon {...}

where infix:± turns the single value into a range for the smartmatch.

Larry