Live data from Hacker News

Premature Abstraction

arendjr.nl

111–116 of 116 posts

Re: Premature Abstraction

#111

Premature Abstraction is a common problem, affecting developers of all ages. Most are too embarrassed to talk about it. Fortunately, there are non-invasive therapies that can reduce the frequency of occurrence.

xD

In all seriousness though, you do hit a great point. The moment you stop being embarrassed about your mistakes and set your ego aside, is the moment that you can truly start learning from those same mistakes. At some point it even becomes the only way you can move forward, unless you want to stay boxed inside a niche of expertise defined by your own self-set boundaries.

Re: Premature Abstraction

#112

I think there's plenty of good advice in this post, though the OP doesn't talk as much about the evils of premature abstraction as one might like. Still, they do talk about how to avoid it using reasonable programming guidelines. In the talk about data structures, I was reminded of Fred Brooks quote from MMM: "Show me your flowcharts, and conceal your table, and I shall continue to be mystified; show me your tables a…

Love it! Great quote and very on point.

As for Heraclitus vs. Plato, I think the lesson I’m trying to teach is to not pick a side until you understand each position’s implications and which of those might be more beneficial to the problem at hand ;)

Re: Premature Abstraction

#113
post #63

Earlier quoted context omitted.

OO code for domain modeling might be, to date, the single greatest source of disillusionment in my career. There are absolutely use cases where it works very well. GUI toolkits come to mind. But for general line-of-business domain modeling, I keep noticing two big mismatches between the OO paradigm and the problem at hand. First and foremost, allowing subtyping into your business domain model is a trap. The problem i…

I'm not a big thinker on such things, but my general rule is that subtyping is okay only for implementation details. I.e. it's okay for ConsoleLogger to be a subtype of Logger, but PaidUser probably shouldn't be a subtype of User.

So interfaces > modelling

ConsoleLogger is a Logger because they share a method (log), PaidUser and User can have some common things, but I don't think it's only in the way it behaves, but also in the way you contact/use them

Re: Premature Abstraction

#114

> /// BAD: This mutates `input`, which may be unexpected by the caller. > [...] > /// GOOD: `input` is preserved and a new object is created for the output. Neither of these are good or bad without knowing their context and understanding their tradeoffs. In particular, sometimes you want to mutate an existing object instead of duplicating it, especially if it's a big object that takes awhile to duplicate.

If you don't mutate, you don't need to duplicate.

Re: Premature Abstraction

#115
post #96

This seems more like premature indirection than abstraction. There are other design “paradigms,” such as denotational design . You start with and build from abstractions.

I used to read and write a lot of Scala and a bit of Haskell code which claims to be very similar to what I think you're mentioning here. There people also start with defining the domain in interfaces (algebras, eDSLs) and data types. In the end it's still the same indirection and abstraction as in any other Java or Go codebase, and it prevents the developer from easily accessing the actual logic of the program.

What I find difficult to understand here is that the logic of the program, in the case of a Haskell-like language, is encoded in the types.

I don’t need to look at the definition of a Monoid instance for a type (unless in rare cases it matter for some reason). I know there’s an identity element of the type and there’s a binary relation that combines elements of the type. Any type that’s a lawful Monoid works the same way.

And it goes up from there.

Denotational design is significantly different from an operational design. It’s not surprising that most programmers are taught and tend to think in terms of how computations are carried out instead of what computations are needed and the ways we can compose them. I still struggle with it at times.

I classify it separately from “indirection,” because of the laws that govern a design process like that. The same rules used in algebra work in programs where you can rely on being able to substitute terms for symbols representing those terms. And algebra seems to have been a rather successful language for manipulating expressions.

Where it does break down though is at the edges where we need to interact with run time exceptions, the state of resources external to the process, etc. Even in Haskell you can write your code procedurally if you want. You won’t get the benefits of denotational design but at least you’ll still have a pretty decent type system that helps you with refactoring and extracting “logic” later on into something more understandable and easier to work with.

Re: Premature Abstraction

#116
post #96

Earlier quoted context omitted.

I used to read and write a lot of Scala and a bit of Haskell code which claims to be very similar to what I think you're mentioning here. There people also start with defining the domain in interfaces (algebras, eDSLs) and data types. In the end it's still the same indirection and abstraction as in any other Java or Go codebase, and it prevents the developer from easily accessing the actual logic of the program.

What I find difficult to understand here is that the logic of the program, in the case of a Haskell-like language, is encoded in the types. I don’t need to look at the definition of a Monoid instance for a type (unless in rare cases it matter for some reason). I know there’s an identity element of the type and there’s a binary relation that combines elements of the type. Any type that’s a lawful Monoid works the same…

> at the edges where we need to interact with run time exceptions, the state of resources external to the process, etc. Even in Haskell you can write your code procedurally if you want. You won’t get the benefits of denotational design

I'd go further and say that effect systems, MTL etc. implement denotational design for procedural code. You can say exactly what your operations denote: a procedure that can throw exceptions only, update state only, a combination of both but not I/O, etc. etc.

Post reply on HN