Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

binding arguments

0 views
Skip to first unread message

Juerd

unread,
Dec 24, 2005, 7:25:55 PM12/24/05
to perl6-l...@perl.org
Merry Christmas to you all!

We use => for pairs, but also for something very different: named
argument binding. Yes, pairs are used for that, but that introduces
problems. The most important problem, that pairs sometimes have to be
passed, and sometimes have to be named arguments, is fixed with a hack
that to me, just doesn't feel right: if the pair is literal and not
inside grouping parens, it's a named argument. Otherwise, it's a pair.
Especially with the function of the () glyphs being different between
with and without whitespace after the subname, this can be very
confusing.

I'd like pairs and argument binding to be two different things. With
different syntaxes.

The next thing I thought was: hey, argument *passing* is actually
*binding* to variables in the sub, so why not use the := operator? That
works very well, because binding as an expression makes no sense anyway,
it being a language thing. And luckily, named arguments are also a
language thing, so that works out:

foo(
named_arg := $value,
other_arg := $value,
);

Incidentally, that happens to be the same as Visual Basic's syntax for
named arguments. But let's quickly forget that.

Using := for this also fixes the problem of having to use *, which feels
like a hack, to use a single stored named argument:

sub f ($foo) { ... }

my $a = foo := $bar; # named argument
my $b = foo => $bar; # pair

f($a); # f($bar);
f($b); # f(:foo($bar));

Pairs can still go into the slurpy *%hash, and I propose :=@args for
catching unknown named arguments. An array, because accessing them by
key individually makes no sense: they're named arguments.

Unary := can perhaps convert a hash to named arguments, should you ever
feel a need to pass a hash that way. f := %foo;


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Joe Gottman

unread,
Dec 24, 2005, 7:59:34 PM12/24/05
to Juerd, perl6-l...@perl.org

The only problem I'd have with this is what if there already exists a
variable with the same name as the named argument?

sub foo($named_arg) {say $named_arg;}

my $named_arg = 1;
my $value = 2;
foo($named_arg := $value); #Does this bind my $named_arg to $value?
say $named_arg; #Must print 1, not 2

To avoid this, perhaps we can use <- or -> instead?

foo($named_arg <- $value);
foo($value -> $named_arg);

Which one of these two is better depends on whether you think the parameter
or the argument being bound to it is more important.


Joe Gottman


Juerd

unread,
Dec 24, 2005, 8:17:18 PM12/24/05
to perl6-l...@perl.org
Joe Gottman skribis 2005-12-24 19:59 (-0500):

> sub foo($named_arg) {say $named_arg;}
> my $named_arg = 1;
> my $value = 2;
> foo($named_arg := $value); #Does this bind my $named_arg to $value?

Because the := is used in .(), it is not binding in the current scope,
but in the called subroutine. In foo($bar := $baz), $bar is always the
name of the argument, and if "foo" doesn't have that name, and doesn't
have anything to slurp unknown named arguments, things fail.

> To avoid this, perhaps we can use <- or -> instead?

The problem about this is that it has to be exactly the other way around
than pairs, which may make the difference a bit too large.

Besides that, it is a big problem for people who don't like to use
whitespace: foo < -5, they write as foo<-5.

I do not think there is any need to have different symbols for direct
binding and named argument binding, because I can't think of any case
where using direct binding in an expression has any benefit. Copying in
expressions is usually done because the copy is modified, but that
argument doesn't work for aliasing.

However, := is a weird symbol, the more I think about it. It has nothing
to do with colons or assignment. Colons are used for pairs, assignment
for copying values. It looks like +=, but doesn't quite work like it.
And ::= seems entirely arbitrarily chosen. But I may be wrong.

Luke Palmer

unread,
Dec 25, 2005, 12:37:58 AM12/25/05
to Juerd, perl6-l...@perl.org
On 12/25/05, Juerd <ju...@convolution.nl> wrote:
> foo(
> named_arg := $value,
> other_arg := $value,
> );

I'll point out that Joe's argument is completely moot, because you're
not using $s on the named arguments. As a matter of fact, we could
double up the := symbol as both binding and named arg passing, using a
=>-like heuristic (\w-only means it's a named arg). That kind of
symbol overloading might be too confusing (but as you point out, no
more confusing than the pair syntax).

> Using := for this also fixes the problem of having to use *, which feels
> like a hack, to use a single stored named argument:
>
> sub f ($foo) { ... }
>
> my $a = foo := $bar; # named argument
> my $b = foo => $bar; # pair
>
> f($a); # f($bar);

Okay, it seems like I have to argue this every time it comes up. In
my "demagicalizing pairs" proposal, the * was by linguistic design,
not a way to get around a problem that the proposal had. One might
even say that it was the main reason for the proposal.

The point was that you should know when you're passing a named
argument, always. Objects that behave specially when passed to a
function prevent the ability to abstract uniformly using functions.[1]
Let's say you're tossing around a list of these "named argument"
objects, constructing it for a call to a function with a very
complicated interface. You see:

sub sort_nameds(*@nameds) {
return () unless @nameds;
my $pivot = shift @nameds;
my @pre = grep { .name lt $pivot.name || .name eq $pivot.name
&& .value < $pivot.value } @nameds;
my @post = grep { .name ge $pivot.name && (.name ne
$pivot.name || .value >= $pivot.value) } @nameds;
return (sort_nameds(@pre), $pivot, sort_nameds(@post))
}

And you say, hmm, interesting, there is some code duplication there.
So you refactor:

sub sort_nameds(*@nameds) {
my sub cmper($x, $y) {
$x.name lt $y.name || $x.name eq $y.name && $x.value < $y.value
}
return () unless @nameds;
my $pivot = shift @nameds;
my @pre = grep { cmper($_, $pivot) } @nameds;
my @post = grep { !cmper($_, $pivot) } @nameds;
return (sort_nameds(@pre), $x, sort_nameds(@post));
}

But there is an error there. You can't pass $pivot (or $_) into cmper
inside those greps, because they will try to bind to the named
arguments of cmper, instead of passing proper as you'd like them to.

You might say "okay, we'll just invent a syntax that says 'pass these
as objects, not as named args'". Maybe \$arg or whatever. Now you
have to know what's in your variables to abstract them properly. This
is pretty much the opposite of the idea of polymorphism, which says "I
can do something to what you give me, no matter what it is". And we
all know by now, hopefully, that once you're beyond scripting,
polymorphism is a good thing.

Convenient, natural syntax is good, but it must not hinder our ability
to abstract. You've got to tell the compiler when you're passing a
named argument. The * syntax to pass a pair was very intentionally
*not* a hack.

As far as the rest of the proposal goes...

The ideas of pairs and named arguments have been separate ever since
we demagicalized them; we've just overloaded their syntax. What you
propose gives each its own syntax, but instead overloads the syntax of
binding to named arguments (which is indeed conceptually closer). But
you lose something important in the process: The :foo($bar) syntax.
I, for one, like writing my named arguments with that style more than
I do with the => style.

So I'd be happy if you stole :foo($bar) for named args and left only
=> for pairs, but that might make people who write hashes with
:foo($bar) pairs unhappy.

All in all, I think the syntax overloading here is a pretty fair
compromise. Maybe it would make you feel less uneasy if you thought
of it as syntactic overloading rather than a special interpretation of
pairs.

[1] This is one of my quibbles with junctions, too.

Luke

Ingo Blechschmidt

unread,
Dec 25, 2005, 11:37:10 AM12/25/05
to perl6-l...@perl.org
Hi,

Juerd wrote:
> The next thing I thought was: hey, argument *passing* is actually
> *binding* to variables in the sub, so why not use the := operator?
> That works very well, because binding as an expression makes no sense
> anyway, it being a language thing. And luckily, named arguments are
> also a language thing, so that works out:

I disagree about binding only being a language thing:

# Happened to me in Perl 5 today
sub foo ($long_parameter_name) {
return 42
if (my $short := $long_parameter_name) == $specialcase;
...usual processing with $short...
}

push @foo, (my $head := pop @grtz);

(my $alias := $long_name).grtz();
# etc.

(Unless of course, you consider this to be obfuscation.)


--Ingo

TSa

unread,
Jan 2, 2006, 8:49:46 PM1/2/06
to perl6-l...@perl.org
HaloO,

Luke Palmer wrote:
> The point was that you should know when you're passing a named
> argument, always. Objects that behave specially when passed to a
> function prevent the ability to abstract uniformly using functions.[1]

> ...


> [1] This is one of my quibbles with junctions, too.

You mean the fact that after $junc = any(1,2,3) there is
no syntactical indication of non-scalar magic in subsequent
uses of $junc e.g. when subs are auto-threaded? I strongly
agree. But I'm striving for a definition where the predicate
nature of the junctions is obvious and the magic under control
of the type system.

The least I think should be done here is to restrict the magic
to happen from within & vars combined with not too much auto-enref
and -deref of junction (code) refs. The design is somewhat too
friendly to the "junctions are values" idea but then not auto-hypering
list operations...

But I have no idea for this nice syntax, yet. Perhaps something like

my &junc = any(1,2,3);
my $val = 1;

if junc( &infix:<==>, $val ) {...}

which is arguably clumsy. The part that needs smarting up is handing
in the boolean operator ref. Might a slurpy block work?

if junc($val): {==} {...}

Or

if junc:{==}($val) {...}

Or $val out front

if $val == :{junc} {...}

which doesn't work with two junctions.

Or reduce syntax:

if [==] junc, $val {...}

OTOH, explicit overloads of all ops applicable to junctions
might end up where we are now:

if $junc == $val {...}

Hmm, wasn't that recently defined as actually beeing

if +$junc === +$val {...} # 3 === 1 --> false

Or how else does a junction numerify? Thus the problem only remains with
generic equivalence if explicit, inhomogenous overloads for junctions
exist. And there are no generic <, >, >= and <=. Does a !== or ^^^
antivalence op exist? I guess not.
--

Luke Palmer

unread,
Jan 2, 2006, 10:31:10 PM1/2/06
to TSa, perl6-l...@perl.org
On 1/2/06, TSa <Thomas....@orthogon.com> wrote:
> But I have no idea for this nice syntax, yet. Perhaps something like
>
> my &junc = any(1,2,3);
> my $val = 1;
>
> if junc( &infix:<==>, $val ) {...}
>
> which is arguably clumsy.

I don't think anyone would waste his time arguing that. :-)

> The part that needs smarting up is handing
> in the boolean operator ref. Might a slurpy block work?
>
> if junc($val): {==} {...}

This all reminds me of Haskell's incantation of the same thing:

if (x ==) `any` [1,2,3]
then ... else ...

Which "reads nicely", but it is quite opaque to the naive user.
Whatever solution we end up with for Junctions, Larry wants it to
support this:

if $x == 1 | 2 | 3 {...}

And I'm almost sure that I agree with him. It's too bad, because
except for that little "detail", fmap was looking pretty darn nice for
junctions.

There is a conflict of design interest here. We would like to maintain:

* Function abstraction
* Variable abstraction

for junctions, but we would also like to maintain genericity with
respect to user-defined operators. Of the proposals so far:

Quantum::Superpositions behavior violates genericity with respect to
user-defined operators.

Autothreading behavior violates function abstraction.

Lexical expansion (i.e. just having the compiler turn $x == 1 | 2 into
$x == 1 || $x == 2) violates variable abstraction.

So, with these three constraints in mind, fmap again comes out on top.
Yes, I'm quite proud of it. Unfortuately, it's ugly, and that's a
constraint too.

There's got to be a good solution lying around here somewhere...

Luke

TSa

unread,
Jan 3, 2006, 12:27:04 PM1/3/06
to perl6-l...@perl.org
HaloO,

Luke Palmer wrote:
> Which "reads nicely", but it is quite opaque to the naive user.

I guess many things are opaque to naive users ;)


> Whatever solution we end up with for Junctions, Larry wants it to
> support this:
>
> if $x == 1 | 2 | 3 {...}
>
> And I'm almost sure that I agree with him.

This actually would be easy if Larry decided that *all* operators
are recognized syntactically and dispatched at runtime. But he likes
to have == strictly mean numeric comparison. Well, with the twist
that the numericy is imposed on the values retrieved from the list
backing the any-junction and the whole thing beeing settled at compile
time syntactically.

But if we assume that all information that is available to the
compiler is available to the runtime as well, then I don't see
any reason why the evaluation of the condition above might not be
a dispatch on the if flow controller multi sub or some such with
some JITing and auto-loading thrown in.

Let me illustrate the point with the well know set of the two
inner operators of nums + and * where * is sort of defined in
terms of +:

3 * 4 --> 12 # symmetric MMD, infix notation,
# atomic evaluation

(3 *)4 --> 4+4+4 # asymmetric prefix, left adjoined operator,
# two step evaluation (addition used for illustration)
# 1: curry lhs to form prefix op
# 2: apply op from step 1

3(* 4) --> 3+3+3+3 # asymmetric postfix, right adjoined operator,
# two step evaluation

I think the compiler decides which of the alternatives is applicable
and generates code accordingly. But why shouldn't it defer the
generation of the semantic tree until dispatch time where the
associativity of the op and the involved types are known? I would
call that syntax tree dispatch or perhaps multi stage MMD. With caching
the results in a local multi this appears as doable to me.


> There is a conflict of design interest here. We would like to maintain:
>
> * Function abstraction
> * Variable abstraction

With container types these two are embedded into the type system
which I still hope supports arrow types properly. I've sort of developed
the mental model of --> being a co-variant forward flow of control
or program execution and <-- beeing a contra-variant keeping of achieved
state:

--> sub junction / iteration / implication / flow
<-- resub junction / reiteration / replication / keep
<--> bisub junction / equivalence / rw container / sync / snap (shot)

The latter two are not yet Perl 6, and the --> has a contra-variant part
in the non-invocant params, which are of course sync or snap points of
a program. Note that lazy params aren't snapped valueish but typeish in
the sense that the imposed constraints *at that moment* in execution
time hold. Well, and if they don't then we have of course 'ex falso quod
libet' later on :)


> There's got to be a good solution lying around here somewhere...

Hmm, operator junctions perhaps? I think that the three relations <, ==
and > are the prototypical order ops. I do not see a priori numerics in
them. This is at best Perl 5 legacy. Note that <=, != and >= are two
element any-junctions from the set of the three primary comparators.
And <=> is a one-junction of all three with succeeding mapping of the
ops to -1, 0 and +1.

Together with negation as center point we get the Fano Plane of the
comparison ops in a crude ASCII chart:

-1|0 0 0|+1
{<=}---{==}---{>=}
\ /
\ {! } /
{<} {>}
none(0,1) <-- -1 \ / +1 --> none(-1,0)
\ /
{!=}
-1|+1 --> none(0)

<=> --> one(-1,0,+1) as circle connecting {<} {==} {>}

can theory theory capture these things in a systematic framework?
--

Jonathan Lang

unread,
Jan 3, 2006, 9:17:26 PM1/3/06
to Luke Palmer, TSa, perl6-l...@perl.org
Luke Palmer wrote:
> Whatever solution we end up with for Junctions, Larry wants it to
> support this:
>
> if $x == 1 | 2 | 3 {...}
>
> And I'm almost sure that I agree with him. It's too bad, because
> except for that little "detail", fmap was looking pretty darn nice for
> junctions.

Not really. If I read the fmap proposal correctly,

if any($x, $y, $z) »==« any(1, 2, 3) {...}

would do the same thing as

if $x == 1 || $y == 2 || $z == 3 {...}

...which fails to dwim. Not to mention

if all($x, $y, $z) »==« any(1, 2, 3) {...}
if any($x, $y, $z) »~~« all($a, $b, $c) {...}

...which ought to work like

if ($x == 1 || $x == 2 || $x == 3)
&& ($y == 1 || $y == 2 || $y == 3)
&& ($z == 1 || $z == 2 || $z == 3)
{...}
if ($x ~~ $a && $x ~~ $b && $x ~~ $c)
|| ($y ~~ $a && $y ~~ $b && $y ~~ $c)
|| ($z ~~ $a && $z ~~ $b && $z ~~ $c)
{...}

And then there's the (minor) ugliness of having to remember to include
hyperspanners (» and/or «) whenever you want to evaluate junctions.

--

Side note: "any(1, 2, 3)" is indistinguishable from "one(1, 2, 3)",
because the values 1, 2, and 3 are mutually exclusive. People often
use the inclusive disjunction when they mean the exclusive one, and
get away with it only because the values that they're dealing with are
mutually exclusive. Another issue is that one-junctions conceptually
represent a single value at a time - though which one is unknowable -
whereas any-junctions can also represent several values at once,
all-junctions usually do so, and none-junctions can even represent no
values. Conceptually, one-junctions are scalar-like, while the other
kinds of junctions are list-like; so one ought to think of "$a ~~
one(@set)" as matching a scalar to a scalar, whereas "$a ~~ any(@set)"
would be matching a scalar to a list (and thus would more properly be
"$a ~~« any(@set)"). But because the distinction between inclusive and
exclusive disjunctions is moot when the component choices are already
mutually exclusive, there's an advantage to any-junctions and
one-junctions behaving in the same way.

--
Jonathan "Dataweaver" Lang

Luke Palmer

unread,
Jan 4, 2006, 12:15:54 AM1/4/06
to Jonathan Lang, TSa, perl6-l...@perl.org
On 1/4/06, Jonathan Lang <dataw...@gmail.com> wrote:
> > And I'm almost sure that I agree with him. It's too bad, because
> > except for that little "detail", fmap was looking pretty darn nice for
> > junctions.
>
> Not really. If I read the fmap proposal correctly,

You didn't :-)

> if any($x, $y, $z) »==« any(1, 2, 3) {...}
>
> would do the same thing as
>
> if $x == 1 || $y == 2 || $z == 3 {...}

The key point is that >>==<< just threads == through the (binary in
this case) functor, and it's up to the functor to decide what that
means. For lists:

(1,2) >>+<< (3,4) === (4,6)

But for junctions:

1|2 >>+<< 3|4 === 4|5|5|6 === 4|5|6

The thing that makes lists "zip-thread" is the definition the
Functor{List} instance, not anything fundamental about functors.

> Side note: "any(1, 2, 3)" is indistinguishable from "one(1, 2, 3)",
> because the values 1, 2, and 3 are mutually exclusive.

That's only true when you're thinking about equality:

1 < any(1,2,3) # true
1 < one(1,2,3) # false (1 < 2 and 1 < 3)

People often
> use the inclusive disjunction when they mean the exclusive one, and
> get away with it only because the values that they're dealing with are
> mutually exclusive. Another issue is that one-junctions conceptually
> represent a single value at a time - though which one is unknowable -

Junctions are frightfully more abstract than that. They only take on
meaning when you evaluate them in boolean context. Before that, they
represent only a potential to become a boolean test. You could think
of them like an "operator voltage": a comparison divided by the
operator and one of the operands.

Luke

TSa

unread,
Jan 4, 2006, 8:02:21 AM1/4/06
to perl6-l...@perl.org
HaloO,

Luke Palmer wrote:
> Junctions are frightfully more abstract than that. They only take on
> meaning when you evaluate them in boolean context. Before that, they
> represent only a potential to become a boolean test.

This is very well spoken err written---except that I would use
beautifully there :)
Well, and their meaning is sort of reduced to one(0,1) in
boolean context. It does not originate there ;)
So junctions are mean outside boolean context :))

BTW, is 'the means' just the plural of 'the mean' or are
these two completely unrelated substantives? E.g. does
one say 'a means' with 'means' beeing a singular noun?
How about the type Mean or Means as supertype of the four
junction types? For example contrasting them with Plain
values?


So, to support the four junction generators the compiler has to
decide at a boolean node of the AST if the subtree originating
there could possibly be junctive and prepare the code for it!

If there is no proof or disproof, this decision must be deferred
to runtime when the actual data---that is the involved parties
not their types---are available.

OTOH, the programmer might short-cut very easily with a 'no junctions'
in the scope. BTW, does that imply that junctions fall back to list
behaviour when it comes to evaluating the node? How does this lexical
pragma traverse the dynamic scopes at runtime? In other words how do
junctive and non-junctive parts of a program interact?

Once again this boosts my believe that junctions should travel
in code vars. E.g.

my &test = any(1,2,3).assuming:op<==>;

my $x = 3;

if $x.test {???}

Also the typeish aspects of first class closures is somewhat
under-represented in Perl6---or I don't see it. What should e.g.
the following

my $sci := (&sin == &cos); # intersectons of sin and cos

put into the var? I think it is a lazy list(ref), an iterator or
generator or simply a calculated code object(ref) with type
:(Ref of List of Num where {sin == cos}). In other words

@sci = pi/4 »+« pi »*« (-Inf..+Inf); # :(Array of List ...)

where I would like the last thing beeing written (-Inf,,+Inf)
or (-Inf,,,). Actually it is the Int type as list, set or any.
With real ranges it might be (-Inf..+Inf):by(pi) or so.

To summarize: I propose to unify the invocations of junctions
with embedded closure calls in general. Of these Perl6 has got
many: there are pipes, lazy lists, slices, control structures,
sorting, key extraction, ...
--

Rob Kinyon

unread,
Jan 4, 2006, 1:15:27 PM1/4/06
to TSa, perl6-l...@perl.org
On 1/2/06, TSa <Thomas....@orthogon.com> wrote:
> HaloO,
>
> Luke Palmer wrote:
> > The point was that you should know when you're passing a named
> > argument, always. Objects that behave specially when passed to a
> > function prevent the ability to abstract uniformly using functions.[1]
> > ...
> > [1] This is one of my quibbles with junctions, too.
>
> You mean the fact that after $junc = any(1,2,3) there is
> no syntactical indication of non-scalar magic in subsequent
> uses of $junc e.g. when subs are auto-threaded? I strongly
> agree. But I'm striving for a definition where the predicate
> nature of the junctions is obvious and the magic under control
> of the type system.

I'm confused at the confusion. To me, junctions are just magical
values, not magical scalars. In theory, one should be able to create
junctions of arrays, hashes, or subs just as easily.

my @junc = any( @a, @b, @c );
my %junc = any( %a, %b, %c );

Then,

if @junc[2] == 9 { ... }

would imply

if @a[2] == 9 || @b[2] == 9 || @c[2] == 9 { ... }

IMHO, one thing that may be causing issues with the junction concept
is that I've never seen anyone talk about the implicit read-only
behavior of a junction. To me, a junction would be required to be
read-only (except for overall assignment). To modify the junction
would be to overwrite it. So, given

my $junc = any( $a, $b, $c );

If you wanted to add $d into there, you'd have to do it this way:

$junc = any( $junc, $d );

Obviously, modifications to $a, $b, or $c would carry through. Doing
this means that array, hash, and sub junctions make sense and behave
no differently than any other readonly variable.

In fact, this behavior seems mandated given the possibility of tying
variables (or is this a Perl5ism that is being discarded in Perl6?)

Rob

Luke Palmer

unread,
Jan 4, 2006, 2:47:37 PM1/4/06
to Rob Kinyon, TSa, perl6-l...@perl.org
On 1/4/06, Rob Kinyon <rob.k...@gmail.com> wrote:
> Luke Palmer wrote:
> > The point was that you should know when you're passing a named
> > argument, always. Objects that behave specially when passed to a
> > function prevent the ability to abstract uniformly using functions.[1]
> > ...
> > [1] This is one of my quibbles with junctions, too.
>
> I'm confused at the confusion. To me, junctions are just magical
> values, not magical scalars. In theory, one should be able to create
> junctions of arrays, hashes, or subs just as easily.

This really has nothing to do with what I was talking about. Here's
what I was talking about:

my $j = get_junction(); # asks for a junction from the user
if $j.values > 4 { die "Too many values" }
my $k = get_junction();
if $k.values > 4 { die "Too many values" }
my $l = get_junction();
if $l.values > 4 { die "Too many values" }

You'd like to abstract this to:

sub toomany($j) {
if $j.values > 4 { die "Too many values" }
return $j;
}
my ($j,$k,$l) = map { toomany(get_junction()) } ^3;

But junctions are so "special", that this abstraction wouldn't work.
Yes, yes, you say "oh, just put a 'Junction' type on the $j
parameter". That's not the point. The point is that now I have to be
aware whenever I'm using a junction, and I have to declare all my
generics as being able to take junctions, instead of it just being
obvious that they do because I didn't put any constraints on the
values. I figure that if you don't have any constraints on the
values, you're not assuming anything about them, so using a junction
should be fine.

Of course, this was introduced for a reason:

sub min($x,$y) {
$x <= $y ?? $x !! $y
}
sub min2($x, $y) {
if $x <= $y { return $x }
if $x > $y { return $y }
}

In the presence of junctions, these two functions are not equivalent.
In fact, it is possible that both or neither of the conditionals
succeed in min2(), meaning you could change the order of the if
statements and it would change the behavior. This is wacky stuff, so
we said that you have to be aware that you're using a junction for
"safety".

But now I'm convinced, but I've failed to convince anyone else, that
the behavior's being wacky doesn't mean that it should be declared,
but that the behavior is just plain wrong. I figure that if something
says it's totally ordered (which junctions do simply by being allowed
arguments to the <= function), both of these functions should always
be the same. The fact is that junctions are not totally ordered, and
they shouldn't pretend that they are.

The other thing that is deeply disturbing to me, but apparently not to
many other people, is that I could have a working, well-typed program
with explicit annotations. I could remove those annotations and the
program would stop working! In the literature, the fact that a
program is well-typed has nothing to do with the annotations in the
program; they're there for redundancy, so they can catch you more
easily when you write a poorly-typed program. But in order to use
junctions, using and not using annotations can both produce well-typed
programs, *and those programs will be different*.

So that's what I was talking about. It didn't have anything to do
with the read-onlyness of junctions.

Luke

TSa

unread,
Jan 4, 2006, 2:48:47 PM1/4/06
to perl6-l...@perl.org
HaloO,

Rob Kinyon wrote:
> I'm confused at the confusion. To me, junctions are just magical
> values, not magical scalars. In theory, one should be able to create
> junctions of arrays, hashes, or subs just as easily.
>
> my @junc = any( @a, @b, @c );
> my %junc = any( %a, %b, %c );

Hmm, and this is unflattened

my @joj = any( @a; @b; @c );

and

+@joj --> any( +@a; +@b; +@c );

then? How long is the junctiveness kept?


> Then,
>
> if @junc[2] == 9 { ... }
>
> would imply
>
> if @a[2] == 9 || @b[2] == 9 || @c[2] == 9 { ... }

Uhh, and

if @joj[2] == 9 { ... }

should effectively means

if @joj[2;*] == 9 { ... }

with re-junctification of the sliced out arrays?

if any( [;] @joj.values[2;*] ) == 9 { ... }


> IMHO, one thing that may be causing issues with the junction concept
> is that I've never seen anyone talk about the implicit read-only
> behavior of a junction. To me, a junction would be required to be
> read-only (except for overall assignment). To modify the junction
> would be to overwrite it. So, given
>
> my $junc = any( $a, $b, $c );

