-
Notifications
You must be signed in to change notification settings - Fork 10
Add guidelines on judicious use of recursion #6
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README looks good aside from minor formatting issue. See my notes re. examples.
@@ -0,0 +1,31 @@ | |||
-module(recursion). | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went to go play with this and noticed that the functions aren't exported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good call. I semi-deliberately left out the exports since I was mainly intending for this code to be a concise, illustrative example, rather than something anyone might ever actually want to run. I suppose it'd be easy enough to just add the one export line though and have a working module, so I'll go ahead and do that.
recurse(S) -> | ||
lists:reverse(recurse(S, [])). | ||
|
||
recurse([], Acc) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is meant as an illustration of your point (if so 👍 😄 ), but this doesn't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hahaha I wish I could claim credit for intentionally writing a bug in this function, but admittedly I did not actually test the code since I was just trying to convey the gist of the idea, and didn't expect anyone to actually run it 😆 . I will fix it along with addressing your other comment above, and then do a rebase and push.
Additionally, to an experienced Erlang developer, folds and list comprehensions are much easier to understand than complex recursive functions. Such contstructs behave predictably: they always perform an action for each element in a list. A recursive function may work similarly, but it often requires careful scrutiny to verify what path the control flow will actually take through the code in practice. | ||
|
||
*** | ||
*** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor formatting (one too many breaks)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, nice catch. Thanks! Will also fix this in a minute.
86e6ef8
to
4abfb96
Compare
👍 |
Isn't this subject already covered somewhere? The title's also feels inaccurate - you're not suggesting avoiding recursion, necessarily, just advising against rolling your own. |
@tburghart I also thought we had something about this already in the guidelines, but it appears we don't. I also don't see anything in the original Inaka version. I know this has come up at meetups before, so maybe we're both just recalling having discussed it. I'm not sure if I understand the difference between you're trying to point out between avoiding recursion vs. advising against rolling your own. By titling the section "avoid recursion when possible", I meant to imply "avoid writing code using recursion when possible"; I wasn't that explicit, but I'm not sure how else someone would interpret it, or whether adding such verbosity would address your concerns. Could you explain a little more about what you found inaccurate there, and perhaps suggest a better title? |
Yeah, there was a separate "architecture guidelines" doc on the wiki somewhere ... maybe I'll see if I can find it. As for the title, I might be being too pedantic, but Erlang is all about recursion - many of the This also conflicts to an extent with our recommendation to use named functions instead of closures when possible, as it's pretty common to have to wrap a function in a |
Ahh got it, that makes sense - I hadn't considered the angle of " That's an interesting point about named functions vs. closures, I hadn't thought about that particular tradeoff. I mean the ideal scenario is you can pass a named function directly into a library function, e.g. My personal feeling is that most of the time I'd still rather we pass a closure into a higher-order function than roll our own recursion, but I can see the argument either way. Perhaps we should defer to the architecture group and see if they can offer any additional thoughts on this. |
This should improve clarity, since technically functions like foldl and map use recursion; we want people to avoid writing their own recursive functions, not avoid using any function that does recursion under the hood.
|
||
%% GOOD: uses a fold instead to achieve the same result, | ||
%% but this time more safely, and with fewer lines of code | ||
fold(S) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lists map lists:map(fun string:to_upper/1, S)
would make the good example better (and almost the BEST ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Valid point! I had really wanted to demonstrate using a fold in my example, since almost any recursive list iteration function can be converted to a fold, so perhaps I will add a map
example alongside fold
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I think what @tburghart was talking about is mentioned in https://github.com/basho/internal_wiki/wiki/Code-Review-Guidelines#code-clarityquality - we had a long conversation about the wording of it over email, so may be worth taking the wording from there? |
@JeetKunDoug 👍 I will update the wording to match. |
This better conveys when and why you should avoid manual recursion.
👍 |
create jira issue |
No description provided.