The myth of using Scala as a better Java
appliedscala.com
appliedscala.com
"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. :\
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"
All of that to send two ints and get one back.
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 :)
The beside my SOAP project last week, I only heard about SOAP and CORBA in university distributed systems class and that was ten years ago.
How is CORBA worse than SOAP? :D
Edit: but it doesn't run F# yet
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.
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.
What, in your mind, is a good language that needs no framework?
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.
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.)
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.
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 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.)
Just say NO to ORMs.
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.
[1]: https://en.wikipedia.org/wiki/Object-relational_impedance_mi...
Have you seen FizzBuzz: Enterprise Edition ?
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
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.
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.
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.
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).
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.
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.
Let me give an example of how Java limits ones thinking.
Look at these Stack overflow answers: http://stackoverflow.com/questions/28459498/why-are-java-str...
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 would wait till Scala does something great natively without standing on shoulders of JVM/JRE etc.
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?
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.
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.
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.
such things are less en vogue these days.
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.
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.
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.
[1]: http://gizmodo.com/programming-sucks-why-a-job-in-coding-is-...
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).
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.
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.
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.
It's not that hard to write a JSON parser.
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.
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.
This chauvinism is a real danger to the industry.
> 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.
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.
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.
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).
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.
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.
* Spring startup config (this is basically coding in another XML-based language)
* JSPs (again, programming in a new XML-based language)
* Maven Config (IMO incredibly painful-to-use XML-based language)
* Hibernate config, mapping files
* 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.
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.
> * Maven Config (IMO incredibly painful-to-use XML-based language)
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 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. :)
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.
[1]: https://en.wikipedia.org/wiki/Dynamic_programming_language#E...
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.
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 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.
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).
That's only true if you stray far from the core. If you stay to the language agnostic parts, it's clean and readable.
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.
> 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).
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.
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.
So congrats to Java for helping shitty devs get shitty code to production faster.
"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.
[1] http://blog.cnccookbook.com/2015/08/19/8-brands-to-consider-...
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.
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..
... for whatever reason ...
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.
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.
[1]: http://www.pbswisstools.com/de/werkzeuge/quality-hand-tools/...
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 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!
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.
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 :)
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!
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.
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.
That's something that holds across all fields of engineering and art.
[1] http://blog.vizuri.com/creating-your-own-angular-material-na... [2] http://stackoverflow.com/questions/28389671/create-a-menu-li...
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.
- 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.
And I’m just sitting here, using https://github.com/ReactiveX/RxJavaFX
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).
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/con...
> 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?
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.
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.
Yes, vanilla Android is terrible.
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.
> 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.
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?
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.
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.
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.
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.
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.
Google and Amazon built businesses on Java, a tool that is as boring as a hammer. It was the architecture that mattered.
- Peter Norvig
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.
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.
JavaScript on the other hand....
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.
A more honest comparison would be screwdriver choice vs whether to use 80 or 100 character column limits.
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.
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.
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.
Sorry, "just a tool" is meaningless.
"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/
You COULD write a website in pure ASM[0], but should you?
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.
I suppose, though, that after spending enough time immersed in a language, even such inconsistency stops being a real obstacle to anything.
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.
[1] T. Rompf, N. Amin, Type Soundness for Dependent Object Types (DOT), http://lampwww.epfl.ch/~amin/drafts/dot_oopsla16.pdf
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.
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 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.
http://www.scala-lang.org/blog/2017/02/28/collections-rework...
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 ...
Nothing requires a rewrite, but five year old code looks nothing like what people say is "best practices" now.
Guys... if only experienced Scala people enjoy reading Scala code, then you kinda have an adoption problem
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.
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!
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.
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"
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.
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.
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.
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.
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!
Im new to scala and I love it.
Also sbt > maven!
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!
I'm going to give you the benefit of the doubt and assume that was a clever and subtle joke.
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'
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.
1 A cash register (noun)
2 In very poorly constructed resumes
3 In the farming sense (verb)
4 In internet forums alongside poorly written English
5 Shakespeare and other literature from several centuries ago.
So my advice: unless you're a time traveller, use "until".
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
Honestly, I don't see it as a problem.
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.
I get you would enjoy deciphering hieroglyphs...
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/) .
Or you could, you know, go directly to the source while experiencing a pretty nice language on its own http://elixir-lang.org/
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 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.
[1] http://www.artima.com/weblogs/viewpost.jsp?thread=260478
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.
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?
You can usually mix and match Java and Scala source code easily. Kind of like C and C++.
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.
http://docs.spring.io/spring-framework/docs/2.5.x/api/org/sp...
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.
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.
What kind of nonsense is this? You can't casually dismiss an entire generation of programmers who built all the systems we take for granted today.
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.
"Language serves not only to express thought but to make possible thoughts which could not exist without it" - Bertrand Russell
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.
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.
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.
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.
Apache Spark supports 4 languages: Scala, Java, Python and R. Most Spark applications are written in Scala.
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.
I might agree with you regarding Akka Streams ;-)
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.
You can read one of the stories here: http://artsy.github.io/blog/2016/08/09/the-tech-behind-live-...
I'm not going to tell you that it's an easy language to master. But I do believe it is a fantastic language for making software.
[0] https://www.jetbrains.com/idea/features/editions_comparison_...
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.
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.
I'm sure by tomorrow someone with more time than I have will write an extensive article explaining in more detail 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.
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.
[0] http://stackoverflow.com/questions/20258417/how-to-get-aroun...
Kotlin is a better Java.
Groovy is a scriptable Java.
Scala is a "worse Haskell" or an "extensible Swift", with close Java interoperability (that last part leading to the warts).
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.
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.
There are many more examples:
https://wiki.haskell.org/Haskell_in_practice
https://www.quora.com/What-are-the-most-famous-software-writ...
Besides the ones others have mentioned, Haxl is probably one of the bigger known industry uses of it. It is used at facebook as their spam filter:
https://github.com/facebook/Haxl
If you scroll to the bottom of that github page, you can find several papers and articles that go into detail about it.
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.
Apache Groovy enables a programmer to script Java, not to be a scriptable Java, which is different.
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).
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.
Have you tried to serialize something to XML in Java? Which of the fifteen libraries did you use?
And Kotlin makes this debate irrelevant anyway.
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.
Kotlin is bundled with Intellij Idea. And Kotlin has smaller adoption barrier.
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.
Android is arguably Kotlin's killer app and it is seriously good. The PR for Kotlin is /r/androiddev ;)
OTOH Scala does not have a killer app.
Most spark projects that I have worked on have been in pure java or pyspark. And kafka has been .. well, everything from python to php to ruby.
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.
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.
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?
But that hasn't stopped people from writing amazing software in it, which to me says a lot about the power of the language.
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.
Of course it is... swift is a mobile PL, and Rust is barely used non-academically (and also takes a long time to be productive in).
Scala let's java devs immediately hit the ground running, for better or worse, and it's hugely popular in the real world.
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.
Well, perhaps not "a better Java" but at least "better than Java".
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)
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.
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.
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
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".
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 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.
Thank you.
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.
[1]https://www.manning.com/books/functional-programming-in-scal...
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.
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?
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...
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.
Alas, I think backtracking on parts of the ecosystem is a hard thing, and I don't see it happening soon.
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.
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.