The fact that a language is terrible for newcomers is a real problem, and a newcomer is a very good judge of that even if they aren't a very good judge of other aspects.
Especially loathsome are those people who teach, say, undergraduates majoring in physics some C++ as a way to introduce them to programming. You might think that someone who manages to deal with the math needed to do physics would be able to absorb C++, and often you'd think wrong; one physics undergrad told an experienced programmer after trying to understand what the fuck cout<<x actually does, "your head is full of garbage!", by which he meant that the amount of completely arbitrary rules that you need to memorize was not something that dealing with math and science prepared him for.
From the above I conclude that people who have a semester's worth of experience in C++ might not be C++ experts but they certainly know enough to burn the instructor who chose C++ in the first place at the stake.
It may sound strange, but I find assembly to be an appropriate language to learn programming. Not only your focus will be on what you are doing rather than on the language itself, you will get a feeling of what is really going on, and you will quickly appreciate - and fully understand - the the reason why C is useful and that it is a good, well designed programming language. (In the same way, with enough experience using C, one comes to appreciate C++.)
I'm not sure where that conversation would go. It prints to stdout. Would the student say the same thing about printf("%d", x)? How far down the rabbit hole did he want to go?
Stream insertion syntax os pretty bad, though, I'll agree with that. Especially when you want to print floating point.
When you provide a shorthand that's all well and good but when you TEACH a short hand it's what's ONLY used by the students.
The students will assume there is no other way to read and write then using >> and << which is horribly incorrect. These are largely inadequate measures for reading and writing in my experience as you probably want to do formatting which printf just does better.
So many of the students in my CS class this semester can't do the first lab, which in all essence, is a tokenizer because they don't know that there are other ways for writing to, or reading from, a stream!
A short hand should only be used in a majority if it can do everything the long hand way can do.
Also for anyone interested what my first C++ project looked like you can see here:
https://web.njit.edu/~gwryan/CS280/CS280-Program-1-Fall-2016...
https://git.gravypod.com/gravypod/school/tree/master/cs280/h...
It's not my best work, but if any C++ people want to notify me of things I'm doing that's wrong I'm more then happy to learn.
Your project looks good. Two minor observations: 1.) You have 'using' statements in a header file. This is fine for a small project, but is considered bad form in larger projects (every file that includes that header will end up including the 'using' statements. This can cause collisions in large projects).
2.) Const correctness is a good habit to get into. (Ie, only pass non-const references if you are actually changing the object in the function)
Coming from Java I have a blanket policy that every variable is final unless needed to be modified. I've run into those pain points.
Your first observation is one I have some into as well but I haven't been taught how to do this.
For example if my header file needs to define the method:
void test(std::string something);
Is it bad form to them define the header in my cpp file as such? void test(string something);
Isn't that also bad form? Coming from C some things like this could be done but very much shouldn't have been done.I know for a fact that namespacing is one of the hugest benifits to large projects I just don't know how to use the tools provided by C++ to do it correctly. Java? Yea I can get anything you want nice and tucked away. But C++ with the way headers and namespacing works its difficult to obviously see what I want to do and how to get it done.
Any examples?
You can always do fprintf instead of that; i almost never do C++ streams for io - there is always a way to avoid them.
But then why is it the first thing we shove into peoples faces when teaching them the language?
The majority of them surely were able to get shit done in C++ at the end of the semester.
Don't get me wrong, I remember the people who taught me C++ rather fondly. It's just done really terribly really often.
Bravo.
My problem is not with what I think you are attributing to me but rather other issues with the language and tool chain. There seems to me very little that can be done in C++ that can't be done cleaner in C.
It's evident that most people who use a language aren't going to have time to spend years becoming a master at it. They are going to join a team and say "So to do my assigned task I need to do X, what features let me to X the cleanest" and this is how I've taken on learning C++.
Sadly, no features that are new have yielded themselves to any problem I've seen. I haven't encountered it.
Your solution to rebut my argument is that "you need to be at least 10 years into the language to know anything kid!" yet you provide no rebuttal.
Please do provide an argument not an insult at my age the next time you'd like to raise a disagreement with my ideas.
C++ isn't a great choice for many purposes, but for some purposes it is the go-to language - and for good reasons, not just because of inertia as some like to suggest.
As with all forms of craftsmanship, you need to choose the right tool for what you're trying to accomplish.
For people who have never touched java's inherited state from extending abstracts or base classes please don't fall into the traps I did. I was writing a redundant networking library that was meant to load packets on the fly so I had some cleaver "c++ level" abstraction written out for it. It only made sense to me because I relied on horribly complex features of Java. I'd say the most complex feature of Java.
Read through this to get an idea of what's going on. You'll notice that this is one of the sections with the least detail in the entire Java Primer thing. This is because in my opinion even the Java developers don't know all the rules.
https://docs.oracle.com/javase/tutorial/java/IandI/multiplei...
Now I don't think I know these rules either. I spent 2 months sorting out this mess and ended up with a polished product. But guess what? I could never go back there and fix something "quick". I'd need to do a bit of reading, read through my source, experiment a bit. This is not productive nor good standards and because of this I try never to rely on inherited state in Java anymore.
The same goes for every pain point of C++. Sure an expert, someone who lives, breaths, and dies by C++ might know exactly what is going on from the get go but that can't just be the assumption for every programmer. It is my opinion that if a language designer expects someone to read up on the language before going in and changing things they have failed at one of the cornerstones of language deign and implementation.
Everything should be "of course" levels of ingenuity but in C++ everything is "what the fuck".
For instance, please read my comment on RAII.
You can also take the multiple inheritance problems I've had in Java and directly apply them to C++.
You've also got strange behavior, when coming from C, for dealing with strings. For instance, where does an std::string get allocated? Is it on the heap or stack?
For instance am I opening myself up to bugs by doing this in my latest CS lab?
https://git.gravypod.com/gravypod/school/blob/master/cs280/h...
There's no apparent flow or rhyme to anything in this language. It just seems to be complexity bolted on simplicity and called "an industry standard".
Also operator overloading. I'd say it's a great thing for defining numeric and mathematical constructs that actually implement the specific operators as you would expect. For instance speaking as someone who has implemented their own basic physics library in java that is a godsend. But why, in the name of god, would you ever think of using numeric operators on non-numeric constructs? That's just inconsistency again leading down the further train of C++ needing to be learning in full before used.
Further, namespacing is taught poorly. I've had to do my own reading and settle on a standard that I think is semi-sane at least.
Rather then using the entire std namespace the same as my class I've settled on specifying namespaced elements I want to use. This is not how anything is taught in any college I've examined.
An example of what I do:
https://git.gravypod.com/gravypod/school/blob/master/cs280/h...
What's the point of using a namespace if you are just going to blanket import the entire namespace? Also if that's not the SOP for industry why is it taught as such in college?
There are many many if-ands-and butts about C++ and I can't go into all of them as I don't know all of them.
I do like reference types though, that's nice.
>> string token = "";
No, you aren't opening yourself to bugs, but it's unnecessary. A default constructed string is already == to "", token.empty() will return true.
get_token_type() should likely take a const reference to the string, as all of the operations on the argument are const. I saw elsewhere in the thread where you said you've avoided const so far. Honestly, const may be C++'s greatest feature; it is far, far stronger than Java's "final" (or Scala's equivalent "val").
Looking over this code from a high level, I'm not sure why you have get_token_type() with a string parameter and a char parameter, when the former just forwards to the latter. Couldn't you have a second char variable, "prev_char" or "last_char", in get_next_token() and then detect when the type of it differs from the current char. Then the only operation you'd be doing on the string "token" is appending to it. I could be missing something, though, as I've only taken a quick glance through the code.
I would generally agree with you that C++ is poorly taught almost everywhere. I think it was a win for CS departments when they transitioned from C++ to Java for introductory courses (and now many are transitioning to Python, also a win). I am fairly convinced that C++ programming is a craft and is therefore best learned under an apprenticeship model, of routine practice with expert review and guidance, coupled with some self-study.
I'm specifically interested in the RAII question to see how they justify fundamentally different behavior for syntactically similar code.