What is the reason for this syntax?

K

Kevin Olemoh

Hello I have been using ruby off and on for a few months and I have been
having a great time with the language but a few things bother me about
the syntax of the language itself. The two glaring issues are:

1. The syntax errors generated by the following code:

a.each
do
#stuff
end

for reasons I do not understand ruby demands that, that line be written as:
a.each do
#stuff
end

Quite frankly I find the second form to be more difficult to read
especially if one tends to create blocks with braces rather than the do
end keywords like I do. Is there some specific reason that both forms
are not supported by Ruby? It is needlessly restrictive with respect to
formatting in my opinion, perhaps a kind ruby-core developer could sneak
this syntax change into a future release?

2. What is with the elseif syntax specifically why is it elsif instead
of elseif when ruby already has an else keyword? I can't count how many
times I got errors because I decided to type elseif instead of elsif
while doing something with an if statement. I can name at least two
popular languages that use elseif not to mention the fact that if
English is your first language you will probably spell out else without
even realizing it since that is the correct way to spell the word in
English. Yes I know its a minor thing but if no one voices their
gripes how do people know something might need a bit of tweaking? :)
 
R

rajeev.networld

Kevin:

1. That is how it works and for me syntax #2 looks more easier.

2. elsif is same one we use in perl.

Ruby has more perl in it than python. It seems like you were a python
programmer that's why. I am perl programmer that this is natural to me.
 
M

Marcin Mielżyński

Kevin said:
Hello I have been using ruby off and on for a few months and I have been
having a great time with the language but a few things bother me about
the syntax of the language itself. The two glaring issues are:

1. The syntax errors generated by the following code:

a.each
do
#stuff
end

for reasons I do not understand ruby demands that, that line be written as:
a.each do
#stuff
end

In ruby statements are terminated by newlines and block is a parameter
to the each method here, consider:

def meth *args
end

meth
1,2

what is Ruby supposed to do in such situation ? In your case you are
calling the each method without any argument and supplying another
statement:

do
end

which obviously is wrong

On the other hand Ruby allows breaking statements when situation is more
obvious:

def meth *args

end

meth 1,
2

Quite frankly I find the second form to be more difficult to read
especially if one tends to create blocks with braces rather than the do
end keywords like I do. Is there some specific reason that both forms
are not supported by Ruby? It is needlessly restrictive with respect to
formatting in my opinion, perhaps a kind ruby-core developer could sneak
this syntax change into a future release?

Nope, they are not equivalent. The {} form binds tighter than do end.

def meth,arg
yield
end

and:

meth a do

end

block applied to the meth method


meth a {

}

block applied do a (which could be a method call) and the result of a
block would be passed to the meth method


lopex
 
V

Vidar Hokstad

Kevin said:
Hello I have been using ruby off and on for a few months and I have been
having a great time with the language but a few things bother me about
the syntax of the language itself. The two glaring issues are:

1. The syntax errors generated by the following code:

a.each
do
#stuff
end

In Ruby an expression continues on the next line if syntax
unambiguously shows that the expression is incomplete.

In this case "a.each" is a complete expression by itself (a method call
with no arguments and no block), and so the "do" on the following line
occurs without anything to take the block.

Vidar
 
G

gwtmp01

Hello I have been using ruby off and on for a few months and I have
been having a great time with the language but a few things bother
me about the syntax of the language itself. The two glaring issues
are:

1. The syntax errors generated by the following code:

a.each
do
#stuff
end

for reasons I do not understand ruby demands that, that line be
written as:
a.each do
#stuff
end

Blocks are part of the syntax of a method call (do/end or {})
Blocks are optional.
Newlines terminate statements.

The net result of those three things is that:

a.each

is considered a syntactically valid and complete statement. Leaving
Ruby to try
to interpret

do
#stuff
end

as the next statement, which fails. If Ruby executes
'a.each' (without the
block) you'll get a runtime exception. It is correct syntax, but
'each' insists
that it be called with a block.

You could of course give a hint to the parser that you want to
continue the statement:

a.each \
do
#stuff
end

