Re: Where is Manhattan Dispatch discussion?

2008-05-06 Thread Ovid
--- John M. Dlugosz [EMAIL PROTECTED] wrote:

 I want to review and collect the wisdom of what has been discussed
 before.  Someone mentioned this the other day, as being a significant
 consensus.  But I can't find anything in the forum archives.
 
 Can someone point to the discussion, position papers, etc.?  

This this:

  http://use.perl.org/~luqui/journal/27362

Luke makes some interesting comments, but you'll want to click the
Great Multimethod Debate link (http://tinyurl.com/5hm4ze).

Cheers,
Ovid

--
Buy the book  - http://www.oreilly.com/catalog/perlhks/
Perl and CGI  - http://users.easystreet.com/ovid/cgi_course/
Personal blog - http://publius-ovidius.livejournal.com/
Tech blog - http://use.perl.org/~Ovid/journal/


my TypeName $x;

2008-05-06 Thread Jonathan Worthington

Hi,

I'm looking for answers/clarification on what (if taken as individual 
programs) $x is in each case.


my Int $x; # $x is Int protoobject
say $x;  # Int
say $x.WHAT; # Int

class Foo { }
my Foo $x;   # $x is Foo protoobject
say $x;  # Foo
say $x.WHAT; # Foo
# This means we can only assign to $x something that isa Foo?

role Bar { }
my Bar $x;   # $x is ???
say $x;  # ???
say $x.WHAT; # ???
# This means we can only assign to $x something that does Bar?

subset EvenInt of Int where { $_ % 2  == 0 };
my EvenInt $x;  # $x is ???
say $x;  # ???
say $x.WHAT;  # Failure?
# This means we can only assign to $x something that matches the constraint

class Dog { }
class Cat { }
my Dog|Cat $x;  # $x is ???
say $x;   # ???
say $x.WHAT;  # Failure?
# This means we can only assign to $x something that isa Dog or isa Cat

Thanks,

Jonathan


Re: my TypeName $x;

2008-05-06 Thread Jon Lang
My thoughts:
.HOW returns information concerning the implementation type; .WHAT
returns information concerning the value type.
.HOW and .WHAT stringify to something resembling the declarations that
would be used to create them.

Also bear in mind that Perl 6 uses prototype-based object orientation,
except where it doesn't.  As such, when I say that $x is a Foo
below, what I mean is that $x is an object with Foo as its
implementation type.

Jonathan Worthington wrote:
 Hi,

  I'm looking for answers/clarification on what (if taken as individual
 programs) $x is in each case.

  my Int $x; # $x is Int protoobject
  say $x;  # Int
  say $x.WHAT; # Int

.WHAT is an Int; stringifies to Int.

  class Foo { }
  my Foo $x;   # $x is Foo protoobject
  say $x;  # Foo
  say $x.WHAT; # Foo
  # This means we can only assign to $x something that isa Foo?

.WHAT is a Foo; stringifies to Foo.

  role Bar { }
  my Bar $x;   # $x is ???
  say $x;  # ???
  say $x.WHAT; # ???
  # This means we can only assign to $x something that does Bar?

This one's tricky: roles cannot be instantiated, so .WHAT cannot be a
Bar.  My gut reaction is that it's an anonymous class that does Bar
and stringifies to Bar.  As long as you don't have both a role and a
class named Bar, this should not be a problem, since the value type
isn't concerned with the implementation.  If it is possible to have
both a role and a class with the same name, you might be able to look
at .WHAT.HOW (or .^WHAT) to figure out with which you're dealing.
That is, the implementation type of the value type ought to provide
more elaborate detail as to the nature of the value type.

  subset EvenInt of Int where { $_ % 2  == 0 };
  my EvenInt $x;  # $x is ???
  say $x;  # ???
  say $x.WHAT;  # Failure?
  # This means we can only assign to $x something that matches the constraint

my guess: .WHAT is an EvenInt that stringifies to EvenInt.  If you
want to know about the structure of EvenInt (e.g., which class is it
based on, and which subset restrictions have been applied to it), you
would refer to .WHAT.HOW.

  class Dog { }
  class Cat { }
  my Dog|Cat $x;  # $x is ???
  say $x;   # ???
  say $x.WHAT;  # Failure?
  # This means we can only assign to $x something that isa Dog or isa Cat

my guess: .WHAT is a Junction that stringifies to Dog|Cat.  To
access the details as to which classes are in the junction and how
they are joined, refer to appropriate methods (I believe that Junction
includes a method that returns a Set of its members) or maybe to
.WHAT.HOW.

As well:

  class Dog { }
  role Pet { }
  my Pet Dog $x;
  say $x;
  say $x.WHAT;

My guess is that .WHAT would be a (dis)Junction of a Dog and an
anonymous class; the anonymous class does Pet and stringifies to
Pet, while the Junction stringifies to Pet Dog.

-- 
Jonathan Dataweaver Lang


Re: nested 'our' subs - senseless?

2008-05-06 Thread TSa

HaloO,

David Green wrote:

On 2008-May-3, at 5:04 pm, John M. Dlugosz wrote:

What does this mean?

our sub outer ()
 {
  ...
  our sub inner () { ... }
 }


inner;  # defined?


I don't know why it would be any more illegal than sub foo { our 
$var... }.  The inner sub would be in the package's scope, but the name 
inner() would be available only in outer's scope.  So that use of 
inner in the last line would be an error.


Why that? I would think assuming that inner has a defined body,
the our scope is around the outer somewhere. So the call there
should succeed. Or is this not like our works? I assume that sub
is not an our scope, BTW.

