“No, we’re telling everyone we are using Java”
twitter.com
twitter.com
But then I noticed that nobody actually cares much about what tools you use, as long as they get the job done. The end result is what counts.
Think about how important maintenance is. If an organization doesn't have in-house skillset to maintain and enhance software solutions they buy outright, why would they want it?
Unfortunately there are a lot of cases where this matter:
- Customer requires the sw to run on their standard environment (think some version of RHEL, or some Windows Server version). Hence you're limited to what's supported there (usually from the vendor). No bleeding edge versions of Python/Node/.NET etc. You might need to build a Go or Rust binary for that specific system and it might not always be obvious. Java might be a different story, but I wouldn't risk it.
- Embedded software (for similar reasons)
- Sw that needs to run on a customer's system
- Sw that needs to interface with an existing system (loading a DLL/.so? JVM?)
That seems... dishonest? What happens when the client wants to hire someone else in the future, only to find out it's not Java, it's actually this language which is not mainstream at all?
Yup, that's exactly my point. Your car analogy is a good one. I was going to make a similar one with house construction but you've hit on it well.
In hindsight I should also have mentioned NoSQL databases and a microservices architecture.
That would just be cruel :(
My apologies for this post being a little tangential.
The JVM is an extremely fast platform given its feature set. It also has a coherent and powerful concurrency specification that is stable. While it is possible to have very low latency systems in Java, it requires a bit more work, and people tend to gravitate to C++ if the 3x penalty from C is too high.
But aside from the latency, if you can deal with full GCs, Java is a data throughput monster. The default GC is actually very good in most cases, and the JVM GCs allow significant performance tuning, which is a discipline in its own right.
It will be interesting if the low latency Z Garbage Collector introduced in JDK11 eventually removes one of the last complaints on Java performance.
Performance is.. complex. The lack of value types causes a lot more indirection, the hotspot compiler patches away some of it, the copy collector will compress connected objects together so that they will fit 'automagically' into CPU cache.
Unoptimized Java code may often run faster than unoptimized C/C++ code, but Java gives you only vague, global flags for attempting to tune memory behavior and code generation.
For monolithic Java applications, you can have a lot of different memory patterns internally (short term objects for the web stack, medium-term objects for transactional state, plus long-term objects representing accumulated state) which can really muck with the garbage collector's assumptions around generations. For server applications, this can cause things like heavy load causing request/response short-term state to be promoted to the mature generation. You start having to break up monolithic applications for performance reasons.
But, that still is being a victim of your success - and you would be better off by default creating the first version of your application in a language that allows your developers to iterate quickly.
Java is fast, has amazing IDE support, large library ecosystem and it's a solid language. And yes, I stand behind the last claim, I don't understand why Java gets so much hate. Swift is the best-designed general purpose language I've used and it's not hugely better than Java.
BTW, part of the decision to use Java was that I'm very familiar with it and wanted to get started fast, but now I'm having second thoughts. I guess Kotlin would be a good choice? And maybe Swift but not sure about library ecosystem on the server.
I remember when java first came out, I thought it would take over the world if they would "finish it". To me, this meant letting it run like other scripting languages:
#!/usr/bin/java
and let it do useful things everywhere in the os, but with wonderful OO.But instead of becoming a systems language, it sort of became a "nice cobol" that was mostly adopted to do business logic. I suspect the limitations imposed on it were to ensure portability and security, but it sort of polarized the people who would or would not adopt it. It was approachable to people who didn't think pointers were necessary (or some who couldn't do pointers), and repulsive to people who didn't want these constraints.
I think over the 20 or so years that followed, the idea of what java is used for has stuck. I also think perl took up the slack on the systems side, with python.
I wonder if java had been more of a systems language from the start, would it have been unsucessful? Or would it have displaced perl/python?
Now that I think about it, I can understand why people would dislike Java, the standard library kind of sucks, it lacked lambda functions before Java 8... and in general there seems to be lack of focus on usability and elegance, which also spreads to the ecosystem. Modern Java is not that bad though.
But - Java offers a surprisingly unique package - it's fast, it has GC, static typing, good library and IDE availability, supports both OOP and functional programming (kind of). There's really only 1 competitor unless I'm missing something - C#. There's also Kotlin if that counts. Swift doesn't have GC and not sure if it's mature enough outside of the Apple ecosystem. Dart is slower.
Ecosystem wise: - The JVM still uses quite a bit of memory, sometimes 3-4x more memory than say Ruby or Python (which are also garbage-collected languages). There is a reason that Android phones ship with several times more system RAM than iOS devices. - The JVM is gradually becoming only suitable for server development. Client GUI development has been mostly abandoned (with applets being deprecated, no Swing improvements for years, and JavaFX no longer being an official project), and the startup time is too slow for systems development a la shell scripts - IDE support is actually more middle-of-the-road in my experience. IDEs can suffer from needing plugins to deal with diverse third party tools such as build systems and test systems, often themselves developed with no regards for how to integrate within a graphical environment - Many popular libraries exist in varying states of disrepair. Lack of clear stewardship by Sun then Oracle caused several libraries to target quite ancient JVMs. - Use of popular libraries can thus hinder your ability to use newer JVM features, and can even hinder your ability to upgrade to newer JVM releases - exploratory and incremental development (REPL environments, exposing server app changes) have historically been pain points. I personally have seen environments where verifying a a fixed typo in a JSP template file requires a five minute redeployment. - there are some very poor programming patterns (such as getter/setters for internal state) which have been cemented in the Java ecosystem, such that I would never recommend it for starting or junior developers. - there is a long-standing reputation for java developers (more than developers in other languages) to treat Java as a hammer and all problems as a nail. In reality, Java is in the top ten for solving certain problems, and outside the top 50 for solving others. You simply can't be good at everything. But this means a lot of recommendations to use Java get discounted - "is this person only recommending to use Java because they have zero experience with anything else?"
The JVM and Java language themselves: - The language has gone years with relatively few improvements. - The language has a strong guideline of backward compatibility maintenance which hinders the efforts to improve it. As examples, lambda support was added in Java 8 without a clear model for dealing with errors, as well as Optional added without compiler support to enforce usage or VM-level support to optimize memory layout. - There is a lot of dead weight and known bad classes in the standard library (many pre-1.2 classes like Hashtable, two date/time systems, CORBA, RMI). Some of these are finally being removed from Java by being relegated to external libraries. - The language and JVM have an obfuscated generics system, with features (such as reified generics) likely never to be completed - The Java language is wordy and simplistic, requiring a lot of code to accomplish tasks compared to many other languages - Due in part to the simplicity of the Java language and focus on supporting multiple implementations of library APIs (such as multiple logging frameworks, multiple XML libraries, multiple JSON libraries, and so on) the language tends to be design-pattern-heavy and complex to navigate. - The exception model of Java (with checked exceptions) is generally considered to have been a poor choice now. - The class loader creates frustrating-to-diagnose issues, eating up valuable time you could be working on your application
Kotlin solves some of the language issues, but not the JVM or ecosystem issues.
Swift has a nicely developing server ecosystem, but does act differently from Java in important ways. Java has a broken intra-process isolation model, but you do still have web "containers" that allow for deployment/redeployment of applications on a running server, and which will attempt to recover gracefully from programmer errors. Many Java applications dedicate a thread for handling a request, and will handle exceptions as a failure in that request - but otherwise continue on attempting to handle future requests.
Swift is _not_ gracious about programmer errors, and will abort() on misuse such as force-unwrapping an optional without a value, or indexing an array beyond bounds. This is not unusual (node and PHP are examples of servers which will abort on certain issues) and is generally a benefit in that you get to diagnose failures by primary effects rather than secondary effects, but it does mean that you need infrastructure to catch such issues and make sure a new instance of your server is started.
(For what its worth, there have been proposals in the future (post a Swift language concurrency model) to add isolation around subprocess or actor boundaries, so that unexpected errors would only abort a "portion" of a server.)
The JVM will use as much memory it is assigned. Different GCs are more liberal with memory usage, especially the ones tuned for throughput. Newer, latency tuned GCs (like G1) will commit unused memory back to the OS.
The performance of Java is nowhere near as Python and Ruby. Furthermore, Java is used in memory constrained systems like blu ray players and chip readers. So it depends on the JVM implementation and tuning.
> There is a reason that Android phones ship with several times more system RAM than iOS devices. - The JVM is gradually becoming only suitable for server development.
Android is not a JVM implementation, so you cannot make this claim.
- Python is a pretty popular language for server development. It does have some performance issues (including a global interpreter lock), so you would have to decide the trade-off of your time vs infrastructure cost. - Ruby on Rails and Sinatra are both pretty mature at this point; less trendy but a known mix of positive/negative points. In particular, I have a pretty easy time making high-quality REST APIs and backing persistence store in rails than in a lot of other languages (but I'll also admit to a stigma against Python based on a prior work project I had to co-own and maintain) - Javascript (via Node) isn't to be flippantly discounted. It isn't the best language and doesn't have the best tooling, but for a web application you likely will have front-end javascript anyways. You can also use Typescript, which usually is a net positive for productivity and maintainability (but I've hit a lot of issues lately with third party library type definitions) - C# is becoming more compelling with the .Net Core work. In some ways it feels like a Java which was properly maintained by its vendor. - I won't bash PHP, since its disadvantages are well known. But for quick prototyping web applications (without excessive javascript), a dev with PHP experience can work faster than in just about anything else - For non-web applications, Erlang (or Elixir) as well as Go may be the best choices due to their inherent support for concurrency. I can't comment on their use for making web applications. - C and C++ win in terms of theoretical maximum throughput and lowest latency/memory usage - but it requires time, knowledge, and skill to achieve that, and you likely care much more about business logic. I've seen experienced developers work months on a C-based server, only to beat its performance with something they wrote in a weekend in another language. - Swift imho has yet to be proven for the server. If you love the language it may be worth trying for a project, but I wouldn't choose it for something on the critical path (yet)
Java still has huge benefits when integrating with third party technologies within a monolithic application. For example, when selling servers acting as on-premises middleware, Java enables you to use third party libraries and some glue code to make a plugin to theoretically support everything. You also have the benefit of being able to publish a programming API for others to extend your product themselves with Java code, something which may not be as easy to accomplish with compiled languages or if it requires the customer to learn something a bit more esoteric.
Java is somewhat unique in how easy it is to add third party code and dependencies to a project - scripting languages usually cannot match this as dependencies may also include native code. This is one area where Pure Java was a win, and is why a lot of distributed processing systems (such as Hadoop and Storm) often are written in and prefer Java.
Finally, I personally don't buy into JVM languages very much (Using JRuby/Jython to run portable code on the JVM is another matter). A different syntax doesn't solve the problems with the Java ecosystem or the JVM's resource usage or lack of inherent support for newer programming concepts. As soon as you branch out to use Java code, you lose a lot of the safety/immutability guarantees and features in the new compiler model. In return, you lose the ability for all of the Java developers to be able to understand and contribute to your code.
It's interesting to me that people don't seem to throw shade on C++ as much even though it's even older and in many ways harder to use effectively than Java.
I hear my friends make dismayed noises about C++ any time they are forced to work on it. When I look at Java or C# code snippets I mostly feel like I understand what's going on. C++ makes me go wat?! far too often.
Personal opinion I think Java would have a better rep if they'd optimized the GC for latency instead of speed. C# on the other hand would have a vastly better rep if it wasn't a Microsoft product.
Also despite the marketing hype the main application for Java was server side. I wouldn't be surprised if GC latency issues weren't a problem in that space.
Go does not scale well and it is a dumb language, not that that is bad. But just that it does not feel like a improvement to switch to Go.
Rust is still new and I think it will not get mass adoption like Java because of higher learning curve.
The rest of the differences are just having different standard libraries/tool chains. I don’t think that, for a novice knowing neither, rust is somehow much harder than c++
I think this argument only really applies to rust’s learning curve if one assumes that each year universities asses the programming language world for the best teaching languages and pick out those which can be used for the courses and are easiest to use. They obviously do not do this and you can tell because they picked c++ (which is actually at least three languages to learn with the preprocessor macros and the functional programming language that is hidden in the template system)
What do you mean? I've seen huge services built in Go handling an enormous amount of traffic.
(Disclosure: I work at Google, primarily in C++ and JS)
Are there any articles to back this up? I'm aware that the scheduler and networking integration are certainly opinionated. Nevertheless it seems to work very well for most applications that I have seen so far.
Additionally, a lot of the systems you mentioned can often benefit from the sophistacted dynamic classloader the JVM provides. For something like Spark (mentioning this one because I am familiar with it), it is a requirement to load and run user specified code dynamically. You can do this in C, but the JVM makes this much easier.
Then add in two decades of entrenched software and network effects.
There is no point to discuss or compare programming languages without having the context about project, environment, scale, resources, and architecture.
With that being said, in this example you have to imagine their competitors certainly will have that context (they'll each be building a replica of the same thing, essentially) and so the situation is different. Only hearing the language / framework they are using becomes more useful and valuable, then.
Google used python, Java, and C++
Amazon used perl and C++
Facebook used PHP!
Such decisions are in fact not simply about languages in themselves. They revolve around languages, availability of libraries needed for the task in hand, community, availability of proficient programmers vs your ability to train new ones etc.
Things that can be rewritten in one weekend are trivial; they don't speak to anything.
A Lisp site that can be rewritten in Python in one weekend can be probably be rewritten in shell + awk + CGI in two weekends.
And regardless this, my point is not showing a rant against Lisp (I'm huge fan of it in fact). My point is simply that the language may be a great choice or a bad one, the outcome is not an intrinsic property of it.
If they do ask then they are planning to make changes. If they're planning for that then it makes sense they would lean towards the most popular and easy to hire for languages.
But I've got enough experience with Delphi and its "VCL" libraries that I'd require a fully licensed and running VirtualBox image with your exact build environment capable of compiling the project before I'd sign off on the deliverable.
Currently my main income is derived from a suite of software I wrote for a small winery who subsequently grew to be a very big winery. They got big enough to hire an IT team and a Manager and a consultant who basically are telling me that Delphi is ancient and my whole system is a risk to the business despite having 100% up-time for the last 10 years (Basically if their server was up the system was up). Nothing I am able to do is going to convince them otherwise and it is on the cards to replace it.
Again I will gracefully back down and support the system until it is changed so should get another 2-4 years out of it based on previous experience *
I was an IT Manager for a long time and I do understand peoples worries but I also understand that if something is working, is documented, has an open source and data structure, can be supported and doesn't have a forced end of life there is sometimes a bigger risk to making a change. Behind a lot of software is generally one guy or gal, I don't try and hide that fact and sometimes pay the price but and I know several other packages that have just one guy as the linchpin but there will be no pressure on them as they hide it behind a company.
I also have C and SQL skills which people don't find so offensive :-)
* The expenses system I wrote in the UK had the same decision made on it in 2004 to replace it with the new mega SAP R/3 ERP they were moving to and it was still being used up until 2016. A Time Management System I wrote in 2008 is still being used despite the client telling me it would be phased out in 2013 as part of a new CRM system.
Where I live it would be easier to just start the project from scratch than to try to find someone proficient in Delphi to maintain it
I mean, a lot of people program in a language they aren't familiar with because it has the best ecosystem for a given job or because the open source project they are modifying is written in that language.
That is big money.
According to the tick boxes you can rapidly develop for any platform and deploy everything without waiting around. I have no idea why anyone would want to develop in anything else. If the client could not find a developer to take on the project they could be up and running pushing all the features by teatime.
It has an active community. I don't know how big it is, though.
> https://twitter.com/devoncestes/status/1104000439987683328
Handling of same amount of users comparing to their competitors with a software stack that requires %70 less employees to run will give them enough room to lower their product price comparing to others. Imagine If they can keep it this way X number of years, then they will be able to eliminate their competition.
> While the rest of the world sees Perl as a legacy language and analysts insist that no one is talking about it, our Perl business is vibrant, alive, and growing. Leading companies such as Amazon, Boeing, and Cisco continue to demand Perl skills in their developers while Booking.com is investing in Perl as its core development language. How can this be explained?
> This is the Perl Paradox. No one is interested in talking about one of the most influential modern programming languages yet it continues to thrive under the radar.
https://www.activestate.com/resources/webinars/perl-paradox/
It's simple: because rewriting it doesn't make business sense. But from having talked to Booking.com devs, I don't get the impression it's something they'd recommend for new projects.
So while some businesses build on Perl might be "growing", is this because of Perl, despite Perl, or doesn't matter? The success of a business says nothing about the ecosystem surrounding the language they are using (unless they get so big they can shape it). A far better proxy for language health is how easy it is to hire a team of competent <language> programmers at all skill levels - by which I mean veterans with enough varied experience, and college graduates who'll consider programming in <language> without a bigger paycheck. (The ultimate metric would factor in turn over due to dissatisfaction/burn out from tech debt.)
For what it's worth, I still love `perl` for one-liners, because it's far more consistent than the various GNU and BSD versions of `sed`/`awk`/`grep`. But I'd rather be programming something else, and I'd rather be deploying something else, given that consistent deployments are possible now with language-agnostic tools like docker. So a big advantage Perl had is gone.
It's not all that hard to hire competent and experienced Perl devs if you're willing to hire over the age of thirty, and remote (i.e. not moving to Amsterdam).
I would mostly recommend Perl 6 over Perl 5 for new projects, though. At least for those intended to last more than 5 years (which de facto means 20 years). I know the module ecosystem is not quite there yet, but the concurrency support is far more advanced than anything planned for Perl 5.
Booking have changed their policy w/r/t sponsoring conferences and/or the "we're hiring" thing in the last 12 months. I know this as I'm one of the Swiss Perl Workshop organisers and they've sponsored us for the last few years, last year we couldn't get anything out of them and when we enquired we found out the reasons. I'll approach them again this year to see if the policy has changed again.
I don't know the exact reasons for this, and I suspect it's not a Perl thing but rather a change in management policy and/or the realisation that throwing devs at their systems is not the solution. Maybe someone read Brooks? I interviewed there several years ago and it seemed utterly bonkers that their dev team was > 100 given the nature of the business.
Anyway, to tie in with the grandparent post - we know that many banks in Switzerland are using Perl but they will absolutely not talk about it, nor sponsor us, nor send employees to the workshops. We know this as we have had private attendees who work for those banks tell us these things.
Perl was everywhere at one point, and by extrapolation that means it's still in an awful lot of places.
> It's not all that hard to hire competent and experienced Perl devs if you're willing to hire over the age of thirty, and remote (i.e. not moving to Amsterdam).
We're looking at the junior route, we've taken on 4 in the last 18 months and intend to continue this. We're at a point where new graduates were born after the Perl peak, so they don't have any knowledge of its decline in usage and/or preconceptions about the language.
I have a much simpler explanation. Publishers and conference organizers like O'Reilly eventually saturate the market for Perl books and conferences (books especially, because used books start to cannibalize their sales), so they move on to promoting a different, new language, so that even their existing customers will have to buy the new books and pay hundreds/thousands of dollars to attend conferences for the new thing.
Can you use a search engine before posting nonsubstantive, dismissive comments?
https://www.publishersweekly.com/pw/by-topic/industry-news/b...
I am not sure the total count of how many books O'Reilly published last year, but they have not exactly slowed down in releasing new titles: http://shop.oreilly.com/
Developer outside of SF (outside of USA, in fact) here. I read blogs, have written them on occasion. Have worked with many developers in many non-SV locales. None of them read programming books, most of them read blogs.
Take this with the grain of salt of any personal anecdote on the Internet, but I can definitely say that Perl is not loved there. Most people hated it deeply, some of them were like "it's not horrible...".
They are now allowing Java as well for the newer project, and they will have Java and Perl as 'blessed' languages moving forward. I don't really believe that they are doubling down on Perl in any sense of the word, they're just doing what any other company with a huge amount of code written in a dying language would.
Basically anyone who wanted to be productive there demonstrated an impressively innovative, cross-cutting skillset that combined deep knowledge of UNIX technologies, the particulars of the application, and an incredibly expert language of the particulars of the language itself.
And honestly?
It sucked.
A lot.
I won't say this about any other platform--not modern security-vuln-in-the-package-manager-every-two-weeks JS, not "do you mean actually cross-platform or relying-on-compiler-UB cross-platform?" C, not the worst old-layered-on-new-layered-on-old-again PHP, but: Perl as a platform on which to build something non-tiny, or something that requires more than a small handful of developers, is unutterably awful. And I say that as someone that got pretty good at it, I think.
At the micro level, TIMTOWDI confuses newcomers, makes code review inconsistent, and means that as soon as someone feels fluent and productive on the codebase, then they have to engage with someone else's code, and they get stuck all over again. This means that mentorship is a complete bastard, and developer progression is incredibly hard to gauge, teams form fiefdoms (even in the face of huge linting tools; things that make an ultra locked-down JS/TS project look paltry by comparison--even for off-to-the-side greenfield projects) and can't transfer developers, you name it. Perl at any sort of scale is worse than the quoted "write-only" slogan: it's "write-once, re-learn from scratch on read". For a junior dev, rewriting would be a blessing.
At the medium (between micro and macro) level, the metaprogramming abilities of Perl just . . . fuck everyone up, no matter what they want to do. Want to get your work done in as straightforward and repetitive a style as possible? Welp, no matter how simple the task, and how straightforward-looking the utilities for it might be (on CPAN or in house), they won't interoperate for shit. Want to reduce boilerplate and ease the pain of common tasks by encapsulating (or, god forbid, applying metaprogramming) to speed up some process? No problem, first-class laws-of-the-universe-altering facilities are available to everyone--to get your change functional, you'll just have to interoperate with . . . well, everyone (some of whom wrote third party modules, and aren't people you can ask nicely for help). Object systems will fight with message queue clients for control over how calling nonexistent methods on arbitrary objects that neither one created should work (you thought Ruby's method_missing was a foot gun? Ha!). A tool for printing console logs will override the alarm(2) hooks used by your main HTTP client, meaning that if someone leaves a debug print in the wrong place, HTTP connections to a down endpoint will start blocking forever and kill you. Can this happen in other languages? Sure! Python, Ruby, and PHP (to some extent) all allow the same flexibility and low-level access. But only Perl makes this the default convention* to follow. I've heard people say "Perl programmers are just C programmers who couldn't hack it, but still want to write C". There's a grain of truth to that. Problem is, those aren't the kind of people I want to share a codebase with.
At the large (5MMSLOC+ codebase) level, Perl's an operational nightmare. Thanks to all the ways that libraries can customize the language, it has the metastasized version of most other interpreted scripting languages' problems when it comes to compilation phase and memory, namely: "what happens when I have to compile a huge dependency graph on startup? Can I cache those things in some sort of intermediately usable format or do I have to wait many minutes to start a test script? Can I fork? When I fork, what gets shared? Just filehandles opened by the application? Or random shit inside libraries too (and are compiled dependencies encouraged to make their IO resources' lifecycles manageable by the outer runtime)? Will my box crash due to GC-caused refcount/allocation cycles if all my forks exit at once?" These aren't unique to Perl, but I think they're worse in it than any other language. Oh, and that's without getting into the insane degree of mutability Perl permits. It's the freedom of C without the discipline ("set environment vars any time you want! Hell, they're a first class language data structure! Oh, and change what the STD* streams point to, that's fine to. And dynamic scoping and Scope::Upper means you can't tell when something will change because some code totally unrelated to yours decided it should!"). When trying to handle requests or do anything "nested" (terminate SSL, alter things that would go on e.g. "Context" in now-unpopular Go idiom), Perl's conventional answer is just "dynamically overwrite globals!" In general, this means that it doesn't matter in what context you tested your code in, it'll do something different at runtime because a) if it does anything interesting it depends on global-ish state, and b) other random code can rewrite SIBLING global state whenever it wants (think Python, but if the convention were for any coder that got stumped about how to pass data around to just modify globals/locals/vars willy-nilly). Again, a risk in most environments, only actively encouraged in Perl.
I promise that wall of text isn't just specific-employer PTSD. I've been through CPAN code, negotiated with package maintainers, gone to conferences, tried to get a sense of how people are contextualizing these problems. And the impression I came away with is that the vast majority of the entire Perl ecosystem--from the practices understood to be desirable by programmers to the behavior of existing/hardened/public code--is overwhelmingly harmfully inaccurate, poorly-thought-through, and defended by the worst strain of cleverness-above-practicality (or "don't touch it, it works when you hold it just right and don't breathe" for incredibly simple requests) when challenged.
Perhaps at some point in the past this ecosystem reflected the cutting edge, but I think that time is long past. If you're making a small commandline utility or personal one-off in Perl, go nuts. I don't think you're a bad person. Just make sure it doesn't get any bigger than one developer's worth of code.
EDIT (probably the first of many, because essay): typos and grammatical fixes. Promise I won't change the substance.
* Why the hell are either of those libraries calling alarm(2)? Answer: the logger didn't realize that write(2) wasn't interruptible, and the HTTP lib author didn't realize that connect(2) took a timeout. By the way, both were in incredibly popular modules on CPAN.
I once wrote a sub at this gig that returned a list (because hashes are lists) containing a string built by sprintf, which contained a sub dereference wrapping a sub that returned a string built by sprintf. Though it was necessary at the time I'm still just really, genuinely sorry about that. I guess the takeaway is that perl reverts even the most civilized devs to utter savagery.
>> Perl at any sort of scale is worse than the quoted "write-only" slogan: it's "write-once, re-learn from scratch on read". For a junior dev, rewriting would be a blessing.
Rewriting is really risky too; global state is problematic in any language that offers it but the almost complete lack of guarantees provided by the language is exhausting and makes it difficult to reason about even the most trivial change. Imagine being dropped into a 5k line function that hasn't been touched in 10 years. There are no tests, few comments, and the author quit 6 years ago. What types can this function return? Is it always called with all of its expected arguments? Where is it called from? None of these questions can be answered trivially. You'd think grep would handle the last, but you'd be wrong because people can and do build identifiers piecemeal as strings and eval.
The casual use of evals and symbol table manipulation in probably any large perl codebase only became more terrifying as I became more comfortable with the language. I cried a little bit when I figured out how the import system is cobbled together, and not exactly for its elegance or simplicity.
On the bright side, building healthcare systems with perl made me a very disciplined and defensive coder. It also got me used to saying things about my code like "reasonably confident" instead of "it works". Software engineering is so much more exciting with assumptions and guesses, who doesn't like to roll the dice every now and then? Now if I could just remember what all the runtime flags do...
To me it just sounds like your colleagues were a little nuts. You don't need metaprogramming to write a large application, and reaching for Devel::Declare should be reserved for last resorts and "hold my beer" moments. You're right that the conferences have a lot of this kind of stuff, but most of us know better than to actually use it, and read Perl Best Practices.
Most of these issues are solved in Perl 6. Any language changes are scoped lexically by default (e.g. declaring sub infix:<==>). Emphasis on threads instead of forking for concurrency, with await and first class Promises. If you want to write see, just write normal C and use NativeCall, instead of writing in the bizarre XS dialect of C. But it's kind of a different language... yeah.
Edit - I guess my point is that it's not good enough to keep a secret. :)
I _have_ seen some projects with pretty terrible code, but that has nothing to do with Erlang/Elixir, and everything to do with the skill level of the team behind the project.
https://lobste.rs/s/pcebor/choosing_elixir_for_code_not_perf...
Care to share them here?
Yup, those companies moved a lot of their business to Java, and C#, and Go, and even Ruby.
Other manufacturers used either some traditional mix of C(++) and assembly or got on the CCITT/ITU bandwagon of CHILL ("CCITT High Level Language"), which is combination of C/BLISS style low level execution model with Algol/Pascal syntax and COBOL-like verbosity with some extent of native support for threading and coroutines.
Can't say about other companies.
Cisco uses Erlang in the control plane apparently [1]
[1] https://www.ericsson.com/en/news/2018/5/erlang-celebrates-20...
Inside the rest of Ericsson, however, there's very little Erlang left. Once again, only hearsay, no hard proof. They still hire for Erlang here and there (used to be primarily non-Swedish offices) [1], and they offer theses for Erlang [2]
[1] https://jobs.ericsson.com/jobs?keywords=erlang&page=1
[2] https://www.linkedin.com/jobs/view/master-thesis-erlang-json...
Do you have other real examples?
I always believe if Sun and Ericsson swap their languages back to 90s, say Sun have Erlang and Ericsson have Java the world would be totally different.
I'm pretty sure Java guys struggled quite some years for distributed Web development. Thread and lock were all the things most of them know.
Listen to Steve Jobs describe object oriented programming. I'm not sure he even knew what it was, but it worked out for the company that he sold it so well. https://www.youtube.com/watch?v=2kjtQnPqq2U
I am glad to hear there are more companies out there giving it a try. Any time I see a job posting for a company that uses it, I give them a hard look. It tells me that they are a) hiring people who are of a certain mindset (see the python paradox[0]) and b) they understand the competitive advantage that using a language like Elixir can bring to the table.
I like being a polyglot, but my schedule is tight enough that I need to hit the ground running or else I get pulled back to reality pretty quickly. There's a lot of posts and videos out there on Elixir, so curators are incredibly awesome in my world.
You will start feeling the magic around chapter 4 with pattern matching and the rest gets just better :)
Try not to migrate your "how to .." thoughts from other languages into Elixir. It has some uniqe ways to solve everyday problems.
Have your interactive elixir console ready to play with as well, good luck!
I get frustrated at least once a week trying to use it in a language that doesn't have it. My brain just thinks in pattern matching!
Docs in elixir are first class citizen, so everything is very well documented. And just like in ruby/rails land, any question you may google will return a lot of high quality posts with answers!
I think it's probably the best way for an experienced programmer to get up to speed on idiomatic Elixir, why you do certain things, etc...
The coding-gnome is the first tutorial that explained OTP, Supervisors and GenServers at a level that helped me understand how to actually use them.
Afterwards, official Elixir Documentation also became much more readable and understandable to me. Before that point, some things just seemed to arcane because my understanding of OTP was wrong.
[0] https://www.amazon.com/Programming-Phoenix-1-4-Productive-Re...
What’s the new python?
They remove loops in the Erlang abstract machine so that there are only ever O(1) instructions executed between each function call (where a tail-recursion is considered a function call.) With this constraint in place, the runtime can get away with a hybrid of cooperative and preemptive scheduling called “reduction scheduling”, where functions only ever yield when they make a function call (or return from one.)
By ensuring every function body has O(1) “reductions” before it hits a CALL or RET op, the runtime guarantees (unlike cooperative scheduling) that execution will always yield from a task in a bounded amount of time; and by ensuring yields only happen at call-sites, the runtime ensures that (unlike preemptive scheduling) there is no register state to preserve at time of yield—all the scheduler has to record when it pauses a task is the thunk (function pointer + parameter list) for the call it was about to make.
Together, these guarantees allow for extremely low-overhead context switching between tasks in a soft-realtime context.
Other systems (e.g. .NET’s Orleans) simulate this hybrid approach by splitting code into state machines with explicit yield points being the state transitions. But AFAIK, only ERTS takes the approach of making function calls into the state transitions. (Because, without the no-native-loops constraint, such an approach doesn’t work at all.)
I think it's important to realise that they're different ways of writing the same thing. For example, in Lisp, the 'do' operator is basically a C-style for loop: in Scheme, it's a macro over tail recursion, and in Common Lisp, it's a macro over gotos, but it provides an almost identical interface to programmers. Using recursion over loops is just a stylistic/syntactic choice, the really important part is understanding how recursive functions are equivalent to loops, and vice versa, so that you can apply your experience in one situation to the other.
Enum.map(1..100, &IO.puts/1)
prints the numbers 1 to 100
for i <- 1..100, do: IO.puts(i)
I guess what people mean is that that’s an abstraction over function calls?
I doubt it would be for someone from a Ruby background, where higher order functions already generally replace built-in loops.
As I've frequently said about Erlang, the language is much more powerful than the sum of its parts. There are a great deal of complementary features in the stack.
I use Elm, which is as statically-typed as possible for a client webapp, but I know I can never guarantee that JSON data I receive from remote servers is of the expected type.
Edit: also, versioning, cross language sharing, use in generative testing, api client code generation and other metaprogramming uses. And documentation generation, eg swagger
If you are using eg Clojure's spec, you can reference the same stuff downstream in the control flow too, for eg fn argument validation.
I've worked on a lot of distributed systems, and I don't see what this has to do with anything. Yes, static typing doesn't prevent you from doing any of the things you mentioned like changing your API out from under someone, but it's not supposed to. It Does however prevent certain classes of mistake in the individual service or executable, which is still a laudable goal in and of itself. It's not a silver bullet, but it's no less useful in distributed systems than it is anywhere else.
Also, are we talking about strong typing or static typing? The OP said one thing and this reply says another. Either way, both are nice in distributed systems too.
If I'm dealing with some complex long-lived distributed system, I don't have time for the bullshit errors no static type checking allows. I'm already waist-deep with real problems!
Also if you control the client and the server, do not just blindly follow Postel's law and except crappy data. Be rigid and lo, and behold, one side quickly excises all the bugs in the other.
> Also if you control the client and the server, do not just blindly follow Postel's law and except crappy data.
But in real world, we do not livd in a bubble. Very often, we do not have the comfort of controlling the server and the client. We have keep edge cases in mind. Unexpected errors / cases happen.
How?
So whenever something was expected to arrive from the wire, it does not parse correctly, depending on the parsing method, once you have that null, all bets are off. Type system gave up.
It all depends.
Another example is Java interfaces. Merely checking for an interface type does not prevent errors down the line. It does limit the amount of errors.
Types can also be very useful for security, to keep track of which runtime safety checks need to be done. For example, you can have a separate type for HTML strings that can be rendered without escaping.
They are opt in of course, but have the property that the more specifications you add and the more precise they are, the more type errors they'd discover. After it run it tells you if there is a type discrepancy. If it can't decide it doesn't say anything.
The technical term for that is "success typing" http://www.it.uu.se/research/group/hipe/papers/succ_types.pd...
Erlang is not in my opinion a “dynamic language gets us going fast” language. It's a language specifically designed to handle large scale reliably for long periods of time.
You will get a lot of milage out the Erlang ecosystem.
IIRC message passing greatly complicates things.
Yes, you can add enough expressive power to the typing system to make this work (e.g. dependent types), but then it stops being pragmatically viable, as far as we know in 2019.
- No type inference, since that's not decidable for dependent types.
- In most industrial software engineering, getting the specifications is a big problem, whence agile methods. Without detailed specifications early on in a software project's lifecycle, what's the point of paying the price for type dependency when you don't even use it.
- Relatedly, dependent types don't solve the oracle problem in software engineering: i.e. where do you get the specs from and how do you know that your specs (in this case types) are correct rather than false?
- Rewriting & refactoring code becomes much more expensive, because you now also have to rewrite / refactor the specifications. (This is already a reason why post-Java, exception specifications have been abandoned)
- No widely used programming language offers full dependent types (yes I'm aware of Scala's path dependent types and Haskell's forays into dependency), and that despite dependent types are at least half a century old [1]. So it's not like programming language designers don't know about them.
- Dependent types have really only been worked out beyond research prototypes for functional languages, not e.g. for message passing concurrency.
My experience with them so far
has been more than great.
I'd be interested to learn what non-trivial code you've written in dependently typed programming languages. By non-trivial, I mean: industrial code, say > 20k LoCs, at least 3 programmers involved, specification changed over time. Specification was not fully available at the start of the project.[1] N. de Bruijn, Automath, a language for mathematics.
You can still have type inference, it just won't be able to infer the type of all valid terms, in which case you just have to add a manual annotation. This is not a strange concept, this is what haskell does for example with higher ranked types.
> getting the specifications is a big problem
You do not need to specify what the whole program will do (in fact you can use a language with dependent types without having to specify anything at all) - that being said, people usually specify the behavior of specific functions in the program.
> - Relatedly, dependent types don't solve the oracle problem in software engineering: i.e. where do you get the specs from and how do you know that your specs (in this case types) are correct rather than false?
I thought that the point of erlang having dependent types would be to make data-dependent code easier, not to specify the behavior of functions. But yes, this is correct, and this holds true with every proof assistant that I am aware, not only with the ones that use dependent types.
> because you now also have to rewrite / refactor the specifications
This is a great thing actually - I would consider it a bug if my function after a refactoring did something that went against its specification, with dependent types I can have the compiler warn me about it.
But again, you are not forced to write a specification. Dependent types only add possibilities without removing anything.
> So it's not like programming language designers don't know about them.
I would argue that most programming language designers are not familiar with type theory. There are thousands of languages, one does not need to be a genius to make one. Heck, two of the most popular languages (C and Go) do not even have parametric polymorphism, not to mention that generics were added in Java only in 2004. In addition to that pretty much no popular language has proper support for higher order types either.
> industrial code, 20k LoCs, at least 3 programmers involved, specification changed over time. Specification was not fully available at the start of the project.
In that case, none. Though I would argue that your standards are too high, after all just the fact that I have not worked in the software industry excludes anything that I have made.
As for LoC, I would not use it to measure the scale of a project. With Java for example even the most trivial program can easily reach thousands of lines.
Types are great at stating and preserving global invariants. Invariants sometimes do vary as systems evolve, though. You may need to handle polymorphism in your data flow mid-transition. And runtime polymorphism is just another phrase for dynamic typing.
Dynamic doesn't really cause problems in its own. Only abuse of it which can be said about most things.
I guess there is an argument that f forces you to have good habits but that comes at a pretty big cost if your team is half decent.
I said don't abuse language features. That is a far cry from writing perfect code.
Non perfect code is expected early in a startup, I'm just saying don't confuse your non perfect code with a language failure.
I'd also like to say if you've never seen "hire perfect developers" scale passed one you've been optimising for the wrong thing.
I've seen a team go from technical debt hell and dread to a powerhouse team where everyone commits daily.
It doesn't take much, and it doesn't take perfect developers, and it certainly doesn't have anything to do with the language.
It had everything to do with honest and healthy code review. It had everything to do with people feeling comfortable enough to say, your solution is a hack, why are you taking this shortcut.
That isn't write perfect code, or hire the right people. That is hire pretty much whoever will take the job. That is prioritising and optimising for quality.
We still had a legacy code base, it still made us money, and it gave us the time opportunity to do things right, but you still need to take the time.
Note I said "now let's scale" -- it's pretty easy to rely on good practices and a steady hand when it's a dozen engineers in a room. When it's a thousand engineers in three timezones it's a fair bit harder.
Edit: typo
You can move slow, choosing a static language only imposes that on you, it doesn't fix the underlying problem (developers being lazy.)
It's done by writing your handlers to accept a closure to use for future requests. It's not inherently different from doing this in Java:
if (req.isUpdate()) {
handler = Class.forName(req.getUpdateName()).newInstance();
} else {
handler.handle(req);
}
It's way easier when you have message passing and every level is set up to restart on crashes, but I don't think anything necessarily stops you from doing the same in any other language.- Given a distributed Erlang system with two nodes, where both nodes are running the same release;
- Given the same process (Erlang thread) on both nodes, running the same code (i.e. a GenServer backed by the same module)
- Given a new version of the release is being applied
You can't assume that the two processes will be upgraded at the same time. This means that messages sent between those processes may violate the types expected by one version or the other. Furthermore, in Erlang, any process can send a message to another process, so there is no way to enforce that the data a particular `receive` expression gets will even be a type defined in the code it is running. Furthermore, even on the same node, during an upgrade, some parts of the system are still running old code, while some parts are running new code, so it isn't even specifically about distribution.
There is a whole area of type system research around session types, which are designed for more or less this use case, but from what I've seen, none of them handle the case of arbitrary messages, or the case where system upgrades are being rolled out and old code may receive messages from new code.
I still think there is a place for a type system in Erlang/Elixir, but it would have to deliberately ignore process messaging at the very least, at least until a type theoretic solution is available.
I think that this ideas generalizes pretty well. Just because a language doesn't have explicit types doesn't mean types don't emerge organically. Assumptions will still be made about certain fields existing, there's just no guarantee that the assumptions still hold!
The nice thing about erlang though is that the nature of the message passing interface and pattern matching means that you can get relatively understandable interfaces.
Now I just feel stupid for working mostly in Java. (It's handy and it works. Leave me alone, okay!)
HN is a very skewed place that's into some very niche stuff. That can be fine, it's good to be interested in new things, but no one should draw too many conclusions from trends we see on here.
Just to poke a few HN bears by way of example:
* Rust will never see widespread adoption. It's just hard and complicated, so seems cool and exclusive. * Lisp isn't gonna happen either, and that's because it's not even a good choice for most problems. It just feels really really cool when you write something in a purely functional way and so you imagine that _must_ mean this is some higher plane of existence. Not really, we've had 30-40 years for this thing to take off, not happening. * Even Erlang, while really cool, is just a super niche thing. If you're making a huge messaging service then definitely go for it, but you're making a website? Choose pretty much anything else.
There's a lot of reasons for all of the above (low average amount of experience leading to long term memory loss for the industry being the big one), but this comment is too long already and everyone's just going to be mad about the Rust stuff anyway.
Knowing that (as I did) why not expand your horizon (as I did) ?
What leads you to believe most Java programmers would prefer Haskell or some flavor of Lisp? You're saying that people who spend time in both will prefer the latter, but it seems equally plausible that people wouldn't spend time in both because they don't like the latter.
That being said, I am told my Java is very unusual: lots of anonymous implementations of interfaces, almost no inheritance, code that feels procedural in its local organization.
Languages have their runtime and their constraints, and there are some areas where maturity, tooling and explicit industry support trumps language quality.
C++’s template system is turing complete, which means its type language is too. That lets you move the vast majority of java runtime type errors to compile time.
Moving from Java to modern C++ is analogous to moving from spaghetti Python code to well-structured Java in my book.
Also, C++ is extremely well established.
Python code quality is more a consequence of its beginner-friendliness (and subsequent prevalence of inexperienced programmers) than of the language itself. Similarly, the range of Java code I've seen goes from spaghetti within spaghetti (i.e. lack of structuring at both code and class/package level) over to extremely well-structured code
Never heard C++'s templates turing completeness described as some kind of advantage.
Because I know (old) C++, some of the modern stuff and a bit of Java, I don't know the full history.
Moreover, when people say the like Java, what they really mean is that they like the JVM.
Want to know a language undoubtedly worse than Java? Easy. Append "Script" to it.
COBOL. BASIC, including VBA. Older versions of FORTRAN. All real languages used widely and in production, all far worse than Java.
That's because you're inexperienced.
For "just write a thing that works" I've come to really prefer C# for desktop apps and Python for small things.
You can of course write all your stuff from scratch like several vendors I know have done with C & C++, but I think that is the exception and not the rule.
Mostly agree on the other points. I do like Rust, but it's still young, and many potential areas of use just don't have mature library support with lots of features yet. And some of the community enthusiasm does get over the top - I'm sure not holding my breath for rewrite everything in Rust crowd's wishes to come true, no matter how bad memory misuse bugs have been - including the Linux kernel and the universe of GNU utils.
The long-running programs I’ve used in other languages are architected so they respawn new processes regularly. Or they crash often enough on their own that they don’t get the opportunity to leak a ton of memory.
Of the 4 long-running C-family programs I use the most, 3 have crashed in the past 2 days.
In fact, 10-something years ago, nobody really cared much on immutability on HN, while everybody still talked about Lisp and functional programming (it was all about first class functions, closures, map/reduce, recursion, DSLs, and macros).
Immutability come into the fore (well, for HN) along with Haskel and Clojure -- plus the idea that immutability gives you multicore for free.
Even in Paul Graham's essays, the "foundational documents" of this community, when he talks about Lisp he hardly talks about immutability as any kind of key point.
Common Lisp does not have the "equivalent of GOTO," it has GOTO. I don't know why you think that is a bad thing.
Suppose he didn't ask and just blabbed away? The trust he's developed over the years would be substantially marred. ("Don't tell Joe anything you don't want to show up on Twitter...")
Do I think keeping your tech stack secret is super important or that that secrecy itself is a competitive advantage? Hell no! Do I think it's still your call to decide what you disclose publicly? Of course.
Part of the reason is that if you're in the Java ecosystem, you can be very comfortable as it gives good performance, great mature tooling and libraries for almost anything under the Sun - so why would you want to leave it. And, there is enough demand that you'll be reasonably employed for a long time.
Which in itself is a reasonable argument, nothing wrong with it. But, on the flip side, if you want to grow as a computer scientist/engineer it is always good to look outside and broaden your horizons.
Of course, it might also be because people who have worked in a variety of languages are already 'used' to learning a new language.
We did use C# for two decades so it’s not completely a lie when we tell people it’s our main language, but it’s still a little silly to lie about it.
Because irrespective to if they want to keep their language secret or not, they might not want to be featured in Elixir's homepage, or have any of the other information they shared in a private message go public.
I'm not sure he did. His tweets say:
> However, I can't say who it is because they asked me not to tell anyone they're using Elixir.
And:
> ... we don't want or competitors to have, so please keep this inquiry private.
So in fact they might have just asked him to keep it quiet without him even asking about it.
Still too many philosophical doubts about a functional language where map and reduce only take one enumerable, and have to be prefixed with "Enum.".
At least it's not JavaScript.
Stop trying to make elixir happen. It's not going to happen.