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

Not enough arguments for map #14195

Open
p5pRT opened this issue Oct 30, 2014 · 10 comments
Open

Not enough arguments for map #14195

p5pRT opened this issue Oct 30, 2014 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 30, 2014

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

Searchable as RT123090$

@p5pRT
Copy link
Author

p5pRT commented Oct 30, 2014

From dean.herington@emc.com

This is a bug report for perl from dean.herington@​emc.com,
generated with the help of perlbug 1.39 running under perl 5.16.3.


I don't understand the following error. I think the result of the
following statement should be the same as the similar one shown later.

  DB<1> p map { a => 1 } 1,2,3
Not enough arguments for map at (eval 9)[C​:/Perl/lib/perl5db.pl​:646] line 2, near "} 1"
syntax error at (eval 9)[C​:/Perl/lib/perl5db.pl​:646] line 2, near "} 1"

  DB<2> $a = 'a'

  DB<3> p map { $a => 1 } 1,2,3
a1a1a1



Flags​:
  category=core
  severity=medium


Site configuration information for perl 5.16.3​:

Configured by gecko at Wed Mar 13 11​:25​:21 2013.

Summary of my perl5 (revision 5 version 16 subversion 3) configuration​:

  Platform​:
  osname=MSWin32, osvers=5.2, archname=MSWin32-x86-multi-thread
  uname=''
  config_args='undef'
  hint=recommended, useposix=true, d_sigaction=undef
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='C​:\PROGRA1\HASKEL1\2013201.0\mingw\bin\gcc.exe', ccflags ='-DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DPERL_TEXTMODE_SCRIPTS -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T -DHASATTRIBUTE -fno-strict-aliasing -mms-bitfields',
  optimize='-O2',
  cppflags='-DWIN32'
  ccversion='', gccversion='realgcc.exe (GCC) 4.5.2', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='C​:\PROGRA
1\HASKEL1\2013201.0\mingw\bin\g++.exe', ldflags ='-L"C​:\Perl\lib\CORE"'
  libpth=\lib
  libs=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt
  perllibs=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 -lmsvcrt
  libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl516.lib
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags='-mdll -L"C​:\Perl\lib\CORE"'

Locally applied patches​:
  ACTIVEPERL_LOCAL_PATCHES_ENTRY


@​INC for perl 5.16.3​:
  T​:\ADE\PerlInc
  C​:/Perl/site/lib
  C​:/Perl/lib
  .


Environment for perl 5.16.3​:
  HOME=W​:\
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=C​:\Program Files\ImageMagick-6.8.9-Q16;C​:\Windows\system32;C​:\Windows;C​:\Windows\System32\Wbem;C​:\Program Files\Haskell\bin;C​:\Program Files\Haskell Platform\2013.2.0.0\lib\extralibs\bin;C​:\Program Files\Haskell Platform\2013.2.0.0\bin;C​:\Perl\site\bin;C​:\Perl\bin;C​:\Windows\System32\WindowsPowerShell\v1.0\;C​:\Program Files\Common Files\EMC;C​:\PROGRA1\COMMON1\EMC;T​:\ADE\bin;C​:\GnuWin32\bin;C​:\Program Files\Haskell Platform\2013.2.0.0\mingw\bin;C​:\rcs57pc\bin\win32;C​:\Program Files\EMC\Navisphere CLI;C​:\Program Files\Graphviz 2.28\bin;C​:\Users\herind\AppData\Roaming\cabal\bin;W​:\bin
  PERL5LIB=T​:\ADE\PerlInc
  PERL_BADLANG (unset)
  SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Oct 30, 2014

From @cpansprout

On Thu Oct 30 13​:55​:41 2014, dean.herington@​emc.com wrote​:

This is a bug report for perl from dean.herington@​emc.com,
generated with the help of perlbug 1.39 running under perl 5.16.3.

-----------------------------------------------------------------
I don't understand the following error. I think the result of the
following statement should be the same as the similar one shown later.

DB<1> p map { a => 1 } 1,2,3
Not enough arguments for map at (eval 9)[C​:/Perl/lib/perl5db.pl​:646]
line 2, near "} 1"
syntax error at (eval 9)[C​:/Perl/lib/perl5db.pl​:646] line 2, near "}
1"

DB<2> $a = 'a'

DB<3> p map { $a => 1 } 1,2,3
a1a1a1

