This is the old "use the right tool for the job" cop-out. The original post went deeper than that. I would summarize it like this: can modern complex, large-scale web apps be built with the tools we have today, be they Python, Ruby or Javascript?
Or do we need an entire new class of tools which have traditionally been used to build large scale systems in the past?
It's a multi-faceted question of type systems, tooling, packaging, dependency resolution and others. And as web apps continue to evolve, my guess is that the current tools will be considered lacking.
It used to be that picking "the right tool" meant choosing between Ruby, Python, PHP, JS. In the future it might mean using (gulp) Java + WebAssembly or a combination of other unusual tools. This would be quite game-changing for most web developers. ;)
If there was depth, I missed it. The only two points I got from it were 'I prefer static typing over duck typing' and 'avoid dependency hell'. The original post didn't add anything new to either argument and both have existed and been rehashed over and over again for decades.
Go statically compiles everything into a single binary. I'm not sure what is meant by "dependency hell", but this at least simplifies the runtime story.
That has been a solved problem in ruby for a long time. Bundler[1] (or similar tools) does the equivalent of static compilation by copying[2] all of the dependencies into the project and statically loading[3] them.
I'm sure it helps, but you still have a runtime dependency on Ruby as well as something to unbundle the bundle. Maybe this isn't a big deal, but it's not as easy as a single static binary.
Fair enough. He would have done well to explain that. Java does the same. Is it considered tomorrows language? At the end of the day its another trade off between compiled and interpreted languages, and one thats been around for years.
also, the image of a pig's face as electric socket while hilarious, shows how much the original author mis understood duck typing. It's not just look like duck, but also quack like a duck. Since when does a pig's nose behave like an electric socket? The idea behind duck typing is about concentrating on behavior instead of identities. He completed missed it.
It was just a funny picture. And besides, duck typing doesn't rely on things behaving the same. It relies on them appearing the same (in terms of method names). A pigs nose appears like an electrical socket in that it has holes in the same places. So actually it is a pretty accurate picture.
That said, I don't think duck typing is Python's biggest problem. Go sort-of has duck typing, in that you can make a type implement an interface just by giving it methods of the right names. It's a bit safer because you have to specify the 'ducks' though. It's kind of static duck typing.
Rust gets it totally right. But anyway the dynamic typing is a far worse issue than duck typing.
A language with more strictly enforced interface inheritance would probably require a more, uh, deliberate intent to stick an electrical outlet into pig's snout, but you could probably still go ahead and do this if you were really hellbent on it.
I will concede that duck typing allows you to do this sort of thing more casually, though.
There still isn't much there, and some of it is just unfounded.
For example, while the author claims there are 'crazy levels of duck typing' in Ruby / Rails he provides no such evidence of it and as noted by recent work from Aaron Patterson the vast majority of calls sites even in a very large rails app are actually monomorhpic (https://www.youtube.com/watch?v=6Dkjus07d9Y).
But more important than this cherry picked example is the complete lack of this type of technical discussion, which is why I find the post very shallow.
Is Java really that unusual of tool? Java 8 + Spring boot + Jooq is a simple and powerful tool to build backend services. There is already great tooling, libraries, and a wealth of information around solved problems. Dare I say, it is almost boring to build backend services with the above stack because it is so straight forward. Maybe that is why it is not used, I mean talked about :)
Has Rails ever been for "complex, large-scale web apps" though?
My understanding of it has always been that it was for the vast majority of web apps, which are neither particularly complex nor particularly large-scale. Rails was there to help those projects get started easily and iterate rapidly. If your Rails app turned out to be a hit you'd probably need to rewrite it, but that was OK because (1) very few apps qualify as "hits" and (2) only apps that actually get written can become hits, and with Rails it was much easier to turn ideas into functioning code.
Large-scale web apps have their own unique types of problems. New tools may be needed to cope with them, but that's a whole different thing than the problems Rails was created to solve.
Why not? I would be curious to see how people tackle large, complex web software in an efficient way - that is with tools support, not by fighting against them and working around inadequacies.
Example: if the unit tests represent 50%+ of the code base, one is probably working around dynamic typing.
And here's some examples of complex software for comparison: image editor, digital audio workstation, CAD, video conferencing, computer vision & imaging, office suite, large games (think DeusEx, not minesweeper).
> Example: if the unit tests represent 50%+ of the code base, one is probably working around dynamic typing
Unit tests are checking a lot more than argument type.. I have no idea what environment you worked in, but the comment comes across as rather clueless.
The 50% heuristic comes from a story I read once about a company claiming they were able to build a ~200 kloc app in a dynamic-typed language.
The secret was their ~200 kloc unit test suite. :)
It has nothing to do with argument types per se, just that one must have very high coverage in order to be able to be reasonably sure that their app won't crash after minor code changes.
In my current project we can get away with having integration tests cover a lot of ground and only unit test what makes sense thanks to static typing. High coverage is good to have, but should be balanced with test development and maintenance effort.
Unit tests check a lot more than whether the argument is Int or String, but so do good type systems. I'd say your comment comes across as more clueless.
A huge portion of unit tests are doing exactly that. Many people simply don't realize how many problems are actually type problems. Like null/nil/whatever as the most trivial example. It is more likely that your comment is made out of ignorance than the one you replied to.
Mmm. By that definition, I would not define the software I built as "complex". But I also wouldn't define Facebook, GMail or Stripe's web app as "complex" either, and I see folks using very complicated client-side technology to build those "simple" apps.
I use intercooler.js, which I built, and which I shill heavily because I'm quixotically trying to fight the Facebook/Google 80's-style-thick-clients-in-javascript zeitgeist.
Claiming it is easy is probably bit of a stretch. I can't imagine any large-scale web app or native desktop app being easy to implement, regardless of the tools.
The original post (not this OP) was clearly a response to Rich Hickey's talk "Simplicity Matters," which was given at a Ruby conference.[0] Particularly the part about "1,000 gems," which Hickey calls "hairballs" in the talk. I've started calling all packages hairballs since watching that.
Actually I would put Ruby, Python and PHP and server side JS into the same category. Need something more performant, look at C or Java. JS has it's own niche on the front end, so you don't really have a choice there. Need concurrency, look at Erlang or GO.
> The original post went deeper than that. I would summarize it like this: can modern complex, large-scale web apps be built with the tools we have today, be they Python, Ruby or Javascript?
Well, clearly they can, because lots of people are doing it. Maybe some other tools would make it easier than it is now but it is certainly possible now.
With a wide interpretation of "can", the answer will be yes. But that's not a particularly interesting question to ask, as you've said it yourself. If X makes it 50% easier to create a complex product than LAMP, that's a huge difference.
> In the future it might mean using (gulp) Java + WebAssembly
You know, after being out of the Java world for about ten years now, I'm starting to get the itch to use it again. I was one of those people that used to joke about programming in XML, but that's really just a layer of indirection which is often a good solution to a problem.
It's a very nice language, is fast, and has so far not been destroyed by Oracle. Plus JavaFX may be ugly, gut it is a cross platform GUI toolkit that works.
Let me take the opportunity to plug Scala, which gives you (better than) the expressiveness of Python or Ruby but with (better than) the safety of Java. (OCaml, F# or Haskell are other options in a similar quadrant).
I'd like to add that ScalaJS on top of Scala + Play is really a pleasure to work with for web applications. The integration with existing Javascript libraries is very smooth and Play/SBT transparently handles the transpiling when you reload a page.
I don't actually like Play (its routing in particular is very ad-hoc and doesn't make good use of Scala's capabilities). I use Spray for JSON APIs and Wicket for HTML UIs.
You should say more rather than better, because better is very debatable when it comes to expressiveness. That expressiveness can often come at the expense of accessibility/readability, and IMHO that's the case with Scala.
A lot of the popularity of Go comes from its explicit lack of expressiveness. I barely use the language, but the one thing I remember most from my time learning it is that I could easily understand every Go source file I found. From Hello, World! all the way up to distributed applications/libraries, Go code was long/verbose, but explicit and easy to understand.
Meanwhile, I've never found Scala code to be very readable. It almost requires that the code be written with the same coding conventions that you're accustomed to using. Even when common conventions are used, we found Scala to be counterproductive in larger teams. Code reviews were significantly less thorough for Scala projects than either Java or Node projects were.
> That expressiveness can often come at the expense of accessibility/readability, and IMHO that's the case with Scala.
I don't think there's inherently a tradeoff. E.g. in Python you have to write "(lambda x: x + 1)" where in Scala you can write "(_ + 1)"; I think the latter is both more expressive and more readable, because naming "x" isn't adding any clarity for the reader, it's just ceremony that you have to skip over when reading. Similarly Python's verbose, repetitive constructors don't clarify anything (worse, they obscure the rare cases where your constructor does something different from "self.x = x; self.y = y; ...", making it too easy for a reader to be surprised/confused by those cases).
> A lot of the popularity of Go comes from its explicit lack of expressiveness. I barely use the language, but the one thing I remember most from my time learning it is that I could easily understand every Go source file I found. From Hello, World! all the way up to distributed applications/libraries, Go code was long/verbose, but explicit and easy to understand.
I think people overestimate the importance of understanding a line in isolation and underestimate the importance of understanding a whole component or system. A one-screen class where you have to spend a couple of seconds understanding each line feels harder to read than a three-screen class where each line is simple, but (IME) ends up being more maintainable.
> Meanwhile, I've never found Scala code to be very readable. It almost requires that the code be written with the same coding conventions that you're accustomed to using. Even when common conventions are used, we found Scala to be counterproductive in larger teams.
All I can say is that's not my experience.
> Code reviews were significantly less thorough for Scala projects than either Java or Node projects were.
I don't follow. Surely if people find it harder to read they should codereview more carefully (or simply reject on grounds of unreadability)? That's what reviews are for, no?
Yes, you can write (x => x + 1) as well, and there are certainly cases where you want to. (Some people argue it's confusing to have two ways of writing the same thing, but it's a very mechanical transformation, just syntax, not a conceptually different way of doing things).
It absolutely does, if you stay away from bad libraries. Most of the time you can translate Python directly 1:1 into Scala, or do better (e.g. none of the junk repetitive "self.x = x" constructors you get in Python).
Add Groovy to that, and you have the dynamic typing and flexibility you see in Python and Ruby with Java. JDBC with Groovy SQL or JSON parsing with Groovy's JsonSlurper is a joy to work with.
> can modern complex, large-scale web apps be built with the tools we have today, be they Python, Ruby or Javascript?
For me, after the experience working on a startup that used TCL using an approach similar to AOLserver back in the first .com wave, web apps are always built with JVM, .NET or any other JIT/AOT enabled language toolchain with JavaScript kept for its indisputable place on the browser.
Rails codebases do not age well, and are always unpleasant to work on. I never saw the same issue with django codebases of a similar age. Nor even ones from Perl or PHP frameworks either.
No. It is a special combination of the shiny insecure magic of Rails, mixed with the happy meal mentality and abilities of most Rails developers.
Or do we need an entire new class of tools which have traditionally been used to build large scale systems in the past?
It's a multi-faceted question of type systems, tooling, packaging, dependency resolution and others. And as web apps continue to evolve, my guess is that the current tools will be considered lacking.
It used to be that picking "the right tool" meant choosing between Ruby, Python, PHP, JS. In the future it might mean using (gulp) Java + WebAssembly or a combination of other unusual tools. This would be quite game-changing for most web developers. ;)