<p>Many C-style languages represent code blocks using curly brackets:</p>
<pre><code>if (condition) {
    ...;
    ...;
}
</code></pre>
<p>Python, however, uses significant whitespace:</p>
<pre><code>if condition:
    ...
    ...
</code></pre>
<p>The first can have some problems though. For example, it can be ambiguous with object literals:</p>
<pre><code>(args) -&gt; { /* Is this an object literal or a code block? */ }
</code></pre>
<p>Are there any alternatives to C-style or Python-style code blocks which are present in mainstream languages?</p>

<syntax><blocks>
Is there a widespread alternative to C-style or Python-style code block syntax?
CC BY-SA 4.0
2023-05-16T17:09:39.663Z
Note that the "object literal" syntactic ambiguity only exists in some languages (such as JS/TS). Others choose to make the literal syntax unambiguous: Rust `Thing { a: 1, b: 2 }`, C `(thing){1, 2}`
zdimension
CC BY-SA 4.0
2023-05-17T11:56:10.260Z
[Wikipedia has it covered](https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Blocks).
Peter Mortensen
<p>Haskell uses the so-called 'layout' syntax, where during lexical analysis, the lexer collects Python-like indentations and translate them into <code>{</code> (start of a block), <code>;</code> (block separator), and <code>}</code> (end of a block). Then, the parser deals with C-style syntax.</p>
<p>This means you can use indentations and <code>{</code>, <code>;</code>, <code>}</code> in the surface syntax at the same time.</p>

CC BY-SA 4.0
2023-05-16T17:18:47.733Z
2023-05-16T17:18:47.733Z
ice1000
<p>This isn't a widespread alternative, but one of the first compilers, FLOW-MATIC, used semicolons to separate statements within an &quot;operation&quot;, and a full stop to terminate the operation. This more or less corresponds to how the punctuation marks are used in English.</p>
<pre><code>(1)  COMPARE PRODUCT-NO (A) WITH PRODUCT-NO (B) ; IF GREATER GO TO OPERATION 10 ;
     IF EQUAL GO TO OPERATION 5 ; OTHERWISE GO TO OPERATION 2 .
</code></pre>
<p>And now you know where the semicolon originally came from!</p>
<p>BASIC does something similar, with colons separating statements within a line.</p>
<pre><code>FOR I = 1 to 10 : PRINT &quot;Hello number &quot;;I : NEXT I
</code></pre>
<p>The full stop terminator is still with us in COBOL declarations:</p>
<pre><code>   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT CUSTMAST-FILE  ASSIGN TO       CUSTMAST
              ORGANIZATION  IS INDEXED
              ACCESS MODE   IS SEQUENTIAL
              RECORD KEY    IS CUSTMAST-PKEY-00001-00012
              FILE STATUS   IS CUSTMAST-STATUS.
       SELECT CUSTLTXT-FILE  ASSIGN TO       CUSTLTXT
              ORGANIZATION  IS LINE SEQUENTIAL
              ACCESS MODE   IS SEQUENTIAL
              FILE STATUS   IS CUSTLTXT-STATUS.
</code></pre>

CC BY-SA 4.0
2023-05-17T04:12:15.370Z
2023-05-17T04:12:15.370Z
Pseudonym
<p>Those &quot;blocks&quot; are <em>compound statements</em>, that is, sequences of <em>statements</em> which themselves are an imperative unit in imperative languages and which is most closely related to Assembly instructions.<br />
Many languages just don't have any of those.</p>
<p>Functional languages, for instance, most of the time have an expression-oriented syntax where &quot;sequence of things&quot; may not exist.<br />
They may look like this:</p>
<pre><code>parseIntOr s x =
    match parseInt s with
        | Some res -&gt; res
        | None -&gt; x
</code></pre>
<p>Those same languages, which include ones like Haskell, Idris, OCaml, Scala or F#, also avoid the statement/declaration problem by having let-bindings as expressions which nest, instead of variable declarations.</p>
<pre><code>main =
    getLine &gt;&gt;= \s -&gt;
        let str = parseIntOr s 42 in
        putStrLn (&quot;Read: &quot; ++ str)
</code></pre>
<p>Note how <code>getLine</code> above is not a function.<br />
In fact, such &quot;stateful operations&quot; as I/O, may be interpreted as values of their owns, which may be abstracted by <a href="https://wiki.haskell.org/Monad" rel="noreferrer">Monads</a> allowing you to chain them (above with the <code>&gt;&gt;=</code> operator function).<br />
It is not uncommon for languages to then also have an optional syntax that makes Monadic uses into statements, as in</p>
<pre><code>main = do
    s &lt;- getLine
    putStrLn (&quot;Read: &quot; ++ (parseIntOr s 42))
</code></pre>

CC BY-SA 4.0
2023-05-20T00:22:25.780Z
2023-05-20T00:22:25.780Z
Longinus
<h1>Prolog-style</h1>
<p>Prolog has a unique approach to syntax, based around commas and terminated by dots. Variables are capitalized and lowercase names are assumed to be atoms (Lispers would call those &quot;symbols&quot;).</p>
<pre><code>length([], 0).
length([_|Xs], N) :-
  M is length(Xs),
  succ(M, N).
</code></pre>
<p>While this was originally designed specifically for logic programming, it's seen adoption in Erlang and its derivatives for more typical imperative use. In Erlang, commas separate the statements of a multi-line function, while semicolons separate clauses of a <code>case</code> or <code>if</code> statement (<code>if</code> in Erlang behaves more like Lisp's <code>cond</code> than, say, a Python <code>if</code>). Functions are terminated by a period.</p>
<pre><code>max(X, Y) -&gt;
  if
    X &gt; Y -&gt; X;
    true -&gt; Y
  end.
</code></pre>

CC BY-SA 4.0
2023-05-16T17:37:12.480Z
2023-05-16T17:37:12.480Z
Silvio Mayolo
<h1>&quot;endif&quot;</h1>
<p>Somewhat similar to <code>}</code> but without requiring an opening brace, phrases like <code>endif</code>, <code>endfor</code> or sometimes <code>fi</code> (which is <code>if</code> written backwards) are common in many languages. This is especially true in scripting languages and templating languages.</p>
<p>Examples include:</p>
<p><strong>Bash</strong></p>
<pre><code>if [ condition ]; then
  your code
fi
</code></pre>
<p><strong>Jinja</strong></p>
<pre><code>{% if condition %}
    code
{% endif %}
</code></pre>

CC BY-SA 4.0
2023-05-16T16:56:19.160Z
2023-05-17T03:45:30.453Z
2023-05-17T03:45:30.453Z
mousetail 'he-him'
CC BY-SA 4.0
2023-05-19T01:19:51.823Z
CMake and Verilog also come to mind.
starball
CC BY-SA 4.0
2023-05-16T17:13:48.227Z
Also pascal has similar syntax (`begin` ... `end`)
TheMisir
CC BY-SA 4.0
2023-05-16T17:14:52.993Z
Languages in the BASIC family do this too.
DLosc
CC BY-SA 4.0
2023-05-17T00:16:22.933Z
It should be noted that languages using `fi` generally will use reversed versions of other keywords (`esac` to end `case`, etc.) Just to clarify that this is the same basic idea as `endif`, and distinct from the `end` described in DLosc's answer. That is: with this technique, the closing keyword is expected to "match" the opening one in same way; the other option is to use the same `end`-like keyword to close every kind of block.
Karl Knechtel
<h1>end</h1>
<p>Some languages, such as MATLAB and Julia, use the keyword <code>end</code> at the end of every block. Here is a MATLAB example from <a href="https://en.wikipedia.org/wiki/MATLAB" rel="noreferrer">Wikipedia</a>:</p>
<pre><code>classdef Hello
    methods
        function greet(obj)
            disp('Hello!')
        end
    end
end
</code></pre>
<p>I suspect, but am not sure, that this syntax evolved from the <code>begin</code> ... <code>end</code> syntax introduced by ALGOL (essentially equivalent to open and close curly braces in C). If all blocks begin with a block-opening statement (<code>function</code>, <code>if</code>, etc.), a <code>begin</code> keyword is not needed.</p>
<p>(This is similar to <code>endif</code> from <a href="https://languagedesign.stackexchange.com/a/4/27">mousetail's answer</a>, but the languages mentioned in that answer have different closing symbols for different types of blocks.)</p>

CC BY-SA 4.0
2023-05-16T17:18:12.893Z
2023-05-17T00:09:24.667Z
2023-05-17T00:09:24.667Z
DLosc
CC BY-SA 4.0
2023-05-16T18:56:23.900Z
Lua does this too.
Seggan
CC BY-SA 4.0
2023-05-16T23:09:55.553Z
+1. ALGOL first appeared in 1958 and FORTRAN first appeared in 1957. FORTRAN has the `ENDIF` and `ENDDO` syntax, but functions/subroutines can end with `END` (I don't know what FORTRAN looked like in 1957, but certainly it was like this in FORTRAN 77!).
Nike Dattani
<h1>Lisp-style</h1>
<pre><code>(if (test-clause) (action₁) (action₂))
</code></pre>
<p>Here, the &quot;brace&quot; includes the keyword.</p>

CC BY-SA 4.0
2023-05-16T16:57:59.760Z
2023-05-16T16:57:59.760Z
Adám
CC BY-SA 4.0
2023-11-29T18:39:25.497Z
Wow, first time seeing this style for some reason and I am really in love with it.
Syed M. Sannan
# Is there a widespread alternative to C-style or Python-style code block syntax?
Posted by: username_0 on 2023-05-16
Many C-style languages represent code blocks using curly brackets:
if (condition) {
    ...;
    ...;
}

Python, however, uses significant whitespace:
if condition:
    ...
    ...

The first can have some problems though. For example, it can be ambiguous with object literals:
(args) -> { /* Is this an object literal or a code block? */ }

Are there any alternatives to C-style or Python-style code blocks which are present in mainstream languages?
**Tags:** syntax blocks
> **Comments:**
> **username_1**: Note that the "object literal" syntactic ambiguity only exists in some languages (such as JS/TS). Others choose to make the literal syntax unambiguous: Rust `Thing { a: 1, b: 2 }`, C `(thing){1, 2}`  
> **username_2**: [Wikipedia has it covered](https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Blocks).  
---
## 7 answers
### Answer by username_14 on 2023-05-16. Score: 18
Lisp-style
(if (test-clause) (action₁) (action₂))

Here, the "brace" includes the keyword.
> **Comments:**
> **username_15** (2023-11-29): Wow, first time seeing this style for some reason and I am really in love with it.  
---
### Answer by username_7 on 2023-05-16. Score: 13
"endif"
Somewhat similar to } but without requiring an opening brace, phrases like endif, endfor or sometimes fi (which is if written backwards) are common in many languages. This is especially true in scripting languages and templating languages.
Examples include:
Bash
if [ condition ]; then
  your code
fi

Jinja
{% if condition %}
    code
{% endif %}
> **Comments:**
> **username_9** (2023-05-16): Also pascal has similar syntax (`begin` ... `end`)  
> **username_10** (2023-05-16): Languages in the BASIC family do this too.  
> **username_11** (2023-05-17): It should be noted that languages using `fi` generally will use reversed versions of other keywords (`esac` to end `case`, etc.) Just to clarify that this is the same basic idea as `endif`, and distinct from the `end` described in DLosc's answer. That is: with this technique, the closing keyword is expected to "match" the opening one in same way; the other option is to use the same `end`-like keyword to close every kind of block.  
> **username_8** (2023-05-19): CMake and Verilog also come to mind.  
---
### Answer by username_10 on 2023-05-16. Score: 10
end
Some languages, such as MATLAB and Julia, use the keyword end at the end of every block. Here is a MATLAB example from Wikipedia:
classdef Hello
    methods
        function greet(obj)
            disp('Hello!')
        end
    end
end

I suspect, but am not sure, that this syntax evolved from the begin ... end syntax introduced by ALGOL (essentially equivalent to open and close curly braces in C). If all blocks begin with a block-opening statement (function, if, etc.), a begin keyword is not needed.
(This is similar to endif from mousetail's answer, but the languages mentioned in that answer have different closing symbols for different types of blocks.)
> **Comments:**
> **username_12** (2023-05-16): Lua does this too.  
> **username_13** (2023-05-16): +1. ALGOL first appeared in 1958 and FORTRAN first appeared in 1957. FORTRAN has the `ENDIF` and `ENDDO` syntax, but functions/subroutines can end with `END` (I don't know what FORTRAN looked like in 1957, but certainly it was like this in FORTRAN 77!).  
---
### Answer by username_6 on 2023-05-16. Score: 8
Prolog-style
Prolog has a unique approach to syntax, based around commas and terminated by dots. Variables are capitalized and lowercase names are assumed to be atoms (Lispers would call those "symbols").
length([], 0).
length([_|Xs], N) :-
  M is length(Xs),
  succ(M, N).

While this was originally designed specifically for logic programming, it's seen adoption in Erlang and its derivatives for more typical imperative use. In Erlang, commas separate the statements of a multi-line function, while semicolons separate clauses of a case or if statement (if in Erlang behaves more like Lisp's cond than, say, a Python if). Functions are terminated by a period.
max(X, Y) ->
  if
    X > Y -> X;
    true -> Y
  end.
---
### Answer by username_3 on 2023-05-16. Score: 7
Haskell uses the so-called 'layout' syntax, where during lexical analysis, the lexer collects Python-like indentations and translate them into `{` (start of a block), `;` (block separator), and `}` (end of a block). Then, the parser deals with C-style syntax.

This means you can use indentations and `{`, `;`, `}` in the surface syntax at the same time.
---
### Answer by username_4 on 2023-05-17. Score: 5
This isn't a widespread alternative, but one of the first compilers, FLOW-MATIC, used semicolons to separate statements within an "operation", and a full stop to terminate the operation. This more or less corresponds to how the punctuation marks are used in English.
(1)  COMPARE PRODUCT-NO (A) WITH PRODUCT-NO (B) ; IF GREATER GO TO OPERATION 10 ;
     IF EQUAL GO TO OPERATION 5 ; OTHERWISE GO TO OPERATION 2 .

And now you know where the semicolon originally came from!
BASIC does something similar, with colons separating statements within a line.
FOR I = 1 to 10 : PRINT "Hello number ";I : NEXT I

The full stop terminator is still with us in COBOL declarations:
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT CUSTMAST-FILE  ASSIGN TO       CUSTMAST
              ORGANIZATION  IS INDEXED
              ACCESS MODE   IS SEQUENTIAL
              RECORD KEY    IS CUSTMAST-PKEY-00001-00012
              FILE STATUS   IS CUSTMAST-STATUS.
       SELECT CUSTLTXT-FILE  ASSIGN TO       CUSTLTXT
              ORGANIZATION  IS LINE SEQUENTIAL
              ACCESS MODE   IS SEQUENTIAL
              FILE STATUS   IS CUSTLTXT-STATUS.
---
### Answer by username_5 on 2023-05-20. Score: 5
Those "blocks" are compound statements, that is, sequences of statements which themselves are an imperative unit in imperative languages and which is most closely related to Assembly instructions.
Many languages just don't have any of those.
Functional languages, for instance, most of the time have an expression-oriented syntax where "sequence of things" may not exist.
They may look like this:
parseIntOr s x =
    match parseInt s with
        | Some res -> res
        | None -> x

Those same languages, which include ones like Haskell, Idris, OCaml, Scala or F#, also avoid the statement/declaration problem by having let-bindings as expressions which nest, instead of variable declarations.
main =
    getLine >>= \s ->
        let str = parseIntOr s 42 in
        putStrLn ("Read: " ++ str)

Note how getLine above is not a function.
In fact, such "stateful operations" as I/O, may be interpreted as values of their owns, which may be abstracted by Monads allowing you to chain them (above with the >>= operator function).
It is not uncommon for languages to then also have an optional syntax that makes Monadic uses into statements, as in
main = do
    s <- getLine
    putStrLn ("Read: " ++ (parseIntOr s 42))
---
