Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-09 Thread TSa (Thomas Sandlaß)
On Tuesday, 9. November 2010 01:45:52 Mason Kramer wrote:
 I have to disagree here.  Arrays and Hashes may be about storage (I don't
 think they are, though, since you can change the (storage) implemenation of
 an Array or Hash via its metaclass and it can still remain an Array or
 Hash).

What I mean with storage is that you put some data into a numbered slot
in an array and a keyed slot into a hash. With the same index or key you
can retrieve your data at any time. This is the case irrespective of the
underlying implementation. A set is not about storage in this sense, because
there is no way of retrieving an element. The only operation is a membership
test which is of boolean nature like number comparison.


 The most important part of the @ sigil, and the reason I preferred it over
 $, is that @ flattens (moritz++'s word), when used in a list context such
 as for @blah,
 map {...}, @blah.

I wonder if it is not possible to bind flattening to Iterable. This of course
has the drawback that it is not syntactically distinguished. But doesn't

   my $x = (1,2,3);
   my $y = map {$^x * $^x}, $x;

result in $y containing the list (1,4,9)? And if $x happens to be a scalar
isn't it just squared? In the end we just need map:( closure, Set $data -- 
Set) as an overload. Or perhaps map:( closure, Iterable ::T $data -- T).


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Smart match isn't on Bool

2010-08-02 Thread TSa (Thomas Sandlaß)
HaloO,

On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote:
 On Sun, Aug 1, 2010 at 6:02 PM, Jonathan Worthington jonat...@jnthn.net 
wrote:
  No, given-when is smart-matching. The RHS of a smart-match decides what
  happens. If you do True ~~ 1 then that's 1.ACCEPTS(True) which is going
  to do +True and thus match.

 OK, but what about 0 ~~ True?  That's what started this thread,
 extricated from the complicating trappings of given/when.  Right now,
 (anything ~~ True) is true, and IMHO that's a misfeature; it's at
 least surprising.  I'd expect (anything ~~ True) to be synonymous with
 ?(anything): true only if the LHS boolifies to true. By the same
 token, (anything ~~ False) would be synonymous with !?(anything).

Note also that ($anything ~~ foo()) just throws away $anything. I would
opt for a regularization of the smart match table. First of all the
generic scalar rule should coerce the LHS to the type of the RHS and
then use === on them. This is how the Any ~~ Set case is specced. The
cases Stringy and Numeric fall out naturally from this definition. The
Bool case should become a special case just like Stringy and Numeric. The
auto-invocation of Callable is a good thing but the fact that the return
value is not subject to the generic scalar case is a misfeature. That is
we loose:

   given 42
   {
  when foo() {...}
  when bar() {...}
  when baz() {...}
   }

which could mean to execute that block whose controlling sub complies
with the given and not the one that returns True first. Note that this
style is particularly usefull with given True. But then we sort of have
the coercing the wrong way around because the idea is to check the
return value in boolean context not coercing the True to whatever the
type of the return value is. BTW, how is the case with a unary sub written?


Could someone please give a rational for the interspersing technique

   given $anything
   {
  when $one {...}
  when two() {...}
  when $three {...}
   }

where two() returning a true value prevents the case $three. And if it
is considered usefull I support the whenever proposal because different
things should look different. BTW, would

   given $anything
   {
   when $one {...}
   if two() {...}
   else { when $three {...} }
   }

still smart match $anything with $three? Or is the topic the return
value of two() at that point?


Regards TSa
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Smart match isn't on Bool

2010-08-01 Thread TSa (Thomas Sandlaß)
HaloO,

On Saturday, 31. July 2010 20:47:49 Patrick R. Michaud wrote:
 On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote:
  It's not unreasonable, especially if that's what you expect.
  But it's even more reasonable to expect this to work:
  given $something {
  when True { say That's the truth! }
  when 42 { say Good answer! }
  when viaduct { say You guessed the secret word! }
  }

 I'm not so sure about this.  There's an argument to be made that
 the Cwhen 42 and Cwhen viaduct cases should never be reachable,
 since both C42 and Cviaduct are considered true values...

Sorry, I don't understand this possible argument. Isn't the intent
of a given/when to select one alternative by means of the given?
This is what a switch statement does. Perl 6 allows non-constants
after when, so it's reasonable to have the constant in the given
and to see e.g. which function returns it. Of course the first actually
doing this determines the switch.


 ... unless you want Cwhen True to do a value-and-type check,
 in which case it doesn't exactly follow the pattern for smartmatching
 of the other builtin types (which only check value equivalence,
 not type equivalence).

This is true only if you want to distinguish 1 and True which are the
same value. But 42 should be distinct from this. Same goes for viaduct.
So these three should be a valid disjoint set of choices that can be
made given $something.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Smart match isn't on Bool

2010-07-31 Thread TSa (Thomas Sandlaß)
HaloO,

On Saturday, 31. July 2010 18:56:47 David Green wrote:
 On 2010-07-31, at 1:33 am, Moritz Lenz wrote:
  sub test() { True };
  given 0 { when test() { say OH NOEZ } }
  I don't think it's unreasonable to expect the output to be OH NOEZ.

How does this relate the given to the when? If I get you right the
given is completely ignored and the truth of test() gives OH NOEZ.
I think the given must determine the result.

 It's not unreasonable, especially if that's what you expect.  But it's even
 more reasonable to expect this to work: given $something {
   when True { say That's the truth! }
   when 42 { say Good answer! }
   when viaduct { say You guessed the secret word! }
   }

Here I expect the $something to *select* one of the alternatives.
It can't be that a literal True ignores the given and just executes
the block.


 In both these examples, the intent is fairly clear from the context.  It's
 easier to forget that Bools behave differently from other types when you
 only have some variable that could be any type: if $guess ~~ $answer { say
 Correct! }  # hope your question wasn't T/F!

 Maybe we can't please everyone, but we can at least try not to displease
 anyone.  Perl is awfully clever at keeping your eaten ponies, and there is
 a way we can have both the helpful syntax and the consistent one:

   given $who-knows-what {
   when True { say It's a true thing! }
   when 42 { say It's numbery! }
   whenever timeout() { say Who cares what you say, time's up! }
   whenever $override { say Whatever, switching to automatic 
 override }
   }

Am I getting your intention to be that when honors the given and whenever just
checks truth? Couldn't we use if for this? That would avoid the new keyword.

Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Suggested magic for a .. b

2010-07-28 Thread TSa (Thomas Sandlaß)
On Wednesday, 28. July 2010 05:12:52 Michael Zedeler wrote:
 Writing ($a .. $b).reverse doesn't make any sense if the result were a
 new Range, since Ranges should then only be used for inclusion tests (so
 swapping endpoints doesn't have any meaningful interpretation), but
 applying .reverse could result in a coercion to Sequence.

Swapping the endpoints could mean swapping inside test to outside
test. The only thing that is needed is to swap from  to ||:

   $a .. $b   # means  $a = $_  $_ = $b  if $a  $b
   $b .. $a   # means  $b = $_ || $_ = $a  if $a  $b

Regards TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Type system for Perl 6

2010-02-05 Thread TSa (Thomas Sandlaß)
HaloO Mr Castagna

On Friday, 5. February 2010 16:43:26 you wrote:
 I see I'm going out of the scope of this list. I apologize for spamming,
 but please continue to post here or send me by PM every information about
 Perls 6 types.

I'm delighted to have you interested in Perl 6. I know your book and
articles and have argued for a type system of Perl 6 here on the list
for quite a while. Unfortunately I'm not able to implement one for
Parrot or so. But if you are willing to port the CDuce code this is
a great thing!

There is no formally defined subtype relation or rules for subsumption.
A type is called narrower without details what that means. And the
odering in dispatch is not a type lattice as in Cecil but a topological
ordering. Again I've no clue what that means. It is possible for one
role to do another as in

   role A does B {...}

and all objects that do A are also B doers. So one could infer that we
have A : B. But note that this subtype relation is not enforced in the
body of the role or in the class it is composed into. The spec says nothing
about class inheritance and type narrowness. Parametric roles are covariant
on their type parameter irrespective of its use. E.g. you can declare a
read/write attribute of that type.


Regards TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Type system for Perl 6

2010-02-05 Thread TSa (Thomas Sandlaß)
HaloO Mr Castagna,

On Friday, 5. February 2010 23:13:25 you wrote:
 Actually I noticed an old post you did on this list 5 years ago. It
 contained the following drawing

Yeah it's a long time. And I've sort of lost interest in type theory.
But then I tried to persuade the list of a sophisticated type system.
But since I couldn't hack it myself nothing has happend. And Audrey
Tang is gone. He/She was a big fan of a type system as well and hacking
Pugs in Haskell.


   A|B lub (lowest upper bound)
  /   \
 / \
A   0   B
   / \ / \
  /   \   /   \
 / AB \   glb (greatest lower bound)
/  1  /   \  2  \
   / /  3  \ \

 and it is the only reference I found to intersection types (since AB is
 the intersection of A and B (if you consider a class type as the set of all
 its instances) that is it contains all objects that are instance both of A
 and of B.

 Is this notation (or the general idea of intersection types) has been
 abandoned since then (I was not able to find it in the synopsis)

Yes, Larry never liked the idea of a type lattice and intermediate types
like A|B or AB. The syntax is now used to simply mean doing A or B.

I've also proposed to have a constraint language in the where clause of
subset declarations that is usable for type checking. But the where clause
is now only a closure that is called when needed. So { $_  10 } is not a
subtype of { $_  20 }. So no predicate dispatch either.

Someone should explain the dispatch algorithm to you. I don't remember
exactly how the voting there works. This would explain what type narrowness
in the spec means.


Regards TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: How does List.map: { .say } work?

2009-11-04 Thread TSa (Thomas Sandlaß)
HaloO,

On Tuesday, 3. November 2009 17:13:22 Carl Mäsak wrote:
 That would make statement modifier for loops less useful. For those,
 there's nowhere to put the lambda arrow.

   ++$_ for @things;

I think this is resolved with the is ref binding which
implies that the thingy that is bound to $_ is a cell
accessor of an array that provides a STORE method.

BTW, the situation of STORE and FETCH methods in classes
is kind of funny. While an object is stored in a container
the respective methods of the container are called. Only
in an is ref binding assignment affects the object directly.
That is, in the scope of the binding the object goes kind of
naked.

Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Int/Rat max precision (was Re: r28882 - docs/Perl6/Spec)

2009-10-27 Thread TSa (Thomas Sandlaß)
HaloO,

On Friday, 23. October 2009 02:27:00 Darren Duncan wrote:
 Thinking further, my interpretation of what you said above is that the
 Rational role is now basically saying that a number is represented in terms
 of numerator/denominator and that certain operators are supported, but now
 it is sounding like the details of whether the operators will produce
 Rational results or Num results is now determinable on a per-class basis,
 so we may end up working with types like Rat32, Rat64, BigRat (just
 this one being unlimited precision), etc after all.

I believe that the thing people that don't care about the precision
should use in sigs and variable declarations is the Rat role. That is
I think that Rat should be the role that is currently named Rational.
More specific instantiations of that role are then written in my proposed
type signature invocant slot syntax as Rat[Rat64:]. Note that this is
no problem because e.g. 'my Rat $x = 3/4' doesn't require Rat to be an
instantiable class. Actually the class that implements Rat is chosen
by the compiler to be e.g. Rat64. Then there need to be installation time
defaults, command line switches and lexical pragmas to influence this
choice. The second thing that needs to be hookable to different classes
is the handling of overflow and underflow of e.g. Rat64 to either upgrade
to BigRat or wrap the offending value back into Rat64 or switch over
to Num. Then there is the problem of mixed precision cases etc.


 Presumably then with the Integer role we'll also have types like Int32,
 Int64, BigInt that do the role and also convert to a Num when their
 bounds are exceeded?

 Does that sound about right?

Yes. I think there should be an Int role and classes implementing it.
The Int role must be a subrole of Rat. E.g. it adds the bit manipulation
operators which are difficult to define for rationals if not outright
meaningless. This subroling is needed for calling Rat routines with an
Int, of course.

From a Huffman POV the roles for generic integers and rationals must be
short, so the Numeric and Rational roles in S32 are going in the wrong
direction.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: unusual invocants

2009-10-26 Thread TSa (Thomas Sandlaß)
HaloO,

On Sunday, 25. October 2009 01:38:21 Martin D Kealey wrote:
 Sounds like going back to static typing -- which does sometimes have some
 advantages.

Well, you can also consider it dynamic. The important point is
that it is a constraint on allowed types e.g. in the sig of a sub
or on a variable. In my proposal they are handled through conversion
on class level.


 One way to implement at would be to use proxy objects, which only do
 one of the roles (by passing them through to the appropriate methods on the
 original object).

Do I understand you right that you propose to have a Dogwood class
and two auxiliary proxy classes for the Dog and Wood roles? Isn't that
too much effort? OTOH, a conversion routine could indeed return such
a proxy if the original shall be kept unchanged.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: role invocant slot in type sig (was: unusual invocants)

2009-10-26 Thread TSa (Thomas Sandlaß)
HaloO,

On Thursday, 22. October 2009 20:58:15 I wrote:
 The class Dogwood however might be written as

class Dogwood does Dog[Dogwood:] does Wood[Dogwood:]
{
method Dog {...}
method Wood {...}
method bark {...}
}

On #perl there was the question if any type could be put
into the brackets, e.g. 'class C does B[A:]'. But this is
a semantic error like using a role in an is clause or a
class in a does clause. However I see this as a weakness
of my proposal. So we could actually use 'class Dogwood
does Dog:self does Wood:self' as alternative. This is
hopefully closer to the point.


 where the explicit invocant type prevents the creation of the
 subclass relations between Dogwood and Dog and Wood. So in an
 environment which requests plain Dog a Dogwood instance is only
 applicable after the call of the coercion routine which could
 setup things so that Dog::bark is dispatched to. Environments
 that want Dogwood::bark need to explicitly coerce Dogwood instances
 to Dog[Dogwood:] which actually is a no-op. But then other non-Dogwood
 Dog doers are excluded unless they have a Dogwood coercion routine.
 Or they use the Dogwood class directly.

While pondering the consequences of my proposal it occurred to me
that the use of a juxtaposed type Dog Wood should not mean Dog[Dog:]
Wood[Wood:]. That is each with its role as invocant, because this
would force an ambiguous type conversion on Dogwood. So I change the
proposal such that a juxtaposition means Dog[::T:] Wood[T] which
nicely gives the Dogwood implementation of bark as requested by the
two roles.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


role invocant slot in type sig (was: unusual invocants)

2009-10-22 Thread TSa (Thomas Sandlaß)
HaloO,

On Thursday, 22. October 2009 18:31:16 I wrote:
 The invocant slot of the role signature is sort of implied in the spec
 already! I also like this because a type in Perl 6 is then always
 written as SomeRole[SomeClass:]. Classes without explicit roles are
 Any[SomeClass:] and untyped is Any[Object:]. Note that a class C doing
 multiple roles spawns several types R1[C:], R2[C:], etc and the class
 name is a short form of their juxtaposition.

Here is an improvement of the concept that also allows to settle the
Dogwood case in the Dogwood class. The change is that plain Foo does
not mean Foo[Object:] but denotes the F-bound fixpoint type Foo[Foo:].
A class Bar doing Foo still creates the type Foo[Bar:] but also enters
the subclass relation between Bar and Foo so that Foo[Bar:] : Foo[Foo:]
makes Bar instances applicable where Foo is required.

The class Dogwood however might be written as

   class Dogwood does Dog[Dogwood:] does Wood[Dogwood:]
   {
   method Dog {...}
   method Wood {...}
   method bark {...}
   }

where the explicit invocant type prevents the creation of the
subclass relations between Dogwood and Dog and Wood. So in an
environment which requests plain Dog a Dogwood instance is only
applicable after the call of the coercion routine which could
setup things so that Dog::bark is dispatched to. Environments
that want Dogwood::bark need to explicitly coerce Dogwood instances
to Dog[Dogwood:] which actually is a no-op. But then other non-Dogwood
Dog doers are excluded unless they have a Dogwood coercion routine.
Or they use the Dogwood class directly.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: unusual invocants

2009-10-21 Thread TSa (Thomas Sandlaß)
HaloO,

On Wednesday, 21. October 2009 12:40:06 Mark J. Reed wrote:
 Rather than disallow the composition, I'd say that any class, role, or
 object that does both roles must override the method in question.

The problem that Ovid posed needs to be resolved in the dispatch
tables seen in certain methods of a class. So the solution is not
overriding the offending method x but the calls to it in methods
foo and bar! The interesting thing is that you have to dig that
information out from the source of the roles T1 and T2. I doubt
that a programmer making the dependency mistake also documents it ;)
I've never seen a call graph of a library in any documentation.


 Which takes us back to Jon's branch of the thread: it would be nice to
 be able to declare such an override in a general way that will apply
 to any such composition that doesn't otherwise override it locally.
 But what should that declaration look like?

Here is a direct syntax for the freeze feature of the paper:

  class C does T1 does T2
  {
  freeze T1::x for foo;
  freeze T2::x for bar;
  method x {...} # for all other methods
  }

The implementation is strait forward: on entry to foo and bar
the dispatch table of the invocant is temporarily patched to
contain the right x. After the call the original is restored.

Heretic question: would it make sense to have a method registry
for roles in CPAN? At least for a set of 'standard' modules that
then allow arbitrary role combinations without conflict.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: unusual invocants

2009-10-20 Thread TSa (Thomas Sandlaß)
HaloO,

On Tuesday, 20. October 2009 18:35:36 David Green wrote:
  So what the OP wants to do is declare a method that is available on
  all those invocants - and only those invocatnts - which do all of
  roles X, Y, and Z.  Granted, you can declare a new role XandYandZ
  that does X, Y, and Z, and define the method there, but that won't
  work on $foo unless you declare explicitly  '$foo does
  XandYandZ' .  The goal is to have the method show up no matter how
  $foo comes to do all three roles.

 Right.

I have difficulty seeing the need for a method here. The distinguishing
feature of a method is the access to the private data of an object that
can hardly be granted by doing the three roles X, Y and Z. After all
there's no unique implementation of these roles!

Perl 6 is a hybrid language as far as dispatch is concerned. There is
the class based method dispatch that I call slot dispatch because the
usual implementation is to have the objects carry a ref to a slot table.
The other dispatch is the type based MMD. Unfortunately this also
goes by the name of method. This is because other languages use classes
as types and conflate the two dispatch regimes that Perl 6 clearly
separates. There used to be fail-over from class dispatch to MMD but
this didn't work---even though I forgot what the exact problems were ;)

So in the end the only problem is that the calling conventions of
$object.method versus method($object) are not interchangeable. But
it makes the priority clear. In the $object.method case the object
is the primary concept. We think of it as the object doing something.
In many cases to its own state. In the method($object) case the method
is the primary concept. The object influences how it is done or what
is the output. The method can of course call mutating methods on the
object but this is a secondary concern.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Freezing role methods

2009-10-14 Thread TSa (Thomas Sandlaß)
HaloO,

On Wednesday, 14. October 2009 12:18:30 Ovid wrote:
 You *could* (this wasn't explained in the paper) extract those
 methods into C::x(), check your callers and dispatch as appropriate, but
 that would get very problematic, particularly with roles composed of other
 roles.

I consider the dependence of T1 and T2 on their respective public
method implementation a design flaw of these methods. They should
each have a private service routine that in turn is called by the
public x method. But here is how this can be worked around in C:

  role T1
  {
 method foo { self.x }
 method x { say T1 }
  }
  role T2
  {
 method bar { self.x }
 method x { say T2 }
  }
  class C does T1 does T2
  {
 enum Source other from_foo from_bar
 has Source $!source = other;

 method foo { self!source = from_foo; T1::foo }
 method bar { self!source = from_bar; T2::bar }
 method x
 {
given self!source
{
   when from_foo { T1::x; self!source = other }
   when from_bar { T2::x; self!source = other }
   default { say C }
}
 }
   }

I admit that this is clumsy. So we need an automatic procedure
and some nice syntax. But it looks to me as code analysis of T1
and T2 is needed to generate the wrappers in C.

One point I don't like in the paper is that freezing methods
can be used to erase methods from a role. This is diametrically
opposed to the intent of roles to make a guaranty to provide
an interface.


Regards TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Synopsis 02: Range objects

2009-08-28 Thread TSa (Thomas Sandlaß)
On Thursday, 27. August 2009 23:58:51 Jon Lang wrote:
 It might also be nice to have a stringifying version; perhaps 'be',
 using the same everything's an acronym naming convention used by
 other stringifying operators (e.g., 'lt' is less than, 'le' is 'less
 than or equal to', 'leg' is less than, equal to, greater than) - in
 this case, 'be' would be 'beginning to end'.  At the very least, this
 would avoid the inevitable questions about why there isn't a
 stringifying version. :)  That said, it may not be good for much more
 than that.

Yeah, sometimes orthogonality of features is too much of a good thing!


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread TSa (Thomas Sandlaß)
HaloO,

On Friday, 27. March 2009 12:57:49 Daniel Ruoso wrote:
 1 - multi infix:+(Set $set, Num $a)
 This would return another set, with each value of $set summed with $a.

I think that this mixed case should numify the set to
the number of elements to comply with array semantics.
infix:+ should remain a numeric operator and numify
other operant types. This operator orientation is a
strong feature of Perl 6 and should not be diluted by
overloads with non-numeric meanings.


 2 - multi infix:+(Set $a, Set $b)
 This would return another set, with $a.values X+ $b.values, already
 removing duplicated values, as expected from a set.

Even the homogeneous case should adhere to numeric semantics.
Set operations are with parens. So disjoint union creation
is (+). We could try to get a meta parens so that (X+) is
conceivably auto-generated. OTOH it collides with (+) visually.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Logo considerations

2009-03-25 Thread TSa (Thomas Sandlaß)
On Tuesday, 24. March 2009 05:47:12 Darren Duncan wrote:
 If you're going for sciencey or mathey illustrations, then I think its
 important to include something that speaks quantum physics in there, since
 quantum superpositions aka Junctions are one of the big central user
 features that Perl 6 provides which is relatively new to languages in
 general.

The concept of superimposed shapes is very well done in the Trisquirclehedron.
See http://lucacardelli.name/Topics/TheoryOfObjects/ObjectSubject.html

Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: a junction or not

2009-03-18 Thread TSa (Thomas Sandlaß)
HaloO,

On Tuesday, 17. March 2009 10:25:27 David Green wrote:
  That is, it would return a Junction of Str, not a Str.  So the
  question is how to get something that returns an expression to the
  effect of:
  'any(' ~ $choice.eigenstates.«perl.join(',') ~ ')'

 say $choice.perl

 ...which will ultimately call (junction-of-.perl's).Str, and
 Str(Junction:) is what produces the any(XXX) string.  [Unless it
 ends up being implemented some other way, of course!]

Note that this contradicts Larry's statement that .perl
autothreads. I think it can't autothread because we expect
it to put the junction constructor in front of the values
or the right operator as infix. So .perl is junction aware!
But it threads the .perl method through the eigenstates,
of course.


  The other question is: given $choice as defined above, how do I find
  out which type of junction it is?

 I guess really Junctions need two public methods: .eigenstates for the
 values, and, er, .eigenop(?!) to return how they're joined -- I'm
 thinking it would return a code ref, i.e. any, all, etc.

A simple solution is to have subtypes of Junction like AnyJunction,
AllJunction, OneJunction and NoneJunction or perhaps like Junction::Any,
Junction::All, Junction::One and Junction::None.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Range and continuous intervals

2009-03-01 Thread TSa (Thomas Sandlaß)
On Friday, 27. February 2009 07:42:17 Darren Duncan wrote:
 I was thinking that Perl 6 ought to have a generic interval type that is
 conceptually like Range, in that it is defined using a pair of values of an
 ordered type and includes all the values between those, but unlike Range
 that type is not expected to have discrete consecutive values that can be
 iterated over.

Hmm, it might not be a bad idea to make Interval a subtype of Range
and allow for iteration if that is requested. This allows an Interval
where Range is expected.

The benefit of a dedicated Interval type comes from supporting set
operations (), (|) etc. which are still unmentioned in S03. BTW,
what does (1..^5).max return? I think it should be 4 because this
is the last value in the Range. Only in 4.7 ~~ 1..^5 does the five
matter. How does ~~ retrieve that information? For open intervals
the .min and .max methods should return the bound outside. Or better,
we should introduce infimum and supremum as .inf and .sup respectively.


 I'm thinking of a Range-alike that one could use with Rat|Num or Instant
 etc, and not just Int etc.  There would be operators to test membership of
 a value in the interval, and set-like operators to compare or combine
 intervals, such as is_inside, is_subset, is_overlap, union, intersection,
 etc.  Such an interval would be what you use for inexact matching and would
 be the result of a ± infix operator or % postfix operator.  Also, as Range
 has a .. constructor, this other type should have something.

Since the Interval type shall be an addition to the Set subsystem I
propose the (..) Interval creation operator together with the open
versions. Admittedly that leaves (^..^) at a lengthy six chars. But
Jon's proposal of setting the by to zero isn't any shorter. Note that
the open versions are more important for Interval than they are for Range
because for Range you can always write it without ^ at the ends.


 Barring a better name coming along, I suggest calling the type Interval,
 and it would be immutable.

The only other name that comes to mind is RangeSet. But I prefer Interval
because this is the name of the concept in math.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: min= (from Rakudo Built-ins Can Now Be Written In Perl 6)

2009-02-24 Thread TSa (Thomas Sandlaß)
On Tuesday, 24. February 2009 07:30:05 Carl Mäsak wrote:
     my $foo is limited(100..200);
     $foo = 5;                       # really does $foo = 100

 Sounds like a good idea for a CPAN module. You can already do
 something similar with the subset keyword, though:

  subset Percentage of Int where { 0 = $^perc = 100 };

  sub set_percentage(Percentage $perc is rw, Int $value) {
try {
  return $perc = $value;
  CATCH {
return $perc = 0 if $value  0;
return $perc = 100
  }
}
  };

  my Percentage $p;
  say set_percentage($p, 50);
  say set_percentage($p, 101)

I would use a parametric role to implement that:

   role Limited[Order ::Type, Order $lower, Order $upper]
   {
  multi sub infix:= (Limited $lhs is rw, Type $rhs -- Type)
  {
 if $rhs before $lower { $lhs.STORE($lower) }
 elsif $rhs after $upper { $lhs.STORE($upper) }
 else { $lhs.STORE($rhs) }
 return $rhs; # provide original for outer scope
  }
   }

   my Limited[Int,0,100] $p;

   $p = 50; # assigns 50
   $p = 101; # assigns 100

This is an interesting example of a role that can be instanciated
without a class unless one regards the generated multi target an
instance of a code class. I used STORE to avoid an infinite recursion
in dispatch of infix:=. I could also have called infix:=:(Type is rw,
Type -- Type) explicitly. This is necessary if it is overloaded as
well.

I'm unsure if parametric roles work like that, especially the use of
Limited inside the sub.

This role should be an easy candidate for inline expansion by the
compiler. Also the 'is rw' on the first parameter enforces an exact
match so there's no need for dynamic dispatch. I assume that an
'is rw' actually dispatches on the declared container type of the
lhs.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Comparing inexact values (was Re: Temporal changes)

2009-02-24 Thread TSa (Thomas Sandlaß)
On Tuesday, 24. February 2009 17:59:31 Larry Wall wrote:
 So it might be better as a (very tight?) operator, regardless of
 the spelling:

 $x ~~ $y within $epsilon

This is a pretty add-on to smartmatch but I still think
we are wasting a valueable slot in the smartmatch table
by making numeric $x ~~ $y simply mean $x == $y. What
is the benefit?


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: References to parts of declared packages

2009-02-13 Thread TSa (Thomas Sandlaß)
On Friday, 13. February 2009 20:30:24 Larry Wall wrote:
 While taking a shower I refined the design somewhat in my head,
 thinking about the ambiguities in package names when you're redefining.
 By my previous message, it's not clear whether the intent of

 multi package Foo::Bar {...}

 is to overload an existing package Foo::Bar in some namespace that
 we search for packages, or to be the prototype of a new Foo::Bar
 in the current package.  In the former case, we should complain if
 an existing name is not found, but in the latter case we shouldn't.
 So those cases must be differentiated.

Sorry, you lost me. I thought that classes are for implementation
and therefore need to allow re-definition in the sense of open classes.
But aren't packages/modules just for holding names? As such they always
make sure that there is exactly one entity in the scope with a unique
name?

So I would advocate a clear split between the functionality of packages
on the one hand and the implementation orientated classes, roles and
subs on the other. The latter have dispatch and overwriting, the former
are just for uniqueness of names. I know that the current design involves
dispatch to packages but I think that blurs the distinction between
packages and classes. If they are all the same anyway then why have the
module, package and class keywords? This is a bit too much redundancy for
me.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: returning one or several values from a routine

2009-01-06 Thread TSa (Thomas Sandlaß)
On Tuesday, 6. January 2009 22:01:36 Jon Lang wrote:
   item($x) # Dwimmey use of item context.

IIRC this is the same as $$x, right? Or does that
extract the invocant slot without dwimmery?

   list($x) # Dwimmey use of list context.
   hash($x) # Dwimmey use of hash context.
   $x._ # the Capture object's invocant, as an item.

How about $x.() here? That looks symmetric to the other
postfix operators and should be regarded as a method
dispatched on the invocant or some such.

   $x.[] # the Capture object's positional parameters, as a list.
   $x.{} # the Capture object's named parameters, as a hash.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: [svn:perl6-synopsis] r14585 - doc/trunk/design/syn

2008-10-05 Thread TSa (Thomas Sandlaß)
On Wednesday, 1. October 2008 21:54:12 [EMAIL PROTECTED] wrote:
  If you apply an assignment operator to a protoobject, it is assumed that
  you are implementing some kind of notional reduction to an accumulator
 -variable.  To that end, the base operator is dropped and a simple
 -assignment is done instead.  Hence you may correctly write:
 +variable.  To that end, the operation is defined in terms
 +of the corresponding reduction operator, where the protoobject
 +becomes the operator's identify value.  So if you say:
 +
 +$x -= 1;
 +
 +it is more or less equivalent to:
 +
 +$x = [-]() unless defined $x;# 0 for [-]()
 +$x = $x - 1;
 +
 +and $x ends up with -1 in it, as expected.

Can't we have that as a general feature of all operators?
That is:

   my ($x, $y);

   say $x * $y; # prints 1
   say $x + $y; # prints 0

It is a cleaver idea to make the operator choose an appropriate
value for a Nothing value. Why having that only for meta operators?


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Smooth numeric upgrades?

2008-10-05 Thread TSa (Thomas Sandlaß)
HaloO,

On Sunday, 5. October 2008 04:23:42 Darren Duncan wrote:
 Note that just as integers are naturally radix independent, the unlimited
 rationals should be too, and the latter can compactly represent all
 rationals as a triple of integers corresponding roughly to a (normalized)
 [mantissa, radix, exponent] triple; with that approach you also get 
 unlimited floats for free, so no reason to make floats an exception where
 they aren't unlimited where integers and other rationals are; after all,
 what is a float or scientific notation than just another notation for a
 rational value literal.

I want to stress this last point. We have the three types Int, Rat and Num.
What exactly is the purpose of Num? The IEEE formats will be handled
by num64 and the like. Is it just there for holding properties? Or does
it do some more advanced numeric stuff?

Another matter is how to represent irrationals. With IEEE floats which are
basically non-uniformly spaced integers imprecession is involved anyway.
But sqrt(2) is a ratio of two infinite integers. How is that handled? Here
I see a way for Num to shine as a type that also involves lazy approximations.
But then we need a way for the programmer to specify how these approximations
shall be handled. 


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: How to define a new value type?

2008-09-14 Thread TSa (Thomas Sandlaß)
On Sunday, 14. September 2008 16:08:19 Patrick R. Michaud wrote:
 So, how does one get an object to pretend to be a value type for
 purposes of assignment?

I think a straight forward approach is to overload the
assignment operator on the actual types of the lhs and
rhs. The dispatch target than clones the value to be stored
in the lhs container after being checked against the
container's constraint.

Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: What happened to err operator?

2008-09-07 Thread TSa (Thomas Sandlaß)
HaloO,

On Thursday, 4. September 2008 03:39:20 Larry Wall wrote:
 Another potential issue is that CATCH doesn't distinguish exceptions
 coming from the current block from those coming from the subcall to a().
 So it could end up returning Failure from the current block when
 you intended to force return of Failure from a().  Not sure what
 to do about that...

I don't understand this issue. I think we have the fact that
*every* operator is at least conceptually dispatched and as
such everything in a block is at least one level down in the
call chain just as a() as a sub call is. This is why a CATCH
block inside the block is so natural to me.

If I understand your intention correctly you want to be able
to force a thrown exception from a() into a returned value
and proceed where this return value is supposed to show up
in the current block, right? The simplest solution that comes
to my mind is some form of goto to that position. Or is that
too inelegant? The point is how the CATCH block knows from
which subordinate scope the exception originates.

   a() proceed: orelse b();
   CATCH
   {
  ... # make $! into return value
  goto proceed;
   }

This kind of needs to know the variable the return value of a()
is stored into. This is easy if orelse is checking $! anyway.
But does it? And is it possible to have labels in the middle
of a line as above?


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: arrayref/hashref in spectest suite

2008-08-20 Thread TSa (Thomas Sandlaß)
On Monday, 18. August 2008 20:38:05 Patrick R. Michaud wrote:
 I would somewhat expect
 a reference to be instead handled using a statement like

 $foo[1] := $bar;

 Comments and clarifications appreciated.

I would also opt for copy semantics whenever = is used
for assignment. But it seems to be the case that this
is not deep, just like captures are only one level deep
readonly. So, I would also expect $foo[1] = \$bar to
result in 24.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Some details of function return captures

2008-08-10 Thread TSa (Thomas Sandlaß)
HaloO,

On Saturday, 9. August 2008 01:32:35 John M. Dlugosz wrote:
 TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote:
  If such a ReturnCapture could also be
  preliminary of some kind, then lvalue subs could be lazily resumed when
  the rvalue comes in.

 Can you elaborate on that?  I don't follow.

The fundamental problem with lvalue methods is that some
of them want to have control *after* they returned
their value. One ugly way to achieve this is how it is
usually done in C++ or Java: the rvalue is a parameter
of the method. So instead of

$obj.foo(1,2) = 3; #1

one writes

$obj.foo(1,2,3); #2

which doesn't look like an lvalue method at all. And you can't
use it in rvalue context as the former:

my $x = $obj.foo(1,2); #3

Here the ReturnCapture collapses right away. But in #1 it could
be resumed with rvalue 3. That is the invocation of .foo(1,2)
resumes after the statement that produced the ReturnCapture.
In the assignable mutators thread I proposed to call that
statement 'yield'. To the function it behaves like the declaration
of a variable that receives the value that is assigned later.
To the outside it is the preliminary rvalue. If no assignment
takes place no resumption is made. The new thing here is that
one needs to write

my $x = |$obj.foo(1,2); #4

to keep the ReturnCapture, and call it later either explicitly

$x.resume(3);

or implicitly

$x = 3;


Hope that helps, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


meta_postfix:*

2008-07-13 Thread TSa (Thomas Sandlaß)
HaloO,

I know that the hot phase of the operator discussions are over.
But here's a little orthogonalizing idea from my side. The observation
is that * can be regarded as repeated addition: 5 * 3 == 5 + 5 + 5
and ** as repeated multiplication. Now imagine having a meta_postfix:*
that gives +* as multiplication (perhaps abbreviated as *) and ** as
(integer) exponentiation. We can then continue with replication as ~*
for strings and ,* for lists thus freeing x and xx as some generic
multiplication operators.

The meta * also is useful e.g. as (1,2) Z* 3 === (1,1,1),(2,2,2). Also
when we apply it to unary postfix as well: $x++* 3 === $x++.++.++ which
is useful when $x is of some class with overloaded ++ where the single
steps are important. The meta postfix * could also be stacked and tetration
falls out naturally as ***.

With + as the default case for meta_postfix:* we win the advantage that
we have +* and * as multiplication operators with the latter being a special
form of the former. But for Vectors +* would automatically yield the scalar
multiplication infix:+*:(Vector,Num) when infix:+:(Vector,Vector) is
defined as expected.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Rakudo test miscellanea

2008-06-29 Thread TSa (Thomas Sandlaß)
HaloO,

On Thursday, 26. June 2008 18:46:25 Larry Wall wrote:
 Neither is nor does is quite right here, because the mathematicians
 have seen fit to confuse representation semantics with value semantics.  :)

Hmm, but the uppercase types should hide the representation type.
IOW, there's only one Int but int8 to int64 or so. Same with Num
and num32 to num128 and perhaps num8 and num16 in the OpenGL world.


 I think what we want is something more like

 Int as Rat
 Rat as Num
 Num as Complex

So, how does this auto-coercion interact with dispatch? And
how do these in turn interact with generic function/type
instanciation?

I imagine a first round of dispatch then some well defined
second attempt after standard coercions. Note that there
might be coercion conflicts if several paths of conversion
are available. Then we need some concept of coercion distance
that favors more direct paths over longer ones and less lossy
ones over lossier ones. The tricky part then becomes the interaction
of coercion with dispatch. E.g. if there is an Int arg and two
dispatch targets for Rat and Num and two conversions Int as Rat
(lossless) and Int as Num (lossy?).  

OTOH, I regard Complex as a structural type like e.g. Vector
or Matrix that is built on top of other numeric types. That is we
have Complex[Int] as the Gaussian Integers and Complex[Rat] and
Complex[Num] in the same coercive relations as the underlying Rat
and Num.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: constraint imperative programming (CIP)

2008-06-16 Thread TSa (Thomas Sandlaß)
HaloO,

On Monday, 16. June 2008 10:03:13 Ovid wrote:
 --- TSa [EMAIL PROTECTED] wrote:
 ... why do you think that
  the way to get at the constraint programming paradigm are the subset
  type definitions?

 Because I can't think of any other way to do it :)

So I´ll try to come up with some creative thoughts =8()


 Now it's my turn to say that I can't follow that statement.

I hope the asymmetry in standard Perl 6 ´$x = $y´ is obvious.
By contrast in constraint programming (CP) ala Oz translated to Perl 6
we have

   $x = $y; # 1
   42 = $y; # 2
   say $x;  # 3 (prints 42)

where line 1 just stores the equality of $x and $y in the constraint
store and goes ahead. Line 2 binds 42 to $y directly and by constraint
solving to $x as well. That is what I call symmetric and which causes
fundamental troubles in implanting CP into imperative Perl 6. Thanks, btw
for the ref to the Kaleidoscope paper, it always amazing how many languages
I haven´t heard about ;)

Now we need a way to express constraint enforcement---called CIP in the
paper. My idea is that it naturally belongs to the variable subsystem. I.e.
we need declarations that declare constraints between variables. My first
attempt is simply

sub move_vertical_line (Line $line, Event $event)
{
   constrain $start := $line.start.x, $end := $line.end.x to
   {
  always $start == $end; # constraint
  SOLVE # enforcer
  {
  $end = $start; # normal assignment through bound vars
  }
   }
   my Event $motion;
   while ($motion = get_next_event()) ~~ ButtonMotion
   {
  $line.start.x = $motion.x; # $line.end.x is enforced
   }
   if $motion ~~ ButtonUp  # last event application
   {
  $line.start.x = $motion.x; # $line.end.x is enforced
   }
}

This is the value constraint from the paper. I would call the other
types almost as in the paper: identity, type and structure constraints.
A type constraint comes closest to the subset type constraints that
are not enforced and hopefully side-effect free. So a global definition
might look like

   constrain PosInt of Int to
   {
  always $_  0;
  SOLVE { $_ = 1 }
   }

   my PosInt $x;

   $x = -17; # invokes SOLVE block
   say $x; # prints 1
 
The SOLVE closure needs beefing up, like e.g. if you have more than
one constraint it has to topicalize the constraint somehow:

   constrain $x, $y, $z to
   {
   always $x + $y == $z;
   SOLVE
   {
  when $x changed { $y = $z - $x; }
  when $y changed { $x = $z - $y; } 
  when $z changed { $x = $Z / 2; } # calls first when
   }
   }


Comments?
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: fallback semantics of list methods

2008-06-16 Thread TSa (Thomas Sandlaß)
HaloO,

On Saturday, 14. June 2008 18:43:05 Daniel Ruoso wrote:
 Moritz convinced me that there's actually no real reason to support

   $nonlist.listmethod

I wouldn´t do that either. But I come to that conclusion from the
line of thought that it is generally a bad idea to block an Any
slot in a multi for a mere casting operation. The whole point of
type based dispatch is to name the intended type in the first place.
That is, a programmer choosing the item sigil $ in combination with
a list operation should be punished with a dispatch error if he doesn´t
know for sure that everything he sticks in the variable is a list
anyway. Note that the other way around is bloody easy in Perl 6. A
@ variable can handle items just fine!

I´m aware that this makes me opt for solution three, the dropping of
fallback from method to sub dispatch. But I consider that a good
thing. They are nicely distinct syntactically, so why mix them
semantically?


 And if we stop, and think for more two seconds, we realise that
 supporting that could end up having a lot of non-interesting side
 effects, because an exported sub with the signature :(Any, Str) is most
 likely to have a lot of false hits.

Technically there are no false hits on an Any slot ;)
In the case at hand it listifies the item and re-dispatches.
IOW, the false hits will be surprises for unaware programmers
who get unexpected dispatches silently.

BTW, there´s the same problem with stringification of the separator.
Combining that with  the listification would end up blocking *join:(Any,Any)
globally.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Complete type inferencing

2005-08-08 Thread TSa (Thomas Sandlaß)

HaloO,

Autrijus Tang wrote:

Yes, I'm aware of Theta's static where clauses, but Perl 6's where
clause is much more dynamic and almost always undecidable.


I know, but what does that buy the programmer? I see a type system
as support of a declarative programming style. Thus the dynamic part
of the type system, that is method dispatch and type instanciation,
has to play in a frame set by the programmer. This is very similar to
regular expressions and grammars. They declare the interpretation of
a string/stream of chars/data. The type system goes on from there to
watch over constraints while this data is processed.



In Litvinov's paper, where clauses are determinisitic at compile time,
as a way to encode structural subtyping (aka duck typing).


Huch, who has coined 'duck typing'? I never heard that before.



The important difference is that the .can() call in Perl 6 would be a
runtime call.  It has to be that way, because .can is not a special
form; it's just a normal method returning a boolean.  If you really
want static treatment, that needs a special form:

sub foo (
$obj can bar:(() returns Int)
) returns Int {
$obj.bar();
}

It will allow constructs such as this:

my subtype Duck
has $.half_life
can doom:()
can quake:(() returns Wolfenstein);


Yes, I like that. I also proposed an object special form for
classless instances in namespace.


# Automagically satisfied iff $obj's interface is compatible
$obj.does(Duck);

Such implicitly-declared Roles is certainly powerful, and we can apply
the same inferencing treatment as for nominal subtyping violations --
fatal error under closed/finalized, raise warning by default.

I think it's cute, and adds real power of row polymorphism to the


What is 'row polymorphism'?


language, iff Perl 6 indeed adopts a compile-time inferencing engine.  


I would call it a bit different, but yes please! My idea is, that the
programmer of Perl 6 can 'store' a lot of information in name/type space
that is later---even at runtime---used by the code generation, class
composition, type instanciation and dispatch system without forcing the
programmer to rummage in the guts, which might actually be very difficult
to do platform independently if not even Parrot is fixed as the underlying
VM!

BTW, is 'special form' a fixed term? I just started using it to decribe
things like sub, class, role, etc. declarations/definitions.
--
$TSa.greeting := HaloO; # mind the echo!


Re: Do slurpy parameters auto-flatten arrays?

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Luke Palmer wrote:

On 8/3/05, Aankhen [EMAIL PROTECTED] wrote:


On 8/3/05, Piers Cawley [EMAIL PROTECTED] wrote:


So how *do* I pass an unflattened array to a function with a slurpy parameter?


Good question.  I would have thought that one of the major gains from
turning arrays and hashes into references in scalar context is the
ability to specify an unflattened array or a hash in a sub call
without any special syntax...


I thought that the obsoletion of special syntax stems from the
type system. Piers seems to have the same view. See his example
of map in his parallel reply.



Well, you can, usually.  This is particularly in the flattening
context.  In most cases, for instance:

sub foo ($a, $b) { say $a }
my @a = (1,2,3);
foo(@a, 3);

Passes the array into $a.  If nothing flattened by default, then you'd
have to say, for example:

map {...} [EMAIL PROTECTED];

And even:

for [EMAIL PROTECTED] - $x {...}

Which I'm not sure people want.  


Ups, I thought the for special form would work as follows.

0. the syntax: for expression block
1. determine (return) type of expression
2. create an iterator for that type
3. Use the iterator until it runs out (is that when it returns undef?)
4. bind the block owner to successive return values of the iterator
   and call the block; if the block is pointy bind its environment as
   well.

With the above

  for @a - $x {...}  # use Iterator of Array

and

  for [EMAIL PROTECTED] - $x {...}  # use Iterator of List

produc the same sequence of values in $x but through different
paths in type space. As long as no user defined types are involved,
I dought they are distinguishable at all.

Here's an idea how a sub becomes its own iterator:

   sub foo() does Iterator[foo]
   {
   random;
   }

   for foo() - $x { say }   # endless loop of random output

How are roles/types composed into Code subtypes?



And the way you pass an array in slurpy context as a single reference
is to backwhack it.  What it comes down to is that either you're
backwhacking things a lot or you're flattening things a lot.  Perl
currently solves it by making the common case the default in each
zone of parameters.


I would be interested to hear arguments to the contrary, however. 


OK, I gave my 0.02.
--
$TSa.greeting := HaloO; # mind the echo!


Re: zip with ()

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Luke Palmer wrote:

On 8/1/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:


In general, (@foo, @bar) returns a new list with the element joined,
i.e. @foo.concat(@bar). If you want to create a list with two sublists,
you've to use ([EMAIL PROTECTED], [EMAIL PROTECTED]) or ([EMAIL PROTECTED], 
[EMAIL PROTECTED]). But of course, I could
be totally wrong. :)



I think that's right.  However, it might be a good idea not to
auto-enreference such bare lists:


I don't like this notion of auto enreference/dereference at all.
Either the type system manages to dispatch things correctly or
you get an error. For the List versus Array problem this dispatch
is IMHO decideable at compile time by strictly typing @ vars as
Array and subtypes thereof. The List type to me is a Code subtype
and as such travels in  vars. I'm only unsure how easily such
variables should enter name space, that is how they behave without
sigil.


sub foo ($x) {...}
foo (1,2,3,4,5);   # foo gets called with [1,2,3,4,5]


Yes, the $x makes foo an Item or even Value taker of arity 1.
The call foo (1,2,3,4,5) OTOH calls it with a List. This should
result in a type error. But sub foo (x) might then work for a List
but not for an Item|Value call foo(1).

Since I think that * in a signature is for extending the arity of
the sub to infinity I wonder if it is possible to capture the caller's
list into a single *$arg?

   sub foo (*$x) {...}
   foo (1,2,3,4,5); # type of $x is now Ref of List of Int?

But with an additional array the slurpy item gets at most one value.

   sub foo (*$x, [EMAIL PROTECTED]) {...}
   foo (1,2,3,4,5); # $x == 1; [EMAIL PROTECTED] == 4
   foo @array; # type of $x is now Ref of Array; @a is undef



When you could just as easily have said:

foo [1,2,3,4,5];

And we'll probably catch a lot of Perl 5 switchers that way.  That
actually makes a lot of sense to me.  The statement:

my $x = (1,2,3,4,5);

Looks like an error more than anything else.


Yep. I opt for type error Can't assign List to Item.
By the same token I would disallow

  my @a = 3; # type error Can't assign Item to Array.

It should be

  my @a = *3;

or

  my @a = (3,);

Hmm, wasn't there a nullary *?

  my @a = *;
  say [EMAIL PROTECTED];  # prints 0



 That's the scalar
comma, which has been specified to return a list.  But maybe it
should be an error.


Sorry, I don't understand this.  I thought comma just is *the*
List constructor per se. Parens required to lift precedence :)
Same applies to semi-colon. (1,2,3;4,5,6) is a List of List of Int.



 The main reason that we've kept a scalar comma is
for:

loop (my $x = 0, my $y = 0; $x*$y = 16; $x++, $y++)
{...}

However, I think we can afford to hack around that.  Make the first
and last arguments to loop take lists and just throw them away.


My interpretation of the loop block controler special form is that
it gets a 4-tupel (Block,Block,Block,Block). The last one is of course
the loop's body. The first is the initializer that is executed in a
scope outside the body. The second and third are the condition and
the stepper and also scoped outside the body.

Now to the comma. It should be parsed as List of Block. In your example
the argument type of loop is (List of Block,Block,List of Block,Block).
The loop instanciates an Iterator[List of Block] and uses it to
execute the Blocks one at a time. The only special case is in the
condition which evaluates only the last Block from the List of Block
for truth and the others in Void context.

Is loop supposed to be a topicalizer? Does it bind the block owner?
Does a pointy body block make sense?

   loop (my $x = 0; $x  10; $x++) - {...}  # current count in $_?
   loop (my $x = 0; $x  10; $x++){...}  # $_ unchanged from outside?

   loop (my $x = 0; $x  10; $x++)
   {
   .blubber   # what is the invocant?
   }

Can the last Block also be separated with semi-colon? I guess not.
How about a Code var?

  loop my $x = 0; $x  10; $x++; say $x;  # works?

  loop my $x = 0; $x  10; $x++; foo; # works?

  loop( my $x = 0; $x  10; $x++; foo ) # perhaps as function call?

  loop
 my $x = 0;
 $x  10;
 $x++;

  say $x; # still the loop body? Or does it need { say $x }?

  loop foo; bar; blubb -
  {
  say  # prints return value of blubb while bar returns true
   # first iteration prints return value of foo
  }


 Can
anyone think of any other common uses of the scalar comma?


Not me. It's a C relict.
--
$TSa.greeting := HaloO; # mind the echo!


Re: Do slurpy parameters auto-flatten arrays?

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

Piers Cawley wrote:

By the way, if flattening that way, what's the prototype for zip? We can after
all do:

   zip @ary1, @ary2, @ary3, ... @aryn


How about

   sub zip( List [EMAIL PROTECTED] ) {...}

a slurpy List of Array of List. The return value is a
not yet iterated Code object that knows how to produce
tuples from the outer lists. This implies that zip(@array)
basically returns an unstarted iterator on @array.
--
$TSa.greeting := HaloO; # mind the echo!


TSa's Perl 6 type lattice version 1.0

2005-08-04 Thread TSa (Thomas Sandlaß)

HaloO,

in case someone might be interested, here is my more or less complete
idea of the Perl 6 type lattice as ASCII art.

Enjoy. Comments welcome.


::Any
...| ...
   ___:___/|\:_:
  |   :| :  |  |   static type :
   Package:| : Void  ?Bool   = context :
  |   :| :__|__|   :
Module:|/:.:
   ___|___:|
  |   |   :|
Class Grammar :|
  |___|   :|
  |   :|
 Role : Object Record =::= Frame =::= Dictionary
  :|
  : __/ \_
  with:|  || ||   |
  invocant(s) :  Code  $Item%Hash Frame@Array Tuple
  :|  ||_||___|
  block owner : topic  |  |   |
   $/ : $_ |  |   |
  :___/ \_ ___|   |
 |:  |\   |   ||  | |  |  |
  .Method : Sub\  -Block   \Ref Value  Undef  Inf  Junction  |
/|:  |\ \ ||  |
   / |:  | \ \  __||_ |
Rule |:  | Macro  \/  ||   |   | ||
 |:_/|Ref[Code]   |  :Pair  /Match/  ~Str  +Num   |
 |:  |||   | ||
   Multi  :  |||   |Int   |
..:  |||   |   / ||
 ||___  ___|   Enum  ||
 ||   \/ |   ||
 ||  Entry[::T.does(Hash)]  Bit  ||
_|__  |___  _||
   || |   \/  |
   =Iterator  *List   |  Pos[::T.does(Str|Array)] |
| |   |
|_   _|___|
   |  | ||\ / |
..Range  Pipe  Lazy  **Eager  Ref[Array|Hash] |
   |__|_||   _|
  \ /
   (to | all leafes)
  \|/
::All
--
$TSa.greeting := HaloO; # mind the echo!


Re: Eliminating {} and *{}

2005-08-03 Thread TSa (Thomas Sandlaß)

HaloO,

Autrijus Tang wrote:

All this led us to think about whether (my foo) can be merely treated
the same as (my Code $foo).  The mutable form will enable convenient
notations such as:


I think (my Code $foo) should be an error on the same reason as
(my Array $foo) is an error. A $var can only contain explicit
Ref types like (my Ref of Array $foo) or (my Ref of Code $foo).

But the following should be allowed

  my pi = 3.14;

  if $num == pi {...}



foo = sub { ... };

So instead of having to explain to newcomers that you cannot assign
to a -sigil symbol, it would all just work.  Under this view, {$x}
would be eliminated with *{}.


I think *{1,2,3} is valid syntax which means listify the code literal.
But it's no special form. In particular * {1,2,3} is the same because
* is a normal prefix op.



Another idea is to treat (my foo) the same way (my Code $foo is constant).
That will discourage people into assigning into functions, and enable
the compiler to detect function variables at lvalue position as errors,
but on the whole I don't think it's worth the complexity.

Does this make sense?


Yes. I think of the (fantastic) four sigils as referential expressions
that are somehow bound to 'real' data. When and how that binding takes
place is another matter. But in particular I like my idea that the 
corresponding dot twigils are firstly applicable only in methods and

are secondly then bound through the invocant. E.g. .action calls the
action slot of the current invocant---method level block owner aka
$?SELF. This is basically the vtbl dispatch. Note that . slots are
auto-generated accessor methods if not explicitly given by the class
implementor. A method special form is *not* a slot method by a 'free'
method specialized on the surrounding class.

PS: could someone give a summary which sigil forms are still in effect.
E.g. ${}, $(), etc.
--
$TSa.greeting := HaloO; # mind the echo!


Re: [S29] Mutating map and grep

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Ingo Blechschmidt wrote:
Is this a bug in S29 or will this be feature removed from Perl 6 
and you'll have to say (for example) 
 
  use listops :mutating; 
  my @result = map { $_++; 42 } @array;  # works now 


Why not just

my @result = map - $_ is rw { $_++; 42 } @array;  # works now

which could be abbreviated as

my @result = map:rw { $_++; 42 } @array;  # works now

And as usual the :rw binding needs the confirmation of @array.

BTW, would the following be parseable in an extreme interpretation of
optionality of block owner and block topic:

   my @result = map:rw{ .++; 42 } @array; # ++ as method on owner
   my @result = map:rw - {  ++; 42 } @array; # ++ as sub with topic
   my @result = map:rw - { .++; 42 } @array; # both:  $/.++($_)
--
$TSa.greeting := HaloO; # mind the echo!


Re: zip with ()

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Andrew Shitov wrote:

Is it possible to avoid significance of whitespaces?


Yes, with:

  say zip .(@odd, @even);

Looks like a method and *is* a method in my eyes.
First zip is looked-up and then bound as block owner.
Arguments are of course two array refs to @odd and @even
respectively.

BTW, you didn't mean originally:

  say zip (@odd), (@even); # prints 13572468 or 12345678?

Does zip now interleave two array refs instead
of flattened arrays?


I think, such an aspect of Perl 6 would be awful.



IB Whitespace is significant:

IB say zip(@odd, @even);
IB say zip (@odd, @even);

--
$TSa.greeting := HaloO; # mind the echo!


Re: zip with ()

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Ingo Blechschmidt wrote:

Whitespace is significant:

say zip @odd, @even;# zip gets two arguments, result is
# 12345678.
say zip(@odd, @even);   # zip gets two arguments, result is
# 12345678.
say zip (@odd, @even);  # zip gets only one argument, the flattened
# list (@odd, @even), containing the


Why flattened? Shouldn't that be *(@odd, @even)?



# elements (1,3,5,7,2,4,6,8). Then zip


Why not ([1,3,5,7],[2,4,6,8]) list of two array refs?

# tries to zip this one list, resulting in 
# 13572468.


If the list of two array refs is not flattened, the result should be
12345678 because how should zip distinguish it from the other cases?

The crux of the first case not requiring parens is that zip is declared
as listop and as such consumes the @even after the , which otherwise would
be left for say. And if say weren't declared/assumed listop, the @even
would be evaluated in Void context and not appear in the print at all.

Or do I miss something important? E.g. has () become a circumfix deref op?
--
$TSa.greeting := HaloO; # mind the echo!


Re: zip with ()

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Andrew Shitov wrote:

TTS BTW, you didn't mean originally:

TTSsay zip (@odd), (@even); # prints 13572468 or 12345678?

That is exactly like with similar printing result of sub() call:

 print sqrt (16), 5; # shout print 45.


That all hinges on the type of the symbol. I guess sqrt
is a unary prefix. Then

   print sqrt 16, 5; # should print 45 as well.

The point is, to not let sqrt 'swallow' the 5 unless
it is declared listop.
--
$TSa.greeting := HaloO; # mind the echo!


Re: sub foo ($x) returns ref($x)

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Autrijus Tang wrote:

[..] For example, assuming argument types are unified in a single
phase, the example below does nothing useful:

sub equitype ((::a) $x, (::a) $y) { ... }

It won't not help even if we replace the implicit does with of:

sub equitype ($x of (::a), $y of (::a)) { ... }

The reason, in Luke Palmer's words:

The trouble with this is that it doesn't provide any type safety.
 In the case of a type conflict, a just degenerates to the Any type.
 (cf. pugs/docs/notes/recursive_polymorphism_and_type)


Luke's analysis is indeed correct. And describes what can be inferred
from the caller side. And I wouldn't introduce the subtlety that the
first ::a is bound to the exact type of $x in the call environment, while
the second is a constraint on $y's type. But I would prescribe exactly
this as the meaning if you use plain 'a' as the type of $y. Thus I opt
for:

   sub equitype ( ::a $x, a $y) { ... }

which is the same behaviour as for the value of $x which can be used
immediately for subsequent parameter bindings. Hmm, how do coderefs behave
in that respect?

   sub codeparam ( foo, ?$val = foo ) {...}

Does this invoke a bar argument once for the call codeparam( bar )
and capture the result in $codeparam::val while the call
codeparam( bar, 42 ) stores 42 without invoking bar through
codeparam::foo? And in which exact environment does a call to
bar take place when needed to bind $val? Purely ::CALLER? Signature
as bound so far? ::OUTER of the use'er of the package which contains
codeparam? Or the ::OUTER of the 'real' package file?

The other remark I have for the form with double ::a is that there's
also an inside view of that type. All type information inferred can
be stored as constraints on ::equitype::a in the ::equitype Code class.
Interesting is how the syntax for a more explicit form reads:

   sub equitype( ::a $x, ::a $y ) where { a.does(SomeRole) }
   {...}


This fact, coupled with the unappealing (::a) syntax,


I like the syntax. BTW, does it have to have parens?
I would actually promote :: to a very fundamental operator/token.
Even if that costs some parens for the ternary ( ?? :: ).


leads me to look
for a more Perlish representation.  Adopting an idea from Odersky's
Nested Types paper, we can let terms occur at type variant position,
by introducing a ref form for types:

sub equitype ($x, $y of ref($x)) { ... }
sub subtype  ($x, $y does ref($x)) { ... }
sub identity ($x) returns ref($x) { ... }


Uhh, please make that sig read ($x, type($x) $y) or at least
($x, $y.does($x.type) or something else with 'type' in it.
Ref is way to overloaded with meanings in Perl6 which are not
easy to unify away because of mismatches on the levels of
abstraction involved. E.g. the sub identity looks like an
alias for \ which it isn't from the type perspective.



This reads like Perl, and can be guarded with trivial compile time
and runtime checks.  We can also use type selectors to check
that pick can always return Int from an Array[of = Int]:

sub pick (@x) returns ref(@x).of { ... }

The only problem I can find is that the possible confusion between the
ref() operator and the unboxed basic type ref.  Another thought is to
simply use ::() as a special ref form:

sub pick (@x) returns ::(@x).of { ... }

But that can confuse with the symbolic dereference syntax.  All in all


Uhh, could we agree to call ::(symbolic) the symbolic lookup form and
::bareword the bareword, pre-runtime lookup form?
Let's not add another referencial thing to the 'Many Refs of Perl6'.
In the end we'll need a dedicated reference manual :)
I guess it would be S08.

Since I opt for ::pick beeing the innermost namespace immediately
after its introduction with 'sub pick' ::x could refer to @x from
the signature. Note that if there are x, $x, @x and %x in the
signature a simple ::x is typed as their supertype Object.
Disambiguation would go as ::x::Code, ::x::Item, ::x::Array and
::x::Hash respectively. And of course you can further descent into
these namespaces as in pick::x::Array::of. Descending along multiple
pathes essentially means any'ing the types together ::x::*::of.
Well, in some namespaces things are all'ed together :)
The supertype of all array entries is of course pick::x::Array::values::*
and single items show up numerically under pick::x::Array::values::
e.g. pick::x::Array::values::8. Note that this is *not* a symbolic
form but well defined. It might evaluate to undef though.

Finally the .of method might just be syntactic sugar for the above:

   sub pick( @x ) returns @x.of {...}

or just

   sub pick( @x ) returns x.of {...}

or

   sub pick( @x ) returns x::of {...}


I'm more happy with ref(), but better suggestions welcome.


I suggest type(), tie() or soul()---the latter is from
'.bless() my .soul()'---if none of the above pleases @Larry.
--
$TSa.greeting := HaloO; # mind the echo!


Re: sub foo ($x) returns ref($x)

2005-08-01 Thread TSa (Thomas Sandlaß)

HaloO,

Autrijus Tang wrote:

On Mon, Aug 01, 2005 at 03:16:50PM +0200, TSa (Thomas Sandla�) wrote:


  sub equitype ( ::a $x, a $y) { ... }



That's not a bad idea at all.  I rather like it.  I'd just still like an
explicit type-unifying parens around ::a, just so people won't say


I try to maintain the 'parens only group' point of view. But it
seems to be violated elsewhere, too.



sub foo (::Int $x) { ... }

and accidentally rebind Int.


Why so shy? It would rebind foo::Int with respect to the inside
of foo. Of course the funny effect is that for a call foo( blahh )
foo::Int means Str :)

I guess this is why $Larry wants a role wrapped around such type parameter
instanciators:

  role Foo[::Int] # hides *Int
  {
 sub foo (Int $x) { ... }
  }

and explicit instanciation

  use Foo[Int]; # or some such
  use Foo[Str];
  use Foo[Num];

But I don't know if he also wants to carry that on to the actual calls:

  Foo[Int]::foo(42);
  Foo[Str]::foo('42');
  Foo[Num]::foo(3.14);

OTOH, one has to use *::Int or *Int to surely get the standard Int,
anyway. And for getting guaranteed type locality inside foo a

  sub foo( MY::Int $x ) {...}

might be needed, too. This nicely fits other pseudo namespaces:

  sub foo(  Int $x ) {...}  # whatever Int is in effect
# at compile time
  sub foo(::Int $x ) {...}  # deferred lookup to CHECK time
  sub foo(  MY::Int $x ) {...}  # dynamically from $x
  sub foo( foo::Int $x ) {...}  # same for all invocations? error?
  sub foo( OUR::Int $x ) {...}  # from package

How usefull OUTER::, CALLER::, etc. are I have no idea. Perhaps it's
a good idea to reserve single capital letter barewords for type params.
Or a twigil if we think of '::' beeing s sigil:

  sub foo( ::^a $x ) {...}

This saves one character compared to your (::a) which is the
same length as MY::a.
--
$TSa.greeting := HaloO; # mind the echo!



Re: Slurpy is rw arrays ([EMAIL PROTECTED] is rw)

2005-07-29 Thread TSa (Thomas Sandlaß)

HaloO,

Adriano Ferreira wrote:

Only

sub foobar (@args) { push @args, 42 }

would change @some_array in

foobar @some_array;

That is how I undestood that. Can someone confirm this belief?


I share your belief. It's up to others to confirm it. I just
want to add that I further believe that the push call is dispatched
on the type of the array and only succeeds if @array.does(Pushable).
I guess a default array does this or another role that implies it.
--
$TSa.greeting := HaloO; # mind the echo!


Re: Elimination of Item|Pair and Any|Junction

2005-07-28 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

On Wed, Jul 27, 2005 at 06:28:22PM +0200, TSa (Thomas Sandlaß) wrote:
: Since we are in type hierachies these days, here's my from ::Any
: towards ::All version.

That's pretty, but if you don't move Junction upward, you haven't
really addressed the question Autrijus is asking.  We're looking
for a simple type name that means none(Junction) for use as the
default type of the $x parameter to - $x {...}.  Whatever we call
it, this type/class/role/subtype has to admit Item and Pair objects
but not Junctions.  (And if that's the wrong way to think about it,
please tell us why.)


Sorry, here's the patch:

  :   Code @Array   %Hash $Item
  : | // |
  with: |   TupleRecord  |
  invocant(s) : ||
  :/ \__  ___|_
 |:  | |\|| |  |
  .Method : Sub  Block   |Value  Inf  Undef  Junction
/|:  |\  |   |
   / |:  | \Ref[Code]|
   Rule  |:  |  Macro|
 |:_/|__/|\___
 |:  |   | | | |  |
   Multi  :  | ~Str  +Num  \Ref  :Pair  /Match/

Now the Junction is nicely constraint with the upper bound Item (less 
specific) and a lower bound Value (more specific). This also reads

nice if you want to (explicitly) allow both:

 sub ( Value|Junction $val_junc )

What sub ( $any ) should default to, I don't know. My $Item indicates
Item, but could also be $Value. Or unspecific $(Item|Value).
--
$TSa.greeting := HaloO; # mind the echo!



Re: Inferring (Foo of Int).does(Foo of Any)

2005-07-28 Thread TSa (Thomas Sandlaß)

HaloO,

Autrijus Tang wrote:
[..much better explaination of the co/contra prob then mine skipped..]

Hence, my proposal is that Perl 6's generics should infer its variancy,
based on the signature of its methods, and derive subtyping relationships
accordingly.


Yes!! That would be great. But I would restrict it to the onboard methods
or however we call them. Outside/free methods specialized on the generic
type are firstly referential in nature, and as such bind their $.attr,
@.array, %.hash and .code referential expressions through the invocant.
They form a mediator layer between unrelated code and the code
implementing the type's guts.



The other alternative is do as Java does, which is assume invariancy by
default, then force users to write variancy annotations, but I think
that is considerably less attractive.  There may be a case for inferring
by default, but overridable by the user; if so there needs to be a
syntax for that.


Well, that pivots around how refs behave. I would opt for them beeing
const unless explicitly allowed :rw by the instance owner. Is the syntax
for that actually \$x:rw? Or even plain \$x if we assume that every sigil
expression *always* means implicit const ref? And thus needs a
dereferencer, e.g. $x()? Then

   $x  = $y; # means dispatch to op =
   $x := $y; # same, but op := requires $x to be writeable
  \$x  = $y; # same as := ?  I prefer \$x:rw which might fail
 #   depending on where $x refs to
  \$x := $y; # ???

Consider

   $x = [EMAIL PROTECTED]; # assume there's no slot 42, then the array could
 # hand-out a \.[42]:rw and allow subsequent
 # assignment
   # but

   $x = [EMAIL PROTECTED]; # assume .[23] is filled, then the array returns
 # a const ref

Such an array would be typed Array of ::T^Ref:rw[Undef of ::T]
and as such a hot candidate for the default array :)
--
$TSa.greeting := HaloO; # mind the echo!


Re: Messing with the type heirarchy

2005-07-28 Thread TSa (Thomas Sandlaß)

HaloO Michele,

you wrote:

On Wed, 27 Jul 2005, [ISO-8859-1] TSa wrote:


value to carry on a useless imaginary part. And
Complex should consistently return undef when compared
to other Nums or Complexes. And the Compare role



My 0.02+0.01i: in mathematics it is commonly used to write e.g. z3 to 
mean z is real AND as a real number is less than 3.


Which in Perl6 is written as

   Complex where { .imaginary =:= 0|Undef } does Num;

somewhere in the Complex package. This would make your
intensions possible by dispatching to infix:{''}:(Num,Num)
but still preventing the general case.
--
$TSa.greeting := HaloO; # mind the echo!


Re: The meaning of returns

2005-07-28 Thread TSa (Thomas Sandlaß)

HaloO Autrijus,

you wrote:

 D) Make the return type observe both #2 and #3 at compile time,
using type variables:

   sub id ( (::T) $x ) returns ::T { return($x) }



And this is a natural extension to guide the inferencer so it won't be
totally giving up on polymorphic functions such as id.  C) and D) can
be taken together, resulting to a powerful soft typed language.


This is my preference. The only known issue with parametric typing is
the proliferation of params as soon as you want to stay away from
unpecificity.



However, if we take the view that type annotation are merely storage
allocation hints and runtime coercers, then A) is probably the way to go.


Please no. Or at least not exclusively. I see your storage allocation
hints as a data environment needed to implement the type.
--
$TSa.greeting := HaloO; # mind the echo!


Re: Do slurpy parameters auto-flatten arrays?

2005-07-27 Thread TSa (Thomas Sandlaß)

Ingo Blechschmidt wrote:

Hi,


ReHi,



are the following assumptions correct?


I don't know in general. But see my assumptions below
for comparison. They are derived from my type theoretic
approach and as such might collide with Perl6's referential
semantics. In particular with the auto-ref/deref and how
far it follows links.



  sub foo ([EMAIL PROTECTED]) { @args[0] }

  say ~foo(a, b, c); # a


foo( List of Str )


  my @array = a b c d;
  say ~foo(@array);# a b c d (or a?)


foo( Ref of Array )  # @args[0] derefs the array ref
 # I guess you need @args[0][0] to get a

