Add guidelines on judicious use of recursion#6
Add guidelines on judicious use of recursion#6nickelization wants to merge 4 commits intobasho:masterfrom
Conversation
paulhenrich
left a comment
There was a problem hiding this comment.
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.
Went to go play with this and noticed that the functions aren't exported.
There was a problem hiding this comment.
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.
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.
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.
README.md
Outdated
|
|
||
| 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.
minor formatting (one too many breaks)
There was a problem hiding this comment.
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.
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.
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.
|
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.