Re: Currying positionals

2005-03-29 Thread Thomas Sandlaß
Larry Wall wrote:
Yeah, I agree.  How 'bout we go with something like you have to *
the actual hash (if it's the first thing) to make it look like a
list of pairs to the parser, and we can just get rid of 3 there.
I'm not sure if 3) was superflous depending on the definition of "non-pair".
Did you mean none(Pair, Hash) or just none(Pair)? And is there something
like a parsed pair---I mean fat arrow in the parse tree as opposed to
an instance of Pair? How is
my Pair $p = (x => 3);
foo $p; # $x = undef, %opts = { x => 3 }
handled in comparison to
foo x => 3; # $x = 3, %opts = undef
Cases 2) and 3) actually look more like special cases of a
type check to me. And does the rule say that type errors are
shoved into the slurpy hash if present? Which would give a
nice way to implement unchecked sigs by adding an implicit
*%_ parameter? IIRC it was mentioned as a feature somewhere
to have more than one slurpy array or hash with different
types.
Regards,
--
TSa (Thomas Sandlaß)


Re: Currying positionals

2005-03-24 Thread Larry Wall
On Thu, Mar 24, 2005 at 03:09:37PM -0700, Luke Palmer wrote:
: Larry Wall writes:
: > Step A: For each positional parameter, if the next supplied argument is:
: > 
: > 1) a non-pair
: > 2) a pair, and this parameter is explicitly declared Pair, or
: > 3) a hash, and this parameter is declared Hash, either explicitly,
: >or implicitly with a % sigil,
: 
: Wait, so:
: 
: sub foo (?$x, *%opts) {...}
: 
: foo @a;  # $x = [EMAIL PROTECTED],   %opts = ();
: foo %a;  # $x = undef, %opts = %a;
: 
: That's asymmetrical, and I think in a bad way. 

Yeah, I agree.  How 'bout we go with something like you have to *
the actual hash (if it's the first thing) to make it look like a
list of pairs to the parser, and we can just get rid of 3 there.

Larry


Re: Currying positionals

2005-03-24 Thread Luke Palmer
Larry Wall writes:
> Step A: For each positional parameter, if the next supplied argument is:
> 
> 1) a non-pair
> 2) a pair, and this parameter is explicitly declared Pair, or
> 3) a hash, and this parameter is declared Hash, either explicitly,
>or implicitly with a % sigil,

Wait, so:

sub foo (?$x, *%opts) {...}

foo @a;  # $x = [EMAIL PROTECTED],   %opts = ();
foo %a;  # $x = undef, %opts = %a;

That's asymmetrical, and I think in a bad way. 

Luke


Re: Currying positionals

