5 ms·
Ask HN: A programming language without if then else?
I'm not sure if there is any high level and practical programming language which forbid usage of if then else ?
- db48x 4y agoEarly languages such as Fortran had only goto, with no structured loops or conditionals at all (Fortran did have an IF keyword, but it was just a form of conditional goto). The first language to have them was Lisp, invented in 1960. Although Lisp has mostly remained a niche language, structured conditionals and loops became ubiquitous pretty quickly. Structured conditionals and loops were retrofitted to Fortran in 1977.
- jonsen 4y agoI'm pretty sure Algol (1958) had full structured programming.
- db48x 4y agoAlmost. Algol-58 had structured loops, but not conditionals (the IF statement only allowed you to skip the next statement, and there was no ELSE). Algol-60 had conditionals identical to what you find in languages today. But Algol-60 was published in 1962! It was certainly an idea that was in the air at the time; computer science was developing rapidly and of course everyone read everyone else’s papers and collaborated with each other. McCarthy, the inventor of Lisp, was also the one to propose structured conditionals for Algol-58, though it wasn’t accepted until later. Lisp was unusual in that it had 10 things that no other languages of the day had: 1. Structured conditionals 2. First–class functions 3. Recursion 4. variables are pointers, only values are typed 5. automatic Garbage Collection 6. no statements, only expressions 7. symbols as a data type distinct from strings 8. all code is entered as a syntax tree (homoiconicity) 9. full language available at load, compile, and run time 10. Macros Most modern languages have adopted most of these, with few exceptions. Systems languages (like Rust) often forgo automatic garbage collection (for good reasons), and nobody does macros as well as Common Lisp. Homoiconicity is quite rare outside the Lisp family of languages, as is having the compiler be part of the run time. On that latter point, Javascript comes the closest; you can go into the dev tools and define a new function that will be JIT–compiled along with all the rest, even if there is no specific function you can call to compile some code, or to disassemble some compiled code. It has an `eval` function you can use to read and evaluate new code from strings. In Lisp this is broken into two functions, `read` to parse code (or data) out of a string and produce list structure, and `eval` which executes code which has previously been parsed by `read`, or constructed by a macro, etc.
- jonsen 4y agoThanks!
- mdp2021 4y agoIt would be a rigid process (e.g. take value, increase, sum, shift, store - that is what you could do)... How can a program be "«practical»" without conditional branching?
- verdverm 4y agological languages do not have branching, such as Prolog and CUE, yet are still practical
- armchairhacker 4y agoIn theory you could create a language without if/else as long as it has pattern matching, because if/else can be emulated like so: match condition { true => { ... } false => { ... } } In fact you can create a language without if/else and pattern-matching, if you have something like first-class functions to handle branching. One notable example of such a language is lambda-calculus: true = λtf.t false = λtf.f if = λctf.ctf Which in more familiar syntax is true = (t, f) => t() false = (t, f) => f() if = (c, t, f) => c(t, f) And would evaluate like so if(true, workCorrectly, crashAndBurn) ==> true(workCorrectly) ==> workCorrectly() However in practice, most high-level languages have if/else. Even lesser-known functional languages like Coq and Haskell which rely more on their pattern matching, still include it simply because it's convenient and easy to implement. Worst case, the compiler can (and sometimes does) just desugar the conditional into one of the above.
- Measter 4y agoI hate that (nightly) Rust lets you do this: #![feature(fn_traits)] #![feature(unboxed_closures)] struct If; impl<T, F, V> FnOnce<(bool, T, F)> for If where T: FnMut() -> V, F: FnMut() -> V { type Output = V; extern "rust-call" fn call_once(self, args: (bool, T, F)) -> Self::Output { let (condition, mut yay, mut nay) = args; let arms: [&mut dyn FnMut() -> V; 2] = [&mut nay, &mut yay]; arms[condition as usize]() } } https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=1b8101ffae222b9645d28a570d0cd72c https://play.rust-lang.org/?version=nightly&mode=release&edi...
- db48x 4y agoWhy do you hate that Rust allows you to write this? You could write something like this in most modern languages.
- tluyben2 4y agoYou would want to find a high level language for which adding if/then would add expressiveness as defined here [0]. If it does not add expressiveness, it’s just desugaring/macros, which is basically the same as having if/then in the first place. [0] https://jgbm.github.io/eecs762f19/papers/felleisen.pdf https://jgbm.github.io/eecs762f19/papers/felleisen.pdf
- john_the_writer 4y agoYou could do this with elixir? def print(true), do: IO.puts("true") def print(_), do: IO.puts("not true") In fact it's typically best practice to do this. I almost never write if statements in elixir. It makes chaining much easier. value |> change_1() |> change_2() |> print()
- revskill 4y agoIs Elixir compile type safe ?
- john_the_writer 4y agoIt's compiled, but I wouldn't say it's perfectly type safe. My c++ background won't let me say that. It is close though.
- GianFabien 4y agoAssembler? Uses conditional and unconditional branches / jumps / calls instead.
- tssva 4y agoAssembler isn't a high level language which was a condition of the question.
- tanseydavid 4y agoI think Assembler is relevant here from the viewpoint that it is essentially machine language. IOW one should expect all computing languages to have some form of conditional branching because it is an elemental part of the logic capability of any CPU.
- JonChesterfield 4y agoNo branching might show up in some GPU kernel related things. Sometimes slow constructs are forbidden by construction. (if predicate consequent alternate) might be missing in favour of only (if predicate consequent), or you might only have the variadic form (cond p0 c0 p1 c1 p2 c2 alternate).
- hayley-patton 4y agoSmalltalk uses method dispatch and closures for control flow, which resembles the "Church encoding" in lambda calculus: 3 < 4 ifTrue: [ 'true' ] ifFalse: [ 'false' ] But very arguably that is still if-then-else, it's just not a special construct in the language. Avoiding Boolean values is also sometimes better to convey intent more precisely ("Boolean blindness"), but that's just a stylistic thing and not forbidding Boolean values entirely.
- Leftium 4y agoThis video explains how all branching was removed by refactoring an imperative-style function into functional-style. The original code is on the top, the refactored code is on the bottom: https://youtu.be/GyYME8btMHE?t=1473 https://youtu.be/GyYME8btMHE?t=1473 Generally, this type of refactoring converts code to a more declarative style: tell the computer what to do instead of how to do it (if-then-else): https://www.wikiwand.com/en/Declarative_programming https://www.wikiwand.com/en/Declarative_programming So you're probably looking for a declarative programming paradigm. (A single programming language can support multiple paradigms.)
- rurban 4y agoOne of the very first, lisp, only had cond and then the minor variants if and when. cond is more general than if then else, and also easier to read.
- the_linux_lich 4y agoGleam doesn't have if-else
- brudgers 4y agoIt is hard to wrap my head around the idea of "a high level programming language without conditional branching." I mean you can sugar up if as "when" or "cond" or "unless," but unless you have conditional branching you won't really have logic within the program. More philosophically, a language that doesn't have conditional branching will still be running on hardware that has it, so long as it is running on a computer. Good luck.
- yellowapple 4y agoEven low-level languages would struggle to get rid of "if"; any conditional branch is pretty much an "if". The various attempts in these comments to define "if" in terms of lambda calculus or pattern matching or whatever are noble, but at the end of the day, they'll be running on actual computers and will boil down to conditional branches - a.k.a. "if" - and even when they ain't, they're still just fancier ways of saying "if" anyway. You can, however, do away with else using unconditional branches - a.k.a. "goto". Pseudocode: goto :positive if input > 0 goto :negative if input < 0 print "Got zero" goto :end :positive print "Got a positive number" goto :end :negative print "Got a negative number" :end Whether this is an improvement is questionable, but I've seen some industrial and enterprise systems with their own "graphical" languages that do this. I've also seen (in similar environments) the inverse where everything is an if/else (or pass/fail), like so: start: compare(input > 0) pass: positive fail: next : compare(input < 0) pass: negative fail: next : out("Got zero") pass: end fail: end positive: out("Got positive") pass: end fail: end negative: out("Got negative") pass: end fail: end end: exit() pass: next fail: next
- revskill 4y agoI think it's possible to design such language. My idea is, wrap an expression, then calculate if it's false then automatically try catch.
- yellowapple 4y agoThe "calculate if it's false" is still an "if", though. At the end of the day it's still a conditional jump. The only way I see about avoiding that is by having the language target a "MOV machine" - that is, one where the only possible operation is to move values to/from memory. Conditionals would then work by writing values to predetermined addresses, reading a result from some predetermined address, and writing that result into the instruction pointer. This is cheating, of course (you've only punted the "if"s to the machine itself), and I wouldn't exactly call it "high-level", but it does technically satisfy the criterion of the language itself having no concept of a conditional jump (so long as it remains blissfully unaware of what the addresses it's reading/writing actually mean).
- bradknowles 4y agoSlack Workflows have no concept of conditionals.
- revskill 4y agoWhat is Slack Workflow ?
- bradknowles 4y agoSlack has a tool called Workflow Builder that is used to do things like develop workflows for different kinds of activity on a channel -- welcome new members, post a monthly FAQ, etc.... It has no conditional methods. It's a very straightforward step by step process that just ends when you don't have any more steps. I've written a few emoji reaction workflows.
- gompertz 4y agoSnobol4 is pretty much exactly this. Everything branches based on success or failure of predicates.
- sinuhe69 4y agoIf you mean there is no if/then keywords in the language then yes, PROLOG is one. But if you mean there is no branching, no comparison (conditional branching) then NO. Even the most basic Turing machine has to decide, and to be able to decide you have to compare and do a form of branching (halt,left or right). Therefore, all “proper” programming languages must have conditional branching.
- comprev 4y agoTerraform's HCL doesn't have "if" statements as such. It does have a "for each" logic though.