Skip to content

Remove implicit returns? #2477

@devongovett

Description

@devongovett

After writing CoffeeScript for quite a long a while, I've come to the realization that implicit returns are actually more annoying than useful. Oftentimes I'll have to go back to a function later and add an explicit return statement to prevent CoffeeScript from adding implicit returns. They are the source of many bugs, and reduce the readability and predictability of CoffeeScript code.

  1. Having to go back an add explicit returns happens especially often when a loop is the last thing in the function, where very rarely do I want the function to return an array (if I did, I could easily add an explicit return). Generating and returning that array when I very rarely want it can also have a potentially large performance impact on the function as well, so I always have to remember to add a return statement at the end of many of my functions to prevent this. Just looking at a function with a loop at the end doesn't tell me that it returns an array so when it turns out it does it can be kinda strange. Usually you end up finding out when you discover another bug related to it or you look at the compiled JavaScript.
  2. It can also be inconsistent when combined with conditional logic. For example:
test = ->
        if someCondition
            doSomething()

This function returns the result of doSomething() only if someCondition is truth-y, otherwise it returns undefined. The question is why I would ever want a return value sometimes and not others. Without an explicit return statement, this seems strange. It isn't clear that this function returns anything just from looking at it.

  1. It can be annoying for functions that do something based on another function's return value. An example of such a function is jQuery's each function, which uses the false sentinel return value as a way to break out of the loop. Using the function in CoffeeScript when the last operation in that function sets a variable to false can be a source of bugs since CoffeeScript implicitly returns false and this stops the loop. For example:
arr = ['a', 'b', 'c']
map = {}
$.each arr, ->
        map[this] = false

Just reading this example doesn't make it clear that the loop will only run once rather than the expected three times. The variable map would equal { a: false } after running this loop. I would have expected to have gotten { a: false, b: false, c: false }. Adding an explicit return as the last line of the each function fixes the problem, but you wouldn't know to do that without reading the compiled JavaScript.

I could probably come up with many more examples to show that implicit returns are usually not a good idea. I think CoffeeScript should actually remove implicit returns from the language. Typing out return really isn't so hard and will lead to more readable and predictable code and keep the language closer to the semantics of JavaScript (a good thing when working with libraries written in JavaScript like jQuery from CoffeeScript code). It would probably be less typing in the end since you will no longer have to add return statements to prevent CoffeeScript from implicitly returning the wrong thing. I know this would be a large change but I think it would be for the better since it is more of a cause of bugs than a helpful language feature.

Removing features from a language is hard, but sometimes the best thing to do. What do you think?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions