A slight syntax change

26 views
Skip to first unread message

Bob Nystrom

unread,
Jun 23, 2011, 1:32:48 AM6/23/11
to magpi...@googlegroups.com
Prompted by a suggestion from someone on IRC (that I've sadly
completely forgotten :( ) I've made a small change to the syntax for
for loops. Instead of separating the pattern from the iterator
expression with "=", it uses "in" instead. It definitely reads better,
though it means adding another reserved word. Some examples:

for i in 1 to(10) do print(i)

for line in open("example/File.mag") do print(line)

for description, block in _specs do
...
end

So far I like it, but consider this an experiment (like everything
else in the language!). Maybe we'll go back to "=". Comments,
criticism?

- bob

Guillaume Laforge

unread,
Jun 23, 2011, 1:56:06 AM6/23/11
to magpi...@googlegroups.com
+1 on in too

Speaking of syntax changes...
I was wondering about your opinion on block demarcation.
Currently, you use a do/begin - end-ish approach (like Pascal, Ruby and others), and I was wondering what you thought about whitespace indentation delimitation like in Python or CoffeeScript. I've come to be used to C-like blocks with curly braces, but I really don't like "end", actually prefer whitespace when not using curlies, and was wondering if you'd consider using space indentation instead.

Guillaume

Bob Nystrom

unread,
Jun 23, 2011, 1:31:08 PM6/23/11
to magpi...@googlegroups.com
On Wed, Jun 22, 2011 at 10:56 PM, Guillaume Laforge <glaf...@gmail.com> wrote:
> I've come to be used to C-like
> blocks with curly braces, but I really don't like "end", actually prefer
> whitespace when not using curlies, and was wondering if you'd consider using
> space indentation instead.

Great question!

There are basically three block styles in languages today:

1. Braces (C, C++, JS, Java, Smalltalk):
if (foo) {
bar();
}

2. Keywords (BASIC, Ruby, Pascal):
if foo then
bar()
end

3. Indentation (Python, CoffeeScript):
if foo:
bar()

Braces are the most common. I shied away from them in Magpie because
they require a certain amount of extra text in all cases. A single
line block like:

if (foo) bar()

Has an unnecessary "(" after "if". It's there just to match the
closing ")" but it doesn't add any value. The only meaningful one is
the ")" because it separates the condition from the body. Go addresses
this by getting rid of the parentheses:

if foo { bar() }

But now you've got a useless "}" at the end. What control syntax
really needs is *separators* between the clauses, and not *grouping*
characters surrounding them. With "if", you need to separate the
condition, the then branch, and the else branch. You can do that with
just: if ... then ... else. To me, that's nicely minimal.

So now, if one of the branches is a block instead of a single
expression, do we use indentation or keywords to delimit it? We could
support either:

if foo then
a
end

or

if foo then
a

In the first case, a newline where the expression is expected (right
after "then") indicates the beginning of the block, and "end" (or
"else") indicates the end. In the second case, the newline and indent
does, and the "dedent" ends it.

Indentation is appealing because it's even more minimal. You should be
indenting for readability anyway, so why not make that thing that
actually defines the blocks?

I actually had Magpie working like that for a while. The problem is
that it doesn't play nice with expression-oriented languages. Python
is statement-oriented, so it works fine, but in Magpie, blocks are
just expressions, which means they can be nested. For example:

match 2
case 1 then "one"
case 2 then "two"
case 3 then "three"
end shouldEqual("two")

Without an "end" keyword, it's hard to tell where that "shouldEqual()"
should go. Would it be like this?

match 2
case 1 then "one"
case 2 then "two"
case 3 then "three"
shouldEqual("two")

That would mean shouldEqual() is just it's own expression. I think
you'd have to do something like:

(match 2
case 1 then "one"
case 2 then "two"
case 3 then "three"
) shouldEqual("two")

Which is... strange. I really like CoffeeScript, but I think they
struggle with this a bit.

After trying both, I found using ending keywords made it a good bit
easier to compose expressions. Maybe this is just me, but I also found
it easier to mentally parse the grammar. I made fewer mistakes and
spent less time thinking "how do I write this?" then I did with
significant indentation.

Aesthetically, I also like the way ending keywords look. I find it
gives code a nice vertical symmetry:

it should("unwind past uncaught error types") with
var caught = false
do
do
throw "unwind error"
catch is Int then
fail("Should not be caught here.")
end
catch is String then
caught = true
end
caught shouldEqual(true)
end

Here it's easy for me to tell that the block started on the first line
has ended because the "end" at the bottom lines up with it. This isn't
a huge deal, but I find it pleasant on the eyes, which matters to me.

But the main reasons are minimalism (which braces lack) and
composability (which indentation lacks).

- bob

Dave Cleaver

unread,
Jun 23, 2011, 5:21:38 PM6/23/11
to magpi...@googlegroups.com
I'm a fan of the change from = to in. I think it increases the
readability of for loops.

Dave

Mike Hershberg

unread,
Jun 23, 2011, 7:20:08 PM6/23/11
to magpi...@googlegroups.com
Thumbs up on the "in" keyword :-)

