Re: Control flow variables

2003-11-25 Thread Luke Palmer
Piers Cawley writes:
> Simon Cozens <[EMAIL PROTECTED]> writes:
> > But it isn't, and I don't know why it isn't, and so we end up
> > spending loads of time discussing things that can be punted out to
> > modules. Designing Perl 6 is hard enough; let's not try to fill
> > CP6AN at the same time.
> 
> But the vast majority of us *aren't* designing Perl 6, that's Larry
> and his team's job. We're in the position of taking the work that's
> been done on the language so far and working out how we'd use it (and
> yes, we're in the business of thinking about the sort of thing
> that will go in CP6AN). Considered in that light, Luke's question is a
> really good one, it points up an ugly idiom and considers how one
> would generate a better idiom in Perl 6. Where he falls down is in
> proposing new syntax to solve the problem rather than in proposing the
> new syntax and then offering a sketch of its implementation as a macro
> in Perl 6. After all, problems with 'implemented' solutions are simply
> demonstrations that the design is sound, and that's good feedback to
> Larry and his team. These things only become real design issues if
> there appears to be no good way to solve such problems. 

Ok, back to the concrete side of things then.  How *would* one implement
a new loop hook?

Let's look at C.  It might be implemented as such:

my sub while_impl(&cond, &block) {
my &cc := Continuation.new;
try {
&block.PRE.() if &block.PRE;
if cond() {
block();
throw X::Next;
}
else {
throw X::Last;
}
CATCH { 
when X::Next { &block.NEXT.() if &block.NEXT; cc() }
when X::Last { &block.POST.() if &block.POST; }
}
}   
}

macro while($cond, $block) {
my (&cond, &block) := ($cond, $block)Â.Âparse;
return -> { while_impl(&cond, &block) }
}

Neglecting things like C.  And so to implement FINISH, you'd need
to stick a C<&block.FINISH.() if &block.FINISH> right before C.

But it would be really nice if you could do this without rewriting
C.  One way is to wrap &cond:

wrap &cond: {
call or &_.FINISH.()
};

But then you need to associate FINISH with the condition instead of the
execution block.  Or just wrap it when you can see the FINISH block.
Like:

macro FINISH($code) {
# When it's a macro/rule, caller naturally returns the parse stack
CallerContext $c = caller &Perl6::Grammar::while;

my &code := $code.parse;
$c[-1].MY.{'&cond'}.wrap({
call or code()
});
return -> {};
}

Okay, that's pretty evil.  Pretty really evil.  I took a currently
executing sub, extracted, and I one of its lexicals.  Evil
enough to make the optimizer very unhappy, in any case.

But such is the life of the Aspect-Oriented programmer.

Can anyone think of a cleaner way?

Luke

Ã


Re: Control flow variables

2003-11-25 Thread Piers Cawley
Simon Cozens <[EMAIL PROTECTED]> writes:
> Luke Palmer:
>> So modules that introduce new concepts into the language can add new
>> syntax for them without working with (ugh) a source filter.  And some of
>> these new syntaxes in the "core" language will actually be in standard
>> modules, if they're not commonly used.  Just like traits.
>
> This is good. This is what I like to hear. This is why the answer to
> all these stupid syntax questions should be "Look, if you need it,
> just put it in a module when we're done. But can we please get on
> with getting Perl 6 designed and out the door, now?"
>
> But it isn't, and I don't know why it isn't, and so we end up
> spending loads of time discussing things that can be punted out to
> modules. Designing Perl 6 is hard enough; let's not try to fill
> CP6AN at the same time.

But the vast majority of us *aren't* designing Perl 6, that's Larry
and his team's job. We're in the position of taking the work that's
been done on the language so far and working out how we'd use it (and
yes, we're in the business of thinking about the sort of thing
that will go in CP6AN). Considered in that light, Luke's question is a
really good one, it points up an ugly idiom and considers how one
would generate a better idiom in Perl 6. Where he falls down is in
proposing new syntax to solve the problem rather than in proposing the
new syntax and then offering a sketch of its implementation as a macro
in Perl 6. After all, problems with 'implemented' solutions are simply
demonstrations that the design is sound, and that's good feedback to
Larry and his team. These things only become real design issues if
there appears to be no good way to solve such problems. 




Re: Control flow variables

2003-11-21 Thread Larry Wall
On Thu, Nov 20, 2003 at 07:27:56PM -0600, Jonathan Scott Duff wrote:
: On Thu, Nov 20, 2003 at 03:26:36PM -0700, Luke Palmer wrote:
: > One wonders what the return value of a loop will be:
: > 
: > my $what = do {
: > while $cond {...}
: > }
: 
: I would expect it to be the value of the last statement executed.

Note that Perl 5 interprets it as the value of the last *expression*
evaluated, which for a while loop is going to be some variant of false:

my $what = do {
$cond = 1; 
while ($cond) { $cond = 0; 123 }
};
print $what,"\n";
__END__
0

But compare:

my $what = do {
$cond = 0; 
until ($cond) { $cond = 1; 123 }
};
print $what,"\n";
__END__
1

Implementation-wise, all that's going on is that the final value on the
expression evaluation stack is magically turned into the return value.
It would take extra effort to remember the result of the last statement
rather than the last expression.  And it would be wasted effort most of
the time.

Larry


Re: Control flow variables

2003-11-21 Thread Jonathan Scott Duff
On Thu, Nov 20, 2003 at 03:26:36PM -0700, Luke Palmer wrote:
> No.  gather{} is a generator (assuming nothing about its name or
> existance whatsoever).  It runs some code, gathering up each pick()
> (same assumption) into a list, and returning that.

Thanks for the post Luke.  I'd seen what Larry wrote, but for some
reason it didn't click until you wrote this.  I think part of that is
because I was thinking of generators something like this:

sub foo :generator { while $cond { ... yield $foo; } }
@list = &foo;

Where the declaration and use were separate (in my fantasy here,
assigning a coderef to a list makes lazy eval happen). What was
throwing my brain I think it that gather is a declaration and "call"
all rolled into one.

> If I interpret Larry correctly, Damian's semantics won't be going in.
> The way you get each of those is:
> 
> my @list = gather {
> while $cond {
> pick do {...}
> }
> }

That makes much more sense the synapse firing that was previously
happening in my head :-)

> One wonders what the return value of a loop will be:
> 
> my $what = do {
> while $cond {...}
> }

I would expect it to be the value of the last statement executed.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-20 Thread Luke Palmer
Jonathan Scott Duff writes:
> On Wed, Nov 19, 2003 at 12:49:21PM -0800, Larry Wall wrote:
> > Sorry, I wasn't being very clear.  It wouldn't be logically attached to
> > the outside of the for, but to the inside of the "confer", or whatever:
> > 
> > @foo = gather {
> > for @a -> $x { pick $x if mumble($x) }
> > DEFAULT { @results }
> > }
> 
> So ... the only way to get Damians semantics ...
> 
> On Wed, Nov 19, 2003 at 08:01:40AM +1100, Damian Conway wrote:
> > * vector control structures like C, C, and C in
> >   a list context return a list of the values of the last statement
> >   each iteration evaluated;
> >
> > * vector control structures like C, C, and C in
> >   a scalar context return an integer indicating the number of
> >   times their block was iterated.
> 
> ... is to surround the control structure with a gather { ... }  ??

No.  gather{} is a generator (assuming nothing about its name or
existance whatsoever).  It runs some code, gathering up each pick()
(same assumption) into a list, and returning that.

If I interpret Larry correctly, Damian's semantics won't be going in.
The way you get each of those is:

my @list = gather {
while $cond {
pick do {...}
}
}

And similarly for each of the other constructs.

But Damian's semantics will work for simple conditionals, it seems.

One wonders what the return value of a loop will be:

my $what = do {
while $cond {...}
}

Luke

> It seems like "gather" or whatever should be some sort of modifier to
> for/loop/while/until
> 
>   @foo = for : gather @a -> $x { ... }
>   if for : gather @a -> $x { ... } < 3 { ... }# ick!
>   if : gather for : gather @a -> $x { ... } < 3 { ... }   # ick!**2
>   for : gather @a -> $x { ... } or @results;
>   for : gather @a -> $x { ... } or do { ... }
> 
> Okay, so the syntax isn't great.  I'm just brainstorming.
> 
> Having a gather block just feels wrong to me. It's weird to say that
> control structure X only has a result when placed inside of a special
> block. But maybe it *needs* to be weird.
> 
> > On the other hand, putting the default up front is clearer if the
> > block is long.  Could even be something like:
> > 
> > @foo = gather is default(@results) {
> > for @a -> $x { pick $x if mumble($x) }
> > }
> 
> Hmm.
> 
>   @foo = for :gather,default(@results) @a -> $x { ... }
> 
> -Scott
> -- 
> Jonathan Scott Duff
> [EMAIL PROTECTED]


Re: Anonymous Multi's? [was Re: Control flow variables]

2003-11-20 Thread Dan Sugalski
On Thu, 20 Nov 2003, Dave Whipp wrote:

> "Larry Wall" <[EMAIL PROTECTED]> wrote:
> > Also, since multi is orthogonal to naming ...
>
> So I'm wondering what the correct syntax is to grab a reference to a group
> of multi-somethings.

While Larry will probably weigh in on this, I'd rather you not actually be
able to do this, at least not to start with. And definitely not the
anonymous version. Maybe for perl 6.2 or 6.4.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Anonymous Multi's? [was Re: Control flow variables]

2003-11-20 Thread Dave Whipp
"Larry Wall" <[EMAIL PROTECTED]> wrote:
> Also, since multi is orthogonal to naming ...

