Re: ACID transactions for in-memory data structures

2006-05-16 Thread Rob Kinyon

On 5/15/06, Audrey Tang [EMAIL PROTECTED] wrote:

Rob Kinyon wrote:
 I'm pretty sure it wouldn't be very feasible to do this natively in
 P5. But, would it be possible to do it natively in P6? As in,
 supported within the interpreter vs. through some sort of overloading.

Look at is atomic in S17draft, and Software Transaction Memory in general?


Would there be a way for me to say Yes, I understand that Perl may
not generically understand how to revert this outside resource, such
as a database, but I do. and do a catch-type block for the revert?

Rob


ACID transactions for in-memory data structures

2006-05-15 Thread Rob Kinyon

I've been working on DBM::Deep, a way to have P5's data structures
stored on disk instead of RAM. One of the major features I've been
adding has been ACID transactions.

I'm pretty sure it wouldn't be very feasible to do this natively in
P5. But, would it be possible to do it natively in P6? As in,
supported within the interpreter vs. through some sort of overloading.

Rob


Re: Instance attributes collision

2006-02-15 Thread Rob Kinyon
On 2/14/06, Stevan Little [EMAIL PROTECTED] wrote:
 I think that the metaclass (stored in the pseudo-lexical $::CLASS)
 should create a number of anonymous roles on the fly:

role {
 multi method a (::CLASS $self) { ... }
 multi method a (::CLASS $self, Scalar $value) { ... }
}

role {
 multi method a (::CLASS $self) { ... }
 multi method a (::CLASS $self, Array @value) { ... }
}

 These roles would then be added to the metaclass using the normal
 rules of role composition. (NOTE: I assume that ::CLASS is unbound
 until the role is composed into a class, I think A12 might have stated
 this detail)

 Now obviously we have a conflict in our multi-methods. S12 only states
 that multi methods will be compared by their long names (name +
 signature) to resolve ambiguity, it does not state what happens when
 those long names conflict. I propose that they work just as normal
 method conflicts do, which is that both methods are excluded and the
 consuming class is then required to implement that method.

Is it just the first multimethod a(::CLASS $self) from each role being
excluded or are all the multimethod a(...)'s being excluded?

Rob


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 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: ff and fff [Was: till (the flipflop operator, formerly ..)]

2006-01-25 Thread Rob Kinyon
On 1/25/06, Juerd [EMAIL PROTECTED] wrote:
 Patrick R. Michaud skribis 2006-01-25 13:47 (-0600):
  On Wed, Jan 25, 2006 at 11:37:42AM -0800, Larry Wall wrote:
   I've changed the flipflop operator/macro to ff, short for flipflop.
   This has several benefits.  ...
  ...another of which is that we can use ff and fff to mean loud
  and really loud in our perl poetr^H^H^H^H^Hmusic.  :-)

 We need pp and ppp for balance.

/me wonders who signed up The Little Einsteins(tm) for P6l ...


Re: Perl 6's bless is (seriously) broken

2006-01-20 Thread Rob Kinyon
On 1/20/06, Juerd [EMAIL PROTECTED] wrote:
 Note, by the way, that JS has primitive strings, and Strings, only the
 latter being objects. Fortunately for us, though, a string is
 automatically promoted to a String when the string is USED AS an object.

In other words, according to userland, everything is an object.

  But, if you must use the WMoT, then I suspect the following will happen:
  1) The WMoT notices your use of bless and marks that package as a
  class and that method as a constructor.
  2) It creates a Perl6 class for your use, noting the accesses into
  the Perl5 reference that you used and calling those attributes.
  3) It then creates your BUILD() method, putting all the non-bless
  components of your new() into it.

 Doesn't solve the problems as mentioned in this thread, like overlapping
 methods.

Yeah it does because all $repr's are p6opaque with direct access being
converted into attribute access. No method overlap.

Rob


Re: Perl 6 OO and bless

2006-01-20 Thread Rob Kinyon
On 1/19/06, chromatic [EMAIL PROTECTED] wrote:
 On Thursday 19 January 2006 19:50, Rob Kinyon wrote:

  Nothing. Just like it's not a problem if Perl6 uses one of the
  Ruby-specific PMCs for storage. In fact, the alternate $repr idea is
  specifically to allow for the use of foreign datatypes as storage.
  Luke's excellent example is to use a C-struct as your storage.

 ... but ...

  Storage of what? What are you trying to do that you need to use an
  object to store your attributes? Why aren't you just using the method
  -that- object is using?

 I can't reconcile these two paragraphs.

The second paragraph was referring solely to where you're dealing with
Parrot datatypes only. If you have to go outside of Parrot (to a C
lib, for instance), then you do need to know about the storage
specifics.

  No. My objection to bless() is BUILD() and CREATE(). There's already a
  mechanism in the P6 OO system for specifying the internal
  representation of the instance.

 This is Perl.  The there should be one obvious way to do it ship, canoe,
 raft, and water wings have sailed, paddled, floated, and inflated.

And there is. You can create your own meta-object protocol on top of
p6opaque or any other representation you want. This is *Perl6* - you
can rewrite the whole damn grammar if you want to. You can use another
VM if you want to. (PIL^N runs on Javascript!)

I think this entire issue is rising out of the fact that very very few
people in this discussion are familiar with the design of the MOP.
Stevan and a few others are the primary movers and I'm lucky enough to
have been Stevan's sounding board for a few pieces. Once you grok the
MOP, it's really hard to imagine wanting to use bless(). It's
literally like trying to explain to a BASIC programmer why recursion
is good or trying to explain to a C programmer why automatic memory
management is handy. The frames of reference are so different that the
meaning being trasmitted is not the meaning being received.

Rob


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

2006-01-20 Thread Rob Kinyon
On 1/20/06, Larry Wall [EMAIL PROTECTED] wrote:
[snip really cool blathering]

I don't have much to say on the deeper question, but I have a few
ideas on the P5 - P6 translation question, especially as it relates
to OO:

1) Don't translate at all. Ponie, delegating to Parrot, is
supposed to handle all of that OO garbage in the same way that Ruby
and Python are going to interact with Perl6. Perl5 and Perl6 are as
similar as Ruby and Python, so you might as well write a translator
between them as one between Perl5 and Perl6.

Pros: Larry doesn't have to do anything more on the WMoT.
Cons: The community, for some reason, really wants this
auto-translator, even though there wasn't one for P4-P5 and P5-P6 is
a greater leap than P4-P5 was.

2) Don't attempt to translate $x-{whatever} (or $x-[2] or
$x-('whatever') ... ) in isolation. If it occurs within a function
defined in a package that has a function that uses bless and it's the
first parameter, it's an attribute access. Otherwise, it's a hash
access.

Pros: It's a nice and easy rule which will work if the programmer
didn't violate encapsulation, only puts methods in classes, and is
generally an all-around nice guy.
Cons: See Pros.

3) Since about half of all classes in P5-land use some module in
Class::* to auto-generate stuff (thus providing a nice place to find
all the attribute names), ask the community to provide a translator
for each of those. Then, use #2 for the others.

Pros: The WMoT can punt in about half the cases.
Cons: The WMoT cannot punt in about half the cases.

Rob


Parrot and PGE will save the day (was Re: as if [Was: Selective reuse of storage in bless.] )

2006-01-20 Thread Rob Kinyon
On 1/20/06, Nicholas Clark [EMAIL PROTECTED] wrote:
 On Fri, Jan 20, 2006 at 04:20:54PM -0500, Rob Kinyon wrote:
  Pros: Larry doesn't have to do anything more on the WMoT.
  Cons: The community, for some reason, really wants this
  auto-translator, even though there wasn't one for P4-P5 and P5-P6 is
  a greater leap than P4-P5 was.

 But (as I understood it) the P4-P5 leap was not intended to be so great
 that a translator would be needed. In fact, that confuses cause and effect.
 Because the technology wasn't there to write a translator, it constrained the
 size of the leap. The important part was that for Perl 5 to still be Perl,
 it had to keep running the vast majority of Perl scripts.

 In fact, Perl 5 still strives to maintain Perl 1 compatibility (and the
 perl5-porters joke is that even thinking about breaking this is the fastest
 way to summon the thought, er backwards compatibility police with a script
 he's been running unchanged since 1987). Why else can you still:

 $ perl -le '$h{1} = Perl; print values h'
 Perl
 $ perl -le 'push a, Perl; print @a'
 Perl

Now, that's an unadvertised feature! I think I need to revisit some golfs ...

 I believe that the translator is seen as needed (even by @Larry, I think)
 to maintain the same level of continuity in the Perl 5-6 transition as
 Perl 4-5 - your existing monolithic script runs on the newer Perl
 interpreter, and you can edit (within that same file) as and when you need
 to.

 Otherwise you're in the situation where you can only inter-operate languages
 the whole file level. Which means that it's the same actions to migrate from
 Perl 5 to (say) Python as from Perl 5 to Perl 6. And somehow I think that
 $Larry has some bias about which language he'd prefer everyone to find it
 easiest to migrate to, even if he's too modest to admit it.

Please don't take offense at this, but I believe you're using 20th
century thinking. The two most important features in Perl6 aren't -in-
Perl6 - they're Parrot and the PGE. Both of them make a translator
unnecessary. More precisely, they make a file-in-P5 to file-in-P6
translator unnecessary because you can have block-level
interoperability.

I'm making a few assumptions here:
1) Since PGE isn't part of Perl6 (because it's written in PIR), it
can be used as the parser/lexer/etc. for any language, not just Perl6.
2) Since PGE can be lexically-scoped, one can change the entire
grammar within a given block, including how variables are referenced,
subroutines are called, etc.
3) Since everything is, at the heart, just a PMC, so long as the
appropriate PIR is emitted, it doesn't matter how the userside code is
written so long as the right parser/lexer/whatever is used to
translate it to PIR.

So, if all three assumptions hold, then your monolithic Perl5 script
can easily inline any Parrot-targeted language you want, simply by
doing the following:
1) Use Ponie.
2) Within a block, import the appropriate PGE module(s) to
redefine the grammar to P6 and do what you need to do.

No translator needed.

Rob


Re: Perl 6 OO and bless

2006-01-19 Thread Rob Kinyon
On 1/19/06, Juerd [EMAIL PROTECTED] wrote:
 Rob Kinyon skribis 2006-01-18 20:57 (-0500):
  Well, for one thing, you can't write OO code in P5.

 Nonsense. OO isn't a set of features, and OO isn't syntax.

 Granted, syntax can really help to understand OO, and a set of features
 is nice, because it avoids having to re-invent wheels.

 But OO is just that: object orientation. It is a way of programming, and
 that can very well be done without any syntax or features for that in
 place.

I've said those very same things on Perlmonks. I stand by them, yet I
still maintain that you cannot write truly OO code in P5.

OOP is all about black-box abstraction. To that end, three items have
been identified as being mostly necessary to achieve that:
1) Polymorphism - aka Liskov substitutability
2) Inheritance - aka specialization
3) Encapsulation

P5 excels at #1, does #2 ok, and fails completely at #3. Now, one can
argue whether the programmer should make the decision as to whether
strong encapsulation is desirable, but the point is that you cannot
create encapsulation in Perl that someone else cannot violate.

Hence, you cannot write OO code in Perl.

 C's filedescriptors are objects/invocants, and so are PHP's MySQL
 resources.

I point you to http://www.perlmonks.org/?node_id=112180 where I say
that Perl's scalars are objects. I have since realized that tilly is
right, particularly after learning a more OO language (which just
happened to be Ruby).

 Perl 5 has syntax for OO, and even a few useful features. Even though
 these are not needed at all to write OO code, it certainly does help
 people to stick to OO design.

 And if more features are needed, CPAN has them.

 Object orientation is still object orientation if you write it
 differently: $bar-{foo}-(), if that's how you decide to write a method
 call on $bar, is still OO.

 Classes, like OO syntax, are not necessary for OO.

Javascript is a good example of this. Yet, even in JS, you have the
prototype, which is the class. Unless you plan on building
everything by hand, you still need a model for the new instance you're
creating. That model is the class. It's not an OO requirement, but an
OO consequence.

  You can write code that behaves like you're in OO-land and that talks
  with an OO accent (so long as you don't look behind the curtain), but
  it's not OO.

 Your definition of OO is far too specific for a 2-letter acronym.

OO is a spectrum, not a point. What I was trying to say was that when
comparing the OO you can do in P5 with the OO you will be able to do
in P6, it seems silly (to me) to cripple P6 out of a misguided effort
to maintain backwards compatibility with P5.

Rob


Re: Class methods vs. Instance methods

2006-01-19 Thread Rob Kinyon
On 1/18/06, Audrey Tang (autrijus) [EMAIL PROTECTED] wrote:
 http://cakoose.com/wiki/type_system_terminology#13

Any practical programming language with structural subtyping will
probably let you create and use aliases for type names (so you don't
have to write the full form everywhere). However, the underlying type
system will only consider the structure of the type when doing its
job.

What's wrong with Perl doing things that way? duck-typing with names
... sounds like a plan to me ...

Rob


Re: Perl 6's bless is (seriously) broken

2006-01-19 Thread Rob Kinyon
To further extend Steve's argument (which I wholeheartedly agree
with), I wanted to point out one thing: bless has nothing to do with
OO programming as conceived of in Perl6. It does one thing and only
one thing:
 - tag a reference with a package name.

This is used in a few places:
- to determine what package the 'meth' function lives in when the
syntax $foo-meth( @parms ) is encountered
- to determine what ref() should return

There are no references in Perl6. In fact, the only think you have in
Perl6 is objects, so why do we need to take something that isn't an
object (which doesn't exist) and do anything to it, let alone tag it
with a package name? Packages don't have anything to do with the class
system. If you want to change the behavior of something at runtime,
you can do so through .meta, roles, mixins, traits, and the like.

bless was a brilliant idea for Perl5. It's wrong for Perl6.

Rob


Re: Perl 6's bless is (seriously) broken

2006-01-19 Thread Rob Kinyon
On 1/19/06, Juerd [EMAIL PROTECTED] wrote:
 Rob Kinyon skribis 2006-01-19 16:10 (-0500):
  There are no references in Perl6.
 I have to admit, though, that I've never seen this statement, or
 anything implying it. It's entirely new to me.

 Is your Perl the same as that of other people on this list? :)

There are no references in Perl6 in the way Perl5 conceives of references.

 Perl still has non-object types. They may represent objects internally,
 but they work differently from what we've historically been calling
 objects. Especially in assignment, the differences are huge, because an
 object is considered a reference, while real scalars, arrays and
 hashes evaluate to (a list of) their values, or a useful representation
 (like the number of elements) when used in non-OO fashion.

No. Objects are *NOT* considered references in most languages other
than Perl5. Even in C++, the least OO language that could be
considered OO, you can have non-reference objects.

I'd say learn Ruby to know what OO is, but I happen to know you
already know a nearly-pure OO language - Javascript. Every single
'thing' in JS is an object - you can hang methods off of a string
literal or a number. Most objects in JS aren't references.

  bless was a brilliant idea for Perl5. It's wrong for Perl6.

 I think it's needed to be able to convert Perl 5 code
 semi-automatically.

 But you have probably thought about this more than I, so I'll ask you:
 what's the alternative?

Well, there's two scenarios - you either run your P5 code using Ponie
or you attempt to use Larry's Wondrous Machine of Translation.

