[% setvar title structures and interface definitions %]
Note: these documents may be out of date. Do not use as reference! |
To see what is currently happening visit http://www.perl6.org/
structures and interface definitions
Maintainer: David Nicol <perl6rfc@davidnicol.com> Date: 8 Aug 2000 Last Modified: 5 Sep 2000 Mailing List: perl6-language-subs@perl.org Number: 75 Version: 2 Status: Frozen
A structure definition language can also be used to provide named arguments to subroutines, and vice versa.
$xys = qs{ $x, my $y }; # $x is pass by reference, $y by value sub foo($xys){ print "x is $x and y is $y\n"; }; %fasthash = unpack( $xys, $Structure ); $Structure = pack( $xys, %fasthash );
Stack based compiled languages like C organize all the arguments to a subroutine onto the stack before calling the subroutine, and from the subroutine the arguments are accessed, in the compiled machine code, with offsets from a "stack pointer."
This process is similar to the way that fields in a record are accessed by a fixed offset from a pointer to the beginning of the record.
Perl has a structure definition syntax, it is the "pack format" language. By extending that language in a way that names are associated with parts of the format, we can achieve something that will interact with the other language elements much like a hash.
We may also import structure definition languages from other languages that have them, such as C or COBOL.
Imagine:
use COBOL_pic; # might not be needed $mypic =<<ENDCOBOL; I don't know COBOL data structure language :) ENDCOBOL %DataHash = unpack $mypic, $SomePackedCobolData; A_routine_taking_the_data(%DataHash); #Or, in a more perl5 way: %{$DataHash} = unpack $mypic, $SomePackedCobolData; bless $DataHash, 'coboldata'; operate $DataHash;
Pseudohash type definitions are Structure-Definitions are Interfaces. All of these may be considered key-value associative arrays for purposes of language syntax.
Structure definitions are declared using the qs
operator,
or can be inlined in situations that syntacticly call for them,
such as function prototypes.
In invoking a subroutine prototyped using a structure definition, (aka fully defined interface) the arguments can come from a list, in which case they are loaded into the structure in order, they can come from a(nother) (pseudo)hash, in which case they are loaded into the structure by name.
Rather than Special-casing the interpretation of function call parameters, we can create an object of type $xy and send it to the function that takes that type. This way the name localization is in the called subroutine, and we don't have names from subroutines appearing in the calling code.
Any subroutine with a prototype with named variables, no matter how scoped, can be called with a hash or hash-like structure with the required keys, and the correct keys will be used as the subroutine parameters.
The default subroutine interface becomes qs{@}
like it
has been all along, but by using explicit interfaces we
can introduce a more extensive conversion step when required.
This system was proposed within RFC 61 as an implementation detail, and after reading RFC 57 it became clear that the problems of stuffing a set of data into the interface for an external function apply equally to a native perl function.
I think that after settling on an extensible interface declaration system, much cool stuff that cannot happen with the current lists will be possible.
perl5 prototype definition language will be one type recognized
by qs
, and perl6 argument coercion will be a proper superset
of perl5 argument coercion.
subroutines expecting hashes decomposed into arrays wouldn't have a prototype indicating anything else, so that's what they'd get.
rewrite to focus on the universality of
interfaces == parameter lists == structures
rather than expecting people to intuit that more readily
RFC 57: Subroutine prototypes and parameters
RFC 61: Interfaces for linking C objects into perlsubs
e-mails from Chaim Frenkel