Re: class interface of roles
HaloO, Jonathan Lang wrote: class GenSquare does GenPoint does GenEqual { has Int $.side; method equal ( GenSquare $p -- Bool ) { return $self.GenPoint::equal($p) and $self.side == $p.side; } } This is exactly what I don't want. Such an equal method needs to be written in each and every class the role GenPoint is composed into. This is what I call a burden instead of code reuse by means of role composition. But I guess our points of view are hard to reconcile. You and the current spec see the class having the final word whereas I think that the role takes over responsibility. This does not require a telepathic compiler. Simply giving priority to the role suffices. Having the role in charge nicely matches the fact that the guarantee of doing a role makes a stronger claim than being an instance of a class. Doing the role happens with objects from different classes. And now imagine that some classes implemented equality correctly and some don't. With my approach the chance for this is diminished to a correct class specific implementation that is required and used by the role. Regards, TSa. --
Re: Synposis 26 - Documentation [alpha draft]
Tim Bunce wrote: That's going to cause pain when people using older parsers try to read docs written for newer ones. Would a loud warning plus some best-efforts fail-safe parsing be possible? Indeed. And that's a important use-case. But best-effort is difficult when you're talking about future-compatibility of core constructs, which these are supposed to be. I guess best-effort for uppercase (semantic) mark-up is just to map: =begin UNKNOWN mumble mumble mumble =end UNKNOWN to: =head1 UNKNOWN =begin para mumble mumble mumble =end para But it's harder to see how to cope with unknown all-lower directives: =begin frobnication ... =end frobnication =for franistat =wassname Especially the last of those, since it might be either an abbreviated block or a pure directive. I suspect that these should either still be fatal, or they should warn-and-ignore. Damian
Re: Synposis 26 - Documentation [alpha draft]
Jonathan Lang wrote: If I understand you correctly, the pain to which you're referring would come from the possibility of a name that's reserved by the newer version of Pod, but not by the older version. Wouldn't the simplest solution be to let a Pod document announce its own version, much like Perl can? That would presumably be: =use 6.0.2 Though it's not quite an exact analogy. If a Perl interpreter isn't recent enough, it can't really fall back on best attempt to execute a program. Code is either valid or unusable. For documentation, even if you don't know how to interpret a particular mark-up, you can always just display it as raw text and the reader can still get most of the benefit of it. It's hard to imagine a circumstance in which a refusal to render Pod: Perldoc v6.0.2 required--this is only v6.0.1, stopped at S26.pod, line 1 would be preferable to actually rendering that Pod, no matter how badly. Damian
Edge case: incongruent roles
Jack is tasked to write a role Foo. He does his job right, and produces a role that perfectly produces the set of behaviours that it's supposed to. Among other things, he defines a method Foo::baz:(). He also writes a routine, foo:( Foo ), which calls Foo::baz. Jill is tasked to write a role Bar. Bar has little if anything in common with Foo conceptually, but neither do the concepts clash with each other. She also does her job right, and produces a role that perfectly produces the set of behaviors that it's supposed to. Among other things, she defines a method Bar::baz:(). She also writes a routine, bar:( Bar ), which calls Bar::baz. These events occur entirely independant of each other. Bob decides to create a class Baz does Foo does Bar. Since the underlying concepts of the roles do not clash, he should be able to. However, because the independent designers of the roles both chose to use baz:(), a collision occurs when Bob tries this. Here's Bob's dilemma: If he resolves the collision by having Baz::baz call Foo::baz, then 'foo ( Baz )' will work properly, but 'bar ( Baz )' will do strange things. Likewise, having Baz::baz call Bar::baz will let 'bar ( Baz )' work properly, but will cause 'foo ( Baz )' to behave strangely. While Bob could write a Baz::foo method that calls Foo::baz or a Baz::bar method that calls Bar::baz, 'foo ( Baz )' or 'bar ( Baz )' wouldn't know to call Baz::foo or Baz::bar (respectively) instead of Baz::baz, and would still act strangely. It is not realistic to expect Bob to write a single routine that works properly in both cases, because the underlying concepts for Foo and Bar are so different from each other. Since Baz does both Foo and Bar, you cannot use type-checking to resolve this dilemma. The way things are now, it would appear that Bob's stuck. Short of rewriting one of ( Foo and foo ) or ( Bar and bar ) to use a different method name in place of baz, he can do nothing to resolve the syntactic collision between Foo and Bar while continuing to let foo and bar run properly. -- Thoughts? -- Jonathan Dataweaver Lang
Re: Edge case: incongruent roles
In a message dated Fri, 13 Oct 2006, Jonathan Lang writes: Since Baz does both Foo and Bar, you cannot use type-checking to resolve this dilemma. Why not? Why shouldn't this work: my Foo $obj1 = getBaz(); # object is a Baz $obj1.baz(); # Foo::baz is called my Bar $obj2 = getBaz(); # object is a Baz $obj2.baz(); # Bar::baz is called my Baz $obj3 = getBaz(); # object is a Baz $obj3.baz(); # Depends on Bob's implementation of ::Baz All three objects happen to be Baz's, yes. But the client code doesn't see them that way; the first snippet wants a Foo, the second wants a Bar. They should get what they expect, or Baz can't be said to do either. If methods are entirely dispatched *by name* (duck typing), then I agree, we have a problem. But Perl 6 supposedly supports a) multiple inheritance, b) multiple dispatch, c) traits, and d) DBC. I believe the union of those requirements means that methods must be dispatched in a more sophisticated way than just looking for a matching name. (I know a guy who works in building maintenance and also does moonlighting as a computer tech. In either of his two roles, he could be said to do windows. But what windows he does when someone asks him to do windows is disambiguated by his current role.) The way things are now, it would appear that Bob's stuck. Short of rewriting one of ( Foo and foo ) or ( Bar and bar ) to use a different method name in place of baz, he can do nothing to resolve the syntactic collision between Foo and Bar while continuing to let foo and bar run properly. Duck-typing would give you this dilemma, no question about it. But I think Perl 6 is beyond duck-typing. The dilemma only arises in the context of calling .baz on a *Baz*--and Bob hasn't written the class Baz yet. The question remaining is just one of disambiguation syntax and/or what happens when Bob chooses to do nothing about disambiguation (compile-, compose- or instantiation-time error, or some arbitrary default dispatch?). Trey -- Thoughts? --
Re: Edge case: incongruent roles
Trey Harris wrote: In a message dated Fri, 13 Oct 2006, Jonathan Lang writes: Since Baz does both Foo and Bar, you cannot use type-checking to resolve this dilemma. Why not? Why shouldn't this work: my Foo $obj1 = getBaz(); # object is a Baz $obj1.baz(); # Foo::baz is called my Bar $obj2 = getBaz(); # object is a Baz $obj2.baz(); # Bar::baz is called my Baz $obj3 = getBaz(); # object is a Baz $obj3.baz(); # Depends on Bob's implementation of ::Baz The first two cases would also depend on Bob's implementation of Baz: for dispatch purposes (single or multiple), the class' method takes precedence over the role's method. This is there so that the class can resolve disputes between roles, and so that the class can refine role behavior as appropriate. Short-cirtuiting past the class' method eliminates the latter option. Also, even if the first two cases did work as you say, how would I get $obj1 to call Bar::baz when it needs to? All three objects happen to be Baz's, yes. But the client code doesn't see them that way; the first snippet wants a Foo, the second wants a Bar. They should get what they expect, or Baz can't be said to do either. In principle, I agree; that's how it _should_ work. I'm pointing out that that's not how things work in practice according to the current documentation. (Well, 99% of the time they do; that's why this is an edge case.) If the first snippet asks for a Foo and gets handed a Baz, it receives a Baz - and then (ideally) works with those portions of Baz that behave like Foo. The problem is that roles that can be used together in theory but which conflict in practice can lead to cases where the snippet _thinks_ it's working with the Foo-like portions when it really isn't. If methods are entirely dispatched *by name* (duck typing), then I agree, we have a problem. But Perl 6 supposedly supports a) multiple inheritance, b) multiple dispatch, c) traits, and d) DBC. I believe the union of those requirements means that methods must be dispatched in a more sophisticated way than just looking for a matching name. This dilemma has nothing to do with dispatch entirely by name (which, incidently, is _not_ duck typing): even the example that I gave allowed for dispatch on the invocant (which includes multiple inheritance and access to roles), and the problem wouldn't go away if I put multi in front of the keywords, bringing MMD into play. (I know a guy who works in building maintenance and also does moonlighting as a computer tech. In either of his two roles, he could be said to do windows. But what windows he does when someone asks him to do windows is disambiguated by his current role.) Thanks for the example; this will make things more concrete. role Janitor { method do_windows() { #code } method sweep_floors() { #code } } sub clean_up ( Janitor $joe ) { $joe.do_windows(); $joe.sweep_floors(); } role Tech { method do_windows() { #code } method do_linux() ( #code } } sub program ( Tech $tom, Bool $boss_is_idiot ) { if $boss_is_idiot { $tom.do_windows() } else { $tom.do_linux() } } class Moonlighter does Tech does Janitor { method do_windows() { # } } my Moonlighter $sam; clean_up($sam); # calls Moonlighter::do_windows() program($sam, :boss_is_idiot); # calls Moonlighter::do_windows() -- Jonathan Dataweaver Lang
Re: Synposis 26 - Documentation [alpha draft]
On 10/7/06, Damian Conway [EMAIL PROTECTED] wrote: The CI formatting code specifies that the contained text is to be set in an Iitalic style I've probably been hanging around Web standards nazis for too long, but can we get a separate code to mark the title of a document that can't be linked to (say, a book) along the lines of HTML's cite tag? =begin item :term('Chttp: and Chttps:') A standard URL. For example: This module needs the LAME library (available from Lhttp://www.mp3dev.org/mp3/) =end item =begin item :termCfile: A filename on the local system. For example: Next, edit the config file (Lfile:~/.configrc). =end item =begin item :termCman: A link to the system man pages. For example: This module implements the standard Unix Lman:find(1) facilities. =end item =begin item :termCdoc: A link to some other Perldoc documentation, typically a module or core Perl documentation. For example: You may wish to use Ldoc:Data::Dumper to view the results. See also: Ldoc:perldata. =end item Actually, a couple more link schemes could probably handle my previous request: LPerl 6 and Parrot Essentials|urn:isbn:059600737X LParrot Magic Cookies in The Perl Review|urn:issn:1553667X/3/0#11 If a renderer cannot find or access the external data source for a placement link, it must issue a warning and render the URL directly in some form. For example: =begin indent BCOPYRIGHT See: /shared/docs/std_copyright.pod BDISCLAIMER See: http://www.megagigatera.com/std/disclaimer.txt =end indent Oooh, transclusion--shiny. Perhaps the pipe character can be used to provide alternative text: PSee standard copyright terms in the distribution.|file:/shared/docs/std_copyright.pod Also, what about non-textual files? If I type Phttp://www.perlfoundation.org/images/onion_64x64.png, will an onion appear in my Pod document? That would obviate custom =Image directives. Perldoc provides a mechanism by which you can extend the syntax and semantics of your documentation notation: the C=use directive. Um...how can this be made to work? Are renderers going to have to know about every possible plugin? Are plugins going to have to know about every possible renderer? Will dogs and cats be living together? C=config specifications are lexically scoped to the block in which they're specified. =config head3 :numbered =cut method foo($bar, $baz) { ... } =head3 Cfoo(RbarC, RbazC) ... Is that =head3 numbered, or is it in a different lexical scope? (Actually, I don't see any reference to =cut in this spec. Is it still there or not?) -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker
Re: Edge case: incongruent roles
On Fri, Oct 13, 2006 at 04:56:05PM -0700, Jonathan Lang wrote: : Trey Harris wrote: : All three objects happen to be Baz's, yes. But the client code doesn't : see them that way; the first snippet wants a Foo, the second wants a Bar. : They should get what they expect, or Baz can't be said to do either. : : In principle, I agree; that's how it _should_ work. I'm pointing out : that that's not how things work in practice according to the current : documentation. The current documentation already conjectures this sort of disambiguation at S12:996, I believe. Larry