"Hey Java is pretty much shit and here is this new better language called Scala, which you can use with your Java ecosystem!"
And I was hyped!
But, well then I saw the actual Java ecosystem...
Java itself is a pretty clunky language, especially for people like me, who did scripting language programming all the time and are probably not considered Real-Developers-TM to the Java folk. So the ideas of Scala resonated with me pretty much.
Anyway, after trying to configure stuff like Kafka, Zookeeper and Maven and setting up a SOAP API, I saw that the problem with Java isn't the language. Yes it's ugly, but JavaScript is ugly too, well even Python has its ugly parts. The problem also isn't performance, like so many C devs cry about daily. The problem seems to be that Java devs like to create things more complex than they need to be. Conglomerates of XML files, layers on layers on layers... I just don't know anymore.
I didn't use Scala for long and it wasn't because it failed me, it did, it brought its own complexity with implicit conversions and overloaded operators etc. but that wasn't the reason, it was the ecosystem which usage Scala enabled, the ecosystem that felt like it was still stuck in pre 2000. :\
> Anyway, after trying to configure stuff like Kafka, Zookeeper and Maven and setting up a SOAP API, I saw that the problem with Java isn't the language
* Kafka: is written in Scala. It doesn't use XML.
* Zookeeper: it was the first of its kind. It doesn't use XML.
* Maven: same complexity as SBT, Gradle, etc... but it is declarative and again pretty much first of its kind (dependency management + build).
* SOAP: this is not Java's fault (if anything Microsoft was the big pusher)
* XML: jesus will people stop the XML is complex and hard thing. YAML is so much more complicated and harder to parse. I know it is easy to read on the eyes but its harder to parse and has more edge cases. XML is still one of the few languages you can parse and manipulate and preserve comments and whitespace.
The XML thing is the dumbest thing. Developers write hundreds of lines of XML all the time... its called HTML (pedantically HTML5 is even more complicated since it allows SGML and XML style). But for some reason when people have to write a build or config file that they are rarely going to have to edit their fingers, eyes, and brains revolt at the complexity.
Scala also has some massively complicated libraries like Akka.
Ruby has Rails. When languages/libraries get mature they get complicated and the languages warts show more and more.
I expect we will see the same thing even with modern languages like Go and Rust.
The problem with Java+XML isn't XML itself, it's that the Java community for a long time was pushing more and more critical code into XML, because doing non-trivial dynamic things in Java itself can be a huge pain. And so over time, enterprise Java apps became giant balls of XML+Java that would break at runtime if you missed an XML parameter or had a stray character somewhere. At that point, what benefit are you getting from Java's static typing? You lose much of the benefits of Java, and suffer twice as much from its drawbacks.
This is slightly better with the push away from XML and toward annotations, but it's not much better. Your program's behavior still depends on tagging the right language constructs with the right magic tags, which is a horrible way to program IMO.
> The problem with Java+XML isn't XML itself, it's that the Java community for a long time was pushing more and more critical code into XML
You are going to have to show some examples.
> because doing non-trivial dynamic things in Java itself can be a huge pain
Actually Java has always been a fairly dynamic language. If it wasn't you wouldn't have all the XML and annotation stuff but code generation like you do in C/C++ and to some extent Go.
You have to remember one of the reasons why there was a shit load of declarative configuration in old Java for enterprise is because software was on premise software. Customers would have different databases, hardware, etc. And there was no way you could say to those customers: "hey how about you go recompile this and that" or "use this syntactically weird DSL".
Really the only better enterprise option back in those days was Lisp we all know how that played out.
> Your program's behavior still depends on tagging the right language constructs with the right magic tags, which is a horrible way to program IMO.
I agree/disagree. It depends on context. Annotations are declarative and thus IMO easier to not screw up and even easier to understand in many cases. Particularly for serialization and code generation. Most languages now have some sort of annotations and this is for good reason.
But yeah too much (annotations) is a bad thing. Java now has annotation overload (spring boot).... probably because people bitched about XML :) ... pretty soon will have convention overload as well (Spring Boot is heading down that path as well like Rails).
You can always take the explicit programmatic option... you know like wiring up your own beans and writing manual SQL but people want "magic". There is probably an even ground somewhere.
* Tomcat config (basically a pre-cursor to Spring in some sense)
Java is not a dynamic language, sorry. The JVM bytecode is fairly dynamic, but the language certainly isn't.
Also, I think Java would have been better off never introducing annotations. They have their uses, but they've been so over-abused that I would consider them a net negative on the language as a whole. I've been thinking about starting a blog, and one of my initial blog posts may be why annotations are bad for Java.
> * Spring startup config (this is basically coding in another XML-based language)
The alternative of manually wiring up beans or giving up and using shitty singleton patterns is pretty awful (remember this was preannotation days).
A pretty sexy annotation DI these days is Dagger2 but alas you seem to hate annotations.
> * JSPs (again, programming in a new XML-based language)
That is not an XML language unless you are talking about JSPX or JSF. It is a crappy templating language. Lots of languages have those (like PHP had Smarty or Pear...). I totally agree JSP and the future JSF was a horrible addition to Java.
A config that your IDE instantly knows how to properly setup and allows for massively powerful inheritance (see super poms).
If you import a Maven project with Eclipse or IntelliJ it just works.
Now I admit Maven is verbose and has lots of baggage but it has some serious pros and a lot of those pros are actually because it uses XML (like Eclipse can automatically adjust your Maven file without changing formatting). I have scripts that I have written in many languages (bash, python, etc) that can read Maven POM files thanks to XML. You can't do this with Gradle.
> * Hibernate config, mapping files
Yep that sucked but you hate annotations... so I guess you propose programmatically doing the mappings?
I despite hibernate anyway.
> * Tomcat config (basically a pre-cursor to Spring in some sense)
Oh like Apache config is any better. I mean seriously Apache has made up weird SGML config.
> Java is not a dynamic language, sorry. The JVM bytecode is fairly dynamic, but the language certainly isn't.
It is a dynamic language. You can instantiate classes by string names and manipulate their bytecode on the fly. You can call methods dynamically as well. Yeah it doesn't have the ease of metaprogramming like Ruby or Python but its its there through libraries (CGLIB).
Honestly I'm not sure what you mean by dynamic (please cite something) but I guess you mean interpreted and even that is sort of wrong as well (bytecode is interpreted by the JVM).
> Also, I think Java would have been better off never introducing annotations
Annotations also allow for preprocessing aka light weight macros. A full macro system probably would have been better. I look forward to your blog post (in all honesty).
You asked for examples and that proceeded to defend almost all of the ones I listed, which basically proves my point that this is how things work in the Java community.
You can call things via reflection, therefore the language is dynamic? You have a strange definition of what makes a language dynamic. By that definition just about every language is dynamic. In C/C++ I can dynamically load symbols, call functions by string names, call C++ constructor functions, etc.
I've never in practice seen anyone use compile-time annotation processors. In practice, annotations define runtime global variables that some frameworks make use of by doing expensive classpath scanning on startup to add or rewrite bytecode at runtime. These frameworks basically help cement java's reputation for having incredibly slow startup times while at the same time making it very difficult to understand how your code works. Even if you aren't doing classpath scanning to generate code, using annotations also introduces unnecessary coupling in your code in practice. The blog post will have some good examples I've seen in the wild. :)
> In practice, annotations define runtime global variables that other frameworks can make use of by doing expensive classpath scanning on startup to rewrite bytecode at runtime.
Dagger2 is DI a compile time annotation library. Yes there needs to be a lot more libraries like this.
I totally understand some of your hate for annotations (I have my own with Spring Boot).
Despite my tone from the previous comment I think there should be a lot more plain old programmatic configuration (ie just load up objects and setup some properties during the bootstrap).
I had aspirations of making a howto guide using Dagger2 and various other compile time / code generation libraries (like jOOQ and MapStruct) as I too absolutely hate the classpath scanning hell that is Spring these days.
I can't deny though that some people find the "magic" more productive particularly for ramp up time.
All in all I violently agree with you more than you think (hence why I'm looking forward to your post).
I still don't know what a dynamic language is and neither does Wikipedia for that matter [1]. Its pretty nebulous. Its like saying strongly typed.
Dynamically typed languages carry the types of values at runtime. That is, whatever is executing your code can look at a value itself and read off the type of it.
Statically typed languages check all of the types of their values at compile time to make sure that it's sound. Then, they can strip the type information from those values and execute them without having to perform any runtime checks.
In a dynamically typed language, the way to apply an operation is to read the type tag on it first, make sure the operation you want to apply can be applied to it, and then execute that operation.
In a statically typed language, that check happened at compile time, so you're safe to just apply the operation to the value.
Oftentimes languages may not be fully statically typed or fully dynamically typed. Java's use of reflection, instanceof, and casting means that it carries some type information at runtime. C++ has typid, C# has GetType(), etc. etc.
Haskell as a language has full type erasure and can be considered fully statically typed, but there are some. GHC extensions (Typeable) which point to some type information being held at runtime by the compiler.
> Actually Java has always been a fairly dynamic language. If it wasn't you wouldn't have all the XML and annotation stuff but code generation like you do in C/C++ and to some extent Go.
That's a point I never really understood. Code generation has it's downsides, but it seems vastly preferrable to the current mess of reflection: There seemed to have been a trend to move a lot of stuff that should logically occur at compile time to run time - therefore both adding a performance penalty and making debugging a royal pain - for what benefit?
There are some recent projects (e.g. Immutables and Dagger2) which seem to favour code generation over reflection again and I really hope this trend picks up steam.
> You have to remember one of the reasons why there was a shit load of declarative configuration in old Java for enterprise is because software was on premise software.
Which sounds reasonable - until you see real-world use where all components of an application are wired together with XML - even though for most of it, there is only a single setting that wouldn't break the application.
> Actually Java has always been a fairly dynamic language. If it wasn't you wouldn't have all the XML and annotation stuff but code generation like you do in C/C++ and to some extent Go.
You're equivocating on "dynamic".
Java is not a dynamically typed language.
It can be seen as "dynamic" in the sense that its behavior can be modified at runtime by external files. Then again, what languages can't?
> YAML is so much more complicated and harder to parse.
YAML has more complexity in syntax, but a data model that fits to data structures in programming languages (records/maps, arrays/lists, integers, floats, boolean, bytes, strings). As long as you do not implement a YAML parser yourself (why would you do that?) you should have easy times with YAML.
XML on the other hand is relatively easy to parse, but has a complex data model that maps well just to a DOM. For anything but markup text, you do not have a direct mapping to/from XML.
> Developers write hundreds of lines of XML all the time... its called HTML
There it makes sense, because it is marked up text you are writing and it is the right tool for the job.
> YAML has more complexity in syntax, but a data model that fits to data structures in programming languages (records/maps, arrays/lists, integers, floats, boolean, bytes, strings). As long as you do not implement a YAML parser yourself (why would you do that?) you should have easy times with YAML.
I mostly agree but YAML sounds like a serialization format and not configuration format to me.
I think a large amount programmers don't realize nor respect the history. Early Java proliferation was during the late 90s and early 2000 on-premise enterprise software. Customers required extreme customization but not all of them wanted to actually crack open and edit files.
The customers wanted to use tools and XML works great for bidirectionally editing not to mention there were shit loads of XML editing tools at the time (XML Spy).
> XML on the other hand is relatively easy to parse, but has a complex data model that maps well just to a DOM. For anything but markup text, you do not have a direct mapping to/from XML.
One of the reasons Java originally pushed XML is the support for it so good (tooling and editors). Java actually has great support for mapping XML to objects (JAXB).
If this is going along the lines of S-Expressions I say touche but it is what it is.
You need markup instead of code sometimes because you want declarative configuration. You want to sandbox a developer/user.
Yeah you can write declarative code in Scala (and many languages using Monads, macros or some sort of non imperative abstraction) using an embedded DSL... but it is embedded and hard to enforce someone from sticking a System.exit(1) somewhere.
Again If you are in the Lisp camp I submit there are better options.
>Kafka: is written in Scala. It doesn't use XML. Zookeeper: it was the first of its kind. It doesn't use XML.
Which is beside the point, since the parent complained about the needless complexity and layers, not just about use of XML.
>Maven: same complexity as SBT, Gradle, etc...
Which is to say: more than the task requires.
>XML: jesus will people stop the XML is complex and hard thing. YAML is so much more complicated and harder to parse. I know it is easy to read on the eyes but its harder to parse and has more edge cases.
It's not about whether it's easy to parse or not, it's about being easy to write and read when we're talking about a configuration format.
And XML in all its glory is hardly easy to parse, except if you mean by using a ready-made existing parser. In which case, everything is easy to parse (and most things, easier than XML to extract values from).
>XML is still one of the few languages you can parse and manipulate and preserve comments and whitespace.
Why would I care for "preserving comments and whitespace" in a configuration format? Except if I was doing something needlessly complex, like generating configuration on the fly on top of user edited configuration.
Which, the doing needlessly complex stuff, is what the parent complained about.
>The XML thing is the dumbest thing. Developers write hundreds of lines of XML all the time... its called HTML (pedantically HTML5 is even more complicated since it allows SGML and XML style).
Unless those developers are web developers, and especially front-end web developers, no, they don't.
And even if they did, it's one thing to write HTML in its intended domain, and totally another to have to write it (or specifically XML) for configuration.
In all, these sound more like "it's always been done that way" and Stockholm Syndrome than actual convincing arguments.
I'm curious... what do you propose instead of XML for configuration. You know that is standard and everybody knows it. Remember Java was/is very good at parsing XML.
> In all, these sound more like "it's always been done that way" and Stockholm Syndrome than actual convincing arguments.
And yeah it is Stockholm Syndrome because shit hasn't gotten that much better. Editing massive YAML or JSON files isn't really any easier IMO. You can't even put a comment in a JSON file and unless you are using Emacs I think even S-Expressions are not easier.
> It's not about whether it's easy to parse or not, it's about being easy to write and read when we're talking about a configuration format.
And XML in all its glory is hardly easy to parse, except if you mean by using a ready-made existing parser.
Except XML is extremely standardized and well established and yeah there are parsers in almost every language. JSON has changed its standard a ton of times. It actually is really hard to parse correctly [1].
> (and most things, easier than XML to extract values from)
XML has XPath and XQuery. Both very well defined and have backing standards. ie not a random github project just supporting one language which is the case for JSON path. IMO XML is one of the easiest formats to extract data from. Even CSV is scary to parse correctly.
>Why would I care for "preserving comments and whitespace" in a configuration format? Except if I was doing something needlessly complex, like generating configuration on the fly on top of user edited configuration.
Which, the doing needlessly complex stuff, is what the parent complained about.
It isn't needlessly complex if there are requirements for such. Maven was designed to be declarative and the hope was it could be imported by IDEs which it successfully achieved.
You know one of the reasons why Rails and various other easy to use frameworks came about is you don't need as much complexity if it is a hosted model. You don't need massive configuration if you are hosting and not delivering on premise software. So circa mid 2000 was the Rails crowd trashing the enterprise Java and probably deservedly sow.
However things are shifting back towards needing complex requirements because people want their cloud stuff to have elasticity, reliability, failover, etc (aka zookeeper) and that shit requires complexity.
People complain about the complexity of Java but I honestly think modern frontend web development is so awful today that I would take even old shitty j2ee over it almost any day (well maybe not that far but close to it).
> The XML thing is the dumbest thing. Developers write hundreds of lines of XML all the time... its called HTML
As if developers like HTML any better. I agree with you about XML being useful because it's easy to parse and the XML hate is overhyped, but that's not what he's saying, he's complaining about configuration hell that seems intrinsic to the Java ecosystem as compared to something like Rails which relies far more on convention than configuration. That's a cultural problem, not a language problem.
There are pros and cons to both ways (aka convention over configuration). That is hiding configuration complexity often get fixed with even more internal complexity except now it is hidden.
With hiding configuration your ramp up time decreases but your overall understanding of how the library/framework may decrease.
To offer the advantages of both requires even more complexity.
Which is actually what happened with Spring Boot. It is the Ruby on Rails of Java now and it is far more complex internally than the olden days of Spring 2.0 explicit XML.
At times I miss the old school Spring XML way. There used to be only like 4 tags (bean, property and include).
You're missing the forest from the trees. Java libraries and frameworks are complicated because Java the language is not expressive enough.
As I like saying, the status quo in Java land is Spring and Hibernate and people bemoaning Scala's implicit parameters never wonder why such monstrosities like Spring or Hibernate happened. Sure, blame the culture, but that's only half the story.
The same thing happens with other inexpressive languages. One of them is Python. And here we disagree again, as I think Python is chock full of ugly parts.
It started with refusing powerful and multi-purpose language features, like multi-line anonymous functions. As a result Python has been patched repeatedly with multiple non-orthogonal features to supplant the need for multi-line anonymous functions and/or to make up for its statement oriented nature. Oh, now Python 3 got await/async as well, but somehow I don't think this will stop people from monkey patching the socket module. I'm going to make the claim that in fact Python is not a TOOWTDI platform, in spite of its much touted "spirit" and anybody making that claim never tried working with Gevent or Eventlet, trying to make it work with MySQL's client and being forced to use the native client because Django wasn't compatible with the pure one. Or with an N-th iteration of Ruby inspired libraries that hack into its meta programming features to make it smell like the DSLs in Ruby, but with limitations and leaks. I don't even want to talk about the build and dependency management tools in Python's land, because it should be self-evident how broken the Python ecosystem has been.
Another language in this category is Go. It's still young enough that people haven't used it much outside the niche it was created for and doesn't have much reuse going on in libraries. Give it time, you'll see the same pattern, same mistakes repeated again and again. Java was also a pioneer in dealing with concurrency, Java introduced generics really late and it was also built by famous engineers working for a sexy company, designed to appeal to beginners and managers.
No. It's not the Java language. It is the developers. They are the ones who have to have 35 levels of abstraction. Why? Because for some reason they think this will make modifying the software they write easier. In reality, no, it doesn't because everyone gets frustrated wading through the abstractions. If I can hold ten items in my brain's working memory and all ten are taken up by keeping track of how many levels deep I'm in, then it is really hard to make any real changes to the code.
haha thanks for sharing that, one of the most absurd things I've ever seen. Every once in a while I think about picking up Java or .NET and going for the enterprise-y jobs...no thanks.
its beautiful, not only is it absurd and hilarious, but it says so much. Not as a direct diss to java, but how badly a simple task can get over-designed to the point of being indecipherable. What would be great is if they added some kind of CRM or e-commerce to it, and donated the proceeds to charity. So like, could "Pay as a service" or sign up for "fizzBuzz as a service" and pay to run fizz buzz up to certain limits.
It's not a language causing shitty abstractions, it's not a framework causing shitty abstractions. It's shitty developers.
One can write a Java application and never touch XML, use AbstractFactoryWhateverTheFuck, and write sane, clean code. I've done so for years, worked on green and brown-field projects. I've also written, maintained, and modified monstrosities in Java... as well as C#, Javascript (front and back-end), PHP, Python, and plenty more.
Java is not the Hot New Thing™ and never will be. It's also not always the answer, but for a run of the mill application running on a web-server you're going to have a hard time finding a better language and ecosystem that will keep on trucking and be reasonable to work with.
The presence of many of these frameworks, spring, AOP etc, is proof that many people do not find Java reasonable to work with. If Java was sufficiently expressive, you would need only libraries.
Not parent, but for example, this is how easy serialization is in Scala Play in the majority of cases:
case class Person(name: String, age: Int, likes: List[CustomObject]) //simple data object
implicit val personFormat: Format[Person] = format[Person] //this creates a "Format[Person]" with serialize/deserialize methods
The code to generate a serializer/deserializer is completely independent from the definition of the data, no annotations or XML needed. It is also efficient in that it doesn't use reflection. This is only possible because of how expressive Scala is - macros and strong type system means a lot of powerful code introspection can be done at compile time.
Because of implicits, most of the time I write that one line above, and an HTTP handler as a simple function from (Person => HttpResponse) and dont even think about the serialization/deserialization. And that one line is not an opaque abstraction, it is very customizable if you need it to be, and all via code not config.
Using Jackson in Java can get much more complex because annotations and XML files creep across the whole code if you want compile time generation. I think this is directly because Java's inspect/generate code at compile-time is not as powerful as macros.
Everything has a cost. As I said, frameworks do not compose and often fundamentally take away control. If you want to change the behaviour of your framework, you need to hope they have created the necessary callback interfaces.
> If I can hold ten items in my brain's working memory and all ten are taken up by keeping track of how many levels deep I'm in...
If you find yourself doing this, it is a clear indication that the software design is failing to abstract properly or at all.
(I'd argue that the industry in general has a terrible ratio of "coders" to people who can design programs, thus you're much more likey to come across poor designs than good ones. Beware of this when judging programming languages.)
> a clear indication that the software design is failing to abstract properly or at all
I believe, it is an indication that people tried to fix all the leaks in the abstractions, which turns the abstraction into an ugly twin of the stuff it tried to simplify.
ORMs are a good example. They start easy and simple, but lack various features of full SQL. If you start a new project, the ORM is fine. At some point, you are forced to use plain SQL, which clashes horribly with the ORM concepts. Thus the desire to extend the ORM. Over time more and more features are bolted on and the complexity grows.
IMO that's still bad design on the end user of the ORM library. There's a time and place to use tools like Hibernate, but it became fashionable so it's used all over the place where it doesn't fit and has created huge messes.
There's a really bad trend in the industry of choosing libraries or tools based on trying to improve your resume, rather than trying to find the best solution to a problem.
I've worked with a number of ORMs, mostly home-grown, admittedly.
I've yet to see a good one.
Often ORMs fail to implement JOINs efficiently.
Every ORM fails to give you a powerful query language: if they had a powerful query language, someone would write an ORM for the ORM, because the reason ORMs exist is that "SQL is hard", as the doll says, and any powerful query language will get the same treatment. But SQL is not really hard, and not having SQL eventually means you pay a huge price.
And then there's things like LDAP, which are absolutely awful. LDAP's object naming scheme has no canonical text representation. Let that sink in. And that's not even the main problem -- forcing your database to be hierarchical and a collection of objects, with no standard relation/pointer type, is. (Yes, Active Directory has an Object DN type, I'm aware.)
This is a well known issue [1], and isn't due to ORMs being poorly written.
It's not true that people who know SQL always prefer using it to using an ORM. In one of my prior jobs we had strict controls on the queries that ran in production for performance reasons. We screened all of the query plans the planner generated, but we also used an ORM. Sometimes we needed to work around or even reimplement the queries that used to be in SQL due to niche features like index hinting or the HAVING clause. And yet usually we used the ORM because it was more concise and reduced manual mapping of columns to fields.
I disagree, it is some developers. Just as some developers can create a big ball of magic code dynamic code or as some developers can make insanely cryptic code in Scala/Haskell that looks like the user is typing in windings.
Java 8 and the current ecosystem can be incredibly lean and devoid of high levels of abstraction. Like today how I took the lovely Sinatra inspired http://sparkjava.com/ out for a spin. I think if Java can shed the memory of it's horrible past (and the enterprise space was truly bad) then it has a lot to offer developers these days.
I agree that there is a Java culture, but I also think that it developed into the way it is because it was so popular during a time when there werent very good engineering practices by non-technical people. The movement towards wanting managers with a technical background I think is fairly recent. The majority mass of java developers now probably "grew up" in the jaded horror story environments we seek to avoid.
Also, i think new grads tend to only know how to make things dry via abstraction (not considering the trade offs) and b/c of javas popularity and oop as a buzzword, always did it via inheritance.
I'm not sure you can really separate the two. Sun pushed out the language and also helped develop much of the culture (enterprise beans, the pet shop example). Languages shape peoples thinking.
Java libraries are complex because Java is inexpressive? Not because the libraries attempt to do everything for every situation? Are there some concrete examples you can point to?
It has been my experience and observation that something like a JMS library in Java are complex because of a different interpretation of "do one thing and do it well." In the Java world, possibly because of enterprise adoption, that means pluggable transport for the queue, pluggable aaa, pluggable security and encryption, pluggable durability storage, configurable delivery protocols and guarantees, aspect based hooks to support different ha patterns, pluggable dispatch on delivery and probably some other things I can't think of this early in the morning. Each JMS implementation is "the best damn message queue ever made" with tons and tons of features. That's not an expressiveness issue, unless it's too expressive. Java makes it easy to add a layer of abstraction at each of those decision points. The typical user here wants to get a message from one piece of software to another, maybe with ordering; JMS will do that more ways than you can imagine or care about and can use pieces of machinery you didn't even want to know about. Where does expressiveness play in to that?
> Java libraries are complex because Java is inexpressive? Not because the libraries attempt to do everything for every situation?
Why do these reasons have to be mutually exclusive?
Furthermore, your second point relies on every single cumbersome/complex java library also being a perpetrator of trying to do too much. Surely a lot of people here can probably think of smaller libraries that explicitly don't try to do everything, and are still "complex" and cumbersome to use. The best examples I can think of were of internal libraries at previous jobs, and that happened across many languages not just java. These sorts of annoyances pop up repeatedly in a wide variety of languages, despite not necessarily having the same culture as java.
Not to play evangelist here, but I just haven't had as many of these kinds of issues with libraries since switching to more modular typed functional languages (i.e. ML/Haskell), and it has really played a role in helping me see the forest instead of the trees. Noticing how language complexity and inexpressiveness leads to those kinds of problems isn't supposed to be obvious or intuitive, because it's effectively a Butterfly Effect that causes most of its severe repercussions much further down the line. We can play whack-a-mole with smaller sources of complexity (such as java having kitchen-sink libraries) as long as we like, but shouldn't the goal be to hunt down where all those "complexity moles" are even coming from in the first place? Because if that is the goal, and even smaller more focused libraries still produce annoying amounts of incidental complexity, then there's not much room to blame anything other than the constraints of the language at that point.
> Java libraries and frameworks are complicated because Java the language is not expressive enough.
I have written Java code and rewritten code large parts done by others. The issue I have noticed is architecture and framework mindset of people who just do not think solving problem at hand is important and good enough task. It would be ok if they wrote elegant library/framework but it was still junk and solved only very narrow problem. At each instance it was the problem of culture and people using Java because I was perfectly able to write productive and simple code with just standard plus very few extra libraries.
> Another language in this category is Go. It's still young enough that people haven't used it much outside the niche it was created
Huh, may be you should be able to give example of highly expressive and popular languages which are a hit with developers in very different domains. Because it is easy to pile on popular Java and increasingly popular Go without talking about alternatives.
No Java is simply not expressive enough, that's why so many frameworks exist. Adding Lambdas certainly helps, but you are missing out if you restrict yourself to Java.
Let me give an example of how Java limits ones thinking.
They are great examples of Java/C# users being unable to explain succinctly what the APIs are doing, because they lack the necessary common language. They have to answer with great essays describing various scenarios and use cases.
A Haskell user just needs to compare the type signatures, showing where the IO is happening. She will then understand the differences and the implications.
I guess I am not obsessed with expressiveness. I think of programing as something to help business/users to get on with what they want to do, as opposed to exercise in elegant self-expression. Towards that goal Java, Go seems very fine languages to me.
But as my example pointed out, expressiveness is often the difference between being able to understand something and not. Expressiveness permits better abstractions, better composition and better libraries, allowing cheaper and faster software. Something business users will appreciate.
I do not disagree that Java, Go could be better. It is just that I remain big sceptic because such better languages leaves very important things which matter in real world and covered by Java, Go etc but not by better languages e.g tooling, GC, powerful runtimes, build tools and so on.
I would wait till Scala does something great natively without standing on shoulders of JVM/JRE etc.
Python does not lack power. It's a different problem.
Monkeypatching is everything you need in terms of power. The problem is that it is too powerful, and Python lack intermediately powerful constructs. So if you have a problem that could be perfectly solved by passing around anonymous functions, creating a DSL, or writing some macro, you will either write everything by hand, Java style, or use monkeypatching and get a mess of mutable code.
Still, monkeypatching will solve the problem. It is more powerful than any of those other features. It's just that killing your fly can be best done with some small tool, and cannons leave a mess wherever they are used.
The last time I looked at Python (which was something like a decade ago) the impression I was left with was that there was a sort of cognitive dissonance or collective self-deception going on. There was a simple, clean language subset which was the one presented in the official tutorial, by and large; and lying underneath there was another language full of introspection and underscores, which seemed to be necessary to get (many) things done without a boilerplate explosion. The impression I got was that everyone writing Python was convinced that those other guys didn't need to think about these dangerous, advanced features, but they were in the 10× hacker elite for which the power was necessary and appropriate. Now probably that's an exaggeration and somewhat unfair, but I think it's probably not completely wide of the mark. ;)
My experience with Python is that 90+% of your code base can be in the "nice" subset, but it requires some discipline. The key is to always, always, always encapsulate the complex parts in helper functions or libraries, and accepting that maybe it isn't worth making your code twice as complicated to save a single line.
The official answer from any Python developer to anybody asking about "magic" is "do not use it". It's simple, gets the message across, and when the ones asking are experienced enough to not need asking about it, they'll just be one disaster away from being experienced enough to know when to use it. (There are plenty of resources on how to do it. Just no assurance that you should.)
Overall, it's a more useful response than the Ruby's community one. Ruby seems to have inherited the Lisp propensity of meta-programing everything so many of its basic libraries are incredibly hard to follow. Even with Ruby's metaprograming features being easier.
Still, providing safe metaprograming features sidesteps everything. I do love Haskell.
Go is as old now as Java was when Spring and Hibernate started to appear on the scene. If it time leads to this kind of pattern, why was Java 'over the hill' by this age, yet Go is still considered young?
Java was adopted very rapidly (as soon as it ran acceptably on commodity hardware) because the industry desperately needed a safe subset of C++. The pain point addressed by Go is mostly deployment and packaging, which is why mostly devops (who have rejected OS packaging for some reason) are excited about it.
> The pain point addressed by Go is mostly deployment and packaging, which is why mostly devops (who have rejected OS packaging for some reason) are excited about it.
What happened to OS packaging was mostly a result of the arcane tools around .debs and .rpms, which led to sysadmins reinventing the wheel (poorly) using symlinks, tarballs, and shell scripts.
FPM helped to a great degree, but even then, what if you want two different versions of the same application on the same machine? And if you hack your way around that, how will you manage which instance of the application gets which port?
When Docker came out, that kind of ended the idea of using OS packages for deploying in-house applications. Why bother with a packaging infrastructure that will only tie you to a certain OS?
I still think OS packages have a place, especially for system level software. Nobody ever complains about how SSH failed to install or upgrade...
But even when using containers for internal software, Dockerfiles can still be a pain to deal with for the simple reason that most languages have horrible build-chains that produce unusable outputs, which as you said Golang addresses beautifully.
However I think you're off the mark when you say "mostly devops" are excited about it. It's entire companies that are excited about it, and for one simple reason: Languages with these bad build chains and bad outputs have led to the creation of an entire teams of people to deal with it.
The realization of this is spreading, and it's going to be an interesting time.
But, if Go hasn't already achieved the same kind of adoption after this many long years, doesn't that suggest that Go will always be relegated to the niche it was designed for? In which case, according to the parent, it won't need to adopt those patterns in the first place.
Kotlin is a cool language, but doesn't do enough to differentiate itself from Java 8.
There are real benefits to picking the mainstream / popular option, which includes tons of documentation, forum discussions, books and developers available immediately for it. So when you go against the mainstream, those alternative tools have to be worth it.
I think Scala got over the worthiness threshold, by exposing one of the best OOP implementations exposed in a static language, sane generics, higher kinded types and implicits which make it possible to encode type-classes, which led to a community emphasizing on functional programming.
I think Kotlin isn't over that threshold. Some people view its thin layer approach to be an advantage. But it either has to evolve in being more than that, or to divorce itself from the JVM, because it is in direct competition with Java 8 otherwise. Evolving to be more than a Java++ goes against its own philosophy. Divorcing itself from the JVM is a work in progress, they also have a Javascript compiler, but the results aren't convincing enough for now.
It's a nice language, but personally I like those with a strong community of functional programmers and libraries. If I'll see http://typelevel.org for Kotlin, I might reconsider.
> but doesn't do enough to differentiate itself from Java 8
Short of implicits and higher kinded types what has Kotlin not yet copied from Scala? FP in the pure sense is still very much niche, nobody cares about Scalaz and Cats in Java land.
Providing a less powerful Scala as an alternative to Java might very well prove to be a great strategic move. Scala's certainly not going mainstream anytime soon, probably in part due to its being too powerful.
Going on 6 years in Scala, staying put for now, but will jump ship if/when something better comes along (for me Kotlin is not it).
I find Scala enormously impressive because it manages to bridge the gap between subtyping. Not sure whether that is worth the complexity this brings, though.
Subtyping makes a lot of things that are easy in purely functional languages hard. I think that is also the main reason why you don't get global type inference.
Thinking of it, SOAP is the most Java-like thing taken to the extreme that I can think off.
Needlessly complex, dozens of imbricated layers that no one knows why they even exist, cult of "the library and server will do it for you, you don't need to know how that works", and when the library invariably fail on some obvious stuff you're left hanging with inscrutable XML files and no decent way to debug the exact layer that fails, with every thread mentioning that issue on the web being met by a variation of "you shouldn't be doing that" or "add this additionnal middleware layer to solve it"
I had to write a SOAP endpoint last week, because the dev in the other company didn't like REST.
It was just one endpoint, that took a set of values.
Took me a few days to get the WSDL right, because no good examples or tutorials were to be found...
In the end it took me 80% of the time to figure out that I had a wrong XMLSchema version used to define my types. Only some heavy XML IDE found this bug, all validators just told me that I didn't define any types, haha... well at least I learned something in the process :)
Yeah my first project ever on Java was an API with Spring Data Rest connected to Oracle. 80/90 percent was config and issues w connecting to Oracle. Spring Data Rest was very nice.
I admit to never having to tame that particular beast. And given the sub comment about it being on the same greatness level as SOAP, I think I may pass :D
Yea, the hobby projects I do using the JVM (currently working on a side-project written mostly in Clojure) look completely different from the eleventy-layers-of-abstraction design-patternsplosion programming-in-xml garbage you're forced to work with at your typical Java shop.
The culture in Javaland is a huge problem, and Scala doesn't really help with that. I'm constantly butting heads with Software "Architects" because, among other things, I tend to prefer building my programs using small libraries rather than uber-frameworks like Spring. I suppose my main problem is that I didn't start my career in Javaland, so I didn't get indoctrinated properly.
I'm not sure if it's a question of indoctrination; I'd prefer to think that it is much more a lack thereof. Many things are "developed" without any appreciation of elegance - and the bit of old, overdesigned and overcomplicated C++ code I've seen tells me that Java's culture problem just stems from everyone moving away from there and continuing their style in Java-Land.
No language will ever be able to combat this - the only strategy you can have is to make your language so different and confusing to regular people that they won't use it; but I doubt that would result in good languages being created.
If you have a look at how modern C++ is presented and explained nowadays, there's much more focus on readable/useful code and actual design. Many language communities go this route (Clojure, Python, what have you), but that doesn't stop the average Joe to ignore those advices it if he so desires.
Add in some crunch time where everything must be implemented ASAP and without consideration of the consequences and voilà: You end up shovelling snow around[1].
That being said, I especially like Clojure's approach to things. For example: Turns out good, maintainable C++ uses const almost everywhere - to avoid messes, you try to encapsulate mutable parts as much as possible (unless performance dictates otherwise). This is a thing that is still very clunky in C# and Java (and it seems very much overkill to use virtual inheritance for this. Say hello to IReadOnlyDictionary<T>). In contrast, Clojure makes almost everything read-only and uses mutation at very specific points. This is great - although of course you won't be writing any high fidelity videogames this way.
Edit: Of course, when I say elegance, I realize that it's very hard to get actual things done from the Tower of the Elephant Tusk[2]. But yeah, stopping once and a while to understand/consider your problem and possible implications of your implementation gets you a long way.
> The problem seems to be that Java devs like to create things more complex than they need to be.
This is the biggest myth! Like seriously how does using a particular language make you want/enjoy making things more
complex?
Why is Java (ecosystem and language) complex? Because Java has a massive very old ecosystem with organizations that have extremely complicated requirements.
Someone else argued Java is complex because it isn't expressive. This is a myth as well as clearly Go language proved you don't need powerful types or annotations to be simply.
Let me give you an example. The Java JSON parser Jackson. It is beloved and yet It is seriously freaking complicated!
Why is it complicated? Well lots and lots of organizations have different requirements.
Most of the libraries in Java that are mature are extremely complicated! They are this way because of requirements and evolution.
Scala is complex but it hides it (and I guess some would say elegantly). I prefer being explicit and so do many Java programmers consequently the complexity is sadly exposed.
There is another language rapidly evolving on the complexity front: Javascript.
The ramp up time alone with modern Javascript is now close to being worse than Java (the transpiling, tools, etc).
>Like seriously how does using a particular language make you want/enjoy making things more complex?
It's not the language, it's the community that uses the language. It's working with people who tolerate working in that language and with that sort of people. The Java community drives out developers with an aesthetic revulsion for things like a ShoelaceTyingStrategyFactory, and you're left with the dregs.
In short, the causation is backwards - folks who want to or enjoy making things more complex end up using Java more often.
> In short, the causation is backwards - folks who want to or enjoy making things more complex end up using Java more often.
That is complete utter nonsense. Developers most likely use Java because
1. they have to which is the case for Android or using existing libraries/code base or
2. because they already know it which is typically caused originally by number 1.
3. The language is still one of the popular language so for many it is a safe bet.
As for ShoelaceTyingStrategyFactory... I have seen that crap in Typescript, I have seen it in C#, I have seen it in Objective C... Its caused by complex annoying needless requirements.
See what happens with Java can happen with any language where you are don't have a proper development process of removing needless requirements. You end up with complexity. And yeah sure some people enjoy solving complex things and making it scale but the neither the language nor the community caused that.
Now if you are talking about the spec writers like the JSR authors... yes those guys actually had it in there interest to make it complex because their company would be the only company that could make a reference implementation (for example Day software with JSR 283). But this is not the Java developer community as a whole.
I'm making the exact opposite point. People use Java for whatever reasons, it's not really a contributing factor. People avoid Java because of ShoelaceTyingStrategyFactory reasons. How likely is the average Java developer to make a ShoelaceTyingStrategyFactory when you convince the vast majority of people who avoid that sort of thing to use a different language?
> Why is it complicated? Well lots and lots of organizations have different requirements.
A sane culture would produce couple of simple libraries solving different requirements. Insane would throw solutions to all the requirements and a kitchen sink into one big ball of mud mega-library.
> A sane culture would produce couple of simple libraries solving different requirements. Insane would throw solutions to all the requirements and a kitchen sink into one big ball of mud mega-library.
Even Spring doesn't do this. Most Java libraries and frameworks are highly modularized via Maven.
Most complain they are too modularized and want an uber jar.
> It's not that hard to write a JSON parser.
Actually it really is [1]. You know a valid one that handles edge cases... something a lot of Java libraries do really well... handling edge cases requires complexity.
Java frameworks are made for very large enterprise systems operating at high scale. Not for startups or POCs or personal projects. Frameworks for that actually exist in Java too, but they are harder to find.
Once you know Spring, it actually makes you faster at building robust systems. Hibernate too, though SQL is easy enough I'd recommend against it, but c3p0 is a must for robustness, and hibernate does make it easy to switch to it.
Now, Java is akin to PHP in that a lot of devs use it at small to medium size companies that don't always value tech. This means a lot of Java is written badly, concepts are misunderstood, best practices like layered architecture, interface indirection, class inheritance are pushed to extreme nonsense and abused greatly.
Kafka and Zookeeper and Maven are hard to setup, but it's because they solve very complex prolems. I don't know any other open source dependency manager who offer the robust features of maven like self hosting, build and dependency resolution all in one and signed artifacts. Zookeeper is like the only coordination frameowrk that passes Jepsen. Kafka is unmatched in its special use case too. You're playing with framework handling highly complex problems, you shouldn't expect the easiest learning curves.
Why are you even playing with these? There's very little project that would need such beasts.
I've always said Java was the first language ecosystem that let developers write code they neither understood nor could manage. I've been doing this long enough to remember what life was like pre-Java, and I did not at that time have a lot of conversations with developers for which their contribution was "I just use the foo framework, I don't really know anything about it."
So congrats to Java for helping shitty devs get shitty code to production faster.
I remember saying python at an IT company once and they were about to expell me from the building. Their face showed à deep '3 seconds of my life wasted'.
So many cool things have been build with Ruby, JavaScript, PHP and Python...
At university my OOP professor was all about how these languages aren't "real" programming languages, like Java or C#. And when I meet people working at older IT shops, that do Qt or Java, they all feel superior.
How intellectually lazy of a developer do you have to be to use Java, stick with it and think you are better for using it than other choices? Wonder if your prof has ever even tried paradigms other than OOP
> The problem seems to be that Java devs like to create things more complex than they need to be.
This was my experience as well when I first tried to experiment with Kotlin for backend web development (coming from a py/rb/jS background).
I would still happily use Kotlin if I had to be on the JVM, but I came away with the impression that most – certainly not all – of the libraries and tools in the ecosystem are... not to my taste.
Out of curiosity, what is the scale of the projects you've used these technologies on? LOC, concurrent users, years of operation... As you can probably guess, I suspect that Java and it's ecosystem are created for a different scale, where this abstraction suddenly ceases to be excessive.
I suspect most Java devs "think" this is the case and do this "abstractions for big scale" all the time, even if 99% of the project would do better without it.
May be. I have a different perspective - I'm now supporting a legacy NodeJS project which would desperately need more abstraction, but the original author was really into "getting things done" mentality and didn't think about future maintainer (me) at all. Magic strings, implicit hierarchies, code duplucation, different entity id scheme on client and server with hackish "translations"... I would give a lot for my project to have a little more of this Java "Enterprise" style right now.
After doing this shit professionally for more years than I could care for anymore, when I see programming language or framework comparisons I immediately think of something like[1]:
"Why Klein Cushion Grip screwdrivers are better than Wera Kraftform screwdrivers", or in this case "The myth of using Kraftform as a better screwdriver".
And then I imagine myself going back to using my shitty old Phillips screwdriver set to screw in a few screws in a non-optimal fashion and someone might say "Wow, thanks for hanging my door!" and I imagine the surprise on my face as I realize that people want functioning doors and are not too bothered about which brand of screwdriver was used to achieve that.
What a crap, supercilious comment. Yes laypeople want functioning doors, but this is not an article for laypeople, it's an article for engineers. What we want are tools that allow us to build performant, maintainable, reliable code.
Besides, if all you do is to fix a door than you may be right. But we build entire tower blocks, with doors, windows, elevators, ventilation systems, structures able to hold up tons of material, and all the rest. Your screwdriver metaphor may be good go way to score a cheap point with strangers on an internet forum, but not much besides.
I used Angular Material to build a website. I dunno if you've ever been to the Angular Material website *https://material.angularjs.org/latest/), but check it out if you haven't. You see that nifty looking navigation bar on the left? You can't actually build that using Angular Material given all those wonderful components they list there. There are entire blog posts created so you can make a similar looking navigation menu [1][2]. There are so many things missing or incomplete in this framework that you'll only realize when you try and build a "real" application with it. Guess what? Angular Material is dead. All the developers decided to start over with Angular Material 2 because there's a new screwdriver brand in town: Angular 2. Yay for the people who just want functional doors.
Let's talk about Material Design Lite. Go check that website, especially the components page (https://getmdl.io/components/index.html). It's really nice and responsive, try changing the size of your browser window and see how the navigation bar collapses to the top. Damn this looks like a great framework, I'd like to do the same thing in my app. Imaging the surprise when you can't actually do that using the framework out-of-the-box. Oh by the way, forget about MDL, all the developers have moved on to Material Components for the Web (https://github.com/material-components/material-components-w...). So much for the guys who just want to hang a door, there's a new brand of screwdrivers on the block.
It would be great if the so-called "engineers" could spend some more time creating a complete toolbox instead of reinventing new screwdrivers every month.
In my experience, this is a much bigger problem in web programming than elsewhere. Take the JVM, for example, since it's the subject of the article- it's been around for decades and while things have changed, you can still pretty just just keep using whatever you're using without fear of the developers jumping ship for something shiny.
Indeed. Also, in more sane / stable areas of the industry, the code doesn't rot so fast. Java is relatively backwards compatible down to version 1.5 or so. In Common Lisp world, the code written more than years ago works perfectly fine without need for any change.
You're not wrong. I am an Angular 1 dev who's in the process of moving to Angular 2 and even that is an up-hill battle. However, I think it's about picking the right tool for the job in that the batteries-included / opinionated nature of Angular is great for once you start scaling a team AND/OR you have a product that you need to keep shippable at all times.
I get that this is the easy way to see it from the outside, but:
- You don't have to learn every new framework. Google has 10k+ Angular 1 projects, this stuff doesn't go away after hitting critical mass.
- This constant iteration has lead to multiple production-ready UI paradigms that were just relegated to FP research. Try using Angular 1 or vanilla React, and then do something with vanilla Android. Or GTK+. Do we want GTK to be our baseline for UI work? Qt is nicer, but it's definitely playing catch-up.
You can poke fun, but there's a reason everyone opts for things like Electron. It's the most satisfying way to build frontends for a lot of people.
Wouldn't really say that I am seeing it from the outside. Have done some web frontend projects last couple of years and also used Electron for a project. Starting an Angular 1 project now is comparable to doing Windows desktop applications in MFC, and Angular 1 is what, 6 years old?
And the only satisfying thing about Electron, is hitting package and getting three platform-specific binaries. Otherwise, it is still web frontend development. In contrast, I have had the pleasure of doing desktop development in Qt and WPF, which was quite enjoyable (and the ecosystem has not changed a lot since I left it years ago).
Also, MVC and MVVM were UI paradigms before web frontend development. And I am quite sure I heard about ReactiveExtensions before Facebook React.
The constant iteration has definitely led to more production ready UI platforms. But once they are in production they are largely abandoned in favour of "shiny new thing 2.0". The rate of change on the web development side is simply too fast to keep up with especially with regards to tooling.
The primary reason to learn new web framework all the time is that current are still not quite there yet. It needs more maturation till it can stabilize into something good enough.
Is JavaFX okay? Or maybe even good? What's wrong with it? (Not polished enough, not maintained enough? Not updated fast enough?) RxJava seems pretty okay.
Off the top of my head: misses some UI elements / widget types (spinner / numeric entry). UI bindings require a lot of manual converters instead of doing conversions that p.e. WPF does out-of-the-box (like double to string when using a text box; principle of least surprise).
And (the worst) it's not conceptually compatible to the model classes (abstract tree model) that almost every UI framework (including Swing) provides. Instead, tree nodes have to be manually instantiated).
> UI bindings require a lot of manual converters instead of doing conversions that p.e. WPF does out-of-the-box (like double to string when using a text box; principle of least surprise).
You can use String.valueOf, but usually don’t want to do that. And how do you want to represent the float? With Scientific notation, Engineering notation, or purely decimal? This is not simple.
> And (the worst) it's not conceptually compatible to the model classes (abstract tree model) that almost every UI framework (including Swing) provides. Instead, tree nodes have to be manually instantiated).
Or you use the FXML bindings for creating them from XML?
Don't know about the OS X problems much, but on Linux it's workable with FX (our product is actually used on both Windows and Linux). OTOH, Electron achieves its portability by shipping the whole Chromium browser with your application...
There is actually one issue JavaFX has on Linux: It uses Gtk to determine renderscale, so it can’t handle HiDPI at all (Gtk only scales in integer amounts, so everything is either 96dpi or 192dpi)
Could you talk a little bit about these problems? I was not aware of any serious issues on non-Windows platform, and would like to hear about them. As Java/Kotlin is generally my go-to language for making things in my off time, that would be helpful to know about.
> You can poke fun, but there's a reason everyone opts for things like Electron. It's the most satisfying way to build frontends for a lot of people.
I'm not convinced it's particularly good reasons. I think ignorance of native GUI coding and the old, "When all you have is a hammer, every problem looks like a nail" mentality has a whole lot to do with it.
I've done a few projects with Angular Material, and I actually ran into that exact same issue of trying to re-create the documentation's sidebar, only to realize the components weren't in the framework.
> Guess what? Angular Material is dead. All the developers decided to start over with Angular Material 2 because there's a new screwdriver brand in town: Angular 2.
I think an important lesson from this is to be careful about the tools you use. If a particular company puts out great tools but changes them in incompatible ways, you might end up having to go back and rehang a lot of doors.
It's a free and open source project and you're still complaining. And browsers and the web, JS and a lot of things changed between Angular 1 and Angular 2.
Yes, Google could have handled those projects better, they could have put up big warning signs that they are "deprecated".
I think it was a good move to recognize how unmaintainable things (can quickly and usually) become with angular1 (or with anything that is a mess of a hundred semi-external JS libraries), hence TypeScript.
>What we want are tools that allow us to build performant, maintainable, reliable code.
Virtually any mainstream language is capable of building performant, maintainable, reliable code. Virtually no developers are capable of creating performant, maintainable, reliable code. After decades in the industry and generations of new whizbang tools, libraries, and languages I've come to terms with the fact that the problem is "us." I've seen exactly one significant sized application keep those 3 qualifications for more than a couple of years. Once all the original core developers on the project moved on, it was less than a year before the code base was a total mess.
I think what you're really asking for is a tool that forces you to build performant, maintainable, reliable code. I'm not sure that's entirely possible until we get AI writing and maintaining its own code. Humans suck.
Not to put words in the parent's mouth, but I think he is suggesting that we (developers) should spend less time creating / analyzing / debating / choosing frameworks and more time thinking about actual end user functionality.
If this is what parent meant, than that's true - we do bicker too much about it in the industry (I'm guilty of it too). Discussions about tools are important, but ultimately what's important is what those tools are used to build.
When you're building a 'tower', what is more important? The strange new hammers and screwdrivers you're using, or the architecture, algorithms and data structures?
Please don't compare a programming language to a hammer. They're not similar in complexity, and it makes a really bad metaphor. Besides, unless you write entire applications in assembler, you DO care about programming languages.
Do u care about what language Amazon uses to write S3? Do u believe it is the language that make S3 succeed, or fail?
Even as a programmer, as to the other services I am calling, things I do care about involving their stability and correctness that affecting my work. I care shit about what how they write their service underneath, may it be cool or dumb.
If we're going to insist on the carpentry tools metaphor ... hammer vs nailgun; a hammer can do everything a nailgun can do and more ... but if you're banging together a timber-frame for a house the nailgun will let you get through the task far far more quickly. If you're running a business, and time is money, which tool would you want your carpenters using for this task?
If I'm running a business that lets say develops an ecommerce platform I won't be too impressed if my developers are using assembler. Java good, but if Scala gives them an edge and cuts my costs so much the better!
Yeah, so choose what works best for u, not assuming the same thing for others without understanding the specific problems they are trying to solve. Maybe they need a hammer, not a nail gun, because they work in specific environment that don't have sufficient power supply? or for the work they are doing, hammer is good enough, it is better for them to invest elsewhere.
I'm kind of making the point that in many environments you'll need both? A nailgun (battery or gas powered) for the "bulk" jobs and a hammer for the finer work. I can't imagine anyone being effective in Scala without first having a good knowledge of Java. Or at least without having Java expertise near to hand.
I used to think so too, but at work I've met programmers who code in Scala without having learned Java first, and it's enlightening. They are proficient in Scala. Whenever they touch Java code, they are upset that the niceties and modern features of Scala aren't there -- whatever we thought was reasonable in Java or "not mainstream" in Scala are exactly the opposite to them. "Why do I have to write all this needless code in Java?", they ask (for example), nicely countering the common but unwarranted notion that Java's verbosity somehow makes code more understandable to regular joes.
It's enlightening to me because a lot of what we consider "hard" or "too academic" is actually our own prejudices speaking. Of course it looks like that to us, coming from Java, but try talking to someone who learned Scala first :)
I also find it encouraging. Maybe some day we will be able to finally take advantage of the JVM without the weight of Java-the-language.
You've met programmers who know scala but not java but tell me this: Were they in an environment without java expertise "to hand"? To me scala is more akin to a skin over java. Particularly when using 3p libraries that were written in java (this ecosystem is one of scala's key advantages over other fucntionalesque programming environments). When you work with scala you'll always need some java guys nearby to deal with the "nitty gritty" details.
No, that's precisely the thing -- I've met programmers who learned Scala as their first language for the JVM (some guys I'm thinking about coded in C and PHP before that), they are pretty proficient, and they absolutely do NOT need Java programmers "at hand". It's interesting that they "get" Scala; they don't try to use it as if it was Java++ (in my experience, this attitude you describe that Scala is merely a "skin" over Java is mostly due to prior knowledge of Java). When these people eventually need to learn some Java, they do so on their own -- and curse the language!
I think we're starting to see a new phenomenon: people who don't start on the JVM with Java. It's interesting because it shows (in my opinion) that the whole "Scala is too difficult" thing was mostly a misconception. What it was truly all about was: it's hard to give up old ways of thinking :)
I honestly can't see the point in scala if you're not integrating with the the javaverse ... I'd have thought you'd be far better off cutting a clean break and using a "proper" functional language like Haskell or Go
Obviously, one big draw of Scala is that it can interoperate with Java and take advantage of existing libraries. But that's a far cry from saying it's mostly a wrapper around Java. New code, including libraries, should be written entirely in Scala. The JVM is itself a valuable target, regardless of Java-the-language.
That said, I love Haskell and would definitely enjoy using it at work, but it's a no go for "political" reasons, which is sort of reasonable even if disappointing. Scala scares management way less than Haskell!
I don't personally care what S3 is built using, but that doesn't mean the people who built S3 shouldn't care. Java, Scala, etc. are all tools with different strengths and weaknesses. Use the best tool for the job, considering the experience and capabilities of the team you have.
_I_ don't care what they use to write their platform, because it's a black box to me. But _they_ care and spend a lot of time debating it, and that's when discussions like the one in the article are important and shouldn't be dismissed.
> unless you write entire applications in assembler, you DO care about programming languages.
That's true, but we've been in the region of diminishing returns for programming languages (I'm not talking about runtimes) for a long, long time now. To go back to the (bad?) tools metaphor, it's like saying that unless you're using nothing but your fingers, you DO care about tools. Well, yeah, but once you have a decent screwdriver, innovation in screwdriver technology -- short of a revolution -- is likely to yield diminishing returns on investment, especially as the cost of adoption remains high. Switching from, say, Java to Scala is not much cheaper (if at all) than switching from, say, assmebly language to FORTRAN or C. This does mean that the effort spent on switching languages (or screwdrivers) should decline.
I completely agree. Bricks would be a better metaphor and still completely contrived. And turns out, you can't build skyscrapers without concrete and steel :)
And just to be pedantic: When I bought my first SwissTools Insider[1], I realized that it's actually still possible to innovate in screwdriver design. That doesn't make them better for every task, but hey, that's the way it is.
Modern skyscrapers would certainly not be reasonable to build without "strange new hammers and screwdrivers" (read: tower cranes, super-powered concrete pumps, etc).
Algorithms and data structures will be mostly the same regardless of what language you use.
Architecture will generally not be. Scala and Java encourage building applications in different ways. That doesn't mean one is better than the other (though I'd argue you could make that claim), but some problem domains are better modeled with Scala, and likely some with Java. And some programmers work better tending toward a pure, immutable, functional style, while others work better with OO, side effects, and mutable data.
While choice of language/framework may not be as important as many other choices you need to make when building an application, but it's not something that should be dismissed as irrelevant, either.
Just cause one thing is more important than another, doesn't mean the other thing is unimportant. You appear to be arguing against discussing tools, because they aren't as important as other things.
> Your screwdriver metaphor may be good go way to score a cheap point with strangers on an internet forum, but not much besides.
The screwdriver analogy is right on a lot of levels. Is it so hard to accept that software developers is not some unique snowflake position that cannot be compared to any other job?
Plus, we have to pad our rèsumès so we can move on to another job before anyone realizes how bad this pile of horse-dookey is and we have to figure out how to maintain it.
Not really at all. A sufficiently expert programmer may be able to switch between Java and Scala with the same ease of switching between brands of screwdriver. But that same programmer would certainly not use Java and Scala in the same ways, as they would with two different brands of screwdriver.
Your example is looking at it from completely wrong way. Computer software users don't care about programming languages and frameworks either, because they know even less about them than they do about screwdrivers. Imagine your surprise if I came to you after you hung my door and said to you "thanks, but no thanks - that screwdriver of yours totally sucks!".
On the other hand, if you worked as a carpenter (or even did some more door hanging on the side), you'd find yourself debating the tools and techniques of your trade with your fellow craftsmen, maybe even engaging in heated debates about their relative performance. The same is true about programming languages - they're tools of our trade. They have different performance characteristics. The discussion about that (and the flame wars) are between the craftsmen, not between the worker and the buyer.
In my experience, no they don't spend much time debating the tools with their fellow craftsmen. And if you look at the tools themselves, they don't change much. They do tend to spend money on good quality versions of the same old tools though and just get on with it. It's more like spending money on a boring well supported commercial framework and focusing on the application rather than jumping to every half invented new thing every week.
To be honest I think a lot of it is because the applications themselves are a bit boring so we like to get our kicks with the tools. When Carmack wrote Doom he didn't use half of what C++ had to offer. It was just boring C with classes. But the application (Doom) was more than interesting at the time.
> To be honest I think a lot of it is because the applications themselves are a bit boring so we like to get our kicks with the tools.
That's true for many of us (but not all - probably e.g. not for most of my cow-orkers; for some people, this is just a 9-5 job). This is the "art" aspect of programming. We can care about the process just as much (or more) than we care about the actual deliverable. I definitely see most of the jobs I've done so far as utterly boring; e.g. most of the web development work I've seen or done would barely challenge a monkey cognitively. What makes things difficult there is usually not the problem, but a) constantly changing definition of the problem, and b) self-imposed complexity. Same seems to be true in desktop projects I work on now.
That's why I like hobby projects - you get to choose problems that are interesting.
I like the idea behind your post because it's true for lots of people - when you're so close to it, you don't realise that you're arguing over maybe 10% efficiency in lots of cases.
But i think programming is kind of unique in this respect too.
The tools sometimes let you approach a problem in a different way; sometimes "just getting on with it" means you're wasting a lot of time dealing with stuff that wouldn't be an issue in a better language.
To give you a concrete example, it's like when you do a CRUD application with a properly normalised database and then you need to add auth. And then you realise a transaction made at a certain date has messed up all later transactions. And then you realise you need to add an audit trail. And then you realise that needs to scale its services independently and you have to add micro-services. And then you realise you've got yourself into consistency issues because your services are sharing state through your db, etc etc.
Or you just implement CQRS and all those problems go away (yep you have different problems).
But i'm just saying that tooling matters, and picking the right tools can be worth hundreds of thousands of dollars.
I think the C / C++ argument is a strawman, it's not using all the features of a language that matters, it's picking the right ones.
Your point about "picking the right ones" is fair enough and of course the language can make some difference but not anywhere near the difference the architecture makes. Which is exactly what your point about CQRS outlines.
Google and Amazon built businesses on Java, a tool that is as boring as a hammer. It was the architecture that mattered.
"In terms of programming-in-the-large, at Google and elsewhere, I think that language choice is not as important as all the other choices: if you have the right overall architecture, the right team of programmers, the right development process that allows for rapid development with continuous improvement, then many languages will work for you; if you don't have those things you're in trouble regardless of your language choice."
Yep I agree that architecture plays the largest part.
But I really don't think it's about a language being boring vs not!
Pure functions are easier to reason about. So it makes sense that a language that encourages their use will be easier to reason about - which will help with maintainability.
Same goes for concurrency patterns - the closer they are to the language, the less room for mistakes.
I think the same for testing, but a lot of the time it's up a layer of the stack with a framework.
"It's more like spending money on a boring well supported commercial framework and focusing on the application rather than jumping to every half invented new thing every week."
That seems to depend on the language. Django seems to be the established framework for Python, Rails for Ruby, there are plenty of choices if you have some special need.
To counter with an alternative tool comparison: drills and impact drivers look very similar. I'd bet that most of my friends don't really know the difference. But for some situations, an impact driver is an entirely more capable tool.
If you use a drill all day, professionally, you'd be a fool not to take a serious look at an impact driver and see if it makes your life easier.
I don’t think using different tools (which a drill and impact driver really is) is what the OP mean’t. He was more along the lines that must people don’t care whether you picked a Bosch impact driver or a DeWalt impact driver to fix their problem.
And if you explain to someone the difference, they usually get it. Even my daughter when she was five could understand why I had two similar looking things when I was working with them..
That may be the point the OP was making, and if that's so, I'd counter that the point is irrelevant to make. Sure, the user of your software doesn't care what it's written in. Duh. Why should they? If they did, it'd be weird. But the people actually writing the software should care about choosing tools that fit the problem. Not because the end-user will care, but because choosing a more appropriate tool will allow them to build software that gets to market faster, and has fewer bugs and is easier to maintain.
The language as physical tool metaphor is meaningless as far as I'm concerned. Physical tools and programming languages have very little in common. The reason so much is written about programming languages on HN and Reddit is because a language shapes the way you think and anything that alters your way of thinking is a serious matter. Some are expressive, others are not. In that sense a programming language has more in common with a political ideology or religion than something found in a garden shed. That's why programmers - at least those with a soul intact after x years in a Java shop - often obsess over the pros and cons of a programming language. To a craftsman it matters.
DHH once made an excellent defence of programmers as writers rather than engineers and it's perhaps no coincidence that the language he was referring to has ancestry with Perl which was designed by a linguist. Try Clojure/Lisp sometime if you haven't already. Then you'll experience programming as closer to expressive linguistic art than engineering.
My first programming language was Perl and I had to choose between Java and Perl at the time. If you haven't read Larry Wall's "Programming Perl" I recommend it regardless of the status of Perl in the current scene. It's a classic, written in a warm, witty style. 5 minutes with Deitel and Deitel's turgid Java tome and I was sold on Perl. The point I'm making is that choosing Perl over Java as my first language made a huge difference to how I programme today having learned many languages since. I still keep my use of objects to a minimum, prefer functional over OOP and love Clojure with a passion.
As someone who used to put in dozens or hundreds of screws in a day, sometimes:
Yeah, if you're hanging one door maybe you don't care so much. But on door #100, when your hand is covered in blisters, and your screwdriver has rounded off to the point it can no longer put in screws, maybe you'll care which screwdriver you're using.
"Another issue is a perennial side-show in the world-wide computer programming circus: the spectacle of nerds arguing over programming tools. The data model can't represent the information that the users need, the application doesn't do what what the users need it to do, and instead of writing code, the "engineers" are arguing about Java versus Lisp versus Perl versus Tcl. If you want to know why computer programmers get paid less than medical doctors, consider the situation of two trauma surgeons arriving at an accident scene. The patient is bleeding profusely. If surgeons were like programmers, they'd leave the patient to bleed out in order to have a really satisfying argument over the merits of two different kinds of tourniquet."
http://blogs.harvard.edu/philg/2003/08/12/
I don't think this a fair analogy, or that it plausibly explains the wage gap between programmers and doctors. I'm sure doctors discuss the merits of different medical techniques at conferences. In a similar "emergency" situation (e.g. customer demands bug fixed by tomorrow) I have not see anyone agonize over the right tool for the job. In both industries there is a time and place to discuss best practices and how we can improve them. I admit that the programming world seems to have these discussions more frequently.
This is exactly how I feel. Too many developers lose sight of what they actually valued for. Sure there are a subset who we need to be at a higher level to do the leg work on building tools etc, but 95% of developers really are far too involved in issues and obsess over things that distract from their actual role.
Despite what a developer is mostly valued for (delivery), his professionalist on picking the best tools for the job (obviously to his knowledge) should also be expected, so that his client has the best outcome from his work: Deliverable suitable for the use case, performant, scalable if required, maintainable, etc
Comparing the decision of a type of screwdriver to use with a programming language is disingenuous at best, given the vast differences in complexity, switching costs and effects on productivity.
A more honest comparison would be screwdriver choice vs whether to use 80 or 100 character column limits.
Indeed. Maybe the original point is better analogized as saying "shovels are better than screwdrivers" rather than comparing two brands. Of course, it's even more meaningless to debate the merits of shovels vs screwdrivers than it is to debate the merits of two different screwdriver manufacturers.
In theory, you're right, Java versus Scala is just small difference in how you express the same things in two different languages. In practice, you're wrong. Choosing Java or Scala makes a huge difference in style and culture.
The mere existence of Scala (and Clojure, and Go) as a viable alternative has intensified the bad tendencies in Java culture, the tendencies responsible for the stereotypes of overabstraction, OO overkill, framework bloat, and gratuitous "enterprisiness." In the past, large numbers of people who did not have a high tolerance for those things worked in Java for good pragmatic reasons. They served as a loyal opposition that called out and pushed back against excesses, saying things like, we can't make every call over CORBA, it's asinine to need reams of XML to configure a simple web application, and Hibernate is harder to get right than the thing it's supposedly protecting us from.
The loyal opposition are dwindling as more developers choose Scala and Go for application development. More and more the people sticking with Java are people who were perfectly happy wiring their applications in XML and learning "best practices" from Sun's marketing department. The Java ecosystem isn't going to regress overnight back to those bad old days, but that's the culture you adopt when you adopt Java as a language for application development.
Sure! And people want functioning software, too. The biggest difference between the two worlds being that maintenance is an exceptional event for a door while being the essence of its lifetime for software.
> They also sell a step-up model whose main difference seems to be that it is made of stainless steel. What will the Germans think of next?
Only stainless steel tools on stainless steel work pieces and vice versa. Don't mix stainless/non-stainless tools and non-stainless/stainless work pieces. Hence stuff like screw drivers will be needed in both variants.
I really wanted to love Scala, and for the first few days I did. But it was a never ending story learning this language. It is so complicated and feature rich that there's just too much to learn. I couldn't just read someone's code without stumbling on some special syntax or language feature that handles a once in a lifetime use case that I didn't know about. Eventually I gave up on Scala.
My impressions after a month spending working in it were somewhat similar. But it's not that there's much to learn (a necessary thing in a powerful tool) - it's that after that month, the language still felt like a totally inconsistent mix of every feature they could find in other languages (beside maybe sane macros, conditions and call/cc).
I suppose, though, that after spending enough time immersed in a language, even such inconsistency stops being a real obstacle to anything.
I echo "oelang"'s request: please explain why you think scala is inconsistent.
As far as I an see Scala has achieved something no other language before did:
1. For the first time, achieves a successful marriage between ML-style functional programming and class-based object-oriented programming (OOP) with subtyping a la Java. Scala achieves this by building functional programming as a special case on top of class-based OOP. Previous attempts at unification (e.g. Ocaml) tried instead to base OOP on top of typed λ-calculus.
2. Scala even improves on ML in that it fuses the language of programs with the language of module systems and brings type-inference to both (albeit partial). It fuses the two without any real compromise on each, indeed one could argue that both were improved since ML's module system doesn't have type inference.
3. Smooth integration of higher-kinded types with OO programming.
4. Having an advanced language running on the stable and well-libraried JVM eco-system. Usually languages with as much novelty as Scala, remain in academic obscurity.
The unity of Scala is witnessed by the fact that it can all be compiled down to a rather simple calculus, namely "dependent object types" (DOT) [1]. I'd say that DOT is to Scala what lambda-calculus is to Haskell. I find it hard to think of another language that combines so much expressive power with being simple and coherent.
I didn't say Scala was inconsistent, only that it felt as such. I've lost access to that codebase since the end of my participation in the project, so I won't provide you with code examples, but the project was using most of the language features available to date (2015). Maybe "inconsistent" is a wrong word. "Messy" would be better. I've been familiar with many of the concepts in Scala from other languages, and here it felt like they were glued together with gratuitous use of syntax and implicit type conversions.
I apologize if my previous comment didn't state it clearly enough, but I'm talking about my impressions of the language here. I'm convinced that after enough time, the whole package starts to make sense and becomes a very powerful tool in one's hands (I have a reverse situation with pre x11 C++ - it was the first programming language I really learned, so all its idiosyncrasies people like to complain about felt completely obvious and justified to me).
One day I hope to immerse myself in type theory deep enough to actually understand the underpinning of Scala better.
If you found C++ natural, then Scala should be even easier, because C++ is orders of magnitude more complex and messy than Scala (speaking as somebody who's comfortable with both languages and has written both professionally).
Yeah, the problem is that the theoretical underpinnings of DOT do not represent Scala as we know it; that would be and is a different compiler (Dotty).
If Dotty works out then we will, for the first time, have a fully specified Scala on sound theoretical footing. Along for the ride: much faster compiler, better tooling, streamlined type system, and nice-to-haves like union types and implicit function types, among other useful features.
It's certainly true that today (3 March 2017) there is still a gap between DOT and the current Scala compiler (version 2.12.1) -- just as there is a gap between Haskell and the lazy lambda calculus. However, as a conceptual guide what Scala is, DOT is quite helpful. With time DOT will become even more helpful
In general, it's OK for there to be a gap between a real programming language, and its theoretical toy model. That's the gap between theory and practise. Why would you care about theory if it was as complex as practise? The ideal case (embodied in the lambda-calculus) is that the theory is much easier, but looses only a modest amount of precision.
I don't really understand all those complaints. I am using it professionally since 8 month and I only had problems the first two month, then I felt good, even if there is always something else to learn.
For the complexity problem, here is how I manage it : the functional programming scala is scala, everything else is garbage included for java compatibility. It works like a charm.
I can't think of a language I could feel better with.
There are some pains associated with Scala, though. Sometimes self-inflicted by people who want it to be like Java: for example, most ORMs for Scala suck. A team at my office tried to use Hibernate to disastrous effects (Scala and Hibernate's hostile takeover of collections don't play well). Even some DSLs like Scalike tend to also be painful and unwieldy. I also dislike Play and its multitude of quirks and incompatible versions.
It used to also be the case that both Eclipse (ScalaIDE) and IntelliJ IDEA were almost unusable with Scala, in particular constantly resulting in spurious compilation errors. I've no idea if Eclipse got better -- completely got rid of it after decades of using it with Java -- but IntelliJ did get better and mostly works (though it still cannot always compile Scalike DSLs).
But even with all of the above, when I have to work with Java code again I cringe. Even with all the pain, Scala is simply better to work with for new code.
Ever asked yourself why it's taken so long for Scala IDEs to be minimally useful? The complexity of the language makes it difficult to optimise compilation and the language is still suffering. Paul Phillips left Scala because of this and he said it was impossible to rectify without re-inventing the language. This shaky complexity is why I refuse to build valuable projects with Scala.
and yet Paul Phillips still, to this day, writes Scala. Think about that, he's one of Scala's biggest critics; still Scala all day, everyday.
There's nothing "shaky" about Scala's complexity, it's quite stable, and not going anywhere until Dotty lands circa 2020.
Despite everything (slow compiler, average tooling, implicit/operator overloaded "magic" code bases, etc.) Scala will draw library creators (like those behind Spark, Kafka, Akka, Play, etc.) which in turn draws developers, resulting in the thriving ecosystem backing the language.
Scala will live on despite itself; the ecosystem is what will carry the language to the Dotty land and beyond.
I don't think it was really about Scala's complexity (or it wasn't the main reason, at least), for multiple reasons:
First, IntelliJ is quite decent nowadays. So it's demonstrably possible to build a decent IDE for Scala.
Second, Eclipse itself has imploded in my opinion. Eclipse used to be a usable and reasonably fast IDE. Then, some years ago, there was noticeable increase in bloat and a downgraded performance for Java. I remember reading some major release of Eclipse, which required a refactor of its UI, didn't have any automated tests because the refactor broke them and there was a lack of volunteers willing to fix the tests. Nowadays I've stopped using Eclipse even for Java, because I cannot stand its slowness and random freezing/crashes.
Yeah, developing in Scala is great. My whole team (including me) had never used Scala before, we set up a weekly study group, had no problems becoming productive in the language in a few weeks.
I understand that not everyone has this experience, and would love to see more/better tutorials for Scala come out, but I've definitely seen several people pick it up without any problems.
To me this seems like much the same malady that C++ suffers from. Is it something that established best practice could be brought to bear on? Scott Meyers' Effective C++ seems to be the bible on this topic for that language, I wonder would something similar for Scala help things a bit?
I guess in Java we are spoiled - though sometimes stifling, the rigid structure and syntax help prevent people doing "bad things". It has struck me once or twice these restrictions may have been derived in part from established C++ best practices ...
More than 10 years ago I was asked to provide some insights about Java and Python for internal use in our lab.
Despite IBM involvement in Java at that time, both Java and Python were see as possibibly immature by my boss.
My own conclusion was exactly what you wrote.
In fact during the Internet bubble there was a recruiting crisis, and Java (Python was not mature enough at that time) was exactly what was needed: A language for undergraduate people that produces good results, was easy to read and maintain, while forbiding "innovative" but often buggy code.
And these days its also about the tools that a strongly typed well structured language enables. I can refactor many things in IntelliJ in a trice. I've heard Bjarne Stroustroup bemoan the fact that the C++ community "can't have nice things" like this because so much of the community still holds on to legacy kludgy practices like cpp macros.
Not knowing C++, what are the types of changes in practices? Which are the most burdensome? I can imagine some accompanying changes in the language (as often best practices are there to cover infelicities in the language that are corrected in future versions). Are these of a scale that require large rewrites? Like, past best practices are now actual flaws (as opposed to just not the peak optimizations)?
I first used C++ around 1990, when it didn't have much of a standard library. Then came the Annotated Reference Manual with its crazy talk of templates and namespaces and what not, which weren't implemented by any compiler I had. Somewhere around here is a copy of PJ Plauger's book on the standard library that doesn't mention templates at all. The standards committee pulled a fast one on Plauger: between the publication of his book and the finalization of the draft, the STL took over the world. Then came C++11, with move constructors, anonymous functions, and a couple of new smart pointers (which was good). C++14 introduced type deduction. And there's Boost's smart pointers (and everything else).
Nothing requires a rewrite, but five year old code looks nothing like what people say is "best practices" now.
I agree it doesn't have strong opinions and every developer has a different flavor of writing it making it difficult to code review without a ton of personal opinion type comments. That said it is a fun language because of how flexible it is too. It just, at times, does not seem practical for projects that have a ton of hands on them compared to other more opinionated languages.
As others have mentioned in top-level comments, definitely give Kotlin a try, as it is specifically designed in response to your conclusion about Scala. I've been using Kotlin full-time for over a year, and I've really enjoyed it.
In 1994, when I started my carrier, the state of computer languages was bad (IMO) and I imagined that one day I would create a new language. I had many ideas. Some of these ideas appeared in java (interfaces). I was very pleased to discovered that almost all my ideas were present in scala (the single exception is a fast compiler). It seems like a perfect language. I have tried to learn it, but failed. It takes too much time (I have 3 childs and a job). I gave up. Maybe it was caused by the complex collections system needed to support immutability. I will try again to learn it when I will have more time (??? ;-))
In my opinion, the tough part is that you need to truly understand each feature. Not just one use case.
Although, once you do, you can really get to work composing the features in interesting ways to get really useful effects. Like implicits + higher-kinded types to get ad hoc polymorphism. Or subtyping + pattern matching to achieve incredibly self-descriptive business logic. I would certainly agree that Scala appeals to people who like to be able to experiment and engage with more theoretical concepts while getting things done.
But let's not pretend that most languages don't have this issue. Programming with major Ruby and Python libraries tends to eventually require you to learn what's going on under the hood in the same way. I would argue that once you start digging under the surface, Scala is much more elegantly designed than those languages.
Go is about the only language that seems to say, "forget theory, we're simply about getting things done". Not my thing, but I understand the appeal!
I've been to multilanguage conferences and every time someone throws a slide up with Scala code on it, I look around me and every damn developer has this sourpuss look on their face. (Almost like when anyone brings up Node in casual conversation, but I digress...)
Guys... if only experienced Scala people enjoy reading Scala code, then you kinda have an adoption problem
Um, Scala "in the small" (for example, in a slide at a conference) is never a problem. It's 100% guaranteed to look cleaner than the equivalent Java snippet, with less boilerplate. I suspect it's snobbery if people get that look in conferences.
Of course, Scala frameworks and its use in large systems might be different things -- though, having used Scala for my day job, I'd also disagree with that.
Fair enough. And to be honest I have not worked with it, and am probably biased by the conventions used in most other popular languages which do not carry over to Scala. It does seem like a disorganized kitchen-sink of ideas, though. And any time you allow mutability in any form (which would pretty much implicate any JVM language), you introduce the possibility of mutation bugs (one of the reasons I went over to functional langs to begin with... I once spent a month tracking down an irreproducible intermittent logout bug which ended up being based on a mutation bug).
> And any time you allow mutability in any form ...
Odersky often says that the mutability should be as 'contained' as possible in what is otherwise a largely immutable codebase. If you can reason cleanly about a black box and are sure that the mutable variables within are not going to 'escape', you get the benefits of both
1. easier to implement, imperative algos which have been around for decades. (the alternative in pure FP is to convert stuff to tail recursion, which is not always the easiest thing to do, let's just say.)
2. easier reasoning about state not leaking to the rest of the system.
I've found following these guidelines to be very helpful.
> Odersky often says that the mutability should be as 'contained' as possible
He's 100% correct (at minimum).
> the alternative in pure FP is to convert stuff to tail recursion
It's a challenge but not THAT difficult, once you get the hang of it. :) I've found conversions fun, actually. Especially when you (of course) have to learn how to trigger TCO. The irony here of course is that at the machine language level, the recursion is converted back to imperative via TCO. But IMHO the resulting recursively functional TCO code is, eh, "more beautiful"
Agreed about the kitchen-sink of ideas. Also agreed about the mess of mutability and compatibility with JVM. But that's hardly something you'd notice looking at a slide in a conference :)
I also prefer cleaner languages. But, in practice, I must choose between Java and Scala, and I'd choose the latter any day, with my eyes closed!
Now the really puzzling question is: How would someone learn about this particular saying without seeing it in writing? Are there actually people still using "hear hear" in everyday speech?
Ironically, I've have an English bachelors degree,and I've never seen it in writing before, till now! Language is active learning. There's no real way to avoiding these pitfalls, besides reading and engaging with others. I'm OK with it aslong as those offering corrections do it kindly.
I've learned German, too. German is 'difficult', not because of its grammar, but because how mistakes are handled. Which is often with harsh commentary, ridicule or confusion. Not sure why that is the case, but English speakers are often kinder when offering corrections!
As a defense I'll say this: I'm arab, grew up mostly on online and speak and write four languages. Their grammars do intertwine, and I can't help it much. my colloquialisms and vernacular are not on paar with that of a native speaker's - my academic work had a higher quality of writing due to proof reading and tight work with a thesaurus.
And it's been a while since I was a student. Cut me some slack :p
And I know I should've written 'i have' instead of 'i've' - in Arabic we say 'ill efforts blacken the face'
To disprove your last point: I'm curious as to how you achieved such a degree while using "till" as shorthand for "until". Are you sure your Bachelor's wasn't in agriculture? ;)
Joking aside, I think it's a consequence of English being a very complicated language with all sorts of borrowing from different language families. There's almost no such thing as "correct" English, and attempts to reason about it in a prescriptive rather than descriptive manner will almost certainly fail. Whether that's a good or bad thing is up for debate, but mistakes happen either way, and I reckon the average English speaker to be a bit more cognizant of that, recognizing that nobody - oneself included - really has a perfect understanding of the English language.
Oh god I remember reading so much about till and until. covers face in shame
I think I even forgot the difference between conjuncts and adjuncts, too. Grammar 1/2/3 were tough courses.
I'm leagues below the level of a native speaker, I'll admit that! But I did still do a ton of reading, which did improve my English, but won't protect against common pitfalls :P it could've been worse. At least I don't make those "your" "you're" mistakes, too often :D
Yes there are. If you tune into House of Commons debates they still shout "Hear, hear" from time to time as a way to indicate their support with what current speaker is saying. So in UK you can still hear this phrase used in a speech, granted not everyday speech.
I hear this quite frequently in day to day speech. e.g. somebody makes a proposition in a meeting and another agrees. Also - have seen this a few times in Whatsapp chats, albeit often misspelled this way (-:
XML syntax is very simple, has very good IDE support (navigation, autocompletion - thanks to xml schema, etc.. can any IDE autocomplete dependencies from repository in .sbt files?). Maven itself provides good easy ways to reuse the configuration across multiple modules.
If you exclude dependencies than for more complex projects the no of lines in pom.xml build files is somewhere between 50 - 100 % more, so it is not like .sbt (or gradle - which I find superior to both) is 10 times less verbose.
the sbt config has been the worth part for me. I could never fully understand the syntax (or let say API because it's scala, but really those operators ...).
Gnu make does not need make to build (it includes a build shell script for that), gcc can be built using any C compiler via a 3-stage bootstrap. But sbt, it seems, can only be built by sbt.
It is way simpler than that. You can specify version of sbt's jar your project needs right in your build files. When you run any against your project it will download the version you specified if different from the one installed. It is not by any means a circular dependency.
Kotlin 1.1 + Reactor (http://projectreactor.io/) has erlang style messaging passing paradigms, world class tooling and is gradually replaceable (class-by-class) for Java.
It's going to be interesting comparing the adoption curves of both these languages especially after Java 9 and most importantly Graal (http://openjdk.java.net/projects/graal/) .
Guards, pattern-matching (even down to the structural level) and typespecs cover a lot of the ground that static typing would, without forcing the type rigidity. Although Haskell seems to have admittedly cornered the static typing market
Wow this is cool. I always preferred Kotlin to Scala and have used it for Android dev. It was extremely easy to get it working compared to writing an app in Scala and the language was more similar with a modern syntax.
This project looks neat and if you had to use JVM tools but wanted some of the benefits of Erlang style development I could see it being a perfect fit.
I once drank the Scala cool-aid as well. Even wrote an enthusiastic article about it [1]. Since then, my enthusiasm has been replaced by disappointment: the JVM interop is a lie, as Java libraries often are a bad fit, people won't have time to write the extensive wrapper code needed to hide it, and as a result ugliness starts permeating your codebase - yes, bad, but that's how teams under time pressure work; the multi-paradigm-and-widening (back in 2009, Scala was a smaller language) is one big headache - everyone has an opinion of how you should write code in Scala, so inevitably you spend a lot of time debating features you should or shouldn't use in your teams (instead of writing code. In Elixir, we never have to debate paradigms, we write code); sbt is a sorry mess - no-one understands it and it's slow.
I still think it's a very well designed language, the choice of the JVM+Java ecosystem as the target just has bogged it down with legacy crap like everything else on that environment and the designers should start to make some choices instead of offloading that on every single development team in the world. I think that "single-paradigm" is one of the reason that simple languages that get shit done, like Golang and Elixir, are so successful these days.
Were I bound to the JVM, I'd still give it a good look (not sold on Clojure or Kotlin yet and it _is_ nicer and less frustrating than Maven+Java if you keep it simple); I'm just not married to the JVM so can freely consider other options.
I took a sip of Scala, and I found it very interesting. Other than LISP it was my first functional language that was being used for something other than a college course project. I liked having been made to think differently about the code I wrote - fitting things into a functional construction.
That being said, I found that many of Scala's features can quickly become drawbacks. I'm not a fan of JVM languages, but I've effectively programmed in Java and there are many useful, well-written frameworks and tools built on top of JVM languages. sbt is a pain in the ass, and I learned that fairly soon in my Scala exploration. Our project also used many Java libraries and it was jarring (no-pun) to switch between the "pure" Scala and the grafted-in Java.
The person or community you enter Scala through can also be very influential on your experience. Though that's likely to happen with any language. The developer leading our project was extremely opinionated and felt that no other language was superior. He forced, oftentimes to the detriment of progress, abstractions in the code that made it nearly inscrutable. He became tiresome during discussions because his speech was mostly a stream of jargon. I could never tell what he was trying to achieve by using all the more complex features of Scala... other than job security.
As someone who is currently having to deal with a monolithic Java app built on spring, hibernate, aspect weaving, code drenched in null checks, and other questionable architecture choices, this article makes me want to switch to Scala, and the reasons are mainly community, not programming language.
I think you could do a lot of the above In Java although the code would be a little boiler-platey. But why do people care about boiler plate so much? Hasn't GoLang shown us that boilerplate is not our greatest enemy?
It's not the boilerplate. When you take some of the best java developers on the planet, after a couple years you end up with a AbstractSingletonProxyFactoryBean, so what is a mere mortal supposed to end up with? Evolve any Java codebase for N years and the result is the same.
You could also make a similar argument for Scala. Not boilerplate, but other problems. There are some epic scala flamewars out there. A mortal could be forgiven for looking at an "idiomatic" scala codebase and scratching their head, looking at all this higher order "stuff" and wondering, "but where is the actual code, that does the actual thing?" And I'm not sure there exists a human on the planet who knows what idiomatic scala is. The whole point of the language was to make some impossible compromises, and as such you can kind of feel forces inside the language in tension with itself, not in alignment. Perhaps FP and OOP are not meant to be unified.
The only thing that keeps FP and OOP from integrating properly is the "Everything is an Object" mentality. Pure-data structs aren't objects, and you start making loads of weird compromises when you force them into an object-shaped hole. Java (and, I guess, C++) kind of pushes classes as better structs, and lots of bizarre problems come from there.
I find that, when I'm programming in the small, on the lower-level implementation details, FP design principles serve me best. Inversely, when thinking about the structure of my applications, OOP principles suit the problem better.
This sort of design is what leads some people to say that Erlang is the most OOP language out there — Erlang processes map very naturally to objects in this sense, and it is, obviously, a functional language through-and-through.
The only thing that keeps FP and OOP from
integrating properly is the "Everything
is an Object" mentality.
Actually ... in Scala everything is an object.
Functions are special cases of objects. That's Scala's great insight and it reverses what people used to think: everything is a function, and OOP is a special case of FP (this is e.g. OCaml's idea). If you look at Scala's foundations (DOT -- the dependent object calculus) this becomes pretty clear.
Could you be referring to the difference between pure programming and stateful programming? Note that OO can be done in a pure way.
The problem here is that "best java developers" really aren't that good. And why is that the case? Is it the community's fault? The language's? I think it can be seen as both to some extent. The mentality and philosophy of a PL community in my opinion can be heavily influenced by the programming language itself.
I think you can design and build perfectly fine software in Java, but the problem to solve is education of software developers. Most software developers can't be bothered to learn basic PL theory or deeply learn multiple programming languages that are very different from each other. As such, when they think about how to solve problems in code, their thoughts are heavily influenced by their primary language.
In this case, what we see from the "best" java developers is the kind of coding you can expect if the only language you ever learn is Java. A more extreme case of this is Perl. Some of the most crazy, convoluted, unnecessarily complex code I've ever seen comes from the Perl community. Now, you can write somewhat normal code in Perl, but the community often doesn't, and the language itself certainly doesn't encourage it.
As to your concern that FP and OOP can't be unified, I don't see this as Scala's core problem. Scala's core problem is that a vocal part of the community wants to use Scala as a worse Haskell, and the other part wants to use it as a better Java. I think Scala will be most successful if instead someone figures out the best way to design software in a Scala-specific way, and I don't think anyone has successfully done that yet, although people are certainly trying.
Martin Odersky, for instance, long ago introduced the cake pattern, something that was fairly scala-specific and represented a new design pattern. Unfortunately, the cake pattern ended up being a bit of a disaster! Since then, he has pushed the idea of "modular" programming, where Scala embraces more of it's ML roots (https://pellucidanalytics.github.io/blog/scalas-modular-root...). I haven't been following the community well enough to know if this kind of thinking ever took off further or not, or if there are other avenues of exploration currently in development.
At the end of the day, Scala is a research language, except the research is more focused on: how can I take existing non-mainstream PL ideas and integrate them into a practical, production-ready language? That research, for better or worse, is still ongoing in my opinion. The only way to validate the research is to try new ideas in production environments and see what works and what doesn't.
There's a reason I put the phrase in quotes. I'm referring to the kinds of programmers that create popular libraries that people can make jabs at with words like "AbstractSingletonProxyFactoryBean". There has been excellent work in the Java community, but the community as a whole embraces abstractions, techniques, frameworks, and libraries that I would consider to be evolutionary dead ends that should be avoided.
Incidentally, my favorite libraries and services in Java have little do with things like DI frameworks, ORM libraries, aspect weaving, or any other strange abuses of annotations. For instance, in my opinion ZooKeeper is one of the best open source services of its kind.
Netty, while it has some warts, is pretty amazing and seems to show up everywhere as a dependency in other libraries and services.
I'm not an expert on them by any means, but the Java-written NoSQL services like Cassandra and HBase seem impressive as well, and seem very competitive in their respective areas.
Hey sorry, not sure if i tunnel visioned your sentence or you edited, but i agree with your general point in the context of "mentality and philosophy of a PL community in my opinion can be heavily influenced by the programming language itself" in fact i think the main point of language is to shape our thoughts, and specializing language to a domain is hugely important
"Language serves not only to express thought but to make possible thoughts which could not exist without it" - Bertrand Russell
This has not been my experience in practice, but it has been my experience that people say this can be done theoretically. I worked at a company where most of the backend was in Java and Scala. There was this platonic ideal of Scala for the usually stated reasons, but what actually happened was weird, half-implemented Scala with Java that was necessary to take it the rest of the way on pretty much every microservice. It never really felt like Scala stood on its own weight without requiring 20% of the solution in Java. That bifurcation ended up making the maintenance sort of a pain.
I don't currently work with Scala (sometimes Java), but I would be interested in hearing some tips from you on how to make Scala more of a first class citizen and stand on its own weight.
What appeals to me about Scala is that is expressive and concise. It also encourages some healthy patterns like such as making distinctions between mutable and immutable containers, using futures/promises for asynchronous functions, using option types to prevent null pointer exceptions and many many others.
It influenced my programming style a lot and I try to prefer those patterns when I use other languages as well.
Some people like more advanced aspects of Scala, and like to flirt with category theory and hardcore functional stuff. Personally I find it hard to express myself in terms of higher order kinds, monoids, functors, semigroups and such. You can learn them but it's a bit like switching from qwerty to dvorak... if you have to look at the keyboard each time it doesn't make things simpler for you.
Scala appeals to those who love programming languages. Java and a few other languages appeal to those who love making software, something that Scala is terrible at.
Actually not true. If you love making software you will probably use Scala without its esoteric features (for the better, imho) and you have a powerful and useful tool, yet very pleasant to work with.
The point I was trying to make is that it does not have to be cryptic at all!
I worked on a play app where it was really easy to go around and even JS front-end developers made small contributions.
Maybe some teams need to set up rules, or do more code reviews idk.
Every teams ends up with different subset of features through. When you take over after different team with different culture, the deciphering problem gets back.
Also, through I did not seen it in Scala but in different language, the part of coding I personally enjoy the least was the prolonged fight over which features are going to be used with code reviews being primary tool to force other team members into submission. Seriously, I like following team standards, but new rules suddenly appearing during code review were pretty annoying - giving me a choice between not meeting deadline and following other dude random opinions whether I agree with them or not.
Why? I assume you are making a joke that Akka is overly complex or?
Akka is clearly a very successful project, being used widely for very high volume systems. Apache Spark removed Akka because so many users were having version compatibility issues between the version of Akka they were using and Spark was using. Enough people want to use both in the same application that the Spark guys rebuilt Spark without Akka.
Scala is a language of compromises. That's part of its success! I think it appeals to people who want to try out many different types of language styles, but the programming language purist in me hates it because it's not opinionated and is such a mish mash.
Scala tries to be everything at once, it's hardly a language of compromises. It was successful because when it was created Java sucked and now of course people are stuck with Scala deployments as nobody can decipher all that code. Java still sucks but less that it used to be. It needs type inference for like yesterday. The biggest drawback of the language is the slow toolchain.
I am opinionated and my opinion is that the more features in the language the better - as long as they're sanely organized, and not a mishmash of things hidden behind arcane syntax inventions. So right now I'm not too fond of Scala because of how messy it seems.
The only language I know of that has a scope comparable to Scala is Oz...a language designed to teach beginner programmers the superset of programming paradigms.
And compared to Oz, I'm quite happy with how neatly unified it has turned out to be. It's not perfect, but as someone who regularly uses both OOP and FP, I'm pretty happy with it. I'm really looking forward to Dotty, because a lot of the cruftier things about Scala can start to go away.
But I think it is complete BS to say that Scala isn't good for "making software". The two most successful projects of my career were relied heavily on Scala to deliver robust product on aggressive timescales, with teams largely composed of first-time Scala users.
I have used Scala to build the backend of https://huu.la for years, which is not a small codebase anymore, I love the language itself, it's fast, typesafe, productive, and gives access to the rich Java ecosystem. The only thing I dislike is the tooling, especially whenever I open eclipse, the fan just screams to hell and it's still slow as a snail.
You should definitely give Jetbrains free community edition of Intellij Idea together with the scala plugin a try. [0] It feels much better to use than Eclipse.
So much Java hate in here. I understand most people think Java devs live in caves, toiling away thinking Java and XML are the only technologies in the world. Still, this Java dev has used Haskell, Prolog, Ruby, Python...etc. I have left the cave. I've seen the world. It's nice, but Java still provides a ton of support and tooling to get things done. People have done bad things in the name of Java, and they have done fine work, too. Most of your practices from the bad old days of 90s to early 2000s Java are in rapid decline.
It's not my favorite language (I heart Ruby), but a practical choice for many projects. Don't kid yourself; once you leave "Hello World" land, and have to deal with a variety of features, platforms, technologies, you can't hope to roll your own salvation--no matter how expressive your favorite language. And you don't want Johnny's 3 star github project solution, sorry. You want a battle tested beast, with the scars to show for it. That's Java for you.
The software engineering community is bottom heavy right now, driven by improvement in accessibility of various platforms (eg Rails), and the prevalence of the San Francisco tech startup bubbles (where tens of thousands of developers have 10 jobs on their resume but never worked on one with more than 20 developers). And then these people go on and get lucky, and you have unicorn billion dollar companies built like if they were startups.
That creates a weird/interesting world, where the #1 priority is "how long does it take to use this if I've never heard of it before, and how quickly can I build an MVP with it"
That...changes priorities. A lot. Java is the other end of the spectrum, being born long before that world existed, and probably went a little too far. Fact remain, Java was born in a world very much opposite to what the majority knows today. So it will get flack from people who don't understand (or worse: don't remember, even though they were there!) why it is that way, and why it's (sometimes! Not always!) valuable.
For a mature project, I don't give a damn how quick it is to learn or how fast you can get your login form ready. The login form was written 10 years ago. I want to see how quickly you can find, debug, diagnose and fix issues or how quickly can a new module be added to the code base while being consistent with the rest of the architecture.
The java ecosystem is actually pretty good at it. At this point I haven't done Java in a very, very long time, but a large part of our stuff at work uses it, and I can open one of our hundreds of repo, look at it, and I know what it does and how I could extend it, even though I've never used the framework its built on.
What "better java" means? It means I can build the same stuff but in a better way. Easier to read, to maintain, and at least with the same performance.
Scala has a big plus on asynchronicity, but the article doesn't even try to go there. Libraries like Akka, FS2, Monix, ScalaZ etc are not mentioned either.
In Scala I can use everything from Java and much more, and this is why is better.
I'm sure by tomorrow someone with more time than I have will write an extensive article explaining in more detail why is better.
A "better Java" means keeping the same concepts and paradigms as Java, but fixing some of the design issues. That's what Kotlin is.
Scala on the other hand is a completely different beast, but some people use is as "a better Java" because it doesn't force you into its paradigms. You can code in Scala without using case class, with var everywhere, etc.
It can be handy to fallback to "Java style" when you don't know how to do it in idiomatic Scala, but at the end of the day if you don't want to embrace the key paradigms of Scala it's better to use a different language.
> In Scala I can use everything from Java and much more, and this is why is better.
You can use everything but it's not always very nice. For instance one of my biggest source of frustration is dealing with XML and SOAP (yes I know...) Scalaxb is good but limited, and using Java libraries means dealing with Java POJOs. I can definitely see Kotlin's potential in the "perfect Java interop" space.
That said, I agree with you, and I enjoy those high-level libraries too much to switch back to a less powerful language.
Regarding json serialisation, at the time I was using scala, I found quite "unusual" that the play library could not deserialize a json with more than 26 fields (or something like that). I hope they fixed it in the newer versions, but still I don't get why to rewrite all the libs from scratch, when java has good ones available.
As asked (and answered) here[0], it used to be a Scala case class limitation. There are tricks to do it anyway, like manually mapping fields by writing your own JsReads or JsWrites for your object.
It was 22 fields and the problem was not serializing/deserializing, but it was a problem with the Scala functions and tuples system not supporting case classes with more than 21 fields. This limitation has been removed since Scala 2.11.
> Scala as a better Java any more than I would Python as a better C
The difference between Python and C is huge because C is not interpreted and doesn't do automatic memory management, which is actually the deal breaker for many apps. Saying that such a difference exists between Scala and Java is simply wrong. It's wrong starting from the fact that both are garbage collected, running on top of the same VM, having the same performance and thus targeting the same application profiles.
> Scala is maybe a "worse Haskell", with extensive Java interoperability
Haskell is a language I like and that I'm in the process of grokking, being a continuous inspiration, but to tell you the truth, to the contrary I think Haskell is a less practical Scala. Scala follows the pragmatism of the ML family. OCaml is another pragmatic language. Clojure and Racket are too.
Empirically speaking, Haskell is good at being a trend setter in the FP community, but besides really cool libraries and concepts, I don't see much in the way of applications built by Haskell folks. Some big companies have built complex systems on top of Scala, not to mention projects like Kafka and Spark, which can also credit Java and the JVM. For OCaml, even with a much smaller community than both Scala and Haskell, you have some really cool stuff like MirageOS. What does Haskell have to show for, besides badly documented libraries and compiler implementations?
Don't get me wrong, correlation does not imply causation, maybe Haskell simply has a popularity problem, but the onus is on the Haskell community to prove that Scala, OCaml and others are inferior alternatives to Haskell by showing some results. Because at the end of the day it's the final artifacts that really matter.
> What does Haskell have to show for, besides badly documented libraries and compiler implementations?
Off the top of my head, the Darcs revision control system, the awesome Pandoc tool (http://pandoc.org/), and the Xmonad window manager. All of these are fully-featured and battle-tested software that don't require any knowledge of Haskell to use on a day-to-day basis.
Facebook also uses Haskell to write parts of its software stack, but most of that code is proprietary and not available for reading.
"Lots" is pretty relative. Haskell has lots compared to what? Arc[0]? It's not in the same league as Scala, that's for sure. And that also means that it is orders of magnitude away from the likes of C, C++, Java, Python, Perl, Ruby, etc. Haskell is and always will be a niche language for more experimental or research-y purposes that somewhat occasionally have real world uses.
That shouldn't be a bad thing. Haskell, like Prolog, SML, Simula, Smalltalk, and Lisp, have influenced the world of programming far more than one could ever expect if we only measured success by large project usage. I don't see why Haskeller's need to defend their meager industry adoption so much. It has some pretty good adoption compared to most research languages, but its industry adoption is not that great for a general purpose language, and it doesn't need to be.
Haskell was designed by academics to be used for programming language research. With that in mind, being a trend-setter seems to be a much better metric for success than actual industry adoption.
I totally agree on the groovy part. Groovy is a great language to do a quick POC or scripting. Things like MetaProgramming makes it easy to develop a DSL's.
First, Java does support macros – you can use Annotation Processors normally (as Butterknife, Dagger, and other projects do), or you can use Annotation Processors to actually get the AST and modify it (not supported officially, but used by projects like Lombok).
Second, Java has no type classes – this is technically true, but not exactly. The mentioned example can also be handled with Java 8’s interfaces, as they support default methods and private or protected methods.
Due to that, you can define a method instead of the writes() field, and then use an interface-defined default method to handle actual serialization.
If combined with Annotation Processing, this allows easy, simple, compile-time generation of JSON serialization (and yes, I’ve written stuff like this before, so I know it’s actually usable, and not too complicated).
Yeah, Scala is not a better Java. And Scala is still a very young language. With a lot of interesting features, yes, but also a _LOT_ of backward and broken things.
Have you tried to serialize something to JSON ? Yes ? Which one of the _TWELVE_ libraries did you use ? Need to compile something ? You can take a coffee break. You defined a `unary_-` function ? I'm sorry you can't search your code to locate the calls.
It is also about tooling and libraries. I find Scala ecosystem to be behind Java ecosystem couple of years (SBT versus Maven/Ant/Gradle, collection libraries...).
That's completely not true because Kotlin has something near zero adoption. I have a Kotlin fanatic coworker so I know all about the manifold benefits of Kotlin -- it sounds awesome.
Never had a project OK'd to use it, probably never will. They obviously need a PR and marketing department; otherwise they end up being the CouchDB to XYZ's Mongo.
If you work with other teams, especially onprem or offshore teams, they use netbeans or some other piece of shit IDE. It's just a fact. They know J7, can be convinced to try J8, once read a blog that mentioned Scala, and don't know what the fuck Kotlin is.
On the other hand, if you decide to use Kotlin, you'll post a job listing, get only a handful of candidates, and nearly all of them will be outstanding and the type of curious, driven engineer that you'd normally have to sift through a mountain of dime-a-dozen, uninspired Java hacks to find.
It's not until you've had to hire Java devs that the mystery of why so many people feel the need to ask a question as facile as FizzBuzz becomes clear.
This is hyperbole, Kotlin has fine adoption considering it only went 1.0 a year ago. Exactly how many times could you have tried and been denied the ability to use it within a year?
Spring is adding dedicated Kotlin support in 5.0 which is likely to give it a huge amount of credibility and make companies running on Spring more comfortable with adopting it.
android development could well be kotlin's killer app. i'm seeing a lot more buzz about it there than anywhere else, especially since it promises a very low overhead over plain java, as contrasted with clojure and scala.
That's a strange point to make about Scala. First of all you can choose if you build your Scala project with SBT, Maven or Gradle. Actually I know quite a few people who switched from SBT to Gradle.
And the collection libraries is where Scala shines comparing to Java. Handling collections in Scala is just so much easier and more fun than in Java. Please try it out if you haven't done it yet.
If you use Gradle with Scala, you are using it as 'better Java' (point from article.
I worked with Scala collections for 9 years, last 5 years I implement collections for living ;-)
Scala collections are behind in implementation. JSR166 (java.util.concurrent) made large performance progress in Java 8 and 9. It was never back ported to Scala.
Nothing like `ConcurrentNavigableMap` is in Scala. Or Set with weakly referenced keys?
My follow-up question would be: Is Scala still competitive to modern languages like Swift and Rust?
I experienced several drawback according to library quality and code-safety. There are too many small details that left me with an unpleasant feeling (I would take ScalaNLP/Breeze for example).
But my central issue is the VM/GC dependency. In times of GPU computing, native interface programming becomes a burden. The knowledge of object ownership improves code readability. I feel uncomfortable leaving object lifetime to a background process.
It depends how you define "competitive". If you are trying to collect hipster points then Scala is not going to help you but let's be real. Nobody is writing big systems in either Rust or Swift, these are playgrounds for people at the moment.
I am big fan of Swift and Scala... and, to be honest, for Swift there's a long way ahead before a big system can be deployed... tooling and libs are not there, also not considering that the lack of ABI stability makes the source code necessary for any external dependency.
Although Kotlin does have a lot of stuff that technically allows to write weird code, most of that (eg. extensions) is around for better interfacing with Java, and normally not used in pure K code.
That seems to be the point. Proper or idiomatic scala code uses tools only available to scala.
I used scala for a while. It has some neat tricks that I grew to like, but I think it ultimately had a problem I noticed in Ruby: there are many "right" ways to do things and each team has its own culture. This makes learning foreign codebase pretty hard--especially with how dense scala code is.
Though correct this author makes a key assumption I dispute. "Scala as a better Java" === "people code in the same way in Scala & Java". This assumption leads to the focus on various Libraries and accepted standards.
But, at least to me, "Scala as a better Java" === "Scala with better syntax and less boiler plate but access to Java libraries if you need them".
Java is a brilliant language. But nothing can survive without some assumptions being voided over time. Despite that, many institutions relay on the good parts of Java (which there are many). Scala is a middle ground which has that backwards compat but with fixes to invalidated assumptions (syntax that has gotten clunky over time, lack of functional constructs)
There are at least two things more important than Scala being a cleaner Java:
1. The IDE
2. Oracle's claims on Java IP
A good IDE is more important than Java being verbose, and the only way Scala will displace Java is if Oracle win suits and makes Java expensive to use.
I wonder if standard practices for Kotlin will diverge from Java in the same way. I could guess either way. On the one hand, Kotlin maps between its properties and Java's standard bean getters and setters, whereas Scala does not. On the other hand, a desire to share code between the back-end and statically optimizable JavaScript (and Android packages) will hopefully push Kotlin libraries away from reflection and toward build-time code generation (presumably based on annotation processors). Then again, the latter option is also available to plain java (see Dagger 2), if only the broader Java community would embrace it.
Scala quicky got my favourite language. I really like handling data using functional and imutable concepts.
Great libraries for db access (slick) and json handling (sparay-json) were not mentioned in the article, I wonder why slick is not even mentioned in the comments, it is really nice!
Using scala with these and combined with akka and futures feels like a so natural way of programming for me.
Scala is compiled against the jvm, so you're able to e.g. compile a scala jar and call it directly from java.
A couple of caveats, though.
- collections are different. You'll need to use helpers from JavaConversions, etc. to e.g. turn a Scala list into a Java list.
- scala methods with default arguments are irritating to call from java.
- avoid the more esoteric scala features
> With compile-time DI, you make service classes accept lower level dependencies as constructor parameters. In Scala, constructor parameters are accessible from regular methods, so most of the time, these services could be completely stateless. This approach is also advocated by several Java (and .NET) experts, but it's by no means mainstream. Interestingly, Scala developers have an advantage over Java/C# users, because they can significantly simplify the implementation by combining a macro-based library with lazy definitions:
Asking for a dependency explicitly is service location not dependency injection. Your code there does not solve anything better than a regular service locator in a constructor would. The point of DI is that it's abstracted from the user code and the user doesn't have to care about these `wire` calls and can test it "as if dependencies were just passed regularly".
I don't think you're understanding what the author was saying. The author is advocating for constructor-based dependency injection, which incidentally, I also advocate for. There is a macro-based library in Scala, MacWire, that helps write the constructor calls for you, essentially acting as an auto-wire-like replacement to Spring and Guice, except that it does all its work at compile time. This mean you catch errors much earlier in the build and deploy process.
I'm not familiar with MacWire, but I believe it's powered by macros. You can think of a macro as a function that runs at compile time. It's input is a syntax tree representing some code, and it's output is an arbitrary syntax tree representing code. The compiler, while processing source code, will recognize places where a macro should be invoked on some syntax. It will call the macro on that syntax, then replace the syntax with the output of the macro.
In this sense, you can imagine a macro that takes in the source code for a class that has wire calls, and rewrites the wire calls into object constructor calls based on introspection of the syntax and types in the class.
If you're familiar with C macros, they are technically the same kind of thing, although very basic, error prone, and unpleasant to work with. If you want to learn more about macros, I would recommend starting with a simpler, more sane macro system like one in Scheme, or, if you want something that looks more like Java, Nemerle (http://www.nemerle.org/About).
Scala's macro system has a bit of a bolt-on feel since the language wasn't designed from the ground up for macros. That said, I applaud Scala's effort to try to figure out how to integrate macros into their core language and hope they are successful in the future with Scala Meta (http://scalameta.org/)
Not surprisingly, this approach has become very popular in
recent years and made the Play team consider promoting it
as the default in the upcoming version of the framework.
It's not really the default. It's just another reasonable choice without adding guice as a dependency.
Even the Starter templates include guice: https://github.com/playframework/play-scala-starter-example/...
Play! also does not enforce somebody to the Scala Ecosystem, it doesn't come with many functional patterns (but they can be used with it).
The overall goal of the last versions was getting a DI approach, so that the testability of an Applikation can be greatly improved and also the testability of Play itself.
I am a long time Java developer and, believe it or not, regularly write important new product features in concise, performant Java 8.
I have looked at Scala time and time again and am not sure what to think. It is currently a popular choice for big data munging -- I'm into Apache Flink and most Flink jobs are way easier to read when written in Scala VS. Java.
But I also feel like Scala requires more decisions per line of code than Java, which makes it a more demanding day-to-day language. Also, it seems to have lots of dark corners. But these are really my impressions based on limited experience, so I am likely wrong.
Also, my limited experience indicates that IDE support for Scala is quite behind that of Java.
But I am still open to it.
To get to my point, actually my question: Where should I look to learn quality, ideomatic Scala?
My preference would be to focus on small example programs that do one thing well while demonstrating the correct, native use of Scala.
I'm just starting to pick up Scala (and functional programming for that matter) and I've been working my way through Functional Programming in Scala[1].
So far, it does a good job of teaching functional programming by taking stateful scala code, and refactoring it using pure functional approaches. The result might be considered quality, ideomatic scala.
The very first example is about DI and advocates MacWire to do that in Scala:
lazy val userDao = wire[UserDao]
I come from Java and when I moved to Scala I wanted to use DI to mock dependencies in my unit tests. The logical choice for DI seemed to be MacWire, however it did not help me with the mocking at all.
In Java you have Mockito and annotations such as @InjectMocks that inject all your mocks into your SUT automagically. In Scala, regardless if I used MacWire or not, I had to override my SUT's implementation and its dependent fields by myself, or use constructors that take all the dependencies as arguments so I could override them in my tests.
Luckily this is much easier in Scala than in Java, but to me MacWire was a disappointment.
Eventually you learn not to need mocks. It's a long road though. An important first step is making your dependencies very very simple functions that are trivial to define on the fly.
Yes I agree, in Scala mocks are not as useful as in Java and the Scala language has some features that make it easier to work around them.
However what I don't understand is what is so great about MacWire. Maybe I'm missing something but I always believed that the main advantage of a DI framework was that it facilitated mocking. If this is not needed in Scala, then what is so great about MacWire?
You're right. The biggest thing that DI frameworks have historically done for me is make mock injection easier.
There are other benefits, however.
- Manual wiring generally has quite a lot of boiler plate (even in Scala, especially if you use free monads)
- DI frameworks enforce a pattern of behaviour. This can be especially helpful when navigating a project.
Having said that, whether these benefits are worth the cost of a DI framework is debatable. My current weapon of choice is FreeK...
Even though Scala might not be the answer, I still think we need a replacement for Java.
All the Java enterprise projects I know suffer from the same problems; incredible complex project structures, a lot of "dead code" (e.g. empty Java interfaces), XML, money being burned for engineers fighting with Tomcat or Glassfish, slow database operations because of an ORM centric development and so on.
I am not sure, what's going to be the solution but from my perspective Java as a language needs to be replaced.
Java 8 is much better for programmer's sanity. If you could force people to jump to that, and completely burn down some areas of the ecosystem (like XML overuse), maybe Java could actually be saved.
Alas, I think backtracking on parts of the ecosystem is a hard thing, and I don't see it happening soon.
Adding: I was messaged by someone who interpreted my comment as if I was saying "Java 8 is better than Scala". That's not what I meant. I mean that with Java 7 and 8, Java the language is more bearable than it was in the past, so Java the language is in less dire need of being replaced by something else.
I'd say, in the end it comes down to two problems; Java's verbosity and the fact, that a lot of frameworks do "magic", things happen without explcitely asking for it (the JPA is a nice example for that).
I don't see anything in your list of complaints that is about the actual language, not meekly about the culture surrounding it. The established perceptions of "best practices" are much more in need of a shakeup than the language itself. Maybe replacing the language is the only way to achieve that change, but then it would be more like a necessary sacrifice than a goal on its own.
That's a true point. Maybe it's more about the culture.
What I actually don't like about Java the language is the boilerplate; it's a very verbose language. I don't like that anymore. I am infected with LISP now.
"With compile-time DI, you make service classes accept lower level dependencies as constructor parameters. In Scala, constructor parameters are accessible from regular methods, so most of the time, these services could be completely stateless."
Um...the constructor parameters become invisible instance variables. It's not stateless.
I like the late-time binding in Spring, it is a very complete answer to the problem of "shipping a set of binary components" and "configuring those components endlessly". Why is that a problem? Because your build is slow and because it's dangerous to patch the source code every time you want to tweak the configuration, ...
Trouble is: a lot of folks "learn" Spring working on a project somebody else started by cutting and pasting and searching for answers on Google and Stackoverflow.
You can learn some things that way, you cannot learn Spring that way. If you read the manual a few times straight through you realize that it makes a lot of sense.
"Hey Java is pretty much shit and here is this new better language called Scala, which you can use with your Java ecosystem!"
And I was hyped!
But, well then I saw the actual Java ecosystem...
Java itself is a pretty clunky language, especially for people like me, who did scripting language programming all the time and are probably not considered Real-Developers-TM to the Java folk. So the ideas of Scala resonated with me pretty much.
Anyway, after trying to configure stuff like Kafka, Zookeeper and Maven and setting up a SOAP API, I saw that the problem with Java isn't the language. Yes it's ugly, but JavaScript is ugly too, well even Python has its ugly parts. The problem also isn't performance, like so many C devs cry about daily. The problem seems to be that Java devs like to create things more complex than they need to be. Conglomerates of XML files, layers on layers on layers... I just don't know anymore.
I didn't use Scala for long and it wasn't because it failed me, it did, it brought its own complexity with implicit conversions and overloaded operators etc. but that wasn't the reason, it was the ecosystem which usage Scala enabled, the ecosystem that felt like it was still stuck in pre 2000. :\