Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest changing default lambda notation to -> for all lambdas #7566

Closed
keithrbennett opened this issue Dec 12, 2019 · 6 comments
Closed

Suggest changing default lambda notation to -> for all lambdas #7566

keithrbennett opened this issue Dec 12, 2019 · 6 comments
Labels
style guide Requires update(s) to the Ruby Style Guide

Comments

@keithrbennett
Copy link

For the reasons described here, I suggest changing the default setting for lambda notation to prefer, or at least tolerate, stabby lambda (->) notation for both single line and multi-line lambdas.

I've done a lot of thinking about this, and have worked with lambdas a lot. I think I have a pretty strong case supporting the use of stabby lambdas, and with the default setting currently prohibiting it for multiline lambdas, for every project I work on I have to bring up the subject of changing the config file, not a productive use of anyone's time, and especially not something a new team member would do without at least a little trepidation.

Describe the solution you'd like

Make the stabby lambda notation permitted, or ideally, preferred, for multiline lambdas.

Additional context

I will paste the relevant content of the article here so it is colocated with this issue:

Stabby Notation as an Indicator of Preferred and Default Proc Type

In a previous article, "lambdas Are Better Than procs", I proposed that lambdas should be used rather than procs in almost all cases, given that they are safer in terms of argument count checking and return behavior.

So it makes sense that -> should create a lambda and not a proc. (As an aside, it always puzzles me when people use the term stabby proc, when it creates a lambda.)

One way to look at it is, by using the stabby lambda notation, we are
saying "make me Ruby's implementation of an objectless function". This is at a level higher than "make me a lambda" or "make me a proc", and is probably a better interface to the programmer, especially the newer Rubyist.

->'s Picture-Like Notation

The picture-like notation -> is quite different from the lambda and proc forms, because although all result in method calls that create Proc instances, lambda and proc look like method calls, while -> does not, instead appearing more like a language construct. On the higher level, it really is a language construct, and the fact that a method needs to be called to create a lambda is an implementation detail that should not matter to the programmer.

The striking appearance of -> says to the reader "take note, something different is happening here, this marks the beginning of a definition of a executable code that will probably be called somewhere else". If a picture is worth a thousand words, then a text picture like -> is worth, well, at least ten.

The Need for Visual Differentiation

Unlike other code in a method, a lambda's code is not called in sequence (unless it is immediately called as a self invoking anonymous function, but this is rare). Also, sometimes a lambda can be used as if it were a nested method, containing lower level code that may be called multiple times in the method in which it was defined. For these reasons, a pictorial indication setting it apart from other code in the method is especially helpful.

Rubocop

Rubocop is a very useful tool for normalizing code style. For better or worse though, Rubocop's defaults constitute implicit recommendations, and deviating from the defaults can require lengthy and contentious team discussions. Because of this potentially high cost of overriding the defaults, it is important that the basis in reasoning for the selection of the default be sound.

Rubocop's default setting for lambdas is to use -> with lambda one-liners but lambda for multiline lambdas. While this is not a matter of monumental importance, I believe it's misguided and should be changed.

My guess is that it is intended to mirror the Ruby code block notation convention of {..} for single line blocks and do...end for multi-line blocks. However, the code block case is different because the do and end are at the end and beginning of the line, respectively (though it is true that if there are arguments they will appear after the do). Although the indentation of the code block within the lambda do...end makes it easy to see that something is going on, it is easy to miss the lambda and assume it is a normal code block. The pictorial nature of -> reduces this risk.

I believe that the Rubocop default should be changed to prefer (or at minimum permit) -> in all cases.

Conclusion

Lambdas are, thankfully, first class objects in Ruby. That is, they can be passed to and returned from methods, and can be assigned to variables. This is a pretty major construct, and I believe a special notation (->), rather than a method name (lambda) is justified and helpful. While it is true that class, module, and def also mark the beginning of major language constructs, they are likely to be the first token on a line, whereas lambdas are usually assigned to variables or passed to methods or other lambdas, and are not.

The conciseness and pictorial nature of -> encourage the use of lambdas, and in my opinion, that is a Good Thing. Lambdas are underused in the Ruby community, and many opportunities for cleaner and clearer code are missed.

@bbatsov bbatsov added the style guide Requires update(s) to the Ruby Style Guide label Jan 5, 2020
@bbatsov
Copy link
Collaborator

bbatsov commented Jan 5, 2020

My guess is that it is intended to mirror the Ruby code block notation convention of {..} for single line blocks and do...end for multi-line blocks.

You're correct - this was the reasoning behind the current suggestion. I'm open to discussing this further, but keep in mind that's more of a topic for rubystyle.guide, as RuboCop simply follows the guidelines there.

@keithrbennett
Copy link
Author

Thanks, @bbatsov. I will post an issue in the style guide repo.

@stale
Copy link

stale bot commented Jul 8, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding!

@stale stale bot added the stale Issues that haven't been active in a while label Jul 8, 2020
@marcandre
Copy link
Contributor

@bbatsov is there a list for cops to exclude from the "main default list"?

@ioquatix
Copy link

Since this is the most closely related issue:

Is there some way to make stabby lambdas prefer ->{} for single line lambdas and ->do...end for multiple line lambdas? (e.g. Style/BlockDelimiters but for stabby lambdas exclusively?)

@stale stale bot removed the stale Issues that haven't been active in a while label Aug 18, 2020
@dvandersluis
Copy link
Member

dvandersluis commented Aug 9, 2022

The cop already supports the style being requested, and default option changes are always subjective.

As mentioned above, opening an issue with rubocop/ruby-style-guide is the correct course of action, and if it is agreed upon there we can certainly change the default on rubocop.

@dvandersluis dvandersluis closed this as not planned Won't fix, can't repro, duplicate, stale Aug 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
style guide Requires update(s) to the Ruby Style Guide
Projects
None yet
Development

No branches or pull requests

5 participants