Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

An article like this is hard to write. This is a good one. I have a few quibbles, but they are just quibbles.

IMHO* a distinguishing feature of Algol like languages (aka "procedural" languages) is the distinction between expressions and statements. Though personally I've never seen the appeal, that distinction seems to be popular for some reason.

* this isn't even a quibble -- the article is fine without it. Just something that has always seemed weird to me.



The distinction in ALGOL, Pascal etc. is useless.

But if you change your definitions such that expressions always evaluate to a single value and do not have any side effects while statements produce some kind of side effect (and may or may not yield a value), the distinction becomes important.

Especially if you believe side-effects need special handling (i.e. you are a functional programmer).


It's been done in some Pascal descendants: functions were required to be pure but procedures were allowed to mutate global state. Some even went as far as to remove functions altogether (with quite unpalatable results).


The only popular language I can think of that requires side effects to be declared is Haskell. Which doesn't have a distinction between statements and expressions.

Are there any good examples of languages that have it, where it isn't "useless"?


python, javascript, pretty much any language that is popular. I believe everything in Haskell is an expression, even the do notation, no?

But I think the argument being advanced is that the distinction between statements and expressions is fundamentally unnecessary. I don’t really know of any good argument in favour of them: I tend to think lisps have the perfect and simplest possible syntax.


Python, Lisp and Javascript don't require functions with side effects to be declared in a particular way. Haskell does.


The question was about expressions vs statements, not about the IO type.


I was replying to the point programmer_dude made in his comment.


Yes, that is indeed the point I was making. And yes, I’m a lisp programmer.


I'm not sure I fully agree with that characterization. Many people would intuitively classify assignment as a statement, yet it's an expression in C, which is fully in the Algol tradition. And Rust is certainly a descendant of C, but blurs the lines a lot further with loops being expressions.


Rust is certainly a descendant of ML. It just adopted curly braces to make it more palatable to C-ish people.

https://doc.rust-lang.org/reference/influences.html


Rust is a strict, GC-less Haskell but with a simpler type system and a more complicated syntax :)


In the case of Lua, the expression/statement distinction allows the language to be completely whitespace insensitive with no delimiters. The Lua grammar top level rule is just Stmt (ws Stmt)*. I think Ruby might work similarly, but I don't remember.

C is less particular about the expression/statement distinction. Java enforces redundancy.


There is no difference between expressions and statement in Ruby (a descendent of the Agol Family). Everything evaluates to a value so everything is an expression.

(to be fair, it took a lot of inspiration from Smalltalk and LISPs)


I would place Ruby in the Self/Smalltalk family, as it’s semantics are more similar to those languages.


If you count the quibbles how many quibbles would there be?


To use si units, a small handful of quibbles.


ALGOL 68 and Rust are expression-oriented languages.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: