Tag Info

Hot answers tagged

58

The very first words of TC++PL4: All problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection. – David J. Wheeler (David Wheeler was my thesis advisor. The quote without the important last line is sometimes called "The first law of Computer Science.")


31

I think you have some misconceptions about the history of computing. The first abstraction (in 1936) was, in fact, Alonzo Church's Lambda Calculus, which is the foundation for the concept of high-order functions and all of the functional languages that followed. It directly inspired Lisp (the second oldest high-level programming language, created in 1959), ...


27

It seems to me that you misunderstand abstractions and code reuse. The whole software development industry is built on abstractions. Just because not using them, i.e. avoiding using frameworks, libraries and in general code which is not written in-house, would increase the cost you need to produce a piece of software by hundred, thousand, probably even ...


26

The answer to "Can you define what a programming abstraction is more or less mathematically?" is "no." Abstraction is not a mathematical concept. It would be like asking someone to explain the color of a lemon mathematically. If you want a good definition though: abstraction is the process of moving from a specific idea to a more general one. For example, ...


26

Which to listen to and how often? Never abstract until you must. In Java, for example, you must use interfaces. They're an abstraction. In Python you don't have interfaces, you have Duck Typing, and you don't need towering levels of abstraction. So you just don't. What is your strategy for this? Don't abstract until you've written it three ...


20

I categorically disagree with most of the answers. This is my answer: Given two sets G and H, a Galois connection (alpha, beta) can be defined between them, and one can be said to be a concretization of the other; reverse the connection, and one is an abstraction of the other. The functions are a concretization function and an abstraction function. ...


20

Frameworks can be tricky indeed. Problems can easily arise when a framework is too "opinionated", i.e. when it really prefers one particular style of application and all parts are geared towards supporting this particular style. For instance, if the framework completely abstracts the authentication process of a user by allowing you to just add one ...


20

Yes, definitely. The thing is, no abstraction is perfect. All of the details of the layer that abstractions sit atop are there for a reason, and it can simplify a lot of things, but if that complexity wasn't necessary at some point, it probably wouldn't be there in the first place. And that means that at some point, every abstraction is going to leak in ...


18

Ah, YAGNI. The most abused concept of programming. There's a difference between making your code generic and doing extra work. Should you spend extra time to make your code loosely coupled and easily adapted to do other things? Absolutely. Should you spend time implementing unneeded functionality? No. Should you spend time making your code work with ...


15

Good uses for wrapper functions: Hiding the complexity of a horribly complex or unsafe, low-level API, for example, the Win32 API. However, your wrapper must actually reduce complexity and/or increase safety for the common cases. Making something cross-platform when you are writing a generic library or have a good reason to believe it needs to be ...


14

Dependency Injection and DDD are two disjoint concepts. Doing Dependency Injection does not require to do DDD nor does DDD require Dependency Injection. A lot of DDD projects fail because they pick the patterns but neglect the process behind DDD. They do not take the time to extract business rules. They do not concentrate on the domain model and on careful ...


14

The keyword for thinking about these things is abstraction. Abstraction just means deliberately ignoring the details of a system so that you can think about it as a single, indivisible component when assembling a larger system out of many subsystems. It is unimaginably powerful - writing a modern application program while considering the details of memory ...


13

Sometimes a change is large enough that you have to design a migration path. Even if the start and end points are well designed, you often can't just switch cold turkey. A lot of otherwise good designers fail to design good migration paths. This is why I think every programmer should do a stint writing software for 24/7 production environments. There's ...


13

You are mistaken. You can write programs that compile directly to hardware! What you do is write a program in a hardware description language, that is then realized in a field programmable gate array. See https://en.wikipedia.org/wiki/Field-programmable_gate_array for confirmation.


12

Yes, every programmer should learn new languages, and particularly languages that uses a different programming paradigm e.g. functional programming or concurrency oriented programming. Even if you will not use the language, you will be a better programmer in the language you use by learning different concepts and see alternative solutions. There is an ...


12