but escaping the newline in this case doesn't improve the readability
(IMHO).
2. What is with the elseif syntax specifically why is it elsif
instead of elseif when ruby already has an else keyword? I can't
count how many times I got errors because I decided to type elseif
instead of elsif while doing something with an if statement. I can
name at least two popular languages that use elseif not to mention
the fact that if English is your first language you will probably
spell out else without even realizing it since that is the correct
way to spell the word in English. Yes I know its a minor thing
but if no one voices their gripes how do people know something
might need a bit of tweaking? :)

I doubt a survey of languages would come up with any sort of
consistency for the keyword in this case, so you are basically asking
why doesn't Ruby use the same syntax for the particular languages
that you are familiar with, which seems like a somewhat arbitrary
expectation and one that could never be satisfied for everyone.

I'm not a parsing/grammar expert, but I also suspect there is some
benefit to keywords not being prefixes of other keywords so that
'else' and 'elseif' create more parsing issues than 'else' and
'elsif'. I'm sure someone else could elaborate on that thought.

Gary Wright
 
J

Just Another Victim of the Ambient Morality

Just to add to a very good response to the original post...


Blocks are part of the syntax of a method call (do/end or {})
Blocks are optional.
Newlines terminate statements.

The net result of those three things is that:

a.each

is considered a syntactically valid and complete statement. Leaving
Ruby to try
to interpret

do
#stuff
end

The following code:

a.each
do
#stuff
end

...is the equivalent of to:

a.each; # note the optional statement terminator...
do
#stuff
end

as the next statement, which fails. If Ruby executes 'a.each' (without
the
block) you'll get a runtime exception. It is correct syntax, but 'each'
insists
that it be called with a block.

You could of course give a hint to the parser that you want to continue
the statement:

a.each \
do
#stuff
end

but escaping the newline in this case doesn't improve the readability
(IMHO).


I doubt a survey of languages would come up with any sort of consistency
for the keyword in this case, so you are basically asking why doesn't
Ruby use the same syntax for the particular languages that you are
familiar with, which seems like a somewhat arbitrary expectation and one
that could never be satisfied for everyone.

I'm not a parsing/grammar expert, but I also suspect there is some
benefit to keywords not being prefixes of other keywords so that 'else'
and 'elseif' create more parsing issues than 'else' and 'elsif'. I'm
sure someone else could elaborate on that thought.

In fact, Ruby has deep Perl roots, which is why so much of its syntax
is so Perl-like (just note its regular expressions). Perl uses "elsif"
and, thus, so does Ruby. Personally, I don't like it either but what can
you do...
 
D

David Vallner

--------------enigA8569A144581527E914455D5
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Kevin said:
Thank you all for your explanations of the syntax I pointed out. All I=
really want with respect to the blocks is the freedom to put the braces=
where I like without escape sequences of course.

Not in a semicolon-free language, I'm afraid. And if nothing else, this
reinforces use of a common style convention, which is a Good Thing.

Most of the people willing to fight vocally for the freedom to ignore
indentation and code style guidelines I've met never used CVS to see
just how horribly two people that have different autoformatting set in
their editors / IDEs confuse diff...

David Vallner


--------------enigA8569A144581527E914455D5
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFJZMuy6MhrS8astoRAsFsAJ9aCSxBURXwTHpUAl1oiXx7kqnl+gCfRc3Q
HsWaXLnj0uTBMz6sPOAy8Sg=
=L3I1
-----END PGP SIGNATURE-----

--------------enigA8569A144581527E914455D5--
 
C

Charles Oliver Nutter

David said:
Not in a semicolon-free language, I'm afraid. And if nothing else, this
reinforces use of a common style convention, which is a Good Thing.

Well let's not go too far down that path, now, or we might add something
horrid like syntactic indentation...
 
D

David Vallner

--------------enigE5026E10E7DA8C065AC347AF
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Well let's not go too far down that path, now, or we might add somethin= g
horrid like syntactic indentation...
=20

I like Python syntax, actually. It just takes a while for your brain to
stop breaking at the thought of pressing backspace meaning "end block" ;)=


David Vallner


--------------enigE5026E10E7DA8C065AC347AF
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFJaTey6MhrS8astoRAiPmAJ9dp/rpxbe7+FSTd/td55NB3+THOACcCq9c
UIXlmqyMUz+7UVrW7B/fHtk=
=8cKb
-----END PGP SIGNATURE-----

--------------enigE5026E10E7DA8C065AC347AF--
 
L

Louis J Scoras

