use types YAPC::US 2011
Author: rurban

# use types;

YAPC::US 2011

rurban - Reini Urban
`vienna.pm`, `houston.pm`

# Outline

- Status Quo: CORE types

  `my TYPE $i; my My::Class $o;`
  `Declaration only. package TYPE must exist`

- Artur Bergman's types module

  `Declare and check type safety. int, double, number, string. params and return values.`

- Optimizations planned for 5.16

  `smaller and faster, ensured at compile-time. typed arrays + hashes, perfect hashes, fast method calls, type declarations via class and attributes, fix types.`

# Who am I

rurban active in p5p since 1995.

maintains cygwin perl since 5.8.8 and 3-4 modules: illguts, B::* => 5.10, mainly the "compiler".

In the future a lot more time for the compiler and CORE.

I'm known as the BAD guy on p5p who started fighting with Nick. Sorry about that. Sometimes I'm just arrogant and stupid, but unfortunately not as funny as Matt.

# Perl's Type System

Yes, the language already has one.

my int $var; # or our
# my :attribs are not known at compile-time, only our.
$ perl -cw -e'package int; package main; our int $i:const;'
Invalid SCALAR attribute: const at -e line 1
$ perl -cw -e'package int; package main; my int $i:const;'
-e syntax OK
sub name (proto) {} => proto: &name->pv

# Perl's Type System

Yes, the language already has one. CORE:

my TYPE $var;
sub name (proto) {} => proto: &name->pv

Only a few out-of-CORE implementations:

Moose, fields, types, typesafety, Lexical::Types

Params: `Devel::Declare`, `Params::Validate`, `Params::Classify`
Objects: `Class::Meta`, `Moose`

# Perl's Type System

At first a look CORE types, not the language:

SCALAR (non-strict, VB-like): IV, NV, UV, PV, ...

ARRAY (non-strict): AV

HASH (non-strict): HV

Objects ("stashes", @ISA, declaration)

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

multiple types (IV,NV,PV) per variable, context dependent.

internally upgraded: IV => PVIV => PVNV

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

multiple types (IV,NV,PV) per variable, context dependent.

IV: integer

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

multiple types (IV,NV,PV) per variable, context dependent.

IV - integer unblessed, untied

=>

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

multiple types (IV,NV,PV) per variable, context dependent.

internally upgraded: IV => NV

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

multiple types (IV,NV,PV) per variable, context dependent.

internally upgraded: IV => NV => PVNV

# Perl's Type System - SCALAR

SCALAR (non-strict, VB-like)

internally upgraded: IV => PVIV => PVNV => "Objects" => Tie

# Perl's Type System - SCALAR

"STASH" - Hierarchical symbol table,
used as package name for Objects. i.e. "Class pointer"

# Perl's Type System - ARRAY

ARRAY (non-strict)

Keys are integers, Values any SCALAR

# Perl's Type System - ARRAY

ARRAY (non-strict)

Keys are integers, Values any SCALAR

@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});

# Perl's Type System - ARRAY

ARRAY (non-strict)

Keys are integers, Values any SCALAR - flexible, untyped, big

@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});

# Typed ARRAY

Typed ARRAYs (optional, faster, less space)

Keys are integers, Values of one type only (native)

my int @a; $#a=256; # pre-allocate: 256 * sizeof(IV)
my int @a = (1); # non-fixed size: 3 * sizeof(IV)
my int @a :const = (1); # fixed size: 1 * sizeof(IV)

Untyped:

my @a; $#a=256; # pre-allocate: 256 * sizeof(SV)

# Typed ARRAY

my int @a;

`AvTYPED && (IOK | NOK | POK)`

# Typed ARRAY

my int @a;

Declaration already possible now!

perl -we'package int; package main; my int @a;'
-e syntax ok

int must be a package definition.

Note: `@a` is declared as `int`, but not blessed.

# Perl's Type System - HASH

HASH untyped: flexible, but big

Keys any SCALAR, Values any SCALAR

%h = ('any' => ["any", 1, 2.5006];
1 => 1,
1.005 => 2.5);

Internally: Keys are stringified.

# Perl's Type System - HASH

HASH untyped: flexible
Keys any SCALAR, Values any SCALAR

# Typed HASH

HASH typed: fast, small

Keys STRING only, Values typed

my string %h; $h{'x'} = 'string';
my int %h; $h{'x'} = 1;
my double %h; $h{'x'} = 1.0;

# Typed HASH

HASH typed: directer access, small
Keys STRING only, Values typed

# Typed HASH

HASH typed: fast, small

Keys STRING only, Values are typed.

my int %h; $h{'any'} = 1;
$h{2} = 1;
=> Wrong type: hash key no string
$h{'2'} = '1';
=> Wrong type: hash value no int

# Perfect HASH

Perfect hashes - guaranteed O(1) lookup, dynamic hash function generation

- `my %h :const;` => untyped perfect hash of unknown size
- `my %h :perfect;` => writable perfect hash
- `study %h`; => optimize lookup function to perfect hash.

study untyped hash => copies the old perl hash (HV) to new perfect hash (PH).

`:const` hashes are always `:perfect`

# Perfect HASH

