[comp.lang.perl] length operator

pett@cgl.ucsf.edu (Eric Pettersen) (02/16/90)

	IMHO, the "length" operator should not allow the "length EXPR" syntax.
I often want to handle "length-2" which, because the above syntax is legal,
forces me to write "length($_) - 2" instead.  Not to mention causing me some
lost time while trying to figure out why "length-2" doesn't work.  This has
probably caught other people as well.  Does "length EXPR" have any supporters?

				Eric Pettersen
				pett@cgl.ucsf.edu
				...!ucbvax!ucsfcgl!pett

merlyn@iwarp.intel.com (Randal Schwartz) (02/16/90)

In article <13103@cgl.ucsf.EDU>, pett@cgl (Eric Pettersen) writes:
| 
| 	IMHO, the "length" operator should not allow the "length EXPR" syntax.
| I often want to handle "length-2" which, because the above syntax is legal,
| forces me to write "length($_) - 2" instead.  Not to mention causing me some
| lost time while trying to figure out why "length-2" doesn't work.  This has
| probably caught other people as well.  Does "length EXPR" have any supporters?

$_ = "a long string";
$len = (length)-2;
print "the length is $len\n";
$len = length()-2;
print "the length is still $len\n";

prints:

the length is 11
the length is still 11

Okay, so it is still a bit icky.  Being able to type "length > 128" (a
good thing) means having that silly optional EXPR stuff (a bad thing).
Maybe there's an alternate, but it won't make it into patch 9. :-)

$_="Just another Perl hacker,";for$i(1..length){print substr($_,$i-1,1);}
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/16/90)

In article <1990Feb15.230159.8255@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes:
: In article <13103@cgl.ucsf.EDU>, pett@cgl (Eric Pettersen) writes:
: | 
: | 	IMHO, the "length" operator should not allow the "length EXPR" syntax.
: | I often want to handle "length-2" which, because the above syntax is legal,
: | forces me to write "length($_) - 2" instead.  Not to mention causing me some
: | lost time while trying to figure out why "length-2" doesn't work.  This has
: | probably caught other people as well.  Does "length EXPR" have any supporters?
: 
: $_ = "a long string";
: $len = (length)-2;
: print "the length is $len\n";
: $len = length()-2;
: print "the length is still $len\n";
: 
: prints:
: 
: the length is 11
: the length is still 11
: 
: Okay, so it is still a bit icky.  Being able to type "length > 128" (a
: good thing) means having that silly optional EXPR stuff (a bad thing).
: Maybe there's an alternate, but it won't make it into patch 9. :-)

I doubt I'll ever "fix" it.  In perl 2.0, we had the problem that you couldn't
tell which single-argument operators were allowed to be unary (that is,
without the parens), and which ones weren't.  The list operators were also
a mess.

In 3.0, I decided to regularize the unary and list operators.  The rules
are very consistent now.  Unfortunately, this makes a couple of counter-
intuitive spots in the language, but I think that's the price that has
to be paid.

Of the two spots, you've discovered one.  A unary operator, in order to
have an argument, must expect the next thing to be a term.  You can
(currently) get away with "length > 128" because no term starts with ">"--
it must be a binary operator.  But there are many characters that
can begin both terms and operators.  F'rinstance:

		Operator		Term
	+	addition		unary plus
	-	subtraction		unary minus
	*	multiplication		*name
	/	division		/pattern/
	<	less than, left shift	<filehandle>, <<EOF
	.	concatenation		.3333
	?	?:			?pattern?
	%	modulo			%assoc
	&	&, &&			&subroutine

You don't realize that the language has all this ambiguity resting on 
whether a term or operator is expected, because that's just not how
our minds work.  Unfortunately, the parser can't read minds.

If I outlawed unary operators, all the following would become illegal:

	chdir "/usr/local/bin";
	chroot "/usr/spool/ftp";
	eval "\@$device = something";
	sleep 20;
	exit 1;
	reset 'a-z';
	rmdir 'try';
	umask 0777;

I don't think you want those outlawed.

The other sticky spot is when you say

	print (1<<20),"\n";

which is the same as

	(print 1<<20), "\n";

There are a few basic rules.  When in doubt, put parens around a function's
arguments, and you'll never go wrong.  (Well, almost never.)  And, don't
take defaults unless you know what you're doing and have a good reason
for being lazy.  If the item following a unary operator could be construed
as a term, throw in a (), which forces the next token to be constued as
an operator.

That's just about all you have to worry about, except for the weirdities
that perl shares with C (like precedence of & and |).

Larry