Re: Calling positionals by name in presence of a slurpy hash

2005-08-24 Thread Nicholas Clark
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

2005-08-24 Thread John Macdonald
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

2005-08-24 Thread Dave Whipp
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

2005-08-24 Thread Chip Salzenberg
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

2005-08-24 Thread John Williams
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

2005-08-24 Thread Paul Seamons
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

2005-08-24 Thread Yuval Kogman
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

2005-08-24 Thread John Macdonald
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

2005-08-24 Thread Yuval Kogman
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

2005-08-24 Thread Damian Conway

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

2005-08-24 Thread Damian Conway

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