DEV Community

Discussion on: Programming Paradigms and the Procedural Paradox

Collapse
 
gaverhae profile image
Gary Verhaegen

This boils down more to the expression vs. statement idea. The smallest atomic building block of the procedural style is the statement: a unit of code that changes the value of the global, implicit state. The smallest atomic building block of the functional style is an expression: a unit of code that expresses a computation that returns a value.

Most languages these days have a pretty arbitrary mix of statements and expressions. For example, in Java, "1 + 1" is an expression, as is "a = 2" (which is why you can write "b = a = 2"), but "if {}" is a statement, so you can't write "a = if {}". "Functional" languages tend to "cheat" and say everything is an expression, but some expressions don't return a value, i.e. return some placeholder like nil or null or Nothing.

There's a good argument to be made that statements don't add anything to a language, and a language should always only be defined in terms of expressions. Existing languages that have statements are not going to get rid of them though.

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

I think the "placeholder" value you are looking for is called unit or () in most languages. Non-FP languages have it too. There it is called void but it is just a keyword, not a value you can return.

Thread Thread
 
gaverhae profile image
Gary Verhaegen

void and unit are generally type names, not values. My point was, even though some languages are syntactically defined such that everything is an expression and there is technically no statement in the language, there are still expressions that do not return any useful value. Clojure and Ruby would be examples of that.

Once static typing gets involved, the compiler may actively prevent using the return value of a void function, but that's a different story.

Thread Thread
 
kspeakman profile image
Kasey Speakman • Edited

Here is a good post on void vs unit. Unit does in fact have a value and a type, unlike void. Otherwise I agree with you. Prime example of what you are saying in F#: when a function returns unit (which is a sign that it performs a side effect), and it contains an if statement, then the compiler will include an implicit else () if you don't supply one. I actually don't like that, because it hindered my understanding when I was first learning F#. The early things you do like printing to the console return unit, so it feels like if is a statement. But then later when you are doing other kinds of logic, it won't compile when you operate under that assumption.