So I'm wondering what the correct syntax is to grab a reference to a group
of multi-somethings. Example:

multi sub foo(Int $a:) {...};
multi sub foo(String $a:) {...};

my $ref = multi &foo;

$ref("hello"); # calls &foo(String)

If this is possible, then $ref is presumably holding some form of junction
of the multi subs. Is it possible to create a similar junction of anonymous
multi-subs?


Dave.




Re: Control flow variables

2003-11-20 Thread Larry Wall
On Thu, Nov 20, 2003 at 11:23:34AM -0800, Michael Lazzaro wrote:
: 
: On Tuesday, November 18, 2003, at 12:15 PM, Luke Palmer wrote:
: >Oh, and if you really want to do that return thing without using a
: >C, you can just:
: >
: >sub blah {
: >return $a || goto CONT;
: >CONT:
: >...
: >}
: >
: >I don't see what's wrong with that. :-p
: 
: Umm... refresh my/our memory.  Did we end up having a post- form of 
: C, such that:
: 
:   return $_ if given $big.long.calculation.{ with }{ some }{ stuff };
: 
: does what I might suppose it does, or does it have to be... longer?

That'd have to be disallowed because you've nested two statement
modifiers (presuming "given" works like "for").  You'd have to write
something like:

$_ && return $_ given $big.long.calculation.{ with }{ some }{ stuff };

or more properly

defined $_ && return $_ given $big.long.calculation.{ with }{ some }{ stuff };

On the other hand, this may be clearer:

given $big.long.calculation.{ with }{ some }{ stuff } { return $_ // break; }

(But see below.)

Another minor quibble with the construct is that the $_ doesn't really belong to
the given--it uses the outer $_, much like "for", which has the same problem:

print $_ for 1..10;

I think we just have to live with that.

: (The point of that old thread was to try and find the smallest possible 
: way to write annoyingly common constructs like:
: 
: method foo ($self: $a,$b,$c) {
: return $self.cached.{ $a }{ $b }{ $c }   # short-circuit 
: calculation,
: if $self.cached.{ $a }{ $b }{ $c };  # if possible
: 
: ... otherwise do actual stuff ...
: }
: 
: but I don't recall the official recommended solution.)

Well, I'd probably write that as:

method foo ($self: $a,$b,$c) {
return $self.cached.{ $a }{ $b }{ $c } // do {
... otherwise do actual stuff ...
}
}

Larry


Re: Control flow variables

2003-11-20 Thread Michael Lazzaro
On Tuesday, November 18, 2003, at 12:15 PM, Luke Palmer wrote:
Oh, and if you really want to do that return thing without using a
C, you can just:
sub blah {
return $a || goto CONT;
CONT:
...
}
I don't see what's wrong with that. :-p
Umm... refresh my/our memory.  Did we end up having a post- form of 
C, such that:

	return $_ if given $big.long.calculation.{ with }{ some }{ stuff };

does what I might suppose it does, or does it have to be... longer?

(The point of that old thread was to try and find the smallest possible 
way to write annoyingly common constructs like:

method foo ($self: $a,$b,$c) {
return $self.cached.{ $a }{ $b }{ $c }   # short-circuit 
calculation,
if $self.cached.{ $a }{ $b }{ $c };  # if possible

... otherwise do actual stuff ...
}
but I don't recall the official recommended solution.)

Forgive the craptacularness of my current P6 knowledge, I have been 
preoccupied with life-involving stuff, with items and things and 
doohickies.

MikeL



Re: Control flow variables

2003-11-20 Thread Michael Lazzaro
On Wednesday, November 19, 2003, at 12:28 PM, Smylers wrote:
Larry Wall writes:
: Michael Lazzaro wrote:
:
: >return if $a { $a }
No, it's a syntax error.  You must write

Excellent!
I too was quietly hoping someone would say that.  These hurt my 
admittedly ever-shrinking brain:

return if $a;  # our old friend
return if $a { $a }# ow!  me noggin!  Always returns, or not?
The C encapsulation helps clarify enormously:

	return do { if $a { $a } }

... well, OK, maybe not enormously...  I'd still be annoyed if anyone 
actually wrote that with a straight face, but there's nothing offensive 
about it being legal.

MikeL



Re: Control flow variables

2003-11-20 Thread Piers Cawley
Smylers <[EMAIL PROTECTED]> writes:

> Larry Wall writes:
>
>> And nested modifiers are still quite illegal in Standard Perl 6.
>
> Right.
>
> Anybody else get the feeling we should write that down somewhere, so we
> don't have to have this conversation again in a few months?

It'll be in the summary.


Re: Control flow variables

2003-11-20 Thread Jonathan Scott Duff
On Wed, Nov 19, 2003 at 12:49:21PM -0800, Larry Wall wrote:
> Sorry, I wasn't being very clear.  It wouldn't be logically attached to
> the outside of the for, but to the inside of the "confer", or whatever:
> 
> @foo = gather {
>   for @a -> $x { pick $x if mumble($x) }
>   DEFAULT { @results }
> }

So ... the only way to get Damians semantics ...

On Wed, Nov 19, 2003 at 08:01:40AM +1100, Damian Conway wrote:
> * vector control structures like C, C, and C in
>   a list context return a list of the values of the last statement
>   each iteration evaluated;
>
> * vector control structures like C, C, and C in
>   a scalar context return an integer indicating the number of
>   times their block was iterated.

... is to surround the control structure with a gather { ... }  ??

It seems like "gather" or whatever should be some sort of modifier to
for/loop/while/until

@foo = for : gather @a -> $x { ... }
if for : gather @a -> $x { ... } < 3 { ... }# ick!
if : gather for : gather @a -> $x { ... } < 3 { ... }   # ick!**2
for : gather @a -> $x { ... } or @results;
for : gather @a -> $x { ... } or do { ... }

Okay, so the syntax isn't great.  I'm just brainstorming.

Having a gather block just feels wrong to me. It's weird to say that
control structure X only has a result when placed inside of a special
block. But maybe it *needs* to be weird.

> On the other hand, putting the default up front is clearer if the
> block is long.  Could even be something like:
> 
> @foo = gather is default(@results) {
>   for @a -> $x { pick $x if mumble($x) }
> }

Hmm.

@foo = for :gather,default(@results) @a -> $x { ... }

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-20 Thread Smylers
Larry Wall writes:

> On Wed, Nov 19, 2003 at 08:08:49AM +1100, Damian Conway wrote:
> 
> : Michael Lazzaro wrote:
> : 
> : >return if $a { $a }
> : 
> : Means:
> : 
> :if ($a) { return $a } else { return undef }
> 
> No, it's a syntax error.  You must write
> 
> return do { if $a { $a } }
> 
> to mean that.  At least in my version of Perl 6.  AIFIYP.

Excellent!  Larry, thank you for being here and enforcing sanity!

The above scared me, so I'm most glad to hear it won't be in the
language.  Apart from looking confusingly similar to much more common
statements, there already seem to be ample ways of doing this,
including:

  return $a || undef;

or, more generally if actually the two C<$a>s are not the same:

  return $a ?? $b :: undef;

Smylers



Re: Control flow variables

2003-11-20 Thread Smylers
Larry Wall writes:

> And nested modifiers are still quite illegal in Standard Perl 6.

Right.

Anybody else get the feeling we should write that down somewhere, so we
don't have to have this conversation again in a few months?

Smylers



Re: Control flow variables

2003-11-19 Thread Sean O'Rourke
[EMAIL PROTECTED] (Austin Hastings) writes:
> What does C do?

That's the operator that's used to assign values to C<$^x> and
friends in closures.  In all its glory, you give it a set of values,
and it assigns them to a block's undefined variables, quieting those
annoying warnings:

@x = 1..10;

scatter @x {
$the = 1;
$teh + $the * $The
}

# ==> 1 + 1 * 2 = 3

/s



RE: Control flow variables

2003-11-19 Thread Austin Hastings
> -Original Message-
> From: Larry Wall [mailto:[EMAIL PROTECTED]

> On the other hand, putting the default up front is clearer if the
> block is long.  Could even be something like:
> 
> @foo = gather is default(@results) {
>   for @a -> $x { pick $x if mumble($x) }
> }

And C is a better name than C, overall.

What does C do?

=Austin




Re: Control flow variables

2003-11-19 Thread Larry Wall
On Wed, Nov 19, 2003 at 09:12:01AM -0600, Jonathan Scott Duff wrote:
: On Tue, Nov 18, 2003 at 09:36:31PM -0800, Larry Wall wrote:
: > As for the original question that started this whole silly thread,
: > control structures that return values should probably be considered
: > some kind of generator, and have an explicit "yield"-like statement
: > that is orthogonal to "last" and such.  Such a generator would be
: > explicitly marked, as with "do {...}" above, only different.  The
: > inside of such a generator after the loop is the natural place
: > to say what happens if nothing in the loop "works".
: 
: I don't understand ...  Do you mean something like this?
: 
:   confer { 
:  for @a -> $x { ... } || beget @results;
:   }
: 
: where "confer" is the do-like marker and "beget" is the yield-like
: statement.  But why not this?
: 
:   for @a -> $x { ... } or do { ... }
: 
: I need an example.

Sorry, I wasn't being very clear.  It wouldn't be logically attached to
the outside of the for, but to the inside of the "confer", or whatever:

@foo = gather {
for @a -> $x { pick $x if mumble($x) }
DEFAULT { @results }
}

In which case you could also write:

@foo = gather {
DEFAULT { @results }
for @a -> $x { pick $x if mumble($x) }
}

But it might be clearer to put it outside:

@foo = gather {
for @a -> $x { pick $x if mumble($x) }
} or @results;

On the other hand, putting the default up front is clearer if the
block is long.  Could even be something like:

@foo = gather is default(@results) {
for @a -> $x { pick $x if mumble($x) }
}

Larry


Re: Control flow variables

2003-11-19 Thread Luke Palmer
Gordon Henriksen writes:
> Larry Wall wrote:
> 
> > On Tue, Nov 18, 2003 at 06:28:59PM -0500, Gordon Henriksen wrote:
> > 
> > > my @b = for @a -> $_ {
> > > ...
> > > }
> > 
> > That will be a syntax error. Generators are too mind-stretching to
> > inflict on novices [...]
> 
> I making the point that within the context of this we-wish-loops-were-
> expressions discussion, the "for expression" was simply another way
> to spell map, at least when autoiterating an array.
> 
> I certainly wasn't thinking in terms of coroutines--they absolutely
> deserve a large syntactic barrier.

I don't think generate{} and yield() were supposed to indicate
coroutines.  Instead, it's more like Mathematica's Sow[] and Reap[],
which would work (Perl6-ized) as follows:

@a = reap { 
sow 1;
some-other-statement;
sow 2;
}  # @a is (1,2)

It's a nice concept; it simplifies certain kinds of list processing
greatly.  It would easily be implemented with coroutines, which might
also explain the yield().

Luke



RE: Control flow variables

2003-11-19 Thread Gordon Henriksen
Larry Wall wrote:

> On Tue, Nov 18, 2003 at 06:28:59PM -0500, Gordon Henriksen wrote:
> 
> > my @b = for @a -> $_ {
> > ...
> > }
> 
> That will be a syntax error. Generators are too mind-stretching to
> inflict on novices [...]

I making the point that within the context of this we-wish-loops-were-
expressions discussion, the "for expression" was simply another way
to spell map, at least when autoiterating an array.

I certainly wasn't thinking in terms of coroutines--they absolutely
deserve a large syntactic barrier.


> > # (Apologies for the perl5-isms.)
> > for @a -> $_ {
> > push @b: do { ... };
> > }
> 
> Hmm?  I see no perl5-isms there.  Or rather, I see no 
> non-perl6-isms...

It's been a while since I read Apocalypses; I wasn't sure if do { }
(still) meant what I meant it to mean ("the result of the last
statement in the block"). There was also a scalar() in there when I
wrote the apology, but I removed it on further consideration of the
equivalence to map {}. :)

--
 
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
[EMAIL PROTECTED]




Re: Control flow variables

2003-11-19 Thread Jonathan Scott Duff
On Tue, Nov 18, 2003 at 09:36:31PM -0800, Larry Wall wrote:
> As for the original question that started this whole silly thread,
> control structures that return values should probably be considered
> some kind of generator, and have an explicit "yield"-like statement
> that is orthogonal to "last" and such.  Such a generator would be
> explicitly marked, as with "do {...}" above, only different.  The
> inside of such a generator after the loop is the natural place
> to say what happens if nothing in the loop "works".

I don't understand ...  Do you mean something like this?

confer { 
   for @a -> $x { ... } || beget @results;
}

where "confer" is the do-like marker and "beget" is the yield-like
statement.  But why not this?

for @a -> $x { ... } or do { ... }

I need an example.

thanks,

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-19 Thread Larry Wall
On Wed, Nov 19, 2003 at 09:30:15AM -0700, Luke Palmer wrote:
: Piers Cawley writes:
: > All of which means you can wrap it up in a macro and prove Simon's
: > point about what's syntax and what's CP6AN:
: > 
: >macro unless_all( Block &test is parsed //,
: >  Block &consequence, [EMAIL PROTECTED] ) 
: >  { my $guard = Object.new;
: >for [EMAIL PROTECTED], $guard 
: >  -> { when $guard { &consequence() ; last }
: >   when &test { last } } }
: > 
: > But I've probably got the signature slightly wrong. 

So far we've only allowed "is parsed" on the macro itself, not on
individual arguments.  Still, that's an interesting idea.

: I think the only thing that's wrong with your signature is that you said
: "macro" instead of "sub".  Well, and &test has to be finessed into an
: executable block somehow, but we're not supposed to know how yet.

Hmm, how about statement:unless_all and modifier:unless_all?

: > Higher Order Functions/Methods/Macros are great aren't they? 
: 
: What a modern thinker!  Use a *function* to do a common task?  *What*
: are you talking about!?  :-)

Well, you mayn't put "is parsed" on a function.  Macros have special
rules to enforce lexical scoping of syntax munging, since the syntax
must be known when the call is parsed.  A function call can be parsed
without such special knowledge.

Larry


Re: Control flow variables

2003-11-19 Thread Larry Wall
On Tue, Nov 18, 2003 at 06:28:59PM -0500, Gordon Henriksen wrote:
: Whuh? Tangential at best... The result would be the same as in a
: non-vectorized version, just repeated automatically for you.
: 
: my @b = for @a -> $_ {
: ...
: }

That will be a syntax error.  Generators are too mind-stretching to
inflict on novices as ordinary syntax.  You'll have to say something
explicit like:

my @b = generate {
for @a -> $_ {
yield ...
}
}

It's vaguely possible that "generate" and "do" are the same thing.
It's quite possible that the best name is something else entirely.
But "for" ain't it...

: Should be broadly equivalent to:
: 
: my @b = map { ... } @a;
: 
: - OR -
: 
: # (Apologies for the perl5-isms.)
: for @a -> $_ {
: push @b: do { ... };
: }

Hmm?  I see no perl5-isms there.  Or rather, I see no non-perl6-isms...

Larry


Re: Control flow variables

2003-11-19 Thread Larry Wall
On Wed, Nov 19, 2003 at 08:08:49AM +1100, Damian Conway wrote:
: Michael Lazzaro wrote:
: 
: >So, just to make sure, these two lines are both valid, but do completely 
: >different things:
: >
: >return if $a;
: 
: Means:
: 
: if ($a) { return }
: 
: 
: >return if $a { $a }
: 
: Means:
: 
:if ($a) { return $a } else { return undef }

No, it's a syntax error.  You must write

return do { if $a { $a } }

to mean that.  At least in my version of Perl 6.  AIFIYP.

Sentences are a basic concept in all human languages.  I've decided
that it's a bad psychological mistake to overgeneralize phrase-level
syntax to encompass sentence-level syntax.  The Perl 6 grammar
will know when it's starting to parse a statement, and will
make distinctions based on that.  That implies that any sub/macro
definitions for "if" have to be overloaded on parser state somehow.
We could play "multi" tricks, but I suspect the right solution is
more on the order of how we differentiate prefix:+ from infix:+.
So perhaps statement level "if" is statement:if, while modifier "if"
is modifier:if.  Huffman says those should be long anyway.

It may well be that there is a generalization to be made here, but
it's more on the order of foo:bar refers to some grammar rule
or set of rules named foo.

Also, since multi is orthogonal to naming, it'd be possible to define
things such that all variants of "if" and "while" look like this:

multi sub *statement:if (...
multi sub *modifier:if (...
multi sub *statement:while (...
multi sub *modifier:while (...

But that sort of generality would completely screw up the optimizer,
I expect, since multi is an inherently run-time concept.  It would
also create a great deal of magical action at a distance.  Lexically
scoped macros (or other grammatical mods) are a much better approach
to control structure variation.  There might be some room for lexically
scoped multi subs defining control structure, but you'd still probably
take the optimizer hit.

Larry


Re: Control flow variables

2003-11-19 Thread Luke Palmer
Piers Cawley writes:
> All of which means you can wrap it up in a macro and prove Simon's
> point about what's syntax and what's CP6AN:
> 
>macro unless_all( Block &test is parsed //,
>  Block &consequence, [EMAIL PROTECTED] ) 
>  { my $guard = Object.new;
>for [EMAIL PROTECTED], $guard 
>  -> { when $guard { &consequence() ; last }
>   when &test { last } } }
> 
> But I've probably got the signature slightly wrong. 

I think the only thing that's wrong with your signature is that you said
"macro" instead of "sub".  Well, and &test has to be finessed into an
executable block somehow, but we're not supposed to know how yet.

> Higher Order Functions/Methods/Macros are great aren't they? 

What a modern thinker!  Use a *function* to do a common task?  *What*
are you talking about!?  :-)

Luke


Re: Control flow variables

2003-11-19 Thread Luke Palmer
Jonathan Scott Duff writes:
> On Tue, Nov 18, 2003 at 11:37:22PM +0100, Seiler Thomas wrote:
> > So... lets call a function instead:
> > 
> > my $is_ok = 1;
> > for 0..6 -> $t {
> > if abs(@new[$t] - @new[$t+1]) > 3 {
> > $is_ok = 0;
> > last;
> > }
> > }
> > if $is_ok {
> > yada()  # has sideeffects...
> > }
> 
> my $t = 0..6;
> yada() if none(abs(@new[$t] ^- @new[$t+1])) > 3;
> 
> :-P

Ghod I love junctions.  :-)

Luke

> -Scott
> -- 
> Jonathan Scott Duff
> [EMAIL PROTECTED]


Re: Control flow variables

2003-11-19 Thread Randal L. Schwartz
> "Randal" == Randal L Schwartz <[EMAIL PROTECTED]> writes:

Randal> I actually consider that an annoying statement.  I have to back up
Randal> three times to figure out what it means.

And before someone whips out the Schwartzian Transform to undermine
my statement... please note that in Perl6, you'll be able to write
that left to right, which I consider a wonderful plus. :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


Re: Control flow variables

2003-11-19 Thread Randal L. Schwartz
> "Austin" == Austin Hastings <[EMAIL PROTECTED]> writes:

Austin> This is surprising. Perl has never failed to provide me with
Austin> an adequacy of rope in other places. Why get squeamish in this
Austin> instance?

The rope in other places provides overwhelming positive benefits as
well, I gather.  Everything is a tradeoff.

Austin> Hmm. While I don't really expect to see leap year code written
Austin> using nested modifiers, I think it would be nice to have each
Austin> of them appear once:

Austin>   print for @a if $debug;

I actually consider that an annoying statement.  I have to back up
three times to figure out what it means.

I think Larry was on the right track here.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


RE: Control flow variables

2003-11-19 Thread Austin Hastings


> -Original Message-
> From: Randal L. Schwartz [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, November 19, 2003 9:46 AM
> To: [EMAIL PROTECTED]
> Subject: Re: Control flow variables
>
>
> >>>>> "Smylers" == Smylers  <[EMAIL PROTECTED]> writes:
>
> Smylers> I also was under the strong impression that Larry had decreed
> Smylers> that we wouldn't have chained statement modifiers ... but I
> Smylers> thought it was because Larry had decided they would be a bad
> Smylers> thing to have rather than because they aren't feasible.
>
> They weren't chained in Perl5, very deliberately.
>
> Larry added modifiers partially to get "do { } while $cond" to work,
> and partially because he had used them in RSTS/E BASIC (which I've
> also used, and recognized immediately).  But when people started
> nesting them, the code became incredibly unreadable quickly, so
> no-nesting for Perl was a deliberate choice, not an implementation
> detail.

This is surprising. Perl has never failed to provide me with an adequacy of
rope in other places. Why get squeamish in this instance?

> Unless Larry has come up with an overwhelming reason to permit them
> after years of not having them, I doubt we'd see that (IMHO mistake)
> in Perl6.

Hmm. While I don't really expect to see leap year code written using nested
modifiers, I think it would be nice to have each of them appear once:

  print for @a if $debug;

=Austin



Re: Control flow variables

2003-11-19 Thread Randal L. Schwartz
> "Smylers" == Smylers  <[EMAIL PROTECTED]> writes:

Smylers> I also was under the strong impression that Larry had decreed
Smylers> that we wouldn't have chained statement modifiers ... but I
Smylers> thought it was because Larry had decided they would be a bad
Smylers> thing to have rather than because they aren't feasible.

They weren't chained in Perl5, very deliberately.

Larry added modifiers partially to get "do { } while $cond" to work,
and partially because he had used them in RSTS/E BASIC (which I've
also used, and recognized immediately).  But when people started
nesting them, the code became incredibly unreadable quickly, so
no-nesting for Perl was a deliberate choice, not an implementation
detail.

Unless Larry has come up with an overwhelming reason to permit them
after years of not having them, I doubt we'd see that (IMHO mistake)
in Perl6.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


RE: Control flow variables

2003-11-19 Thread Austin Hastings
> Austin Hastings wrote:
>
> > I'm way not sure about how the vector context result of iteration
> structures
> > will work. Specifically, what happens when a loop forks a thread, or
> passes
> > to a parallelized coroutine? There may not actually BE a result. (Of
> course,
> > in a right-thinking system this will be noted, and replaced by a
> placeholder
> > object that will "wait" for the result if evaluated.)
>
> Whuh? Tangential at best... The result would be the same as in a
> non-vectorized version, just repeated automatically for you.

Would EVENTUALLY be the same as ...

Sure. The whole iterator/generator thing has already been covered, so I'm
pretty sure we've got the underpinnings.

> my @b = for @a -> $_ {
> ...
> }
>
> Should be broadly equivalent to:
>
> my @b = map { ... } @a;
>
> - OR -
>
> # (Apologies for the perl5-isms.)
> for @a -> $_ {
> push @b: do { ... };
> }

Yes. I think I made that point lower down. In fact, the "collector" behavior
of evaluating for in a vector context should help people transition from
C to C. (Only Satan, or his handpicked successor Damian, will help
them get from there to C/C, however. :-)


> If the non-vectorized version has hidden a thread join operation in a
> tied or otherwise magical result value, then so too would the vectorized
> version. But that's a completely orthogonal feature; unrelated and not
> in conflict.

True, but of course the scalar version doesn't have to wait for the results.

=Austin



RE: Control flow variables

2003-11-19 Thread Gordon Henriksen
> Damian Conway wrote:
> 
> > push @moves, [$i, $j];
> > for 0..6 -> $t {
> > if abs(@new[$t] - @new[$t+1]) > 3 {
> > pop @moves;
> > last;
> > }
> > }


Thomas Seiler writes:

> my $is_ok = 1;
> for 0..6 -> $t {
> if abs(@new[$t] - @new[$t+1]) > 3 {
> $is_ok = 0;
> last;
> }
> }
> if $is_ok {
> yada()  # has sideeffects...
> }


Ironically, this flow control problem was solved many years ago indeed,
and with considerable elegance. To wit:

my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
goto SKIP_YADA;
}
}

yada();
  SKIP_YADA:

Yeah, so I'm a trouble-maker. Sorry: I don't consider downwards,
scope-escaping goto to be harmful.

Does this cause a bit less heartburn?

  YADA: {
my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
break YADA;
}
}

yada();
}

Loop controls are just goto in disguise, anyhow.

--
 
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
[EMAIL PROTECTED]> 




RE: Control flow variables

2003-11-19 Thread Gordon Henriksen
Austin Hastings wrote:

> I'm way not sure about how the vector context result of iteration
structures
> will work. Specifically, what happens when a loop forks a thread, or
passes
> to a parallelized coroutine? There may not actually BE a result. (Of
course,
> in a right-thinking system this will be noted, and replaced by a
placeholder
> object that will "wait" for the result if evaluated.)

Whuh? Tangential at best... The result would be the same as in a
non-vectorized version, just repeated automatically for you.

my @b = for @a -> $_ {
...
}

Should be broadly equivalent to:

my @b = map { ... } @a;

- OR -

# (Apologies for the perl5-isms.)
for @a -> $_ {
push @b: do { ... };
}

If the non-vectorized version has hidden a thread join operation in a
tied or otherwise magical result value, then so too would the vectorized
version. But that's a completely orthogonal feature; unrelated and not
in conflict.

--
 
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
[EMAIL PROTECTED]




Re: Control flow variables

2003-11-19 Thread Jonathan Scott Duff
On Tue, Nov 18, 2003 at 11:37:22PM +0100, Seiler Thomas wrote:
> So... lets call a function instead:
> 
> my $is_ok = 1;
> for 0..6 -> $t {
> if abs(@new[$t] - @new[$t+1]) > 3 {
> $is_ok = 0;
> last;
> }
> }
> if $is_ok {
> yada()  # has sideeffects...
> }

my $t = 0..6;
yada() if none(abs(@new[$t] ^- @new[$t+1])) > 3;

:-P

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-19 Thread Smylers
Michael Lazzaro writes:

> [EMAIL PROTECTED] (Dan Sugalski) writes:
> 
> > Luke Palmer:
> > 
> > > That's illegal anyway.  Can't chain statement modifiers :-)
> > 
> > Will be able to.
> 
> I was under the strong impression that Larry had decided that
> syntactic ambiguities prevented this from happening.

