--- Matthew Walton <[EMAIL PROTECTED]> wrote:
> Dov Wasserman wrote:
> 
> > my $id = ...;
> > my Int age = ...;
> > my Str $name = ...;
> > my DbHandle $db = ...;
> > my Int of Hash @array = ...;
> > 
> > Therefore, the compile-time type of the term must be
> > assignment-compatible with any and all lvalues. This will have to
> > be true at least in those contexts that ask for strict type-
> > checking, even if other scopes don't care.
> > This reminds me of Java's C<null> literal reference value which can
> > be validly assigned to any reference type. (Technically, it's not a
> > keyword, but try giving that answer on an interview at your own 
> > peril.)
> > 
> > I don't see any functional problem with this special property as
> > long as it can be implemented in the core language. Seems like it
> > would have to be a special rule of type checking. So we'd have 
> > generic Scalar as the universal recipient, and now the Yada 
> > literal as the universal donor. (Any association of strong type-
> > checking with the extraction of blood is purely imaginary.
> 
> As far as the compiler's concerned at that point, it might behave 
> something like C<undef>. For the purposes of the type checker that
> would probably be sufficient. Worrying about the actual value 
> wouldn't be a problem until runtime, at which time it's quite safe
> for C<...> to do what it's supposed to do and complain.
> 

I think of this as very much like the typed-undef we discussed last
month or so: ... should return an unthrown exception wrapped in
undef-ness. 

The type returned by ... should just have a multitude of type-casting
tricks associated:

   my int $i = ...; # Fails at compile time -- no good conversion.

   my Int $i = ...; # Warns at compile time, fails at runtime.

> > [Special Property #2]
> > As mentioned in A6, redefining a function (subroutine, method,
> > etc.) which has only been declared with the Yada Yada Yada closure 
> > does not generate a warning. It seems like Perl 6 will have to 
> > take some special note, then, when we declare a function as:
> > 
> >     sub foo($bar, $baz) {...}; # pre-declaring sub foo()
> > 
> > as opposed to:
> > 
> >     sub foo($bar, $baz) { die }; # defining sub foo() to throw an
> > exception (mod throwing syntax)
> > 
> > so that the first case can be redefined without a warning, while
> > the second case would warn on redefinition.
> 
> I would guess again that the body of the sub not being actually
> executed until the sub is called means that C<...> passes through 
> the compile phase without a problem. The compiler would have to
> special-case it though, to allow the redefinition.

Perhaps not. If {...} evaluates to C<(Code)(undef but something)>, the
transition from C<defined(&foo) == FALSE> to C<defined(&foo) == TRUE>
might not be grounds for a redef warning.

> I'm going to assume that if you tried
> 
> my Int $number = ...;
> $number = 5;
> 
> it would still die at run time on the first C<...>. I really hope it 
> would anyway, because if you really want to do something like that
> we've already got C<undef>.

This is wrong. The purpose of C<undef> is "I declare that I've thought
about the issue and at this point in the code $number should have no
value." The purpose of C<...> is "I declare that there should be
something here, but I haven't thought about it yet."

IOW, C<...> is a form of literate programming that's relatively
self-explanatory and highly compatible with Agile development:

class foo {
  has $.x = ...;
  method bar() {...}
  method baz($a)
  {
    if ($a) 
    {
      .bar();
    }
    
    say "Hello";
  }
}

class foo_test
{
  is UnitTestCase;
  has $.foo;

  method test_empty_baz()
  {
     $.foo = new foo;
     $.foo.baz(undef);
  }
}

This code should work okay -- no Yadda ever gets executed.

Then when I add:

  method test_valid_baz()
  {
    $.foo = new foo;
    $.foo.baz(1);
  }

there should be a failure, because $.foo.baz calls $.foo.bar, which is
defined C<{...}>, which evaluates to an unspecified value exception.

> > [Question #1]
> > I'd like to understand how Aaron Sherman's initial example would
> > work:
> > 
> > class Foo {
> >     has $.a;
> >     has $.b;
> >     ...;
> > }
> > 
> > We know that the class will compile fine, but when exactly would it
> > pitch a fit (or exception)? I'm unsure of the meaning of this
idiom,
> > because the only time the C<...> line gets evaluated is at class 
> > compilation time, which is when we don't want any complaints in 
> > this case.
> 
> I thought class closures 'ran' at object creation time. I'm probably 
> wrong about that. Object creation time would be a good time for that 
> particular yada yada yada to start complaining though. I suspect
> C<...> is going to be considerably more sophisticated than a macro
> that replaces it with C<{ die }>.

I think the metaclass "class assembler" function will behave like this:

  If only a Yadda is provided, just return a typed Yadda object.

  If anything other than a Yadda:

  If you provide a definition of any name, it goes in.

  If you provide a Yadda, it gets recorded.

  When wrapping up, if any methods are provided, then a special
    yadda-on-not-found dispatcher is provided. If no methods are 
    provided, a special yadda-on-not-inherited dispatcher is provided.

  A similar data member access is provided.

So that:

  class Foo {
    has $.a;
    has $.b;
    ...
  }

Becomes:

  class Foo {
    AUTOMETH {
      if inherited($method_name), run it.
      else return sub {...};
    }

    has $.a;
    has $.b;  
    AUTOMEMBER {
      if inherited($member_name), return it.
      else return \...;
    }
  }

> > [Question #2]
> > Does C<...> know when it's being called during compilation and when
> > it's being used at run-time? I.e., how would it behave in a 
> > compile-time block such as BEGIN:
> > 
> > BEGIN {  our IO $server = ...; };

I suspect that C<...> constructs a Yadda object literal.

> > The rhs value is evaluated here at compile-time. Is C<...> smart
> > enough to know that and keep quiet?

So it executes, constructs the object, and puts it into $server. No
problem yet. Perl should whine at you if you tell it to warn on
incomplete code.

Storing it shouldn't be fatal, but reading from it or executing it
should.

> I would expect that to run and complain at compile time. That might
> be irritating, but I'm not sure how else it could be done, because 
> BEGIN blocks are run then, and when they're run you need to know what
> values you're going to assign to the variables.
> 
> Unless you gather it up inside some sort of lazy evaluation construct
> that keeps delaying the evaluation of it until you hit run phase, at 
> which point you've probably got the entire BEGIN block ready to go,
> with everything that comes after it also hanging around, and... no,
> doesn't sound good does it?

Again, I like it. A partially defined object isn't fatal unless you
actually need that part.

=Austin

Reply via email to