Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I am an XP whore and if I reply multiple times, I'll get more XP. So have more thoughts.

Point Class

Your Perl version of the Point class can be simplified a lot using the features of existing modern versions of Perl.

use v5.20; use experimental 'signatures'; package Point { sub new ($class, $x, $y) { bless [$x, $y] => $class; } sub x ($self) { $self->[0] } sub y ($self) { $self->[1] } sub inverted ($self) { ref($self)->new($self->y, $self->x); } }

Yeah, I cheated by making x and y read only, but dammit they should be read only. If they change, it's a different point, so you should make a different object.

Incidentally, making them read only makes the implementation simpler in Perl, but harder in the other languages you gave examples for.

Type Checking in Core

As for type checking in core, there's already parser support for:

my Foo $foo = Foo->new(...);

However, other than checking that a package "Foo" exists, core Perl doesn't do anything with that.

I think the best route for adding decent type support to Perl would be:

  1. Provide an API which allows a type library module to define types such as my Str $x where Str isn't a package name and $x would be a plain old string not a blessed reference. These should be scoped (either lexically or by package).

    If you try to use a type which hasn't been declared for lexical scope, Perl assumes you meant it as a class name.

    I'll provide an outline of a simple and perhaps workable API below.

  2. Bundle a module with core which defines a bunch of predefined types. Perhaps automatically load it if a recent enough use VERSION line is given.

    Including the following in the core set of types shouldn't be controversial because they conform roughly to the existing types Perl kinda exposes to end users already.

    • All the standard ref types: "ArrayRef", "HashRef", "ScalarRef", "CodeRef", "GlobRef", "RegexpRef", etc.
    • The types of value that can be stored in an SV: "Int", "UInt", "Num", "Str".
    • "Defined" and "Blessed".

    Having a type called "Undef" would probably be non-controversial, but it's also pretty useless to declare a variable which will be undef and which will always be undef.

    There are loads of other types which are often handy, like "PositiveNum" but which seem likely to end up in bikeshedding. (For example, should "PositiveNum" include zero because that's more useful in most cases, even if zero isn't strictly positive. Should it be called "UNum" for consistency with "UInt", even though the former isn't a well-established name like the latter is, and "Unum" is Latin for "one" in the accusative form. Should it accept overloaded objects? Et cetera.)

    To avoid such bikeshedding, plus to allow people to define their own useful application-specific type constraints, I think the core set of types should be kept small and non-controversial, with the API mentioned above being used to define other types.

  3. Allow these types to also be used in sub signatures.

    sub foo (Int $bar, Str $baz) { ...; }

    Would be roughly equivalent to:

    sub foo { my Int $bar = $_[0]; my Str $baz = $_[1]; die "..." if @_ > 2; ...; }

Sketch of an API for Pluggable Types

If Perl encounters:

my Foo $x = $y;

It should interpret "Foo" much the same way it would in the case of Foo->new(). That is, if there's a Foo sub, Perl should treat it as Foo(). If there's no "Foo" sub, then "Foo" is treated as a package name (string). Perl would make this decision based on whether the Foo sub existed at compile time.

After that, any time a value is assigned to $x, then one of the following happens:

"Foo"->CHECK_SCALAR(\$newvalue); Foo()->CHECK_SCALAR(\$newvalue);

I'm naming the method CHECK_SCALAR instead of just CHECK to allow for it to possibly be extended to arrays and hashes. Passing the value by reference for added efficiency, and because checking arrays and hashes will likely require passing a reference anyway.

This would be the basic API for creating user-defined types. There should probably also be an XS API which would allow a value to be checked via a single xsub call rather than all that method dispatch stuff. The basic type library bundled with core would make use of the XS API, because I'm pretty sure we don't want using the most basic type checks in signatures to slow down our code very much.

Oh yeah, and also:

sub UNIVERSAL::CHECK_SCALAR (Str $class, ScalarRef $sref) { require Scalar::Util; unless (Scalar::Util::blessed($$sref) && ${$sref}->isa($class)) { require Carp; Carp::croak("..."); } }

In reply to Re: Recap: The Future of Perl 5 by tobyink
in thread Recap: The Future of Perl 5 by Ovid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2024-04-19 21:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found