Re: Calling positionals by name in presence of a slurpy hash
On Tue, Aug 23, 2005 at 10:11:37AM -0700, Larry Wall wrote: > setting up the proxy hash. It's possible that COW hashes can be made > to work efficiently. We'll need to copy hashes if we want to modify > them to pass to subfunctions, just as when you change your environment > it doesn't affect your parent process's environment variables. I would assume that for parrot, with vtables, a "simple" COW hash would be very efficient. By simple, I mean one that does a complete copy and separation the first time someone tries to write to one of the "copies", rather than the more complex concept of maintaining state on partial copies. My hunch would be that a "simple" system of COW plus an overlay hash would work very well for the case of adding to (or deleting from) a hash passed in as default arguments, because 95% of the time that hash is only directly manipulated by functions back up the call frame, so for the duration of the call would be unchanged. But this is all arm-wavy, and needs real code to analyse before committing to it as a strategy. Nicholas Clark
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 10:12:39AM -0700, Chip Salzenberg wrote: > On Wed, Aug 24, 2005 at 08:38:39AM -0400, John Macdonald wrote: > > When calling a function, I would like to be able to have a > > mixture of named and positional arguments. The named argument > > acts as a tab into the argument list and subsequent unnamed > > arguments continue on. > > I see a main point of named parameters to free the caller from the > tyranny of argument order (and vice versa). It seems to me you're > asking for the worst of both worlds. Perhaps I didn't make it clear in my original message - I agree that arbitrary mixing of named and positional is usually a bad thing. The only place where I find it useful is with a group of arguments that are always provided in the same order, used one or more times each by a number of functions, with additional arguments for some/all of those functions. So, a function that takes position and/or vector values would provide a name for each vector/position, but expect each to have an x, a y, and (possibly) a z argument following the name. I saw this in the DO system - a shell written at CDC back in the late 70's. The provided scripts were designed so that all programming scripts used the same sequence of arguments after the OPT keyword, the LINK keywork, etc. As I said originally, the value is diluted in a language with structured data types - you can use a single argument for a position that is a hash or array which contains the x/y/z components within it. The named group helps especially if you generally want to provide separate-but-related arguments. This tends to be things like an optional sub-action that requires multiple parameters if it is used at all. So, I'm mostly saying that a mixture of named and positional arguments is not ALWAYS bad, and that there may be some value in permitting such a mixture in certain circumstances. --
Re: Demagicalizing pairs
I've been trying to thing about how to make this read right without too much line noise. I think Lukes keyword approach ("named") is on the right track. If we want named params at both start and end, then its bound to be a bit confusing. But perhaps we can say that they're always at the end -- but either at the end of the invocant section or the end of the args. Also, "named" is a bit of a clumsy name. "Where" and "given" are taken, so I'll use "with": I think something like these read nicely, without too much line noise: draw_polygon $canvas: @verticies with color => "red"; draw_polygon $canvas with color => "red": @vertices; Dave.
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 08:38:39AM -0400, John Macdonald wrote: > When calling a function, I would like to be able to have a > mixture of named and positional arguments. The named argument > acts as a tab into the argument list and subsequent unnamed > arguments continue on. I see a main point of named parameters to free the caller from the tyranny of argument order (and vice versa). It seems to me you're asking for the worst of both worlds. -- Chip Salzenberg <[EMAIL PROTECTED]>
Re: Demagicalizing pairs
On Wed, 24 Aug 2005, Damian Conway wrote: > Larry wrote: > > > Plus I still think it's a really bad idea to allow intermixing of > > positionals and named. We could allow named at the beginning or end > > but still keep a constraint that all positionals must occur together > > in one zone. > > If losing the magic from =>'d pairs isn't buying us named args wherever we > like, why are we contemplating it? I've lost track of the score in this thread, but I thought I would throw a couple pennies into the fountain. I really dread the thought of losing C< name => value > for named parameters. Off the top of my head, ADA, PL/SQL, and php all use that syntax, so it would be a shame to lose something that newbies might find familiar. On the other hand I would like it if the adverbial named parameter style C< :name(value) > were allowed at the begining as well as the end of the parameter list. I think adverbs read better when they are next to the verbs they modify, and I would be nice if I didn't have to resort to macro magic to get them there. Mixing named and positionals is bad though. ~ John Williams
Re: Demagicalizing pairs
I don't think this example reads very clearly. Visually you have to parse until you see the next => and then back track one word to figure out the key. > move( from=> $x, $y, delta=> $up, $right ); Personally I'd write that as either move(from => [$x, $y], delta => [$up, $right]); OR assuming I has a Position object and a vector object move(from => $pos1, delta => $vec1); The original example just seems difficult to parse. Paul
Perl 6 code - a possible compile, link, run cycle
WRT to PIL and compilation and all that, I think it's time to think about how the linker might look. As I see it the compilation chain with the user typing this in the prompt: perl6 foo.pl perl6 is a compiled perl 6 script that takes an input file, and compiles it, and then passes the compiled unit to the default runtime (e.g. parrot). perl6 creates a new instance of the perl compiler (presumably an object). The compiler will only compile the actual file 'foo.pl', and disregard any 'require', 'use', or 'eval' statements. The compiler produces an object representing a linkable unit, which will be discussed later. At this point the runtime kicks in. The runtime really runs compiled byte code for the runtime linker, which takes the compiled unit that the compiler emitted and prepares it for execution. The runtime linker checks if any inclusions of outside code have been made, and if so, invokes a search routine with the foreign module plugin responsible. For example 'use python:Numerical' will use the pyhon module plugin to produce a linkable unit. A given module will normally traverse a search path, find some source code, check to see if there is a valid cached version of the source code, and if needed, recompile the source code into another linkable unit. As the linker gets new linkable units it checks if they have any dependencies of their own, and eventually resolves all the data and code that modules take from one another. The resulting mess has only one requirement: that it can be run by the runtime - that is, byte code can be extracted out of it. If the modules expose more than just byte code with resolved dependencies in the modules, for example type annotations, serialized PIL, serialized perl 6 code, and so forth, it may, at this point, do any amount of static analysis as it pleases, recompiling, relinking, optimizing, inlining, performing early resolution (especially of MMD) and otherwise modifying code (provided it was asked to do this by the user). The optimization premise is: by the time it's linked it probably won't change too much. Link time isa magictime for resolving calls, inlining values, folding newly discovered constants, and so forth. Furthermore, a linker may cache the link between two modules, regardless of the calling script, so that optimization does not have to be repeated. The result is still the same: code that can be executed by the runtime. It just might be more efficient. The linker also must always be able to get the original version of the linked byte code back, either by reversing some changes, or keeping the original. At this point the runtime's runloop kicks in, starting at the start point in the byte code, and doing it's thing. Runtime loading of code (e.g. eval 'sub foo { }') simply reiterates the above procedure: 'sub foo { }' is compiled by the compiler, creating a linkable unit (that can give 'sub foo { }' to the world). The runtime linker gets a fault saying "byte code state is changing, $compiled_code_from_eval is being ammended to $linked_byte_code_in_runtime_loop". The linker must then link the running code to the result of eval. To do this it may need to undo it's optimizations that assumed there was no sub foo. For example, if there is a call to 'foo()' somewhere in foo.pl, the linker may have just inlined a 'die "no such sub foo()"' error instead of the call. Another linker may have put in code to do a runtime search for the '&foo' symbol and apply it. The linker that did a runtime search that may fail doesn't need to change anything, but the linker which inlined a fatal error must undo that optimization now that things have changed. The behavior of the linker WRT to such things is dependant on the deployment setting. In a long running mod_perl application there may even be a linker that optimizes code as time goes by, slowly changing things to be more and more static. As the process progresses through time, the probability of new code being introduced is lower, so the CPU time is invested better. Furthermore, latency is not hindered, and startup is fast because the linker doesn't do any optimizations in the begining. This is part of the proposed optimizer chain, as brought up on p6l a month or so ago. Anyway, back to runtime linking. Once the code is consistent again, e.g. calls to foo() will now work as expected, eval gets the compiled code, and runs it. It just happens that 'sub foo { }' has no runtime effects, so evak returns, and normal execution is resumed. To get the semantics of 'perl -c' you force the linker to resolve everything, but don't actually go to the runloop. Linkable units are first class objects, and may be of a different class. This has merits when, for example, a linkable unit is implemented by an FFI wrapper. The FFI wrapper determines at link time what the foreign interface looks like, and then behaves like the linkable unit one might expect if it were a native interface. It can generate bytecode to cal
Re: Demagicalizing pairs
On Wed, Aug 24, 2005 at 04:27:03PM +1000, Damian Conway wrote: > Larry wrote: > > >Plus I still think it's a really bad idea to allow intermixing of > >positionals and named. We could allow named at the beginning or end > >but still keep a constraint that all positionals must occur together > >in one zone. > > If losing the magic from =>'d pairs isn't buying us named args wherever we > like, why are we contemplating it? When calling a function, I would like to be able to have a mixture of named and positional arguments. The named argument acts as a tab into the argument list and subsequent unnamed arguments continue on. That allows you to use a name for a group of arguments: move( from=> $x, $y, delta=> $up, $right ); In this case, there could even be an optional z-coordinate argument for each of the from and delta groups. The named group concept works well for interfaces that use the same groups in many different functions. It is especially powerful in languages which do not have structured types, which means it is not so necessary in Perl, but even here, you often are computing the components (like $up and $right above) separately, rather than always computing a single structured value (which would mean writing delta=>(x=>$up, y=>$right) instead). --
Re: ~ and + vs. generic eq
On Tue, Aug 23, 2005 at 16:32:37 -0700, Larry Wall wrote: > Hmm, well, I don't think >>&op<< is valid syntax, but you did say > "semantics", so I can't criticize that part. :-) What is >><<, btw? Is it &circumfix:{'>>','<<'} (Code &op --> Code); # takes some code, returns a listop or &precircumfix:{'>>','<<'} (Code &op, [EMAIL PROTECTED] --> List); > I don't know how close ~~ and eqv will end up. There are some > differences in emphasis, and when two operators get too much like each > other, I tend to add more differences to make them inhabit different > parts of the solution space. One current difference is that, despite > the symmetry of ~~, it's not actually a symmetrical operator much of > the time, such as when matching values to rules. ~~ is intended to > be heavily dwimmical, so it's allowed to do various kinds of abstract > coercions to figure out some mystical "good enough" quotient. But eqv > on the other hand should probably be false in asymmetrical situations. > The implementation of ~~ may delegate to eqv in certain symmetrical > situations, of course. Right... Magic is defined in the "base" definitions of ~~: &infix:<~~> ($x, Rule $r) { ... } &infix:<~~> ($x, Code &test) { code($x) } And so on and so forth, and then it is extended by the extender to make cool aggregate operations, but even this doesn't have to be the same for ~~ and eqv, it's just that eqv should have good builtins for collections, is all. > should say "true", since those are the same values, and they can't > change. However, in Perl-5-Think, [1,2,3] produces mutable arrays, > so unless we come up with some kind of fancy COW for [1,2,3] to be > considered immutable until someone, er, mutes it, I think eqv would > have to return false, and consider two such objects to be different > values (potentially different if not actually different). Well, when I use it as if (@array eqv [1, 2, 3]) { } I think it's obvious that I'm checking "what is the value right now", and ditto when I say my $str = "foo"; $hash{$str} = 1; $str ~= "bar"; $hash{$str}; # not the same Arguably use of an array as a hash key is using a reference to a container, and use of a scalar as a hash key is using the value inside a container, so in a sense the hash key didn't change when I appended the string, but this distinction is subtle and mostly an implementation detail. > It would be possible to declare %hash some way that forces a "snapshot" > via some kind of serialization or other, but then it gets hard to keep > the identity around. Then the question arises how we doctor > > if [1,2,3] eqv [1,2,3] { say "true" } else { say "false" } eqvs! it pronounces very well: 'eekyoovies'. Try it: if 1 2 3 eekyooviesses 1 2 3 say true, otherwise say false It's fun, but I hate it even more than eqv ;-) > to do the same snapshot comparison. Arguably ~~ could do it, since it's > explicitly *not* about identity. > > if [1,2,3] ~~ [1,2,3] { say "true" } else { say "false" } But ~~ is not "is the same" it's "matches". This is also true, and not what I want eqv for: if [1, 2, 3] ~~ [code { 1 }, rx/\d+/, Num] { say "true" } else { say "false" } > Or we could have a more explicit way of doing whatever it is that the > snapshot hash does to each argument. > > if [1,2,3].snap eqv [1,2,3].snap { say "true" } else { say "false" } I think the opposite is better, make snapshotting by default, and mutable value equality false by saying [1, 2, 3] eqv [1, 2, 3] :always # or :forever -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah pgpkL3zKnNBEK.pgp Description: PGP signature
Re: ~ and + vs. generic eq
Larry wrote: Or we could have a different operator that coerces like == and eq, only via .snap: if [1,2,3] equals [1,2,3] { say "true" } else { say "false" } (Actual name negotiable, of course). The advantage of the latter approach is that you can say @foo >>equals<< @bar and the .snaps are automatically distributed. Otherwise you'd have to say @foo<<.snap >>eqv<< @bar<<.snap which is a pain. On top of which, equals doesn't actually have to implemented in terms of .snap--it could just compare the current values of the mutable objects directly. (Just as =:= doesn't have to be implemented in terms of .id.) Just a meta-point...one thing we really do need to be careful of is not ending up with 17 different "equality" operators (like certain languages I shall refrain from naming). So far we're contemplating: =:= ~~ == eq eqv equals Do we really need even that many??? Damian
Re: Demagicalizing pairs
Larry mused: On the other hand, I'm not all that attached to colon itself. I *am*!!! If, as proposed elsewhere, we get rid of the %Foo:: notation in favor of some Foo<> variant, then trailing :: becomes available (ignoring ??/:: for the moment), and new Dog:: tail => 'long' almost makes sense, insofar as it kinda looks like it's marking Dog as a type name, even though it isn't. But new Dog:: :tail doesn't look so good. Nor do object methods: wag $dog:: 'tail'; say $fh:: $whatever; On the other hand, looking at it from the other end, the MMD notation tiebreaking notation is a little hard to spot, since colon is easy to miss. Is it??? I've been writing quite a bit of MMD notation, and I think the colon is very obvious...and exactly the right visual "weight". Maybe there's something that shows up better in a signature that also works as the invocant marker and, by extension, the indirect object marker. Since it's an ordering kind of thing, you'd kind of like to work > into it somehow, since the left side is of "greater" importance than the left. Unfortunately, though, "the good ones are all taken". Maybe some digraph like method new ($what*> $:tail) {...} method new ($what+> $:tail) {...} method new ($what.> $:tail) {...} method new ($what|> $:tail) {...} method new ($what>> $:tail) {...} giving new Dog*> :tail new Dog+> :tail new Dog.> :tail new Dog|> :tail new Dog>> :tail I guess that last one is eqivalent to: method new ($what» $:tail) {...} new Dog» :tail which I could maybe get used to. It kind of looks like a prompt to me. Not one of these is anything close to as readable as: new Dog: :tail name $dog: 'Rover'; say fh: @whatever *Please* don't give up on the colon there. It's much more readable. I especially like it for setting up objects: $person = Contact.new; first_name $person: "George"; family_name $person: "Bush"; title $person: "President"; email $person: "[EMAIL PROTECTED]"; spouse $person: search $contacts: "Laura"; The ordinary MMD might look like multi foo ($a, $b, $c» $d) And Lisp-like MMD fallback on every argument would look like multi foo ($a» $b» $c» $d») I suppose that particular use of » could be construed as encouraging people not to do that. :-) I truly believe that using the French quotes or (shudder!) their Texan equivalents here would be a dire step backwards. They're already overloaded for word lists and hyperoperators. I think using them for an invocant marker as well would simply be too much. The colon really was (and still is) the right choice here. Damian