2005-03-24 Thread Larry Wall
On Thu, Mar 24, 2005 at 12:58:32PM -0800, Larry Wall wrote:
: Note, the adverbial :{...} is defined as a named binding to the first
: *& parameter (or first *$ parameter if there isn't a slurpy *&), so
: it's already bound by Step C, even if it occurred later syntactically.

Hmm, that's ambiguous, so s:w/by Step C/by Step B before Step C happens/.

Larry


Re: Currying positionals

2005-03-24 Thread Larry Wall
On Wed, Mar 23, 2005 at 11:08:17PM +0200, Yuval Kogman wrote:
: On Wed, Mar 23, 2005 at 11:53:06 -0800, Larry Wall wrote:
: > This seems a little backwards--I think all positionals should be bound
: > before you start binding named pairs, if currying is to be consistent with
: > "ordinary" binding.
: 
: Currying and ordinary binding are implemented in the same
: function... =P

I think that's good, though it's presumably possible for the function
in question to know whether it's the final binding, and make
allowances for the difference of intent.  Or perhaps there could
be options to .assuming, though we'd have to change the signature.
Probably should do that anyway, or we'll never be able to have a
variant of .assuming that can take options.  So I suspect the first
two positional arguments to .assuming should be a [...] list of
positionals followed by a [...] list of pairs.  Then we're free to
have options as the 3rd and subsequent parameters.  Alternately we
just pass one [...] list as the first argument, which we parse as an
ordinary argument list with a transition from positionals to named.
That makes .assuming and binding more like the same operation, modulo
the extra indirection in the first argument.

I suppose one could keep the current syntax if you distinguish the
case of the first positional argument being an anonymous array, in
which case if you wanted to bind an array as the first assumed argument,
you'd have to double bracket it.  I can argue it both ways.

: > Otherwise you can't catch binding explicitly to
: > a positional Pair argument.
: 
: soo... how would you diambiguate that in the general case?

In the current formulation it's disambiguated by whether the positional
argument is explicitly declared as Pair, though we could possibly
relax that to any type that "does" Pair, presuming it's not a role
that is going to sneak into a lot of types.  If it does sneak into
a lot of types, then we'd probably better keep it as an explicit Pair
declaration.

: Can I pass a named for an optional?

Certainly, as long as the optional isn't declared Pair, and as long as
you've made the transition from processing positional arguments to
named arguments, and don't expect to go back to positional processing.

: or is that always a positionally bound pair?

It is positionally bound if declared Pair.  Otherwise a pair is always
taken to be the transition from positional to named processing, and
that and any subsequent optional positionals are immediatly bound to
their defaults in the final binding.  Here is where it breaks down
if you're trying to use the exact same function for currying, since
currying shouldn't force the defaults to resolve.  Either your function
has to distinguish the cases, or the actual binding of defaults has
to be an additional step between your function and the actual call.

Another difference is potentially the binding of slurpies.  I'm not sure
it's practical to do a partial binding of a slurpy array.  The slurpy
array is really a kind of named binding underneath, so it seems kind
of all or nothing, and we could go as far as to require named notation
to bind a slurpy argument with .assuming.  Maybe that's overkill, but
we probably need to do something to avoid the situation of trying to
direct two different pipes into the function, unless we can come up
with a clean and efficient semantics for the curried pipe to be exhausted
before the user-supplied pipe is read from.

: I'm reading through S06 a bit more in detail, and I see
: 
:   Arguments destined for positional parameters must come before
:   those bound to named parameters.
: 
: Do pairs get slurped until there are no more required positionals to
: fill in? In that case, how do you actually assign by name? Can you
: mix positional and named params?

Step A: For each positional parameter, if the next supplied argument is:

1) a non-pair
2) a pair, and this parameter is explicitly declared Pair, or
3) a hash, and this parameter is declared Hash, either explicitly,
   or implicitly with a % sigil,

then bind positionally.  Otherwise, you're done with positional processing.

Step B: Now we do named processing. If there are no pairs or hashes
as the next supplied argument, skip to Step C.  For each supplied
pair or hash, bind arguments by name, but bind positionals only if
they weren't already bound in Step A.  If you find a pair name that
doesn't correspond to a parameter, it's an error for a sub unless
it declares *%.  For subs and methods with explicitly declared *%
and methods with implied *%, shove unbound arg into *%.  (It would
be good if we can optimize away the "shove" by reusing the existing
argument structure, and we trying to take that into account in
allowing duplicates in *% for otherwise bound parameters).  If Step B
bound an argument to the slurpy array, skip Step C.

Step C:  By definition, the next available argument is not a pair
or hash.  (Or if it is, it was protected by a pipe operat

Re: Currying positionals

2005-03-24 Thread Luke Palmer
Yuval Kogman writes:
> More!
> 
> can you have several slurpy params, of the same type, which are
> assigned contiguous sequences of the thing they can slurp?
> 
>   foo([EMAIL PROTECTED], *%a, [EMAIL PROTECTED])
>   foo(1, 2, 3, a => b, c => d, 4, 5, 6); 
>   
> for me that makes sense for slurpy blocks, but not anything else

I don't think so.  If the signature didn't give you an error for doing
that (which it would), we could expect these bindings:

@a : [1, 2, 3, a => b, c => d, 4, 5, 6]
%a : {}
@b : []

Slurpy array is a greedy bastard.  Slurpy hash is only greedy for pairs,
and it stops trying after it sees something that is not a pair.

But that makes me wonder whether you can do this:

sub foo ($a, $b, *%options, &code)

Given how I've described the slurpy hash above, that should work fine.
But given the current semantics, that doesn't work.

Perhaps, in the absence of accepting my more general proposal, we could
just define a left-to-right matching order.  Named arguments would be
assumed to be part of a slurpy hash (and must always come immediately
before a slurpy hash if there is one).  Likewise with slurpy scalars.
But it would allow things like this:

sub svn (*%svnopts, $command, *%commandopts)

Which authors would have their own reasons for writing.

Luke


Re: Currying positionals

2005-03-23 Thread Yuval Kogman
More!

can you have several slurpy params, of the same type, which are
assigned contiguous sequences of the thing they can slurp?

foo([EMAIL PROTECTED], *%a, [EMAIL PROTECTED])
foo(1, 2, 3, a => b, c => d, 4, 5, 6); 

for me that makes sense for slurpy blocks, but not anything else

-- 
 ()  Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418  perl hacker &
 /\  kung foo master: /me sneaks up from another MIME part: neeyah!



pgpPp0zr5P5Yv.pgp
Description: PGP signature


Re: Currying positionals

2005-03-23 Thread Yuval Kogman
On Wed, Mar 23, 2005 at 11:53:06 -0800, Larry Wall wrote:
> On Wed, Mar 23, 2005 at 05:43:52PM +0200, Yuval Kogman wrote:
> : The algorithmic approach to binding some params:
> : 
> : bind invocants
> : 
> : bind named parameters, and keep leftover pairs for %_
> : 
> : treat nonpairs as positionals, and bind them sequentially. Left
> : over nonpairs get put in @_
> 
> This seems a little backwards--I think all positionals should be bound
> before you start binding named pairs, if currying is to be consistent with
> "ordinary" binding.

Currying and ordinary binding are implemented in the same
function... =P

> Otherwise you can't catch binding explicitly to
> a positional Pair argument.

soo... how would you diambiguate that in the general case?

Can I pass a named for an optional? or is that always a positionally
bound pair?

I'm reading through S06 a bit more in detail, and I see

Arguments destined for positional parameters must come before
those bound to named parameters.

Do pairs get slurped until there are no more required positionals to
fill in? In that case, how do you actually assign by name? Can you
mix positional and named params?

Going down further, I see:

sub formalize($text, +$case, +$justify)

This can we name text => "foo"? or will $text actually contain that
pair, as bound positionally?

> I also think doing it the other way leads to weird situations
> where the first two positional arguments can bind to, say, the
> first and third formal parameters, which is a situation I'm trying
> to avoid.

Yeah, that's why I raised this stuff here. Once I managed to
actually read Autrijus's code (not his fault!) I got thinking, and
wasn't sure the way it was done is the good way, since it seemed to
work, but was not really strechable to corner cases.

> But it's possible that .assuming() should be allowed to violate this,
> if we let it do positionals at all.  It would be a convenience to
> allow positionals, but for a known function, you can get the same
> behavior with named arguments.

Since we have .arity, why don't we make this a little more
introspectable too?

> : foo(x => 1, x => 2); # yields $x = 1, %_ = 2
> 
> I think that should probably be an error for a sub because it doesn't
> have a signature that enables %_.

And if it had a slurpy hash?

> : foo(1, x => 2); # $x = 2, @_[0] = 1
> 
> There's where your scheme comes out backwards to me.  I think it should
> absolutely bind the 1 to $x, and then the x turns out to be extra, an
> error in the case of a sub, and put into %_ in the case of a method.
> But we can't have the situation of a positional argument being bound
> to anything but the next positional parameter.

So again, how do we unambiguously tell apart a positional from a
named, when it's a pair? What's not yet bound? where we are in the
binding?

I think some concrete examples would be very good for me.

> : (&foo.assuming(1))(x => 2); # $x = 1, %_ = 1
> 
> Would also be illegal for a sub, and put x=>2 into %_ for methods.

Ok. that's the consistency i want to attain. By that I mean:

foo(  )

is the same as

(&foo.assuming .).(...)
   ..  ..

(&foo.assuming(.).assuming(.).assuming(.)).(.)

etc, given any syntax in '.' that stays the same.

> But more than anything I want to be able to curry a module or class.
> And that's probably almost exclusively a named-argument thing,
> unless you just happen to define every sub in your module to have a
> consistent first argument type.  But maybe, as with partial binding,
> it's just sort of a partial dispatch, so say, if you curry a class with
> an object as the first argument, it would curry the instance methods
> but not the class methods.  This seems pretty dwimmy to a human being.
> (Or it could curry the class methods too if an object is allowed to
> play the role of its class.)

I sort of agree with that, but i'm not sure... what if a named param
is missing? is it slurped? if we go that far, perhaps positionals
are the same?

-- 
 ()  Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418  perl hacker &
 /\  kung foo master: /me climbs a brick wall with his fingers: neeyah!



pgpdT5mwSdamj.pgp
Description: PGP signature


Re: Currying positionals

2005-03-23 Thread Larry Wall
On Wed, Mar 23, 2005 at 08:24:48PM +0200, Yuval Kogman wrote:
: On Wed, Mar 23, 2005 at 17:43:52 +0200, Yuval Kogman wrote:
: > Hola... I've spend some time these last few days slowly getting
: > currying to work in pugs.
: 
: It should also be mentioned that I made magical $?SUB et al unbind
: the sub.
: 
: In a curried sub, should that happen?
: 
: It looks more consistent for me, because a sub shouldn't know it's
: curried, but you never know in p6 ;-)

I agree, the sub should not have to know it's been curried.  (For
instance, it would certainly call itself assuming its full signature.)
It would be a violation of "excapsulation" to require the sub to
know how it's being used.  Context dependencies should generally be
optional, not forced--anything beyond simple scalar/list dependencies
should probably be the province of explicit calls to want() and
caller().  (Which calls are likely to pessimize various optimizations.)

Larry


Re: Currying positionals

2005-03-23 Thread Larry Wall
On Wed, Mar 23, 2005 at 05:43:52PM +0200, Yuval Kogman wrote:
: The algorithmic approach to binding some params:
: 
:   bind invocants
: 
:   bind named parameters, and keep leftover pairs for %_
: 
:   treat nonpairs as positionals, and bind them sequentially. Left
:   over nonpairs get put in @_

This seems a little backwards--I think all positionals should be bound
before you start binding named pairs, if currying is to be consistent with
"ordinary" binding.  Otherwise you can't catch binding explicitly to
a positional Pair argument.  I also think doing it the other way leads
to weird situations where the first two positional arguments can
bind to, say, the first and third formal parameters, which is a situation
I'm trying to avoid.  I'd like the transition from positional to named
processing to be irrevocable, at least in the case of ordinary binding.

But it's possible that .assuming() should be allowed to violate this,
if we let it do positionals at all.  It would be a convenience to
allow positionals, but for a known function, you can get the same
behavior with named arguments.

:   if we have slurpy params, they act as %_ and @_.
: 
:   package a sub with the bindings, and the unbound params, and
:   return it.

: and, well... that's it.
: 
: This has some funny properties, like:
: 
:   foo ($x) { ... }
: 
:   foo(x => 1, x => 2); # yields $x = 1, %_ = 2

I think that should probably be an error for a sub because it doesn't
have a signature that enables %_.

:   foo(1, x => 2); # $x = 2, @_[0] = 1

There's where your scheme comes out backwards to me.  I think it should
absolutely bind the 1 to $x, and then the x turns out to be extra, an
error in the case of a sub, and put into %_ in the case of a method.
But we can't have the situation of a positional argument being bound
to anything but the next positional parameter.

:   (&foo.assuming(1))(x => 2); # $x = 1, %_ = 1

Would also be illegal for a sub, and put x=>2 into %_ for methods.

: Are these bugs? I could live with them, but they are a bit
: perl5-ish.
: 
: I think we need a little more guidance, as the exact semantics of
: currying are not that well defined.

Another thing to think about is whether you allow application of
.assuming to a generic multimethod before it is dispatched.  It would
be nice to be able to do that, and I can see that if multis don't
name their first parameters consistently, currying on position would
allow a dispatch that named currying wouldn't be able to express.

But more than anything I want to be able to curry a module or class.
And that's probably almost exclusively a named-argument thing,
unless you just happen to define every sub in your module to have a
consistent first argument type.  But maybe, as with partial binding,
it's just sort of a partial dispatch, so say, if you curry a class with
an object as the first argument, it would curry the instance methods
but not the class methods.  This seems pretty dwimmy to a human being.
(Or it could curry the class methods too if an object is allowed to
play the role of its class.)

Larry


Re: Currying positionals

2005-03-23 Thread Yuval Kogman
On Wed, Mar 23, 2005 at 17:43:52 +0200, Yuval Kogman wrote:
> Hola... I've spend some time these last few days slowly getting
> currying to work in pugs.

It should also be mentioned that I made magical $?SUB et al unbind
the sub.

In a curried sub, should that happen?

It looks more consistent for me, because a sub shouldn't know it's
curried, but you never know in p6 ;-)

-- 
 ()  Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418  perl hacker &
 /\  kung foo master: : neeyah!



pgpPofLsZmRD0.pgp
Description: PGP signature