Re: Synopsis 02: Range objects
HaloO, Jon Lang wrote: '' and '=' numify their arguments before comparing them. 'lt' and 'le' stringify their arguments before comparing them. 'before' compares its arguments without any coercion. Note that there's no equivalent to '='. This last one is !after and !before is '='. 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: Synopsis 02: Range objects
On Mon, Aug 31, 2009 at 12:42 AM, TSa thomas.sandl...@vts-systems.de wrote: HaloO, Jon Lang wrote: '' and '=' numify their arguments before comparing them. 'lt' and 'le' stringify their arguments before comparing them. 'before' compares its arguments without any coercion. Note that there's no equivalent to '='. This last one is !after and !before is '='. Only when total ordering is involved. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
On 2009-Aug-27, at 3:11 pm, Mark J. Reed wrote: Given how easy chained relational ops make explicit range checking with endpoints, e.g. $a = $x = $b I'd be perfectly happy with a Range smartmatching only the elements that you get out of the RangeIterator. Yes -- although sometimes that would require separating out the $a and the $b parts, which is why having something to mean between would be handy. On 2009-Aug-27, at 11:08 am, TSa wrote: Note that order is not a prerequisite for a notion of range and range iteration. I think of ranges more like set and set iteration. Except the meaning of the word range and the spec both indicate order: (S03) A star on both sides prevents any type from being inferred other than the COrdered role. Instead, can't the existing series operator take on the series aspects of ..? ... can take a function on the RHS that generates new values, or it can take * to generate an arithmetic or geometric sequence. If only a single value is given as the LHS, it could use .succ, so 1...* or a...* would work like C.. does. I think the reason C... doesn't take a value other than * as the RHS is because of the problem of how to figure out whether the series will ever reach that value or not. But that's easy to figure out in the case of an arithmetic or geometric sequence, so 1, 3, 5 ... 99 should be OK, and 1, 3, 5 ... 100 should probably be an error. Maybe * || 100 as an endpoint could mean go on forever or until hitting this value. Similarly, it's simple to figure out whether .succ applied to strings will reach the endpoint or not. For an arbitrary function, it's not so easy. However, each type could have a you can't get there from here function for figuring out whether an endpoint is part of a series or not; if the endpoint passes that test, then you can use it; if it doesn't, or if there is no such function that can tell you, the only valid endpoint is *. The :by adverb as applied to C... could take a value, which would be added (or handled according to the appropriate type when not dealing with Nums) just like it was with ..; or :by could take a block, which would run that function. So 1 ... {foo} would be short for 1 ... *||Nil :by({foo}). This way all the series stuff is gathered together, and a Range can simply represent a pair of starting and ending points without trying to be a list iterator as well. I expect its main use would be meaning between: $foo ~~ $range. If a Range is not a Series, then there's no confusion as to whether being in the range means being in the series or not. S03: Alternately, we could treat an ellipsis as special when it follows a comma to better support traditional math notation. That seems like an easy mistake to make, so treating it specially would be a good quirk. -David
Re: 1.23 becomes Rat (Re: Synopsis 02: Range objects)
Karl == Karl Brodowsky lis...@brodowsky.com writes: Karl - or should there be a new numeric type similar to Rat that is always Karl having powers of 10 as denominator (like BigDecimal in Java or Karl LongDecimal for Ruby or decimal in C# or so)? If so, please use something compatable with ieee 754 decimal floats, so that they can be used when running on hardware which supports them. Even w/o such hardware, gcc (at least) has support for software emulation of _Decimal32 and _Decimal64 (and _Decimal128?). -JimC -- James Cloos cl...@jhcloos.com OpenPGP: 1024D/ED7DAEA6
Re: Synopsis 02: Range objects
Michael == Michael Zedeler mich...@zedeler.dk writes: Michael The Range 1.0001 .. 2.15 makes sense as an interval definition, but Michael there can hardly be a useful list definition without defining a step Michael size, at least, making it possible to use step sizes less than one. The obvious (default) choice for a step size would be the precision of the more precise of the two values. So 0.0001 in your example above. Michael Well... maybe. How do you specify the intended precision, then? If I Michael want the values from 1 to 2 with step size 0.01, I guess that writing Michael 1.00 .. 2.00 The parser would have to note the precision as represented. On systems which have ieee-754 decimal floats that will be automatic (1., 1.0, 1.00, etc all have different representations in 754 decimal floats); it would not be a bad idea for Perl to keep track of that for all numerics. Complex .. Complex should have a defined meaning in p6. Michael there is no natural ordering of complex numbers, and without Michael some ordering, you may be able to decide what should be in the Michael list to return, but not which order to use. [I'm merging stuff here.] Indeed, for interval arith it isn't ordering but inclusion which is relevant. If order is of value, it seems that it would have to be imposed. I can imagine that some people will want to zigzag from the point closest to (−∞,−∞) to the point closest to (+∞,+∞), whereas others might prefer to start at the point with the least r, sweeping θ through either [0°,360°) or (−π,π] or [−π,π) or Michael I believe that anything we put into Perl 6 should have obvious Michael use cases and fall natural into place in the domain that the Michael construct in question belongs to. That is reasonable. Michael but I must admit that I'd prefer if Complex .. Complex was left Michael undefined in the Perl 6 core, leaving it up to anyone to Michael specify it later. BTW, it I should have written a disc with diameter running between the two points rather than specifying an enclosing circle. It is true that when I think of p6, I think of more than core. But I would like support for interval arithmetic as ingrained in the p6 culture as, say, regexps. The set of problems which would benefit from widespread use of efficient interval techniques is significant. All that said, it may be the case that the .. syntax, though useful for specifying intervals, may not be preferred by those doing such coding. The may prefer a ± syntax, or something like ΤεΧ’s strech and shrink syntax for glue. -JimC -- James Cloos cl...@jhcloos.com OpenPGP: 1024D/ED7DAEA6
Re: Synopsis 02: Range objects
On Thursday, 27. August 2009 23:58:51 Jon Lang wrote: It might also be nice to have a stringifying version; perhaps 'be', using the same everything's an acronym naming convention used by other stringifying operators (e.g., 'lt' is less than, 'le' is 'less than or equal to', 'leg' is less than, equal to, greater than) - in this case, 'be' would be 'beginning to end'. At the very least, this would avoid the inevitable questions about why there isn't a stringifying version. :) That said, it may not be good for much more than that. Yeah, sometimes orthogonality of features is too much of a good thing! 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: Synopsis 02: Range objects [recap]
Timothy S. Nelson wrote: I think a Complex range only makes sense if you provide 4 endpoints, not 2, but I haven't been following the conversation, so I'll leave it up to the Complex number experts :). (start-angle, start-length) :by(angle-step, length-factor) -- Ruud
Re: Synopsis 02: Range objects [recap]
Jon Lang wrote: Michael Zedeler wrote: Proposed changes: It shouldn't be possible to construct RangeIterators over Str (apart from single length strings) or Complex using the Range operator (..). I'd go one step further with Complex, to say that Range isn't a useful concept at all so long as before and after are undefined. Agreed. I should have written that as part of the proposal as well. As for Str, I'm not sure that we should go so far as to say that you _can't_ create RangeIterators over them, so much as to say that the default step algorithm is defined only for single-character strings, and fails if you give it anything else. In particular, the programmer should be allowed to enable Str-based RangeIterators by explicitly supplying his own step algorithm. That is: 'aa' .. 'zz' # Error in list context: default stepper rejects multi-character endpoints 'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns The difference between this and the triple dot-operator is that we provide an upper bound (and are forced to use the :by-adverb). Is it worth the while? Next open question: What about Ranges using different types in each endpoint? 1.5 .. 10 :by(0.5) (Rat .. Int) 0 .. 7 Should they be coerced - and in that case to what? If we don't coerce them, what should be returned? This is only a half-formed thought at the moment, so please bear with me: maybe Ranges should extend the triptych that exists with comparison operators. That is, you have before and after, lt and gt, and and ; you also have cmp, leg, and =. Perhaps .. should be treated as the numeric operator, and equivalent Str and generic operators should be supplied separately. I'd be inclined to spell the generic Range operator - the one corresponding to before/after/cmp - as to. I'm not sure how the Str-based one ought to be spelled. With .., there should be automatic coercion of both endpoints to numbers, just as there is with and . With to, there should be no coercion at all, just like before after, and cmp. And just like .. should nummify, the to operator should stringify? Sounds nice. Regards, Michael.
Re: Synopsis 02: Range objects
Karl Brodowsky wrote: Michael Zedeler schrieb: Well... maybe. How do you specify the intended precision, then? If I want the values from 1 to 2 with step size 0.01, I guess that writing 1.00 .. 2.00 won't be sufficient. Trying to work out the step size by looking at the precision of things that are double or floats doesn't really sound so feasible, since there are a lot of holes in the actual representation, so 1.0001 may become 1.0, yielding very different results. That is a general problem of floats. We tend to write them in decimal notation, but internally they use a representation which is binary. And it is absolutely not obvious what the precision of 1.0001 might be. There could be a data type like LongDecimal in Ruby or BigDecimal in Java, that actually has a knowlegde of its precision and whose numbers are fractions with a power of 10 as the denominator. But for floats I would only see the interval as reasonably clear. Even a step of 1 is coming with some problems, because an increment of 1 does not have any effect on floating point numbers like 1.03e300 or so. Yes. Exactly my point. By the way, do we want to warn if someone writes 1e300 .. 1e301 :by(1) given that the number implementation yields 1e300 + 1 == 1e300? Regards, Michael.
Re: Synopsis 02: Range objects
Shouldn't it autopromote to Bignum at that point? On 8/27/09, Michael Zedeler mich...@zedeler.dk wrote: Karl Brodowsky wrote: Michael Zedeler schrieb: Well... maybe. How do you specify the intended precision, then? If I want the values from 1 to 2 with step size 0.01, I guess that writing 1.00 .. 2.00 won't be sufficient. Trying to work out the step size by looking at the precision of things that are double or floats doesn't really sound so feasible, since there are a lot of holes in the actual representation, so 1.0001 may become 1.0, yielding very different results. That is a general problem of floats. We tend to write them in decimal notation, but internally they use a representation which is binary. And it is absolutely not obvious what the precision of 1.0001 might be. There could be a data type like LongDecimal in Ruby or BigDecimal in Java, that actually has a knowlegde of its precision and whose numbers are fractions with a power of 10 as the denominator. But for floats I would only see the interval as reasonably clear. Even a step of 1 is coming with some problems, because an increment of 1 does not have any effect on floating point numbers like 1.03e300 or so. Yes. Exactly my point. By the way, do we want to warn if someone writes 1e300 .. 1e301 :by(1) given that the number implementation yields 1e300 + 1 == 1e300? Regards, Michael. -- Sent from my mobile device Mark J. Reed markjr...@gmail.com
Re: Synopsis 02: Range objects [recap]
On Thu, Aug 27, 2009 at 2:59 AM, Jon Langdatawea...@gmail.com wrote: Michael Zedeler wrote: Jon Lang wrote: As for Str, I'm not sure that we should go so far as to say that you _can't_ create RangeIterators over them, so much as to say that the default step algorithm is defined only for single-character strings, and fails if you give it anything else. In particular, the programmer should be allowed to enable Str-based RangeIterators by explicitly supplying his own step algorithm. That is: 'aa' .. 'zz' # Error in list context: default stepper rejects multi-character endpoints 'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns The difference between this and the triple dot-operator is that we provide an upper bound (and are forced to use the :by-adverb). Is it worth the while? It _does_ give you an upper bound, which ... doesn't do. This is only a half-formed thought at the moment, so please bear with me: maybe Ranges should extend the triptych that exists with comparison operators. That is, you have before and after, lt and gt, and and ; you also have cmp, leg, and =. Perhaps .. should be treated as the numeric operator, and equivalent Str and generic operators should be supplied separately. I'd be inclined to spell the generic Range operator - the one corresponding to before/after/cmp - as to. I'm not sure how the Str-based one ought to be spelled. With .., there should be automatic coercion of both endpoints to numbers, just as there is with and . With to, there should be no coercion at all, just like before after, and cmp. And just like .. should nummify, the to operator should stringify? Sounds nice. No. Technically, there should be three versions: a generic version that does no coercion; the version that nummifies; and the version that stringifies. I can only think of two names to use; so unless someone else can come up with a viable third name, we have to do without one of the three. The one that stringifies is the most expendible, since one can always explicitly stringify when no coercion is implicitly done, but there's no way _not_ to stringify if it _is_ implicitly done. And stringified ranges aren't nearly as important to have as numified ones are. -- Jonathan Dataweaver Lang -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
HaloO, David Green wrote: For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? I see no problem when a Range matches for values which are not produced by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is not in 1,2,3,4,5. The same applies for 'aaa' ~~ 'aa'..'az'. I find this quite natural. Note that order is not a prerequisite for a notion of range and range iteration. I think of ranges more like set and set iteration. I'm going to post my take on the complex case elsewhere in this thread. 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: Synopsis 02: Range objects
HaloO, Michael Zedeler wrote: James Cloos wrote: Michael Complex .. Complex - undef, exception or some other bad thing. Complex .. Complex should have a defined meaning in p6. A definition which is easy to compute would be the set of points contained by the square which has opposite corners at the two specified points. We should not think of complex ranges as areas. The thing used in complex analysis is the path along which you integrate. OTOH circles are the two dimensional equivalents of intervals. But is that useful? Complex numbers are mostly for mathematics, so I guess we have to look in that domain for a good use case. In that domain there is no natural ordering of complex numbers, and without some ordering, you may be able to decide what should be in the list to return, but not which order to use. I have stated elsewhere that order is not necessary. A notion of distance suffices. The direction of iteration is well defined by the complex step size. I believe that anything we put into Perl 6 should have obvious use cases and fall natural into place in the domain that the construct in question belongs to. This means we have to come up with a design (there currently is no specification of Complex .. Complex), some kind of use case to as justification and finally a validation that ensures that the design is consistent with other things in the language. The complex case should result in the numeric case when given real numbers as bounds and step size. So my proposal for complex range iteration is to use complex addition to generate the next candidate and complex distance to check whether it is closer to the endpoint or not. The only drawback I see is that 1.2 .. 5 then iterates up to 5.2 not 4.2 as in the order based approach. But I don't consider this a bad outcome because the endpoint isn't hit in both cases and 5.2 is closer ;) Applying the above metric procedure to complex range matches is however a bit more problematic because the direction from start to end is not necessarily the same as that given by the step size. Since the step size should be ignored in real matches we should do so in the complex case as well and check whether the number in question lies on the line from start to end. Problem is how accurate this check shall be. IOW, what is the line width of the range? I would add an eps parameter to the range creating operator with a default around 1e-10. This would be useful for real ranges with excluded ends as well. Actually this parameter should be a relative error not an absolute one. Another idea is to make matches succeed in the intersection of the two circles around the endpoints through the other endpoint. E.g. then 2+i ~~ 1..3 is true and 2+2i ~~ 1..3 is false. This works for reals such that 1..3 is the intersection of -1..3 and 1..5 which are the one dimensional circles of radius 2 around 1 and 3 respectively. Note that this metric definition of interval can be generalized to vector spaces of arbitrary dimension where one intersects hyperspheres around two points. One can also generalise to non-euclidean metrics, of course. Perhaps even a string distance function might work. 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
1.23 becomes Rat (Re: Synopsis 02: Range objects)
Larry Wall wrote: Another note, it's likely that numeric literals such as 1.23 will turn into Rats rather than Nums, at least up to some precision that is pragmatically determined. Doing these as Rat would avoid a lot of the precision issues that floating point arithmetic has all the time. It will actually work perfectly well with addition, because the denominator is always a small power of 10, so that is true for the sum as well. Multiplying might be an issue, because the denominator becomes a large power of 10, but I think that that can be handled pretty well, unless the multiplication is really performed to an extent that the result uses significant amounts of memory. But as soon as division is occuring, these rational numbers tend to develop denominators that are not powers of 10 any more. Combining this with some multiplications and additions this may result in huge numerators and denominators that are somewhat expensive to handle. So what would happen after such a long calculation: - would the Rats somehow know that they are all derived from Rats that were just used instead of floats because of being within a pragmatically determined precision? Then the result of * or / could just as pragmatically become a floating point number? - would the Rats grow really huge numerators and denominators, making it expensive to work with them? - would the first division have to deal with the conversion from Rat to floating point? - or should there be a new numeric type similar to Rat that is always having powers of 10 as denominator (like BigDecimal in Java or LongDecimal for Ruby or decimal in C# or so)? Even in this last case the division is not really easy to define, because the exact result cannot generelly be expressed with a denomonator that is a power of 10. This can be resolved by: - requires additional rounding information (so writing something like a.divide(b, 10, ROUND_UP) or so instead of a/b - implicitely find the number of significant digits by using partial derivatives of f(x,y)=x/y - express the result as some kind of rational number - express the result as some kind of floating point number. Regards Karl
Re: Synopsis 02: Range objects
TSa wrote: HaloO, David Green wrote: For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? I see no problem when a Range matches for values which are not produced by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is not in 1,2,3,4,5. I suspect that the double meaning of Ranges is going to confuse some people and bite others. If things stay as they are, I hope that the use of :by will be flagged as a syntax error if used in literal Range smart matching. Of course, that doesn't help the unsuspecting when variables are being used, ala 2.5 ~~ $myrange. (For the record, 2.5 ~~ '!'..5 is also true on my system, although I don't know why! I certainly wouldn't expect it though :) The same applies for 'aaa' ~~ 'aa'..'az'. I find this quite natural. Not sure if you're saying that's something you'd like or if you think that that's something already there. It doesn't match for me using recent(ish) Rakudo. Of course, that could just be me! :) I'd personally prefer it if Ranges just did lists, including when smart matching, but had an interval method or such like for explicit matching against the endpoints, e.g. 2.5 ~~ interval(1..5) # or 2.5 ~~ $myrange.interval I'm new in town though, so I'll happily admit that I don't know the full implications of such a change. Having context-insensitive Ranges DWIM's better to me, but DWIMery, like beauty, is clearly in the eye of the beholder! :) Cheers, -- smuj
Re: Synopsis 02: Range objects
Given how easy chained relational ops make explicit range checking with endpoints, e.g. $a = $x = $b Imd be perfectly happy with a Range smartmatching only the elements that you get out of the RangeIterator. On 8/27/09, smuj s...@iol.ie wrote: TSa wrote: HaloO, David Green wrote: For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? I see no problem when a Range matches for values which are not produced by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is not in 1,2,3,4,5. I suspect that the double meaning of Ranges is going to confuse some people and bite others. If things stay as they are, I hope that the use of :by will be flagged as a syntax error if used in literal Range smart matching. Of course, that doesn't help the unsuspecting when variables are being used, ala 2.5 ~~ $myrange. (For the record, 2.5 ~~ '!'..5 is also true on my system, although I don't know why! I certainly wouldn't expect it though :) The same applies for 'aaa' ~~ 'aa'..'az'. I find this quite natural. Not sure if you're saying that's something you'd like or if you think that that's something already there. It doesn't match for me using recent(ish) Rakudo. Of course, that could just be me! :) I'd personally prefer it if Ranges just did lists, including when smart matching, but had an interval method or such like for explicit matching against the endpoints, e.g. 2.5 ~~ interval(1..5) # or 2.5 ~~ $myrange.interval I'm new in town though, so I'll happily admit that I don't know the full implications of such a change. Having context-insensitive Ranges DWIM's better to me, but DWIMery, like beauty, is clearly in the eye of the beholder! :) Cheers, -- smuj -- Sent from my mobile device Mark J. Reed markjr...@gmail.com
Re: Synopsis 02: Range objects
smuj wrote: TSa wrote: HaloO, David Green wrote: For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? I see no problem when a Range matches for values which are not produced by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is not in 1,2,3,4,5. I suspect that the double meaning of Ranges is going to confuse some people and bite others. If things stay as they are, I hope that the use of :by will be flagged as a syntax error if used in literal Range smart matching. Of course, that doesn't help the unsuspecting when variables are being used, ala 2.5 ~~ $myrange. Another possibility is that literal Range smartmatching works as is in the absence of :by (that is, with a Range), but becomes a set membership test in its presence (i.e., with a RangeIterator). Or not; see below. (For the record, 2.5 ~~ '!'..5 is also true on my system, although I don't know why! I certainly wouldn't expect it though :) One explanation would be that it's comparing the String 2.5 to the String-terminated Range !..5. Since 2 falls between ! and 5, so does 2.5. The same applies for 'aaa' ~~ 'aa'..'az'. I find this quite natural. Not sure if you're saying that's something you'd like or if you think that that's something already there. It doesn't match for me using recent(ish) Rakudo. Of course, that could just be me! :) I'd personally prefer it if Ranges just did lists, including when smart matching, but had an interval method or such like for explicit matching against the endpoints, e.g. 2.5 ~~ interval(1..5) # or 2.5 ~~ $myrange.interval I don't like the Huffman encoding: does $x come after $a and before $b? is a common test, and so should be short. I'd rather require you to force it into list context if your goal is to test for set membership. In fact, that might be a clean way of handling its dual nature: in item context, it behaves as a Range object; in list context, it behaves as the RangeIterator. So: 2.5 ~~ 1..5 # true: equivalent to 2.5 ~~ 1 = $_ = 5. 2.5 ~~ @(1..5) # false: equivalent to 2.5 ~~ (1, 2, 3, 4, 5). Incidently, this first example is why I think that Range is intimately related to the various order-related operators, and in particular before and after: its most common use outside of generating sequential lists is to provide a shorthand for $min before $_ before $max and similar range-testing expressions. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
I think $a = $^x = $b is short enough, and lets you choose between and = on both ends and without having to remember how many dots each maps to. But I do like your list context for list behavior idea. I would support that happily. On 8/27/09, Jon Lang datawea...@gmail.com wrote: smuj wrote: TSa wrote: HaloO, David Green wrote: For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? I see no problem when a Range matches for values which are not produced by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is not in 1,2,3,4,5. I suspect that the double meaning of Ranges is going to confuse some people and bite others. If things stay as they are, I hope that the use of :by will be flagged as a syntax error if used in literal Range smart matching. Of course, that doesn't help the unsuspecting when variables are being used, ala 2.5 ~~ $myrange. Another possibility is that literal Range smartmatching works as is in the absence of :by (that is, with a Range), but becomes a set membership test in its presence (i.e., with a RangeIterator). Or not; see below. (For the record, 2.5 ~~ '!'..5 is also true on my system, although I don't know why! I certainly wouldn't expect it though :) One explanation would be that it's comparing the String 2.5 to the String-terminated Range !..5. Since 2 falls between ! and 5, so does 2.5. The same applies for 'aaa' ~~ 'aa'..'az'. I find this quite natural. Not sure if you're saying that's something you'd like or if you think that that's something already there. It doesn't match for me using recent(ish) Rakudo. Of course, that could just be me! :) I'd personally prefer it if Ranges just did lists, including when smart matching, but had an interval method or such like for explicit matching against the endpoints, e.g. 2.5 ~~ interval(1..5) # or 2.5 ~~ $myrange.interval I don't like the Huffman encoding: does $x come after $a and before $b? is a common test, and so should be short. I'd rather require you to force it into list context if your goal is to test for set membership. In fact, that might be a clean way of handling its dual nature: in item context, it behaves as a Range object; in list context, it behaves as the RangeIterator. So: 2.5 ~~ 1..5 # true: equivalent to 2.5 ~~ 1 = $_ = 5. 2.5 ~~ @(1..5) # false: equivalent to 2.5 ~~ (1, 2, 3, 4, 5). Incidently, this first example is why I think that Range is intimately related to the various order-related operators, and in particular before and after: its most common use outside of generating sequential lists is to provide a shorthand for $min before $_ before $max and similar range-testing expressions. -- Jonathan Dataweaver Lang -- Sent from my mobile device Mark J. Reed markjr...@gmail.com
Re: Synopsis 02: Range objects
Jon Lang wrote: smuj wrote: I'd personally prefer it if Ranges just did lists, including when smart matching, but had an interval method or such like for explicit matching against the endpoints, e.g. 2.5 ~~ interval(1..5) # or 2.5 ~~ $myrange.interval I don't like the Huffman encoding: does $x come after $a and before $b? is a common test, and so should be short. I'd rather require you to force it into list context if your goal is to test for set membership. In fact, that might be a clean way of handling its dual nature: in item context, it behaves as a Range object; in list context, it behaves as the RangeIterator. So: 2.5 ~~ 1..5 # true: equivalent to 2.5 ~~ 1 = $_ = 5. 2.5 ~~ @(1..5) # false: equivalent to 2.5 ~~ (1, 2, 3, 4, 5). Incidently, this first example is why I think that Range is intimately related to the various order-related operators, and in particular before and after: its most common use outside of generating sequential lists is to provide a shorthand for $min before $_ before $max and similar range-testing expressions. So you're saying you'd like things to stay exactly as they are at the moment!? :-) -- smuj
Re: Synopsis 02: Range objects
On Thu, Aug 27, 2009 at 2:36 PM, Mark J. Reedmarkjr...@gmail.com wrote: I think $a = $^x = $b is short enough, and lets you choose between and = on both ends and without having to remember how many dots each maps to. How many dots? Note that there are three sets of comparison operators: '' and '=' numify their arguments before comparing them. 'lt' and 'le' stringify their arguments before comparing them. 'before' compares its arguments without any coercion. Note that there's no equivalent to '='. I'm unclear as to which of these cases '..' is currently like, if any; it may be an unholy hybrid of all three. But for the sake of argument, I'll assume that it's currently like '' and '='. $a ~~ 1..5 # $a ~~ 1 = $_ = 5 $a ~~ 1^..5 # $a ~~ 1 $_ = 5 $a ~~ 1..^5 # $a ~~ 1 = $_ 5 $a ~~ 1^..^5 # $a ~~ 1 $_ 5 What's so hard about that? And if '..' is like 'before', it can do things that can't easily be done otherwise: $a ~~ 1..5 # 1 before $_ before 5 || $_ === 1 | 5 -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
smuj wrote: So you're saying you'd like things to stay exactly as they are at the moment!? :-) Not quite. I'd like to see the effects of context spelled out more clearly than they are; and I'd like a revision so that '..' numifies its endpoints while a new 'to' operator doesn't. That is, restrict '..' to cases when you're defining a range of numbers, and use 'to' to handle all other cases. It might also be nice to have a stringifying version; perhaps 'be', using the same everything's an acronym naming convention used by other stringifying operators (e.g., 'lt' is less than, 'le' is 'less than or equal to', 'leg' is less than, equal to, greater than) - in this case, 'be' would be 'beginning to end'. At the very least, this would avoid the inevitable questions about why there isn't a stringifying version. :) That said, it may not be good for much more than that. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
On Thu, Aug 27, 2009 at 02:21:12PM -0700, Jon Lang wrote: : 2.5 ~~ 1..5 # true: equivalent to 2.5 ~~ 1 = $_ = 5. Current specced behavior for Range objects. : 2.5 ~~ @(1..5) # false: equivalent to 2.5 ~~ (1, 2, 3, 4, 5). Not by current rules; which say the left side matches the list 1..5 as a whole. We don't do implicit junctifying of lists anymore, and haven't for several years. Which points to the correct Perl 6 utterance for that: 2.5 ~~ any(1..5)# false Wherein, as you suggest, the 1..5 in list context does in fact iterate the range to produce individual values. Larry
Re: Synopsis 02: Range objects
On Thu, Aug 27, 2009 at 2:34 PM, Larry Wallla...@wall.org wrote: On Thu, Aug 27, 2009 at 02:21:12PM -0700, Jon Lang wrote: : 2.5 ~~ 1..5 # true: equivalent to 2.5 ~~ 1 = $_ = 5. Current specced behavior for Range objects. : 2.5 ~~ @(1..5) # false: equivalent to 2.5 ~~ (1, 2, 3, 4, 5). Not by current rules; which say the left side matches the list 1..5 as a whole. We don't do implicit junctifying of lists anymore, and haven't for several years. Which points to the correct Perl 6 utterance for that: 2.5 ~~ any(1..5) # false Wherein, as you suggest, the 1..5 in list context does in fact iterate the range to produce individual values. You're right, of course. I keep getting tripped up on those details... -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
On Aug 27, 2009, at 17:48 , Jon Lang wrote: On Thu, Aug 27, 2009 at 2:36 PM, Mark J. Reedmarkjr...@gmail.com wrote: I think $a = $^x = $b is short enough, and lets you choose between and = on both ends and without having to remember how many dots each maps to. How many dots? .. vs. ... operators, I presume. -- 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: Synopsis 02: Range objects [recap]
Thanks to everyone who has posted their thoughts on Ranges. Here are the conclusions I have drawn: Ranges are for checking whether something is within a given interval. RangeIterators are for iterating over elements in a Range with a given step size using :by. We discussed using Series or Sequence in place of RangeIterator, but Series seems too general and Sequence has already been taken. Up to this point, there are no changes to the spec afaik. Proposed changes: It shouldn't be possible to construct RangeIterators over Str (apart from single length strings) or Complex using the Range operator (..). Next open question: What about Ranges using different types in each endpoint? 1.5 .. 10 :by(0.5) (Rat .. Int) 0 .. 7 Should they be coerced - and in that case to what? If we don't coerce them, what should be returned? Regards, Michael Zedeler.
Re: Synopsis 02: Range objects [recap]
Michael Zedeler wrote: Proposed changes: It shouldn't be possible to construct RangeIterators over Str (apart from single length strings) or Complex using the Range operator (..). I'd go one step further with Complex, to say that Range isn't a useful concept at all so long as before and after are undefined. As for Str, I'm not sure that we should go so far as to say that you _can't_ create RangeIterators over them, so much as to say that the default step algorithm is defined only for single-character strings, and fails if you give it anything else. In particular, the programmer should be allowed to enable Str-based RangeIterators by explicitly supplying his own step algorithm. That is: 'aa' .. 'zz' # Error in list context: default stepper rejects multi-character endpoints 'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns Next open question: What about Ranges using different types in each endpoint? 1.5 .. 10 :by(0.5) (Rat .. Int) 0 .. 7 Should they be coerced - and in that case to what? If we don't coerce them, what should be returned? This is only a half-formed thought at the moment, so please bear with me: maybe Ranges should extend the triptych that exists with comparison operators. That is, you have before and after, lt and gt, and and ; you also have cmp, leg, and =. Perhaps .. should be treated as the numeric operator, and equivalent Str and generic operators should be supplied separately. I'd be inclined to spell the generic Range operator - the one corresponding to before/after/cmp - as to. I'm not sure how the Str-based one ought to be spelled. With .., there should be automatic coercion of both endpoints to numbers, just as there is with and . With to, there should be no coercion at all, just like before after, and cmp. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
Michael Zedeler schrieb: Well... maybe. How do you specify the intended precision, then? If I want the values from 1 to 2 with step size 0.01, I guess that writing 1.00 .. 2.00 won't be sufficient. Trying to work out the step size by looking at the precision of things that are double or floats doesn't really sound so feasible, since there are a lot of holes in the actual representation, so 1.0001 may become 1.0, yielding very different results. That is a general problem of floats. We tend to write them in decimal notation, but internally they use a representation which is binary. And it is absolutely not obvious what the precision of 1.0001 might be. There could be a data type like LongDecimal in Ruby or BigDecimal in Java, that actually has a knowlegde of its precision and whose numbers are fractions with a power of 10 as the denominator. But for floats I would only see the interval as reasonably clear. Even a step of 1 is coming with some problems, because an increment of 1 does not have any effect on floating point numbers like 1.03e300 or so. Regards, Karl
Re: Synopsis 02: Range objects [recap]
On Wed, 26 Aug 2009, Michael Zedeler wrote: Thanks to everyone who has posted their thoughts on Ranges. Here are the conclusions I have drawn: Ranges are for checking whether something is within a given interval. RangeIterators are for iterating over elements in a Range with a given step size using :by. We discussed using Series or Sequence in place of RangeIterator, but Series seems too general and Sequence has already been taken. Up to this point, there are no changes to the spec afaik. Proposed changes: It shouldn't be possible to construct RangeIterators over Str (apart from single length strings) or Complex using the Range operator (..). I haven't been following the conversation, but I've had an idea -- maybe it should be possible to construct a RangeIterator if an ordered set is provided. For example, if the ordered set was '0'.. '9', then the RangeIterator would know that the thing went '0' .. '9', '10' .. '19', '20', etc, whereas if the ordered set was 'a' .. 'z' then it could be something like 'a' .. 'z', 'aa', 'ab' ... 'az', 'ba'... I realise that maybe the first set should've been '1' .. '0' instead, but the general idea is the thing at the moment. I wrote all this, and then saw Jon Lang's idea of providing steppers, which is also good. I think a Complex range only makes sense if you provide 4 endpoints, not 2, but I haven't been following the conversation, so I'll leave it up to the Complex number experts :). HTH, - | Name: Tim Nelson | Because the Creator is,| | E-mail: wayl...@wayland.id.au| I am | - BEGIN GEEK CODE BLOCK Version 3.12 GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V- PE(+) Y+++ PGP-+++ R(+) !tv b++ DI D G+ e++ h! y- -END GEEK CODE BLOCK-
Re: Synopsis 02: Range objects
On 2009-Aug-24, at 4:17 pm, Daniel Ruoso wrote: Em Seg, 2009-08-24 às 23:50 +0200, Michael Zedeler escreveu: The most elegant solution would be if the data types themselves indicated their capabilities. One thing I think you missed entirely is the fact that the infix:.. operator is a multi sub, so it falls to regular dispatch semantics, But Michael's point was not about what's *possible*, but rather what's *reasonable*. Given that Ranges can act in two ways that lead to inconsistency, it would be less confusing to separate the list-kind from the interval-kind. For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? A Range might get implicitly cast to an Interval by using its endpoints; that leaves us open to the same confusion, although the context would help. # Assuming infix:between (Any, Interval) say 5 between [1, 10]; say 5 between 1 .. 10; say 'aaa' ~~ 'aa' .. 'ba'; # false say 'aaa' between aa ba; # true say 'aaa' between 'aa'..'ba'; # hm... Come to think of it, the word range suggests ordering (like the related word rank), so perhaps Range is the right name for the interval-type, and Series should be the type that produces a series of values that may or may not have an innate ordering. (For example, you could produce a Complex series with: 5+5i .. 10+10i :by(1+1i).) -David
Re: Synopsis 02: Range objects
James Cloos wrote: Michael == Michael Zedeler mich...@zedeler.dk writes: Michael The Range 1.0001 .. 2.15 makes sense as an interval definition, but Michael there can hardly be a useful list definition without defining a step Michael size, at least, making it possible to use step sizes less than one. The obvious (default) choice for a step size would be the precision of the more precise of the two values. So 0.0001 in your example above. Well... maybe. How do you specify the intended precision, then? If I want the values from 1 to 2 with step size 0.01, I guess that writing 1.00 .. 2.00 won't be sufficient. Trying to work out the step size by looking at the precision of things that are double or floats doesn't really sound so feasible, since there are a lot of holes in the actual representation, so 1.0001 may become 1.0, yielding very different results. It could be really nice to come up with something dwimmy, but I can't really se any really good candidates, when it comes to floating point numbers and strings. If they were specified in hex float syntax, such as 0x1.01P0 .. 0x3.123P0, then the (default) step should be 0x0.001P0 (which is the same as saying 1.00390625 .. 3.071044921875 with a step size of 0.000244140625). Fair enough, but again - I guess they are translated straight to some internal representation where the information in this notation would be lost. Just like it would be in decimal notation. Michael Complex .. Complex - undef, exception or some other bad thing. Complex .. Complex should have a defined meaning in p6. A definition which is easy to compute would be the set of points contained by the square which has opposite corners at the two specified points. But is that useful? Complex numbers are mostly for mathematics, so I guess we have to look in that domain for a good use case. In that domain there is no natural ordering of complex numbers, and without some ordering, you may be able to decide what should be in the list to return, but not which order to use. I believe that anything we put into Perl 6 should have obvious use cases and fall natural into place in the domain that the construct in question belongs to. This means we have to come up with a design (there currently is no specification of Complex .. Complex), some kind of use case to as justification and finally a validation that ensures that the design is consistent with other things in the language. An example of an obvious inconsistency is ranges on strings compared to how cmp works. A better definition would be the set of points contained by the circle which has a diameter running between the two points. In that case, you'd really need a step size, since circles tend bend :-) Also, I'd like to see an obvious and intuitive ordering. In both cases, of course, including the points actually on the 1-manifold. Either choice has the same meaning on the real axis as .. generates when given real args, and is useful for interval arithmetic. Something for which p6 is well suited. I'll go and get my old topology book and see what I can find there, but I must admit that I'd prefer if Complex .. Complex was left undefined in the Perl 6 core, leaving it up to anyone to specify it later. Regards, Michael.
Re: Synopsis 02: Range objects
Michael Zedeler wrote: The obvious (default) choice for a step size would be the precision of the more precise of the two values. So 0.0001 in your example above. Well... maybe. How do you specify the intended precision, then? If I want the values from 1 to 2 with step size 0.01, I guess that writing 1.00 .. 2.00 won't be sufficient. Trying to work out the step size by looking at the precision of things that are double or floats doesn't really sound so feasible, since there are a lot of holes in the actual representation, so 1.0001 may become 1.0, yielding very different results. It could be really nice to come up with something dwimmy, but I can't really se any really good candidates, when it comes to floating point numbers and strings. For floating point numbers, assume a default step size of 1, just like integers; use the :by adverb to specify a different step size, either by supplying a floating point number to be added in or by supplying a block that generates the next step when fed the current one. So: 1.00 .. 2.00 # 1.00, 2.00 1.00 .. 2.00 :by .01 # 1.00, 1.01, 1.02, ..., 1.98, 1.99, 2.00 Also, I want to second David Green's point: we're not talking Range and Interval here; we're talking Range and Series. A Series would be a kind of Range that has the additional ability of generating a list. The :by adverb would be a property of a Series, but not a Range. Using Num for your endpoints would result in a Series; using Complex for your endpoints should result in an error: Complex numbers don't have a viable definition of before or after, let alone between. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
On Tue, Aug 25, 2009 at 5:58 PM, Jon Langdatawea...@gmail.com wrote: Also, I want to second David Green's point: we're not talking Range and Interval here; we're talking Range and Series. But a series refers to a more general concept than a discrete range. I still think Range and Interval fit better. using Complex for your endpoints should result in an error: Complex numbers don't have a viable definition of before or after, let alone between. Slight overstatement, IMO. Sure, complex numbers don't form an ordered field: given three numbers, z0, z1, and z2, you can't ask if z0 z1 or z0 z2, at least not without imposing some artificial ordering rule. Even without defining an ordering, though, you can meaningfully ask whether z0 lies within or outside the rectangle formed by z1 and z2, which is a viable (if nonlinear) definition of between. You can only get a Boolean answer, but it's a valid question. That's just nitpicking, though. It's perfectly reasonable to fail() if someone tries to construct a Range/Series/Interval out of Complex numbers. We can use a different class for complex rectangles if we need them. -- Mark J. Reed markjr...@gmail.com
Re: Synopsis 02: Range objects
Mark J. Reed wrote: On Tue, Aug 25, 2009 at 5:58 PM, Jon Langdatawea...@gmail.com wrote: Also, I want to second David Green's point: we're not talking Range and Interval here; we're talking Range and Series. But a series refers to a more general concept than a discrete range. I still think Range and Interval fit better. IME, range and interval are largely interchangeable terms. The only time that they aren't is when range is used in contrast to domain; and even there, it still doesn't refer to a list of discrete values. That's generally referred to as a sequence; unfortunately, that's a term that Perl has already co-opted. using Complex for your endpoints should result in an error: Complex numbers don't have a viable definition of before or after, let alone between. Slight overstatement, IMO. Sure, complex numbers don't form an ordered field: given three numbers, z0, z1, and z2, you can't ask if z0 z1 or z0 z2, at least not without imposing some artificial ordering rule. Even without defining an ordering, though, you can meaningfully ask whether z0 lies within or outside the rectangle formed by z1 and z2, which is a viable (if nonlinear) definition of between. You can only get a Boolean answer, but it's a valid question. It's also every bit as artificial as the ordering rules that can be imposed. It would be just as valid to ask whether z0 lies on the line segment that runs between z1 and z2, or within the smallest circle that includes z1 and z2. And if you _do_ establish an artificial ordering rule, it's also perfectly valid to ask if z0 is after z1 and before z2 (or vice versa, if z2 is before z1). That's just nitpicking, though. It's perfectly reasonable to fail() if someone tries to construct a Range/Series/Interval out of Complex numbers. We can use a different class for complex rectangles if we need them. Agreed. -- Jonathan Dataweaver Lang
Re: Synopsis 02: Range objects
On Tue, Aug 25, 2009 at 02:58:05PM -0700, Jon Lang wrote: : Michael Zedeler wrote: : The obvious (default) choice for a step size would be the precision of : the more precise of the two values. So 0.0001 in your example above. : : : Well... maybe. How do you specify the intended precision, then? If I want : the values from 1 to 2 with step size 0.01, I guess that writing : : 1.00 .. 2.00 : : won't be sufficient. Trying to work out the step size by looking at the : precision of things that are double or floats doesn't really sound so : feasible, since there are a lot of holes in the actual representation, so : 1.0001 may become 1.0, yielding very different results. : : It could be really nice to come up with something dwimmy, but I can't really : se any really good candidates, when it comes to floating point numbers and : strings. : : For floating point numbers, assume a default step size of 1, just like : integers; use the :by adverb to specify a different step size, either : by supplying a floating point number to be added in or by supplying a : block that generates the next step when fed the current one. So: : : 1.00 .. 2.00 # 1.00, 2.00 : 1.00 .. 2.00 :by .01 # 1.00, 1.01, 1.02, ..., 1.98, 1.99, 2.00 Note that your :by adverb is malformed; it must be :by(.01), or it's parsed as a boolean :by followed by a term. Another note, it's likely that numeric literals such as 1.23 will turn into Rats rather than Nums, at least up to some precision that is pragmatically determined. : Also, I want to second David Green's point: we're not talking Range : and Interval here; we're talking Range and Series. A Series : would be a kind of Range that has the additional ability of generating : a list. The :by adverb would be a property of a Series, but not a : Range. Using Num for your endpoints would result in a Series; using : Complex for your endpoints should result in an error: Complex numbers : don't have a viable definition of before or after, let alone : between. We already make this distinction in the spec. A Range means an interval, possibly annotated with a step, but this is meaningless unless the range is iterated. An attempt to use such a Range in a list produces a RangeIterator, which yields a series of values. However, the name series operator is already reserved to mean infix:... rather than infix:... So your second example above basically turns into this series: 1.00 ... { $_ + 0.01 if $_ 2.00 }; except that 1.00 .. 0.00 produces (), not 1.00. A more exact translation might be () ... - $x = (1.00-0.01) { $x + 0.01 if $x 2.00 }; I am currently assuming such loops will default to Rat rather than Num for numbers that aren't too far off the beaten path, where on the beaten track is defined as rats that fit into a pair of int64s or so, that is, which can be represented with rat64. Larry
Synopsis 02: Range objects
Hi Perl 6 people. I've been looking closely at the definition of the Range class in S02 and the current Rakudo implementation, and I have some comments... It seems that there are two intended uses for this class: Range A pair of Ordered endpoints Lets call the above the interval definition. The |..| operator now constructs a |Range| object rather than merely functioning as an operator. Both sides are in item context. Semantically, the |Range| acts like a list of its values to the extent possible, but does so lazily, unlike Perl 5's eager range operator. And this one the list definition. It seems fair enough to demand that a class supports both the concept of being able to tell whether some value is between two endpoints (even supporting open ranges) as well as being a lazy list in disguise, but this concept only works on countable domains. The most common example is 1 .. 100, which represents both an object that can tell whether some other Integer is between 1 and 100 (inclusive) as well as the list of numbers from 1 to 100. But there are problems if you try extending it to other data types that model over-countable things, such as real numbers. The Range 1.0001 .. 2.15 makes sense as an interval definition, but there can hardly be a useful list definition without defining a step size, at least, making it possible to use step sizes less than one. This issue also surfaces when working with strings. As far as I can see, Rakudo has some other comparison operation, which means that Ranges using String endpoints are not dwimmy in the sense I'd expect: say @(a .. ax).perl; # expands to a .. z, aa .. ax say @(aa .. b).perl; # expands to the empty list As far as I can see, the ordering is like so: sub { $^a.chars cmp $^b.chars || $^a cmp $^b } The code below shows that Rakudo does not currently use lexicographical comparison, which may be surprising. say 'aaa' cmp 'aa'; say 'aaa' cmp 'ba'; say 'aaa' ~~ 'aa' .. 'ba'; The output is: 1 -1 0 The last 0 should be 1 if using normal lexicographical ordering, just like cmp does. It is necessary to consider the data types that we want to use as interval endpoints and carry out some sort of analysis of their domains. The basic requirements are: For the interval definition: there must be an obvious ordering relation, so we can do $a cmp $b on any $a and $b of the given data type. For the list definition: for any value $a of the given datatype, it must be possible to come up with some $b, where no $c exists so $a $c $b. Now for a short analysis of the different data types used as end points: Integers - both interval and list definitions are ok. Str - using lexicographical comparison permits only the interval definition. Using the different comparison operator above permits both, but results in counter-intuitive interval definition. Num - using numerical comparison permits only the interval definition. It should be easy to come up with a way to specify step sizes to support list definition. Complex - neither definitions are possible. I am unsure about how this can be solved, apart from extracting the interval definition to a super class to Range (we could call it an Interval). The backside is that the class returned by the .. operator depends on the operands: Int .. Int - Range Str .. Str - Interval Complex .. Complex - undef, exception or some other bad thing. DataTypeA .. DataTypeB - undef, exception or some other bad thing. The most elegant solution would be if the data types themselves indicated their capabilities. So if the given class has a cmp method working on the same data type, the .. can construct an Interval. If the given class has a next method (my name for a method returning the next value), the .. can even construct a Range. If you want to construct an Interval using non-countable things, you should then be able to provide your own next replacement. Maybe like so: my $range = 1.14 .. 1.82 :by {* + 0.01}; Another option is to provide a completely different operator for constructing Intervals. Darren Duncan brought this up before. See http://osdir.com/ml/perl6-language/2009-02/msg00422.html Regards, Michael Zedeler.
Re: Synopsis 02: Range objects
Em Seg, 2009-08-24 às 23:50 +0200, Michael Zedeler escreveu: The most elegant solution would be if the data types themselves indicated their capabilities. One thing I think you missed entirely is the fact that the infix:.. operator is a multi sub, so it falls to regular dispatch semantics, in a way that any new class can export its own version of it with the desired semantics... my $range = 1.14 .. 1.82 :by {* + 0.01}; Including mandatory named arguments... Another option is to provide a completely different operator for constructing Intervals. The other thing you're missing is that Range is a role, not a class, which means that any type can behave like a range even if it provides a completely different behavior, which might include method list { fail This type of Range cannot be used as a list... } daniel