Perfect hash. Should be typed to optimize implementation.

my int %h :const = ('my' => 1, 'your' => 2);

No need to study with :const and init on declaration.

my %h :const = ('my' => 1, 'your' => 2);
# untyped: value = SV

# Perfect HASH Idioms

- Avoid copy from perl hash to perfect hash.

my int %h :perfect;
$h{$_}=1 for @h;
study %h;

# Perfect HASH Idioms

- Declare size in advance.

my int %h :perfect;
length %h = length @h; # not legal yet, but should be
$h{$_}=1 for @h;
study %h;

# Perfect HASH Idioms

- :const hash with computed key => values, without study

Idea 1

my int %h :const;
length %h = length @keys; # not legal yet, but should be
$h{$_} = $i++ for @keys;

Init until length is filled

# Perfect HASH Idioms

- :const hash with computed key => values, without study

Idea 2

my int %h :const = map { $h{$_} => $i++} @keys;
=>
my int %h :const;
{ $h{$_} = $i++ for @keys; }

Initialization on next expression, usually a block.

# Perl's Type System - OBJECTS

OBJECTS: typed, but dynamic

run-time changable, mostly no compile-time optimizations possible.

Features: STASH ("class hash"), @ISA (mro), DESTROY

# Perl's Type System - OBJECTS

OBJECTS: typed, but dynamic.

Class by STASH, Inheritance by @ISA (mro), magic DESTROY methods.

Four method calls possible:

- Class->method()
- $object->method()
- Class->$method()
- $object->$method()

# Compilation of a function

Class::sub(ARGS...)
`pushmark
ARGS...
gv => GV *Class::sub
entersub`

Class->method()
$object->method()
Class->$method()
$object->$method()

# Compilation of a static method call

Class::sub()

Class->method(ARGS...)
`pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub`

$object->method()
Class->$method()
$object->$method()

# Compilation of a method call

$object->method(ARGS...)
`pushmark
padsv => GV *object
ARGS...
method_named => PV "method"
entersub`

# Compilation of a method call

Class->$method(ARGS...)
`pushmark
const => PV "Class"
ARGS...
method => GV *method
entersub`

# Compilation of a method call

$object->$method(ARGS...)
`pushmark
padsv => GV *object
ARGS...
method => GV *method
entersub`

# Optimization of a static method call

Class->method()
`pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub
=>
pushmark
const => PV "Class"
ARGS...
gv => GV *Class::method
entersub`

# Optimization of a static method call

Class->method(...) => &Class::method('Class', ...)
if defined &Class::method

or `package Class` :locked

i.e. not changed at run-time.

Note: `@Class::ISA` :const = `qw(bla);` does not help.

# Summary so far

All this is possible now, without changing the language.

Just optimized implementations are missing.

# More optimizations

More compile-time optimizations.

:const for variables

:locked for packages: const `@ISA`, no run-time created methods.

# use types;

types is Artur Bergman's compile-time checking attempt from 2002, after the compiler, B::Generate and optimize.

And before optimizer, which uses types to improve the optree.

# use types;

types does compile-time type-checking only.

compile-time type-optimizations in optimizer.

Problem: slower, not faster.

# use types;

The idea is to make programs with `use types;`

faster, not slower.

And define basic scalar types from CORE

`int`, `double` and `string`

# B::CC

The same types and declarations are used in B::CC also to optimize types even further.

# B::CC - optimizing perl compiler

B::CC also needs a syntax to optionally declare simple types:

int and double (strict)

So far it was done by magic variable name suffices: `$a_i`, `$n_d`;

faster, much faster

# B::CC - User Type declarations

Strict types as class, and optional type hints as attributes.

my int $foo :const;

With `use types` you get type-declarations,
partial type-safety, and
type optimizations at compile-time.

# SUMMARY

my double $foo = "string"; #compile-time error
sub foo (int $foo) { my ($foo) = @_ };
foo("hi"); #compile-time Type mismatch error
my int $int;
sub foo { my double $foo; return $foo }
$int = $foo; # compile-time Type mismatch error
my int @array = (0..10); # optimized internal representation
$array[2] = 2; # no SV, just the raw int at slot 2.

# SUMMARY

my int @array :const = (0..10);
# even more optimized internal representation
$array[2] = 2; # int @array is readonly
$array[2] = '2'; # compile-time const error
my string %stash :perfect =
(foo => 'str1', bar => 'str2'); # perfect hash (stashes)
; # more init...
study %stash; # initialization finished
print $stash{foo}; # faster lookup O(1)
$stash{new} = 1; # compile-time Type mismatch error

# SUMMARY

my int $i :double; # declares a IV with SVf_NOK.
my $i:int:double; # same but without type-check
my int $i; # declares an IV.
my $i:int; # same but without type-check
my int $i :string; # declares a PVIV.
my int @array :unsigned = (0..4);
# Will be used as c var in faster arithmetic and cmp.
# Will use no SV value slot, just the direct value.
my string %hash :const = (foo => 'any', bar => 'any');
# declare string keys only
# generate as read-only perfect hash.

# Questions?

http://blogs.perl.org/users/rurban/2011/02/use-types.html