Me, I choose the former. Now, I don't worry about how objects are
mediated between languages - Ponie and Parrot have to do that for me.
And, before you start worrying, this is a feature that was planned
into Parrot from Day 1. Ruby and Python and Perl6 all have to
interoperate, including inheritance from each others' classes. Perl5
- Perl6 will be no different.

But, if you must use the WMoT, then I suspect the following will happen:
1) The WMoT notices your use of bless and marks that package as a
class and that method as a constructor.
2) It creates a Perl6 class for your use, noting the accesses into
the Perl5 reference that you used and calling those attributes.
3) It then creates your BUILD() method, putting all the non-bless
components of your new() into it.

That's it. No bless in Perl6 needed.

Rob


Re: Perl 6 OO and bless

2006-01-19 Thread Rob Kinyon
On 1/19/06, chromatic [EMAIL PROTECTED] wrote:
 On Wednesday 18 January 2006 20:02, Rob Kinyon wrote:

  On 1/18/06, chromatic [EMAIL PROTECTED] wrote:

   Answer me this then -- under your scheme, can I subclass a Perl 5 class
   with Perl 6 code, instantiate the subclass, and use that object in Perl 5
   code as if the subclass were Perl 5 code, without rewriting all of my
   Perl 5 code?
 
  You have two cross-language interactions.
  1) Subclass a LangX class in LangY
  2) Instantiate a LangY class and use that object in LangZ

  That LangX === LangZ is irrelevant to the discussion.

 Unless, of course, if $omeone had promised backwards compatibility with LangZ
 5 from LangY 6.

I'm not sure how that promise is broken if Perl 6.0.0 includes Ponie
as part of the distribution.

 Next question.  If Ponie and Perl 6 are both running on Parrot, and if Ponie
 has PMCs that represent Perl 5 data containers, such as p5hash, p5array,
 p5symbol, and so on, what's the problem with having a Perl 6 object that uses
 one of those PMCs as its internal storage?

Nothing. Just like it's not a problem if Perl6 uses one of the
Ruby-specific PMCs for storage. In fact, the alternate $repr idea is
specifically to allow for the use of foreign datatypes as storage.
Luke's excellent example is to use a C-struct as your storage.

 I realize one of Stevan's objections is But if you use a Hash, does your
 object automatically support the .keys method and .kv and so on? to which I
 reply No, of course not.  That's silly.  It just uses the Hash for
 *storage*.

Storage of what? What are you trying to do that you need to use an
object to store your attributes? Why aren't you just using the method
-that- object is using?

And, for the record, I'm currently working on a proposal to p6l to
restrict object representations to unboxed types. So the problem that
Stevan is worried about in this objection would become moot.

 Is that your objection to bless()?

No. My objection to bless() is BUILD() and CREATE(). There's already a
mechanism in the P6 OO system for specifying the internal
representation of the instance. In fact, if you're crazy enough, you
can specify that at runtime. In other words, the functionality of
bless() has already been subsumed into the OO system and is called by
a few different names.

 Or is the question about Why is there a need for bless() when you can already
 pass arguments to CREATE()?  In that case I dunno.

Exactly. :-)

Rob


Class methods vs. Instance methods

2006-01-18 Thread Rob Kinyon
Today on #perl6, Audrey, Stevan and I were talking about $repr. A
tangent arose where Audrey said that the difference between class
methods and instance methods was simply whether or not the body
contained an attribute access.

Is this true? If it is, then I think it violates polymorphism as
demonstrated by the following:

class Dog {
method tail { brown and short }
};

class Chihuahua is Dog {
has $.color;
method tail { $.color _  and short }
};

You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
Chihuahua.tail. That's extremely counter-intuitive.

I think that class methods should be explicitly defined as class
methods and you cannot call a class method upon an instance, just as
you cannot call an instance method upon a class. Plus, this should be
determinable (for the most part) at compile time, which is a bonus,
imho.

Thanks,
Rob


Re: Class methods vs. Instance methods

2006-01-18 Thread Rob Kinyon
On 1/18/06, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Jan 18, 2006 at 01:56:53PM -0500, Rob Kinyon wrote:
 : Today on #perl6, Audrey, Stevan and I were talking about $repr. A
 : tangent arose where Audrey said that the difference between class
 : methods and instance methods was simply whether or not the body
 : contained an attribute access.
 :
 : Is this true? If it is, then I think it violates polymorphism as
 : demonstrated by the following:
 :
 : class Dog {
 : method tail { brown and short }
 : };
 :
 : class Chihuahua is Dog {
 : has $.color;
 : method tail { $.color _  and short }
 : };
 :
 : You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
 : Chihuahua.tail. That's extremely counter-intuitive.

 I don't think it's counterintuitive.  You've defined Dog with an
 invariant .tail but not Chihuahua.  It's doing exactly what you asked
 for under a prototype view of reality.

Except there are no such things as classes in a prototype view of
reality. Everything is an instance and there are no such things as
class methods. The entire idea that an object (::Dog) can call methods
that are for another object ($fido) is ... well ... it's a little off.

That's like saying any object can call any method from any other
object so long as that method is invariant.

 : I think that class methods should be explicitly defined as class
 : methods and you cannot call a class method upon an instance, just as
 : you cannot call an instance method upon a class. Plus, this should be
 : determinable (for the most part) at compile time, which is a bonus,
 : imho.

 I believe this is already determinble at compile time for the most part.

 But I have a strong gut-feeling that over the long term it's going to
 be important to be able to view a given object as either a partially
 instantiated class or a partially undefined object, and for that we have
 to break down the false class/instance dichotomy.  And to the extent
 that the dichotomy *isn't* false, we're trying to sweep classness into
 the .meta object, which is the *real* class object in Perl 6.

I'm sure you understand the distinction you're making. I know I don't
and I've been trying to follow this discussion for the past year. I'm
may not be the brightest bulb in the chandelier, but I'm no 15W dimmer
switch, either.

Frankly, you should be using people like me, Matt Fowles, and the
other  programmers on the list as sounding boards. If we're having
problems understanding the concept, then how are we going to explain
partially-instantiated classes on Perlmonks or #perl or clmp? Like
it or not, we're the sergeants in the Perl army. We're the guys
explaining all this stuff to the privates coming up the ranks. It may
be a nice extension to have, but I'm not sure this should be part of
the standard MOP.

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, chromatic [EMAIL PROTECTED] wrote:
 On Wednesday 18 January 2006 14:13, Stevan Little wrote:

  Do we really still need to retain the old Perl 5 version of bless?
  What purpose does it serve that p6opaque does not do in a better/
  faster/cleaner way?

 Interoperability with Perl 5 code.

Well, for one thing, you can't write OO code in P5. You can write code
that behaves like you're in OO-land and that talks with an OO accent
(so long as you don't look behind the curtain), but it's not OO.

Given that, I'm not sure that conceptual interoperability with P5 code
should be a design goal, particularly in the OO-space. Allowing
methods to be called on references that have been associated with a
given package is an easy addition to the current MOP. Just add
.blessed_into and have a step right before AUTOLOAD (or method_missing
or whatever) to check .blessed_into and try that package, if one is
set.

Also, given that the semantics of a number of items is changing (
.split(':') anyone?), how closely will P6 really mirror P5 behavior
given identical code?

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, chromatic [EMAIL PROTECTED] wrote:
 On Wednesday 18 January 2006 17:57, Rob Kinyon wrote:

  Well, for one thing, you can't write OO code in P5.

 I'll play your semantic game if you play my what-if game.

 I have a fair bit of Perl 5 code.  Ponie works.  I want to migrate my Perl 5
 code to Perl 6 slowly.  Everything new is Perl 6 code.  When I have a chance,
 I migrate classes and modules from Perl 5 to Perl 6 code.

 I have a handful of Perl 5 classes.  One day, I need to subclass one of them.
 Per my goal, I do so in Perl 6.  Of course, it has to interoperate with the
 Perl 5 in the system, per that pesky Liskov rule.  If I can specify an
 alternate internal representation for the object corresponding to the
 appropriate internal representation for the Perl 5 class I'm extending,
 great!

I think the more relevant question is How do I subclass a Ruby class
in Python and delegate to it from a Perl6 object that's used in a
Perl5 module that's implementing the event loop for a Java app?

The answer, of course, is that everything is mediated by Parrot (or
whatever VM they all choose to target). Just because one side is Perl6
and the other side is Perl5 doesn't mean that they should have any
closer of a relationship than Ruby and Python would. They are separate
languages, related only through a common creator, a shared community,
and the same VM. Nothing less, nothing more.

As for how that will be handled, I would think that it would be as follows:
- in Perl6, objects created in another language will be treated as
p6opaque (unless some other unbox is a more suitable $repr).
- in Perl5, objects created in another language will be treated as
inside-out objects.

 If not, your programming language sucks and doesn't do what the box leads me
 to believe that it should do -- especially if the answer is Well you
 shouldn't want to do that.

The box you're talking about is the box with Parrot on the cover,
not Perl6. And, you most definitely want to be able to do what you're
suggesting and it will be possible.

You'll just have to give up on the mismeme of bless, and I think
you'll find that oddly freeing.

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, chromatic [EMAIL PROTECTED] wrote:
 On Wednesday 18 January 2006 19:11, Rob Kinyon wrote:

  As for how that will be handled, I would think that it would be as follows:
  - in Perl6, objects created in another language will be treated as
  p6opaque (unless some other unbox is a more suitable $repr).

 ... and I specify this exactly how?

I was intending for that to mean that Parrot might indicate that the
representation in Perl6 for a Perl5 object could be p6hash instead of
p6opaque, but that might be a little too clever.

I was thinking, actually for interoperability with something like C++
where your classes are laid-out-in-memory structs (which is the best
reason I've heard for having alternate $repr). There certainly is no
good reason within Perl6 itself to muddy up the waters like that.

You really want to read
http://svn.openfoundry.org/pugs/docs/notes/piln_object_repr_types.pod

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, chromatic [EMAIL PROTECTED] wrote:
 1) by default, your object is opaque
 2) if you don't want this, you can always use bless()

 For interoperability with Perl 5 classes, I don't want to use an opaque
 object.  Ergo, I want to use bless() (or something, but does that explain why
 I think bless() is important?).

No, you want to specify the $repr in CREATE(). But, p6hash will still
not be the same as a ref to an HV. Frankly, I think you're better off
letting Parrot mediate things the same way it would mediate Ruby and
Perl6 or Perl5 and Python. Worrying about it in userland is just going
to cause you headaches.

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, chromatic [EMAIL PROTECTED] wrote:
 On Wednesday 18 January 2006 19:39, Rob Kinyon wrote:

  No, you want to specify the $repr in CREATE(). But, p6hash will still
  not be the same as a ref to an HV. Frankly, I think you're better off
  letting Parrot mediate things the same way it would mediate Ruby and
  Perl6 or Perl5 and Python. Worrying about it in userland is just going
  to cause you headaches.

 Answer me this then -- under your scheme, can I subclass a Perl 5 class with
 Perl 6 code, instantiate the subclass, and use that object in Perl 5 code as
 if the subclass were Perl 5 code, without rewriting all of my Perl 5 code?

You have two cross-language interactions.
1) Subclass a LangX class in LangY
2) Instantiate a LangY class and use that object in LangZ
That LangX === LangZ is irrelevant to the discussion.

So long as you aren't peeking behind the curtain (method calls only),
Parrot should be able to mediate everything. In other words, if your
code is good OO code, then you shouldn't have any problems.

Rob


Re: Perl 6 OO and bless

2006-01-18 Thread Rob Kinyon
On 1/18/06, Trey Harris [EMAIL PROTECTED] wrote:
 Excuse my ignorance of the finer points, but I thought the reason for
 bless's continued existence was so that the same sort of brilliant OO
 experimentation that Damian and others have done with pure Perl 5 can
 continue to be done in pure Perl 6 without having to hack p6opaque?

That's what the .meta and the MetaObject Protocol is for. Not to
mention that 90% of the hacking done in Class:: and Object:: will
handled by the fact that Perl6 has actual OO syntax. (Look Ma, no
hands!) You won't need Class::MakeMethods because Perl6 will make
your accessors for you. You won't need Class::Std to protect your
instance data because p6opaque will ... well, it's opaque. :-)

As for the ability to hook into the P6 OO system, you'll have
CREATE, BUILD, BUILDALL, true NEXT semantics, and the ability to
completely rewrite the method dispatcher (if you really feel like it).
I think we've gone well beyond bless.

Rob


Re: Indeterminate forms for the Num type.

2006-01-17 Thread Rob Kinyon
On 1/17/06, Audrey Tang [EMAIL PROTECTED] wrote:
 But putter on #perl6 reports 1 on his amd64.  I'd be happy we spec it
 has to have to return 1 always for boxed Num types, even though it means
 additional cycles for boxed numeric types.

Isn't the point of boxing to provide a hardware-independent dependable
solution at the cost of additional cycles?

Rob


Re: The old $x will not stay shared thing.

2006-01-16 Thread Rob Kinyon
On 1/16/06, Larry Wall [EMAIL PROTECTED] wrote:
 Yes, at least for any block that really is capturing a closure.
 Perhaps we need to distinguish those from accidentally nested
 top-level functions.  But undecorated sub is more-or-less defined
 to be our sub anyway, just as with package, module, and class
 these days.  The only difference is that our explicitly introduces
 a lexically scoped alias, while the undecorated form presumably doesn't.
 Though we could break that too, I suppose.

What is the benefit for -not- explicitly introducing a lexically
scoped alias? Is there some performance reason why the undecorated
form wouldn't?

 : * If we insert a call to g() above without calling f() first, should it
 : assume an uninitialized $x, or throw an exception (Pugs currently does
 : the latter)?

 An exception is fine, modulo what I said about accidental nesting.
 When do you detect the condition?  If the inner function can't
 reference $x, does it still fail?  On the other hand, we can get into
 eval issues where it might or might not reference $x.  I'm okay
 with requiring lexical scopes to have some existing relationship
 with dynamic scopes, especially when we know some initialization is
 required.

What other forms would be useful other than our sub g {...}? If
they're useful, shouldn't they have keywords?

Rob


Re: Table of Perl 6 Types

2006-01-12 Thread Rob Kinyon
 I wouldn't see a problem with defining a Real role that has a fairly
 sparse set of operations. Afterall, a type that does support ++ and --
 (e.g. Int, Num) could easily does Enumerable if it wants to declare
 that it supports them.

What about the scripty-doo side of Perl6? One of the overriding design
considerations that Larry put forward at the very beginning was that
the easy things are easy part of the philosophy would still remain.
I want to still be able to do something like

perl -pia -e '@F[2]++' somefile.xsv

And it just DWIM for numbers like 1.2 ( - 2.2). If Real is what 1.2
is implicitly coerced into, what do I do now?

Remeber a few truisms:
* The most common usage of Perl after bad CGIs is systems administration.
* The most powerful feature of Perl for sysadmins is the scalar

Rob


Re: Table of Perl 6 Types

2006-01-12 Thread Rob Kinyon
On 1/12/06, Ævar Arnfjörð Bjarmason [EMAIL PROTECTED] wrote:
 The next/prev semantics are, and should be more general than ±1, I
 just think that ±1 should remain the default for reals  ints.

So, Num (and all types that derive from Num) should have a next of {
@_[0] + 1 } and a prev of { @_[0] - 1 } (boundschecking against the
limits of the type, of course) ... ?

That sounds reasonable and dwimmish to me.

Rob


Re: Junctions again (was Re: binding arguments)

2006-01-04 Thread Rob Kinyon
On 1/2/06, TSa [EMAIL PROTECTED] wrote:
 HaloO,

 Luke Palmer wrote:
  The point was that you should know when you're passing a named
  argument, always.  Objects that behave specially when passed to a
  function prevent the ability to abstract uniformly using functions.[1]
  ...
  [1] This is one of my quibbles with junctions, too.

 You mean the fact that after $junc = any(1,2,3) there is
 no syntactical indication of non-scalar magic in subsequent
 uses of $junc e.g. when subs are auto-threaded? I strongly
 agree. But I'm striving for a definition where the predicate
 nature of the junctions is obvious and the magic under control
 of the type system.

I'm confused at the confusion. To me, junctions are just magical
values, not magical scalars. In theory, one should be able to create
junctions of arrays, hashes, or subs just as easily.

my @junc = any( @a, @b, @c );
my %junc = any( %a, %b, %c );

Then,

if @junc[2] == 9 { ... }

would imply

if @a[2] == 9 || @b[2] == 9 || @c[2] == 9 { ... }

IMHO, one thing that may be causing issues with the junction concept
is that I've never seen anyone talk about the implicit read-only
behavior of a junction. To me, a junction would be required to be
read-only (except for overall assignment). To modify the junction
would be to overwrite it. So, given

my $junc = any( $a, $b, $c );

If you wanted to add $d into there, you'd have to do it this way:

$junc = any( $junc, $d );

Obviously, modifications to $a, $b, or $c would carry through. Doing
this means that array, hash, and sub junctions make sense and behave
no differently than any other readonly variable.

In fact, this behavior seems mandated given the possibility of tying
variables (or is this a Perl5ism that is being discarded in Perl6?)

Rob


Re: relationship between slurpy parameters and named args?

2005-12-30 Thread Rob Kinyon
On 12/30/05, Piers Cawley [EMAIL PROTECTED] wrote:
 Stuart Cook [EMAIL PROTECTED] writes:

  On 29/12/05, Austin Frank [EMAIL PROTECTED] wrote:
  So, is there a conceptual connection between imposing named argument
  interpretation on pairs in an arg list and slurping up the end of a
  parameter list?  Are there other meanings of prefix:* that relate to
  one or the other of these two meanings?
 
  The missing link is that prefix:* in an argument list also causes
  things like arrays to be treated as a sequence of separate parameters,
  rather than as a single array parameter.  See Flattening argument
  lists in S06.
 
  (This was the original meaning of prefix:* in arglists; the
  named-pair behaviour was added later, when pair values ceased to have
  named behaviour automatically.)

 Personally, I think that prefix * in an arglist should only flatten
 array arguments if there is only one array. And if it doesn't, how do
 I declare parameter that is 'a slurpy list of arrays' or 'the rest
 of the arguments, without flattening'. If I *really* want aggressive
 flattening then I can call, say, @slurpy_param.flatten

Does this imply that [EMAIL PROTECTED] === @slurpy.flatten ?

Or, put another way, can't we just say that prefixed * is symbolic
notation for flatten() in the same way that postfixed [] is symbolic
notation for slice()?

Rob


Re: Array/list transformations.

2005-12-27 Thread Rob Kinyon
On 12/27/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Tue, Dec 27, 2005 at 12:10:45AM -0500, Rob Kinyon wrote:
 : Creating an array whose positions are aliases for positions in another
 : array can be useful. How about
 :
 : my @s := @a[0,2,4] is alias;
 :
 : @a[2] = 3; # @s[1] == 3
 : @s[1] = 4; # @a[2] == 4
 :
 : The default slicing behavior would default to is copy, to preserve
 : the current semantics. Does that sound reasonable?

 Hmm.  Assignment is already adequate for copying semantics.  And binding
 the individual elements can presumably be done by:

 my [EMAIL PROTECTED] := @a[0,2,4];

What's the difference between:

my @s := @a[0,2,4];

and

my [EMAIL PROTECTED] := @a[0,2,4];

?

Rob


Re: Array/list transformations.

2005-12-26 Thread Rob Kinyon
On 12/22/05, Jonathan Scott Duff [EMAIL PROTECTED] wrote:
 On Thu, Dec 22, 2005 at 04:47:21PM +0100, Michele Dondi wrote:
  Also I wonder if one will be able to push(), pop(), etc. array slices as
  well whole arrays. A' la
 
  my @a=qw/aa bb cc dd ee/;
  my $s=pop @a[0..2];  # or [0,2] or just [0] for that matters!
  # $s='cc';
  # @a=qw/aa bb dd ee/; = same as what I can do with slice()
 
  Not terribly necessary, but indeed consistent IMHO.

 Not quite sure why you'd want this, but if we have something like this:

 my @a = qw/aa bb cc dd ee/;
 my @slice :=  @a[0..2];
 my $s = pop @slice;

 (where @slice is a reference to part of @a)

 You get what you want and more.

To echo Scott's point, @a[0..2] === @a.splice(0,3).

Now, a more interesting problem is @a[0,2,4], which doesn't map to a
single splice() call. Ruby's syntax for this is problematic, which
points to a problem with how the solutionspaces are mapping to the
problemspaces.

Creating an array whose positions are aliases for positions in another
array can be useful. How about

my @s := @a[0,2,4] is alias;

@a[2] = 3; # @s[1] == 3
@s[1] = 4; # @a[2] == 4

The default slicing behavior would default to is copy, to preserve
the current semantics. Does that sound reasonable?

Rob


Re: handling undef better

2005-12-17 Thread Rob Kinyon
On 12/17/05, Darren Duncan [EMAIL PROTECTED] wrote:
[snip]
 2. Until a value is put in a container, the container has the
 POTENTIAL to store any value from its domain, so with respect to that
 container, there are as many undefs as there are values in its
 domain; with some container types, this is an infinite number.

 Only a container that can have exactly one possible value can be
 equated with; but then you have a constant.

 In a manner of speaking, an undef is like a quantum superposition, in
 that it has no specified value, but rather all possible domain values
 at once, so you can not absolutely say it is equal to anything.

So, in essence, you're saying that undef === one( #the domain of the
type# ) ... I'm not sure I'm comfortable with that. If I have an undef
of a constrained type and I compare it to a value of some other
constrained type whose domains don't overlap, then, by this
definition, I -can- say something about the truth value. For example,
if I define EvenInt and OddInt in the obvious ways, then the following
should hold:

my EvenInt $e;
my OddInt $o;

if ( $e != $o ) { say This should print out. }

I'm not sure that works with the Principle of Least Surprise. While I
cannot say what it is, you're saying that I can now say what it isn't.
While that follows from typing, that doesn't follow from the common
understanding of undef.

Rob


Re: relational data models and Perl 6

2005-12-16 Thread Rob Kinyon
On 12/16/05, Ovid [EMAIL PROTECTED] wrote:
 --- Rob Kinyon [EMAIL PROTECTED] wrote:

  As for the syntactic sugar, I'm not quite sure what should be
  done here. And, with macros, it's not clear that there needs
  to be an authoritative answer. Personally, I'd simply overload
  + for union, - for difference, * for cross-product, / for
  divide, and so forth.

 Bear with me for just a moment here while I provide some background.
 I'll eventually touch on Rob's topic.

 One of the issues with handling relations correctly in databases is the
 following:

   SELECT emp.name, cust.balance
   FROM   emp, cust
   WHERE  emp.id = cust.age

 That's perfectly valid SQL but it doesn't make a lick of sense.  In the
 original relational model, that would not be a valid query because the
 emp.id would be a different type from the cust.age.  Operations between
 different types are simply not allowed.

 However, sometimes it makes sense to allow those operations, though.
 For example, if cust.id and emp.id are different types but may share
 identical and meaningful integer values, you might want to compare
 those even though you can't.  So every type must have selectors which
 behave more or less like we think of when we try to cast a variable to
 a different type.

 So what if, for some crazy reason, we really did want to compare emp.id
 to cust.age.  If cust.age is an integer, we might have something like
 this pseudo-code:

   WHERE emp.id = EMP_ID(cust.age)

I'm going to interject here with the following:
* P6 has the capability to be optionally strongly-typed. This is
obvious from the type signatures, if nothing else.
* According to the latest metamodel, as I understand it from
Stevan, types are, essentially, classes. This implies that I can
create my own types that inherit from some base type.

Overriding the operators in a generic way so that you have to have an
exact type match before you compare values also, imho, shouldn't be
that hard. So, for the relational calculus, you can have very strong
typing.

 * The domain of acceptable values (potentially infinite)
 * Selectors to cast to and from the value
 * Operators and their behaviors

I would argue that you don't have selectors, by default. You should
have to explicitly add a selector. Otherwise, into C-land you will go,
my son!

 Needless to say, in order to properly apply the relational model, we
 wind up with mandatory strong typing and this takes us very far afield
 from Perl.  If we skip the strong typing, we may still have something
 good, but it won't be the relational model.

If you end up in the relational section, which will be invoked with a
module, then you are choosing to use the typing that is available
through that module. I don't think anyone has argued that the
relational model should be built into the core or should even be a
module included in the core.

In fact, I see at least three modules coming out of this -
Type::Create, Type::Strengthen, and Model::Relational. Of these, I
would think only the Type:: modules should even have a chance to be in
the core distro. Type::Create may be a consequence of the metamodel,
but I'll let Steve or Audrey field that one.

Rob


Re: relational data models and Perl 6

2005-12-16 Thread Rob Kinyon
On 12/16/05, Ovid [EMAIL PROTECTED] wrote:
 Minor nit:  we're discussing to the relational algebra and not the
 relational Calculus (unless the topic changed and I wasn't paying
 attention.  I wouldn't be surprised :)

Algebra, in general, is a specific form of calculus. So, we're
speaking of the same thing, just in different terms.

   * The domain of acceptable values (potentially infinite)
   * Selectors to cast to and from the value
   * Operators and their behaviors
 
  I would argue that you don't have selectors, by default. You
  should have to explicitly add a selector. Otherwise, into
  C-land you will go, my son!

 I'm not entirely sure, but I think we agree here.  You have to have, at
 minimum, one selector for each new datatype if for no other reason than
 to cast a string to your new data type.  Otherwise, your data types
 would only be constants because you would have no way of assigning a
 value.

Fair enough. One would need to be able to convert back and forth
between the base type (Int, String, etc) and the type.

Rob


Re: handling undef better

2005-12-16 Thread Rob Kinyon
On 12/16/05, Darren Duncan [EMAIL PROTECTED] wrote:
 Something else I've been thinking about, as a tangent to the
 relational data models discussion, concerns Perl's concept of
 undef, which I see as being fully equivalent to the relational
 model's concept of null.

The relational model doesn't have a concept of NULL. SQL has a concept
of NULL which many relational theorists feel is completely bad.

The way to look at NULL is as a CodeSmell saying I haven't normalized
this data enough.

 Therefore, I propose that the default behaviour of Perl 6 be changed
 or maintained such that:

 0. An undefined value should never magically change into a defined
 value, at least by default.

Fold this into strictures. Instead of this, there should be a
stricture for it. use strict 'undef'; sounds nice.

 1. Any expression that expects a defined value as an argument, such
 as typical mathematical or string operations, and gets an undefined
 argument, will as a whole have undef as its value, or it will fail.
 Examples are the expressions $anything + undef and $anything ~
 undef.

 1a. If such an expression will always return a value, the value is undef.

 1b. If the expression is allowed to fail, it can do that instead.

I'm not sure I want to see the NaN fallacy in Perl6. Since every
operation is allowed to fail through throwing an exception, I'd argue
that this should be the case under strict 'undef'.

 2. Any boolean-returning expression should return undef or false or
 fail if given an undef.

 2a. At the very least, undef equality-test-op undef should NEVER
 return true, because an unknown quantity can not be claimed to be
 equal to an unknown quantity.  Rather, the defined() method, which is
 analagous to 'IS NOT NULL', and such things are the proper way to
 test if a variable is unknown.

 2b. As a pseudo-exception, while undef/unknown values are
 conceptually all unequal to each other, they should all sort
 together; eg, calling sort() on an array of values where some are
 defined and some not, should group all the undefs together.  I leave
 it up to discussion as to whether they should sort before or after
 all the defined values, but one of those choices should be picked for
 predictability.

How many different undefs are there?

[snip]

 The fact is, that in any normal program, using an undefined value as
 if it were a defined one is a bug. . . .

Many times, I've treated undef as 0 or '' in little scripty-doos,
simply because it's easier to do it that way. I think that this
behavior (which is desirable) and the behavior you're describing
(which is desirable) is easily handled by a new stricture.

 Now, in the spirit of TMTOWTDI, such as for people that like to turn
 strictures or warnings off, I suggest that there can be an optional
 feature, perhaps a pragma or better a core module, where a developer
 can say that they want undefs to automatically become zero in numeric
 contexts or an empty string in string contexts, or false in boolean
 contexts, etc.  But they should have to explicitly activate that
 feature, like saying treat undef as 0 in all my code, and this
 treating would not happen by default.

No - a stricture. :-)

Rob


Re: relational data models and Perl 6

2005-12-15 Thread Rob Kinyon
[snip entire conversation so far]

(Please bear with me - I'm going to go in random directions.)

Someone please correct me if I'm wrong, but it seems that there's only
a few things missing in P6:
1) An elegant way of creating a tuple-type (the table, so to speak)
2) A way of providing constraints across the actual tuples of a
given tuple-type
3) Syntactic sugar for performing the relational calculus

To me, a tuple-type is more than a class in the standard OO. It has to
be able to apply any constraints that might be upon the tuple-type,
such as uniqueness of a given element across all tuples or foreign-key
constraints. While this is certainly possible using the P6 OO
constructs, it would make sense for a baseclass to provide this
functionality.

Actually, this is a really great place for metaclasses to shine. The
actual tuple-type needs to be constructed from some class-constructor
(which would be, in the metamodel, itself a class). This is so that it
has the appropriate types for the elements of the tuple along with any
necessary constraints upon the tuples / elements of the tuples.

In addition, you're going to want to take actions not just on the
tuple, but on the entire tuple-type. That screams class-level methods
that operate across all instances of the class. Maybe, a set of roles
would be good for organizing this kind of across-all-instances
behavior that the tuple-type can take advantage of. I'm sure that this
wouldn't be limited to just the relational calculus.

As for the syntactic sugar, I'm not quite sure what should be done
here. And, with macros, it's not clear that there needs to be an
authoritative answer. Personally, I'd simply overload + for union, -
for difference, * for cross-product, / for divide, and so forth.
There's been some discussion with sets as to creating new operators
using the set-operators that come in Unicode. As tuples and relations
among tuples aren't necessarily sets, those might not be appropriate.

It also seems clear that junctionish iterators may be of use here. For
example, Give me all the tuples that match this criteria might
return an iterator that also acts as an any-junction.

It could also return a class object that has a different set of
instances marked as created from it. Though, I'm not too sure how that
would work when asking a given instance who is the class object that
created you? ... maybe it returns the initial one or maybe it returns
them all? I think the initial one is more correct, as the others are
just subsets. When dealing with SQL, I don't care about the subsets
that a given row belongs to - I only care about the table. So, maybe
the subset class objects delegate all methods to the original class
object except for those that deal with Who do you have? and Give me
a subset where ...

Also, joins between tuple-types would have to create a new tuple-type,
with the tuples within being delegators to the underlying tuples? I'm
not sure that this (or any other) derived tuple-type class object
should be allowed to create new tuples (though I'm sure someone can
think of a good reason why I'm wrong).

Again, just a bunch of meandering thoughts. Bonus points to whomever
can help me bridge the gap between what I just blathered and an
elegant solution to Sudoku.

Rob


Re: Perl grammar for Perl5 - Perl6

2005-12-08 Thread Rob Kinyon
 As for the original question, I think that the Perl 6 grammar will
 be a much better example for how to parse other languages than a
 Perl 5 grammar would be, since one of the underlying design currents
 from the beginning has been that Perl 6 had to be a language that
 was amenable to parsing by Perl 6 rules (with a little help from a
 bottom-up operator-precedence expression parser.)

Once Patrick is done with PGE, will it be able to parse Perl5? If so,
why aren't we focusing on that?

Rob


Capabilities in Perl6?

2005-12-01 Thread Rob Kinyon
I just read the slides about CAPerl (http://caperl.links.org/) and it's an
interesting idea. Leaving aside the question of whether this would work in
Perl5 or not, I think it would be very interesting to look at building this
concept into Perl6. Here's how I'd envision doing so:

* Any subroutine is allowed to work with the parameters it was given.
(If you didn't want it to work with those, why did you give them to it?)
Variables outside its scope are, by default, not allowed.
* When looking at a variable you're allowed to see, you are only allowed
to use the methods it exposes - no peeking!
* A subroutine may be explicitly granted access to a variable in a
parent scope through the grant keyword. (More later.)
* A subroutine may be disallowed access to a variable in a parent scope
through the revoke keyword. (More later.)
* Access to resources outside the program (files, etc) must be provided
to the subroutine through parameters or explicit grants.
* The outermost scope is completely trusted. (Someone has to be ...)

Grant/revoke (names may be changed, as needed) take the following
(pseudocode) signatures:
grant ( Sub, Var, [Var, ... ] )
revoke( Sub, Var, [Var, ... ] )

It is an error to:
* attempt to grant/revoke access to a variable you don't have access to
* attempt to grant/revoke access to a variable that isn't in scope for
the grantee

Thanks,
Rob


Re: Lazy lists in Str context

2005-11-23 Thread Rob Kinyon
On 11/23/05, Flavio S. Glock [EMAIL PROTECTED] wrote:
 Can we have:

   say 1..Inf;

 to output an infinite stream, instead of just looping forever?

 OTOH, it would be nice if

   say substr( ~(1..Inf), 0, 10 )

 printed 1 2 3 4 5.

 Flattened lists would still loop forever (or fail):

   say **(1..Inf);

   $s = substr( ~( **(1..Inf) ), 0, 10 );

This would work, I think, if ranges were convertable to iterators,
stringification was lazy, and substr() informed the stringification of
how much it needed to do. I'm not sure how feasible that last one is
...

Rob


Re: Lazy lists in Str context

2005-11-23 Thread Rob Kinyon
On 11/23/05, Flavio S. Glock [EMAIL PROTECTED] wrote:
 How about allowing reduce() to return a scalar with the same laziness
 as the list:

 [EMAIL PROTECTED] - a lazy string if @list is lazy
 [EMAIL PROTECTED] - a lazy number if @list is lazy

 It would look like:

 $foo = substr( [~](1..Inf), 10 );
 my $revfoo := reverse $foo;
 $revfoo ~~ s/foo/bar/g;

That would violate the principle of least surprise. If all scalars
are, by default, eager, then:

foo( [EMAIL PROTECTED] );
foo( @list.join('') );

could potentially do different things, including possibly run out of
memory in some cases. Plus, what if the @list isn't lazy?

Better, I think, would be:

say substr( ~(1..Inf) is lazy, 0, 10 );

Or, have substr()'s signature be:

sub substr( Str $str is rw is lazy, Int $start, Int $?end, Int $?replacement );

Rob


Re: type sigils redux, and new unary ^ operator

2005-11-23 Thread Rob Kinyon
On 11/23/05, Larry Wall [EMAIL PROTECTED] wrote:
 : I'm also puzzled that you feel the need to write 0..$n-1 so often; there
 : are so many alternatives to fenceposting in P5 that I almost never write
 : an expression like that, so why is it cropping up that much in P6?

 Couple reasons occur to me offhand.  First we're doing away with $#foo.
 Second is all the array sizing in P5 is implicit, whereas S9 style
 arrays are all about explicit array sizing, and 0..$n-1 comes up all
 the time there.  But I also am liking the generalization of unary ^
 to mean domain.

What about @array.indices instead? Then, there's no possible
fenceposting, your code is self-documenting, and we're not introducing
another unary operator?

 And in an axiomatic sort of way, it corresponds to those theories
 of math that build up the integers by counting set elements.  The
 argument that produces 5 is 0..4.  And it works out that +^5 == 5.

So, +^5 is the way to generate the Church number for 5 through the use
of an iterator masquerading as a range?

 But the generalization to hashes is even cooler because I can say

 my %thishash{^%thathash};

 or some such to duplicate the shape regardless of the typology
 of %thathash.

  my %thishash{%thathash.keys};

Much easier to read. The methods are there for a reason. Don't re-add
operators where there's a perfectly good method. Plus, overwriting
methods is much easier to grok for the average programmer than the
corresponding operator, unless you're aliasing the operator, in which
case I have problems figuring out why this is good, unless we're
deliberately designing P6 for the obfu/golf crowd.


Re: type sigils redux, and new unary ^ operator

2005-11-22 Thread Rob Kinyon
On 11/22/05, Larry Wall [EMAIL PROTECTED] wrote:
 What tipped me over the edge, however, is that I want ^$x back for a
 unary operator that is short for 0..^$x, that is, the range from 0
 to $x - 1.  I kept wanting such an operator in revising S09.  It also
 makes it easy to write

 for ^5 { say }  # 0, 1, 2, 3, 4

I read this and I'm trying to figure out why P6 needs a unary operator
for something that is an additional character written the more legible
way. To me, ^ indicates XOR, so unary ^ should really be the bit-flip
of the operand. So, ^0 would be -1 (under 2's complement) and ^1 would
be -2. I'm not sure where this would be useful, but that's what comes
to mind when discussing a unary ^.

Thanks,
Rob


Re: statement_controlfoo() (was Re: lvalue reverse and array views)

2005-11-21 Thread Rob Kinyon
On 11/21/05, TSa [EMAIL PROTECTED] wrote:
 HaloO,

 Luke Palmer wrote:
  On 11/21/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 
 Of course, the compiler is free to optimize these things if it can prove
 that runtime's statement_control:if is the same as the internal
 optimized statement_control:if.
 
 
  Which it definitely can't without some pragma.

 Isn't the question just 'when'? I think at the latest it could be
 optimized JIT before the first execution, or so. The relevant AST
 branch stays for later eval calls which in turn branch off the
 sourrounding module's version from within the running system such
 that the scope calling the eval sees the new version. And this in
 turn might be optimzed and found unchanged in its optimized form.

 Sort of code morphing of really first class code. Everything else
 makes closures second class ;)

This is very close to a proposal I made to the ruby-dev mailing list
(which was Warnocked). I proposed a very basic engine that would work
with the parser/lexer to determine what action to take instead of
using the huge case statements that are the heart of both P5 and Ruby.
It would look something like:

TOKEN:
while ( my $token = get_next_token(params) ) {
for my $length ( reverse length($token) .. 1 ) {
if ( my $actions = find_actions( substr( $token, 0, $length ) ) ) {
$action-[-1]-(  params, if necessary  );
}
next TOKEN;
}
throw SyntaxError;
}

The for-loop + substr() would be to handle longest-token-first rules.
So, ... is correctly recognized instead of handled as .. and ..
The key would be that the $actions arrayref would get push'ed/pop'ed
as you enter/leave a given lexical scope.

Obviously, this could be optimized to an extremely large degree, but
it -should- work.

Rob


Re: lvalue reverse and array views

2005-11-20 Thread Rob Kinyon
On 11/20/05, Daniel Brockman [EMAIL PROTECTED] wrote:
 Reversing an array, changing it, and then rereversing it ---
 I think that kind of pattern is common.

I would think that reversing a string, modifying it, then reversing it
back is more common. Does modifying the reversal of a string modify
the original?

Rob


statement_controlfoo() (was Re: lvalue reverse and array views)

2005-11-20 Thread Rob Kinyon
On 11/20/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
[snip]
 Yep. Also note that for is not a special magical construct in Perl 6,
 it's a simple subroutine (statement_control:for, with the signature
 ([EMAIL PROTECTED], Code *code)). (Of course, it'll usually be optimized.)

 Example:

 {
 my sub statement_control:for ([EMAIL PROTECTED], Code *code) {
 map code, reverse @array;
 }

 for a b c - $item { say $item }
 # c\nb\na\n
 }

 # for restored, as the modified for went out of scope:
 for a b c - $item { say $item }
 # a\nb\nc\n

Is there a list of the statement control items that are implemented as
such vs. implemented in another way?

Thanks,
Rob


Re: What's the latest on Iterators?

2005-11-11 Thread Rob Kinyon
On 11/11/05, Joe Gottman [EMAIL PROTECTED] wrote:
The various synopses contain many mentions of Iterators.  These are used,
 for instance, to implement lazy lists so the expression 1..1_000_000 does
 not have to allocate a million element array.  But as far as I can tell the
 term is never defined anywhere in the synopses. Is Iterator a role, and if
 so what methods is it required to have?  Do functions like map and grep,
 which in Perl5 return lists, return Iterators in Perl6?  Can an Iterator be
 passed to a function (like map and grep again) that requires a list as an
 input?  Does an array or hash have only one Iterator or can it have several
 independent ones?

I'm going to speculate on a few of these items.

Iterator most certainly will be a role, though that doesn't mean that
internal iterators will do this role. I expect they would, though. It
will probably have methods that do the following:
* next_item
* prev_item
* nth_item
* rewind
* has_next_item?
* has_prev_item?

I expect that lists will be convertable to iterators and vice-versa.
You can do this in P5 already:

  sub create_iterator_from_list {
  my @list = @_;
  return sub {
  return shift @list;
  };
  }

  create_list_from_iterator {
  my ($iterator) = @_;
  my @list;
  while ( my $item =$iterator-() ) {
  push @list, $item;
  }
  return @list;
  }

Of course, that's extremely inefficient. I expect that Perl6 will be a
little smarter, though it's not clear how much smarter it can be. For
one thing, Iterators will have to support two modes - one where the
list is frozen (the P5 version I posted above) so that changes to list
don't change the iterator and another where the iterator iterates into
the list as it stands, so that changes to the list are reflected in
the iterator immediately. The second mode has the possibility of being
unstable, but if you choose this mode (which wouldn't be the default),
then it's on your head.

As for multiple iterators, that's the point of having a separate
iterator object. Each iterator maintains its own state, allowing for
multiple traversals across the same set.

As for lazylists (1..Inf), they have to be implemented via iterators
(which is why I'm almost positive the two will be interchangeable).
And, if you pass (1..Inf) to map/grep/sort, it would HAVE to return an
iterator back, otherwise you'll hang at that instruction.

Of course, if you said while (my $n = 1..Inf) { }, it's on your head
to provide a last in there somewhere.

Rob


Re: Thoughs on Theory.pm

2005-11-11 Thread Rob Kinyon
On 10/13/05, Dave Whipp [EMAIL PROTECTED] wrote:
 (ref: http://svn.openfoundry.org/pugs/docs/notes/theory.pod)

  theory Ring{::R} {
  multi infix:+   (R, R -- R) {...}
  multi prefix:-  (R -- R){...}
  multi infix:-   (R $x, R $y -- R) { $x + (-$y) }
  multi infix:*   (R, R -- R) {...}
  # only technically required to handle 0 and 1
  multi coerce:as (Int -- R)  {...}
  }
  
   This says that in order for a type R to be a ring, it must
   supply these operations.  The operations are necessary but
   not sufficient to be a ring; you also have to obey some
   algebraic laws (which are, in general, unverifiable
   programmatically), for instance, associativity over
   addition: C(a + b) + c == a + (b + c).

 I started thinking about the in general, unverifiable programmatically
 bit. While obviously true, perhaps we can get closer than just leaving
 them as comments. It should be possible to associate a
 unit-test-generator with the theory, so I can say:

I've been thinking about this. If we have a type inferencer, we know
that any function we define to be N,N-N will be that way. The only
items we have to show is for all a in N, there is a unique succesor
which is also in N and that for all b in N, b != 1, there is a unique
predecessor. If we have that, then we get the laws of arithmetic. Is
it possible to put that into the type inferencer if the types are
defined as iterators? Kind of like Church numbers, but in P6 notation.
I think that by defining our types as iterators, we can satisfy the
succ/pred requirements of Peano's, meaning we have the arithmetic
rules.

Rob


Re: given too little

2005-11-10 Thread Rob Kinyon
snarky

 But if we have a mandatory type inferencer underneath that is merely
 ignored when it's inconvenient, then we could probably automatically
 delay evaluation of the code.   . . .

I'm not so certain that ignoring the mandatory type inferencer is a
good idea, even when it's inconvenient. I don't know about you, but my
son keeps trying to get me to let him ignore his homework when it's
inconvenient (ie, the gamecube calls) and I don't let him. So, just
because the gamecube is calling, we should probably listen to the
mandatory type inferencer.

/snarky


Re: Implicit Role Declarations (was Re: implicitly doing a role)

2005-11-08 Thread Rob Kinyon
On 11/8/05, chromatic [EMAIL PROTECTED] wrote:
 On Fri, 2005-11-04 at 13:15 -0500, Austin Frank wrote:

  If roles are interfaces, do we want any class that provides an interface
  consistent with a role to implicitly do the role?  That is, if a class
  fulfills all of the interface requirements of a role without actually
  saying it does the role, does it do the role anyway?

 After thinking about this a little more, I think there may be a bit of
 misunderstanding about what I want here.

 Having a class implicitly *do* a role if it has methods and attributes
 of the appropriate name is a bad idea -- there's too much room for
 accidental collision there.

 Sure, people shiny-eyed about duck typing might reasonably say Why?
 That doesn't make sense! but it's a careless duck typer who randomly
 throws objects in collections and hopes for the best.  You *can*
 mistakenly use an object that quacks incorrectly and spend some time
 debugging it, but if we're providing a system that can catch some of
 that incorrectness, I don't see what benefit there is to subverting its
 ability to detect incorrectness.

 What I want instead, and what might seem similar in the sense that it's
 exactly the opposite, is implicit declaration of a role for each
 explicitly declared class.

 That is, if I declare a Dog class, there immediately springs into being
 a Dog role empty of everything but the expectation that whatever does
 that role provides everything publicly accessible that an instance of
 the Dog class does.

In other words, a role is just a closed class and a class is just an
open role? Larry stipulated this about a month ago.

Rob


Re: Perl6 perlplexities [was: Re: $1 change issues...]

2005-11-07 Thread Rob Kinyon
On 11/7/05, Michele Dondi [EMAIL PROTECTED] wrote:
 On Fri, 4 Nov 2005, Rob Kinyon wrote:

  So, for a bit of extra complexity, I get peace of mind for myself and my
  users.

 The point being, and I'm stressing it once again but no more than once,
 that maybe we're adding two bits of extra complexity, whereas just one bit
 not only would have been enough, but would have bought you even more peace
 of mind. Then again: this is a _feeling_ I got e.g. by reading the
 appearently endless discussions about the specifications of sub
 parameters, which seem to ensue inherent technical difficulties having to
 do with the attempt _conciliate_ too many different paradigms.

Honestly? I skip about 50% of the discussions on this list. I don't
care about most of the syntax discussions and I don't care about sub
signatures. Well, I -DO- care, just not enough to wrangle about it.
All I care about is Can I do what I want to do in an easy fashion?
That's why I spent so much time on roles and why I've released
Perl6::Roles to CPAN. (Well, that was for DBI-2, but I can claim it
was for me, right?) The point is that I will not use a lot of the
features in Perl6, just like I didn't use alot of the features in
Perl5. I doubt I'll ever use PGE directly (though macros will be nice,
once I figure out where I'd use them). Same with most of the
subroutine types.

Though, I do find the complexity reassuring. I like having the
options, even though I will never use them. The alternative is Perl5,
where you can do (almost) anything you could want, except you have you
jump through lots of hoops and you end up with something that works,
but really really slowly. No-one wants that.

Rob


Re: Perl6 perlplexities [was: Re: $1 change issues...]

2005-11-07 Thread Rob Kinyon
 Okay, I won't shout (not even on PerlMonks :-), but named parameters
 default to optional, so you'd have to write that as

 sub convert (:$from!, :$to!, :$thing!) { ... }

 in the current scheme of things.

Either way, the point is still that the benefits FAR outweigh any
additional complexity. Ruby could benefit from this, too. (While
first-class blocks rock my world, the weird subroutine signature stuff
most certainly doesn't.)

Rob


Re: $_ defaulting for mutating ops

2005-11-04 Thread Rob Kinyon
 $ perl -le '$u=1; ($y=$u*=5)++; print $y'
 6

It's interesting to note that this parse (due to precedence) as
($y=($u*=5))++, not (($y=$u)*=5)++

This is important for overloaded operators (which are going to become
much easier to do in Perl6). The importance arises if Perl6 allows
assignment to be overloaded like Ruby does. If it does, then the two
expressions aren't guaranteed to be identical as they are now in
Perl5.

Rob


Re: Perl6 perlplexities [was: Re: $1 change issues...]

2005-11-04 Thread Rob Kinyon
On 11/4/05, Michele Dondi [EMAIL PROTECTED] wrote:
 I'm still convinced my remark _partly_ applies in the sense that the
 overall impression is that a vast majority of most common needs is
 addressed by a *subset* of the current features and trying to stuff all
 them in has brought in quite a lot of discussions of which I'm not even
 sure if they've all settled down.

I think a good comparison can be made to Ruby. For work, I've been
learning Ruby this past week (we're going to try out Rails to see if
we like it). As my colleague put it, Ruby has all the P6 features we
want and it's usable now.

Ruby's OO system is 1000% more complex that Perl5's. Yet, it's still a
net win. For one thing, I don't have to write the following anymore
(lifted from a CPAN module I am working on):

sub children {
my $self = shift;
if ( caller-isa( __PACKAGE__ ) || $self-isa( scalar(caller) ) ) {
return wantarray ? @{$self-{_children}} : $self-{_children};
}
else {
return @{$self-{_children}};
}
}

This is in a vain attempt to implement a protected subroutine. In
fact, I really want a private writing accessor with a public reading
accessor, but have absolutely no way to implement that.

Why do I want such a beast? Because I want to GUARANTEE in an absolute
kind of way that, unless my user truly intended to do so, he's not
going to be able to accidentally screw up my internal state.

And, no, I don't want to use inside-out classes. They're cool (in
all the good and bad senses of the word), don't play well with other
P5 solutions, and STILL don't provide the necessary granularity. The
problem isn't with $object-{foo} = 3; The problem is with the
subroutines that aren't real methods with correct protection
mechanisms.

So, for a bit of extra complexity, I get peace of mind for myself and my users.

(Oh, and Ruby has first-class block. W00T!)

Rob


Re: implicitly doing a role

2005-11-04 Thread Rob Kinyon
On 11/4/05, Austin Frank [EMAIL PROTECTED] wrote:
 Hello!

 If roles are interfaces, do we want any class that provides an interface
 consistent with a role to implicitly do the role?  That is, if a class
 fulfills all of the interface requirements of a role without actually
 saying it does the role, does it do the role anyway?

  role Documented {
   has $.documentation;
  }

  class Foo does Documented { ... }

  # I don't know why Bar isn't declared as doing Documented
  # but it meets all the requirements of doing Documented...
  class Bar {
  has $.documentation;
  }

  my $baz = Foo.new( $documentation = q to quit );
  my $qux = Bar.new( $documentation = enter to continue );

  sub show_docs ( $obj.does( Documented ) )  { # or $obj ~~ Documented
  say $obj.documentation;
  }

  show_docs( $baz ); # q to quit
  show_docs( $qux ); # enter to continue -or-
 # error because Bar doesn't explicitly do
 # Documented?


 I guess we don't really need implicit doing of roles to get both of
 those objects to print their documentation, as we could have something like

  sub show_docs ( $obj ) {
  if ( defined $obj.documentation ) {
  say $obj.documentation;
  }
  else {
  die Should have included a documentation string
  }
  }


 Should roles that are implicitly done pass tests like .does and ~~ ?
 What are the reasons that they should or shouldn't?

I say no. It goes back to does a role provide a list of function names
with possible default implementations or does it provide a behavior
that is supported by a set of related functions that one can override,
if desired. What you're proposing assumes that roles are nothing more
than jazzed up Java interfaces. I would hate to see that happen. So, I
say that it should be the latter.

Rob


Re: Perl6 perlplexities

2005-11-04 Thread Rob Kinyon
 And when your user does want to, essentially say Nah, you screwed up 
 designing
 that object protocol, children shouldn't've been protected. it's the work of 
 a
 moment to write:

thing.send(:children, *args)

I told you I'm still learning. I hadn't gotten to that part of the Pickaxe. :-/

  (Oh, and Ruby has first-class block. W00T!)

 And continuations. But continuations are scary. Good scary, but still scary.

First-class blocks make continuations and coros almost neglible to
implement from an API perspective. Almost makes me wonder how much
trouble it would be to implement this in P5 ...

Rob


Re: syntax-variants, RPN (was: Re: $_ defaulting for mutating ops)

2005-11-03 Thread Rob Kinyon
On 11/3/05, Michele Dondi [EMAIL PROTECTED] wrote:
 On Wed, 2 Nov 2005, Ruud H.G. van Tol wrote:

  http://www.nntp.perl.org/group/perl.perl6.language/17556
 
  I understand that Perl6 allows blocks with changed/enhanced syntax, so
  it is or will become possible (to add it) as if it was in the core
  language.
  Do I understand that right? Something as simple as a 'use RPN' in a
  block? (assuming that someone created such an RPN-pre-processor
  or -compiler)

 Indeed this is what that we all know. Of course the possibility of doing
 so will depend on the possiblity of building up suitable RPN syntax
 consistent with the rest of the syntax.

If Perl6 is parseable by Perl6, then wouldn't you be able to
completely throw out the default Perl6 syntax and create your own,
completely unrelated syntax? I don't know ... maybe you have PGE::Ruby
that would throw out the P6 grammar and give you Ruby's grammar within
the block. Then, it's just a matter of describing what PGE::RPN does -
what it adds, what it removes, and what it modifies.

In my opinion, if you use a grammar extension, ALL bets are off within
that scope until you've read the documentation. Literally anything and
everything can happen, if the author deemed it so. It's a source
filter-like construct that doesn't suck because source filter-like
constructs are part of the spec.

Rob


Re: Role Method Conflicts and Disambiguation

2005-11-03 Thread Rob Kinyon
 On Nov 2, 2005, at 9:02 PM, Jonathan Lang wrote:
  Let's say you have this:
 
role A {method foo() { code1; } }
role B {method foo() { code2; } }
role C does A does B {
  method foo() { A::foo(); }
  method bar() { B::foo(); }
}
 
  Should the following be valid?
 
role D does C { method foo() { B::foo(); } }
 
  IMHO, it shouldn't, because D doesn't do B.

Additionally, D most certainly does B. That it does B through a proxy
is irrelevant. Think about it this way - if you had Surfer and Dog and
SurferDog does Surfer does Dog, wouldn't you want to know that
class ScoobyDoo does SurferDog does Dog?

If SurferDog doesn't do Dog, how would ScoobyDoo do Dog?

 I think this is too restrictive, D should be able to freely
 disambiguate or override using anything it want's to. It need not be
 related at all to it's subroles.

To further expand on this, D's disambiguation of method foo() could be:

  role D does C { method foo() { Completely::Unrelated::foo() } }

Rob


Re: Role Method Conflicts and Disambiguation

2005-11-01 Thread Rob Kinyon
 1. choose one of a set of available methods to call its own.
 2. create a version of its own.
 3. pass the buck.

#1 and #2 are identical. Stevan and I have always viewed #1 as a
special case of #2. If you want to choose a method to call, then
create a method of your own and have it wrap the one you want to call.

The benefit here is that you can do more than just pick a method.
Let's say that you have a conflict and the correct behavior is to do
them all, but in a certain way. Or, maybe the correct behavior is to
provide a limited API over one version.

Maybe, there'll be some sugar to allow #1 to be its own syntax, but it
should be viewed as a #2.

Rob


Re: $_ defaulting for mutating ops

2005-10-28 Thread Rob Kinyon
 But IMHO the reduction in typing for this relatively minor issue is not
 really worth the surprise to newbies at seeing operandless operators.

AMEN!

Rob


Re: Role Method Conflicts and Disambiguation

2005-10-28 Thread Rob Kinyon
On 10/28/05, Jonathan Scott Duff [EMAIL PROTECTED] wrote:
 Roles can hold instance data that will be composed into a class.  What
 I'm saying is that if you have two roles:

 role X { has $:foo; }
 role Y { has $:foo; }

 And a class that's composed of them:

 class Xy does X does Y { ... }

 That there will not be two slots for $:foo in Xy, but only one.

 But, I'm probably wrong about this as the X role may have methods that
 use $:foo in one way and the Y role may have methods that use $:foo in
 some other, incompatible way, so perhaps there will be a conflict just
 as when there are 2 methods of the same name.

The solution I proposed to Steve is somewhat involved, so let me take a moment.

In my view of objects, there are only behaviors. An attribute is
simply a behavior that will store some value (somehow) when asked and
will return the last value stored (somehow) when asked. The whole
concept of the attribute is to support behaviors that are (ultimately)
used publicly. Hence, from a strict encapsulation POV, the attributes
should be private to the definer.

As such, a role would have private methods that can only be called by
methods defined within that role (stubs aside). Stuff that composes
said role into themselves would only be composing the public API, not
the private API. Those methods that get composed would be able to
access the private methods (attributes or not) that were defined
within the role.

If this solution were to be enacted, then the role wouldn't pollute
the class's attributespace with its attributes and there couldn't be
any conflict between roles or the roles and the classes. This also
extends to attributes and inheritance - the private concept that C++
has. (I don't agree with the protected concept, but private vs. public
is good.)

Doing it any other way leads to the following: if A does rA and B isa
A and B defines an attribute that conflicts with the one provided by
rA, how on earth is that supposed to be detected? Especially given
that the inheritance tree of a class can be modified at runtime.

Rob


Re: Role Method Conflicts and Disambiguation (Theory-theoretic take)

2005-10-28 Thread Rob Kinyon
On 10/28/05, Luke Palmer [EMAIL PROTECTED] wrote:
[snip]
 It was the fact that at each stage of the game, we summarized the
 defaults and requirements for each role, ignoring the internal makeup
 (i.e., what roles were composed into it, etc.).

So, in theory, one should be able to ask any given role What do you
provide? as well as What do you require?. (I'm not saying that the
syntax should be available, but that the information to answer those
questions should be easily calculable.)

One concern I have is that I would like to believe that a role is a
group of related behaviors that provides a functionality. So, if Foo
does roleA and I as the user of Foo asks Do you do roleA? and it
replies Yes, then I can make some assumptions about Foo's
functionality. Otherwise, this devolves into interfaces. Interfaces
suck, especially given as they're limited to naming.

Now, if we were to say that all roles, by default, provide
multimethods, then conflicts only occur for methods that have
identical dispatching semantics. At that point, it's truly a conflict
and would need to be resolved by the composer (whether that's a role
or a class).

Now, it's obvious why a class would have to resolve that conflict. I
would say that a role would have to resolve the conflict is that a
role should present a consistent API to the rest of the world. In
other words, I want to be able to depend on the fact that classA does
roleAB means something in terms of the functionality that classA
provides to me. I don't want it to be a glorified can() check. That
does no-one any good.

Rob


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-27 Thread Rob Kinyon
On 10/26/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Oct 26, 2005 at 07:35:05PM -0700, chromatic wrote:
 : On Wed, 2005-10-26 at 21:58 -0400, Rob Kinyon wrote:
 :
 :  Plus, the argument is a straw man. Instead of:
 : 
 :  class Some::Class is also {
 :  }
 : 
 :  you would do:
 : 
 :  class My::Version {
 :  does Some::Class;
 :  }
 : 
 :  Problem solved.
 :
 : Don't forget the fun of modifying all existing uses of Some::Class to
 : use My::Version instead, if that's even possible.

 That should mostly be handled by virtualized class names.

Will I be able to do something like:

package Foo;
$*VERSION = 1.3.2;

use Foo-1.3.1;

role My::Foo { does Foo; ... }
alias My::Foo - Foo; # Or whatever the syntax should be

And, in my other code, use Foo; will DWIM?


Re: +$arg changed to :$arg

2005-10-27 Thread Rob Kinyon
On 10/27/05, TSa [EMAIL PROTECTED] wrote:
 HaloO,

 Larry Wall wrote:

  : Yes, and dispatch as a runtime keyed access into a code multitude.
  : The covariant part of the method's sig! The code equivalent to keyed
  : data access into hashes.
 
  Um, yeah.  Won't play in Peoria, though.

 Where or what is Peoria?

It's an expression in the US. Peoria is a town in the state of
Illinois. It has a reputation for being conservative and a keeper of
American Values (whatever that means). So, when you say something
won't play in Peoria, you're saying that it's unlikely to be
accepted by the masses.

Rob


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-27 Thread Rob Kinyon
On 10/27/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Thu, Oct 27, 2005 at 05:37:13AM -0400, Rob Kinyon wrote:
 : Will I be able to do something like:
 :
 : package Foo;

 Hmm, you just started in Perl 5 mode.

 : $*VERSION = 1.3.2;

 Perl 5 would get confused here, so I'm presuming Perl 6.  But Perl 6
 isn't likely to let you override the global run-time Perl version.

 : use Foo-1.3.1;

 That I think I understand.

 : role My::Foo { does Foo; ... }

 Okay, My::Foo does Foo here.  Presumably it must do the Foo alias
 that the use just installed.  And presumably the Foo you just used
 is a role that can be done.  Certainly you can't do the global
 package Foo, assuming that's what your original package declared.

 : alias My::Foo - Foo; # Or whatever the syntax should be

 I have no clue where you're intending to install that alias.
 Are you trying to install a *Foo alias?  A bare Foo is going to first
 find the local alias to the Foo you used, and that hides the global
 Foo that it would have found otherwise.  I suspect you're trying to
 say

 *Foo := My::Foo;

 : And, in my other code, use Foo; will DWIM?

 I don't know quite what you mean, so I don't know if it'll do what
 you mean.  If you're trying to establish a policy that defaults a
 particular name to a particular version, the library interface will
 probably give you a more straightforward way to set that up.

Sorry. I'm not up on the syntax. I should do some serious backlog reading.

What I'm trying to do is load role Foo 1.0, have My::Foo do Foo, then
call My::Foo version 2.0 of Foo so that anyone else in my program will
see My::Foo instead of the original Foo. Is this possible?

Rob


Re: new sigil

2005-10-26 Thread Rob Kinyon
 And in fact, its very existence defies another implicit principle of
 mine, that is, the principle of partial definition:  Defining a new
 type or instance can only break a previously typechecking program by
 making it ambiguous.  The idea behind that is that at some time you
 may realize that oen of your types already obeys another type, and
 declare that it conforms to that interface.  But you don't go the
 other way around, undeclaring that an interface holds, without your
 program having been erroneous in the first place.  Declaring that a
 new interface holds (so long as it actually does) shouldn't break
 anything that was already correct.

 The principle also has strong implications with library code:
 including a new library but doing nothing with it shouldn't start
 randomly breaking stuff.  (Unless, of course, it breaks the rules and
 does crazy stuff, in which case anything goes)

Is this better expressed as side-effect-free programming or loose
coupling/tight cohesion?

Rob


Re: Ways to add behavior

2005-10-26 Thread Rob Kinyon
 That's just self.meta.add_method($label, $method) by my lights.
 A .meta already implies/ignores the .class coercion.  If we are to
 support prototype-based programming $x.meta *must not care* whether
 it has been given a class or an instance or something in between.
 What I am calling a class here is basically that portion of the
 current instance that is the same for all members of its class.
 And that common information presumably includes information on what to
 do if a method is called that is not directly recognized by the object.
 Class-based and prototype-based systems have different answers to that,
 but they have something in common, and I'd like to abstract that out
 and call it something.  I've been calling it class, but maybe I
 should call it something else to avoid confusion.  A type maybe.
 That would imply that ¢ is really a type variable rather than a class
 variable.  But maybe type is too overloaded already.  But maybe not.

I'd like to take this moment and point to my somewhat hand-wavy
metamodel proposal from last week. When Stevan and I were talking
about this, we called it a quark. Atom also works quite nicely,
but quarks are cooler.

Plus, if you think about the definitions that go into creating an
instance (class, role, prototype, etc), it makes sense that if the
instance is the smallest indivisible thing there is, then the things
that go about being its definition are the quarks.

 Anyway, if my class turns into type or something else, maybe I
 can be persuaded to go with ^T instead of ¢T.

Q(T) ? :-)

Rob


Re: Ways to add behavior

2005-10-26 Thread Rob Kinyon
On 10/26/05, Stevan Little [EMAIL PROTECTED] wrote:

 On Oct 26, 2005, at 12:05 PM, Larry Wall wrote:
  Of course, there are other words that are somewhat synonymous with
  class, Unfortunately sort is already hosed.  Maybe kind.

 Actually kind is used in the Core Calculus for Metaclasses paper
 which I brought to the hackathon (not sure if you got to read it or
 not). Here is a link:

 http://research.sun.com/projects/plrg/core-calculus.pdf

 They present an rather interesting view on things, that the
 definition of the instance creating portion of a class should be
 seperated from the class or kind portion of the class. Actually
 the first metamodel prototype grew out of an implementation of the
 model they describe in the paper.

This might dovetail quite nicely into the discussion of how types are
now sets instead of junctions. Objects are now a junction of the
various kinds that were used to create it. Thus, boxed types are now
almost trivial to implement ... ?

Rob


Re: Ways to add behavior

2005-10-26 Thread Rob Kinyon
 So maybe we can define our terms like this:

 type: a completely generic metaterm for any of the following,
 and then some.

 class: a mutable interface object that manages instances in the
 classical way, with covariant derivational properties.

 role: an immutable and possibly generic interface class, with
 covariant compositional properties.

 kind: the abstract, often unnamed type of an actual instance
 or storage location, abstracted from any of its machinery or
 degree of definedness.  You should not generally declare a kind,
 they just happen.

 subtype: a potentially contravariant type based on any of the
 previous types, allowed to impose constraints that are more
 selective than a kind is allowed to be.

 Then ^T $x binds T to the kind of $x.  And $x.kind == $y.kind asks
 if two objects are of the same type, but $x.kind isn't a class-like
 object, only an identity of some sort.  $x.meta returns the Class
 instance, or whatever.

A few questions:
1) Where does prototype-style OO fit into all of this? I hope it's not
through repeated eigenclasses (or whatever they're called this week)
... that just sounds too heavy.
2) Isn't Dog|Cat kinda declaring a kind? Thus, can't you say my
Dog|Cat $catdog; and be talking about a kind? I would think that a
named kind is just a role ...
3) Aren't classes mutable and roles immutable by default only? Or has
this changed?

Rob


Roles vs. Classes (was Re: Ways to add behavior)

2005-10-26 Thread Rob Kinyon
 : 3) Aren't classes mutable and roles immutable by default only? Or has
 : this changed?

 Of course.  To change the default for a role, call it a class, and
 to change the default for a class, call it a role.  :-)

Does this mean that roles are the recommended way to create immutable
classes? Given that roles and classes now seem to differ only in their
mutability, I can't see a reason why I would use class as my default
object definer. I would prefer to use roles as they're closed by
default, leaving class to be my powertool, if I need the power.

Rob


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-26 Thread Rob Kinyon
On 10/26/05, chromatic [EMAIL PROTECTED] wrote:
 On Wed, 2005-10-26 at 20:29 -0400, Rob Kinyon wrote:

  I would prefer to use roles as they're closed by default, leaving
  class to be my powertool, if I need the power.

 I don't understand this desire; can you explain your reasoning?

If a role is an immutable class, that means that its internals cannot
be changed. Hence, the compiler can trust that it will be the same at
the end as at the beginning. Which means it's optimized. Which means
my objects run faster if I create them from roles than if I create
them from classes. And, given that this seems to be the sole
difference between them (mutability vs. immutability), why would I use
classes as my standard?

Rob


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-26 Thread Rob Kinyon
On 10/26/05, Luke Palmer [EMAIL PROTECTED] wrote:
[snip]
 Okay, an open class means you can add methods to it, right?  So, let's
 say you have this class:

 class Foo {
 method foo() {...}
 method bar() {...}
 }

 And this code:

 my Foo $x = Foo.new;
 $x.foo();
 $x.bar();

 This might be compiled to the following pseudo intermediate code:

 my $x = Foo[0]();
 Foo[1]($x);
 Foo[2]($x);

 Now let's say you extend the class:

class Foo is also {
method baz() {...}
}

 Is there any reason that the preceding pseudo intermediate code is no
 longer valid?  I don't see one; baz() is just installed in slot 3.  So
 why would you say it was faster to have it closed?

What about:

class Foo is also {
method foo() { ... }
}

Where the second foo() is no longer what the first foo() did.
Furthermore, let's say you have:

class Bar isa Foo {
method floober() { ... }
}

If they were roles, then role Bar could alias all the methods it
inherits from role Foo. In other words, it can cache all the method
lookups at compile-time. That's a substantial savings. If they're open
classes, the runtime has to throw out all the cached lookups the
moment any of the classes upstream are modified.

Plus, the argument is a straw man. Instead of:

class Some::Class is also {
}

you would do:

class My::Version {
does Some::Class;
}

Problem solved.

Rob


Re: $_ defaulting for mutating ops

2005-10-25 Thread Rob Kinyon
On 10/25/05, Juerd [EMAIL PROTECTED] wrote:
 I think it'd be great if +=, ~=, +=, ++, etc, could all assume $_ on
 their LHS when there is no obvious operand.

 This clashes with prefix:=, but that's nothing a space cannot fix.
 Same for lvalue subs called x or xx (or X or XX).

 my $subject = foo foo foo;
 given ($subject) {
 s/foo/bar/;  # bar foo foo
 ++;  # bar foo fop
 x= 2;# bar foo fopbar foo fop
 ~= !;  # bar foo fopbar foo fop!
 }

 Especially bare ++ would be useful, I think.

Did you post this specifically to anti-address the fear that P6 will
be more line-noise-ish than P5? :-p

Rob


Re: new sigil

2005-10-25 Thread Rob Kinyon
 Basically, ¢T is a close analog of t, which is the variableish form
 for sub t.  When used in a declaration, both of them introduce a
 bare name as an alias into whatever scope the declaration is inserting
 symbols, albeit with different syntactic slots.  So just as

 my t := { ... }

 introduces the possibility of

 t 1,2,3

 so also a

 my ¢T := sometype();

 introduces the possibility of

 my T $x;

I'm assuming that when you allow

my ¢T := sometype();

you're also allowing

my class T := sometype();

So, what happens when stupid me names a class class through
symbol-table craziness?

Rob


Re: Perl 6 fears

2005-10-25 Thread Rob Kinyon
On 10/25/05, Luke Palmer [EMAIL PROTECTED] wrote:
 On 10/24/05, H.Merijn Brand [EMAIL PROTECTED] wrote:
  On Mon, 24 Oct 2005 11:49:51 -0400, Joshua Gatcomb [EMAIL PROTECTED]
  wrote:
   FEAR: Perl6 internals will be just as inaccessable as p5
 
  paradox. Many people don't find perl5 inaccessible at all

 Who?  Do you know anybody who hacks the regex engine?

japhy. Though, granted, he's on a whole new level of insanity.

Rob


Re: Perl 6 fears

2005-10-24 Thread Rob Kinyon
On 10/24/05, Nate Wiger [EMAIL PROTECTED] wrote:
 Joshua Gatcomb wrote:
  On 10/24/05, Juerd [EMAIL PROTECTED] wrote:
 
 Feel free to add your own, or fears you heard about!
 
  FEAR: The Perl6 process is driving away too many good developers
 
  FEAR: Perl6 will not be as portable as p5
 
  FEAR: Perl6 is un-necessary and the time, money, and resources is impacting
  p5.

 These are at the top of my list. Sooner or later big Perl advocates
 (like myself) are going to look for other languages because the future
 is too uncertain and unstable.

 Also, in terms of module rewriting: This is a massive effort. I don't
 know if anybody's looked at the internals of stuff like Class::DBI and
 its derivatives, but it's huge.

I have. Module rewriting should be look at in terms of implementing
something completely new to fit the current spec, at least in the
beginning. Modules like CDBI are good because they have a lot of
tests. So, you run the tests in P5 and have them access the P6
classes. Add new tests to test new P6-only features, like roles, and
you're good to go. You don't need to read the internals to port the
module.

Plus, rewriting is going to happen over the space of 1-2 years, which
is just fine. Remember, there's still Perl4 code out there, and that
was over 10 years ago. In 10 years, there will still be Perl5 code out
there, and it will run just fine on Parrot (and whatever other VMs are
out there).

This is the point I think you're missing - you can write pure native
Perl5 in a Perl6 environment and call Perl6 modules, without a single
issue. You can call Perl5 modules from Perl6 without a single issue.
Everything else is icing.

 The fact that there's not alot of active p5p'ers on this list should
 alarm people more.

Why? They're focused on Perl5, not Perl6, as it should be.


Re: Avoid the Yen Sign [Was: Re: new sigil]

2005-10-23 Thread Rob Kinyon
On 10/23/05, Autrijus Tang [EMAIL PROTECTED] wrote:
 Dan Kogai wrote:
  To make the matter worse, there are not just one yen sign in  Unicode.
  Take a look at this.
 
  ¥ U+00A5 YEN SIGN
  ¥ U+FFE5 FULLWIDTH YEN SIGN
 
  Tough they look and groks the same to human, computers handle them
  differently.  This happened when Unicode Consortium decided to make  BMP
  round-trippable against legacy encodings.  They were distinct in  JIS
  standards, so happened Unicode.

 In addition to your handy table, the  and  french quotes, which are used
 quite heavily in Perl 6 for both bracketing and hyper operators, also have
 full width equivalents:

 300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;Y;OPENING DOUBLE ANGLE BRACKET
 300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;Y;CLOSING DOUBLE ANGLE BRACKET

 Half width: «»
 Full width: 《》

 There is no way to type out the half-width yen and double angle brackets under
 MSWin32, under either the traditional or simplified code pages; only full 
 width
 variants are available.

 One way to approach it is to make Perl 6 accept both full- and
 half-width variants.

 Another way would be to use ASCII fallbacks exclusively in real programs, and
 reserve unicode variants for pretty-printing, the same way that PLT Scheme and
 Haskell recognizes λ in literatures, but actually write lambda and
 \ respectively
 in everyday coding.

Isn't this starting to be the question of why we have the Unicode
operators instead of just functions? Would it be possible to have a
function be infix?

Rob


Re: new sigil

2005-10-21 Thread Rob Kinyon
On 10/21/05, Steve Peters [EMAIL PROTECTED] wrote:
 On Fri, Oct 21, 2005 at 02:37:09PM +0200, Juerd wrote:
  Steve Peters skribis 2005-10-21  6:07 (-0500):
   Older versions of Eclipse are not able to enter these characters.  That's
   where the copy and paste comes in.
 
  That's where upgrades come in.
 
 That's where lots of money to update to the next version of WSAD becomes the
 limiting factor.

So, you are proposing that the Perl of the Unicode era be limited to
ASCII because a 15 year old editor cannot handle the charset? That's
like suggesting that operating systems should all be bootable from a
single floppy because not everyone has access to a CD drive.

Rob


YAMM (Yet Another MetaModel)

2005-10-21 Thread Rob Kinyon
I'd like to propose a new metamodel that (I hope) will meet all the
specs @Larry has stated thus far. This metamodel is in two parts.

Part the first:
There is a single object given to P6 called Factory. (No, Steve, there
are no turtles.) Factory has two behaviors, no state, and no classes.
The behaviors are:
* create() - this will create a blank object with no behaviors or state.
* set_behavior( $object, $name, $behavior) - this will assign
$behavior to $object callable by $name.

Part the second:
A set of keywords will be used to generate objects. That set of
keywords would include class and role. These objects do not have
classes - they are -things- in their own right. (Still no turtles,
Steve.) class and role, for instance, would be given the behaviors:
* new() - the constructor. This wraps Factory.create() and
Factory.set_behavior() appropriately. It's unclear whether each item
new() creates should have the methods within them or aliases to the
class's methods.
* eat() - this would support composition through has
* clone() - maybe?
Plus, whatever other behaviors is necessary. The keyword is would be
handled by adding in state (which is just a behavior wrapping some
data) to handle method redispatching to another object (the parent
class).

Yes, this is very prototype-ish. But, the metamodel that Steve's been
working on is moving in that direction. Everything is an object
already. Let's just clear some of the cobwebs and provide a truly
clean interface.

Rob


Re: new sigil

2005-10-21 Thread Rob Kinyon
  So, you are proposing that the Perl of the Unicode era be limited to
  ASCII because a 15 year old editor cannot handle the charset? That's
  like suggesting that operating systems should all be bootable from a
  single floppy because not everyone has access to a CD drive.

 I saying that, since my up-to-date version of vi on my up-to-date OpenBSD
 can't type, much less even allow me to paste in, a Latin-1 character, this
 is an issue.

You're still using the base vi vs. vim?!? I didn't know people did
that when it wasn't 3am on Sunday when trying to fix a borked /etc ...
Huh!

Rob


Fwd: $1 change issues [was Re: syntax for accessing multiple versions of a module]

2005-10-21 Thread Rob Kinyon
Feh - I really need to get on gmail's case for providing a keystroke
for Reply to All.

Rob

-- Forwarded message --
From: Nate Wiger [EMAIL PROTECTED]
Date: Oct 21, 2005 2:38 PM
Subject: Re: $1 change issues [was Re: syntax for accessing multiple
versions of a module]
To: Rob Kinyon [EMAIL PROTECTED]


Rob-

BTW, C and PHP both use - still.

 That's because PHP is a Perl templating engine that got too big for
 its britches. (http://www.devshed.com/c/a/PHP/An-Introduction-to-PHP/)

Hah, that's a funny way to look at it. Although, PHP forked back in
1997, reading the article. There's alot of stuff it does differently
nowadays, some better, some worse.

Anyways, you can listen or not listen to those of us from real, large,
corporate environments. I'm just trying to temper the enthusiasm for
many of the real improvements in Perl 6 with some of the real costs -
which are largely being ignored as no big deal.

 I think YOU forget that nearly everyone else on this list, including
 @Larry, has worked in large corporate environments. My understanding
 of the response has been Yes, there might be issues. They are all
 solveable with a little elbow grease. And, frankly, you can run every
 P5 program under Perl6. I'm not seeing what the problem is.

Fair enough. Maybe I'm just a whiner. That's possible.

But, I'm on the cusp of a major new outing, namely [snip]. The
point is, I don't like the idea of having to relearn a ton of stuff
midway thru the 5+ year product cycle of [snip]. So I'll probably end up
choosing a different language for the team to use, which is too bad.

-Nate

P.S. I didn't post this to the list, because you didn't


Re: Slightly OT: zip() for Perl5?

2005-10-21 Thread Rob Kinyon
Does TYE's Algorithm::Loops's mapcar() provide the basic functionality
of what you're looking for?

Rob

On 10/21/05, Mark Reed [EMAIL PROTECTED] wrote:
 Is there a CPAN module which provides the functionality of ¥/zip() for
 Perl5?  I don't see anything obvious in the Bundle::Perl6 stuff.  Not hard
 to write, of course, just wondering if it's been done . . .






Re: syntax for accessing multiple versions of a module

2005-10-20 Thread Rob Kinyon
On 10/20/05, Nate Wiger [EMAIL PROTECTED] wrote:
 Larry Wall wrote:
  I think there can be some kind of community metainformation that sets
  defaults appropriately.  And if not, the site/project can certainly
  establish defaults.  On the other hand, a lot of projects do simply
  want to specify the version and author explicitly eveyr time,
  and they'd rather tweak it by hand (or by script) if they want to
  change it, since then at least they know when they need to rerun the
  regression tests.

 I think it's a laudable idea in theory, but not necessarily application.
 I've done quite alot of Perl programming, and I've never run into this
 personally. Who has? (Really, I'm being serious.) Are there really
 multiple modules sharing interchangeable interfaces? Or instances where
 we want to allow the same name to mean different concepts depending on
 the author?

Please see http://www.perlmonks.org/?node_id=501496 for more on the
issue of names. My Tree module and Schwern's Tree distro have almost
zero interface compatibility. They both represent N-ary trees, except
mine exposes the tree interface and Schwern's is just a OO interface
for a hash implemented as a tree. My module is descended from
Tree::Simple, except ::Simple almost never is.

The same thing goes for my version of Tree::Binary and Stevan
Little's. Two completely different interfaces, but here we're solving
the same problem. The major difference between mine and his is that
mine inherits from my Tree whereas his is an independent module. This
means that adding transparent persistence (which is what my rewrite
does) to his module is a bit of a bear.

Hence, you might want to use RKINYON's Tree::Binary over STEVAN's
Tree::Binary. Or, what should I call mine? (This is a real question -
if you have any suggestions, please let me know!)

 There's no logical difference between:

 use DBI:TIMB
 use DBI:JEFFSTER

 And:

 use TIMB::DBI
 use JEFFSTER::DBI

No, this isn't any good, either. I took over DFERRANCE's PDF::Template
implementation. He has nothing to do with it anymore. So,
DFERRANCE::PDF::Template now becomes RKINYON::PDF::Template? Or, does
RKINYON now maintain something in the DFERRANCE namespace? What on
earth does the name DFERRANCE provide, except for an additional layer
of confusion.

 Anyways, I don't like the idea of people being able to upload
 identically named modules to CPAN. I think that's a very bad idea. See
 Rob Kinyon's message.

I think you misinterpreted my message. My point is that uploading
things with the same name is a good plan, but it has to be thought
through, especially given the points I raised. But, I very much agree
that it should happen.

I'd like to propose a slight shift in emphasis. I think that more
focus needs to be made in project-wide or namespace-wide
disambiguation and module aliasing. If I was able to say in my CP6AN
distro that I depend on DBI:2.05-:cpan-TIMB and that I'm going to call
it DBI, then all the files in my distro should automatically have that
alias built in. This means that anyone wanting to use DBI:cpan-JRANDOM
in their code can alias it as DBI on a project-wide basis, yet still
be able to use my distro and everything be ok.

The important thing here, I think, is that while aliasing package
names is a lexical action, there can be a larger lexical scope. It may
be that we need the concept of a Project, along with Module,
Package, Class, and Role. This way, the Project states Whenever you
load a file that matches the criteria below, apply the following
lexical _stuff_.

Rob


Re: syntax for accessing multiple versions of a module

2005-10-20 Thread Rob Kinyon
On 10/20/05, Nate Wiger [EMAIL PROTECTED] wrote:
 And, it shares alot with other languages people know and use.

That's more because languages are incestuous (like Perl) instead of
languages independently arriving at the same conclusions. Yes, the
while loop is going to look the same everywhere. But, the fact that
everyone uses $1 to mean the first match has nothing to do with
whether or not that's a good idea. The first engine did so, which
means the next one probably will.

 Right now the design is going towards something that's very very
 un-Perlish from a syntax standpoint. Sure, the philosophy's there, but
 there are fewer and fewer things Perl 6 shares with Perl 5 (or other
 widely-used languages).

I wholeheartedly disagree. You can take any piece of P5 code and, with
very few modifications, have it run as native P6 code. You won't be
using a ton of the greatest features, but we have that in P5. I once
taught a programmer who'd been using Perl for over a year how to use
hashes. I have an article coming up in early November on perl.com
about how and why to use subroutines. Just because _you_ know about
the feature doesn't mean the hoi-polloi do. Heck, I've been
programming in Perl for almost 10 years and I have NEVER written a
line of XS. I wouldn't know where to start.

Frankly, most of the features in P6 look to be usable by 1% of the
Perl developers, and then only about 1% of the time. Most of my P6 is
going to be very vanilla. I'll take advantage of most of the new list
operators and thoroughly abuse the class/role system, but I'm not
going to be writing my own grammars or deal with $0/$1/etc. I don't
deal with them now - I prefer named captures.

The point is that if you want to truly clean off the cruft, you have
to approach with a completely open mind. That open mind is going to
piss off a lot of people and you will never do everything you were
hoping to do, but the end product will be better off for it. You'll
never reach the moon unless you shoot for the stars.

Rob


Re: syntax for accessing multiple versions of a module

2005-10-20 Thread Rob Kinyon
 Unfortunately many people WILL have to deal with such changes, and
 the question should be: Does a given change offer a clear improvement?
 As you said, if we're helping %1 of people %1 of the time, are the
 other 99% really going to change all their scripts? No chance.

You again misread what I said. The other 99% aren't even going to
notice the changes. Remember - 90% of all Perl code in the wild that
should use hashes doesn't. 90% of all Perl code that should use map
and grep doesn't. 90% of all Perl code that should use regexes
doesn't. The authors of those programs aren't even going to notice
that P6 changed. All they're going to see is that there's a few VERY
MINOR syntactical changes, they'll adjust, and they'll be happy.

Please remember the primary uses of Perl5 - systems administration,
package management, and CGI scripts. By far, those are the
overwhelming uses of Perl. In fact, I would argue that 99% of all Perl
code in the world falls under those three categories.

If you don't believe me, read The Pragmatic Programmer. These are
excellent programmers and their view of Perl is for:

1) Writing tests (pp. 53, 197)
2) Project management and glue (pp. 100-101)

In fact, they specifically state in Tip 28 that every programmer
should learn a Text Manipulation Language (the authors prefer Ruby
and Perl) in order to do these things.

These are The other 90% you refer to. They're not going to care one
way or the other. And, if they do, /usr/local/bin/perl won't suddenly
disappear like Cindarella at the ball, you know.

Rob


Re: new sigil

2005-10-20 Thread Rob Kinyon
On 10/20/05, Steve Peters [EMAIL PROTECTED] wrote:
 I have some serious concerns about using Latin-1 sigils within Perl 6 and
 the ASCII multi-character aliases.  Am I not understanding something that
 I should see this as an advantage?

I had the same concern a few months back. I've come to see the light
in this fashion:
1) more and more Perl programmers come from non-English countries.
Heck, the Pugs effort is at least 50% non-US, if not more. None of the
are on US soil and very few of the leaders are US citizens.
2) More and more of us are programming with internationalization
(i18n) in mind. Just recently, I had to edit french text within the
templates of an app I work on. If you haven't already, you will be
doing so in the near future, within the next 3 years.
3) Every editor (with very few exceptions) can display Latin-1
and, with a few more exceptions, can input Latin-1. If your favorite
editor cannot, then that's something to bring up with the authors.

