Clarification of behavior for .isa() on built-in types

1 view
Skip to first unread message

Stevan Little

unread,
May 7, 2005, 1:09:52 PM5/7/05
to perl6-l...@perl.org
Hello All,

So I am expanding our .isa() tests for built-in datatypes (in
particular Array), and I have a few (probably very simple) questions
(since I cannot seem to find details on this anywhere).

Is there an isa() built-in for this?

Or it is really @array.meta.isa() (from the Introspection section of
S12)?

According to S12/Introspection, isa() does 2 things:

(NOTE: this my interpretation since the details are not speced)

- If given no arguments (only an invocant), it returns a list of the
invocant's parent classes
- If given a class name as an argument, it returns a boolean (true if
invocant.isa(class) and false otherwise)

Now some questions about 'class name' argument described in the second
item above. (NOTE: I am asking general .isa() questions now, not just
about built-ins).

I assume it can be a Class name: $fido.isa(Dog)
Or it can be a String: $fido.isa('Dog')

But can it also be a Junction? :
$fido.isa(Dog | Cat) # true if $fido.isa(Dog) or $fido.isa(Cat)
$fido.isa(Dog & Beagle) # true if $fide.isa(Dog) and $fido.isa(Beagle)

If it can be a Junction, it makes me wonder if maybe what is happening
behind the scenes is not some variant of the "smart-match" (~~). In
that case, then would something like this DWIM (ignoring the
questionable sanity of actually doing it for a momemnt)

@array.isa(@array)

or even:

@array.isa([]) # basically @array.isa(List)

However, maybe this is going to far :)

Any clarification would be much appreciated.

Stevan

Matt Fowles

unread,
May 7, 2005, 1:16:24 PM5/7/05
to Stevan Little, perl6-l...@perl.org
Stevan~

On 5/7/05, Stevan Little <ste...@iinteractive.com> wrote:
> But can it also be a Junction? :
> $fido.isa(Dog | Cat) # true if $fido.isa(Dog) or $fido.isa(Cat)
> $fido.isa(Dog & Beagle) # true if $fide.isa(Dog) and $fido.isa(Beagle)
>
> If it can be a Junction, it makes me wonder if maybe what is happening
> behind the scenes is not some variant of the "smart-match" (~~). In
> that case, then would something like this DWIM (ignoring the
> questionable sanity of actually doing it for a momemnt)

This can be accomplished by simply using the autothreading semantics
of junctions. The isa() call will be made repeatedly with the
different arguments and then the junction will know how to combine
that into a single boolean result.

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-???

Larry Wall

unread,
May 7, 2005, 3:32:13 PM5/7/05
to perl6-l...@perl.org
On Sat, May 07, 2005 at 01:09:52PM -0400, Stevan Little wrote:
: Hello All,

:
: So I am expanding our .isa() tests for built-in datatypes (in
: particular Array), and I have a few (probably very simple) questions
: (since I cannot seem to find details on this anywhere).
:
: Is there an isa() built-in for this?
:
: Or it is really @array.meta.isa() (from the Introspection section of
: S12)?

The latter, I think, though probably it only redirects to .meta.isa when it
can't find .isa directly. That is, Object.isa delegates to .meta.isa.
Unless it's Any.isa...

: According to S12/Introspection, isa() does 2 things:


:
: (NOTE: this my interpretation since the details are not speced)
:
: - If given no arguments (only an invocant), it returns a list of the
: invocant's parent classes

Recursively? That is, any classes for which .isa(X) would be true?

: - If given a class name as an argument, it returns a boolean (true if
: invocant.isa(class) and false otherwise)

Yes.

: Now some questions about 'class name' argument described in the second

: item above. (NOTE: I am asking general .isa() questions now, not just
: about built-ins).
:
: I assume it can be a Class name: $fido.isa(Dog)
: Or it can be a String: $fido.isa('Dog')

That seems reasonable. Note that ::Dog is equivalent to Dog in every
respect, including looking for a local definition of Dog before a global
one.

: But can it also be a Junction? :


: $fido.isa(Dog | Cat) # true if $fido.isa(Dog) or $fido.isa(Cat)
: $fido.isa(Dog & Beagle) # true if $fide.isa(Dog) and
: $fido.isa(Beagle)

Autothreads, so .isa needn't worry about it.

: If it can be a Junction, it makes me wonder if maybe what is happening

: behind the scenes is not some variant of the "smart-match" (~~).

Well, there aren't really variants of ~~, except insofar as people
add new MMD behaviors. As for your question, it's more the other way
around, since ~~ is *almost* defined in terms of .isa. (It's defined
in terms of .does instead, which with no argument produces a superset
of what .isa produces, since $x.does(X) is defined to be true for any
role X or parent class X or parent class's role X (or any subtype derived
from those for which the constraints are satisfied. That implies .does
without arguments could get kind of expensive.)

Anyway, if inside .isa you try to do $obj ~~ $class, you'll just end up
turning .isa into a version of .does. I think you probably need something
more like

$obj.class =:= ::($class);

assuming symbolic references can also take hard refs. Also, that's
not going to look up a string class starting in the correct package.
May have to separate out the string case and force lookup in the
caller's scope somehow.

In fact, I foresee this is going to be a general problem. Maybe there
needs to be an optional argument to symbolic refs that specifies the
scope of the caller somehow, including both the lexical scope at the
point of the call and the package of the caller.

: In

: that case, then would something like this DWIM (ignoring the
: questionable sanity of actually doing it for a momemnt)
:
: @array.isa(@array)

Depends on what you mean. Do you mean that @array contains a list of
types, or that @array is standing in for Array? From your next example
it sounds like you mean the second of these:

@array.isa(any(@array))
@array.isa(@array.dispatcher)

: or even:


:
: @array.isa([]) # basically @array.isa(List)

That's not a List, it's an Array by the time .isa sees it. You never
see a naked List in Perl unless you take specific steps to declare
a parameter to see it, or peek at an arrays .specs.

: However, maybe this is going to far :)

Well, it may fall out of the fact that the .dispatcher of either a class
or an object of the class is the class itself.

Larry

Reply all
Reply to author
Forward
0 new messages