YAPC::US 2011
rurban - Reini Urban
vienna.pm
, houston.pm
my TYPE $i; my My::Class $o;
Declaration only. package TYPE must exist
Declare and check type safety. int, double, number, string.
params and return values.
smaller and faster, ensured at compile-time.
typed arrays + hashes, perfect hashes, fast method calls,
type declarations via class and attributes, fix types.
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.
Yes, the language already has one.
my int $var; # or ourYes, the language already has one. CORE:
my TYPE $var;Only a few out-of-CORE implementations:
Moose, fields, types, typesafety, Lexical::Types
Params: Devel::Declare
, Params::Validate
, Params::Classify
Objects: Class::Meta
, Moose
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)
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => PVIV => PVNV
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
IV: integer
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
IV - integer unblessed, untied
=>
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => NV
SCALAR (non-strict, VB-like)
multiple types (IV,NV,PV) per variable, context dependent.
internally upgraded: IV => NV => PVNV
SCALAR (non-strict, VB-like)
internally upgraded: IV => PVIV => PVNV => "Objects" => Tie
"STASH" - Hierarchical symbol table,
used as package name for Objects. i.e. "Class pointer"
ARRAY (non-strict)
Keys are integers, Values any SCALAR
ARRAY (non-strict)
Keys are integers, Values any SCALAR
@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});ARRAY (non-strict)
Keys are integers, Values any SCALAR - flexible, untyped, big
@a = ("any", 1, 2.5006, \&code, ['arrayref'], {hashref=>1});
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)Untyped:
my @a; $#a=256; # pre-allocate: 256 * sizeof(SV)
AvTYPED && (IOK | NOK | POK)
my int @a;
Declaration already possible now!
perl -we'package int; package main; my int @a;'int must be a package definition.
Note: @a
is declared as int
, but not blessed.
HASH untyped: flexible, but big
Keys any SCALAR, Values any SCALAR
%h = ('any' => ["any", 1, 2.5006];Internally: Keys are stringified.
HASH untyped: flexible
Keys any SCALAR, Values any SCALAR
HASH typed: fast, small
Keys STRING only, Values typed
my string %h; $h{'x'} = 'string';HASH typed: directer access, small
Keys STRING only, Values typed
HASH typed: fast, small
Keys STRING only, Values are typed.
my int %h; $h{'any'} = 1;Perfect hashes - guaranteed O(1) lookup, dynamic hash function generation
my %h :const;
=> untyped perfect hash of unknown sizemy %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. 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);- Avoid copy from perl hash to perfect hash.
my int %h :perfect;- Declare size in advance.
my int %h :perfect;- :const hash with computed key => values, without study
Idea 1
my int %h :const;Init until length is filled
- :const hash with computed key => values, without study
Idea 2
my int %h :const = map { $h{$_} => $i++} @keys;Initialization on next expression, usually a block.
OBJECTS: typed, but dynamic
run-time changable, mostly no compile-time optimizations possible.
Features: STASH ("class hash"), @ISA (mro), DESTROY
OBJECTS: typed, but dynamic.
Class by STASH, Inheritance by @ISA (mro), magic DESTROY methods.
Four method calls possible:
pushmark
ARGS...
gv => GV *Class::sub
entersub
Class->method()
$object->method()
Class->$method()
$object->$method()
Class::sub()
pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub
$object->method()
Class->$method()
$object->$method()
pushmark
padsv => GV *object
ARGS...
method_named => PV "method"
entersub
pushmark
const => PV "Class"
ARGS...
method => GV *method
entersub
pushmark
padsv => GV *object
ARGS...
method => GV *method
entersub
pushmark
const => PV "Class"
ARGS...
method_named => PV "method"
entersub
=>
pushmark
const => PV "Class"
ARGS...
gv => GV *Class::method
entersub
or package Class
:locked
i.e. not changed at run-time.
Note: @Class::ISA
:const = qw(bla);
does not help.
All this is possible now, without changing the language.
Just optimized implementations are missing.
More compile-time optimizations.
:const for variables
:locked for packages: const @ISA
, no run-time created methods.
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.
types does compile-time type-checking only.
compile-time type-optimizations in optimizer.
Problem: slower, not faster.
The idea is to make programs with use types;
faster, not slower.
And define basic scalar types from CORE
int
, double
and string
The same types and declarations are used in B::CC also to optimize types even further.
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
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.