But I don't like this level of reference preservation.
E.g. one then needs to know how far out the flat array
resides, to use the right number of dereferencers. Here
type theory doesn't constrain the definitional freedom
because both interpretations are compatible with [EMAIL PROTECTED]

Actually that unspecificity could be preserved, see below.



  say ~foo(@array, z);   # a b c d (or a?)


foo( Ref of Array, Str )  # @args[0] as above

Here typing constrains the interpretation to be the
one that needs @args[0][0] to get at a. This is slightly
untrue. The problem is actually shifted to the question:
How does comma handle a Ref of Array?.



  say ~foo([EMAIL PROTECTED]);   # a


foo( List of Str build from Array of Str)



  say ~foo(*(@array, z));# a
 


  sub bar ([EMAIL PROTECTED]) { [EMAIL PROTECTED] }

  say bar(1,2,3);  # 3
  say bar(@array); # 1 (or 4?)


Type theory actually should come up with any(1|4) :)
And yes, any(1|4) is a type literal and any($x,$y)
is a parametric type which is fixed whenever $x and
$y are.

Side node: A nice test for hidden assumptions in
code is to replace functions which return Any to
behave randomly.

A Vogon optimizer OTOH, might blow away a complete
planet and return 42 everywhere :)

For this very reason the default signature of the
ideal sub is of course ::Any -- ::All where All is
pure specificity. And---even thow I should start a
'type theory foundations of Perl6' thread, I mention it
here---the ideal method is

  ::All . ::Any -- ::All