The map entry in perlfunc says​:

  "{" starts both hash references and blocks, so "map { ..." could be
  either the start of map BLOCK LIST or map EXPR, LIST. Because Perl
  doesn't look ahead for the closing "}" it has to take a guess at
  which it's dealing with based on what it finds just after the "{".
  Usually it gets it right, but if it doesn't it won't realize
  something is wrong until it gets to the "}" and encounters the
  missing (or unexpected) comma. The syntax error will be reported
  close to the "}", but you'll need to change something near the "{"
  such as using a unary "+" to give Perl some help​:

  %hash = map { "\L$_" => 1 } @​array # perl guesses EXPR. wrong
  %hash = map { +"\L$_" => 1 } @​array # perl guesses BLOCK. right
  %hash = map { ("\L$_" => 1) } @​array # this also works
  %hash = map { lc($_) => 1 } @​array # as does this.
  %hash = map +( lc($_) => 1 ), @​array # this is EXPR and works!

  %hash = map ( lc($_), 1 ), @​array # evaluates to (1, @​array)

  or to force an anon hash constructor use "+{"​:

  @​hashes = map +{ lc($_) => 1 }, @​array # EXPR, so needs
  # comma at end

  to get a list of anonymous hashes each with only one entry apiece.

So you could say this is not a bug, or a known limitation. However, I would like to try and fix the most obvious cases, like your examples, so that it just does the right thing. (That means doing look-ahead to see if there is a comma after the closing brace, which can only work for the most simple code.)

Personally I usually do ‘map +(...), LIST’, since it always works, unless I need multiple statements in the block.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Oct 30, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From @demerphq

On 30 October 2014 22​:51, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Thu Oct 30 13​:55​:41 2014, dean.herington@​emc.com wrote​:

This is a bug report for perl from dean.herington@​emc.com,
generated with the help of perlbug 1.39 running under perl 5.16.3.

-----------------------------------------------------------------
I don't understand the following error. I think the result of the
following statement should be the same as the similar one shown later.

DB<1> p map { a => 1 } 1,2,3
Not enough arguments for map at (eval 9)[C​:/Perl/lib/perl5db.pl​:646]
line 2, near "} 1"
syntax error at (eval 9)[C​:/Perl/lib/perl5db.pl​:646] line 2, near "}
1"

DB<2> $a = 'a'

DB<3> p map { $a => 1 } 1,2,3
a1a1a1

The map entry in perlfunc says​:

       "\{" starts both hash references and blocks\, so "map \{ \.\.\."

could be
either the start of map BLOCK LIST or map EXPR, LIST. Because
Perl
doesn't look ahead for the closing "}" it has to take a guess at
which it's dealing with based on what it finds just after the
"{".
Usually it gets it right, but if it doesn't it won't realize
something is wrong until it gets to the "}" and encounters the
missing (or unexpected) comma. The syntax error will be
reported
close to the "}", but you'll need to change something near the
"{"
such as using a unary "+" to give Perl some help​:

           %hash = map \{  "\\L$\_" => 1  \} @&#8203;array \# perl guesses EXPR\.

wrong
%hash = map { +"\L$_" => 1 } @​array # perl guesses BLOCK.
right
%hash = map { ("\L$_" => 1) } @​array # this also works
%hash = map { lc($_) => 1 } @​array # as does this.
%hash = map +( lc($_) => 1 ), @​array # this is EXPR and
works!

           %hash = map  \( lc\($\_\)\, 1 \)\,   @&#8203;array \# evaluates to \(1\,

@​array)

       or to force an anon hash constructor use "\+\{"&#8203;:

           @&#8203;hashes = map \+\{ lc\($\_\) => 1 \}\, @&#8203;array \# EXPR\, so needs
                                                  \# comma at end

       to get a list of anonymous hashes each with only one entry

apiece.

So you could say this is not a bug, or a known limitation. However, I
would like to try and fix the most obvious cases, like your examples, so
that it just does the right thing. (That means doing look-ahead to see if
there is a comma after the closing brace, which can only work for the most
simple code.)

Personally I usually do ‘map +(...), LIST’, since it always works, unless
I need multiple statements in the block.

Yet most of us would prefer to see map EXPR, LIST removed in favour of map
BLOCK list.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From sog@msg.mx

On 10/31/2014 01​:25 AM, demerphq wrote​:

On 30 October 2014 22​:51, Father Chrysostomos via RT
<perlbug-followup@​perl.org <mailto​:perlbug-followup@​perl.org>> wrote​:

On Thu Oct 30 13&#8203;:55&#8203;:41 2014\, dean\.herington@&#8203;emc\.com
\<mailto&#8203;:dean\.herington@&#8203;emc\.com> wrote&#8203;:
> This is a bug report for perl from dean\.herington@&#8203;emc\.com
\<mailto&#8203;:dean\.herington@&#8203;emc\.com>\,
> generated with the help of perlbug 1\.39 running under perl 5\.16\.3\.
>
>
> \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
> I don't understand the following error\.  I think the result of the
> following statement should be the same as the similar one shown
later\.
>
> DB\<1> p map \{ a => 1 \} 1\,2\,3
> Not enough arguments for map at \(eval
9\)\[C&#8203;:/Perl/lib/perl5db\.pl&#8203;:646 \<http&#8203;://perl5db\.pl&#8203;:646>\]
> line 2\, near "\} 1"
> syntax error at \(eval 9\)\[C&#8203;:/Perl/lib/perl5db\.pl&#8203;:646
\<http&#8203;://perl5db\.pl&#8203;:646>\] line 2\, near "\}
> 1"
>
> DB\<2> $a = 'a'
>
> DB\<3> p map \{ $a => 1 \} 1\,2\,3
> a1a1a1

The map entry in perlfunc says&#8203;:

           "\{" starts both hash references and blocks\, so "map \{
\.\.\." could be
           either the start of map BLOCK LIST or map EXPR\, LIST\. 
Because Perl
           doesn't look ahead for the closing "\}" it has to take a
guess at
           which it's dealing with based on what it finds just
after the "\{"\.
           Usually it gets it right\, but if it doesn't it won't
realize
           something is wrong until it gets to the "\}" and
encounters the
           missing \(or unexpected\) comma\.  The syntax error will
be reported
           close to the "\}"\, but you'll need to change something
near the "\{"
           such as using a unary "\+" to give Perl some help&#8203;:

               %hash = map \{  "\\L$\_" => 1  \} @&#8203;array \# perl guesses
EXPR\. wrong
               %hash = map \{ \+"\\L$\_" => 1  \} @&#8203;array \# perl guesses
BLOCK\. right
               %hash = map \{ \("\\L$\_" => 1\) \} @&#8203;array \# this also works
               %hash = map \{  lc\($\_\) => 1  \} @&#8203;array \# as does this\.
               %hash = map \+\( lc\($\_\) => 1 \)\, @&#8203;array \# this is EXPR
and works\!

               %hash = map  \( lc\($\_\)\, 1 \)\,   @&#8203;array \# evaluates to
\(1\, @&#8203;array\)

           or to force an anon hash constructor use "\+\{"&#8203;:

               @&#8203;hashes = map \+\{ lc\($\_\) => 1 \}\, @&#8203;array \# EXPR\, so needs
                                                      \# comma at end

           to get a list of anonymous hashes each with only one
entry apiece\.

So you could say this is not a bug\, or a known limitation\. 
However\, I would like to try and fix the most obvious cases\, like
your examples\, so that it just does the right thing\.  \(That means
doing look\-ahead to see if there is a comma after the closing
brace\, which can only work for the most simple code\.\)

Personally I usually do ‘map \+\(\.\.\.\)\, LIST’\, since it always works\,
unless I need multiple statements in the block\.

Yet most of us would prefer to see map EXPR, LIST removed in favour of
map BLOCK list.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

I think that a note about "{;" should be included in the documentation
to cover both cases.

sortiz.

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From dean.herington@emc.com

Thanks for making me realize that the description of `map` has been enhanced since my edition of the Perl bible was published.

Personally, I would have opted for a much simpler rule​: If what follows `map` is `{`, it starts a BLOCK. One can always signal an EXPR that's an anonymous hash with `+{`.

I do like the `map +(...), ...` option.

Thanks!

-----Original Message-----
From​: Father Chrysostomos via RT [mailto​:perlbug-followup@​perl.org]
Sent​: Thursday, October 30, 2014 5​:52 PM
To​: Herington, Dean
Subject​: [perl #123090] Not enough arguments for map

On Thu Oct 30 13​:55​:41 2014, dean.herington@​emc.com wrote​:

This is a bug report for perl from dean.herington@​emc.com, generated
with the help of perlbug 1.39 running under perl 5.16.3.

-----------------------------------------------------------------
I don't understand the following error. I think the result of the
following statement should be the same as the similar one shown later.

DB<1> p map { a => 1 } 1,2,3
Not enough arguments for map at (eval 9)[C​:/Perl/lib/perl5db.pl​:646]
line 2, near "} 1"
syntax error at (eval 9)[C​:/Perl/lib/perl5db.pl​:646] line 2, near "}
1"

DB<2> $a = 'a'

DB<3> p map { $a => 1 } 1,2,3
a1a1a1

The map entry in perlfunc says​:

  "{" starts both hash references and blocks, so "map { ..." could be
  either the start of map BLOCK LIST or map EXPR, LIST. Because Perl
  doesn't look ahead for the closing "}" it has to take a guess at
  which it's dealing with based on what it finds just after the "{".
  Usually it gets it right, but if it doesn't it won't realize
  something is wrong until it gets to the "}" and encounters the
  missing (or unexpected) comma. The syntax error will be reported
  close to the "}", but you'll need to change something near the "{"
  such as using a unary "+" to give Perl some help​:

  %hash = map { "\L$_" => 1 } @​array # perl guesses EXPR. wrong
  %hash = map { +"\L$_" => 1 } @​array # perl guesses BLOCK. right
  %hash = map { ("\L$_" => 1) } @​array # this also works
  %hash = map { lc($_) => 1 } @​array # as does this.
  %hash = map +( lc($_) => 1 ), @​array # this is EXPR and works!

  %hash = map ( lc($_), 1 ), @​array # evaluates to (1, @​array)

  or to force an anon hash constructor use "+{"​:

  @​hashes = map +{ lc($_) => 1 }, @​array # EXPR, so needs
  # comma at end

  to get a list of anonymous hashes each with only one entry apiece.

So you could say this is not a bug, or a known limitation. However, I would like to try and fix the most obvious cases, like your examples, so that it just does the right thing. (That means doing look-ahead to see if there is a comma after the closing brace, which can only work for the most simple code.)

Personally I usually do ‘map +(...), LIST’, since it always works, unless I need multiple statements in the block.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From @jandubois

On Fri, Oct 31, 2014 at 12​:25 AM, demerphq <demerphq@​gmail.com> wrote​:

Yet most of us would prefer to see map EXPR, LIST removed in favour of map
BLOCK list.

Seriously? I bet that would break tons of existing code. E.g. I
frequently use expressions like

  for (map lc, grep defined, @​list) { ... }

And I consider this concise syntax very "perlish". :) I also find it
more readable than the block form​:

  for (map { lc } grep { defined } @​list) {

Anyways, I think removal of "map EXPR, LIST" would have to be enabled
by a pragma and not be the default.

Cheers,
-Jan

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From @demerphq

On 31 October 2014 17​:42, Jan Dubois <jand@​activestate.com> wrote​:

On Fri, Oct 31, 2014 at 12​:25 AM, demerphq <demerphq@​gmail.com> wrote​:

Yet most of us would prefer to see map EXPR, LIST removed in favour of
map
BLOCK list.

Seriously? I bet that would break tons of existing code. E.g. I

frequently use expressions like

I didnt say i think its feasible. I just think its what most of us would
prefer if we had the option.

for \(map lc\, grep defined\, @&#8203;list\) \{ \.\.\. \}

And I consider this concise syntax very "perlish". :) I also find it
more readable than the block form​:

for \(map \{ lc \} grep \{ defined \} @&#8203;list\) \{

I dont much like either personally. Three loops for one list? But whatever.

Anyways, I think removal of "map EXPR, LIST" would have to be enabled
by a pragma and not be the default.

I dont think we can remove it at all. I just wish we could.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Oct 31, 2014

From @ikegami

On Thu, Oct 30, 2014 at 5​:51 PM, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

Personally I usually do ‘map +(...), LIST’, since it always works, unless
I need multiple statements in the block.

And to force the block syntax, you can use​: map {; ... } LIST

@p5pRT
Copy link
Author

p5pRT commented Nov 1, 2014

From @cpansprout

On Fri Oct 31 00​:46​:13 2014, sortiz wrote​:

I think that a note about "{;" should be included in the documentation
to cover both cases.

The docs did already mention { +... }, which works, too; but I added {; to the documentation nonetheless in commit 24fe90a. I don’t consider this issue resolved until the parser can search past the closing brace, at least for the simple cases of {string, string} and {var, var}, and combinations of those.

--

Father Chrysostomos

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

No branches or pull requests

2 participants