Google Gruppi non supporta più i nuovi post o le nuove iscrizioni Usenet. I contenuti storici continuano a essere visibili.

S6: Named parameters are always optional?

11 visualizzazioni
Passa al primo messaggio da leggere

John Siracusa

da leggere,
11 apr 2003, 18:57:2611/04/03
a Perl 6 Language
I forget if this was covered earlier, but what is the reason for this? I
can easily imagine wanting to create subroutines that only accept named
parameters, some or all of which are required. How would this be done in
Perl 6?

Yes, I guess all the parameters could be declared as positional, and then I
could scold users in the documentation to only use named parameters when
calling these subroutines, but that seems silly--and dangerous, since,
inevitably, some users won't listen and will use positional parameters
(after looking at the source to discover the correct order, or whatever).
So I'm stuck maintaining an argument order for what are (as far as I'm
concerned) not positional parameters.

I guess I could also die() if I'm missing a named parameter, but that seems
so Perl-5-ish (i.e. "more work")

So...why can't I have required named parameters? If it is due to vagaries
of the parameter definition syntax and it's funny little "zones", then I say
change the syntax instead of disallowing required named parameters :)

-John

Luke Palmer

da leggere,
11 apr 2003, 20:46:0911/04/03
a sira...@mindspring.com, perl6-l...@perl.org
> I forget if this was covered earlier, but what is the reason for this? I
> can easily imagine wanting to create subroutines that only accept named
> parameters, some or all of which are required. How would this be done in
> Perl 6?
>
> Yes, I guess all the parameters could be declared as positional, and then I
> could scold users in the documentation to only use named parameters when
> calling these subroutines, but that seems silly--and dangerous, since,
> inevitably, some users won't listen and will use positional parameters
> (after looking at the source to discover the correct order, or whatever).
> So I'm stuck maintaining an argument order for what are (as far as I'm
> concerned) not positional parameters.
>
> I guess I could also die() if I'm missing a named parameter, but that seems
> so Perl-5-ish (i.e. "more work")

You want it to be easy to make using your module harder? Sorry,
that's something the community just won't let you do.

Unfortunately, there is a solution. Macros:

module LazyMaintainer;
sub _changesalot($required, $parameters, $here) { ... }

macro changesalot
is parsed(/ $a := (<Perl::pair>) @b := [ , (<Perl::pair>)] * /) {
{ _changesalot($a, *@b) }.parsed
}

But that makes:

sub changesalot(*%param) {
exists $param{ all(<<requred parameters here>>) }
or die "Required parameter not given"
}

Look easy. And more portable, too.

> So...why can't I have required named parameters?

It's TMTOWTDI, forced upon you. The users of your module can use
whichsoever style they prefer, and you have to go to a lot of trouble
to keep them from doing that. And I think it's a good thing. I see
your position on the maintainability standpoint, but there's just
things you have to do when you're a maintainer.

By the way, it's not a maintenance problem. You want to be able to
add new parameters without breaking old code using your module, right?
Well, you can't add new I<required> parameters without breaking old
code anyway! So your argument is moot, in any case.

> If it is due to vagaries of the parameter definition syntax and it's
> funny little "zones", then I say change the syntax instead of
> disallowing required named parameters :)

I say: Perl is an extensible language. Write a module that adds the
capability, and make it easy for yourself again.

Luke

John Siracusa

da leggere,
11 apr 2003, 21:09:5111/04/03
a Perl 6 Language
On 4/11/03 8:46 PM, Luke Palmer wrote:
>> I forget if this was covered earlier, but what is the reason for this? I
>> can easily imagine wanting to create subroutines that only accept named
>> parameters, some or all of which are required. How would this be done in
>> Perl 6?
>>
>> Yes, I guess all the parameters could be declared as positional, and then I
>> could scold users in the documentation to only use named parameters when
>> calling these subroutines, but that seems silly--and dangerous, since,
>> inevitably, some users won't listen and will use positional parameters
>> (after looking at the source to discover the correct order, or whatever).
>> So I'm stuck maintaining an argument order for what are (as far as I'm
>> concerned) not positional parameters.
>>
>> I guess I could also die() if I'm missing a named parameter, but that seems
>> so Perl-5-ish (i.e. "more work")
>
> You want it to be easy to make using your module harder? Sorry,
> that's something the community just won't let you do.

Huh? How is requiring named parameters making my module "harder"? IMO,
positional parameters are "harder" because they require the user to remember
a specific order. Once you get beyond a certain number of parameters,
allowing them to be supplied positionally results in not-so-nice code like
this:

foo(1, 'bar', 5.5, @baz, 7, [5 .. 10], 'a', 7, $blee, 'wow hi', %floo);

No one wants to look at or maintain that, and yet it must be allowed if all
of those arguments are required.

>> So...why can't I have required named parameters?
>
> It's TMTOWTDI, forced upon you. The users of your module can use
> whichsoever style they prefer, and you have to go to a lot of trouble
> to keep them from doing that. And I think it's a good thing.

TMTOWTDI means that you can allow required parameters to be specified
positionally in the code that you write, if you want to. Forcing *everyone*
to allow required parameters to be specified positionally is Bondage and
Discipline, IMO.

To imply that users of your code should be able to pick any possible WTDI is
an argument against any kind of subroutine signature at all!

> By the way, it's not a maintenance problem. You want to be able to
> add new parameters without breaking old code using your module, right?

The underlying objection is that there's nothing about either "positional"
or "named" that implies "can be required" and "must always be optional"
It's just an arbitrary rule, as far as I can see, and one that I don't
happen to agree with.

> I say: Perl is an extensible language. Write a module that adds the
> capability, and make it easy for yourself again.

Sure, but that's not an argument for why it shouldn't be there in the first
place.

-John

Luke Palmer

da leggere,
11 apr 2003, 21:26:4711/04/03
a sira...@mindspring.com, perl6-l...@perl.org
> > You want it to be easy to make using your module harder? Sorry,
> > that's something the community just won't let you do.
>
> Huh? How is requiring named parameters making my module "harder"? IMO,
> positional parameters are "harder" because they require the user to remember
> a specific order. Once you get beyond a certain number of parameters,
> allowing them to be supplied positionally results in not-so-nice code like
> this:
>
> foo(1, 'bar', 5.5, @baz, 7, [5 .. 10], 'a', 7, $blee, 'wow hi', %floo);
>
> No one wants to look at or maintain that, and yet it must be allowed if all
> of those arguments are required.

Hey, maybe they do. They can write them as named if they want to.

And if you honestly have a sub with that many required parameters, you
probably need to rethink your design.

> >> So...why can't I have required named parameters?
> >
> > It's TMTOWTDI, forced upon you. The users of your module can use
> > whichsoever style they prefer, and you have to go to a lot of trouble
> > to keep them from doing that. And I think it's a good thing.
>
> TMTOWTDI means that you can allow required parameters to be specified
> positionally in the code that you write, if you want to. Forcing *everyone*
> to allow required parameters to be specified positionally is Bondage and
> Discipline, IMO.

I<allow> is the key word here. Forcing *everyone* to allow the users
of their module to use the C<$obj.call($p)> (as opposed to
C<call $obj: $p>) is Bondage and Dicipline? Definitely not. It's the
same deal: the module writer might consider a certain way easier to
read and write, but the user, the one the module is *for*, might not.

And you don't have to document the order. That forces people to work
harder if they want to make their code less readable.

> To imply that users of your code should be able to pick any possible WTDI is
> an argument against any kind of subroutine signature at all!

This is not true. I<This> is the one that allows the module writer to
pick any possible WTDI, but enforces a particular style on the users.
We saw that in Perl 5. Some modules used named syntax, some modules
used procedural methodology, but most used OO with functions with one
or two parameters. But by no means could you pass named parameters to
a sub where the module author didn't feel like supporting them.

In Perl 6, you get automatic support for multiple ways to do it.
Don't be so strict!

