As much as I like Dijkstra and this particular article of his (it is an assigned reading in my "Software Engineering" class), developing any large scale software that we have today starting from formal methods is just a fantasy.
I understand the importance of learning formal methods (discrete math, logic, algorithms, etc.), but they are not nearly enough to help someone get started with a software project and succeed at it.
So, if not "software engineering", then what should we teach to a student who is going to be thrown into the software world as it exists in its current form?
Formal methods have advanced enough now that any competent software engineer should know that it is at least an option. It's obviously not practical or necessary to apply everywhere but in any sufficiently large piece of software there are likely a few modules where applying formal methods would allow for faster, higher quality delivery at lower cost. Making those trade-offs and selecting appropriate approaches is the fundamental essence of engineering as a profession.
Maybe if developing large-scale software starting with the formal methods we have today is just a fantasy—and that's plausible—we shouldn't be trying to formalize "software engineering". Imagine trying to formalize medicine before Pasteur, motor engineering before Carnot, mechanical engineering before Reuleaux, or structural engineering before Galileo. Today, we do have relevant bodies of formal knowledge that are enough to help someone get started with a project in those areas and succeed at it. As you say, that knowledge doesn't exist yet for software.
So what would you teach an architect in 01530 or a mechanical engineer in 01850? In addition to the relatively sparse formal knowledge that did exist, you'd make them study designs that are known to have worked, you'd apprentice them to currently successful master architects or mechanical engineers, and you'd arrange for their apprenticeship to give them experience doing the things people already do know how to do.
I understand the importance of learning formal methods (discrete math, logic, algorithms, etc.), but they are not nearly enough to help someone get started with a software project and succeed at it.
So, if not "software engineering", then what should we teach to a student who is going to be thrown into the software world as it exists in its current form?