8 ms·
Okay, you got me. I am in the camp that says calling the library is (in the general case) obviously the better choice. My (camp's) reasoning: 1. Your handroll
by seisvelas 7y ago
Okay, you got me. I am in the camp that says calling the library is (in the general case) obviously the better choice.
My (camp's) reasoning:
1. Your handrolled solution is likely worse than the library anyway
2. You're wasting effort reinventing the wheel
3. You risk adding unnecessary opacity by littering the program with dense math
4. Other programmers will assume there is a pertinent reason you handrolled the algorithm instead of using the library. Now everytime someone touches that code they have to reverse engineer your approach to see what it does different from the library such that you had to roll it yourself (surprise: nothing!).
The two exceptions I imagine are 1) if you really do absolutely need some slightly modified microoptimization of what the library does or 2) if you are working for a platform where there is good reason to avoid even slight bloat (embedded).
For the people who read OP's comment and believe I am (obviously) wrong, what is your camp's way of looking at this?
- enriquto 7y ago> I am in the camp that says calling the library is (in the general case) You misunderstood the question. The question is not about the general case. It is about solving a linear system of two equations and two variables. The solution is not found by "an algorithm", it is a simple formula that fits in one line.
- heisenbit 7y agoI was tending to go in your direction, but then the formula contains a division and we could be faced with a division by zero error. Which makes me a bit uncertain whether it is so simple. If we are guaranteed the matrix is invertible then doing it by hand is something I would prefer. And likely if it is not then as well since... The invertibility issue also plagues any library and while it may not blow up by a division by zero we likely still would need to handle that case. This requires to understand the libraries handling of corner cases and how it affects the results.
- crispyambulance 7y agoSure, if you're solving a 2x2 in ONE place in a piece of software, it makes sense to just perform the computation directly without using a library. Realistically speaking, though, if you're doing one 2x2 computation, you're probably going to end up doing a bunch of other linear algebra as well. If you don't do linear algebra in your everyday work, the threshold from rolling-your-own solution to grabbing a library is going to come up very quickly. The Armstrong example is perhaps a bit mis-titled. He's talking about "implementing from scratch" only insofar as he can use the facilities of his platform to perform exactly the task he needs to do rather than bringing in a huge dependency, in this case, an FTP server that does a lot more than the one task at hand.
- NohatCoder 7y agoIf you don't know how to do linear algebra, a library is unlikely to help you. Rote stuff like matrix inversion is the easy part, figuring that that is what you need is where things tend to get hairy.
- crispyambulance 7y agoI think also that people can "know" linear algebra but not be skilled it's practical implementation and usage in software. That's partly why computation libraries are among the longest-lived pieces of software in existence.
- SilasX 7y agoI hate to nitpick like this, but... The question asked about inverting a 2x2 matrix, nothing about solving a linear system of equations. The latter is certainnly one common use of inverting a matrix, sure, but from the problem as given, the use-case could just as well be "report to the end user what the inverse is".
- ci5er 7y agoAnd, now, we know why we have an explosion of libraries that do the job badly OR end up with bloated binaries by including LINPACK when a one-liner would have done the trick. You triggered a conversation thread that made me understand the ecosystem dynamics a bit better. Thank you.
- throwsprtsdy 7y ago> Your handrolled solution is likely worse than the library anyway This assumption led to a lot of O(n^2) left-padding happening over the years, via left-pad from node.js. Ideally libraries would be well-tested and of high quality, but at this point there may be too many of them to vet. My own 2 cents is that if it's easier to implement the code from scratch than to evaluate and choose a library, perhaps the invent-it-here choice works best.
- jolux 7y agoIf you're better at this than LAPACK to the extent that you do not even trust it to function correctly, more power to you.
- BubRoss 7y agoI'm not going to integrate LAPACK for a single line expression.
- jolux 7y agoLAPACK is the underlying library behind most linear algebra packages in other languages and furthermore it was just an example. My guess is that you probably don’t have just one line of matrix manipulation ever, in which case using a well established library is a good idea. If not, then sure. Do it yourself. But that’s still more code that you have to maintain now.
- username90 7y ago> But that’s still more code that you have to maintain now. 10 lines of code is easier to maintain than a whole dependency.
- jolux 7y agoThat's arguable, because 10 lines of code almost never just stays 10 lines of code, and my point in the first place was more contesting that the dependency is hard to choose, or that there aren't solid proven libraries for this.
- bryanrasmussen 7y ago1. If you were Joe Armstrong or at his level, probably not. 2. If you're Joe Armstrong the amount of time you're wasting is negligible, and you don't need to worry about working with an unneeded dependency. I mean I would be wasting a significant amount of time because I'm not Joe Armstrong but there are things I get asked to do that other people would use a library for and I think what, why? 3. Opacity is in the eye of the beholder. If you're working on a project only you and a few people you know can handle it will ever look at, then you are that beholder. If you're working for a big organization as a consultant and your contract runs down in a month, think of the worst guy you have ever worked with that was still a programmer - that guy is the beholder. 4. If you write a comment then they won't make the assumption. Later: Why the downvote? Even Later: Upvoted, so I guess someone didn't like or maybe just clicked wrong.
- zimpenfish 7y ago> 1. If you were Joe Armstrong or at his level, probably not. But 99% of us are not at his level. And more importantly, 99% of the people who come after to maintain this code are not either.
- bryanrasmussen 7y agoI'm not sure if the people who come after Joe Armstrong to maintain his code are not at his level. Or at least close enough that this particular decision wouldn't be a problem
- NohatCoder 7y ago1. The computation is a handful of simple arithmetic statements, there is almost nothing one can do to optimize those. The library is likely written to handle inversion of any size matrix, that means it adds a bunch of control code to be more general, but also slower for this case. 2. You are wasting effort evaluating libraries. And I wonder what you lose in compile time? 3. You are calling into a black box, and you talk about opacity, a simple comment: /* this inverses the matrix */ will deal with your perceived issue. 4. Other programmers will assume there is a pertinent reason you included yet another dependency. Wonder what it does that 5 lines of code couldn't have done (surprise: nothing!).
- SilasX 7y ago>The computation is a handful of simple arithmetic statements, there is almost nothing one can do to optimize those. I'm not sure that's right in this case. For inverting a matrix, it makes a huge difference whether the determinant is exactly zero or just very close, and (IIRC) floating point math may give the wrong answer. A library will have worked through this issue.
- rzwitserloot 7y agoThe history of various bugs in various very commonly used libraries, with them being extremely obvious after being discovered, strongly suggests this: If there is some situation that is somewhat likely to come up and needs special code, but it is not immediately obvious (and, going by OP's evident lack of realizing it, that's some proof to say it is not immediately obvious)? It may not be there. And even if it is the common path, it can still be buggy. Is is less likely that a library with some actual use out there has these bugs vs. handrolling it, but, if you handroll it, you're writing it for _your_ case, specifically with what you have in mind, whereas the library is more general than that. That's usually upside, but there's also downside, in what may be obvious to your usecase may not be obvious to the library. The central point of the top comment here, that opinions differ and that there isn't actually an obvious answer even if you think there is one, holds true here.
- NohatCoder 7y ago
- rubyn00bie 7y ago> 1. Your handrolled solution is likely worse than the library anyway I quite doubt that, though I used to feel the same. The one feature I need in the library is probably implemented for a specific use case which is undocumented or misrepresented; and use cases outside of that are likely to be egregiously unsupported. Fixing the issues is almost always more work than just implementing X directly and looking up gotchas. (aside: to understand this first-hand, go pick any JavaScript[0] animation library, and then go add a library that integrates it the core framework you're using (or not)... et voila, enjoy the descent into hell.) A simple implementation of X that doesn't lock you into patterns you don't need or will one day harm you is worth its wait in gold. Seriously, I'd rather sacrifice DRY code than fuck myself eight months down the road by using a shitty over-engineered pattern that doesn't actually fit my needs. > 2. You're wasting effort reinventing the wheel Probably not; it turns out most of the wheel was invented and given to you in the language and runtime. For the article, it's 100% true, BEAM is pretty much an operating system and a great one at that. We often abstract for the sake of abstraction; I honestly think Elixir/Erlang has helped break me of quite a bit of that. Rust is also nice because it'll make things so very painful for you when you abstract for no reason. > 3. You risk adding unnecessary opacity by littering the program with dense math Opaque libraries are the exact same thing but are even harder to understand since the source code doesn't comply with your same coding standards, methodologies, or test suite. > 4. Other programmers will assume there is a pertinent reason you hand-rolled the algorithm instead of using the library. Now everytime someone touches that code they have to reverse engineer your approach to see what it does different from the library such that you had to roll it yourself (surprise: nothing!). Documentation is the answer here, it doesn't have much to do with library or DIY. Why go through the trouble to properly evaluate a solution, decide the best solution was to implement your specific use case (or otherwise), and then not document it? You're just asking to repeat yourself or forget. On the flip-side, its really easy to assume that library authors did something brilliant when in fact they've done the opposite. Or someone will assume you've chosen this library because you took the time to properly evaluate it and never question it... Ex. After eight months of having the library run slow and leak memory some junior engineer pulls you aside and softly says "I have a minor in mathematics, I noticed that library Y is only doing simple matrix multiplication... I can do the same thing with this [shows you four lines of code] and its a lot faster... I just assumed we had to use that library since its in our code base." Adding libraries before you need them causes more headaches than not because now you've littered a dependency throughout your code which may not be sufficient for future use cases. This goes back to I'd rather have less DRY code than be bound to a shitty inflexible pattern. > The two exceptions I imagine are 1) if you really do absolutely need some slightly modified microoptimization of what the library does or 2) if you are working for a platform where there is good reason to avoid even slight bloat (embedded). I don't totally agree with either of those statements fully but I don't strongly disagree with them either. I'd like to add for me these would be of much high significance: 1. Your future use case are unknown. 2. You do not know if the library will be maintained; so, by using it, you're going to own it anyway. There are no free lunches. 3. You're using only a small, defined subset of some standard (i.e. RFC or specification). The existing solutions provide too much cruft for your specific use case. 4. The solution is obvious and has one correct answer. In some languages this is easier because of strong conventions and standard libraries. In others, this is probably a pipe dream. 5. The libraries are not tested adequately or are not easily testable. I dunno, over the past few years especially, I've just started doing more things myself and yeah things do take slightly longer to start (sometimes...) they almost never take more time to maintain, expand on, or use. Each line of code used by your project is a liability (debt), not an asset, on your balance sheet... Less code, less liability, less debt. [0] No offense to JavaScript <3, I only choose it, because it's so ubiquitous.
- mrighele 7y agoI used to be in the "implement from scratch" side, but these days my position is a lot more "it depends". My approach to deciding if using an external library or write the code goes more or less as follows: a) Limit yourself to a few big libraries that are widely used and well supported. Especially if you work with a language where it is trivially easy to publish a new library, let's say javascript, you will find that even if you are just an average programmer half of the libraries you have access to have worse code that you would have written (so your point 1. is not necessarily correct) Also using a library has a number of costs with it: increase in code size, time wasted updating it when needed, learning how to use it, understanding its documentation (if there is any at all), understanding why it doesn't behave how it is supposed to, checking github for bugs not yet fixed, etc. (so the effort spent in your 2. point is not necessarily bigger) This cost is reduced is the library is a quality one, and also if you use a good amount of it, so my second point is b) try to avoid a library if you just you need to use little of its functionality Not only it may be cheaper to re-implement the part that you need, but adding a whole library means that you give charte blanc to other developers to use all the other parts of that library. This may be something that you want to avoid, expecially if the library has varying quality and not all parts are well-written. On the other side, if you know that you will probably need other parts in the future, it may be better to use the library instead. My third rule is c) keep in mind your team If most people in your team already know a library, the cost of using it is greatly reduced. On the other side, if it new for most of them, it may be easier for them to maintain custom code (relates to your point 3.).
- ci5er 7y ago2x2? Do it by hand. No dense math involved. One line of code (or so, depending on coding style). If you want to implement or call LINPACK to do a 2x2, you've got other problems.
- henriquez 7y agoEvery time I npm install my projects and get the "you have 10 new critical vulnerabilities!" message it makes me a little more cautious about relying on third party code. I think there's a balance between rolling your own and using a lib, and it boils down to the domain of the problem being solved. If you're really just flipping a 2x2 matrix, the linear algebra lib will have way too much junk you don't need, and learning to use it would be more work than just solving a math problem. On the other hand, if you need a lot of common functionality (like multitouch events on the frontend), then why reinvent the wheel when there are a handful of great libraries for it.
- smichel17 7y agoHey, you're me!'I would do this: 1. Add an "invert2x2Matrix(theMatrix)" function. 2. Implement the function myself (no library). 3. Add a comment at the top of the function to the effect of "if this ever ends up doing much more than what the name says, consider replacing it with a library."
- Scarblac 7y agoDo you know that we are talking about applying 1 well-known formula? And that he mentioned that the library wasn't otherwise used in the project?