Re: How to define a new value type?

2008-09-19 Thread John M. Dlugosz

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?

2008-09-18 Thread TSa

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?

2008-09-17 Thread TSa

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?

2008-09-17 Thread Moritz Lenz
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?

2008-09-17 Thread TSa

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?

2008-09-17 Thread John M. Dlugosz

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?

2008-09-17 Thread John M. Dlugosz

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?

2008-09-16 Thread Stéphane Payrard
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?

2008-09-16 Thread Mark J. Reed
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?

2008-09-16 Thread TSa

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?

2008-09-16 Thread Moritz Lenz
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?

2008-09-16 Thread Daniel Ruoso
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?

2008-09-16 Thread John M. Dlugosz

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?

2008-09-16 Thread John M. Dlugosz

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?

2008-09-16 Thread John M. Dlugosz

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?

2008-09-15 Thread John M. Dlugosz

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?

2008-09-15 Thread Darren Duncan

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?

2008-09-15 Thread John M. Dlugosz

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?

2008-09-15 Thread Patrick R. Michaud
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?

2008-09-14 Thread TSa (Thomas Sandlaß)
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?

2008-09-14 Thread John M. Dlugosz

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.