Re: unusual invocants
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
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
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
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
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
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
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)
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
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)
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