Re: Blocks and semicolons
Hello everybody, that's a few month i'm following this mailing list. i dont like all the changes that are being made to perl, i'm using perl since '97, anyway if i think about it they're mostly all (until i understand everything) benefit to the language. To make the background i was an assembly programmer on 6500, 6502, and well 65xx, and whatever you may think off, amiga (680x0), snes (65c816), that really good archimede (that nobody ever used), and the intel marmelade since their 80386... all this to say i know a few things about computers. If i must place languages that i like in order i would say: 1) ASM 2) perl 3) basic (yeah i know, everybody sez it stinks) i like poetry in perl, i like obfuscations, i like obvious solutions made more obvious. i like when peoples teach me perl. i like to tell peoples about perl. Now i came thru this: 2002-09-11 21:38:30, Luke Palmer had a funny time writting: > ... > across all expression blocks, whether user-defined or built-in. Any > expression block construct can be treated as either a statement or a > component of an expression. Here's a block that is being treated as a > term in an expression: > $x = do { > ... > } + 1; > > However, if you write > $x = do { > ... > } > + 1; > then the + will be taken erroneously as the start of a new statement. > (So don't do that.) > ... This is the part i like about perl 5. Really. I like it, it seems when you're doing I/O on a device, and nobody knows about the features. I like it! You're writting a driver an nobody suspects what's you're about. Now, if like asm for such things, i wouldnt use perl for such features. Why? well you're used to: > $x += > +1; not to: > } # implicit ';' THIS IS CRAZY#@!? > +1; If you're all going to make perl6 please try to keep things together. I mean i'd prefer to: > }; > +1 now perhaps i'm completly wrong. but for me, those CANT be different (yes, i know, they can..). I admit it, it could be fun to have such things, but it doesnt stand really clearly in my mind. And i dont think it fit any DWIM things. Well, if it could fit in any mind (for consistency) i'd like to have someone to explain. It doesnt feel natural, does it? Before stopping this annoyance, for my first post here, i'd like to say, for perl and parrot, some big thanks to: Damian Conway Dan Sugalski Larry Wall Luke Palmer Michael G Schwern Piers Cawley Simon Cozens Uri Guttman Randal L. Schwartz The p5p mailling list, the p6p too, And everybody i forgot here, but that i read so frequently Sorry for bothering, i've dropped a few schilling on yetanother.org :-) Freddo PS: if i can do anything to help, just ask (with enough help), i'm running cygwin (on WinXP, the cygwin experimental version), linux, hp-ux and solaris (different flavours) -- i know NOTHING about C, well, not that much about C. http://freddo.netfirms.com/
Re: Blocks and semicolons
Luke Palmer wrote: > This requires infinite lookahead to parse. Nobody likes infinite > lookahead grammars. Perl already needs infinite lookahead. Anyways, most people don't care whether a grammar is ambiguous or not -- if we did, natural human languages would look very different. People want expressive languages. (Some people even consider ambiguity a feature. Poets? Comedians? Lawyers?) I don't know how we should handle code blocks, but I do know that the answer should solve human problems, not yacc's. Perl 5 doesn't accept either of these loops: if ($_) { print "$_\n" } for (qw(1 0)); print "$_\n" if ($_) for (qw(1 0)); The code must be written as: for (qw(1 0)) { print "$_\n" if ($_) } Why won't a similar solution work for user-defined syntax in Perl 6? (It would be no worse than Perl 5...) - Ken
Re: Blocks and semicolons
On Thu, 12 Sep 2002, Ken Fox wrote: > Luke Palmer wrote: > > This requires infinite lookahead to parse. Nobody likes infinite > > lookahead grammars. > > Perl already needs infinite lookahead. Anyways, most people > don't care whether a grammar is ambiguous or not -- if we did, > natural human languages would look very different. Really? Where? Computers don't like ambiguous grammars, because they don't know which to execute. Ambiguity is a feature in natural language, but not computer. Or you could make a language that selects a meaning randomly, but that just feels too much like INTERCAL :). > Perl 5 doesn't accept either of these loops: > >if ($_) { print "$_\n" } for (qw(1 0)); >print "$_\n" if ($_) for (qw(1 0)); Indeed. But in Perl 5, C is not a sub. This is valid: eval { print "foo\n" } for @ar; And I've been hearing that you can do this in Perl 6: eval { print "foo\n" } (of course with C instead, but this is more illustrative) And _that_ is a terminated statement. But it's also an expression. This is problematic, because of the ambiguity presented earlier. > The code must be written as: > >for (qw(1 0)) { > print "$_\n" if ($_) >} > > Why won't a similar solution work for user-defined syntax in > Perl 6? (It would be no worse than Perl 5...) Because subs have to work as expressions. It would all be well and good if you had to give an C-like sub a special property: sub perhaps ($cond, $prob, &code) is statement {...} But somehow that doesn't seem very elegant. Luke
Re: Blocks and semicolons
Luke Palmer wrote: > On Thu, 12 Sep 2002, Ken Fox wrote: > > Perl already needs infinite lookahead. > > Really? Where? Indirect objects need infinite lookahead and they are in the core language. Hyper operators may need lookahead. Place holders may need lookahead. User defined rules will definitely need infinite lookahead. (Remember we are switching from LR to LL parsing. LL(1) parsing is not as powerful as LR(1), so Perl 6 will need lookahead even in places where Perl 5 doesn't.) > Computers don't like ambiguous grammars ... The "dangling else" problem is ambiguous. Every time you get a shift-reduce conflict in yacc, you have an ambiguous grammar. Computers don't care about ambiguous grammars, but some of the common tools (yacc) disambiguate whether we like it not. ;) BTW, there are some parser generators that handle ambiguous grammars -- they either support backtracking, infinite lookahead, or simultaneously parse all possible derivations. In the case of the simultaneous parse, they can actually return multiple parse trees and let the code generator decide how to interpret things. > But in Perl 5, C is not a sub. > ... > Because subs have to work as expressions. In Perl 6 the difference between "sub" and "syntax" is almost non-existant. Some subs will behave like built-in syntax, some subs will behave like "normal" function calls. (AFAIK, the only difference is that subs can not provide lazy argument evaluation. Maybe the "is rx" property eliminates even that? BTW, does anybody else find "is rx" funny? "This is your argument. This is your argument on drugs." (Rx is an abbreviation for drug prescription in the U.S.)) I think Perl 5's solution for handling "if" can be applied to Perl 6 subs that look like syntax. It might not be an improvement over Perl 5, but at least it's no worse. A better solution may be to continue the parse until we see if "for" is followed by a block. (That's really hard to do with yacc, which might be why Perl 5 does what it does.) - Ken
Re: Blocks and semicolons
> BTW, there are some parser generators that handle > ambiguous grammars -- they either support backtracking, > infinite lookahead, or simultaneously parse all possible > derivations. In the case of the simultaneous parse, they > can actually return multiple parse trees and let the > code generator decide how to interpret things. A la my very own Parse::Earley. But don't try to use the parse "graph" yet, as it is near impossible to traverse. > > But in Perl 5, C is not a sub. > > ... > > Because subs have to work as expressions. > > In Perl 6 the difference between "sub" and "syntax" is > almost non-existant. Some subs will behave like built-in > syntax, some subs will behave like "normal" function > calls. (AFAIK, the only difference is that subs can not > provide lazy argument evaluation. Maybe the "is rx" > property eliminates even that? BTW, does anybody else > find "is rx" funny? "This is your argument. This is your > argument on drugs." (Rx is an abbreviation for drug > prescription in the U.S.)) Yeah, that's exactly why I said that. This discussion is getting rather stagnant, so I'll just back off and let the design team work all this out. > I think Perl 5's solution for handling "if" can be > applied to Perl 6 subs that look like syntax. It might > not be an improvement over Perl 5, but at least it's > no worse. > > A better solution may be to continue the parse until > we see if "for" is followed by a block. (That's really > hard to do with yacc, which might be why Perl 5 does > what it does.) > > - Ken Luke
RE: Blocks and semicolons
Ken Fox: # derivations. In the case of the simultaneous parse, they can # actually return multiple parse trees and let the code # generator decide how to interpret things. Of course, in Perl 6, they'd return a superposition of all possible parses, and trying to use the superposition would cause it to collapse to one of the possibilities. :^) --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) "In other words, it's the 'Blow up this Entire Planet and Possibly One or Two Others We Noticed on our Way Out Here' operator." --Damian Conway
Re: Blocks and semicolons
From: Ken Fox [EMAIL PROTECTED] > BTW, does anybody else find "is rx" funny? Only because they're not called regular expressions anymore. How about "px" for "pattern expression"? -Miko mail2web - Check your email from the web at http://mail2web.com/ .
XS in Perl 6
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 /* 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 #include}); 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
RE: XS in Perl 6
Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote: > 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. > [ some interesting stuff] > Thoughts? Its good to start thinking about this early; but should we be thinking "Parrot's" XS; not "Perl 6's"? Parrot has to solve the problem of binding multiple languages together within a unified framework: Ruby calls a python method, passing a Perl object as a parameter. I would hope that the solution to that challenge will be sufficiently powerful to solve the problem of describing/generating an interface to C, C++, Java, Eiffel, and INTERCAL. Given that parrot will solve it in a language-neutral way, I am not sure that we should focus an a Perl6 XS, "rather than an external pre-processor". We may want a Perl6 module that hides the complexity of the Parrot stuff; but that depends on how complex the Parrot stuff turns out to be. Dave.
RE: XS in Perl 6
Aaron Sherman: # 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'); I prefer: module System::FS is version(1.0.0); use Parrot::XS 'load'; sub chdir(string $path //= $ENV{HOME}) is external returns(int); sub curdir() is external returns(string); # 'returns' would be Perl's normal way to declare return # value, not a special thing for external functions only. load module => System::FS, version => 1.0; But that's just the shell around the real XS file: parrot_xs { module = System::FS; pversion = 0.0.8; xsversion = 0.0.1; modversion = 1.0.0; } #include xsub extern int chdir(char*); xsub char* curdir() { ... } /* Creates a wrapper and argument converter like: Parrot_PMC * Parrot_XS_System__FS_dispatch(Parrot_String func, Parrot_PMC obj, Parrot_PMC retto, Parrot_PMC args) { if(Parrot_string_eq_cstr(func, "chdir")) { Parrot_pmc_set_integer( retto, chdir( Parrot_string_to_cstr( Parrot_pmc_get_string( Parrot_pmc_get_keyed_integer( args, 0 ) ) ) ) ); } else if(Parrot_string_eq_cstr(func, "curdir")) { Parrot_pmc_set_string( retto, curdir() ); } else { Parrot_xs_die(Parrot_sprintf_cstr("Function %S not found!", func)); } } except with all the missing references to 'interpreter'. */ Of course, if you wanted to, you could use something like Inline.pm: module System::FS is version(1.0); use Parrot::XS::Inline; inline C => qq{ #include }; sub chdir(string $path //= $ENV{HOME} is external('C', 'int', 'char*') returns(int); sub curdir() is external('C', 'char*') returns(string) { /* C code here */ ... } --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) "In other words, it's the 'Blow up this Entire Planet and Possibly One or Two Others We Noticed on our Way Out Here' operator." --Damian Conway
RE: XS in Perl 6
On Thu, 2002-09-12 at 20:09, David Whipp wrote: > Aaron Sherman [mailto:[EMAIL PROTECTED]] wrote: > > 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. > > [ some interesting stuff] > > Thoughts? > > Its good to start thinking about this early; but should we be thinking > "Parrot's" XS; not "Perl 6's"? I disagree. Parrot will have a way to access runtime-loadable libraries and call them from parrot code, but the argument marshaling and type conversion specification will all happen in the way that the target language specifies, since that language will be constrained in how it can take advantage of Parrot and the native library it's accessing. Yes, Parrot's facility for external binding must be established, but it's almost 100% tangential to the discussion of how Perl 6 will interface through that facility. > Parrot has to solve the problem of binding multiple languages together > within a unified framework: Ruby calls a python method, passing a > Perl object as a parameter. Good point. However, Perl6 will call Ruby in different ways than Python will. Certainly a function that returns a list in Perl would be called differently form Scheme or BASIC, since Scheme supports list types albeit very different ones from Perl, where BASIC does not. No, Parrot will make it easier for these languages to call external binary objects or PBC modules from other languages, but the solution will ultimately involve a heavy amount of custom work per-language. -- Aaron Sherman <[EMAIL PROTECTED]> http://www.ajs.com/~ajs
RE: XS in Perl 6
On Thu, 2002-09-12 at 21:10, Brent Dax wrote: > Aaron Sherman: > # I'm thinking XS thoughts > # Something like: > # > # module somesuch; > # use External (language=>"C"); > # sub chdir(string $path //= $ENV{HOME}) is > # external(returns=>'int'); > > I prefer: > > module System::FS is version(1.0.0); > use Parrot::XS 'load'; > > sub chdir(string $path //= $ENV{HOME}) is external returns(int); > sub curdir() is external returns(string); > # 'returns' would be Perl's normal way to declare return > # value, not a special thing for external functions only. I like "returns" as a property. Much cleaner, and I really like the ability to specify a return type generally. You do need to be able to specify the target language, though. > load module => System::FS, version => 1.0; I would think that this version number and the one in the module statement before would always be the same (since they're in the same file, and the XS is generated by this file). What's more, this whole statement could be considered "implied" by the use of C. > #include Too magical. You need to have some way to specify an arbitrary string in your module that will be exported to the target language ala my "PREP" parameter. That C<#include> statement would go in the string along with any glue functions required. So, to re-write both of our suggestions as one: module System::FS is version(1.0.0); use Parrot::XS language => 'C', prep => q{ #include }; sub chdir(string $path //= $ENV{HOME}) is external returns(class int); sub curdir() is external returns(class string); I stuck the "class" keyword in with the returns property because otherwise I think it's ambiguous. However, that was my simple example. Here again (and slightly re-written based on your suggestions) is my more complex example: module getpw is version(1.0.0); use Parrot::XS language => 'C', prep => q{ #include #include }; 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(class passwd); -- Aaron Sherman <[EMAIL PROTECTED]> http://www.ajs.com/~ajs
rw and types
What are the restrictions on "is rw"? For example, can it be used with variables of a particular type? If so, does the parameter passed have to already be that type? What does this do? sub process(int $i is rw) { $i++ } my $x = "10"; process($x); Does C<$x> become 11? That would require that a temporary be created, I suppose, which is not horrible, I just worry about implying efficiency where it doesn't really exist. The above is the simple case, of course because a scalar can contain an integer. What does this do: sub process(Dog $i is rw) { $i.bark } my Cat $x; process($x); That I guess the sub could expand to: my Dog $i = @_[0]; # If it works, it works $i.bark @_[0] = $i; But that could have very different semantics than the user expects -- Aaron Sherman <[EMAIL PROTECTED]> http://www.ajs.com/~ajs
Re: Blocks and semicolons
On Wed, 2002-09-11 at 19:11, [EMAIL PROTECTED] wrote: > Hello everybody, > > that's a few month i'm following this mailing list. i dont like all the changes > that are being made to perl Imagine how I felt when Perl 4 came out, with all that silly binary I/O stuff! I had no idea what Larry had been smoking! :-) > This is the part i like about perl 5. Really. I like it, it seems when you're > doing I/O on a device, and nobody knows about the features. I like it! You're > writting a driver an nobody suspects what's you're about. If no one can determine what your code does, it's bad code. That's one of the reasons that I don't particularly like the implicit semicolon, though I do very much like the idea of solving the eval{}; vs for{} discrepancy. Here's how I would solve the problem: If the last argument to a subroutine is a code value (e.g. C<&block>) then the subroutine invocation does not require a semicolon. Thus: eval {...} / 2 would be an error in exactly the same way that if 0 {...} / 2 would be, but the common eval {...}; would be ok, even though it's got a null statement. Remember, all's fair if you pre-declare. -- Aaron Sherman <[EMAIL PROTECTED]> http://www.ajs.com/~ajs
RE: XS in Perl 6
Aaron Sherman: # On Thu, 2002-09-12 at 21:10, Brent Dax wrote: # > Aaron Sherman: # > # I'm thinking XS thoughts # # > # Something like: # > # # > # module somesuch; # > # use External (language=>"C"); # > # sub chdir(string $path //= $ENV{HOME}) is # > # external(returns=>'int'); # > # > I prefer: # > # > module System::FS is version(1.0.0); # > use Parrot::XS 'load'; # > # > sub chdir(string $path //= $ENV{HOME}) is external returns(int); # > sub curdir() is external returns(string); # > # 'returns' would be Perl's normal way to declare return # > # value, not a special thing for external functions only. # # I like "returns" as a property. Much cleaner, and I really # like the ability to specify a return type generally. # # You do need to be able to specify the target language, though. I don't think so. As long as it's something that C can load in, why should you have to specify the language? # > load module => System::FS, version => 1.0; # # I would think that this version number and the one in the # module statement before would always be the same (since # they're in the same file, and the XS is generated by this # file). What's more, this whole statement could be considered # "implied" by the use of C. Except that I might want to implement this with a number of platform-specific modules, to make sure I don't try to pull in another platform's module: given($*OS) { #Or whatever $^O becomes #Make sure I don't try to use something designed for # a different platform when /Solaris/ { load module => System::FS::Solaris, version => 1.0 } when /Linux/ { load module => System::FS::Linux , version => 1.0 } ... } Since the loaded module need not have the same name as the surrouding module, the version number is needed. # > #include # # Too magical. You need to have some way to specify an # arbitrary string in your module that will be exported to the # target language ala my "PREP" parameter. That C<#include> # statement would go in the string along with any glue # functions required. I consider this more generic--the C command is for any arbitrary code. # So, to re-write both of our suggestions as one: # # module System::FS is version(1.0.0); # use Parrot::XS language => 'C', prep => q{ # #include # }; # # sub chdir(string $path //= $ENV{HOME}) is external # returns(class int); # sub curdir() is external returns(class string); # # I stuck the "class" keyword in with the returns property # because otherwise I think it's ambiguous. Why do you need your own class? Presumably XS would know how to convert between C's C and Perl's C... # However, that was my simple example. Here again (and slightly # re-written based on your suggestions) is my more complex example: # # module getpw is version(1.0.0); # use Parrot::XS language => 'C', prep => q{ # #include # #include # }; # # 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 C is already a built-in type, and presumably XS would understand how to convert a C into a C. But why use C? Are C and C not enough? (Or are you using C instead of C because you don't know about C? Or does it say somewhere that it's C and I'm incorrect in thinking it's 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 # }] # } # } Why not: class passwd is xs_struct( qw(pw_name pw_passwd pw_uid pw_gid pw_gecos pw_dir pw_shell) ) { ... And for simpler types: class Parrot::String is xs_type('Parrot_String' => $.ptr) { my Parrot::XS::Pointer $.ptr; ... # sub getpwuid(uid_t $uid //= $_) is external returns(class passwd); Once again, why the C? --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) "In other words, i