A multi sub/method is in that view a *metric* dispatcher
on the middle ::Any between the selector before the dot
and the return type after the arrow.



  say bar(@array, z);# 2 (or 5?)


I opt for 2.


  say bar([EMAIL PROTECTED]);# 4


Yep.
--
TSa (Thomas Sandlaß)




block owner, topic and the referential environment

2005-07-27 Thread TSa (Thomas Sandlaß)

This is another spin-off from the 'Exposing the Garbage Collector'
thread. Here is an enhanced version.

I wonder how the generic, lexically scoped invocant/owner is called.
I propose to call it $/ (other option is to call it $)and let the
former topicalizer become block owners and $_ the block topic that flows
into blocks from further outside if not explicitly bound with - like:

   $topic := Some.new;
   $_ := $topic;
   for @objects { .action } # call on $/ from @objects with $_ := $topic
# in all loops

   @objects».action;  # same for single action syntax


   # but
   for @objects - { .action } # means $/.action($/) because
   # $_ bound to dynamic block owner;
   # but usefull for methods that don't
   # use the topic, in particular accessors
   # and mutators
   # same as sub call
   for @objects - { action }  # means action($/) because $_ := $/
   # but $/ is there if action is of
   # type Method

   # but the $. @. %. and . are bound through $?SELF
   # in particular
   for @objects - { .action } # subref curried on invocant

This implies that a .action means name lookup of 'action' while
.action is an onboard method of $?SELF. This latter case is
typically implemented with a vtbl lookup.

The only drawback I see is, that the careless method programmer could be
caugth in an endless .action loop if .action invokes .action explicitly
on $_ where $_ := $/ from the outside. The same endless loop could of
course be achieved with a free standing .action but that looks more like
intention.

With the lurking pitfalls an occasional check of $_ =:= $?SELF and
$/ =:= $_ seems advisable and indicates that the invocant wasn't
exchanged midway :)

Same with other block topicalizers/owners

  given $x{...}  # topic untouched, but $/ := $x
  given $x - {...}  # $_ := $x as well

But

  if $x{...}   # $/ and $_ untouched
  if $x - {...}   # $_ := $x (non boolean value)

One more interessting thing is that in exception handlers all three
variables $!, $/ and $_ are in scope. This might allow to resume where
the exception occurred after the cause was fixed e.g. by loading or
generating some code, some revamping or other DEEP_MAGIC. Hmm, debug
exceptions come to mind...
--
TSa (Thomas Sandlaß)




Re: Exposing the Garbage Collector (Iterating the live set)

2005-07-27 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

On 7/26/05, TSa (Thomas Sandlaß) [EMAIL PROTECTED] wrote:


Piers Cawley wrote:


I would like to be able to iterate over all the
objects in the live set.


My Idea actually is to embedd that into the namespace syntax.
The idea is that of looking up non-negativ integer literals
with 0 beeing the namespace owner.

  for ::Namespace - $instance
  {
 if +$instance != 0 { reconfigure $instance }
  }



Oh, so a namespace can behave as an array then.  Well, to avoid
auto-flattening problems in other, more common places, we ought to
make that:

for *::Namespace - $instance {...}


Well, even more huffmanized would be

  for Namespace - {...; use $_}

might be what you expect after

  my @array = (0,1,2,3);
  ::Namespace ::= @array;



However, this is very huffmanly incorrect.  First of all, what you're
doing may take a quarter of a second or more for a large program
(which isn't a short amount of time by any means).  Second, the fact
that you're using it means you're doing something evil.  Third, only a
fraction of 1/omega perl programmers will be using this feature. 
Therefore, it should probably look like:


use introspection;
for introspection::ALL_INSTANCES(::Namespace) - $instance {...}


This is why I wonder how writeable the namespace is, and when.
On some platforms it might actually not even be readable because
it was compiled away or stripped from the excecutable ;)
All that remains then is the possible behaviour as it is constrained
by the types of souls/daemons the creator happened to *choose*.
I guess you should re-read $Luke::Bible or watch the 
$*::Movies::WarnerBrothers::Matrix again :))

If both refs are undef in your namespace, go and bind them!

If the above is insulting, feel free to invoke my .apologize with
you as topic. You know, I'm the $/ of this $email.



And it might even be platform-specific, given the constraints of some
of our targets.


The platform is yet another restriction on Space::Search::Solution.
Interestingly namespace lookup is big endian...
--
$Language::Perl6::TSa.greeting
(somehow we are all part of it or was that $_?)



Re: Messing with the type heirarchy

2005-07-27 Thread TSa (Thomas Sandlaß)

HaloO,

Ingo Blechschmidt wrote:

I've probably misunderstood you, but...:

role Complex does Object {...}
Num does Complex;
# That should work and DWYM, right?


My 0.02: Complex should provide e.g. a + that, when
called with two Nums, doesn't bother the return
value to carry on a useless imaginary part. And
Complex should consistently return undef when compared
to other Nums or Complexes. And the Compare role
shouldn't treat undef == false but as any(true|false).
Otherwise funny things can happen  (as was observered
correctly in another thread about != applied to any
Juntions). In code:

   if $c  3 { die if $c.does(Complex) }

This is the Perl6 representation of the following
sentence: If Any::$c is less then Int::3 then
die if this $c does behave like a Complex. I hope
$Larry likes it. BTW, is their a plain english output
module planned, that would produce the above automatically?

Don't question (Light ::= Particle|Wave) with a double
slit! At least not if you want a deterministic answer
where it actually passed.

tie rant
Imagine a Casino that hands out ties to players
who don't have one even though the Casino is
a tied area. If a Num playing in the Casino likes
the imaginary standard tie it can keep it. But
among Nums this imaginary tie is no differentiator.
Actually other Num methods will say: A tie? I see
no tie. Must be an imaginary one. In simple
environments the tie might not even be applicable
imaginarily. Thus it's stripped off or entrance is
denied. Under all cicumstances the Num may decide
how to deal with this tieing.

fun: d(en)ie(d) == die in the end :)
/tie rant

The only question is how much effort all this is for
(1) the implementor of Complex
(2) the implementor of Num
(3) the user of either one in isolation
(4) when they come together

In particular the user in (4) should be able to
state his expectations in a form that is checkable
by the VM. Which basically means that (1) and (2)
have to state their assumptions to the VM in the
same form/syntax.
--
$TSa.greeting := HaloO; # mind the echo!


Re: execution platform object? gestalt?

2005-07-27 Thread TSa (Thomas Sandlaß)

Randal L. Schwartz wrote:

This is similar to the OS-9's gestalt tables, which got smarter as
the operating system had more features, but was a consistent way to
ask do we have a color monitor here?.

Is something like this already planned?


From my bubble in the Perl6 Universe this thing is an unbound
symbolic reference $::(to The Type System).

Welche Gestalt es bisher angenommen hat weiss ich nicht.

But it should be capable to appear in any(@form) to help
all(@us) where {any(@us) != ::United::States of America}. :)
--
$TSa.greeting := HaloO; # mind the echo!


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread TSa (Thomas Sandlaß)

HaloO,

Larry Wall wrote:

Yes.  The only thing I don't like about it is that any() isn't an Any.
Maybe we should rename Any to Atom.  Then maybe swap Item with Atom,
since in colloquial English you can say that pair of people are
an item.


Since we are in type hierachies these days, here's my from ::Any
towards ::All version. The bottom part where everything finds
together is missing for this installment.

 ::Any
... | ..
   ___:_|_:static type :
  |   : | :  | | = context :
   Package: | : Void  Bool :
  |   : | :.
Module: |
   ___|___: |
  |   |   : |
Class Grammar : |
  |___|   : |
  |   : |
 Role :   Object
  : |
  : | || |
  :   Code @Array   %Hash $Item
  : | // |
  with: |   TupleRecord  |
  invocant(s) : ||
  :/ \__   __|_
 |:  | |\ /  || |  |   |
  .Method : Sub  Block   |   |   Inf  Undef  Match  Junction
/|:  |\  |   |
   / |:  | \Ref[Code]|
   Rule  |:  |  Macro|
 |:_/|__/|\
 |:  |   | | | |
   Multi  :  | ~Str  +Num  \Ref  :Pair
..:  |   | | |\|
 |   |Int| \   |
 ___/|   | | |  Entry[::T where T.does(Hash)]
| |  |   |/|\|
  *List  Pipe =Iterator Enum ?Bit  Pos[::T where T.does(Str|Array)]
|\___
|  | |
 **Eager  Lazy  Ref[Array|Hash]


any() == lub( all --- any ) == glb( any -- all )   lesser -- greater
all() == glb( all --- any ) == lub( any -- all )

Some operators and prefixes are added in to show their
relation to the corresponding type. I hope it looks familiar.

Here is some pseudo code that describes a bare minimum data layout
required to support the respective types.

type Item[::T]
{
  has $.value of T;
}

type Pair[::T]
{
  has $.key;
  has $.value of T;
}

type Tuple[::T where T does lub( @.values )]  # lub = least upper bound
{
  has @.values of T;
  has $.value ::= @.values; # auto-enreference for Item subtyping
  has T $.head ::= @.values[0];
  has T $.tail ::= @.values[-1];
}

type Record[::T where T does lub( @.values )]
{
  has @.keys;
  has @.values of Pair[T];
  has @.pairs ::= { zip @.keys, @.values };
  has $.value ::= @.pairs;
}

type Code
{
  has %.MY;# lexical scratchpad
  has .block;
  has $.value ::= { use %.MY; .block() }; # coderef literal
}

type Junction[::T where enum any all one none]
{
  has @.values;
  has Junction $.value ::= { @.values as Junction[T] };
  has .evaluate ::= ::JUNCTION_MAGIC; # what's the exact type of this?
}
--
$TSa.greeting := HaloO; # mind the echo!


Re: Exposing the Garbage Collector (Iterating the live set)

2005-07-26 Thread TSa (Thomas Sandlaß)

Piers Cawley wrote:

I would like to be able to iterate over all the
objects in the live set.


My Idea actually is to embedd that into the namespace syntax.
The idea is that of looking up non-negativ integer literals
with 0 beeing the namespace owner.

  for ::Namespace - $instance
  {
 if +$instance != 0 { reconfigure $instance }
  }

Hmm, how would that be written inside the owning class?

  for :: - $instance {...} # or perhaps ::_ or ::0

H, and the current actor/owner is $/ which gives the expanded
method call syntax:

   .method   #  really means:   $/.method($_)

Then we need to distinguish between the owner of a block and
the topic of the block. In methods the owner is called invocant,
of course. This also nicely unifies rules and methods. But with
the drawback that the brawl then shifts from topic versus invocant
to rules and method competing for ownership :)



ISTM that exposing the Garbage Collector at the
Language level is the neatest way of doing this (or coming up with something
like Ruby's ObjectSpace, but conceptually I reckon the GC is the right place to
hang it).


To me the GC is an implementation detail for rendering the
illussion of infinite memory :)

For example +::Int could return the number of instances in use
not the potential Inf many ones. Adding the infix namespace wildcard
could allow to retrieve attributes as arrays indexed by object id:

  @instvalues = ::SomeClass::*::attr;

The access control on a level behooves its owner/origin that
is ::NameSpace::0. This gives in the end a virtual tree of all
static information. As a fallout, structured rule matches can also
be queried with :: and as such nicely blend strings into the
type system. E.g. after successfull recognition an object could
be created by simply reparenting it from the rule to its class/owner.

The referential fabric and the call chains are hang-off this
structure somehow, as well. Everything else is basically garbage.

Too far off the mark? If not, I've ideas for ?? and :: beeing
top precedence namespace query ops. Only effect is that the
current meaning needs parens like ($condition ?? $value :: $other)
for preventing strange tokenization. OTOH would the barebone
structure of Perl6 revolve around ?? :: ::= () ; and namespace lookup.
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

The problem I have with is private is that, while there may very
well be a trait of that name that you can interrogate, I really
want people to think of the private methods as being in a different
namespace so that there's no confusion about the fact that you can
have a private method and a public method of the same name.  And the
reason I want that is because I strongly believe that private methods
must be absolutely invisible to the public interface, and confusing
the namespaces puts you in a situation where adding a private method
can clobber public inheritance of the same name.

Even worse, it clobbers your private interface.  As soon as you say

method foo() is private {...}

then you can't call $?SELF.foo() and expect to get the public .foo method.
Putting the difference as part of the name forces people to distinguish

$?SELF.foo()
$?SELF._foo()

on the call end.  And the _ has the advantage of being *perceived* as
part of the name.


I start to understand the problem I have with perceiving this.

You think of the name ::foo beeing looked up somehow *in* the object
you want to call on, while I always assumed that the name ::foo is
looked up first. In a method invocation expression this lookup has
to yield a method implementation that has got an invocant type that
is compatible with the one the caller wants to put in.

If ::foo shall not be visible why not arrange for the lookup to fail?
Failing *look*up and invisibility are---linguistically spoken---very
related concepts, or not?

This method-first approach has the added benefit that anyone can place
a compatible method into a lexically closer scope than the one they want
to overwrite. If the closeness still prevents the call because of lacking
specificity a simple

  temp $object does MyStuff;

and a method in scope that is specialized on .does(MyStuff) hardly leaves
outsiders a chance to prevent the dispatch! The same thing without temp
might be construed as anti-social by whomever gave you $object ;)

The otherway round should look more like $?SELFfoo() or SELF::foo().
Hmm, and nullary .foo performs the lookup on $_ or some such. Honestly
I don't understand why the vtbl implementation detail of e.g. C++ is
taken as template for Perl6 SMD OO.

Private methods of an object come into play because the dispatch of
a publicly visible method is called. The private method must be in
scope there. The only requirement on the name is to not leak out into
public namespace.



 The problem with

$?SELF.:foo()

is that people see that as a .: operator on the foo method.


Which is a *BIG* problem in an Operator Oriented Language!
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

$x is visible only in the rest of the lexical scope.  In contrast,
$_y would presumably still be visible if the class were reopened.


Which brings me to the question how the name information is told
to a prospective user if the source code of the the first definition
shall not be disclosed. I mean of course there is the documentation
but I thought more of a machine readable form. Some kind of a interface
definition of a package.



:   # or does class scope mean shared by all instances
:   # and lexically scopes per instance?

Class scope is basically package scope.  For instance attributes and
methods the package contains proxies representing the slots in the
actual instance.


Sorry, this proxy is the invocant, right? And the type system ensures
compatibility to the methods expectations. This is to me the whole point
in the method call procedure: to bind the invocant to the variables of
the method with respect to the invocant. Since variables in Perl6 code
bear one of the four sigils Code, $Item, @Array and %Hash this binding
to the invocant is simply indicated by the . twigil and supervised by
the type system.



Sure, if you want to declare an attribute containing a code reference.
But  doesn't have much to do with the call syntax in any event,
whether you're calling subs or methods.  You can declare an attribute
as .foo and call it as $.foo without a problem, since it's just
$?SELF.foo() either way, and the accessor methods are not associated
with sigils.  I think $.foo and .foo are synonymous as attributes,
except insofar as we can probably deduce that .foo is dealing with
a sub ref and not just any old scalar value.


Sorry, I meant the  sigil as generic Code type markup which includes
in particular methods on behalf of the invocant. Actually I see no
point in assuming sub ref for . but a ref to a method with the
invocant type as specializer. The type information for an object that
is blessed into a type comes of course from just the artifact from
the blessing, however it is retrieved from the invocant.

So with these two things at hand a method invocation can be spawned:
1) the invocant ref
2) a method ref
All referential expressions in the code block of the method are
bound according to the runtime representation of the object in that
moment.



: * All roles can write completely private $x attributes that are not
: 	visible outside their lexical scope but are nevertheless 
: 	per-instance.
: 
: I understand that correctly, that $x in
: 
:role Foo { has $x = 7; method foo { $x++ } }
: 
: denotes a reference to an Item from the data environment of the object

: that foo is invoked on.

I don't know what you mean by data environment.  The second
occurrence of $x denotes the generic proxy declared by the has
that represents an eventual slot in the actual instance.  This slot
presumably has no other obvious name to any other role or to the
class that composes this role, though presumably there's an internal
way to get back from a particular slot to the slot's metadata, which
presumably knows which role supplied the definition.


With data environment I mean the stuff reachable through the invocant.
The actual type of the invocant and the method's formal invocant type
specify what is available through the link as long as the invocation
persists.



: The type of the $?SELF that Foo is composed into
: obviously is a subtype of Foo. What happens with this hidden payload if
: the object changes its type such that it is no Foo anymore? E.g. by
: undefining the slot .Foo::foo?

Um, people who undefine functions that are going to be called later get
what they deserve.  As for what happens to $x's slot in the absence
of the lexical reference from Foo::foo, I expect the metadata would
still have pointers to it so it wouldn't necessarily be reclaimed
unless you told the object that is undoes Foo.  Or to look at it
another way, all the objects that do Foo have a closure over that
$x proxy, so it's not going to go away until everyone forgets about
the Foo role itself.


Ups, I hoped that the type system would find out mismatches of the
objects actual structure and the methods expectations of it. Essentially
rendering the method in question not applicable to the object anymore.
BTW, what is the inverse operation of bless? Expel?
--
TSa (Thomas Sandlaß)




Re: Referring to package variables in the default namespace in p6

2005-07-21 Thread TSa (Thomas Sandlaß)

Matthew Hodgson wrote:
These rules are all fair enough - but they are then ambiguous for 
$::Foo. Is that the leaf name variable Foo in your current (innermost) 
namespace?


It is not ambiguous if the sigil rules that expression. I assume
that the parameters of a sub are definining innermost names to
their body:

sub foo ( $param )
{
   say $::param; # prints argument bound to $param
   say $param;   # same

   say $OUTER::param;  # prints value of result of a lookup
   # that starts outside of sub foo

# but
   my ::param $x = ::param.new; # look for param type info

   # The above compiles preliminarily but eventually needs
   # a type param. If the only name that is in scope is the
   # formal param then I presume a late compile error occurs.
   # Well, or the runtime *value* of $param is taken as the
   # type which essentially renders $x a constant.

# and
   my param $y = param.new; # works only if param pre-declared.

# Also
  say  param(); # requires a code type to be in scope
  say param(); # same with late binding
  say .param(); # late binding with method sigil
}

Interesting question is how the last two lines above behave depending
on whether param.does(Sub) or param.does(Method) and what light
that sheds on the $?SELF.method problem :)



Or is it an attempt to dereference the disambiguated type Foo?


What is the use of reference to a type? The compiler, dispatcher
and class and object composer need type information to do their
job, of course. And they might handle this information through
refererences. But when this happens the source is already digested.

In other words you just can't use a sigiled expression where a type
is expected: my $::Foo $x; is just a syntax error. This is why I regard
the sigils as type mark-up. That means writing $Foo or $::Foo just
tells the compiler that you want to handle the item Foo.



 Or is it like perl5, shorthand for $*Main::Foo?


This is clearly specified as not beeing the case.


Is there any reason why $::Foo could not do both, and not start by 
searching your current namespace for a variable called $Foo... and then 
start searching your current namespace hierarchy for a type called Foo 
and try to dereference it (whatever that does)?


This is my position if I read the double negation correctly.
Sorry if that wasn't clear initially. But I hope the above rants
clarify what I mean.


Presumably it should behave in precisely the same way that $::('Foo') 
does for sanity - does that search the current namespace for just types 
or variables or both?


Not for sanity. $::Foo is just syntactic sugar for $::('Foo') because
'Foo' is a compile time constant. But $::( some_calculated_name ) might
not in general be evaluateable at compile time and thus forces the
compiler to generate symbolic lookup code which
1) calls some_calculated_value
2) starts lookup with the stringified return value

Note that because of the $ sigil it looks for something that does the
Scalar/Item role! We can consider the sigils as lookup filters.

Regards,
--
TSa (Thomas Sandlaß)




Re: More on Roles, .does(), and .isa() (was Re: Quick OO .isa question)

2005-07-21 Thread TSa (Thomas Sandlaß)

chromatic wrote:

On Tue, 2005-07-19 at 18:47 +0200, TSa (Thomas Sandlaß) wrote:

I strongly agree. They should share the same namespace. Since
code objects constitute types they also share this namespace.
This means that any two lines of

class   Foo {...}
roleFoo {...}
sub Foo {...}
method  Foo {...}
subtype Foo of Any where {...}

in the same scope should be a simple redefinition/redeclaration error.



I don't understand this.  What does a scope have to do with a namespace?


I meant a scope of source code, basically everything delimited by braces.
And that nesting of braces *is* the namespace, or not? Well, at least the
compile time view of it.

The Perl6 namespace is available at runtime as well. But it is beyond me
how much these differ. But for the specification of the language only the
source code aspect is relevant.



Why does a code object constitute a type?


Is this more a 'how do function types work' question or
are you doughting the usefullness of this concept for Perl6?

The sort function e.g. takes a parameter of type Comparator
which is a code type describing instances that accept two parameters
of the type that is to be sorted and return a value of a type
that describes the relative order implemented by the comparator.

Actually the Comparator is usually a parametric type, that is
instanciated with concrete types and thus forming a non-parametric
code type. The invokation of such a type are the instances of the
type. During a sort run many of these instances are created.



I can understand there being separate types, perhaps, for Method,
Submethod, MultiSub, MultiMethod, and so on,


... and subtypes thereof.


but I don't understand the
purpose of sharing a namespace between types and function names,


What should 'mysubtype' in the following signature

  sub blah ( mysubtype sref )
  {
  my Int $x = sref( Str, 23, Foo.new );
  }

mean if not a constraint of the type of sref?
Above it is used as a function that accepts (Str, Int, Object)
and returns Int. Depending on the definition of ::mysubtype
this usage is erroneous or not. I ask myself---or @Larry---how
the same effect could be achieved without the indirection through
a name. Perhaps:

  sub blah( Code[Str, Int, Object -- Int] sref )  {...}

The same question arises when ::subtype shall be declared:

  subtype mysubtype of Code[Str, Int, Object -- Int];

  subtype mysubtype of Code:(Str, Int, Object) returns Int;



nor of
having funcitons declare/define/denote/de-whatever types.


Here's an attempt of code joke around foo (ignore at will)

class foo
{
   submethod postfix:{'( )'} ( $x ) { say $x }
}

sub foo( foo ) { say foo }

sub bar ( foo $foo, foo foo )
{
   $_ = foo.new;
   my foo $f = \foo;
   my foo f = \foo;
   my foo @f = foo;
   say foo(23);
   say .(42);
}
--
TSa (Thomas Sandlaß)



Re: MML dispatch

2005-07-21 Thread TSa (Thomas Sandlaß)

chromatic wrote:

Why would a class not also define a type?


It does. A class is an instance generator. So all instances
share the same property of 'beeing instanciated from SomeClass'.
This can be used to type them. Question is where this type is
placed in the type lattice and how it compares to the type of
structurally/semantically identical objects beeing instanciated
from another class.

My proposal is to hang the type off the top, most unspecific
type Any or actually a bit further down, under Object
which excludes Package, Module, Class, Grammar and Role.

The name of the class is inserted in the appropriate place into
the namespace and is available as type parameter for the Ref[::T]
role.

It is actually quite interesting that there is no special form
for compile time object instantiation with the keyword object.

   class Point
   {
  has Num $.x;
  has Num $.y;
   }

   object center of Point  # without of we get classless objects
   {
  .x = 23;
  .y = 42;
   }

   object pi of Num = 3.14;

   our Int object answer = 42;

   say answer;  # prints 42
   say center.x # prints 23

   # and even more

   our Array object some_values = (1,2,3,4,5);

   for some_values { say }

Hmm, looks somewhat unperlish :))
--
TSa (Thomas Sandlaß)




Re: Referring to package variables in the default namespace in p6

2005-07-21 Thread TSa (Thomas Sandlaß)

HaloO Matthew,

you wrote:
I wasn't getting hung up on whether $::($varname) should somehow be 
cached to avoid a dynamic lookup based on the current value of $varname 
every time.  And I assume that if $*Main::foo hadn't been created, 
assigning to $::($varname) would create it as expected (again, without 
any caching of $varname).


Here your expectations might be disappointed, sorry.

The non-symbolic form $*Main::foo = 'bar' creates code that
makes sure that the lhs results in a proper scalar container.
The symbolic form might not be so nice and return undef!
Then undef = 'bar' of course let's your program die.

Unfortunately I'm unsure how the runtime interface to
making dynamic namespace entries looks like. Note that
the operator ::= acts at compile time, too.

My guess is that the compiler collects all potential data
items and arranges for auto-vivification and/or autoloading
and even on-the-fly instance composition and such like things.
But for symbolics this is your task.


My confusion initially stemmed from chat on #perl6 about $::Foo and 
$::('Foo') being Very Different Things - and the fact that there was 
ever any confusion over whether $::foo was your 'closest' $foo variable 
or something else.


So to conclude, for reading they amount to the same result but through
different paths. But since the symbolic lookup might result in undef
the behaviour for writing is indeed a Very Different Thing.


@Larry, please correct if I gave wrong advice.
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

has $x; # private rw, no accessors, not virtual, name lexically scoped

has $_x;# private rw, rw _x accessor, not virtual, name class scoped


Even if I come across as intellectually handicapped but could
someone help me over this mental bridge: What is the difference
between these two scopes?

class Foo
{
#class scope starts here

  has $x;  # where does this go if not Foo::x

  has $_y; # this goes into Foo::_y

  # both $x and $_y can be used in code from here on
  # and refer to the same two things respectively, right?

  # or does class scope mean shared by all instances
  # and lexically scopes per instance?

#class scope ends here
}




Other thinkings:

* Any self method can be called via $.x(@args) syntax, short for
$?SELF.x(@args).


Isn't  the code sigil?




* All roles can write completely private $x attributes that are not
visible outside their lexical scope but are nevertheless per-instance.


I understand that correctly, that $x in

   role Foo { has $x = 7; method foo { $x++ } }

denotes a reference to an Item from the data environment of the object
that foo is invoked on. The type of the $?SELF that Foo is composed into
obviously is a subtype of Foo. What happens with this hidden payload if
the object changes its type such that it is no Foo anymore? E.g. by
undefining the slot .Foo::foo?


Regards,
--
TSa (Thomas Sandlaß)




Re: User-defined behaviour of hashes in list context

2005-07-20 Thread TSa (Thomas Sandlaß)

HaloO Ingo,

you wrote:

according to Damian [1]...:

my %hash  = (a = 1, b = 2);
my @array = %hash;
say @array[0].isa(Pair);  # true

How can I override this behaviour?

class MyHash is Hash {
# Please fill in here


  # my idea is to overload *infix:=

  multi method infix:{'='} ( Array @a, MyHash +%h )
  {
  # your stuff here ...
  # in particular you have access to your private attrs
  # and methods
  }

}

my %hash is MyHash = (a = 1, b = 2);
my @array  = %hash;   # should call my own routine


I hope the initialisation in my also calls the overloaded
operator. But why shouldn't it?
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-19 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

Implicit is that role distance is N + the distance to the nearest
class that incorporates that role for small values of N.

If class Dog does role Bark and also does role Wag, then passing a
Dog to

multi (Bark $x)
multi (Wag $x)

should result in ambiguity.  The interesting question is whether N should
be 0 or 1 (or possibly epsilon).  If we have

multi (Bark $x)
multi (Dog $x)

arguably Dog is more specialized than Bark, which says N maybe
shouldn't be 0.  Whether it should be epsilon or 1 depends on how
you think of role composition, and whether you think of roles more
like immediate parent classes or generic paste-ins.  You can think
of them as immediate parent classes, but in that case they're actually
closer than a real parent class that would have distance 1, since
role methods override parent class methods.  That argues for N  1.


Sorry, has Perl6 now reverted to setting classes above types?

I would think that the programmer specifies what type a class
implements by letting it do a set of roles. This implies that
by default a class does the very unspecific Any. In your example
the type system needs the information if Dog does a supertype or
subtype. The syntax could be junctive:

class Dog does Bark | Wag {...} # union type (least upper bound)
class Dog does Bark  Wag {...} # intersection type (greatest lower bound)
class Dog does Bark , Wag {...} # same as  or typeless composition?

If Dog is made a supertype then neither multi (Bark $x) nor multi (Wag $x)
is in the applicability set. For the subtype case both are applicable
and an ambiguity type error occurs. This needs disambiguation through
defining multi (Dog $x). The question is at what time this error occurs
and what restrictions allow a compile time detection. Note that the
ambiguity doesn't go away with a metric approach because there are no
other parameters that could compensate.

Regards,
--
TSa (Thomas Sandlaß)




Re: How do subroutines check types?

2005-07-19 Thread TSa (Thomas Sandlaß)

Ingo Blechschmidt wrote:
How do I have to annotate the type specification in the 
declaration of the subroutine to not include the class Foo, but 
only allow instances of Foo? 


My understanding is that Foo.does(Foo) is false and sub params
are checked with .does(). This automatically excludes class args.
That is you have to explicitly order them:

sub blarb (Foo|Class[Foo] $foo, $arg) # or with CLASS[Foo] ?
{
   ...;   # Do something with instance or class $foo
}

Foo|Class[Foo] is a supertype of Foo and Class[Foo] and as
such allows its subtypes Foo and the Class[Foo] parametric
role instanciation. Note that Foo|Class allows calls like
blarb( Int, HaHa ).

Actually I'm not convinced that class Foo should automatically
constitute a (proper) type other than Any. But since .does falls
back to .isa it comes out the same since the only way here to get
a Foo doer is by instanciating the class Foo.
--
TSa (Thomas Sandlaß)




Re: More on Roles, .does(), and .isa() (was Re: Quick OO .isa question)

2005-07-19 Thread TSa (Thomas Sandlaß)

HaloO chromatic,

you wrote:

Have I mentioned before that I think you should be able to say:

class Foo
{
method foo { ... }
method more_foo { ... }
}

class Bar does Foo
{
method foo { ... }
}

... probably get a compile-time error that Bar doesn't support
more_foo()?


We've discussed that when I was ranting about the type lattice
and co- and contravariance...

I'm not sure what my position back then was but now I agree
because I see CLASS as a subtype of ROLE. The only problem
is that $Larry said that he doesn't want parametric classes.


I see a reason to differentiate between roles and classes on the 
metalevel, but the argument is not as strong on the user-level.



I go further to see little reason to distinguish between role, class,
and type names (and what reason there is is for introspective
capabilities, not standard user-level type checking).


I strongly agree. They should share the same namespace. Since
code objects constitute types they also share this namespace.
This means that any two lines of

class   Foo {...}
roleFoo {...}
sub Foo {...}
method  Foo {...}
subtype Foo of Any where {...}

in the same scope should be a simple redefinition/redeclaration error.
OK, sub and method can escape from this fate by means of the keyword
multi and different sigs.

Since sigils somehow define references Foo could mean e.g. a classref
while ::Foo could be a Code type. If we then also promote . to a primary
sigil for Method... hmm have to think about that!
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-13 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

On Tue, Jul 12, 2005 at 08:13:22PM +0200, TSa (Thomas Sandlaß) wrote:
: Actually it's a pitty, that the multi method call syntax isn't as
: rich as the single method call syntax where we have .?method, .+method
: and .*method. Something like (Snoopy, Mr_PotatoHead, HopeDiamond).*foo
: doesn't exist, right? Or is it foo.*(Snoopy, Mr_PotatoHead, HopeDiamond)?

It doesn't seem to make much practical sense.  Multimethods are
generally written to be exclusive of ancestral methods.  Ordinary
methods are generally written to be cumulative with ancestral methods.


Interesting that we are thinking in orthogonal ways. I was arguing
for a syntax that allows the caller to prevent 'no method' and 'method
ambiguous' errors with .?() and .+() respectively. And .*() would prevent
both. In the ambiguous case all applicable targets would be called in an
undefined order.

Is there also an answer to the odering versus metric question?
Why was the former rejected and the latter choosen?
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-13 Thread TSa (Thomas Sandlaß)

HaloO Damian,

thank you very much for your explaination. I just want to hint the
Perl6 community to the fact that there exists a US patent on geometric
MMD:

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2Sect2=HITOFFp=1u=/netahtml/search-bool.htmlr=1f=Gl=50co1=ANDd=ptxts1=ferragina.INZZ.OS=IN/ferraginaRS=IN/ferragina

I haven't check the relevance to Perl6 yet.
Has someone access to the STOC'99 paper?
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-12 Thread TSa (Thomas Sandlaß)

Mark Reed wrote:

And one more dumb question: why is it that the L[1] metric is superior to
the L[2] metric for this purpose?


I am also interested in the rational behind the approach to manage MMD
my means of a metric instead of a partial order on the types.
Metric is a geometric concept which in my eyes doesn't fit type
theory.

I would join Luke and recommend 'pure' MMD. That is there has to
be exactly one target that is most specific on all positions relevant
for the dispatch. In particular do I dislike the the property of a
metric that several smaller mismatches can be compensated by a good match.
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-12 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

This is a much less dwimmy solution than Yuval's or Luke's, but it has the
advantage that those eight steps reduce to eight words:

Unique least-inherited most-specialized match, or default


Do I read this correctly as dispatching partly in the class hierarchy
and partly in the type hierarchy? Or do you mean with 'least-inherited'
most specific non-where type and with 'most-specialized' the strictest
where clause? To me these two concepts are the same if you think of the
does operator as a predicate:

multi sub foo ($x where { $x.does(Num) }) {...}

beeing the same as

multi sub foo (Num $x) {...}
--
TSa (Thomas Sandlaß)




Re: How to write a self.pm (Re: method calls on $self)

2005-07-12 Thread TSa (Thomas Sandlaß)

Autrijus Tang wrote:

The compiler, in turn inspect whether there's an bound $_ in scope
with $?SELF set.  It is not trivial, because this should work:

sub baz (c) { c() }
method foo { baz { .bar } } # $_ is free in inner closure

But this needs to fail:

sub baz (c) { c(1) }
method foo { baz { .bar } } # $_ is bound in inner closure


I might still not understand topic, $_ or lexical vars in general.
But why does the fact that c is called with a parameter
in the second case and without one in the first example make a
difference? Isn't $_ always coming in out of band? So .bar is always
invoked on the invocant of foo if we think that there is an implicit
$_ := $?SELF before the call to baz in foo.  And I hope the binding
of $_ to $?SELF is a read-only binding!
--
TSa (Thomas Sandlaß)




