Le mardi 24 mai 2016 à 23:00 -0400, Tom Breloff a écrit : > > if g() returns `nothing` then this code is fine; if g() returns a > > value, then we are accidentally returning it. > > This is the frustrating part for me. I very frequently have methods > which "do something and then pass control to another method". So by > putting g() at the end of f, I'm purposefully (not accidentally) > saying that I want to return whatever g() returns. Adding "return" > before that doesn't change the function, or the intention. If > someone doesn't care or want what is returned, then they don't use > it. I still don't see any benefit of a change, but I do see a real > annoyance. The problem isn't so much functions returning values that are not useful, but functions which inadvertently return a value just because it's what the last expression happens to evaluate to. Then callers may start relying on it, and the day you refactor the function a bit it returns something different and their code breaks.
To avoid this, you need to add explicit "return nothing" or "nothing" at the end of functions, which is annoying (and can easily be forgotten when you never experienced the problem). Regards > Is there an actual performance hit if there's a value returned but > not used? I assume that the compiler sees that the return value is > unused and discards it as if nothing was returned. Am I wrong with > that assumption? > > On Tue, May 24, 2016 at 6:29 PM, Stefan Karpinski <stefan@karpinski.o > rg> wrote: > > On Tue, May 24, 2016 at 5:08 PM, Steven G. Johnson <stevenj.mit@gma > > il.com> wrote: > > > As Jeff says, the current behavior is consistent in that a block > > > like begin...end has a value equal to its last expression in any > > > other context, so it would be odd if begin...end in a function > > > body did not have the same behavior. I mostly like the style of > > > explicit "return" statements in functions, but I think this > > > should be more of a linting thing. > > > > > What I proposed doesn't change anything about what any expression > > evaluates to. The only thing it changes is that > > > > function f(args...) > > # stuff > > end > > > > would implicitly mean > > > > function f(args...) > > # stuff > > return > > end > > > > That way unless you put an explicit return in a long form function, > > it automatically returns nothing, avoiding accidentally returning > > the value of the last expression. > > In order to adjust for this change one would at most need to add a > > single return at the end of long-form functions which are > > *intended* to return a value. Short-form functions would not have > > to change and long-form functions with explicit returns would not > > have to change. > > > > The problem with making this "a linting thing" is that we don't > > statically know which expressions return nothing. When you see code > > like this: > > > > function f(args...) > > # stuff > > g() > > end > > > > should it be a lint warning or not? It depends on what g() returns: > > if g() returns `nothing` then this code is fine; if g() returns a > > value, then we are accidentally returning it. Whether the code > > passes linting depends on the unknowable behavior of g(). Even if > > we did dynamic instrumentation, there's a chance that g() could > > return `nothing` as a meaningful value (see match). With the change > > I proposed, we can statically tell the difference between an > > accidental return and an intentional one. > >