Like Ref values, then?


> If you wanted to add $d into there, you'd have to do it this way:
>
> $junc = any( $junc, $d );
>
> Obviously, modifications to $a, $b, or $c would carry through.

Which first of all smells strongly like closure creation, that
is Code types! But shouldn't the read-only enreferencing be
more prominent notationally? Like

my $junc = any( \$a, \$b, \$c );

or through an Arglist (which means malice in German):

my $junc = any\( $a, $b, $c );

Otherwise I would strongly opt for value snapshotting
when the junction closure is created. And of course
the underlying functionality must be easily available
for user defined junctions. Things like set-, min-, max-
and sort-junctions come to mind...

> Doing
> this means that array, hash, and sub junctions make sense and behave
> no differently than any other readonly variable.

Combined with lazy evaluation that yields on unavailable
values we enter the realm of constraint programming.
The grand unification then comes with multi threading
this concurrently. With side-effects that becomes *REALLY*
challenging!


> In fact, this behavior seems mandated given the possibility of tying
> variables (or is this a Perl5ism that is being discarded in Perl6?)

That is what := does these days? BTW, a rw junction is just
three chars around the corner:

my $junc = any:rw( $a = 1, $b = 2, $c = 4); #1
my $junc = any( $a = 1, $b = 2, $c = 4, :rw); #2
my $junc = any( $a = 1, $b = 2, $c = 4 ):rw; #3

$junc = 3; # means $junc.pick = 3?

I'm not sure which syntax of #1 to #3 really hits the junctions
creator with a named arg. And it might not support it for good
reasons! Just think what fun breaks loose if someone hands around
an array that contains (rw => 1):

push @array, (rw => 1);

$surprise = any(*@array);


Or simply

my $junc := any( $a = 1, $b = 2, $c = 4);

So, do we want junctive assignment? Or should it complain like

my $val := 3; # error: can't bind constant

hopefully does.
--

TSa

unread,
Jan 4, 2006, 5:21:47 PM1/4/06
to perl6-l...@perl.org
HaloO,

Luke Palmer wrote:
> But junctions are so "special", that this abstraction wouldn't work.

Well my point is that I dought that it is tractible for the compiler
to come up with the dwimmery to pull the invocation of .values on the
return value out of toomany and leave the cardinality check in,
depending on the input beeing a junction or not. That is to re-write
the junctive case to:

sub toomany($j)
{
if $j > 4 { die "Too many values" }
return $j;
}
my ($j,$k,$l) = map { toomany(get_junction().values) } ^3;

Sort of a junctive compile :)
My syntactical idea is that this might work if you naively write
it without explicit .value and a junction numerifying to its
cardinality. To get the junctive behaviour to trigger as you outline
would be

sub toomany(&j) # or perhaps even *&j
{
if j > 4 { die "Too many values" }
return &j;
}

while an &j.values in the if still keeps the junction untriggered.
Then an uncertain j.values might result in the compile time warning
"return value of j not necessarily a junction". The only remaining
thing for @Larry is to define an exclusive set of methods for querying
junctions. Sort of like the "handle with care" stickers on containers!


> Yes, yes, you say "oh, just put a 'Junction' type on the $j
> parameter". That's not the point. The point is that now I have to be
> aware whenever I'm using a junction, and I have to declare all my
> generics as being able to take junctions, instead of it just being
> obvious that they do because I didn't put any constraints on the
> values. I figure that if you don't have any constraints on the
> values, you're not assuming anything about them, so using a junction
> should be fine.

Could it be that you think about it the wrong way around? I mean
the values should be in the object grammar slot: "..., so a
junction using *them* should be fine."


> Of course, this was introduced for a reason:
>
> sub min($x,$y) {
> $x <= $y ?? $x !! $y
> }
> sub min2($x, $y) {
> if $x <= $y { return $x }
> if $x > $y { return $y }
> }
>
> In the presence of junctions, these two functions are not equivalent.

Neither are they in the presence of references

min(\3,{\3}) === min2({\3},\3)

when the outer non-closure refs are created and optimized away
by the compiler and the inner ones later depending on the order
in which === evaluates its args. I mean that it sees

3 === \3

and returns false. Well, or I don't understand === ;)


> In fact, it is possible that both or neither of the conditionals
> succeed in min2(), meaning you could change the order of the if
> statements and it would change the behavior. This is wacky stuff, so
> we said that you have to be aware that you're using a junction for
> "safety".

But control is outside. Junctions help people to obfuscate things like

if min2(1,0) && min2(0,1) {die}

where the inputs to && are returned from different spots in min2.


> I figure that if something
> says it's totally ordered (which junctions do simply by being allowed
> arguments to the <= function), both of these functions should always
> be the same. The fact is that junctions are not totally ordered, and
> they shouldn't pretend that they are.

Junctions aren't ordered totally of course. But neither are they
arguments to <=. The reverse is true: <= is an argument to the junction.
And my point originally was about inventing a pleasing syntax that
highlights this fact.

E.g. the Complex type might support <= such that it returns true
in case of equality and undef otherwise. The latter might lead
people to regard it as false and hopefully cross-check with > and
then draw the right conclusion after receiving another undef and
promoting it to false. Namely that the net effect was a negated
equality check! A gray view of a picture emerges from a blurred
array of black and white pixels, and it takes more than two primal
constituents for a color picture to emerge, e.g. black, white and
fast motion with the right patterns deceive the human eye into
perceiving color!

Or think of contexts where 5 is not considered prime! Is it
always? If not, in which context?

The real objective of a type system is to quench undefinedness
out of the essential parts of a program.


> The other thing that is deeply disturbing to me, but apparently not to
> many other people, is that I could have a working, well-typed program
> with explicit annotations. I could remove those annotations and the
> program would stop working!

The thing that haunts me is that junctions make only sense if they
bubble up into the control heaven so far that to achieve invariance
a *complete* program has to be run for all conceivable permutations
of pathes through the call graph! Might be nice for testing if given
enough time, though :)


> In the literature, the fact that a
> program is well-typed has nothing to do with the annotations in the
> program; they're there for redundancy, so they can catch you more
> easily when you write a poorly-typed program. But in order to use
> junctions, using and not using annotations can both produce well-typed
> programs, *and those programs will be different*.

That depends on your definition of different. Any UNIX process is
easily described as: "running until it has determined its exit code
which is then returned to its parent process". This e.g. covers
network buffer overflow attacks that depending on their nature suddenly
make the program trying to crack the root password! Well, or think of
the wonderfull hard contraint that a 32bit processor will never access
memory outside of the 4GB range ;)

There are two sides of correctness: the spec and the implementation.
No spec at all makes any program correct. Contradicting specs make
any implementation fail for one or the other reason. In other words
there are also incorrect specs. But that we know since Gödel ;)
--

Jonathan Lang

unread,
Jan 4, 2006, 8:23:17 PM1/4/06
to Luke Palmer, Rob Kinyon, TSa, perl6-l...@perl.org
Luke Palmer wrote:
> Of course, this was introduced for a reason:
>
> sub min($x,$y) {
> $x <= $y ?? $x !! $y
> }
> sub min2($x, $y) {
> if $x <= $y { return $x }
> if $x > $y { return $y }
> }
>
> In the presence of junctions, these two functions are not equivalent.
> In fact, it is possible that both or neither of the conditionals
> succeed in min2(), meaning you could change the order of the if
> statements and it would change the behavior. This is wacky stuff, so
> we said that you have to be aware that you're using a junction for
> "safety".

Hmm... min2 behaves differently from min because the > function
doesn't act as the negation of the <= function when dealing with
junctions. As you say, wacky stuff.

> But now I'm convinced, but I've failed to convince anyone else, that
> the behavior's being wacky doesn't mean that it should be declared,
> but that the behavior is just plain wrong. I figure that if something
> says it's totally ordered (which junctions do simply by being allowed
> arguments to the <= function), both of these functions should always
> be the same. The fact is that junctions are not totally ordered, and
> they shouldn't pretend that they are.

If junctions say that they're totally ordered by virtue of being
usable in the <= function, and junctions shouldn't say that they're
totally ordered, it follows that they shouldn't be usable in the <=
function. Since one of the main purposes of junctions is to be usable
in the <= function, this constitutes a problem.

IMHO, the fallacy is the claim that something is totally ordered
simply by being allowed arguments to the <= function. Total ordering
is achieved by being allowed arguments to a <=> function that always
returns one of -1, 0, or +1. When a junction is fed into a <=>
function, it will not always return one of -1, 0, or +1; it could
instead return a junction of -1's, 0's, and/or +1's (or maybe it
should fail?).

> The other thing that is deeply disturbing to me, but apparently not to
> many other people, is that I could have a working, well-typed program
> with explicit annotations. I could remove those annotations and the
> program would stop working! In the literature, the fact that a
> program is well-typed has nothing to do with the annotations in the
> program; they're there for redundancy, so they can catch you more
> easily when you write a poorly-typed program. But in order to use
> junctions, using and not using annotations can both produce well-typed
> programs, *and those programs will be different*.

I'm not following; could you give an example?

--
Jonathan "Dataweaver" Lang

Rob Kinyon

unread,
Jan 5, 2006, 10:13:56 AM1/5/06
to Luke Palmer, TSa, perl6-l...@perl.org
On 1/4/06, Luke Palmer <lrpa...@gmail.com> wrote:
> Of course, this was introduced for a reason:
>
> sub min($x,$y) {
> $x <= $y ?? $x !! $y
> }
> sub min2($x, $y) {
> if $x <= $y { return $x }
> if $x > $y { return $y }
> }
>
> In the presence of junctions, these two functions are not equivalent.
> In fact, it is possible that both or neither of the conditionals
> succeed in min2(), meaning you could change the order of the if
> statements and it would change the behavior. This is wacky stuff, so
> we said that you have to be aware that you're using a junction for
> "safety".
>
> But now I'm convinced, but I've failed to convince anyone else, that
> the behavior's being wacky doesn't mean that it should be declared,
> but that the behavior is just plain wrong. I figure that if something
> says it's totally ordered (which junctions do simply by being allowed
> arguments to the <= function), both of these functions should always
> be the same. The fact is that junctions are not totally ordered, and
> they shouldn't pretend that they are.

To me, this implies that junctions don't have a complete definition.
Either they're ordered or they're not. Either I can put them in a <=
expression and it makes sense or I can't. If it makes sense, then that
implies that if $x <= $y is true, then $x > $y is false. Otherwise,
the definitions of <= and > have been violated.

And, if I can't put them in a <=, then Perl should complain very
loudly, just as if I put something else that shouldn't be put into <=,
like a Person object. If I call min() or min2() with a Person object
and an array, I should expect loud complaints from the runtime. If a
junction cannot behave itself in a numeric comparison, then similar
complaints should be made.

Rob

Jonathan Lang

unread,
Jan 5, 2006, 10:44:07 AM1/5/06
to Rob Kinyon, Luke Palmer, TSa, perl6-l...@perl.org
Rob Kinyon wrote:
> To me, this implies that junctions don't have a complete definition.
> Either they're ordered or they're not. Either I can put them in a <=
> expression and it makes sense or I can't. If it makes sense, then that
> implies that if $x <= $y is true, then $x > $y is false. Otherwise,
> the definitions of <= and > have been violated.

I'll beg to differ. If you insist on that kind of restriction on
Junctions, they won't be able to serve their original (and primary)
purpose of aggragating comparison tests together. Remember:

if $x <= 1 & 5 {...}

is intended to be 'shorthand' for

if $x <= 1 && $x <= 5 {...}

Therefore,

$x = 3;
if $x <= 1 & 5 {say 'smaller'}
if $x > 1 & 5 {say 'larger'}

should produce exactly the same output as

$x = 3;
if $x <= 1 && $x <= 5 {say 'smaller'}
if $x > 1 && $x > 5 {say 'larger'}

If it doesn't, then Junctions are useless and should be stricken from Perl 6.

And the definition of '>' is "greater than", not "not (less than or
equal to)". The latter is a fact derived from how numbers and letters
behave, not anything inherent in the comparison operator. Just like
'<=' is "less than or equal to", as opposed to "not greater than".
You aren't violating the definitions of <= and > by failing to insist
that they be logical negations of each other; you're only violating
the common wisdom.

--
Jonathan "Dataweaver" Lang

Juerd

unread,
Jan 5, 2006, 11:03:39 AM1/5/06
to perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-12-25 17:37 (+0100):

> I disagree about binding only being a language thing:

I fail to see how your example code illustrates your disagreement.

> return 42
> if (my $short := $long_parameter_name) == $specialcase;

That's terribly horrible style!

> push @foo, (my $head := pop @grtz);

A bit better style, but I'd still recommend against it.

> (Unless of course, you consider this to be obfuscation.)

Not obfuscation, but horrible style. You're doing something in an
expression that has no effect on what happens in the expression itself.

($bar = $foo) =~ s/// is useful because you need a copy, and the inline
copying is a clear indication of $bar's function: to be $foo in its
state after s///. The same thing with := instead of = would be horrible,
because $bar and $foo would be the same thing, during and after the
expression, and the aliasing itself had nothing to do with the
substitution.

Ingo Blechschmidt

unread,
Jan 5, 2006, 12:32:06 PM1/5/06
to perl6-l...@perl.org
Hi,

Juerd wrote:
> Ingo Blechschmidt skribis 2005-12-25 17:37 (+0100):
>> I disagree about binding only being a language thing:
>
> I fail to see how your example code illustrates your disagreement.
>
>> return 42
>> if (my $short := $long_parameter_name) == $specialcase;

I inferred that you think/thought that binding should/can't be used in
expressions:

Juerd wrote:
> That works very well, because binding as an expression makes no sense
> anyway, it being a language thing.

Thus I wanted to demonstrate that "binding as an expression" does make
sense (to me at least).

Sorry if I misinterpreted your post.

>> push @foo, (my $head := pop @grtz);
>
> A bit better style, but I'd still recommend against it.

Consider:

my @sites = < abc.org def.org ghi.org >;
loop {
push @sites, (my $site := shift @sites);
check_for_updates($sites);
sleep ...;
}

> You're doing something in an expression that has no effect on what
> happens in the expression itself.

Right; but I don't consider this as bad style or as "problematic".

Consider a perhaps more usual example:

# Perl 5
while(...) {
process($tasks[$i++]);
# The "++" does not have an effect on the expression itself,
# writing "process($tasks[$i])" wouldn't make any difference.

if(...) { $i-- } # redo the last task
if(...) { $i = 0 } # redo all tasks
if(...) { $i++ } # skip next task
}


--Ingo

Juerd

unread,
Jan 5, 2006, 1:08:44 PM1/5/06
to perl6-l...@perl.org
Ingo Blechschmidt skribis 2006-01-05 18:32 (+0100):

> Juerd wrote:
> > Ingo Blechschmidt skribis 2005-12-25 17:37 (+0100):
> >> I disagree about binding only being a language thing:
> > I fail to see how your example code illustrates your disagreement.
> >> return 42
> >> if (my $short := $long_parameter_name) == $specialcase;
> I inferred that you think/thought that binding should/can't be used in
> expressions

No, that's not what I meant.

A "language thing" means it's mostly relevant for the way you write
something as a result of the feature. In case of binding, the most used
application is aliasing: getting a second way to address the same
variable -- probably because the alias is less typing.

> >> push @foo, (my $head := pop @grtz);
> > A bit better style, but I'd still recommend against it.
> Consider:
> my @sites = < abc.org def.org ghi.org >;
> loop {
> push @sites, (my $site := shift @sites);
> check_for_updates($sites);
> sleep ...;
> }

my $site := shift @sites;
push @sites, $site;
check_for_updates($sites);

Although in Perl 6 I'd be much tempted to do:

given shift @sites {
push @sites, $_;
check_for_updates($_);
}

Because $_ is visually easy to recognise, making it immediately obvious
that it's the same thing in both lines.

(This is also my main argument against any style that ALWAYS provides an
explicit loop variable: $_ is easy to spot, and thus is more than just
easy to type.)

> Consider a perhaps more usual example:

> while(...) {
> process($tasks[$i++]);


> if(...) { $i-- } # redo the last task
> if(...) { $i = 0 } # redo all tasks
> if(...) { $i++ } # skip next task
> }

As ugly. In fact, using an index is the ugliest part of your example.
Still, separately, $i++ in the process() instruction is bad style IMO.
Incrementing $i is important for program flow, and should be its own
statement, directly following indentation.

Also, if you remove process() here, the entire program is broken,
because there was an important but easy to overlook subexpression was in
it.

David Green

unread,
Jan 5, 2006, 1:55:35 PM1/5/06
to perl6-l...@perl.org

On 1/4/06, Luke Palmer wrote:
>The other thing that is deeply disturbing to me, but apparently not to
>many other people, is that I could have a working, well-typed program
>with explicit annotations.

I don't think it disturbs me... but that might just be because I
don't really understand it.

>I could remove those annotations and the program would stop working!

If it changes how the program works, then by definition doesn't that
mean it wasn't really an "annotation" to begin with?
As far as specifying "Junction" in signatures to control
auto-threading, that always felt funny to me anyway, because it's not
consistent with the normal meaning of specifying a parameter type. I
would've expected "is threaded" or "is junctive" or "is
junctothreaded" or something.

I'm not sure if this is (part of) what you're getting at or not. In
a strongly-typed language, can you always remove the typing from a
working program without changing it? Or maybe just particular
strongly-typed languages... in Perl, typing can be used to provide
bonus information (say, as optimisation hints); but it can also be
used for multiple-dispatch, so I certainly wouldn't expect a program
to continue working properly if I changed *that* information.
(Assuming "well-typed" refers to the former, but not the latter --
hope I've got that straight.)

In that vein, I think of junctions as a sort of implicit
polymorphism: I define "sub foo(Int $a)" and also get "sub
foo(Junction of Ints $j)" for free. Which is why "<" acting wacky
doesn't bother me -- numbers may be well-ordered, but junctions
aren't, and there are two different <'s at work. Arguably, different
functions should have different names to avoid confusion, but I think
that calling the junctive less-than something other than "<" would be
even more confusing. (Certainly it would be too unDWIMilly pedantic
to be Perl.)

Of course, I was also never bothered by using "+" to mean numeric
addition and string concatenation. Come to think of it, perhaps
that's because languages which do that are picky about distinguishing
strings from numbers -- in Basic, 123 + "123" will get you a
type-mismatch error, but to Perl, 123 and "123" are the same thing,
so you need a numeric == and a stringic 'eq'.

But Perl does know the difference between a number and a junction.
That means the programmer has to follow along at home, but ok,
sometimes you just gotta be aware of what your code is doing. I
think I understand your Functor proposal, and it does have a certain
appeal for me... but along with the advantage of making it clearer
when junctions are being used, it carries the disadvantage of
*requiring* you to know when junctions are being used. I can't just
say "if $x<3 ..." and expect it to Do the Right Thing regardless of
whether $x happens to be an ordinary number or a junction -- I have
to split up the two cases and handle them separately. That's surely
going to reduce the happy-go-lucky usefulness of junctions.

Besides, don't we have a "no junctions" pragma that you can stick
into any scope where you need exact mathematical purity?


-David

TSa

unread,
Jan 5, 2006, 3:19:51 PM1/5/06
to perl6-l...@perl.org
HaloO,

Jonathan Lang wrote:
> Rob Kinyon wrote:
>
>>To me, this implies that junctions don't have a complete definition.
>>Either they're ordered or they're not.

So, is there a number between 0 and 1? Shades between black and white?
When is a 360 degree turn not returning a system into its initial state?
What has a 720 degree turn to do with sign reversal, negation and
twisted arms? Anyone know the Eisenstein integers? Is 5 a prime complex
number? What is its quadratic residue?

(-1)**2 == -i**2 == +1
\
?-->0 # if <=>
/
i**2 == -1
------------------------------ mirror symmetry axis
j**2 == -1
\
!-->0 # unless <=>
/
(-1)**2 == -j**2 == +1

But note that *same* symmetrie is broken! Ever wondered why a mirror
changes left and right, but not up and down? And what has all that
to do with anagrams like 'OTTO' and 'TOOT' or with bits '.**.' and
'*..*'? Or the range operators ^..^ .^^.?

Conceptually the 0 has no sign unless you want it to be junctive ;)
if you rotate the above vector diagrams by 120 degrees endlessly
clockwise and counter clockwise you get

