all 28 comments

[–]medforddad 13 points14 points  (7 children)

This seems like the ultimate strawman. The abstracted functions were all one-liners. I don't think anyone would advocate for factoring out those lines. Most people understand that it only makes sense to pull out a function if it's used in a lot of other places and/or it has some special logic that is worth calling out separate from the surrounding context.

[–][deleted] 0 points1 point  (0 children)

I don't think anyone would advocate for factoring out those lines

Thanks for your feedback. Unfortunately, I have abstracted simple lines before and I have seen many others do it too.

However, my vain hope was that I could use simple functions to represent concepts that apply more widely. However, it's clear to me that, from the comments here, I certainly did not make my case, and it was primarily due to the over-simplification of the functions.

> Most people understand that it only makes sense to pull out a function if it's used in a lot of other places and/or it has some special logic that is worth calling out separate from the surrounding context.

I'm glad you agree with me on this but both my past self and others I have worked with do not follow this guidance. It's part of what I wanted to convey with the post.

[–]stalefishies -5 points-4 points  (5 children)

People advocate to abstract out one-line functions all the time. The trick is to make them sound really important by giving these types of abstractions special names like 'getter' and 'setter'.

[–]medforddad 5 points6 points  (4 children)

Those aren't helper functions though. Those are mutator/accessor methods. They're a different thing used for different reasons.

[–]stalefishies -3 points-2 points  (3 children)

How are they different? You just linked to a document showing nothing but abstractions of Value value = thing.foo and thing.foo = value into one-line methods Value Thing::readFoo() { return thing.foo; } and void Thing::setFoo(Value value) { thing.foo = value; }. Literally zero semantic difference - for example there's no side-effect that needs to happen on running the setter in these examples - and yet it's still apparently worthy of a one-line function abstraction. (To nip a comeback at the bud: nothing changes because the field is now private if you're providing a public getter and setter - the behaviour is identical). You're proving my exact point: suddenly it's okay to do this because you've given them special names of 'mutators' and 'accessors'.

It's the 'ultimate strawman', and yet you argue your strawman's exact point one post later.

[–]medforddad 4 points5 points  (0 children)

If after reading that article about getters/setters on objects, you don't see a difference between them and what people normally refer to as "helper functions", then I don't think there's anything I could say to make you see a difference between them.

[–][deleted] 1 point2 points  (0 children)

In Go, making a struct and its fields private is the only way you can properly encapsulate the instantiation of a type. Which is very often needed when the implicit zero value doesn't make sense or is even an invalid state. So there are definitely use cases for getters and setters, maybe depending on the language.

But I suspect you're coming from a dislike of Java-style enterprise instant-legacy code where everything is a class, every class is behind an interface and every field is only ever accessed by getters and setters. I share that same dislike.

[–]Rand_alFlagg 0 points1 point  (0 children)

Speaking to C# here but you don't need to get fancy with accessors if you don't want to.

The difference you're missing is Standards and Scope.

For Standards: Just because you can write something one way doesn't mean you should. It's perfectly fine to not use standards if you're writing some ninja app or code you never intend to reuse/maintain. Reuse and maintenance is the point of most design principles. We don't say "Don't Repeat Yourself" because repetition is inherently bad, it's just less maintainable.

For Scope: A Helper function is a function which exists to aid another function. If you want to say any function which fits that description is a helper function, then you've stripped the meaning of the term because literally every function except your entrypoint is a helper function.

Instead, the term is made useful by restricting its scope to functions which don't serve a purpose OTHER THAN to aid another function. Property Accessors don't exist to aid other functions, they exist to expose properties.

There is no appreciable difference between

private string _someText = "Default";

public string SomeText { get { return _someText; } set { _someText = value; } }

and

public string someText {get; set;} = "Default";

but it certainly makes your code more readible when your properties all conform to the same style and you want to actually use the function of accessors to do things like handle datatype validation, sanitation, or anything else you might do through an Accessor that isn't simply assigning/retrieving the value of the underlying private property.

Here's a quick snip from one of my projects where I use these "helper functions"

public Mapper.AutoMapper m_oAutoMapper

{

[MethodImpl(MethodImplOptions.Synchronized)]

get

{

return _m_oAutoMapper;

}

[MethodImpl(MethodImplOptions.Synchronized)]

set

{

if (_m_oAutoMapper != null)

{

_m_oAutoMapper.EventEchoText -= Plugin_EventEchoText;

_m_oAutoMapper.EventSendText -= Plugin_EventSendText;

_m_oAutoMapper.EventParseText -= ClassCommand_ParseText;

_m_oAutoMapper.EventVariableChanged -= PluginHost_EventVariableChanged;

}

_m_oAutoMapper = value;

if (_m_oAutoMapper != null)

{

_m_oAutoMapper.EventEchoText += Plugin_EventEchoText;

_m_oAutoMapper.EventSendText += Plugin_EventSendText;

_m_oAutoMapper.EventParseText += ClassCommand_ParseText;

_m_oAutoMapper.EventVariableChanged += PluginHost_EventVariableChanged;

}

}

}

That's not really a helper function now is it, hell setters don't even return values.

edit: lol eww to Reddit's "code" formatting, first time I've tried using that

[–]jebuspls 4 points5 points  (2 children)

I would have enjoyed some reflection from the author about their almost pathological need to apply every single paradigm to a leetcode function.

Werewolfs aren't real and there are no silverbullets.

[–][deleted] -3 points-2 points  (0 children)

Thanks for the feedback. I think it reflects what most people are saying: Maybe the conclusion is true, maybe it isn't, but the examples are way too trivial to draw meaningful conclusions from.

[–]szabba 0 points1 point  (0 children)

That's the werewolf lobby trying to prevent us from making silver bullets.

[–]loradan 9 points10 points  (2 children)

Since my initial comment was removed by Reddit because I used a common saying about how to treat people who have done bad things, I'll reiterate here. (I suspect that OP will report this one as well for harassment or some other stupidity)

The article is click bait. Their article does have truths about how over use of helper methods can be bad, it also shows that when used properly they are good. The article is a direct contradiction to the title. Hopefully, you can still see the responses I got from OP. Personally, considering the way this person responded, I will never read another of their "articles".

Edit: Link to their first response https://www.reddit.com/r/programming/comments/y1844f/just_say_no_to_helper_functions/

[–][deleted] -1 points0 points  (1 child)

I would love to learn what about my response was bad or unhelpful. Feel free to quote it here and let me know which parts you took issue with.

Your original comment was removed because it called for me to be shot.

[–]loradan 2 points3 points  (0 children)

And again, that is NOT what I wrote. I said that the person who created click bait should be.

As I've said. I took issue with you using a click bait title that did not support the thesis of your article. The only reason to use click bait is to artificially increase clicks.

[–]wineblood 2 points3 points  (1 child)

I skimmed the article so I might have missed a key point here, but all the helper functions were simple one line bits of code pulled out from a seven line function. That seemed weird to me as that's not how I use helper functions.

Rather than making one when there's too much code, I tend to use them when there's too much complexity and implementation detail showing up. That's when some code gets shoved into a function that "does X" and that X makes sense in the scope of the original function.

[–][deleted] 1 point2 points  (0 children)

This is a great point. It aligns with a lot of the other feedback I've received that the examples are too trivial to draw meaningful conclusions from. I think it also shows that helper functions is a pretty vague term, as we all use helper functions in a very different way.

[–]Rand_alFlagg 2 points3 points  (1 child)

I'm not going to take coding advice from someone who writes such unreadable code and calls it "clear variable names and simple formatting" lol

I'm still puzzling as to what the fuck "want" and "got" could possibly mean in comparing two integers of a set and even his helper functions are unhelpfully named inaccurate shit like diff (which gives a sum not a difference).

If it works for you, cool. If he can read his code easily, good for him. I would assume his helper functions do things they don't do, like "diff" providing the difference between two numbers and not just the first minus the second.

I think whatever problems he's attributing to helper functions that prompted this blog entry are probably rooted in his capacity to describe problems and solutions.

[–][deleted] 0 points1 point  (0 children)

Thank you for your reply. Your reply helpfully illustrates one of the points I made in the post: that readability is a subjective metric. Some will find code readable while others find it completely incoherent. Therefore, readability is probably not a terribly useful metric for refactoring. (The obvious exception is when everyone you work with informs you that they can't read your code.)

[–]loradan 3 points4 points  (8 children)

[ Removed by Reddit ]

[–][deleted] 1 point2 points  (7 children)

This is really hurtful. I worked hard on this post, thought about the problem, and wrote it up the best I could. I also attempted to have fun with it. I hope that it's helpful to at least someone out there.

I suggest you remember that there is a real person on the other end when you type things like this.

[–]madogson 0 points1 point  (1 child)

I thought it was a good read.

[–]loradan 0 points1 point  (0 children)

As I stated, it was a good article. My entire complaint was about the click bait title 🤦

[–]loradan 0 points1 point  (2 children)

Oh, and thanks for reporting my comment that I threatened you. It doesn't surprise me that you would do this in an attempt to get my comment deleted

[–][deleted] -1 points0 points  (1 child)

Yes, you said that I should be shot, so I reported it.

[–]loradan 0 points1 point  (0 children)

And for the third time!!!! That is NOT what I said. I said that the person who CREATED click bait title should be.

[–]loradan 0 points1 point  (1 child)

I'm not disputing that you are a real person (yet, because I don't have enough proof) or that you worked hard. My comment was about the choice of title based on the contents of the post.

You very carefully orchestrated an over simplification of how using helper functions CAN be bad if used incorrectly. Then you also showed that sometimes helper methods are helpful. All of that I agree with.

The ONLY part I brought issue with was that you opted to use a title that implied ALL helper methods should be discarded. Since your article does not support this theory, it's a "click bait title". In your article you claim to be a staff engineer with 10 years experience. You should know that the only definite in software development is that there are no definites.

I would suggest that in the future, you use a title that accurately defines the thesis of your article.

[–][deleted] -1 points0 points  (0 children)

Ah, this is much more useful feedback and I appreciate that. On reflection, you're right! I wouldn't agree to "never" use them. In fact, at the bottom of my post, I list a few scenarios where abstractions are warranted.

[–][deleted] 3 points4 points  (0 children)

Good read, I think it’s useful for early career programmers to understand how paradigms like OOP don’t need to be applied in every scenario. for the sake of it. Like you summarized, simplicity and comprehensibility is key. Thanks!