[% setvar title Controllable Data Typing %]
Note: these documents may be out of date. Do not use as reference! |
To see what is currently happening visit http://www.perl6.org/
Controllable Data Typing
Maintainer: Syloke Soong <syloke.soong@nsc.com> Date: 10 Aug 2000 Last Modified: 12 Aug 2000 Mailing List: perl6-language@perl.org Number: 89 Version: 2 Status: Developing
Provide a choice for a programmer to define non-convertible and semi-convertible variables with explicit data-types.
Current intelligence and flexibility of Perl variables are extremely indispensable. However at times this feature is also extremely inconvenient. As an example, character string "007" is often mistaken as int 7. So that concatenation of a variable strings "001999", "." , "03" to form an output filename could, unless with more extensive treatment, form a filename of 1999.3 instead. Attempts at storing into a hash with the key "007" or " 7" rather than 7 is a trying experience. Not to mention attempts at reading a hash using similar keys.
A compromise between dead-bolted types and liberal types is struck through constrained and controllable typing. There is a hint of polymorphic behaviour.
Retain current flexibility of Perl liberal variables. Provide a new form of declaring variables:
scope cast-type $varname:constraint;
Valid declarations would be:
my $varname; my (var-list); my cast-type $varname; my cast-type (var-list); my $varname:constraint; my (var-list):constraint; my cast-type $varname:constraint; my cast-type (var-list):constraint; my $varname:(constraint-list); my (var-list):(constraint-list); my cast-type $varname:(constraint-list); my cast-type (var-list):(constraint-list);
my $old; my int $k; my varchar $str; my char(5) $zip; use CGI; my CGI $q; my Net::SNPP ($pg, $pq); my int $a = 3.9; my int $ceil = 3.9 + 0.5; my int $i = 'hello'; my double $f1 = 'hello'; my double $f2 = $a;
$old is the declaration of a liberal type; $a evaluates to int 3; $ceil evaluates to int 4; $i evaluates to int 0; $f1 evaluates to double 0.; $f2 evaluates to double 4.;
A constant confered by the keyword const creates a final value; That value stays immutably the same throughout the scope of its existence.
my $a1:const; my int $k1:const; my varchar $str1:const; my $a21:const = '023'; my $a22 = 3 + $a21; my $a23 = 3.$a21; my int $k21:const = '023'; my int $k22:const = 23; my varchar $str21:const = 3; my char $str22:const = 3; my char(1) $str22:const = 3; my Net::SNPP ($pg, $pq):const; my Net::SNPP ($pr, $ps):const = new Net::SNPP ; my Net::SNPP ($pt = $pu, $pv):const = new Net::SNPP ; use strict(constcroak); $str22 = 'hello';
$a1, $k1, $str1 are henceforth constantly null liberal, int and varchar respectively; $$a21 acquires constant value of char(3) '023'; $a22 acquires variable value of liberal-type 26; $a22 acquires variable value of liberal-type 3023;
$k21, $k22 both acquire constant values of int 23; $str21, $str22, $str23 all acquire variable values of char(1) 3;
$pg and $pq henceforth vainly reference null objects of Net::SNPP; Whereas $pr, $ps, $pv usefully and loyally reference separate objects of Net::SNPP; $pt and $pu both reference the same Net::SNPP object constantly.
The strict directive, default being noconst (disregard any harassment on a const), is set to croak when an attempt to change the value of constant $str22 is made. Use of
use strict(constdie);
should also be an option.
my $id:(double,int); my int $id1:(double,int) = 1.7; my int $id2:(varchar, double) = 2.6; my int $id3:(varchar, double, int) = 2.6; my char $c1 = 'a'; my char $c2:char = 'a'; my char $c3:(char) = 'a'; my $id4:(varchar, double, int) = 2.7; my $id5:(varchar, double, int) = 3; my $id6:(varchar, double, int) = 'Fatrick Perlland';
$id is constrained to behave either as double or int; $id1 is constrained to behave either as double or int, but int casting initialises it to (double,int) 1;
$id2 and $id3 are similar declarations such that a cast not found in the constraint list will be spontaneously added to the constraint list; Both acquires (varchar, double) value of 2.6;
Declarations of $c1, $c2, $c3 are all equivalent forms. Declaration of $c1 follows the rule of spontaneous appending a cast to its constraint list.
$id4, $id5, $id6 are constrained to behave either as varchar, double or int; $id4 acquires value of (varchar, double, int) 2.7; $id5 acquires value of (varchar, double, int) 3; $id6 acquires value of (varchar, double, int) 'Fatrick Perlland';
my $allowedtypes = [int,varchar]; my $ivd:@$allowedtypes; if ($somecondition){push @$allowedtypes , double}
Initially $ivd would be allowed the behave either as int or varchar. On condition $somecondition, it is allowed an additional degree of freedom of double due to appendage to the array referenced by $allowedtypes.
The member types chosen as the snap-shot type depends on the rules in order. First, suitability. Then precedence.
my $ie4:(varchar, double, int, char(16)) = 2.7; my $ie5:(varchar, double, int, char(16)) = 3; my $ie6:(varchar, double, int, char(16)) = 'Fatrick Perlland';
The declarations has types in the following precedence: 1st varchar, 2nd double, 3rd int, finally char(16). $ie4 is assigned value 2.7 as double is the most suitable type to receive it. $ie5 is assigned value 3 as int is most to receive it. $ie6 has as candidates varchar and char(16), but since varchar is declared in precedence to char(16), the receiver is a varchar. The inclusion of varchar(16) is in vain as varchar completely over-rides it.
While the value of a constant is immutable, its snap-shot representation is not.
my $oxygen:(const, char(4), int, double) = '3.3'; print "#", $oxygen."oxymen\n"; print "#", $oxygen + 4 , "oxylady\n"; print "#", $oxygen + 1.5 , "foxylady\n"; print "#", int ($oxygen + 1.5) , "dixieland\n"; print "#", ($oxygen + 1.5):int , "dixiechicks\n"; print "#", ($oxygen + 1.2378):decimal(3.2) , "Reba\n";
The following STDOUT results: # 3.3oxymen #7oxylady #4.8foxylady #4dixieland #4dixiechicks # 4.53Reba
my $perl:(int,varchar, double); my double $isnotc:(varchar, double) = '4.5'; # $isnot casted to receive double 4.5 int $perl = $isnotc; # $perl casted to receive int 4 int $isnotc = $perl; # Do nothing, $isnotc does not have constraint type int use strict (croakbadcast); int $isnotc = $perl; # Do nothing but a croak will be forthcoming from Perl system use strict (diebadcast); int $isnotc = $perl; # Do nothing and die int $cisnot = $perl; # $cisnot is a new variable and takes on the constraint int
There has been questions - what about hash and arrays?. If they are to be considered as types then the following is possible.
my \@ $aref; #equiv to: my $aref:(\@) = []; my \% $hfer; #equiv to: my $href:(\%) = {}; my int @href; #array of ints my CGI @AQ; #array of CGI objects my CGI %HQ; #hash which has values resolving to CGI objects
In the declaration
my int $maine:const = 12;
$maine loyally references an immutable memory location. Shall there be such where $mall is a mutable variable allowed to reference only constants? Hmmm...
my int $mall:\const = 13;
There's a hint of wanting Perl references to behave as pointers and that's not a good attitude. However an array of hash of constants may be declared and each pigeon hole of the array or hash may reference only constants.
my int $shania:const = 11; my int @twain:const = ($shania); #valid assignment my int $alberta = $twain[0];
#Perl is not C.
Use of colon is plagiarised from email discussions with/from perl6-language@perl.org