TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Algorithms as Objects

77 pointsby giladalmost 6 years ago

12 comments

enriqutoalmost 6 years ago
I&#x27;m honestly impressed. After more than 20 years programming and reading about programs, this is the first time that I find such a thing: a concise and well-written description of the <i>exact opposite</i> of everything that I believe in. It&#x27;s like the author was reading my mind and applied a NOT filter before writing it back.
评论 #20224377 未加载
评论 #20222676 未加载
评论 #20222506 未加载
评论 #20223033 未加载
vorealmost 6 years ago
I don&#x27;t think I agree with using objects as the public interface to an algorithm, especially if its primary purpose is to apply some transformation over the input (i.e. a natural fit for a function). The examples given have a bit of a two-phase initialization smell: initialize some internal state, then run the algorithm: steps that are never performed separately.<p>Objects as an algorithm internal state might be a better approach: the caller doesn&#x27;t have to worry about the algorithm&#x27;s internal state, they only need to call the external function entry point (and you&#x27;ll destroy or otherwise forget the internal state at the end of the function, rather than putting the burden on the caller).
评论 #20226598 未加载
Someonealmost 6 years ago
<i>”It’s impossible for a client to call the wrong function; there’s only one way of doing things.<p><pre><code> my_algorithm = MyAlgorithmClass() results = my_algorithm.run()</code></pre> “</i><p>Only one? That API opens the door for<p><pre><code> my_algorithm = MyAlgorithmClass() results = my_algorithm.run() more_results = algorithm.run() </code></pre> , which, hopefully, resets exactly the right amount of state to work just fine.<p>There’s also the ‘fun’ of sharing an ‘algorithm’ between threads. That will teach you that this ‘algorithm’ is more a set combining function arguments with function state, and a method that uses them to compute a result. Next, if you’re smart, you’ll separate the arguments from the state.<p>⇒ if you do something like this, use that builder pattern.
评论 #20222011 未加载
keymonealmost 6 years ago
i really don&#x27;t see how<p><pre><code> AlgorithmClass().WithXValue(10.0) .WithYValue(20.0) .WithEtc(...) .Run(); </code></pre> is any better than<p><pre><code> Algorithm(x=10.0, y=20.0, etc=...) </code></pre> the argument that text books teach us algorithms in form of single function with inputs and outputs is quite weak, there&#x27;s a very simple solution - break up the large function into smaller functions.<p>i&#x27;ll always prefer a set of isolated functions with explicit argument and return declarations over a class implementation with methods because:<p>- argument list tells me immediately what is required and what are possible additional options as opposed to having to scan the method list for methods matching `WithFooBar` names<p>- methods become coupled to internal state of the algorithm object because let&#x27;s face it - code rots, maintainers take shortcuts, state proliferates, everything that is allowed by a compiler&#x2F;interpreter will eventually make it into the codebase; it&#x27;s much more preferable to avoid&#x2F;diminish most of these problems by writing isolated functions<p>- explicit arg&#x2F;return declarations help with default static analysis&#x2F;checks, much harder to do that with classes and internal state
评论 #20222800 未加载
评论 #20222100 未加载
评论 #20223174 未加载
评论 #20223051 未加载
hmschreckalmost 6 years ago
I stopped reading here:<p>It’s fine for the algorithm to have separate logical parts, but in a function this is a violation of the single responsibility principle.<p>If it&#x27;s contained inside the algorithm, and never done elsewhere, then it&#x27;s still following the SRP to have the algorithm as a single function. This is just someone who learned a new set of principles and over applies them.
评论 #20224189 未加载
smnplkalmost 6 years ago
I sometimes wonder if people like Bob Martin aka &quot;Uncle Bob&quot; and Martin Fowler have done more damage than good with their arbitrary rules. Or maybe people are too blindly following their rules in every aspect of software design.
评论 #20223713 未加载
评论 #20222601 未加载
viraptoralmost 6 years ago
The traversal example is a bit weird. There&#x27;s a simple solution to what the author wanted. Replace `print(root.value)` with `yield root.value`. Now you&#x27;ve got a simple algorithm where the caller can decide what to do with the values. And it nicely resembles every kind of iterating things in python. Instead, the object idea makes the algorithm specific to one single use case.<p>Same with the second example: You can write this as a filter on a function which reads the data. You get a generic reader and a generic filter which can be tested separately.<p>Twisting the code to fit it into the strategy pattern and preserving some hidden state just to make that possible seems silly to me. Is the class really worth writing instead of composable &#x2F; reusable &#x2F; testable &#x2F; streamable:<p><pre><code> def data_reader(fin): fin.readline() for line in fin: yield [int(val) for val in line.split()] def fill_zero(source): last_day = 0 for next_day, value in source: while last_day &lt; next_day - 1: yield 0 last_day += 1 yield value last_day = next_day</code></pre>
评论 #20222252 未加载
kace91almost 6 years ago
The start of the article is a very compelling description of why you should split your code into smaller components instead of just having a single structured procedure. Levels of abstraction, testability, etc. - Pretty basic stuff I think.<p>I don&#x27;t know where he took the leap to consider objects those components though. You can perfectly expose a function that is internally split without making it public in the public interface. And you certainly don&#x27;t want to deal with the extra problems of having shared state...<p>Object-oriented is not an antonym of monolithic. In fact, I&#x27;d say they tend to end up being related terms, rather than opposed.
评论 #20223023 未加载
评论 #20232885 未加载
UglycupRawkyalmost 6 years ago
Pendulum is slowly turning back to &quot;Everything&#x27;s an Object&quot;. Time to decorate Jabba sections in that CV and remember to drop in an obvious reference to GoF&#x2F;Fowler&#x2F;UncleBob writeups.
skybrianalmost 6 years ago
This is a reasonable pattern commonly used to implement recursive-descent parsers, where you have a parsing function for each language construct but they all need to access common state (such as the lexer and the error output). Passing this common state as separate parameters becomes tedious, so it makes sense to group them into a struct.<p>It&#x27;s not all that well-motivated in the article, though, since helper functions aren&#x27;t in themselves a code smell. You can just make them private. It&#x27;s also not strictly necessary to convert the helper functions into methods on the object holding the state, though this can be convenient.<p>Also, the state object is an implementation detail and should usually be private. The public API of of the parser can be a pure function.
Sutanreyualmost 6 years ago
<a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Strategy_pattern" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Strategy_pattern</a>
andyg_blogalmost 6 years ago
Although the examples are predominantly Python, the approach is useful in any language where functions aren&#x27;t forced to be in a class.