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