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

coercion and context

6 views
Skip to first unread message

Juerd

unread,
Sep 14, 2005, 5:38:04 PM9/14/05
to perl6-l...@perl.org
I was asked to { Verb 'p6l' } the idea of types providing context, and
well, here it is.

(We got at these thoughts from a discussion of a hypothetic lexical pragma
to disable automatic coercion, which I thought was a bad idea because
that's practically to ignore context, Perl's strongest language feature
(imo). Instead, if you don't want something to coerce, be explicit:
$foo.does(Blah) or fail;, or even: $foo.isa(Blah) or fail;.)

Some types can coerce into eachother. This happens transparently because
of context. The simplest example I can think of is a Num, that in Int
context is coerced to an int. Lossily, but that's not my point right
now.

my Int $int = $num;

Explicit coercion, however, isn't done with context: it is done with the
.as() method: $num.as(Int). I think that's weird.

Why not see "bare" types as functions that create context? We'd then
have Int $num, Int($num), and automatically, $num.Int. All are easy to
recognise because of the capital I.

Is this weird syntax? Perhaps so, but we've known it from undef for
ages. undef without arguments is just undef, but when you give it
arguments, it suddenly actually *does* something.

undef($foo) makes $foo undef, undef() just returns undef.

Compare with:

Int($foo) makes $foo Int, Int() just returns ::Int.

Of course, for this comparison to work, undef would have to be a type.
Which makes having interisting undefs easier: they'd be parametrized
types. And undef could simply provide undef context, in which every
scalar coerces to... undef. But mutating, of course. I don't think it
would be a problem to have undef be a little special. ucfirst Undef
could be a non-mutating form, if consistency here is important.

Miscellaneous remarks:

- There would no longer be a need for int(), as Int() suffices. I'm
assuming that you only get to have a system native value in a typed
variable.

- The reason for having both Scalar() and item() is that Scalar()
coerces: afterwards, a Num is no longer a Num.

- We agreed that there have to be two ways (at least) to test for
ability to coerce, as this can happen lossily and losslessly. Thinks
like $foo.canbe(Int) and $foo.fitsin(Int) came to mind, but single word
method names are probably better, if only someone can think of any.


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Luke Palmer

unread,
Sep 14, 2005, 6:21:12 PM9/14/05
to Juerd, perl6-l...@perl.org
On 9/14/05, Juerd <ju...@convolution.nl> wrote:
> Instead, if you don't want something to coerce, be explicit:
> $foo.does(Blah) or fail;, or even: $foo.isa(Blah) or fail;.)

We've been thinking of changing .isa to something longer, or a method
on .meta, because it's a notion that is often misused. Use .does
instead; that's what you mean anyway (unless you're snooping around
the guts of an object).

> my Int $int = $num;
>
> Explicit coercion, however, isn't done with context: it is done with the
> .as() method: $num.as(Int). I think that's weird.

Not to mention the fact that you might have put an Int there for
typechecking purposes instead of coersion purposes, and you actually
want it to die if $num is a string. Hmmm, how do we get both at once?

> Why not see "bare" types as functions that create context? We'd then
> have Int $num, Int($num), and automatically, $num.Int. All are easy to
> recognise because of the capital I.

You realize that those functions would all be the identity map with
various expectations on their input. That's okay, it's just an
interesting notion.

> Is this weird syntax? Perhaps so, but we've known it from undef for
> ages. undef without arguments is just undef, but when you give it
> arguments, it suddenly actually *does* something.
>
> undef($foo) makes $foo undef, undef() just returns undef.

Except we changed that because it was biting people:

undef is null-ary and represents the undefined value; undef $foo is illegal
undefine($foo) is mandatory unary, and always undefines its argument

> Compare with:
>
> Int($foo) makes $foo Int, Int() just returns ::Int.

That bugs me a little. But it's a bug I could get used to pretty
quickly I reckon.

I just wonder what kind of role coercion plays in the larger scheme of
things. Does coercing to a Str work with anything that has a
stringify operation (conversely, is ~ just a Str context applicator?)?
If a parent class defines a coercion operation, do you get it too
(and what are the implications of that)? What role does coercion play
in multimethod dispatch?

I can't seem to map the notion of coercion into my world model, so I'd
personally like to see a proposal that covers these questions from
someone who can map it into his world model. I'll bash it to pieces
of course, but it'd be good to have somewhere to start. :-)

Luke

Juerd

unread,
Sep 14, 2005, 6:28:34 PM9/14/05
to Luke Palmer, perl6-l...@perl.org
Luke Palmer skribis 2005-09-14 22:21 (+0000):

> (conversely, is ~ just a Str context applicator?)?

Yes, the way I think of it is that ~ is short for Str(), + is short for
Num(), and ? is short for Bool().

> If a parent class defines a coercion operation, do you get it too
> (and what are the implications of that)? What role does coercion play
> in multimethod dispatch?

Good questions. Relevant regardless of coercion syntax. I have no idea.

Dave Rolsky

unread,
Sep 14, 2005, 11:19:19 PM9/14/05
to perl6-l...@perl.org
On Wed, 14 Sep 2005, Luke Palmer wrote:

>> my Int $int = $num;
>>
>> Explicit coercion, however, isn't done with context: it is done with the
>> .as() method: $num.as(Int). I think that's weird.
>
> Not to mention the fact that you might have put an Int there for
> typechecking purposes instead of coersion purposes, and you actually
> want it to die if $num is a string. Hmmm, how do we get both at once?

My 2 cents ...

Coercion and typechecking need to be fairly distinguishable for reading
and writing code, as they're very different things.

I for one like "my Int $int" as type checking, meaning it'll die if not
given an int, and some sort of method/function for coercion, presumably
the above-mentioned "as(Int)".

The default should be type-checking is always strict, and coercion is
never automatic, IMO. Otherwise it's just not that useful, because you
always have to remember the various auto-coercion rules.

Of course, for people who think that's "intuititive", there could be some
sort of "use coercion" pragma, maybe something like:

use coercion Num => Int uses .int,
String => Int uses .numerify_if_looks_like_number,
Date => String uses .date;

Of course I'm pulling the syntax/API from my nether regions.


-dave

/*===================================================
VegGuide.Org www.BookIRead.com
Your guide to all that's veg. My book blog
===================================================*/

0 new messages