HaloO,

Larry Wall wrote:
On Thu, Aug 11, 2005 at 04:47:49PM +0200, TSa wrote:
: >    defined($spot);       # false!?
: : true! Even for my $spot = ::Dog because when my is evaluated the
: name ::Dog has be be bound, AUTOLOADED or by whatever means become
: available.

What does binding have to do with definedness?

We seem to struggle in around words which can be deceiving.
This is why I used 'whatever'. Before some meaning is attached
to them the three strings '$spot', '=' and '::Dog' are just
three sequences of characters separated by whitespace.

Since the moment when meaning is put behind '::Dog' is somewhat
vague, I tried to preserve that vagueness in my sentence. And
it seems to be the case that '::Dog' is more vague than 'Dog'.
I don't care of how many people's code, modules, packages,
AUTOLOADERS or whatever has to meddle before the meaning behind
::Dog becomes available. Could we please agree on a term that
denotes the fact that ::Dog leads somewhere. Seemingly my
'name ::Dog ... bound' wasn't clear enough.


 In Perl 6 the object
itself decides if it's defined regardless of how or where it's bound.

I wasn't talking about an object at all. The string 'defined($spot)'
once again needs a meaning attached to 'defined' and '$spot' the
parens are prescribed by the grammar. And so is the fact that 'defined'
has to be a Sub subtype that can handle the type of $spot. I guess we
all agree that the least type of &defined is :( Item --> Bool) and
$spot has at most that type by virtue of the $ sigil. So we know that
the type of 'defined($spot)' is Bool. The value at runtime is irrelevant
in that contemplation. The question is can we do better and conclude
a subtype of Bool, that is either the type true or the type false,
not the runtime values! This knowledge can hardly come from the return
value of &defined. Thus it must be derived from more specific type
information about $spot. If that is not available, the story ends here.

<interjection>
The above invocation of &defined happens in Void context
but I suppose that &defined is not (declared|defined|specified|whatever)
to provide that type. Could that be optimized to not generating
a call at all? How would such a feature be declared? Are there
'is eager' and 'is lazy' traits for subs and methods? And which is
the default?
</interjection>


That's how we get interesting values of undef.  The recent proposal
only tweaks that idea to unify typed undefs with interesting undefs
so that an unthrown exception can also be an abstract (albeit
unsuccessful) IO or Dog or whatever, so that you don't have to play
games with junctions to get undef into typed variables.

Sorry, I can't follow. What is a 'typed variable' to you? How does
it relate to 'typed undef'. I have put Undef as a subtype under Item,
next to Value, Ref and Junction. This means to me that if you know
of a certain expression that it is typed as Value then Undef is
excluded. If all you know is that you have an Item then Undef is
also included as is Ref or Junction. This is how type systems work.

For example the string 'my @a' introduces an Array by virtue of the
single char @. The expression '@a[23]' is already a quite complicated
thing. It's an invocation of the index operator. The type of which
is :( Array, Int --> Item). And with the Item our friend Undef enters
the picture. Consider

  my Int @a;
  my Int $i;

  $i = @a[23]; # dispatch to op = :(Undef of Int, Pos[Array])
               # note that (Undef of Int).does(Int) hypothetically
  @a[23] = 42;

  say $i; # prints 42?

A nice implementation of op = could store something in $i that
somehow finds back to slot 23 of @a. My idea of such a type is
Pos[Array of Int] which is a subtype of Int through two paths.
And of Ref[Int], but that is not important here directly.
Thus its value can be interpreted as any(23,42) with a
preference for 42 because that is what the user might expect.
Please note that this behaviour is implemented by providing
a certain target for op = dispatches, *not* through messing with
the Array, Item or Int classes! If @a[23] returns an Int
eagerly then the dispatch goes to :(Undef of Int, Int) and
something else happens. But this decision of return type again
needs different targets for the index operator *not* the variables,
containers or classes!

 In other
words, $spot is not successful, but that can be either because we
tried and failed, or because we haven't tried yet.  That's the
unification I'm looking at.

What would you expect from

  delete(@a[23]);  # make slot 23 in @a undefined again

  say $i;

The type system is quite happy with the integer value 23.
But the Pos type could be made to complain that it's link
to the 42 is cut if that is what you want.

BTW, is the distinction between Entry of Hash and Pos of Array
usefull or should that be unified under Elem of Hash|Array|Str?
But then again the pairs of a hash are not retrieved as List of Pair
with the .elems method which retrieves a List of Item from an Array,
or are they? Actually I fear that I have the wrong attitude here
and suspect the answer: "But .pairs is inside the Hash class while
.elems is inside the Array class." The question is if you start
from the Array class and then reason about the methods it has or
if you start from the .elem method---which is an instance of the
Method class---and reason how it behaves given different types of
invocants.

Blue Sky question: is it thinkable to fold slot calls into the
pair syntax as follows?

  my $obj = SomeClassWithSlot_foo.new;

  say $obj:foo; # prints return value of slot call foo

I mean the adverbial modifier syntax already works on Code objects.
That is

  sub blahh( +$foo ) {...}

  $obj = &blahh;

already attaches a meaning to

  say $obj:foo;

This time the return value of blahh is printed. I guess blahh receives
a $foo = 0 but true. This might also give the shortest form of hash
access proposed so far:

  %hash:key = 23; # %hash<key> = 23; is one char longer ;)

and

  %hash :key = 23; # %hash .<key> = 23; is two chars longer ;))

Even better, the syntax

  say:loud:margin(8):tabs(4) foo();

can be seen as currying &say one named parameter at a time
from left to right. The result is a sub that receives the
return value of the foo() invocation for printing. Since I'm
at it...

  &mysay = &say:loud:margin(8):tabs(4); # currying slot calls

might just be a short form of .assuming and then

  mysay foo();

is the same as above. And of course also

  &map_add = &map:{$^x + $^y};

  say map_add 1,2,3,4,5,6;

But of course I'm not the language designer---and much
less the Lord of the Colon.

The above in a certain way increases the number of sigils
to my favorite 'The 7 Endless':

  ::Meta

   &Sub
   .Method  :Slot

   :Pair    %Hash
   $Item    @Array

First comes unavoidably the typing Destiny, then his brother
and sister Dream and Death, then the data part of the Family:
Destruction, Desire, Despair and Delirium.

Besides, seven is a very beautiful number. E.g.

  7 == 2**0 + 2**1 + 2**2 == 1 + 2 + 4

The sum of Two taken to the power of the three levels of the type system.
Level[-1]: the underlying VM
Level [0]: pure abstraction, but standard Perl6 pre-loaded
Level [1]: closure introduction
Level [2]: fundamental types to build stuff from,
           that is given to closures to do something with it

Here is my mapping:

  ::Meta    --> Destiny, the oldest all knowing, blind wanderer

   &Sub     --> Dream, Morpheus, the Sandman
   .Method  --> Death, dealing on invocants

   :Pair    --> Destruction, left his realm and actually constructs things
   %Hash    --> Delirium, somewhat puzzled err hashed
   @Array   --> Desire, always wanting more content (sigil is a heart)
   $Item    --> Despair, when nothing else works (her sigil is a hook)

Your pick?
--
$TSa.greeting := "HaloO"; # mind the echo!

Reply via email to