Re: A12: default accessors and encapsulation
John Siracusa wrote: I'd either like a way to more cleanly extend the default accessor's assignment behavior down the road (i.e. by just writing a new name() method, not by hacking away at STORE traits and adding private worker subs) or a way to auto-generate the slightly more boring default accessor shown above. There *is* a way to do the latter. In A12, Larry implies that the declarators in the body of a class definition are actually method calls on an instance of MetaClass: http://www.perl.com/pub/a/2004/04/16/a12.html?page=3#use_of_classes http://www.perl.com/pub/a/2004/04/16/a12.html?page=19#new_grammatical_categories So, presumably, by defining a new Cscope_declarator:has, you would be able to override the default accessor-generating behaviour. The least scary way to do this would be to encapsulate it in a trait that is applied to (and has its way with ;- the class declaration: class Dog is getset { has $.name is rw; ... } or perhaps is applied instead to individual attribute declarations: class Dog { has $.name is getset; ... } Alternatively, you could just *cheat* and define a macro (putting it in a lexically-scoped module for convenience and safety): module GetSet; macro getset is export(:MANDATORY) is parsed(rx:words/ ?Perl6.type? ?Perl6.attr_var/) ($attr) { my $accessor = substr $attr{attr_var}, 2; return method set_$accessor ($attr{type} $attr{$attr_var}) {} ~ method get_$accessor () { return $attr{attr_var} } ~ has $attr{type} $attr{attr_var} ; } and then: class Dog { use GetSet; getset $.name; ... } Damian
Re: backticks (or slash, maybe)
Sean O'Rourke wrote: I'm saying division is now defined such that when the numerator is a hash(-ref), the result is the set of values associated with the denominator. I've never tried to divide a hash or hashref by something without it being a bug. Right...in Perl 5. In Perl 6, a hash in a numeric context returns the number of entries it contains. So I can readily imagine: sub decimate_hash (%hash is rw) { for 1..%hash/10 { delete %hash{ pick any(keys %hash) }; } } Damian
Re: A12: Required Named Parameters Strike Back!
On Mon, Apr 19, 2004 at 01:44:53PM -0400, John Siracusa wrote: : On 4/19/04 1:30 PM, Larry Wall wrote: : On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote: : : I know we are running out of special characters, but I really, really think : : that required named parameters are a natural fit for many common APIs. A12 : : has reinforced that belief. Save me, Dami-Wan Wallnobi, you're my only : : hope... : : Well, actually, we saved you last summer when we decided to make + : mean that the parameter must be named. : : ...named and required, or named and optional? IOW, is this all true? : : sub foo(+$a, +$b) { ... } : : foo(); # compile-time error! : foo(1, 2); # compile-time error! : foo(a = 1, 2); # compile-time error! : foo(a = 1);# compile-time error! : : foo(a = 5, b = 7); # ok : foo(b = 1, a = 2); # ok Well, no, we're still stuck at run-time validation of that. In the case of methods you can't really do anything else anyway, generally speaking. For subs, we could make the compiler pay attention to something in the declaration: sub foo(+$a is req, +$b is req) { ... } sub foo(+$a = fail, +$b = fail) { ... } But I still don't think it rates a strange character of its own. Possibly there's something going on with multi subs and invocants. I'm not sure what 6.0.0 will make of a declaration like: multi sub foo(+$a, +$b: +$c) { ... } since we've told the Parrot people they don't have to worry about anything but positional parameters for 6.0.0. But none of this has much bearing on BUILD routines, which are shielded from positional semantics anyway by the fact that .bless() doesn't take any extra positional parameters. Larry
Re: A12: Required Named Parameters Strike Back!
John Siracusa asked: Well, actually, we saved you last summer when we decided to make + mean that the parameter must be named. ...named and required, or named and optional? Named and optional, by default. IOW, is this all true? sub foo(+$a, +$b) { ... } foo(); # compile-time error! No. foo(1, 2); # compile-time error! Yes. foo(a = 1, 2); # compile-time error! Yes. foo(a = 1);# compile-time error! No. foo(a = 5, b = 7); # ok foo(b = 1, a = 2); # ok Yes. Yes. You want: sub foo(+$a is required, +$b is required) { ... } Damian
Re: A12: default accessors and encapsulation
On Mon, Apr 19, 2004 at 06:53:29PM -0400, John Siracusa wrote: : Yeah, that's exactly what I don't want to type over and over :) I really don't understand what you're getting at here. First you complain that you'd rather write an ordinary method, and then you complain that you have to. Have I met someone lazier than me? :-) Larry
A12 - Protected Attributes and Methods
Apocalypse 12 was very clear about the difference between private and public class members, but it didn't say anything about protected ones? How can you define a protected member? Do you have to do the following? has $.foo is protected; method bar() is protected; Maybe we could have another secondary sigil to mark a protected method or attribute. I'd suggest the semicolon, but I'm afraid it would cause havoc with the parser. Joe Gottman
community involvement - Was: Re: backticks
Since this horse came back to life, I'm going to give it a good thrashing, and I've got goons to help me. I've asked the Phoenix Perl Mongers for their take on the situation. I've posted a _completely_ unbiased synopsis of the situation. Here are excerpts from the replies: Tony's take: Rename Perl 6 to something else. Tony never posts more than a single line in reply to anything but replies to everything. This comment appears to be in response to %foobar, the gullimets, and the behavior of %foo{shift} changing to mean %foo{'shift'} with no reguard for %foo`bar except to dismiss it. Perl 6 i going to end up looking like Morse Code. =) This was a second, seperate reply, also consisting of a single line. I corrected Tony, reminding him that Morse Code only has dots and dashes - no gullimets. Ada is the common analogy, and I reitterated this. Tony then pointed out that he worked at the Pentagon and many contractors refused to use Ada, holding out with Jovial until after the Ada push had passed. Funny that now days many government workers hold out against other languages, refusing to give up Ada. Eden's take: I like it, but I don't see why perl can't just adopt the dot like Java and C. I forgot to mention that . was unusable because Perl 6 autoboxes, so this misunderstanding was my fault, not Eden's. Eden went on with a discussion of string concatonation versus subscripting which made me nod my head. Eden also wanted to know that currying was still going to be there - yes, though it is no longer automatic. Andrew's take: Scott, I can tell you without hesitation that I /hate/ this. Mostly for the cons you've already specified. I agree wholeheartedly here, and with the poster that said, call it something besides Perl 6. In a later post, Andrew conceded that %hash`foo isn't really more complex (I pointed out that it is up in the air whether %hash`foo is more or less complex), and goes on to say: True, and I do generally like JavaScript, and do like that syntax feature. OTOH, it also looks a bit like PHP, and I generally hate PHP. I've attached my summerized pros and cons at the end for reference. Andrew writes meticulously clean Perl. He went on to express hope for reduction of complexity and fewer synonyms in Perl 6. Doug's take: Personally, I don't mind typing the {} [edited], so I don't particularly feel the need for extra syntax. ... I probably just won't use the new syntax. The new syntax was used to describe %foo`bar specifically. Doug is the head Perl monger and an unfailing voice of reason. Victor's take: I've worked in APL. Terse is *not good*. (Although having matrix inversion built into the language definitely rocks.) Sign me stuck in the mud. If the mud is Perl 5.8, it's not half bad. Victor wrote a two page email that was interesting and entertaining. I've attached a slightly edited version to the end of this document. Michael's take: ... I'd vote against using backtick in this instance. For one thing, it'll throw my editor's syntax coloring off, because it assumes that you'll always have a matched pair. :-) In general, though, I'm with the group that says there's nothing wrong with being verbose. I'd rather have a clear %foo{bar()} and %foo{'bar'} which fit my existing ideas of programming syntax* than something involving single quote marks. But, TMTOWTDI, and since I'll never use the single backtick in any related context, it really doesn't matter for my personal coding. Michael went on to praise Perl, in its current incarnation, for still being readable by programmers of other languages, citing ==, =, , and so on, concluding that standard usage of symbols is a Good Thing, even though it stretches the use of the symbols a bit. Michael also writes Java and has shown disposition towards clean code, having done an excellent presentation on writing tests as a way to life and increased productivity. Summary: I'm doing this as an experiment towards community interest - both generating it and making it visible. Unlike PerlMonks or IRC, Phoenix Perl Mongers is a reasonable representation of people who use Perl - PerlMonks, IRC, and lists tend to attract power users, academiacs, and hackers. This makes Phoenix Perl Mongers an interesting test bed. They're largely professional Perl programmers. They show up to presentations that expose how other companies are using Perl, share time saving techniques, and explain how difficult problems were solved. Examples of production code draw crowds. Academic topics and advanced features are less interesting, but there is an interest in how things are done outside of the Perl world. 5 people believe they wouldn't use %foo`bar. 1 person likes it. Resolve not to use it seemed to be the common message. Only a few people hinted that they would prefer it not be in the language at all, suggesting that there are too many ways (or agreeing with that point in the Cons). More people cited TMTOWTDI than complained of too many
Re: A12 - Protected Attributes and Methods
On Mon, Apr 19, 2004 at 08:21:58PM -0400, Joe Gottman wrote: :Apocalypse 12 was very clear about the difference between private and : public class members, but it didn't say anything about protected ones? How : can you define a protected member? You can't. The concept of protected does not exist in Perl 6. A class is encapsulated even from its subclasses. Larry
Re: A12: default accessors and encapsulation
On 4/19/04 7:20 PM, Larry Wall wrote: On Mon, Apr 19, 2004 at 06:53:29PM -0400, John Siracusa wrote: : Yeah, that's exactly what I don't want to type over and over :) I really don't understand what you're getting at here. First you complain that you'd rather write an ordinary method, and then you complain that you have to. Have I met someone lazier than me? :-) Possibly :) Here's what I'm saying. In the first version of a class, there will probably be a lot of simple get/set attributes. It's convenient not to have to write any explicit methods for those. If I accept the default accessors that you get for free when a class has $.foo is rw, then that means the users of my class can do $obj.foo = whatever in order to set the foo attribute. That's fine...until, some day down the road, I decide that getting and/or setting the foo attribute needs to do something a bit more complex. Or maybe I remove the $.foo attribute all together and replace it with a collection of other attributes or something. I can do that by writing my own foo() method, but there's the problem of all the existing code out there that says $obj.foo = whatever. In order to continue to support that, I have to provide an lvalue. As has been pointed out, I can use will STORE to add the extra behavior while continuing to use $.foo (or a proxy object, yadda) as my lvalue. But I find that slightly kludgy. If the default accessor had instead been defined like (the Perl 6 equivalent) of this: sub name { @_ 1 ? $_[0]-{'foo'} = $_[1] : $_[0]-{'foo'} } then I wouldn't have any existing code doing $obj.foo = whatever to worry about. So extending my foo() accessor by writing my own method would be straight-forward. Another alternative is to have a simpler, more direct way to continue to support the $obj.foo = whatever semantics by writing a particular kind of foo() method. I don't like piling the side effects into a will STORE trait, since in version 4.0 of my class there could be a ton of code hanging off that hook. It just looks like the wrong place to put that. I'd rather have all the fancy things done when I call $obj.foo() defined in method foo { }. A final alternative is to never use the default accessor that I get when my class has $.foo is rw because that means having to support $obj.foo = whaever semantics forever and ever. But that means I have to write (the Perl 6 equivalent of) this: sub name { @_ 1 ? $_[0]-{'foo'} = $_[1] : $_[0]-{'foo'} } for every single attribute. That's tiresome. Basically, I'm wondering exactly who is the target audience for the default accessor? It seems to tie the API to a very confining set of behaviors, and expose more of the internals of a class than I'd like. If $ob.foo will really never expand beyond a simple get/set interface to an attribute, it works fine. But that's rarely true in the long term, IME. It also, I think, creates an artificial distinction between those simple attributes that users can expect to set with $obj.foo = whatever, and the more complex attributes that must be set with $obj.foo(whatever). I'd like more symmetry in my APIs, but then I'm faced with the options describe above, none of which are as appealing as I'd like. I think others will also value API symmetry and will therefore either create their own old-style accessors everywhere, or (more likely) go to heroic measures to support $obj.foo = whatever everywhere, forever, probably by dangling 80% of their attribute accessor methdod code off of will STORE hooks by the time version 4.0 cof their class rolls around. That's not pleasant, IMO. -John
Re: A12: Required Named Parameters Strike Back!
On 4/19/04 9:05 PM, Damian Conway wrote: You want: sub foo(+$a is required, +$b is required) { ... } Yes, that would be just fine :) -John
Re: A12: default accessors and encapsulation
On 4/19/04 10:04 PM, Damian Conway wrote: John Siracusa wrote: I'd either like a way to more cleanly extend the default accessor's assignment behavior down the road (i.e. by just writing a new name() method, not by hacking away at STORE traits and adding private worker subs) or a way to auto-generate the slightly more boring default accessor shown above. There *is* a way to do the latter. In A12, Larry implies that the declarators in the body of a class definition are actually method calls on an instance of MetaClass [...] So, presumably, by defining a new Cscope_declarator:has, you would be able to override the default accessor-generating behaviour. Ooo, that would be neat. The least scary way to do this would be to encapsulate it in a trait that is applied to (and has its way with ;- the class declaration [...] or perhaps is applied instead to individual attribute declarations Either of those looks okay...well, maybe Damian okay which is a slightly different standard ;) Alternatively, you could just *cheat* and define a macro That's a bit much for me. I mean, yeah, sure, you can basically do anything that way, but come on. I dread what you will do with (or is that to) Perl 6 once it's released... ;) -John
Re: A12: default accessors and encapsulation
On 4/20/04 1:25 AM, Luke Palmer wrote: John Siracusa writes: The will STORE stuff covers the easy cases, but can I extend it all the way up to a name() that's a multimethod with a ton of optional args? I supposed you can (technically) do all of that with will STORE, but it seems an odd place for what would more naturally be code in the name() method itself. I think a role on the attribute is not the right place to put it. What you're doing is returning a proxy object that knows how to set both the name and the gender. That's a bit too example-specific. Really what I was getting at was arbitrary, simple extensibility to do anything in response to $obj.foo (with and without args) down the road, not just to do the specific thing that I described in my example. With a boring Perl 5 style get/set accessor API, I can just rewrite method foo { } until the cows come home. I find that a lot more straight-forward than the role playing you describe, but YMMV :) -John
Re: backticks
On Fri, 16 Apr 2004 23:45:48 +0200, Juerd wrote: Jonathan Scott Duff skribis 2004-04-16 15:51 (-0500): Except that you've put things in this explanation that shouldn't be there IMHO. The %varnamekey is a special case, but not of getting a single item from a hash, rather it's a special case of a one element list generated from evaluating to the element. So, if you remove that bit, it's the same as the two below just with different syntax. I think %hashkey key key is best explained as %hash{ key key key } with implicit curlies, not as an alternative to curlies. In that case, why aren't you suggesting something more in line with that? Here's what I'd like to see instead of your suggestion: %hashkey key key === %hash{key key key} %hash'key'=== %hash{'key'} %hashkey=== %hash{key} That has * as few keystrokes as perl5's $hash{key} * delimiters at both ends, so you can even use non-bareword constants * existing syntax reused in the same way as the variant * interpolation allowed in the double quoted variant. That said, I really wish we could keep perl5's $hash{key}. It's obviously a subscript, and I use constant bareword keys much more frequently than zero-arg sub/builtin calls in hash subscripts. -- Peter Haworth [EMAIL PROTECTED] The capacity of human beings to bore one another seems to be vastly greater than that of any other animals. some of their most esteemed inventions have no other apparent purpose, for example, the dinner party of more than two, the epic poem, and the science of metaphysics. -- H. L. Mencken
Re: A12: default accessors and encapsulation
Let me just chime in with my support for John's basic idea. I would definitely prefer that it be easy to arrange things such that $obj.foo = 'bar' winds up invoking a method on $obj with 'bar' as an argument, rather than invoking a method on $obj that returns an lvalue to which 'bar' is then assigned. (Yes, like Ruby's def foo=; I have a Rubyometer and I'm not afraid to use it!) It doesn't need to be the default rw accessor behavior, but I would like it to be accomplishable without jumping through a lot of hoops. -Mark
Re: A12: Required Named Parameters Strike Back!
At 9:50 AM -0400 4/20/04, John Siracusa wrote: On 4/19/04 7:16 PM, Larry Wall wrote: Well, no, we're still stuck at run-time validation of that. In the case of methods you can't really do anything else anyway, generally speaking. Why is that? Because at compile time all you have is a generic thing, a (possibly indirectly accessed) method name, and a list of parameters. There's no good way to tell which method will ultimately be called, and validating against all declared methods of that name won't get you anything useful there since the result's likely going to be pretty contradictory. since we've told the Parrot people they don't have to worry about anything but positional parameters for 6.0.0. Can we do some magic behind the scenes that will make required named params look positional to parrot? Maybe. There are issues of indirect named parameters (where you pass in a scalar ref to a pair, which if I've read properly should be treated as a named parameter) though we could have the compiler shift 'em all to the end. The problem there is that positional parameters have to maintain their position of the destination sub has no names--we can't go reordering things for subs that do the traditional: sub foo { my ($bar, $baz, $plugh) = @_; } in that case the positional parameters need to stay where they are. They also can't move if the destination sub or method doesn't do named parameters (because either it doesn't or it's not perl 6) since in that case the named parameters need to degrade nicely (and in place) to their values. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: A12: Required Named Parameters Strike Back!
On 4/20/04 10:42 AM, Dan Sugalski wrote: At 9:50 AM -0400 4/20/04, John Siracusa wrote: On 4/19/04 7:16 PM, Larry Wall wrote: Well, no, we're still stuck at run-time validation of that. In the case of methods you can't really do anything else anyway, generally speaking. Why is that? Because at compile time all you have is a generic thing, a (possibly indirectly accessed) method name, and a list of parameters. There's no good way to tell which method will ultimately be called, and validating against all declared methods of that name won't get you anything useful there since the result's likely going to be pretty contradictory. Hm, so how would the is required trait that Damian posted work? Would it simply be shorthand for a run-time check that I don't have to write myself? I was under the impression that it would work the way I described earlier: sub foo(+$a is required, +$b is required) { ... } foo(); # compile-time error! foo(1, 2); # compile-time error! foo(a = 1, 2); # compile-time error! foo(a = 1);# compile-time error! foo(a = 5, b = 7); # ok foo(b = 1, a = 2); # ok It really is a shame about the inability to do it at compile-time with methods, but shorthand for a run-time check in that case would be welcome too :) -John
Re: A12: Required Named Parameters Strike Back!
At 10:51 AM -0400 4/20/04, John Siracusa wrote: On 4/20/04 10:42 AM, Dan Sugalski wrote: At 9:50 AM -0400 4/20/04, John Siracusa wrote: On 4/19/04 7:16 PM, Larry Wall wrote: Well, no, we're still stuck at run-time validation of that. In the case of methods you can't really do anything else anyway, generally speaking. Why is that? Because at compile time all you have is a generic thing, a (possibly indirectly accessed) method name, and a list of parameters. There's no good way to tell which method will ultimately be called, and validating against all declared methods of that name won't get you anything useful there since the result's likely going to be pretty contradictory. Hm, so how would the is required trait that Damian posted work? Would it simply be shorthand for a run-time check that I don't have to write myself? Yes. It may have the added advantage of continuing the search for a sub that matches--that is, we could continue on as if we'd not found the sub and then hit MMD. Or not. I could see it going either way. It really is a shame about the inability to do it at compile-time with methods, but shorthand for a run-time check in that case would be welcome too :) Everybody's OO gets hit this way, unless you get really vicious with the signatures of overridden methods. (If they're all the same it's easier) Perl's really dynamic nature makes it tough for subs, too. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: backticks
Peter Haworth skribis 2004-04-20 14:56 (+0100): I think %hashkey key key is best explained as %hash{ key key key } with implicit curlies, not as an alternative to curlies. In that case, why aren't you suggesting something more in line with that? Here's what I'd like to see instead of your suggestion: %hashkey key key === %hash{key key key} %hash'key'=== %hash{'key'} %hashkey=== %hash{key} That has * as few keystrokes as perl5's $hash{key} * delimiters at both ends, so you can even use non-bareword constants * existing syntax reused in the same way as the variant * interpolation allowed in the double quoted variant. Hm, not bad. Doesn't do anything to arrays yet, but I like the idea. We could maybe even treat hashes and arrays as list operators. That would allow whitespace, and also: @array 15 But I liked about the backtick that it's special syntax, which makes it recognisable. Still, your idea is doable. Juerd
Re: A12: default accessors and encapsulation
Mark J. Reed wrote: Let me just chime in with my support for John's basic idea. I would definitely prefer that it be easy to arrange things such that $obj.foo = 'bar' winds up invoking a method on $obj with 'bar' as an argument, rather than invoking a method on $obj that returns an lvalue to which 'bar' is then assigned. (Yes, like Ruby's def foo=; I have a Rubyometer and I'm not afraid to use it!) It doesn't need to be the default rw accessor behavior, but I would like it to be accomplishable without jumping through a lot of hoops. -Mark It sounds a lot like C#'s properties, which are in my opinion one of the best things in C#. Nice easy syntax for those as well, although I can't remember it well enough right now to give an example, as I don't generally keep a C# reference lying around at work where I never use it. Effectively though, if you have an object foo with a property bar, things like foo.bar = 5; seem to get turned into foo.set_bar(5); where set_bar() was pulled from the property declaration's set {} block, where some magic goes on. However, it would appear that what John is asking for is already possible, just not necessarily particularly obviously, as returning a proxy object to act as the lvalue and then do the appropriate magic would work, but seems a little mucky. Even if that's what happens behind the scenes. On the other hand, just as a thought from a crazy C++er, couldn't you accomplish a similar effect by defining your $.foo attribute to be of a custom class, then overriding the = operator for that class... I know, messy messy. Don't go that way. I shouldn't even have thought of it.
RE: A12: default accessors and encapsulation
-Original Message- From: Mark J. Reed [mailto:[EMAIL PROTECTED] Let me just chime in with my support for John's basic idea. I would definitely prefer that it be easy to arrange things such that $obj.foo = 'bar' winds up invoking a method on $obj with 'bar' as an argument, rather than invoking a method on $obj that returns an lvalue to which 'bar' is then assigned. (Yes, like Ruby's def foo=; I have a Rubyometer and I'm not afraid to use it!) It doesn't need to be the default rw accessor behavior, but I would like it to be accomplishable without jumping through a lot of hoops. A problem with $obj.foo = 'bar'; getting converted to $obj.set_foo('bar'); (or whatever) is that set_foo may not have lvalue semantics. That is, it may not behave appropriately by returning an lvalue object for use in cascading assignment constructs: $obj.foo = $obj.baz = 'bar'; Hanging the behavior off Cwill STORE and/or Cwill FETCH has the benefit of P6 doing some or all of the work for you. has $.foo will STORE { .:set_foo($^value); } submethod :set_foo($new_foo) {...} ... $obj.foo = 'bar'; A better solution to your scenario is to 6PAN a new MetaClass that does what you want: use AccessorClasses; accessor_class Object { has $.foo is rw; method :set_foo($new_foo, ?$optional_extra) {...} method :get_foo() {...} } A simple, easily bundled grammar mod that automatically generates the Cwill STORE logic for you, provided that you follow a simple xxx_ method naming convention. =Austin
A12: Storage class/class traits
One of the things that got a little less clear with A12 was the idea of multiple Cis clauses. Once upon a time, we talked about: my $spot is Dog is const is persistent is ...; Obviously some of those are traits, now. However, I'm wondering how to handle things like my recent suggestion of a class (metaclass instance) that generated different accessor behavior. The obvious way was: use GrammarMod; # use AccessorClass; NewKeyword thing {...} # accessor_class thing {...} but isn't there a better way? In particular, is there some way for the trait to declare that it modifies the metaclass, not the class, so that: use GrammarMod; # use AccessorClass; class thing is NewKeyword {...} # class Obj is accessor_class { has $.foo is rw; } would be able to change the metaclass behavior, not the class behavior? At first blush, this is a macro: class OtherBehavior is MetaClass {...} # class AccessorClass is MetaClass {...} macro NewKeyword is parsed(Perl6::ClassDecl) { $0.meta_class = new OtherBehavior; } but then there's the issue of composition. Perhaps the accessor function behavior is a role, but it seems more like a MetaRole: macro NewKeyword is ... { $0.meta_class will do OtherRole; } Comment? =Austin
Re: A12: default accessors and encapsulation
Mark J. Reed writes: Let me just chime in with my support for John's basic idea. I would definitely prefer that it be easy to arrange things such that $obj.foo = 'bar' winds up invoking a method on $obj with 'bar' as an argument, rather than invoking a method on $obj that returns an lvalue to which 'bar' is then assigned. (Yes, like Ruby's def foo=; I have a Rubyometer and I'm not afraid to use it!) It doesn't need to be the default rw accessor behavior, but I would like it to be accomplishable without jumping through a lot of hoops. Okay, well, I thought that my example did that, but apparently using Cwill get and Cwill set is a little too complex... (my sentiments are beginning to follow Larry's, in that I'm not sure you know what you want -- perhaps you could give a hypotheical syntax?) So, what you really want is a way so that: $obj.foo = 'bar'; Is translated into: $obj.foo('bar'); When you get rid of C$.foo and replace it with a Cfoo method. This is doable (without a syntax munge), but it requires some cleverness. First I'll do it by hand, then I'll wrap it up in a trait. Please realize that all this I'm doing is an *implementation* of a very easy usage. class Dog { class :FooProxy { has $.method; multi sub infix:= (FooProxy $proxy, Any $val) { $.method($val); } } method foo_call (?$arg) { # accessor code here } method foo ($self:) is rw { FooProxy.new(method = { $self.foo_call($_) }) } } That should turn: $obj.foo = 'bar'; Into: $obj.foo('bar'); And now we want to wrap that up so we can just say Cis accessor: role accessor { class :Proxy { has $.method; multi sub infix:= (Proxy $proxy, Any $val) { $.method($val); } } multi sub trait_auxiliary:is (accessor $a, code is rw: ?$arg) { my sub access (::_ $self:) { Proxy.new(method = { code($self: $_) }) } code = access; } } There. Now here's the important part: in order to *use* all this, you import whatever module defines it, and then say: class Dog { method foo (?$arg) is accessor { # accessor code here } } If that's not easy enough for you, well, you're probably out of luck. Luke
Re: A12: Storage class/class traits
Austin Hastings writes: One of the things that got a little less clear with A12 was the idea of multiple Cis clauses. Once upon a time, we talked about: my $spot is Dog is const is persistent is ...; Obviously some of those are traits, now. However, I'm wondering how to handle things like my recent suggestion of a class (metaclass instance) that generated different accessor behavior. The obvious way was: use GrammarMod; # use AccessorClass; NewKeyword thing {...} # accessor_class thing {...} but isn't there a better way? In particular, is there some way for the trait to declare that it modifies the metaclass, not the class, so that: use GrammarMod; # use AccessorClass; class thing is NewKeyword {...} # class Obj is accessor_class { has $.foo is rw; } I imagine you would just replace $.meta in the argument to trait_auxiliary:is. Or you could just define a new scope_declarator that knew how to modify the class appropriately. Luke
Re: backticks
Juerd writes: Peter Haworth skribis 2004-04-20 14:56 (+0100): I think %hashkey key key is best explained as %hash{ key key key } with implicit curlies, not as an alternative to curlies. In that case, why aren't you suggesting something more in line with that? Here's what I'd like to see instead of your suggestion: %hashkey key key === %hash{key key key} %hash'key'=== %hash{'key'} %hashkey=== %hash{key} That has * as few keystrokes as perl5's $hash{key} * delimiters at both ends, so you can even use non-bareword constants * existing syntax reused in the same way as the variant * interpolation allowed in the double quoted variant. Hm, not bad. Doesn't do anything to arrays yet, but I like the idea. We could maybe even treat hashes and arrays as list operators. That would allow whitespace, and also: @array 15 Yeah, look at that! Wow. What a spectacle. Gee, if it weren't in severe violation of RFC 28 I'd jump on the idea. Luke [1] http://dev.perl.org/perl6/rfc/28.pod
Re: A12: default accessors and encapsulation
On Tue, 20 Apr 2004, Luke Palmer wrote: There. Now here's the important part: in order to *use* all this, you import whatever module defines it, and then say: class Dog { method foo (?$arg) is accessor { # accessor code here } } If that's not easy enough for you, well, you're probably out of luck. It would be even easier if we could put the read-accessor-code and write-accessor-code in different methods. class Dog { multi method foo { ... } multi method foo ($arg) is accessor { ... } } With this syntax, either method could be simply be omitted to create a read-only or write-only accessor. The tricky part is getting the trait on foo($) to override foo() correctly. ~ John Williams
Re: A12: default accessors and encapsulation
John Williams writes: On Tue, 20 Apr 2004, Luke Palmer wrote: There. Now here's the important part: in order to *use* all this, you import whatever module defines it, and then say: class Dog { method foo (?$arg) is accessor { # accessor code here } } If that's not easy enough for you, well, you're probably out of luck. It would be even easier if we could put the read-accessor-code and write-accessor-code in different methods. class Dog { multi method foo { ... } multi method foo ($arg) is accessor { ... } } Ugh! That's what I originally suggested, and it was shot down it was. My first solution to your problem introduced the traits Cget and Cset, allowing you to write it like this: class Dog { method foo () will get { ... } will set { ... } { } # usually empty } I guess I bogged down that message with the implementation, so the result may have been easy to miss. Luke
Re: A12: default accessors and encapsulation
On 2004-04-20 at 10:51:47, Luke Palmer wrote: I guess I bogged down that message with the implementation, so the result may have been easy to miss. That is what happened in my case. Apologies; it looks like your original solution would do the job nicely. As long as the requisite module comes standard I'd be satisfied. :) -- Mark REED| CNN Internet Technology 1 CNN Center Rm SW0831G | [EMAIL PROTECTED] Atlanta, GA 30348 USA | +1 404 827 4754
Re: A12: default accessors and encapsulation
On 4/20/04 12:14 PM, Luke Palmer wrote: Okay, well, I thought that my example did that, but apparently using Cwill get and Cwill set is a little too complex... (my sentiments are beginning to follow Larry's, in that I'm not sure you know what you want -- perhaps you could give a hypotheical syntax?) There are a couple of solutions, each with some syntax. Here they are, in no particular order: * Provide a second kind of default accessor class Foo; has $.foo is accessor; # or whatever, pick a name With that has line alone, you auto-magically get an accessor that works like this: $obj.foo# get value of $.foo $obj.foo(5) # set $.foo = 5 Why this is useful: It doesn't require you to write anything other than the has line, and it provides a clean, simple way to extend the foo() accessor later in the life of the class by actually writing a foo() method. Unlike the is rw default accessor, there's no fear that any code will exist that says $obj.foo = whatever. I also think it's a more sensible default than the is rw semantics (*unless* the solution below is implemented). Training people to use the default is rw accessors only to have to explain later about all the hoops they will have to jump through in order to maintain that API when the foo method gets more complex is not my idea of a good time. * Provide a simple(r) way to easily support the $obj.foo = whatever behavior in perpetuity for any method. There are a few ways this could be done. One suggestion was to somehow appropriately remap this: $obj.foo = 5; to this: $obj.foo(5); once foo() mutates from an is rw default accessor to a full-blown method foo(...) { } I briefly entertained this solution in one of my earlier posts, but I think it's not a good idea. It's a good description of the type of behavior I want, but I don't like futzing with infix:= in order to get it. Another solution is to have a way to tell method foo() to yank its arg out of the rvalue if called as an lvalue. I don't have any good ideas about this syntax, but here's the overview: # Version 1.0 class Foo; has $.foo is rw; ... $obj.foo; # get $obj.foo = 5; # set Then: # Version 4.0 class Foo; has $.foo; # or maybe $.bar or anything else method foo(?$arg) { # The magic happens in the line below $arg = the rvalue if(caller wants lvalue); # Do all sorts of crazy stuff, possibly involving $.foo, possibly not ... return something; # maybe $.foo, maybe not } $obj.foo; # get $obj.foo(5); # set $obj.foo = 5; # still works, equivalent to $obj.foo(5) All the code for maintaining the ability to do $obj.foo = whatever is in the foo() method itself. It's not hanging off the $.foo attribute, and there may no longer even be a $.foo attribute anymore. The fact that a $.foo attribute existed at all was an implementation detail in version 1.0 of class Foo, IMO. I think all of these solutions are simpler and cleaner than the STORE hooks, proxy objects, roles, and macros that have been suggested (all of which seem like they'd work, FWIW). -John
Final Answer [Was: backticks]
Okay, let's put this one to rest. I've suspended judgement long enough. Let me first say that I have my own personal biases, and they are towards keeping things visually and psychologically distinctive, rather than towards reducing keystrokes. (Though I have enough arthritis in my hands to at least empathize with the latter view.) Leaving aside the use of C`` as a term for the moment, we will not use C` as an operator in the core. I tend to classify it into the same visual category as the widely scorned C¦ operator. I have to think (and squint) for way too long when I see one. It reminds me (irrationally, I admit) too much of $foo'bar. It's a form of dangling syntax, and I tend to prefer constructs with a beginning and an end when I can get 'em. The flip side is that, since we won't use C` as an operator in Perl 6, you're free to use it to introduce any user-defined operators you like, including a bare C`. All is fair if you predeclare. Most languages won't even give you that... But I think C«» is much more visually distinctive, and I don't mind biasing the language in favor of it for reasons of readability. It helps people separate the code from the data visually, and that's a win in the Perl world (if not in the Lisp world). The C{shift} nonsense was a mistake, even if I did persuade people to get used to it. It is my firm resolve to persuade people to get used to different mistakes this time. :-) As for Cqx//, it probably needs to be completely rethought anyway, along with Csystem. Perhaps both will be subsumed under a Crun function of some sort. But that's for a future Apocalypse. Larry
Re: A12: default accessors and encapsulation
On Tue, 20 Apr 2004, Luke Palmer wrote: John Williams writes: On Tue, 20 Apr 2004, Luke Palmer wrote: There. Now here's the important part: in order to *use* all this, you import whatever module defines it, and then say: class Dog { method foo (?$arg) is accessor { # accessor code here } } If that's not easy enough for you, well, you're probably out of luck. It would be even easier if we could put the read-accessor-code and write-accessor-code in different methods. class Dog { multi method foo { ... } multi method foo ($arg) is accessor { ... } } Ugh! That's what I originally suggested, and it was shot down it was. My first solution to your problem introduced the traits Cget and Cset, allowing you to write it like this: class Dog { method foo () will get { ... } will set { ... } { } # usually empty } I guess I bogged down that message with the implementation, so the result may have been easy to miss. Well, I think we've come full circle. The get/set is the same as the presumed current implementation, just with different keywords: class Dog { has $.foo will FETCH { ... } will STORE { ... } ; } I'm not saying there is anything wrong with that, but John Siracusa is asking for something different, I think. A simple accessor which looks like a method without having to play with Proxy, FETCH, STORE, etc. If it still looks like $obj.foo = 1 outside the class, that's good too. (Delphi and C# can do it; why can't we?) Getting the multi-methods foo()/foo($) to automagically act as the reader/writer for a virtual foo attibute seems like it would fulfill his requirements. foo() already works for the reader, but foo($) needs some help to make $obj.foo = 1 call $obj.foo(1). Here's a feeble attempt to do what I suggested: role accessor { has $.accessor = 1; multi sub trait_auxiliary:is( accessor $trait, meth(Any) ) { my $class = meth.meta.class; class $class is extended { # class methods take precedence, so install a method # in the class is default so it gets called first multi method $meth.meta.name () is default { return my $proxy is Proxy ( STORE = { meth($^val) }, FETCH = { my ($reader) = grep !$_.meta.default , $class.meta.getmethods; $reader; }, ); } } $meth does accessor; } } class Dog { multi method foo { ... } multi method foo ($arg) is accessor { ... } } my Dog $spot; $spot.foo++; ~ John Williams
A12: Strings
Well, I have a lot to digest, but off the top of my head (and having nothing to do with objects, but rather the string discussion at the end), it would be very useful if I could assert: no string complex; or something like that. That is to say, I would love to have a way to say that my strings are just plain old C-style arrays of 8-bit characters. I know that at a low level Parrot is still going to have its way with these, but at the very least, I want to be able to put the tag in there (lexically or otherwise) to make me feel better about myself as a human being when I do: my $n = ''; for @stuff - $_ {$n ~= (defined($_)??1::0)} my $stuff_as_bitvec = pack(b*,$n); %state_is_known{$stuff_as_bitvec} = 1; It's going to be hard for me to accept that that operation is going to have to worry about codepoints... really hard. Especially so if I'm doing this is a tight loop as I was recently. I suppose if there were a type: my Octets $stuff_as_bitvec = ''; ... Then that would be a start, but even then what of the hashing operation? Will there be some property of a hash I have to set too? class Octets_Num_Pair is Pair { my Octets $.key; my Num $.val; ... redefine key management in terms of Octets ... } my Octets_Num_Pair %state_is_known; Is that right, or would there be a key_type property on hashes? More to the point, is it worth it, or will I be further slowing down hash access because it's special-cased in the default situation? -- Aaron Sherman [EMAIL PROTECTED] Senior Systems Engineer and Toolsmith It's the sound of a satellite saying, 'get me down!' -Shriekback
Re: A12: default accessors and encapsulation
On Tue, Apr 20, 2004 at 01:15:24PM -0400, John Siracusa wrote: : With that has line alone, you auto-magically get an accessor that works : like this: : : $obj.foo# get value of $.foo : $obj.foo(5) # set $.foo = 5 I don't care what syntactic sugar you put underneath, but if you expose this interface to the user, it's fundamentally flawed. This is my argument from the Apocalypse, and it hasn't changed. It's wrong to introduce a fundamental asymmetry that breaks the contract that an accessor can be used as a variable. The arguments to an accessor should function as part of the long name of whatever it is you're setting, whether it's concrete or abstract. Some of those arguments may want to be optional, or have other weirdnesses that get introduced as your interface develops. Having an extra argument on the end just totally screws up that sort of extensibility. So do whatever you like to the declarations, but make sure you preserve the symmetry and extensibility of $obj.foo([EMAIL PROTECTED], *%NONSENSE) # get value of $.foo $obj.foo([EMAIL PROTECTED], *%NONSENSE) = 5 # set $.foo = 5 And while you're at it, make sure your syntactic sugar doesn't force people to duplicate the code to process [EMAIL PROTECTED] and *%NONSENSE in their getter and setter. Them's the specs. Larry
Re: A12: default accessors and encapsulation
On 4/20/04 2:37 PM, Larry Wall wrote: On Tue, Apr 20, 2004 at 01:15:24PM -0400, John Siracusa wrote: : With that has line alone, you auto-magically get an accessor that works : like this: : : $obj.foo# get value of $.foo : $obj.foo(5) # set $.foo = 5 I don't care what syntactic sugar you put underneath, but if you expose this interface to the user, it's fundamentally flawed. This is my argument from the Apocalypse, and it hasn't changed. It's wrong to introduce a fundamental asymmetry that breaks the contract that an accessor can be used as a variable. Er, I think we have different definitions of accessor. I'm perfectly happy to never allow anyone to do $obj.foo = whatever. I just don't want to write trivial methods that get and set an attribute behind the scenes. -John
Re: A12: default accessors and encapsulation
On 2004-04-20 at 11:37:18, Larry Wall wrote: So do whatever you like to the declarations, but make sure you preserve the symmetry and extensibility of $obj.foo([EMAIL PROTECTED], *%NONSENSE) # get value of $.foo $obj.foo([EMAIL PROTECTED], *%NONSENSE) = 5 # set $.foo = 5 And while you're at it, make sure your syntactic sugar doesn't force people to duplicate the code to process [EMAIL PROTECTED] and *%NONSENSE in their getter and setter. Works for me. I just want to make sure that it's easy to write classes that preserve that interface when there *is* no $.foo within the implementation of the class. After all, the point of abstraction is to hide implementation details, so it shouldn't matter to the caller whether or not the attribute exists. And the fact that it looks like it exists to the caller shouldn't force the implementation to manufacture attributes just because otherwise there's no lvalue to return for assignment purposes. As a trivial example, imagine that I want a class Length that lets me do conversions: my $len = new Length(furlongs = 10) say $len.feet == 6600.0132 $1en.feet = 6 say $len.meters == 1.8288 say $len.furlongs == 0.0090908909 Ideally, the implementation of this class should consist of a single attribute to store the length (in whatever it considers to be the canonical units), a conversion table, and a single AUTOLOAD/method_missing/whatever method which does conversions based on (a) the name by which its invoked and (b) whether it's invoked as an lvalue or rvalue. -Mark
Re: A12: default accessors and encapsulation
On Tue, 2004-04-20 at 15:40, John Siracusa wrote: On 4/20/04 2:37 PM, Larry Wall wrote: It's wrong to introduce a fundamental asymmetry that breaks the contract that an accessor can be used as a variable. Er, I think we have different definitions of accessor. I'm perfectly happy to never allow anyone to do $obj.foo = whatever. I just don't want to write trivial methods that get and set an attribute behind the scenes. Eh? Why would you never allow anyone to use a simple syntax? $oldfoo = $obj.foo; $obj.foo = 1; What's the problem here? No having to write trivial methods, no complexity. What Larry's trying to get at is that: $status = $thread_shared_data.status(lock=1); could be defined as a multi which gets the value of the status variable, but also asserts that thread synchronization or some form of threadsafe locking must be performed. You're not SETTING status, you're reading it, but you are passing parameters to the read accessor. How do you do that if parameters force a write? -- Aaron Sherman [EMAIL PROTECTED] Senior Systems Engineer and Toolsmith It's the sound of a satellite saying, 'get me down!' -Shriekback
Re: A12: default accessors and encapsulation
John Williams wrote: class Dog { has $.foo will FETCH { ... } will STORE { ... } ; } I'm not saying there is anything wrong with that, but John Siracusa is asking for something different, I think. A simple accessor which looks like a method without having to play with Proxy, FETCH, STORE, etc. If it still looks like $obj.foo = 1 outside the class, that's good too. (Delphi and C# can do it; why can't we?) C# does it as public int buffersize { get { return my_buffer.length(); } set { //[1] double sqrt=Math.sqrt(value);//value is a keyword in C# // because of this feature. if(Math.floor(sqrt) == sqrt) { my_buffer=new byte[value]; } else { throw new InvalidArgumentException( Value is not a power of two ); } } } How different is that from: method buffersize() will fetch { +$.buffer.bytes } will store { my $sqrt=$^v.sqrt; die $^v is not a power of two unless int($sqrt) == $sqrt; $.buffer = \x[0] x $^v; } {} Or even (my suggestion): method buffersize() will store { my $sqrt=$^v.sqrt; die $^v is not a power of two unless int($sqrt) == $sqrt; $.buffer = \x[0] x $^v; } { +$.buffer.bytes } ? Of course, the best way to implement that would probably be something like: our type Buffer ::= ByteString where { int sqrt +.bytes == sqrt +.bytes }; has Buffer $.buffer; But that's neither here nor there... [1] I'm certain there's a more efficient way to do this test, probably involving bit twiddling. Whatever. -- Brent Dax Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker Oceania has always been at war with Eastasia.
Re: A12: default accessors and encapsulation
On 4/20/04 4:08 PM, Aaron Sherman wrote: On Tue, 2004-04-20 at 15:40, John Siracusa wrote: On 4/20/04 2:37 PM, Larry Wall wrote: It's wrong to introduce a fundamental asymmetry that breaks the contract that an accessor can be used as a variable. Er, I think we have different definitions of accessor. I'm perfectly happy to never allow anyone to do $obj.foo = whatever. I just don't want to write trivial methods that get and set an attribute behind the scenes. Eh? Why would you never allow anyone to use a simple syntax? $oldfoo = $obj.foo; $obj.foo = 1; What's the problem here? The problem is when foo() becomes a complex method some time in the future. It's some work to upgrade foo from a simple is rw attribute to a full-blown method while also maintaining the end user's ability to say $obj.foo = whatever. What Larry's trying to get at is that: $status = $thread_shared_data.status(lock=1); could be defined as a multi which gets the value of the status variable, but also asserts that thread synchronization or some form of threadsafe locking must be performed. You're not SETTING status, you're reading it, but you are passing parameters to the read accessor. How do you do that if parameters force a write? If that's your situation, you can make status() a getter only and add a set_status() setter. Or you could make foo() say if I get a single scalar (i.e. non-pair) arg, then set, otherwise get with options. But maybe that's as evil to some people as writing trivial get/set accessors is to me :) -John
Re: A12: default accessors and encapsulation
Brent 'Dax' Royal-Gordon skribis 2004-04-20 12:58 (-0700): method buffersize() will store { my $sqrt=$^v.sqrt; die $^v is not a power of two unless int($sqrt) == $sqrt; $.buffer = \x[0] x $^v; } { +$.buffer.bytes } Could this be written as: method buffersize { +$.buffer.bytes } will store { my $sqrt = $^v.sqrt; ... } Or does will store BLOCK really have to go before the main block? Juerd
minimal accessor declaration
On Tue, 20 Apr 2004, Brent 'Dax' Royal-Gordon wrote: John Williams wrote: I'm not saying there is anything wrong with that, but John Siracusa is asking for something different, I think. A simple accessor which looks like a method without having to play with Proxy, FETCH, STORE, etc. If it still looks like $obj.foo = 1 outside the class, that's good too. (Delphi and C# can do it; why can't we?) C# does it as ... Interesting. Here's the Delphi version, for comparison. // the trivial attibute SomeNumber : Integer; // the virtual property // read/write can refer to either a variable or a func/proc property VirtWrite : Integer read SomeNumber write SetSomeNumber; procedure SetSomeNumber( in : Integer ); function GetSomeNumber : Integer; The big win being that one can replace the trivial attribute with a property, and the interface stays the same. The perl6 version of that would of course be class Dog { method getfoo returns Int {...}; method setfoo(Int $v) {...}; has Int $.foo will FETCH \getfoo will STORE \setfoo; } I'm not saying there is anything wrong with that. I completely agree with Larry that the correct interface for accessors is $x = $obj.foo = $y; I'm mainly curious if there is an even simpler way to define the implementation of the accessor than the above. The simplest possible rw accessor is method foo is rw { $.foo }; which basically just makes $.foo available to the outside. When you get more complex and need to intercept the reading and writing, it's clear that returning a Proxy object is the best way (so far proposed) to do the right thing for ($x = $obj.foo = $y) and ($obj.foo++). For convenience and to avoid being uncool-retro, one also wants to separate the accessor into read and write multi methods. multi method foo() returns Int {...}; multi method foo(Int $v) {...}; has Int $.foo will FETCH { .foo } # ignore the name conflict for now will STORE { .foo($^value) }; The declaration of the has variable to delegate to the above methods now becomes repetitive boilerplate code, which could be eliminated by a clever trait. It also interferes with the obvious name for a multi method reader. foo() obviously works fine (by itself) as a reader, but foo($) needs some help. Somehow foo() has to return a Proxy which delegates STOREs to foo($), and FETCHes to itself. Since foo() works fine as a read-only accessor by itself, a minimalist approach shouldn't require foo() to add a trait. foo($) needs the help so it should get the trait. So I propose (in the request-for-comments sense, not the this should go into perl6 core sense) that given a trivial accessor: has $.foo is rw; the minimal replacement with full read/write control would be this: multi method foo() {...}; multi method foo($v) is accessor {...}; (And the accessor trait somehow does the magic to define a new foo() which returns a Proxy which delegates to the declared foo() or foo($).) ~ John Williams
run / qx/ etc.
On Tue, 2004-04-20 at 13:55, Larry Wall wrote: Okay, let's put this one to rest. Good, and I'll not try to speak ill of the dead thread, so ignoring hash and/or array access, let me respond to the end of your message. As for Cqx//, it probably needs to be completely rethought anyway, along with Csystem. Perhaps both will be subsumed under a Crun function of some sort. But that's for a future Apocalypse. Now, you had to go and do it didn'cha? ;-) I've been thinking about this for a long time, but for other reasons. It seems to me that there are dozens of ways to run a program from within Perl 5. Some are simple, some ugly as sin (sorry, I mean complex), but given A12, I think we can start to home in on a great deal of the standard tools. In specific, here is a proposal for execution: multi run(string $command) returns(Process) {...} # Funky shell default multi run(Process $process) returns(Process) {...} # Relies on $process.cmdline multi run(Program $program, IO::Mode $mode=undef) returns(Process) {...} which gives us our process control, all nicely bottled up: my Process $p = run(find / -name null); say Spawned find $($p.getpid); $p.kill('TERM'); But if you don't want that, you can always: run(find / -name null).wait; which might have an alias called system. And if you provide mode: my Process $p = run(program=find / -name null, mode=r); Then you actually get back a: class ExecPipe is Process does IO::Handle {...} which lets you do: say Found null at: $p.getline; and which could have a wrapper: $x = readpipe(pwd); ahhh... simple. open2, open3, exec and all manner of other strange things should be simple aliases for complex run invocations. The reason for making Program an object? Why for this: run(Program(path=find,name=finding null,args=[/ -name null],exec=true)); which has the alias exec. Making this as magical as Perl 5 system would be difficult, though, and I'm not sure you need to preserve that particular way of doing things. I leave the definition of Program up to the imagination of the reader. Incidentally, if Process is a standard class, and happens to do: class Process { ... method prefix:~() { return ~($.getpid) } method prefix:+() { return $.getpid } ... } Then $$ is just a Process object, but behaves exactly as you always expected it to. $$.kill(ABRT) then does what you might expect, as does: say $$.cmdline; -- Aaron Sherman [EMAIL PROTECTED] Senior Systems Engineer and Toolsmith It's the sound of a satellite saying, 'get me down!' -Shriekback
Re: A12: default accessors and encapsulation
On Tue, 20 Apr 2004, Juerd wrote: Brent 'Dax' Royal-Gordon skribis 2004-04-20 12:58 (-0700): method buffersize() will store { my $sqrt=$^v.sqrt; die $^v is not a power of two unless int($sqrt) == $sqrt; $.buffer = \x[0] x $^v; } { +$.buffer.bytes } Could this be written as: method buffersize { +$.buffer.bytes } will store { my $sqrt = $^v.sqrt; ... } Or does will store BLOCK really have to go before the main block? The syntax rules in Apocalypse 6 require the main block to be at the end. http://dev.perl.org/perl6/apocalypse/A06.html#The_sub_form
Re: A12: default accessors and encapsulation
On Tue, Apr 20, 2004 at 10:25:04PM +0200, Juerd wrote: Brent 'Dax' Royal-Gordon skribis 2004-04-20 12:58 (-0700): method buffersize() will store { my $sqrt=$^v.sqrt; die $^v is not a power of two unless int($sqrt) == $sqrt; $.buffer = \x[0] x $^v; } { +$.buffer.bytes } Could this be written as: method buffersize { +$.buffer.bytes } will store { my $sqrt = $^v.sqrt; ... } Sure method buffersize will do { +$.buffer.bytes } will store { ... } IIRC -Scott -- Jonathan Scott Duff Division of Nearshore Research [EMAIL PROTECTED] Senior Systems Analyst II
Re: A12: Strings
On Tue, Apr 20, 2004 at 02:16:01PM -0400, Aaron Sherman wrote: : Well, I have a lot to digest, but off the top of my head (and having : nothing to do with objects, but rather the string discussion at the : end), it would be very useful if I could assert: : : no string complex; : : or something like that. That is to say, I would love to have a way to : say that my strings are just plain old C-style arrays of 8-bit : characters. Yes, that's in the works. The plan is to have four Unicode support levels. Level 0 character = byte Level 1 character = codepoint Level 2 character = grapheme Level 3 character = letter These would be declared by lexically scoped declarations: use bytes 'ISO-8859-1'; use codepoints; use graphemes; use letters 'Turkish'; It's possible to get into level 0 with a bare use bytes but then you just get C locale semantics. Often you might specify which 8-bit semantics are the default. It's not possible to get into level 3 without declaring a specific language. You can't just say use letters. Possibly there's support for use letters :locale, but don't tell Jarkko. :-) Note these just warp the defaults. Underneath is still a strongly typed string system. So you can say use bytes and know that the strings that *you* create are byte strings. However, if you get in a string from another module, you can't necessarily process it as bytes. If you haven't specified how such a string is to be processed in your worldview, you're probably going to get an exception. You might anyway, if what you specified is an impossible downconversion. So yes, you can have use bytes, but it puts more responsibility on you rather than less. You might rather just specify the type of your particular string or array, and stay with codepoints or graphemes in the general case. To the extent that we can preserve the abstraction that a string is just a sequence of integers, the values of which have some known relationship to Unicode, it should all just work. In particular, latin-1 is by definition the 8-bit subset of Unicode, so if you stick to those codepoints you're safe. Functions and interfaces that require 8-bit bytes will be able to convert such a string regardless of its internal representation. : I know that at a low level Parrot is still going to have its way with : these, but at the very least, I want to be able to put the tag in there : (lexically or otherwise) to make me feel better about myself as a human : being when I do: : : my $n = ''; : for @stuff - $_ {$n ~= (defined($_)??1::0)} : my $stuff_as_bitvec = pack(b*,$n); : %state_is_known{$stuff_as_bitvec} = 1; : : It's going to be hard for me to accept that that operation is going to : have to worry about codepoints... really hard. Especially so if I'm : doing this is a tight loop as I was recently. If you never put anything into a string bigger than U+00ff, you're guaranteed to get semantics indistinguishable from a byte string, regardless of how the characters might actually be stored. We aimed for this ideal in Perl 5 but were never quite able to achieve it in all the nooks and crannies of the language. There was just too much legacy to deal with. Jarkko took it as far as humanly possible, and in some cases farther. But hopefully we can make a clean break from the looney locale legacy with Perl 6. : I suppose if there were a type: : : my Octets $stuff_as_bitvec = ''; : ... : : Then that would be a start, but even then what of the hashing operation? : Will there be some property of a hash I have to set too? : : class Octets_Num_Pair is Pair { : my Octets $.key; : my Num $.val; : ... redefine key management in terms of Octets ... : } : my Octets_Num_Pair %state_is_known; Hashes aren't declared to return pairs, but rather values. If you need to change the key type it's a trait on the storage class. But... : Is that right, or would there be a key_type property on hashes? More to : the point, is it worth it, or will I be further slowing down hash access : because it's special-cased in the default situation? Hashes should handle various types of built-in key strings properly by default. It's only if you want to start hashing on objects that you have to make sure your class does Hashkey or some such. Larry