RE: A few multiple dispatch questions
noncitizen is the more appropriate term you are looking for I think regards steve -Original Message- From: chromatic [mailto:[EMAIL PROTECTED] Sent: 06 August 2008 04:03 To: Bob Rogers Cc: perl6-language@perl.org Subject: Re: A few multiple dispatch questions On Tuesday 05 August 2008 15:25:47 Bob Rogers wrote: On Tuesday 05 August 2008 12:01:29 Larry Wall wrote: I believe veto is giving the wrong idea here as something that happens after the fact. What's the term for only allowing acceptable candidates to put their names on the ballot? disenfranchise In the context of balloting, that applies to voters; the equivalent word for candidates is qualify (or disqualify). My state has closed primaries; same effect. -- c No virus found in this incoming message. Checked by AVG - http://www.avg.com Version: 8.0.138 / Virus Database: 270.5.12/1592 - Release Date: 8/5/2008 6:03 AM
Re: A few multiple dispatch questions
Larry Wall wrote: On Tue, Aug 05, 2008 at 06:17:30PM +0200, Jonathan Worthington wrote: Hi, I am currently reviewing bits of the spec surrounding multiple dispatch and, of course, have a question or two (I'll probably have some more later, as the dust settles in my head). 1) The spec says: -- A proto also adds an implicit multi to all routines of the same short name within its scope, unless they have an explicit modifier. -- If you write: proto sub foo(:$thing) { ... } sub foo(Int $x) { ... } only sub foo() { ... } Does this give some kind of error, because you've declared something with 'only', but it clearly can't be the only one because we also have a proto in there? I'd consider it an error. OK, sounds sane. 2) If I write: multi sub foo(Int $blah) { ... } # 1 proto sub foo(:$blah) is thingy { ... } # 2 multi sub foo() { ... } # 3 Does #1 get the thingy trait, or not because it was declared before the proto was? I'm clear that #3 gets it... I think a proto cannot be expected to work retroactively. In fact, I think it's probably an error to declare a proto after a non-proto in the same scope. OK, error for this also seems sane. 3) The spec says: -- A parameter list may have at most one double semicolon; parameters after it are never considered for multiple dispatch (except of course that they can still veto if their number or types mismatch). -- Does the veto take place once the multiple dispatch has given us a candidate and we try to bind the parameters to the signature, or as part of the multiple dispatch? For example, supposing I declare: multi foo(Int $a;; Num $b) { ... } # 1 multi foo(Int $a;; Str $b) { ... } # 2 multi foo(Int $a;; Num $b, Num $c) { ... } # 3 What happens with these? foo(2, RandomThing.new); # Ambiguous dispatch error foo(2, 2.5); # Ambiguous dispatch error, or 1 because 2 vetos? foo(1, 2.5, 3.4); # Ambiguous dispatch error, or 3 because only one with arity match? Basically, what I'm getting at is, are all of these multi-methods ambiguous because they all have the same long name, and just because binding fails doesn't make us return into the multiple dispatch algorithm? (This is what I'm kinda expecting and would mean every one of these fails. But I just want to check that is what was meant by the wording.) I believe veto is giving the wrong idea here as something that happens after the fact. What's the term for only allowing acceptable candidates to put their names on the ballot? I'm not sure, but since we're carving up the set of possible candidates so the dispatcher only sees those that could bind, maybe we should go for gerrymandering. ;-) Anyway, as TSa surmises, the ballot is vetted or stacked in advance--only those candidates that *could* bind are considered to be part of the candidate set. OK, so that would seem to mean that if we're looking at what could bind then we also check the arity and the type constraints of the non-MMD parameters (after the C;;) during the dispatch. So for my examples we'd get: foo(2, RandomThing.new); # No matching candidates error foo(2, 2.5); # Only 1 is a candidate, so we get that foo(1, 2.5, 3.4); # Only 3 is a candidate, so we get that In the abstract, candidates that cannot match never get their names on the ballot, though of course an implementation might choose to determine this lazily as long as it preserves the same semantics. I'm thinking mine will do this bit lazily, at least in the first cut. Alternately, even if the list of valid candidates is determined eagerly, if the candidate list construction is memoized based on the typeshape of the Capture, it will generally not have to be redone until you see a different typeshape (where the meaning of different may depend on how specific the signatures are, and in particular on whether any of the signatures rely on subset constraints (including individual values, which are just degenerate subsets)). *nod* That sounds like we're starting to wonder down the road of optimizations though, and I'd rather do something simple and correct first, at least until there's a large enough body of tests to be sure that optimizations aren't making us just get the wrong answers really quickly. Thanks, Jonathan
smart match Any ~~ Num
HaloO, the smart match table in S03 has the Any ~~ Num meaning numeric equality. But shouldn't that be a bit fuzzier? E.g. a match $x ~~ $num should check abs($x - $num) epsilon with an epsilon that depends on the size of $num. Also for strings some fuzziness might be a good idea, e.g. to go case insensitive. The driving idea is that if someone uses ~~ instead of == or eq some form of approximation is intended. 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: new article, A Romp Through Infinity
HaloO, I wrote: That is you can do the usual Int arithmetic in the ranges Inf..^Inf*2 and -Inf*2^..-Inf except that Inf has no predecessor and -Inf no successor. Well, and we lose commutativity of + and *. I.e. 1 + $a != $a + 1 if $a is transfinite. Well, we can of course count downwards from Inf to Inf-1, Inf-2, etc. That is we don't have a global sign but signed coefficients with the highest multiple of Inf determining the side of Zero we are on. For the Num type we also might consider reciprocals of Inf as infinitesimals. The only thing we need to define then is at which points in computations these hypernums are standardized back into Num ;) An application for transfinite Ints is if you have two infinite files concatenated into one. Then you can keep transfinite indices into the second one. The size of such a file would be Inf*2 of course. 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: syntax question: method close is export ()
On Tue, Aug 05, 2008 at 05:43:57PM +0800, Audrey Tang wrote: John M. Dlugosz 提到: Does that mean that traits can come before the signature? Or should it be corrected to method close () is export { ... } It's a simple typo. Thanks, fixed in r14572. The strange thing is that we might have to support that order if we want to allow user-defined operators in the signature, since sub infix:foo ($x, $y, :$z = $x foo $y bar 1) is equiv(infix:baz) {...} would not know the precedence soon enough to know whether foo is tighter or looser than bar. Whereas sub infix:foo is equiv(infix:baz) ($x, $y, :$z = $x foo $y bar 1) {...} could presumably attach that information in a timely fashion to the definition of the foo operator. 'Course, there are workarounds in the current scheme of things: sub infix:foo is equiv(infix:baz) is sig(:($x, $y, :$z = $x foo $y bar 1)) {...} sub infix:foo ($x, $y, :$z = infix:foo($x, $y) bar 1) is equiv(infix:baz) {...} but I'm inclined to simplify in the direction of saying the signature syntax is just a trait variant so the order doesn't matter. The one remaining question I see is whether it's possible to declare a sub with the name is: sub is is foo {...} and if so, whether it's possible to have an anonymous sub with traits and no signature: sub is foo {...} I suspect we should bias it towards the first case on the grounds that you can write the latter with an explicit missing sig sig as sub ([EMAIL PROTECTED] is rw) is foo {...} Though, of course, we could solve it the other direction with an explicit I am not a sub name sub name. Not sure which side least suprise works on, but the fact that we already have a representation for no sig seems to say we don't need an explicitly anonymous name. But maybe such a name would be more generally useful, which would make it a wash. One obvious candidate for a null name: sub () is foo {...} is of course not possible. I suppose we could nudge things in a direction that sub is foo {...} would work, since that'd be much like state $ = do { I am a fake START block } But if we allow sub foo then people will wonder what sub @foo means... Larry
Catching exceptions with the // operator
In a little language that I wrote some time ago, I found it very useful to let the // operator catch exceptions: f(x) // g(y) does: * If f(x) returns a defined value, use this value. * If f(x) returns an undefined value, use the value of g(x) instead. * If f(x) throws an exception, catch and keep it in $!, use the value of g(x) * But don't catch exceptions of g(x). Similarly, f(x) // g(y) // h(z) catches exceptions of f(x) and of g(y) but not of h(z). I would like to suggest the same semantics for perl6. Let me explain why this is useful and why I think this is the right thing: First of all, it provides a very light-weight exception handling using well-known ideoms like: $file_content=read_file($filename) // $default_value; compute_statistics($data) // write_log_message(stats failed: $!); With the proposed change, these ideoms work whether the functions throw exceptions or not. But why should this be the right thing? Obviously, // is the fallback or redundancy operator: Don't despair if the first computation doesn't produce a usable result --- we have another way of getting the job done. In this context, and exception conveys the same message as an undefined value: The first step failed. You need to fall back to some other alternative or give up! As the second expression provides exactly this other alternative, there is no need to jump out of the normal processing order anymore. Best regards --- and many thanks for the continued effort on perl6! Yaakov Belch
Re: Catching exceptions with the // operator
On Wed, Aug 6, 2008 at 8:58 AM, Yaakov Belch [EMAIL PROTECTED] wrote: In a little language that I wrote some time ago, I found it very useful to let the // operator catch exceptions: f(x) // g(y) does: * If f(x) returns a defined value, use this value. * If f(x) returns an undefined value, use the value of g(x) instead. * If f(x) throws an exception, catch and keep it in $!, use the value of g(x) * But don't catch exceptions of g(x). Similarly, f(x) // g(y) // h(z) catches exceptions of f(x) and of g(y) but not of h(z). I would like to suggest the same semantics for perl6. Let me explain why this is useful and why I think this is the right thing: First of all, it provides a very light-weight exception handling using well-known ideoms like: $file_content=read_file($filename) // $default_value; compute_statistics($data) // write_log_message(stats failed: $!); With the proposed change, these ideoms work whether the functions throw exceptions or not. But why should this be the right thing? Obviously, // is the fallback or redundancy operator: Don't despair if the first computation doesn't produce a usable result --- we have another way of getting the job done. In this context, and exception conveys the same message as an undefined value: The first step failed. You need to fall back to some other alternative or give up! As the second expression provides exactly this other alternative, there is no need to jump out of the normal processing order anymore. i don't think this will work for perl 6. since perl 6 has resumeable exceptions (like Cwarn), the meaning of the C// operator could be ambiguous. given the following statement, my $bill = ack() // thpp() // ppt(); with perl 6's current semantics, if Cack(), throws a resumable exception that is handled in the current scope or an outer scope, execution will resume before C// and the definedness of the result from Cack() will be tested in order to determine whether or not to call Cthpp(). using your semantics, if a resumable exception is thrown in Cack(), C// will cause Cthpp() to be invoked immediately, discarding any possible defined result from Cack(). also, the question arises that if Cthpp() doesn't handle the type of exception thrown, should Cppt() be called immediately, or only if Cthpp() returns an undefined result? seems to me it would try to handle the exception thrown by Cack(). so how do i signify that my exception has been handled, and that i can now assign a default value to C$bill? in my mind, this strays too far from the meaning of C// and adds ambiguity that makes the operator unusable. perhaps there's room for an operator that gives some sugar for my $bill = try { ack() CATCH { thpp() } }; but to me that code is concise enough that it doesn't warrant syntactic relief. ~jerry
Re: Catching exceptions with the // operator
in my mind, this strays too far from the meaning of C// and adds ambiguity that makes the operator unusable. perhaps there's room for an operator that gives some sugar for my $bill = try { ack() CATCH { thpp() } }; but to me that code is concise enough that it doesn't warrant syntactic It seems that the following should address the issue while providing enough indication about what is occurring: my $bill = try { ack() } // thpp(); That seems to be closer to what the original post was desiring. Paul
Re: Catching exceptions with the // operator
Yaakov Belch perl6-at-yaakovnet.net |Perl 6| wrote: Let me explain why this is useful and why I think this is the right thing: First of all, it provides a very light-weight exception handling using well-known ideoms like: $file_content=read_file($filename) // $default_value; compute_statistics($data) // write_log_message(stats failed: $!); With the proposed change, these ideoms work whether the functions throw exceptions or not. You can change the meaning of fail to throw exceptions or to return the unthrown object which is an interesting value of undef. So under use fail 'return'; your line works as intended. This is what you should do if you are expecting failure in this case. A macro can give you some syntactic sugar for that: macro ttt ($x) is parsedexpression { return { use fail 'return'; $x; }; }
Re: new article, A Romp Through Infinity
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: Firstly, shouldn't there also be infinite strings? E.g. 'ab' x Inf is a regularly infinite string and ~pi as well. Other classes might have elaborate notions of infinity. A string whose length is Inf is not itself equal to Inf. But $s.chars $b would be true for all normal values of the Num b. The Complex e.g. might have an angle associated to an Inf. I think there are too many different ways of doing that to make it built in. Normal Complex numbers are not ordered. But as described, a complex number but Inf will still be greater than any normal complex number. Just as real numbers are pretty basic, you can add Inf to that domain to form *affinely extended real number system, which is what I think the IEEE floats model a finite precision subset of. But there are many ways to extend the basic, and someone using such a system would need to use a module or define his own to get the exact behavior wanted.* Secondly, you only have a single Inf constant and its negation. But there should be a multitude of infinities. E.g. a code fragment my Int $a = random(0..1) 0.5 ?? 3 !! Inf; my Int $b = $a + 1; say yes if $b $a; should always print yes. That is we continue counting after Inf such that we have transfinite ordinals. 0, 1, 2, ..., Inf, Inf+1, Inf+2, ..., Inf*2, Inf*2+1, ... Inf + $n == Inf for all real numbers $n. You don't get different infinities that way. Likewise for multiplication: 2*Inf or even Inf**2 is still the _same_ value Inf. The proposed Infinite class (see the thread I started on 4/25/2008) does handle transfinite cardinals. Nothing in the P6 standard library cares whether you mean the number of integers or the number of real numbers etc. except for comparing Infinite values directly. But basic support is available for that in the class, and more specialized applications can write functions that use those values or extend the class to the desired domain. The implementation is strait forward as an array of coefficients of the Inf powers with Inf**0 == 1 being the finite Ints. The sign bit goes separate from the magnitude. That is you can do the usual Int arithmetic in the ranges Inf..^Inf*2 and -Inf*2^..-Inf except that Inf has no predecessor and -Inf no successor. Well, and we lose commutativity of + and *. I.e. 1 + $a != $a + 1 if $a is transfinite. What? A power series of Inf is just the same Inf. Were you trying to remember something concerning a power _set_? I'm not sure if such a concept of interesting values of infinity is overly useful, though. In TeX e.g. there are infinitely stretchable spacings of different infinitudes so that they overwrite each other. That kind of light-duty use (not mathematically rigorous but easy to represent TeX's two springs) is why I included transfinite ordinals in the class. Also I think we can have finite conceptual infinities for types like int32 and num64. In the latter case we also have infinitely small values and infinities like sqrt(2). In short everything that falls out of the finite range of these types and is captured in Int or Num. The domain of int32 is a finite subset of \mathbb{Z}. If you want to reserve some of the bit representations to mean other things, define another type. The point of the lower-case types is to do the native CPU stuff. num64, assuming IEEE semantics, will include special values for + and - Inf and for underflows like you indicate. I suppose that the implementation of Num will use the underlying bit representations when you convert Inf to Num. The Int type also is defined as being able to represent + and - Inf, and the implementation will need to flag it as such, somehow. BTW, with an infinite precision Num I see no need for the Rat type! The Num type is not infinite precision, but the highest-precision native type that operates at full speed. Since there are high or arbitrary precision float libraries available now, I'm sure CPAN6 will include some. --John