8 ms·
I understand this thought process, but in my opinion it's the wrong way to think about software concepts. Understanding what a bridge is doesn't mean knowing ho
by LEDThereBeLight 5y ago
I understand this thought process, but in my opinion it's the wrong way to think about software concepts. Understanding what a bridge is doesn't mean knowing how to build one, and in fact tying your understanding to a certain implementation of a bridge just limits your ideas about what is, in fact, an abstract concept.
We understood functions as "mappings" between objects for hundreds of years, and when programming came along it gave us new ways to think about functions, but being able to "make" a function in hardware/software doesn't actually change what a function is at its core.
There's a reason why computer science professors explain concepts at a high or abstract level and don't jump into implementation to help students understand them. It's because the concepts ARE the high-level meanings, and if you need to see an implementation then you're not really understanding the idea for what it is.
If an idea stays abstract in your mind, it gives you more flexibility with how you apply it and more ways to find use out of it. But it does take a mindset shift, and is an actual learned skill, to be able to see something as purely abstract and accept that how it's made doesn't matter.
-- Edit - just realized who I was replying to. So take this comment as not meant to be lecturing, but just a 2c to offer :).
- WalterBright 5y agoI didn't understand how engines worked until I took them apart, either. I was taking things apart to understand them long before computers :-) But the notions of sending a "message" to a "method" just was way way too handwavy for me. I like examining the theory after I learn the nuts and bolts. > Understanding what a bridge is doesn't mean knowing how to build one If you don't know how to build one, you don't understand them. Architects who get commissions to design innovative skyscrapers definitely know how to build them.
- Koshkin 5y ago> sending a "message" to a "method" I think you mean “to an object.” The problem with an approach like yours is that implementations of abstract concepts often vary, and learning the “nuts and bolts” of one does not necessarily give you the true understanding of the concept itself.
- WalterBright 5y agoYeah, sending a message to an object via a method.
- tralarpa 5y agoSome months ago I had to learn React for a project. I was struggling a lot. The documentation was so poor. And everything looked so inconsistent (it still does...) and the "solutions" on stackoverflow looked so arbitrary. Until I remembered the lessons I had learned in the past and sat down and studied how it was internally working. Then things started to make sense. I think it's an advantage to be able to mentally map high-level constructs to low-level operations. (Edit) Learning the low-level stuff first can help to understand what problems high-level languages are trying to solve. For example, the first languages that I learned were assembly and BASIC. Many people said that learning such low-level languages would make it harder for you to learn abstract thinking and structured programming with high-level languages. For me, it was quite the opposite. Writing complex programs in BASIC was so cumbersome, it made me appreciate programming in C with local variables and data structures. After mastering function pointers in C and discovering that you can elegantly express operations on "living" data structures with them (I wrote simple game engines and world simulations for fun), the concept of messages and methods in OO languages looked so natural when I first learned about them. And once you witnessed the mess of complex interdependencies in large programs (with or without multithreading), immutability and functional programming looked like the right way.
- KineticLensman 5y ago> Writing complex programs in BASIC was so cumbersome, it made me appreciate programming in C with local variables and data structures My language trajectory was approximately from BASIC to Pascal to C to Common Lisp, but I had a very similar reaction. My move from C to Common Lisp probably had the greatest increase in appreciation because a task I semi-failed to complete in three years of C programming took me six months in CL, which was perfectly suited to the task in hand. (the C task was postgraduate work in AI, in the late 1980s. As well as the importance of choosing the right language for the task, I also learned a lot about the importance of clearly agreed requirements, integration tests and software project management, none of which really existed on the four-person project I was working on).
- yxhuvud 5y agoOn the other hand, you can walk over a bridge any amount of times without understanding the nuts and bolts of it. There are plenty of ways to build a bridge, there are static concrete bridges, there are bridges that can open, there are hanging bridges and a lot more variants. But for the people making use of them, the implementation matter a lot less than the purpose - connecting two places. But yes, you are of course right in that if you build bridges, you need to understand the mechanics, and someone that builds a language of course need to have a deeper understanding of how the underlying abstractions work together than most of the users will have.
- LEDThereBeLight 5y agoThank you, what you wrote is exactly what I meant.
- cogman10 5y agoIs it possible to really learn how programming concepts work, though? Modern optimizing compiler are pretty amazing and just seeing the assembly output may make a concept harder to grasp. To your bridge analogy. At this point what we are saying is "give me a method to traverse this river" and compilers are either building bridges, shooting out maps to fallen trees, or draining the river all together. If you looked at that output you might consider "traversing rivers" to only be walking over natural bridges. This gets even more sticky when talking about types. Computers don't care about types, they are strictly a concept to help developers. Or to your class point, would you know better what a class does if you pulled up godbolt and found that the this pointer is completely removed? You might come to the mistaken conclusion that classes are simply a name-spacing technique.
- astrange 5y ago> Is it possible to really learn how programming concepts work, though? Modern optimizing compiler are pretty amazing and just seeing the assembly output may make a concept harder to grasp. They usually have debugging options that let you read the internal steps (SIL, LLVM, GIMPLE, etc). That can be easier to understand than full asm, but also, the asm can't hide anything from you unless it's obfusticated.
- cogman10 5y ago> the asm can't hide anything from you unless it's obfusticated. I think that misses the point. It's not the case of the ASM hiding things, it's a case of the optimizing compiler erasing things. Here's a simple example: You say "Ok, the time I need to wait is 30 minutes. This method takes seconds, so I'll send in 60 (seconds in a minute) * 30 (minutes). The compiler is free to take that and say "Oh hey, 60 * 30? I know that's simply 1800 so I'll put that there instead of adding the instructions for multiplication". Trying to learn how something like that works from the ASM output would leave you confused trying to reason where that "1800" came from. It's not hidden, it's not obfuscated. It's simply optimized. That's a simple example, but certainly not the end of the optimizations a compiler can apply. The ASM isn't lying, but it also isn't telling the whole picture. The very nature of optimizing compilers is to erase parts of the picture that's ultimately only there for programmers benefit.
- maxwell86 5y agoHave you taken Rust appart yet?
- convolvatron 5y agoit would have helped me a lot.from the outside it looks very complicated and capricious. I really do get the sense that the little axiomatic ur-language inside is a lot more tractable - would love to have learned that first.
- maxwell86 5y agosame, i'd like to see such an approach
- jksmith 5y ago>>"But the notions of sending a "message" to a "method" just was way way too handwavy for me." This. I've felt like I haven't been able to keep up with commodity programming because I can't stand the way today's drivers (MSFT) control mindshare by emphasizing frameworks over mechanics. I feel like it's a people aggregation move instead of facilitating more creative solutions. The most enjoyable classes I had in uni were 370 assembler and all the Wirth language classes taught by the guy who ran the uni patent office.
- jancsika 5y ago> But the notions of sending a "message" to a "method" just was way way too handwavy for me. I like examining the theory after I learn the nuts and bolts. Ooh-- are we talking about Smalltalk here? Java? C'mon, Walter. You can't tell half a ghost story and then say goodnight. What did you find staring back at you deep in the void of all that object-orientedness? Or, if this is a famous ghost story you've told before at least give us a link. :)
- anonair 5y ago> But the notions of sending a "message" to a "method" You mean to an “object”? Also, this looks like a perfect example of theory vs practice, having different implementations of object communication as in classic OOP vs actors etc?
- mbrodersen 5y agoIt’s because the “sending message” explanation is BS unless you talk languages like Erlang. The OOP explanations doesn’t make sense because they are BS. In the real world you don’t ask your shoe to tie itself, you don’t ask a tree to chop itself etc. And in OOP languages you normally don’t ask a string to send itself over a socket or draw itself in 3D using OpenGL. The reality is that you have code operating on data. The same way you have an axe operating on a tree, or your hands operating your shoe laces. That’s it. Everything else is BS.
- CogitoCogito 5y ago> if you need to see an implementation then you're not really understanding the idea for what it is. I 100% disagree. At the very least, I think you're wrong if your assumption is that such a statement applies in general. That statement certainly doesn't fit me as well as many people I've taught in the past. I got my PhD in (pure) mathematics and I could only understand high level abstractions _after_ I worked through many concrete examples. I know the same applies for many successful mathematical researchers because we discussed the subject at length. Now such a statement certainly does apply for _some_ people (I've taught them as well), but certainly not all. If you're someone that likes this sort of abstract thinking, that's great. If you're someone that needs concrete examples to understand, that's great too. The real lesson is that everyone learns differently.
- Koshkin 5y agoBut there's a difference between trying to understand, say, a theorem by applying it in concrete situations and by studying its proof.
- CogitoCogito 5y ago> But there's a difference between trying to understand, say, a theorem by applying it in concrete situations and by studying its proof. There may be a difference or there may not. You could study a proof within the context of a specific example. That is how I usually would do it. But yes of course it's possible not to do like that (many people don't study proofs that way). In any case, I don't really understand your point.
- Koshkin 5y agoI was drawing an analogy, in this particular context, between studying the proof and taking something apart.
- yodsanklai 5y agoI tend to agree with you in principle, but for me too, a lot of high-level features are better understood in term of translations. Objects, coroutine, closures... Even in formal CS, it's common to define the semantics of a language by translation, which can give more hindsight than operational semantics. Now that I think of it, I think the problem is that most languages are defined informally which can be imprecise and inadequate. The translation provided by the compiler is the closest thing we have to a formal semantics, it's natural to rely on it.
- professoretc 5y ago> The translation provided by the compiler is the closest thing we have to a formal semantics, it's natural to rely on it. Which translation, though? Depending on your compiler flags, you may get very different translations, sometimes (if your program contains undefined behavior) even with dramatically different runtime effects.
- WalterBright 5y agoI've found that C compiler documentation on how their extensions work to be woefully inadequate. The only way to figure it out is to compile and examine the output. Most of the time, the implementors can't even be bothered to provide a grammar for their extensions.
- hnlmorg 5y ago> I understand this thought process, but in my opinion it's the wrong way to think about software concepts. You cannot really tell someone that the way their brain learns is the "wrong way". Different people's brains are wired differently and thus need to learn in different ways. > Understanding what a bridge is doesn't mean knowing how to build one, and in fact tying your understanding to a certain implementation of a bridge just limits your ideas about what is, in fact, an abstract concept. Software development is about more than just understanding what something is. It's about understanding how to use it appropriately. For some people, simply being told "you use it this way" is enough. Other people like to understand the mechanics of the concept and can then deduce for themselves the correct way to use it. I also fall into that category. While I'm not comparing my capabilities to Bright's I do very much need to understand how something is built to have confidence I understand how to use it correctly. Neither approach is right nor wrong though, it's just differences in the way our brains are wired. > There's a reason why computer science professors explain concepts at a high or abstract level and don't jump into implementation to help students understand them. Professors need to appeal to the lowest common denominator so their approach naturally wouldn't be ideally suited for every student. It would be impossible to tailor classes to suit everyone's need perfectly without having highly individualised lessons and our current educational system is designed to function in that way. > If an idea stays abstract in your mind, it gives you more flexibility with how you apply it and more ways to find use out of it. But it does take a mindset shift, and is an actual learned skill, to be able to see something as purely abstract and accept that how it's made doesn't matter. The problem here is that abstract concepts might behave subtly differently in different implementations. So you still need to learn platform specifics when writing code on specific platforms, even if everyone took the high level abstract approach. Thus you're not actually gaining any more flexibility using either approach. Also worth noting that your comment suggests that those of us who like to understand the construction cannot then derive an abstract afterwards. Clearly that's not going to be true. The only difference between your approach and Bright's is the journey you take to understand that abstract.
- LEDThereBeLight 5y agoI like to understand the construction too, it's why I'm in engineering. I'm just saying it shouldn't be necessary in order to understand an idea. For me, it was a crutch I used for years before I grokked how to decouple interfaces from implementations because I naturally understand things better after I build them. But if you use an implementation to understand an idea, you couple implementation to interface in your mind, and so it changes your understanding.
- skohan 5y agoI 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 you to consider tradeoffs more carefully in terms of things like time and performance. You shouldn't be able to hand translate every line of code you write into assembly, but in my experience you write much better code if you at least have an intuition about how something would compile.
- Koshkin 5y agoThis 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.
- skohan 5y agoI tend to think you should be able to go back and fourth between mental models. Like obviously when you're thinking through how to set up business logic, you should not be thinking in terms of registers and memory layouts. 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.
- LEDThereBeLight 5y agoI 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.
- 5y ago
- zozbot234 5y ago> I understand this thought process, but in my opinion it's the wrong way to think about software concepts. ... just limits your ideas about what is, in fact, an abstract concept. There's nothing abstract about language constructs. Learning about a language construct via translation is a perfectly fine way of clarifying its semantics, whereas an "abstract" description can easily be too general and fail to pin down the concept; it can also rely on unstated "rules of the game" for how the abstract construct will operate within the program, that not everyone will understand the same way.
- dogleash 5y ago>There's a reason why computer science professors explain concepts at a high or abstract level and don't jump into implementation to help students understand them. It's because they're trying to teach something to people who don't have anything to build on. Later in their education that'll be different. At the school I attended Object Oriented Programming class had Computer Organization as a pre-req and the teacher would often tangent into generated assembly to help students understand what was happening. Regardless of whether I agree with your thoughts about the ideal approach to understanding the concepts vs implementation, I live in the status quo where - sooner or later - a C++ programmer is going to encounter a situation where they need to know what a vtable is.
- WalterBright 5y agoI did not understand what virtual functions were at all until I examined the output of cfront. Oh, it's just a table of function pointers.
- donkeybeer 5y agoSometimes textbook descriptions are just needlessly obtuse. I have noticed that there are some concepts which I already understood but if I were first introduced to them via the textbook, I would have been hopelessly confused. I wasn't confused only because I recognized this as something I already knew.
- CRConrad 5y agoYou must have just had the bad luck to have read the most appallingly stupid books. I think you might be even a little older than I, and I got into the game late-ish; those C++ manuals or specs you read were probably from the 1970s or 80s? By the time I learned (imperative- and inheritance-based[1]) OOP from the Delphi manuals in the late nineties the virtual method table was explicitly mentioned and explained, along with stuff like "since all objects are allocated on the heap, all object references are implicitly pointers; therefore, Borland Object Pascal syntax omits the pointer dereferencing markers on object variable names" (which you also mention about C above). I'm fairly certain this gave the reader a pretty good grasp of how objects work in Delphi, but I still know nothing about what machine language the compiler generates for them. It's not the idea of top-down learning from abstractions that's wrong, it's being given a shitty presentation -- more of an obfuscation, it seems -- to learn about the abstractions from that is the problem. ___ [1]: So yeah, that whole Smalltalk-ish "messaging paradigm" still feels like mumbo-jumbo to me... Perhaps because it's even older than C++, so there never were any sensible Borland manuals for it.
- marcosdumay 5y agoYes, you are correct. But you are wrong too. People need complete understanding of their tools. And complete understanding includes both how to use the concepts they represent and how those concepts map into real world objects. If you don't know both of those, you will be caught by surprise in a situation where you can't understand what is happening. That focus on the high level only is the reason we had a generation of C++ developers that didn't understand the v-table while being perfectly capable of creating one by hand. It's also why we have framework-only developers that can't write the exact same code outside of the magical framework, even when it's adding no value at all.
- anonair 5y agoIMO this is very elitist view of software developers' job. The analogy from tangible world would be all the bridge engineers using "proven" / "boring" / "regulator endorsed" practices and techniques to build a "standard" bridge versus those constantly pushing the limits of materials and construction machines to build another World-Wonder-Bridge. There is nothing wrong with having both types of engineers.
- CRConrad 5y ago> There is nothing wrong with having both types of engineers. Acksherly, yes there is. In this context, there is: The world doesn't need engineers "constantly pushing the limits of materials" when building bridges; let's stick with proven, boring, regulator endorsed practices and techniques for that.
- dasil003 5y agoThe issue with viewing programming concepts as purely abstract is that the abstractions have varying degree of leakiness. Even with the most mathematically pure languages like Haskell you run into implementation details space leaks which you have to understand to build reliable systems. There’s certainly something to be said for abstract understanding, but one thing I’ve learned in software and in business is that details matter, often in surprising ways.
- WalterBright 5y agoChris, a friend of mine in college (who is unbelievably smart) decided one day to learn how to program. He read the FORTRAN-10 reference manual front to back, then wrote his first FORTRAN program. It ran correctly (as I said, the man is very smart) but ran unbelievably slowly. Mystified, he asked another friend (Shal) to examine his code and tell him what he did wrong. Shal was amazed that his program worked the first time. But he instantly knew what was wrong with it - it wrote a file, character by character, by: 1. opening the file 2. appending a character 3. closing the file Chris defended himself by saying he had no idea how I/O and disk systems worked, and so how could he know that the right way was: 1. open the file 2. write all the characters 3. close the file and he was perfectly correct. This is why understanding only the abstractions does not work.
- CRConrad 5y ago> This is why understanding only the abstractions does not work. I don't think your example shows that at all: If it didn't actually explicitly say in his Fortran reference manual that "The 'thing' you write between a file-open and a file-close can only be a single character", then... Sorry, but then AFAICS your example only shows that he didn't understand the abstraction that "file-open" just opens a file for writing, without specifying what to write. (Maybe he slavishly followed some example in the manual that only wrote one character?) This needless sprinkling of file-open / file-close looks a bit like he did the work of a current optimising compiler (only here it was pessimising), "unrolled a loop"... So AIUI it shows the opposite of what you set out to show: Too concrete without higher-level understanding was what did him in.
- patrick451 5y agoI don't really buy this. It's like saying we should teach about fields before addition of real numbers, or about measure spaces before simply C^n. The most abstract version of a concept is usually much more difficult to grok.
- redsaz 5y agoI am not a child psychologist, so take all of this with a grain of salt. I believe children first learn concepts by looking at and playing with concrete things first. "Oh look at this fun thing... Oh whoops I moved it, it looks slightly different, but if I rotate it, it looks like it used to... It doesn't really taste like anything, but it feels hard... Whoa, what's this new thing over here? Oh wait, this is the same size and shape as the thing I played with previously... In fact it behaves just like the first thing did. Oh cool, there's a whole stack of them over here, I bet they work just like the first things did!" This is how one might interpret a baby's first interactions with blocks. Later in life, they might find out about dice and understand some similarities. Later, still in school, the kid learns about cubes in geometry class, and can think back to all the concrete hands on experience he had and see how the various principles of cubes apply in real life. So, people learn by experiencing concrete things first, and then grouping all those experiences into abstract concepts. Sometimes (ok, often) they'll group them incorrectly: Kid: "This thing doesn't have fur and moves without appendages. It's a snake. Whoa, look at this thing in the water, it moves without appendages either! It must also be a type of snake." Teacher: "That's an eel, not a snake." Kid: "oh. I guess snakes are for land and eels are for water" Teacher: "Water Moccasin is a type of snake that is quite adept in the water." Kid: "oh. They look kinda the same, what's the difference?" Teacher: [performs instruction] This form of learning by compiling all sorts of concrete things down into a few abstract concepts is so powerful and automatic that we do it ALL THE TIME. It can even work against us, "overtraining" to use an ML term, like with our various biases, stereotypes, typecasting of actors ("this guy can only ever do comedies"). Sometimes folks need a little help in defining/refining abstract concepts, and that's the point that teachers will be most helpful. So, for me anyway, and I suspect many others, the best way to learn a concept is to get many (as different as possible) concrete examples, maybe a few concrete "looks like the same thing but isn't", and THEN explain the abstract concept and its principles. Or, to explain the process without words, look at Picasso's first drawing of a dog, and the progressively shinier simpler drawings until he gets to a dog drawn with a single curvy line.