> > By the way, it's not a maintenance problem. You want to be able to
> > add new parameters without breaking old code using your module, right?
>
> The underlying objection is that there's nothing about either "positional"
> or "named" that implies "can be required" and "must always be optional"
> It's just an arbitrary rule, as far as I can see, and one that I don't
> happen to agree with.

But adding extra syntax to specify whether things are required is also
an arbitrary rule. You have to choose somewhere.

> > I say: Perl is an extensible language. Write a module that adds the
> > capability, and make it easy for yourself again.
>
> Sure, but that's not an argument for why it shouldn't be there in the first
> place.

I don't see here an argument for why it should. Indeed, I'm not
making an argument for why it shouldn't, I'm just trying to explain
why it's not.

Luke

John Siracusa

da leggere,
11 apr 2003, 21:34:5411/04/03
a Perl 6 Language
On 4/11/03 8:46 PM, Luke Palmer wrote:
> You want it to be easy to make using your module harder? Sorry,
> that's something the community just won't let you do.

But even Perl 6 itself seems to want to do it:

From S6:
> Every subroutine has an .assuming method. This method takes a series of
> named arguments, whose names must match parameters of the subroutine itself:
>
> &textfrom := &substr.assuming(str=>$text, len=>Inf);

If "named parameters are always optional", then the phrase "takes a series
of named arguments" seems pretty meaningless, and downright confusing in the
case where the subroutine being curried has required parameters...

(...not to distract from my earlier points, which still stand, but I thought
this description of .assuming was an odd bit or wording, at the every
least.)

-John

John Siracusa

da leggere,
11 apr 2003, 21:57:5711/04/03
a Perl 6 Language
On 4/11/03 9:26 PM, Luke Palmer wrote:
>>> You want it to be easy to make using your module harder? Sorry,
>>> that's something the community just won't let you do.
>>
>> Huh? How is requiring named parameters making my module "harder"? IMO,
>> positional parameters are "harder" because they require the user to remember
>> a specific order. Once you get beyond a certain number of parameters,
>> allowing them to be supplied positionally results in not-so-nice code like
>> this:
>>
>> foo(1, 'bar', 5.5, @baz, 7, [5 .. 10], 'a', 7, $blee, 'wow hi', %floo);
>>
>> No one wants to look at or maintain that, and yet it must be allowed if all
>> of those arguments are required.
>
> Hey, maybe they do. They can write them as named if they want to.

Hey, maybe I don't want them to, which is the whole point in creating an API
in the first place. I say this method requires at least 3 parameters, and I
say the "count" parameter has to be an int, and I say you have to use named
parameters for foo(). It's all of the same ilk, IMO.

> And if you honestly have a sub with that many required parameters, you
> probably need to rethink your design.

Even three or four becomes opaque quickly:

foo(1, 4, 2);

vs.

foo(red => 4,
pink => 2,
black => 1);

Quick, without looking back up, what is the value of "pink" in this call?

foo(99, 22, 33);

> the module writer might consider a certain way easier to read and write, but
> the user, the one the module is *for*, might not.

Users are always allowed to have an opinion about a module's API. This
small corner of the language is going to have a much smaller effect than
much broader issues of API design when it comes to a user's happiness with a
module.

> And you don't have to document the order. That forces people to work
> harder if they want to make their code less readable.

That's all well and good, but again, it doesn't actually argue for
disallowing required named parameters. I still see nothing about "named"
that makes me think "can never be required."

>> To imply that users of your code should be able to pick any possible WTDI is
>> an argument against any kind of subroutine signature at all!
>
> This is not true. I<This> is the one that allows the module writer to
> pick any possible WTDI, but enforces a particular style on the users.
> We saw that in Perl 5. Some modules used named syntax, some modules
> used procedural methodology, but most used OO with functions with one
> or two parameters. But by no means could you pass named parameters to
> a sub where the module author didn't feel like supporting them.
>
> In Perl 6, you get automatic support for multiple ways to do it.
> Don't be so strict!

I'm all for allowing a routine to support both, and this is clearly a
feature of Perl 6. I just think the programmer should control which
parameters are required and which are optional independent of any decisions
about how they are allowed to be supplied.

If things were completely symmetrical (i.e. if both named and positional
parameters could be either optional or required.), then I'd probably be more
accepting...

>>> I say: Perl is an extensible language. Write a module that adds the
>>> capability, and make it easy for yourself again.
>>
>> Sure, but that's not an argument for why it shouldn't be there in the first
>> place.
>
> I don't see here an argument for why it should.

If you can't think of *any* good reason why it shouldn't be done, then it
should be done, IMO. That aside, the argument is:

* it's a useful tool for API design
* it's not an unreasonable request (e.g. outlandish or at odds with the
language)
* at least one person wants to be able to do it (me :)

Failing that, as I alluded to earlier, at least just make things symmetrical
and allow both named and positional parameters to be either optional or
required. That's even less B&D-ish, and even more WTDI for everyone: module
users and module writers.

> Indeed, I'm not making an argument for why it shouldn't, I'm just trying to
> explain why it's not.

Maybe it's because Damian lost a coin toss? Who really knows? ;)

-John

John Siracusa

da leggere,
11 apr 2003, 22:05:4011/04/03
a Perl 6 Language
On 4/11/03 9:57 PM, John Siracusa wrote:
> Failing that, as I alluded to earlier, at least just make things symmetrical
> and allow both named and positional parameters to be either optional or
> required. That's even less B&D-ish, and even more WTDI for everyone: module
> users and module writers.

I just realized that this makes very little sense, given Perl 6's parameter
specification system, so just disregard this bit.... :)

-John

Brent Dax

da leggere,
13 apr 2003, 04:30:2913/04/03
a sira...@mindspring.com, Perl 6 Language
John Siracusa:
# From S6:
# > Every subroutine has an .assuming method. This method takes
# a series
# > of named arguments, whose names must match parameters of the
# > subroutine itself:
# >
# > &textfrom := &substr.assuming(str=>$text, len=>Inf);

That's to avoid this situation:

&textfrom := &substr.assuming($text, 0);
#Did I really want len to be 0, or did I mean index?

It forces you to name things *because* positional parameters no longer
make sense.

# If "named parameters are always optional", then the phrase
# "takes a series of named arguments" seems pretty meaningless,
# and downright confusing in the case where the subroutine
# being curried has required parameters...

It just fills in those parameters, just as if they had been appended in
the named zone. This call is perfectly legal:

substr(index => 0, str => $text, len => Inf);

So this is too:

&textfrom := &substr.assuming(str => $text, len => Inf);
textfrom(index => 0);

Because they're exactly equivalent.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

>How do you "test" this 'God' to "prove" it is who it says it is?
"If you're God, you know exactly what it would take to convince me. Do
that."
--Marc Fleury on alt.atheism

Austin Hastings

da leggere,
13 apr 2003, 11:20:2313/04/03
a sira...@mindspring.com, perl6-l...@perl.org

--- John Siracusa <sira...@mindspring.com> wrote:
> Sure, but that's not an argument for why it shouldn't be there in the
> first place.

We had this discussion last week: what's justification for inclusion in
core.

IMO, "enables a paradigm" is the easiest justification for new core
bits. "Require named parameters" doesn't enable a paradigm. It enables
a coding standard.

You can pass required args using named-arg notation, so there's no
reason you can't get both type-checking (from the requirement stuff)
and clarity (by coding yourself with named args-style). You just can't
require *ME* to do that.

Frankly, I think that if you're writing functions with too many args to
remember, you should consider wrapping your function into an object. Do
you really CHANGE all those args all the time? Or are three or four of
them "relatively constant"?

That is, does it make more sense to say:

something($a, $b, $c, Metric, Freedom);

or

$o.set_units(Metric);
$o.set_language(Freedom); # NB: Was "French" 3/10/03
$o.do_something($a, $b, $c);


>
> -John
>

=Austin

John Siracusa

da leggere,
13 apr 2003, 11:22:0313/04/03
a Perl 6 Language
On 4/13/03 4:30 AM, Brent Dax wrote:
> John Siracusa:
> # From S6:
> # > Every subroutine has an .assuming method. This method takes
> # a series
> # > of named arguments, whose names must match parameters of the
> # > subroutine itself:
> # >
> # > &textfrom := &substr.assuming(str=>$text, len=>Inf);
>
> That's to avoid this situation:
>
> &textfrom := &substr.assuming($text, 0);
> #Did I really want len to be 0, or did I mean index?
>
> It forces you to name things *because* positional parameters no longer
> make sense.

IMO, positional parameters "no longer make sense" if the API was not
designed to use positional parameters. I don't see how the call to
.assuming() is a "special case", or why only it should be allowed to require
named parameters, while code that regular users write cannot (without
run-time checks)

-John

John Siracusa

da leggere,
13 apr 2003, 11:34:5013/04/03
a Perl 6 Language
On 4/13/03 11:20 AM, Austin Hastings wrote:
> --- John Siracusa <sira...@mindspring.com> wrote:
>> Sure, but that's not an argument for why it shouldn't be there in the
>> first place.
>
> We had this discussion last week: what's justification for inclusion in
> core.
>
> IMO, "enables a paradigm" is the easiest justification for new core
> bits. "Require named parameters" doesn't enable a paradigm. It enables
> a coding standard.

What about "saves the programmer work" and "enables compile-time checks that
are impossible otherwise"? After all, that's what formal parameter lists
do. You can do all of the checks and coercions they perform "long-hand" at
runtime, but that a) is more work, and b) is all done at runtime, and
therefore is less efficient.

> You can pass required args using named-arg notation, so there's no
> reason you can't get both type-checking (from the requirement stuff)
> and clarity (by coding yourself with named args-style). You just can't
> require *ME* to do that.

I can force you to pass three args, not two, and I can force you to make the
first arg an int, but I can't force you to pass only named parameters?

As for "forcing" call styles, why is Perl 6 forcing everyone to allow all of
the required parameters to their routines to be passed as positional
parameters?

> Frankly, I think that if you're writing functions with too many args to
> remember, you should consider wrapping your function into an object.

See earlier post. I think things can get foggy with even just three or four
arguments.

And as for objects, constructors are a perfect example of routines that
might have many required arguments, none of which I'd like to allow as
positional parameters. But I can't do that without runtime hackery in Perl
6 (unless I'm writing ".assuming()", apparently) Why? Because my desire
for clarity in my API does not represent a "new paradigm"? And requiring
positional parameters somehow does?

-John

Austin Hastings

da leggere,
13 apr 2003, 11:39:4313/04/03
a sira...@mindspring.com, Perl 6 Language

--- John Siracusa <sira...@mindspring.com> wrote:

Umm. Do you understand what .assuming does?

Because it doesn't REQUIRE any parameters -- they're all optional. But
if you're going to specify a parameter, it's required to be in the
named-parameter form.

So, in declaration terms, none of the parameters to &foo.assuming are
in the "required" zone. They're all in the named zone, they're all
optional, and that's the only way to specify them.

Let's be clear on the difference between

required to be present

and

required to be specified using name=>value style

here.

From what I can gather from your writings, you want to be able to do
both:

require that all args come in as named, and
require that all args be present.

That, you can't do.

You can require args to be present, and then use the name=>value
notation to specify them if you want.

You can require args to be name=>value specified, but let them be
optional (requiring you to check for their values, a la P5, inside your
sub).

=Austin

Austin Hastings

da leggere,
13 apr 2003, 11:44:5013/04/03
a sira...@mindspring.com, Perl 6 Language

To me, yes. The P6 core provides the capability for you to write an
interface that will require named parameters. This requirednamed stuff
has not, apparently, infused the list with "we MUST be able to do that
from the get-go" spirit. Ergo, you want, you write it.

The "new paradigm" part has been satisfied: you've got introspection,
macros, grammar changes, required args -- all the tools you need to
implement the paradigm. It's your bike shed. Start painting.

> -John

=Austin

John Siracusa

da leggere,
13 apr 2003, 11:57:2013/04/03
a Perl 6 Language
On 4/13/03 11:39 AM, Austin Hastings wrote:
> Because it doesn't REQUIRE any parameters -- they're all optional.

Yeah, brainfart there, sorry :)

OTOH, is a call to .assuming() with no arguments allowed? If not, is it
caught at runtime or compile-time?

> From what I can gather from your writings, you want to be able to do
> both:
>
> require that all args come in as named, and
> require that all args be present.
>
> That, you can't do.

I just want to be able to require that any arbitrary argument of my choice
must come in as named, independent of whether it's required or optional.

> You can require args to be name=>value specified, but let them be
> optional (requiring you to check for their values, a la P5, inside your
> sub).

...which is what Perl 6 is supposed to save me from doing, IMO.

-John

John Siracusa

da leggere,
13 apr 2003, 12:01:4713/04/03
a Perl 6 Language
On 4/13/03 11:44 AM, Austin Hastings wrote:
> The P6 core provides the capability for you to write an interface that will
> require named parameters. This requirednamed stuff has not, apparently,
> infused the list with "we MUST be able to do that from the get-go" spirit.
> Ergo, you want, you write it.
>
> The "new paradigm" part has been satisfied: you've got introspection,
> macros, grammar changes, required args -- all the tools you need to
> implement the paradigm. It's your bike shed. Start painting.

I think requiring that a parameter come in as named is in the same class of
features as most of the rules that can be applied to formal parameters. I
don't see why it should be left out, while other similar features have nice
syntactic shorthand, and possibly compile-time checks. After all, we have
"all the tools" to write our own checks for parameter types too.

-John

Austin Hastings

da leggere,
13 apr 2003, 13:37:3013/04/03
a sira...@mindspring.com, Perl 6 Language

--- John Siracusa <sira...@mindspring.com> wrote:
> On 4/13/03 11:44 AM, Austin Hastings wrote:
> > The P6 core provides the capability for you to write an interface
> that will
> > require named parameters. This requirednamed stuff has not,
> apparently,
> > infused the list with "we MUST be able to do that from the get-go"
> spirit.
> > Ergo, you want, you write it.
> >
> > The "new paradigm" part has been satisfied: you've got
> introspection,
> > macros, grammar changes, required args -- all the tools you need to
> > implement the paradigm. It's your bike shed. Start painting.

In the interest of putting my money where my fingers are, I've been
thinking about this.

What is wanted is the ability to confirm that certain "named"
parameters are in fact present.

If we assume:

sub foo(
+$a is Type is required,
+$b is OtherType is required,
+$c is SomeType)
{...}

Then $a, $b, and $c are all named parameters, but $a and $b have the is
required trait.

So I want something like this:

sub foo(...as above ...) {
for &_.signature -> $sigelt {
next unless $sigelt.required;
die $sigelt.name ~ " not specified"
unless exists(&_.named{$sigelt.name});
}

...
}

But this gets old, quickly. So we wrap it:

sub check_reqnames() {
for &_.signature -> $sigelt {
next unless $sigelt.required;
die $sigelt.name ~ " not specified"
unless exists(&_.named{$sigelt.name});
}
call;
}

and then:

&foo.wrap(check_reqnames);

But this has the drawback of being a run-time operation, as John points
out. What is really wanted is some of those introspection bits. This
isn't going to be a macro, because I don't intend to replace the
run-time thing. I intend to do compile time work, on the caller, not
the callee. So I have to have a way of taking

sub foo(...as above...) {...}

and converting that into

macro foo(...) {...}

in a relatively innocuous manner. For example, I'd like to say:

module Austin::IsTheGreatest;

BEGIN {
sub check_subdecl_and_maybe_macroize() {

my $emit_macro = false;

if (any(@args).required) {
$name := "_reqd_args_" ~ $name;
$emit_macro = true;
}

call;

if $emit_macro {
'macro ' ~ $name ~ ' is parsed(<subcall>) {
for &_.args -> $a {
next unless $a.required;
die "In call to ~ {&_.name}, argument ~{$a.name} not given
as named arg"
unless exists &_.named{$a.name};
}

&_reqdargs_' ~ $name ~ '.call(**&_.args);
}";
} # if $emit_macro
} # sub check_subdecl_and_maybe_macroize

Perl6::Grammar::subdecl.wrap(&check_subdecl_and_maybe_macroize);
}

And that should automatically convert C<sub foo> into C<macro foo> plus
C<sub _reqdargs_foo> and the appropriate checking at compile time.

Note that I'm assuming that the introspection stuff will attach static
data AND dynamic data via the &_ current-function-handle, which may be
wrong. But it seems the way to go for now.

All you have to do is say:

use Austin::IsTheGreatest;

at the top of all your code. :-)

=Austin

John Siracusa

da leggere,
13 apr 2003, 14:09:0713/04/03
a Perl 6 Language
On 4/13/03 1:37 PM, Austin Hastings wrote:
[big, scary example code snipped]

No offense, but that example makes me want required named parameters to be
part of the base language even more... ;)

-John

Luke Palmer

da leggere,
13 apr 2003, 14:14:5613/04/03
a Austin_...@yahoo.com, sira...@mindspring.com, perl6-l...@perl.org
Austin writes:
> [ Bunch of code and Austin::IsTheGreatest module ]

>
> And that should automatically convert C<sub foo> into C<macro foo> plus
> C<sub _reqdargs_foo> and the appropriate checking at compile time.
>
> Note that I'm assuming that the introspection stuff will attach static
> data AND dynamic data via the &_ current-function-handle, which may be
> wrong. But it seems the way to go for now.
>
> All you have to do is say:
>
> use Austin::IsTheGreatest;
>
> at the top of all your code. :-)

And as much as we all would love to make that affirmation :), I don't
think you need to make a macro maker, uh, macro. Checking things at
compile time is going to be something that will make Perl 6 great, and
there might just be a trait on parsable things that executes code upon
parsing.

sub foo(+$name, +$lang)
will BEGIN { die unless exists($name & $lang) }
will do {...}

Or something like that. (Presumably, $name and $lang only have their
parse trees filled in, but we don't care, as long as they
exist). Sure, your way works if we don't have it (although your code
had some---a lot of bugs. But it *is* still a nonexistent language),
but I do think it would be a worthwhile trait.

Not that it *needs* to be built-in. Maybe Austin::IsTheGreatest
should implement that trait f as wellor greater flexibility. Once we
learn how to implement traits.

Luke

Austin Hastings

da leggere,
13 apr 2003, 14:15:0313/04/03
a sira...@mindspring.com, Perl 6 Language

--- John Siracusa <sira...@mindspring.com> wrote:
Bah! You're just afraid to put Austin::IsTheGreatest at the top of all
your modules.

:-)

=Austin


Austin Hastings

da leggere,
13 apr 2003, 14:28:2313/04/03
a Luke Palmer, Austin_...@yahoo.com, sira...@mindspring.com, perl6-l...@perl.org

Bugs don't bother me -- greatness may take some time to achieve, after
all.

I wonder about the BEGIN thing, though. To me, the BEGIN thing is
called once, and not once-per-invocation.

>
> Not that it *needs* to be built-in. Maybe Austin::IsTheGreatest
> should implement that trait f as wellor greater flexibility. Once we
> learn how to implement traits.
>

Traits seem like a lot of things. It occurs to me that Larry's notion
of (sub)typing ties in here:

sub foo(+$name, +$lang)
will PRE { validate_name($name); check_lang($lang); }
{...}

could profitably be rewritten as:

sub foo(+$name is validated({validate_name($_)}),
+$lang is validated({check_lang($_)}))
{...}

which could then be considered typing:

class Name {
submethod BEGIN { validate_name($_) && SUPER::BEGIN($_); }
}

class Lang {
submethod BEGIN { check_lang($_) && SUPER::BEGIN($_); }
}

sub foo(+$name is Name, +$lang is Lang) {...}

This is great for contract enforcement, preconditions, etc. but it's
still a compile-time thing. The way to get runtime behavior is going to
have to be with macros or builtins. As I said to John, if it can be
done in a macro, we don't need the built-in -- the macro has to be
written once. (See <stdio.h>::getchar() for a spectacular, if
horrible, example of this...)


> Luke

=The Greatest

Luke Palmer

da leggere,
13 apr 2003, 14:29:3213/04/03
a fibo...@babylonia.flatirons.org, Austin_...@yahoo.com, sira...@mindspring.com, perl6-l...@perl.org
I wrote:
>
> sub foo(+$name, +$lang)
> will BEGIN { die unless exists($name & $lang) }
> will do {...}

Then we run into the problem of:

%attrs := { name => 'Everybody',
language => 'Perl' };
foo *%attrs;

Which is, naturally, impossible to detect except for in the simplest
of cases. This makes me wonder how $name and $lang would actually get
bound at compile time to anything at all.

So this kind of checking would have to be deferred until runtime when
there's a *% argument. So making a macro maker macro might manifest
to the most mutable method (Whew, no more alliterations for me for
a while :). I just want to be able to do stuff easily at compile time,
using all the information I can without worrying about a macro that
just repeats itself as a sub call, etc.

Luke

Austin Hastings

da leggere,
13 apr 2003, 14:42:2913/04/03
a Luke Palmer, sira...@mindspring.com, perl6-l...@perl.org

--- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> I wrote:
> >
> > sub foo(+$name, +$lang)
> > will BEGIN { die unless exists($name & $lang) }
> > will do {...}
>
> Then we run into the problem of:
>
> %attrs := { name => 'Everybody',
> language => 'Perl' };
> foo *%attrs;
>
> Which is, naturally, impossible to detect except for in the simplest
> of cases. This makes me wonder how $name and $lang would actually
> get bound at compile time to anything at all.

And yet it flies.

Run time binding: there's no conceivable way to get the data before
hand. Hell, the data might not exist at run-time: consider parsing a
file and putting keyword=value into the hash.

So the required args stuff will always have a check at runtime, in case
one of the wierd cases comes along. Humbug.

>
> So this kind of checking would have to be deferred until runtime when
> there's a *% argument. So making a macro maker macro might manifest
> to the most mutable method

Hey, not bad!

>(Whew, no more alliterations for me for
> a while :). I just want to be able to do stuff easily at compile
> time,
> using all the information I can without worrying about a macro that
> just repeats itself as a sub call, etc.

Ah, but making a manifestly mutable macro making macro (m5, or m35o?
anyway:) making a m35o absquatulates the whole issue. We hide the
bizarre behavior in the parser, except for the bit about run-time
checks. Frankly, the proper way to do that is probably to make the
_reqdargs_foo version use positional parameters (laugh!) so that we get
the cheapest possible run-time checking.

Or we could just give it a pass, and declare that anyone who passes a
hash, or passes a list, is doing "enough of the right thing" that we
don't worry about the actual presence of the named arguments in
question.

John, how would you like the condition handled?

Example:

sub foo(+$name is required, +$lang is required) {...}

sub fn1(%a)
{
foo(%a);
}

What should the parser do given that circumstance?

=Austin

John Siracusa

da leggere,
13 apr 2003, 16:10:2813/04/03
a Perl 6 Language
On 4/13/03 2:28 PM, Austin Hastings wrote:
> As I said to John, if it can be done in a macro, we don't need the built-in

But doesn't that also apply to a whole slew of things in the existing
"built-in" Perl 6 routine signature system?

-John

John Siracusa

da leggere,
13 apr 2003, 16:14:4713/04/03
a Perl 6 Language
On 4/13/03 2:42 PM, Austin Hastings wrote:
> John, how would you like the condition handled?
>
> Example:
>
> sub foo(+$name is required, +$lang is required) {...}
>
> sub fn1(%a)
> {
> foo(%a);
> }
>
> What should the parser do given that circumstance?

I don't mind falling back on runtime checks when there's absolutely no way
to know enough at compile time. But I can also imagine someone wanting to
be more strict.

-John

Austin Hastings

da leggere,
13 apr 2003, 16:55:3513/04/03
a sira...@mindspring.com, Perl 6 Language

--- John Siracusa <sira...@mindspring.com> wrote:

Meaning what? That foo(%a) is not acceptable, but
foo(name => 'Everybody', lang => 'Perl6') is acceptable?

That's actually the easier case to write -- blow up if you don't see
exactly what you want.

Accepting the %a in place of the named args, but then requiring
run-time checks, that's going to be a pain. Probably best to generate
the two-entry-point monster discussed a while back (arg-checking, no
arg-checking) and call that.

sub foo__with_checking() { do_checks(); foo();}

=Austin

John Siracusa

da leggere,
13 apr 2003, 17:16:1413/04/03
a Perl 6 Language
On 4/13/03 4:55 PM, Austin Hastings wrote:
>> I don't mind falling back on runtime checks when there's absolutely no way to
>> know enough at compile time. But I can also imagine someone wanting to be
>> more strict.
>
> Meaning what? That foo(%a) is not acceptable, but
> foo(name => 'Everybody', lang => 'Perl6') is acceptable?

Yeah, unless it can be determined at compile time that %a will have only the
expected/allowed keys.

-John

Damian Conway

da leggere,
13 apr 2003, 18:25:4513/04/03
a Perl 6 Language
John Siracusa wrote:

> I just want to be able to require that any arbitrary argument of my choice
> must come in as named, independent of whether it's required or optional.

There's no syntax for that at present.

The easiest way at the moment would be:

sub foo ($required1, $required2, $required3) {
# implementation here
}
BEGIN {
&foo.wrap( sub(*%args){call} )
}

Of course that doesn't enforce compile-time checking of names. But even if
there *were* a declarative syntax for required, named parameters, you still
couldn't guarantee compile-time checking:

foo(%args);
foo($nameA=>1, $nameB=>2, $nameC=>3);

If you really want to *insist* on parameter names being compile-time
constants, then you'd need to parse that yourself by going macro-biotic:

macro foo ($args) is parsed(/<list <ident> =\> <Perl.expr>>>/) {
"sub {
# implementation here
}.($args)"
}


Damian

John Siracusa

da leggere,
13 apr 2003, 18:45:4613/04/03
a Perl 6 Language
On 4/13/03 6:25 PM, Damian Conway wrote:
> John Siracusa wrote:
>> I just want to be able to require that any arbitrary argument of my choice
>> must come in as named, independent of whether it's required or optional.
>
> There's no syntax for that at present.

Ah ha! A glimmer of hope! Maybe :)

> even if there *were* a declarative syntax for required, named parameters, you
> still couldn't guarantee compile-time checking:
>
> foo(%args);
> foo($nameA=>1, $nameB=>2, $nameC=>3);

Right, but like I said earlier, I don't mind if it falls back to a runtime
check when it has no other choice. But I'd expect some minimal amount of
cleverness from the compiler:

my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax, right?
foo(%args); # you're a smart compiler, do that check for me :)

-John

Damian Conway

da leggere,
13 apr 2003, 19:51:4513/04/03
a perl6-l...@perl.org
>>There's no syntax for that at present.
>
> Ah ha! A glimmer of hope! Maybe :)

Maybe. I can see the potential value in mandatorily named arguments. I'm just
not sure I see a suitable syntax. Unless it's really the case that the
requireness/optionality and positionality/namedness traits of parameters
really are traits, and the punctuational modifiers are just convenient shorthands:

sub foo($a) {...} # short for: sub foo($a is required) {...}
sub foo(?$a) {...} # short for: sub foo($a is optional) {...}
sub foo(+$a) {...} # short for: sub foo($a is optional is named) {...}
sub foo(*$a) {...} # short for: sub foo($a is listiferious) {...}

in which case:

sub foo($a is named) {...}

would presumably provide what you wanted.


>>even if there *were* a declarative syntax for required, named parameters, you
>>still couldn't guarantee compile-time checking:
>

> Right, but like I said earlier, I don't mind if it falls back to a runtime
> check when it has no other choice. But I'd expect some minimal amount of
> cleverness from the compiler:
>
> my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax, right?
> foo(%args); # you're a smart compiler, do that check for me :)

Sure. But the compiler can't do that in an even slightly more complex case:

my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax, right?

bar(%args);
foo(%args); # will &bar change %args at run-time???

so I think it's doubtful it would check in the simple case either. But that's
Dan's headache, not mine. :-)

Damian

John Siracusa

da leggere,
13 apr 2003, 21:03:3213/04/03
a Perl 6 Language
On 4/13/03 7:51 PM, Damian Conway wrote:
>>> There's no syntax for that at present.
>>
>> Ah ha! A glimmer of hope! Maybe :)
>
> Maybe. I can see the potential value in mandatorily named arguments. I'm just
> not sure I see a suitable syntax.

This was my secret fear: that the feature was really left out because all
the suitable characters were used up in the existing signature syntax ;)

> Unless it's really the case that the requireness/optionality and
> positionality/namedness traits of parameters really are traits, and the
> punctuational modifiers are just convenient shorthands:
>
> sub foo($a) {...} # short for: sub foo($a is required) {...}
> sub foo(?$a) {...} # short for: sub foo($a is optional) {...}
> sub foo(+$a) {...} # short for: sub foo($a is optional is named) {...}
> sub foo(*$a) {...} # short for: sub foo($a is listiferious) {...}

I thought that was already true...but I guess it was that just a
mailing-list suggestion that got mixed in with the "official" stuff in my
head. Anyway, yeah, something like that would be nice.

> Sure. But the compiler can't do that in an even slightly more complex case:
>
> my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax, right?
> bar(%args);
> foo(%args); # will &bar change %args at run-time???
>
> so I think it's doubtful it would check in the simple case either.

Sure it would...why not? If it's so simple...

> But that's Dan's headache, not mine. :-)

My thoughts exactly :)

-John

Brent Dax

da leggere,
13 apr 2003, 22:24:3013/04/03
a Austin_...@yahoo.com, Luke Palmer, sira...@mindspring.com, perl6-l...@perl.org
Austin Hastings:
# sub foo(+$name is validated({validate_name($_)}),
# +$lang is validated({check_lang($_)}))
# {...}

Hopefully, it would be

sub foo(+$name will validate { validate_name($_) },
+$lang will validate { check_lang($_) })
{...}

Uri Guttman

da leggere,
13 apr 2003, 23:13:0613/04/03
a Damian Conway, perl6-l...@perl.org
>>>>> "\DC" == Damian Conway <dam...@conway.org> writes:


\DC> Sure. But the compiler can't do that in an even slightly more
complex case:

\DC> my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax, right?
\DC> bar(%args);
\DC> foo(%args); # will &bar change %args at run-time???

\DC> so I think it's doubtful it would check in the simple case either. But
\DC> that's Dan's headache, not mine. :-)

and it is even worse if you pass the ref down the call chain.

sub foo ( $ref ) { bar( $ref ) }
sub bar ( $a, $b ) { ... }

foo( { a => 1, b => 2 } ) ;

no way that could be checked at compile time without some serious
halting test skills.

i use named vars for a large p5 system and i have to do runtime
checking as it is pure OO and the compiler won't even know which method
would get called at compile time.

the goal of forcing the caller to use named args has to be split into
two cal types: explicit passing of a list of pairs and implicit passing
of the args from a hash or array. you can't force the coder to only use
explicit pairs as one major advantage of using named args is passing in
optional ones by building up a list of pairs. in fact forcing that is a
bad thing as you lose the power of that dynamic arg generation. the
caller would have to build up their pairs, extract all the args and then
make an explicit call with all the required named args:

my %args = build_args() ;
foo( a => %args{a}, b => %args{b} ) ;

that is putting too much burden on the caller. but it does allow for
compile time checking of required named args.

so if YOU want stronger compile time checking for the calls YOU make,
you have to do the above hack. it is not the responsibility of the
callee to enforce a calling style. the callee can enforce required
params and also support named args but it has no control over calling
style.

and since the callee won't know how it was called, it still has to do
runtime checking for required named params. maybe a hidden arg could be
passed if the caller was compile timed checked and had all the required
args. then it can skip the runtime check, otherwise it must be done.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Mark Biggar

da leggere,
13 apr 2003, 18:06:1413/04/03
a perl6-l...@perl.org
Austin Hastings wrote:

> Ah, but making a manifestly mutable macro making macro (m5, or m35o?
> anyway:) making a m35o absquatulates the whole issue. We hide the
> bizarre behavior in the parser, except for the bit about run-time
> checks. Frankly, the proper way to do that is probably to make the
> _reqdargs_foo version use positional parameters (laugh!) so that we get
> the cheapest possible run-time checking.

As a macro can just return a full macro definition as a string,
you can always write just such a macro gening macro.

> Or we could just give it a pass, and declare that anyone who passes a
> hash, or passes a list, is doing "enough of the right thing" that we
> don't worry about the actual presence of the named arguments in
> question.
>
> John, how would you like the condition handled?
>
> Example:
>
> sub foo(+$name is required, +$lang is required) {...}
>
> sub fn1(%a)
> {
> foo(%a);
> }
>
> What should the parser do given that circumstance?

Wrap the call to foo with the proper runtime checks of course.

and if I do

{ ... foo(name => "bar", lang => 'logban'); ... }

the the complier can do the check and I don't get the runtime overhead.
even partial cases like can be

sub fn2 (%a)
{
foo(name => 'george', %a);
}

get handled correctly using part compile time and part runtime checking.


--
Mark Biggar
ma...@biggar.org
mark.a...@attbi.com


Michael Lazzaro

da leggere,
14 apr 2003, 14:08:4414/04/03
a Perl 6 Language

On Sunday, April 13, 2003, at 06:03 PM, John Siracusa wrote:
> On 4/13/03 7:51 PM, Damian Conway wrote:
>> Unless it's really the case that the requireness/optionality and
>> positionality/namedness traits of parameters really are traits, and
>> the
>> punctuational modifiers are just convenient shorthands:
>>
>> sub foo($a) {...} # short for: sub foo($a is required) {...}
>> sub foo(?$a) {...} # short for: sub foo($a is optional) {...}
>> sub foo(+$a) {...} # short for: sub foo($a is optional is named)
>> {...}
>> sub foo(*$a) {...} # short for: sub foo($a is listiferious) {...}
>
> I thought that was already true...but I guess it was that just a

Seeing that it solves the problem -- I too would like to see a
capability for named but required parameters -- I propose we just do
this, then. Say that you can say "is named", "is required", "is
optional" as traits, and be done with it, but that's not what the
C<+$a> shortcut will do.

Can I get an Amen?

MikeL

John Siracusa

da leggere,
14 apr 2003, 14:29:1114/04/03
a Perl 6 Language

...I don't suppose anyone is up for:

sub foo(+$a) {...} # short for: sub foo($a is required is named)
sub foo(+?$a) {...} # short for: sub foo($a is optional is named)

OTOH, I don't mind always having to write out the traits for required named
parameters, but Perl 6 seems to be all about scavenging characters... :)

-John

Michael Lazzaro

da leggere,
14 apr 2003, 14:47:5414/04/03
a perl6-l...@perl.org

On Sunday, April 13, 2003, at 04:51 PM, Damian Conway wrote:
> my %args = { a => 1, b => 2 }; # this is the Perl 6 syntax,
> right?
> bar(%args);

Err... a question. My previous impression was that the above would
_NOT_ work, if bar() was expecting two arguments $a and $b, because
you're sending bar() a single parameter, of type hash, rather than two
arguments $a and $b.

So that this would work:

bar(*%args);

but this would not:

bar(%args);

???

MikeL

Paul

da leggere,
14 apr 2003, 14:47:2814/04/03
a Michael Lazzaro, perl6-l...@perl.org

That was my thinking.

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://tax.yahoo.com

Paul

da leggere,
14 apr 2003, 14:51:2214/04/03
a Michael Lazzaro, Perl 6 Language

--- Michael Lazzaro <mlaz...@cognitivity.com> wrote:
> On Sunday, April 13, 2003, at 06:03 PM, John Siracusa wrote:
> > On 4/13/03 7:51 PM, Damian Conway wrote:
> >> Unless it's really the case that the requireness/optionality and
> >> positionality/namedness traits of parameters really are traits,
> >> and the punctuational modifiers are just convenient shorthands:
> >>
> >> sub foo($a) {...} # short for: sub foo($a is required) {...}
> >> sub foo(?$a) {...} # short for: sub foo($a is optional) {...}
> >> sub foo(+$a) {...} # short for: sub foo($a is optional is named)
> >> sub foo(*$a) {...} # short for: sub foo($a is listiferious)
> >
> > I thought that was already true...but I guess it was that just a
>
> Seeing that it solves the problem -- I too would like to see a
> capability for named but required parameters -- I propose we just do
> this, then. Say that you can say "is named", "is required", "is
> optional" as traits, and be done with it, but that's not what the
> C<+$a> shortcut will do.
>
> Can I get an Amen?
>
> MikeL

There comes a point at which a shorthand adds a lot of work.
Someone extremely familiar with it might have no problem, but the next
guy is probably not going to be quite that much the guru. For simple
things, the shorthand is sometimes best, but when it gets complex and
"persnickety", just bite the bullet and type the damned traits out
where anybody can read it.

In other (and fewer) word, "Amen". :)

Brent Dax

da leggere,
14 apr 2003, 15:06:2514/04/03
a sira...@mindspring.com, Perl 6 Language
John Siracusa:
# ...I don't suppose anyone is up for:
#
# sub foo(+$a) {...} # short for: sub foo($a is required is
# named)
# sub foo(+?$a) {...} # short for: sub foo($a is optional is
# named)

Not. A. Chance.

This is one of the big reasons I *don't* want there to be required named
parameters--logically speaking, you would want + alone to do a required
parameter, but that goes against Huffman coding.

John Siracusa

da leggere,
14 apr 2003, 15:00:5314/04/03
a Perl 6 Language
On 4/14/03 3:06 PM, Brent Dax wrote:
> John Siracusa:
> # ...I don't suppose anyone is up for:
> #
> # sub foo(+$a) {...} # short for: sub foo($a is required is
> # named)
> # sub foo(+?$a) {...} # short for: sub foo($a is optional is
> # named)
>
> Not. A. Chance.
>
> This is one of the big reasons I *don't* want there to be required named
> parameters--logically speaking, you would want + alone to do a required
> parameter, but that goes against Huffman coding.

That's not a reason not to want required named parameters. That's just a
reason to reject the particular shortcut I proposed :) Like I said, I
wouldn't mind typing out the traits for required named parameters if a
suitable shortcut isn't possible. But I think it *might* be possible with
some clever ASCII shuffling in the signature syntax...

(...by someone other than me, it seems ;)
-John

Paul

da leggere,
14 apr 2003, 15:04:0814/04/03
a Brent Dax, sira...@mindspring.com, Perl 6 Language

--- Brent Dax <bren...@cpan.org> wrote:
> John Siracusa:
> # ...I don't suppose anyone is up for:
> # sub foo(+$a) {...} # short for: sub foo($a is required is named)
> # sub foo(+?$a) {...} # short for: sub foo($a is optional is named)
>
> Not. A. Chance.

I'm with Brent. Aside from other complications, do you *really* want to
maintain code like this? Geez, it really does start to look like
shorthand. We'll *need* Unicode characters at this rate. :)

> This is one of the big reasons I *don't* want there to be required
> named parameters--logically speaking, you would want + alone to do a
> required parameter, but that goes against Huffman coding.

I don't understand this. I definitely think there should be the option
of required named params, and I personally don't care if they don't
even have a shorthand. I admit that it's easy enough to check at
runtime in the function, but would prefer to put it in the declaration
-- using trait names, personally.

But I don't know what you mean. Sorry, density attack. Elaborate? :)

Brent Dax

da leggere,
14 apr 2003, 15:29:0614/04/03
a Hod...@writeme.com, sira...@mindspring.com, Perl 6 Language
Paul:
# --- Brent Dax <bren...@cpan.org> wrote:
# > This is one of the big reasons I *don't* want there to be required
# > named parameters--logically speaking, you would want +
# alone to do a
# > required parameter, but that goes against Huffman coding.
#
# I don't understand this. I definitely think there should be
# the option of required named params, and I personally don't
# care if they don't even have a shorthand. I admit that it's
# easy enough to check at runtime in the function, but would
# prefer to put it in the declaration
# -- using trait names, personally.
#
# But I don't know what you mean. Sorry, density attack. Elaborate? :)

What I mean is that, if we support required named parameters, the
logical syntax would be:

ZONE REQUIREDNESS MEANING
(nothing) (nothing) Required positional
(nothing) ? Optional positional
+ (nothing) Required named
+ ? Optional named

But I suspect that optional named parameters are going to be *much*
*much* more common than required named parameters, so the syntax above
is bad from Huffman's POV.

I'm starting to wonder if we really need the question-mark at all.
Maybe you just have to provide a default explicitly if you want a
parameter to be optional:

sub substr(Str $text, Int ?$index=0, Int ?$len=Inf) { ... }
sub substr(Str $text, Int $index=0, Int $len=Inf) { ... }

I suppose it depends on whether defaulting to undef will be more common
than defaulting to something else. If defaulting to something else will
be more common, then it saves keystrokes, but if defaulting to undef
will be more common, it costs them. And it does solve the
named-required-vs.-named-optional dispute nicely--if you provide a
default it's optional, otherwise it's required.

John Siracusa

da leggere,
14 apr 2003, 15:27:3114/04/03
a Perl 6 Language
On 4/14/03 3:29 PM, Brent Dax wrote:
> if we support required named parameters, the logical syntax would be:
>
> ZONE REQUIREDNESS MEANING
> (nothing) (nothing) Required positional
> (nothing) ? Optional positional
> + (nothing) Required named
> + ? Optional named
>
> But I suspect that optional named parameters are going to be *much*
> *much* more common than required named parameters, so the syntax above
> is bad from Huffman's POV.

So, what other characters can we steal...

ZONE REQUIREDNESS MEANING
(nothing) (nothing) Required positional
(nothing) ? Optional positional

- (nothing) Required named
+ (nothing) Optional named

Or maybe swap + and - above? Hmmm...

-John

Paul

da leggere,
14 apr 2003, 15:33:5314/04/03
a Brent Dax, sira...@mindspring.com, Perl 6 Language

--- Brent Dax <bren...@cpan.org> wrote:
> Paul:
> # --- Brent Dax <bren...@cpan.org> wrote:
> # > This is one of the big reasons I *don't* want there to be
> # > required named parameters--logically speaking, you would want +
> # > alone to do a required parameter, but that goes against Huffman
> # > coding.

> #
> # I don't understand this. I definitely think there should be
> # the option of required named params, and I personally don't
> # care if they don't even have a shorthand. I admit that it's
> # easy enough to check at runtime in the function, but would
> # prefer to put it in the declaration
> # -- using trait names, personally.
> #
> # But I don't know what you mean. Sorry, density attack. Elaborate?
>
> What I mean is that, if we support required named parameters, the
> logical syntax would be:
>
> ZONE REQUIREDNESS MEANING
> (nothing) (nothing) Required positional
> (nothing) ? Optional positional
> + (nothing) Required named
> + ? Optional named
>
> But I suspect that optional named parameters are going to be *much*
> *much* more common than required named parameters, so the syntax
> above is bad from Huffman's POV.

Ah, ok. Well, I'm starting to wonder if we need the shortcuts.
There are times when Huffman has to give way to maintenance....
but that's not an argument for having or not having them as language
features; just for using or not using them in a given bit of code.
Personally, I'd rather *not* have them available, because if they
exist, I'll probably *use* them, lol....

> I'm starting to wonder if we really need the question-mark at all.
> Maybe you just have to provide a default explicitly if you want a
> parameter to be optional:
>
> sub substr(Str $text, Int ?$index=0, Int ?$len=Inf) { ... }
> sub substr(Str $text, Int $index=0, Int $len=Inf) { ... }
>
> I suppose it depends on whether defaulting to undef will be more
> common than defaulting to something else. If defaulting to
> something else will be more common, then it saves keystrokes, but
> if defaulting to undef will be more common, it costs them.

I'd suspect the undef will be more likely.

> And it does solve the named-required-vs.-named-optional dispute
> nicely--if you provide a default it's optional, otherwise it's
> required.

That it does; once again, I can let Huffman coding suffer in this.
It's good to name things using Huffman code when you can, but you have
to be reasonable. We could make all the built-in functions like split
and join be s() and j(), and when those ran out on the more used func's
we could say sp() and jn(), but I don't think that's wise, for obvious
reasons.

Huffman in great for deciding between "hungry" and "slurpificatious",
but probably not between "is optional is named" and "+?$x". But that's
just me, and even then, I don't rule it out; I just don'tplan to use it
until I've become so familiar with it that it looks obvious to me, the
way "{ $/ = undef; $f = <FOO>; }" is readable to me...but my coworkers
curse me for it when I do that....

Peter Haworth

da leggere,
16 apr 2003, 12:03:2516/04/03
a Perl 6 Language
On Fri, 11 Apr 2003 18:57:26 -0400, John Siracusa wrote:
> I forget if this was covered earlier, but what is the reason for this? I
> can easily imagine wanting to create subroutines that only accept named
> parameters, some or all of which are required. How would this be done in
> Perl 6?

I realise this has been discussed to death already, but can't you solve this
with documentation, pretending that your required positional parameters are
actually required named parameters? This doesn't stop users of your routine
from passing positional parameters, but you can change the order with every
release to prevent that :-)

=item foo()

Accepts the following named parameters:

bar (required): description of bar
baz (required): description of baz
qux (optional): description of qux

=cut

sub foo($bar, $baz, +$qux){...}

--
Peter Haworth p...@edison.ioppublishing.com
"Visual Basic designers have chosen to pile more and more doodads on
a weak foundation, knowing that doodads, not foundations, sell boxes."
-- Bruce McKinney

Michael Lazzaro

da leggere,
16 apr 2003, 13:00:1316/04/03
a Peter Haworth, Perl 6 Language
On Wednesday, April 16, 2003, at 09:03 AM, Peter Haworth wrote:
> On Fri, 11 Apr 2003 18:57:26 -0400, John Siracusa wrote:
>> can easily imagine wanting to create subroutines that only accept
>> named
>> parameters, some or all of which are required. How would this be
>> done in
>> Perl 6?
> I realise this has been discussed to death already, but can't you
> solve this
> with documentation, pretending that your required positional
> parameters are
> actually required named parameters?

Yes, you can. The sole reason people have proposed 'required' named
parameters is because it they believe it to be a hole in the syntax.
The probable parameter possibilities would seem to be:

Positional + Required
Positional + Optional
Named + Required
Named + Optional

Of those, we can't do the third. Not "can't do easily", but simply
"can't do". We can get the same effect by using positional required
parameters, but that, itself, is not self-documenting, to put it
softly. Hence you would want your proposed documentation to be added
wherever you were taking advantage of that feature.

The proposal to allow "longhand" forms of the above, via traits, solves
the problem:

$a is positional is required
$a is positional is optional
$a is named is required
$a is named is optional

(Though whether 'required' or 'optional' is the default for each I
leave to others.)

The proposal to use an additional '?', at the expense of Hoffmanism,
also solves the problem:

$a
?$a
+$a
?+$a

and is marginally more self-documenting, since it makes the
"optionalness" of both types of arguments more visually distinct. But
it means you always have to use the '?' if the named parameter is
indeed optional.

The reason that there is a debate is that many or most people do not
see a need to ever _have_ required named parameters, as opposed to just
using required positional parameters.

The most sensible reason for including them is so you could add
additional required parameters to variants of an already-extant
positional-based multi -- adding them "out-of-band", as it were.

The most sensible reason for not including them is that many people do
not believe they would be used.

Myself, I'm inclined to vote with the people who think they need them,
if for no other reason than the general belief that people should be
allowed to code the way they want to, and it seems either proposal
would allow syntax that is more self-documenting, even in the general
case.

