Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

P6Objects: Hints, allegations & things left unsaid

8 views
Skip to first unread message

Austin Hastings

unread,
Apr 23, 2003, 12:14:52 AM4/23/03
to Perl6 Language

I started this before MikeL started his summary of a few days back. I
finished well after. Guess who's the better writer?

I've gone into the wayback machine (about 2 years) for some of this stuff,
including a post from Damian that answered most of the questions asked last
week :( Shame I couldn't remember it before starting to write this.


=head1 Perl6::Objects

Here's the stuff I think I know from the list-to-date:


=head2 Trivia

=head3 Pair Type

There's a Pair type in some of Damian's messages. I hadn't really paid
attention before, but the implication seems to be that (1) it's a built-in;
and (2) it may well be the default return type of a hash in list context.
Well, it surprised me, anyway. You got this, MikeL?

sub draw_triangle ( Point|Pair $a is copy,
Point|Pair $b is copy,
Point|Pair $c is copy) {
when Pair {$_ = Point.new(.key,.value)} for $a, $b, $c;
...
}


=head2 Scope

=head3 Everything is an object

First, everything's an object. Or, according to Dan, nothing's an object.
The point is that object access will no longer be via an indirect ref or
whatever.

Instead, object methods get invoked as $object.method. In keeping with the
philosophy, however, there's an awful lot of stuff that is being described
in object terms: File Handles, Arrays, Hashes, Various 'Magic' system things
(e.g., C<caller>), and the Perl6 parser itself. (Arrays, at minimum "cannot
be discerned from objects.")

=head3 Object Syntax is folded in

There are things that Larry (and @Larry) has already said about objects,
such as example class declarations, that make it obvious that "object"
keywords are being unified with other stuff. Consider C<is>:

class Dog is Pet {...}

my Int $i is Persistent;

The bad old days of C<bless> and C<ref> (and C<ref>) are no more. Gone are
C<@ISA> and C<new>. Instead, the interface for objects is built in. C<bless>
is really dead. C<ref> will probably live on (there's too many EEEVIL PH's
out there to let it go completely :). C<new> is now a class method, not
required in the basic case.

=head3 Everything has methods

Everything, as far as I can tell, will support the .id method. This includes
the "small" types - int, num, str - as well as "first class" objects.


=head2 Properties & Attributes

=head3 Properties are "traits"

Properties, hereafter, means "but ..." additions to data items. The working
model for @Larry has been that properties in this mode are singleton
overrides of a (possibly non-existant) method. If a property is absent, the
object's method for that class will be invoked, if available.

=head3 I<true> is a property

This includes the "but true" case - classes are free to embrace and extend
the definition of truth. Returning C<new Dog: "Spot" but true> applies an
override to the normal Dog::true method, forcing an affirmative return.

=head3 Potentially, all RW & arity(0) methods are properties

Given the above, and the possible confusion between Class.true and
Object.true, Larry has suggested making all C<.method(/* no args*/ is rw>
methods be properties. Which is to say, they would show up in any potential
"Properties Hash" that was available from the objects:

for $my_object.properties.keys {
print "$_\t$my_object.properties{$_}\n";
}

=head3 Attributes

Attributes are probably private by default. Methods are public by default.
There may well be a property on a class that makes all its attributes public
by default, so it acts more like a struct in C++.

(Yeah, we need more of those...)


=head2 Contrasts of Note

=head3 Class versus Type

I'm arbitrarily defining TYPE as "Prescribed externally-visible behavior."
Which is to say, "If it acts like a duck, it's a duck."

I'm defining CLASS as "implementation of a type."

Which means, first off, that CLASS is a superset of TYPE. (In I<Theta>, for
example, such methods as constructors are viewed as unfortunate overhead
involved in the implementation of abstractly ideal behavior.)

Second off, it means that a CLASS can be a failed or imperfect
implementation of TYPE.

Larry has indicated that he is "considering" the use of TYPEs in Perl6.


=head4 Mixins & Multiple Inheritance

Several people have suggested that the C<is Foo> behavior might be usable as
a "mixin" class mechanism, or as a multiple inheritance mechanism.
Consideration has also been given to C<is Foo> as a way of specifying
interfaces.


=head4 Curried Classes

Larry has explicitly mentioned Ada's "subtyping" mechanism in this context,
so Perl6 types may not resemble the Theta/Java/C++ family. Instead,
visualize a class Matrix for 2D matrices. Then visualize a subtype of this
class such that the matrices were always square. (max_x == max_y). Voila,
subtype.

Alternatively, consider writing a very generalized class in Perl6 to perform
some abstract behavior. Perhaps a doubly linked list. Now imagine using the
C<.assuming> modifier to produce a version such that all of the node data
were optimized to work with C<YourClass> objects. Same source code, better
performance via global optimization.


=head4 Conversion versus Coercion

If w/e 2003-04-19 was any indication, there's still some uncertainty
surrounding this issue.

I'm arbitrarily defining "COERCION" as pretending or substituting a value of
an appropriate type.

I'm arbitrarily defining "CONVERSION" as invoking Code that will change the
original value, or return a temporary value significantly altered from the
original.

And, for the sake of completeness, let's define "CASTING" as an explicit
context, coercion or conversion operation invoked by the coder.


=head4 Parameter Passing

This brief diversion required by the discussion of coercions and
conversions, next.

=head5 Compatibility

P6 subroutine and operator parameters are passed in certain well-defined
ways. By default, it's const-reference. You can say "is copy" or "is rw" to
get different behavior, of course (I'm not sure if "is copy" implies "is rw"
or still "is const". Anyone?)

This has an immediate impact on the possibilities for coercion and
conversion, because those two activities only occur when data is being used
in an expression (operators) or passed to a subroutine.

If the data being passed is complex, it becomes obvious that no DWIM hack is
going to get around the fact that while class Foo may have a Foo-to-int
conversion function defined, an array of Foo is nowhere close to an array of
int.

So this constrains the very possibility of conversion or coercion. If a Foo
can act like an int, maybe it can be coerced. But if a conversion function
is required, no chance - unless the signature calls for C<is copy>.

No definitive statement on the level of DWIMness, yet. Damian has suggested
that the C<is copy> semantics may actually encourage the Routine to do
aggressive conversion, even.

=head5 Conformance

Larry has suggested that as an optimization measure, it may be possible to
build call snapping (thunks, anyone?) into the code generator. That is,
there may be two (or more) entry points into a Routine. The outer entry
points would be responsible for checking type on arguments and the like. The
inner entry points would be less and less type-secure. The theory is that
for routines which have call-flow data available, it may be possible to
notify the thunk(s) of the level of stability available, and let the
validation thunk snap the call pointer to one of the internal entry points.


=head4 Type-interchange Basics

Larry has positively stated that the Scalar/Int/String interchangeability of
Perl must remain.

Additionally, he has given support to the notion that while the "lowercase
classes" (int, str, etc.) are storage-impaired, they may be supported at
some run-time cost via a sort of "featherweight class" approach as having
some or all of the same attribute/trait behavior that their capitalized
cousins have.


=head4 Hierarchical Method Access

Access to explicitly scoped methods can be had via

$object.PRETEND_CLASS::method();


=head4 Coercion multimethods

Larry has discussed using multimethods as the mechanism for coercion. He has
suggested that multimethods may have to include return type as part of the
signature for this reason. (This is false, if you view coercion as a binary
assignment-like operator, but the trend has been away from this.)


=head4 Explicit Conversion

Explicit coercion (& conversion, for that matter) has been described as
using the target type name as a subroutine name. Thus int() -> int, Foo() ->
Foo, etc.

See also Parameter Passing, above, regarding the C<is copy> directive.


=head4 Automatic Coercion

Automatic coercion generally takes the form of the compiler treating some
set of objects as equivalent (at least in one direction).

=head5 Automatic Widening Coercion

No one has had anything negative to say about automatic widening coercions
on inheritance-based superclasses. Noone has had anything whatsoever to say
about automatic widening coercion on mixin-/interface- based superclasses.

=head5 Automatic Complex Type Coercion

Damian gave a very complete example involving a Set of Apple and a Basket of
Fruit and how assignments involving a third object might work. Essentially,
the basal storage class specifier (e.g., C<is Array>) and the complex object
details (any C<of ...> or C<returns ...> statements) must be individually
compatible (widening is permitted, natch).

=over 4
"In other words, to be able to assign a C<Righty> object to a C<Lefty>
variable
(or use a C<Righty> in any other context where a <Lefty> is expected):

my Lefty $var = Righty->new();

each component of type C<Righty> must be in a valid C<.isa> relationship to
the corresponding element of C<Lefty>."

=back


=head4 Automatic Conversion

As always, Perl will read your mind if the optional Computer-Telepathy
Interface has been activated. The prospect of multiple routes for conversion
has been acknowledged, but no resolution yet. However, see note about about
Scalar/Int/String interoperability.

=head5 Automatic Lossy Conversion

No one has commented on whether a Num/Float type can be assigned into an Int
type without harassment. In this case, I suspect the explicit C<$i =
Int($f);> won't cause the peasants to revolt under C<use strict>.

On the other hand, there's only Larry's inclination towards "keeping the
entry ramp low" to suggest that it will work when strict is not in effect.

=head3 Storage versus Stowage

There are two types associated with a variable in P6: the type that contains
the data, and the type that constrains the data. (Somebody stop me before I
appear on Geraldo!)

The container type is called the variable type. The other one is the value
type. If it helps, the variable type has to agree with the sigil, while the
value type should agree with the methods invoked.

my @a is Array of Int;

The variable type in the previous statement is Array, while the value type
is to the right of a C<returns> or an C<of> keyword.

Note that the sigil provides one level of variable-type information for
free - this may cause confusion later:

my @a is Array of Int; # Redundant
my @a returns Array of Int; # Not.

Larry expects to do optimizations based on the variable types. Since
variable types can be inherited and extended (see below), and since this is
Perl, I expect that we'll see Perl6+epsilon introduce the ability to
subclass the code generator, not just the parser, for those aggressive
type-developers out there.

One of the optimizations based on type is knowing that a given value will
always be an integer. This, combined with the "lean" towards strictness in
type checking, implies that method dispatch is going to be heavily optimized
based on this data.

Certain types tend to blend variable- and value- typing together. The
lowercase types (int, str, bit) are an example. Given that just about
everyone expects that an C<Array of bit> will allocate length/32 words of
storage, there's going to be type-magic somewhere at the bottom.

"Move along folks, nothing to see here."


=head4 Tie

I infer from several messages that the difference between a variable type
and a value type is the signature. That is, extending Array -> FileArray is
syntactically comparable to extending Window -> TextPane. (It's just a
SMOP.)

The "traditional" tie-associated upper-case method names come into play when
defining a storage type.

One new one is C<.copy>, which may be how assignment is handled.


=head4 Binding

When binding, the expected behavior is that the compiler will only allow
operations consistent with the type of the bound name. However, the bound
name should respond with polymorphic behavior to the names it knows.

Ex.: my Array @a := SpecialArray.new;

@a will respond only to Array methods, but will invoke SpecialArray::method
on each call.


=head4 Assignment & Operators

Given the above, it appears that the assignment operations are not going to
be trivial to override, if they can be overridden at all.

I suggest that they may not be overridden since (1) it's common, and
therefore subject to extreme optimization; and (2) since the rules for
assignment are somewhat simple, all the "real joy" may be pushed into magic
methods like C<.copy>, above.

This ignores the friends and fans of Nicklaus Wirth, who may wish to
override infix:=($a, $b) to serve as a comparison operator, not an
assignment. Eat dirt, Modula-boy!

=over 4
"Intrinsic types are copied by default, plus any objects with a .copy
method. In other words, Scalar has a .copy method by default, and anything
else is your own doing. Int, Num, Str, and Ref inherit the .copy interface
from Scalar. In particular, a Ref only copies itself unless it refers to
something with a .copy method."

=back


=head4 Auto-instantiation

Mike Lazzaro points out that the C<is TYPE> syntax seems to autoinstantiate
a TYPE object, or at least mark one as being instantiated at first use.
(This is a significant difference, IMO, but skip it.)

Damian has agreed that C<my $f is Foo> does, in fact, create an
(inaccessible) instantiation object, a la C<tie>.


=head2 Methods and Submethods and Multimethods, oh my!

Apparently there's a desire to provide uninheritable methods, because a
whole keyword, C<submethod>, was introduced in A6 to declare methods that
would not be inherited by derived classes. (I don't recall the answer, if
any, to the question of whether a submethod could sit at the top of the
chain.)

=head3 Junctions

Junctions are, I think, basic value types. They can have methods, which
suggests that they can be subclassed. If a method call is invoked on a
junction, the dispatcher first considers whether the method is a method of
the particular junction (or a parent class). If so, fine. If not, however,
the junction will I<distribute the call> across its states.

This is fascinating, since it suggests either Big Magic in the junction
implementation, or that classes may have an .AUTOLOAD method or some such,
which is invoked when no obvious method is available. (The performance
impact of this should be obvious, and frightening. Full on method searches
can be expensive. Adding AUTOLOAD moreso.)

=head3 Automatic invocation

The use of the colon after invocants may be optional for single-argument
method calls. The notion of

close $fh:;

disturbs and offends. The suggestion is that $fh.close would be invoked if
no sub (or multi?) were available.

=head3 Value-based (multi) dispatch

There have been several calls for value-based dispatch, all apparently
influenced by an EEEVIL C++ trick involving, well, EEEVIL. While @Larry have
consistently denied these requests, I suspect they'll wind up including them
sooner or later, because (1) it's a cheap hack; and (2) requiring bad coding
isn't the Right Thing(tm).

However, allowing value-based method dispatch is akin to allowing method
multidispatch. 'Ware 'gators!

=head3 Weird Dispatch

There's talk of a "wa" operator (forwhich), sort of the opposite of C<given>
in a bunch of ways. The idea is that it would enable reversing the argument
list from the method name, as in:

($a, $b, $c) forwhich foo();

Alternatively:

given \($a, $b, $c) { foo(*$_); }

This is vaguely reminiscent of the pipeline operators from A6, but with a
different context, I suppose.

I wonder if this sort of magic isn't related to the pointy-block notation
and zip:

zip $a, $b, $c -> &foo;

=head3 Basic rules of Dispatch

Methods are dispatched based on their (single) invocant and its run-time
type. Disagreement between passed and declared arguments is an error.

Submethods likewise, save that a submethod is not inherited, so does not
participate in the dispatch search of subclasses.

Multimethods have multiple invocants, indicated with the colon in the
signature. No colon implies all the arguments are invocants. The list of
types associated with the invocants determines which multimethod is invoked.
Damian will probably devote one or more chapters of his next book to
describing the algorithm for this. :)

=head3 More rules of dispatch - complex types

Complex types can be used for dispatch. All the conversion/casting
discussion from L<Types>, above, apply -- somehow. May God have mercy on our
souls.

=head3 Foggy rules of dispatch - untyped vs. typed

Damian has suggested that an untyped scalar would fail if passed to a typed
parameter. Larry has expressed concern about the typed/untyped interface.
Stay tuned.

=head3 More rules of dispatch - isa and can

Multimethod dispatch will use C<isa> to determine type compatibility. This
is a rather direct refutation of interface-based compatibility, but it was
made before the issue officially came up.

There has been some talk of using C<can> for similar purposes.

It may be that there is value in allowing C<can> as a mixin specifier as
well - it would imply public interface but not private data. This dates way
back, but still seems to have merit.

class Zero {
multi *isa ($obj, Zero $class) { $obj ~~ 0 }
}

# and then...

multi factorial (Int&Zero $g) { 1 }

=head3 Parameterized Types

Apparently, this strikes fear into the hearts of some section of the team.
Woe is us - to be laughed at by C++ lusers.


=head2 Namespaces

=head3 Special modifier '*'

Star in method context ($a.*id) is short for $a.Object::id -
root-of-method-inheritance. On the other hand, $*foo is short for
$Global::foo (for some value of "Global").

=head3 Routine existence

Long ago the suggestion was made that you might test for Routine existence
with the exists keyword, either as a function or as a method.

exists &Main::foo
&Main::foo.exists

=head3 C<.can>

C<.can> may have a slightly different meaning in this context, suggesting
that it is scope-aware - that is, &Main.can would ask "were I in the scope
of Main, could I meaningfully invoke this thing?" including outer
namespaces.

=head3 C<.can> and multimethods

It's not clear what .can should return for a multimethod, either. One
alternative was an enumeration of the signatures. Another would be a
hypothetical-call operation - do all the type/method lookup and
coercion/conversion mapping, but don't implement any side-effects and don't
transfer control.

if (foo.can()).assuming($a = 1, $b = 2) { # assuming, anyone?
print "Can do, sir!\n";
}

Good grief.

On the optimistic side, Larry was heard to say "Sort of what a try block
would like to be when it grows up", suggesting that transaction/rollback for
side effects is just the beginning of his breathtaking vision on this
subject.

Stay tuned.


=head2 Syntax

=head3 Class declaration

# Value type
class Person {
has $.age;
has $.dob;
has $.gender;
has $.idnum;
has $.name is public; # Generates an accessor

state $census = 0; # Class variable

# Class methods (& rule!)

rule ssn { \d<3>-\d<2>\d<4> }
sub check_idnum($n) { $n =~ /<ssn>/; }
sub check_date($d) { $d =~ /<Perl6::Rules::GenericDate>/; }

method new($class:
Str $.name,
Str $.gender,
Num ?$.age is default(0),
Str ?$.idnum) {

++ $census;
print "A $.gender child is born!\n"
unless $.age;

$.dob = Date::Today()
unless $.age;

# I don't think bless is required anymore, but if so
# it's a class method.
}

method operator:+($self) { return $.age; }
method operator:?($self) { return $.gender; }
method operator:~($self) { return $.name; }

# Autogenerated by "is public", above.
# method name is rw { return $.name; }

method dob(?$bday) {
if ($bday) {
die "Can't change your birthday!" if $.dob;
die "Bad date format" unless check_date($bday);
$.dob = $bday;
}
$.dob;
}
}

# Variable type
class AppOnlyArray is Array {
method STORE(int $index, $value) {
fail "Can't modify existing element" if $index < .length;
.SUPER::STORE($index, $value);
}
}

=head3 Declaration of Variables

my Person @Acquaintances is AppOnlyArray;

my $input_format = / <name> <gender> [<age> <idnum>?]? /;

while <> {
@Acquaintances.push(m $input_format);
}


Michael Lazzaro

unread,
Apr 23, 2003, 12:32:46 PM4/23/03
to Austin Hastings, Perl6 Language

On Tuesday, April 22, 2003, at 09:14 PM, Austin Hastings wrote:
> I've gone into the wayback machine (about 2 years) for some of this
> stuff,
> including a post from Damian that answered most of the questions asked
> last
> week :( Shame I couldn't remember it before starting to write this.

Very, very cool; thanks. It goes well with our ongoing
"discussion"[1]. Mind you, I'm a bit concerned about how many
questions it still raises... :-/

MikeL

[1] discussion: n. 1. A state of verbose panic. 2. An argument, but
with more important sounding words interspersed throughout.

Michael Lazzaro

unread,
Apr 23, 2003, 2:10:56 PM4/23/03
to Austin Hastings, Perl6 Language

A few comments... Again, I've only commented where I think things have
really, really been set in stone, so if I'm wrong on _anything_ I say,
I'd like to know, because it will daisy-chain through quite a lot of
other assertions I have.


On Tuesday, April 22, 2003, at 09:14 PM, Austin Hastings wrote:

> =head3 Pair Type
>
> There's a Pair type in some of Damian's messages. I hadn't really paid
> attention before, but the implication seems to be that (1) it's a
> built-in;
> and (2) it may well be the default return type of a hash in list
> context.
> Well, it surprised me, anyway. You got this, MikeL?
>
> sub draw_triangle ( Point|Pair $a is copy,
> Point|Pair $b is copy,
> Point|Pair $c is copy) {
> when Pair {$_ = Point.new(.key,.value)} for $a, $b, $c;
> ...
> }

Yep, pretty sure that's been confirmed. A hash is an unordered list of
Pairs. The Pair constructor is the C<=>> operator:

$k, $v; # a list of two elements
$k => $v; # a single Pair consisting of two elements.

Details on how pairs work in various contexts are a little fuzzy, but
they probably can be inferred fairly easily.


> =head3 Everything is an object
>
> First, everything's an object. Or, according to Dan, nothing's an
> object.
> The point is that object access will no longer be via an indirect ref
> or
> whatever.
>
> Instead, object methods get invoked as $object.method. In keeping with
> the
> philosophy, however, there's an awful lot of stuff that is being
> described
> in object terms: File Handles, Arrays, Hashes, Various 'Magic' system
> things
> (e.g., C<caller>), and the Perl6 parser itself. (Arrays, at minimum
> "cannot
> be discerned from objects.")

"Everything will appear to be an object, in that you can call methods
on it" was definitely confirmed. Whether things like C<Str> are
internally implemented as 'real' objects is unknown and probably
irrelevant; they cannot be discerned from objects, and they can be
subclassed as if they were objects.

(Except the lowercase primitives like C<str>, C<int>... you have to use
C<Str>, C<Int>, etc. if you want to subclass them.)


> =head3 Everything has methods
>
> Everything, as far as I can tell, will support the .id method. This
> includes
> the "small" types - int, num, str - as well as "first class" objects.

I don't think this was decided, was it? Last I remember, there was
disagreement over what to call it -- some people were begging for
C<.identity>, since C<.id> is a very, very commonly used method name in
most programming, and they don't want it to conflict. (And other
people didn't want it at all, because it allowed the programmer to do
Stupid Things to themselves.)

It is true, however, that everything "appears" to have methods, even
primitives like C<int> and C<str>, probably via magic. So you can say:

my str $s = 'blah';
$s.chars; # or whatever 'length' is called


> =head4 Explicit Conversion
>
> Explicit coercion (& conversion, for that matter) has been described as
> using the target type name as a subroutine name. Thus int() -> int,
> Foo() ->
> Foo, etc.

Yes, but... personally, I have big namespace worries about this... that
doing it that way (putting every possible conversion type in the normal
'method' namespace, e.g. C<$string.int>, etc., will create much more
polluted namespaces than if we required an explicit conversion
"operator" such as C<$s as int> or C<$s to int>.


> =head5 Automatic Widening Coercion
>
> No one has had anything negative to say about automatic widening
> coercions
> on inheritance-based superclasses. Noone has had anything whatsoever
> to say
> about automatic widening coercion on mixin-/interface- based
> superclasses.

I recall that some people do see a need for a way to explicitly
_forbid_ widening... I believe this was what the C<dammit> operator was
proposed to do?


> =head5 Automatic Lossy Conversion
>
> No one has commented on whether a Num/Float type can be assigned into
> an Int
> type without harassment. In this case, I suspect the explicit C<$i =
> Int($f);> won't cause the peasants to revolt under C<use strict>.
>
> On the other hand, there's only Larry's inclination towards "keeping
> the
> entry ramp low" to suggest that it will work when strict is not in
> effect.

We really, really need a matrix of what can be autoconverted to what,
and which of those may be lossy, if anyone's working on that...

MikeL

Austin Hastings

unread,
Apr 23, 2003, 2:16:11 PM4/23/03
to Michael Lazzaro, Perl6 Language

Breaking this out so as to avoid the dreaded "multiple questions"
thread.

I used to believe this, but the interaction between the "efficient
storage" and "variable types" is too intriguing to let go by.

Given that "int" versus "Int" is primarily a stowage preference, why
shouldn't I be able to subtype it?

class IO_Port is int {
method new($address) {...}
}

Likewise, in Paul's example earlier today of mapping 'C' structs to
Perl6, I can see wanting to say:

class NativeBuffer is Array of char {
method new($address, $length) {...}
}

One of the reasons for the "small" types was to enable the Perl ->
native interface. Subtyping seems a natural way to support that.

=Austin

Austin Hastings

unread,
Apr 23, 2003, 2:21:33 PM4/23/03
to Michael Lazzaro, Perl6 Language

--- Michael Lazzaro <mlaz...@cognitivity.com> wrote:
>> > =head3 Everything has methods
> >
> > Everything, as far as I can tell, will support the .id method. This
> > includes the "small" types - int, num, str - as well as "first
> > class" objects.
>
> I don't think this was decided, was it? Last I remember, there was
> disagreement over what to call it -- some people were begging for
> C<.identity>, since C<.id> is a very, very commonly used method name
> in most programming, and they don't want it to conflict. (And other
> people didn't want it at all, because it allowed the programmer to do
> Stupid Things to themselves.)

I didn't investigate exhaustively, but I saw some posts from Larry that
seemed to nod in the direction of objects whose .id method was
overridden for some local purpose. Specifically, the commentary about
being able to use $object.*id to get the "official" id method seemed to
suggest that (1) you can override it if you want; but (2) we're using
it.

It really doesn't matter to me or the document-- I was using C<.id> as
an example of a method that every "object" has. If it's called
C<.show_me_your_papers>, it's still ubiquitous.

> It is true, however, that everything "appears" to have methods, even
> primitives like C<int> and C<str>, probably via magic. So you can
> say:
>
> my str $s = 'blah';
> $s.chars; # or whatever 'length' is called
>

Which is what I was trying to illustrate.

=Austin

Austin Hastings

unread,
Apr 23, 2003, 2:33:31 PM4/23/03
to Michael Lazzaro, Perl6 Language

--- Michael Lazzaro <mlaz...@cognitivity.com> wrote:
> > =head4 Explicit Conversion
> >
> > Explicit coercion (& conversion, for that matter) has been
> > described as using the target type name as a subroutine name.
> > Thus int() -> int, Foo() -> Foo, etc.
>
> Yes, but... personally, I have big namespace worries about this...
> that doing it that way (putting every possible conversion type in
> the normal 'method' namespace, e.g. C<$string.int>, etc., will
> create much more polluted namespaces than if we required an
> explicit conversion "operator" such as C<$s as int> or C<$s to int>.

Worse, what happens when we try to use an anonymous, possibly
auto-generated, class as a conversion step. (Example: Java frequently
has anonymous classes created for implementing "Listener"
functionality. Read any book about Mouse Events.)

In this case, C<$evt as CLASS> or C<$evt as typeof($self)> is much more
accessible than C<(CLASS)($evt)> or C<typeof($self)($evt)>.

Ugh!

> > =head5 Automatic Widening Coercion
> >
> > No one has had anything negative to say about automatic widening
> > coercions on inheritance-based superclasses. Noone has had anything
> > whatsoever to say about automatic widening coercion on mixin-
> > /interface- based superclasses.
>
> I recall that some people do see a need for a way to explicitly
> _forbid_ widening... I believe this was what the C<dammit> operator
> was proposed to do?

I'm the one who proposed it, and I was trying to force acceptance of a
narrowing cast.

my Car $c = new Vehicle: $transporter # dammit

This probably fails under strict (Car isa Vehicle, not Vehicle isa Car)
but if you "know" that the program flow is designed to only store
Car-type parameters in $transporter at this point, you should be able
to notify the compiler of that somehow, or at least suppress the
warning.

> > =head5 Automatic Lossy Conversion
> >
> > No one has commented on whether a Num/Float type can be assigned
> > into an Int type without harassment. In this case, I suspect the
> > explicit C<$i = Int($f);> won't cause the peasants to revolt under
> > C<use strict>.
> >
> > On the other hand, there's only Larry's inclination towards
> > "keeping the entry ramp low" to suggest that it will work when
> > strict is not in effect.
>
> We really, really need a matrix of what can be autoconverted to what,
> and which of those may be lossy, if anyone's working on that...

Isn't that a p6d task? Are you there yet?

=Austin

Michael Lazzaro

unread,
Apr 23, 2003, 3:21:05 PM4/23/03
to Austin_...@yahoo.com, Perl6 Language

Yes, it is and we are -- but it all hinges on how autocoercions work.
We can document something, but only when it's decided enough to
document. :-P

In fact, *every* section I've tried to write in the last 3 months has
been dependent on how types and autocoercions work, and the
still-wiggly difference between 'primitive' (lowercase) and 'promoted'
(uppercase) types. A6 solved the majority of those problems... the
type-related threads I started here are my attempt to get the last bits
of information I need.

I'll give a shot at a preliminary matrix: These are what conversions
are _POSSIBLE_ to make automatic, not which ones _ARE_ automatic.
That's what we need to decide.

+: Automatic conversion, conversion is not lossy
L: Lossy... possible, but not automatic?

FROM -> str Str int Int num Num bit Bit bool Bool
TO: str - L + L + L + L + L
Str + - + + + + + + + +
int L L - L L L + L + L
Int L L + L L L + + + +
num L L + + - L + L + L
Num L L + + + - + + + +
bit L L L L L L - L + L
Bit L L L L L L + - + +
bool L L L L L L + L - L
Bool L L L L L L + + + -

Everything marked with an 'L' is a decision that needs to be made... do
we accept a lossy (automatic) conversion, or report it as an error?

The ref,Ref,Array,Hash types have some autoconversions, too.
The Code,Package,Grammar types I'm thinking don't autoconvert at all.

MikeL

Uri Guttman

unread,
Apr 23, 2003, 5:42:15 PM4/23/03
to Michael Lazzaro, Austin_...@yahoo.com, Perl6 Language
>>>>> "ML" == Michael Lazzaro <mlaz...@cognitivity.com> writes:

ML> +: Automatic conversion, conversion is not lossy
ML> L: Lossy... possible, but not automatic?

ML> FROM -> str Str int Int num Num bit Bit bool Bool
ML> TO: str - L + L + L + L + L
ML> Str + - + + + + + + + +
ML> int L L - L L L + L + L
ML> Int L L + L L L + + + +
ML> num L L + + - L + L + L
ML> Num L L + + + - + + + +
ML> bit L L L L L L - L + L
ML> Bit L L L L L L + - + +
ML> bool L L L L L L + L - L
ML> Bool L L L L L L + + + -

i assume bit is a single bit and not a bit string. PL/I supported bit
strings and i wrote the library (in c) for its conversions for all of
its types (about 13 of them) and you don't want to redo that!

and bit strings were not portable as it used the machine format of the
original data.

ML> Everything marked with an 'L' is a decision that needs to be
ML> made... do we accept a lossy (automatic) conversion, or report it as
ML> an error?

PL/I did some lossy conversions but they followed the ANSI book on
it. and in some cases it was platform dependent which really is nasty
(see bit string above).

one area you missed is big int/float. they won't be builtin but they
might/will be converted to when Ints/Nums get too big or too many
digits. they may need to be declared by the user but they will act like
Int/Num in most cases. prolly a tied class or something similar. parrot
will have builtin support for some version of that. other versions can
be plugged in. i did a full decimal math package for PL/I too.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

0 new messages