Re: as if [Was: Selective reuse of storage in bless.]

2006-01-26 Thread Stevan Little
On 1/25/06, Jonathan Lang [EMAIL PROTECTED] wrote:
 Larry Wall wrote:
  But my hunch is that it's
  a deep tagmemic/metaphorical problem we're trying to solve here.
  Such issues arise whenever you start making statements of the form
  I want to use an A as if it were a B.  The problem is much bigger
  than just how do I translate Perl 5 to Perl 6.  It's questions like:
 
  What makes a particular metaphor work?
  Will the cultural context support use of an A as if it were a B?
  How do we translate the user's thoughts to the computer's thoughts?
  How do we translate one user's thoughts to another user's thoughts?
  How do we know when such a translation is good enough?
  How do we know when our mental model of an object is adequate?
  How do we know when the computer's mental model of an object is 
  adequate?
  What does adequate mean in context?
  Will the culture support partially instantiated objects?  :-)
 
  That's tagmemics, folks.  The main problem with tagmemics is that, while
  it helps you ask good questions, it doesn't give you easy answers for 'em...

 Let me take a (feeble) crack at this:

 It sounds like we're talking about something vaguely akin to C++'s
 typecasting, where you treat an object of a given class as if it were
 an object of a different class.

Actually this might not be a bad approach in this case. Take this for instance:

method foo (Foo $self, $key) {
((Hash) $self){$key}
}

The syntax is ugly, but it makes what you are doing more explicit. I
would also think that in most cases this could be compile time checked
(if we can check $self's type (Foo), we can make sure Foo does/isa
Hash).

Here are some other ideas for a typecasting syntax using as for the
keyword (which IIRC is taken for coercion??):

$self as Hash {
 # $self is treated as a Hash inside the block
 $self{$key} = $value;
}

# it could also return a wrapped
# $self for use in wider scopes
my $h = $self as Hash;
$h{$key} = $value;

Anyway, it's just a early morning (not enough coffee in my system) thought.

Stevan


Re: as if [Was: Selective reuse of storage in bless.]

2006-01-26 Thread Rob Kinyon
On 1/26/06, Stevan Little [EMAIL PROTECTED] wrote:
 Actually this might not be a bad approach in this case. Take this for 
 instance:

 method foo (Foo $self, $key) {
 ((Hash) $self){$key}
 }

 The syntax is ugly, but it makes what you are doing more explicit. I
 would also think that in most cases this could be compile time checked
 (if we can check $self's type (Foo), we can make sure Foo does/isa
 Hash).

 Here are some other ideas for a typecasting syntax using as for the
 keyword (which IIRC is taken for coercion??):

 $self as Hash {
  # $self is treated as a Hash inside the block
  $self{$key} = $value;
 }

 # it could also return a wrapped
 # $self for use in wider scopes
 my $h = $self as Hash;
 $h{$key} = $value;

Isn't typecasting a DesignSmell? This kind of overloading is, imnsho,
going to cause more coding bugs and is going to be considered a design
flaw in P6.

If there is need to treat something as a Hash, then provide it with a
postcircumfix{} and leave it at that. It's highly unlikely that you
will want to add Hash-like behavior to something that already has a
postcircumfix{} because it probably has that behavior already.

Rob


Re: as if [Was: Selective reuse of storage in bless.]

2006-01-26 Thread Stevan Little
On 1/26/06, Rob Kinyon [EMAIL PROTECTED] wrote:
 On 1/26/06, Stevan Little [EMAIL PROTECTED] wrote:
  Actually this might not be a bad approach in this case. Take this for 
  instance:
 
  method foo (Foo $self, $key) {
  ((Hash) $self){$key}
  }
 
  The syntax is ugly, but it makes what you are doing more explicit. I
  would also think that in most cases this could be compile time checked
  (if we can check $self's type (Foo), we can make sure Foo does/isa
  Hash).
 
  Here are some other ideas for a typecasting syntax using as for the
  keyword (which IIRC is taken for coercion??):
 
  $self as Hash {
   # $self is treated as a Hash inside the block
   $self{$key} = $value;
  }
 
  # it could also return a wrapped
  # $self for use in wider scopes
  my $h = $self as Hash;
  $h{$key} = $value;

 Isn't typecasting a DesignSmell? This kind of overloading is, imnsho,
 going to cause more coding bugs and is going to be considered a design
 flaw in P6.

General typecasting is probably a really really bad idea, I agree. But
some tightly controlled typecasting (shhh dont call it that or the
C/C++/Java programmers will freak out), might be useful in this case.
If you like, you can think of this as coercion, and not typecasting,
in fact this is probably the better word for it anyway.

 If there is need to treat something as a Hash, then provide it with a
 postcircumfix{} and leave it at that. It's highly unlikely that you
 will want to add Hash-like behavior to something that already has a
 postcircumfix{} because it probably has that behavior already.

Well this is in relation to how to deal with an object which is a
blessed p6hash, in which case you may or may not want to have a
^Hash-like interface for it (you might even want to overload the
^Hash-like interface too).

So, let me explain myself (hopefully) more clearly.

