<A12>
which doesn't quite work, because $spot is undefined. What probably happens
is that the my cheats and puts a version of undef in there that knows it
should dispatch to the Dog class if you call .self:new() on it. Anyway,
we'll make it work one way or another, so that it becomes the equivalent of:
</A12>
I want to point out this is a pretty good idea overall, not as just some
"magic" behavior. Specifically, if I say:
my Dog $spot;
I should then be able to call class methods of Dog via $spot without further
initialization:
print defined($spot); # FALSE
$rover = $spot.new;
@breeds = $spot.list_breeds;
This is, as pointed out, just sugar for Dog::new and Dog::list_breeds, but
it brings up the spectre of undef invocants:
class C {
method ctor {...}
method foo returns C {...; return undef; ...}
method bar returns C {...; return undef; ...}
method baz {...}
}
my C $c .= ctor; # $c is defined and all is well.
$c->foo->bar->baz; # If foo or bar fails, what happens?
There are potentially two flavors of undef:
undef
undef but class = C
Given that the foo and bar methods are declared to return C, should the
'return undef' code emit a 'pure' undef, or a undef-of-type-C?
And if so, should it be legal to have an undef invocant? A typed-undef
invocant?
This sort of wanders towards the question: Is undef a value, or a
meta-value? That is, can a UDT rely on scalar undef as part of its range (a
la NaN/Inf in the numbers space) or must undef be considered part of the
Perl domain, "you're not a Thingy yet."
(The mapping of undef <-> SQL's NULL comes to mind.)
=Austin
But shouldn't you then just use "my Class $spot = Dog" then? Or maybe
just "my $spot := Dog"?
> This is, as pointed out, just sugar for Dog::new and Dog::list_breeds, but
> it brings up the spectre of undef invocants:
:: or .? I'm confused.
> $c->foo->bar->baz; # If foo or bar fails, what happens?
-> or .? Even more confused now.
Juerd
Well, maybe, but what if you're being passed it in via a sub? And
what if you don't know the type. Eg.
sub foo ($x is copy) {
$x //= $x.new;
}
That would clearly die if you said:
foo(undef);
But what if that undef was cascaded from somewhere else? It allows you
to have an *undefined* object floating around that knows what it
*should* be.
To be clear, I don't know exactly what benefit that has just yet, but it
seems like one of those things that has potential.
On the other hand, A12 said that $x.new when $x is undef should in turn
be undef. That also seems like something potentially useful.
> > This is, as pointed out, just sugar for Dog::new and Dog::list_breeds, but
> > it brings up the spectre of undef invocants:
>
> :: or .? I'm confused.
Dog::new is the name of the method; Dog.new is how you call it. So the
answer is yes.
> > $c->foo->bar->baz; # If foo or bar fails, what happens?
>
> -> or .? Even more confused now.
You'll have to give Austin some rope in the syntax area. His brain
occasionally stops working (hmm, I know that feeling %-), but you can
usually figure out what he means. :-p
Luke
> -----Original Message-----
> From: Juerd [mailto:ju...@convolution.nl]
>
> Austin Hastings skribis 2004-04-23 13:33 (-0400):
> > I should then be able to call class methods of Dog via $spot
> > without further initialization:
> > print defined($spot); # FALSE
> > $rover = $spot.new;
> > @breeds = $spot.list_breeds;
>
> But shouldn't you then just use "my Class $spot = Dog" then? Or maybe
> just "my $spot := Dog"?
Hmm, no. The point is that typed-undef should know what to do, by default,
when calling class methods. And maybe it should even call non-class (i.e.,
"object") methods, with a typed-undef invocant.
> > This is, as pointed out, just sugar for Dog::new and Dog::list_breeds,
but
> > it brings up the spectre of undef invocants:
>
> :: or .? I'm confused.
It's :: to indicate class::function naming.
> > $c->foo->bar->baz; # If foo or bar fails, what happens?
>
> -> or .? Even more confused now.
$c.foo.bar.baz
Sorry, I've been PHPing a lot.
=Austin
It would make some of the current p6i nargery a bit simpler, too.
--
In this talk, I would like to speculate a little, on ... the development
of intelligent life. I shall take this to include the human race, even
though much of its behaviour throughout history has been pretty
stupid... - Stephen Hawking
$class.bless(undef, *%_);
But I made it 0 instead merely because it's shorter. That does, however,
free up "undef" as a way of asking for an explicitly undefined but
blessed value.
: There are potentially two flavors of undef:
:
: undef
:
: undef but class = C
There are potentially many flavors of undef already. I've already said
that many undef flavors contain an unthrown exception stating why the
value in question is undefined, such that if you try to use the value
as defined, you can throw an intelligent exception that will point the
user back to the real problem.
That is one of the real innovations in Perl 6, as opposed to the borrowings.
: Given that the foo and bar methods are declared to return C, should the
: 'return undef' code emit a 'pure' undef, or a undef-of-type-C?
Don't know the answer to that one. One possible answer with a certain
amount of appeal is that it is completely illegal to return a bare undef.
It either has to be an unthrown exception, or a proto-object.
: And if so, should it be legal to have an undef invocant? A typed-undef
: invocant?
Depends on what it's pretending not to be, I suspect.
: This sort of wanders towards the question: Is undef a value, or a
: meta-value? That is, can a UDT rely on scalar undef as part of its range (a
: la NaN/Inf in the numbers space) or must undef be considered part of the
: Perl domain, "you're not a Thingy yet."
I'd say the concept of defined/undefined as a constraint depends entirely
on whether the object in question returns true or false to .defined(),
regardless of its other characteristics. Perl is otherwise agnostic to
its thinginess, at least until you ask it to care.
: (The mapping of undef <-> SQL's NULL comes to mind.)
Hmm, yes, that might fall out rather neatly, as long as it's clear to
the reader when you mean NULL rather than undef. It's almost a funny
kind of junction.
Larry
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
>
> Interestingly, the opaque shortcut used to be
>
> $class.bless(undef, *%_);
>
> But I made it 0 instead merely because it's shorter. That does, however,
> free up "undef" as a way of asking for an explicitly undefined but
> blessed value.
^^ This is pretty much the whole answer. Sweet! ^^
>
> : There are potentially two flavors of undef:
> :
> : undef
> :
> : undef but class = C
>
> There are potentially many flavors of undef already. I've already said
> that many undef flavors contain an unthrown exception stating why the
> value in question is undefined, such that if you try to use the value
> as defined, you can throw an intelligent exception that will point the
> user back to the real problem.
Sure, but "You haven't provided a value yet." doesn't seem very ...
exceptional.
> That is one of the real innovations in Perl 6, as opposed to the
> borrowings.
>
> : Given that the foo and bar methods are declared to return C, should the
> : 'return undef' code emit a 'pure' undef, or a undef-of-type-C?
>
> Don't know the answer to that one. One possible answer with a certain
> amount of appeal is that it is completely illegal to return a bare undef.
> It either has to be an unthrown exception, or a proto-object.
I was hoping for "Perl will type-convert the undef for you". :-)
> : And if so, should it be legal to have an undef invocant? A typed-undef
> : invocant?
>
> Depends on what it's pretending not to be, I suspect.
Sure -- the class of the object may object to the object being undef. (Sorry
:-) But does Perl object to an undef object of the class of the object
object?
That is:
$foo = (undef as Dog).collar();
The important thing will be "You didn't provide a value at line 42, though
you didn't actually try to use it till line 582."
: Sure -- the class of the object may object to the object being undef. (Sorry
: :-) But does Perl object to an undef object of the class of the object
: object?
:
: That is:
:
: $foo = (undef as Dog).collar();
Haven't the foggiest. I just pretend to be a language designer.
Larry
I was talking about unthrown exceptions objects. I have no opinions on
how lazy undef wants to be for ordinary objects.
Larry
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
>
> On Fri, Apr 23, 2004 at 02:50:42PM -0400, Austin Hastings wrote:
> : Sure, but "You haven't provided a value yet." doesn't seem very ...
> : exceptional.
>
> The important thing will be "You didn't provide a value at line 42, though
> you didn't actually try to use it till line 582."
So the "typed undef" doesn't get built or inserted or whatever until some
reference is made to the object?
my Dog $spot;
my Dog $rover;
At this point, no calls have been made to the 'default undef constructor',
right?
$spot = $rover.clone();
At this point, $rover gets typed-undef, then cloned?
=Austin
Just wondering, are we going to have semantics similar to the old NaN Vs
Signaling-Nan in IEEE floating point? An IEE NaN has an N-bit field where
the source of the NaN can place a value representing the reason for the NaN.
It can also set a flag which selects between two behaviors:
* normal NaN: If you attempt to use the NaN in any calculation, then you'll
get back the original NaN (the defined semantics are actually a bit fuzzy
here -- an implementation is permitted to lose any information that you
embedded in your NaN. But presumably, if your hardware inserts a value, it
also knows not to trash it).
* Signaling NaN: If you attempt to use the NaN in any calculation then you
get an FP exception. If you have set your processor to trap on exceptions,
then you get a trap.
I'm not sure how much of this is relevant to C<undef>, but it might be nice
to have the ability to have an undef that says "if used, then trap" (using
the current "use fail" mode -- if that still exists)
Dave.
ps. as an aside, it would be really nice to have support for
getting/handling numeric exceptions -- even for things like an overflow
("carry") on a primitive "int". As a bonus, an "int" with saturation
semantics (cf the normal modulo semantics) would be nice, too. I think that
would need parrot-level support to be efficient.
I suppose one could give a typed undef whatever semantics you like with an
appropriate AUTOMETH definition.
: ps. as an aside, it would be really nice to have support for
: getting/handling numeric exceptions -- even for things like an overflow
: ("carry") on a primitive "int". As a bonus, an "int" with saturation
: semantics (cf the normal modulo semantics) would be nice, too. I think that
: would need parrot-level support to be efficient.
I expect so. Low-level types tend to be rather, well, low-level.
Larry
> Just wondering, are we going to have semantics similar to the old NaN Vs
> Signaling-Nan in IEEE floating point? An IEE NaN has an N-bit field where
> the source of the NaN can place a value representing the reason for the NaN.
> It can also set a flag which selects between two behaviors:
Didn't we decide that NaN was a reserved word and should never be spoken
again, especially with respect to undef? ;-)
Seriously, though, I think there's some detail in terms of standard
library that have to get covered before it makes sense to explore this
in much depth.
--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback