Rod Adams wrote:
> The purpose of a junction is to allow for performing several tests at a > given time, with the testing code needing no knowledge of that junctions > are present. While a junction can represent several values at the same > time, such notions as "hold" and "contain" should be avoided, and they > can be very misleading, they betray the fact that a junction is a single > entity. As such, junctions are best thought of as Scalar. (Like other > scalars, it may reference to something much more complex, but that's > beside the point). Therefore the result of a junction evaluation should > be Scalar.
Everything is okay to here.
> (We will see later that this scalar value is in fact boolean).
Err...no. See below.
> But what is a "junction evaluation"? Simply put, it is the results of > threading all values of a junction through an expression and the > recombination of these results back into a scalar, via the logic of the > associated boolean predicate.
Correct.
> Note the fact that it's a _boolean_ predicate. That means that the end > result of any junction evaluation is a single boolean value.
No. For example:
# Print a list of substrings... my $substring = substr("junctions", any(1..3), any(3..6)); say $substring.values();
> Therefore, the only place that it makes sense to evaluate a junction > is in a place where a boolean value is expected. This brings us to our > "Prime Junction Rule": > > Junctions can only be evaluated as part of a boolean expression.
No.
> Attempting to evaluate a junction anywhere else is an error.
No.
> Some comments about what this does for us. > > - Threading in this case is purely implicit. This allows a user to drop > a junction into any place a test parameter is called for. Asking for > explicit threading here makes the concept useless.
Correct.
> - Nesting of junctions is not an issue, since each threaded evaluation > is yet another boolean expression.
Not necessarily, but boolean evaluation of does indeed work that way.
> - Things like C< for $j .. 10 {...} >, are illegal. They didn't make > much sense in the first place.
Probably.
> - In fact, most code written without junctions in mind will execute > cleanly and as expected, since the result of the threading operation > will be exactly what is expected: boolean.
It doesn't have to be boolean, but the point is basically correct.
> - As such there should be no limitation as to where a junction can be > stored and passed. Functions will have the ability to explicitly reject > junctions as arguments by typing their parameters with something like > C< all(any(Int, Str), none(Junction)) >. Yes, that's using junctions to > reject junctions.
Yes.
> - There is still a limited case of "Nasty Side Effect Syndrome" that can > be caused by having an assignment, output, or other undesirable type of > function/operator as part of a boolean expression. There will therefore > need to be a "is unautothreadable" trait to be had for functions. All > builtin I/O and assignment functions should have this on. This > protection is shallow. If the call is not in the text of the evaluated > expression, it is not guaranteed to be tested.
I need to think about this. I'm not sure I'm convinced this isn't covered by none(Junction) typing on parameters.
> - If you wanted to thread a junction in a non-boolean way, you probably > didn't want a junction. You likely either wanted an array or a set, and > some combination of hyper operators. See below.
Not convinced of this.
> Sets > ==== > > Despite several surface similarities between a set and a junction, they > are quite different. Sets actually contain other things. Junctions hold > several values at once, and can even hold the same value more than once > at once.
Err, no. Junctions *are* values, and those values are unique.
> Sets are inherently plural in thought process. Junctions are > inherently singular. The operations one wishes to perform on a set are > radically different from those performed on a junction.
True.
> Sets and hashes are an odd pair. Hashes are not a good basis for Sets > due to the restriction that the keys are strings. Even if this is not > the case,
It's not.
> In addition, a set evaluated in a list context returns it's members.
Err...then how do you create a list of sets???
> In addition to C< ~~ > for membership, we will borrow the {} > subscripters from hashes (not sure about the <> or «» variants).
You'd have to take them, I'm afraid. Introducing gratuitous inconsistencies would be a Bad Idea.
> In this form, a C< $set{$key} > reference will look for the element > that matches the place in the sort identified by $key (in other > words, the element with the matching .key() or value). If something > is there, it then returns C< .value||$_ >, assuming $_ is the element > at that place. > > This seemingly bizarre set of semantics gives us something very > powerful. One can make a Set of Pairs, which behaves much like a hash, > only with the ability to use any data type as the key.
Hashes already have this ability. I don't think overloading the hash access syntax on Sets is worth the trouble.
> Sets will borrow at least the following methods from Arrays: > grep, map, elems > and these from hashes: > keys, values, each, delete, exists
Keys? Surely sets only have values???
> HyperQuotes > =========== > > Just to round out any corner cases that the existing hyper operators do > not cover, and to add a clearer way to do some of them, we will allow > any list surrounded with » «, called hyperquotes, to thread the > immediate function, treating each element of the list as a scalar, and > have the expression return a list of the results. Some samples: > > @s = 'item' _ [EMAIL PROTECTED];
That's:
@s = 'item »_« @x;
> $x = 'abcdabc'; > @x = split »/a/, /c/, /d/«, $x;
That's:
@x = »split« [/a/, /c/, /d/], $x;
but I can see the appeal. Though I still think it's more readble to write:
@x = values split any(/a/, /c/, /d/), $x;
> @x = func($a, [EMAIL PROTECTED]);
That's:
@x = »func«($a, @y);
But, y'know, this one almost convinces me. Especially when you consider:
sub func ($i, $j, $k) {...}
@x = func($a, [EMAIL PROTECTED], @z);
> With these and all the other hyper operator, one should be able to easy > perform the equivalent threading operation that they lost with the Prime > Junction Rule.
I very much doubt we're going to lose it. ;-)
> These are also infinitely more useful, since you can be guaranteed that > they won't short circuit, and they are in exactly the order you > specified.
This is admittedly very nice.
> So that's how I feel about things. The Prime Junction Rule was the big > revelation I had the other night. The rest of this was the logical > consequence spawned off that single thought to make it a complete idea. > > I think that overall in this process I've done the following: > - Kept the real power of Junctions intact. > - Provided fairly strong protection for newbies, without sacrificing > power. > - Kept Nasty surprises to a minimum. > - Got rid of the need for "half on" features. > - Provided back any power that the Prime Rule removed through sets and > expanded hyper ops.
Leaving aside the Unnecessary Restriction on junctions (a.k.a. Prime Rule ;-), the main downside is that we would be multiplying our entities. We'd need to be certain that the increased cognitive load is worth the benefits.
Damian