Incidentally, I find strange misuses of "call" ("calling a command", "calling a button") one of the more grating phrases used by ESL CS students.
Incidentally, I find strange misuses of "call" ("calling a command", "calling a button") one of the more grating phrases used by ESL CS students.
(In the way you'd call upon a skill, not in the way you'd call upon a neighbor.)
My favourite (least favourite?) is using “call” with “return”. On more than one occasion I’ve heard:
“When we call the return keyword, the function ends.”
I don't know enough Smalltalk to be sure but I think to remember it has a similar approach of everything is an object and I wouldn't be surprised if they'd coerced control flow somehow into this framework.
Also Forth comes to mind, but that would probably be a stretch.
It does. It's been discussed on HN before, even: https://news.ycombinator.com/item?id=13857174
λexpr1.λexpr2.λc.((c expr1) expr2)In in Tcl, `if` is called a "command".
The semantics of `if` requrie at least, `if(cond, clause)`, though more generally, `if(cond, clause, else-clause)`
e.g. in C:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf
(6.8.5.1) selection-statement:
if ( expression ) secondary-block
if ( expression ) secondary-block else secondary-block
in C++:https://eel.is/c++draft/gram.stmt
selection-statement:
if constexpropt ( init-statementopt condition ) statement
if constexpropt ( init-statementopt condition ) statement else statement
if !opt consteval compound-statement
if !opt consteval compound-statement else statement
where condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator brace-or-equal-initializer
structured-binding-declaration initializer
More examples:https://docs.python.org/3/reference/grammar.html
https://doc.rust-lang.org/reference/expressions/if-expr.html...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
expression != argument
So in the abstract, if is a ternary function. I think the original comment was reflecting on how "if (true) ... " looks like a function call of one argument but that's obviously wrong.
"If" can be implemented as a function in Haskell, but it's not a function. You can't pass it as a higher-order function and it uses the "then" and "else" keywords, too. But you could implement it as a function if you wanted:
if' :: Bool -> a -> a
if' True x _ = x
if' False _ y = y
Then instead of writing something like this: max x y = if x > y then x else y
You'd write this: max x y = if' (x > y) x y
But the "then" and "else" remove the need for parentheses around the expressions.But I assume the comment you were replying to was not referring to the conditional syntax from C-like languages, instead referring to a concept of an if "function", like the `ifelse` function in Julia [1] or the `if` form in Lisps (which shares the syntax of a function/macro call but is actually a special form) [2], neither of which would make sense as one argument function.
[1] https://docs.julialang.org/en/v1/base/base/#Base.ifelse
[2] https://www.gnu.org/software/emacs/manual/html_node/elisp/Co...
(if true '())
Or if you wanted to capture the exact same semantics (rather than returning a null value to the continuation of the if) (if true (values))
Now it's obvious that if takes two (or three) arguments :)In an imperative programming language with eager evaluation, i.e. where arguments are evaluated before applying the function, implementing `if` as a function will evaluate both the "then" and "else" alternatives, which will have undesirable behavior if the alternatives can have side effects.
In a pure but still eager functional language this can work better, if it's not possible for the alternatives to have side effects. But it's still inefficient, because you're evaluating expressions whose result will be discarded, which is just wasted computation.
In a lazy functional language, you can have a viable `if` function, because it will only evaluate the argument that's needed. But even in the lazy functional language Haskell, `if` is implemented as built-in syntax, for usability reasons - if the compiler understands what `if` means as opposed to treating it as an ordinary function, it can optimize better, produce better messages, etc.
In a language with the right kind of macros, you can define `if` as a macro. Typically in that case, its arguments might be wrapped in lambdas, by the macro, to allow them to be evaluated only as needed. But Scheme and Lisp, which have the right kind of macros, don't define `if` as a macro for similar reasons to Haskell.
One language in which `if` is a function is the pure lambda calculus, but no-one writes real code in that.
The only "major" language I can think of in which `if` is actually a function (well, a couple of methods) is Smalltalk, and in that case it works because the arguments to it are code blocks, i.e. essentially lambdas.
tl;dr: `if` as a function isn't practical in most languages.
if' :: Bool -> a -> a -> a
if' True x _ = x
if' False _ y = y
The compiler could substitute this if it knew the first argument was a constant.
Maybe it was needed in early versions. Or maybe they just didn't know they wouldn't need it yet. The early versions of Haskell had pretty terrible I/O, too.
In GHC, `if` desugars to a case statement, and many optimizations flow from that. It's pretty central to the compiler's operation.
> Maybe it was needed in early versions. Or maybe they just didn't know they wouldn't need it yet.
Neither of these are true. My comment above was attempting to explain why `if` isn't implemented as a function. Haskell is a prime example of where it could have been done that way, the authors are fully aware of that, but they didn't because the arguments against doing it are strong. (Unless you're implementing a scripting-language type system where you don't care about optimization.)
[1]: https://softwareengineering.stackexchange.com/questions/1957...
The post claims that this is done in such a basic way that if you have managed to rebind `ifThenElse`, your rebound function gets called. I didn't confirm this, but I believed it.
ifFalse: alternativeBlock
"Answer the value of alternativeBlock. Execution does not actually
reach here because the expression is compiled in-line."
^alternativeBlock valueBut yeah, this is a pretty critical point for optimizations - any realistic language is likely to optimize this sooner or later.
return(value);In many early computer programming documents the term "order" was used instead of "statement", where "order" was meant as a synonym for "command" and not as referring to the ordering of a sequence.
I believe that the term "statement" has been imposed by the IBM publications about FORTRAN, starting in 1956.
Before the first public documents about IBM FORTRAN, the first internal document about FORTRAN, from 1954, had used the terms "formula" for anything that later would be called "executable statement", i.e. for many things that would not have been called formulas either before or after that, like IF-formulas, DO-formulas, GOTO-formulas and so on, and the document had used "sentence" for what later would be called "non-executable statements" (i.e. definitions or declarations).
Before FORTRAN (1951 to 1953), for his high-level programming language Heinz Rutishauser had used the term "Befehl", which means "command". (For what we name today "program", he had used the term "Rechenplan", which means "computation plan".)
"Plan" is really a much better term than "program". My next compiler will be called "plantran" for "plan translator". "pt" for short.
An interpreter and editor in 1K sounds very challenging! Do you mean 1K of Squeak bytecode? Including vectors of literals and selectors?
The 1KB target was for Baby 8 (the associated processor) binary code. That processor had a few quirks (like only indirect addressing outside the "zero page") and the language design partly reflected that. Seeing other people fit Lisp into less than 512 bytes made me think I had sacrificed too much functionality for size.
The incomplete Squeak code was just a quick test to see if the language made sense at all before wasting time doing the assembly version.
The sieve example uses a single 8Kword array https://github.com/jeceljr/baby8/blob/main/examples/bla/siev...
Best I can tell, all usable definitions surrounding "Command" seem to suggest an associated action, which isn't true of all statements in imperative programming.
The defining characteristic of a programming "statement" is that it can perform some action (even if not all of them do), whereas statements in the usual everyday sense are inert. So it's not a good term.
Given a declaration "statement" such as:
int x;
What is the expected action? Memory allocation... I guess? Does any compiler implementation actually do that? I believe, in the age of type systems being all the rage, one would simply see that as a type constraint, not as a command to act upon.Expressing an idea (the values used henceforth should be integers) seems more applicable, no?
> int x;
> What is the expected action?
In a language that requires you to declare variables before you use them, it clearly does something - you couldn't do "x = 5;" before, and now you can. If you're trying to understand the program operationally (and if you're not then why are you thinking about statements?) it means something like "create a variable called x", even if the implementation of that is a no-op at the machine code level.
> I believe, in the age of type systems being all the rage, one would simply see that as a type constraint, not as a command to act upon.
But in that case by definition one would not be seeing it as a statement! Honestly to me it doesn't really matter whether "int x;" is an expression, a statement, or some mysterious third thing (in the same way that e.g. forward declaring a function isn't a statement or an expression). When we're talking about the distinction between statements and expressions we're talking primarily about statements like "x = x + 1;", which really can't be understood as a statement in the everyday English sense.
> Memory allocation... I guess? Does any compiler implementation actually do that?
Toy/research or embedded compilers do yes.
Including Ken Thompson's very own[1]. Fair enough that in the olden days there was a clearer distinction made, but even the man who (co-)created C changed his mind on that later because that is how the term has evolved. Now, in normal conversation, if you call `int x;` a statement, nobody is going to struggle to understand what you mean. Are you still living in the 1970s? If so, I admittedly missed that. My assumption was that this discussion is taking place in 2025 with the words of its time.
The distinction hasn't gotten any less clear, but it was already easy to find people in the 01970s who didn't know the difference. You're one of today's lucky ten thousand!
I do frequently encounter people who are failing to solve their problems because they don't know things that were already known in the 01970s, so I think it's worthwhile to study 01970s informatics. Mostly, though, I think it's worth studying the zeitgeist of the 01970s in informatics: some people were making rapid progress on solving fundamental problems, partly because they didn't have certain self-defeating attitudes that are popular in informatics today, such as not caring whether what they say is true or false.
Well, of course not. Hnlang is clearly not the same language as Go. The different name tips you off to that. However, the same intent can be expressed as a Go statement:
var x int
For what it is worth, the silly pedantry you offer is as funny as you had hoped it would be, so kudos. But it is telling that you had to reach for being funny to mask your cluelessness. Better than being one of those idiots that doubles down on their idiocy once they realize that they have no idea what is going on, I suppose!From my own experience, native speakers (who are beginners at programming) also do this. They also describe all kinds of things as "commands" that aren't.