square signatures

There is a change we could make to signature syntax, within the scope of
the present experimental feature, which would have some value and which
I think we should consider making.  The change I propose is firstly that
signatures should be delimited by square brackets instead of parentheses,
and secondly that enabling signature syntax should not disable the short
prototype syntax.  Under this arrangement we would see things like:

    use feature "signatures";
    sub add [$x, $y] { $x + $y }            # signature
    sub my_rand (;$) { rand($_[0] || 5) }   # prototype
    sub mul ($$) [$x, $y] { $x * $y }       # prototype and signature

Why do this?  Because a perennial problem around signatures has been
confusion between signatures and prototypes.  A lot of the proposals for
signatures suffered from treating them as a funny kind of prototype.
If implementors couldn't keep them straight, we can't expect users to
be clear about them.  The confusion largely arises from them having
some syntactic similarity, so much that they actually clash and so we
needed to disable one syntax when the other is enabled.  Brackets in
place of parens make signatures very visually distinct from prototypes,
which would probably be a big help in keeping them mentally distinct.
A side benefit is that signature syntax would no longer clash with short
prototype syntax, so we would have no need to disable the latter.

We didn't consider this at the time of the original development of
signatures because no one thought of it.  The quick consensus we had on
the basic features was built on an an assumption that the delimiters would
be parens, based on nothing more than that being the usual arrangement
in other languages.  The consensus also incorporated an unambiguous and
technically simple way to distinguish the syntaxes.  It wasn't until
confusion became evident after implementation that I started thinking
"wish we'd made them more syntactically distinct, delimited them with
square brackets or something".  Since then my line of thought has
gradually solidified to the position that I think there's real benefit
in obvious non-clashing syntax, and that brackets are probably the best
way to do it.

If brackets are too weird, there are other options for distinguishing
them such as sticking a "+" before the opening paren.  The downside is
that with parens still being the main delimiters the degree of visual
distinction is much lower.

In summary, pros:

* can immediately see whether you're looking at a prototype or a
  signature, not having to consider pragmata

* prototype and signature more mentally distinct

* nicer syntax for prototypes when signatures are enabled

* enabling signature syntax (in one file, or as a "use 5.030" bundle)
  doesn't break the old prototype syntax in existing code

* documentation that gives examples using prototypes doesn't need any
  complexification

Cons:

* looks a bit weird

* all existing signature-using code (which either emits or explicitly
  muffles a "signatures are experimental" warning) needs to change

Let the opinions flow.

-zefram
0
zefram
11/13/2017 8:07:00 PM
perl.perl5.porters 46731 articles. 0 followers. Follow

11 Replies
12 Views

Similar Articles

[PageSpeed] 6

Zefram:
> Under this arrangement we would see things like:
....
>     sub mul ($$) [$x, $y] { $x * $y }       # prototype and signature

I like this idea.

At first glance, though, I wonder what that array is doing there.
Since anonymous arrays are very common, and file globbing is rela-
tively rare, perhaps this would be a better syntax:

    sub mul ($$) <$x, $y> { $x * $y }

Also, you never see file globbing that looks like <$a, $b>, so it is
hard to confuse them.

This should make code more skimmable.

> Let the opinions flow.

I will just add that I fully support putting attributes before signa-
tures, the way they used to be in 5.20.
0
sprout
11/13/2017 8:37:29 PM
Father Chrysostomos wrote:
>Since anonymous arrays are very common, and file globbing is rela-
>tively rare, perhaps this would be a better syntax:
>
>    sub mul ($$) <$x, $y> { $x * $y }

That interacts poorly with default value expressions.  "($a = $b > $c)"
is a legal signature (under the current syntax); with angle brackets
">" in that place would be ambiguous between comparison operator and
signature delimiter.  The next character after the comparison operator
could even be "{" for maximum confusion.  We have no precedent for angle
bracketing of arbitrary expressions.  The delimiter really has to be
something that we use specifically to enclose expressions, and there
aren't many options available there.

>Also, you never see file globbing that looks like <$a, $b>, so it is
>hard to confuse them.

You do get stream reads of the forms "<$a>" and "<>", which would be
very common signatures.

If simple square brackets look too much like array construction, we
could go to composite delimiters:

    sub mul ($$) <[$x, $y]> { $x * $y }

but that seems unPerlishly cumbersome.

>I will just add that I fully support putting attributes before signa-
>tures, the way they used to be in 5.20.

Thanks, but that doesn't belong on this thread.  The placement of
signatures relative to attributes is almost entirely orthogonal to
the choice of delimiter.  (There's a little bit of interaction in that
changing the delimiter would get rid of the whitespace sensitivity that
occurs with ":bar($a)" (attribute with argument) versus ":bar ($a)"
(attribute followed by signature) when the signature follows attributes.)
Your comment would be better on [perl #132141], where none of the
supporters of signatures preceding attributes have yet suggested how to
resolve the bug that that change introduced.

-zefram
0
zefram
11/13/2017 9:45:45 PM
--001a1134fb1a6bba41055df75ef3
Content-Type: text/plain; charset="UTF-8"

On Mon, Nov 13, 2017 at 9:07 PM, Zefram <zefram@fysh.org> wrote:

> There is a change we could make to signature syntax, within the scope of
> the present experimental feature, which would have some value and which
> I think we should consider making.  The change I propose is firstly that
> signatures should be delimited by square brackets instead of parentheses,
> and secondly that enabling signature syntax should not disable the short
> prototype syntax.  Under this arrangement we would see things like:
>
>     use feature "signatures";
>     sub add [$x, $y] { $x + $y }            # signature
>     sub my_rand (;$) { rand($_[0] || 5) }   # prototype
>     sub mul ($$) [$x, $y] { $x * $y }       # prototype and signature
>
> Why do this?  Because a perennial problem around signatures has been
> confusion between signatures and prototypes.  A lot of the proposals for
> signatures suffered from treating them as a funny kind of prototype.
> If implementors couldn't keep them straight, we can't expect users to
> be clear about them.  The confusion largely arises from them having
> some syntactic similarity, so much that they actually clash and so we
> needed to disable one syntax when the other is enabled.  Brackets in
> place of parens make signatures very visually distinct from prototypes,
> which would probably be a big help in keeping them mentally distinct.
> A side benefit is that signature syntax would no longer clash with short
> prototype syntax, so we would have no need to disable the latter.
>
> We didn't consider this at the time of the original development of
> signatures because no one thought of it.  The quick consensus we had on
> the basic features was built on an an assumption that the delimiters would
> be parens, based on nothing more than that being the usual arrangement
> in other languages.  The consensus also incorporated an unambiguous and
> technically simple way to distinguish the syntaxes.  It wasn't until
> confusion became evident after implementation that I started thinking
> "wish we'd made them more syntactically distinct, delimited them with
> square brackets or something".  Since then my line of thought has
> gradually solidified to the position that I think there's real benefit
> in obvious non-clashing syntax, and that brackets are probably the best
> way to do it.
>
> If brackets are too weird, there are other options for distinguishing
> them such as sticking a "+" before the opening paren.  The downside is
> that with parens still being the main delimiters the degree of visual
> distinction is much lower.
>
> In summary, pros:
>
> * can immediately see whether you're looking at a prototype or a
>   signature, not having to consider pragmata
>
> * prototype and signature more mentally distinct
>
> * nicer syntax for prototypes when signatures are enabled
>
> * enabling signature syntax (in one file, or as a "use 5.030" bundle)
>   doesn't break the old prototype syntax in existing code
>
> * documentation that gives examples using prototypes doesn't need any
>   complexification
>
> Cons:
>
> * looks a bit weird
>
> * all existing signature-using code (which either emits or explicitly
>   muffles a "signatures are experimental" warning) needs to change
>
> Let the opinions flow.


Quite frankly, I think that this is terrible language design. The current
syntax has one immense advantage: it's meaning is clear to anyone familiar
with pretty much any programming language. I quite frankly don't care about
the advantages for prototypes, they're clearly the wrong thing to optimize
for.

Leon

--001a1134fb1a6bba41055df75ef3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Nov 13, 2017 at 9:07 PM, Zefram <span dir=3D"ltr">&lt;<a href=3D"mailto=
:zefram@fysh.org" target=3D"_blank">zefram@fysh.org</a>&gt;</span> wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">There is a change we could make to signatu=
re syntax, within the scope of<br>
the present experimental feature, which would have some value and which<br>
I think we should consider making.=C2=A0 The change I propose is firstly th=
at<br>
signatures should be delimited by square brackets instead of parentheses,<b=
r>
and secondly that enabling signature syntax should not disable the short<br=
>
prototype syntax.=C2=A0 Under this arrangement we would see things like:<br=
>
<br>
=C2=A0 =C2=A0 use feature &quot;signatures&quot;;<br>
=C2=A0 =C2=A0 sub add [$x, $y] { $x + $y }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 # signature<br>
=C2=A0 =C2=A0 sub my_rand (;$) { rand($_[0] || 5) }=C2=A0 =C2=A0# prototype=
<br>
=C2=A0 =C2=A0 sub mul ($$) [$x, $y] { $x * $y }=C2=A0 =C2=A0 =C2=A0 =C2=A0#=
 prototype and signature<br>
<br>
Why do this?=C2=A0 Because a perennial problem around signatures has been<b=
r>
confusion between signatures and prototypes.=C2=A0 A lot of the proposals f=
or<br>
signatures suffered from treating them as a funny kind of prototype.<br>
If implementors couldn&#39;t keep them straight, we can&#39;t expect users =
to<br>
be clear about them.=C2=A0 The confusion largely arises from them having<br=
>
some syntactic similarity, so much that they actually clash and so we<br>
needed to disable one syntax when the other is enabled.=C2=A0 Brackets in<b=
r>
place of parens make signatures very visually distinct from prototypes,<br>
which would probably be a big help in keeping them mentally distinct.<br>
A side benefit is that signature syntax would no longer clash with short<br=
>
prototype syntax, so we would have no need to disable the latter.<br>
<br>
We didn&#39;t consider this at the time of the original development of<br>
signatures because no one thought of it.=C2=A0 The quick consensus we had o=
n<br>
the basic features was built on an an assumption that the delimiters would<=
br>
be parens, based on nothing more than that being the usual arrangement<br>
in other languages.=C2=A0 The consensus also incorporated an unambiguous an=
d<br>
technically simple way to distinguish the syntaxes.=C2=A0 It wasn&#39;t unt=
il<br>
confusion became evident after implementation that I started thinking<br>
&quot;wish we&#39;d made them more syntactically distinct, delimited them w=
ith<br>
square brackets or something&quot;.=C2=A0 Since then my line of thought has=
<br>
gradually solidified to the position that I think there&#39;s real benefit<=
br>
in obvious non-clashing syntax, and that brackets are probably the best<br>
way to do it.<br>
<br>
If brackets are too weird, there are other options for distinguishing<br>
them such as sticking a &quot;+&quot; before the opening paren.=C2=A0 The d=
ownside is<br>
that with parens still being the main delimiters the degree of visual<br>
distinction is much lower.<br>
<br>
In summary, pros:<br>
<br>
* can immediately see whether you&#39;re looking at a prototype or a<br>
=C2=A0 signature, not having to consider pragmata<br>
<br>
* prototype and signature more mentally distinct<br>
<br>
* nicer syntax for prototypes when signatures are enabled<br>
<br>
* enabling signature syntax (in one file, or as a &quot;use 5.030&quot; bun=
dle)<br>
=C2=A0 doesn&#39;t break the old prototype syntax in existing code<br>
<br>
* documentation that gives examples using prototypes doesn&#39;t need any<b=
r>
=C2=A0 complexification<br>
<br>
Cons:<br>
<br>
* looks a bit weird<br>
<br>
* all existing signature-using code (which either emits or explicitly<br>
=C2=A0 muffles a &quot;signatures are experimental&quot; warning) needs to =
change<br>
<br>
Let the opinions flow.</blockquote><div><br></div><div>Quite frankly, I thi=
nk that this is terrible language design. The current syntax has one immens=
e advantage: it&#39;s meaning is clear to anyone familiar with pretty much =
any programming language. I quite frankly don&#39;t care about the advantag=
es for prototypes, they&#39;re clearly the wrong thing to optimize for.</di=
v><div><br></div><div>Leon<br></div></div></div></div>

--001a1134fb1a6bba41055df75ef3--
0
fawaka
11/14/2017 8:38:05 PM
Leon Timmermans wrote:
>                                           I quite frankly don't care about
>the advantages for prototypes, they're clearly the wrong thing to optimize
>for.

Prototypes are not the motivation for this proposal; re-enabling their
short syntax is just a bonus.  The motivation is to make signatures and
prototypes more distinct.  In allocating the delimiter characters, we're
constrained by the fact that prototypes got there first and bagged parens.

-zefram
0
zefram
11/14/2017 8:57:58 PM
On Mon, 13 Nov 2017 20:07:00 +0000
Zefram <zefram@fysh.org> wrote:


> * can immediately see whether you're looking at a prototype or a
>   signature, not having to consider pragmata


> * prototype and signature more mentally distinct

IMO :prototype() makes them *much* more distinct.

> 
> * nicer syntax for prototypes when signatures are enabled
> 

I'd argue that :prototype() is the nicer syntax, because:

1. It's more explicit and it's googleable, which is important in case of
a rarely used feature.

2. It's more consistent. Prototype is nothing else than an attribute of
a subroutine, so it shouldn't be treated differently than :lvalue or
:const.

> * enabling signature syntax (in one file, or as a "use 5.030" bundle)
>   doesn't break the old prototype syntax in existing code

I don't think that it's important. In a typical codebase, prototypes are
used in a tiny minority of functions. Converting them to :prototype()
should take no more than a few minutes.

Even in the most extreme case of CPAN modules from the List::* namespace,
it still isn't a lot of work.

If for some unlikely reason you can't update your prototypes to the new
syntax, don't enable signatures. That's the whole point of feature.pm.

> * documentation that gives examples using prototypes doesn't need any
>   complexification
> 
> Cons:
> 
> * looks a bit weird

I'm sorry, but "a bit weird" is an understatement. This syntax looks
completely alien. I agree with Leon, anything else than our current
syntax is counter-intuitive.

> 
> * all existing signature-using code (which either emits or explicitly
>   muffles a "signatures are experimental" warning) needs to change
> 
> Let the opinions flow.
> 
> -zefram
0
me
11/15/2017 1:15:36 AM
--001a11405b9a34dc9a055dfc2a34
Content-Type: text/plain; charset="UTF-8"

On Mon, Nov 13, 2017 at 12:07 PM, Zefram <zefram@fysh.org> wrote:

> There is a change we could make to signature syntax, within the scope of
> the present experimental feature, which would have some value and which
> I think we should consider making.  The change I propose is firstly that
> signatures should be delimited by square brackets instead of parentheses,
> and secondly that enabling signature syntax should not disable the short
> prototype syntax.  Under this arrangement we would see things like:
>
>
The problem I see with this is that it goes against what I see the purpose
of signatures to be.
I wasn't involved with their original design but am a tentative user of
them.  They're intended
to make Perl a bit less obscure and "just do the right thing" that new
users of the language
expect.  In their current form they go a long way towards doing this, and
it's something that
a lot of people have been desiring and working towards.  This is well
evidenced by the many
modules on CPAN that provide similar syntax as the current function
signatures:Function::Parameters,
Fun, Kavorka, signatures, Sub::Signatures, Filter::Signatures,
Method::Signatures,
Type::Tiny::Signatures, Parse::Method::Signatures, Perl6::Signatures,
MooseX::Signatures,
Method::Signatures::WithDocumentation, Method::Signatures::PP, and
Method::Signatures::Simple.
Also probably a lot of other modules that I missed.

Ryan Voots

--001a11405b9a34dc9a055dfc2a34
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Nov 13, 2017 at 12:07 PM, Zefram <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:zefram@fysh.org" target=3D"_blank">zefram@fysh.org</a>&gt;</span> wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex">There is a change we c=
ould make to signature syntax, within the scope of<br>
the present experimental feature, which would have some value and which<br>
I think we should consider making.=C2=A0 The change I propose is firstly th=
at<br>
signatures should be delimited by square brackets instead of parentheses,<b=
r>
and secondly that enabling signature syntax should not disable the short<br=
>
prototype syntax.=C2=A0 Under this arrangement we would see things like:<br=
>
<br></blockquote><div><br></div><div>The problem I see with this is that it=
 goes against what I see the purpose of signatures to be.=C2=A0 <br></div><=
div>I wasn&#39;t involved with their original design but am a tentative use=
r of them.=C2=A0 They&#39;re intended</div><div> to make Perl a bit less ob=
scure and &quot;just do the right thing&quot; that new users of the languag=
e <br></div><div>expect.=C2=A0 In their current form they go a long way tow=
ards doing this, and it&#39;s something that <br></div><div>a lot of people=
 have been desiring and working towards.=C2=A0 This is well evidenced by th=
e many</div><div> modules on CPAN that provide similar syntax as the curren=
t function signatures:Function::Parameters, <br></div><div>Fun, Kavorka, si=
gnatures, Sub::Signatures, Filter::Signatures, Method::Signatures, <br></di=
v><div>Type::Tiny::Signatures, Parse::Method::Signatures, Perl6::Signatures=
, MooseX::Signatures, <br></div><div>Method::Signatures::WithDocumentation,=
 Method::Signatures::PP, and Method::Signatures::Simple.=C2=A0 <br></div><d=
iv>Also probably a lot of other modules that I missed.</div><div><br></div>=
<div><font color=3D"#000000">Ryan Voots</font><br></div><span class=3D"gmai=
l-m_-6986705389682721351HOEnZb"></span><span class=3D"gmail-m_-698670538968=
2721351HOEnZb"></span></div></div></div>

--001a11405b9a34dc9a055dfc2a34--
0
simcop2387
11/15/2017 2:21:43 AM
Zefram writes:

> Leon Timmermans wrote:=20
>=20
> > I quite frankly don't care about the advantages for prototypes,
> > they're clearly the wrong thing to optimize for.=20
> =20
> The motivation is to make signatures and prototypes more distinct.  In
> allocating the delimiter characters, we're constrained by the fact
> that prototypes got there first and bagged parens.=20

When teaching Perl, it's relatively straightforward to cover, in order:

=E2=80=A2 invoking functions using parens round the arguments
=E2=80=A2 defining functions, using parens round the parameters
=E2=80=A2 ...
=E2=80=A2 advanced feature: declaring prototypes, using :prototype to denot=
e
  them

It's more awkward to teach: =E2=80=9CWhen defining functions, you have to u=
se
square brackets around the parameters, not the parens you were expecting
from invoking functions in Perl and from declaring functions in many
other languages, because parens are used for some other, advanced,
feature that you don't need to know about until after we've got the hang
of just declaring functions.=E2=80=9D Because the question would definitely=
 crop
up.=20

The users most burdened by the syntax clash are those who have already
made use of prototypes. They are more advanced users, so should be in a
better position to cope with the conflict than those learning Perl or
who have never used prototypes.

Smylers
0
smylers
11/15/2017 11:35:03 AM
On 14 November 2017 at 21:57, Zefram <zefram@fysh.org> wrote:
> Leon Timmermans wrote:
>>                                           I quite frankly don't care about
>>the advantages for prototypes, they're clearly the wrong thing to optimize
>>for.
>
> Prototypes are not the motivation for this proposal; re-enabling their
> short syntax is just a bonus.  The motivation is to make signatures and
> prototypes more distinct.  In allocating the delimiter characters, we're
> constrained by the fact that prototypes got there first and bagged parens.

Can we make the prototype part be in square brackets? Possibly version
controlled so that old code keeps working, but new code always treats
the parens as being signature definitions?

Yves

-- 
perl -Mre=debug -e "/just|another|perl|hacker/"
0
demerphq
11/15/2017 12:23:04 PM
demerphq wrote:
>Can we make the prototype part be in square brackets?

In signature-syntax mode we technically could add back a short prototype
syntax using square brackets, but it would sow even more confusion, by
making the same thing (prototypes) look different in nearly the same
context.  It's the converse of the confusion that arises from making
different things look similar.  What do you hope to achieve?  Is there
a pressing need for short prototype syntax in signature-syntax mode?

Outside signature-syntax mode, it's out of the question to change
prototype syntax.  The short syntax with parens is the only way for pure
Perl code to establish prototypes that's portable any earlier than 5.20
(which is when the :prototype attribute was added).

>Possibly version
>controlled so that old code keeps working, but new code always treats
>the parens as being signature definitions?

You're describing putting the signatures feature into a version feature
bundle.  That's entirely possible once signatures are stable, but has
no bearing on questions of what the syntax in signature-syntax mode
should be.
0
zefram
11/15/2017 3:01:25 PM
On Tue, Nov 14, 2017 at 3:38 PM, Leon Timmermans <fawaka@gmail.com> wrote:

> [...] The current
> syntax has one immense advantage: it's meaning is clear to anyone familiar
> with pretty much any programming language. [...]

Agreed.

And I think :prototype() is the right way to go.

If there is a shorthand for it, that's fine by me, but leave () for
signatures please!

-- Matthew Horsfall (alh)
0
wolfsage
11/15/2017 3:22:12 PM
--Sig_/1FrkZfVh_86K8C6jRsN4Wly
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

On Wed, 15 Nov 2017 10:22:12 -0500, "Matthew Horsfall (alh)"
<wolfsage@gmail.com> wrote:

> On Tue, Nov 14, 2017 at 3:38 PM, Leon Timmermans <fawaka@gmail.com> wrote:
>=20
> > [...] The current
> > syntax has one immense advantage: it's meaning is clear to anyone famil=
iar
> > with pretty much any programming language. [...] =20
>=20
> Agreed.
>=20
> And I think :prototype() is the right way to go.
>=20
> If there is a shorthand for it, that's fine by me, but leave () for
> signatures please!

What Mathew said.

> -- Matthew Horsfall (alh)


--=20
H.Merijn Brand  http://tux.nl   Perl Monger  http://amsterdam.pm.org/
using perl5.00307 .. 5.27   porting perl5 on HP-UX, AIX, and openSUSE
http://mirrors.develooper.com/hpux/        http://www.test-smoke.org/
http://qa.perl.org   http://www.goldmark.org/jeff/stupid-disclaimers/

--Sig_/1FrkZfVh_86K8C6jRsN4Wly
Content-Type: application/pgp-signature
Content-Description: OpenPGP digital signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBAgAGBQJaDGJcAAoJEAOhR6E+XcCYANkIAIcndU849P3+t1I3g2QSs9jU
IsQRyxuue6XMQ20CLBkKJCO9PbqKY9R/X/skTYviFkS2NJOx8HZV773RAcM51AX7
uRLuwqf9oe3TSr9TkC7+Ilw2WVL6FG6GUEEDBMCeIwkqDvDBIBboZa74lLG05Y7M
Aq33X9S5RdhYnYMch/k4VSI4ii0ZOMDW+ryLh6Y2Kk3s4SmOTzfrNojx6wrzigxk
vGvxddB9z0GFA/l4+4xFVBFC9LaMCetjq6yNVc06/aRBZPTtM8h/axg1ApP7nCm9
rXv8RozEBRdrtrVhUv3G/SdI64w71Sld6ybETzeG2n+KrZklYxdhStT3uLxFaYM=
=fNnM
-----END PGP SIGNATURE-----

--Sig_/1FrkZfVh_86K8C6jRsN4Wly--
0
h
11/15/2017 3:50:45 PM
Reply: