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: [EMAIL PROTECTED] 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
[perl #57652] [BUG] successfull 'when' does not skip the following tests.
# New Ticket Created by [EMAIL PROTECTED] # Please include the string: [perl #57652] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=57652 Yesterday, I downloaded and compiled perl6 of parrot-0.6.4. Testing some basic perl6 features, I found this example: my xyz=spot; given $xyz { when 'spot' { say 'is spot';} when /spot/ { say 'contains spot'; } default { say 'unknown'; } } This should print 'is spot'. But, in fact, it prints all three lines: is spot contains spot unknown I hope that this can be fixed easily.
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
Re: [perl #57608] [PATCH] add ports/cygwin
On Tuesday 05 August 2008 20:57:53 chromatic wrote: On Tuesday 05 August 2008 01:35:48 Reini Urban wrote: Attached patch adds the directory ports/cygwin with the most recent cygports file, the most recent src patch and the sources for the CYGWIN patches. (the contents of parrot-0.6.4-2.cygwin.patch which creates those files in CYGWIN-PATCHES/) Thanks, applied as r30048. This patch causes t/codingstd/filenames.t to fail (because the filename has multiple dots). Perhaps an exception should be made in this case? Mark
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
On Wed, Aug 06, 2008 at 09:36:16AM -0700, jerry gay wrote: : 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(). Yes, the basic problem with the proposal is that it catches all exceptions willy nilly and uses them all for control flow whether that is appropriate or not. I have some sympathy with the proposal, however, because I'm currently using exceptions for just that purpose in the STD grammar. But it's suffering from the same difficulty, and I have to be careful to rethrow if the exception I trapped wasn't the one I expected. : 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. Well, right now you can write either of: my $bill = try { ack() } // thpp(); my $bill = try { ack() } orelse thpp(); where the latter has the advantage of setting $! on the right to the return value of the try. We *could* go as far as making orelse carry try semantics, but I think a more appropriate solution might be to reduce the precedence of blockless try/do/gather etc. to below orelse. And then you could say my $bill = try ack() orelse try thpp() orelse do ppt(); But I need to think through the ramifications of such a precedence change. It would make blockless do rather pointless, for instance, but maybe that's a worthwhile tradeoff. And I'm using it above as a no-op to indicate a non-try. It might also be useful to have a try variant that only catches exceptions intended as benign failure to match. Or maybe try should have a way of indicating the severity of exception it wishes to trap by default. This could be a keyword variant, or an adverb, or a pragma. I'm thinking the pragma is most likely to distribute syntactic relief nicely over a lexical scope. In any case it would only set the default CATCH handler which could still be overridden in any particular try block. So, basically, we could just turn blockless try/gather/do into listops from a precedence point of view, though they'd still essentially be macros. This seems like a good thing. At worst it means you need to use parens: try($x if $y); if you need a statement as an argument, where currently you could write try $x if $y; But staring at those two, I'd say the parens are almost a feature from the least surprise viewpoint. Larry
Re: [perl #57636] [TODO][PDD19] Document the reason for :unique_reg flag
On Tue, Aug 05, 2008 at 10:51:08AM -0700, Klaas-Jan Stol wrote: From pdd19: The optional C:unique_reg modifier will force the register allocator to associate the identifier with a unique register for the duration of the subroutine. This, however, does not document /why/ you would want to do that. Why do we have this flag? Maybe add an example. Sometimes the register allocator will re-use a register when it's important that the register not be reused. The :unique_reg flag is supposed to guarantee that whatever register is allocated for a symbol is used _only_ for that symbol and not re-allocated. PGE has used :unique_reg to try to turn off the register allocator for the subs it generates, which tended to perform badly both in terms of speed and in terms of correctly allocating registers. (All of PGE's generated subs use a small fixed number of registers and so the register allocator is a detriment and not a help.) Pm
Re: [perl #57608] [PATCH] add ports/cygwin
On Wed, Aug 6, 2008 at 11:09 AM, Mark Glines [EMAIL PROTECTED] wrote: On Tuesday 05 August 2008 20:57:53 chromatic wrote: On Tuesday 05 August 2008 01:35:48 Reini Urban wrote: Attached patch adds the directory ports/cygwin with the most recent cygports file, the most recent src patch and the sources for the CYGWIN patches. (the contents of parrot-0.6.4-2.cygwin.patch which creates those files in CYGWIN-PATCHES/) Thanks, applied as r30048. This patch causes t/codingstd/filenames.t to fail (because the filename has multiple dots). Perhaps an exception should be made in this case? Mark Yes. I highly recommend that anyone with a commit bit subscribe to the failing smolder test RSS feed. =-) Test updated in r30065. -- Will Coke Coleda
Re: [perl #57636] [TODO][PDD19] Document the reason for :unique_reg flag
On Wed, Aug 6, 2008 at 1:58 PM, Patrick R. Michaud [EMAIL PROTECTED] wrote: On Tue, Aug 05, 2008 at 10:51:08AM -0700, Klaas-Jan Stol wrote: From pdd19: The optional C:unique_reg modifier will force the register allocator to associate the identifier with a unique register for the duration of the subroutine. This, however, does not document /why/ you would want to do that. Why do we have this flag? Maybe add an example. Sometimes the register allocator will re-use a register when it's important that the register not be reused. Can you describe a situation where this occurs that isn't a bug in the register allocator? The :unique_reg flag is supposed to guarantee that whatever register is allocated for a symbol is used _only_ for that symbol and not re-allocated. PGE has used :unique_reg to try to turn off the register allocator for the subs it generates, which tended to perform badly both in terms of speed and in terms of correctly allocating registers. (All of PGE's generated subs use a small fixed number of registers and so the register allocator is a detriment and not a help.) Pm -- Will Coke Coleda
Re: [perl #57636] [TODO][PDD19] Document the reason for :unique_reg flag
On Wednesday 06 August 2008 11:08:13 Will Coleda wrote: Sometimes the register allocator will re-use a register when it's important that the register not be reused. Can you describe a situation where this occurs that isn't a bug in the register allocator? I can't think of one. -- c
Re: [perl #57548] [TODO] enhance #CONDITIONED_LINE by recursive logical expressions as in LISP
2008/8/3 Reini Urban via RT [EMAIL PROTECTED]: First patch was wrong, this is ok. (conf arg was missing) And this patch actually implements this feature for 90%. (and or not mult.keys) Just the parenthesis grouping is missing. (and key (not key)) I'll commit more useful examples later, where I actually need them. For now just the root Makefile is changed. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ Index: parrot-svn/lib/Parrot/Configure/Compiler.pm === --- parrot-svn.orig/lib/Parrot/Configure/Compiler.pm +++ parrot-svn/lib/Parrot/Configure/Compiler.pm @@ -181,17 +181,41 @@ to '#', Creplace_slashes to enabled, a If the name of the file being generated ends in CMakefile, this option defaults to true. -=item conditioned_lines +=item conditioned_lines and #+(): #-(): -If conditioned_lines is true, then lines in the file that begin with: -C#CONDITIONED_LINE(var): are skipped if the var condition is false. Lines -that begin with C#INVERSE_CONDITIONED_LINE(var): are skipped if -the var condition is true. For instance: +If conditioned_lines is true, then lines in the file that begin with +C#+(expr): are skipped if the expr condition is false. +Lines that begin with C#-(var): are skipped if the expr condition is true. +For legacy the old syntax #CONDITIONED_LINE(var): and +#INVERSE_CONDITIONED_LINE(var): is also supported. + +A condition expr may be a single keyword, which is true if a config key is true +or equal to the platform name, +or a logical combination or (and expr1 expr2...) or (or expr1 expr2...) or +(not expr) as in the common lisp reader, 'OR' being the default for multiple keys. +Multiple keys are space seperated. + +TODO: Keys may also consist of key=value pairs, where the key is checked for +equalness to the value. Note that values may contain no spaces here. +TODO: support quotes in values - #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O) + #+(var1 var2...) defaults to #+(or var1 var2...) + #-(var1 var2...) defaults to #-(or var1 var2...) + +For instance: + + #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O) will be processed if the platform is win32. + #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O) + +will be skipped if the platform is win32 or cygwin. + + #+(and win32 glut (not cygwin)): + +will be used on win32 and if glut is defined, but not on cygwin. + =item comment_type This option takes has two possible values, C# or C/*. If present and @@ -320,12 +344,20 @@ sub genfile { last; } if ( $options{conditioned_lines} ) { -if ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { -next unless $conf-data-get($1); + # allow multiple keys and nested parens here +if ( $line =~ m/^#([-+])\((.+)\):(.*)/s ) { + my $truth = cond_eval($conf, $2); + next if ($1 eq '-') and $truth; + next if ($1 eq '+') and not $truth; +$line = $3; + } + # but here not (legacy) + elsif ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { +next unless cond_eval($conf, $1); $line = $2; } elsif ( $line =~ m/^#INVERSE_CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { -next if $conf-data-get($1); +next if cond_eval($conf, $1); $line = $2; } } @@ -425,6 +457,42 @@ sub genfile { move_if_diff( $target.tmp, $target, $options{ignore_pattern} ); } +# Just checks the logical truth of the hash value (exists and not empty). +# Also check the platform name if the hash key does not exist. +# Recursive, evaluate AND, OR, NOT with multiple keys. +# Check for key=value, like #+(ld=gcc) +sub cond_eval { +my $conf = shift; +my $expr = shift; +# TODO: parse parenthesis groups, (and (not win32) has_glut) +$expr =~ s/[\(\)]/ /g; # currently ignored +my @keys = split /\s+/, $expr; +my $key = $expr; +if (@keys 1) { # multiple keys: recurse into + my $truth; + my $op = pop @keys; + if ($key =~ /^(or|and|not)$/i) { + $op = lc($key); + $key = pop @keys; + } + while (!$truth and $key) { + $truth = cond_eval($conf, $key); + if ($op eq 'not') { $truth = $truth ? 0 : 1; } + elsif ($op eq 'and') { $truth = (@keys1) if $truth; } + $key = pop @keys; + } + return $truth; +} +if ($key =~ /^(\w+)=(.+)$/) { + return $conf-data-get($1) eq $2; +} else { + #FIXME: return $conf-data()-exists($key) + return exists($conf-data-{c}-{$key}) +? $conf-data()-get($key) + : $key eq $^O; + } +} + sub append_configure_log { my $conf = shift; my $target = shift; @@ -452,6 +520,6 @@ sub append_configure_log { # Local Variables: # mode: cperl # cperl-indent-level: 4 -# fill-column: 100 +# fill-column: 80 # End: # vim: expandtab shiftwidth=4: Index: parrot-svn/lib/Parrot/Configure/Data.pm
Re: [perl #57636] [TODO][PDD19] Document the reason for :unique_reg flag
Will Coleda wrote: Can you describe a situation where this occurs that isn't a bug in the register allocator? Yes. IIRC, it was added when I was working on the .Net bytecode translator, and it needed to take references to registers in callers. If you're doing that, you need to know that the register won't get re-used once the reference has been taken, or you'll end up with a reference to the wrong register. Named registers holding things that references were being taken to, were marked with :unique_reg, to make sure this didn't happen. It also, as Pm mentioned, works as a hint to the register allocator not to bother trying to allocate something that will have life over the entire compilation unit anyway. Jonathan
Re: [perl #57548] [TODO] enhance #CONDITIONED_LINE by recursive logical expressions as in LISP
2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/3 Reini Urban via RT [EMAIL PROTECTED]: First patch was wrong, this is ok. (conf arg was missing) And this patch actually implements this feature for 90%. (and or not mult.keys) Just the parenthesis grouping is missing. (and key (not key)) I'll commit more useful examples later, where I actually need them. For now just the root Makefile is changed. Adding testcases actually helps. This patch adds tests, and fixes a nasty recursion bug. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ Index: parrot-svn/lib/Parrot/Configure/Compiler.pm === --- parrot-svn.orig/lib/Parrot/Configure/Compiler.pm +++ parrot-svn/lib/Parrot/Configure/Compiler.pm @@ -1,5 +1,5 @@ -# Copyright (C) 2001-2007, The Perl Foundation. -# $Id: Compiler.pm 26761 2008-04-05 02:32:23Z jkeenan $ +# Copyright (C) 2001-2008, The Perl Foundation. +# $Id: Compiler.pm 29966 2008-08-03 16:09:47Z jkeenan $ =head1 NAME @@ -175,23 +175,47 @@ replacement syntax assumes the source te =item makefile -If set to a true value, this flag sets (unless overriden) Ccomment_type +If set to a true value, this flag sets (unless overridden) Ccomment_type to '#', Creplace_slashes to enabled, and Cconditioned_lines to enabled. If the name of the file being generated ends in CMakefile, this option defaults to true. -=item conditioned_lines +=item conditioned_lines and #+(): #-(): -If conditioned_lines is true, then lines in the file that begin with: -C#CONDITIONED_LINE(var): are skipped if the var condition is false. Lines -that begin with C#INVERSE_CONDITIONED_LINE(var): are skipped if -the var condition is true. For instance: +If conditioned_lines is true, then lines in the file that begin with +C#+(expr): are skipped if the expr condition is false. +Lines that begin with C#-(var): are skipped if the expr condition is true. +For legacy the old syntax #CONDITIONED_LINE(var): and +#INVERSE_CONDITIONED_LINE(var): is also supported. + +A condition expr may be a single keyword, which is true if a config key is true +or equal to the platform name, +or a logical combination or (and expr1 expr2...) or (or expr1 expr2...) or +(not expr) as in the common lisp reader, 'OR' being the default for multiple keys. +Multiple keys are space seperated. + +TODO: Keys may also consist of key=value pairs, where the key is checked for +equalness to the value. Note that values may contain no spaces here. +TODO: support quotes in values - #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O) + #+(var1 var2...) defaults to #+(or var1 var2...) + #-(var1 var2...) defaults to #-(or var1 var2...) + +For instance: + + #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O) will be processed if the platform is win32. + #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O) + +will be skipped if the platform is win32 or cygwin. + + #+(and win32 glut (not cygwin)): + +will be used on win32 and if glut is defined, but not on cygwin. + =item comment_type This option takes has two possible values, C# or C/*. If present and @@ -219,21 +243,21 @@ a very helpful option when writing Makef =item expand_gmake_syntax -If set to a true value, then certain types of gmake syntax will be expanded +If set to a true value, then certain types of Igmake syntax will be expanded into their full equivalents. For example: $(wildcard PATTERN) -Will be replaced Iat config time with the list of files that match this +Will be replaced Bat config time with the list of files that match this pattern. Note! Be very careful when determining whether or not to disable -this expansion during config time and letting gmake evaluate these: the +this expansion during config time and letting Igmake evaluate these: the config system itself may change state of the filesystem, causing the directives to expand differently depending on when they're run. Another potential issue to consider there is that most makefiles, while generated -from the root directory, are Irun from a subdirectory. So relative path names +from the root directory, are Brun from a subdirectory. So relative path names become an issue. -The gmake replacements are done repeatedly on a single line, so nested +The Igmake replacements are done repeatedly on a single line, so nested syntax works ok. =over 4 @@ -277,7 +301,9 @@ sub genfile { } if ( $options{comment_type} ) { -my @comment = ( DO NOT EDIT THIS FILE, Generated by . __PACKAGE__ . from $source ); +my @comment = ( 'ex: set ro ft=c:', +'DO NOT EDIT THIS FILE', +'Generated by ' . __PACKAGE__ . from $source ); if ( $options{comment_type} eq '#' ) { foreach my $line (@comment) { @@ -294,8 +320,7 @@ sub genfile { else { die Unknown comment type '$options{comment_type}'; } -foreach my $line (@comment) { print $out $line; } -print $out
Re: [perl #57548] [TODO] enhance #CONDITIONED_LINE by recursive logical expressions as in LISP
2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/3 Reini Urban via RT [EMAIL PROTECTED]: First patch was wrong, this is ok. (conf arg was missing) And this patch actually implements this feature for 90%. (and or not mult.keys) Just the parenthesis grouping is missing. (and key (not key)) I'll commit more useful examples later, where I actually need them. For now just the root Makefile is changed. Adding testcases actually helps. This patch adds tests, and fixes a nasty recursion bug. And this tests the key=value feature also. Now my laptop battery is over soon... Index: parrot-svn/lib/Parrot/Configure/Compiler.pm === --- parrot-svn.orig/lib/Parrot/Configure/Compiler.pm +++ parrot-svn/lib/Parrot/Configure/Compiler.pm @@ -1,5 +1,5 @@ -# Copyright (C) 2001-2007, The Perl Foundation. -# $Id: Compiler.pm 26761 2008-04-05 02:32:23Z jkeenan $ +# Copyright (C) 2001-2008, The Perl Foundation. +# $Id: Compiler.pm 29966 2008-08-03 16:09:47Z jkeenan $ =head1 NAME @@ -175,23 +175,47 @@ replacement syntax assumes the source te =item makefile -If set to a true value, this flag sets (unless overriden) Ccomment_type +If set to a true value, this flag sets (unless overridden) Ccomment_type to '#', Creplace_slashes to enabled, and Cconditioned_lines to enabled. If the name of the file being generated ends in CMakefile, this option defaults to true. -=item conditioned_lines +=item conditioned_lines and #+(): #-(): -If conditioned_lines is true, then lines in the file that begin with: -C#CONDITIONED_LINE(var): are skipped if the var condition is false. Lines -that begin with C#INVERSE_CONDITIONED_LINE(var): are skipped if -the var condition is true. For instance: +If conditioned_lines is true, then lines in the file that begin with +C#+(expr): are skipped if the expr condition is false. +Lines that begin with C#-(var): are skipped if the expr condition is true. +For legacy the old syntax #CONDITIONED_LINE(var): and +#INVERSE_CONDITIONED_LINE(var): is also supported. + +A condition expr may be a single keyword, which is true if a config key is true +or equal to the platform name, +or a logical combination or (and expr1 expr2...) or (or expr1 expr2...) or +(not expr) as in the common lisp reader, 'OR' being the default for multiple keys. +Multiple keys are space seperated. + +TODO: Keys may also consist of key=value pairs, where the key is checked for +equalness to the value. Note that values may contain no spaces here. +TODO: support quotes in values - #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O) + #+(var1 var2...) defaults to #+(or var1 var2...) + #-(var1 var2...) defaults to #-(or var1 var2...) + +For instance: + + #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O) will be processed if the platform is win32. + #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O) + +will be skipped if the platform is win32 or cygwin. + + #+(and win32 glut (not cygwin)): + +will be used on win32 and if glut is defined, but not on cygwin. + =item comment_type This option takes has two possible values, C# or C/*. If present and @@ -219,21 +243,21 @@ a very helpful option when writing Makef =item expand_gmake_syntax -If set to a true value, then certain types of gmake syntax will be expanded +If set to a true value, then certain types of Igmake syntax will be expanded into their full equivalents. For example: $(wildcard PATTERN) -Will be replaced Iat config time with the list of files that match this +Will be replaced Bat config time with the list of files that match this pattern. Note! Be very careful when determining whether or not to disable -this expansion during config time and letting gmake evaluate these: the +this expansion during config time and letting Igmake evaluate these: the config system itself may change state of the filesystem, causing the directives to expand differently depending on when they're run. Another potential issue to consider there is that most makefiles, while generated -from the root directory, are Irun from a subdirectory. So relative path names +from the root directory, are Brun from a subdirectory. So relative path names become an issue. -The gmake replacements are done repeatedly on a single line, so nested +The Igmake replacements are done repeatedly on a single line, so nested syntax works ok. =over 4 @@ -277,7 +301,9 @@ sub genfile { } if ( $options{comment_type} ) { -my @comment = ( DO NOT EDIT THIS FILE, Generated by . __PACKAGE__ . from $source ); +my @comment = ( 'ex: set ro ft=c:', +'DO NOT EDIT THIS FILE', +'Generated by ' . __PACKAGE__ . from $source ); if ( $options{comment_type} eq '#' ) { foreach my $line (@comment) { @@ -294,8 +320,7 @@ sub genfile { else { die Unknown comment type '$options{comment_type}'; } -
Re: [perl #57548] [TODO] enhance #CONDITIONED_LINE by recursive logical expressions as in LISP
2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/6 Reini Urban [EMAIL PROTECTED]: 2008/8/3 Reini Urban via RT [EMAIL PROTECTED]: First patch was wrong, this is ok. (conf arg was missing) And this patch actually implements this feature for 90%. (and or not mult.keys) Just the parenthesis grouping is missing. (and key (not key)) I'll commit more useful examples later, where I actually need them. For now just the root Makefile is changed. Adding testcases actually helps. This patch adds tests, and fixes a nasty recursion bug. And this tests the key=value feature also. Now my laptop battery is over soon... A little bit of power is still left. This patch is against the current svn of Compiler.pm actually. Sorry. -- Reini Urban http://phpwiki.org/ http://murbreak.at/ Index: parrot-svn/lib/Parrot/Configure/Compiler.pm === --- parrot-svn.orig/lib/Parrot/Configure/Compiler.pm +++ parrot-svn/lib/Parrot/Configure/Compiler.pm @@ -181,17 +181,41 @@ to '#', Creplace_slashes to enabled, a If the name of the file being generated ends in CMakefile, this option defaults to true. -=item conditioned_lines +=item conditioned_lines and #+(): #-(): -If Cconditioned_lines is true, then lines in the file that begin with: -C#CONDITIONED_LINE(var): are skipped if the Cvar condition is false. Lines -that begin with C#INVERSE_CONDITIONED_LINE(var): are skipped if -the Cvar condition is true. For instance: +If conditioned_lines is true, then lines in the file that begin with +C#+(expr): are skipped if the expr condition is false. +Lines that begin with C#-(var): are skipped if the expr condition is true. +For legacy the old syntax #CONDITIONED_LINE(var): and +#INVERSE_CONDITIONED_LINE(var): is also supported. + +A condition expr may be a single keyword, which is true if a config key is true +or equal to the platform name, +or a logical combination or (and expr1 expr2...) or (or expr1 expr2...) or +(not expr) as in the common lisp reader, 'OR' being the default for multiple keys. +Multiple keys are space seperated. + +TODO: Keys may also consist of key=value pairs, where the key is checked for +equalness to the value. Note that values may contain no spaces here. +TODO: support quotes in values - #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O) + #+(var1 var2...) defaults to #+(or var1 var2...) + #-(var1 var2...) defaults to #-(or var1 var2...) + +For instance: + + #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O) will be processed if the platform is win32. + #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O) + +will be skipped if the platform is win32 or cygwin. + + #+(and win32 glut (not cygwin)): + +will be used on win32 and if glut is defined, but not on cygwin. + =item comment_type This option takes has two possible values, C# or C/*. If present and @@ -321,12 +345,20 @@ sub genfile { last; } if ( $options{conditioned_lines} ) { -if ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { -next unless $conf-data-get($1); + # allow multiple keys and nested parens here +if ( $line =~ m/^#([-+])\((.+)\):(.*)/s ) { + my $truth = cond_eval($conf, $2); + next if ($1 eq '-') and $truth; + next if ($1 eq '+') and not $truth; +$line = $3; + } + # but here not (legacy) + elsif ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { +next unless cond_eval($conf, $1); $line = $2; } elsif ( $line =~ m/^#INVERSE_CONDITIONED_LINE\(([^)]+)\):(.*)/s ) { -next if $conf-data-get($1); +next if cond_eval($conf, $1); $line = $2; } } @@ -426,6 +458,41 @@ sub genfile { move_if_diff( $target.tmp, $target, $options{ignore_pattern} ); } +# Just checks the logical truth of the hash value (exists and not empty). +# Also check the platform name if the hash key does not exist. +# Recursive, evaluate AND, OR, NOT with multiple keys. +# Check for key=value, like #+(ld=gcc) +sub cond_eval { +my $conf = shift; +my $expr = shift; +# TODO: parse parenthesis groups, (and (not win32) has_glut) +$expr =~ s/[\(\)]/ /g; # currently ignored +my @keys = split /\s+/, $expr; +if (@keys 1) { # multiple keys: recurse into + my ($truth, $key); + my $op = $key = shift @keys; + if ($op =~ /^(or|and|not)$/i) { + $op = lc($op); + $key = shift @keys; + } + while (!$truth and $key) { + $truth = cond_eval($conf, $key); + if ($op eq 'not') { $truth = $truth ? 0 : 1; } + elsif ($op eq 'and') { $truth = (@keys1) if $truth; } + $key = shift @keys; + } + return $truth; +} +if ($expr =~ /^(\w+)=(.+)$/) { + return $conf-data-get($1) eq $2; +} else { + #FIXME: return $conf-data()-exists($key) + return exists($conf-data-{c}-{$expr}) +?
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