Just to ensure that I get the our behavior right, consider

sub foo
{
   our $inner = 3;
}
sub bar
{
   our $inner = 4; # redeclaration error?
}
say $inner;

Does this print 3 even when foo was never called? IOW, is the assignment
in foo a real one that only happens when foo is invoked or is it a
pseudo-assignment that initializes the variables as if the whole
statement where outside of foo? The latter would actually mean that
the line in foo behaves different with or without the our. Without the
our, the say would print 3, 4 or undef depending on the call sequence of
foo and bar, right? Now how does that compare to sub definition?

sub foo
{
our sub inner { 3 }
}
sub bar
{
our sub inner { 4 } # redefinition error?
}
say inner;

My favorite is what the spec already seems to say: a symbol can be
declared/defined exactly once in a scope. Usage prior to 
declaration/definition is an error. Usage of undeclared/undefined

symbols is parsed provisionally as if defined/declared with our
immediately before this use. Take e.g. class definition in a sub

sub foo
{
our class inner { has $.x = 3 }
}
sub bar
{
our class inner { has $.x = 4 } # redefinition error?
}
say inner.new.x;

The consequence of a sub not doing Package is that there are
no separate foo::inner and bar::inner classes as in

class foo
{
our class inner { has $.x = 3 }
}
class bar
{
our class inner { has $.x = 4 }
}
say inner.new.x; # error: no inner in scope


My personal idea is to unify class and sub by allowing sub to do
Package.

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: my TypeName $x;

2008-05-06 Thread Jon Lang
Upon further review:

It might be possible that $x.WHAT returns a Signature object, with the
value type of $x as the invocant (or return type?), and everything
else empty.  But that merely begs the question of how to introspect a
Signature object.  If I tell Perl 6 to say a Signature, what gets
displayed?  Can I ask Perl 6 to look at a particular parameter in a
Signature?  If so, what kind of object does the Signature object
return if I ask it to give me its invocant?  Surely not another
Signature object?  Whatever it is that Perl 6 returns in that case
would probably work better as the return type of the .WHAT method,
too.

-- 
Jonathan Dataweaver Lang


Re: my TypeName $x;

2008-05-06 Thread Brandon S. Allbery KF8NH


On 2008 May 6, at 10:15, Jon Lang wrote:


Signature?  If so, what kind of object does the Signature object
return if I ask it to give me its invocant?  Surely not another
Signature object?  Whatever it is that Perl 6 returns in that case


Turtle?  :)

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: Where is Manhattan Dispatch discussion?

2008-05-06 Thread John M. Dlugosz
I'm still in the dark... I find an positions for manhattan distance 
but no definition of what that is.  I did find the alternative pod page 
earlier.


--John

Ovid publiustemp-perl6language2-at-yahoo.com |Perl 6| wrote:

--- John M. Dlugosz [EMAIL PROTECTED] wrote:

  

I want to review and collect the wisdom of what has been discussed
before.  Someone mentioned this the other day, as being a significant
consensus.  But I can't find anything in the forum archives.

Can someone point to the discussion, position papers, etc.?  



This this:

  http://use.perl.org/~luqui/journal/27362

