I'm thinking XS thoughts because we're going to need a few external things at SOME point.... It would be so nice if Perl 6's XS was part of the language, rather than an external pre-processor.
Something like: module somesuch; use External (language=>"C"); sub chdir(string $path //= $ENV{HOME}) is external(returns=>'int'); Then you could extract the C source like so: perl -MExternal -e 'extract "chdir"' Which would generate something along the very vague lines of: #include<parrot_external.h> /* modulename.c */ void perlexternal_chdir(parrot_sv *path) { char* param_path = parrot_sv_to_char_STAR(path); int RETVAL = chdir(param_path); parrot_stackpush(parrot_int_to_iv(RETVAL)); } The more complex case: module getpw; use External(language=>"C",PREP=>q{ #include<pwd.h> #include<sys/types.h>}); class uid_t := class real; # Proposed class alias syntax (see below) class gid_t := class real; class passwd { my string $.pw_name; # Proposed pseudo-classes "string" and "real" my string $.pw_passwd; # are required to determine how to convert my int $.pw_uid; # the value to C my int $.pw_gid; my string $.pw_gecos; my string $.pw_dir; my string $.pw_shell; method storage { # storage returns a string name of the C type # or a listref to the field names if it's a # struct. If it's a scalar type in C, then # this class must contain a $.internal of the # appropriate Perl pseudo-class type (string, # int or real). return [qw{ pw_name pw_passwd pw_uid pw_gid pw_gecos pw_dir pw_shell }] } } sub getpwuid(uid_t $uid //= $_) is external(returns=>'passwd'); So, to recap: All types passed to an externally defined function must be classes which have well defined type behavior. A subroutine is declared external by using "is external" which takes argument pairs as parameters. One of external's parameters is "returns" which take a class name as its parameter. The function will return an object of the given class. Classes can be aliased using the C<:=> construct The following pseudo-classes are defined, which force a parrot-internal storage and define the mechanism by which the value is translated to external representation (these are all scalar types): int - signed integer value real - floating point string - A character string utf8string - A string which is never converted to ASCII bytes - A string which may contain binary data including nul each of these will implicitly have a method called "storage" which returns their class name, for consistency. There are some limitations to this very abstract approach, but most of those can be overcome by defining glue functions in External's "PREP" value. For example, if your target language is C++, and the default way of implementing "is rw" in C++ is to expect the target function to take a reference, then you could define your own glue function: module a; use External (language=>'C++', PREP=>q{ int _b(int& c) { aab(&c) } }); sub b(int $c is rw) is external(returns=>'int', call=>'_b'); This lets us do the quick-and-dirty conversion automatically and the fine-grained things in the target language. The big advantage to this mechanism is that it does not require a user to know the internals of Perl or Parrot in order to create linkage to external programs. Thoughts? -- Aaron Sherman X137 [EMAIL PROTECTED] "We had some good machines, but they don't work no more." -"Faded Flowers" / Shriekback