I also was under the strong impression that Larry had decreed that we
wouldn't have chained statement modifiers ... but I thought it was
because Larry had decided they would be a bad thing to have rather than
because they aren't feasible.

> (Now, of course, you will ask me for a cite to the thread, which I
> can't even begin to find at this point...)

Me neither.  A Google Groups search on perl.perl6.language with the
author 'Larry' doesn't through up anything relevant for "statement
modifiers" or obvious variants.

Smylers



RE: Control flow variables

2003-11-19 Thread Gordon Henriksen
No, because the

if $a

from "return if $a;" doesn't match the production

if   [else ]

I so don't want to be anywhere near the Perl6 parser...

--
 
Gordon Henriksen
IT Manager
ICLUBcentral Inc.
[EMAIL PROTECTED]


> -Original Message-
> From: Michael Lazzaro [mailto:[EMAIL PROTECTED] 
> Sent: Tuesday, November 18, 2003 2:06 PM
> To: [EMAIL PROTECTED]
> Subject: Re: Control flow variables
> 
> 
> 
> On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> > Given that we've introduced the concept of "if" having a 
> return status:
> >
> >   my $result = if ($a) { $a } else { $b };
> >
> 
> Would that then imply that
> 
>  sub blah {
>...  # 1
>return if $a;# 2
>...  # 3
>  }
> 
> ...would return $a if $a was true, and fall through to (3) if it was 
> false?
> 
> 
> > [EMAIL PROTECTED] (Dan Sugalski) writes:
> >>> Luke Palmer:
> >>>> That's illegal anyway.  Can't chain statement modifiers :-)
> >> Will be able to.
> 
> I was under the strong impression that Larry had decided that 
> syntactic 
> ambiguities prevented this from happening.  (Now, of course, you will 
> ask me for a cite to the thread, which I can't even begin to find at 
> this point...)
> 
> MikeL
> 
> 




Re: Control flow variables

2003-11-19 Thread Jonathan Scott Duff
On Tue, Nov 18, 2003 at 11:05:57AM -0800, Michael Lazzaro wrote:
> 
> On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> >Given that we've introduced the concept of "if" having a return status:
> >
> >  my $result = if ($a) { $a } else { $b };
> >
> 
> Would that then imply that
> 
> sub blah {
>   ...  # 1
>   return if $a;# 2
>   ...  # 3
> }
> 
> ...would return $a if $a was true,

That makes no sense.  Besides in the above fantasy, the result of the
"if" is the last thing evaluated in the block.  In this case, the
block is a single "return" statement.  Perhaps it would be clearer
thusly:

my $result = if ($a) { $b } else { $c };# Same as ...
my $result = ($a) ?? $b :: $c;  # ?

> and fall through to (3) if it was 
> false?

Of course, that's how it works :)

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Control flow variables

2003-11-19 Thread Piers Cawley
Damian Conway <[EMAIL PROTECTED]> writes:

> David Wheeler wrote:
>
>> Isn't that just:
>> for @array_of_random_values_and_types, 'ok' -> $t {
>> when 'ok' { yada(); last }
>> last unless some_sort_of_test($t);
>> }
>> IOW, the topic is only 'ok' when all of the items in the array have
>> been processed
>
> Unless, of course, the string 'ok' is also one of the random_values_and_types.
> Hence my alternative solution.

Or:

   my $guard = Object.new;
   for @array_of_random_values_and_types, $guard 
 -> { when $guard { yada(); last }
  last unless some_sort_of_test($_) }

If there's some danger of some weird equality thing somehow causing a
problem there, you might need to make a Guard class with a very strict
'=~' implementation, but otherwise I can't see any problem.

Of course, that's better if some_sort_of_test is actually a method,
because then it becomes:

   my $guard = class { method some_sort_of_test { yada() }}.new;

   for [EMAIL PROTECTED], $guard 
 -> { last unless .some_sort_of_test }

All of which means you can wrap it up in a macro and prove Simon's
point about what's syntax and what's CP6AN:

   macro unless_all( Block &test is parsed //,
 Block &consequence, [EMAIL PROTECTED] ) 
 { my $guard = Object.new;
   for [EMAIL PROTECTED], $guard 
 -> { when $guard { &consequence() ; last }
  when &test { last } } }

But I've probably got the signature slightly wrong. 

Higher Order Functions/Methods/Macros are great aren't they? 








Re: Control flow variables

2003-11-18 Thread Larry Wall
On Tue, Nov 18, 2003 at 11:14:54AM -0500, Dan Sugalski wrote:
: On Tue, 18 Nov 2003, Simon Cozens wrote:
: 
: > [EMAIL PROTECTED] (Austin Hastings) writes:
: > > This is what I was talking about when I mentioned being able to do:
: > >   &cleanup .= { push @moves: [$i, $j]; }
: >
: > This reminds me of something I thought the other day might be useful:
: >
: > $cleanup = bless {}, class {
: > method DESTROY { ... }
: > };
: >
: > Of course, it probably wouldn't work in this context because you couldn't
: > guarantee that the destructor will be called at the point of loop exit, but I
: > like the anonymous class syntax anyway.
: 
:  $cleanup = bless {}, class : impatient {
:  method DESTROY { ... }
:  };
: 
: That'll probably do it, at the expense of extra runtime block exit
: overhead until the object dies. If you just want a block exit action,
: then:
: 
:  add_block_exit_action(\&foo);
: 
: or something similar will do it. (Though we could add new syntax for it if
: you really want... :-)

Why are you guys dragging all this Perl 5 syntax back into Perl 6?
There is no bless function in Perl 6--it's a method.  Class traits
are introduced with "is", not ":".  And you don't need to backwhack
the &foo.

Sheesh.

Oh, by the way, if you want to return a value from a control structure,
you will have to do so explicitly by putting "do {...}" around it.
We will certainly *not* allow both of these:

return if $a;
return if $a {...};

Shudder.  That is so unreadable.  It doesn't even work in English.

And nested modifiers are still quite illegal in Standard Perl 6.

As for the original question that started this whole silly thread,
control structures that return values should probably be considered
some kind of generator, and have an explicit "yield"-like statement
that is orthogonal to "last" and such.  Such a generator would be
explicitly marked, as with "do {...}" above, only different.  The
inside of such a generator after the loop is the natural place
to say what happens if nothing in the loop "works".

It's important with unusual control structures to say what you mean
up front.  Making the reader back up and reparse is antisocial.
Which is why we allow statement modifiers only in moderation.

Larry


Re: Control flow variables

2003-11-18 Thread David Wheeler
On Tuesday, November 18, 2003, at 06:44  PM, Joseph Ryan wrote:

And also if @array_of_random_values contains 'ok'.
D'oh! See Damian's solution, then. ;-)

David

--
David Wheeler AIM: dwTheory
[EMAIL PROTECTED]  ICQ: 15726394
http://www.kineticode.com/ Yahoo!: dew7e
   Jabber: [EMAIL PROTECTED]
Kineticode. Setting knowledge in motion.[sm]


Re: Control flow variables

2003-11-18 Thread Damian Conway
David Wheeler wrote:

Isn't that just:

for @array_of_random_values_and_types, 'ok' -> $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have been 
processed
Unless, of course, the string 'ok' is also one of the random_values_and_types.
Hence my alternative solution.
Damian



Re: Control flow variables

2003-11-18 Thread Joseph Ryan
David Wheeler wrote:

On Tuesday, November 18, 2003, at 06:11  PM, Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types -> $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }


Isn't that just:

for @array_of_random_values_and_types, 'ok' -> $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have 
been processed, which in your code is what happens when  
some_sort_of_test($t) returns a true value.


And also if @array_of_random_values contains 'ok'.

- Joe



Re: Control flow variables

2003-11-18 Thread David Wheeler
On Tuesday, November 18, 2003, at 06:11  PM, Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types -> $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }
Isn't that just:

for @array_of_random_values_and_types, 'ok' -> $t {
when 'ok' { yada(); last }
last unless some_sort_of_test($t);
}
IOW, the topic is only 'ok' when all of the items in the array have 
been processed, which in your code is what happens when  
some_sort_of_test($t) returns a true value.

Regards,

David

--
David Wheeler AIM: dwTheory
[EMAIL PROTECTED]  ICQ: 15726394
http://www.kineticode.com/ Yahoo!: dew7e
   Jabber: [EMAIL PROTECTED]
Kineticode. Setting knowledge in motion.[sm]


Re: Control flow variables

2003-11-18 Thread Damian Conway
Joseph Ryan wrote:

Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types -> $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }
That's just:

given @array_of_random_values_and_types -> @data {
for @data.kv, [EMAIL PROTECTED] -> $i, $t {
when [EMAIL PROTECTED] { yada() }
last if not some_sort_of_test($t);
}
}
;-)

Damian



Re: Control flow variables

2003-11-18 Thread Joseph Ryan
Damian Conway wrote:

Seiler Thomas wrote:

So... lets call a function instead:

my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
$is_ok = 0;
last;
}
}
if $is_ok {
yada()  # has sideeffects...
}


That's just:

for 0..6, 'ok' -> $t {
when 'ok' { yada() }
last if abs(@new[$t] - @new[$t+1]) > 3;
}
;-)

Damian 


Not to be a jerk, but how about:

   my $is_ok = 1;
   for @array_of_random_values_and_types -> $t {
   if not some_sort_of_test($t) {
   $is_ok = 0;
   last;
   }
   }
   if $is_ok {
   yada() # has sideeffects...
   }
:)

- Joe



Re: Control flow variables

2003-11-18 Thread Damian Conway
Seiler Thomas wrote:

So... lets call a function instead:

my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
$is_ok = 0;
last;
}
}
if $is_ok {
yada()  # has sideeffects...
}


That's just:

for 0..6, 'ok' -> $t {
when 'ok' { yada() }
last if abs(@new[$t] - @new[$t+1]) > 3;
}
;-)

Damian





Re: Control flow variables

2003-11-18 Thread Seiler Thomas
Damian Conway wrote:

>  push @moves, [$i, $j];
>  for 0..6 -> $t {
>  if abs(@new[$t] - @new[$t+1]) > 3 {
>  pop @moves;
>  last;
>  }
>  }
>
>

Indeed, an elegant way around the problem.
So... lets call a function instead:

my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
$is_ok = 0;
last;
}
}
if $is_ok {
yada()  # has sideeffects...
}

(wrote many such constructs for cgi sanity
checks and always found it mildly annoying)

regards
thomas

--
Imagination is more important than knowledge [Einstein]


begin 666 wink.gif
M1TE&.#EA#P`/`+,``+^_O___
M`"'Y! $```$`+ `/``\```0T,$@):ITX5,'Y
MQ4 G>E,[EMAIL PROTECTED]>PI;C9:YZYGOQK?C12

RE: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Austin Hastings wrote:

>
>
> > -Original Message-
> > From: Dan Sugalski [mailto:[EMAIL PROTECTED]
> > Sent: Tuesday, November 18, 2003 4:34 PM
> > To: Language List
> > Subject: RE: Control flow variables
> >
> >
> > On Tue, 18 Nov 2003, Austin Hastings wrote:
> >
> > > This seems excessive, but easily discarded during optimization.
> > On the other
> > > hand, I don't trust the "last statement evaluated" behavior for
> > loops, since
> > > the optimizer could very well do surprising things to loop statements.
> > > (Likewise, however, for scalar control structures.)
> >
> > This shouldn't be a problem. If there's potential ambiguity then the
> > optimization can't be applied. Modulo optimizer bugs you'll be fine.
> >
>
> That's the problem I have with it. I'm inclined to believe that the
> optimization is more important than the postcondition, most of the time.

Then don't do the things that would disable the optimization. It's
reasonably straightforward to tell whether a block's value may be used--if
there's any following statement then, well, it isn't.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Dan Sugalski [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 4:34 PM
> To: Language List
> Subject: RE: Control flow variables
>
>
> On Tue, 18 Nov 2003, Austin Hastings wrote:
>
> > This seems excessive, but easily discarded during optimization.
> On the other
> > hand, I don't trust the "last statement evaluated" behavior for
> loops, since
> > the optimizer could very well do surprising things to loop statements.
> > (Likewise, however, for scalar control structures.)
>
> This shouldn't be a problem. If there's potential ambiguity then the
> optimization can't be applied. Modulo optimizer bugs you'll be fine.
>

That's the problem I have with it. I'm inclined to believe that the
optimization is more important than the postcondition, most of the time.

On the gripping hand, I *really* like "Damian's Simple Rules for Control
Flow Return Values". So much so that I can easily see a bunch of idioms
coming up around them.

First:

  return if (some hideously long and possibly expensive guard);

That one just rocks. It's like:

  $_ = &expensive();
  return if;


  Valley Perl .. It's .. Valley Perl
  like .. return if
  when...ever
  duh!


Second:

I'm way not sure about how the vector context result of iteration structures
will work. Specifically, what happens when a loop forks a thread, or passes
to a parallelized coroutine? There may not actually BE a result. (Of course,
in a right-thinking system this will be noted, and replaced by a placeholder
object that will "wait" for the result if evaluated.)

Third:

The scalar count of iterations will make it seem that C is a
macrification of C, which isn't necessarily bad. In fact, I can see
this:

  $count = for [EMAIL PROTECTED] -> $a {
check($a) or last;
  }

  if ($count != @a) { fail; }

Leading to:

  if (scalar(@a) != for [EMAIL PROTECTED] -> $a { check($a) or last; }) { fail; }

Which leads to C/C pretty directly:

  if grep {!check($^a) } @a { fail; }

So it should actually help with the newbie learning curve, providing an easy
transition from loops to map/grep.

Which really is a good thing.

=Austin



Re: Control flow variables

2003-11-18 Thread Damian Conway
Luke Palmer wrote:

My C/C typo may
have misled you, but the original example pushed only if *none* of them
passed the condition.
Ah, sorry, I misunderstood.

So you want:

push @moves, [$i, $j];
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
pop @moves;
last;
}
}
;-)

Damian





Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
> > From: Luke Palmer [mailto:[EMAIL PROTECTED]
> >
> > Austin Hastings writes:
> > > > From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
> > > >
> > > > Would that then imply that
> > > >
> > > >  sub blah {
> > > >...  # 1
> > > >return if $a;# 2
> > > >...  # 3
> > > >  }
> > > >
> > > > ...would return $a if $a was true, and fall through to (3) if it was
> > > > false?
> > > >
> > > 
> > In particular, if we kept our bottom-up parser around, this particular
> > construct would cause an infinite-lookahead problem.  So for ambiguity's
> > sake, C should not be a valid term without a block following.
> > 
> 
> How on earth are you going to have an infinite lookahead problem when a semicolon is 
> the next character?

Sorry, s/\$a/some-hideously-long-condition/

Luke

> =Austin
> 


RE: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Austin Hastings wrote:

> This seems excessive, but easily discarded during optimization. On the other
> hand, I don't trust the "last statement evaluated" behavior for loops, since
> the optimizer could very well do surprising things to loop statements.
> (Likewise, however, for scalar control structures.)

This shouldn't be a problem. If there's potential ambiguity then the
optimization can't be applied. Modulo optimizer bugs you'll be fine.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Luke Palmer [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 3:11 PM
> To: Austin Hastings
> Cc: Michael Lazzaro; [EMAIL PROTECTED]
> Subject: Re: Control flow variables
> 
> 
> Austin Hastings writes:
> > 
> > 
> > > -Original Message-
> > > From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
> > > Sent: Tuesday, November 18, 2003 2:06 PM
> > > To: [EMAIL PROTECTED]
> > > Subject: Re: Control flow variables
> > >
> > >
> > >
> > > On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> > > > Given that we've introduced the concept of "if" having a 
> return status:
> > > >
> > > >   my $result = if ($a) { $a } else { $b };
> > > >
> > >
> > > Would that then imply that
> > >
> > >  sub blah {
> > >...  # 1
> > >return if $a;# 2
> > >...  # 3
> > >  }
> > >
> > > ...would return $a if $a was true, and fall through to (3) if it was
> > > false?
> > >
> > 
> > It sure should, provided there were a correct context waiting, 
> which would
> > quite nicely address another WIBNI thread a couple of months 
> back about a
> > quick return under those conditions.
> 
> I don't think so.  I say that all the time to mean precisely:
> 
> if $a { return }
> 
> And I don't think people are ready to give that up. 
> 
> In particular, if we kept our bottom-up parser around, this particular
> construct would cause an infinite-lookahead problem.  So for ambiguity's
> sake, C should not be a valid term without a block following.
> 

How on earth are you going to have an infinite lookahead problem when a semicolon is 
the next character?

=Austin



RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Damian Conway [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 4:02 PM
> To: Language List
> Subject: Re: Control flow variables
>
>
> Luke Palmer started a discussion:
>
>
> > I see this idiom a lot in code.  You loop through some values on a
> > condition, and do something only if the condition was never true.
> > $is_ok is a control flow variable, something I like to minimize.  Now,
> > there are other ways to do this:
> >
> > if (0..6 ==> grep -> $t { abs(@new[$t] - @new[$t+1]) })
> > { ... }
> >
> > But one would say that's not the cleanest thing in the world.
>
> Only because you overdid the sugar. :
>
>  if grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6
>  { ... }
>
> is pretty clean.
>
> But, in any case, handling exceptional cases are what exceptions are for:
>
>  try {
>  for 0..6 -> $t {
>  die if abs(@new[$t] - @new[$t+1]) > 3;
>  }
>   CATCH {
>  push @moves: [$i, $j];
>  }
>  }
>
> As regards return values of control structures, I had always assumed that:
>
>  * scalar control structures like C, C, and C
>return the value of the last statement in their block that they
>evaluated;
>
>  * vector control structures like C, C, and C in a
list
>context return a list of the values of the last statement each
>iteration evaluated;
>
>  * vector control structures like C, C, and C in
>a scalar context return an integer indicating the number of times
>their block was iterated.

This seems excessive, but easily discarded during optimization. On the other
hand, I don't trust the "last statement evaluated" behavior for loops, since
the optimizer could very well do surprising things to loop statements.
(Likewise, however, for scalar control structures.)

What does this say about order of evaluation?

  if @arry.length != while @arry { transmit(@arry.pop) or last; }
  {
print "Couldn't send them all.";
  }

I'm pretty sure that has to have unspecified behavior, but ... comment?

>
> So we might also write:
>
>  for 0..6 -> $t {
> last if abs(@new[$t] - @new[$t+1]) > 3;
>  }
>  < 7 and push @moves: [$i, $j];
>
>
> Damian

Oh goody. Another (ab)use for named blocks:

  my &named_block = for 0..6 -> $t { last if abs (@new[$t] - @new[$t+1]) >
3; }

  push @moves: [$i, $j] if &named_block() < 7;

This seems hideously powerful, but at the same time dangerous. Kind of like
select.

=Austin



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Damian Conway writes:
> Luke Palmer started a discussion:
> 
> 
> >I see this idiom a lot in code.  You loop through some values on a
> >condition, and do something only if the condition was never true.
> >$is_ok is a control flow variable, something I like to minimize.  Now,
> >there are other ways to do this:
> >
> >if (0..6 ==> grep -> $t { abs(@new[$t] - @new[$t+1]) })
> >{ ... }
> >
> >But one would say that's not the cleanest thing in the world.
> 
> Only because you overdid the sugar. :
> 
> if grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6
> { ... }
> 
> is pretty clean.

Right, but I messed it up, which isn't that important until later:

unless grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6
{ ... }

Yeah, it is cleaner (I really like to put the list up in the front seat,
but in this case it doesn't help), but it's not really *clearer*, IMO.
Still a bit too "poetic" to read easily, IMO.

> But, in any case, handling exceptional cases are what exceptions are for:
> 
> try {
> for 0..6 -> $t {
> die if abs(@new[$t] - @new[$t+1]) > 3;
> }
>   CATCH {
> push @moves: [$i, $j];
> }
> }

And that's exactly equivalent to:

for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
push @moves: [$i, $j];
last;
}
}

Which also eliminates the control variable.  My C/C typo may
have misled you, but the original example pushed only if *none* of them
passed the condition.

[snip]
> So we might also write:
> 
> for 0..6 -> $t {
>last if abs(@new[$t] - @new[$t+1]) > 3;
> }
> < 7 and push @moves: [$i, $j];

Providing the semicolon rule doesn't bite us in the curly brace.

Hmm, you inspired a fine ambiguity:

if $something { 
... 
} 
< 7 and $foo > if $something_else { ... }

Maybe control structures shouldn't return values after all :-p

(I honestly don't know what I have against that, other than fear that
someone might actually use it)

Luke


Re: Control flow variables

2003-11-18 Thread Damian Conway
Michael Lazzaro wrote:

So, just to make sure, these two lines are both valid, but do completely 
different things:

return if $a;
Means:

if ($a) { return }


return if $a { $a }
Means:

   if ($a) { return $a } else { return undef }

Damian



Re: Control flow variables

2003-11-18 Thread Damian Conway
Luke Palmer started a discussion:


I see this idiom a lot in code.  You loop through some values on a
condition, and do something only if the condition was never true.
$is_ok is a control flow variable, something I like to minimize.  Now,
there are other ways to do this:
if (0..6 ==> grep -> $t { abs(@new[$t] - @new[$t+1]) })
{ ... }
But one would say that's not the cleanest thing in the world.
Only because you overdid the sugar. :

if grep {abs(@new[$^t] - @new[$^t+1]) > 3} 0..6
{ ... }
is pretty clean.

But, in any case, handling exceptional cases are what exceptions are for:

try {
for 0..6 -> $t {
die if abs(@new[$t] - @new[$t+1]) > 3;
}
CATCH {
push @moves: [$i, $j];
}
}
As regards return values of control structures, I had always assumed that:

* scalar control structures like C, C, and C return
  the value of the last statement in their block that they evaluated;
* vector control structures like C, C, and C in a list
  context return a list of the values of the last statement each
  iteration evaluated;
* vector control structures like C, C, and C in a scalar
  context return an integer indicating the number of times their block
  was iterated.
So we might also write:

for 0..6 -> $t {
   last if abs(@new[$t] - @new[$t+1]) > 3;
}
< 7 and push @moves: [$i, $j];
Damian




Re: Control flow variables

2003-11-18 Thread Michael Lazzaro

Would that then imply that

 sub blah {
   ...  # 1
   return if $a;# 2
   ...  # 3
 }
...would return $a if $a was true, and fall through to (3) if it was
false?
It sure should, provided there were a correct context waiting, which 
would
quite nicely address another WIBNI thread a couple of months back 
about a
quick return under those conditions.
I don't think so.  I say that all the time to mean precisely:

if $a { return }

And I don't think people are ready to give that up.

In particular, if we kept our bottom-up parser around, this particular
construct would cause an infinite-lookahead problem.  So for 
ambiguity's
sake, C should not be a valid term without a block following.
So, just to make sure, these two lines are both valid, but do 
completely different things:

return if $a;
return if $a { $a }
MikeL



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
> 
> 
> > -Original Message-
> > From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
> > Sent: Tuesday, November 18, 2003 2:06 PM
> > To: [EMAIL PROTECTED]
> > Subject: Re: Control flow variables
> >
> >
> >
> > On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> > > Given that we've introduced the concept of "if" having a return status:
> > >
> > >   my $result = if ($a) { $a } else { $b };
> > >
> >
> > Would that then imply that
> >
> >  sub blah {
> >...  # 1
> >return if $a;# 2
> >...  # 3
> >  }
> >
> > ...would return $a if $a was true, and fall through to (3) if it was
> > false?
> >
> 
> It sure should, provided there were a correct context waiting, which would
> quite nicely address another WIBNI thread a couple of months back about a
> quick return under those conditions.

Oh, and if you really want to do that return thing without using a
C, you can just:

sub blah {
return $a || goto CONT;
CONT:
...
}

I don't see what's wrong with that. :-p

Luke


Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
> 
> 
> > -Original Message-
> > From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
> > Sent: Tuesday, November 18, 2003 2:06 PM
> > To: [EMAIL PROTECTED]
> > Subject: Re: Control flow variables
> >
> >
> >
> > On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> > > Given that we've introduced the concept of "if" having a return status:
> > >
> > >   my $result = if ($a) { $a } else { $b };
> > >
> >
> > Would that then imply that
> >
> >  sub blah {
> >...  # 1
> >return if $a;# 2
> >...  # 3
> >  }
> >
> > ...would return $a if $a was true, and fall through to (3) if it was
> > false?
> >
> 
> It sure should, provided there were a correct context waiting, which would
> quite nicely address another WIBNI thread a couple of months back about a
> quick return under those conditions.

I don't think so.  I say that all the time to mean precisely:

if $a { return }

And I don't think people are ready to give that up. 

In particular, if we kept our bottom-up parser around, this particular
construct would cause an infinite-lookahead problem.  So for ambiguity's
sake, C should not be a valid term without a block following.

Luke


RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Michael Lazzaro [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 2:06 PM
> To: [EMAIL PROTECTED]
> Subject: Re: Control flow variables
>
>
>
> On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
> > Given that we've introduced the concept of "if" having a return status:
> >
> >   my $result = if ($a) { $a } else { $b };
> >
>
> Would that then imply that
>
>  sub blah {
>...  # 1
>return if $a;# 2
>...  # 3
>  }
>
> ...would return $a if $a was true, and fall through to (3) if it was
> false?
>

It sure should, provided there were a correct context waiting, which would
quite nicely address another WIBNI thread a couple of months back about a
quick return under those conditions.

Very nice.

=Austin



Re: Control flow variables

2003-11-18 Thread Michael Lazzaro
On Tuesday, November 18, 2003, at 06:38 AM, Simon Cozens wrote:
Given that we've introduced the concept of "if" having a return status:

  my $result = if ($a) { $a } else { $b };

Would that then imply that

sub blah {
  ...  # 1
  return if $a;# 2
  ...  # 3
}
...would return $a if $a was true, and fall through to (3) if it was 
false?


[EMAIL PROTECTED] (Dan Sugalski) writes:
Luke Palmer:
That's illegal anyway.  Can't chain statement modifiers :-)
Will be able to.
I was under the strong impression that Larry had decided that syntactic 
ambiguities prevented this from happening.  (Now, of course, you will 
ask me for a cite to the thread, which I can't even begin to find at 
this point...)

MikeL



Re: Control flow variables

2003-11-18 Thread Mark A. Biggar
OOPS, totally miss-read your code, ignore my first part of my last
message.
--
[EMAIL PROTECTED]
[EMAIL PROTECTED]




Re: Control flow variables

2003-11-18 Thread Mark A. Biggar
Luke Palmer wrote:

I was reading the most recent article on perl.com, and a code segment
reminded me of something I see rather often in code that I don't like.
Here's the code, Perl6ized:
... ;
my $is_ok = 1;
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
$is_ok = 0;
last;
}
}
if $is_ok {
push @moves: [$i, $j];
}
...
What's wrong with:

 for 0..6 -> $t {
 if abs(@new[$t] - @new[$t+1]) > 3 {
 push @moves: [$i, $j];
 last;
 }
 }


I see this idiom a lot in code.  You loop through some values on a
condition, and do something only if the condition was never true.
$is_ok is a control flow variable, something I like to minimize.  Now,
there are other ways to do this:
if (0..6 ==> grep -> $t { abs(@new[$t] - @new[$t+1]) })
{ ... }
But one would say that's not the cleanest thing in the world.
and very unreadable, (even if that's heresy :-) )

Python pulled this idiom out in to the syntax (yay them), with C
on loops.  The else block on a python loop executes only if you never
broke out of the loop.  That's a great idea.
So, in Perl's postmodern tradition, I think we should steal that idea.
I'm a little uneasy about calling it C, though.  Maybe C
would do, making the example:
for 0..6 -> $t {
if abs(@new[$t] - @new[$t+1]) > 3 {
last;
}
FINISH { 
push @moves: [$i, $j];
}
}
Violates least surprise, if the 'if' is true for '$t == 6' due
to the ambiguity between 'last' on '$t==6' and falling out the bottom
of the loop.  Maybe you want FINISH_EARLY instead?
--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Luke Palmer [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 10:49 AM
> To: Austin Hastings
> Cc: Language List
> Subject: Re: Control flow variables
> 
> 
> Austin Hastings writes:
> > Luke Palmer wrote: 
> > > I was reading the most recent article on perl.com, and a code segment
> > > reminded me of something I see rather often in code that I don't like.
> > > Here's the code, Perl6ized:
> > > 
> > > ... ;
> > > my $is_ok = 1;
> > > for 0..6 -> $t {
> > > if abs(@new[$t] - @new[$t+1]) > 3 {
> > > $is_ok = 0;
> > > last;
> > > }
> > > }
> > > if $is_ok {
> > > push @moves: [$i, $j];
> > > }
> > > ...
> > 
> > This is what I was talking about when I mentioned being able to do:
> > 
> >   &cleanup .= { push @moves: [$i, $j]; }
> > 
> > a few weeks ago. Treat code vars like code, not like sub-refs.
> 
> I'm not sure I know what you mean with regard to this example.
> Exemplify further, please?
> 

Quoting Luke Palmer from weeks back:

> From: Luke Palmer [mailto:[EMAIL PROTECTED]
> Jeff Clites writes:
> > Austin Hastings writes:
> > > Speaking to the practical side, I have written code that has to 
> > > disentangle itself from the failure of a complex startup sequence. 
> > > I'd love to be able to build a dynamic exit sequence. (In fact, 
> > > being able to do &block .= { more_stuff(); }; is way up 
> > > on my list...)
> > 
> > I've wanted to do that sort of thing before, but it seems simpler 
> > (conceptually and practically) to build up an array of cleanup 
> > subs/blocks to execute in sequence, rather than to have a .= for 
> > blocks. (Another reason it's handy to keep them separate is in cases in 
> > which each needs to return some information--maybe a status which 
> > determines whether to proceed, etc.)
> 
> But this is already supported, in its most powerful form:
> 
> wrap &block: { call; other_stuff() }
> 
> Luke

Which begs the question of whether there's a way to get a handle to the current 
for loop from within?

  LOOP: for 0..6 -> $t {
 if abs(@new[$t] - @new[$t+1]) > 3 {
 wrap &Block(): { call; handle_error(); };
 last;
 }
 }

 # handle_error() called here?

(Yes, this would presume that the call came first, since how could it 
interpolate the call otherwise. It's a limitation of the wrap-as-append philosophy.)

=Austin



Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

> [EMAIL PROTECTED] (Austin Hastings) writes:
> > This is what I was talking about when I mentioned being able to do:
> >   &cleanup .= { push @moves: [$i, $j]; }
>
> This reminds me of something I thought the other day might be useful:
>
> $cleanup = bless {}, class {
> method DESTROY { ... }
> };
>
> Of course, it probably wouldn't work in this context because you couldn't
> guarantee that the destructor will be called at the point of loop exit, but I
> like the anonymous class syntax anyway.

 $cleanup = bless {}, class : impatient {
 method DESTROY { ... }
 };

That'll probably do it, at the expense of extra runtime block exit
overhead until the object dies. If you just want a block exit action,
then:

 add_block_exit_action(\&foo);

or something similar will do it. (Though we could add new syntax for it if
you really want... :-)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Austin Hastings) writes:
> This is what I was talking about when I mentioned being able to do:
>   &cleanup .= { push @moves: [$i, $j]; }

This reminds me of something I thought the other day might be useful:

$cleanup = bless {}, class { 
method DESTROY { ... }
};

Of course, it probably wouldn't work in this context because you couldn't
guarantee that the destructor will be called at the point of loop exit, but I
like the anonymous class syntax anyway.

-- 
I've looked at the listing, and it's right!
-- Joel Halpern


Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

> [EMAIL PROTECTED] (Dan Sugalski) writes:
> > > Luke Palmer:
> > > > That's illegal anyway.  Can't chain statement modifiers :-)
> > Will be able to.
>
> I thought as much; Perl 6 will only be finally finished when the biotech
> is sufficiently advanced to massively clone Larry...

Not because of this. It's easier to allow it than not allow it.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Luke Palmer
Austin Hastings writes:
> Luke Palmer wrote: 
> > I was reading the most recent article on perl.com, and a code segment
> > reminded me of something I see rather often in code that I don't like.
> > Here's the code, Perl6ized:
> > 
> > ... ;
> > my $is_ok = 1;
> > for 0..6 -> $t {
> > if abs(@new[$t] - @new[$t+1]) > 3 {
> > $is_ok = 0;
> > last;
> > }
> > }
> > if $is_ok {
> > push @moves: [$i, $j];
> > }
> > ...
> 
> This is what I was talking about when I mentioned being able to do:
> 
>   &cleanup .= { push @moves: [$i, $j]; }
> 
> a few weeks ago. Treat code vars like code, not like sub-refs.

I'm not sure I know what you mean with regard to this example.
Exemplify further, please?

Luke

> =Austin
> 


RE: Control flow variables

2003-11-18 Thread Austin Hastings


> -Original Message-
> From: Luke Palmer [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 18, 2003 9:21 AM
> To: Language List
> Subject: Control flow variables
> 
> 
> I was reading the most recent article on perl.com, and a code segment
> reminded me of something I see rather often in code that I don't like.
> Here's the code, Perl6ized:
> 
> ... ;
> my $is_ok = 1;
> for 0..6 -> $t {
> if abs(@new[$t] - @new[$t+1]) > 3 {
> $is_ok = 0;
> last;
> }
> }
> if $is_ok {
> push @moves: [$i, $j];
> }
> ...

This is what I was talking about when I mentioned being able to do:

  &cleanup .= { push @moves: [$i, $j]; }

a few weeks ago. Treat code vars like code, not like sub-refs.

=Austin



Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Dan Sugalski) writes:
> > Luke Palmer:
> > > That's illegal anyway.  Can't chain statement modifiers :-)
> Will be able to.

I thought as much; Perl 6 will only be finally finished when the biotech
is sufficiently advanced to massively clone Larry...

-- 
 Sometimes it's better not to pedant.


Re: Control flow variables

2003-11-18 Thread Dan Sugalski
On Tue, 18 Nov 2003, Simon Cozens wrote:

> Luke Palmer:

> > That's illegal anyway.  Can't chain statement modifiers :-)
>
> Bah, should be able to!

Will be able to.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk



Re: Control flow variables

2003-11-18 Thread Simon Cozens
Luke Palmer:
> Well... it is and isn't.  At first sight, it makes the language look
> huge, the parser complex, a lot of syntax to master, etc.  It also seems
> to me that there is little discrimination when adding new syntax. 

Correct.

> But I've come to look at it another way.  Perl 6 is doing something
> (many things, really) that no other language has done before: making it
> very easy to add new syntax to the language.

Well, that's hardly a new concept for a programming language.

> So modules that introduce new concepts into the language can add new
> syntax for them without working with (ugh) a source filter.  And some of
> these new syntaxes in the "core" language will actually be in standard
> modules, if they're not commonly used.  Just like traits.

This is good. This is what I like to hear. This is why the answer to
all these stupid syntax questions should be "Look, if you need it, just put it
in a module when we're done. But can we please get on with getting Perl 6 
designed and out the door, now?"

But it isn't, and I don't know why it isn't, and so we end up spending loads
of time discussing things that can be punted out to modules. Designing Perl 6
is hard enough; let's not try to fill CP6AN at the same time.

> I'll also point out that FINISH isn't really extra syntax, just extra
> vocabulary.

It's extra special cases, which come to the same thing.

> >   my $result = if ($a) { $a } else { $b };
> 
> Ack!  We have?  It does make sense if we want to be able to implement
> C as a regular sub... I guess.  Yuck.

Yep, we did. Of course, the "nice" thing about it is that it allows

do_thing() if if ($a) { $b } else { $c };

> That's illegal anyway.  Can't chain statement modifiers :-)

Bah, should be able to!

> But a close relative would be possible:
> push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED]) > 3 }
> 
> Yeah, how about no.  :-)

That's the thing, see. By saying no, we're saying "control structures like
'if' will be able to return a value, but control structures not like 'if'
won't", and that means we need to remove at least three words from 'When syntax
or semantics change, it will always be a change for the better: for greater
consistency, for more intuitability, for extra Do-What-I-Meanness.'... ;)

-- 
Resist the urge to start typing; thinking is a worthwhile alternative.
-- Kernighan and Pike


Re: Control flow variables

2003-11-18 Thread Luke Palmer
Simon Cozens writes:
> [EMAIL PROTECTED] (Luke Palmer) writes:
> > I was reading the most recent article on perl.com, and a code segment
> > reminded me of something I see rather often in code that I don't like.
> 
> The code in question got me thinking too; I wanted to find a cleaner
> way to write it, but didn't see one.
> 
> > So, in Perl's postmodern tradition, I think we should steal that idea.
> 
> I agree, but (as usual) would like to consider whether there's a way
> to solve a general problem rather than solving a specific problem by
> throwing additional syntax at it. (which sadly seems to be fast becoming
> the Perl 6 way)

Well... it is and isn't.  At first sight, it makes the language look
huge, the parser complex, a lot of syntax to master, etc.  It also seems
to me that there is little discrimination when adding new syntax. 

But I've come to look at it another way.  Perl 6 is doing something
(many things, really) that no other language has done before: making it
very easy to add new syntax to the language.

So modules that introduce new concepts into the language can add new
syntax for them without working with (ugh) a source filter.  And some of
these new syntaxes in the "core" language will actually be in standard
modules, if they're not commonly used.  Just like traits.

But even when they're not, Perl is a generic, multiparadigm language.
It covers and supports many concepts, and new concepts grafted onto an
existing but unfit syntax make things harder.  Humans are pretty good at
syntax.  Many times mathematicians make up new syntax when they
introduce a new concept: making it easier to think about, and easier to
recognize.

I'll also point out that FINISH isn't really extra syntax, just extra
vocabulary.

> Given that we've introduced the concept of "if" having a return status:
> 
>   my $result = if ($a) { $a } else { $b };

Ack!  We have?  It does make sense if we want to be able to implement
C as a regular sub... I guess.  Yuck.

> Then why not extend this concept and have a return status from other
> control structures?
> 
>   for 0..6 -> $t { 
> last if abs(@new[$t] - @new[$t+1]) > 3;
>   } or push @moves: [$i, $j];
> 
> Of course, these things have consequences; I'm not sure whether we really
> want people saying
> 
>   push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])>3 for 0..6;

That's illegal anyway.  Can't chain statement modifiers :-)

But a close relative would be possible:

push @moves: [$i, $j] unless for 0..6 { last if abs(@[EMAIL PROTECTED]) > 3 }

Yeah, how about no.  :-)

Luke



Re: Control flow variables

2003-11-18 Thread Simon Cozens
[EMAIL PROTECTED] (Luke Palmer) writes:
> I was reading the most recent article on perl.com, and a code segment
> reminded me of something I see rather often in code that I don't like.

The code in question got me thinking too; I wanted to find a cleaner
way to write it, but didn't see one.

> So, in Perl's postmodern tradition, I think we should steal that idea.

I agree, but (as usual) would like to consider whether there's a way
to solve a general problem rather than solving a specific problem by
throwing additional syntax at it. (which sadly seems to be fast becoming
the Perl 6 way)

Given that we've introduced the concept of "if" having a return status:

  my $result = if ($a) { $a } else { $b };

Then why not extend this concept and have a return status from other
control structures?

  for 0..6 -> $t { 
last if abs(@new[$t] - @new[$t+1]) > 3;
  } or push @moves: [$i, $j];

Of course, these things have consequences; I'm not sure whether we really
want people saying

  push @moves:[$i, $j] unless last if abs(@[EMAIL PROTECTED])>3 for 0..6;

-- 
The course of true anything never does run smooth.
-- Samuel Butler