Re: MML dispatch

2005-07-12 Thread TSa (Thomas Sandlaß)

Mark Reed wrote:

On 2005-07-12 12:22, TSa (Thomas Sandlaß) [EMAIL PROTECTED]
wrote:


I am also interested in the rationale behind the approach to manage MMD
my means of a metric instead of a partial order on the types.
Metric is a geometric concept which in my eyes doesn't fit type
theory. 



The geometric interpretation does bring us into somewhat philosophical
territory. Not that that's anything new on this list. :)

Let me try a concrete example.  Suppose that class Answer has subclasses
Animal, Vegetable, and Mineral, with respective subclasses Dog, Potato, and
Diamond.  There are two methods named foo in scope, neither overriding the
other.  One is declared to take (Animal, Vegetable, Mineral), the other
(Dog, Potato, Answer).  Assuming the obvious memberships, which method
should foo(Snoopy, Mr_PotatoHead, HopeDiamond) call?  And more importantly,
why do you feel that is the right answer?
 
According to Damian's metric, we have distances of 0+0+2=2 and 1+1+1=3, so
(Dog, Potato, Answer) is closer and would get called.  


Uhh, both targets are applicable but none is more specific on all
positions. I would like this to be an ambiguous dispatch error.

Actually it's a pitty, that the multi method call syntax isn't as
rich as the single method call syntax where we have .?method, .+method
and .*method. Something like (Snoopy, Mr_PotatoHead, HopeDiamond).*foo
doesn't exist, right? Or is it foo.*(Snoopy, Mr_PotatoHead, HopeDiamond)?
--
TSa (Thomas Sandlaß)




Re: Hackathon notes

2005-07-08 Thread TSa (Thomas Sandlaß)

Autrijus Tang wrote:

* deref is now 0-level; $x = 3; $y = \$x; $y++. # now an exception


That is because postfix++:(Ref) doesn't exist, right?



* sub foo (?$x, ?$Inf) {}
  my $y = (x = 3); foo($y); # binds $x
  my $z = (+Inf = 3); foo($z); # binds $Inf


Isn't the lhs of = autoquoted? Why does '+Inf' as key bind $Inf?



* Constrained types in MMD position, as well as value-based MMDs, are _not_
  resolved in the type-distance phase, but compile into a huge given/when
  loop that accepts the first alternative.  So this:

multi sub foo (3) { ... }
multi sub foo (2..10) { ... }

  really means:

multi sub foo ($x where { $_ ~~ 3 }) { ... }
multi sub foo ($x where { $_ ~~ 2..10 }) { ... }

  which compiles two different long names:

# use introspection to get the constraints
fooANONTYPE_1
fooANONTYPE_2

  which really means this, which occurs after the type-based MMD tiebreaking
  phase:

given $x {
when 3 { fooANONTYPE_1.goto }
when 2..10 { fooANONTYPE_2.goto }
}
  in the type-based phase, any duplicates in MMD is rejected as ambiguous; but
  in the value-based phase, the first conforming one wins.


I hope that is a temporary solution. Usually one would expect 3 beeing a
more specific type then 2..10 irrespective of definition sequence.



  The upshot is that these are now errors:

sub foo ($x) is rw { $x }
my $a;
foo($a) = 4;# runtime error - assign to constant


I assumed lvalue subs would implicitly return void and an
assignment goes to the function slot of the args used in the assignment
and subsequent calls with these args return exactly this value.
In that respect arrays and hashes are the prime examples of lvalue
subs. Other uses are interpolated data, Delauny Triangulation etc.


Regards,
--
TSa (Thomas Sandlaß)




Re: Hackathon notes

2005-07-08 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

Anyway, I think that once we start diving inside expressions to
measure their specificity, we've gotten too complex to be predictable.


Well, we don't have where clauses, but where closures! The former
should be a declarative sublanguge like regexps. They are evaluated
at compile time or type instanciation time or however it is called
and entered into the type constraint environment where the MMD looks
for it. For the latter a warning should be produced and they are *not*
considered for MMD other than applicability checking. They are of
course called for non-invocant params, in assignments etc.

For research on the topic see e.g.
http://www.cs.washington.edu/research/projects/cecil/www/Papers/predicate-classes.html
--
TSa (Thomas Sandlaß)




Re: Type variables vs type literals

2005-07-07 Thread TSa (Thomas Sandlaß)
idea breaks down.

[..]

Okay, you've used ::Type as a type variable--now how do you declare
that you simply want Type treated as a forward declaration of Type.
I'm not quibbling with the desire to bind types to type variables.
It's just we've got a conflict in the definition of what :: means
that we'll have to resolve one way or another.


I don't want value-like type variables because that would generate
a big mess if one wanted to store type refs in value vars:

my $typeref = $object.type;

my ::$typeref $same_type_object; # do we want this?
my $typeref $weird; # or even this??

The only use of type variables is in parametric types. And since
you want to restrict that to roles the need for implicit type binding
shifts onto the does operator and role instanciation. But how automatic
will your example

role FooStuff[T] {
sub foo (T $x, T $y) { }
...
}

be instanciable? I guess the explicit forms are:

   FooStuff[Int]::foo(1,2);

   strfoo ::= (FooStuff[Str].new)::new; # from Autrijus Hackathon notes

Will re-instanciation be prevented when the latter is spelled

   strfoo := (FooStuff[Str].new)::foo; # or with =

Actually this syntax might be wrong usage of ::.

But do I get you right that the lazy forms are

   does FooStuff; # lazy role instanciation into current scope

   foo(1,2);   # FooStuff[Int]::foo:(Int,Int)
   foo(1,'blahh'); # type error?

Regards,
--
TSa (Thomas Sandlaß)




Re: Submethods

2005-07-06 Thread TSa (Thomas Sandlaß)

Stevan Little wrote:
The concept of non-inherited infrastructural methods is fairly simple to 
accomplish in the meta-model, by just giving submethods their own 
dispatch table inside the metaclass. However where I am somewhat 
confused is in how and when they get called.


I think the question is posed a bit confusingly. Since as you point out,
when the invocant is clear, calling the (sub)method is an easy lookup in
its vtable with subsequent call.



Take this example for instance:

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

Is this an error (Synopsis 12 seems to indicate it is *not* an error)?


The only inconvenience I see is that the name Foo::bar is not unique.
The sigil doesn't disambiguate because in both cases it is Foo::bar.
Furthermore the :() is used only to distinguish different sigs, not the
Code subtype behind the name. Hmm, or is this a special cased two-entry
MMD table? One entry for bar:(Foo) and one for bar:(MetaClass[Foo])?


When I call bar() on an instance of Foo, which is called? The method? or 
the submethod? Is it somehow dependent upon the calling context? (called 
from within the class, or from outside the class). Take for instance, 
this example:


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

method baz ($self:) {
$self.bar() # which one does this call?
}
}


I think this is pretty clear. There is exactly one class object Foo
but many instances. The submethod can only be called on the Foo class
object which is available through the .meta method. Thus to call
the submethod one needs $self.meta.bar(). I doubt the usefullness
of falling back to submethod lookup in the class chain when an object
doesn't have the method.

There's actually no syntactical distinction possible because of:

my $object = new Foo;
my $meta = $object.meta;

$meta.bar() # calls submethod but looks like method call

I guess the type of $meta is Ref of Class or somesuch.


Regards,
--
TSa (Thomas Sandlaß)




Re: Type variables vs type literals

2005-07-06 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

Well, there's something to be said for that, but my gut feeling says
that we should reserve the explicit generic notation for compile time
processing via roles, and then think of run-time lazy type aliasing


Could you explain what exactly 'run-time lazy type aliasing' is?
I mean what does it achieve and how does it compare to type
instanciation and parametric contraint checking?



as something a little different.  So if you really want to write
that sort of thing, I'd rather generalize roles to work as modules
containing generic subs:

role FooStuff[T] {
sub foo (T $x, T $y) { }
...
}

Otherwise people are tempted to scatter generics all over the
place, and it's probably better to encourage them to group similarly
parameterized generics in the same spot for sanity.  It also encourages
people to instantiate their generics in one spot even if they're
calling them from all over.

[..]

I think people should say does FooStuff[Int] and automatically alias
all the routines to the Int form so we don't have to scatter :[Int]
all over.  Or if they just say does FooStuff, they get lazily-bound
type parameters.


I get that right, FooStuff can be instanciated without a class or object?
Something like unary operator does? Into which scope do these role 
instanciations go? Does does *FooStuff[Int] mean global?




: ::T $x := $obj;
: my T $y = $x;
: 
: The prime use of that feature is to ensure type homogenity for

: temporary and loop vars in a certain scope. But the scope in the
: above syntax is not apparent enough---to me at least.

Actually, I was holding those up as bad examples of scope visibility,
so I'm agreeing with you there.  (Which is why I suggested that we
require a my context, even if only implied by the formal paramter list.)

: Thus I opt for an explicit
: 
:subtype T of $obj.type; # or just $obj perhaps?

:T $x := $obj;
:my T $y = $x;

Yuck.  I think that completely obscures the lazy type binding.
Plus you've managed to omit the my, so you've created a global
subtype T.  (Unless, as I'm leaning towards, we make such bare inner
types illegal, and require my, our, or *.)


The only thing I did was to replace the :: sigil with a subtype
declaration. Does subtype always go into global scope? I thought
that it requires a *name to go into global and our to go to the
innermost module---or was that package? I mean even non-declared
auto-vivified vars go into the immediately surrounding scope,
or am I horribly mistaken?

sub foo()
{
   if (1) { $x = 'from above' }
   if (2) { say $x }  # prints 'from above' even if no outer $x exists?

   say $x; # prints undef or 'from above' if outer $x
}


Up til now I assumed that ::T and plain T mean exactly the same if T
is pre-declared/defined. The type sigil is only needed to defer the
definition/binding. In a certain sense this is a hanging type reference
similar to foo beeing a reference to Code. Which brings me to the
question how to bind a type reference. I mean we have

my fooref := foo

which allows fooref() calls, right? How are type references derefed
if not by dropping the sigil? ::TypeRef() perhaps?

my ::TypeRef; # type variable?

sub make ( ::Type, Type $value ) returns Type
{
   if (::TypeRef != ::Type)
   {
  ::TypeRef = ::Type;
   }
   my Type $x;
   $x = $value;
   return $x;
}

my $i = make(Int, 17);
my @a = make(Array, [1,2,3]); # single element array?
  # or three element array?

my $e = make(Int 'string'); # type error in make?

With the automatic binding of a ::Type variable to the type
of it's argument the definition of make could be shortend to

sub make ( ::Type $value ) returns Type
{ ... }

and called like this

my $i = make(17);

which at least prevents type errors ;)


Regards,
--
TSa (Thomas Sandlaß)




Re: Time::Local

2005-07-06 Thread TSa (Thomas Sandlaß)

Juerd wrote:

I think the problem one has is much bigger even if a day *number* is
ever displayed. Then beginning with 1 because that's where most humans
begin counting, is wrong. It's a technical thing, and that should be
kept as simple as possible, and as technical as possible, for easier
compatibility with existing technical things.


As a technical remark I like to point out, that you need 8 time points
to define 7 days. Every day is bounded by two such time points---which are
of course 24 hours apart. This is necessary to get the arithmetic right!
Weekday arithmetic is modulo 7. Or put differently

   $week.end() - $week.start() == $week.length == 7 days

must hold. If e.g. you start your week with Monday than this becomes

   $Sunday.end() - $Monday.start() == 7 days.

The next order of precision in calender arithmetic is the hour *within*
the day, then minutes and seconds. The weeks themselfs are subdivisions
of years. And the scheme is not completely regular in e.g. the Gregorian
calendar---but almost e.g in the Sym454 calendar which only has leap
weeks.

I think, that this type of integer with remainder arithmetic shows up
in Perl6 in other places as well. E.g. chars in strings depending on the
Unicode level and index arithmetic of arrays. Some unification of the
underlying math would be nice, indeed. And that typically involves
starting from 0 and the positive remainder pointing into the day.

Regards,
--
TSa (Thomas Sandlaß)




Re: Type variables vs type literals

2005-07-04 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

On Thu, Jun 30, 2005 at 09:25:10AM +0800, Autrijus Tang wrote:
: Currently, does this:
: 
: sub foo (::T $x, ::T $y) { }
: 
: and this:
: 
: sub foo (T $x, T $y) { }
: 
: Means the same thing, namely
: 
:a) if the package T is defined in scope, use that as the

:   type constraint for $x and $y
: 
:b) otherwise, set ::T to be the most immediate common supertype

:   of $x and $y.
: 
: Is this understanding correct?  I'd like to disambiguate the two cases

: by making ::T in parameter list to always mean type variable (sense b),
: and the bare T always mean type name (sense a)?

I think it would be good to distinguish those, but I've been mulling
over whether ::T should be the syntax for b.  (And also whether b
is the correct way to think about it in Perl 6.)  The problem with
using ::T for autovivify your type from the argument is that ::($x)
doesn't mean that, and it looks like it should.


I think the point is that using a type variable in the signature of a sub
is too subtle for recognizing it as a type function that produces typed
subs. Thus---even if it resembles C++ templates---I suggest to put the
type parameters onto the sub:

sub foo[T] (T $x, T $y) { }

which basically constrains $x and $y to have the same type. A call
to foo might automatically instanciate appropriate implementations.
With MMD and all methods and attributes beeing virtual this could
usually be a no-op as far as the code generation is concerned.
But the type checker has to know what constraints are in effect.


The syntax for explicit selection could be foo:(Int)('3','2') which
prevents the interpretation foo:(Str,Str). OTOH, this might overload
the :() too much. Could we invent more colon postfix ops?
Thus the above were foo:[Int]('3','2'). And while we are at it
since () is more call-like and [] lookup-like we could reserve :()
for more complicated type literals and use :[] for formal type signatures
on subs as it is the case for roles.



 The :: does imply
indirection of some sort in either case, but it's two very different
kinds of indirection.  ::($x) can't declare a lexical alias for
some type, whereas ::T presumably could, though your formulation seems
more of a unificational approach that would require ::T everywhere.

In other words, if we do type binding like b, we would probably want to
generalize it to other binding (and assigning?) contexts to represent
the type of the bound or assigned object, and at the same time create
a lexical alias for the bare type.  So we might want to be able to say

::T $x := $obj;
my T $y = $x;


The prime use of that feature is to ensure type homogenity for
temporary and loop vars in a certain scope. But the scope in the
above syntax is not apparent enough---to me at least.
Thus I opt for an explicit

   subtype T of $obj.type; # or just $obj perhaps?
   T $x := $obj;
   my T $y = $x;

With my proposal from above the short form could be

   :[T] $x := $obj;
   my T $y = $x;

or the current form with :()

   :(T) $x := $obj;
   my T $y = $x;


Regards,
--
TSa (Thomas Sandlaß)




Re: return() in pointy blocks

2005-07-04 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

On Wed, Jun 08, 2005 at 12:37:22PM +0200, TSa (Thomas Sandlaß) wrote:
: BTW, is - on the 'symbolic unary' precedence level
: as its read-only companion \ ?.

No, - introduces a term that happens to consist of a formal signature
and a block.  There are no ordinary expressions involved until you
get inside the block.  (Or set a default on one of the parameters, to
the extent that those are ordinary expressions.)


So without a block there is a syntax error?

  $x = - $y;

Or could this be understood as a short form of

  $x = - { $y } # $y from outer scope

I still think the pointy looks really cute as a prefix operator
for constructing rw refs. Especially if we use () to evaluate
the blockref returned. For plain variable assignment this is
not overly usefull because it amounts to the same as

  $x := $y;

but in lists it is quite nice

  %h = { foo, 'bar', blah, - $y };

or not?

  %h = { foo = 'bar', blah = - $y };

hmm, can the following be interpreted as spoiling pair notation?

  %h = { :foobar, :blah - $y }; # would blah- $y parse at all?

I think not because this works

  %h = { :foobar, :blah{- $y} };

Regards,
--
TSa (Thomas Sandlaß)




Re: reduce metaoperator on an empty list

2005-06-17 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

Let's assume that op is overloaded for two completely unrelated types
A and B, which are both defining their respective identity elements
but !(A.identval =:= B.identval). How should the op multi method object
pick the correct one *without* looking at $value's type?



Your mistake is in thinking that the identity trait is on the operand 
type. It isn't; it's on the operator itself.


I agree, that the pair of operator and type which determines the identity
element can be stored as a trait of the operator implementation. *But* the
operator selection from the multi has to use the type of $value. In
particular it might not be inferable at compile time. Thus the compiler
has to produce MMD code and hook half way into it to perform the selected
call with two args: the identity op.identval and $value.

Which brings me to the question: is there a syntax to invoke the
target selection from a multi? E.g. op.select($value,$value) here?
Or is it op:($value,$value)?
--
TSa (Thomas Sandla)




Re: Ignoring parameters

2005-06-17 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

No. That needs to be:

  method greet(FooClass ::class:) { say Hello!; }

(as implied by takes a class as its invocant in S12).
^


Ohh, does that mean that ::class can be used as a type
inside the body? E.g.

method template ( FooClass ::foo :)
{
   my foo $f;

   ... # use $f
}
--
TSa (Thomas Sandla)




Re: MMD vs. anonymous parameter types referencing earlier parameters

2005-06-14 Thread TSa (Thomas Sandlaß)

Chip Salzenberg wrote:

This:

multi sub is_equal(Integer $a, Integer where { $_ == $a } $b: ) { 1 }

hurts.  At least as I've been given to understand it[*], is impossible
to implement, because the second parameter's type can't be precalculated
in order to prepare for MMD dispatching.


Quite interesting that Cecil already has it. The thing is called
Predicate Dispatch and there exist efficient implementation strategies.
And it is possible to calculate a static supertype of the above,
which is is_equal:( Integer, Integer : ).



