Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

foo()() should be valid syntax (no arrow between argument lists) #10334

Open
p5pRT opened this issue Apr 20, 2010 · 13 comments
Open

foo()() should be valid syntax (no arrow between argument lists) #10334

p5pRT opened this issue Apr 20, 2010 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 20, 2010

Migrated from rt.perl.org#74540 (status was 'open')

Searchable as RT74540$

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From @mauke

Created by @mauke

Hello,

I'd really like for foo()() to be valid syntax (equivalent to foo()->()).

Rationale​:
The arrow is optional between subscripts. $foo->()() already works.
In all other cases you can omit the arrow even if its LHS is not a dereference
operator, e.g. $foo[0][0] is the same as $foo[0]->[0], even if the first [0] is
part of the $ [] array element syntax.
Similarly, I want foo()() to mean foo()->(), even if the first () is part of
the function call syntax.

I think it would make the language more regular. (In fact, I was surprised to
discover that it's not already valid Perl.)

Perl Info

Flags:
    category=core
    severity=wishlist

This perlbug was built using Perl v5.8.8 - Wed Mar 22 20:53:12 CET 2006
It is being executed now by  Perl v5.10.1 - Sun Sep 13 11:42:53 CEST 2009.

Site configuration information for perl v5.10.1:

Configured by mauke at Sun Sep 13 11:42:53 CEST 2009.

Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=2.6.27-gentoo-r8, archname=i686-linux
    uname='linux nora 2.6.27-gentoo-r8 #4 preempt mon apr 13 21:59:34 cest 2009 i686 amd athlon(tm) 64 processor 3200+ authenticamd gnulinux '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.3.3', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.9.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.9'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'

Locally applied patches:
    SAFEARGV0 - disable magic open in <ARGV>
    METHQUAL0 - allow qualified method calls without a valid object
    UNWARN0 - disable stupid warnings for print and qw


@INC for perl v5.10.1:
    /home/mauke/usr/local/lib/perl5/5.10.1/i686-linux
    /home/mauke/usr/local/lib/perl5/5.10.1
    /home/mauke/usr/local/lib/perl5/site_perl/5.10.1/i686-linux
    /home/mauke/usr/local/lib/perl5/site_perl/5.10.1
    /home/mauke/usr/local/lib/perl5/site_perl/5.10.0/i686-linux
    /home/mauke/usr/local/lib/perl5/site_perl/5.10.0
    /home/mauke/usr/local/lib/perl5/site_perl
    .


Environment for perl v5.10.1:
    HOME=/home/mauke
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH=/home/mauke/usr/local/lib
    LOGDIR (unset)
    PATH=/home/mauke/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/4.3.4:/opt/sun-jdk-1.4.2.13/bin:/opt/sun-jdk-1.4.2.13/jre/bin:/opt/sun-jdk-1.4.2.13/jre/javaws:/opt/dmd/bin:/usr/kde/3.5/bin:/usr/qt/3/bin:/usr/games/bin:/opt/vmware/server/bin
    PERL_BADLANG (unset)
    PERL_UNICODE=SAL
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From zefram@fysh.org

l.mai@​web.de wrote​:

The arrow is optional between subscripts.

foo() isn't a subscript. Crucially, unlike in $foo[0] or $foo->(),
the parens are optional. Trying to make foo() behave like that kind of
subscript expression would introduce another ambiguity to the grammar.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From @ap

* Zefram <zefram@​fysh.org> [2010-04-20 23​:55]​:

Crucially, unlike in $foo[0] or $foo->(), the parens are
optional. Trying to make foo() behave like that kind of
subscript expression would introduce another ambiguity to
the grammar.

How so?

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From zefram@fysh.org

A. Pagaltzis wrote​:

How so?

Currently, "$x = f();" means the same thing as "$x = f;", where f is a
declared function. Similarly, "$x = f(g());" means the same thing as
"$x = f g;", where g is also a declared function. Now add parens on
the end of them.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From ajs@ajs.com

On Tue Apr 20 15​:09​:30 2010, aristotle wrote​:

* Zefram <zefram@​fysh.org> [2010-04-20 23​:55]​:

Crucially, unlike in $foo[0] or $foo->(), the parens are
optional. Trying to make foo() behave like that kind of
subscript expression would introduce another ambiguity to
the grammar.

How so?

For sake of example assume that these calls all return references to
subroutines that, when invoked return a scalar​:

my $a = foo;
my $b = bar(1);

How you dereference now​:

my $a = foo->();
my $b = bar(1)->();

How you dereference if we used bare parens​:

my $a = foo()();
my $b = bar(1)();

Note that you have to first add the previously unrequired parens to
first example before you can dereference.

Me, I think this is a trivial concern and doesn't impede the change, but
I do understand that it's there.

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2010

From @ikegami

On Tue, Apr 20, 2010 at 6​:14 PM, Zefram <zefram@​fysh.org> wrote​:

Currently, "$x = f();" means the same thing as "$x = f;", where f is a
declared function. Similarly, "$x = f(g());" means the same thing as
"$x = f g;", where g is also a declared function. Now add parens on
the end of them.

f() and f g() are not of the form f(...)(). You didn't describe an
ambiguity.

Mind you, I think the proposed syntax is ugly.

@p5pRT
Copy link
Author

p5pRT commented Apr 21, 2010

From ben@morrow.me.uk

Quoth ikegami@​adaelis.com (Eric Brine)​:

-=-=-=-=-=-

On Tue, Apr 20, 2010 at 6​:14 PM, Zefram <zefram@​fysh.org> wrote​:

Currently, "$x = f();" means the same thing as "$x = f;", where f is a
declared function. Similarly, "$x = f(g());" means the same thing as
"$x = f g;", where g is also a declared function. Now add parens on
the end of them.

f() and f g() are not of the form f(...)(). You didn't describe an
ambiguity.

Should

  f ()

be interpreted as

  (f())

or as

  (f())->()

? (The whitespace is for effect, it's obviously not significant.) It may
be obvious how to resolve the ambiguity, but it's still there. There are
other, less clear, cases as well​: for instance, should

  f g() ()

be parsed as

  f( g()->() )

or as

  f( g() )->()

or indeed as

  g->f()->()

?

Mind you, I think the proposed syntax is ugly.

IMHO it's slightly less ugly than f()->(), but not by much.

Ben

@p5pRT
Copy link
Author

p5pRT commented Apr 21, 2010

From @ikegami

On Tue, Apr 20, 2010 at 8​:19 PM, Ben Morrow <ben@​morrow.me.uk> wrote​:

Should
f ()
be interpreted as

f () *is* interpreted as (f())

It may be obvious how to resolve the ambiguity, but it's still there.

"f ()" is not of the form "f()()", so it was not covered by the proposal.

There are

other, less clear, cases as well​: for instance, should

f g() ()
be parsed as

Just as clear. "f g() ()" (as a whole) is not of the form "f()()", so it was
not covered by the proposal. "g() ()" is (allowing for the WS), and noone
suggested precedence should be changed.

Mind you, you are free to expand to scope of the proposal. *That* could open
up ambiguities.

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From @ap

* Zefram <zefram@​fysh.org> [2010-04-21 00​:20]​:

A. Pagaltzis wrote​:

How so?

Currently, "$x = f();" means the same thing as "$x = f;", where
f is a declared function. Similarly, "$x = f(g());" means the
same thing as "$x = f g;", where g is also a declared function.
Now add parens on the end of them.

This is not what the proposal is about.

As Eric has already covered, nothing should change, except that
some cases of `)(`, all of which I believe are currently syntax
errors, would become valid syntax that implies `)->(`. I don’t
see any ambiguity being introduced with this.

* Ben Morrow <ben@​morrow.me.uk> [2010-04-21 02​:20]​:

Should

f \(\)

be interpreted as

\(f\(\)\)

or as

\(f\(\)\)\->\(\)

?

Is

  $f {foo}

interpreted as

  $f{foo}

or as

  $f->{foo}

?

If you want the `f()->()` parse, you simply write it that way​:

  f->()

much like you’d write either `$f{foo}` or `$f->{foo}`, but you
never *have* to write `$f{foo}->{bar}` when `$f{foo}{bar}` will
do just as well.

That’s not ambiguous, and neither would this syntax be.

Oh, and of course, `f->()` already *does* work that way.

(The whitespace is for effect, it's obviously not significant.)
It may be obvious how to resolve the ambiguity, but it's still
there.

There is no such ambiguity. The proposal concerns only cases
where the text of the program reads `)(` (modulo whitespace);
it does not have anything to do with whether there are function
calls are chained inside an expression.

There are other, less clear, cases as well

Not at all; by all I can tell, it’s very, very simple.

for instance, should

f g\(\) \(\)

be parsed as

f\( g\(\)\->\(\) \)

or as

f\( g\(\) \)\->\(\)

or indeed as

g\->f\(\)\->\(\)

?

How would

  f g() -> ()

parse? That’s how

  f g() ()

should parse as well.

There is, I repeat, absolutely no ambiguity in this proposal as
far as I can tell, since – I think – all possible uses of `)(`
(modulo whitespace) are currently a syntax error.

Paging Abigail…

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

1 similar comment
@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From @ap

* Zefram <zefram@​fysh.org> [2010-04-21 00​:20]​:

A. Pagaltzis wrote​:

How so?

Currently, "$x = f();" means the same thing as "$x = f;", where
f is a declared function. Similarly, "$x = f(g());" means the
same thing as "$x = f g;", where g is also a declared function.
Now add parens on the end of them.

This is not what the proposal is about.

As Eric has already covered, nothing should change, except that
some cases of `)(`, all of which I believe are currently syntax
errors, would become valid syntax that implies `)->(`. I don’t
see any ambiguity being introduced with this.

* Ben Morrow <ben@​morrow.me.uk> [2010-04-21 02​:20]​:

Should

f \(\)

be interpreted as

\(f\(\)\)

or as

\(f\(\)\)\->\(\)

?

Is

  $f {foo}

interpreted as

  $f{foo}

or as

  $f->{foo}

?

If you want the `f()->()` parse, you simply write it that way​:

  f->()

much like you’d write either `$f{foo}` or `$f->{foo}`, but you
never *have* to write `$f{foo}->{bar}` when `$f{foo}{bar}` will
do just as well.

That’s not ambiguous, and neither would this syntax be.

Oh, and of course, `f->()` already *does* work that way.

(The whitespace is for effect, it's obviously not significant.)
It may be obvious how to resolve the ambiguity, but it's still
there.

There is no such ambiguity. The proposal concerns only cases
where the text of the program reads `)(` (modulo whitespace);
it does not have anything to do with whether there are function
calls are chained inside an expression.

There are other, less clear, cases as well

Not at all; by all I can tell, it’s very, very simple.

for instance, should

f g\(\) \(\)

be parsed as

f\( g\(\)\->\(\) \)

or as

f\( g\(\) \)\->\(\)

or indeed as

g\->f\(\)\->\(\)

?

How would

  f g() -> ()

parse? That’s how

  f g() ()

should parse as well.

There is, I repeat, absolutely no ambiguity in this proposal as
far as I can tell, since – I think – all possible uses of `)(`
(modulo whitespace) are currently a syntax error.

Paging Abigail…

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From @Abigail

On Thu, Apr 22, 2010 at 05​:45​:06PM +0200, Aristotle Pagaltzis wrote​:

* Zefram <zefram@​fysh.org> [2010-04-21 00​:20]​:

A. Pagaltzis wrote​:

How so?

Currently, "$x = f();" means the same thing as "$x = f;", where
f is a declared function. Similarly, "$x = f(g());" means the
same thing as "$x = f g;", where g is also a declared function.
Now add parens on the end of them.

This is not what the proposal is about.

As Eric has already covered, nothing should change, except that
some cases of `)(`, all of which I believe are currently syntax
errors, would become valid syntax that implies `)->(`. I don’t
see any ambiguity being introduced with this.

* Ben Morrow <ben@​morrow.me.uk> [2010-04-21 02​:20]​:

Should

f \(\)

be interpreted as

\(f\(\)\)

or as

\(f\(\)\)\->\(\)

?

Is

$f \{foo\}

interpreted as

$f\{foo\}

or as

$f\->\{foo\}

?

If you want the `f()->()` parse, you simply write it that way​:

f\->\(\)

much like you’d write either `$f{foo}` or `$f->{foo}`, but you
never *have* to write `$f{foo}->{bar}` when `$f{foo}{bar}` will
do just as well.

That’s not ambiguous, and neither would this syntax be.

Oh, and of course, `f->()` already *does* work that way.

(The whitespace is for effect, it's obviously not significant.)
It may be obvious how to resolve the ambiguity, but it's still
there.

There is no such ambiguity. The proposal concerns only cases
where the text of the program reads `)(` (modulo whitespace);
it does not have anything to do with whether there are function
calls are chained inside an expression.

There are other, less clear, cases as well

Not at all; by all I can tell, it’s very, very simple.

for instance, should

f g\(\) \(\)

be parsed as

f\( g\(\)\->\(\) \)

or as

f\( g\(\) \)\->\(\)

or indeed as

g\->f\(\)\->\(\)

?

How would

f g\(\) \-> \(\)

parse? That’s how

f g\(\) \(\)

should parse as well.

There is, I repeat, absolutely no ambiguity in this proposal as
far as I can tell, since – I think – all possible uses of `)(`
(modulo whitespace) are currently a syntax error.

Paging Abigail…

I don't think 'f () ()' going to mean 'f () -> ()' is going to cause a problem.

*However*, making the arrow optional should also mean making the arrow
optional in the following cases​:

  f (a, b, c) -> [1];

Currently,

  f (a, b, c) [1];

is a syntax error. But there's room for some kind of executive decision here.
Is it going to mean​:

  f (a, b, c) -> [1];

or

  f (b);

?

I'd go for the first meaning, after all, the second meaning can easily
be achieved by writing​:

  f +(a, b, c) [1]; # Pre-declaring f may be needed

or

  f ((a, b, c) [1]);

Of course, since it's currently a syntax error, picking either meaning
is fine, and isn't going to break code (other than code that relies on
certain strings not compiling).

Personally, I don't care that much for '() ()' going to mean '() -> ()'.
I care more for '() []' to be '() -> []' and '() {}' to be '() -> {}'.
I try to use '->' only when it involves calling a method or a sub, that is,
I write​:

  $$array_ref [1];

instead of

  $array_ref -> [1];

But that also means writing

  ${f ()} [1];

which is a lot uglier than

  f () -> [1];

It would be a lot nicer if I could just write

  f () [1];

Oh, and to answer your question, as already pointed out in this thread​:

  f -> () ();

*is* valid. The proposal doesn't change this meaning, but it's an occurance
of ') (' which is legal syntax. And not extremely rare.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From @ap

* Abigail <abigail@​abigail.be> [2010-04-22 18​:20]​:

*However*, making the arrow optional should also mean making
the arrow optional in the following cases​:

f \(a\, b\, c\) \-> \[1\];

Currently,

f \(a\, b\, c\) \[1\];

is a syntax error. But there's room for some kind of executive
decision here. Is it going to mean​:

f \(a\, b\, c\) \-> \[1\];

or

f \(b\);

?

I'd go for the first meaning, after all, the second meaning can
easily be achieved by writing​:

f \+\(a\, b\, c\) \[1\];   \# Pre\-declaring f may be needed

or

f \(\(a\, b\, c\) \[1\]\);

In this case I would say mu. There is a third possible parse​:

  (f (a, b, c)) [1]

And that is almost *always* the parse I want, eg.

  my $inode = stat ($fh) [1];

or

  my $firstname = split (/ *, */, $fullname) [1];

Of course, since it's currently a syntax error, picking either
meaning is fine, and isn't going to break code (other than code
that relies on certain strings not compiling).

Personally, I don't care that much for '() ()' going to mean
'() -> ()'. I care more for '() []' to be '() -> []' and '()
{}' to be '() -> {}'.

The regularity between `()[]` and `(){}` is of course a nice
aspect of your proposal.

I try to use '->' only when it involves calling a method or
a sub, that is, I write​:

$$array\_ref \[1\];

instead of

$array\_ref \-> \[1\];

But that also means writing

$\{f \(\)\} \[1\];

which is a lot uglier than

f \(\) \-> \[1\];

It would be a lot nicer if I could just write

f \(\) \[1\];

Oh, and to answer your question, as already pointed out in this
thread​:

f \-> \(\) \(\);

*is* valid. The proposal doesn't change this meaning, but it's
an occurance of ') (' which is legal syntax. And not extremely
rare.

Oh wow​:

  $ perl -MO=Deparse,-x7,-p -e'f->()()'
  f()->();
  -e syntax OK

Learn something new every day. How does that even work? I suppose
the same way `%hash->{foo}` works?

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants