John M. Dlugosz wrote:

if you call
 $q = "aaa";

then the value passed in is a Str. The static type is Any, the dynamic type is Str.

Sorry, I got that messed up. The ::Type captures the dynamic type
of the value, of course. But I want to get at the constraint of
the caller's container. The purpose is to read out the intents of
the caller which are manifested in the container constraint. BTW,
you call the container constraint the static type of the variable.

$x.VAR.WHAT will be the prototype object for Scalar, which has nothing to do with the value inside it.

I doubt that. I believe that Scalar is the HOW of VAR $x. That is their
syntactic slots are:

   my $x is HOW of WHAT;

The actual value brings in another pair of HOW and WHAT. This WHAT
has to be compatible with the WHAT of $x. As far as type checking
is concerned the HOW is of secondary interest.

>>       ::T $x = $ret if T ~~ Type; # don't violate caller's constraint
>>       return $ret;
>>   }
> T is undefined.

My idea was to capture it from $ret which is a compile time
activity as far is the origin of ::T is concerned. Then I

   my ::T $temp = $ret;
   if T ~~ Type { $x = $temp; }

into a single line.

>>   say incr(5); # print 6, no error
> Compile-time error; can't bind 5 to an rw.

But I wanted a decent rw parameter that particularly does not
show this unforgiving behavior. The error should be signaled
when the rw is actually used as an lvalue. That is $x := 5
is ok, but a subsequent $x = 6 is an error.

Why not just let MMD do it? Switching on the type is bad smell. Polymorphism should do that.

The whole point of my ranting was to behave differently for

  my Str $x = "-100"; # $x.WHAT === $x.VAR.WHAT === Str


  my $y = "-100"; # $y.WHAT === Str but $y.VAR.WHAT === Any

MMD only sees the Str of "-100" *not* the Str of $x!

multi sub incr (Str $x is rw --> Str) { ... } # do the string version.
   multi sub incr (Numeric ::T $x is rw --> T)
    $x += 1;

This is a potential error. Because here is where the caller's
container's constraint needs to be checked against the value
you try to write into it. Numeric is *not* the store constraint
of the caller.

However I've no clever idea how to denote a contra-variant constraint
on the caller's container's constraint in an rw sub. Perhaps

   sub foo (FooOut <-- FooIn $x is rw) {...}

The arrow is of course optional. Its absence means that the caller has
to provide an unconstraint container to be type save. The visual problem
with this arrow is that is cousin --> is not per parameter but for the
whole sub. Alternatively it could be a signature on the trait.

I think I see what you're getting at. But I don't see what it has to do with the container. The value bound to $x needs to be at least as general as FooIn.

You mean FooIn is a contra-variant constraint of the value? I figured
that binding is about containers. Binding to a value implies a read-only
binding. Now how would that be expressed in terms of constraints? Easy,
the constraint of the virtual container is unconditionally false.

   my where {False} $x = 17; # same as: constant $x = 17;

Here the = 17 is pseudo-assignment and doesn't check the constraint.
Otherwise you can't get in a value at all. We could also extent that
to single assignment semantics and allow exactly one assignment to $x
including the one at initialization time.

The problem with rw parameters is that the current spec doesn't have
enough syntactic slots to put the cross checking of values' types for
in- and output. In sub foo (A $a) the A is a constraint for a value that
$a could be bound to at call time. But changing that to sub foo (A $a
is rw) still means A being a constraint on the values you bind to $a
at call time. But where is the syntactic slot of the constraint for
assignment to $a in the body of foo? In this slot foo announces the
type of things it is going to put into $a.

Hmm, or are you thinking of subset constrained containers trying to bind to $x? Currently, there is no mechanism to propagate the constraint in.

But the outer constraint has to be checked whenever a new value is
stored in the caller's variable. So it *must* go in somehow.

If the binding chooses to work by "copy/return" mechanism, then it will be checked when the value is copied back to the original container, using that container's SET, assuming copy/return is designed and intended to reference the original container not just the differently-typed value. I can see the need for that, such as with tied variables in general. Or maybe the container for $x aliases the original container -- that might be what "is ref" is supposed to mean.

Apart from the fact that I really have difficulties to see a difference
between 'is rw' and 'is ref' I nonetheless try to define binding in a
type sound fashion. A signature with a rw parameter is exactly the same
as binding two containers together.

    my A $a .= new;
    my B $b .= new;

    rand > 0.5 ?? $a := $b !! $b := $a;

First of all I think the two cases should be the same binding. Which
sort of is badly indicated by the asymmetric nature of := operator.
The assignment operator = looks symmetric but isn't. So we sort of
have that the wrong way around. I guess the asymmetry is which value
is lost in both cases. A brutal approach were to totally kick out B
in $a := $b. The value in $b would be checked with compatibility with
A and subsequent assignment to $b also checks compatibility with A.

But the main issue is how A and B are handled in the binding. Before the
binding the constraints A and B are checked as follows:

   $a = $x; # checks $x ~~ A
   $b = $x; # checks $x ~~ B

So, what constraints apply to assignments after the binding was done?
I think the only reasonable way is to enforce their logical and written
with type juxtaposition.

   my A B $c;

   $c = $x; # checks $x ~~ A && $x ~~ B

   $a = $c; # OK

   say $b; # prints value of $x

In summary I think that $a := $b checks the current value in $b against
the combined constraint of $a and $b. Everything else hardly is type

Regards, TSa.

"The unavoidable price of reliability is simplicity"  -- C.A.R. Hoare
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan

Reply via email to