upper: ...,0, 1,-1,0,...
lower: ...,0,-1, 1,0,...

which when superimposed additively lets the infinity of the
lists nicely vanish. But not the same is not true if one is
shifted, the other squared and then subtracted, or some such.
The thing is you end up with the infinte list (...,!0,!0,...).

The net effect is the same as reading the list's string representations
in opposite directions. There is no dark side of the moon really!

Here's the same in another ascii picture:

i\+/+
-\+ +\- 2** -<=>+ **2 +/+ -/-
-/-\-i**2

center stage we find <=> which returns one(-1,0,+1) or rotations
thereof: one(0,+1,-1) or one(+1,-1,0). Or the odd permutations
one(0,-1,+1), one(-1,+1,0) and one(+1,0,-1). In other words three
pairs of ones that cancel each other if zipped additively. The only
thing we need is a neutral element to get a group. Let's take the
empty one() junction. But an empty any() would do as well. These
sort of represent no comparison at all and a comparison you don't
care to constrain any further! In the latter case an undef return
value is not unexpected, I hope.

This is how that looks in an example:

'foo' cmp 'bor'

--> <f o o> »cmp« <b o r> <--

--> (-1, +0, +1) | (+1, -0, -1) <--

The arrows indicate reading direction of the respective string.
In a optimised implementation the outer f/b and and r/o give
the invariant relative positions of one('foo','oof') and
one('bor','rob') in the order of strings in viewing direction.
At least that is the observable behaviour. Endianess of the
machine, representation of junctions and what not may differ
for concrete implementations of Perl6 :)

Note that

[?] (-1, +0, +1) »+« (+1, -0, -1)
--> [?] (0,0,0)
--> false

With (-++) and (+--) beeing dual Minkowski metrics.


>> Either I can put them in a <=
>>expression and it makes sense or I can't.

HiHi, this is a statement about the programmer's abilities...
not about Perl 6 the language!


>> If it makes sense, then that
>>implies that if $x <= $y is true, then $x > $y is false. Otherwise,
>>the definitions of <= and > have been violated.
>
> I'll beg to differ. If you insist on that kind of restriction on
> Junctions, they won't be able to serve their original (and primary)
> purpose of aggragating comparison tests together. Remember:
>
> if $x <= 1 & 5 {...}
>
> is intended to be 'shorthand' for
>
> if $x <= 1 && $x <= 5 {...}

I beg to differ, two err too. I mean potentially from both depending
on what they intented to say and how I understood them.

My point is that the junctive case sort of means:

if $x.all:{<=}(1,5) {...}

where :{<=} receives similar meta treatment as [<=] reduce would.
BTW, isn't bareword suffixing {<=} reserved for type theoretic
manipulations? I still regard the junctions as Code subtypes and
thus any{<=} and friends as parametric meta operation.


> Therefore,
>
> $x = 3;
> if $x <= 1 & 5 {say 'smaller'}
> if $x > 1 & 5 {say 'larger'}
>
> should produce exactly the same output as
>
> $x = 3;
> if $x <= 1 && $x <= 5 {say 'smaller'}

This is slightly untrue. because if the junction contains two
identical values or an undef ordered object the < part is
essentially stripped away:

if $x <= 5 && $x <= 5 {say 'smaller'}

can be permuted into

if $x <= 5 && 5 > $x {say 'smaller'}

and optimized to

if $x == 5 {say 'smaller'}


> if $x > 1 && $x > 5 {say 'larger'}
>
> If it doesn't, then Junctions are useless and should be stricken from Perl 6.
>
> And the definition of '>' is "greater than", not "not (less than or
> equal to)". The latter is a fact derived from how numbers and letters
> behave, not anything inherent in the comparison operator.

The complete group of comparison operators imposes the order on the
underlying uninterpreted set of data.


> Just like
> '<=' is "less than or equal to", as opposed to "not greater than".

Indeed I regard the gangs of 2*7 + 7 == 21 comparison operators
bound by a theory of GF(8) === GF(2**3), that is a Galois group
with 8 members.

Here are more (pretty|pitty) pictures:


{>=}----{>}
/ \ / \
/ \ / \
/ \ / \
{==}----{?}----{!=}
\ / \ /
\ / \ / {gt}---{ge}
\ / \ / / \ / \
{<=}----{<} / \ / \
/ \ / \
:( cmp --> {ne}----{~}----{eq} <-- pmc :)
\ / \ /
{>}-----{>=} \ / \ /
/ \ / \ \ / \ /
/ \ / \ {lt}---{le}
/ \ / \
{!=}----{!}----{==}
\ / \ /
\ / \ /
\ / \ /
{<}-----{<=}

I hope the two numeric ones on the left look like projected cubes
while the string gadget is a flat hexagon projected from stringfinity.
The generators of the theory instances are {if <=>}, {unless <=>} and
{cmp} respectively. BTW the latter could actually return one of the
three strings '<', '=' or '>' and numerifying as

+'=' == 75 == 60 + 15 == 60 + 7 + 8 == 2:111100 + 2:111 + 2:100
+'<' == 74 == 60 + 14 == 60 + 7 * 2 == 2:111100 + 2:111 * 2:010
+'>' == 76 == 60 + 16 == 60 + 2 * 8 == 2:111100 + 2:010 * 2:100

in the---at least to me---obvious way :)


> You aren't violating the definitions of <= and > by failing to insist
> that they be logical negations of each other; you're only violating
> the common wisdom.

Well, and any optimizations that depend on Galois theory to hold ;)
--

Jonathan Lang

unread,
Jan 5, 2006, 11:53:03 PM1/5/06
to TSa, perl6-l...@perl.org
Me no follow. Please use smaller words?

--
Jonathan "Dataweaver" Lang

Markus Laire

unread,
Jan 6, 2006, 12:42:59 PM1/6/06
to TSa, perl6-l...@perl.org
On 1/5/06, TSa <Thomas....@orthogon.com> wrote:

> Jonathan Lang wrote:
> > Therefore,
> >
> > $x = 3;
> > if $x <= 1 & 5 {say 'smaller'}
> > if $x > 1 & 5 {say 'larger'}
> >
> > should produce exactly the same output as
> >
> > $x = 3;
> > if $x <= 1 && $x <= 5 {say 'smaller'}
>
> This is slightly untrue. because if the junction contains two
> identical values or an undef ordered object the < part is
> essentially stripped away:
>
> if $x <= 5 && $x <= 5 {say 'smaller'}
>
> can be permuted into
>
> if $x <= 5 && 5 > $x {say 'smaller'}
>
> and optimized to
>
> if $x == 5 {say 'smaller'}

Do you claim that


if $x <= 5 && $x <= 5 {say 'smaller'}

is same as


if $x == 5 {say 'smaller'}

--
Markus Laire

0 new messages