Re: unusual invocants

2009-10-22 Thread Ben Morrow
Quoth tho...@sandlass.de (TSa (Thomas =?utf-8?q?Sandla=C3=9F?=)):
 
 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.

Isn't this just sugar for something like

class C does T1 does T2
{
method foo {
my $tmp = self but role { 
method x { return self.T1::x }
};
return $tmp.foo;
}

method x { ... }
}

(Excuse me if I have any syntactic details wrong.)

The most important detail here is that the *class* gets to pick which
imported methods need to be wrapped. Most of the time you want a method
x in the class to be called from a method foo in the role: that's the
point.

What this doesn't fix is that some other code (outside the class) will
be expecting C::x to have T1::x semantics, and some will be expecting it
to have T2::x semantics. If these are contradictory, there is no way to
write an x which works. That's where the 'hats' idea comes in, so you
could write something like

class C does T1 does T2
{
method T1::x { ... }
method T2::x { ... }
}

and have callers that thought they were getting a T1 call the
appropriate override. However, there's still a problem with callers that
know they have a C: which method do they get?

AFAICS the only real solution to this is something like COM, where you
say 'I would like to talk to this object as though it were a T1 now'.
Might it be possible to use the type system to make this less painful
than it usually is?

Ben



r28880 - docs/Perl6/Spec

2009-10-22 Thread pugs-commits
Author: lwall
Date: 2009-10-22 17:31:38 +0200 (Thu, 22 Oct 2009)
New Revision: 28880

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] refine global linkage policies


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-10-22 11:00:55 UTC (rev 28879)
+++ docs/Perl6/Spec/S02-bits.pod2009-10-22 15:31:38 UTC (rev 28880)
@@ -13,8 +13,8 @@
 
 Created: 10 Aug 2004
 
-Last Modified: 8 Oct 2009
-Version: 183
+Last Modified: 22 Oct 2009
+Version: 184
 
 This document summarizes Apocalypse 2, which covers small-scale
 lexical items and typological issues.  (These Synopses also contain
@@ -2067,16 +2067,43 @@
 All Perl code can see CCORE anyway as the outermost lexical scope,
 so there's no need to also put such things into CGLOBAL.
 
-The CGLOBAL package itself is rooted at CCORE::GLOBAL.
-The CPROCESS package is rooted at CCORE::PROCESS.  You will note
-that CPROCESS is not the parent of CGLOBAL.  However, searching
+The CGLOBAL package itself is accessible via CUNIT::GLOBAL.
+The CPROCESS package is accessible via CUNIT::PROCESS.
+The CPROCESS package is not the parent of CGLOBAL.  However, searching
 up the dynamic stack for context variables will look in all nested
 dynamic scopes (mapped automatically to each call's lexical scope,
-not package scope) out to CUNIT; once all the dynamic scopes are
+not package scope) out to the main dynamic scope; once all the dynamic scopes 
are
 exhausted, it also looks in the CGLOBAL package and then in the
 CPROCESS package, so C$*OUT typically finds the process's standard
-output handle.
+output handle.  Hence, CPROCESS and CGLOBAL serve as extra outer
+dynamic scopes, much like CCORE and CSETTING function as extra outer
+lexical scopes.
 
+Extra CSETTING scopes keep their identity and their nesting within CCORE,
+so you may have to go to COUTER several times from CUNIT before you get
+to CCORE.  Normally, however, there is only the core setting, in which
+case CUNIT::OUTER ends up meaning the same as CSETTING which is the same
+as CCORE.
+
+Extra CGLOBAL scopes are treated differently.  Every compilation unit has
+its own associated CUNIT::GLOBAL package.  As the currently compiling
+compilation unit expresses the need for various other compilation units,
+the global names known to those other units must be merged into the new
+unit's CUNIT::GLOBAL.  (This includes the names in all the packages
+within the global package.)  If two different units use the same global
+name, they must generally be taken to refer to the same item, but only if
+the type signatures can be meshed (and augmentation rules followed, in the
+case of package names).  If two units provide package names with
+incompatible type signatures, the compilation of the unit fails.  In other
+words, you may not use incompatible global types to provide a union type.
+However, if one or the other unit underspecifies the type in a compatible
+way, the underspecified type just takes on the extra type information as it
+learns it.  (Presumably some combination of Liskov substitution, duck-typing,
+and run-time checking will prevent tragedy in the unit that was compiled with
+the underspecified type.  Alternately, the compiler is allowed to recompile or
+re-examine the unit with the new type constraints to see if any issues are
+certain to arise at run time, in which case the compiler is free to complain.)
+
 Any context variable declared with Cour in the user's main program
 (specifically, the part compiled with CGLOBAL as the current package)
 is accessible (by virtue of being in CGLOBAL) as a context variable
@@ -2084,8 +2111,14 @@
 vars do *not* look in CCORE for anything.  (They Imight look in
 CSETTING if you're running under a setting distinct from CCORE,
 if that setting defines a dynamic scope outside your main program,
-such as for the C-n or C-p switch.)
+such as for the C-n or C-p switch.)  Context variables declared
+with Cour in the CGLOBAL or CPROCESS packages do not need to
+use the C* twigil, since the twigil is stripped before searching
+those packages.  Hence, your environment variables are effectively
+declared without the sigil:
 
+augment package GLOBAL { our %ENV; }
+
 =item *
 
 You may interpolate a string into a package or variable name using



r28881 - docs/Perl6/Spec

2009-10-22 Thread pugs-commits
Author: lwall
Date: 2009-10-22 17:55:21 +0200 (Thu, 22 Oct 2009)
New Revision: 28881

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] document desire to have decimal literals biased toward Rat storage


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-10-22 15:31:38 UTC (rev 28880)
+++ docs/Perl6/Spec/S02-bits.pod2009-10-22 15:55:21 UTC (rev 28881)
@@ -14,7 +14,7 @@
 Created: 10 Aug 2004
 
 Last Modified: 22 Oct 2009
-Version: 184
+Version: 185
 
 This document summarizes Apocalypse 2, which covers small-scale
 lexical items and typological issues.  (These Synopses also contain
@@ -2694,6 +2694,12 @@
 
 ((1 / 2) * 3) / 4
 
+Decimal fractions not using e notation are also stored as CRat values:
+
+6.02e23.WHAT # Num
+1.23456.WHAT # Rat
+1.1 == 11/100# True
+
 =item *
 
 Complex literals are similarly indicated by writing an addition of



r28882 - docs/Perl6/Spec

2009-10-22 Thread pugs-commits
Author: lwall
Date: 2009-10-22 18:21:29 +0200 (Thu, 22 Oct 2009)
New Revision: 28882

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] tweak Rat to max out at rat64 by default


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-10-22 15:55:21 UTC (rev 28881)
+++ docs/Perl6/Spec/S02-bits.pod2009-10-22 16:21:29 UTC (rev 28882)
@@ -672,6 +672,15 @@
 Numeric values in untyped variables use CInt and CNum semantics
 rather than Cint and Cnum.
 
+However, for pragmatic reasons, CRat values are guaranteed to be
+exact only up to a certain point.  By default, this is the precision
+that would be represented by a Crat64 type, that is, with a numerator
+and denominator consisting of Cint64 values.  CRats that would require
+more than 64 bits of storage in either numerator or denominator are
+automatically converted to CNums.  (If rationals are defined by a
+role, it may be possible to instantiate a CRat type with a different
+maximum precision.)
+
 =item *
 
 Perl 6 should by default make standard IEEE floating point concepts



Re: unusual invocants

2009-10-22 Thread TSa

HaloO,

Ben Morrow wrote:

Isn't this just sugar for something like


Yes it is. My intent was to lighten the burden. I think we can agree
that Ovid's problem can be solved by means of the current spec and
some support syntax could be easily added.



What this doesn't fix is that some other code (outside the class) will
be expecting C::x to have T1::x semantics, and some will be expecting it
to have T2::x semantics. If these are contradictory, there is no way to
write an x which works. That's where the 'hats' idea comes in, so you
could write something like

class C does T1 does T2
{
method T1::x { ... }
method T2::x { ... }
}

and have callers that thought they were getting a T1 call the
appropriate override. However, there's still a problem with callers that
know they have a C: which method do they get?


I have the following proposal to integrate the problem with the type
system. We simply say that roles have an invocant slot in their
type signature that is filled by the class they are composed into.
That is 'class C does R' creates the type R[C:] which is distinct
from R[A:] for 'class A does R'. These two are of course applicable
where plain R is expected because this means R[Object:] and we have
covariance in the invocant parameter.

As a limiting case the role has type R[R:] that is an empty anonymous
class with only the role composed. This can of course not be
instanciated. Using that as a constraint e.g. in a signature or a
container means that neither R[A:] nor R[C:] are applicable. However
they can implement coercion routines C::R and A::R that convert the
object and these are invoked when needed. So an extreme class might
provide coercion routines to all its roles without loosing the identity
of the object. And perhaps these might be generated automatically for
easy cases.

Consider the cartesian versus polar complex number example. Here one
provides a role Complex and two classes Cartesian and Polar that do
that role and implement conversion routines to each other. Then some
optimized multi subs might be written that require Complex[Polar:] and
Complex[Cartesian:]. Others just use Complex and are happy with both
representations.



AFAICS the only real solution to this is something like COM, where you
say 'I would like to talk to this object as though it were a T1 now'.
Might it be possible to use the type system to make this less painful
than it usually is?


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.

So a typical CPAN module might provide a role together with classes
that implement it in different ways and the users can nicely choose
between them and add their own implementations. Users and such split
modules can then use the roles and classes as bases for their own
development.

Note that this also allows more specific signatures like
foo( Order[::T:] $x, Order[T:] $y ) which guarantees comparability of
$x and $y without relying on mixed case MMD. Also we might have
explicit specializations Order[Real:] that provides , =,  and
= in addition to before and after. Likewise for Order[Str:] which
is of course not applicable to Order[Real:] without coercion of
Str to Num which does Real.

The default Rat is then just Rat[rat64:] for example. And the
instanciating class might also be defaulted lexically. Essentially
all types are then denominated in this form which uniquely identifies
a role/class combination by means of the colon in brackets after the
name.


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: r28881 - docs/Perl6/Spec

2009-10-22 Thread Eirik Berg Hanssen
pugs-comm...@feather.perl6.nl writes:

 +1.1 == 11/100# True

  New math? :)


Eirik
-- 
O misbegotten pile of festering aardvark's fewmets! O vile unwashed ill-doer!
I blast you with the curse of the mad witch of Wickham! May every boychild
born to you , and to your sons, and to your sons' sons, even unto the Seventh
Generation, be born  male! (well I told you she was mad!).


r28883 - docs/Perl6/Spec

2009-10-22 Thread pugs-commits
Author: moritz
Date: 2009-10-22 19:34:58 +0200 (Thu, 22 Oct 2009)
New Revision: 28883

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] use old school math, Eirik++

Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-10-22 16:21:29 UTC (rev 28882)
+++ docs/Perl6/Spec/S02-bits.pod2009-10-22 17:34:58 UTC (rev 28883)
@@ -2707,7 +2707,7 @@
 
 6.02e23.WHAT # Num
 1.23456.WHAT # Rat
-1.1 == 11/100# True
+0.11 == 11/100   # True
 
 =item *
 



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


r28886 - docs/Perl6/Spec

2009-10-22 Thread pugs-commits
Author: moritz
Date: 2009-10-22 23:41:42 +0200 (Thu, 22 Oct 2009)
New Revision: 28886

Modified:
   docs/Perl6/Spec/S05-regex.pod
Log:
[S05] allow multiple aliases as per IRC consesus

Modified: docs/Perl6/Spec/S05-regex.pod
===
--- docs/Perl6/Spec/S05-regex.pod   2009-10-22 19:59:04 UTC (rev 28885)
+++ docs/Perl6/Spec/S05-regex.pod   2009-10-22 21:41:42 UTC (rev 28886)
@@ -1163,6 +1163,14 @@
 
 $foo = bar
 
+Multiple aliases are allowed, so
+
+foo=pub=bar
+
+is short for
+
+$foo = $pub = bar
+
 If the first character after the identifier is whitespace, the
 subsequent text (following any whitespace) is passed as a regex, so:
 



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

2009-10-22 Thread Darren Duncan

pugs-comm...@feather.perl6.nl wrote:

Author: lwall
Date: 2009-10-22 18:21:29 +0200 (Thu, 22 Oct 2009)
New Revision: 28882

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] tweak Rat to max out at rat64 by default

Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-10-22 15:55:21 UTC (rev 28881)
+++ docs/Perl6/Spec/S02-bits.pod2009-10-22 16:21:29 UTC (rev 28882)
@@ -672,6 +672,15 @@
 Numeric values in untyped variables use CInt and CNum semantics
 rather than Cint and Cnum.
 
+However, for pragmatic reasons, CRat values are guaranteed to be

+exact only up to a certain point.  By default, this is the precision
+that would be represented by a Crat64 type, that is, with a numerator
+and denominator consisting of Cint64 values.  CRats that would require
+more than 64 bits of storage in either numerator or denominator are
+automatically converted to CNums.  (If rationals are defined by a
+role, it may be possible to instantiate a CRat type with a different
+maximum precision.)
+
 =item *
 
 Perl 6 should by default make standard IEEE floating point concepts


What is the simplest way then to ensure all your Rat math is unlimited precision 
by default, same as your Int math?  I would expect those 2 types to be 
consistent with each other in that way.


Or are Int values now also guaranteed to be exact only up to int64, and then 
automatically change to Num?


Now I can understand why you might make that change to Rat's default behaviour, 
expecially if users are getting a Rat by default simply for writing their 
numbers in a certain format like 3/4 or 1.3 and they may have actually wanted 
inexact semantics.


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.


Is that where you're going with this?

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?

If it is, then I propose the following:

1.  Have some classes like the above, eg Rat32+BigRat+Int32+BigInt etc 
pre-defined portably in the language spec, and make it so that plain Int and 
Rat are simply declared as installation-specific aliases for one of those more 
specific-named types.  These alias definitions are defined in the setting or 
something and would be defined to match the largest values that either can be 
efficiently handled on the particular platform or are likely to be needed by the 
users with exact precision.


2.  And then, people who want to be guaranteed that specific numeric semantics 
are portable across all Perl 6 implementations, with a possible hit in 
performance, would explicitly use say Rat64 or BigRat etc in their code, and 
those for whom the precise semantics don't need to be portable, can just use 
plain Rat, and know they'll get the best that the implementation thinks it can 
deliver with good efficiency.


3.  As a middle-ground, still do #1 but also let users redefine what Int and 
Rat alias on a per-program basis, so they can still choose the 64 or Big etc 
option explicitly for portable behavior, but they only have to write the plain 
Rat etc in all their code.


What do you think about that?

Note that names can change, but I think being able to do what I stated would go 
further to let more users have what they want than under-serving a large number 
in favor of another large number.


-- Darren Duncan