Re: Draft Proposal: Symmetry between Attributes and Accessors

2002-10-05 Thread Paul Johnson

On Fri, Oct 04, 2002 at 04:42:27PM -0700, Michael Lazzaro wrote:

 [Draft Proposal: Symmetry between Attributes and Accessors]
 
 It is proposed that class attributes may be treated as functionally 
 equivalent to an identically named accessor method.  In this manner, it 
 shall become irrelevant to callers whether a public attribute of an 
 object is implemented as an attribute, or an lvalue method.

Excellent.  When Chip was starting Topaz a lot of implementation
languages were suggested.  Eiffel seemed to have a lot going for it, and
this was one of its features that I really liked.

The argument, of course, is that the implementation is, well, just an
implementation detail and that exposing it to the class user breaks
encapsulation.

 [CONS]
 
 - Making publicly accessible attributes at all is considered Bad Form 
 in most OO methodologies, which advocate the use of explicit accessor 
 methods.  We may wish to discourage or even prohibit the behavior.

If, as a class user, you can't (easily) tell the difference between a
method call and an attribute, I don't see any problem.

 - An attribute and a method are _not_ typically implemented in the same 
 manner.  Treating the two as interchangeable might imply runtime 
 overhead.

Bah!  I bet the internals list will laugh at you :-)

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net



Re: Draft Proposal: Symmetry between Attributes and Accessors

2002-10-05 Thread Dan Sugalski

At 10:58 AM +0200 10/5/02, Paul Johnson wrote:
On Fri, Oct 04, 2002 at 04:42:27PM -0700, Michael Lazzaro wrote:
   - An attribute and a method are _not_ typically implemented in the same
  manner.  Treating the two as interchangeable might imply runtime
  overhead.

Bah!  I bet the internals list will laugh at you :-)

will? Nah, we've been laughing for days. ;-P
-- 
 Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
   teddy bears get drunk



Re: Private contracts?

2002-10-05 Thread Chris Dutton


On Friday, October 4, 2002, at 06:23  PM, [EMAIL PROTECTED] wrote:

 On Fri, Oct 04, 2002 at 09:13:45AM -0400, Chris Dutton wrote:
 How exactly does one weaken a precondition?

 At least in Eiffel, if you redefine a method, you may not give it
 stringer preconditions than the original method, but you may have
 stronger postconditions.  In essence, you're not requiring any more of
 the client, but you can ensure more to them on completion, thus
 maintaining the parent's contract.

 But what does it mean to be stronger?  How does Eiffel figure out if
 a given precondition is stronger or weaker than another?

Perhaps an example is the best way to demonstrate this:

class FOO
creation make
feature
make(input: SOME_OTHER_CLASS) is
require
input /= Void
do
-- something here
ensure
input /= Void
end
end

-- Good:

class BAR
inherit FOO redefine make end
creation make
feature
make(input: SOME_OTHER_CLASS) is
-- no requirements, weaker precondition
do
-- yada yada
ensure
input /= Void
old input.some_attribute /= input.some_attribute
-- stronger postcondition is ok.
end
end

-- Bad:

class BAR
inherit FOO redefine make end
creation make
feature
make(input: SOME_OTHER_CLASS) is
require
input /= Void
input.some_attribute = 1
-- requiring more than the parent's make procedure is bad.
do
-- yada yada
-- Not ensuring anything to the client is bad.
-- The parent honored that in its contract, so
-- the child must also.
end
end




Re: Private contracts?

2002-10-05 Thread Allison Randal

On Fri, Oct 04, 2002 at 12:03:44AM -0400, Trey Harris wrote:
 In a message dated Thu, 3 Oct 2002, John Williams writes:
 
  On Thu, 3 Oct 2002, Trey Harris wrote:
 
   Incidentally, has there been any headway made on how you DO access
   multiple classes with the same name, since Larry has (indirectly) promised
   us that?  I.e., I import two classes LinkedList and BTree, both of
   which define a Node class?
 
  Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines
  a BTree::Node class.  Either by explicitly naming them that or by virtue
  of being defined as an inner class (which might also make it private).
 
 Ah, but that's the way you do it now--name the classes differently.
 (Easy--assuming you control the source code!)  In Perl 6, we're supposed
 to be able to use multiple versions of the same class concurrently, which
 I think would imply also being able to use multiple classes that happened
 to be named the same thing.

It doesn't imply that. The currently proposed solution is that the true
name of a class will include at least the version. But, you can alias
classes just like variables:

# compile time
class Foo is really (Acme::Kung::Foo-1_54);

# runtime
class Foo := Acme::Kung::Foo-1_54;

# (the full classname format hasn't been hashed out yet, this is
# just for sake of illustration)

So, you could reuse the same short name for multiple different classes,
as long as you lexically scoped your aliases. I wouldn't recommend it
though, unless you're trying to confuse people. Even in the rare case
when you need to use two different versions of the same class in the
same code, there will be a clearer way to do it.

More useful: keep a site-wide or company-wide file of version aliases to
make sure everyone uses the same version, and to make upgrades to the
next version as simple as editing a single file.

Allison



Re: Private contracts?

2002-10-05 Thread Trey Harris

In a message dated Sat, 5 Oct 2002, Allison Randal writes:
 More useful: keep a site-wide or company-wide file of version aliases to
 make sure everyone uses the same version, and to make upgrades to the
 next version as simple as editing a single file.

Ah, but the usual case is this:

You download from CPAN class A that depends on version 1.0 of class N.
You then download class B that also depends on version 1.0 of class N.
You create an application that uses both classes A and B (and thus N
through the dependencies.) Some time later, you discover a bug that
requires you to upgrade class B, but the upgrade now depends on class 1.1
of class N.  Class A hasn't been upgraded yet, and turns out not to work
well with version 1.1 of N.  So you need both versions 1.1 and 1.0 of
class N running in the application--preferably without having to modify
any of your app, class A, or class B.

This could be made to work (assuming that classes A and B both specify
which version of N they need).

Trey




Re: Draft Proposal: Attributes: public vs. private

2002-10-05 Thread Michael Lazzaro

Dan Sugalski wrote:
 
 There won't be any direct access to attributes outside class methods
 of the class that defines the attributes, unless Larry changes his
 mind in a big way. (And, honestly, probably not even then) Instead
 it'll all be accessed via lvalue methods. If an attribute is exposed
 there's just an lvalue method created, if it's not exposed there
 isn't.

Ack!  Hold on, there:  I'm being told that Damian thinks lvalues are
probably out, and that Larry thinks that pseudo-attributes will be made
accessed through the use of lvalues.  Please confirm, which is it?  I
don't particularly care, I just want to write an example down in
best-guess form.

Now, second question: if slots are in, that means that there is
fundamentally no difference between a method and attribute.  (This is a
Very, Very Good Thing.)  Will there be a _syntactic_ difference?  e.g.

class Zap { # style A
attr $sfoo = 5; # scalar
attr %kfoo = { key = value };  # hash(?)
method sbar { ... code ... };   # method
}

- vs something like -

class Zap { # style B
method sfoo = 5;# scalar
method kfoo = { key = value }; # hash(?)
method sbar { ... code ... };   # method
}

- or like -

class Zap { # style C
slot $sfoo = 5; # scalar
slot %kfoo = { key = value };  # hash(?)
slot $sbar = method { ... code ... };   # method
}


MikeL



RE: Draft Proposal: Attributes: public vs. private

2002-10-05 Thread Brent Dax

John Williams:
# Personally, I hope they look like attributes.  But if they 
# do, the perl5 
# lvalue subs are not the way to do it.  Why?  Because an 
# lvalue sub returns 
# a lvalue which get set _after_ the sub returns.  At that 
# point it is too 
# late for the sub to do anything useful with the new value.

You can do validation in Perl 5 with tied variables (I think), but
that's a lot of effort.

We could do something related to the old lvalue subs, with optional
validation:

#Just like Perl 5
method foo() is rw {
return $.foo;
}

#A little different
method bar() is rw($new_bar) {
if(defined $new_bar) {
#yeah, I know, what if $new_bar=undef--maybe
exists?
validate_bar($new_bar);  #Throws an exception if
invalid
$.bar=$new_bar;
}
else {
$.bar;
}
}

--Brent Dax [EMAIL PROTECTED]
@roles=map {Parrot $_} qw(embedding regexen Configure)

