Control Structures I: given

0 views
Skip to first unread message

Timothy S. Nelson

unread,
Nov 14, 2002, 3:05:26 PM11/14/02
to perl6-l...@perl.org
Hi all. I missed out on the original RFC process; it was over before
I even heard of perl6. Anyway, there's something I want to contribute to the
Perl community. I've had an idea about control structures which I've never
seen anywhere else, so I guess I'm the inventor :). I hope this is the
appropriate forum to do it; it looks to me like it is, but I could be wrong.

I was planning to put them all in one message, but then I thought it
would be more useful to separate them, so I'll do that instead; they'll make
much more sense if you read them in order.

Anyway, the first part is the given statement modified to fit this
idea. It'd run something like this:

--------------------------------------------------------------
given ($this) {
when $that_happens { "Have a party" }
when $that_doesnt_happen { "Sing" }
all {
# Do something
}
any {
# Do something else
}
some {
# Do something other
}
none {
# Do something however
}
}
--------------------------------------------------------------

The basic idea is that you have two "special" variables which I will,
just for now, call $truecount and $falsecount. Basically, every time one of
the "when" clauses comes up true, it increments truecount; whenever one comes
up false, it increments $falsecount. The blocks below the given get evaluated
under the following conditions

all: $falsecount == 0
any: $truecount > 0
some: $falsecount > 0
none: $truecount == 0

So anyway, "none" replaces the old "default" option, and the others
can be useful from time to time too :).

Hope this is useful.

:)


---------------------------------------------------------------------
| Name: Tim Nelson | Because the Creator is, |
| E-mail: way...@smartchat.net.au | I am |
---------------------------------------------------------------------

----BEGIN GEEK CODE BLOCK----
Version 3.1
GCS d? s: a-- C++>++++$ US+ P++ L++ E- W+++ N+ w+> M-- V- Y+>++
PGP->++ R(+) !tv B++ DI++++ D+ G e>++ h!/* y-
-----END GEEK CODE BLOCK-----


Jonathan Scott Duff

unread,
Nov 14, 2002, 11:21:11 AM11/14/02
to Timothy S. Nelson, perl6-l...@perl.org
On Fri, Nov 15, 2002 at 07:05:26AM +1100, Timothy S. Nelson wrote:
> --------------------------------------------------------------
> given ($this) {
> when $that_happens { "Have a party" }
> when $that_doesnt_happen { "Sing" }
> all {
> # Do something
> }
> any {
> # Do something else
> }
> some {
> # Do something other
> }
> none {
> # Do something however
> }
> }
> --------------------------------------------------------------

So, I was all set to show how this could work with junctions, but then
I realized that I don't understand them well enough, so here's what I
came up with:

$j0 = $that_happens | $that_doesnt_happen;
$j1 = !$that_happens | !$that_doesnt_happen;
given ($this) {
when $j0 ~~ $that_happens { ... }
when $j0 ~~ $that_doesnt_happen { ... }
when all($j0) { ... }
when any($j0) { ... }
when any($j1) { ... } # "some" Rare, I expect
when none($j0) { ... }
}

Is that right? Is there a better way? What happens when there's a
junction on either side of a smart match?

> The basic idea is that you have two "special" variables which I will,
> just for now, call $truecount and $falsecount. Basically, every time one of
> the "when" clauses comes up true, it increments truecount; whenever one comes
> up false, it increments $falsecount. The blocks below the given get evaluated
> under the following conditions
>
> all: $falsecount == 0
> any: $truecount > 0
> some: $falsecount > 0
> none: $truecount == 0

-Scott
--
Jonathan Scott Duff
du...@cbi.tamucc.edu

Luke Palmer

unread,
Nov 14, 2002, 1:38:34 PM11/14/02
to way...@smartchat.net.au, perl6-l...@perl.org
> Mailing-List: contact perl6-lan...@perl.org; run by ezmlm
> Date: Fri, 15 Nov 2002 07:05:26 +1100 (EST)
> From: "Timothy S. Nelson" <way...@smartchat.net.au>
> Sender: way...@elphin.nelson.org.au
> X-SMTPD: qpsmtpd/0.12, http://develooper.com/code/qpsmtpd/

>
> Hi all. I missed out on the original RFC process; it was over before
> I even heard of perl6.

Right. Me too. But, as you'll notice, this is certainly not keeping
it from changing :)

> Anyway, there's something I want to contribute to the Perl
> community. I've had an idea about control structures which I've
> never seen anywhere else, so I guess I'm the inventor :). I hope
> this is the appropriate forum to do it; it looks to me like it is,
> but I could be wrong.

Yes, it is.

Well, it's an interesting idea, but I don't think it's necessary. I
honestly don't recall a time when this would be useful. Perhaps a
sane example could convince me otherwise...

(As a rule of thumb, always include sane, real-world-like examples in
proposals)

Luke

Timothy S. Nelson

unread,
Nov 15, 2002, 1:48:45 PM11/15/02
to du...@pobox.com, perl6-l...@perl.org

No doubt you understand them better than I do. My complete knowledge
comes from http://archive.develooper.com/perl6-l...@perl.org/msg10178.html
(search for "superpositions").

Since I don't understand what ~~ does, I'm not quite sure I understand
your code.

I'll be glad when that virtual mug throwing guy gets the documentation
for this kind of thing done a bit more, or when synopses for the other
sections get done, so I don't have to go hunting for this kind of thing any
more :).

>
> > The basic idea is that you have two "special" variables which I will,
> > just for now, call $truecount and $falsecount. Basically, every time one of
> > the "when" clauses comes up true, it increments truecount; whenever one comes
> > up false, it increments $falsecount. The blocks below the given get evaluated
> > under the following conditions
> >
> > all: $falsecount == 0
> > any: $truecount > 0
> > some: $falsecount > 0
> > none: $truecount == 0
>
> -Scott
>

Timothy S. Nelson

unread,
Nov 15, 2002, 1:03:57 PM11/15/02
to Luke Palmer, perl6-l...@perl.org
On Thu, 14 Nov 2002, Luke Palmer wrote:

> > The blocks below the given get evaluated under the following
> > conditions
>
> > all: $falsecount == 0
> > any: $truecount > 0
> > some: $falsecount > 0
> > none: $truecount == 0
> >
> > So anyway, "none" replaces the old "default" option, and the others
> > can be useful from time to time too :).
>
> Well, it's an interesting idea, but I don't think it's necessary. I
> honestly don't recall a time when this would be useful. Perhaps a
> sane example could convince me otherwise...
>
> (As a rule of thumb, always include sane, real-world-like examples in
> proposals)

I hope you can see uses for "none", because it's "default" under a
different name :).

I've only needed this one twice in my life since I first thought of it
about 3 or 4 years ago; since I didn't have this syntax at that time, I'm not
sure I could find those problems again. At the time, I designed a solution to
the problem (ie this), but neglected to note down the problem :).

One thing I *do* recall about one of those examples (this was the
looping version which used all/any/some/none; see the loop thread I started)
-- it wasn't sane :). It was a big loop -- the stuff inside was more than 150
lines (well, that's big to me, anyway :) ). Basically, I felt like the code
didn't intuitively represent what was going on, and that's bad for
maintainability when even the original programmer thinks that :).

:)

Me

unread,
Nov 15, 2002, 4:59:00 PM11/15/02
to Timothy S. Nelson, du...@pobox.com, perl6-l...@perl.org
> My complete knowledge comes from
> archive.develooper.com/perl6-language...
> (search for "superpositions").

I find google (rather than develooper's
archive/search) the best tool for most
searching of p6lang. Unfortunately even
google only goes back so far, and doesn't
search punctuation.

Perl 6's analog to "superpositions" is
currently called "junctions".


> Since I don't understand what ~~ does,

Polymorphic equals.

Smart match.

The old =~ operator was a specific variant
of this general idea.

More generally, based on an a table of what
to do for the various LHS/RHS combinations,
a value is picked from the LHS and compared
with a value picked from the RHS. The overall
hope is it just DWIMs.


--
ralph

Timothy S. Nelson

unread,
Nov 16, 2002, 9:18:20 AM11/16/02
to Me, du...@pobox.com, perl6-l...@perl.org
On Fri, 15 Nov 2002, Me wrote:

> > My complete knowledge comes from
> > archive.develooper.com/perl6-language...
> > (search for "superpositions").
>
> I find google (rather than develooper's
> archive/search) the best tool for most
> searching of p6lang. Unfortunately even
> google only goes back so far, and doesn't
> search punctuation.

Actually, what I intended was:
1. Go to the page mentioned
2. Use your web browser's built in search feature to search within the
page for "superpositions".

> > Since I don't understand what ~~ does,
>
> Polymorphic equals.
>
> Smart match.
>
> The old =~ operator was a specific variant
> of this general idea.
>
> More generally, based on an a table of what
> to do for the various LHS/RHS combinations,
> a value is picked from the LHS and compared
> with a value picked from the RHS. The overall
> hope is it just DWIMs.

Ok. I think I see what Mr. Duff was suggesting. He was wanting the
result of each comparison added to the junction represented by $j0. If this
is possible, it'd cover it pretty well; not the optimal syntax, but
considering how often most people would use it, probably not too important.

Or, we could have $truecount and $falsecount as junctions that
automatically are set the way $j0 is set, and then we could use the junction
functions on them (is there anything else which rhymes with junction? :) ).

Damian Conway

unread,
Nov 16, 2002, 8:43:04 PM11/16/02
to perl6-l...@perl.org
Scott Duff essayed:

> So, I was all set to show how this could work with junctions, but then
> I realized that I don't understand them well enough, so here's what I
> came up with:
>
> $j0 = $that_happens | $that_doesnt_happen;
> $j1 = !$that_happens | !$that_doesnt_happen;
> given ($this) {
> when $j0 ~~ $that_happens { ... }
> when $j0 ~~ $that_doesnt_happen { ... }
> when all($j0) { ... }
> when any($j0) { ... }
> when any($j1) { ... } # "some" Rare, I expect
> when none($j0) { ... }
> }
>
> Is that right?

Not quite. The first problem is that if either of the first two C<when>
fire, we immediately break out of the C<given>. There will probably be
a lexical pragma to reverse that default behaviour.

The other problem is that your using junctions of junctions, which have
quite different semantics.

Here's some code that has (what I construe to be) the desired behaviour:

@possible_states = ($that_happens, $that_doesnt_happen);
given ($this) {
use fallthrough;


when $that_happens { "Have a party" }
when $that_doesnt_happen { "Sing" }

when all(@possible_states) {
# Do something
}
when any(@possible_states) {
# Do something else
}
when $_ !~ all(@possible_states) {
# Do something other
}
when none(@possible_states) {
# Do something however
}
}


> What happens when there's a
> junction on either side of a smart match?

That depends (multimorphically) on the types of the junctions.
Here's a handy table:


all(A,B) ~~ all(C,D) --> ( A~~C && A~~D ) && ( B~~C && B~~D )
all(A,B) ~~ any(C,D) --> ( A~~C || A~~D ) && ( B~~C || B~~D )
all(A,B) ~~ one(C,D) --> ( A~~C ^^ A~~D ) && ( B~~C ^^ B~~D )
all(A,B) ~~ none(C,D) --> (!(A~~C) && !(A~~D)) && (!(B~~C) && !(B~~D))

any(A,B) ~~ all(C,D) --> ( A~~C && A~~D ) || ( B~~C && B~~D )
any(A,B) ~~ any(C,D) --> ( A~~C || A~~D ) || ( B~~C || B~~D )
any(A,B) ~~ one(C,D) --> ( A~~C ^^ A~~D ) || ( B~~C ^^ B~~D )
any(A,B) ~~ none(C,D) --> (!(A~~C) && !(A~~D)) || (!(B~~C) && !(B~~D))

one(A,B) ~~ all(C,D) --> ( A~~C && A~~D ) ^^ ( B~~C && B~~D )
one(A,B) ~~ any(C,D) --> ( A~~C || A~~D ) ^^ ( B~~C || B~~D )
one(A,B) ~~ one(C,D) --> ( A~~C ^^ A~~D ) ^^ ( B~~C ^^ B~~D )
one(A,B) ~~ none(C,D) --> (!(A~~C) && !(A~~D)) ^^ (!(B~~C) && !(B~~D))

none(A,B) ~~ all(C,D) --> (!(A~~C && A~~D)) && (!(B~~C && B~~D))
none(A,B) ~~ any(C,D) --> (!(A~~C || A~~D)) && (!(B~~C || B~~D))
none(A,B) ~~ one(C,D) --> (!(A~~C ^^ A~~D)) && (!(B~~C ^^ B~~D))
none(A,B) ~~ none(C,D) --> !(!(A~~C) && !(A~~D)) && !(!(B~~C) && !(B~~D))

The logic is straightforward and the pattern not too hard to see: the type of
the left operand determines the "top level" (i.e. lower precedence)
logical connective whilst the type of the right operand determines the "bottom level"
(higher precedence) logical connectives.

BTW, the same table works for any boolean operation between junctives.
And, of course, it generalizes to any number of states on either side.

Damian

Reply all
Reply to author
Forward
0 new messages