--- 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