[% setvar title Controllable Data Typing %]

This file is part of the Perl 6 Archive

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);

Simple examples

	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.;

Constant constraint

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.

Constraint lists

	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';

Conditional constraints

	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.

Suitability and precedence in constraint lists

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.

Mutable representation of constants

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

type casting

	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

What about hash and arrays

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	

What about pointers to const

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