Windows ... yeah. As you pointed out, the old joke goes Doctor,
it hurts when I use Windows . . . then, don't use Windows! With the
availability of dual-booting into FreeBSD/Linux (given the
near-complete migration of all the necessary Office products) and both
gvim and emacs having been successfully ported to WIn32, there is a
way to do it. gvim on WinXP will do all Latin-1 charset with the vim
keys. (I don't know about emacs, but I'd be shocked if it didn't.) If
your IT department's policy is rigid, a quick discussion with your
manager's manager will solve that problem immediately. Or, the cost of
a few lunches with your favorite IT person will exempt your computer
from the nightly audit. ($50 goes a long way ...)

Personally, I plan on using every single Latin-1 operator I am
given access to. All the cool kids will ...

Rob


Re: new sigil

2005-10-20 Thread Rob Kinyon
 Surely you aren't suggesting that these non-English speakers do not have
 access to the ASCII (or EBCDIC) character sets for their editors, are you?

Surely you aren't suggesting that your editor doesn't have access to
the Latin-1 charset, are you? Let's take a look at popular editors:
vi - check
emacs - check
eclipse - check
mutt - check (http://www.rano.org/mutt.html)
Notepad - check
A bazillion other editors - check
(http://www.alanwood.net/unicode/utilities_editors.html)

 I have worked on an app that needed to work with English (US and GB),
 German, and Japanese.  I do not, however, remember having to write my
 code in anything but ASCII.

No, I had to edit my -templates- and -data files- that included French
text. Some of them could use HTML entities, but the datafiles intended
for the DB couldn't.

 As I mentioned earlier, most programmers in a corporate environment have
 limited access to system settings.  Changing them in some cases can cause
 reprimands or dismissal.  Systems are often set up with the bare minimum
 of locales and character sets necessary to do the job.  Also, you have to
 deal with the situations where programmers are connecting to *nix servers
 through a variety of Windows-based XWindows servers (Exceed, Cygwin, etc.)
 complicates what character sets are available immensely.

I have worked as a contractor in almost a dozen settings, most of them
corporate lockdowns, and I've always been able to go to my manager and
say To be more productive, I need this tool and it would be loaded
the next day. The few times I've had to talk to an IT person to
explain the tool, I'd do it over lunch (my treat) and it would be on
my desktop the next morning. Saying you cannot get a tool you need
loaded on your machine is, essentially, saying that you cannot play
corporate politics. I'm assuming you can, which means this is a straw
man.

Rob


Re: subclassing associated classes elegantly

2005-10-19 Thread Rob Kinyon
On 10/19/05, Darren Duncan [EMAIL PROTECTED] wrote:
[snip]
 An example of when this situation can arise is if person X implements
 a simplified XML DOM implementation using 2 classes, Document and
 Node, that work together, where one of those classes (Document) can
 create objects of the other (Node), and person Y wants to subclass
 the XML DOM implementation, meaning that those same Node objects made
 by one of person Y's Document subclass should be objects of person
 Y's Node subclass.

 To illustrate, say we had these 4 classes (the syntax may be wrong):

# This is one associated class set:

class A {
  submethod one () {
return 'hello';
  }

  submethod two () {
B.four();
  }
}

class B {
  submethod three () {
A.one();
  }

  submethod four () {
return 'here';
  }
}

# This is separate and optional associated class set:

class C is A {
  submethod one () {
return 'world';
  }
}

class D is B {
  submethod four () {
return 'there';
  }
}

 What I want to be able to do is set things up so that user code can
 do something that is effectively like this:

my $first = A.two(); # returns 'here'
my $second = B.three(); # returns 'hello'
my $first = C.two(); # returns 'there'
my $second = D.three(); # returns 'world'

 The situation is that classes C and D represent any arbitrary named 2
 classes that are subclassed from A and B, and so the latter can't
 know the names of the former, and the latter have to work
 independently of C and D also.

 This is one variant of a solution I have come up with:

# This is one associated class set:

role AB {
  submethod name_of_class_A () {
return 'A';
  }

  submethod name_of_class_B () {
return 'B';
  }
}

class A does AB {
  submethod one () {
return 'hello';
  }

  submethod two () {
.name_of_class_B().four();
  }
}

class B does AB {
  submethod three () {
.name_of_class_A().one();
  }

  submethod four () {
return 'here';
  }
}

# This is separate and optional associated class set:

role CD {
  submethod name_of_class_A () {
return 'C';
  }

  submethod name_of_class_B () {
return 'D';
  }
}

class C is A does CD {
  submethod one () {
return 'world';
  }
}

class D is B does CD {
  submethod four () {
return 'there';
  }
}

 This is another variant of a solution I have come up with:

# This is one associated class set:

role AB {
  submethod invoke_one () {
return A.one();
  }

  submethod invoke_four () {
return B.four();
  }
}

class A does AB {
  submethod one () {
return 'hello';
  }

  submethod two () {
.invoke_four();
  }
}

class B does AB {
  submethod three () {
.invoke_one();
  }

  submethod four () {
return 'here';
  }
}

# This is separate and optional associated class set:

role CD {
  submethod invoke_one () {
return C.one();
  }

  submethod invoke_four () {
return D.four();
  }
}

class C is A does CD {
  submethod one () {
return 'world';
  }
}

class D is B does CD {
  submethod four () {
return 'there';
  }
}

 In either case, the expectation here is that the submethods of role
 CD will override those of role BC regardless of which class' other
 methods invoke those, when the invocant class is C or D.

 So I'm wondering what is the best way to develop my associated class
 sets such that it is easiest for third parties to be able to
 subclass-extend them.  Should I use one of the two solutions above
 (both of which have been tried in real life, in Perl 5, the second
 more recently)?  Or is there another solution that is better than
 both?

 Also, in such a situation as the above, is it reasonable to support
 easy subclassing, or would it be better to avoid that complexity and
 instead expect users to create objects that wrap the others instead
 of subclassing them?

 Assume also that it may be counter-productive for one class to expect
 user code to invoke the second class on its behalf, such as if when
 pair of classes is hidden behind a second pair of classes that
 mediate access to them.

 What are some best practices here that can be used by anyone faced by
 a similar problem?

 -- Darren Duncan

[snip]

In Perl5, I would think the easiest solution would be to trick the
base Document class into using the right Node class.

1) Load Node.
2) Rename Node to Node::Base
3) Create your Node, subclassing Node::Base
4) Load Document
5) Rename Document to Document::Base
6) Create your Document, subclassing Document::Base

Something along the lines of:

package Node::Mine;

use 

Re: syntax for accessing multiple versions of a module

2005-10-19 Thread Rob Kinyon
On 10/19/05, Nate Wiger [EMAIL PROTECTED] wrote:
 My concern is that we're solving problems that don't really exist in
 real-world Perl usage. Are there really two competing authors of DBI?
 Or, for any product, do two people really try to market SuperWidget?
 No, one person just changes to SuperGadget. And with URI's, one person
 gets amazon.com. Sorry, name taken.

 I think we're actually *encouraging* problems by allowing long, clashing
 names. Pretty soon all DBI modules will have to start with

 use DBI:TIMB;

 Because JEFFSTER decided to upload his DBI (Derivative Binary Index)
 module.

 I think it will have the opposite effect of what we're trying to avoid.

I'm of two minds about this, in large part because I have two
experiences with the current CPAN.

My first CPAN module was taking over PDF::Template, originally written
by DFERRANCE. Now, it's maintained by RKINYON, soon to be maintained
by RKINYON and STEVAN due to amazing contributions by AUTRIJUS (or
whatever those characters are supposed to be).

Now, how are authorship-changes going to be handled, particularly in
the face of having two PDF::Templates out there already? Everyone is
disambiguating their modules with PDF::Template-DFERRANCE vs.
PDF::Template-JRANDOM. Now, they cannot upgrade to my latest feature
because that requires changing every place they had hard-coded
DFERRANCE. Or, will the package system map PDF::Template-DFERRANCE to
PDF::Template-RKINYON?

The second experience is one I'm going through right now. I was adding
a feature to Tree:Simple a few weeks back and realized that it needed
to be gutted to do what I needed it to do. With the encouragement of
the author, I rewrote it completely. My development name for the
distro is Forest, but I have Tree and Tree::Binary as the packages.
(Yeah, it's a math joke.)

Except, there's two problems with that - Tree is a TLN (top-level
namespace) with a lot of unrelated distros beneath it. And, Tree is
owned by someone else, but that person hasn't updated Tree in 6 years.
And, Tree::Binary is owned by the same guy who owns Tree::Simple.

How is that going to work in P6? (For the record, I still haven't
figured out what I'm going to do yet. Check Perlmonks for the SOPW in
a few minutes.)

Rob


Re: top 5 list needed

2005-10-18 Thread Rob Kinyon
Some other features:

1) You can write your program in any combination of programming styles
and languages, as you see fit. Thus, you can use your OO library
written in Ruby, that really fast C routine, and your Perl code, all
in one place.
2) There are a large number of operators that support list
manipulation, such as the zipper, the == and == operators, reduce,
and others I can't remember in addition to P5's map, grep, and sort.
3) Macros. Nuff said.
4) More declarative syntax. This is more of a handwavy, but the syntax
feels (to me) as if it's more declarative than before. For example,

for @x - $x { ... }
for @x - $x, $y { ... }

That reads like a math proof. For all X, do such-and-such.

Rob


Re: Making Wrong Code Type Wrong

2005-10-18 Thread Rob Kinyon
[snip]

Let me rephrase to see if I understand you - you like the fact that
boxed types + roles applied to those types + compile-time type
checking/inference allows you to tag a piece of information (int,
char, string, obj, whatever) with arbitrary metadata. Add that to the
fact that you can lexically mark certain function signatures as
checking against said arbitary metadata and you can provide
taint-checking to an arbitrary complexity.

Yeah, that's cool. :-)

Rob


Re: syntax for accessing multiple versions of a module

2005-10-18 Thread Rob Kinyon
On 10/18/05, Juerd [EMAIL PROTECTED] wrote:
 Nicholas Clark skribis 2005-10-18 22:41 (+0100):
my $foo = DBI(1.38)-new();
my $bar = DBI(1.40)-new();

 I like this syntax, and have a somewhat relevant question: can a module
 be aliased entirely, including all its subclasses/-roles/-.*?

 Something like

 use DBI   as RealDBI;
 use MyDBI as DBI;

Since a Package or a Module can be a scalar, there shouldn't be a
reason why this isn't possible.

Rob


Re: top 5 list needed

2005-10-18 Thread Rob Kinyon
On 10/18/05, Uri Guttman [EMAIL PROTECTED] wrote:
  SL == Stevan Little [EMAIL PROTECTED] writes:

   SL On Oct 18, 2005, at 1:45 PM, Luke Palmer wrote:

On 10/18/05, Rob Kinyon [EMAIL PROTECTED] wrote:
   
3) Macros. Nuff said.
   
   
Not quite.  Lispish macros, that is, macros that let you look at what
you're expanding.

   SL To further expand on this, they will be AST-manipulating macros (LISP
   SL style) rather than text-replacing macros (C style).

 my impression is that both styles are supported as you can return either
 text or an AST (compiled code) from a macro.

That sounds really ... inefficient. For that to work, you'd have to
have seen the macro definition earlier in the parse cycle, then
encounter the call to the macro (thus consuming the token), unshift
the tokens of the macro into the parse queue (thus necessitating a
parse queue), then reparse the whole block because of potential
bracing issues.

Text-substitution macros would have to be handled in an earlier pass,
but the macro might be referencing items from BEGIN blocks already
seen ...

It's called a preprocessor in C for a reason.

Rob


Re: Custom Metaclass and Inheritance of Class Methods

2005-10-14 Thread Rob Kinyon
 == CONCLUSION / WRAP-UP

 So, now that I have sufficiently bored you all to tears, I will do a
 quick re-cap of the main question, and the possible solutions.

 Should metaclasses be inherited along normal class lines?

 Meaning that if Foo uses a custom metaclass, and Bar isa Foo, then
 Bar also uses that metaclass.

 If we say yes, then I think it is clear that in order to get a sane
 method and predictable resolution order the custom metaclass would
 always need to precede the inherited eigenclass in the superclass
 list. (see the last example above).

 If we say no, then we need to introduce another anyonomous class into
 our mix, which we call an 'x' class. The 'x' class would need to use
 a breath-first dispatch order in order to produce a sane and
 predictable method resolution order.

I would like to expand on my position in the discussion Steve and I
had, which is the no position. The crux of my view is that Foo is an
instance of some custom metaclass. Bar is an instance of Class (for
the sake of argument). Foo and Bar are unrelated, save for the fact
that instances created by Bar's new() function will have access to all
the behaviors and state that instances created by Foo's new() function
will have.

This is why I also feel that class methods shouldn't have the same MRO
as instance methods, but that's a moot discussion.

Rob


Should roles and classes be merged?

2005-10-14 Thread Rob Kinyon
In the discussions I've had with Steve, one thing that always
nagged me - what's the difference between a class and a role? I
couldn't fix it in my head why there were two separate concepts.
Steve, yesterday, mentioned to me that in the metamodel that he's got
so far, Class does Role. This means that you can have Class A does
Class B, and it will DWIM. Additionally, Larry has said that he wants
to be able to instantiate a role.

This makes gut-sense to me. A role is really just a class
snippet, complete or not. You can compose these snippets together to
make a larger class. Or, in many cases, you can just instantiate the
snippet and have a viable instance. You can also have an incomplete
snippet, just as you can have an incomplete class. This could be
useful for things like interfaces.

Now, you can have your class inherit from another class, compose
itself from other classes, or both! It's completely up to you. You can
have your roles in an inheritance hierarchy, and it will all just
DWIM.

What this means is that classes and roles both quack, swim, and
lay eggs. They're both just ducks. Given that, there's no need for two
separate concepts in the implementation. It just makes for a more
complex implementation.

I need to stress that I'm not suggesting that the keyword role
be removed. It won't be the first time we have keywords that mean the
same thing, just with a little sugar added. It definitely improves
maintainability to have separate keywords for separate ideas, even if
they're implemented identically.

Thanks,
Rob


Re: Should roles and classes be merged?

2005-10-14 Thread Rob Kinyon
On 10/14/05, Larry Wall [EMAIL PROTECTED] wrote:
 : I need to stress that I'm not suggesting that the keyword role
 : be removed. It won't be the first time we have keywords that mean the
 : same thing, just with a little sugar added. It definitely improves
 : maintainability to have separate keywords for separate ideas, even if
 : they're implemented identically.

 Certainly a different keyword can be used to convey a different intent.
 And because there's a different intent, we can have different defaults
 for them, at minimum.

 But I think it goes a little deeper than that.  Not to put too fine
 a point on it, classes want to be open, and roles want to be closed.
 Let's not forget that the main point of roles is to commit to units
 of behavior that can be composed into classes (and other roles)
 at compile time.  It's your basic mutable/immutable distinction.
 The compiler can rely on immutable values not changing.

Ok. So, in essence, a role is a class that defaults to being closed
and a class is a role that defaults to being open. Am I rephrasing you
correctly? If so, then they're really the same beast under the hood,
just with different default behaviors.

 Going the other direction, you could also use a class as if it
 were a role, but only by taking a snapshot of its current value.
 If you're planning to modify your base class after that, you'd
 better be using inheritance rather than composition, or the derived
 class won't see the change to the base class, and that would be
 unfortunate.

As you said in the recent class methods thread, it won't be the first
time the programmer would be surprised that the computer did exactly
what it was told to do. If you choose to compose, you're fixing the
behaviors/state at the time of composition, regardless of what happens
after composition. If you choose to inherit, you're not fixing
anything (save when you choose to close).

  It's bad enough that you might have to notify all
 the existing objects that one of its base classes has been modified.
 Doing that notification to objects of classes that have composed roles
 with compile-time assumptions would be a nightmare of pessimization.
 The first implementation of Perl 6 might not make use of optimizations
 based on compile-time composition, but we need to leave that door open.

Why would that notification need to be done? I, the programmer, chose
to compose class A into class B. If I then change class A, I do -not-
want class B to see those changes. Granted, it's an unmaintainable
pile of dreck, but it's MY unmaintainable pile of dreck. And, Perl
shouldn't get in the way of my ability to create piles of dreck. I
think inheritable class methods are horrid, but I do agree that Perl
should give you as much rope as you want.

Rob


Re: Closed Classes Polemic (was Re: What the heck is a submethod (good for))

2005-10-13 Thread Rob Kinyon
 I think this is an opportune time for me to express that I think the
 ability to close-source a module is important.  I love open source,
 and I couldn't imagine writing anything by myself that I wouldn't
 share.  But in order for Perl to be taken seriously as a commercial
 client-side language, it must be possible to close the source.  I
 started writing a game with a few friends last year, and as we were
 picking our implementation strategy, using Perl as the primary
 sequencing engine for non-time-critical tasks was immediately
 discounted when I commented that anybody can look at your perl source
 if they want to.

I'd be interested in finding out how this is reasonably feasible for,
given that you just said a disassembler for Parrot is going to be
relatively simple due to the level of introspection Perl is going to
require.

Of course, given that Parrot is the ultimate interoperability swiss
army knife, one could envision a language without the introspection
Perl requires (such as C) that would target Parrot quite nicely.
(Isn't Carrot the name for this push? I haven't kept up with the
Parrot list.) Then, disassembling that bytecode back to its original
form becomes much less desirable.

 Of course, there is no argument there for allowing closed-source
 *modules*, just complete applications.  But I'm sure you could fish
 one out involving dynamic loading, or modding, or whatever you want to
 call it.

The argument that was made was for closing modules, not applications.
Specifically, a DB vendor might be more comfortable providing a DBD
for their product(s) if they could close the source.


Re: Closed Classes Polemic (was Re: What the heck is a submethod (good for))

2005-10-12 Thread Rob Kinyon
On 10/12/05, chromatic [EMAIL PROTECTED] wrote:
 On Wed, 2005-10-12 at 21:50 +0200, Yuval Kogman wrote:

  This has even more implications with closed classes to which you
  don't have source level access, and if this can happen it will
  happen - i'm pretty sure that some commercial database vendors would
  release closed source DBDs, for example.

 Closed classes should not exist.

 At least, they should only exist if the person *running* Perl 6 wants
 them to exist -- never if merely the class writer wants to close them.

I'm not sure y'all are talking apples and apples. Yuval is talking
about lack of source-level access and the class being closed. I'm not
quite sure how we end up with a lack of source-level access,
particularly as that locks me, the user of your module, into one
specific P6 interpreter (presumably Parrot). Given the work that
Autrijus and company have been doing with PIL and Pugs in general,
closing the source (presumably by releasing Parrot bytecode) isn't
going to really work. (Plus, I can't imagine that a reverser for
Parrot code is going to be that hard to write.)

Furthermore, is releasing just the Parrot bytecode going to work in
multi-lingual apps? Aren't there optimizations that may not be
appropriate before all the languages are known? (I'm completely out on
a limb, here.)

That said, I agree with chromatic closing (or finalizing) a class
should be the action of the consumer, not the producer. Maybe the
producer could signal his/her desire to close the class when some
phase is finished. That would mean the consumer could either modify
the class before that phase is finished and/or the consumer could
intercept the request for finalization.

Alternately, maybe you have a pragma that says Finalize all classes
unless I specify that it should remain open. Maybe, we need a
negation for close? keep_open?

Rob


Re: Proposal to make class method non-inheritable

2005-10-12 Thread Rob Kinyon
All -

I'm partly to blame for this thread because I put the idea into
Steve's head that class methods being inheritable may be dogma and not
a useful thing. Mea culpa.

That said, I want to put forward a possible reason why you would
want class methods to be inheritable - to provide pure functions.

If we go back to every function/method/subroutine being behavior,
it's pretty evident that you need some state for that behavior to
operate upon. In a procedural function, the state is provided. In an
object, that state is both provided and inherent in the instance the
method is operating upon. In functional languages, functions maintain
their own state through closures, continuations,  and the like.

I might want to provide in a base class a set of useful sorting
routines or other such items. These would be true procedural functions
and there would be a warning thrown if it accessed class state.

Rob


Re: How much do we close over?

2005-06-12 Thread Rob Kinyon
 Piers Cawley said:
 in other words, some way of declaring that a subroutine wants to hang onto
 every lexical it can see in its lexical stack, not matter what static analysis
 may say.

I'm not arguing with the idea, in general. I just want to point out
that this implies that you're going to hold onto every single
file-scoped lexical, leading to quite a bit of action-at-a-distance.

Maybe, instead, you should say sub is lexical_stack(N) where N is
the number of scoping levels it will hold onto in addition to any
lexical it actually refers to. I would have 0 be the innermost scope,
1 be the enclosing scope, etc.

Rob


Re: date and time formatting

2005-06-03 Thread Rob Kinyon
 localtime() and gmtime() seem fairly core to me.  The array contexts are
 simple, and the scalar context is an RFC valid string.  Nothing too heavy
 there.  The time() function is typically only moderately useful without
 localtime().

This is true if the time() function returns a simple scalar containing
seconds since the Unix epoch. If, however, it returned a DateTime
object that numified to said value, but provided both localtime() and
gmtime() methods (and a whole lot more) ... wouldn't that be better?

Rob


  1   2   >