Luke makes some interesting comments, but you'll want to click the
Great Multimethod Debate link (http://tinyurl.com/5hm4ze).

Cheers,
Ovid

--
Buy the book  - http://www.oreilly.com/catalog/perlhks/
Perl and CGI  - http://users.easystreet.com/ovid/cgi_course/
Personal blog - http://publius-ovidius.livejournal.com/
Tech blog - http://use.perl.org/~Ovid/journal/

  




Re: Where is Manhattan Dispatch discussion?

2008-05-06 Thread Carl Mäsak
John ():
 I'm still in the dark... I find an positions for manhattan distance but no
 definition of what that is.  I did find the alternative pod page earlier.

I don't have a whole answer for you, but a part that may help. What is
generally meant by Manhattan distance is so-called L1 distance, i.e.
Pythagoras' distance summation formula but without all the squaring
and surding.

 http://en.wikipedia.org/wiki/Taxicab_geometry

I imagine the concept is applied to parameter types in the discussion
in question.

// Carl


Re: Where is Manhattan Dispatch discussion?

2008-05-06 Thread Mark A. Biggar

Carl Mäsak wrote:

John ():

I'm still in the dark... I find an positions for manhattan distance but no
definition of what that is.  I did find the alternative pod page earlier.


I don't have a whole answer for you, but a part that may help. What is
generally meant by Manhattan distance is so-called L1 distance, i.e.
Pythagoras' distance summation formula but without all the squaring
and surding.

 http://en.wikipedia.org/wiki/Taxicab_geometry

I imagine the concept is applied to parameter types in the discussion
in question.


To do multi method dispatch, you want to select the method that best 
matches the parameters in the call. One way to do that is to define a 
measure for distances between types and they use the method that's at 
the minimum distance.  One simple measure is that a type is distance 0 
from itself and distance 1 from it's immediate super-types, distance 2 
from the immediate super-types of it's immediate super-types, etc. When 
dispatching over a single parameter picking the method at the minimum 
distance is the usual most specific type match. But when you want to do 
multi-method dispatch, you need some rule to combine the various 
distances of the individual parameters into a single measure value, then 
pick the method at the minimum distance by that combined measure. 
Manhattan Distance or Taxicab Distance is the rule that the combined 
distance is just the simple unweighted sum of the individual parameter 
distances. The is named after the fact that a taxi must follow the 
streets and to go 3 block north and 4 blocks west it must travel 7 
blocks not the 5 blocks of the euclidean distance.


BTW, if you want to do euclidean distance comparisons you don't need to 
do any square roots. Square root is monotonic, so order relations 
between the sums of squares values is the the same whether you take 
square roots or not.



--
[EMAIL PROTECTED]
[EMAIL PROTECTED]



Re: my TypeName $x;

2008-05-06 Thread TSa

HaloO,

Jon Lang wrote:

My thoughts:
.HOW returns information concerning the implementation type; .WHAT
returns information concerning the value type.


My addition to these thoughts is that the WHAT and HOW are
cascaded. Let's say we start at level 0 with the objects,
thingies or however we want to name the atoms of our discourse.
At the zero level HOW, WHAT etc. are vacuously identical with
the object. They fall apart on level 1 from each other and among
them selfs but they are all sets of level-0 objects. In general
a level n concept contains level 0..^n objects and is the name
for a something they share.



.HOW and .WHAT stringify to something resembling the declarations that
would be used to create them.


Yeah. Stringification is relatively easy.



 class Foo { }
 my Foo $x;   # $x is Foo protoobject
 say $x;  # Foo
 say $x.WHAT; # Foo
 # This means we can only assign to $x something that isa Foo?


.WHAT is a Foo; stringifies to Foo.


Note that $x is not initialized. This means the say has to
give something like undef of Foo.



 role Bar { }
 my Bar $x;   # $x is ???
 say $x;  # ???
 say $x.WHAT; # ???
 # This means we can only assign to $x something that does Bar?


This one's tricky: roles cannot be instantiated, so .WHAT cannot be a
Bar.


What? I would say it is a level 1 WHAT. The next level concept
$x.WHAT.WHAT is role. BTW, there are not very many levels up.



 My gut reaction is that it's an anonymous class that does Bar
and stringifies to Bar.  As long as you don't have both a role and a
class named Bar, this should not be a problem, since the value type
isn't concerned with the implementation.  If it is possible to have
both a role and a class with the same name, you might be able to look
at .WHAT.HOW (or .^WHAT) to figure out with which you're dealing.
That is, the implementation type of the value type ought to provide
more elaborate detail as to the nature of the value type.


Hmm, are these meta accessors commutative? I.e. are
$x.WHAT.HOW and $x.HOW.WHAT the identical level 2 entities?
I would rather opt for $x.HOW of a role .WHAT.WHAT to be
the level 1 undef which is a set of interesting level 0 values
of undef.



 subset EvenInt of Int where { $_ % 2  == 0 };
 my EvenInt $x;  # $x is ???
 say $x;  # ???
 say $x.WHAT;  # Failure?
 # This means we can only assign to $x something that matches the constraint


my guess: .WHAT is an EvenInt that stringifies to EvenInt.  If you
want to know about the structure of EvenInt (e.g., which class is it
based on, and which subset restrictions have been applied to it), you
would refer to .WHAT.HOW.


I would argue that $x.WHAT.WHAT is subset. I think the
idea of introspection is to have $x.WHAT.of return Int
as a level 1 WHAT and $x.WHAT.where return the constraint
closure. That said I would expect $x.HOW to be the identical
level 1 HOW object that $x.WHAT.of.HOW returns. When Int.WHAT.WHAT
is a role then this is undef of Int.



 class Dog { }
 class Cat { }
 my Dog|Cat $x;  # $x is ???
 say $x;   # ???
 say $x.WHAT;  # Failure?
 # This means we can only assign to $x something that isa Dog or isa Cat


my guess: .WHAT is a Junction that stringifies to Dog|Cat.  To
access the details as to which classes are in the junction and how
they are joined, refer to appropriate methods (I believe that Junction
includes a method that returns a Set of its members) or maybe to
.WHAT.HOW.


On level 1 the WHATs of Dog and Cat are distinct. Dog|Cat is a level 2
WHAT. The level 2 $x.WHAT.HOW is a union. $x.WHAT.WHAT is class.



As well:

  class Dog { }
  role Pet { }
  my Pet Dog $x;
  say $x;
  say $x.WHAT;

My guess is that .WHAT would be a (dis)Junction of a Dog and an
anonymous class; the anonymous class does Pet and stringifies to
Pet, while the Junction stringifies to Pet Dog.


Again the say $x should print undef of Pet Dog. Similar to above
$x.WHAT.HOW is an intersection. But $x.WHAT.WHAT is role|class and
the question is what their common abstraction is. Though, whatever
it is, you get it with $x.WHAT.WHAT.WHAT. But you can't call .new
on it. The $x.HOW might be Dog but $x can't store an object created
by its .new method because Dog.new.WHAT is in the part of the level
1 Dog that is not part of the level 2 WHAT Pet Dog. So to initialize
you need

  my Pet Dog $x = .new does Pet;

After this $x.HOW.HOW is Dog. Since the anonymous class created by
does is not of interest the $x.WHAT remains the level 2 WHAT Pet Dog.


I know that this sounds like turtles all the way down but the
levels of abstraction are all derived from the source code. So,
as long as your source is finite so is the WHAT structure over
the objects. The worst that can happen is that there is a 1:1
mapping between a lower level at the one above it.
--

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: Where is Manhattan Dispatch discussion?

2008-05-06 Thread TSa

HaloO,

Mark A. Biggar wrote:
To do multi method dispatch, you want to select the method that best 
matches the parameters in the call.


The fundamental flaw of metric mmd is that it trades degrees of
specificity. Consider the subtype chain E : D : C : B : A
where the rule is that having an E it is better handled by a
method dealing with a D than one dealing with an A. The same
is the case for having a D being better handled by a C than an
A method. Now consider a multi with the two signatures :(A,C,C)
and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since
7  8. But note that it handles the two Ds as As instead of Cs
as in single dispatch.

Dispatch has to go to the single most capable implementation
*not* to the least misfit! The call above has to be brought
to the attention of a programmer.


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


MMD thoughts 2008

2008-05-06 Thread John M. Dlugosz

TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote:


The fundamental flaw of metric mmd is that it trades degrees of
specificity. Consider the subtype chain E : D : C : B : A
where the rule is that having an E it is better handled by a
method dealing with a D than one dealing with an A. The same
is the case for having a D being better handled by a C than an
A method. Now consider a multi with the two signatures :(A,C,C)
and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since
7  8. But note that it handles the two Ds as As instead of Cs
as in single dispatch.





OK, why would someone create those forms in the first place?  The 
subtyping relationship could mean either value subset (e.g. integer 
passed to code that can handle reals) or polymorphic isa objects.  The 
implementation should treat the E correctly because of virtual functions 
on E, even though the code was written for an A.  So why write different 
forms with =related= classes?  I would define operators with the same 
name around unrelated classes, so I can use that operator with things 
that don't already know what to do.


So why are we focusing on the pathalogical cases?  That's like saying we 
should not support division because you could divide by zero.  Rather, 
what is the common typical use?  For the bad stuff, don't do that and 
do this instead.  I think the MMD should work well and be tuned for 
the areas in which it ought to be used, and the above problem analyzed 
to see what the programmer was really trying to accomplish.


Maybe for special tuning in hacked-up (as opposed to nicely refactored 
code) we need something like submethods, that handle the exact case and 
don't get in the way of other distances.  Maybe some of this should be 
done with generics rather than MMD.


For example, I don't need to define something on a wide variety of 
number-like types individually, I'll use generic types to specify the 
minimal properties of the kind of type it applies to, and that the 
arguments match. 

So my MMD is between two forms:  anything that is integral in nature 
and anything that is a type of Vehicle, without any analysis 
concerning whether a Bus is more like a generic Vehicle than a BCD is 
like an abstract integer concept.


--John


Re: my TypeName $x;

2008-05-06 Thread Jon Lang
TSa wrote:
  Jon Lang wrote:

  My thoughts:
  .HOW returns information concerning the implementation type; .WHAT
  returns information concerning the value type.

BTW, S12 more or less confirms the above: .WHAT returns a prototype
object that stringifies to its short name, while .HOW allows
introspection of the attributes and methods and composed roles and
inherited classes and...

  My addition to these thoughts is that the WHAT and HOW are
  cascaded. Let's say we start at level 0 with the objects,
  thingies or however we want to name the atoms of our discourse.
  At the zero level HOW, WHAT etc. are vacuously identical with
  the object. They fall apart on level 1 from each other and among
  them selfs but they are all sets of level-0 objects. In general
  a level n concept contains level 0..^n objects and is the name
  for a something they share.

In English, please?

I _think_ that you're saying that you can use WHAT and HOW
recursively: that is, you can talk about WHAT.WHAT, WHAT.HOW,
HOW.WHAT, HOW.HOW, etc.  If so, note a few caveats:
first, if $x is a Foo, then $x.WHAT will be a Foo.  As such, there is
no difference between $x.WHAT and $x.WHAT.WHAT.  Likewise, forget
about my comments about $x.WHAT.HOW; since $x is of exactly the same
type as $x.WHAT, you can get the same information by saying $x.HOW as
you could about $x.WHAT.HOW.

Second, $x.HOW.WHAT gives you a prototype of the metaclass object.  If
you're ever doing type checking that refers to the metaclass class,
this might be useful; otherwise, don't bother.

Third, $x.HOW.HOW would let you look at the inner workings of the
metaclass class.  Going beyond that would be redundant, since you'd
be using a metaclass object to look at the metaclass class.

role Bar { }
my Bar $x;   # $x is ???
say $x;  # ???
say $x.WHAT; # ???
# This means we can only assign to $x something that does Bar?
  
 
  This one's tricky: roles cannot be instantiated, so .WHAT cannot be a
  Bar.


  What? I would say it is a level 1 WHAT. The next level concept
  $x.WHAT.WHAT is role. BTW, there are not very many levels up.

Again, English please?

As I said, roles cannot be instantiated.  $x is not a Bar; it is an
object of an anonymous class that does Bar.  $x.WHAT is a prototype
object of $x, meaning that it, too, is an object of an anonymous class
that does Bar.  The only difference between them is that $x may
eventually have a value assigned to it; $x.WHAT never will.  Well...
that, and $x.WHAT stringifies differently than $x does.

subset EvenInt of Int where { $_ % 2  == 0 };
my EvenInt $x;  # $x is ???
say $x;  # ???
say $x.WHAT;  # Failure?
# This means we can only assign to $x something that matches the
# constraint
 
  my guess: .WHAT is an EvenInt that stringifies to EvenInt.  If you
  want to know about the structure of EvenInt (e.g., which class is it
  based on, and which subset restrictions have been applied to it), you
  would refer to .WHAT.HOW.

  I would argue that $x.WHAT.WHAT is subset. I think the
  idea of introspection is to have $x.WHAT.of return Int
  as a level 1 WHAT and $x.WHAT.where return the constraint
  closure. That said I would expect $x.HOW to be the identical
  level 1 HOW object that $x.WHAT.of.HOW returns. When Int.WHAT.WHAT
  is a role then this is undef of Int.

Ah; _that's_ what you mean by cascading levels.  Ugh.

By my understanding, $x and $x.WHAT are both the same kind of thing:
they're both EvenInt.  Again, the only difference is that $x.WHAT will
always be undefined and will stringify to EvenInt.

class Dog { }
class Cat { }
my Dog|Cat $x;  # $x is ???
say $x;   # ???
say $x.WHAT;  # Failure?
# This means we can only assign to $x something that isa Dog or isa Cat
 
  my guess: .WHAT is a Junction that stringifies to Dog|Cat.  To
  access the details as to which classes are in the junction and how
  they are joined, refer to appropriate methods (I believe that Junction
  includes a method that returns a Set of its members) or maybe to
  .WHAT.HOW.

  On level 1 the WHATs of Dog and Cat are distinct. Dog|Cat is a level 2
  WHAT. The level 2 $x.WHAT.HOW is a union. $x.WHAT.WHAT is class.

Huh?

-- 
Jonathan Dataweaver Lang


Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread John M. Dlugosz

Mark A. Biggar mark-at-biggar.org |Perl 6| wrote:


To do multi method dispatch, you want to select the method that best 
matches the parameters in the call. One way to do that is to define a 
measure for distances between types and they use the method that's at 
the minimum distance.  One simple measure is that a type is distance 0 
from itself and distance 1 from it's immediate super-types, distance 2 
from the immediate super-types of it's immediate super-types, etc. 
When dispatching over a single parameter picking the method at the 
minimum distance is the usual most specific type match. But when you 
want to do multi-method dispatch, you need some rule to combine the 
various distances of the individual parameters into a single measure 
value, then pick the method at the minimum distance by that combined 
measure. Manhattan Distance or Taxicab Distance is the rule that 
the combined distance is just the simple unweighted sum of the 
individual parameter distances. The is named after the fact that a 
taxi must follow the streets and to go 3 block north and 4 blocks west 
it must travel 7 blocks not the 5 blocks of the euclidean distance.



OK, so basically the fit is the sum of the fits of all the parameters.  
If form A has a distance of 2 for the first argument and 5 for the 
second, and form B has a distance of 0 for the first and 10 for the 
second, form A is better.


I heard this term come up the other day with respect to matching value 
types =and= other attributes such as rw or ref-ness.  I thought he meant 
that these were different directions like streets and avenues, of one 
parameter.


I have problems with a simple sum.  The distance is artificially 
inflated if you make lots of small derivation steps vs one large 
change.  The concept of derivation steps is ill-defined for 
parameterized types and types that change virtual type names during 
derivation so there is no subtype relationship.


In C++, which must be resolved at compile time, the overloading 
resolution mechanism demands that =every= parameter be at least as good 
of a match, and one strictly better match.  So the implementation never 
guesses if worse-left/better-right is a better fit than 
better-left/worse-right.  However, you are assured that everything is 
brought to your attention at program build time, before run time, so 
complaining is not as serious as a run-time error where you might prefer 
DWIM.


--John


Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread TSa

HaloO,

John M. Dlugosz wrote:
In C++, which must be resolved at compile time, the overloading 
resolution mechanism demands that =every= parameter be at least as good 
of a match, and one strictly better match.  So the implementation never 
guesses if worse-left/better-right is a better fit than 
better-left/worse-right.  However, you are assured that everything is 
brought to your attention at program build time, before run time, so 
complaining is not as serious as a run-time error where you might prefer 
DWIM.


Perl 6 is the same, just at runtime with actual types of actual objects.
That's it.

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: nested 'our' subs - senseless?

2008-05-06 Thread David Green

On 2008-May-6, at 6:07 am, TSa wrote:

Just to ensure that I get the our behavior right, consider

   sub foo
   {
  our $inner = 3;
   }
   sub bar
   {
  our $inner = 4; # redeclaration error?
   }
   say $inner;

Does this print 3 even when foo was never called?


No, it throws an error about $inner not being declared properly --  
just as in P5 you'd get 'Variable $inner is not imported. Global  
symbol $inner requires explicit package name'.


There's no redeclaration error in bar() because it's declaring the  
name for the first time (in bar's scope, that is), and then  
(re)assigning a value to $inner, which is fine.  If foo said our Int  
$inner and then bar said our Str $inner, that should be an error  
though.



sub foo
{
our $inner = 3;
}
sub bar
{
our $inner = 4;  # fine, assigns or re-assigns $inner
}

say $inner;  # error, name $inner not recognised here

our $inner;  # now the name is available in this scope
say $inner;  # OK, $inner is undef

foo; say $inner; # prints 3

bar; say $inner; # prints 4


IOW, is the assignment in foo a real one that only happens when foo  
is invoked or is it a pseudo-assignment that initializes the  
variables as if the whole statement where outside of foo?


The assignment happens only when foo() is invoked.  However, the  
variable $*Main::inner is declared at compile-time.  Similarly, an  
our sub inner inside foo() would declare the name, but you couldn't  
call inner() until after running foo() --or bar()-- since you can't  
call an undefined sub.




The consequence of a sub not doing Package is that there are
no separate foo::inner and bar::inner classes as in

   class foo
   {
   our class inner { has $.x = 3 }
   }
   class bar
   {
   our class inner { has $.x = 4 }
   }
   say inner.new.x; # error: no inner in scope

My personal idea is to unify class and sub by allowing sub to do  
Package.


I don't understand what a sub doing Package is supposed to do.  I  
think you get the same thing from that last example whether foo and  
bar are classes or whether they're subs: either way, bar will raise a  
redefinition error, and say inner.new.x will throw a no 'inner' in  
scope error.



-David




Re: MMD thoughts 2008

2008-05-06 Thread TSa

HaloO,

John M. Dlugosz wrote:

OK, why would someone create those forms in the first place?


I would think they grow like that historically. A five steps
long subtyping chain is not particularly extraordinary. Note that
multi entries live outside of classes and their single dispatch.


 The 
subtyping relationship could mean either value subset (e.g. integer 
passed to code that can handle reals) or polymorphic isa objects.  The 
implementation should treat the E correctly because of virtual functions 
on E, even though the code was written for an A.


Yes, but code that specifies to get an A sanely only uses functionality
covered by that requirement. E : A of course means that the A interface
works on an E. But a multi method target should be the most specific
choice for *all* parameters. Only that guarantees that all relationships
amongst the involved types are taken into account up to a
*deterministic* level of specificity.



 So why write different forms with =related= classes?


Different forms?


 I would define operators with the same 
name around unrelated classes, so I can use that operator with things 
that don't already know what to do.


If I understand what you say, then you mean homogeneous multis.
These can be implemented with single dispatch on the invocant and
generic type enforcement for the other parameters. But MMD is about
the heterogeneous case!

BTW, the types that already know what to do must be implemented
with the same features as all the others. There are no magic built-ins.


So why are we focusing on the pathalogical cases?  That's like saying we 
should not support division because you could divide by zero.


But we throw an exception just as with a faulty dispatch.


 Rather, 
what is the common typical use?  For the bad stuff, don't do that and 
do this instead.  I think the MMD should work well and be tuned for 
the areas in which it ought to be used, and the above problem analyzed 
to see what the programmer was really trying to accomplish.


You want a runtime analysis what the programmers might have meant?
So Perl 6 requires AI?


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: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread chromatic
On Tuesday 06 May 2008 10:38:38 John M. Dlugosz wrote:

 I have problems with a simple sum.  The distance is artificially
 inflated if you make lots of small derivation steps vs one large
 change.  The concept of derivation steps is ill-defined for
 parameterized types and types that change virtual type names during
 derivation so there is no subtype relationship.

Those are precisely my objections.  I'm not a fan of derivation in general, 
but I've never understood how changing MMD resolution based on degree of 
derivation didn't break Liskov.  (Damian tried to explain it to me at least 
once, but he's smarter than I am and I didn't get it.)

-- c


Re: nested 'our' subs - senseless?

2008-05-06 Thread TSa

HaloO,

David Green wrote:
The assignment happens only when foo() is invoked.  However, the 
variable $*Main::inner is declared at compile-time.  Similarly, an our 
sub inner inside foo() would declare the name, but you couldn't call 
inner() until after running foo() --or bar()-- since you can't call an 
undefined sub.


Do you mean there is an uninitialized variable *Main::inner that is
only bound when either foo or bar are executed? How is the body handled?
If there are different bodies in foo and bar, is that a re-definition
of inner error at compile time? If not, does the body bound to
*Main::inner depend on whether foo or bar was called first? Or does it
even toggle?


I don't understand what a sub doing Package is supposed to do.  I 
think you get the same thing from that last example whether foo and bar 
are classes or whether they're subs: either way, bar will raise a 
redefinition error, and say inner.new.x will throw a no 'inner' in 
scope error.


No, a class definitely does Package. So, my classes foo and bar get
two separate classes foo::inner and bar::inner and there is *no*
*Main::inner class at all. In particular there should be no
re-definition error in bar. This is exactly the behavior I want for
subs as well.


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: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread Larry Wall
On Tue, May 06, 2008 at 08:20:40PM +0200, TSa wrote:
 HaloO,

 John M. Dlugosz wrote:
 In C++, which must be resolved at compile time, the overloading resolution 
 mechanism demands that =every= parameter be at least as good of a match, 
 and one strictly better match.  So the implementation never guesses if 
 worse-left/better-right is a better fit than better-left/worse-right.  
 However, you are assured that everything is brought to your attention at 
 program build time, before run time, so complaining is not as serious as a 
 run-time error where you might prefer DWIM.

 Perl 6 is the same, just at runtime with actual types of actual objects.
 That's it.

Indeed, Perl 6 threw out Manhattan distance a couple years ago.  Do we
have to spec everything that Perl 6 ever was but isn't now?  :)

Larry


Re: MMD thoughts 2008

2008-05-06 Thread Buddha Buck
Sorry to reply to the wrong comment, but I lost the original thread in
my mail archives and didn't notice this until now.

On Tue, May 6, 2008 at 1:54 PM, John M. Dlugosz
[EMAIL PROTECTED] wrote:
 TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote:

 
  The fundamental flaw of metric mmd is that it trades degrees of
  specificity. Consider the subtype chain E : D : C : B : A
  where the rule is that having an E it is better handled by a
  method dealing with a D than one dealing with an A. The same
  is the case for having a D being better handled by a C than an
  A method. Now consider a multi with the two signatures :(A,C,C)
  and :(D,A,A) and a call with (E,D,D) that goes to :(D,A,A) since
  7  8. But note that it handles the two Ds as As instead of Cs
  as in single dispatch.

Is this right?  (E,D,D) to (A,C,C) is (4,1,1), with a L1 metric of 6.
(E,D,D) to (D,A,A) is (1,3,3) with an L1 metric of 7.  Are you sure
(E,D,D) would bind to (D,A,A)?


Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread John M. Dlugosz

TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote:

HaloO,

John M. Dlugosz wrote:
In C++, which must be resolved at compile time, the overloading 
resolution mechanism demands that =every= parameter be at least as 
good of a match, and one strictly better match.  So the 
implementation never guesses if worse-left/better-right is a better 
fit than better-left/worse-right.  However, you are assured that 
everything is brought to your attention at program build time, before 
run time, so complaining is not as serious as a run-time error where 
you might prefer DWIM.


Perl 6 is the same, just at runtime with actual types of actual objects.
That's it.

Regards, TSa.
Then why is everyone against no worse for all parameters, rather than 
summing?


Re: Minimal Distance (Re: Where is Manhattan Dispatch discussion?)

2008-05-06 Thread John M. Dlugosz

Larry Wall larry-at-wall.org |Perl 6| wrote:

On Tue, May 06, 2008 at 08:20:40PM +0200, TSa wrote:
  

HaloO,

John M. Dlugosz wrote:

In C++, which must be resolved at compile time, the overloading resolution 
mechanism demands that =every= parameter be at least as good of a match, 
and one strictly better match.  So the implementation never guesses if 
worse-left/better-right is a better fit than better-left/worse-right.  
However, you are assured that everything is brought to your attention at 
program build time, before run time, so complaining is not as serious as a 
run-time error where you might prefer DWIM.
  

Perl 6 is the same, just at runtime with actual types of actual objects.
That's it.



Indeed, Perl 6 threw out Manhattan distance a couple years ago.  Do we
have to spec everything that Perl 6 ever was but isn't now?  :)

Larry

  
No, just point me to what it says now.  Or the scraps so I can collect 
them together and say it during my productive period.


When I mentioned this before, there was big flack over mentioning the 
way C++ did it.  I think that must have been miscommunicated, since I 
wasn't even talking about summing all the arguments when he brought up 
Manhattan dispatch.


Re: my TypeName $x;

2008-05-06 Thread Jon Lang
Larry Wall wrote:
 Jonathan Worthington wrote:
   role Bar { }
   my Bar $x;   # $x is ???
   say $x;  # ???
   say $x.WHAT; # ???
   # This means we can only assign to $x something that does Bar?

  Correct, and for the same reason.  The container checks the role--it
  has little to do with what's in $x currently, which *cannot* have
  the type of Bar, since you can't instantiate that.


   subset EvenInt of Int where { $_ % 2  == 0 };
   my EvenInt $x;  # $x is ???
   say $x;  # ???
   say $x.WHAT;  # Failure?
   # This means we can only assign to $x something that matches the constraint

  Yes, again, checked by the container, not by $x.  $x cannot have the
  type of a subset either!  The actual type of $x is Int.  Objects may
  only be blessed as valid storage types of some kind or other.  Subsets
  are merely extra constraints on a storage type (here Int).


   class Dog { }
   class Cat { }
   my Dog|Cat $x;  # $x is ???
   say $x;   # ???
   say $x.WHAT;  # Failure?
   # This means we can only assign to $x something that isa Dog or isa Cat

  Well, maybe $x is just Object, or whatever is the closest type that
  encompasses both Dog and Cat.  But note that Object is just the most
  generic kind of undef, so this is more or less equivalent to doing
  no initialization in p5-think.  I don't think I'm interested in making
  the run-time system calculate a Dog|Cat storage type, so it comes out
  to just a constraint.

  Really, the main reason we initialize with an undef of the correct sort
  is so that you can say

 my Dog $x .= new();

  But what would (Dog|Cat).new() do?  Constructors are not required to
  know about subset types or roles.  Constructors just create plain ordinary
  classes, I expect.  Composition and constraint checking happen
  elsewhere.

Two questions:

1. Apparently, my presumption that $x.WHAT was for retrieving the
value type was wrong; from the above, it's sounding like it is
supposed to retrieve the implementation type.  Is this correct?  If
so, for what purpose does $x.WHAT exist that you can't do just as well
with $x itself?  If it's for the stringification of the container's
name, couldn't that be accomplished just as easily by means of a
$x.HOW method, such as $x.^name?

2. How _do_ you retrieve the value type of $x?  That is, how can the
program look at $x and ask for the constraints that are placed on it?
I don't see $x.HOW being useful for this, since HOW is essentially
there to let you look at the inner workings of the container; and none
of the other introspection metamethods in S12 come close to addressing
this question.

-- 
Jonathan Dataweaver Lang


Re: my TypeName $x;

2008-05-06 Thread Larry Wall
On Tue, May 06, 2008 at 07:01:29PM -0700, Jon Lang wrote:
: 1. Apparently, my presumption that $x.WHAT was for retrieving the
: value type was wrong; from the above, it's sounding like it is
: supposed to retrieve the implementation type.

I don't know what you mean by those terms.  .WHAT gives you an value
of undef that happens to be typed the same as the object in $x,
presuming your metaobject believes in types.  .HOW gives you the
metaobject that manages everything else for this object.  It might
or might not believe in classes or types.


: Is this correct?  If
: so, for what purpose does $x.WHAT exist that you can't do just as well
: with $x itself?

You can do type reasoning with the WHAT type just as you can with
a real value of the same type.  Int is a prototypical integer from
the standpoint of the type system, without actually having to *be*
any particular integer.

In contrast, the .HOW object for Int is very much *not* an Int.
Perl doesn't know or care what the type of the .HOW object is, as
long as it behaves like a metaclass in a duck-typed sort of way.
It's probably a mistake to try to use the type of the .HOW object in
any kind of type-inferential way.

: If it's for the stringification of the container's
: name, couldn't that be accomplished just as easily by means of a
: $x.HOW method, such as $x.^name?

No, that's not what it's for at all.  It's only convenient that it
generally stringifies to something that looks like a package name,
assuming it's not an anonymous type.  But the primary purpose is to
provide a closed system of types that is orthogonal to whether the
object is defined or not.  In Haskell terms, they're all Maybe types,
only with a little more ability to carry error information about
*why* they're undefined, if they're undefined.

: 2. How _do_ you retrieve the value type of $x?

Do you mean the variable, or its contents?  The contents returns its
object type via $x.WHAT, which for an Int is always Int, regardless
of any extra constraints imposed by the container.

: That is, how can the
: program look at $x and ask for the constraints that are placed on it?

Placed by the variable, or by the type of the contents?  The
constraints on the value are solely the concern of whatever kind of
object it is.  If you mean the constraints of the container, then
VAR($x).WHAT will be, say, Scalar of Int where 0..*, and VAR($x).of
probably can tell you that it wants something that conforms to Int.
I'm not sure if the of type should include any constraints, or just
return the base type.  Probably a .where method would return extra
constraints, if any.

: I don't see $x.HOW being useful for this, since HOW is essentially
: there to let you look at the inner workings of the container; and none
: of the other introspection metamethods in S12 come close to addressing
: this question.

$x.HOW is not the inner workings of the container, but of the value.
You'd have to say VAR($x).HOW to get the inner workings of the
container.  Scalar containers always delegate to their contents.  In
contrast, @x.HOW would be equivalent to VAR(@x).HOW, because composite
objects used as scalars assume you're talking about the container.

Larry


Re: my TypeName $x;

2008-05-06 Thread Jon Lang
On Tue, May 6, 2008 at 8:09 PM, Larry Wall [EMAIL PROTECTED] wrote:
 On Tue, May 06, 2008 at 07:01:29PM -0700, Jon Lang wrote:
  : 1. Apparently, my presumption that $x.WHAT was for retrieving the

 : value type was wrong; from the above, it's sounding like it is
  : supposed to retrieve the implementation type.

  I don't know what you mean by those terms.

Oh?  I took them straight out of S2:

Explicit types are optional. Perl variables have two associated
types: their value type and their implementation type. (More
generally, any container has an implementation type, including
subroutines and modules.) The value type is stored as its of property,
while the implementation type of the container is just the object type
of the container itself. The word returns is allowed as an alias for
of.

The value type specifies what kinds of values may be stored in the variable.

By my reading of this: given my Dog|Cat $x, the value type would be
Dog|Cat, since you've specified that $x can store values that are
Dogs or Cats.

  .WHAT gives you an value
  of undef that happens to be typed the same as the object in $x,
  presuming your metaobject believes in types.  .HOW gives you the
  metaobject that manages everything else for this object.  It might
  or might not believe in classes or types.

OK; that's what I thought you were saying.

  : Is this correct?  If
  : so, for what purpose does $x.WHAT exist that you can't do just as well
  : with $x itself?

  You can do type reasoning with the WHAT type just as you can with
  a real value of the same type.  Int is a prototypical integer from
  the standpoint of the type system, without actually having to *be*
  any particular integer.

Yes; but what can you do with $x.WHAT that you _can't_ do just as
easily with $x itself?  After all, you've already got $x; and it has
already been initialized with an undefined Int upon creation, making
it a prototypical integer until such time as you assign a value to it.
 Furthermore, whether or not it has a value is utterly immaterial for
type-checking purposes.  So why would I ever say $x.WHAT instead of
just $x?

  In contrast, the .HOW object for Int is very much *not* an Int.
  Perl doesn't know or care what the type of the .HOW object is, as
  long as it behaves like a metaclass in a duck-typed sort of way.
  It's probably a mistake to try to use the type of the .HOW object in
  any kind of type-inferential way.

That's more or less what I understood.

  : If it's for the stringification of the container's
  : name, couldn't that be accomplished just as easily by means of a
  : $x.HOW method, such as $x.^name?

  No, that's not what it's for at all.  It's only convenient that it
  generally stringifies to something that looks like a package name,
  assuming it's not an anonymous type.  But the primary purpose is to
  provide a closed system of types that is orthogonal to whether the
  object is defined or not.  In Haskell terms, they're all Maybe types,
  only with a little more ability to carry error information about
  *why* they're undefined, if they're undefined.

Right.  I didn't think that the stringification was a big deal; but it
was the only thing that I could find that differentiated $x from
$x.WHAT.

  : 2. How _do_ you retrieve the value type of $x?

  Do you mean the variable, or its contents?  The contents returns its
  object type via $x.WHAT, which for an Int is always Int, regardless
  of any extra constraints imposed by the container.

I've been assuming that the value type is associated to the variable;
otherwise, a simple assignment of a completely different container to
the variable would completely bypass any and all constraints.  Am I
wrong about this?

  : That is, how can the
  : program look at $x and ask for the constraints that are placed on it?

  Placed by the variable, or by the type of the contents?  The
  constraints on the value are solely the concern of whatever kind of
  object it is.  If you mean the constraints of the container, then
  VAR($x).WHAT will be, say, Scalar of Int where 0..*, and VAR($x).of
  probably can tell you that it wants something that conforms to Int.
  I'm not sure if the of type should include any constraints, or just
  return the base type.  Probably a .where method would return extra
  constraints, if any.

OK; I'll have to look up what I can about VAR.

  : I don't see $x.HOW being useful for this, since HOW is essentially

 : there to let you look at the inner workings of the container; and none
  : of the other introspection metamethods in S12 come close to addressing
  : this question.

  $x.HOW is not the inner workings of the container, but of the value.
  You'd have to say VAR($x).HOW to get the inner workings of the
  container.  Scalar containers always delegate to their contents.  In
  contrast, @x.HOW would be equivalent to VAR(@x).HOW, because composite
  objects used as scalars assume you're talking about the container.

...and you appear to be using