9 ms·
Interfaces all the way down
- RyanAdamas 3y agoHave we reached adaptive interfaces yet? The kind that mold to the users preference based on the setup of other interfaces they us? Would be nice to have one interface to rule them all, tailored for everyone.
- beezlewax 3y agoThis sounds awful
- RyanAdamas 3y agoYou must design interfaces.
- eduction 3y ago>Great product designs require no manual, and similarly, great interfaces need no documentation. Imagine having to read a manual on how to use a coffee mug. This could not be more wrong. Not everything is easy. If a library is addressing a complicated domain, solving by definition a complicated problem, it is fine if it requires some learning. When did expertise and learning become bad things? If software is an engineering discipline, why would people in it ever promulgate the idea that any random cog can step in to any “engineer”s shoes? Rich Hickey analogizes this mentality to the world of music, where it taken for granted that learning an instrument requires a lot of study: “ We start with the cello. Should we make cellos that auto tune? Like, no matter where you put your finger, it's just going to play something good, play a good note. “[Audience laughter] “Like, you're good. We'll just fix that. “ Should we have cellos with, like, red and green lights? Like, if you're playing the wrong note, you know, it's red. You slide around, and it's green. You're like, great! I'm good. I'm playing the right song. Right? “ Or maybe we should have cellos that don't make any sound at all. Until you get it right, there's nothing. “ [Audience laughter]” https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/DesignCompositionPerformance.md https://github.com/matthiasn/talk-transcripts/blob/master/Hi... If something can be made easier without undermining its integrity, great. Not everything can be made as easy as drinking from a cup, something most 3 year olds can handle. If you think hitting dot in your IDE and choosing among the options is as much as you should be required to learn, you are asking to use NERF toys instead of power tools. Sometimes you need to read things, welcome to adulthood.
- 88913527 3y agoOpining that "everything should be simple" is a sign of having been in the management class for too long and not being in the weeds.
- morelisp 3y agoMost people would do well to learn more than they have, but also most things could be a lot simpler than they are. Honestly, the best way to achieve the latter is probably to encourage the former. (Which will never happen as long as companies prefer to hire N interchangable people than M well-trained people, even with M ≪ N.)
- aiisjustanif 3y agoJust to note simple does not mean less complicated [1], easy is an enemy more often. [1]: https://youtu.be/LKtk3HCgTa8 https://youtu.be/LKtk3HCgTa8
- jimmaswell 3y ago> If you think hitting dot in your IDE and choosing among the options is as much as you should be required to learn, you are asking to use NERF toys instead of power tools. It depends. It's really great when that does work out. It's traditionally my first step (copilot frequently beats me to the correct use of an unfamiliar API today), second step being the documentation if that's not enough. Step 1 is almost always sufficient.
- yowlingcat 3y agoI get where Rich Hickey is coming from, but his analogy does have gaps. Not every piece of music is for a cello, and in fact, much of it is for discretized and not continuously pitched instruments such as pianos and guitars, which also take out the variable of bowing. The innovation of discrete pitch was practical -- for many songwriters, the point is to get out the song and not focus on "implementation details" -- and I think there are a lot of similarities there to software.
- khaledh 3y agoA good interface guides the user to doing the right thing. To quote Brad Adams (who borrowed it from Rico Mariani)[1]: Rico called this the Pit of Success. That concept really resonated with me. More generalized, it is the key point of good API design. We should build APIs that steer and point developers in the right direction. Types should be defined with a clear contact that communicates effectively how they are to be used (and how not to). This concept is also tied closely with the concept of "making illegal states unrepresntable," popularized by Yaron Minsky[2]. For example, a document workflow system might naively model Document as a single entity that has all possible fields for all possible states. This could result in the need to raise exceptions (or return error codes) when the Document state is invalid, e.g. you can't approve a draft document until it's submitted. A better API models each state separately (e.g. using a union type, if your language supports it); so you'd have `DraftDocument`, `SubmittedDocument`, `ApprovedDocument`, `RejectedDocument`, where only `DraftDocument` would offer a `submit` method, and `SubmittedDocument` offer a `approve` and `reject` methods, returning an `ApprovedDocument` or `RejectedDocument`, respectively. [1] https://learn.microsoft.com/en-gb/archive/blogs/brada/the-pit-of-success https://learn.microsoft.com/en-gb/archive/blogs/brada/the-pi... [2] https://blog.janestreet.com/effective-ml-revisited/ https://blog.janestreet.com/effective-ml-revisited/
- moonchrome 3y agoAnd what happens when you have orthogonal traits ? You have to implement a matrix of all valid permutations ? Sounds like "you should wear a straightjacket because you might fall down when running with scissors" kind of a solution.
- greiskul 3y agoThen you do something else. Engineering is a matter of tradeoffs. There is no silver bullet, we don't throw off an approach because it doesn't solve everything.
- Supermancho 3y ago> You have to implement a matrix of all valid permutations ? I think the example was pretty bad, however the union type being referenced is that matrix, afaik. Let's start with a different example. I have a business process that runs off a plan-document. The plan-document includes things like caps for number of times things can happen over a period (including, all-time), or day parting specifying when things can happen at all (only saturdays), and absolute controls like "active" or "inactive", on top of the creation/deletion paradigm. When the process runs, what is the state of the business process at any given time? "inactive because capped out" or "inactive because day parting"? This set of labels will grow, in permutations, over time as well as discoverable business needs. eg Was it "inactive" because it was created that way or someone manually deactivated it with an update? Now the program needs to reference a history of changes as well as referencing run-state. A business that is building a new product, especially within a domain that few people understand, requires more than building a set of states and assume they will always meet the needs. This is a recipe for lots of large-scale rework and bugs. A set of states (be it a bitfield or json blob or whatever) fed into a rules engine (or component) will likely be more extensible over time than looking at simple labels. Granted, this is predicated on the software being a non-trivial system.
- seeknotfind 3y agoYou never come up with the right interface at first because there is no right interfaces. There are better interfaces, but you usually need to encounter more situations to find it. Balancing up front time designing an interface with velocity to test it is a principle problem of software development.
- samstave 3y ago>You never come up with the right interface at first because there is no right interfaces. There are better interfaces, but you usually need to encounter more situations to find it. Balancing up front time designing an interface with velocity to test it is a principle problem of software development. You never come up with the right medicine at first because there is no right medicine. There are better medicines, but you usually need to encounter more outcomes to find it. Balancing up front time designing a medicine with velocity to test it is a principle problem of medicine development. Thank you for your template
- sanderjd 3y agoI think good software interfaces are essentially always extracted from already-working systems, rather than being designed. The tricky part is figuring out when to do that and how to successfully advocate for it.
- lpapez 3y agoAgree with this. Starting with a "well-designed set of interfaces" usually results in half of them being unused having only one implementation and the other half being rewritten because the requirements changed (worst offenders are interfaces which only have one implementation, not even used for mocks in tests, the runner-up being interfaces accepting multiple boolean parameters). On the other hand, finding an opportunity to introduce a common interface to a familiar codebase feels like leaving behind a mental burden. Sounds crazy I know, but introducing order into a chaotic mess is just relaxing to me, especially when I know I will have to maintain it.
- jinay 3y agoI agree that there is no absolute best interface, and a good interface will be battle-tested and motivated by real problems. As with all design, there are certain intuitions you develop over time that are widely applicable. You can eliminate a lot of errors up front that way.
- bombela 3y agoIn my experience, applying the same mindset and efforts to interfaces for which the principal user is not a developer also yield similar benefits. Good interfaces are retroactively obvious. Not like my modern microwave.
- kevmo314 3y ago> His advice contradicted my idea that a great senior dev should learn better communication or management. What are interfaces if not ways to communicate?
- klysm 3y agoalso they aren't mutually exclusive lol
- sanderjd 3y agoNailed it right here. Lots of people don't think of it this way though :)
- ak217 3y agoYes, and not just that. A lot of management boils down to aligning teams' responsibilities with their interfaces, and committing the teams to a baseline of usability of their interfaces. See also Stevey's Platforms Rant (https://gist.github.com/chitchcock/1281611 https://gist.github.com/chitchcock/1281611)
- bombela 3y agoIndeed. A way to communicate, reduce mistakes, all the while; hopefully; without restricting the task at hand. Basically, the opposite of a modern microwave.
- jinay 3y agoSounds like you've got a personal vendetta against modern microwaves.
- bombela 3y agoI have a personal vendetta against almost all modern UIs, coffee machine and printers included, like the sibling comment joked about. The lag on key/touch presses. The stupid and overcomplication of the controls. The simple made difficult. The hard made impossible.
- 3y ago
- 63 3y agoIt took me until the last 3 paragraphs to realize they meant ux and not Java interfaces. Maybe I've been writing too much Java recently but I feel like it could be clearer.
- EGreg 3y agoI should also point out that comments are a code smell. The vast majority of the time you feel the need to add a comment, you should probably refactor your code into a well-named function — whether a closure or a method. Your code should read well even without comments! (There are some exceptions, that have to do with notes eg for security implications, or optimization techniques, or side effects. And also to document parameters in duck-typed languages. But even those should be put into structured comments, like DocBlock or YUIdoc or whatever kids use these days.) I have learned this with time. Like when you are procrastinating and putting off doing something, that’s a sign you need to attract partners.
- bartwr 3y agoWhat a terrible advice (sorry). Great comments are not about "what does this code do?". They are about "why does it do it?". In some domains like scientific or high performance computing they are absolutely necessary to a) provide context to others b) make you not forget c) prevent unintended consequences and regressions. You reorder some operations or do seemingly weird things for improved performance, numerical stability, or address some not easily testable bug? If you don't comment it, this knowledge will be lost and someone might obliterate it during a refactor.
- gonzo41 3y ago---I should also point out that comments are a code smell. I would encourage you to ponder this a little more. I work on scientific code bases and there's just some processes and math that requires line by line exposition beyond what the code can offer. There's also nothing worse than digging into a library to view the code and just being left with a ton of small classes and no notes on how it's all meant to interact. Comments here and there are helpful.
- garethrowlands 3y agoThe book the post mentions, A philosophy of Software Design, has a lot to say about having lots of small classes. It’s not in favour. That book is also strongly in favour of comments, lots of them. This book is well worth reading.
- krm01 3y agoI wrote an ebook [1] about interface design for engineers after seeing time and time again that the best interfaces I worked on all came about when engineers and designers both contributed to the process. [1] https://uidesignforengineers.com/ https://uidesignforengineers.com/
- deleted 3y ago[deleted]
- cpeterso 3y agoOne of my favorite relevant quotes, whether you’re talking about code or user interfaces: The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise. — Edsger Dijkstra
- moth-fuzz 3y agoI agree that interface is key to not just software design, but design in general. Designing parts in isolation, you can do pretty much whatever you want. But people being able to gracefully handle where and when two parts collide is what makes the software world go round. One of my favorite bits on interfaces is this Rust Koan[0], which has a funny twist of pragmatism at the end. It's a shame too many developers think this huge idea is just the interface keyword, or OOP, or even just the `object.method()` syntax. I hear dot-autocomplete come up in conversation almost every day now. When I was in college people asked me "How can you even use C? It doesn't even have classes...?", the implication being you couldn't encapsulate your code at all, and I get the same shrinking feeling when people talk about dot-autocomplete as if it's synonymous with interface discoverability. But it's really just one particular implementation (heh) of a much broader and more abstract (heh) idea. It's like calling all tissues Kleenex or all sodas Coke. 0. https://users.rust-lang.org/t/rust-koans/2408/3 https://users.rust-lang.org/t/rust-koans/2408/3
- travisjungroth 3y agoDot autocomplete is only one option, but I’ve never seen anything work as well for discoverability. Just talking about it in terms of functions, you usually have at least one argument. Then you’re trying to find the right functions and remaining arguments. Single dispatch and the dot syntax support this very well! I’ve never seen it, but maybe you could do the same thing with functions. Just put in the first arg, maybe more, and then the function name.
- Tokumei-no-hito 3y agoI’m not sure in C but in Python and JS the encapsulation can be at the module level rather than using a class. So you still get dot hunting by importing the module.
- 3cats-in-a-coat 3y agoI love citing this one (from https://spacecraft.ssl.umd.edu/akins_laws.html https://spacecraft.ssl.umd.edu/akins_laws.html): > 15. (Shea's Law) The ability to improve a design occurs primarily at the interfaces. This is also the prime location for screwing it up. While this is about hardware interfaces, software interface fulfill the same exact role, and the same exact principle applies. The design is in the interface. The implementation is just grinding until it's done, because the decision of how something will be implemented are already determined by the interfaces and the information we have on the infrastructure we'll be doing the implementation in.
- mkoubaa 3y agoI would add that interface design is so hard you have to assume you will get it wrong, and think about adaptability as a design goal.
- kmoser 3y ago> Great product designs require no manual, and similarly, great interfaces need no documentation. Imagine having to read a manual on how to use a coffee mug. It's a fallacy to assume a perfect interface needs no documentation, just as it's a fallacy to assume perfect code needs no comments. Most interfaces are far more complex than a coffee mug. In reality, the more complex something is, the more documentation is needed to describe how it works, how to use it, how not to use it, and why it works that way.
- sanderjd 3y agoYes and no to this, IMO. I think the best interfaces have a "happy path" simple usage that doesn't require documentation to intuit one's way through without any dangerous footguns but also doesn't do very much, and then an arbitrarily deep path into more powerful use cases requiring more detailed documentation.
- tosihakkeri 3y agoMaybe not just designing the interfaces but their boundaries?