Re: A12: Required Named Parameters Strike Back!
On Wed, 5 May 2004, John Siracusa wrote: Anyway, once we're spelling things out, don't forget to throw in some traits for params that are required and must be provided as pairs. Damian promised! ;) Looking thru what exists of P6C I saw this in P6C/Nodes.pm: use Class::Struct P6C::signature = { qw(positional @ optional @ required_named @ slurpy_array $ slurpy_named $ optional_named @ ) }; So in theory it is all there :), and must have been for a while! It does not (yet) have an invocant, but the required_named is there. -John --Abhijit
Required Named Params and go write your own grammar
As I try writing P6 programs I do find myself needing required named params, and I thought I'd like something like ++$named_req for myself as a shorthand for +$named_req is required or whatever is decided. Now, larry often says (only partly jokingly) go write your own grammar. But I do not know how I'd change/modify/append the grammar to accomodate that cosmetic change above. Needing to know the entire P6 grammar isn't mouth watering. I am sure this has been discussed before, so can somebody please point me to some place where I can start reading about this? macros does not seem to be an answer as I seem to think of them as defining syntax for new commands that you are writing. (In this case, I do not know where I would put the is parsed trait). I may be wrong and macros in some form are the answer. Either way, I'd appreciate any thoughts/answers/pointers on this. --Abhijit Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
Re: Required Named Params and go write your own grammar
On Tue, 4 May 2004, Luke Palmer wrote: Abhijit A. Mahabal writes: Needing to know the entire P6 grammar isn't mouth watering. grammar Grammar::ReqNamed { is Grammar::Perl; Ah, I see. That does answer my question. I had forgotten that grammers can be inherited from and you can change only the bits you want to change... thanks. Luke --Abhijit
Re: A12: on inheriting wrappers
On Fri, 30 Apr 2004, Aldo Calpini wrote: let's suppose I want to build a class that keeps track of the objects it creates. let's suppose that I want this class to be the base for a variety of classes. let's suppose that I decide, rather than fiddling with the default constructor, to wrap it up. something like: class Animal { our @.zoo; new.wrap( { my @results = call(); push(@.zoo, @results[0]); return @results; } ); } class Lion is Animal { ... } class Tiger is Animal { ... } class Panther is Animal { ... } my $simba = Lion.new(); my $shere_khan = Tiger.new(); my $bagheera = Panther.new(); my @all = @Animal::zoo; # @all should contain ($simba, $shere_khan, $bagheera); will the above code work as expected, or is there something I've overlooked? For this particular case, I guess wrapping the BUILD submethod of Animal would work as it will surely get called. Moreover, since it will be called by BUILDALL in its own class the wrapper will work, regardless of how wrappers get inherited. But I suppose you were asking about wrapper inheriting in general... cheers, Aldo --Abhijit
Re: A12: on inheriting wrappers
On Fri, 30 Apr 2004, Aldo Calpini wrote: so I wanted to explore the possible interoperability of wrappers and classes. another example I can think of: role Logging { POST { foreach ( ::_.meta.getmethods() ) - $method { $method.wrap( { log($somewhere, calling $method); call; log($somewhere, called $method); } ); } } class Foo does Logging { ... } does something like this make sense? Sure, but where is inheritance involved here? Roles are composed into classes, not inherited from. (That particular Role seems to be messing with the class though.. its a trait rather than a role... and it will have to be processed *after* all methods in the class are known (including those that come from other roles)... all that may render what I say below meaningless) If further you said something like class Bar is Foo {...} and wanted that to do Logging for Bar methods, that is a different question. But since you'd have only so many classes saying class Bar is Foo does Logging {...} isn't too much work, and this gives you the chance to control logging on a class by class basis. cheers, Aldo --Abhijit
Re: MethodMaker techniques in Perl 6
On Sat, 24 Apr 2004, John Siracusa wrote: Based on the default accessors and encapsulation thread, it seems like a Perl 6 equivalent of Class::MethodMaker will be still be useful in our (or at least my) Brave New World. I've been pondering the best way to create such a beast in Perl 6. Yes, I agree. As you point out below, Class::Makemethods does lots of crazy stuff. Much of that (like pre- and post-hooks) will be easier to write in P6, but there is still lots of stuff that won't be in the core. The most common two Perl 5 techniques are: 1. Use a string eval: build up a big string that looks the code for the method that I would have typed myself if I wasn't so lazy, then eval the string and assign the resulting code ref to the appropriate typeglob. Example: $attr = 'baz'; *{Foo::$attr} = eval qq(sub { \$_[0]-{'$attr'} }); This technique seems to have the best runtime performance in Perl 5 (by a small margin), but it's also much more expensive (not to mention tedious and persnickety) to create the method in the first place. For whatever reason, it's always just struck me as wrong (sort of like source filtering where code is just seen as a giant string--something that Perl 6 blessedly saves us from :) 2. Use a closure: build a method by assigning what would normally be constant values to a set of variables, then capturing their state in a closure. Example: $attr = 'baz'; *{Foo::$attr} = sub { $_[0]-{$attr} }; Symbol tables and typeglobs and such belong to A10... and the * has been stolen... so I'll just speculate in pseudocode. Blocks-are-subroutines makes life easier, and in pseudocode that can be just: *{Foo::name1} = - $a { $a-{name1} }; OR: for @names - $name { my $private_scalar = $name; *{Foo::$name} = - $a {$a-{$private_scalar}}; } Making the method this way has always seemed cleaner to me, but it bothers me that $attr a full blown variable that has to be read from every time the method is run. Really, it should be a constant, which is probably why the string eval version has a speed edge at runtime. That is something the compiler may be able to deal with. I don't know much about compilers, but here is something from the camel book, 3rd ed, page 229 about inlining functions: BEGIN { my $prod = 1; for (1..10) { $prod *= $_; } sub NFACT () { $prod } } Here, NFACT is inlined because the compiler sees that $prod can never change. So maybe the $private_scalar above can also be inlined. (There is a new $private_scalar each time through the loop because of the my, and $name is also implicitly my). For that code I did not need to introduce $private_scalar, but I put it there to stand for more complex calculations if you need there. Maybe there should be a way to give hints to the compiler that inlining maybe possible. The two Perl 5 techniques still seem like they will work (albeit with different syntax), but I'm sure there are better ways...perhaps something involving macros? The ideal solution has the strengths of both Perl 5 techniques, but none of their weaknesses. Creation should be fast and clean, and there should be no wasted overhead when calling the generated methods. It should be just as if I wrote the methods myself. I haven't retained enough Perl 6 syntax to have any idea what this would look like, so I'm looking for suggestions. Which Perl 6 features are best suited to creating a good Perl 6 MethodMaker? Anyone want to post some simple examples? Wicked Traits come to mind. They seem to be all about warping class behaviors... role methodmaker{ method trait_auxillary:install( : Class $container, $method_semantics, [EMAIL PROTECTED]){ given $method_semantics { when semantics1 { for @names - $name { ... my $method = - $arg {...}; $container.install($name, $method); } for @names - $name { my $method = $container.get_method($name); $method.i_wont_change___inline_variables_if_possible; } } } } } # And in our class: class Dog{ install some_semantics, bark howl whine; } Or perhaps you want to put the install in a BEGIN{} if you want to have the body of the class see these (especially their signatures). class Dog{ BEGIN{ install some_semantics, bark howl whine } } -John --abhijit
Re: MethodMaker techniques in Perl 6
On Sun, 25 Apr 2004, Dave Whipp wrote: Abhijit A. Mahabal [EMAIL PROTECTED] wrote: Symbol tables and typeglobs and such belong to A10... and the * has been stolen... so I'll just speculate in pseudocode. Blocks-are-subroutines makes life easier, and in pseudocode that can be just: *{Foo::name1} = - $a { $a-{name1} }; If I read A12 correctly, this could be written as: Foo::$name1 := - $a {$a.name1}; Could be; that sounds somewhat right, but could you point out where in A12 because a search for := revelaed nothing relevant to me. In any case, I should have written that as: *{Foo::name1} = - $a { $a.name1 }; Oscillating between using P5 and P6 is occasionally frustrating, though working at a stretch in either is a pleasure... The issue for P6 is more complicated than in P5 because you cannot just assign to the typeglob: you will somehow have to take signatures in consideration while populating the symbol table. Dave. --abhijit
A question about binary does
This is actually a couple of questions: 1: can you extend roles by saying: role Set is extended {} 2: if yes, does this change variables for which you said $var does Set? In other words, is the singleton class like a closure or a first-class class? What follows is just some example code in case my question is vague. --Abhijit role Set{ method add ($elt) { $self.{$elt} = 1 } method remove ($elt) {...} method intersection($other where Set) { # can I write that as: method intersection (Set $other) ? return $self.keys.grep { exists $other{$^a} } } } class Set_class does Set {} class Collector{ has %.coins does Set;# brand new singleton class has Set_class %.stamps; # use existing class } my Collector $collector .= new; $collector.coins.add(new Coin()); #okay $collector.stamps.add(new Stamp()); #okay # much later during compilation role Set is extended{ # is this: die if any collision in any class method difference ($other where Set) {...} } $collector.stamps.difference(...); # okay $collector.coins.difference(...); # Is that legal? # In other words, is the singleton class like a closure or like a first-class class? Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
Re: A12: syntax to call Attributes
On Wed, 21 Apr 2004, Brent 'Dax' Royal-Gordon wrote: Which actually brings up an interesting question: class Silly { has $.thing=1; has @.thing=(2, 3); has %.thing=(4 = 5, 6 = 7); } I had assumed that'd be illegal: each of $.thing, @.thing and %.thing autogenerates a method named thing. I would hope that is illegal, for my head would hurt otherwise keeping track of what a particular thing means. We surely don't allow the following in the same class: has @.thing is Array of Cat; has @.thing is Array of Dog; It seems to me that the $.thing/@.thing issue is similar (though the sigil makes this easier for the compiler): has $.thing is Scalar; has @.thing is Array; --Abhijit
Re: Apo 12: Space in method calls
On Mon, 19 Apr 2004, Larry Wall wrote: On Sat, Apr 17, 2004 at 01:07:44PM -0500, Abhijit A. Mahabal wrote: : $obj.method ($x + $y) + $z : : From the earlier examples (like $obj.method +1), I got the impression that : you look ahead until you find a term or an operator. In the example above, : isn't ($x + $y) a full term, all by itself, and in that case would not : What am I missing? The distinction is not term/operator exactly. It's a four-way distinction between definitely a postfix op - () hold arguments, otherwise no arguments definitely a binary op- there are no arguments ambiguous - require disambiguation definitely a term - treat method as list operator where the last category assumes that the term indicates the first item in an expression. (Note that a definite unary operator is the beginning of a term.) $obj.meth,- obviously not arguments $obj.meth $foo,$bar - obviously arguments $obj.meth() + $bat - obviosly not arguments $obj.meth () + $bat- obviosly not arguments $obj.meth ($foo + $bar) + $bat - ambiguous, likely to be list $obj.meth($foo + $bar) + $bat - $foo + $bar the argument $obj.meth($foo + $bar), $bat - list Is that about the story so far? Or is the last example probably going to be illegal without a space? How bad is it to require space before arguments that are a list, so that the no-space case is unambiguous? Larry --Abhijit
Is Dog|undef a legal type?
If we have a method that returns Dog if it returns anything at all, can we say: method foo returns Dog|undef {...} In a similar vein, if the function reurns a dog or a refernce to an array , can we use Dog|Array? And is this legal: given ($obj){ when Dog: ... when Array: ... #obviously $obj can be a ref to an array, not itself an array } --Abhijit Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
Re: Apo 12: Space in method calls
No, obviously arguments. Okay, I see the problem. What you're missing is that in an earlier Apocalypse, we said that postfix subscripts and argument lists may not have an intervening space. Oh, I see. Yes, I had missed that. Thanks for clearing that up. --Abhijit
Re: Is Dog|undef a legal type?
Abhijit A. Mahabal skribis 2004-04-19 11:00 (-0500): when Dog: ... when Array: ... Shouldn't that be: when Dog { ... } when Array { ... } Or is there some .when that I have not yet heard of? Guilty as charged. My Perl6 is getting rusty... --Abhijit
Apo 12: Space in method calls
I do not understand one of the examples in the Use of methods/the dot notation section: $obj.method ($x + $y) + $z From the earlier examples (like $obj.method +1), I got the impression that you look ahead until you find a term or an operator. In the example above, isn't ($x + $y) a full term, all by itself, and in that case would not this mean ($obj.method($x + $y)) + $z, the same as the other call it is contrasted with: $obj.method($x + $y) + $z What am I missing? --Abhijit Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
RE: Array/Hash Slices, multidimensional
On Fri, 16 Apr 2004, Aaron Sherman wrote: @matrix... = 1 0 0 1; In the case of: @matrix = 1 2 3 4 5; You need only add the type: int @matrix = 1 2 3 4 5; There is no string phase, or at least should never be. The compiler can pre-compute the list: int @matrix = ('1','2','3','4','5'); And it then has another obvious pre-computation to perform: int @matrix = (+'1', +'2', +'3', +'4', +'5'); And since everything is a constant, you end up with: int @matrix = (1, 2, 3, 4, 5); This int business may make sense for a one dimensional array, but I meant @matrix to be 2 dimensional, and hence you'd need something like my @matrix is Array of Array of Int = 1 2 3 4 5; # that syntax won't work, obviously, but I do not know how to take slices, and that was my original question... It seems to me that trying to get the compiler to do all that for all sorts of weird constructs is hard, more work than what we get out of it, and all you'd probably get is something that works for a few special cases. In any case, I used 1 2 3 4 5 because it is less typing, and I use stuff like qw{2 3 5 7 11} in P5 all the time. --Abhijit
Array/Hash Slices, multidimensional
As the hash syntax is being worked out, I thought it'd be a good time to ask if the following will be supported in some form: If I have some structure like %foo{monday}, %foo{tuesday} etc, I can set their values enmass using: %foomonday tuesday wednesday = a b c; What if I had %foo{monday}{food_expenditure} = 10; %foo{tuesday}{fuel_expenditure} = 100; %foo{monday}{food_expenditure} = 15; %foo{tuesday}{fuel_expenditure} = 150; Can I say %foo... = 10 100 15 150; for some definition of ...? I don't claim that we'd need that frequently. We probably do need the array version of the same problem frequently, though: @matrix... = 1 0 0 1; At least we'd need it more frequently if we had it. A2 says that something like this will be supported, come A9. --Abhijit Abhijit A. Mahabal http://www.cs.indiana.edu/~amahabal/
Re: but true
On Fri, 19 Dec 2003, Larry Wall wrote: On Fri, Dec 19, 2003 at 10:23:45AM -0800, Austin Hastings wrote: : Of course, when I do: : : my $x = 0 but (true|false); : : then what happens? That's the problem with making them methods. Any such operational definition is going to get you in trouble. I think I like them better as enums, because then you can have junctions of them functioning as a kind of subtype. Is that thought about just traits, or also about roles? Sometime earlier Larry mentioned that roles could add multimethods, and my worry about that is this: If you simultaneously have a multi method with a signature and another without, given a particular call to this multimethod how do you choose which of the two happens if the signature matches? Disallowing such clashes seems problematic because it may mean that if the class writer used types and signatures these get forced onto the user of the class. --Abhijit
macros and is parsed
In E6 Damien writes about macros: As soon as it has parsed that subroutine call (including its argument list) it will detect that the subroutine request is actually a macro, so it will immidiately call request with the specified arguments. If macroness is found *after* parsing the arguments, when does the is parsed trait's action kick in? Elsewhere, he writes: The 'is parsed' trait tells the parser what to look for immediately after it encounters a macro's name. I would guess that the latter is what is intended. Or is it that the absence of an explicit is parsed changes the behaviour (for efficiency reasons, perhaps, as many common uses will parse arguments in standard ways [though act in mind warping ways] ) ? abhi. Abhijit A. Mahabalhttp://cs.indiana.edu/~amahabal/
Macro question
This is a rather silly question: The code: macro foo() { return {my $x = 7} } foo; print $x; is equivalent to which of the following? {my $x = 7} print $x; or my $x = 7; print $x; Thanx, abhi.
Re: Perl 6's for() signature
[EMAIL PROTECTED] (Rod Adams) wrote in message Proposed behavior of *?@ : All Arguement to Parameter mapping left of it are processed Left to Right. Once seen, the mapping starts over right to left. Everything remaining is slurpable. Yes, it's more expensive to use, just like the RE version, but shouldn't impact performance _too_ bad when it's not, since the behavior will be detectable at compile time. Thoughts? There is another problem beyond efficiency: the P6 list semantics is lazy. The following is valid P6, AFAIK: for 1 .. Inf { print $_; last when 10; } And then most of the proposed methods (including popping off [EMAIL PROTECTED]) would not work. There is another problem that I see with a user defined my_for. We want to be able to write my_for 1 .. 5 { something } and not have to write: my_for 1 .. 5 {something }; What is bothering me is the following: If we have a sub with the signature: sub very_complicated(Int $x, Code [EMAIL PROTECTED]) how would the following get parsed: very_complicated 7 { print Hello, } { print world!} # Those were the 3 args I wanted to pass # and the next one is outside the call sub next_routine {...} It seems to me, then, that calls to user defined subs will need to end with a semi-colon. Abhi Abhijit A. Mahabal Home: 520 N. Grant St, Apt #2 Graduate Student, Bloomington IN 47408 Dept of Cog Sci and Computer Science, 812 331 2286 Indiana University Off: LH301I; 812 855 8898
Re: Junctions Set Theory
On Fri, 1 Aug 2003, Derek Ross wrote: Do junctions have a direct representation as predicate logic statements? In particular, do the following logic statements correspond directly to the following perl6 junctions: LOGIC PERL6 JUNCTION (DESCRIP) = (exists x)(x is false) one (abjunction) I'm more familiar with), but it seems that the fourth type of junction, one is inconsistent with the logic definition. Maybe one should be named one_isnt, or the logic statement should become (exists a single x)(x is true). Either way, maybe another junction is needed! The logic statement should become (exists a unique x) (x is true). This is typically written (exists!)(x is true). No other junction should be necessary: If you want to say that something is *false* for at least one of the values, you can just rephrase that as not (true for all values). On the other hand, if you wanted to say true for all except exactly one value, I can't think of a way. (but then, nor of a reason for wanting to). Derek Ross. Abhi.