Well let's not go too far down that path, now, or we might add something
horrid like syntactic indentation...

Exactly what I was thinking. On the other hand, although I don't care
for Python, the whitespace thing doesn't bother me in Haskell. I
don't know why, but I get the feeling that it wouldn't be so bad in
Ruby code either, but it's just a guess.

To tell the truth, I do wish there was a visible statement seperator
though (semi-colon). I find this

some_long_variable name = long_expression_which_needs
+ to_break_across_lines;

method
.chaing
.is.more.noticiable;

to be more readable than:

some_long_variable name = long_expression_which_needs +
to_break_across_lines

method.
chaining.
stands.out.less

Also, a syntax for associating more than one block with a method would
be nice too.

Of course these are minor gripes. As it is often cited, ruby is a
beautiful language.
 
M

Martin Coxall

So, use a '\' at the end of a line to indicate it continues on the
next. Not the end of the world.

Martin
 
J

Jean Helou

Exactly what I was thinking. On the other hand, although I don't care
for Python, the whitespace thing doesn't bother me in Haskell. I
don't know why, but I get the feeling that it wouldn't be so bad in
Ruby code either, but it's just a guess.

To tell the truth, I do wish there was a visible statement seperator
though (semi-colon). I find this
[...]
As far as I know nothing prevents you from using a semi-colon at the
end of your statements if you wish ...
see :

irb(main):001:0> class A; def t; @t||=[];end;end;
irb(main):002:0* a=A.new
=> #<A:0x100d29e8>
irb(main):013:0> u=a.
irb(main):014:0* t.
irb(main):015:0* length;
irb(main):016:0* u
=> 0

it does work so if you have some really long statement on multiple
lines and you want a visual marker at the end, go ahead, semi-colon
works just fine
 
L

Louis J Scoras

As far as I know nothing prevents you from using a semi-colon at the
end of your statements if you wish ...

Sure you can, but that solves a different problem really. If you want
to continue with more than one expression per line, reach for the
semicolon. You see this idiom a lot when building up a hash with
inject.

some_enumerable.inject(Hash.new(0)) {|h, i| h+= 1 ; h}

Since the semicolon is not required though--i.e.: an endline is a
valid separator--you must leave the line in a place such that the
parsing will be unambiguous. Lines need to be broken after operators
rather than before. The reason you would want it the other way around
is so that you can see what's going on in the code by scanning the
beginning of the lines.
 
K

Kevin Olemoh

People really should be able to write code in the way that they
understand they shoulf not need to concern themselves with wrapping
their minds around a contrivance of the language they happen to be
using to get something done. Things like requiring the use of the
ternary operator (A special form of if in c/c++) in certain situations
are just mistakes on the part of the people who created the language.

I'm very glad I bothered to bring this up since at least now I have a
workaround until such time that the defacto requirement for K&R style
indentation with respect to blocks is removed. I doubt any of us
would think it good to disallow the use of single letter variables in
Ruby simply because the makers all happen to think that single letter
variables are bad formatting. (Which they are but as long as you keep
them to blocks they are fine in Ruby anyway.) People would be better
served encouraging people to use comments in code other people could
reasonably be expected to need or want to read rather than forcing
users to use obscure forms of some structures, or building in silly
things like syntactic indentation that expects you to judge whitespace
for the beggining and ending of various things.
It really does not matter how neat syntactically a language is if you
do not explain what your code is doing especially in a language such
as this that does not require explicit declaration of variables as
well as support (to an extent at least.) for implicit conversion of
data types.

These features do encourage what could very well be considered bad
programming ppractice since variables can pretty much appear anywhere
with no readily apparent indication of how they got there. (blocks) I
cannot express how thankful I am that ruby-core documentation is
generally incredibly well written and detailed as it offsets a great
deal of the potential WTF factor that this language could produce.

I was also wondering is there a way to *not* have to write the following:

magick::fobar.blah
or simillar when using libraries?
further more what exactly is magick:: supposed to be called?


As far as I know nothing prevents you from using a semi-colon at the
end of your statements if you wish ...

Sure you can, but that solves a different problem really. If you want
to continue with more than one expression per line, reach for the
semicolon. You see this idiom a lot when building up a hash with
inject.

some_enumerable.inject(Hash.new(0)) {|h, i| h+= 1 ; h}