MikeL

Trewth Seeker

da leggere,
26 apr 2003, 01:17:1526/04/03
a
fibo...@babylonia.flatirons.org (Luke Palmer) wrote in message news:<ygcvfxk...@babylonia.flatirons.org>...

> > I forget if this was covered earlier, but what is the reason for this? I
> > can easily imagine wanting to create subroutines that only accept named
> > parameters, some or all of which are required. How would this be done in
> > Perl 6?
> >
> > Yes, I guess all the parameters could be declared as positional, and then I
> > could scold users in the documentation to only use named parameters when
> > calling these subroutines, but that seems silly--and dangerous, since,
> > inevitably, some users won't listen and will use positional parameters
> > (after looking at the source to discover the correct order, or whatever).
> > So I'm stuck maintaining an argument order for what are (as far as I'm
> > concerned) not positional parameters.
> >
> > I guess I could also die() if I'm missing a named parameter, but that seems
> > so Perl-5-ish (i.e. "more work")
>
> You want it to be easy to make using your module harder? Sorry,
> that's something the community just won't let you do.
>
> Unfortunately, there is a solution. Macros:
>
> module LazyMaintainer;
> sub _changesalot($required, $parameters, $here) { ... }
>
> macro changesalot
> is parsed(/ $a := (<Perl::pair>) @b := [ , (<Perl::pair>)] * /) {
> { _changesalot($a, *@b) }.parsed
> }
>
> But that makes:
>
> sub changesalot(*%param) {
> exists $param{ all(<<requred parameters here>>) }
> or die "Required parameter not given"
> }
>
> Look easy. And more portable, too.
>
> > So...why can't I have required named parameters?
>
> It's TMTOWTDI, forced upon you. The users of your module can use
> whichsoever style they prefer, and you have to go to a lot of trouble
> to keep them from doing that. And I think it's a good thing.

This isn't a consistent argument -- or rather, you aren't applying it
consistently to S6. The difference between ?$foo and +$foo is that,
in the latter case, the user isn't allowed to pass the argument
positionally. What (by your argument) is gained by that? Why have
+$foo at all? By all the logic of orthogonality (I realize that this
is not a Perl value), +$foo should be a required named parameter and
?+$foo (or +?$foo) should be an optional named parameter.

Your argument, which I agree with, is that requiring named parameters
enforces a style of usage but serves no legimate needs of the code
author. Likewise, I claim, for requiring that parameters be named.
Therefore, '+' should go; it serves no legitimate purpose over '?',
and only encourages code authors to impose unnecessary restrictions
and to misunderstand their role, which is to provide functionality,
not to enforce style.

> I see
> your position on the maintainability standpoint, but there's just
> things you have to do when you're a maintainer.

If '+' were eliminated and and '?' were used in its place, the only
extra maintenance burden would be that the order of the parameters
must not change -- which is no burden at all. And as you mention
elsewhere, you don't need to document argument ordering. The argument
that people can look at the code doesn't wash -- people who look at the
code to take advantage of undocumented features, whether argument
ordering or algorithmic details or anything else, get what they deserve
if those things change. The maintainer is responsible for documenting
the functionality supplied and for supplying the functionality documented,
and that's it.

> By the way, it's not a maintenance problem. You want to be able to
> add new parameters without breaking old code using your module, right?
> Well, you can't add new I<required> parameters without breaking old
> code anyway! So your argument is moot, in any case.

Nor can you change the ordering or slot numbering of positional parameters,
optional or not, if you've documented that ordering. If you want to
be able to change the ordering, then just don't document it -- adding
things like '+' to the language are the wrong approach, IMO. And if
it's not the wrong approach, then the argument against a mechanism
for requiring named parameters goes out the window.

> > If it is due to vagaries of the parameter definition syntax and it's
> > funny little "zones", then I say change the syntax instead of
> > disallowing required named parameters :)
>
> I say: Perl is an extensible language. Write a module that adds the
> capability, and make it easy for yourself again.

I say: don't. If you don't want to commit to an order for parameters,
then don't document their order. Going to a lot of extra effort to prevent
people from specifying them positionally anyway is a waste,
especially when there's no reason for the maintainer to later change the
order of non-positional parameters. (Someone else might come along
and provide another implementation that used a different order, since
you didn't document it, but why would you want to go to the effort
to make sure that users hadn't coded calls incompatibly with such
other implementations, especially when there are all sorts of other
ways that people can write invalid implementation-dependent code
that can't be caught at compile time?)

--
TS

Trewth Seeker

da leggere,
26 apr 2003, 01:31:3926/04/03
a
sira...@mindspring.com (John Siracusa) wrote in message news:<BABEF8DB.67859%sira...@mindspring.com>...

> On 4/13/03 4:30 AM, Brent Dax wrote:
> > John Siracusa:
> > # From S6:
> > # > Every subroutine has an .assuming method. This method takes
> > # a series
> > # > of named arguments, whose names must match parameters of the
> > # > subroutine itself:
> > # >
> > # > &textfrom := &substr.assuming(str=>$text, len=>Inf);
> >
> > That's to avoid this situation:
> >
> > &textfrom := &substr.assuming($text, 0);
> > #Did I really want len to be 0, or did I mean index?
> >
> > It forces you to name things *because* positional parameters no longer
> > make sense.
>
> IMO, positional parameters "no longer make sense" if the API was not
> designed to use positional parameters. I don't see how the call to
> .assuming() is a "special case", or why only it should be allowed to require
> named parameters, while code that regular users write cannot (without
> run-time checks)

Er, um, assuming has no REQUIRED named parameters. That's quite different
from requiring that parameters be named, which is what '+' does,
which "code that regular users write" can use. I would, however,
argue that there's no need for '+' and its requirement, for either
assuming or any other code.

--
TS

Trewth Seeker

da leggere,
26 apr 2003, 01:36:3926/04/03
a
bren...@cpan.org (Brent Dax) wrote in message news:<000f01c302b8$f28a8c30$6401a8c0@deepblue>...

> John Siracusa:
> # ...I don't suppose anyone is up for:
> #
> # sub foo(+$a) {...} # short for: sub foo($a is required is
> # named)
> # sub foo(+?$a) {...} # short for: sub foo($a is optional is
> # named)
>
> Not. A. Chance.
>
> This is one of the big reasons I *don't* want there to be required named
> parameters--logically speaking, you would want + alone to do a required
> parameter, but that goes against Huffman coding.

It's totally wrong to reject a feature *just* because of Huffman coding.
Provide the feature with less compact syntax -- such as "is required".
--
TS

Trewth Seeker

da leggere,
26 apr 2003, 01:42:1326/04/03
a
sira...@mindspring.com (John Siracusa) wrote in message news:<BABEFBDA.67863%sira...@mindspring.com>...

> On 4/13/03 11:20 AM, Austin Hastings wrote:
> > --- John Siracusa <sira...@mindspring.com> wrote:
> >> Sure, but that's not an argument for why it shouldn't be there in the
> >> first place.
> >
> > We had this discussion last week: what's justification for inclusion in
> > core.
> >
> > IMO, "enables a paradigm" is the easiest justification for new core
> > bits. "Require named parameters" doesn't enable a paradigm. It enables
> > a coding standard.
>
> What about "saves the programmer work" and "enables compile-time checks that
> are impossible otherwise"? After all, that's what formal parameter lists
> do. You can do all of the checks and coercions they perform "long-hand" at
> runtime, but that a) is more work, and b) is all done at runtime, and
> therefore is less efficient.
>
> > You can pass required args using named-arg notation, so there's no
> > reason you can't get both type-checking (from the requirement stuff)
> > and clarity (by coding yourself with named args-style). You just can't
> > require *ME* to do that.
>
> I can force you to pass three args, not two, and I can force you to make the
> first arg an int, but I can't force you to pass only named parameters?

These are very different -- the functionality *requires* three args,
and *requires* that the first arg be an int -- if you're doing this
just because you like forcing things on people, you're in the wrong
business (and certainly using the wrong language).
--
TS

0 nuovi messaggi