Wire telegraph is a kind of a very, very long cat. You pull his tail in
New York and his head is meowing in Los Angeles. And radio operates
exactly the same way. The only difference is that there is no cat.
--Albert Einstein (explaining radio)




Re: RFC: [] as the solitary list constructor

2002-10-05 Thread Larry Wall

On Tue, 24 Sep 2002, Luke Palmer wrote:
: =head1 TITLE
: 
: Square brackets are the only list constructor
: 
: =head1 VERSION
: 
:   Maintainer: Luke Palmer [EMAIL PROTECTED]
:   Date: 24 Sep 2002
:   Number: 362 (?)
:   Version: 1
: 
: =head1 ABSTRACT
: 
: This RFC responds to the fury on perl6-language about the redundancy of 
: parentheses and brackets with respect to list construction.  It proposes 
: that only brackets may be used to create lists (or arrays), and 
: parentheses be left for grouping.
: 
: =head1 DESCRIPTION
: 
: Because of the addition of the flattening operator, parentheses in Perl 6, 
: when used as list constructors, are entirely redundant with brackets. 

I cringe every time someone says Parens construct lists in Perl 6.
Parens don't construct lists in Perl 6.  They merely group.  The only
difference from Perl 5 is that if they happen to group a comma in
scalar context, the comma acts differently, not the parens.  But the
comma acts differently whether or not there are parens.  It depends
only on the context.  I admit that it's difficult to get a comma into
scalar context without parens, at least with the current precedence
table.  But if we swapped the precedence of comma and assignment,
it would still be the case that

$a = 1,2,3;

generates a list because of the comma.  The grouping would be implicit.
(But there are other problems with doing that.)

You can actually do the grouping without parens:

$foo = do { 1,2,3 };

Gee, maybe we should get rid of parens, since they're redundant.   :-)

So the parens have little to do with the list construction.  It's all
the comma's fault.

And in general, parentheses should not be used to construct lists in
scalar context.  It's better to use [] explicitly.  In list context,
the [] is not at all the same as (), because () is essentially a
no-op in list context, while [] creates an array ref.

I suppose we could make comma merely puke in scalar context rather
than DWIM, at least optionally.

: Additionally, parentheses have one inconsistency which brackets do not:
: This is the following case, already shown on perl6-language:
: 
:   $a = ();# $a is a list reference with 0 elements
:   $a = (10);  # $a is the scalar 10
:   $a = (10, 20);  # $a is a list reference with 2 elements
:   # ...
: 
: If the ability to construct lists with parentheses is removed, so is this 
: inconsistency.

I don't think that's an important inconsistency.

: This has the added benefit that there is a significant 
: visual clue about when a list is being tossed around.  This doesn't break 
: any convenience, just changes the look of it:
: 
:   # Perl 6# Perl 5
:   [$a, $b] ^= [$b, $a];   # ($a, $b) = ($b, $a)
:   print *[$a=$b],\n;# print(($a=$b), \n);
:   push @a: *[1,2,3];  # push @a, (1,2,3);
:   push @a: [1,2,3];   # push @a, [1,2,3];

I'd rather they just work the way people expect from Perl 5.  Requiring
people to say *[1,2,3] when they could say 1,2,3 is needless obfuscation.

: =head2 Subroutines
: 
: One place of quarrel is subroutine calls. Would this change the argument 
: list delimiters to brackets?  I argue no, because they were never a 
: parenthesis-delimited list in the first place:
: 
:   print(Hello, World, \n);
:   print Hello, World, \n;
: 
: Thus, in this case, parentheses are used for grouping around the argument 
: list, not constructing it.

Indeed.   :-)

: The following transformation has been 
: mentioned:
: 
:   print($a, $b);
: 
: is equivilent to
: 
:   (print $a, $b);
: 
: so no change is necessary on account of subroutine calls.
: 
: =head2 Semantics
: 
: The semantics of brackets need to be changed slightly to support this.  
: Specifically, instead of creating a list Ireference, they create a list 
: Iobject.  This object may be stored in an @array interface, or a $scalar 
: interface.  The $scalar interface works the same way as array references 
: did.  But the way @arrays are assigned changes in this manner:
: 
:   @array = [1, 2, 3]; # @array has 3 elements, not 1
:   @array = [[1, 2, 3]];   # @array has 1 element: an array object
:   @array[0] = [1, 2, 3];  # same thing
: 
: Slices work as they always have.

