Timeline for Are lessons on tail recursion transferable to languages that don't optimize for it?
Current License: CC BY-SA 4.0
10 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Nov 28, 2021 at 9:05 | comment | added | Steve | You asked in your answer (paraphrase) "why complicate a language by adding two concepts to it, when one basic concept can perform all necessary activities?". The answer is that getting one basic concept to perform all activities can be a complicated and difficult process for the programmer. Therefore it can be simpler to have two tools that each require little skill and concentration to apply to the task they are suited to, than to have one tool that always requires the highest skill and concentration to apply. (2/2) | |
| Nov 28, 2021 at 9:05 | comment | added | Steve | Well in your user-defined example, there is actually twice as much code (if you include the helper method), and ten times more theory (if you include understanding the helper method), than the equivalent block in C. That's what makes loops easier to use than recursion. You've chosen an example where the syntax at the outer call site is equivalent, but like a magician, up your sleeve is yet more code that supports the whole trick, and in your crafty mind is a more complicated understanding. (1/2) | |
| Nov 28, 2021 at 5:21 | comment | added | Jörg W Mittag | @Steve: I don't really understand what you are saying. Let's take Scala as an example, because it actually has a while loop built in as a language construct but also supports proper direct tail recursion. Given the definition of a user-defined library function for a while loop I gave in my answer above, this is what a loop using my user-defined whiley loop looks like: whiley (i < 10) { println(i); i += 1 }. And this is what a loop using the language built-in while loop looks like: while (i < 10) { println(i); i += 1 }. How exactly is the second one easier to use than the first one? | |
| Nov 27, 2021 at 21:52 | comment | added | Steve | But have you understood my point that the syntax itself is important for ease of use? Anything you can do with a for-loop you can do with a while-loop, and anything you can do with a while-loop you can do in assembly - and assembly can do at least as much as any higher level construct. Yet the for-loop remains indispensable, for example because of the way it brings into the block header all the control elements which relate to certain kinds of loops. Similarly, it may be possible to do anything with tail recursion alone, but syntactically it leaves a lot to be desired in most cases. | |
| Nov 27, 2021 at 19:46 | comment | added | Jörg W Mittag | … tail recursion, then you cannot elegantly solve the ones that require tail recursion. OTOH, if you have proper tail recursion but not loops, you can elegantly solve both, because you can trivially and elegantly implement loops using tail recursion. | |
| Nov 27, 2021 at 19:45 | comment | added | Jörg W Mittag | @Steve: If you have proper tail calls, or even just proper tail recursion, you can implement all of those looping constructs you mentioned, and even ones you didn't mention, or ones that haven't been invented yet, or ones that are not general enough to warrant inclusion in the language but might be perfect for your particular situation, as library functions. No need for loops as a language construct, when implementing them as a library function is just a one-liner. Put another way: some problems can be elegantly solved with tail recursion, some with loops. If you only have loops but no proper | |
| Nov 27, 2021 at 19:39 | comment | added | Steve | "why make your language unnecessarily complex with two concepts..." - indeed, why have function calls when you can write it all in assembly? For me, the problem is that just because everything can be done recursively, does not mean it is usually the easiest possible conception of the task, especially with the typical syntax. There are several common looping constructs in imperative languages - while, for, foreach, etc. They can all be implemented in terms of conditions and jumps, but they exist severally because each one is suited to a different use and makes it easier for the programmer. | |
| Nov 27, 2021 at 9:24 | history | edited | Jörg W Mittag | CC BY-SA 4.0 | deleted 3 characters in body |
| Nov 16, 2020 at 19:06 | vote | accept | J. Mini | ||
| Nov 15, 2020 at 21:20 | history | answered | Jörg W Mittag | CC BY-SA 4.0 |