Re: syntax for accessing multiple versions of a module
On Tue, Oct 18, 2005 at 07:38:19PM -0400, Stevan Little wrote: : Then this is added as "Dog-0.0.2-cpan:LWALL" into the main symbol : table. Then once the compilation process is complete, I traverse the : symbol table hierarchy collecting all the names. Any duplicate short : names (Dog) are noted for later. Once I have collected all the names, : I build all my aliases. : : So if I find: : : use Cat-0.0.1-cpan:JRANDOM; : : only once, I build an alias for (at a minimum) "Cat" and "Cat-0.0.1". But you have to have the aliases there for correct parsing. Otherwise "Cat" is a bareword, which is illegal. Of course, you can add the alias without deciding what to bind it to. In fact, within a method, we require "Cat" to be considered a virtual name, so if a derived class uses a different Cat, it means that one instead for this object. : For my duplicates, the table would look something like this I think: : : Dog => Dog-1.2.1-cpan:JRANDOM : Dog-1.2.1 => Dog-1.2.1-cpan:JRANDOM : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : We are explictly giving the preference to the later version number (I : think we discussed this at the Toronto hackathon). Hmm, don't remember that. But I have a bad memory. : Another school of thought would be that "Dog" alone would be : considered ambiguious and so we would just alias far enough to be : clear, like this: : : Dog => Ambiguity Error! : Dog-1.2.1 => Dog-1.2.1-cpan:JRANDOM : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : Of course, this means that if I also load "Dog-1.2.1-cpan:LWALL" that : the table looks like this: : : Dog => Ambiguity Error! : Dog-1.2.1 => Ambiguity Error! : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : And the user is now forced to add the cpan id to get Dog-1.2.1. I am : not sure how strict @Larry wants this to be. I think $Larry wants to be strict on this, at least this week. If you're using two different versions explicitly within the same scope, you should probably be required to alias one of them. The main purpose of version co-existence is for different modules to use different versions, not the same module. I think using two different versions from the same module is going to be relatively rare. Larry
Re: Re(vised): Proposal to make class method non-inheritable
On Tue, Oct 18, 2005 at 04:43:57PM +0200, Juerd wrote: : dot sigils are not actually special. They are required on has-variables : and forbidden on all other. Changing them to be optional is trivial, or : so I hope. Dot sigils drive accessor generation, which essentially hoists an ordinary variable into the object's namespace. They are not just commentary. : (I believe that sigils or twigils should not indicate scope, duration or : type. The distinctin between the major variable types is useful, further : distinction is not.) Eh? Sigils are for type, twigils are precisely for doing weird things with scope or duration. * global scope + currently compiling scope ? currently compiled scope = current file/pod scope < current $/ scope ^ current signature scope : make $:foo equivalent to :foo($foo) (conjectural) Larry
Re: Re(vised): Proposal to make class method non-inheritable
Larry Wall skribis 2005-10-19 1:43 (-0700): > On Tue, Oct 18, 2005 at 04:43:57PM +0200, Juerd wrote: > : dot sigils are not actually special. They are required on has-variables > : and forbidden on all other. Changing them to be optional is trivial, or > : so I hope. > Dot sigils drive accessor generation, which essentially hoists an > ordinary variable into the object's namespace. They are not just > commentary. "has" can do this without the dot, in theory. > : (I believe that sigils or twigils should not indicate scope, duration or > : type. The distinctin between the major variable types is useful, further > : distinction is not.) > Eh? Sigils are for type, twigils are precisely for doing weird things > with scope or duration. This doesn't change how I feel about them, though :) Still, I do like twigils for automatically existing variables, like %*ENV and &?SUB. Here, I do see the need and use for indicating scope and duration, but I mostly read the twigil as: this variable is /special/. Global scope needs a twigil because in most cases, the declaration would be nowhere to be found. Declaring superglobals doesn't necessarily make sense anyway. The ^ twigil is needed for the same reason: declaration is implicit. Object attributes are declared by the Perl coder and initialized by code. I know where they come from, and if not, I can look it up very easily. There is no twigil for "my" and "our" variables, and we don't need any. Same for "has": declaration is explicit. > : make $:foo equivalent to :foo($foo) (conjectural) This one is new to me. I'm not sure I understand what it's used for. Is there already some documentation about it? And does this mean $:foo is no longer a private $.foo? (which could be a very good thing, by the way) What replaces that? Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Re(vised): Proposal to make class method non-inheritable
On Wed, Oct 19, 2005 at 12:33:11PM +0200, Juerd wrote: : > : make $:foo equivalent to :foo($foo) (conjectural) : : This one is new to me. I'm not sure I understand what it's used for. Is : there already some documentation about it? It's in my copy of S06, which I haven't checked in yet. By the way, the form is intended to work in either signatures or as an rvalue, and in signatures replaces + to mark named args. + becomes the marker for required attributes (assumed on initial positional args). : And does this mean $:foo is no longer a private $.foo? (which could be a : very good thing, by the way) What replaces that? The absence of a dot creates a private attribute. We decided it should be even easier to declare a private attribute than a public one, so it's just has $foo; and then it is visible only in the lexical scope. Larry
Re: syntax for accessing multiple versions of a module
Larry Wall: > I think using two different versions from the same > module is going to be relatively rare. For dealing with two generations at the same time, like with conversions: in stead of designing and applying a patch (SQL's ALTER COLUMN, etc.), create a new dataset and let the old information pour in. -- Grtz, Ruud
Re: Re(vised): Proposal to make class method non-inheritable
Larry Wall skribis 2005-10-19 4:03 (-0700): > The absence of a dot creates a private attribute. We decided it should > be even easier to declare a private attribute than a public one, so it's > just > has $foo; > and then it is visible only in the lexical scope. This takes away my objections to the dot twigil entirely. Juerd -- http://convolution.nl/maak_juerd_blij.html http://convolution.nl/make_juerd_happy.html http://convolution.nl/gajigu_juerd_n.html
Re: Translitteration and combining strings and array references
HaloO, Luke Palmer wrote: It looks nicer if you use the indirect object form: trans "string": [ => "0", ]; Given the right interpretation this just looks like a typed label selection in a multi method. multi trans { Str $x: ...; return; Int $x: ...; return; ...; return; } Is this definitional form supported? To me it nicely unifies the indirect object syntax---and postfix colon in general---with labels. --
Re: Re(vised): Proposal to make class method non-inheritable
On Wed, Oct 19, 2005 at 04:03:54AM -0700, Larry Wall wrote: > : This one is new to me. I'm not sure I understand what it's used for. Is > : there already some documentation about it? > > It's in my copy of S06, which I haven't checked in yet. Is there an AES commit feed available somewhere? -- Gaal Yahas <[EMAIL PROTECTED]> http://gaal.livejournal.com/
Re: Translitteration and combining strings and array references
HaloO, Juerd wrote: Luke Palmer skribis 2005-10-18 11:57 (-0600): It looks nicer if you use the indirect object form: trans "string": [ => "0", ]; It'd also look very nice with optional parens: "string".trans [ => "0" ]; Or is it not yet time to resuggest that? :) I like it. Given enough Meta Information---namely the structural arrow type---the .trans could be parsed as postfix op that returns a prefix op. Otherwise you get a 'two terms in a row' *syntax* error! (($ &) $) The left item is actually calculated at compile time from string interpolation. The $ on the right is an itemized pair. Further expanded we get ((&.($) & :$) or perhaps (&.($).&.(:$) BTW, lets assume the non-invocant param of .trans were called $foo. Would in the above case +($foo.key) == 2? And I guess the parens could be dropped because .key binds tighter than prefix:<+>, right? I mean the type of the key in the pair is an array of compile time strings. Or is that not preserved? --
Re: syntax for accessing multiple versions of a module
Larry, On Oct 19, 2005, at 4:10 AM, Larry Wall wrote: On Tue, Oct 18, 2005 at 07:38:19PM -0400, Stevan Little wrote: : Then this is added as "Dog-0.0.2-cpan:LWALL" into the main symbol : table. Then once the compilation process is complete, I traverse the : symbol table hierarchy collecting all the names. Any duplicate short : names (Dog) are noted for later. Once I have collected all the names, : I build all my aliases. : : So if I find: : : use Cat-0.0.1-cpan:JRANDOM; : : only once, I build an alias for (at a minimum) "Cat" and "Cat-0.0.1". But you have to have the aliases there for correct parsing. Otherwise "Cat" is a bareword, which is illegal. Of course, you can add the alias without deciding what to bind it to. In fact, within a method, we require "Cat" to be considered a virtual name, so if a derived class uses a different Cat, it means that one instead for this object. I suppose this could be done earlier in the compilation process then, possibly we can make assumptions along the way and alias short names immediately, only to retract the alias later if we see something that conflicts. Assuming we do not encounter any user-level aliasing, I think this would probably be okay. However, this brings up an issue I was thinking about. Take this code for instance: use Cat-0.0.1; use PetStore; my Cat $kitty .= new(); --- in PetStore.pm --- use Dog; use Cat-0.0.5; Which Cat is used? I can see several options: 1) Cat-0.0.1 is used since it is in the local scope, so clearly the users choice. 2) Cat-0.0.5 is used since it is loaded after Cat-0.0.1. 3) An Ambiguity error is thrown because "Cat" is not specific enough. Any option other than 1 requires the user to know what is going on within PetStore. : For my duplicates, the table would look something like this I think: : : Dog => Dog-1.2.1-cpan:JRANDOM : Dog-1.2.1 => Dog-1.2.1-cpan:JRANDOM : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : We are explictly giving the preference to the later version number (I : think we discussed this at the Toronto hackathon). Hmm, don't remember that. But I have a bad memory. To be honest, I am not sure who I discussed it with, it might have been autrijus. Either way it was in the early days of the hackathon, and being a not-so-exciting topic, it was quickly forgotten about for much cooler topics :) To be honest, I don't really like this approach anyway. : Another school of thought would be that "Dog" alone would be : considered ambiguious and so we would just alias far enough to be : clear, like this: : : Dog => Ambiguity Error! : Dog-1.2.1 => Dog-1.2.1-cpan:JRANDOM : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : Of course, this means that if I also load "Dog-1.2.1-cpan:LWALL" that : the table looks like this: : : Dog => Ambiguity Error! : Dog-1.2.1 => Ambiguity Error! : Dog-0.0.2 => Dog-0.0.2-cpan:LWALL : : And the user is now forced to add the cpan id to get Dog-1.2.1. I am : not sure how strict @Larry wants this to be. I think $Larry wants to be strict on this, at least this week. Horray! If you're using two different versions explicitly within the same scope, you should probably be required to alias one of them. The main purpose of version co-existence is for different modules to use different versions, not the same module. I think using two different versions from the same module is going to be relatively rare. Well, the first thing that comes to mind is that you could create a "best-of-both-worlds" proxy object/module. Say some insane CPAN developer radically changes an API, some of the changes make senses, some of the changes clearly illustrate the developers insanity. It might be useful to be able to create some kind of mix-up of the two module versions in which you alias part of each API (assuming they can co-exist peacefully that is). Sure it's an out-on-the-edge case, but I could see some possible usefulness. Stevan
Re: syntax for accessing multiple versions of a module
On Wed, Oct 19, 2005 at 12:59:34PM +0200, Ruud H.G. van Tol wrote: : Larry Wall: : : > I think using two different versions from the same : > module is going to be relatively rare. : : For dealing with two generations at the same time, like with : conversions: in stead of designing and applying a patch (SQL's ALTER : COLUMN, etc.), create a new dataset and let the old information pour in. Yes, that's the use case I was thinking of. But I think version collisions will happen much more often by accident, when two different modules use different versions of the same module. Larry
Re: syntax for accessing multiple versions of a module
On Wed, Oct 19, 2005 at 09:33:39AM -0400, Stevan Little wrote: > However, this brings up an issue I was thinking about. Take this code > for instance: > > use Cat-0.0.1; > use PetStore; > > my Cat $kitty .= new(); > > --- in PetStore.pm --- > > use Dog; > use Cat-0.0.5; > > Which Cat is used? I can see several options: > > 1) Cat-0.0.1 is used since it is in the local scope, so clearly the > users choice. > > 2) Cat-0.0.5 is used since it is loaded after Cat-0.0.1. > > 3) An Ambiguity error is thrown because "Cat" is not specific enough. I would be _highly_ surprised if my $kitty wasn't a Cat-0.0.1 (assuming these auto aliases happen). Which Cat is available to the programmer is a lexical property that shouldn't be invalidated because some other module decided to use a different Cat. That would *so* be action at a distance. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: syntax for accessing multiple versions of a module
On Wed, Oct 19, 2005 at 09:33:39AM -0400, Stevan Little wrote: : On Oct 19, 2005, at 4:10 AM, Larry Wall wrote: : >On Tue, Oct 18, 2005 at 07:38:19PM -0400, Stevan Little wrote: : >: Then this is added as "Dog-0.0.2-cpan:LWALL" into the main symbol : >: table. Then once the compilation process is complete, I traverse the : >: symbol table hierarchy collecting all the names. Any duplicate short : >: names (Dog) are noted for later. Once I have collected all the : >names, : >: I build all my aliases. : >: : >: So if I find: : >: : >: use Cat-0.0.1-cpan:JRANDOM; : >: : >: only once, I build an alias for (at a minimum) "Cat" and : >"Cat-0.0.1". : > : >But you have to have the aliases there for correct parsing. Otherwise : >"Cat" is a bareword, which is illegal. Of course, you can add the : >alias without deciding what to bind it to. In fact, within a method, : >we require "Cat" to be considered a virtual name, so if a derived : >class uses a different Cat, it means that one instead for this object. : : I suppose this could be done earlier in the compilation process then, : possibly we can make assumptions along the way and alias short names : immediately, only to retract the alias later if we see something that : conflicts. Assuming we do not encounter any user-level aliasing, I : think this would probably be okay. Yes, especially if the result of a collision is somewhat fatal, so we don't really have to try to undo anything. Another reason for taking the strict line. : However, this brings up an issue I was thinking about. Take this code : for instance: : : use Cat-0.0.1; : use PetStore; : : my Cat $kitty .= new(); : : --- in PetStore.pm --- : : use Dog; : use Cat-0.0.5; : : Which Cat is used? I can see several options: They alias Cat differently in their lexical scope. $kitty is a version 0.0.1 kitty. If $kitty is is passed into PetStore, methods on it still call into Cat-0.0.1. If PetStore makes a new cat, it's a 0.0.5 cat. Whether different versions of cat are interconvertable probably depends on whether 0.0.5 supplies the appropriate conversion functions for earlier versions of Cat. Possibly these can be assumed in some cases, such as when the attribute list hasn't changed. : 1) Cat-0.0.1 is used since it is in the local scope, so clearly the : users choice. : : 2) Cat-0.0.5 is used since it is loaded after Cat-0.0.1. : : 3) An Ambiguity error is thrown because "Cat" is not specific enough. 4) The Cat alias is lexically scoped, and two different scopes can have two diffferent aliases. : Any option other than 1 requires the user to know what is going on : within PetStore. I think it just requires that later versions of Cat know how to deal with earlier versions. : >If you're using two different versions explicitly within the same : >scope, you should : >probably be required to alias one of them. The main purpose of : >version : >co-existence is for different modules to use different versions, not : >the same module. I think using two different versions from the same : >module is going to be relatively rare. : : Well, the first thing that comes to mind is that you could create a : "best-of-both-worlds" proxy object/module. Say some insane CPAN : developer radically changes an API, some of the changes make senses, : some of the changes clearly illustrate the developers insanity. It : might be useful to be able to create some kind of mix-up of the two : module versions in which you alias part of each API (assuming they : can co-exist peacefully that is). : : Sure it's an out-on-the-edge case, but I could see some possible : usefulness. Well, sure, I'm not trying to disallow it, just re-Huffmanize it. The explicit aliasing mechanism (using :as, perhaps) should be sufficient to handle the marginal cases without complicating the implicit aliasing mechanism. The exporter is already in the business of aliasing various names into the current namespace, so making it alias the whole module is no big deal. No need for extra built-in syntax. Larry
Class Methods are inheritable
Just an FYI to anyone who is interested. I have implemented the basic Eigenclass structure into the most recent meta-model prototype. It basically looks like this: Class ^ : eFoo<...eBar ^ ^ | | Foo<...Bar This allows for completely inheritable class methods. However, this does have an impact on the use of custom meta-classes (see the "Custom Metaclass and Inheritance of Class Methods" thread for more detail), as well as a speed impact (class creation is now more expensive because the eigenclass needs to be explicitly created for each class in order to deal with inheritance properly). As I said in the svn commit message, it is currently in the "get it working" stage, I will now clean it up and hopefully speed it up. Stevan
Fwd: top 5 list needed
> > Text-substitution macros would have to be handled in an earlier pass, > > I still don't see evidence for this. Or maybe I do, but I don't see > any reason that the preprocessing pass must finish before the parsing > begins. Mixing C and Perl ... my $foo; BEGIN { $foo = '}'; } #define OPEN { #define CLOSE $foo void main (void) OPEN BEGIN { $foo = '{''; } printf( "I don't work\n" ); CLOSE How does that work out? The issue is that you can interrupt the parsing process with executable code that can affect the parsing. That's a good thing. It doesn't work so well with text-substitution, though. Hence, I would argue it should be disallowed. Rob
Re: Fwd: top 5 list needed
> "RK" == Rob Kinyon <[EMAIL PROTECTED]> writes: >> > Text-substitution macros would have to be handled in an earlier pass, >> >> I still don't see evidence for this. Or maybe I do, but I don't see >> any reason that the preprocessing pass must finish before the parsing >> begins. RK> Mixing C and Perl ... RK> my $foo; RK> BEGIN { $foo = '}'; } RK> #define OPEN { RK> #define CLOSE $foo RK> void main (void) RK> OPEN RK> BEGIN { $foo = '{''; } RK> printf( "I don't work\n" ); RK> CLOSE RK> How does that work out? The issue is that you can interrupt the RK> parsing process with executable code that can affect the parsing. RK> That's a good thing. It doesn't work so well with text-substitution, RK> though. Hence, I would argue it should be disallowed. from S06: Macros (keyword: macro) are routines whose calls execute as soon as they are parsed (i.e. at compile-time). Macros may return another source code string or a parse-tree. i see uses for text macros. sure they can trip you up but that is going to be true about AST macros as well. macros are inherently trickier than plain coding as you are dealing with another level at the same time. so the author of your bad example should learn how to do that correctly and not expect perfect DWIMMERY with an advanced technology. and that excerpt also means that p6 macros are not done in a preprocessing pass but at normal compile time as soon as the macro call is fully parsed. so a text returning macro would run and the compiler will replace the text of the parsed macro call and start reparsing with the returned text. there may be some juggling of the main parse tree to deal with this but it can be done without going too insane. :) uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org
S29 problems and plan/TODO
Yesterday, the spam filters on p6l didn't like me, but that's all been fixed. So, on to the good stuff I've been consumed by work for a while, but every time I return to the S29 work I have the same problem: p6l is a constantly bubbling cauldron of ideas, proposals, decisions, reversals, modifications, etc. My list circa earlier this year of "top priority" messages that needed to be incorporated was long, and over the summer and early fall it has grown substantially, and I haven't even had the time to fully compile a TODO list before it becomes obsolete. If I'm to finish this, I have to draw a line in the sand, and say, "these are the dates of authority, and these are the people who I'm going to pay attention to." I thus propose 2005-03-16 (last Rod Adams update) - 2005-10-17 (yesterday, yes that's arbitrary) on the mailing list and pugs/ext from svn as of revision 7682 as the inputs for the next revision of S29. I'll compile a TODO list based on that range and produce a new draft of S29. As for who: I intend to take any proposed modification to existing Perl 5 builtins, the builtins that are already in S29 and a select few others that seem to be intended for such a document from any of the following (and, of course, from anyone that the following people responded to in favor of such a proposal): Luke Palmer <[EMAIL PROTECTED]> chromatic <[EMAIL PROTECTED]> Nicholas Clark <[EMAIL PROTECTED]> Larry Wall <[EMAIL PROTECTED]> Autrijus Tang <[EMAIL PROTECTED]> Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]> Chip Salzenberg <[EMAIL PROTECTED]> Damian Conway <[EMAIL PROTECTED]> That seems like a suitably long list of messages to grovel through (around 900). Before I re-re-embark on this task, does anyone have any comments or concerns? Some thoughts for digestion: * S29 as it stood last has made several assumptions about the nature of the type/object system that will accompany it. As a second and third pass, it will probably make sense to create a separate document that lays out the core types/classes that S29 needs and then to come back and revise S29 to reflect the changes that were required. * As stated previously, the line between operators and builtin functions in P6 is blurry. * Note that A14, A16 and A17 currently block the resolution of some issues (see the Pending Apocalypse section of the current draft). If someone would give me commit rights on the pugs svn, I'll probably fork a separate "docs/AES/S29draft.pod" as "docs/AES/S29working.pod" so that others can actively collaborate rather than just waiting for a final product, and replace the draft once it's actually in a consistent state. Otherwise, I'd have to muck around with branching, and I'd rather not. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback
Re: syntax for accessing multiple versions of a module
Stevan Little wrote: Nicholas, This is addressed in S11, here is a link: http://search.cpan.org/~ingy/Perl6-Bible/lib/Perl6/Bible/S11.pod To summarize, the syntax to load the modules is: use Dog-1.2.1; While the syntax to create a specific version of a module is: my Dog-1.3.4-cpan:JRANDOM $spot .= new("woof"); I'd really like to see a more extensible syntax for this. So: use Dog 1.2.1; # ala Perl5 And then to extend: use Dog { version => 1.2.1, cpanid => 'JRANDOM' }; This would allow arbitrary specifications, ie: use Dog { interface => 0.2, version => ['>=', 1.2.1], company => 'Sun Microsystems' }; I addresses the class creation syntax partially in the initial version of the Metamodel prototype, which was built in p5. I basically just aliased the package with the long name (%{"Dog-1.3.4- cpan:JRANDOM::"} = %{"Dog::"}). However this does no good for loading of modules. Building off the above: %{Dog}{1.2.1}{JRANDOM} Or some such, with the longest-matching object winning. -Nate
Re: S29 problems and plan/TODO
On Wed, 2005-10-19 at 16:07, Aaron Sherman wrote: > I thus propose 2005-03-16 (last Rod Adams update) - 2005-10-17 > (yesterday, yes that's arbitrary) on the mailing list and pugs/ext from > svn as of revision 7682 as the inputs for the next revision of S29 s{pugs/ext}{pugs/t/builtins} for the most part, though some items in pugs/ext are germane. Sorry about that slip-up.
Re: syntax for accessing multiple versions of a module
On Wed, Oct 19, 2005 at 01:30:07PM -0700, Nate Wiger wrote: : Stevan Little wrote: : >Nicholas, : > : >This is addressed in S11, here is a link: : > : > http://search.cpan.org/~ingy/Perl6-Bible/lib/Perl6/Bible/S11.pod : > : >To summarize, the syntax to load the modules is: : > : > use Dog-1.2.1; : > : >While the syntax to create a specific version of a module is: : > : > my Dog-1.3.4-cpan:JRANDOM $spot .= new("woof"); : : I'd really like to see a more extensible syntax for this. So: : :use Dog 1.2.1; # ala Perl5 : : And then to extend: : :use Dog { version => 1.2.1, cpanid => 'JRANDOM' }; : : This would allow arbitrary specifications, ie: : :use Dog { interface => 0.2, : version => ['>=', 1.2.1], : company => 'Sun Microsystems' :}; : : >I addresses the class creation syntax partially in the initial version : >of the Metamodel prototype, which was built in p5. I basically just : >aliased the package with the long name (%{"Dog-1.3.4- cpan:JRANDOM::"} = : >%{"Dog::"}). However this does no good for loading of modules. : : Building off the above: : :%{Dog}{1.2.1}{JRANDOM} : : Or some such, with the longest-matching object winning. Well, we thought about opening it up like that, but we really kinda need to establish what is an official part of the "long name" for uniqueness purposes, and try to avoid too much visual clutter in standard usage. That being said, you can certainly add additional search constraints on a "use" by passing adverbs, but those aren't counted as part of the official long name. And we do leave the meaning of "naming authority" open, so that part is still subject to extension, and that's one reason we put the naming authority at the end. We could even add more hypthenated fields if they were deemed to be of universal significance. Larry
Autogenerated MetaModel Diagrams
Hey all, I was messing around with GraphViz today and wrote a quick hack to autogenerate class diagrams using the reflective capabilities of the metamodel prototype. I put some of the more interesting diagrams online, you can view them here: http://perlcabal.org/~stevan/mm_viz/index.html Enjoy! Stevan
Re: syntax for accessing multiple versions of a module
Larry Wall wrote: Well, we thought about opening it up like that, but we really kinda need to establish what is an official part of the "long name" for uniqueness purposes, and try to avoid too much visual clutter in standard usage. Going with that... I would think that the "official" part is really just the module name. Are there lots of problems with CPAN collisions between different authors? No. People just choose a slightly different name if their preferred one is taken. It seems the biggest problem is requiring *only* a specific version, or range of versions, or <= a version. I know this is addressed already. Not trying to rant (really), but one thing that is starting to bother me about Perl 6 is that there's lots of changes that require special syntax for one specific instance. It's making it really really difficult to remember or generalize, two things that I thought we were trying to improve. -Nate
subclassing associated classes elegantly
I'm in a long-standing situation with my module development where I want to design a set of associated classes such that invocations of submethods or class methods, such as new(), of one class by another class continue to work as expected when any or all of those classes is subclassed. I have a solution already that works, but I'm looking for the most optimal solution. An example of when this situation can arise is if person X implements a simplified XML DOM implementation using 2 classes, Document and Node, that work together, where one of those classes (Document) can create objects of the other (Node), and person Y wants to subclass the XML DOM implementation, meaning that those same Node objects made by one of person Y's Document subclass should be objects of person Y's Node subclass. To illustrate, say we had these 4 classes (the syntax may be wrong): # This is one associated class set: class A { submethod one () { return 'hello'; } submethod two () { B.four(); } } class B { submethod three () { A.one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: class C is A { submethod one () { return 'world'; } } class D is B { submethod four () { return 'there'; } } What I want to be able to do is set things up so that user code can do something that is effectively like this: my $first = A.two(); # returns 'here' my $second = B.three(); # returns 'hello' my $first = C.two(); # returns 'there' my $second = D.three(); # returns 'world' The situation is that classes C and D represent any arbitrary named 2 classes that are subclassed from A and B, and so the latter can't know the names of the former, and the latter have to work independently of C and D also. This is one variant of a solution I have come up with: # This is one associated class set: role AB { submethod name_of_class_A () { return 'A'; } submethod name_of_class_B () { return 'B'; } } class A does AB { submethod one () { return 'hello'; } submethod two () { .name_of_class_B().four(); } } class B does AB { submethod three () { .name_of_class_A().one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: role CD { submethod name_of_class_A () { return 'C'; } submethod name_of_class_B () { return 'D'; } } class C is A does CD { submethod one () { return 'world'; } } class D is B does CD { submethod four () { return 'there'; } } This is another variant of a solution I have come up with: # This is one associated class set: role AB { submethod invoke_one () { return A.one(); } submethod invoke_four () { return B.four(); } } class A does AB { submethod one () { return 'hello'; } submethod two () { .invoke_four(); } } class B does AB { submethod three () { .invoke_one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: role CD { submethod invoke_one () { return C.one(); } submethod invoke_four () { return D.four(); } } class C is A does CD { submethod one () { return 'world'; } } class D is B does CD { submethod four () { return 'there'; } } In either case, the expectation here is that the submethods of role CD will override those of role BC regardless of which class' other methods invoke those, when the invocant class is C or D. So I'm wondering what is the best way to develop my associated class sets such that it is easiest for third parties to be able to subclass-extend them. Should I use one of the two solutions above (both of which have been tried in real life, in Perl 5, the second more recently)? Or is there another solution that is better than both? Also, in such a situation as the above, is it reasonable to support easy subclassing, or would it be better to avoid that complexity and instead expect users to create objects that wrap the others instead of subclassing them? Assume also that it may be counter-productive for one class to expect user code to invoke the second class on its behalf, such as if when pair of classes is hidden behind a second pair of classes that mediate access to them. What are some best practices here that can be used by anyone faced by a similar problem? -- Darren Duncan
Re: Translitteration and combining strings and array references
On Wed, Oct 19, 2005 at 01:48:08PM +0200, TSa wrote: : HaloO, : : Luke Palmer wrote: : >It looks nicer if you use the indirect object form: : > : >trans "string": [ : > => "0", : >]; : : Given the right interpretation this just looks like : a typed label selection in a multi method. : : multi trans : { : Str $x: ...; return; : : Int $x: ...; return; : : ...; return; : } : : Is this definitional form supported? To me it nicely : unifies the indirect object syntax---and postfix colon : in general---with labels. We would certainly not define a new syntax just for that. But it could easily fall out of something resembling Luke's tuple proposal in conjuction with a switch, assuming we add signature matching: multi trans (*$_) { when :(Str $x) { ... } when :(Int $x) { ... } default{ ... } } give or take a bit of signature notation. Maybe something with pointies: multi trans (*$_) { when -> Str $x { ... } when -> Int $x { ... } default{ ... } } but we'd have to tell "when" not to look for a second block after evaluating its condition, and the pointy would have to be smart enough to realize it was being passed a tuple/arg list and not just try to bind it to the first parameter. Personally, I think the situation will arise seldom enough that special syntax is not warranted, and a general sig match via the smart operator is sufficient. Though that approach also mandates a bit of kludginess to make sure the signatures bindings persist across the block and no further. Though maybe that falls out naturally if we include optional arrow on case values and assume an implicit *$_ as the when target: multi trans (*$_) { when *$_ -> Str $x { ... } when *$_ -> Int $x { ... } default{ ... } } In that case, the only oddity is that the selection of the case includes the success of binding it to the argument. And also the extra implied * on the case argument to flatten the tuple. This is also all subject to the notion that we might have types that are essentially named type tuples, probably as cases in a union type. In such cases you can match the type name against the entire tuple and then bind the args without typing them: multi trans (Tree *$_) { when Leaf -> $x { ... } when Node -> $x,$y,$z { ... } default { !!! } } But I'm still working my way through oodles of possible syntaxes for declarative tree types and parametric types, so don't quote me on this. And in general people will want to declare these as separate subs unless they have some particular reason for wanting to force evaluation order, which is somewhat suspect in the first place if you're using declared tree types. Larry
Re: syntax for accessing multiple versions of a module
On Wed, Oct 19, 2005 at 03:10:13PM -0700, Nate Wiger wrote: : Larry Wall wrote: : >Well, we thought about opening it up like that, but we really kinda : >need to establish what is an official part of the "long name" for : >uniqueness purposes, and try to avoid too much visual clutter in : >standard usage. : : Going with that... I would think that the "official" part is really just : the module name. Are there lots of problems with CPAN collisions between : different authors? No. People just choose a slightly different name if : their preferred one is taken. Now imagine that process applied to a CPAN that 20 years old and 200 times as big. We're trying to avoid the equivalent of DLL hell here, and I think this is one are where .NET got it pretty much right. : It seems the biggest problem is requiring *only* a specific version, or : range of versions, or <= a version. I know this is addressed already. We can squabble about the syntax, but the basic components of the long name are all pretty important. This is one of those accomodations to the real world, like everyone agreeing on a standard URI format. We're really trying to keep these module names close to what you'd see as the name of, say, the corresponding .rpm file. These modules have to have names that work outside of Perl as well as inside, and {...} isn't going to fly in general. : Not trying to rant (really), but one thing that is starting to bother me : about Perl 6 is that there's lots of changes that require special syntax : for one specific instance. It's making it really really difficult to : remember or generalize, two things that I thought we were trying to improve. Well, you're painting with kind of a broad brush here. If you can point to other areas where we could usefully generalize without getting too abstract for newbies, I'd be delighted to hear them. Much better to spot our limitations now than later, even if we decide we have to keep the limitations for some reason. Larry
Re: subclassing associated classes elegantly
On Wed, Oct 19, 2005 at 03:11:21PM -0700, Darren Duncan wrote: : What are some best practices here that can be used by anyone faced by : a similar problem? My battery's running low, so I just skimmed your article, but my impression is that this is something that would be handled by virtualizing all class names within methods to be the version of the class seen by the actual object rather than the declared class. This is a behavior that has already been mandated, not just for inner classes, but any external class referenced by name. (This applies only within methods. Within a class outside the methods, names are not virtual.) Larry
Re: syntax for accessing multiple versions of a module
Larry Wall wrote: This is one of those accomodations to the real world, like everyone agreeing on a standard URI format. We're really trying to keep these module names close to what you'd see as the name of, say, the corresponding .rpm file. These modules have to have names that work outside of Perl as well as inside, and {...} isn't going to fly in general. My concern is that we're solving problems that don't really exist in real-world Perl usage. Are there really two competing authors of DBI? Or, for any product, do two people really try to market "SuperWidget"? No, one person just changes to "SuperGadget". And with URI's, one person gets "amazon.com". Sorry, name taken. I think we're actually *encouraging* problems by allowing long, clashing names. Pretty soon all DBI modules will have to start with use DBI:TIMB; Because "JEFFSTER" decided to upload his DBI (Derivative Binary Index) module. I think it will have the opposite effect of what we're trying to avoid. : Not trying to rant (really), but one thing that is starting to bother me : about Perl 6 is that there's lots of changes that require special syntax : for one specific instance. It's making it really really difficult to : remember or generalize, two things that I thought we were trying to improve. Well, you're painting with kind of a broad brush here. If you can point to other areas where we could usefully generalize without getting too abstract for newbies, I'd be delighted to hear them. The method syntax is starting to make my head spin, for one. Many things, as a longtime Perl 4/5 programmer and CPAN goon, are problematic because we're reusing established operators for completely different ideas. From a design standpoint, I feel it's going to hamper adoption of the language. People don't have the time (or interest) to re-learn that much language, when Perl 5 works fantastic for 95% of the cases. -Nate
Re: Translitteration and combining strings and array references
On Wed, Oct 19, 2005 at 03:02:14PM +0200, TSa wrote: : HaloO, : : Juerd wrote: : >Luke Palmer skribis 2005-10-18 11:57 (-0600): : > : >>It looks nicer if you use the indirect object form: : >> trans "string": [ : >>=> "0", : >> ]; : > : > : >It'd also look very nice with optional parens: : > : >"string".trans [ => "0" ]; : > : >Or is it not yet time to resuggest that? :) : : I like it. Given enough Meta Information---namely the structural : arrow type---the .trans could be parsed as postfix op that returns : a prefix op. Otherwise you get a 'two terms in a row' *syntax* error! : :(($ &) $) I think it'd be somewhat unfortunate if we started trying to guess which .trans was eventually going to get called and change the parse based on that. : The left item is actually calculated at compile time from string : interpolation. The $ on the right is an itemized pair. Further : expanded we get : :((&.($) & :$) : : or perhaps : :(&.($).&.(:$) This notation is unfamiliar to me. : BTW, lets assume the non-invocant param of .trans were called $foo. : Would in the above case +($foo.key) == 2? And I guess the parens : could be dropped because .key binds tighter than prefix:<+>, right? : I mean the type of the key in the pair is an array of compile time : strings. Or is that not preserved? Yes, that should be preserved, seems to me. Larry
Re: subclassing associated classes elegantly
Darren, Your problem reminds me of the "Expression Problem", which is something that IIRC Luke's Theory idea was trying to solve. Here is the link to a paper Luke referred me to on the subject: http://scala.epfl.ch/docu/files/IC_TECH_REPORT_200433.pdf Also, you can Google the phrase "Expression Problem" and find quite a bit on the subject. Stevan On Oct 19, 2005, at 6:11 PM, Darren Duncan wrote: I'm in a long-standing situation with my module development where I want to design a set of associated classes such that invocations of submethods or class methods, such as new(), of one class by another class continue to work as expected when any or all of those classes is subclassed. I have a solution already that works, but I'm looking for the most optimal solution. An example of when this situation can arise is if person X implements a simplified XML DOM implementation using 2 classes, Document and Node, that work together, where one of those classes (Document) can create objects of the other (Node), and person Y wants to subclass the XML DOM implementation, meaning that those same Node objects made by one of person Y's Document subclass should be objects of person Y's Node subclass. To illustrate, say we had these 4 classes (the syntax may be wrong): # This is one associated class set: class A { submethod one () { return 'hello'; } submethod two () { B.four(); } } class B { submethod three () { A.one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: class C is A { submethod one () { return 'world'; } } class D is B { submethod four () { return 'there'; } } What I want to be able to do is set things up so that user code can do something that is effectively like this: my $first = A.two(); # returns 'here' my $second = B.three(); # returns 'hello' my $first = C.two(); # returns 'there' my $second = D.three(); # returns 'world' The situation is that classes C and D represent any arbitrary named 2 classes that are subclassed from A and B, and so the latter can't know the names of the former, and the latter have to work independently of C and D also. This is one variant of a solution I have come up with: # This is one associated class set: role AB { submethod name_of_class_A () { return 'A'; } submethod name_of_class_B () { return 'B'; } } class A does AB { submethod one () { return 'hello'; } submethod two () { .name_of_class_B().four(); } } class B does AB { submethod three () { .name_of_class_A().one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: role CD { submethod name_of_class_A () { return 'C'; } submethod name_of_class_B () { return 'D'; } } class C is A does CD { submethod one () { return 'world'; } } class D is B does CD { submethod four () { return 'there'; } } This is another variant of a solution I have come up with: # This is one associated class set: role AB { submethod invoke_one () { return A.one(); } submethod invoke_four () { return B.four(); } } class A does AB { submethod one () { return 'hello'; } submethod two () { .invoke_four(); } } class B does AB { submethod three () { .invoke_one(); } submethod four () { return 'here'; } } # This is separate and optional associated class set: role CD { submethod invoke_one () { return C.one(); } submethod invoke_four () { return D.four(); } } class C is A does CD { submethod one () { return 'world'; } } class D is B does CD { submethod four () { return 'there'; } } In either case, the expectation here is that the submethods of role CD will override those of role BC regardless of which class' other methods invoke those, when the invocant class is C or D. So I'm wondering what is the best way to develop my associated class sets such that it is easiest for third parties to be able to subclass-extend them. Should I use one of the two solutions above (both of which have been tried in real life, in Perl 5, the second more recently)? Or is there another solution that is better than both? Also, in such a situation as the above, is it reasonable to support easy subclassing, or would it be better to avoid that complexity and instead expect users to create objects that wrap the others instead of subclassing them? Assume also that it may be counter-productive for one class to expect user code to invoke the second class on its behalf, such as if when pair of classes is hidden behind a second pair of classes th
Re: subclassing associated classes elegantly
On 10/19/05, Darren Duncan <[EMAIL PROTECTED]> wrote: [snip] > An example of when this situation can arise is if person X implements > a simplified XML DOM implementation using 2 classes, Document and > Node, that work together, where one of those classes (Document) can > create objects of the other (Node), and person Y wants to subclass > the XML DOM implementation, meaning that those same Node objects made > by one of person Y's Document subclass should be objects of person > Y's Node subclass. > > To illustrate, say we had these 4 classes (the syntax may be wrong): > ># This is one associated class set: > >class A { > submethod one () { >return 'hello'; > } > > submethod two () { >B.four(); > } >} > >class B { > submethod three () { >A.one(); > } > > submethod four () { >return 'here'; > } >} > ># This is separate and optional associated class set: > >class C is A { > submethod one () { >return 'world'; > } >} > >class D is B { > submethod four () { >return 'there'; > } >} > > What I want to be able to do is set things up so that user code can > do something that is effectively like this: > >my $first = A.two(); # returns 'here' >my $second = B.three(); # returns 'hello' >my $first = C.two(); # returns 'there' >my $second = D.three(); # returns 'world' > > The situation is that classes C and D represent any arbitrary named 2 > classes that are subclassed from A and B, and so the latter can't > know the names of the former, and the latter have to work > independently of C and D also. > > This is one variant of a solution I have come up with: > ># This is one associated class set: > >role AB { > submethod name_of_class_A () { >return 'A'; > } > > submethod name_of_class_B () { >return 'B'; > } >} > >class A does AB { > submethod one () { >return 'hello'; > } > > submethod two () { >.name_of_class_B().four(); > } >} > >class B does AB { > submethod three () { >.name_of_class_A().one(); > } > > submethod four () { >return 'here'; > } >} > ># This is separate and optional associated class set: > >role CD { > submethod name_of_class_A () { >return 'C'; > } > > submethod name_of_class_B () { >return 'D'; > } >} > >class C is A does CD { > submethod one () { >return 'world'; > } >} > >class D is B does CD { > submethod four () { >return 'there'; > } >} > > This is another variant of a solution I have come up with: > ># This is one associated class set: > >role AB { > submethod invoke_one () { >return A.one(); > } > > submethod invoke_four () { >return B.four(); > } >} > >class A does AB { > submethod one () { >return 'hello'; > } > > submethod two () { >.invoke_four(); > } >} > >class B does AB { > submethod three () { >.invoke_one(); > } > > submethod four () { >return 'here'; > } >} > ># This is separate and optional associated class set: > >role CD { > submethod invoke_one () { >return C.one(); > } > > submethod invoke_four () { >return D.four(); > } >} > >class C is A does CD { > submethod one () { >return 'world'; > } >} > >class D is B does CD { > submethod four () { >return 'there'; > } >} > > In either case, the expectation here is that the submethods of role > CD will override those of role BC regardless of which class' other > methods invoke those, when the invocant class is C or D. > > So I'm wondering what is the best way to develop my associated class > sets such that it is easiest for third parties to be able to > subclass-extend them. Should I use one of the two solutions above > (both of which have been tried in real life, in Perl 5, the second > more recently)? Or is there another solution that is better than > both? > > Also, in such a situation as the above, is it reasonable to support > easy subclassing, or would it be better to avoid that complexity and > instead expect users to create objects that wrap the others instead > of subclassing them? > > Assume also that it may be counter-productive for one class to expect > user code to invoke the second class on its behalf, such as if when > pair of classes is hidden behind a second pair of classes that > mediate access to them. > > What are some best practices here that can be used by anyone faced by > a similar problem? > > -- Darren Duncan > [snip] In Perl5, I would think the easiest solution would be to "trick" the base Document class into using the right Node class. 1) Load Node. 2) Rename Node to Node::Base 3)
Re: syntax for accessing multiple versions of a module
On 10/19/05, Nate Wiger <[EMAIL PROTECTED]> wrote: > My concern is that we're solving problems that don't really exist in > real-world Perl usage. Are there really two competing authors of DBI? > Or, for any product, do two people really try to market "SuperWidget"? > No, one person just changes to "SuperGadget". And with URI's, one person > gets "amazon.com". Sorry, name taken. > > I think we're actually *encouraging* problems by allowing long, clashing > names. Pretty soon all DBI modules will have to start with > > use DBI:TIMB; > > Because "JEFFSTER" decided to upload his DBI (Derivative Binary Index) > module. > > I think it will have the opposite effect of what we're trying to avoid. I'm of two minds about this, in large part because I have two experiences with the current CPAN. My first CPAN module was taking over PDF::Template, originally written by DFERRANCE. Now, it's maintained by RKINYON, soon to be maintained by RKINYON and STEVAN due to amazing contributions by AUTRIJUS (or whatever those characters are supposed to be). Now, how are authorship-changes going to be handled, particularly in the face of having two PDF::Templates out there already? Everyone is disambiguating their modules with PDF::Template-DFERRANCE vs. PDF::Template-JRANDOM. Now, they cannot upgrade to my latest feature because that requires changing every place they had hard-coded DFERRANCE. Or, will the package system map PDF::Template-DFERRANCE to PDF::Template-RKINYON? The second experience is one I'm going through right now. I was adding a feature to Tree:Simple a few weeks back and realized that it needed to be gutted to do what I needed it to do. With the encouragement of the author, I rewrote it completely. My development name for the distro is "Forest", but I have Tree and Tree::Binary as the packages. (Yeah, it's a math joke.) Except, there's two problems with that - Tree is a TLN (top-level namespace) with a lot of unrelated distros beneath it. And, Tree is owned by someone else, but that person hasn't updated Tree in 6 years. And, Tree::Binary is owned by the same guy who owns Tree::Simple. How is that going to work in P6? (For the record, I still haven't figured out what I'm going to do yet. Check Perlmonks for the SOPW in a few minutes.) Rob
Re: subclassing associated classes elegantly
On 10/19/05, Stevan Little <[EMAIL PROTECTED]> wrote: > Darren, > > Your problem reminds me of the "Expression Problem", which is > something that IIRC Luke's Theory idea was trying to solve. Indeed, this problem is almost exactly the contravariant half of the expression problem. Once upon a time, a theory was supposed to represent your "role AB", but it has diverged from that. Nowadays I think a problem like this solved by deriving from a module, which isn't too unlike what you were showing. The "factory" abstraction from the theory proposal solves the well-typedness of this kind of solution. Here's a guess: module AB; class A { submethod one () { return 'hello'; } submethod two () { B.four(); } } class B { submethod three () { A.one(); } submethod four () { return 'here'; } } module CD; is AB; class A is AB::A { submethod one () { return 'world'; } } class B is AB::B { submethod four () { return 'there'; } } This is treating all names in a module as virtual. There may be a downside to this, in which case we could go Scala's direction and make the distinguishing property of a role (there called "trait") that the things it declares are virtual. However, if you're ever deriving from a module, a somewhat uncommon thing to do, supposedly you're doing so precisely to make the names virtual like this. So this may just be the right solution. Luke