I think if you're going to replace the whole array using a reference, it's
better to use the explicit binding:

@array := [1,2,3]

It's awfully handy that the right side of a normal list assignment
automatically flattens.  And it's what Perl 5 programmers expect.
They certainly won't expect [] to flatten.

: =head2 Hashes
: 
: For consistency, parentheses must be disallowed for hash construction as 
: well.  The same semantic changes apply to braces. This fixes the common 
: mistake:
: 
:   %hash = { a = 1, b = 2 };
: 
: will now DWIM.  

Well, that one can be caught, if not the other one.  Again, the right
approach to dealing with references is probably to bind:

%hash := { a = 1, b = 2 };

Re: RFC: [] as the solitary list constructor

2002-10-05 Thread Chip Salzenberg

According to Larry Wall:
 I suppose we could make comma merely puke in scalar context rather
 than DWIM, at least optionally.

I rather like Perl 5's scalar comma operator.

 : $a = ();# $a is a list reference with 0 elements
 : $a = (10);  # $a is the scalar 10
 : $a = (10, 20);  # $a is a list reference with 2 elements
 
 I don't think that's an important inconsistency.

What if $a and $b are both array refs, and maintenance programmer
changes:
for $a, $b { print }
to:
for $a { print }
Will that end up iterating across @$a?  The equivalent of that gotcha
was forever bugging me in Python (gack).
-- 
Chip Salzenberg - a.k.a.  -[EMAIL PROTECTED]
 It furthers one to have somewhere to go.



Re: Draft Proposal: Attributes: public vs. private

2002-10-05 Thread Noah White


On Friday, October 4, 2002, at 07:39  PM, Michael Lazzaro wrote:

[SNIP]

 Definition: private:

   A private attribute is an attribute whose scope is restricted such 
 that
   it may be accessed only within the class in which it has been 
 declared.
   It is not available to subclasses, nor to code outside the class.
   [But see an alternative possible definition, below]

[SNIP]

 Note that an alternate definition of private is often used, as 
 follows:

   A private attribute is an attribute whose scope is restricted such 
 that
   it may be accessed only within the class in which it has been 
 declared,
   OR WITHIN ANY CLASS THAT INHERITS FROM THAT CLASS.

I'll agree with that.


 Many programmers in fact expect private attributes to work this way. 
  Some languages recognize all three definitions, calling the above 
 protected access.

I'm not sure what languages you are referring to specifically, but if 
you are including JAVA in that list then you are incorrect because JAVA 
allows protected members to be accessed from within any class within 
the same package as well, wether it is a subclass or not.


 The notion of public attributes is controversial within the OO 
 world.  In general, public attributes may be better implemented as 
 public accessor methods to an attribute that remains private.  (It 
 typically depends on how the language in question uses attributes, 
 and whether the language treats attributes and methods in a roughly 
 symmetric fashion.)

It depends on how you want to encapsulate your implementation details. 
One of the weakest points of PERL5 is data encapsulation (IMHO). A 
respectable language should, at its core, enforce a simple, straight 
forward notion of scoping. So while languages may differ on the types 
of scoping they offer, the rules and implementations surrounding them 
should be concise and not open for interpretation.

Encapsulation in OO PERL5 provides a multitude of opportunity for 
people to go out and kill themselves, and anyone else using their code 
in grand array of variations.  Each variation producing its own unique 
and ghastly crime scene photo op.

You have at your disposal such ghastly choices of mayhem as:

Encapsulation via closures
Tie::SecureHash
Encapsulation via scalars...one of my personal masochistic favorites

Something as basic as scoping/encapsulation should not be something 
left up to the programmer to create an implementation of.  Nor, should 
they have the ability to create their own version of it.  I'm all for 
having 16 ways to approach a problem but not when it comes to 
fundamental language aspects. That degrades the robustness of the 
language. Two words, 'access modifiers'. :-)

OK, so back to the original topic of this thread.

I like Java's notion of things. Attributes and methods are package 
private by default. Which means they are only visible to package they 
are in (slightly more restrictive then protected). Java also offers the 
following access modifiers:

private - no visibility outside of the class
protected - classes in the package and subclasses inside or outside the 
package
public - all classes

-Noah




Re: Draft Proposal: Attributes: public vs. private

