6 ms·
No you're very wrong. >No, one kind of technical debt arises that way. Not the only kind. There's another kind that arises when everything is in such small pie
by lerptime 6y ago
No you're very wrong.
>No, one kind of technical debt arises that way. Not the only kind. There's another kind that arises when everything is in such small pieces that nobody can tell how the pieces relate to each other. You can easily understand each piece, but you have to go through a chain of a bazillion function calls to see what's actually going on.
All this logic must exist regardless of whether it's coupled or uncoupled. You do not alleviate the logical burden by coupling logic together or uncoupling the logic. If you call this "technical debt" then you cannot get rid of it. Why even call it debt then as logic is intrinsic to application.
In fact decoupling logic can improve readability as it marks each piece of logic with a contextual function name. Either way you do not alleviate complexity by coupling logic. You alleviate this complexity problem by providing logical layers, using namespaces, and using good function naming.
Coupling logic into Objects does nothing objectively as it does not eliminate complexity it only makes sure that the complexity is LESS modular.
Let's be clear though. I am saying that the lower levels of your application should be ALL uncoupled logic. Then you build logical layers on top of your primitives that consists of compositions of your logic that build higher and higher. So a person on layer 5 only needs to go to layer 4 to understand it, and does not need to go to layer 1 to understand every primitive.
>This is like economists, who have correctly predicted nine of the last two recessions. Sure, you're prepared for when the change comes (if you can find where to make it - see above). You've also prepared for all the changes that never come. That's rather wasteful.
Analogies don't offer proof of an argument. Additionally it's not a good analogy. Economists don't completely understand what causes recessions and how to prevent them. We do, however, completely understand the difference between uncoupled logic and coupled logic.
>Sure, it may. And when that happens, we'll decouple it. And in the meantime, we'll enjoy the coupling that, at the moment, is the correct thing.
This is the main point of tech debt. It is hard to decouple. You can have all logic decoupled at the lowest layer and still have everything be readable. I think the previous sentence is just a type of programming you haven't dealt with. You've never wrote a program with decoupled logic that was readable. Think deeper. There is no reason why coupled logic should be more readable then decoupled logic. The Logic still exists either way, you either compose two modules and give it a name or you don't even use modules shove all your logic into a module with a single name.
>See, this is all in the context of SOLID, the very first piece of which is "Single Responsibility". We don't couple things on a whim.
The problem is OOP does this all the time. It couples state with logic. These two things should be uncoupled.
- to11mtm 6y ago> Let's be clear though. I am saying that the lower levels of your application should be ALL uncoupled logic. Then you build logical layers on top of your primitives that consists of compositions of your logic that build higher and higher. So a person on layer 5 only needs to go to layer 4 to understand it, and does not need to go to layer 1 to understand every primitive. Yep. If you do this right you only need to understand one or two layers at a time. Great example of this is the Akka Toolkits for JVM and .NET; Every time I've hacked on a given subsection, the amount of domain knowledge I've had to have was 'Basics anyone using Akka has to know' and then just the layer I was working with and maybe one other. > The problem is OOP does this all the time. It couples state with logic. These two things should be uncoupled. Agreed. And dare I say, when you start going from coupled state+logic, and go more towards functional... you'll find you can possibly shed a layer or two in your overall design.
- AnimalMuppet 6y agoYou seem to think that FP is the one right answer. You are mistaken. There are places where it's the right answer, or at least a very good one - the best definition I've seen is when your program looks like a pipe. And there are places where FP is the wrong answer - where your program has state, and there are multiple parts to the state, and those parts have to be kept in sync with each other. At that point, bundling the data to the functions is warranted, because it limits the number of functions that can put the data in an inconsistent state. And if you're going to say "don't structure the data that way", well, there are times when that's the nature of the problem, not just the nature of the program to solve the problem.
- nendroid 6y ago>You seem to think that FP is the one right answer. You are mistaken. There are places where it's the right answer, or at least a very good one - the best definition I've seen is when your program looks like a pipe. All programs are pipes from IO to IO or from one state to another state. Purity lives in the pipes, impurity lives in the IO nodes between the pipes. The goal is to keep the impurity as small as possible and have most of your logic live in the pipe, as combinators are the most composeable primitive. I also never said FP is the one right answer. Most programs need to modify state. In FP everything is immutable so your program cannot be pure FP in most cases. What I am saying is to segregate state and IO from logic. Example: void addOneToState() can be broken down into int addNTo(int n, int m) void changeStateTo(int x) I have split the code above into a method that is devoid of logic and only updates state and logic that lives as a stateless combinator. All programs are made from a series of pipes and tubes. You just need to find the pipe and modularize it and seperate it from the parts that can't be pipes. >At that point, bundling the data to the functions is warranted. It's never warranted. There is no benefit. Whether you couple it or uncouple it from data the logic still exists, the only difference is coupling. Adding coupling does not improve your code in any other way other than adding coupling. >And if you're going to say "don't structure the data that way", well, there are times when that's the nature of the problem, not just the nature of the program to solve the problem. There is no data structure that has to be coupled with logic. However you structure your data it can always be decoupled from logic. Always. >where your program has state, and there are multiple parts to the state, and those parts have to be kept in sync with each other. This doesn't change anything. State makeNewState (State oldState) { newY = addNTo(oldState.y, 1) return New State { x = oldState.x y = newY somethingToBeInSyncTo = newY } } void updateState(State x) y is still in sync with somethingToBeInSyncTo.