Caramel: an Erlang back end for OCaml
github.com
github.com
The intermediate representations used in (and even accepted as input formats by) the compiler are relatively unstable, with the exception of the Erlang Abstract Format.
This makes it a great target for other compilers because they don't have to track breaking changes to the intermediate formats, they don't have to worry about generating BEAM bytecode, and they get to take advantage of all optimisations already implemented in erlc (the Erlang compiler).
As an example of recent amazing changes to the BEAM: JIT to x86_64 https://github.com/erlang/otp/pull/2745
Another way of looking at it: almost nothing that is important or wonderful about writing Erlang is the language itself. Most of what people rave about is the BEAM. This means you can fairly easily throw out the language and use a different one and get all the benefit.
Now that I'm thinking about it - that last point is a spectacular achievement of design and abstraction.
so it's easy to get started, easy to get something usable quick and easy to see how it's used in real stuff.
https://github.com/kjnilsson/fez
https://skillsmatter.com/skillscasts/11312-fez-fsharp-type-s...
Static analysis is great and required for modern development in dynamic languages and CPU/memory intensive to do well
These big companies should write their own LSP server since all editors support the LSP protocol and mandate their use in employee editors
Waiting till compile time to find that typo is rubbish, at runtime and compile time there should be as little checks as possible to keep performance up and the application running but on every keystroke in the editor it should be check city and again in CI
Instead Facebook keeps lagging up their dynamic languages by building incompatible languages with static analysis into the compile step fracturing communities for a worse solution
With a good IDE it's more pleasant than writing Elixir with typespecs and guards in that regard.
So what are you unable to accomplish in Erlang that makes you feel like it’s missing something?
You can write extremely reliable code in C (e.g. medical devices and car ECUs) but you have to be vary careful with any concurrency and usually dynamic memory allocation is banned. An enormous amount of testing and other design rules are needed. Maybe Rust would help to automatically check some of those things that otherwise require a lot of work to achieve.
You can write highly concurrent server applications in C. It's a lot of work and bug prone. If you write them in Elrnag or Elixir your life will be much easier. That's why we use them.
Maybe a static type system would help enforce some invariants about your code. Maybe it saves you from witting some classes of test. Basically, maybe you get to the same endpoint but with less work.
The things that help you usually also limit you
See: training wheels or armbands
I've seen much code written in static typed languages (mostly JVM languages) that supposedly help the programmer to write better code or code with less errors just by playing tennis with the compiler
Thruth is that most of the code I've seen written "with type aids" is terrible from any other point of view
The types are correctly passed to each function, but what purpose those types serve it's a mistery
When you only have numbers, binaries, lists and tuples,you are forced to think about data structures in a simpler and more elegant way
IDE generated "type safe" code too often is simply "a class for everything" and bad abstractions
Most of the time when I review code my remarks is: it should be a 10 lines function, why did you write 10 classes with 10 getters and setters each?
This is the fault of the language or programmer itself instead of its type system.
I am programming in Dart and sometimes I feel that I am writing some code just to workaround some limitations in the language (the language itself is nice 90% of time, just to make it clear).
Now, I also program in Python using mypy, and I never needed to write "10 getters and setters" to make the compiler happy. Sometimes I do need to write additional code to make mypy happy, but generally it is in overly clever code that mypy doesn't understand. So generally fixing the issues makes the code better.
Not that I disagree, but I argue that bad programmers are the result of bad languages enabling them and bad use of types by the programmers is the result of a bad implementation of types in the language.
Most of the statically typed languages around are used to enforce conventions inside large teams of coders, they are not used to "model the problem elegantly".
If type driven development really produced bug free code while requiring the same cognitive load as hammering tens of lines of code one after the other, we will all be using something like Idris.
This is not the fault of the type system though. It is the fault of things like enforcing access via private/protected/public keywords. While most people confuse this with a static type system, this is not part of the type system.
> [..] they are not used to "model the problem elegantly".
I concur, but let me make my point more clearly: this is either the fault of the language for not allowing the programmer to express itself clearly, or it is the fault of the programmer by using patterns from a less expressive programming language in a more expressive programming language.
This is not the fault of the type system, that doesn't (by itself) require the user to create a Class with getters and setters for every attribute, for example. If the language you're using makes you do those kinda of things, it is the problem with the language itself, the type system is just the point of the iceberg (that is making the problem worse).
> If type driven development really produced bug free code while requiring the same cognitive load as hammering tens of lines of code one after the other, we will all be using something like Idris.
It doesn't produce bug free code (because there is still logic bugs), but it helps to reduce the number of bugs. But only in expressive type systems that are also sound. The Java type system for example doesn't help much (however I think they implemented nullables at some point, so the situation should be better).
Java is an extremely poor example of a helpful type system. Consider OCaml, Haskell, Elm, and others which avoid much of the verbosity you describe.
Static typing is really helpful when doing refactoring. The fact that a statically typed program compiles gives you important assurances - especially post-refactor. It's not a silver bullet but it's also certainly not "playing tennis with the compiler" as you describe.
My point exactly!
Most of them are.
Java is not special in this regard.
C? bad
COBOL? bad
C++? bad
Pascal? bad
Rust? better, but somewhat confusing
Go? not particularly good, but at least it's very simple
C#? same defects Java has
etc. etc.
Statically typed languages IMO are like turbo charged engines, if you are an expert driver you could go way faster, granted the road is in good shape, but if you are not, you'll crash, possibly in a horrible way.
> The fact that a statically typed program compiles gives you important assurances - especially post-refactor.
The only assurance in most of the statically typed languages is that code compiles, not that it works.
I'm at the point where I refuse to write production code in a language that doesn't have an expressive type system. Dynamically typed languages are even worse.
Scala is so complicated that people use only a fraction of its features, usually the simpler ones.
It takes a real commitment to become a prolific Scala programmer.
> Dynamically typed languages are even worse.
I don't comment on personal taste, everybody has their own.
Scala is complex, writing production grade Scala requires skill not common, it is like asking regular commuters to only drive F1 cars.
Would everyone go faster or there would be more crashes?
Would you blame drivers for the crashes?
I used to be a professional Scala dev and loved the language. Sure, there's some complexity, but I still strongly believe it is the most powerful and expressive static language around.
(I studied Scala at EPFL with Martin Odersky as professor)
ADTs, inference, type-checking, pattern-matching...
All those tools are made to help the programmer write better, safer programs more easily, as well as lay out his thought It is generally associated with FP, and are fond in languages such as Rust, Ocaml, Typescript, Haskell, F#
From what your examples are ( C, java, C#...) and the drawbacks you see (too much getters -> linked to an OOP style of programming), what you mean by "strong type systems" looks like it is the old C-style type systems (+ OOP though I don't really get what oop has to do with type systems). These systems are not mainly intended to help the programmer but are really meant ro help the compiler. When in C you write
`int a;`
What you're doing is indicating to the compiler that for operations involving variable a, it should use the machine instructions for operation on integer (you can replace C with java and machine with jvm...). These are necessary in order to have low-level control, but are not really hepful (apart from, maybe, documentation purposes. It is always useful to know that that ipv4 variable is a 24-bit int and not a string...)
These two types of systems are tremendously different things. I can really understand that you don't like static type systems if you only know the second type of system, which basically only adds constraints.
I think you should take a look at ocaml, or perhaps haskell, it would probably expand your horizons
With generics added 15 years ago, lambdas with argument type inference 6 years ago, local variable type inference two years ago, and ADTs and pattern-matching [1] gradually rolling out already, Java is practically becoming an ML. I say that as someone who likes both ML and Java. The two are becoming so similar that I think it's a stretch to claim one of their type systems is more helpful than the other.
But I think people overlook type systems' biggest benefits. Empirical observation has not found any significant benefit to correctness in general (although there seems to be some in particular cases like JavaScript vs. TypeScript and I wouldn't be surprised if we find it in Rust vs. C), but the main benefits are code organisation and tooling support (refactoring, code completion).
[1]: https://cr.openjdk.java.net/~briangoetz/amber/datum.html
For new code, yes.
For old code, it's more in the realm of COBOL
Also given that is one of the few languages that can speak fluently with technologies that are not very well known anymore, but still rocking many boats like SOAP webservices or AS400 mainframes
The bulk of the Java applications are inside banks and insurance companies
> are code organisation and tooling support (refactoring, code completion).
Agree.
Even though code completion has never been a problem for me in the past 20 years, not even with bash lately
If you're talking about programming style, I don't see the resemblance (have you seen COBOL code?), and if you're talking about usage, then Java is much more popular and used in many more domains than COBOL ever was. If you must compare it to anything, then the C of large server-side software would be a more apt comparison, I think.
> The bulk of the Java applications are inside banks and insurance companies
And Apple and Google and Netflix and Amazon and Alibaba and governments and militaries and telcos and cedit card companies and airports and power plants and factories; wherever you'd find big, mission critical server apps, really.
A lot of it
Always stayed away from it
> Java is much more popular and used in many more domains than COBOL ever was
It was merely a comparison on the number of line codes deployed that never changed over decades and nobody wants to touch anymore because they drive critical systems, that move a lot of money
The same reason why much of the COBOL in existence is still around
I wasn't comparing the capabilities or the qualities of the two
> And Apple and Google and Netflix and Amazon and Alibaba and governments and militaries and telcos and cedit card companies and airports and power plants and factories
They rely on COBOL code too...
Believe me
> They rely on COBOL code too...
And quite possibly VB, too. But those companies write much of their new software in Java. They don't do it in COBOL (or in VB).
The same code from 20 or 30 years ago compiles today with little or no modifications
Try to run a servlet from 1998 or a struts web app from 2001 with a recent JVM
And yet you still find them in a lot of places, that you don't see, because you don't work with them, but that probably manage some of the transactions you make
They are legacy because they are being maintained for clientst hat have been using them for at least 2 decades and are virtually untouchable, but are still being updated, slowly, to keep them running
I'm not insisting, it's what it is.
VB is not legacy, VB is dead
No large company ever relied on VB to keep going
__ever__
COBOL is still being developed, because it's still used
To the point that COBOL can interface to Java or C# because companies prefer to update thei COBOL programs to call outside than rewrite them
The final approved ISO (of Object oriented COBOL) standard was approved and published in late 2002.
Still, there are probably billions of legacy lines of code in C, C++ and Java, and hundreds of millions of lines of code in those languages are still being written every year (in Java more than in C/C++). In fact, more new lines of code are professionally written in new Java codebases than any other language with the possible exceptions of JS and Python (although probably not).
Like COBOL, existing VB code is still maintained, but very little new code is written. I'm not saying VB is exactly like COBOL, but I don't see any resemblance between Java and COBOL any more than I would between C and COBOL or Python and COBOL.
Are you sure?
Most of the APIs have been deprecated.
Builds for modern systems (64 bit) are non existent.
OS/2 has been dead for 20 years and there isn't much code being written for it anymore, I remember the Italian train company using OS/2 terminals, they have been dismissed more than a decade ago because IBM ended support for it.
Ironically you can run OS/2 in your browser, but not Java applets.
https://www.pcjs.org/software/pcx86/sys/os2/ibm/1.0/
Now, to explain you what I mean when I say old Java code is as legacy as COBOL I will start with a story: it took Github a year and a half to upgrade from Rails 3.2 to Rails 5.2, on a less than 10 years old code base, to some of the best Ruby/Rails experts in the World.
Imagine that there are services that government agencies use, written 20 years ago in Java, by average former COBOL programmers that wanted to try new things, that will not be rewritten soon, and if they will it will take years for them to be adopted, that are interfacing with even older code running on mainframes.
Management bought the story that Java programmers were easy to find (they still are), being a Virtual Machine it would run easily (write once, run everywhere) and that was Enterprise (it was in the name).
It wasn't completely true.
The path Oracle pushed Java to make it compelling for new generations of programmers left behind a lot of already written and deployed code that can't be run directly on modern systems, can't be touched 'cause companies rely on that code and even if it could be upgrade there are no Java programmers that wants/are able to do it (it doesn't boost your career to work on it) if the hardware won't fail in the meantime.
2000 Java code is harder to write/maintain/upgrade for a Java programmer of 2020 than 2000 COBOL was for a COBOL programmer of the 70s.
In 5-10 years, when the first generation of early Java adopters will retire, there will be billions of lines of Java code that nobody will know how to keep running.
To coin an old programming phrase "The determined Real Programmer can write COBOL programs in any language"
Yes.
> Most of the APIs have been deprecated.
Most of Java 1.0 is not deprecated, and runs unchanged today. Also, deprecated doesn't mean removed. The browser plugin is no longer developed and is not supported by contemporary browsers, but it's easy to turn an applet into a desktop app that runs on the latest version of Java (the Applet classes are still shipped with JDK 15, you can still compile that code, and you can still run it if you wrap it with some desktop runner).
> OS/2 has been dead for 20 years and there isn't much code being written for it anymore
You're missing the point. A lot of C code out there targets platforms like that. It is much harder to maintain than Java code.
> Ironically you can run OS/2 in your browser, but not Java applets.
You can run Java them (and desktop apps) the same way: https://www.leaningtech.com/pages/cheerpj.html
> The path Oracle pushed Java to make it compelling for new generations of programmers left behind a lot of already written and deployed code that can't be run directly on modern systems, can't be touched 'cause companies rely on that code and even if it could be upgrade there are no Java programmers that wants/are able to do it (it doesn't boost your career to work on it) if the hardware won't fail in the meantime.
Except this is more true for C and C++ than for Java, and I still don't see the connection with COBOL. It's easier to run old Java code than old C/C++ code because the compatibility is so much better.
> 2000 Java code is harder to write/maintain/upgrade for a Java programmer of 2020 than 2000 COBOL was for a COBOL programmer of the 70s.
I don't know if that's true or not, but I do know that 2000 Java code is much easier to maintain than 20-year-old C/C++ code. Seems like you're not familiar with legacy C/C++: the situation there is much worse. I've seen systems running on ancient hardware because the C software was written for OS/2 or a particular version of the AIX compiler that comes with an AIX version that doesn't run on more modern hardware. I don't think there's any language with a better situation than Java when it comes to old codebases.
Like a lot of Java code targeting Android is harder to maintain than C++, after just 6 months or depending on the brand of phone it runs on...
> You can run Java them (and desktop apps) the same way: https://www.leaningtech.com/pages/cheerpj.html
Cool
Android isn't Java, and it's never been. It's an incompatible fork that has never conformed to the Java specification of parts of an old version of Java. Its compatibility story might be very different from Java. It is also much smaller in its reach than Java, and even of COBOL, and its domain is also much smaller than either.
In my experience, Java's generics were horribly confusing and not quite type-safe, in contrast to the dead-simple polymorphism in Haskell. But feel free to correct me here.
> ADTs and pattern-matching gradually rolling out already
What a language gives you is less important that what it makes easy, and I cannot imagine a more cumbersome syntax for ADTs than the one in the linked proposal.
Oh, they're typesafe (except for a bug in the implementation found a couple of years ago) but I agree they're more confusing than in languages without subtyping. I'd still pick Java over Haskell any day (but I'd take Haskell over Scala). Pick your poison, I guess.
> What a language gives you is less important that what it makes easy, and I cannot imagine a more cumbersome syntax for ADTs than the one in the linked proposal.
Nah, the syntax is fine. Somewhat more verbose than ML's or Haskell's, but it fits well with the rest of the language. So instead of Haskell's,
data Expr = ConstantExpr Int
| PlusExpr Expr Expr
| TimesExpr Expr Expr
| NegExpr Expr
deriving (Show, Eq);
You write, sealed interface Expr {}
record ConstantExpr(int i) implements Expr {}
record PlusExpr(Expr a, Expr b) implements Expr {}
record TimesExpr(Expr a, Expr b) implements Expr {}
record NegExpr(Expr e) implements Expr {}
Not quite as succinct, but it's not really any more tedious (and you get component names, too).Static typing with functional programming languages works really well because the types are so simple. If you look at OCaml, or Haskell, or F# you simple types, but with a lot of benefit of type checking.
No, I'm not.
I'm simply pointing out that most statically typed languages, the most used ones especially, don't particularly benefit from static typing.
> Static typing with functional programming languages works really well because
IMO it is because they are mostly used by more experienced programmers, that can already layout the types in their head.
Try to teach the average Java programmer (I'm not saying I'm a better programmer, Iḿ just intending it as "they are trying to get through the day with the tool they already know") how to effectively use types "like in Haskell" and they will be confused at best.
> OCaml, or Haskell, or F#
I do look at them but together they make probably less than 5% of Java programmers, even less if we measure lines of code
EDIT:
My position is based on the time spent reading studies about the subject.
Let's not be emotional and downvote what we don't like to hear and be more rational and look at the facts.
If you like statically typed language because they make you feel safer, use them.
Is it an universal property of statically typed languages? Id it a measurable phenomenon?
Are statically typed languages inherently safer for everybody?
The problem, at the time of writing, is undecidable.
here's a review on the literature on the matter
https://danluu.com/empirical-pl/
> Other than cherry picking studies to confirm a long-held position, the most common response I've heard to these sorts of studies is that the effect isn't quantifiable by a controlled experiment
> Try to teach the average Java programmer (I'm not saying I'm a better programmer, Iḿ just intending it as "they are trying to get through the day with the tool they already know") how to effectively use types "like in Haskell" and they will be confused at best.
Counterpoint: I don't use any ML/Haskell languages regularly, but I do use a couple of projects written in them[1]; my preferred language is Common Lisp, the It dynamic language. When I needed a feature, it was dead simple to do so.
1: matterhorn, the Mattetmost client and bower, the E-mail client, which are written respectively in Haskell and Mercury.
I'm faster at finding and solving the issues with languages I know best (not surprisingly) regardless of their static or dynamic nature.
Experience, in my case, is knowing where to look, being able to quickly parse an error message, from the compiler, the linter or the runtime, but most of all knowing the code base at heart.
When I confront a code base that is new for me, I feel lost, whatever paradigm has been used.
I simply don't know where to put my hands before I spent time reading and analyzing it.
The time required to understand it depends exclusively on the complexity of the project.
There hasn't been a single time where types have helped me (more than being able to grep the function signature) or their absence slowed me down.
And as someone who has written JS for over a decade, TS is hands down better, it’s not been close how much nicer it is to work in the latter. The bigger the project is the more it helps.
Don't want to sound harsh, but it doesn't take much to be better than JS
I have had the opportunity to teach java programmers the basics of Haskell, and indeed, it was not great. Trying to tell java programmers to write haskell-flavored java is not a great idea.
On the other hand, I have also had the opportunity to work with C#, JS, C programmers that were taught to work in a haskell codebase, and the result was much better.
I guess using a language explicitly made for this helps a lot.
Not because of their Java background, but because the complexity of developing in Java is hidden behind tooling not available in other languages, that make it manageable
It is almost unimaginable for Java programmers to use vim or a non Windows setup (thanks to Java IDE like Eclipse, Nerbeans or Intellij that's less of a problem nowadays)
That's an opinion presented as fact. You are outright discounting the opposing view. That's why you're being downvoted, not because anyone is being emotional.
Some benefits:
- performance. compiler can make huge optimizations if it knows the types.
- refactoring. changing functions might change data expected in another function. you could remedy this with unit tests, or just use static typing.
- onboarding. new developers on a project, regardless of experience, don't "layout the types in their head", static typing helps.
and yet, none of us seem to be programming in binary.... huh. Maybe there's some value in those "training wheels".
The benefit just isn’t that prominent in a system built for the BEAM from what I’ve seen. And there are a bunch of negative trade offs that make distribution and hot reloading a lot more complicated.
Static typing severely hinders hot code-reload, which was deemed more important for long running systems.
And whether your types are runtime-checked or statically checked doesn't really matter with regard to the invariants that hold for your code. In the former case, you'll have to be able to handle type errors at runtime as well, which is reasonably easy in Erlang due to the strong isolation it provides.
Probably there is a subset of extremely smart people who can write good and very reliable software in a dynamic language without going mad, but I am not among them. In the end I just left the language and now I am much happier with a mix of TypeScript, OCaml and Rust
Also the reliability they are talking about is quite different from the reliability that most people (especially ones who have not worked on erlang-y systems) think of when they hear the word. The Erlang reliability is about finding bugs and patching them (often in production) and not about avoiding them in the first place. Also it's about avoiding total system failure because of some bug in a part in it. This is a nice to have thing in all systems, but Erlang makes it easier to implement.
Of course, they also like to avoid bugs, but for that they use testing. And of course, we have to mention dialyzer which is something like TypeScript for Erlang but a lot less polished and with practically no tooling support. It is used in every significant Erlang project but the process is IMO quite sub-optimal and the price you pay (in suffering) is quite high.
It's not that you can't make good code in any language, but the cost is often not worth it; anything that makes it easier and more reliable saves you time and effort in the long run.
Hence I am waiting on Gleam before I invest in Erlangy stuff. In the meantime I will explore the actor model of concurrency with F# Mailboxes.
This is kind of the key bit.
To caveat this - I'd like better typing in Erlang, and when i last used it in production I added type annotations to everything and ran Dialyzer as part of the build. But this is personal preference, and I'm not convinced it was the best use of my time; just the most conservative way to approach things for a system I needed extremely high uptime on.
You have to write tests anyway. Just because a statically typed system compiles doesn't mean your test load is reduced. While it eliminates certain classes of bugs, those same classes mostly get covered just by writing functional tests of sufficient coverage.
Between that, and Erlang's supervision tree (so that if you DO get a type error at runtime, it would be in a path you haven't adequately tested, and so not your expected 'happy path', and as such, can reasonably be restarted), it strikes me as a reasonable position to take.
Regarding testing - I think it depends on the type of application you are writing. If you need 99.99% uptime, probably you have to have almost full test coverage.
But for the kind of software that I write (at least lately), I rely on "let's make illegal states unrepresentable" to a large degree, then write a small number of regression tests (or fix the types) when we find bugs... This has proven (at least to me) to be good enough, especially compared to my clients' previous experience, which is usually very poor: extremely buggy software in a dynamic language with almost no tests and docs. Perfect quality is usually not needed or at least not worth the price.
Will you not be testing your code anyways? Will you not have unit tests and integ tests and have it run in a devo environment first? Before going to production?
If so, then what would the gap be? If you catch those same type errors as you test, and you will be testing anyways?
When I write Erlang, I'm not necessarily concerned with avoiding errors. The philosophy of the system is that errors will occur, and the focus is on making sure errors do not compound into system failure (supervision tree helps with this), that they're easy to see (appropriate logging of crashes), and that it's easy to deploy fixes (hotloading).
I'm sure there are many ways to avoid some errors in production, but more focus is on responding to errors than on preventing them. At least in my experience.
Examples:
- I accidentally pass in 3 params instead of 4 to a function (with static typing this does not compile)
- I forgot to handle an edge case (I can use a discriminated unions for example to handle all cases explicitly)
- I did not check if something was null and pass it in to a function (does not happen in most ML languages)
I know that you can have editor plugins to handle these, still. I can develop reliable code much faster in F# than in Clojure, even though I love Clojure to death.
You can do many things in Erlang that helps with these, still it would be really good to have a language that unifies Erlang and ML (any ML with Hindley–Milner type system would work).
In Erlang this will also not compile, unless you have a 3 parameter version of the function, in which case static typing will not help you.
- I forgot to handle an edge case (I can use a discriminated unions for example to handle all cases explicitly)
You also forgot to write a test it sounds like. And if it affects your production code, you also forgot to think through your supervisor restart strategy.
- I did not check if something was null and pass it in to a function (does not happen in most ML languages)
Null isn't a special thing in Erlang. You can have the atom 'null' or 'undefined' or whatever, but that's an intentional assignment you create. And given the single assignment immutable nature of Erlang, you won't accidentally be setting/leaving things set to 'null'.
> unless you have a 3 parameter version of the function, in which case static typing will not help you
I half disagree. Let's say we go with the above scenario. If you have a three parameter function, static typing adds a check that the input parameter types need to match, if they don't, the program will not compile. Additionally, the returned type of the function may also not match, which would also be caught by the compiler, and depending on when the developer is writing the code, maybe immediately by the developer noticing that the type signature of the function does not match what they expect.
With dynamic typing, those checks have to happen at runtime or as a human written test. But if the compiler is smart enough to do it automatically, why not use that?
> You also forgot to write a test it sounds like. And if it affects your production code, you also forgot to think through your supervisor restart strategy.
Programming languages like F# have exhaustive pattern matching, which obviates the need for testing on whether all cases of a union type have been matched, because if they haven't, the compiler will emit a warning or error depending on one's language server settings. Whichever setting is used, the developer immediately knows they are missing a pattern match case at compile time.
>ngiven the single assignment immutable nature of Erlang, you won't accidentally be setting/leaving things set to 'null'.
This is similar to ml languages like F#. They are also immutable by default. F# calls it "unit".
Re: testing - regardless of whether you have static typing or not, you should be exhaustively testing every pattern you match on, to ensure you're doing the right thing. If you don't, you don't care about the behavior in those cases - in most languages that's a problem, in Erlang it's a "if that happens, supervisor restarts", and you focus your effort on ensuring restarts put you back into a good state (which you do anyway, ergo, no additional work unless you choose to invest it).
Erlang is a little unique in this regard; it's not that it doesn't have error handling and that static typing might not be a benefit, it's that proper focus should be on the supervisor strategy and "what happens when things go wrong". Of course things that reduce how often things go wrong are helpful (for log consumability if nothing else), but they don't buy you that much if you're doing things correctly; the whole 'correctness' mechanism is separate and distinct from those concerns (whereas most other languages it is not).
In theory what you say is equivalent, but in practice, thinking about these things at the design phase is far more easier than to handle them with testing (which is pretty forgiving if you miss things).
But I recognize that as -personal preference- when it comes to Erlang. It allows me (and my teammates) to be explicit, and the machine helps me (us) be consistent in my explicitness, even when, again, via experience, I know it doesn't really effect how reliable the code is. Reliability in Erlang comes from testing, and proper supervisor patterns and reasoning. Static typing might reduce the number of supervisor restarts, but it doesn't reduce my test surface, nor the need to ensure arbitrary restarts get my system back to a good state. Even when using Dialyzer, it didn't push the needle on how reliable the system was. It just changed the characteristics of writing/reading the code; a bit more work to write, a bit less work to read.
> In Erlang this will also not compile, unless you have a 3 parameter version of the function, in which case static typing will not help you.
This is only true if the function you are calling is part of the same module (and is not called in module:func(Args)-form). If it's not, Erlang will happily compile it and you'll have to rely on xref to catch the error.
This is one of the compromises it takes to get hot code reload.
With a statically typed language I (or my teammates, or people who write libraries I use) cannot forget to write a test for something like that because the type system ensures that it is caught. I don't have to worry about someone forgetting to write tests, and I don't have to wait until they've got a suitably large test suite to be certain of the guarantees the code can make.
At which point, it really matters and then you spend more time and effort checking and fixing incorrect types. My application crashing because some deep dependency wanted an integer instead of a string, and neglected to tell me is an annoying experience that slows me down, and having to write messy code to validate everything ends up getting in the way of actual business logic. Wildly sending variables into functions and just hoping it won't crash or behave incorrectly and then relying on devs writing comprehensive-enough tests to cover everything produces fragile code in my opinion. Writing and maintaining boilerplate tests just to ensure basic behaviour (before we even get to testing the actual functionality) instead of relying on a type system to simply prevent those issues from ever occurring in the first place seems like a mistake to me.
Isn't BEAM already strongly typed? Did you mean a static type system?
In the linked slides they say "We are working on a [static typing implementation (what exactly it will look like is still unclear afaik)] prototype, open-sourcing in November"
What is the real benefit of this over ocamlc ? Can we get erlang interop ?
You basically can't run anything on the BEAM without that interop anyway.