55 comments

[ 2.9 ms ] story [ 107 ms ] thread
This is the best landing page/documentation I've seen in a while. The examples with detailed comments are really outstanding.
Indeed. I wish every language/library site were at least this good.
I sincerely disagree. The introduction requires way too much effort. It is difficult to read, it is not structured well enough, it is too wordy (but missing vital "to the point" examples), and with bad fonts and color choices.
I totally disagree. After reading the landing page, I have no idea what kind of programming language this is.

Someone else mentioned this is based on JVM. There is no mention of JVM on the homepage. So, is it based on JVM? Or some interpreted language? Or compiled to native code?

"The Network in the Language" What does this mean?

"Sequence Diagrams for Programming" What does this mean?

"Structural, Open-by-Default Typing" Looks pretty standard?

"From Code to Cloud" What does this mean? Just some nice tooling?

"Batteries Included" Like most other languages.

"Developer First" What does this mean? What's different to other languages?

This sounds all like marketing fuzz, without telling actually any information. Really. I have no idea what this language is about.

Is this a competitor to other JVM languages? Or to system languages like C++/Rust/Nim/etc? Or to languages like Go/Erlang? Or to languages like Python/Ruby? And what's special about this language?

mdasen summarized my complaints in a nice way: https://news.ycombinator.com/item?id=22402053

My understanding is that Ballerina has semantics for defining multiple services in the same program, and it “compiles” to a set of containers and cloud configs that allow these programs to talk to each other. So very basically it’s like putting Kubernetes or AWS into a language. But there documentation is pretty unclear as many others have noted so I really doubt my interpretation is precisely accurate.
I have followed this language passively for ~1.5 years. I think it's revolutionary, and the big barrier for my adoption is the fact that I do not currently write services for the JVM.

But the ability to define services as HTTP/Ingress endpoints, Docker containers, and Kubernetes/Openshift resources natively as part of the language is incredible. Add that to the fact that they have native support for things like tabular data and table queries as primitives, stream operations, distributed transactions baked in, multiple kinds of service-level auth natively, and a bunch of other goodies like observability/metrics primitives + support for Kafka/OpenAPI/etc etc and you have one hell of a language.

Interoperability with the existing Java and JVM ecosystem is huge.

I would be unpleasantly surprised if this does not take off, or at least similar concepts in other languages. Today, the closest thing you can get is Pulumi for defining infrastructure + deployments in code, and then your regular application codebase on the side.

If you want to see a featureset that a modern language built for web-services & cloud-native architecture should strive for, check out their learn-by-example list (in particular, the items past basic grammar & syntax):

https://ballerina.io/v1-1/learn/by-example/

I looked through examples and I don't see what's so revolutionary about it.

This is specialized language suited for more or less one task that has nothing specialized for that task which cannot be rolled in Clojure in a day or two.

Challenge me, give one example that can't be done as easily with Clojure.

I am curious as well; this still looks like too much plumbing to be revolutionary. It is too close to what we have been doing for years with mainstream languages and tools.
Generally, the big benefit of not using Clojure is to reduce the probability of having Clojure programmers on the project.
This is offensive. Do you want to mean all Clojure developers are garbage? What technology are you working with? Does your entire community consist of stellar individuals with no faults?

Clojure problems typically start because some member of the team had enough power to convince their manager to do something in Clojure. It is not an organization that typically hires Clojure developers and has already people that know Clojure and can interview Clojure candidates. Clojure projects are typically a byproduct of having developers who are not satisfied with your language (Java most of the time) and try to seek out a better tool for the job.

It is not an inherent problem with Clojure or those people. Most developers need an organization to support them and lacking expertise around them they tend to fail in one way or another.

Programming Clojure requires huge amount of discipline and guidance with regards to the structure of actual code which you don't have when you just had got hooked up on it and red through couple of articles. Lacking the discipline and guidance, the code reflects thinking process and understanding of Clojure by a single, novice developer who has the most power within the project. But that is because of how powerful and malleable lisp is.

Languages like Java force you to use particular solutions to particular problems and have huge amount of public guidance and expectations with regards to program structure which means the code is easier to read and interact with by other developers.

You would do better by, instead of being lazy in your thinking and offensive to other communities, to actually try to use your head and try to understand the problem.

(comment deleted)
Must've stuck a nerve there.

> Do you want to mean all Clojure developers are garbage?

Of course not, many Clojure programmers are excellent at programming in Clojure.

> You would do better by, instead of being lazy in your thinking and offensive to other communities, to actually try to use your head and try to understand the problem.

I don't have to do that, because I'm not using Clojure.

Static typing
Love to get downvoted for something factually true that answers the explicit question above it
I did not downvote you, but how is static typing in any sense revolutionary? It is certainly not a new concept and you know it, but your answer does not elaborate any of this at all.

It may be factual, but it is factually useless.

You see, people tend to get hooked up on features of the language they are using especially if they have very limited choice of languages they know. They will vehemently defend their point of view fortified by whole range of cognitive biases. Their combined effect like more alcohol to the drunk to make him feel strong and able to overcome bouncers.

I personally believe no person who can't program in both assembly and lisp should call themselves real/full programmers because they have not been exposed to full range of concepts. You have to, of course, start somewhere. But until you have experienced full variety of possible language features you are not really qualified to discuss any them with any authority.

See also Blub Paradox (http://www.paulgraham.com/avg.html) by the very author of this site.

I have plenty of experience in Clojure (even some of it still in production!), as well as "C family" languages, both statically and dynamically typed. I didn't answer the question out of ignorance. The thing that immediately jumped out at me that "can't be done as easily with Clojure" is static typing.
The question was "Challenge me, give one example that can't be done as easily with Clojure." The answer is "static typing". I never claimed it's revolutionary.
Static typing is a property of the programming language, not something you "do". Do you mean your clients want static type something?

Static typing is a preference of the developer or development organization on whether they want speed or they need a bit of help to understand what they have before their eyes. It lets the compiler call you out on some of your transgressions at the cost of quirky type system and possibly having to need a bunch more code where a very simple solution would present itself when type system does not get in the way.

Static typing is neither bad or good. It "depends".

I didn't make any value claims about static typing (though I do prefer it), I just answered the question of what "can't be done as easily with Clojure". You cannot easily statically type Clojure, and as a consequence cannot easily do any of the things that static typing enables in a language, regardless of how much you value those things.
It doesn't really depend, static typing is objectively superior to dynamic typing, starting with the simple observation that all the mainstream dynamically typed languages are busy adding/retrofitting static typing.
I won't challenge you, but if you're looking for a Clojure/LISP language discourse you might be interested in what James Clark has to say about his language choices. James is behind Ballerina and was working on SGML and groff in his former life, had specified/implemented DSSSL, the transformation and stylesheet language for SGML based on Scheme, and later XSLT (based on his experience with DSSSL, although without LISP syntax).
On quick glance, it looks like a language with lots of battery included. Plus rpc, thrift, maybe?
So, the home page makes some big claims, but doesn't link to how Ballerina solves those issues. I'm not saying that it doesn't. I'm saying that it would be nice to have a link to what makes it different for that aspect.

For example, "Structural, Open-by-Default Typing". It sounds really interesting, but the image next to it just looks like what you'd get in Go (except for nullability checks), C#, Kotlin, and many other languages. Yes, static typing (especially with nullability checks) can make life difficult. You have to make create-request objects that don't have an id in them or you have to make the id nullable. Responses might include different fields like an updatedAt. How do you convert between those types without requiring lots of boilerplate conversion code that you're likely to mess up. But it doesn't really say what it's solving. The saying about being liberal in what you accept and strict in what you send is nice, but doesn't tell me anything. How does it achieve that without lots of code and checking? From the struct on the left, it looks like I'll have to constantly check if id is filled out...or have a CompleteResult type where id isn't optional. A link to an example of what this means and how other languages don't solve it would be wonderful.

Likewise, it says "The Network in the Language". Sounds like great marketing speak that doesn't mean anything. Ah yes, "the fallacies of distributed computing". How does it solve the fact that networks aren't reliable in a way that other languages don't?

I guess I always want to know the "how". Claims are easy, but for many of these problems there's a reason why someone else hasn't solved them. Maybe you have figured out a better way, but the site hasn't said what that better way is. The example image for "Structural, Open-by-Default Typing" doesn't look different from a Kotlin data class: it has statically typed fields, some are nullable. Can I assign a string to an int field and it won't crash? What about when I try to read it? What does "Structural, Open-by-Default Typing" mean? From what I see in the image, lots of other languages have it and I don't see how it enables the robustness principle.

Again, there might be great things in here, but the home page doesn't show anything and the quick tour shows error handling that's similar to Rust (or Go's with a short-cut to return the error like has been proposed for Go 2.

Instead of linking to a description of the problem on Wikipedia, it would be great to link to a page with your solution and how it's a pain point in other languages. Like, how do you abstract away the fact that the network is unreliable? The quick tour shows a client requesting from an API, but the only thing I see is a `check` keyword which is similar to the `?` operator in Rust which just returns the error if there is one and unwraps the result if it succeeded. It's a short-cut over Go's `if err != nil` and more explicit than runtime exceptions, but it hasn't shown me how it's different from other languages.

I guess I just need to know how someone solved a problem if they're saying they've solved it. Yea, we all know that networks are unreliable. We all know the pain of dealing with data that's slightly wrong over the wire. Link to how you're making that better and how other languages aren't handling it well.

> For example, "Structural, Open-by-Default Typing". It sounds really interesting, but the image next to it just looks like what you'd get in Go (except for nullability checks), C#, Kotlin, and many other languages.

Go types are structural. C# types are nominal.

https://en.wikipedia.org/wiki/Structural_type_system

"Open-by-Default" probably refers to the fact that structural types are more flexible to use.

>Go types are structural. C# types are nominal.

Go's type system is also nominal. If it were structural, it would allow you to have two types `type foo struct { id string }` and `type bar struct { id string }`, and let you assign a value of type `foo` to a binding of type `bar`, which it does not.

There’s lots of detail in the language spec:

https://ballerina.io/spec/lang/2019R3/

I also wrote a blog explaining what we are trying to achieve:

https://blog.jclark.com/2019/09/ballerina-programming-langua...

Would be great to have that insight on the landing page. Most people (including me) will first make a judgement call looking at the landing page for a few seconds before deciding if they want to learn more and go through the specs & examples.
> Be conservative in what you send, be liberal in what you accept.

I can't believe we haven't all learnt the lesson of how much of a bad idea this principle is. Has this guy not heard of HTML and quirks mode?

Only because nobody ever persuaded document authors to be conservative (strictly schema conforming) in what they send.
And that is because everyone was liberal in what they accepted, so there was no need to.
Many have tried. The problem is, if the page works as intended, there is no benefit in making it strictly conforming.
It's a great principle when you can ship one version every 18 months or so. A better maxim for today: "be strict in what you accept, and send garbage now-and-then to keep the others on their toes".
The principle makes sense for ambiguities in the specification. But input which is unambiguously illegal should be rejected.
It's being deprecated everywhere to be honest.
I like the idea but I'm not impressed by the language. Syntactically there is a lot of noise (e.g. semicolons, function types are incredibly verbose). It seems to be missing generic types, pattern matching doesn't seem to express structural recursion, if is not an expression, etc. etc.
The language has a lot of syntactic compromises, because it has a design goal of being familiar to users of C-family languages like C, JavaScript, Java, C#, etc.
I don't really buy that argument. Even Java has simple lambdas now, for example.
Ballerina has simple lambdas e.g. x => x + 1.
But several of the listed problems don't exist in many of the listed languages or close relatives (I wouldn't really call JavaScript C-family either, as, except maybe C-style for-loops, it has nothing that distinguishes C from other Algol-syntax languages, and other than Algol-style syntax it's more a blend of ideas from Lisp and Self than anything related to C), so those flaws cannot be necessary for familiarity to users of those languages (Java, C#, and several of JS’s statically-typed derivatives that are designed to be familiar to JS programmers, like TypeScript, have generics, so “missing generics” doesn't make sense as a familiarity compromise for users of those languages.)
I didn't say that all the listed problems were caused by the goal of being familiar.

It doesn't yet have generics because they are hard to get right and the language is still at an early stage. Many languages that subsequently added generics did not have them in the earliest versions of the language (C++, Java, C#, TypeScript, Go).

“Network in the language” has to be a deliberate reference / kudos to Sun’s famous slogan “the network is the computer”.
Session types do exist in other programming languages. Unlike what the site seems to imply.
This is what the future of programming languages should look like. Not necessarily syntactically, but with full-fledged systems out of the box. We're not getting further as a community by just building new source code to plug into our Docker/Kubernetes/Chef/Terraform/gRPC monstrosities. Something needs to tame that complexity. I love that things like sequence diagrams are first class. I've made barely any of these since college and I'd love to see us be able to truly get to working at that level day-to-day
> Robustness Principle: Be conservative in what you send, be liberal in what you accept.

That's a debunked principle that causes unintended harm.

Programs should be conservative in accepting just their documented range of inputs, and loudly rejecting and diagnosing anything else.

Any behavior that looks "liberal" should actually be so by a specified design, within exact limits, operation outside of which is ideally flagged and rejected.

Misunderstood principle. Liberal does NOT mean Malformed.

As you say, all behaviors should be fully specced, and inputs that violate that spec should rightly be rejected. It’s the spec itself that should be forgiving.

e.g. Don’t require fields for which sensible defaults can be assumed. Don’t be needlessly anal about case and white space variations. Maintain backwards-compatibility by continuing to accept older input formats alongside the latest and greatest. Accept ints where floats are expected. And so on.

HTTP is a good application. Whereas the eejits who invented HTML have a helluva lot to answer for.

Yes, the principle does actually mean that nonconforming inputs should be accepted. Well, only if someone has decided that their meaning is clear. But that is rarely so if you're outside of the spec. The intended meaning of a bunch of bits (syntax) can be anything, or nothing at all.

Sensible defaults can't be assumed; they have to be specified. My sensible may be your silly.

If a spec defines certain parameters, and neglects to say anything about their defaults, and an implemention assumes defaults, that will cause issues.

Firstly, the user will break if they go to another implementation which rejects their data. It's not that implementation's fault; it's just catching the error of missing values with unspecified defaults.

Worse, the user's data can silently be interpreted with some different defaults.

You have to be exactly as anal about case and white space variations as the spec says.

A C compiler or linker can't treat PrintF as printf just because the meaning seems clear enough, and PrintF has not been declared or defined.

> Whereas the eejits who invented HTML have a helluva lot to answer for.

In my original version of the comment I used HTML as an example, but decided to omit that.

The problem wasn't the invention of it (though that doesn't escape criticism) but rather the fact that during early Web history and during the first Browser War era, browsers tried to accept non-conforming HTML and render it anyway. Thus people writing bad HTML had no feedback. The pages looked good with whatever browser they tested with. So browsers had to scramble to reverse engineer and imitate each other's handling of bad HTML as good. The effects of that situation persist; it's not fully resolved.

That will happen with any interchange or storage format, if treated with Postel's principle.

Postel's principle is from the point of view of keeping the internet working, in a situation where messages pass through multiple hosts, which are inaccessible to either the sender or the receiver. If something is rejected due to violating a rule, there is no diagnosis; the symptom looks the same like a severed cable at the bottom of the ocean. It's understandable where that came from.

Postel's principle somewhat applies to intermediary data handlers.

If you're just routing messages, and see a message that you don't understand, then just pass it along.

The principle should be "have as little effect as possible; look at only the parts of data needed to do your job, and don't interpret and act on payloads that don't belong to you; try hard to route rather than drop."

True, especially since non defined and non documented behavior will be used and relied on over time by your customers.
> Ballerina is an open source programming language and platform for cloud-era application programmers to easily write software that just works.

Meaningless tagline.

> Static typing is the network application programmer’s development headache and dynamic typing is the reliability engineer’s nightmare. Ballerina’s statically-typed, structural type system that is designed to be network data schema friendly allows application programmers to write code that adheres to the Robustness Principle: Be conservative in what you send, be liberal in what you accept.

Nowadays we recognize that this is not necessarily a good idea. Se the very long ietf@ietf.org thread titled "deprecating Postel's principle - considered harmful".

"Yet, no current programming language lets you write your logic as a sequence diagram."

Welcome to automation (PLC) programming where sequence programming has been around since 80s.

I saw this at Kubecon 2018 and even got a sweater from the folks there. The idea of an all-in-one soup-to-nuts system is pretty unusual these days.

So, this is a fascinating project. I don't know how I'd introduce it at a company though. Maybe in a skunkworks group or something. Possibly if I was working as some sort of middleware-integrator group.

The JVM bits don't bother me, but it does make things heavierweight than I'd like.

Curious if anyone is using it, it seems to have tons of potential.

I saw their demo at Kube-Con Barcelona. Pretty cool stuff. They deployed the sample into kubernetes by generating YAML and docker via the compiler. An aspect that other languages should think of.