develooper Front page | perl.perl5.porters | Postings from July 2020

Re: Types in Cor (and Perl)

Thread Previous | Thread Next
From:
Leon Timmermans
Date:
July 13, 2020 08:48
Subject:
Re: Types in Cor (and Perl)
Message ID:
CAHhgV8iOtz7N2K-qPnQ-2yqQZR_zB_ua=iRFjVS9F0kUauCSFA@mail.gmail.com
On Sun, Jul 12, 2020 at 3:05 PM Ovid via perl5-porters
<perl5-porters@perl.org> wrote:
>
> Hi all (directly copying Dave as this could impact his signature work),
>
> This might seem premature give that Perl 7 is still being actively discussed, but I'm hitting a stumbling block in Cor's design regarding types. (I assume types cannot be implemented in the first release unless we steal from Types::Standard and friends). For quite some time, I've had things like this in my examples:
>
> has $foo :isa(Int);
>
>
> However, I know that Dave Mitchell is working on signatures and he's looking at types too. If we have types in signatures and types in Cor, we're eventually going to get to the point of someone expecting this to work:
>
> my $foo :isa(Int);
>
>
> In other words, Perl will support gradual typing with all of the lovely safety that so many of us crave (or maybe just I do?)
>
> However, we have both syntax and semantic issues. Dave's proposal (https://www.nntp.perl.org/group/perl.perl5.porters/2019/11/msg256683.html) looks very clear and, given that it predates Cor, it's not surprising that his syntax is different from Cor's syntax. If Perl is going to have types, we do not want different syntax for signatures, variable declarations, and class slot declarations.
>
> The reason Cor uses attributes is because the has declarator, unlike in Moo/se, only declares the instance variable. It does nothing else. All other behaviors are provided via attributes and those attributes are almost fully composable (I've tried hard to decouple everything). For example, a 2D Point class that allows you to read and write the x/y data looks like this:
>
> class Point {
>     has ( $x, $y ) :reader :writer :new :isa(Num);
>
>     method invert () {
>         return Point->new( x => $y, y => $x );
>     }
> }
>
>
> Attributes are very familiar to Perl developers and it seemed an easy  way to extend things. Going with Dave's proposal, I'd have to do this:
>
> has ( $x, $y ) :reader :writer :new is Num;
>
>
> I find that a touch jarring, but I could live with it. Whatever syntax we go with, it needs to be nailed down so design work can continue.
>
> That brings me to semantics.
>
> I've been doing a moderate amount of reading about type systems and one thing that stands out is that bolting type systems onto languages without "traditional" type systems is hard. While I've opened a ticket about this, I think it would be particularly helpful if people were to read a follow-up comment about what types would mean in Perl. The summary: Perl's behavior, absent types, should not change. Perl's behavior, with types, should provide a sound type system and not try to emulate Perl's behavior. (you can throw rotten tomatoes at me now).
>
> I know very little of Perl's internals or what this would mean. For Cor V1, I'd be tempted to go with attributes and Types::Standard (:isa(ArrayRef[Int])), but I strongly suspect that it will conflict with David's work, and it won't provide the type safety one would expect.
>
> If there are strong counter-arguments, I'd be delighted to say I was wrong.
>
> Best,
> Ovid

There are (at least) three kinds of type system like things that you
could want. And before we continue this discussion it is probably
important to specify exactly what we're trying to achieve here.

1. Input/output validation.

This is achievable right now without major modification to the
implementation as it is "just" syntax smithing around things that are
already possible. Essentially this is what Dave proposed.

2. Typed values.

As far as I know there are four kinds of scalar values visible in user
code (but I'm half expecting someone to point out we have another
obscure one that I forgot):
a. References. We all know these. These can be divided further into
blessed into various packages.
b. Undefined. This speaks for itself.
c. Regexp. This is actually always hidden behind a reference (I think
since 5.12), so you probably should also pretend these don't exist. I
don't really think we are guaranteeing they will keep existing in this
way in the future anyway.
d. Fakeglobs. These are fairly esoteric and generally considered a bad
thing. If you don't know what I'm talking about, you may want to keep
it that way.
e. Primitives (stringy, numeric, wibbly wobbly).

So essentially, the scalar type system is "reference, undef or other".
Further typing of references is mostly obvious and undefs don't have
further typing, but primitives are not so simple. As far as the
implementation is concerned we don't have a concept of "the type of
this is integer". Any integer concept would be subsetting, e.g. "It's
an other, that looks like a number". Changing that at this stage would
be difficult as both pure-perl code and xs have been making
assumptions about that for 30 years.

Typed primitive types are a quagmire, but without primitives it seems
of limited use.

3. Typed variables.

We don't have much of a concept of a variable as separate from a value
(the way Raku has with its containers), not in the last place because
values are mutable unless they're not. This does make it quite a bit
harder to have anything like typed variables. All the solutions I can
think up for that are terrible and break really quickly.

Quite frankly anything other than option 1 seems like a massive undertaking.

Leon





Leon

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About