Re: some misc Perl 6 questions
Larry Wall wrote: That's...sick... I love it. *Please* don't tell Damian. whisper Well there are some people who consider it quite sane :) http://www.cduce.org/papers/icalp04.pdf Abstract: This paper studies the problem of matching sequences against regular expressions in order to produce structured values. To me handling XML data is an area where Perl 6 could|should|will excel! I think Perl 5 already does. /whisper MfG -- TSa (Thomas Sandlaß)
Re: some misc Perl 6 questions
Darren Duncan [EMAIL PROTECTED] wrote: A question: Would has PkgNameArray @.tmpl_set_nms; do what I expect, where the array as a whole is the sub-type, or would it make an array where each element is the sub-type? I think this declares an array of PkgNameArrays, but has @.tmpl_set_nms is PkgNameArray; will do what you want. New question: Is there a way to say that two classes have a privileged relationship, sort of like a marriage, such that each can see and/or change otherwise private attributes in objects of the other class, and yet the attribute list of each class is completely different from the other? Neither of the two objects is a subclass of the other, nor fulfills a role defined by the other. S12: Attributes are never visible outside a class definition, so a multi method can only directly access the attributes of a class it's defined within. However, it may call the private attribute accessors from a different class if that other class has indicated that it trusts the class the multi method is defined in: class MyClass { trusts Yourclass; ... } (end quote) So for the relationship to work both ways, each class would have to mark the other as trusted. -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker I used to have a life, but I liked mail-reading so much better.
Re: some misc Perl 6 questions
On Tue, Mar 08, 2005 at 10:29:30PM -0800, Darren Duncan wrote: [...] By using subtypes in this way, I could remove a lot of explicit input checking code from my methods, which is great. Also, the where clause is not being repeated for every argument or attribute or variable declaration. (I like SQL domains for the same reasons.) That's very cool. I start to see the appeal of AOP. New question: Is there a way to say that two classes have a privileged relationship, sort of like a marriage, such that each can see and/or change otherwise private attributes in objects of the other class, and yet the attribute list of each class is completely different from the other? Neither of the two objects is a subclass of the other, nor fulfills a role defined by the other. [...] Also, does my request sound like something that would be reasonable to do, or a bad practice to avoid? FYI, in C++, the keyword 'friend' precisely describes the relationship you are discussing (and appears to be homologus to P6 'trusts'). There are good and bad things to be said about these relations but, IME, they are usually used because they have to be in order to achieve certain behavior, not because it is the cleanest or most appropriate way to build the model. Therefore, I would be very cautious about using 'trusts'. YMMV. --Dks -- [EMAIL PROTECTED]
Re: some misc Perl 6 questions
On Tue, Mar 08, 2005 at 10:29:30PM -0800, Darren Duncan wrote: : The biggest change is that, upon a re-reading Synopsis 12 (and 9) : that was inspired by your above comment, I created some subtypes : which I now use everywhere; the declarations and some examples of use : are: : : subtype KeyName of Str where { $_.defined and $_ ne '' and $_ !~ m/\W/ } : : subtype KeyNameHash of Hash is shape(KeyName) of Str; # keys are of : type KeyName, values of type Str : : subtype PkgName of Str where { $_.defined and $_ ne '' and $_ !~ : m/-[a-zA-Z0-9_:]/ } : : subtype PkgNameArray of Array of PkgName; Those seem to by syntactically correct. What they don't allow you to distinguish is whether you're using the constraints for MMD pattern matching or validation--the practical difference being that you want to give good error feedback if you're doing validation, and you want to silently fail if you're doing MMD, and let the default routine spit out error messages. I'm not sure how to solve that problem offhand. Using different subtypes for ordinary methods vs multi methods seems like about twice as many subtypes as you need. Hmm, perhaps it's just another failure context dependency. So you write subtype Foo of Bar where { .defined or fail Undefined Foo } and then the ordinary method dispatch can report the error, while the MMD can suppress it and keep going. My other quibble is that you seem to be prone to stating things in the negative for at least two of your three tests here: subtype KeyName of Str where { $_.defined and $_ ne '' and $_ !~ m/\W/ } and it seems to me that you could simplify all that to just subtype KeyName of Str where { m/^\w+$/ } If that succeeds, you know it's defined and non-null. You might argue that the m/\W/ short-circuits, but I would counter-argue that failure is supposed to be the exceptional case, and in every successful call you have to scan the whole string anyway. Plus it's just easier to understand. And it lets you write the constraint without explicit reference to $_, which I will admit was my first motivation in wanting to rewrite your constraint. The negatives and redundancies I only noticed later. : class Locale::KeyedText::Message { : : has KeyName $.msg_key; # str - the machine-readable key that : uniquely identifies this message That's fine. : has KeyNameHash %.msg_vars; # hash (str,str) - named variables : for messages, if any, go here That's not. As pointed out in another message want has %.msg_vars is KeyNameHash; # hash (str,str) - named variables or maybe just has Str %.msg_vars is shape(KeyName); # hash (str,str) - named variables and avoid cluttering up the symbol table. : method new( $class: KeyName $msg_key, KeyNameHash ?%msg_vars ) : returns Locale::KeyedText::Message { : my $message = $class.bless( {} ); : $message.msg_key = $msg_key; : $message.msg_vars = %msg_vars; # copy list values : return( $message ); : } I'd write return $message; but that's just stylistic. Creturn is actually a list operator (at least syntactically), so the parens are optional. But I personally prefer to view return as more of a keyword than a function. : ... : : class Locale::KeyedText::Translator { : : has PkgNameArray @.tmpl_set_nms; # array of str - list of : Template module Set Names to search : : has PkgNameArray @.tmpl_mem_nms; # array of str - list of : Template module Member Names to search Here too, I'd probably just write has PkgName @.tmpl_set_nms; has PkgName @.tmpl_mem_nms; : method new( $class: PkgNameArray @set_names, PkgNameArray : @member_names ) returns Locale::KeyedText::Translator { method new( $class: PkgName @set_names, PkgName @member_names ) returns Locale::KeyedText::Translator { or maybe even just method new( $class: @set_names, @member_names ) returns Locale::KeyedText::Translator { and rely on the assignment to do the validation. (But having the type names will work better under MMD.) And yes, trusts bestows trust on another class. I have no opinion on its suitability for any particular task. I'm just the language designer--my job is to shoot you in the foot and make you think you did it to yourself. :-) Larry
Re: some misc Perl 6 questions
Larry Wall wrote: and it seems to me that you could simplify all that to just subtype KeyName of Str where { m/^\w+$/ } If that succeeds, you know it's defined and non-null. My view is that typing strings by means of patterns should always exhaust the string as the above pattern does. I can imagine some magic that lets my KeyName @a = First Second; allow to actually have two entries @a[0] eq First and @a[1] eq Second by somehow morphing the pattern into continued matching mode where the next index continues where the previous left off---and skipping whitespace. Just an idea... -- TSa (Thomas Sandlaß)
Re: some misc Perl 6 questions
On Wed, Mar 09, 2005 at 06:51:43PM +0100, Thomas Sandlaß wrote: : Larry Wall wrote: : and it seems to me that you could simplify all that to just : : subtype KeyName of Str where { m/^\w+$/ } : : If that succeeds, you know it's defined and non-null. : : My view is that typing strings by means of patterns should always : exhaust the string as the above pattern does. I can imagine some : magic that lets : : my KeyName @a = First Second; : : allow to actually have two entries @a[0] eq First : and @a[1] eq Second by somehow morphing the pattern into : continued matching mode where the next index continues where : the previous left off---and skipping whitespace. That's...sick... I love it. *Please* don't tell Damian. Larry
Re: some misc Perl 6 questions
At 10:03 AM -0800 3/9/05, Larry Wall wrote: On Wed, Mar 09, 2005 at 06:51:43PM +0100, Thomas Sandlaß wrote: : Larry Wall wrote: : and it seems to me that you could simplify all that to just : : subtype KeyName of Str where { m/^\w+$/ } : : If that succeeds, you know it's defined and non-null. : : My view is that typing strings by means of patterns should always : exhaust the string as the above pattern does. I can imagine some : magic that lets : : my KeyName @a = First Second; : : allow to actually have two entries @a[0] eq First : and @a[1] eq Second by somehow morphing the pattern into : continued matching mode where the next index continues where : the previous left off---and skipping whitespace. That's...sick... I love it. *Please* don't tell Damian. Larry However, with my particular use I wouldn't want that to happen; I would want the assignment to just fail with an error. If we're going to do what you want, we should have some way of specifying which of the behaviours we want using different syntax around the rule definition. Incidentally, I noticed that '@a = First Second' looked a lot like the reverse of what '$b = @a' did in Perl 5. -- Darren Duncan
using Rules with undefined values (was Re: some misc Perl 6 questions)
At 9:08 AM -0800 3/9/05, Larry Wall wrote: My other quibble is that you seem to be prone to stating things in the negative for at least two of your three tests here: subtype KeyName of Str where { $_.defined and $_ ne '' and $_ !~ m/\W/ } and it seems to me that you could simplify all that to just subtype KeyName of Str where { m/^\w+$/ } If that succeeds, you know it's defined and non-null. You might argue that the m/\W/ short-circuits, but I would counter-argue that failure is supposed to be the exceptional case, and in every successful call you have to scan the whole string anyway. Plus it's just easier to understand. And it lets you write the constraint without explicit reference to $_, which I will admit was my first motivation in wanting to rewrite your constraint. The negatives and redundancies I only noticed later. Okay, I have gone and replaced the $_ ne '' and $_ !~ m/\W/ with a m/^\w+$/. However, unless Perl 6 is different than Perl 5 in its treatment of undefined values, I still need the .defined part, meaning I end up with: subtype KeyName of Str where { .defined and m/^\w+$/ } In Perl 5, running something like the un-gated $msg_key =~ m/^\w+$/ gives this warning: Use of uninitialized value in pattern match (m//) at Locale/KeyedText.pm line 85. To avoid that, I do defined( $msg_key ) and $msg_key =~ m/^\w+$/ in Perl 5. You have mentioned before that Perl 6 still treats the use of undefined values other than in boolean context as an error. So would applying a Rule against an undefined value produce a warning in Perl 6 or not? (A quick scan of S12 didn't say.) -- Darren Duncan
some misc Perl 6 questions
Greetings, I have just started to write a large amount of Perl 6 code, partly to help with testing the Pugs (and later Parrot) implementation of the language. During this process, I discovered a few details about Perl 6 that I don't yet understand, and haven't yet been able to get answers to in my reading of the Synopsis. So I'll ask about them here. For some of these points, I just wanted clarification on something I think I already know, and for others its just a how do I matter: 0. As I understand it, the current state of being says that all Perl 6 code will by default use strict and use warnings (y/n), unless it's a one-liner? 1. What is the behaviour of require() in regards to what it does when a module or class was previously defined in a file that was already loaded, but that file didn't have a file name that corresponded to the module or class? Eg, say a program determines at runtime that it wants to use module Foo, and that module is defined in a file named Bar that declares both the Bar and the Foo module. If the program had already loaded file Bar sometime earlier, then will require Foo use the existing declaration, or try to load a file named Foo but fail? Or will something else happen. Essentially, I want users of my module to be able to declare a data-containing module using either method, its own file or shared in another file, and my module to just see and use it. For reference, this is what I currently have to do in Perl 5: no strict 'refs'; my $package_is_loaded = defined %{$template_module_name~'::'}; use strict 'refs'; unless( $package_is_loaded ) { require $template_module_name; } $text = $template_module_name-get_text_by_key( $message.msg_key ); I do that because Perl 5 require() always attempts to load a matching file name. 2. Related to the above, if the require() of Perl 6 will indeed try to load a file with the matching name, then what is the proper way to test if a module was already loaded? Hopefully this is elegant, rather than the Perl 5 no strict 'refs' cludge. ('cludge' means anything I need to un-strict to accomplish.) 3. Does my explicit new() method get a $self: argument that is already instantiated like other methods, or do I have to do something like a bless() on my own declared variable of the class type and explicitly return that? 4. Is it possible to create a 'class' that sub-classes a 'module' or can one only subclass a 'class'. The reason I'm declaring the parent as a module is because it doesn't have any attributes, but it does have utility functions that I wish for users of multiple sub-classes to be able to invoke off of them. 5. If I have a class property defined using has Str %.foo;, and an object of the class is named $bar, then is it correct syntax to refer to the property as a whole using $bar.foo and an element using $bar.foo{'abc'}? 6. I understand that sub/method arguments are passed in read-only by default. However, if (see #2) I do a return( $bar.foo ); when will the caller getting that return value have received a reference to or a copy of the attribute? 7. Say I have 2 arrays of arrays, @foo and @bar. What is the most concise Perl 6 syntax for each of these operations in Perl 5? The Perl 5 equivalent is expressed where each is an array having array refs that are unalike in size. @foo = @bar # a shallow copy @foo = map { [EMAIL PROTECTED] } @bar # a deep copy 8. Is it possible with a sub or method argument signiture to specify that the arguments must have defined values? Or are specced non-optional arguments only guaranteed to have the correct container passed to them? 9. What does the as() method on built-in types do on a hash that has undefined values? Does it raise a use of undefined value in string warning, or just substitute the empty string? 10. When using as(), can I specify that the results get sorted? Or alternately, will hashes always serialize in the same order on all platforms, unlike in Perl 5 where its pairs come out in an apparently random order? If not, I will have to continue to do manually what as() does. Okay, that's it for my initial set of questions. Thanks in advance for any feedback, whether they are plain answers or pointers to where *exactly* in the Perl 6 spec I should successfully find the answer. -- Darren Duncan
Re: some misc Perl 6 questions
On Tue, Mar 08, 2005 at 03:50:41PM -0800, Darren Duncan wrote: : Greetings, : : I have just started to write a large amount of Perl 6 code, partly to : help with testing the Pugs (and later Parrot) implementation of the : language. During this process, I discovered a few details about Perl : 6 that I don't yet understand, and haven't yet been able to get : answers to in my reading of the Synopsis. So I'll ask about them : here. : : For some of these points, I just wanted clarification on something I : think I already know, and for others its just a how do I matter: : : 0. As I understand it, the current state of being says that all Perl : 6 code will by default use strict and use warnings (y/n), unless : it's a one-liner? Yes. : 1. What is the behaviour of require() in regards to what it does when : a module or class was previously defined in a file that was already : loaded, but that file didn't have a file name that corresponded to : the module or class? Eg, say a program determines at runtime that it : wants to use module Foo, and that module is defined in a file named : Bar that declares both the Bar and the Foo module. If the program : had already loaded file Bar sometime earlier, then will require Foo : use the existing declaration, or try to load a file named Foo but : fail? Or will something else happen. Essentially, I want users of : my module to be able to declare a data-containing module using either : method, its own file or shared in another file, and my module to just : see and use it. : : For reference, this is what I currently have to do in Perl 5: : : no strict 'refs'; : my $package_is_loaded = defined %{$template_module_name~'::'}; : use strict 'refs'; : unless( $package_is_loaded ) { : require $template_module_name; : } : $text = $template_module_name-get_text_by_key( $message.msg_key ); : : I do that because Perl 5 require() always attempts to load a matching : file name. I think Perl 6 will probably try to do the same. I suspect it's better to keep the require/use interface as a simple mapping to filename space, and let you provide a different interface that documents that you're doing something non-standard, rather than complicating the standard interface. Of course, I speak with forked tongue here, because we're already complicating the whole module system with the shortname/longname distinction in order to get control of versioning, so there probably has to be a database somewhere of mappings of each short name to all corresponding long names, and for each of those, to their compilation state and actual location. You could in principle subvert that mechanism. But I still think it'd be a mistake, unless we can make it fall out of the design naturally. : 2. Related to the above, if the require() of Perl 6 will indeed try : to load a file with the matching name, then what is the proper way to : test if a module was already loaded? Hopefully this is elegant, : rather than the Perl 5 no strict 'refs' cludge. ('cludge' means : anything I need to un-strict to accomplish.) There is no need for strict refs in Perl 6, since we distinguish symbolic naming from referential naming syntactically in most cases. But as for whether a module is loaded or not, what do you mean by module? I think the interface should allow you to ask, If I did this particular use or require, what would it actually do. Part of the return information on that would be not only whether it would load a file, but which version of the file would be loaded (or is already loaded), if you've wildcarded the version and/or author. : 3. Does my explicit new() method get a $self: argument that is : already instantiated like other methods, or do I have to do something : like a bless() on my own declared variable of the class type and : explicitly return that? Er, the invocant on a constructor is generally not $self, but $class. But anything that is declared method rather than sub gets an implicit invocant if the first arg doesn't end with ':'. You do have to do a $class.bless(%args) at some point in the constructor. A12 discusses this. (Note there are Updates since the syntax has changed over time.) The new $self is not mentioned as an argument, just returned, at least for objects of the standard opaque class. Objects emulating Perl 5 hashes and such can specify an input hash to bless--the details are delegated to the CREATE and BUILD submethods, which .bless calls implicitly. : 4. Is it possible to create a 'class' that sub-classes a 'module' or : can one only subclass a 'class'. The reason I'm declaring the parent : as a module is because it doesn't have any attributes, but it does : have utility functions that I wish for users of multiple sub-classes : to be able to invoke off of them. That sounds more like a role than a class or module. You can compose a role into a class and its methods may be inherited by subclasses. It's probably illegal to
Re: some misc Perl 6 questions
Thanks for your feedback Larry; much appreciated it is. A few more interesting things happened since then, which can be seen in the current version of Locale::KeyedText in the Pugs version control. At 5:35 PM -0800 3/8/05, Larry Wall wrote: : 8. Is it possible with a sub or method argument signiture to specify : that the arguments must have defined values? Or are specced : non-optional arguments only guaranteed to have the correct container : passed to them? I think you can place that constraint on a formal parameter with $arg of Any where { .defined } or some such. The MMD engine will simply ignore that particular signature if the constraint isn't satisfied. The biggest change is that, upon a re-reading Synopsis 12 (and 9) that was inspired by your above comment, I created some subtypes which I now use everywhere; the declarations and some examples of use are: subtype KeyName of Str where { $_.defined and $_ ne '' and $_ !~ m/\W/ } subtype KeyNameHash of Hash is shape(KeyName) of Str; # keys are of type KeyName, values of type Str subtype PkgName of Str where { $_.defined and $_ ne '' and $_ !~ m/-[a-zA-Z0-9_:]/ } subtype PkgNameArray of Array of PkgName; ... class Locale::KeyedText::Message { has KeyName $.msg_key; # str - the machine-readable key that uniquely identifies this message has KeyNameHash %.msg_vars; # hash (str,str) - named variables for messages, if any, go here method new( $class: KeyName $msg_key, KeyNameHash ?%msg_vars ) returns Locale::KeyedText::Message { my $message = $class.bless( {} ); $message.msg_key = $msg_key; $message.msg_vars = %msg_vars; # copy list values return( $message ); } ... class Locale::KeyedText::Translator { has PkgNameArray @.tmpl_set_nms; # array of str - list of Template module Set Names to search has PkgNameArray @.tmpl_mem_nms; # array of str - list of Template module Member Names to search method new( $class: PkgNameArray @set_names, PkgNameArray @member_names ) returns Locale::KeyedText::Translator { my $translator = $class.bless( {} ); $translator.tmpl_set_nms = @set_names; # copy list values $translator.tmpl_mem_nms = @member_names; # copy list values return( $translator ); } ... By using subtypes in this way, I could remove a lot of explicit input checking code from my methods, which is great. Also, the where clause is not being repeated for every argument or attribute or variable declaration. (I like SQL domains for the same reasons.) So how does that code sample look? Anything that looks like invalid Perl 6. Anything no one thought of doing before but that looks like a good idea? A question: Would has PkgNameArray @.tmpl_set_nms; do what I expect, where the array as a whole is the sub-type, or would it make an array where each element is the sub-type? : 5. If I have a class property defined using has Str %.foo;, and an : object of the class is named $bar, then is it correct syntax to : refer to the property as a whole using $bar.foo and an element : using $bar.foo{'abc'}? Yes, except that has always declares instance attributes, not class attributes. You'd want our or my instead. But as long as you declare the name with %.foo, it'll generate the accessor. However, it might be wiser to go ahead and wrap your own accessor around it that takes the subscripting out of the hands of the user, in case you want to change the representation from hash to something else. I meant to say attributes, sorry. I have my own accessors, with different names, and don't expect anyone to use the autogenerated ones. But I made the attributes public for now so that one of my classes could access the attributes of one of my other ones directly; both of these are defined in the same file. Maybe that's a bad idea, and if so I can change it. New question: Is there a way to say that two classes have a privileged relationship, sort of like a marriage, such that each can see and/or change otherwise private attributes in objects of the other class, and yet the attribute list of each class is completely different from the other? Neither of the two objects is a subclass of the other, nor fulfills a role defined by the other. For example, say that there are two closely related classes, Container and Node, where conceptually a Container object is an environment in which Node objects live. I would like to declare the attributes of both classes private from the viewpoint of all other classes, but I want Container and Node objects to be able to read or set each others' attributes directly as if they were public. Both classes have their own set of methods that outside code can invoke directly, and each kind of object can be held by external code. Also, does my request sound like something that would be reasonable to do, or a bad practice to avoid? Thank you for all the hard work you have been doing. -- Darren Duncan