Re: Comparing inexact values (was "Re: Temporal changes")
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")
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.) -Martin
Re: Comparing inexact values (was "Re: Temporal changes")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
On Wed, Feb 25, 2009 at 07:03:27PM +1300, Martin D Kealey wrote: : 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) That seems a little cheesy to me. : 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. Half-open, certainly, so really same as ($y - 5) ..^ ($y + 5). Larry
Re: Comparing inexact values (was "Re: Temporal changes")
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
Re: Comparing inexact values (was "Re: Temporal changes")
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")
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: 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 C 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")
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: 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")
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")
On Tue, Feb 24, 2009 at 1:39 PM, Daniel Ruoso 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")
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")
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")
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")
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")
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")
Em Ter, 2009-02-24 às 08:59 -0800, Larry Wall escreveu: > I'm using ± more in the engineering sense than the mathematical > sense. 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... daniel
Re: Comparing inexact values (was "Re: Temporal changes")
Larry Wall wrote: > So it might be better as a (very tight?) operator, regardless of > the spelling: > > $x ~~ $y within $epsilon I like this: it's readable and intuitive. As well, it leaves ± available for use in its mathematical sense. > 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. OTOH, there aren't going to be very many cases where you're going to want to derive either from the other. You're more likely to derive both from the same base stock: $y ± 5 # same as ($y - 5) | ($y + 5) $y within 5 # same as ($y - 5) .. ($y + 5) -- Jonathan "Dataweaver" Lang
Re: Comparing inexact values (was "Re: Temporal changes")
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")
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. Chris
Re: Comparing inexact values (was "Re: Temporal changes")
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
Comparing inexact values (was "Re: Temporal changes")
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