Since the semicolon is not required though--i.e.: an endline is a
valid separator--you must leave the line in a place such that the
parsing will be unambiguous. Lines need to be broken after operators
rather than before. The reason you would want it the other way around
is so that you can see what's going on in the code by scanning the
beginning of the lines.
 
J

John Turner

Vidar said:
In Ruby an expression continues on the next line if syntax
unambiguously shows that the expression is incomplete.

So why can't the parser continue a statement on to the next line if the
syntax unambiguously shows that the expression on the next line is the
continuation of the line before it, such as lines starting with do or
..foo which are incorrect otherwise?
 
A

Alex Young

Sorry for jumping in mid-thread, but...

Kevin said:
People really should be able to write code in the way that they
understand they shoulf not need to concern themselves with wrapping
their minds around a contrivance of the language they happen to be
using to get something done.
*Everything* is a contrivance of the language you're using in some
respect, no matter which language you're talking about.
Things like requiring the use of the
ternary operator (A special form of if in c/c++) in certain situations
are just mistakes on the part of the people who created the language.
Where are ternary operators required?
I'm very glad I bothered to bring this up since at least now I have a
workaround until such time that the defacto requirement for K&R style
indentation with respect to blocks is removed.
Why would it be removed? The current situation is consistent, clear and
easy to understand.

It really does not matter how neat syntactically a language is if you
do not explain what your code is doing especially in a language such
as this that does not require explicit declaration of variables as
well as support (to an extent at least.) for implicit conversion of
data types.
I *think* what you're saying is that if you don't understand a language,
it won't be obvious what's going on. Welcome to the learning curve!
I'm not sure if you're arguing for type coercion or not here, but that
way lies (more or less) religious arguments in which Ruby's position is
clear and well-known.
I was also wondering is there a way to *not* have to write the following:

magick::fobar.blah
or simillar when using libraries?
further more what exactly is magick:: supposed to be called?
In this case, Magick would be a module. The same syntax can be used for
classes, though. If you want to short-cut it, you can say:

include Magick
Fobar.blah

The 'include Magick' line adds the Magick module to the list of places
that are searched for the Fobar class.
 
G

gwtmp01

I'm very glad I bothered to bring this up since at least now I have a
workaround until such time that the defacto requirement for K&R style
indentation with respect to blocks is removed.

I'm not sure where you are going with this but I think it is terribly
misleading to think of Ruby blocks (do/end and {}) as in any way similar
to the blocks deliminated by {} in C. They use the same punctuation,
but
beyond that they have vastly different semantics and so I'm not sure how
it follows necessarily that their textual representation would be
similar.
I was also wondering is there a way to *not* have to write the
following:

magick::fobar.blah
or simillar when using libraries?
further more what exactly is magick:: supposed to be called?

Sure you can write:

magick.foobar.blah # instead of using the scope :: operator

or you can create a temporary reference

fb = magick::foobar
fb.blah

I think there are two schools of thought on the :: scope operator.

1) Only use it to access constants:

Math::pI

2) Use it as in 1) but also use it when calling class methods:

Math::sin(0)

Its use in 1) is required, that is the only way you can access
constants within
modules or classes.

Its use in 2) is a style choice. Ruby is just as happy to access
class methods
using the dot notation:

Math.sin(0)


For method and constant lookup you can create shortcuts by using
include:

PI # uninitialized constant
include Math # add Math to the search path for constants and methods
PI # OK now because Math is searched also

So in your example, if magick was a module (Magick) and foobar was a
constant (Foobar)
you could do:

Magick::Foobar # explicit access
Foobar.blah # error
include Magick # include Magick in method/constant lookup path
Foobar.blah # ok now

This also works if foobar is a method for similar reasons but Magick
has to be a module
for include to work, and the include has to be executed in a module
(or top level) scope.

You could also use 'extend' to make a particular object search Magick
for methods and
constants:

class A; end
a = A.new
a.foobar # error
a.extend Magick
a.foobar




Gary Wright
 
E

Eero Saynatkari

--xQmOcGOVkeO43v2v
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

=20
So why can't the parser continue a statement on to the next line if the= =20
syntax unambiguously shows that the expression on the next line is the=20
continuation of the line before it, such as lines starting with do or=20
.foo which are incorrect otherwise?

It might require arbitrary parsing lookahead or other facilitation at
the parser/lexer level.

In any case, I just suggest getting over it (pun intended) and falling
in line (muhahaa) with the normal Ruby layout :)

--xQmOcGOVkeO43v2v
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFFJpct7Nh7RM4TrhIRAj6jAKCZBbVhHZNOPCMPDjdz0RJogjCXLQCggQmi
W4wtU5cDsB5/4xpJ3l514vk=
=EFZB
-----END PGP SIGNATURE-----

--xQmOcGOVkeO43v2v--
 
D

David Vallner

--------------enig78555F5272974ABBF9FA776F
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Kevin said:
People really should be able to write code in the way that they
understand

Let me introduce you to Real Life. This specific variant of that
interesting game has you working as a programmer. And lo and behold, you
work on a project with several people on it. And it's highly probable
some 75%-90% of your work will be in a team, and some of that will be
either maintaining code written by others, or writing code others maintai=
n.

People should write code OTHERS will understand. Irregardless of your
personal preference, you are to use the prevalent / official convention
in a given language when writing any nonpersonal code.
Whitespace-sensitivity flames aside, this is one of the points on which
Guido van Rossum is so right it ain't funny anymore.
ternary operator (A special form of if in c/c++)

Ternary operator isn't a special form of if in C or C++. I don't feel in
the mood for prechewing and spoonfeeding, so no code snippets today.

Also, for heaven's sake, LEARN a programming language before you flame it=
=2E
I have a workaround

Which you shouldn't use.

[snip rest of rant]

David Vallner


--------------enig78555F5272974ABBF9FA776F
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD4DBQFFJsJgy6MhrS8astoRAhWWAJ0SMfy49pe4xTfJvTD26j3VUSlW6QCXdqMW
A7t03Iw5614MgCgJudm2wg==
=3zC7
-----END PGP SIGNATURE-----

--------------enig78555F5272974ABBF9FA776F--
 
K

Kevin Olemoh

I don't think of the blocks in the same way the real problem is that
since the open brace is so close to the close to another character I
have trouble actually seeing the brace itself. Editors that support
brace matching are great and I use them but they don't help much if I
am looking at code in a book or on a webpage.

When I say "until such time as the defacto requirement for K&R style
formating with respect to blocks is removed..." I do not mean making
said style illegal in anyway, all I mean is that programs breaking
because someone didn'r use this style is eliminated.

Thanks for the pointers with libraries and such.


David just because you like a given way of formatting does not mean
that everyone else should have to use it while they are creating
something even if they are working with you. The points you brought
up are the reason people need to be using comments in code not a
reason for the language itself to try and force a method of formatting
onto its users. I can't count how many times i have seen code that
while well formatted does not make nearly as much sense as it could
because whoever wrote the code did not put in enough comments if any
at all. In the real world you speak of people need to actually
explain themselves when others are going to be reading the code the
formatting of the code is almost entirely secondary.
This is what wikipedia has on the ternary operator
http://en.wikipedia.org/wiki/?:

(Are you sure you actually now what you are talking about what with
the overwhelming arrogance that you are exuding and all?)

I should have said that the ternary operator is a conditional
expression that often serves the same or very simillar functinction as
a "traditional" if statement in c/c++

However my real point was that requiring things like that which can be
very difficult to read is a mistake on the part of the people creating
the syntax of a language and that point still stands.
The only person who is flaming anyone here is you my friend.



Kevin said:
People really should be able to write code in the way that they
understand

Let me introduce you to Real Life. This specific variant of that
interesting game has you working as a programmer. And lo and behold, you
work on a project with several people on it. And it's highly probable
some 75%-90% of your work will be in a team, and some of that will be
either maintaining code written by others, or writing code others maintain.

People should write code OTHERS will understand. Irregardless of your
personal preference, you are to use the prevalent / official convention
in a given language when writing any nonpersonal code.
Whitespace-sensitivity flames aside, this is one of the points on which
Guido van Rossum is so right it ain't funny anymore.
ternary operator (A special form of if in c/c++)

Ternary operator isn't a special form of if in C or C++. I don't feel in
the mood for prechewing and spoonfeeding, so no code snippets today.

Also, for heaven's sake, LEARN a programming language before you flame it.
I have a workaround

Which you shouldn't use.

[snip rest of rant]

David Vallner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top