Perl-Apollo / Corinna

Corinna - Bring Modern OO to the Core of Perl
Artistic License 2.0
157 stars 19 forks source link

Type System #21

Closed Ovid closed 3 years ago

Ovid commented 4 years ago

Use this ticket to leave feedback for the Type System document.

wollmers commented 4 years ago

Don't forget unsigned integers. In most languages it's tricky to force them if needed e.g. for bit fiddeling.

In current Perl 5 (AFAIK 5.10 to 5.32) it needs the following:

### get the width of an integer in bits without loading the heavy Config.pm.
our $width = int 0.999+log(~0)/log(2);

use integer;
no warnings 'portable'; # for 0xffffffffffffffff
moritz commented 4 years ago

Another consideration is structural vs. nominal typing.

In a nominal type system (using Raku notation, because I'm familiar with it), you cannot assign [1, 2, 3] to a parameter declared Int @a, because [1, 2, 3] is just Array, notArray[Int]`.

On the other hand, in a nominal type system, you can declare class UUID is Str { ... } and class PersonName is Str { ... }, and that prevents you from accidentally assigning a name to a UUID and vice versa, even though structurally they are both stored as strings.

TypeScript has had great success adding structural, compile-time only types to Javascript, which indicates it might be a good fit for retrofitting a type system onto a previously "untyped" language; but TBH I'm not familiar enough with that to judge if Perl 7+ could copy that approach.

moritz commented 4 years ago

(I'm leaving separate comments for separate pieces of feedback on the wiki page, hope that simplifies things compared to one big comment blob)

Regarding generics: I could totally live with a first version of a type system that doesn't handle generics at all, though I guess people will compare that to what Moose supports now, and loudly complain.

Coming up with a good type system that works with generics tends to be really hard though (just look at Java, Go, C++), so another option would be to cheat like Go does, and allow generics for built-in types only (Array[Int], Hash[Point]). Given the prevalence of arrays and hashes in Perl code, this could be acceptable 80/20 solution.

moritz commented 4 years ago

Thinking more about what classes of bugs a type system can prevent, there's one that annoys me at least once per week that Perl currently gets wrong and every[tm] other language gets right (I'm sure somebody will point out TCL now...):

Producing correct JSON is way too hard right now in Perl.

JSON distinguishes integers, floats, strings and booleans, and for Perl those are all just scalars. At work we use json schema to validate messages exchanged between services, and that makes me acutely aware of every time a Perl service produces something unexpected.

The two most common pitfalls for me are:

Not having proper booleans is also annoying, though manageable through explicit JSON::XS::true conversions or using the ´\0and\1` hack.

I don't know if this is in scope for the Cor type system to fix, but I sure hope something fixes it eventually :-)

wollmers commented 4 years ago

On the other hand, in a nominal type system, you can declare class UUID is Str { ... } and class PersonName is Str { ... }, and that prevents you from accidentally assigning a name to a UUID and vice versa, even though structurally they are both stored as strings.

Good examples. In text or language processing I typically define (via Unicode properties):

Ovid commented 4 years ago

@moritz wrote:

Producing correct JSON is way too hard right now in Perl.

This is an old, old problem. I have had to deal with too much hell in the past from SOAP getting types wrong, too. Basically, if Perl has to interoperate with another system where "type" information is conveyed, it's a nightmare. SOAP, JSON, XML, and so on. It makes Perl look buggy and error-prone (because both are true in this context) to those who interoperate with the language.

anjohnson commented 4 years ago

One thing that :isa(*) does which leaving if off doesn’t is fix the type of what’s stored in the variable, so the compiler and/or runtime can catch any later attempt to assign something that isn’t a bike to it. I think that makes it worth including.

robrwo commented 3 years ago

I think adding a type system to Perl is worth a separate parallel process. It would be nice to add type signatures to perl functions and methods in general (with a later enhancement to enable static type checking in lexical scope via a pragma).

Ovid commented 3 years ago

Closing this because it's out of scope of V1 and impacts far more than just Corinna.