> In video game design there is a saying: Show locked doors before you show a key This is something I've tried putting into words many times. I'll try to solve a problem and get to know its challenges deeply. Then a tool is introduced that brings it all together. In these cases, I seem to quickly get a full grasp of the operation and essence of the tool. I wish education was based around this principle. A bit like wh…
In defense of complicated programming languages
231–240 of 379 posts
Re: In defense of complicated programming languages
#232> In video game design there is a saying: Show locked doors before you show a key This is something I've tried putting into words many times. I'll try to solve a problem and get to know its challenges deeply. Then a tool is introduced that brings it all together. In these cases, I seem to quickly get a full grasp of the operation and essence of the tool. I wish education was based around this principle. A bit like wh…
I totally agree there and I think it's due to the fact that you've got a mental model of the problem space and your brain can see the empty hole. Once you have a tool of that shape, your brain knows where it goes and how it solves your problem.
Re: In defense of complicated programming languages
#233Earlier quoted context omitted.
That's not very convincing. Why can't a "dog" be a perfectly ordinary data structure that you manipulate the usual way? while True: for dog in dogs: if dog["hungry"] == True: dog["lastfed"] = time() dog["hungry"] = False Okay, I hear you say, but the fact that a dog is an associative array is an implementation detail. Supposing I want to abstract that - don't I need objects then? No! Just define some functions: while…
If you don't have any imagination and you treat dogs as database entries then yes you might do just that. If you are only person writing it and using that code, the same. You did not address interaction between dogs. Some other idea, how do you pass dogs to a playpen, how would they interact - maybe you want different playpens where you can send your dogs into, some playpens having food, some not having a food, diffe…
All that objects are, are functions glued to data. That's it. Whether or not you choose to glue them together, the behavior of the dog lies in the functions, and the state of the dog lies in the data. Frankly, your examples seem to lead away from objects - how will another developer add the ability to heal dogs, for instance? They can't change the class definition, so they'll have to do something awful like subclass it into HealableDog(), which doesn't interoperate with all the existing dog code at all. Meanwhile, if 'dog' is simply a big ol' struct of data, they can write a function heal(dog) and call it a day.
I highly recommend the first part of this video, which explains the composability problems with objects very well - with dogs and cats even! https://www.youtube.com/watch?v=kc9HwsxE1OY
Re: In defense of complicated programming languages
#234A 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.
Is it possible to optimize too much for experts, and sacrifice learning curve too much?
Here's something like the tenth or fifteenth chunk of code I wrote in J. It solves a programming puzzle. I doubt people who have mastered J would call it well-written, but it solves the problem.
list=:_9]\33 30 10 _6 18 _7 _11 23 _6 16 _19 9 _26 _8 _19 _8 _21 _14 17 12 _14 31 _30 13 _13 19 16 _6 _11 1 17 _12 _4 _7 14 _21 18 _31 34 _22 17 _19 20 24 6 33 _18 17 _15 31 _5 3 27 _3 _18 _20 _18 31 6 4 _2 _12 24 27 14 4 _29 _3 5 _29 8 _12 _15 _7 _23 23 _9 _8 6 8 _12 33 _23 _19 _4 _8 _7 11 _12 31 _20 19 _15 _30 11 32 7 14 _5 _23 18 _32 _2 _31 _7 8 24 16 32 _4 _10 _14 _6 _1 0 23 23 25 0 _23 22 12 28 _27 15 4 _30 _13 _16 _3 _3 _32 _3 27 _31 22 1 26 4 _2 _13 26 17 14 _9 _18 3 _20 _27 _32 _11 27 13 _17 33 _7 19 _32 13 _31 _2 _24 _31 27 _31 _29 15 2 29 _15 33 _18 _23 15 28 0 30 _4 12 _32 _3 34 27 _25 _18 26 1 34 26 _21 _31 _10 _13 _30 _17 _12 _26 31 23 _31 _19 21 _17 _10 2 _23 23 _3 6 0 _3 _32 0 _10 _25 14 _19 9 14 _27 20 15 _5 _27 18 11 _6 24 7 _17 26 20 _31 _25 _25 4 _16 30 33 23 _4 _4 23
sumOfRows =: ([: +/"1 [: |: ] \* [: |: _1 + 2 \* [: #: [: i. 2 ^ #)"1 list
rowSigns =: (;/@:,/@:>)"2 {|:(_1;_1 1;1) {~ (_1&rowSigns))
theAnswers =: (] #~ [: (0&
In case anyone wants an explanation: https://gcanyon.wordpress.com/2009/10/30/a-solution-to-einav...Re: In defense of complicated programming languages
#235Earlier quoted context omitted.
I also have a hard time with learning concepts too if there are handwavey parts of it. I remember by recreating the higher level concepts from lower level ones at times.
To me, the abstraction is an oversimplification of actual, physical, systemic processes. Show me the processes, and it's obvious what problem the abstraction solves. Show me only the abstraction, and you might as well have taught me a secret language you yourself invented to talk to an imaginary friend.
You're more comfortable with a certain level of abstraction that's different from others. I can't endorse others that try to criticize your way of understanding the world, but I'd also prefer if some people who in this thread subscribe to this "bottom up" approach had a bit more humility.
Re: In defense of complicated programming languages
#236Earlier quoted context omitted.
I agree that everyone shouldn't need to know every implementation detail, but I'd argue there should be more emphasis on the low-level details in CS education. Programming is often approached from a purely abstract point of view, almost a branch of theoretical mathematics, but imho in 99% of cases it's better understood as the concrete task of programming a CPU to manipulate memory and hardware. That framing forces y…
I think that's the difference between computer science and programming. Yes, you'll be a better programmer if you focus on the low-level details, but you'll be a worse computer scientist. I guess, if your goal is to write optimizations, focus on details. If your goal is to find solutions or think creatively, focus on abstractions. Obviously, there’s a lot of overlap, but I’m not sure how else to describe it.
I tend to think focusing on abstractions is almost always the wrong approach. Abstractions should arise naturally as a solution to certain problems, like excess repetition, but you should almost always start as concrete as possible.
Re: In defense of complicated programming languages
#237As 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…
You have probably noticed in your "fairly simple scripts" that your language has some notion of types. Your variables are one type or another type, in some languages they can change type and in others they mustn't, but likely the language has the notion that, for example, while dividing 9 by 3 is a reasonable thing to do, dividing your array of business departments by the name of a CSV file is not.
Now, these types aren't like the elements (whether classical or chemical) they were chosen by the language authors. There are probably a handful of obvious ones, probably strings like "Clown" and numbers like 19.03 are different types, your dictionary isn't a number, and if your scripts are allowed to access files probably a file "Handle" or equivalent isn't the same kind of thing as a dictionary.
So, in this sense a class is merely a type that you can define in your program.
This has any number of useful properties, for example suppose you deal with a lot of Social Security Numbers, if you had an SSN class it'd be clearer that, while SSNs might well be "numbers" in some sense, you can't go around summing them up, any place that seems to be happening is a bug waiting to happen, as a class there's no reason it should be possible to do arithmetic on SSNs. Your chosen language might provide easy ways to say e.g. "This dictionary is for numbers, don't put anything else in it" and chances are if that's available you can likewise say "Only for SSNs" and now there's no risk you accidentally got the total number of people processed as a Social Security Number.
Does that justify classes as an idea to you?
The specific word "class" is associated with a particular approach to programming called Object Oriented Programming, which is much less popular today than it was at the end of last century, but this general idea of being able to make types for your application is more general.
Re: In defense of complicated programming languages
#238Earlier quoted context omitted.
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.
Rust here says OK, we'll define Mul (the * operator) for the same type (and for references to that type) so let a: u16 = 0xFFFF; let b: u16 = a; let c: u16 = a * b; ... is going to overflow, Rust would actually detect that because 0xFFFF is a constant, so, this says "Silently do overflowing arithmetic" and er, no, it doesn't compile. However if you achieved the same thing via a blackbox or I/O Rust doesn't know at co…
In C, the problem isn't the silent wraparound, the problem is that when the compiler sees that expression, it will assume that the resulting value is less than INT_MAX, and optimise accordingly. The other insidious problem is that wraparound is defined for other unsigned arithmetic, so a programmer that hasn't had this explained to them, or read the standard very carefully, would quite easily assume that arithmetic on unsigned short values is just as safe as it is for unsigned char, int or long, which is not the case.
Re: In defense of complicated programming languages
#239Earlier quoted context omitted.
I agree that everyone shouldn't need to know every implementation detail, but I'd argue there should be more emphasis on the low-level details in CS education. Programming is often approached from a purely abstract point of view, almost a branch of theoretical mathematics, but imho in 99% of cases it's better understood as the concrete task of programming a CPU to manipulate memory and hardware. That framing forces y…
This depends heavily on the context. In The Art of Computer Programming , the analysis of algorithms is done in terms of machine code. On the other hand, the proverbial centipede lost its ability to move as soon as it started wondering about how it moves.
But when you're considering two different architectural approaches, you should, at least in broad terms, be able to think about how the machine is going to execute that code and how the data is roughly going to be laid out in memory for instance.
Re: In defense of complicated programming languages
#240Earlier quoted context omitted.
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?
I just added a -vasm switch to the dmd D compiler so you can learn it from the bottom up! https://news.ycombinator.com/item?id=30058418 You're welcome!