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

The point is the kotlin compiler not handling tail recursive calls of other functions. If it cannot handle it that is a build time error, not a runtime one. It shouldn’t even get to the jvm. Clojure is way more dynamic so such errors would be expected.

The whole thing is attempting to hack together something that superficially competes with c# but just doesn’t have the substance.



Tailcalls is something that a language compiler that targets VM bytecode cannot easily address by itself and ideally needs cooperation from the VM.

I'm not aware of implementation details of either Clojure or Kotlin but if it is anything like F#, then I would really not hold tailcalls against either of them.

In order to effectively support FP languages, CIL specification defines tail. prefix for call, calli and callvirt opcodes, and CoreCLR fully supports it except scenarios outlined by the spec.

Does JVM bytecode specification have something like this?

Edit: Turns out F# compiler does additional heavy lifting besides emitting the prefix https://github.com/dotnet/fsharp/blob/main/docs/large-inputs...


interesting, thanks! any idea what the situation is like on wasm?


WASM does appear to have significant tailcall consideration: https://github.com/WebAssembly/tail-call/blob/main/proposals...


the high bit here seems to be 'Currently, the Wasm design explicitly forbids tail call optimisations'?


I'm not keeping up closely with WASM development, but doesn't it say this was the case at the time the proposal was written? It seems it goes quite extensively into the subject which is a good look for WASM (which I'm otherwise on the fence about when it comes to using it outside of browser scenarios).


`tailrec` in kotlin is a modifier to the function, not to the function call site. let's stipulate that that's a sensible decision (i don't think it is, but the rest of the thread is moot otherwise). are you suggesting that a `tailrec` function shouldn't be allowed to call any function other than in tail position? i think that would make it so restrictive as to be useless for most tail-recursive loops

the clojure approach (as i understand it; i've only written a few dozen lines of clojure) is to use an explicit `recur` operator, at the call site, for a tail-recursive call. implicitly that operator invokes the same function, not a different one, because that's the best you can do on the jvm. it's not a runtime error


I am suggesting that calling another tailrec function in the return statement and failing to error out when this isn’t actually going to work is an error. (I believe they have since adopted this position).

i.e. someone familiar with tail recursion but not the specifics of kotlin would not reasonably expect any such restrictions. It is better to not have such concepts at all than half done in this way, as it destroys confidence in the rest of the language constructs.


if you're programming in kotlin you're probably going to have to get pretty familiar with the jvm


Once again, it's not the JVM that's the problem, I am very familiar with the JVM. It is the Kotlin developers not caring to alert people to the idiosyncrasies of their features.

You don't get to say "it supports tail recursion" and then only do so in the most narrow sense imaginable - i.e. the case that is trivial to turn into a while loop. If they can't make actual uses work on the JVM properly then don't claim to have the feature in the first place.


often the more general concept is called 'tail-call optimization' to distinguish it from the narrower sense kotlin can handle. sometimes it's even called 'tail-call elimination' because 'optimizations' aren't supposed to change semantics

i agree that 'Kotlin supports a style of functional programming known as tail recursion.' is somewhat exaggerating kotlin's capabilities here




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

Search: