1. Java enums
2. Java's generics, especially covariance/contravariance with wildcards (erasure really isn't as bad as people make it out to be)
3. Java's standard collections library
4. Java's method override rules (lets you extend return types on derived classes)
5. Default interface methods (.Net has them too now, but Java was first)
6. @Functional interfaces. They may seem a bit funny at first, but they are very useful (especially when combined with default interface methods)
- portability is not a high priority.
- garbage collection is not a high priority.
Those are 2 reasons why you don't want to start with Java. You can teach it later, sure. But it's not a good start.
Here I disagree. I would not start teaching programming in a manual memory language (though that is how I started) because memory corruption is really hard to deal with and completely inconsequential to the basics of programming.
I do think it's important that every programmer should know how to work with raw memory and pointers, but it is a good subject for an intermediate class, after you have the basics of what you are supposed to do while programming.
And then over the next few years it would be great to dissect this. CPU, ALU, ASM, raw memory, network basics, IP (BGP ~ distance vector routing), TCP, buffers, syscalls. RDBMS, MVCC, B-trees, merge sort, heap sort, and so on.
Oh well, one can dream. But usually students are just bombarded with completely disconnected courses.
It could be my chauvinism speaking. I'll admit to having some. My CS program taught us three relatively small programming languages (Scheme first, followed by C, and then MIPS assembly) in the first year before introducing OOP in the second year. So we ended up getting exposure to a variety of programming paradigms and environments, and came away with a lot of tools in our belt, and a fairly deep understanding of programming language theory and paradigms. And I did eventually find myself settled in a Java shop. When I did, I found that within only a couple months I had already developed a deeper understanding of the language than colleagues who had spent their entire careers working in it. And I believe a lot of that is because I had enough background knowledge to distinguish between, "This is how programming is done," and, "This is how programming is done in Java."
And before someone points out that, actually-technically, Java is always pass by value, I will pre-retort that reference-as-value isn't an argument we should ever be having about an intro programming language.
Either teach a systems language with unambiguous pointers, or teach something that abstracts consistently.
I understand why (now), but at the time, it just added unnecessary cognitive load on top of already learning hardware models.
C and Pascal require fewer exceptions, despite a larger base knowledge requirement.
C++ is ok. Students can use a very simple subset of C++, they don't have to use the more advanced parts of it.
C is even better.
Go is fine, too.
Typescript is a good enough choice.
Thanks to C and C++ I did understand the most important bases of programming, how a program runs, how hardware works and the most important algorithms and data structures.
I think it's important to learn something that doesn't do too many abstraction but it isn't too low level like the assembly language.
You need to understand
* access modifiers (public/private)
* classes
* static methods
* void return values
* the main() function
* modules (System.out.println)
Just to understand a basic "hello world". It's too much for first-time programmers.
class Test {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
And then javac Test.java
java Test
The class acts as a kind of namespace here, you don't need to go into OOP concepts for hello world at all. The beginner will have to understand* Class is in file with the same name ¯\_(ツ)_/¯ and contains functions (maybe it'll help me later in organizing code?).
* Command line arguments (not strictly necessary concept but not too problematic either)
* Types - why is there String[] in the definition? (A must have in a statically typed language anyway)
* void - the function doesn't return anything (OK)
* public (not OK, some magic here)
* static (not OK, some magic here)
* Compilation vs. run step (a must have in a compiled language)
So IMHO there are just two concepts that could be thrown away. Or three, if you accessed CLI args from a library. But the meaning of public and static will come naturally when the students will learn about OOP.
Sounds like excellent training for a long and successful career in enterprise Java.
> * access modifiers (public/private)
I think you can omit the "public"s in the Java hello world (thereby making everything package protected, and sneakily sidestep the issue), but I don't want to ruin this machine by installing Java on it to make sure.To be super thorough, you would also have to understand:
- semicolons (and the related issue of newlines being semantically equivalent to normal spaces)
- naming conventions (to explain why it's not "System.Out.Println" and "Main")
If someone applying for an architecture degree or engineering degree is required to have basic drawing skills and basic math knowledge, why we shouldn't assume the same for CS?
If I was a teacher and I'm going to teach someone what a linked list is, or what a binary tree is, I can of course use natural language and drawing, I can use abstract algebraic concepts.
But the student should be also able to construct said structures and observe how they work. The same for any other concept.
The upshot of this was that I didn't have a clue what Maven was until I started working, but you can learn tooling on the job.
It wasn't until the final year of my 4 year Software Engineering degree I used an IDE for the first time (Eclipse, actually) and I was totally disoriented, not understanding how all the magic was happening.
But for intermediate/advanced classes I think Java is a must learn for every CS graduate.
1. While it is bloated, it has so many modern and not so modern concepts into it, that learning it makes you understand those concepts better. (eg: It is hard to understand Generics if your favorite language doesn't have them)
2. A lot of enterprises (and major tech) backends still run on Java. I thin knowing it is a must to be competitive in the job market as a fresh grad
3. Learning Java (and probably disliking it) it will make you appreciate and perhaps make you better at learning other more nimble languages (aka. GoLang and friends)
CS programs aren't to let you make some easy money in the next few years. CS programs are to provide an thorough and high level of computing, from which writing code is just a small part. Having a CS degree much more than learning a language and framework.
If one's goal is just to earn some money in the next few years, he would be better served by taking an Udemy course.
University didn't teach me how to code, I did that myself before going to university. What it did teach was the why's and how's of computing without which I would be just a code monkey churning code without having a better understanding.
It is the same difference between someone who make an course learning how to repair electrical appliances and electronics and the engineer who designs them.
It'd definitely different if you work for an IT company, but not always.
For example, in C# IList<Foo> and IList<Bar> are two different interfaces that happen to have similar methods. Whereas in Java, List<Foo> and List<Bar> are the same interface. This means you can do things like this in Java:
List<?> list = ...
Object o = list.get(0);
To do something similar in C# is significantly more effort. You either have to duplicate all of your interfaces (IList + IList<T>), use `dynamic`, or use reflection to compile delegates at runtime.A common complaint is "but erasure lets you add an integer to a list of strings". But as long as you follow PECS[1] rules you can avoid most of those situations.
[1] Producer: extends. Consumer: super
C# creates one instance of a generic for all reference types. The general consideration in instantiating multiple versions is object size. All reference types are the same size, so not a concern. Value types, however, range wildly in size and so generally get their own specialized versions during code generation.
The same choice effects the ability to wildcard. C# probably could implement wildcards over reference types, but it would feel inconsistent without value types. And, honestly, a good portion of wildcarding in my experience is to handwave away the compiler when you know what you're doing without reified types. Simply not an issue in C# -- its stronger guarantees around generic types means I can make that same code generic over the type I'm wildcarding in Java.
In C#, you can do:
class MyClass : IList<Foo>, IList<Bar> { ... }
In Java, you can't do: class MyClass implements List<Foo>, List<Bar> { ... }
I know this is commonly viewed as an annoying restriction, but, IMO, it's rather an indication that you're writing code that doesn't respect the contract of the generic interface. For example, what should the `Count` property return if you're implementing IList<T> twice? (C# wiggles around this with explicit interface implementations, but I think it's fair to argue that that's not a strictly superior approach to Java's).Wouldn't have wanted it any other way.
Then I found this new kid on the block Python and it was a completely different story. I fell in love with programming and hacking in general and finally at the end of the study I knew enough of python to bootstrap myself with Java which I still think is an abomination.
Fast forward to 2 years ago, I did MsC at the same University and most courses were done using Java. I guess that's due to the long arm of Sillicon Valley.
Although Java was used for teaching material, the teachers allowed assignments in your language of your choice if the problem permitted. I did most of the assignments in C#. One I did in Java because I needed a powerful search tool and C# version of Apache Lucene was old. Other people used Java for assignments, one guy was using Python.
I have nothing against Java or using Java for teaching. I think it's better to use Java than Python since it has strong typing, enables parallel computing and it's faster being a compiled language.
However, I dread Java and I avoid it as much as I can. It feels verbose, boilerplate code is too much, it lacks some features. C# feels a lot cleaner. Even if it does have many libraries and enables you to target anything and do all kind of programming, it lacks the massive ecosystem of Java.
If someone would force me to choose between C++ and Java, I'd happily choose C++ if the task permits (i.e. I won't use C++ for web). And that says a lot since I am not very fond of solving the kind of bugs C++ almost guarantees you will have if the code is large enough. I'd rather solve C++ bugs than deal with the boilerplate and bloat and verbosity of Java.
That being said, I don't blame Java or people who designed Java and Java libraries. Allmost all old systems have their share of problems and Java is kind of old now.
Never programming languages and their ecosystems are solving some of Java's problems but if they will still exist in 20 years, we'll see they will bring their own baggage of problems.
I guess a perfect programming language is like an unicorn: we strive to catch it even if we know it doesn't exist.
What matters to me most these days is productivity, the speed something decent can be brought to market. By decent I mean something somewhat testable, somehow easy to understand in the future, somehow extendable and somehow maintainable.
There will always going to be trade-offs, making the right trade-offs based on the particular problem and resources is an art.
I can't imagine why people start teaching teens from C and Java and make them think programming is boring and annoying. Absolutely worse than not taking the class.
I struggled with the Java, but got my teeth into it on my own time to the detriment of my marks in other modules. Eventually it clicked enough, I got a degree and walked into a career where my skills have been in demand for 15 years. I'm pretty happy with that, I'd go so far as to say Java was by far the best part of the course for me.
I was thought through Java but it was all command-line and jacvac.
I did once sort a much better programmers final year project for him though - years later that I worked with - cos he had a CLASSPATH issue. That did make me realise there are people thought the way you say that miss some of the basics.
What I do instead, though, talk about the architecture and backgrounds, show different ways and let them make the mistakes that help learn to solve problems.
And you don't even begin to grasp what all those steps you just took in the IDE did until you're at least 1+ years in, and you don't learn what all of those magic words even remotely mean by at least halfway into your second semester.
I felt like every single thing I ever did was magic, never having a clue why it ever actually worked the way it did, and as a result nearly dropped out. The only time things _finally_ started to make sense is when I got to Computer Architecture/Organization with MIPS followed by some work in C.