Re: "Don't tell me what I can't do!"
On Wed, Oct 04, 2006 at 12:43:04PM -0700, chromatic wrote: > On Wednesday 04 October 2006 12:09, jesse wrote: > > > Perhaps I'm misunderstanding what you mean by "person writing the > > program" and "person writing the libraries." In fact, I've _gotta_ > > be. I'd like to be able to put my strictures in a library rather than > > forcing them into the main body of a program. Are you saying > > you don't want to let people do this? > > Let me rephrase. Libraries and modules can be as strict or as lax as they > like, but the program *using* those libraries and modules should always be > able to override those strictures. If you write a class in a library and > declare it as closed, that's fine -- but any program that uses the class > should always have the option of saying "Nope, not closed. I need to do > something with it." > > It's the person *using* the libraries and modules and classes who knows how > strict they need to be, how closed they need to be, and how optimized they > need to be. If any of those policies are irreversible--if they leak out of > libraries and modules and classes--then there is a problem. Ok. So, I think what you're saying is that it's not a matter of "don't let people write libraries that add strictures to code that uses those modules" but a matter of "perl should always give you enough rope to turn off any stricture imposed on you by external code." Do I have that right? > > -- c > --
Re: "Don't tell me what I can't do!"
On Wed, Oct 04, 2006 at 01:04:45PM -0700, chromatic wrote: > On Wednesday 04 October 2006 12:48, jesse wrote: > > > Ok. So, I think what you're saying is that it's not a matter of "don't let > > people write libraries that add strictures to code that uses those modules" > > but a matter of "perl should always give you enough rope to turn off any > > stricture imposed on you by external code." > > > > Do I have that right? > > Yes. You might also add "... or enable further strictures", but that sounds > like what I was trying to say. Ah. Then I'm in violent agreement. Excellent. > -- c > --
Re: class interface of roles
HaloO, Brad Bowman wrote: Sam Vilain wrote: This will be the same as requiring that a class implements a method, except the method's name is infix:<==>(::T $self: T $other) or some such. Sure. The point is, how does a role designer mix in the x and y coordinate attributes *and* augment the notion of equality to encompass these new attributes *without* shifting this burden onto the class implementor! Does the "class GenSquare does GenEqual does GenPointMixin" line imply an ordering of class composition? This would seem to be required for the super.equal hand-wave to work but part of the Traits Paper goodness came from avoiding an ordering. Composition is just order insensitive flattening. Conflicts like the equal method in the OP have to be explicitly resolved in the target class, either using aliases or fully qualified names. So there's no super needed. Hmm, my aim was more at the class composition process as such. I envision a type bound calculation for all composed roles. This bound then is available as super to all roles. Inter-role conflicts are orthogonal to this. If the bound is fulfilled the order of role composition doesn't matter. In the case of the equality checks the different participants of the composition call each other and use logical and to yield the final equality check. To the outside world the equality method appears to be a single call on the type of the objects created from the class. Note that it is type correct in the sense that all participants are considered. My hope is that this is achieved automatically as outcome of the composition process and not by intervention of the class implementor. (I should confess that I haven't yet read the OP linked article), To understand it you might actually need to read previous articles in the series, too. Regards, --
Re: RFC: multi assertions/prototypes: a step toward programming by contract
HaloO, Larry Wall wrote: Basically, all types do Package whenever they need an associated namespace. Great! This is how I imagined things to be. And the reason why the :: sigil is also the separator of namespaces. And most of the Package role is simply: method postfix:<::> () { return %.HOW.packagehash } or some such, so "$type.::" returns the symbol table hash associated with the type, if any. It's mostly just a convention that the Foo prototype and the Foo:: package are considered interchangable for most purposes. Do these namespaces also give a structural type definition in the sense of record subtyping? That is a package is a subtype of another package if the set of labels is a superset and the types of the slots available through the common labels are in a subtype relation? Regards, --
[svn:perl6-synopsis] r12736 - doc/trunk/design/syn
Author: larry Date: Thu Oct 5 11:16:58 2006 New Revision: 12736 Modified: doc/trunk/design/syn/S04.pod Log: Removed hash composers from line-ending curly rule entirely. Now a parsefail. Modified: doc/trunk/design/syn/S04.pod == --- doc/trunk/design/syn/S04.pod(original) +++ doc/trunk/design/syn/S04.podThu Oct 5 11:16:58 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 19 Aug 2004 - Last Modified: 26 Sep 2006 + Last Modified: 5 Sep 2006 Number: 4 - Version: 41 + Version: 42 This document summarizes Apocalypse 4, which covers the block and statement syntax of Perl. @@ -138,11 +138,14 @@ sub { 3 } # the statement won't terminate here ]; -However, a nested hash block must be disambiguated by a trailing comma: +However, a hash composer may never occur at the end of a line. If the +parser sees anything that looks like a hash composer at the end of +the line, it fails with "closing hash curly may not terminate line" +or some such. -# Without the trailing comma, this becomes a code block my $hash = { -1 => { 2 => 3, 4 => 5 }, +1 => { 2 => 3, 4 => 5 }, # OK +2 => { 6 => 7, 8 => 9 } # ERROR }; Because subroutine declarations are expressions, not statements,
[svn:perl6-synopsis] r12737 - doc/trunk/design/syn
Author: larry Date: Thu Oct 5 11:42:26 2006 New Revision: 12737 Modified: doc/trunk/design/syn/S04.pod Log: "Bad dates..." Modified: doc/trunk/design/syn/S04.pod == --- doc/trunk/design/syn/S04.pod(original) +++ doc/trunk/design/syn/S04.podThu Oct 5 11:42:26 2006 @@ -12,7 +12,7 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 19 Aug 2004 - Last Modified: 5 Sep 2006 + Last Modified: 5 Oct 2006 Number: 4 Version: 42
if-else and statement-ending blocks?
S04 says: A line ending with a closing brace "}", followed by nothing but whitespace or comments, will terminate a statement if an end of statement can occur there. That is, these two statements are equivalent: my $x = sub { 3 } my $x = sub { 3 }; Does this mean that if $foo == 123 { ... } else { ... } is same as if $foo == 123 { ... }; # <-- notice the semicolon here else { ... } because if-statement could end there. -- Markus Laire
Re: "Don't tell me what I can't do!"
chromatic wrote: jesse wrote: > Ok. So, I think what you're saying is that it's not a matter of "don't let > people write libraries that add strictures to code that uses those modules" > but a matter of "perl should always give you enough rope to turn off any > stricture imposed on you by external code." > > Do I have that right? Yes. You might also add "... or enable further strictures", but that sounds like what I was trying to say. Consider the following idea, bearing in mind that chromatic will probably consider it to be a waste of time and that we shouldn't hold up the release of p6 in order to develop it even if it's deemed acceptable: A 'policy' is a thing which places restrictions on what the programmer can do. Policies can be named or anonymous. Named policies can be exported. A module that exports policies is also known as a contract. As a means of making this easier, a 'contract' trait exists for modules which applies the 'export' trait to all policies found within. Proper use of policies is to define them in a contract, then import them into the appropriate lexical scope with 'use' - this lets you deport them later (using 'no') when you no longer want their restrictions. Example: module strict is contract; policy vars { ... }; # Handwavium for the definition of a policy named 'vars'. ... # EOF # somewhere in another module: use strict; # imposes all of strict's policies on this lexical scope. ... { no strict ; # rescinds the 'vars' policy within this codeblock. ... } AFAICT, this can't be done using the current toolkit, as there's nothing akin to policy definition. Compared to that, adding a 'contract' trait is trivial. Alternatively, contracts could be promoted to the same level as classes and modules, with a keyword of their own and an additional requirement that policy definition must occur within a contract. You'd still make use of a policy by importing it from a contract where appropriate, and all that would change in the above example would be that the first line would change to "contract strict;" Another benefit of this approach is that it might be possible to say that a contract is exempt from its own policies; you have to import policies from a contract in order for them to take effect. This keeps contract writers from having to abide by the policies that they're writing while they write them. -- Jonathan "Dataweaver" Lang
import collisions
What if I import two modules, both of which export a 'foo' method? IMHO, it would be nice if this sort of situation was resolved in a manner similar to how role composition occurs: call such a conflict a fatal error, and provide an easy technique for eliminating such conflicts. One such technique would be to allow the import list to rename items by means of Pairs: any Pair that occurs in the import list uses its key as the item's old name and its value as the new name. Thus, use Foo (foo => 'bar'); use Bar (:foo); would import 'foo' from 'Foo', but it would appear in the current lexical scope as 'bar'. Likewise, it would import 'foo' from Bar, but would rename it as 'baz'. Another possibility would be to supply a substitution rule that transforms the names. -- Jonathan "Dataweaver" Lang
Hash composers and code blocks
S04 now reads: == However, a hash composer may never occur at the end of a line. If the parser sees anything that looks like a hash composer at the end of the line, it fails with "closing hash curly may not terminate line" or some such. my $hash = { 1 => { 2 => 3, 4 => 5 }, # OK 2 => { 6 => 7, 8 => 9 } # ERROR }; == I think this is a bit of a problem, since it leads to a number of "looks fine to the uninitiated" errors, and is likely output from code generators. In general, there's just no particularly good answer to "why can't I do that?" So, why not provide an unambiguous form for all of the sigiled types, leaving {...} as the ambiguous, half-cousin? (note: I don't think I'm the first to suggest this) Proposal: A sigil followed by [...] is always a composer for that type. %[...] - Hash. Unicode: ⦃...⦄ @[...] - Array. Unicode: [...] ? - Seq. Unicode: ⎣...⎤ &[...] - Code. Unicode: ⦕...⦖ |[...] - Capture. Identical to \(...). Unicode: ⦇...⦈ $[...] - Scalar. Identical to item(value). Unicode: ⦋...⦌ #[...] - A comment. Just seeing if you're paying attention ;) So, construction of an anonymous data structure might now look like: my $hash = %[ 1 => %[ 2 => 3, 4 => 5 ], 2 => @[ 6 => 7, 8 => 9 ], 3 => &[ %[ 10 => 11, 12 => 13 ] ] ]; Which is also: my $hash = ⦃ 1 => ⦃ 2 => 3, 4 => 5 ⦄, 2 => ⟦ 6 => 7, 8 => 9 ⟧, 3 => ⦕ ⦃ a => 1, b => 2 ⦄ ⦖ ⦄; And there is exactly no ambiguity. You can always use the old {...} if you like: my $hash = { 1 => { 2 => 3, 4 => 5 }, 2 => [ 6 => 7, 8 => 9 ], 4 => { { a => 1, b => 2 }; } }; And you get whatever confusion you deserve (I don't even know if that would do what I think it should, to be honest). As always, I tend to prefer any solution that involves placing the disambiguating bits in the FRONT, rather than at the end. I would expect that compiler-writers feel similarly.
Re: import collisions
Jonathan Lang wrote: What if I import two modules, both of which export a 'foo' method? That's always fine unless they have exactly the same signature. In general, that's not going to happen because the first parameter is created from the invocant. Thus: use HTML4; use Math::BigFloat; should give me a: # A divide-by-string form. Who knows why. our Math::BigFloat multi method div(Math::BigFloat $self: Str $divisor) is export {...} # Generate an HTML block that contains self + new content our HTML4 multi method div(HTML4 $self: Str $more) is export {...} When exported these do not conflict. Only plain multis would conflict: module A; our Str multi foo(Str $x) is export {...} module B; our Str multi foo(Str $x) is export {...} IMHO, it would be nice if this sort of situation was resolved in a manner similar to how role composition occurs: call such a conflict a fatal error, and provide an easy technique for eliminating such conflicts. I think that should probably be a warning under "use warnings", and otherwise ignored. You asked for the modules in a particular order, and that's the way they were merged. Overlaps are bound to happen sometimes. use Foo (foo => 'bar'); use Bar (:foo); That's an advisory, of course, requesting that aliases be created, but how much work that does depends on how many signatures are defined for each name. You could still call Foo::foo, of course, but yeah, this makes fine sense.
Re: Hash composers and code blocks
Aaron Sherman wrote: Proposal: A sigil followed by [...] is always a composer for that type. %[...]- Hash. Unicode: ⦃...⦄ @[...]- Array. Unicode: [...] ... I left out ::, which is probably a mistake. Part of the elegance of this, IMHO, is that it behaves the same for all sigils. The body of :: should probably be a capture whose invocant (required) is a type name: ::[Foo: 1,2,:x<3>,:y<4>] Which is identical to: Foo.new(1,2,:x<3>,:y<4>) Unicode for that seems like overkill, but if we needed it, ⦗...⦘ would suffice. Thus: ⦗Foo: 1,2,:x<3>,:y<4>⦘ That gives me the visual sense that something big and heavy is being created ;-)
Re: Hash composers and code blocks
On 10/5/06, Aaron Sherman <[EMAIL PROTECTED]> wrote: Proposal: A sigil followed by [...] is always a composer for that type. %[...] - Hash. Unicode: ⦃...⦄ @[...] - Array. Unicode: [...] ? - Seq. Unicode: ⎣...⎤ &[...] - Code. Unicode: ⦕...⦖ |[...] - Capture. Identical to \(...). Unicode: ⦇...⦈ $[...] - Scalar. Identical to item(value). Unicode: ⦋...⦌ #[...] - A comment. Just seeing if you're paying attention ;) Are those supposed to be question marks up there (meaning "up for discussion"), or did something go awry in the email encoding (possibly on my end)? -- Mark J. Reed <[EMAIL PROTECTED]>
Re: Hash composers and code blocks
Mark J. Reed wrote: On 10/5/06, Aaron Sherman <[EMAIL PROTECTED]> wrote: Proposal: A sigil followed by [...] is always a composer for that type. %[...] - Hash. Unicode: ⦃...⦄ @[...] - Array. Unicode: [...] ? - Seq. Unicode: ⎣...⎤ &[...] - Code. Unicode: ⦕...⦖ |[...] - Capture. Identical to \(...). Unicode: ⦇...⦈ $[...] - Scalar. Identical to item(value). Unicode: ⦋...⦌ #[...] - A comment. Just seeing if you're paying attention ;) Are those supposed to be question marks up there (meaning "up for discussion"), or did something go awry in the email encoding (possibly on my end)? There is one occurance of ? in there (Seq has no sigil, and thus no [...] form). The rest are Unicode characters, and my headers did include: Content-Type: text/plain; charset=UTF-8; format=flowed so, I don't think there's a problem there... still, what Unicode characters are chosen (if any) is rather moot. The real issue is: do we want to have a disambiguated composer form, and if so is [...] the right choice?
Updated: Re: Hash composers and code blocks
Aaron Sherman wrote: (updated based on followup conversations) Proposal: A sigil followed by [...] is always a composer for that type. %[...]- Hash. @[...]- Array. &[...]- Code. |[...]- Capture. Identical to \(...). $[...]- Scalar. Like item(...), but forces copying even in argument lists Added after: ::[Type:...] fglock pointed out that @(...), %(...) actually already do this. I was going to modify this proposal around that, but then I looked at the variations. I now contend that (...) has more of a "cast" semantic than a "compose" semantic. If we wish to combine the two, then we could, but that would require that &(...) take a block body, not an expression (again, not what &(...) does now, at all). In the end, I still think the bracket forms are a wonderfully simple solution to the ambiguity problem, and I'm more convinced every time I look at this that the ambiguity needs a fix. What's more, having one syntax for composition of container and non-container types in free-form data structures is tremendously appealing. We've thrown out ${...}, so we could use that instead of brackets, but that's just one more shift-key, and it doesn't seem to buy much. Am I wrong? fglock also suggested that this might not be seen by the community as "looking like perl." I'm not so sure that's the case, since we already have @(...) and @{...}, but even if some do feel that way, I AM NOT proposing that we eliminate any currently correct behavior. I am only suggesting that we add "one more way to do it" for those of us who want to dodge the ambiguity. Surely, that's not a big request? To sum up: (...) - cast expression ... to type implied by sigil [...] - composition of type implied by sigil Nice and uniform, no?