The Big Programming Thread - Page 927
Forum Index > General Forum |
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. | ||
TMG26
Portugal2017 Posts
| ||
sc-darkness
856 Posts
| ||
TMG26
Portugal2017 Posts
It's pros are 'easyness to understand' and 'mapping to domain' which are both full of crap. Easyness to understand is a falacy, peopele start to apply real world logic to computers which never cared about it, and don't get the realiabilty of good old math. This meme of easyness makes sure that OOP code is full of bad practices from programmers that didn't understood neither CS math concepts or the underlying hardware. And abstracting to domain is crap, you should abstract math concepts, xenturies old categories used by everyone which makes the code actually reusable, rather than looking reusable. Old full OOP languages are full of bad legacy stuff given by the necessary OOP things of the time and ignorance of math concepts. Then there is the whole 'adding OOP stuff' to languages that never needed it. I'm a bit drunk so I not gonna expand more. I dobhave more complains about it, and OOP is what I do for a living! I mainly devolep in Java and ruby, with some bash scripting for the whole CI/CD thing to work. All my hobby work is eiher in Haskell, C, Erlang and shell scripting though... Here's a nice list of quotes from relevant people: http://harmful.cat-v.org/software/OO_programming/ A warning the site is full of very extremist opinions in more than just software, something that is interesting because!it makes you think. | ||
TMG26
Portugal2017 Posts
This is apparently by Joe Armstrong, need to confirm that tough, but I'm not surprised. | ||
Excludos
Norway7969 Posts
On December 08 2017 06:49 TMG26 wrote: All things considered: object oriented programming is cancer. Stick either to procedural (closer to hardware) or functional(math reliability). WAT... It literally revolutionised how we program, making things modular, readable, fixable and expandable. Either there's a joke I'm not getting or someone has fallen off the wagon this morning. I can only ever imagine anyone not liking OO programming have never done full stack or worked on a large software made by tens to hundreds of people over several years, or is just too used to their outdated ways (Yeah, I know. OO isn't exactly a new thing, so when I say outdated I really mean it) | ||
sc-darkness
856 Posts
On December 08 2017 08:01 Excludos wrote: WAT... It literally revolutionised how we program, making things modular, readable, fixable and expandable. Either there's a joke I'm not getting or someone has fallen off the wagon this morning. I can only ever imagine anyone not liking OO programming have never done full stack or is just too used to their outdated ways (Yeah, I know. OO isn't exactly a new thing, so when I say outdated I really mean it) Yes, UI design patterns such as MVC and MVVM come to mind. Without them, it's a total mess to understand and maintain. Also, I'm not aware that you can represent data structures without OOP. At some point, even in C, you will have to refer to a struct and this is when it becomes object-oriented. Yes, C structs don't have access modifiers and stuff, but struct is still very close to OOP. | ||
TMG26
Portugal2017 Posts
Also, I'm not aware that you can represent data structures without OOP. At some point, even in C, you will have to refer to a struct and this is when it becomes object-oriented. Yes, C structs don't have access modifiers and stuff, but struct is still very close to OOP. Nope. Structs = Data representation Objects = data + how to use that data. OOP is defining by having objects only and their only interaction is by passing 'messages'. Our so called methods. That is purest OOP. Sure you can put mimic OOP in C by putting function pointers on structs, but that is forcing it. | ||
TMG26
Portugal2017 Posts
On December 08 2017 08:01 Excludos wrote: making things modular, readable, fixable and expandable. All of those existed before OOP and OOP didn't impreve any. | ||
sc-darkness
856 Posts
On December 08 2017 08:17 TMG26 wrote: Nope. Structs = Data representation Objects = data + how to use that data. OOP is defining by having objects only and their only interaction is by passing 'messages'. Our so called methods. That is purest OOP. Sure you can put mimic OOP in C by putting function pointers on structs, but that is forcing it. That's what I mean. Class is an entity which consists of state and behaviour. Struct can give you that - data and function pointers. As noted earlier, you can't have encapsulation, inheritance in non-hacky way, etc, but you're not massively away from OOP. | ||
TMG26
Portugal2017 Posts
And encapsulation wasn't started by OOP, it was just called scope and modules in other paradigms. OOP I just the bad practice of binding data and behaviour so you could try and maintain the sin of changing state. State change ia aome that should only be done for performance reason and be put away in their little corner. Only now with the comming of high concurrent services are OOP programmers starting to get why state is evil. And binding state and behavihour and hiding it under a single file is proprably archivable in any general purpose language, functunal or procedural... So I guess you can use OOP in any language. | ||
waffelz
Germany711 Posts
OOP is way too much of a proven concept to be bad in general, just like any other concept (like said procedural) which has been around for some time while also being able to deflect most criticism. It is almost as fruitless of a discussion as discussions regarding the need for certain programming languages since the person arguing against a certain language/concept/paradigm usually do so use an unreasonable or extreme example (like I hinted at with some of the bizarre discussions you can come up with in design when someone follows OOP like a religion), or one that is one that is (often specifically) not the intended use of said concept/language. Yes, OOP isn’t the “be all end all”, but I haven’t really heard anyone notable seriously state so. Responding to the link, I would also like to add that I am pretty sure no one tries to claim that OOP is easier to learn. At least to me everyone I ever dealt with admitted that OOP forces you to learn a bit more in the beginning (compared to just hacking away), but it pays off in the long run. Not saying that OOP is the only way to do so, but I feel like for any reasonable person, the concept of OOP is like a programming language: a tool to be used when it is appropriate for the task ahead. | ||
Neshapotamus
United States163 Posts
For ex: Math: x = 1 x = x + 1 ( this would be considered invalid in math) You have been trained your whole life in math classes that the above statement is incorrect, but for some reason, in an imperative setting, this is ok? This is why I say that reasoning about imperative programs is hard. I am sure you are all polyglot programmers. You should have all noticed how all imperative languages started adding functional concepts into their programming language. Some examples: C# - LINQ and lambda's, anonymous functions, anonymous classes. Java - Java 8 introduced first class syntax for functional programming. Did you also notice that hamcrest is fully functional? Or notices that the new LocalDateTime and LocalDate classes are fully functional? Did you notice that your Mock libraries are also fully functional? TMG26 - those quotes are great. I am going to start using them. | ||
bo1b
Australia12814 Posts
I have a dream of writing a video game engine in rust, with a haskell interpreter on top of it for really fast, really quick to code video games. | ||
Neshapotamus
United States163 Posts
So, I wanted to clarify that I specifically said Dependency Injection with Inversion of Control. Dependency Injection by itself is just another name for composition. You learn this Object-oriented programming 101. Why not just call it that instead of this fancy name? How does dependency injection change whether an error is compile time vs runtime errors in the slightest? Dependency Injection doesn't, but Inversion of Control does. Normally, when you are using IoC, you will normally have a container that will create and manage lifetimes of objects for you. This is when you will start having runtime errors. This can be a compile time error if object construction is made explicit at compile time. Why does it inhibit your ability to reason about your program? I would argue the opposite, that it clarifies in the intent of your program because each dependency is explicitly laid out at a single point in your class. Now, when you state that you have all your dependencies explicitly in one point is where I have a problem. It is much better to have your arguments at a function level, rather than at the scope of the class. When you give arguments to a function, you are basically scoping what you can use and cant use at that function. Hence it should be easier to reason about. Mathematically, the distance I have to travel to find the scope of variables would be a good metric of complexity. In a pure function setting, the complexity can be measured
In an object-oriented setting
I have arbitrarily chosen 0 and 1, but really, object level scope = function scope + 1 (because of the 1 level of nesting) You don't need to switch the implementation of an object to realize the benefits of dependency injection. But you can. We use it every day, because, at the highest level, different build flavours use different implementations of the same classes. At a lower level, it allows us to switch between mock, staging and production endpoints at run-time. I get this all the time, that you can pass in different implementations for testing and etc. Yes, this is true but this is what an interface is supposed to provide. The idea is not a specific to dependency injection. The whole point of an interface is to provide a set of constraints to a type. The idea of passing in the correct implementation at runtime is what people use IoC for. This is when things go bad. It is very accessible to pass in objects and not think about the design. This is an empty statement. Your code can always be misused. In fact, it's the other way around. Injecting allows you to establish an explicit contract that this feature will depend on this other feature. If you want to scope down a dependency, expose it as a separate interface, which can also be injected. This is not a baseless statement. So to give some context, I am a tech lead for large organization, with over 4000 developers. I have both inherited code and created new code. I have lead teams as large at 30 developers to as small as 2 developers. I get to see a lot of bad code. This is the biggest problem that I see; People will misuse the DI framework and inject a dependency because its easy for them to get access to something. This usually creates a bad API design. I have seen 5 layers of nested dependencies instead of thinking about the problem differently. (Usually at the domain level) These two sentences contradict each other? I'm not sure what is the point being made. There is absolutely object construction when using DI. Not sure where you get the idea that you shouldn't make objects when you have a DI framework. Someone made the statement that the "new" keyword should disappear when you use DI w/ IoC In the opposite manner, people spend too much time thinking about their code and not about how it lives in the framework of the application they are writing. Once the framework is set up, DI is invisible. Annotate and put in the constructor and be done for the majority of cases, really until you want to swap implementations, which is a feature of DI, not the core. If DI doesn't work, it's almost always that it was written with another intent in mind. Or maybe it's just wrong. Scoped DI allows you to clarify the intent of where the object lives. I guess we have different styles of thinking. You should think about the code and how you should compose functions and build a domain specific language. What I would suggest is learning functional programming paradigm. It has been an eye opener for me and might do the same for you. | ||
TMG26
Portugal2017 Posts
On December 08 2017 15:04 Neshapotamus wrote: I used to be an advocate of OOP, but have since lost that attitude after learning about different styles of programming. OOP is closely tied to imperative programming. Imperative programming is good for the reason that its the closest to hardware and makes code really fast. However, it comes at a disadvantage that the program is harder to reason about. My switch really came about after I learned functional programming in Scala. I am now an exponent of haskell, scala and basically any functional programming language. A lot of people who make arguments that OOP is great normally don't take the time to learn the new paradigm such as functional programming. It is fundamentally rooted in math. The way you apply math is fundamentally different than the way you write imperative code. For ex: Math: x = 1 x = x + 1 ( this would be considered invalid in math) You have been trained your whole life in math classes that the above statement is incorrect, but for some reason, in an imperative setting, this is ok? This is why I say that reasoning about imperative programs is hard. I am sure you are all polyglot programmers. You should have all noticed how all imperative languages started adding functional concepts into their programming language. Some examples: C# - LINQ and lambda's, anonymous functions, anonymous classes. Java - Java 8 introduced first class syntax for functional programming. Did you also notice that hamcrest is fully functional? Or notices that the new LocalDateTime and LocalDate classes are fully functional? Did you notice that your Mock libraries are also fully functional? TMG26 - those quotes are great. I am going to start using them. The tendency is keep adding functional concepts to OOP languages, but they are still tied down to retro-compatibility. That's also why I praise kotlin for just being a pragmatic new version and clean up of java instead of a completly new language. Some languages really need those clean-up, keeping adding more stuff on top of them won't solve their flaws. About java8: it did bring some functional stuff, but it's very limited. There was this discussion of Optional being a monad or not. It apparently is a Monad like haskell's Maybe. Until you use it in practice. It isn't a Monad due to the possibility of null references in it breaking the monad laws. And the possibility of things being null in java exists since day 0 and it won't go away any time. So, even with java getting more and more functional stuff, it will never get the higher order math concepts that make functional languages like Haskell great. Still, FP while being easier to reason, simple to do concurrency, there is always the problem of performance, you can optimize you haskell code all you want, you would be better off using a laguage closer to hardware like C. | ||
Manit0u
Poland17203 Posts
On December 08 2017 15:04 Neshapotamus wrote: I used to be an advocate of OOP, but have since lost that attitude after learning about different styles of programming. OOP is closely tied to imperative programming. Imperative programming is good for the reason that its the closest to hardware and makes code really fast. However, it comes at a disadvantage that the program is harder to reason about. My switch really came about after I learned functional programming in Scala. I am now an exponent of haskell, scala and basically any functional programming language. A lot of people who make arguments that OOP is great normally don't take the time to learn the new paradigm such as functional programming. It is fundamentally rooted in math. The way you apply math is fundamentally different than the way you write imperative code. For ex: Math: x = 1 x = x + 1 ( this would be considered invalid in math) You have been trained your whole life in math classes that the above statement is incorrect, but for some reason, in an imperative setting, this is ok? This is why I say that reasoning about imperative programs is hard. I am sure you are all polyglot programmers. You should have all noticed how all imperative languages started adding functional concepts into their programming language. Some examples: C# - LINQ and lambda's, anonymous functions, anonymous classes. Java - Java 8 introduced first class syntax for functional programming. Did you also notice that hamcrest is fully functional? Or notices that the new LocalDateTime and LocalDate classes are fully functional? Did you notice that your Mock libraries are also fully functional? TMG26 - those quotes are great. I am going to start using them. You know of course that in Scala everything is an object (even functions) so you're doing functional programming on objects? Can we call it functional object programming? The same goes for other languages, like Ruby. Anyway, you can do functional programming in most of the modern languages, some just make it hard (hard to chain, no anonymous functions/lambdas or really weird types). Personally, I find the concepts of FP very interesting and useful even if you can't use all of its power. It definitely helps to at least try and write your code like it would be FP. I know it helped me immensely in PHP and Ruby when I stopped mutating variables whenever I could (started using much less variables in the process). This lead to much cleaner and more robust code. Now I keep scolding our interns whenever I see them use each on enumerables (you must have a really good reason to do that if you have access to map, reduce, inject and stuff like that). | ||
Blisse
Canada3710 Posts
On December 08 2017 16:09 Neshapotamus wrote: I guess ignorance is Blisse. (sorry too ez! :p) So, I wanted to clarify that I specifically said Dependency Injection with Inversion of Control. Dependency Injection by itself is just another name for composition. You learn this Object-oriented programming 101. Why not just call it that instead of this fancy name? It's not exactly that though, because DI involves the process of abstracting the source of the dependencies, which is another layer on top of plain composition. Dependency Injection doesn't, but Inversion of Control does. Normally, when you are using IoC, you will normally have a container that will create and manage lifetimes of objects for you. This is when you will start having runtime errors. This can be a compile time error if object construction is made explicit at compile time. I'm still not seeing this. Do you have an example in mind? If I'm understanding correctly, I don't think swapping implementations at runtime is a feature of DI or IoC or together, but I also can't see how this could be solved by object construction at compile time. Now, when you state that you have all your dependencies explicitly in one point is where I have a problem. It is much better to have your arguments at a function level, rather than at the scope of the class. When you give arguments to a function, you are basically scoping what you can use and cant use at that function. Hence it should be easier to reason about. Mathematically, the distance I have to travel to find the scope of variables would be a good metric of complexity. In a pure function setting, the complexity can be measured
In an object-oriented setting
I have arbitrarily chosen 0 and 1, but really, object level scope = function scope + 1 (because of the 1 level of nesting) I think here I feel there's a specific difference between object dependency and functional dependency. An object dependency tells you about the existence of a relationship between these objects, and given how we treat objects as domain models, lets you easily say, my AccountManager depends on my AccountService, LocalStorage, etc., which is very clear, IMO, regardless of lines used. And then we can consider the usages of the service function calls. And really, I find you never really care about the original object after it's been injected. The naming of the object and method call usually implicitly gives you a lot of knowledge about it, and you end up searching for the method docs or impl if necessary anyways. I get this all the time, that you can pass in different implementations for testing and etc. Yes, this is true but this is what an interface is supposed to provide. The idea is not a specific to dependency injection. The whole point of an interface is to provide a set of constraints to a type. The idea of passing in the correct implementation at runtime is what people use IoC for. This is when things go bad. It is very accessible to pass in objects and not think about the design. Given that DI is just one example of IoC, I feel the two here are pretty much intertwined. A non-DI approach with IoC here relies on the user explicitly coupling the new object with a dependency. With DI, this coupling is specified at a high level at certain focal points. This is not a baseless statement. So to give some context, I am a tech lead for large organization, with over 4000 developers. I have both inherited code and created new code. I have lead teams as large at 30 developers to as small as 2 developers. I get to see a lot of bad code. This is the biggest problem that I see; People will misuse the DI framework and inject a dependency because its easy for them to get access to something. This usually creates a bad API design. I have seen 5 layers of nested dependencies instead of thinking about the problem differently. (Usually at the domain level) I work with the people who wrote a pretty important DI framework. So maybe I'm a bit biased :p I don't think we have the idea of leads at our company, but maybe 500-1000 devs? Not all of them on the same product though. I see it both ways, people can misuse the framework, and I can't really decide whether it's developer apathy, high barrier to entry, framework complexity, or really just poor documentation and communication. Those fit on the misuse scale in different ways. I've never really personally found the dependency and design problem difficult, but I do end up cleaning up code that's been unnecessarily blown up. But that's usually when the documentation, or existing usages of DI, isn't clear. I also don't see a problem with injecting dependencies everywhere, because in my experience, you can have smart developers who understand how to compose APIs in a clear manner, or you can restrict injection and only expose APIs downstream that you clearly specify. Our immediate codebase is only maintained by 50 people though, so I can imagine it could get out of hand quickly, but then I usually think back on poor documentation and communication. Someone made the statement that the "new" keyword should disappear when you use DI w/ IoC Yeah, I disagree with what that guy said. A better way would be, DI involves not explicitly constructing objects (via new or factory-likes), and seeing it seems problematic in a DI world. I guess we have different styles of thinking. You should think about the code and how you should compose functions and build a domain specific language. What I would suggest is learning functional programming paradigm. It has been an eye opener for me and might do the same for you. I actually started with FP, thanks. Started on Scheme for way too long, then through all the C's C, C++, C#, and now Java. Some Go during the middle of that. I still like the OO languages more. FP is neatly expressive but not anymore so than I care about, as I'm more focused on clarity and intention and organization, which is where I feel the plain C-like-langs excel in. I do think that languages should converge towards a OOP/FP hybrid though, like Java and Kotlin are turning towards, as you get to realize more of both advantages. | ||
Deleted User 3420
24492 Posts
I have an adjacency list of tuples. So, an outter list, and each element of that list is a list of tuples. I want to sort the primary (outter list) by the following criteria. For each inner list we have the first two tuples as (a,b),(c,d). b and d are integers. I want to take the difference of those two integers. I then want to sort the primary list by those differences. example: if I had an adjacency list AL, where AL[0] was a list that started with ("fun",5),("stuff",8) and AL[574] started with ("crabs",9),("water",10) then the sorting would place AL[574] before AL[0], because AL[574] has a difference of only 1, and AL[0] has a difference of 3. I know that I could literally write my own sorting algorithm, but I am wondering if anyone knows how to use sorted well enough to tell me how to use key= to do this kind of thing, so that I can just feed it the differences and let it use it's quicksort or whatever. edit: nevermind, figured it out like 5 minutes later. if anyone wants to know how you do it, it's like this:
| ||
Manit0u
Poland17203 Posts
On December 08 2017 07:54 TMG26 wrote: Everything. Trying to hide both hardware and math under the desguise of 'domain'. Hiding file globals under the desguise of instace variables. Promises of reusabile that were never kept. Idiot ways of handling state. It's pros are 'easyness to understand' and 'mapping to domain' which are both full of crap. Easyness to understand is a falacy, peopele start to apply real world logic to computers which never cared about it, and don't get the realiabilty of good old math. This meme of easyness makes sure that OOP code is full of bad practices from programmers that didn't understood neither CS math concepts or the underlying hardware. And abstracting to domain is crap, you should abstract math concepts, xenturies old categories used by everyone which makes the code actually reusable, rather than looking reusable. Old full OOP languages are full of bad legacy stuff given by the necessary OOP things of the time and ignorance of math concepts. Then there is the whole 'adding OOP stuff' to languages that never needed it. I'm a bit drunk so I not gonna expand more. I dobhave more complains about it, and OOP is what I do for a living! I mainly devolep in Java and ruby, with some bash scripting for the whole CI/CD thing to work. All my hobby work is eiher in Haskell, C, Erlang and shell scripting though... Here's a nice list of quotes from relevant people: http://harmful.cat-v.org/software/OO_programming/ A warning the site is full of very extremist opinions in more than just software, something that is interesting because!it makes you think. What you forgot to mention is that most software is created to be used by people and that's where OOP really shines. Procedural programming is mostly used for system level programming (people hardly interact with kernel drivers directly) and functional programming is used for highly theoretical academic stuff (math proofs) and multi-threaded/asynchronous systems (telecoms come to mind). The vast majority of software that is being built though are applications that require user interaction (games, websites, ERP systems etc.) and those benefit greatly from this "dreadful domain approach". Sure, you probably could do it "the proper way" (like people who are trying to build website frameworks in Haskell, LOL), but you must realize that the demand for such software is so high that there's constantly a shortage of developers. If you were to raise the barrier of entry to people who have at least PhD in maths and are fluent in functional programming then nothing would get done. It's a compromise, you get less reliable systems but can build them much easier and faster (and worry about making them reliable later down the line) because what's the most important in programming is actually getting shit done, not making sure that it's "pure" or "proper". | ||
sc-darkness
856 Posts
On December 09 2017 05:36 Manit0u wrote: What you forgot to mention is that most software is created to be used by people and that's where OOP really shines. Procedural programming is mostly used for system level programming (people hardly interact with kernel drivers directly) and functional programming is used for highly theoretical academic stuff (math proofs) and multi-threaded/asynchronous systems (telecoms come to mind). The vast majority of software that is being built though are applications that require user interaction (games, websites, ERP systems etc.) and those benefit greatly from this "dreadful domain approach". Sure, you probably could do it "the proper way" (like people who are trying to build website frameworks in Haskell, LOL), but you must realize that the demand for such software is so high that there's constantly a shortage of developers. If you were to raise the barrier of entry to people who have at least PhD in maths and are fluent in functional programming then nothing would get done. It's a compromise, you get less reliable systems but can build them much easier and faster (and worry about making them reliable later down the line) because what's the most important in programming is actually getting shit done, not making sure that it's "pure" or "proper". Weren't you against OOP in the past? Have you changed your mind? | ||
| ||