Re: Flunking tests and failing code
Luke Palmer <[EMAIL PROTECTED]> wrote: > I wonder if there is a macroey thing that we can do here. That is, > could we make: > > ok(1); > is(1, 1); > like("foo", /foo/); > > Into: > > ok(1); > ok(1 == 1); > ok("foo" ~~ /foo/); > > And lexically analyze the argument to ok() to find out how to report > the error? Something in the style of Smart::Comments which looks at > subexpressions and tells you about them automatically. It strikes me that the test framework is probably the one part of the libraries where simplicity is more important than DWIMmery, lest a Perl bug manifest itself somewhere deep in the bowels of the test framework itself. -- Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]> Perl and Parrot hacker
Re: the $! too global
On 12/5/05, Darren Duncan <[EMAIL PROTECTED]> wrote: > Under the current system, a subroutine argument is an alias for the > container passed to it; The most immediate offender here is the referential passing semantics. Here is a code case: sub foo ($x, &code) { &code(); say $x; } my $bar = 41; foo($bar, { $bar++ }); As far as I recall, the spec says that this should output "42". My intuition tells me that it should output "41". In fact, most modern languages (python, java, ...) would consider it to be "41". They have "assignment" semantics, rather than "binding" semantics. What was the reason for choosing binding semantics? Luke
Re: the $! too global
HaloO, Luke Palmer wrote: The most immediate offender here is the referential passing semantics. IIRC, the default is to be a read-only ref. Not even local modifications are permitted if the 'is copy' property is missing. Here is a code case: sub foo ($x, &code) { &code(); say $x; } my $bar = 41; foo($bar, { $bar++ }); As far as I recall, the spec says that this should output "42". My intuition tells me that it should output "41". My intuition also opts for 41. Evaluating &code() inside foo either violates the constance of its own $x if the changes propagate back into the already bound/passed argument or violates the callers excapsulation. The latter depends on what exactly the second argument of the call of foo closes over. Theoretically the binding of CALLER<$bar> to foo<$x> could spill over to the closure which then would mean foo(x => $bar, { $x++ }) and require $x beeing declared either 'is copy' or 'is rw'. In other words it could be marked as error. -- $TSa.greeting := "HaloO"; # mind the echo!
Re: the $! too global
TSa skribis 2005-12-05 12:32 (+0100): > IIRC, the default is to be a read-only ref. Not even local modifications s/ref/alias/, which you can see as an implicit or automatic reference, but which we usually don't call that. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: the $! too global
HaloO, Darren Duncan wrote: The problem is that $! is being treated too much like a global variable and not enough like a lexical variable. Consider the following example: Wasn't the idea to have $! only bound in CATCH blocks? sub foo () { try { die MyMessage.new( 'key' => 'dang', 'vars' => {'from'=>'foo()'} ); }; CATCH { if ($!) { display_message( $! ); } else { display_message( MyMessage.new( 'key' => 'nuthin_wrong', 'vars' => {'from'=>'foo()'} ) ); } } # end of CATCH } Note that, while my examples don't use a CATCH block (which isn't yet implemented in Pugs), you get the exception from $! or an alias thereof anyway, so whether or not I used CATCH is factored out of the discussion at hand here. Well, I think it brings us back to the discussion about the exception semantics ;) A CATCH block is not supposed to be executed under normal circumstances and $! is undef outside of CATCH blocks. Your code mixes these two things. The big problem here is that almost any argument for any subroutine could potentially come from $!, and it would be rediculous for them all to be 'is copy' just to handle the possibility. Oh, you are advocating exception handling while an exception is handled! Thus after handling the exception exception the one-level-down exception handler procedes normally exceptional again. Finally the normal, non-exceptional layer is re-instated, or some such. Nor is it reasonable for a caller to have to copy $! to another variable before passing it to a subroutine just because that sub *may* have its own try block ... a caller shouldn't have to know about the implementation of what it called. I welcome feedback on this issue and a positive, elegant resolution. I'm still advocating a semantic for exceptions that drop out of the normal flow of events and call code explicitly dedicated to that task. Returning to the normal flow as if nothing exceptional happened is particularly *not* guarenteed! Thus the context of $! is *not* the runtime context, just like the compile context isn't runtime either. Actually, many of the exceptions might be compiled-in assertions that where silenced warnings of the compiler: "didn't I say we'll meet again :)". -- $TSa.greeting := "HaloO"; # mind the echo!
Re: the $! too global
On Mon, Dec 05, 2005 at 12:32:03PM +0100, TSa wrote: > HaloO, > > Luke Palmer wrote: > >The most immediate offender here is the referential passing semantics. > > IIRC, the default is to be a read-only ref. Not even local modifications > are permitted if the 'is copy' property is missing. > > > > Here is a code case: > > > >sub foo ($x, &code) { > >&code(); > >say $x; > >} > >my $bar = 41; > >foo($bar, { $bar++ }); > > > >As far as I recall, the spec says that this should output "42". My > >intuition tells me that it should output "41". > > My intuition also opts for 41. Evaluating &code() inside foo either > violates the constance of its own $x if the changes propagate back > into the already bound/passed argument or violates the callers > excapsulation. The latter depends on what exactly the second argument > of the call of foo closes over. Theoretically the binding of > CALLER<$bar> to foo<$x> could spill over to the closure which then > would mean foo(x => $bar, { $x++ }) and require $x beeing declared > either 'is copy' or 'is rw'. In other words it could be marked as error. No, I think not, because the closure on the last line closes over a read/write variable. It happens that read only reference to the same variable is passed into the subroutine, but that's fine, because the subroutine never writes to *its* reference. Thinking about it in C terms, where pointers and values are explicit, it's as if function arguments are always passed as const pointers to a value in a outer scope. This seems fine and consistent to me, but you can never be sure whether anyone else has another pointer to that same value, which they can modify at any time. If nearly all function parameters are PMCs (internally) I don't think that this is an efficiency problem, as PMCs are always reference semantics, even when loaded into Parrot's registers. Nicholas Clark
Re: the $! too global
HaloO, Nicholas Clark wrote: No, I think not, because the closure on the last line closes over a read/write variable. It happens that read only reference to the same variable is passed into the subroutine, but that's fine, because the subroutine never writes to *its* reference. So, you argue that Luke's example should print 42? Thinking about it in C terms, where pointers and values are explicit, it's as if function arguments are always passed as const pointers to a value in a outer scope. This seems fine and consistent to me, but you can never be sure whether anyone else has another pointer to that same value, which they can modify at any time. Sure. But I consider this a semantic nightmare. And the optimizer thinks the same. Basically every variable then becomes volatile in C terms :( Note that lazy evaluation does *not* imply permanent refetching. Actually the opposite is true, lazy evaluation implies some capturing of former state as far as the lazied part needs it to produce its content. And item parameters aren't even lazy by default! If nearly all function parameters are PMCs (internally) I don't think that this is an efficiency problem, as PMCs are always reference semantics, even when loaded into Parrot's registers. The point I'm argueing about is how exposed subs like Luke's foo should be to this. Essentially I want the invocation of foo to create a COW branchpoint in the outer $bar such that when, from where ever, this value is changed, the former $bar that foo's $x was bound to remains unharmed. And is garbage collected when foo is done with it. -- $TSa.greeting := "HaloO"; # mind the echo!
Re: scalar/array contexts in perl5 vs. perl6
On Sun, Dec 04, 2005 at 01:10:44PM -0500, Mike Li wrote: > what is a good translation of the following C into perl6? [snip] > > in perl5, i would've written something like: > > > my $x = 0; my @y = 1..9; @y[$x++]++; print "$x\n"; print "@y\n" > > > but in perl6, the '@' sigil always means list context, Um ... do you mean s/perl6/perl5/ above? In perl6 the @ sigil does not always mean list context; it just means that you're dealing with an array somehow. Your code above is practically perl6 already. The only problem with it that I see is that you need to use @y[] to interpolate an array into a string: my $x = 0; my @y = 1..9; @y[$x++]++; print "$x\n"; print "@y[]\n" -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: the $! too global
My gut-level feeling on this is that $! is going to end up being an "env" variable like $_. (If you don't know what "env" is then you've not read the conjectural parts of S2 lately.) Then the problem reduces to what you do with an unhandled $! at the end of a lexical scope, which is probably just to fail, insofar as this style of processing is treating the rest of the block as an implicit catch block. We'd also have to determine what "handled" means. Probably just evaluating $! for boolean is sufficient to mark it as handled. With the env solution, if an inner sub wants to refer to its caller's $!, it'd use $+! or ENV::<$!> instead of $!. And $! passed to a sub as an argument would simply be a different variable, just as everyone gets their own $_ right now. Larry
Re: Flunking tests and failing code
On Mon, Dec 05, 2005 at 07:54:25AM +, Luke Palmer wrote: > I wonder if there is a macroey thing that we can do here. That is, > could we make: > > ok(1); > is(1, 1); > like("foo", /foo/); > > Into: > > ok(1); > ok(1 == 1); > ok("foo" ~~ /foo/); > > And lexically analyze the argument to ok() to find out how to report > the error? Something in the style of Smart::Comments which looks at > subexpressions and tells you about them automatically. I like that a lot. -kolibrie
Re: Flunking tests and failing code
Nathan Gray: > Luke Palmer: >> I wonder if there is a macroey thing that we can do here. That is, >> could we make: >> >> ok(1); >> is(1, 1); >> like("foo", /foo/); >> >> Into: >> >> ok(1); >> ok(1 == 1); >> ok("foo" ~~ /foo/); >> >> And lexically analyze the argument to ok() to find out how to report >> the error? Something in the style of Smart::Comments which looks at >> subexpressions and tells you about them automatically. > > I like that a lot. ok("that" ~ /I/) -- Grtz, Ruud
Re: Flunking tests and failing code
On Mon, 2005-12-05 at 07:54 +, Luke Palmer wrote: > I wonder if there is a macroey thing that we can do here. That is, > could we make: > > ok(1); > is(1, 1); > like("foo", /foo/); > > Into: > > ok(1); > ok(1 == 1); > ok("foo" ~~ /foo/); Can you do it without giving up the nice diagnostics that Test::More::is() provides? Note that Test.pm in Perl 5 uses ok() for everything and that DWIMmery too often doesn't. -- c