In short, $b has no pre-calculable type.  And you can't calculate the
MMD potential of a subroutine unless you know the actual types of its
MMD-participating parameters.


I don't know what 'MMD potential' is.



(This also means that the type of is_equal:(...) is impossible to
express, unless I greatly misunderstand the foo:() syntax.  But
it doesn't matter what you call it if you can't call it.)


The syntax might just be:

   is_equal:(Integer $a, Integer where { $_ == $a } :)

The only point is that I see no way for the compiler to
optimize to anything but a dynamic dispatch. Thus a more
declarative style of predicate specification would be
helpfull.



PS: Of course this example also implies that each parameter's
declaration introduces a new lexical scope to its right.


Well the colloquial spec of your function is just 'it takes
two equal integers'. And the two element list (3,3) is a
subtype of it.

Regards,
--
TSa (Thomas Sandlaß)



Re: MMD vs. anonymous parameter types referencing earlier parameters

2005-06-14 Thread TSa (Thomas Sandlaß)

Chip Salzenberg wrote:

Link link.

http://www.cs.washington.edu/research/projects/cecil/www/Papers/gud.html



In case it matters, we're trying to support the Perl 6 semantics of
both ($a:$b:) and ($a,$b:).  The former looks like something that
could be implemented with something called predicate dispatch, but
the latter I'm not so sure of.


I never understood the difference. So if someone were so nice to
enlighten me...



(This also means that the type of is_equal:(...) is impossible to
express, unless I greatly misunderstand the foo:() syntax.  But
it doesn't matter what you call it if you can't call it.)


The syntax might just be:

  is_equal:(Integer $a, Integer where { $_ == $a } :)




It's a new type object every time, so every time you run that code you
get a new type object to describe $b, and therefore the type object of
the expression will never match up with the one used in the function
definition.


Hmm, looks like we have very different views of how dispatch works
and what the acting entitys are. To me is_equal is an object that
knows a set of targets basically indexed by their :() --- let's
call that the implementation signature. The call site knows the list
of parameters and is_equal. From this information a set of applicable
targets is calculated. This is the first time that the where clause
comes into play. If it returns false, that target is not considered
any further. When it returns true the closure comes into play when
the most specific target is determined. The value and type of $a are
known and as such constrain the type of $b and produce a more specific
match then an unconstrained Integer. In other words the type of $b
is a parametric, single value subtype of Integer.



Are you suggesting that type equivalence tests include introspection
into the semantics of the closure?


No. I just think that the closure is called at dispatch time as discribed
above and that this is the very moment when the instanciation of the
parametric type of $b takes place.



 If so, what is close enough?  If
not, how can Parrot ever know that

Integer where { $_ == $a }

is the same as

Integer where { $^foo == $a }

but different from

Integer where { $_ != $a }


It doesn't. The Code object stores the targets and the respective
closures.



?  Down that path lay madness.[*]


MMD becomes MAD ;)



s/the compiler/Parrot/, since the specific multi implementation can be
introduced after the call is compiled.


Yep, but the type system is still there. And you are right, that there
is no chance in pre-calculating such dispatches. But that is the expected
price to pay for predicate dispatch. And the target selector living inside
the MMD object might actually be 'recompiled' during runtime when new
instances are added. That is similar to the automata behind regular
expressions.

Regards,
--
TSa (Thomas Sandlaß)




Re: reduce metaoperator on an empty list

2005-06-09 Thread TSa (Thomas Sandlaß)

Edward Cherlin wrote:
That means that we have to straighten out the functions that can 
return either a Boolean or an item of the argument type. 
Comparison functions   = = = != should return only Booleans,


I'm not sure but Perl6 could do better or at least trickier ;)
Let's assume that   = = when chained return an accumulated
boolean and the least or greatest value where the condition was
true. E.g.

  0  2  3   returns  0 but true

  1  2  1   returns  1 but false

  4  5  2   returns  2 but false

Then the reduce versions [] and [=] naturally come out as min
and strict min respectively.

Is it correct that [min] won't parse unless min is declared
as an infix op, which looks a bit strange?

if 3 min 4 { ... }

--
TSa (Thomas Sandla)




Re: reduce metaoperator on an empty list

2005-06-09 Thread TSa (Thomas Sandlaß)

HaloO Larry,

you wrote:

: Might I add that it should read
: 
:   $var = (op.does(identval) ??

:   op.identval($value) :: undef) op $value;
: 
: The rational is, that op is subject to MMD, so the .identval method

: should be dispatched as well. Actually op.identity($value) reads
: quite natural and self documenting if the parameter is required.

I don't think there's a double dispatch there.


What do you mean with double dispatch? A single MMD on two arguments
or two dispatches after each other?



 I think op just knows
it can default its left argument to an existing attribute value if it
(somehow) knows it's part of an assignment op.  There's not a lot of
payback in getting all abstract here, as far as I can see.


Let's assume that op is overloaded for two completely unrelated types
A and B, which are both defining their respective identity elements
but !(A.identval =:= B.identval). How should the op multi method object
pick the correct one *without* looking at $value's type? Or does the
indentval role force their takers to provide all infix ops with a
test for undef args and a fallback to the respective identity value?
If that is the case, the test for the role is superfluous. Or is the
intent to enforce a unique identity value for each operator like 0 for +
and 1 for *?

There's actually a second problem. Will the op.does(identval) condition
be true or false if the op multi contains some targets with and some
without an identval?

Finally I don't understand how the knowledge about a pending assignment
eases the choice problem for the multi. Note that the choice of
assignment operator depends on the return value of the operator and
the type of which the lhs is undef.

Regards,
--
TSa (Thomas Sandlaß)




Re: return() in pointy blocks

2005-06-08 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

Says not:

   Boo
   Boo
   Boo
   ...


This is clear, but I would expect the output

   Boo
   42

because the return value of foo is a ref to a block that
makes the caller return 42. This is written in my current
Perl6 as

foo:( : -- Block -- 42)

The question is when exactly this call chain is invoked:

  1) when it is assigned to $code? Or,
  2) when postfix:( ) is invoked on $code?

I prefer 2) because it better fits my understanding of
referential semantics. About the relationship to the lazy
versus eager trade-off I'm unsure. So 1) is also a good
choice.

With this in mind, I wonder how \ and - are related. Is

  $x = 3;
  $rw = - $x;

valid syntax? And does it mean that

  $rw = 7;
  say $x; # prints 7

This can be construed as the eager version of

  $x = 3;
  $rw = - { $x };

  $rw = 7;
  say $x; # means: say $x();

A block in a chain of references is a stop mark in a chain of refs.

  $x  = 3;
  $r  = - $x;
  $rr = - $r;

  say $rr();  # prints 3, because say $r; also prints 3

  $rr = 7;
  say $r;  # prints 7
  say $x;  # prints 3

Looks like we have found a candidate for the transparent ref creator!
And I hope Juerd likes it. After all it looks *pointy* :)

PS: A chain of refs can thus be reduced to the leaf lvalue with
([()] $rr) = 23; which stores a new value in $x. This might even
warrant the special case of ([] $rr) = 23;
--
TSa (Thomas Sandlaß)



Re: reduce metaoperator on an empty list

2005-06-08 Thread TSa (Thomas Sandlaß)

Damian Conway wrote:

So, to clarify again, if $var is undefined, then the assignment:

$var op= $value;

is equivalent to:

$var = (op.does(identval) ?? op.identval() :: undef) op $value;

Correct?


Might I add that it should read

  $var = (op.does(identval) ??
  op.identval($value) :: undef) op $value;

The rational is, that op is subject to MMD, so the .identval method
should be dispatched as well. Actually op.identity($value) reads
quite natural and self documenting if the parameter is required.

Hmm, the MMD form identity( op, $value ) looks even better. This
folds the identity value selection problem back into type-space
and it's runtime agent MMD.
--
TSa (Thomas Sandlaß)



Re: return() in pointy blocks

2005-06-08 Thread TSa (Thomas Sandlaß)

Well,

does using - as blockref creator also give anonymous scalars?

$y = - $x { $x = 3; $x }; # $y:(Ref of Block of Int)

BTW, is - on the 'symbolic unary' precedence level
as its read-only companion \ ?. Are they pure macros?
--
TSa (Thomas Sandlaß)




Re: return() in pointy blocks

2005-06-08 Thread TSa (Thomas Sandlaß)

Piers Cawley wrote:

My preference is for:

Boo
Boo
Can't dereferene literal numeric literal 42 as a coderef.


How do you reach the second 'Boo'? Iff - does not create a Sub
but a Block instance then Luke's code can be interpreted as a
much smarter version of

   sub foo()
   {
   enter: 42;
   if $?RETURN_LABEL { goto $?RETURN_LABEL }
   return;
   }

say Boo!;
say goto foo::enter; # goto sets up $?RETURN_LABEL
say after goto;

which of course prints

   Boo
   42
   after goto

The smartness is in the value that prefix:{'-'} returns
while in the snippet above it is explicitly coded.

Or do I completely misunderstand the distinction between
blocks and closures?
--
TSa (Thomas Sandlaß)




Re: return() in pointy blocks

2005-06-08 Thread TSa (Thomas Sandlaß)

Piers Cawley wrote:

TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes:



Piers Cawley wrote:


My preference is for:
   Boo
   Boo
   Can't dereferene literal numeric literal 42 as a coderef.


How do you reach the second 'Boo'? Iff - does not create a Sub
but a Block instance then Luke's code can be interpreted as a
much smarter version of



I really wish you'd quote in more detail, it makes it a real PITA to go back
and find the explanatory code.  


Sorry, but I try to quote only the text that I'm really referring to,
not the transitive closure of the thread at that point. If I cut
too much here, I apologize.



sub foo () {
  return - { return 42 }
}


What I do not understand right now is, how the first
return is handled. As Luke pointed out, the inner return
inevitably makes the current invocation of foo return.
But you argue, that - suspends the current invocation
of foo and returns it as continuation. How does that fit
the pointy sub of a for loop? Is the surrounding sub
suspended as well? And then one could continue right there?

sub forfoo ()
{
   for 0..9 - $x
   {
  return $x;
   }
}

my $y = forfoo(); # suspends forfoo in first loop?

say $y; # prints 0, and suspends forfoo in second loop

say **$y; # prints the remaining invocations of forfoo?


I figure that the implementation is actually straight
forward. The pointy sub catches the return exception
and handles it by suspending forfoo and returning the
resulting continuation.



my $code =   foo();
#  ^--- continuations points to the RHS of the assignment
say Boo!;
$code();

So, this is what happens.

1. foo() returns a coderef to the RHS of the assignment.
2. The coderef gets assigned to $code.
3. say Boo!
4. We invoke the coderef, which returns 14 to continuation which was current
   when it was created.
5. That means 42 gets returned to the RHS of the assignment
6. say Boo!
7. Try to invoke the literal 42.


Hmm, I see in both cases an MMD to postfix:( ) with
the then current value of $code as invocant. In the
first run the target is postfix:( ):( Ref of Block :)
and in the second case it's postfix:( ):( Int :).
If the latter is defined to die, so be it. I opt for
just returning the value. Which produces the fallout that

$y = 42();

Is first of all valid syntax, and dispatches at runtime
unless the compiler can proof at compile time that there
can't possibly be an implementation at runtime. Thus one
could write:

multi sub *postfix:( ) ( 42 ) # or ( Int $x where $x eq '42' )
{
   return 66; # == hex 42
}

A pragma like 'use hexliterals' might actually implement a
general version of this idea.
--
TSa (Thomas Sandlaß)




Re: return() in pointy blocks

2005-06-08 Thread TSa (Thomas Sandlaß)

Piers Cawley wrote:

[..] then I think it means we can write:

sub call-with-current-continuation(Code $code) {
my $cc = - $retval { return $retval }


For the records: the return here is the essential ingredient, right?
Without it the block would be evaluated or optimized away to an undef
or some such.


$code($cc);
}

Which I personally think is rather cute.


Me too!



Even if I can't quite bring myself to
believe it's that simple... 


I have convinced myself.
How can I be of assistance on your side?
--
TSa (Thomas Sandlaß)




Re: Transparent / Opaque references

2005-06-07 Thread TSa (Thomas Sandlaß)

Juerd wrote:

$y() = 7;


No, sorry, that looks to me as if $y is a reference to an lvalue sub,
not like any form of referencing of scalars.


I think it will come naturally to the C++ and Java folks. There the
accessor kind of functions is either mapped into the name get_y()
and set_y(value), or operator () is overloaded. In the latter idiom
assignment actually becomes $y(7). Which might be a bit far out for
Perlkind. But OTOH it looks like a function call...

This idiom looks better with scalar attributes of objects:

  $obj.attr() = 7; # parser supports to drop the .()

and

  $obj.attr(7); # beware, attr becomes 7 if the class of $obj works as such

And it nicely gives:

  $y = \$obj.attr;
  $y() = 7; # dereffed assignment
  $y = 13;  # detaches from $obj.attr
  say $obj.attr; # prints 7

I'm not sure but in Perl5 the equivalent to the second line above is

  $y- = 7; # postfix - is now spelled ()

isn't it?
--
TSa (Thomas Sandlaß)



Re: (multi)subroutine names

2005-06-06 Thread TSa (Thomas Sandlaß)

Rod Adams wrote:

It used to be

   fooArray,Int
   fooHash,Int


And has become

  foo:(Array,Int)
  foo:(Hash,Int)

The return type arrow -- inside the :() type spec is not
yet approved by @Larry.


In my mind, the more interesting question is what does foo without the 
 specifiers return when foo is multi? I see the following three options:


1) undef/error, since there's no single sub called foo, and multi's need 
a postfix .


This applies only if you want to by-pass actual dispatch by
selecting a sub yourself. Otherwise foo is an instance of the
class/type MultiMethod which is a subtype of Sub and Method,
which in turn are subtypes of Code.


2) the name 'foo', and then performs in effect call by name when 
deferenced, using the dereferencing scope to determine which flavors of 
foo are available at this time, and dispatching accordingly.


I'm unsure how much the Perl6 semantics depend on name lookup
when no explicit symbolic expression ::('foo') is used. But that
aside I think the type is enough information to handle a value.
So foo is typed foo:(MultiMethod) or foo:(Ref of MultiMethod).
This latter thing is another open question on my end: the referential
semantics. E.g. are *all* plain sigil expressions :(Ref of ...) and
need an implicit or explicit dereferencer?


3) a dispatch table of all the foo's currently in scope at the time the 
reference is made.


Yes, that's it. But note that it's not a passive table that the caller
needs to handle correctly. MMD is about basing the decision which
implementation of a signature to call on the runtime types in the
argument list. Without multi this degenerates to a mere type compatibility
check for subs.

A direct extension of the above is that the type system might be able
to dynamically instanciate parametric types to fill 'gaps' dynamically.
Something like 'compilation on demand' if that is the only way to actually
instanciate a template---but I'm not sure if Perl6's parametric types are
actually called templates.


I hope that helps.
--
TSa (Thomas Sandlaß)



Re: comprehensive list of perl6 rule tokens

2005-06-02 Thread TSa (Thomas Sandlaß)

Patrick R. Michaud wrote:

Of course, there are other implicit parameters that are given
to a rule -- the target string to be matched and an initial
starting position.  But I think some of those details are still 
being worked out.  


Wasn't it said that rules have the current match object/state
as invocant? I would assume that everything else can be found
through it? Actually the mnemonics that $/ is the match and
methods on $?SELF are called with ./method fits. The only
remaining thing is to define the method set of the Match class.
--
TSa (Thomas Sandlaß)



Re: Empty hash

2005-06-02 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

Should {} be an empty hash rather than an empty code?


Does it matter? More interesting is the question what it returns
or evaluates to if it's a block. Actually with my idea of List
beeing a subtype of Code the parse time recognition of blocks
as List of Pair has no implication for the semantics! It falls
into the category of optimizations that can be performed if the
involved types can be determined at compile time.

Thus assigning that to a plain % sigiled variable expression would
kick out the previous content and store a freshly created undef
under a key calculated from the incoming undef. Which in my eyes
is pretty useless. In particular if the outcome is that +%hash == 1
instead of defining that

%hash = {};

clears the content of the hash and that +%hash == 0. But the fans
of extra levels of indirection in the @array case might like to get
a default key like '' or 0 beeing used, such that the particular
undef from the {} of the rhs of the assignment can be retrieved with
%hash00. For an arbitrary undef any non-existing index suffices :)



Why did we change { %hash } from making a shallow copy of a hash to
the code that returns %hash?


Sorry, I don't understand this question. Do you want 'shallow copy'
to mean 'take a ref'? Or Parrot/Pugs level COW?

Are you alluding to the referential semantics discussion?
--
TSa (Thomas Sandlaß)



Re: Transparent / Opaque references

2005-06-02 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

When we heard that Larry didn't acutally want $$foo to infinitely
dereference, some of us were overjoyed, and others severely
disappointed.  Both transparent dereferencing (infinite $$foo) and
opaque dereferencing (one-level $$foo) have their uses, but they are
definitely distinct.


I guess a syntax like the reduce meta operator

[$]$ref = whatever();

doesn't work for the $ sigil because it firstly is
no operator and secondly unary. So I join the single
$-single-steps-party.

Might it be applicable to use .() as the dereferencer
of scalar variables that derefs to the next none(Ref)
type and if that is a Code it dispatches to it as expected?
This nicely gives:

$x = 3
$y = \$x;

$y() = 7;

say $x;  #  prints 7

$y = 23; # detaches from $x

say $x;  # still prints 7

One detail is that lvalue subs without params
must be taken care of. But they'll have a proxy
anyway to handle assignment.

Another general thing is of course that explicitly constant Refs
shall not be applicable as a lhs of assignment. This applies to
chains of prefixed $ as well.
--
TSa (Thomas Sandlaß)



  1   2   >