2002-10-05 Thread Noah White


 Note that an alternate definition of private is often used, as 
 follows:

  A private attribute is an attribute whose scope is restricted such 
 that
  it may be accessed only within the class in which it has been 
 declared,
  OR WITHIN ANY CLASS THAT INHERITS FROM THAT CLASS.

 I'll agree with that.


ACK!  After re-reading this I about puked. No, that notion of private 
would not be something I'd agree with :-) That's more like protected.

-Noah




Re: RFC: [] as the solitary list constructor

2002-10-05 Thread Noah White


On Saturday, October 5, 2002, at 09:33  PM, Larry Wall wrote:


 : Additionally, parentheses have one inconsistency which brackets do 
 not:
 : This is the following case, already shown on perl6-language:
 :
 : $a = ();# $a is a list reference with 0 elements
 : $a = (10);  # $a is the scalar 10
 : $a = (10, 20);  # $a is a list reference with 2 elements
 : # ...
 :
 : If the ability to construct lists with parentheses is removed, so is 
 this
 : inconsistency.

 I don't think that's an important inconsistency.

[SNIP]


 : This has the added benefit that there is a significant
 : visual clue about when a list is being tossed around.  This doesn't 
 break
 : any convenience, just changes the look of it:
 :
 : # Perl 6# Perl 5
 : [$a, $b] ^= [$b, $a];   # ($a, $b) = ($b, $a)
 : print *[$a=$b],\n;# print(($a=$b), \n);
 : push a: *[1,2,3];  # push a, (1,2,3);
 : push a: [1,2,3];   # push a, [1,2,3];

 I'd rather they just work the way people expect from Perl 5.  Requiring
 people to say *[1,2,3] when they could say 1,2,3 is needless 
 obfuscation.

I think needless obfuscation is treating $a = (10); as a scalar instead 
of a list reference containing one item when the rest of the the $a = 
() are list references.

-Noah




RE: RFC: [] as the solitary list constructor

2002-10-05 Thread Brent Dax

Noah White:
# I think needless obfuscation is treating $a = (10); as a 
# scalar instead 
# of a list reference containing one item when the rest of the the $a = 
# () are list references.

I think needless obfuscation is treating $a = (10) differently than $a =
10.  The latter is the behavior we've come to expect from other
languages.

This may not look consistent:

$a = (10);
$a = (10, 20);
$a = (10, 20, 30);
#...

But it is consistent with this:

$a = do { 10 };
$a = do { 10, 20 };
$a = do { 10, 20, 30 };
#...

(Thanks for pointing that out, Larry.)

Parens don't construct lists EVER!  They only group elements
syntactically.  One common use of parens is to surround a
comma-separated list, but the *commas* are creating the list, *not* the
parens!

--Brent Dax [EMAIL PROTECTED]
@roles=map {Parrot $_} qw(embedding regexen Configure)

Wire telegraph is a kind of a very, very long cat. You pull his tail in
New York and his head is meowing in Los Angeles. And radio operates
exactly the same way. The only difference is that there is no cat.
--Albert Einstein (explaining radio)




Re: Interfaces

2002-10-05 Thread Noah White


On Monday, September 30, 2002, at 08:23  PM, Michael G Schwern wrote:

 OTOH, Java interfaces have a loophole which is considered a design 
 mistake.
 An interface can declare some parts of the interface optional and then
 implementors can decide if they want to implement it or not.  The 
 upshot
 being that if you use a subclass in Java you can't rely on the optional
 parts being there.


Say what?!? I don't think so. If a JAVA class which implements an 
interface does not declare all of the methods of the interface then 
that class will be abstract and you won't be able to instantiate a 
concrete instance of it. You are guaranteed that any concrete instance 
of a class which implements an interface will contain ALL methods 
defined by the interface.

-Noah




Re: RFC: [] as the solitary list constructor

2002-10-05 Thread Noah White


On Sunday, October 6, 2002, at 01:50  AM, Brent Dax wrote:

 Parens don't construct lists EVER!  They only group elements
 syntactically.  One common use of parens is to surround a
 comma-separated list, but the *commas* are creating the list, *not* the
 parens!


Following this rule would mean that

  $a = ();  # $a is a list reference with 0 elements

should not be a list reference at all and would appear inconsistent.

-Noah