Lets say we treat infix:as as a general purpose coercion operator.
So that things like:

$num as Str;

will pretty much DWIM since a number can be easily coerced into a
string (at least 99% of the time, I am sure some of the math whizzes
will tell me different so I leave the 1% for that ;).

Now, in order for C$self as Hash to make sense, $self would have to
be coercable into a Hash in some way. If $self is a blessed p6array
this might not make that much sense, so we would die because the
coercion failed. However, if $self is a blessed p6hash, then it would
make plenty of sense (IMO at least). It would allow us to get at the
underlying representation without having to sacrifice flexibility in
the class from which $self came. Basically you could do things like
this:

class Golum;

method new (Golum $class, Hash %params) {
$class.bless(%params);
}

method postcircumfix:{} (Golum $self, Any $key, Any $value) {
 die Nasssty Hobbitses if $value.does(Hobbit);
 $self as Hash {
$self{$key} = $value;
}
}

We could also do this with the p5hash representation too, assuming we
have a ^P5Hash of some kind (which is probably not a bad idea really).

Anyway, I now have some more caffine in my system (coffee,.. yummy),
not that it makes the idea any better, but at least it is more
detailed ;)

Stevan


Re: as if [Was: Selective reuse of storage in bless.]

2006-01-26 Thread Rob Kinyon
On 1/26/06, Stevan Little [EMAIL PROTECTED] wrote:
  If there is need to treat something as a Hash, then provide it with a
  postcircumfix{} and leave it at that. It's highly unlikely that you
  will want to add Hash-like behavior to something that already has a
  postcircumfix{} because it probably has that behavior already.

 Well this is in relation to how to deal with an object which is a
 blessed p6hash, in which case you may or may not want to have a
 ^Hash-like interface for it (you might even want to overload the
 ^Hash-like interface too).

[snip]

 Now, in order for C$self as Hash to make sense, $self would have to
 be coercable into a Hash in some way. If $self is a blessed p6array
 this might not make that much sense, so we would die because the
 coercion failed. However, if $self is a blessed p6hash, then it would
 make plenty of sense (IMO at least). It would allow us to get at the
 underlying representation without having to sacrifice flexibility in
 the class from which $self came. Basically you could do things like
 this:

 class Golum;

 method new (Golum $class, Hash %params) {
 $class.bless(%params);
 }

 method postcircumfix:{} (Golum $self, Any $key, Any $value) {
  die Nasssty Hobbitses if $value.does(Hobbit);
  $self as Hash {
 $self{$key} = $value;
 }
 }

How about just inheriting from Hash?

class Gollum extends Hash;

method postcircumfix:{} (Golum $self, Any $key, Any $value) {
 die Nasssty Hobbitses if $value.does(Hobbit);
$self.NEXT.{}( $key, $value );
}

Rob


Re: as if [Was: Selective reuse of storage in bless.]

2006-01-26 Thread Stevan Little
On 1/26/06, Rob Kinyon [EMAIL PROTECTED] wrote:
 On 1/26/06, Stevan Little [EMAIL PROTECTED] wrote:
   If there is need to treat something as a Hash, then provide it with a
   postcircumfix{} and leave it at that. It's highly unlikely that you
   will want to add Hash-like behavior to something that already has a
   postcircumfix{} because it probably has that behavior already.
 
  Well this is in relation to how to deal with an object which is a
  blessed p6hash, in which case you may or may not want to have a
  ^Hash-like interface for it (you might even want to overload the
  ^Hash-like interface too).

 [snip]

  Now, in order for C$self as Hash to make sense, $self would have to
  be coercable into a Hash in some way. If $self is a blessed p6array
  this might not make that much sense, so we would die because the
  coercion failed. However, if $self is a blessed p6hash, then it would
  make plenty of sense (IMO at least). It would allow us to get at the
  underlying representation without having to sacrifice flexibility in
  the class from which $self came. Basically you could do things like
  this:
 
  class Golum;
 
  method new (Golum $class, Hash %params) {
  $class.bless(%params);
  }
 
  method postcircumfix:{} (Golum $self, Any $key, Any $value) {
   die Nasssty Hobbitses if $value.does(Hobbit);
   $self as Hash {
  $self{$key} = $value;
  }
  }

 How about just inheriting from Hash?

 class Gollum extends Hash;

 method postcircumfix:{} (Golum $self, Any $key, Any $value) {
  die Nasssty Hobbitses if $value.does(Hobbit);
 $self.NEXT.{}( $key, $value );
 }


Well, postcircumfix:{} is not just for emulating Hash :)

class struct;

has @.struct_def;
has $.struct_name;

method postcircumfix:{} ($class, Array of Pair @struct, $name) {
$class.new(
struct_def = @struct,
struct_name = $name
);
}

Then you could do something like this maybe:

my $jedi_struct = struct{(
   first_name = 'Luke',
   last_name  = 'Skywalker'
)} = jedi;

At least I assume you can, taking advantage of the a class is
prototypical instance thing to call postcircumfix:{} like that.

But I just might have had too much caffine at this point though ;P

Stevan