Now I just feel stupid for working mostly in Java. (It's handy and it works. Leave me alone, okay!)
Now I just feel stupid for working mostly in Java. (It's handy and it works. Leave me alone, okay!)
HN is a very skewed place that's into some very niche stuff. That can be fine, it's good to be interested in new things, but no one should draw too many conclusions from trends we see on here.
Just to poke a few HN bears by way of example:
* Rust will never see widespread adoption. It's just hard and complicated, so seems cool and exclusive. * Lisp isn't gonna happen either, and that's because it's not even a good choice for most problems. It just feels really really cool when you write something in a purely functional way and so you imagine that _must_ mean this is some higher plane of existence. Not really, we've had 30-40 years for this thing to take off, not happening. * Even Erlang, while really cool, is just a super niche thing. If you're making a huge messaging service then definitely go for it, but you're making a website? Choose pretty much anything else.
There's a lot of reasons for all of the above (low average amount of experience leading to long term memory loss for the industry being the big one), but this comment is too long already and everyone's just going to be mad about the Rust stuff anyway.
Knowing that (as I did) why not expand your horizon (as I did) ?
What leads you to believe most Java programmers would prefer Haskell or some flavor of Lisp? You're saying that people who spend time in both will prefer the latter, but it seems equally plausible that people wouldn't spend time in both because they don't like the latter.
Still, this is a bit harsh to return your argument like this, because you're striking a good point: getting to know a language and its "philosophy of use" takes time. However, i do not see why not having taken the energy to climb out of your comfort zone to reach what is considered a better optimum by those who have would give any more weight, by comparison to the alternatives, to your opinion.
Edit: I have never used Haskell, but if I had to chose a next language to learn this would probably be it. Simply because people who use it speak of it as a kind revelation by comparison to the the way they used to program in their previous language. Also since I have worked for quite some time with the dynamic alternative in FP (Clojure) I might well try its static variant with Haskell. However as you pointed out, I'm not learning it because of lack of time/focus. Still that does not prevent me from listening closely to what Haskellers have to say, or say people from Common Lisp or even people attached to the JVM and its language ecosystem. Why ? because their experience is valuable. It's not just theirs, and it could way have been mine.
If you'd like, I can trade anecdotes instead - I used to work at a company with a large codebase consisting of nontrivial Java, Clojure, Scala and Haskell. Nearly every engineer I spoke to preferred Java (and I had to interact with nearly all the 300 engineers who worked on it).
Now at this point it may seem like I'm being a curmudgeon. But the reason I'm harping on this is because your implicit claim is that Haskell/Lisp are better languages for either productive or aesthetic reasons. But I don't think that's a fair statement - they're different languages, suited to different tasks. You shouldn't draw the conclusion that people who have e.g. moved on to Haskell from Java are representative of most Java developers. It's equally plausible that most Java programmers don't want to move on from Java, and so wouldn't like Haskell if they've tried it. Or perhaps they have tried it and simply didn't jive with it.
What tasks exactly do you think Java is better suited to than Haskell? The "innovation" of Java was to take the runtime of a high-level language and combine it with the productivity of a low-level one. It is not well particularly suited to systems programming or high-level programming (e.g. ML and analytics, parallelism, concurrency).
You never hear that point of view though, because they wouldn't spend their time on Hacker News discussing their favorite languages.
The idea that everything java is bad, uncool and for lesser programmers was here since java came out. It was not true back then and is not true now.
That being said, I am told my Java is very unusual: lots of anonymous implementations of interfaces, almost no inheritance, code that feels procedural in its local organization.
Languages have their runtime and their constraints, and there are some areas where maturity, tooling and explicit industry support trumps language quality.
C++’s template system is turing complete, which means its type language is too. That lets you move the vast majority of java runtime type errors to compile time.
Moving from Java to modern C++ is analogous to moving from spaghetti Python code to well-structured Java in my book.
Also, C++ is extremely well established.
Because I know (old) C++, some of the modern stuff and a bit of Java, I don't know the full history.
> That lets you move the vast majority of java runtime type errors to compile time
That's a huge win.
NullPointerException is a run time type error and quite common. I'm not convinced it's a problem C++ adequately solves, though.
I don't think NPEs go much beyond Java's own definition though. If you have a reference to a String, it's not necessarily of type String. You'd get a runtime error if you try to treat it as such, just like you would in Python.
This is not the case in C++, though obviously it's not an example of template metaprogramming.
Pointers, new, delete, malloc, free are all still there. But, you really don't need them any more. You can write large-scale programs using only objects, containers, iterators and unique_ptr (and shared_ptr if you can't clean up your design enough to avoid it). You basically get full memory management without garbage collection and while retaining RAII destructor capability.
"Optionally define this function based on these class properties. Else, define this alternative implementation" used to require a significant about of template boilerplate to pull off SFINAE. That has been cut down dramatically by if constexpr (). constexpr in general has been expanding to the point that someone wrote a compile-time ray tracer just to see if he could. Also, the oddly-named void_t makes it easy for if constexpr to "define this code if this statement will compile, else do this alternative". Between if constexpr, modules and a few more extensions (source_file/source_line?) there is a goal of eliminating 90%+ of the need for the preprocessor.
Functions with auto parameters, auto return types and containing some if constexpr can effectively be powerful templates without any <>.
Lambdas are obviously a shorthand for "functor" style class definitions. And, they can (auto)->auto.
range based for(auto &x:container) is much simpler than for(int i=0; i<n; i++) even though you are so familiar with for(;;) that you barely see it any more. But, even better, the standard algorithms spell out intent much better than a generic loop in 90% of cases.
Coroutines are already implemented in multiple compilers and are being standardized currently.
Variadic templates, parameter packs and tuples make wrapping arbitrary function signatures fast and easy.
nodiscard return types eliminate a whole class of errors. optional<T> return types are nice. The upcoming "zero-overhead deterministic exceptions" and expected<T,Error> are big improvements to error handling.
The point is that you can write large programs without ever calling delete or free() and still not leak memory. True, it's not completely general nor impossible to screw up. You still need to be aware of issues like circular references. And, using shared_ptr would make lifetime as ambiguous as a Java reference. But, if you keep everything a DAG of containers and unique_ptrs, not only will your memory thank you, your coworkers will too.
No, you don't. Reference counting is not equivalent to garbage collection.
Edit: Garbage collection has no problem collecting circular references if they are out of scope. Not so much for reference counted pointers. You will start leaking memory accidentally if you are not carefull - i.e. reference counting is not "automatic full memory management" - it will delete stuff once it's reference count goes to zero but it you will have to be careful not to come up with circular references that will leak.
Take MVC GUI programming in Java, which I mention because the thread is about Java, and considerable effort was made by the core Java team at Sun to make this work well.
If you use swing or awt and you call “longLivedThing.addEventListener(shortLivedThing)“ then you’ve written a memory leak.
The two options: (1) create a directed a cyclic graph encoding desired object lifetimes, and make sure references obey it, or (2) use weak references to manually break the cycles.
(1) is much easier in C++ because you can use rich reference types to get the compiler to automatically audit the lion’s share of your codebase. I don’t know of anyone that actually does (2) in Java because it makes it extremely difficult to reason about the actual runtime behavior of the program.
Operator overloading
The const keyword
C++ can guarantee stack allocations
C++ has faster boot times
C++ templates are more powerful than Java generics
C++ latency is better, which is important for some applications such as audio
C++ can manage external resources better using RAII
Not saying C++ is better in all cases, but it does bring things to the table that Java does not.
Python code quality is more a consequence of its beginner-friendliness (and subsequent prevalence of inexperienced programmers) than of the language itself. Similarly, the range of Java code I've seen goes from spaghetti within spaghetti (i.e. lack of structuring at both code and class/package level) over to extremely well-structured code
Never heard C++'s templates turing completeness described as some kind of advantage.
You write declarative specifications of your data types and it gets the C++ compiler to generate json serializers and deserializers.
(Note that C++ templates are a statically typed, lazily evaluates, pure functional language, so many of the advantages of Haskell, etc. can be shoe-horned into C++ types).
Moreover, when people say the like Java, what they really mean is that they like the JVM.
Want to know a language undoubtedly worse than Java? Easy. Append "Script" to it.
COBOL. BASIC, including VBA. Older versions of FORTRAN. All real languages used widely and in production, all far worse than Java.
As someone who doesn't program Fortran, but has read a lot of vendor Fortran (77' and 90') and C++, I vastly prefer Fortran.
No, I wouldn't use it for a standard enterprise app, but it really shines for numeric computing where it has a lot of what is required baked into the native language. It is very fast and no-nonsense.
That's because you're inexperienced.
And why would you think I’m inexperienced based on that view alone?
It doesn't take into account the purpose of the language, the ecosystem, the quality of the compiler, gc, et al, the evolution of the syntax and semantics, the available libraries, and so on.
It's just a knee jerk reaction (following old wives tales) of the "Java is verbose", "Java is slow", "Java is this", "Java is that", only staying at the surface level, and based on 2005-era enterprise Java coding practices.
True. But Kotlin was developed with 20+ years of hindsight, and Ruby is dynamic and pays by being slow for many of its higher level features that make it less verbose.
And even Java is much less verbose today, with "var" and "closures", and functional interfaces, and auto inference.
The main cause of verbosity in Java code was BS J2EE fashion (throw in all kinds of Patterns to make it "enterprise"). This -- the 2005-era practices as you say, are more or less a thing of the past now. Are some of them in use for new projects? In some sure, you can't immediately erase the influence of a decade of code and tutorials and such. But e.g. even J2EE itself in later versions got rewritten in a different style, Spring today leverages the new features and stuff like Annotations, verbose XML everything has fallen out of favor, etc.
Just because something is older doesn't mean it's not still useful. Many developers these days hold an odd kind of logical fallacy that if something hasn't been done in the last few years, it's outmoded completely. Many concepts still hold high value dating back 40 or 50 years.
Everything has its uses and has its faults. The great thing about software is that, given enough time, money, and people, it can get better. And Java has.
I wouldn't say my situation is great, most jobs are Java jobs :)
In fact, 10-something years ago, nobody really cared much on immutability on HN, while everybody still talked about Lisp and functional programming (it was all about first class functions, closures, map/reduce, recursion, DSLs, and macros).
Immutability come into the fore (well, for HN) along with Haskel and Clojure -- plus the idea that immutability gives you multicore for free.
Even in Paul Graham's essays, the "foundational documents" of this community, when he talks about Lisp he hardly talks about immutability as any kind of key point.
Common Lisp does not have the "equivalent of GOTO," it has GOTO. I don't know why you think that is a bad thing.
CL's go operator is a mechanism for abandoning the currently executing form up to just below an enclosing tagbody or prog, subsesquent to which, another subform of that tagbody/prog is selected for evaluation, identified by the label that was specified the go form.
The initial abandonment of the original form a non-local dynamic control transfer, with all the unwinding that implies. Then the final transfer to another form resembles an unconditional branch.
CL go will jump between function activations. A tagbody that has not itself terminated yet can be re-entered by means of a lexical closure. A jump out of that closure is possible.
For "just write a thing that works" I've come to really prefer C# for desktop apps and Python for small things.
You can of course write all your stuff from scratch like several vendors I know have done with C & C++, but I think that is the exception and not the rule.
The long-running programs I’ve used in other languages are architected so they respawn new processes regularly. Or they crash often enough on their own that they don’t get the opportunity to leak a ton of memory.
Of the 4 long-running C-family programs I use the most, 3 have crashed in the past 2 days.
Mostly agree on the other points. I do like Rust, but it's still young, and many potential areas of use just don't have mature library support with lots of features yet. And some of the community enthusiasm does get over the top - I'm sure not holding my breath for rewrite everything in Rust crowd's wishes to come true, no matter how bad memory misuse bugs have been - including the Linux kernel and the universe of GNU utils.
Suppose he didn't ask and just blabbed away? The trust he's developed over the years would be substantially marred. ("Don't tell Joe anything you don't want to show up on Twitter...")
Do I think keeping your tech stack secret is super important or that that secrecy itself is a competitive advantage? Hell no! Do I think it's still your call to decide what you disclose publicly? Of course.
Part of the reason is that if you're in the Java ecosystem, you can be very comfortable as it gives good performance, great mature tooling and libraries for almost anything under the Sun - so why would you want to leave it. And, there is enough demand that you'll be reasonably employed for a long time.
Which in itself is a reasonable argument, nothing wrong with it. But, on the flip side, if you want to grow as a computer scientist/engineer it is always good to look outside and broaden your horizons.
Of course, it might also be because people who have worked in a variety of languages are already 'used' to learning a new language.
We did use C# for two decades so it’s not completely a lie when we tell people it’s our main language, but it’s still a little silly to lie about it.
Because irrespective to if they want to keep their language secret or not, they might not want to be featured in Elixir's homepage, or have any of the other information they shared in a private message go public.
I'm not sure he did. His tweets say:
> However, I can't say who it is because they asked me not to tell anyone they're using Elixir.
And:
> ... we don't want or competitors to have, so please keep this inquiry private.
So in fact they might have just asked him to keep it quiet without him even asking about it.