Live data from Hacker News

Kill Your Dependencies

mikeperham.com

91–100 of 229 posts

Re: Kill Your Dependencies

#91
post #2

As everything, I think a bit of balance is needed. You're doing a quick MVP to demonstrate that your idea is working? Fuck it, just throw in dependencies for everything, just care about solving the problem you're trying to solve and proving/disproving your point. Once you verified it, then go and kill your dependencies. But don't do it just because you want to do it. If in the end the users doesn't benefit from you o…

That'd be good advice if those MVPs didn't so often become the actual product themselves. If industry and management understood that these things were proof of concepts, and realized that the actual product is going to have to be rewritten, then I'd agree with you.

Re: Kill Your Dependencies

#92
post #82

I find this argument sort related to the framework vs library and opinionated vs agnostic. Being an old fart Java developer I generally prefer things where you can plugin your own implementation (ie agnostic). That is there is an extreme for killing your dependencies of either extreme copy'npaste OR which every library offers a plugin SPI (ie inversion of control) (or a combo of both). The problem with the dependency…

You're probably more experienced in java development than me. But maybe a good rule of thumb is that most Java libraries shouldn't use reflection or dynamically loaded classes (i.e. using Class.forName or ClassLoader). That rules out most dependency injection frameworks.

That is correct that the libraries should not have DI but I should be able to wire up the library on my own and not let the library do its own static initialization. What is far worse than Class.forName and other crap is libraries self imposed singletons.

Take for example Hystrix. I'm just now fixing that the thing loads up its own configuration framework (Archaius) which uses static initialization. Archaius needed like 10 other dependencies. This is all really because Hystrix uses static singleton (HystrixPlugins) and many frameworks need this or else is incredibly difficult to get an implementation up (ie using pseudo singleton to avoid excessive passing of a context).

https://github.com/Netflix/Hystrix/pull/1083

Re: Kill Your Dependencies

#93
post #81
post #45

Earlier quoted context omitted.

There's an important kind of compromise that isn't discussed as often: using an external library but behind an interface of your own design, an "anti corruption layer". If the external dependency is limited to one small bridge in your application, then it's so much easier to see what parts of the dependency you actually depend on, to upgrade the dependency when its API inevitably changes, to replace it entirely if it…

The downside is that you bring in another layer of indirection and, as a result, greater cognitive load for yourself. Mycode -> facade -> library Navigating code becomes more cumbersome and stack traces longer. I do like this approach too but it isn't free.

Hah I stopped worrying about stack trace length when I started writing Scala ;)

Usually only 1 or 2 lines of the trace matter, you learn to skip the rest pretty fast.

Re: Kill Your Dependencies

#94
post #86

A large number of dependencies is only a problem in environments that aren't amenable to per-function static linking or tree-shaking. These include dynamically typed languages like Python, Ruby, and JavaScript (except when using the Google Closure Compiler in advanced mode), but also platforms like the JVM and .NET when reflection is allowed. Where static linking or tree-shaking is feasible, the run-time impact of br…

The casual link between tree-shaking-compatible-languages and accepting a large number of dependencies is not that clear. It could be that those who use large number of dependencies just prefer less dynamic languages when dependencies are very explicit and manageable.

> It could be that those who use large number of dependencies just prefer less dynamic languages when dependencies are very explicit and manageable.

Tell that to anyone using NPM.

Re: Kill Your Dependencies

#95

A large number of dependencies is only a problem in environments that aren't amenable to per-function static linking or tree-shaking. These include dynamically typed languages like Python, Ruby, and JavaScript (except when using the Google Closure Compiler in advanced mode), but also platforms like the JVM and .NET when reflection is allowed. Where static linking or tree-shaking is feasible, the run-time impact of br…

The jvm isn't really penalized because the concurrency model tends to be threads, rather than processes, so you don't pay a per-worker cost for a large library. Plus the jvm will optimize only the actually used code, including de-virtualizing.

Re: Kill Your Dependencies

#96

A large number of dependencies is only a problem in environments that aren't amenable to per-function static linking or tree-shaking. These include dynamically typed languages like Python, Ruby, and JavaScript (except when using the Google Closure Compiler in advanced mode), but also platforms like the JVM and .NET when reflection is allowed. Where static linking or tree-shaking is feasible, the run-time impact of br…

Tree shaking is helpful but not enough. It makes dependencies more fine-grained and binaries smaller by removing some false sharing. But library maintainers still have to be careful about true sharing, where a function calls another function, which in turn pulls in something big (like a lot of data stored in a constant).

You need both tree shaking and a community dedicated to keeping code small.

Javascript has the latter; it's not universally true, but lots of JavaScript libraries pride themselves on small code size and few dependencies.

That's great. But you can't stop doing that work just because you have a tree-shaking compiler. For example, there's a lot of work going into making Angular 2 apps reasonably sized and dart2js doesn't magically make it go away.

Re: Kill Your Dependencies

#97
post #57

Earlier quoted context omitted.

> Rob Pike has a lot of experience, he's seen a lot, and he knows what he's doing. So does pcwalton. Ever heard of https://www.rust-lang.org/ ?

It doesn't matter. If I were Einstein, and von Neumann disagreed with me, I would take that seriously, even though I were a super-genius etc.

I do take it seriously. I'm no super-programmer. Rob Pike is a better programmer than I am.

I just disagree with him on this one thing.

Re: Kill Your Dependencies

#98
post #84

A large number of dependencies is only a problem in environments that aren't amenable to per-function static linking or tree-shaking. These include dynamically typed languages like Python, Ruby, and JavaScript (except when using the Google Closure Compiler in advanced mode), but also platforms like the JVM and .NET when reflection is allowed. Where static linking or tree-shaking is feasible, the run-time impact of br…

Yeah, but it seems like you listed most of the platforms most people actually use, all in the X column. How do we get from 100MB Electron deployment and fat, partially used jars and dlls to this magical tree-shaking world?

You're right; most of the languages and platforms used for developing applications don't have reliable support for tree-shaking or fine-grained static linking. But there's hope for some of them.

When building Android applications, it's common to process the JVM bytecode with ProGuard before converting it to Dex bytecode. ProGuard includes a tree-shaking step. Sometimes it's necessary to tell ProGuard about specific classes or class members that it should leave alone, if they're accessed dynamically (e.g. using java.lang.reflect or Class.forName). But it's still better than nothing.

Likewise, .NET applications for the Windows Store are compiled to native code using .NET Native, and that compilation includes a tree-shaking step. This introduces some limitations on the use of reflection. I'm guessing similar limitations will apply to the native compilation option of .NET Core.

As for JavaScript, Google's Closure Compiler can do tree-shaking. But I don't know if the Closure Compiler's advanced mode works with any of the popular JavaScript libraries or frameworks, or just Google's Closure Library.

Re: Kill Your Dependencies

#99
post #86

Earlier quoted context omitted.

The casual link between tree-shaking-compatible-languages and accepting a large number of dependencies is not that clear. It could be that those who use large number of dependencies just prefer less dynamic languages when dependencies are very explicit and manageable.

Perhaps I wasn't clear. What I meant is that in environments that do support tree-shaking, you can depend on large libraries, and/or many small libraries, and the run-time impact will be no more than if you had written or copied and pasted just the functionality you need.

This could be very true, but to show the causality it is necessary that tree shaking abilities of language/tools on average precedes widespread use of huge dependency trees. It could be in reverse. That is when for some unknown reasons multiple dependencies appears, tree-shaking tools follow and it is just easier to create them for static languages.
Post reply on HN