So, virtual functions aren't real because they're just vtables implemented in C. But C isn't real because it's just fancy assembly language. But assembly language isn't real because it's just fancy machine language. But machine language isn't real because it's just 0's and 1's zipping around the hardware. So I have to learn how integrated circuits work before learning how to program? No.
Bottom-up knowledge is important for understanding performance and other trade-offs. However, there's also a lot of benefit in learning how to program in a formal system without knowing much about how that system is implemented under the covers. If I was teaching an intro programming course to undergrads in 2017, I'd be strongly inclined to teach them a clean functional language first (e.g. Elixir, F#, etc.), and only introduce gory details like pointers and memory allocation later on.
I'm sure it would be possible to produce a few excellent software developers doing the bottom up approach as well, starting with a course on hardware, then assembly and then going up the stack from there. I would have loved that approach personally, but it would probably turn the average CS student into an awful programmer.
Sure, start the freshman off with Python. Let them get their feet wet and see whether they even enjoy this dark art at all. Besides, knowing about the hardware before "Hello World" isn't very helpful.
After their intro class, you don't do bottom up or top down. You start at both ends and work your way in. You got your computer systems course which teaches C and a smattering of assembly and hardware and your algorithms and data structures class that can use an easier language like (python/scheme) to reduce the cognitive overhead to teach the material.
If the students are taking these at the same time and the professors coordinate to explain how they relate at the various levels, you get very balanced developers. (Assuming they do well in the classes!)
I took a couple classes in college that were designed to teach what is going on underneath the 1s and 0s of instruction sets. I didn't take the classes about how circuits work, but they existed, I had friends who took them, and I really wish I had as well.
Maybe this isn't required knowledge to do software engineering, but it's definitely useful knowledge. Why wouldn't we want to learn these things?
Python is a fairly decent language for starting people off:
* It doesn't have a lot of boilerplate, so no magic "I'll teach you what this means in three weeks" steps
* Output for debugging is fairly easy, since print accepts a lot of stuff without needing to muck with formatting strings
* Assignment is a statement, not an expression. You can't say "if x = 3" by accident
* Python is one of the major programming languages, so you're teaching students something that is pretty much guaranteed to be useful for them.
Scheme levels the playing field. I have never encountered a student who entered university with years of functional programming experience and I was a TA for an introductory CS course. I think moving back to Scheme would be a wise choice for universities that are combating problems with diversity.
6.001 was a course in functional programming, based on the book Structure and Interpretation of Computer Programs.
6.01 (the replacement course that uses Python) is a project-based course involving robots and stuff.
Neither of these courses depend on any specific knowledge, but they would be very difficult courses if you've never programmed before. (Most people coming into MIT course 6 have programmed before.)
The "you don't know how to program, here's how to program" course has taken various forms over the years. When I was there it was 1.00, a Java course for engineers. Later it was 6.00, an optional intro to Python, based on "How To Think Like A Computer Scientist".
While I can't speak for MIT, SICP was used as the introductory course for CS in a number of universities. It assumes no programming. It is challenging, but that's the point of going to top universities.
(I skipped the first two intro CS classes in college after talking to the professors and figuring out the right place to start given my background.)
In university, successfully challenging also gives you credits for that course (though there is a small fee per unit). I successfully challenged four courses (all in graphic design) - three of which were based on portfolio review and the fourth was based on completion of course projects in an accelerated period. Additionally, though not quite a challenge, I was able to speak with a couple CS professors and get them into admitting me into their courses despite not having the prerequisites (though was doing them concurrently).
The course requisite structure is more a guideline than a rigid computer system that works one way and only that way.
One of my friends was able to skip 61a by meeting with the department chair, Paul Hilfinger, and convincing him that 61a would be a waste of time for him. My friend could drone on and on about the simplest of subjects so we assumed he just annoyed Hilfinger until he said "enough already".
When I want to university I never took a CS class before and nevertheless could program really well. I believe one is not able to go to a university if one is not able to teach oneself the prerequirements of the subject that one want to study.
Luckily the introductory course was based on SICP - and it really realigned my BASIC- and C- damaged brain.
It turned out to be the only course that I enjoyed so I eventually switched to a more computer systems and sciences oriented education.
It was a good introductory course for me, and perhaps most others. Perhaps not good for the most daft though...
I guess you also need some assembler-skills but it's hard in a totally different dimension somehow.
This is essentially what CS50 at Harvard does, and it seems to work well. Once a student has been exposed to these 3 languages, subsequent courses can explain how a computer works and introduce new paradigms (FP, LP).
There's time for them to learn the details, but just learning that the functionality exists and knowing how to use it is a good start.
Inductive logic and the functional paradigm maps onto all of these. And allows for more diverse abstractions without lying either.
1) Learning must be applied learning. Give people problems to solve and they will come to you for data structures and algorithms, O notation, etc. If they don't, they should do something else
2) A lot of what's out there in programming languages are cargo cults, and newbies need to be prepared for this. For instance, virtual function inheritance isn't a thing. It's a weird call chain pipeline system glued into your vtable, which C++/Java teaching also won't bother to tell you exists. Make people start from assembly, graduate to C, then write their OWN vtable, so it's demystified. Now you've reduced the ability of software designers to piss on your leg and tell you it's raining.
So ideally I'd want students (at first) to be doing something either close to the machine or in the functional model. As they say though, the imperative of 1) means getting people to actually produce something, which is easier in Python.