Live data from Hacker News

In defense of complicated programming languages

viralinstruction.com

151–160 of 379 posts

Re: In defense of complicated programming languages

#151
post #46

I remember first encountering classes. I simply could not understand what they were from reading the documentation. Later, I picked op Bjarne's C++ book, read it, and could not figure out what classes were, either. Finally, I obtained a copy of cfront, which translated C++ to C. I typed in some class code, compiled it, and looked at the emitted C code. There was the extra double-secret hidden 'this' parameter. Ding!…

You've never seen tutorials written that way because roughly nobody but you learns programming languages from the bottom up. There is just no demand. By the way, where can I read a D tutorial from the bottom up?

Is there really no demand? Or do those of us who like to learn that way just get used to researching these things ourselves so quietly get on with it. Many of the existing tutorials are at least a good starting point to teach engineers what topics they need to examine in more detail.

Anecdotally, when I've mentored juniors engineers I've had no shortage of people ask me "why" when I've explain concepts at a high level; them preferring I start at the bottom and work my way up. So I quite believe there could be an untapped demand out there.

Re: In defense of complicated programming languages

#152

>Encapsulation, modularization, abstraction - let's not pick nits about the precise meaning of these terms, they are all about the same thing, really: Managing complexity of your own code. The thing is, code complexity can be managed superbly without the concept of a class. Golang doesn't have classes. C doesn't have classes. But both have structs and they have functions taking a pointer to, or a struct of type T. (w…

> The thing is, code complexity can be managed superbly without the concept of a class.

It can be managed by modules/namespaces, but without even that (a la C), I really don’t see it managing complexity well. The important point of OOP is the visibility modifiers, not “methods on structs”, that would provide no added value whatsoever.

What OOP allows is - as mentioned - not having to worry about the underlying details at call site. Eg, you have a class with some strict invariant that must be upheld. In case of structs you have to be careful not to manually change anything/only do it through the appropriate function. And the bad thing is that you can make sure that your modification is correct as per the implementation, but what classes allow for is that this enforced invariant will remain so even when the class is modified - while now your call site usage may not fulfill the needed constraints.

Re: In defense of complicated programming languages

#153
post #117

Earlier quoted context omitted.

How does a short learning curve necessarily correlate to a "nearly empty" toolbox? That seems like a fallacy to me. Ruby is fairly easy to learn. Does that mean it has a nearly empty toolbox? No it doesn't. A language with a GC is easier to learn than one without a GC. Does the one with a GC have less in the toolbox? What if it also allows opting out of GC? ObjC is considered a hard language to learn, esp for people…

> Ruby is fairly easy to learn No, its not. Ruby as a language is about as complex as they come. It is easy to get to a productive state though, but that is not the same thing as having learned the language. Length of learning curve and accessibility are vastly different things.

Getting productive easily is the pretty much the definition of not having a steep learning curve. So I have difficulties making sense of your argument.

Re: In defense of complicated programming languages

#154

Earlier quoted context omitted.

I don't understand. That uses algebra.

The proof is on the left, and doesn't require algebra. You can use another picture for the right part, like this https://microexcel.ru/wp-content/uploads/2020/05/kvadrat-sum... (it also uses algebraic notation which can be ignored)

Pythagorus's theorem is literally written using algebra. You can't even write it down without algebra.

Re: In defense of complicated programming languages

#155
post #152

>Encapsulation, modularization, abstraction - let's not pick nits about the precise meaning of these terms, they are all about the same thing, really: Managing complexity of your own code. The thing is, code complexity can be managed superbly without the concept of a class. Golang doesn't have classes. C doesn't have classes. But both have structs and they have functions taking a pointer to, or a struct of type T. (w…

> The thing is, code complexity can be managed superbly without the concept of a class. It can be managed by modules/namespaces, but without even that (a la C), I really don’t see it managing complexity well. The important point of OOP is the visibility modifiers, not “methods on structs”, that would provide no added value whatsoever. What OOP allows is - as mentioned - not having to worry about the underlying detail…

> The important point of OOP is the visibility modifiers,

OOP is not required for implementation hiding. It can be done entirely by convention (eg. names starting with an underscore are internal and not to be used).

Go took this a step further and simply enforces a convention at compile time: Any symbol in a package not starting with an uppercase letter, is internal and cannot be accessed by the consumer.

Re: In defense of complicated programming languages

#156

As a non-professional and in essence beginner programmer who likes to learn about programming and writes simple to moderately complicated scripts I have to say I am currently in the mindset of not needing classes. In fact the first part of the article I was like: yeah no need for classes there, a function is way simpler. Now like I say I write fairly simple scripts, I mostly automate manual processes, but even after…

A file is a class of objects you probably perform operations on with your scripting. You could instead use some kind of function instead to change, say, the entries in the disk index used to map sectors but using a class function like "rename" is just so much more understandable from the human point of view.

You asked for an example where a class is more suitable than a function. I can think of no better example than the abstract concept of files on a modern operating system. In fact it's so useful you will probably have difficulty coming up with ways to perform the same operations without using an object-oriented strategy.

Re: In defense of complicated programming languages

#157

Earlier quoted context omitted.

OO implies far far more than simply grouping data in a struct and passing it by reference.

Such as? The only other things that come to mind when I think about "OOP" are: * inheritance, which at this point even lots of proponents of OOP have stopped defending * encapsulation, which usually gets thrown out the window at some point anyway in sizeable codebases * design patterns, which usually lead to loads of boilerplate code, and often hide implementation behind abstractions that serve little purpose other t…

How is encapsulation thrown out the window in sizeable codebases?? It is the single most important thing OOP gives, and is used by the majority of all programmers and has solid empirical evidence for its usefulness.

Re: In defense of complicated programming languages

#158
post #42

Given their example about classes and "don't show the key before showing the lock", it's ironic the writer pans languages aiming to be "simpler" without understanding the kind of complexity they're actually avoiding. Zig, Go, (and Java and C# and other not as sexy and modern examples) are avoiding C++'s complexity - features with complicated interactions between each other that can sink your program without you being…

And now I see that HackerNews ate my multiplication symbols. What I meant to type is that

    unsigned short a = 0xFFFF;
    unsigned short b = a;
    unsigned short c = a * b;
Is currently undefined behaviour on platforms where int has more bits than short (like x64 and arm) due to the interaction between the integer promotion rules and undefined integer overflow.

Re: In defense of complicated programming languages

#159

A language with a short learning curve is like a toolbox that’s nearly empty. You quickly run out of ways it could help you. We should optimize for experts, because that’s where each of us is going to spend most of his career.

At the same time, a language with built-in abstractions that are not fitting the problem at hand will force its users to spend time working around the bad abstractions, which will be messier than not having the abstractions in the first place. More churn can definitely be expected in a complex language.

What do you have in mind? I think the language providing an abstraction doesn’t mean in most cases that it has to be used — if classes are not a good fit for this specific thing, just don’t use them. So that would still boil down to inexperienced developers not using proper abstractions - which can happen (with smaller blast radius) in less expressive languages as well.

Re: In defense of complicated programming languages

#160

As a non-professional and in essence beginner programmer who likes to learn about programming and writes simple to moderately complicated scripts I have to say I am currently in the mindset of not needing classes. In fact the first part of the article I was like: yeah no need for classes there, a function is way simpler. Now like I say I write fairly simple scripts, I mostly automate manual processes, but even after…

> Can someone point me to an example where a class is more suitable than a function working on an object like an associative array?

I/O or resources.

Any time you're interacting with a stateful system like an API or a database, there's inevitable setup and maintenance to keep access to that resource sound. Additionally, you rarely care how that resource is kept coherent, you just need to access it at parts of your program. Without a class or some system that keeps some bookkeeping data around with methods, every function has to have that bookkeeping state passed in as a handle, and all of a sudden all functions need to know something about how setup works, as opposed to what it does. This is a rare instance of where namespaces + globals relative to those namespaces reduce complexity; even languages like Clojure have DI "objects" for resource access, and lots of languages that have IO monads are really a data structure over some state + functions.

This setup of objects as things you can't interact with directly--aka not data--is the original one in the literature. Once upon a time you needed to interact with a device driver or a mouse or a screen or a hard drive, and logically encapsulating that device was useful. You'd then interact via "messages" dispatched to the object which are effectively what methods are these days (the term "dispatch" is still used in the literature). It also makes mocking out that physical real-world thing easier.

Notably, objects never were meant as a way to represent data. I'm one of those functional programming weirdos that likes most things to be immutable, and I have simple stateless functions in an enclosing namespace. I pass simple structs (or case classes) of data around in those functions and it works well for me. But the I/O or externally interfacing parts of my program are always in specific places in my program, and they always use dependency injection, and it's always obvious what they are. They look like a sandwich where those objects are at the edges of the program (APIs/ingress and database/egress), but the meat of the program is in the inside and is boring pure functions.

Post reply on HN