Re: some misc Perl 6 questions

2005-03-10 Thread Thomas Sandlaß
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

2005-03-09 Thread Brent 'Dax' Royal-Gordon
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

2005-03-09 Thread David Storrs
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

2005-03-09 Thread Larry Wall
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

2005-03-09 Thread Thomas Sandlaß
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

2005-03-09 Thread Larry Wall
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

2005-03-09 Thread Darren Duncan
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)

2005-03-09 Thread Darren Duncan
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

2005-03-08 Thread Darren Duncan
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

2005-03-08 Thread Larry Wall
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

2005-03-08 Thread Darren Duncan
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