Mike Hershberg

unread,
Jun 23, 2011, 7:24:56 PM6/23/11
to magpi...@googlegroups.com
I like Magpie's use of "end" keywords to denote the blocks. I think it helps readability a great deal. It also saves me mental cycles when I don't have to check how all the indentation lines up to make sure that I understand the code correctly. The lack of braces also reminds me that this language is not of the C/C++/C#/Java world and, honestly, just looks cleaner.

-Mike-

Guillaume Laforge

unread,
Jun 24, 2011, 3:22:44 AM6/24/11
to magpi...@googlegroups.com
Bob gave an excellent explanation of the choice of syntax, thank you Bob.

I like writing DSLs very much and sometimes for DSLs having those ending "end" all over the place make the user remember he's using a programming language rather than an external DSL. That's why I don't like "end" too much. The braces are slightly less of a problem as they don't take too much visual space and can be considered mere punctuation, and I was thinking indentation might be nicer on the eye for DSL users.

That said, composability of expressions might indeed make things tough with indentation, which I understand very well.
OTOH, I would tend to advise users to avoid composing expression statements (if/match/etc) too much, as I fear the ultimate algorithm may be hard to decypher.

Guillaume

Bob Nystrom

unread,
Jun 24, 2011, 11:01:59 AM6/24/11
to magpi...@googlegroups.com
On Fri, Jun 24, 2011 at 12:22 AM, Guillaume Laforge <glaf...@gmail.com> wrote:
> Bob gave an excellent explanation of the choice of syntax, thank you Bob.
> I like writing DSLs very much and sometimes for DSLs having those ending
> "end" all over the place make the user remember he's using a programming
> language rather than an external DSL.

The "end" may not be that bad even in that case. I could be wrong, but
I wouldn't be surprised if non-programmers found keywords friendlier
than punctuation like braces. It's worth noting that "end" comes from
BASIC, which was intentionally designed for non-experts to use.

> OTOH, I would tend to advise users to avoid composing expression statements
> (if/match/etc) too much, as I fear the ultimate algorithm may be hard to
> decypher.

Agreed. Just because you *can* nest them deeply, doesn't mean you
*should*. When learning a language, people tend to follow the style of
the standard library and the code that came before them, so it will be
up to us to set a good example.

- bob

Guillaume Laforge

unread,
Jun 24, 2011, 12:03:10 PM6/24/11
to magpi...@googlegroups.com
On Fri, Jun 24, 2011 at 17:01, Bob Nystrom <munifi...@gmail.com> wrote:
[...]

The "end" may not be that bad even in that case. I could be wrong, but
I wouldn't be surprised if non-programmers found keywords friendlier
than punctuation like braces. It's worth noting that "end" comes from
BASIC, which was intentionally designed for non-experts to use.

"end" is not that bad for... English DSLs :-)
If you were French like me, and wanted to make a DSL in quasi-French, the fact of using "end" as a keyword could be a bit painful.
The various kind of braces seemed less of a problem wrt DSLs in my experience -- but it's not a scientific study of course :-)

It's funny how certain decisions can impact various aspects of the language: absence of dots for method calls, absence of end-of-statement punctuation, etc.
Everything is always inter-related in the syntax of a language. The combinatorial makes things interesting!
 
> OTOH, I would tend to advise users to avoid composing expression statements
> (if/match/etc) too much, as I fear the ultimate algorithm may be hard to
> decypher.

Agreed. Just because you *can* nest them deeply, doesn't mean you
*should*. When learning a language, people tend to follow the style of
the standard library and the code that came before them, so it will be
up to us to set a good example.

Exactly!
Sometimes, languages are prescriptive somehow in that area. 
For example, on the Groovy language, early on, we decided not to have "everything is an expression", as we feared that people would abuse it too much and nest things in an horrible way. 
I could go on with the impact of certain decisions as well, but anyway, that's beyond the scope of the thread, sorry for that digression.

Guillaume

--
Guillaume Laforge
Groovy Project Manager
Head of Groovy Development at SpringSource
http://www.springsource.com/g2one

Bob Nystrom

unread,
Jun 24, 2011, 6:35:06 PM6/24/11
to magpi...@googlegroups.com
On Fri, Jun 24, 2011 at 9:03 AM, Guillaume Laforge <glaf...@gmail.com> wrote:
> "end" is not that bad for... English DSLs :-)

Ah, good point! How Anglo-centric of me. :)

- bob

Mike Hershberg

unread,
Jun 24, 2011, 9:42:39 PM6/24/11
to magpi...@googlegroups.com
All kidding aside, I don't think syntax should be dictated by one use of the language alone. Writing a DSL is very useful but there are a million other use cases for a language where the choice of the word "end" has no bearing. I would worry if we put one particular use case ahead of all others when creating syntax.

Guillaume Laforge

unread,
Jun 25, 2011, 5:38:53 AM6/25/11
to magpi...@googlegroups.com
Hi Mike,

You're right, the language shouldn't be designed by just one use of the language -- unless the language were portrayed as a special purpose language obviously.
However, if the language can cope with more use cases than less, it can't be a bad thing either :-)
So if there were a proper syntax or approach to that would allow a nice usage for DSLs as well, that would be a nice bonus.
But even with "end", it ain't that bad at all for now, the language being already very readable in its current state.

Guillaume

Bob Nystrom

unread,
Jun 25, 2011, 1:21:30 PM6/25/11
to magpi...@googlegroups.com
On Sat, Jun 25, 2011 at 2:38 AM, Guillaume Laforge <glaf...@gmail.com> wrote:
> So if there were a proper syntax or approach to that would allow a nice
> usage for DSLs as well, that would be a nice bonus.

It isn't documented yet, but there's actually a lot more in Magpie for
that than it first seems. The entire expression grammar can be
extended and you can take over the parser completely. If you want to
see an example, take a look in lib/magpie/core.mag. You'll see that
all of these are defined in Magpie code:

- Arithmetic operators (including precedence)
- if/then/else
- The "and" and "or" operators, including short-circuiting

I'm still figuring out some details on how it works, which is part of
the reason it isn't documented yet, but Magpie should let you go
farther with your own DSLs than most languages let you. At some point,
I need to write down my thoughts on metamodules too. :)

> But even with "end", it ain't that bad at all for now, the language being
> already very readable in its current state.

Great! :)

- bob

Mike Austin

unread,
Oct 27, 2011, 9:12:12 PM10/27/11
to magpi...@googlegroups.com
I also like "end" instead of braces or significant whitespace because of the symmetry.  I could see how it works, for example, in F# because of the nature of the language, but it's still not a favorite.

Mike

Reply all
Reply to author
Forward
0 new messages