Re: How to define a new value type?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: So again the question: are back refs from the value to the containers required to implement Perl 6? I guess not. If I understand what you are saying, I agree. You can only go from some container to a value, not the opposite direction, and can't tell if the object is held by more than one container.
Re: How to define a new value type?
HaloO, John M. Dlugosz wrote: TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: Is it generally foreseen that an object knows about the containers it is stored in? Yes. But it is not generally the case that this is the same container as the caller is holding. Detailed specifications of the meaning of 'read-only', 'rw', 'copy', and 'ref' and the binding semantics thereof need to address this, and address the concerns of efficient implementations. I meant the general 1:n relation of value to containers not the relation of outer and inner containers in sub calls. I think that back refs from the value to all containers is cumbersome and of little practical value if the semantics of the language don't require it. E.g. if the deletion of values were possible then all containers holding the value need to be nulled. The back refs need to be updated when a container receives a new value. It has to detach from the former value and attach to the new one. So again the question: are back refs from the value to the containers required to implement Perl 6? I guess not. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: How to define a new value type?
HaloO, Moritz Lenz wrote: When you read carefully through S29 you'll notice that most methods in immutable classes (like Str, List, Int) only return modified copies, even if they mutate the string in Perl 5. Great! (There are some exceptions like Str.substr, which explicitly 'is rw', and which implies that the object somehow has to gain access to its container). Reading the description there I wonder how this is supposed to work. our Str multi method substr (Str $string: StrPos $start, Int $length) is rw is export $string ~~ /(barney)/; substr($string, $0.from, $0.to) = fred; The 'is rw' is on the method but I guess it is foreseen that the result is stored in $string without preserving the identity of the string? my $a = His name is barney; my $b = $a; $a ~~ /(barney)/; substr($a, $0.from, $0.to) = fred; say $b; # prints fred? If substr should get access to the container passed as argument then the signature should read our Str multi method substr (Str $string is rw: StrPos $start, Int $length) is rw is export and the docu should say that the result is written into the container passed in the invocant slot. But the 'is rw' on the invocant has the drawback that calling with a string literal is precluded. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: How to define a new value type?
TSa wrote: The 'is rw' is on the method but I guess it is foreseen that the result is stored in $string without preserving the identity of the string? No. It means that the Str object has to get hold of the container in which it is stored, and store a modified copy in it. If that fails (for example in abc.substr(0, 1) = foo, where abc isn't in a container at all) the write operation will fail. my $a = His name is barney; my $b = $a; $a ~~ /(barney)/; substr($a, $0.from, $0.to) = fred; say $b; # prints fred? No, the match object needs to be bound to the value (which is immutable) unless the :rw modifier is present. If substr should get access to the container passed as argument then the signature should read our Str multi method substr (Str $string is rw: StrPos $start, Int $length) is rw is export and the docu should say that the result is written into the container passed in the invocant slot. But the 'is rw' on the invocant has the drawback that calling with a string literal is precluded. Makes sense to me. (The Int should really be StrLen, but that's only a minor glitch). That said, much of S29 needs some loving care... Moritz -- Moritz Lenz http://moritz.faui2k3.org/ | http://perl-6.de/
Re: How to define a new value type?
HaloO, Moritz Lenz wrote: TSa wrote: The 'is rw' is on the method but I guess it is foreseen that the result is stored in $string without preserving the identity of the string? No. It means that the Str object has to get hold of the container in which it is stored, and store a modified copy in it. If that fails (for example in abc.substr(0, 1) = foo, where abc isn't in a container at all) the write operation will fail. Sorry, I don't understand why you say 'no' and then explain that the resulting new string is stored in the container. The only container that could be affected by this is $string in the example. The way for a method to get access to the container is by declaring a parameter as rw. Note that this brings the discussion back to the point how rw is handled in dispatch and if an anonymous container is autovivified for a naked value. Did you mean the 'no' as answer to the question if the identity of the string--i.e. its pointer--is preserved? This would violate the immutability assertion of string values. Is it generally foreseen that an object knows about the containers it is stored in? Furthermore is it informed which of these is currently used as lvalue in a mutating operation? I think both are expensive and much better handled through the rw declaration of parameters because at binding time the container is available. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: How to define a new value type?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: Reading the description there I wonder how this is supposed to work. I don't think S29 is in any shape as a serious design specification. Maybe you should not design it that way. Maybe the left-hand-side is as ref so it can change the identity of the object it is called on. our Str multi method substr (Str $string is ref: StrPos $start, Int $length) is rw is export { ... compute result in a new variable $string = $result; # ta-da! ... and what am I supposed to return? A Str-like object that is a proxy to just the changed substring? } As for your other comments in general, I think S29 is NOT in any shape as a gospel, and going over the (very preliminary) design is a necessary task. --John
Re: How to define a new value type?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: Sorry, I don't understand why you say 'no' and then explain that the resulting new string is stored in the container. The only container that could be affected by this is $string in the example. The way for a method to get access to the container is by declaring a parameter as rw. Note that this brings the discussion back to the point how rw is handled in dispatch and if an anonymous container is autovivified for a naked value. For rw yes, for ref no. Did you mean the 'no' as answer to the question if the identity of the string--i.e. its pointer--is preserved? This would violate the immutability assertion of string values. Is it generally foreseen that an object knows about the containers it is stored in? Yes. But it is not generally the case that this is the same container as the caller is holding. Detailed specifications of the meaning of 'read-only', 'rw', 'copy', and 'ref' and the binding semantics thereof need to address this, and address the concerns of efficient implementations. But off the cuff, I think it is safe to say that 'ref' parameters are guaranteed to have the same container that the caller sees, and 'copy' parameters are guaranteed not to. default (read-only) passing may or may not at the implementation's whim, but you won't change it so it doesn't matter. 'rw' may allow the value to change before binding; 'ref' never permits that. --John
Re: How to define a new value type?
On Tue, Sep 16, 2008 at 6:11 AM, Patrick R. Michaud [EMAIL PROTECTED] wrote: On Mon, Sep 15, 2008 at 10:09:41PM -0500, John M. Dlugosz wrote: Darren Duncan darren-at-darrenduncan.net |Perl 6| wrote: So, how does one get an object to pretend to be a value type for purposes of assignment? I have been under the impression that value types are supposed to define immutable objects, or at least objects that pretend to be immutable; any operators on them would produce new objects rather than mutating existing ones. [...] I agree. A value type is immutable, where the identity is keyed to the value. Making a value type that can mutate can cause confusion. I'm now thinking that the normal = you write should always give reference assignment semantics. In the case of value types, assuming they are indeed immutable, it does not matter whether they have value or reference assignment semantics, since the same value will give the same identity, regardless of memory (or in-register) representation. [...] I think I can accept this reasoning for now, although it has some strong implications for managing array elements and binding operations (especially given Parrot's model of them). But we'll come up with something, and thanks. Pm I don't understand how = differs with that semantic from := I would expect that = would make a copy (clone?) of the object. For a mutable object, I don't know if that copy should be immediate or deffered by a mechanism of copy on write. Probably that behavior could depend on a trait of the class that implements to be copied object. -- cognominal stef
Re: How to define a new value type?
On Tue, Sep 16, 2008 at 4:26 AM, Stéphane Payrard [EMAIL PROTECTED] wrote: I don't understand how = differs with that semantic from := I would expect that = would make a copy (clone?) of the object. Assignment does copy the value between two containers, but in this case, the value just happens to be a reference to an object. Binding makes another name refer to the same container (not the same value). Imagine that some college roommates have a keyrack near their door where they keep their car keys, each hook labeled with the occupant whose key goes there (maybe at the insistence of one particularly OCD roommate). Mary's car goes into the shop, but her schedule is such that she can use John's car when he doesn't need it, so for a while John and Mary are driving the same car. If she gets a copy of his key and puts it on her own hook, that's like assignment. If she just peels the label off her hook and moves it next to his hook, that's like binding. Either way she's referencing the same object (driving the same car), but the key copy is a more flexible arrangement. -- Mark J. Reed [EMAIL PROTECTED]
Re: How to define a new value type?
HaloO, Darren Duncan wrote: If you are wanting to actually mutate a Dog in a user-visible way rather than deriving another Dog, then I don't think that calling Dog a value type is appropriate. I think that mutating methods of immutable value types just have to modify the identity. The problem is how that relates to references. Take e.g. the Str type my $s = 'abc'; # $s points to 'abc' $s.reverse; where the reverse method returns a new string that somehow has to find its way into $s. That is, the method call sequence has to be different for object types and value types. The start is identical: 1) fetch pointer from container 2) bind self to this pointer and call method For object types this is sufficient because the pointer in the container remains valid. A value type on the other hand needs 3) capture new pointer 4) store new pointer in container Note that the return value of the method is independent of this new pointer to the modified value. To unify these two sequences the system either has to know which type of object the pointer in the container belongs to or all four steps are executed for both types where the mutable ones always return the same pointer. The price to pay for the flexibility of the latter approach is with expensive store operations of the container. Well, or the language is explicit about the capture of the new value. Is this meant with $s.=reverse; # means $s = $s.reverse or is this an error that 'abc' is readonly? Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: How to define a new value type?
TSa wrote: HaloO, Darren Duncan wrote: If you are wanting to actually mutate a Dog in a user-visible way rather than deriving another Dog, then I don't think that calling Dog a value type is appropriate. I think that mutating methods of immutable value types just have to modify the identity. The problem is how that relates to references. Take e.g. the Str type my $s = 'abc'; # $s points to 'abc' $s.reverse; [...] Well, or the language is explicit about the capture of the new value. Is this meant with $s.=reverse; # means $s = $s.reverse or is this an error that 'abc' is readonly? $s.reverse returns a reversed copy of $s, and $s.=reverse does the in place reverse, ie it directly modifies $s (but not the string stored in $s. At least conceptually. But you can't observe the differences, afaict) When you read carefully through S29 you'll notice that most methods in immutable classes (like Str, List, Int) only return modified copies, even if they mutate the string in Perl 5. (There are some exceptions like Str.substr, which explicitly 'is rw', and which implies that the object somehow has to gain access to its container). Moritz -- Moritz Lenz http://moritz.faui2k3.org/ | http://perl-6.de/
Re: {SPAM} Re: How to define a new value type?
Ter, 2008-09-16 às 18:04 +0200, TSa escreveu: I think that mutating methods of immutable value types just have to modify the identity. The problem is how that relates to references. Take e.g. the Str type I really think we are looking at this problem from the wrong perspective. For an Object to be a value, it means that if you build an object with the same value, it will be seen as the same value that some other object with this value. A sane requirement for this to happen is that value objects are read-only, which is something pretty straight-forward. The thing is that, for a value object, there isn't any difference in saying: my $a := 3; or my $a := 3.clone(); Because the number '3' is a value, and you usually doesn't expect a value to change its value at a distance, that's why Int is Immutable. daniel
Re: How to define a new value type?
Stéphane Payrard cognominal-at-gmail.com |Perl 6| wrote: I don't understand how = differs with that semantic from := I would expect that = would make a copy (clone?) of the object. For a mutable object, I don't know if that copy should be immediate or deffered by a mechanism of copy on write. Probably that behavior could depend on a trait of the class that implements to be copied object. Not the best illustration, but the only one I have prepared so far: http://www.dlugosz.com/Perl6/web/assignment/assign-1.png This shows $x = $y;. The use of := (binding) would affect the leftmost column. my $z := $y; would have $z's symbol table entry point to the same Item as $y, namely #8CD9. Assignment (=) does not clone or copy the object. In the illustration, note that both Items refer to the same Dog (#A829) after assignment. With reference assignment semantics, if you want a copy or clone, you make one as an explicit step. Hence the existence of methods like deepcopy in the base Object of languages with that feature. The copy-on-write behavior you suggest is what Perl 5 does to make operator overloading appear to have value semantics. But Perl 6 does not describe this mechanism in any way. Instead, value types are immutable so it doesn't matter that the object is not cloned. --John
Re: How to define a new value type?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: I think that mutating methods of immutable value types just have to modify the identity. The problem is how that relates to references. Take e.g. the Str type my $s = 'abc'; # $s points to 'abc' $s.reverse; where the reverse method returns a new string that somehow has to find its way into $s. That is, the method call sequence has to be different for object types and value types. The start is identical: Don't do that. Changing the identity of the object will mean that other containers pointing to the same copy will change, but other containers pointing to another physical copy (but the same id) will not. Well, or the language is explicit about the capture of the new value. Is this meant with $s.=reverse; # means $s = $s.reverse Yes. Define .reverse to return a new object, and use .= if you want it to go back into the same container. I suppose that seeing .= will make it easy for the compiler to optimize, if the object is not shared it can reuse the structure. --John
Re: How to define a new value type?
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: For an Object to be a value, it means that if you build an object with the same value, it will be seen as the same value that some other object with this value. Perl 6 formalizes this by defining a value type as one whose identity is keyed to its value. Multiple physical copies in memory (or copies without memory like numbers in registers) will test as identity-equvilent. A sane requirement for this to happen is that value objects are read-only, which is something pretty straight-forward. The thing is that, for a value object, there isn't any difference in saying: my $a := 3; or my $a := 3.clone(); Because the number '3' is a value, and you usually doesn't expect a value to change its value at a distance, that's why Int is Immutable. Yes, with immutable objects you don't have to clone it. Multiple copies can be shared. By making value types as described above also immutable, it formally removes all distinction between reference assignment and value assignment.
Re: How to define a new value type?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: Taking only the lhs into account doesn't work in Patrick's code because he has untyped variables. The Dog is only on the rhs. This is why I think we need a binary dispatch. I don't see much use for the type of the LHS, though. C++ dispatches assignment on the declared type of the container on the LHS. This hardly makes sense in Perl 6. I agree. I'm in the middle of a deep meditation on this, and will post later ... maybe in a few days, maybe tonight, depending on my muse. --John
Re: How to define a new value type?
Patrick R. Michaud wrote: In [1], Larry writes: [...] we left = in the language to provide (to the extent possible) the same semantics that it does in Perl 5. And when it comes to non-value types, there really are still references, even if we try not to talk about them much. So I think assignment is basically about copying around identities, where value types treat identity differently than object types (or at least, objects types that aren't pretending to be value types). So, how does one get an object to pretend to be a value type for purposes of assignment? Currently if I do the following class Dog { ... } my $a = Dog.new; my $b = $a; then $a and $b both refer to the same Dog object. How would I define Dog such that it acts like a value type -- i.e., so that $b would be a copy of $a and future changes to the object in $a don't affect $b. I have been under the impression that value types are supposed to define immutable objects, or at least objects that pretend to be immutable; any operators on them would produce new objects rather than mutating existing ones. Therefore assignment can actually work the same way for all types, whether value types or not, by making the LHS container just hold an additional reference to what the RHS container holds. Since the value types are effectively immutable, there is no harm to them not being copied by default, and in fact this would be a feature, making it simpler to avoid unnecessary work. If you are wanting to actually mutate a Dog in a user-visible way rather than deriving another Dog, then I don't think that calling Dog a value type is appropriate. -- Darren Duncan
Re: How to define a new value type?
Darren Duncan darren-at-darrenduncan.net |Perl 6| wrote: So, how does one get an object to pretend to be a value type for purposes of assignment? Currently if I do the following class Dog { ... } my $a = Dog.new; my $b = $a; then $a and $b both refer to the same Dog object. How would I define Dog such that it acts like a value type -- i.e., so that $b would be a copy of $a and future changes to the object in $a don't affect $b. I have been under the impression that value types are supposed to define immutable objects, or at least objects that pretend to be immutable; any operators on them would produce new objects rather than mutating existing ones. Therefore assignment can actually work the same way for all types, whether value types or not, by making the LHS container just hold an additional reference to what the RHS container holds. Since the value types are effectively immutable, there is no harm to them not being copied by default, and in fact this would be a feature, making it simpler to avoid unnecessary work. If you are wanting to actually mutate a Dog in a user-visible way rather than deriving another Dog, then I don't think that calling Dog a value type is appropriate. I agree. A value type is immutable, where the identity is keyed to the value. Making a value type that can mutate can cause confusion. I'm now thinking that the normal = you write should always give reference assignment semantics. In the case of value types, assuming they are indeed immutable, it does not matter whether they have value or reference assignment semantics, since the same value will give the same identity, regardless of memory (or in-register) representation. Furthermore, just because you CAN write an infix:= for some types that give value assignment semantics, you SHOULDN'T do that, any more than you should write an infix:= to do addition. We want to avoid the Java et.al. mess, and the ideas behind value types in Perl 6, and the conceptual separation already present in comparison operators, gives the natural solution: You don't have value types a'la Java that behave differently with respect to assignment. Just like you can TEST for identity or value equality by your choice of === or 'eqv', you can specify reference assignment or value assignment (if available) by your choice of operator. To match the testing operators and existing meaning for '=', I suggest that '=' ALWAYS be reference assignment and not be overloaded to do something else, and the word 'assign' (to go with words being used for value tests: 'eqv', 'before', 'after') be a method that mutates the object to become 'eqv' the argument. And, if you want to get fancy, define ← as an infix operator for that meaning. --John
Re: How to define a new value type?
On Mon, Sep 15, 2008 at 10:09:41PM -0500, John M. Dlugosz wrote: Darren Duncan darren-at-darrenduncan.net |Perl 6| wrote: So, how does one get an object to pretend to be a value type for purposes of assignment? I have been under the impression that value types are supposed to define immutable objects, or at least objects that pretend to be immutable; any operators on them would produce new objects rather than mutating existing ones. [...] I agree. A value type is immutable, where the identity is keyed to the value. Making a value type that can mutate can cause confusion. I'm now thinking that the normal = you write should always give reference assignment semantics. In the case of value types, assuming they are indeed immutable, it does not matter whether they have value or reference assignment semantics, since the same value will give the same identity, regardless of memory (or in-register) representation. [...] I think I can accept this reasoning for now, although it has some strong implications for managing array elements and binding operations (especially given Parrot's model of them). But we'll come up with something, and thanks. Pm
Re: How to define a new value type?
On Sunday, 14. September 2008 16:08:19 Patrick R. Michaud wrote: So, how does one get an object to pretend to be a value type for purposes of assignment? I think a straight forward approach is to overload the assignment operator on the actual types of the lhs and rhs. The dispatch target than clones the value to be stored in the lhs container after being checked against the container's constraint. Regards, TSa. -- The unavoidable price of reliability is simplicity -- C.A.R. Hoare Simplicity does not precede complexity, but follows it. -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: How to define a new value type?
TSa (Thomas Sandlaß) thomas-at-sandlass.de |Perl 6| wrote: I think a straight forward approach is to overload the assignment operator on the actual types of the lhs and rhs. The dispatch target than clones the value to be stored in the lhs container after being checked against the container's constraint. Regards, TSa. Since infix:= is an operator called on the value of the left-hand-side, the semantics are naturally value semantics, as in C++. It would be difficult to write it otherwise: take the LHS by ref and call STORE on the container.