It can, but likely won't lead to a problem. It's just economics. If the vast majority of people lose the ability to understand the underlying architecture, and there is still a huge NEED to understand the underlying architecture, then the ones who do will have jobs and get paid more, while those who don't will only have jobs where that is not needed (and ...


12

A shim is typically something written specifically to maintain backwards compatibility. For example, if you have two versions of an API, version 1 and version 2, then rather than maintaining version 1 independently of version 2, you might write a shim that intercepts calls to version 1 of the API, translates the parameters to what version 2 requires, and ...


12

Yes, you're right - in general Java requires a lot of ceremony for surprisingly simple situations*. The obvious advantage is that you see each step of the way to your goal, so you have more control. Network communications are done by wrapping messages inside envelopes, so you are exposed to this layering -- your library already hides many layers for you, but ...


11

Abstraction is more focus on What and less on How. Or you can say, know only the things you need to, and just trust the provider for all other services. It sometimes even hides the identity of the service provider. For example, this site provides a system for asking questions and answering them. Almost everyone here knows what are the procedures for asking, ...


11

A syllogism: Generality is expensive. You are spending other people's money. Therefore the expense of generality must be justified to the stakeholders. Ask yourself if you are really solving the more general problem in order to save the stakeholders money later on, or if you just find it an intellectual challenge to make an unnecessarily general ...


11

That means that every time I'm going to write a class that isn't a simple data structure, which is most classes, I should write an interface or abstract class first, right? Yup. Is it really worthwhile to go that far in defining abstract classes an interfaces? No, but you should err toward more interfaces than less. Can anyone explain why in ...


11

In the vast majority of languages and frameworks, the stream is an abstract concept, and methods can be designed to accept generic streams (which can be substituted for in-memory data) instead of concrete file system objects. I personally have not found much benefit to unit-testing file operations beyond that level, because there are so many things that can ...


9

I've got no problem with using high-level abstractions, with two caveats: Any abstraction that you can't get underneath when necessary is evil, because it will occasionally be necessary. Avoid these. Don't ever use any abstraction without a solid understanding of what's really going on under the hood. Not doing this will frequently cause performance ...


9

I think so. It's a trend that has me worried. No abstraction is perfect; if there was a perfect way to simplify any complex problem, it would replace the original very quickly. (That's happened in the past, occasionally with computers, and a lot more frequently in other fields that don't worry as much about backwards compatibility as we do, such as ...


9

I'd recommend you to read the Big Ball of Mud essay. Basically the point that the design tends to deteriorate as you progress with development and you have to dedicate work towards containing the complexity. The complexity itself can't be eliminated, only contained, because it's inherent in the problem you are trying to solve. This leads to the main ...


9

The point of a factory is to hide the fact that you may get objects from slightly different classes. Therefore, if some of these objects need certain data and others don't... Either they aren't similar enough to be produced by the same factory. Then you need to have more than one factory and make the decision way earlier than you are currently doing. Or ...


8

My questions are: Would passing the thrown internal exception as the previous exception be leaking the abstraction? If not, would it be suitable to simply reuse the previous exception's message? The answer is: "it depends". Specifically, it depends on the exception, and what it means. In essence, rethrowing it means you are adding that to your ...


8

I think the abstract methods are the better choice. If the implementation of these properties is not something you want the sub-classes to worry about, you may even want the base class to be responsible for it i.e. use private fields in the base class with public accessors and protected mutators: public class SuperBaseClass { private int numberOne; ...


8

Simply put, an ADT (Abstract Data Type) is more of a logical description, while a Data Structure is concrete. Think of an ADT as a picture of the data and the operations to manipulate and change it. A Data Structure is the the real, concrete thing. It can be implemented and used within an algorithm.


8

The fundamental idea in DI is simply to push dependencies into objects, rather than letting them pull dependencies from outside. This was also called "inversion of control" earlier. This allows one to control dependencies much better, and - last but not least - to write code which is easy to unit test. DI frameworks only build on top of this idea, and ...



Only top voted, non community-wiki answers of a minimum length are eligible