fmontesi

Joined 11 years ago

Karma
87
Submissions
31
Member since
Feb 3
Professor of Computer Science. Principal Investigator of Choreographic Programming. Lead Maintainer of CSLib, the Lean Computer Science Library. Maintainer and co-creator of the Jolie programming language.

Twitter: https://twitter.com/famontesi

View on Hacker News

Recent submissions

Comment · 2 months ago
This question is in fact core to research in the paradigm. Let me first address how it works and then the expressivity question.

A choreographic programming language features programming abstractions for programming communication intent. For example, often they have a primitive like:

Alice.expr -> Bob.x

read 'Alice communicates the evaluation of expr to Bob, which stores the message in its local variable x'. (In fact, we discovered that we can extend any mainstream language to have this kind of high-level primitives by extending data types with locations, see choral-lang.org).

This makes it impossible to write mismatched communication actions, because you're expressing both the send and receive actions in a single atomic instruction: they are well-matched by construction. You then build a compiler (typically called 'projection') that generates distributed programs for Alice and Bob -- the former doing the send to Bob and the latter doing the receive from Alice. We like making formal models of these compilers and mathematically proving them correct. A compiler that respects the choreography then automatically entails deadlock-freedom of the compiled code without the need for complex checks, because the source choreography cannot syntactically express deadlocked terms.

Consequently, there are no deadlocked distributed programs that we can compile from choreographies. It's an application of the neat trick of designing high-level languages for 'guiding' programming: instead of programming a distributed system with low-level primitives and then attempting the generally very hard task of checking for deadlocks, we use a high-level language where deadlocks cannot be written (or are at least easy to check against).

The above hopefully explains the intuition of how choreographic programming works. But then, as you did, one naturally asks: What can we express in choreographic programming languages? Are there fundamental limitations?

We do not know exactly yet; this is an area of very active exploration. Over the years, people have developed more and more clever choreographic programming languages that capture more and more interaction patterns.

What's perhaps surprising is that, for some theories of distributed languages (or interaction patterns, if you like), we know that choreographic programming is complete, in the sense that it can capture all deadlock-free systems that can be modelled in those theories. The first result of this kind was about capturing all interaction behaviours that can be described in linear logic (in the Curry-Howard interpretation of it with process calculi), but there are also works that can deal with recursive behaviour and even process spawning (fork). That's encouraging.

I think that investigating what the paradigm precisely can and cannot do is fascinating (but I'm very biased here..), not least because using a mathematically-modelled compiler lets us optimise the generated code aggressively (e.g., adding more asynchrony, as in Ozone). From the state of the art already out there, it looks like choreographic programming is 'expressive enough' for many different purposes. Hopefully it's gonna be the typical situation with high-level abstractions, whereby for most cases and most people the high-level language is gonna be good and low-level communication actions will be necessary only in niche scenarios. In the meantime, there are choreographic languages that can be integrated with middleware and foreign APIs to cover up for deficiencies (like Choral, HasChor, etc.).

Comment · 5 years ago
Comment · 5 years ago
Comment · 5 years ago
In a nutshell: because we want to minimise code <-> model distance. Other languages make you program in terms of functions, objects, etc., and make yourself model services by using these concepts. In Jolie, you write code that maps directly to the concepts that matter. What are the important concepts? APIs, Access Points, and Services (duh..) are examples.

Some more info at:

- https://dzone.com/articles/introduction-to-jolie (a brief introduction to Jolie and some concepts)

- https://hackernoon.com/a-detailed-introduction-to-service-or... (a deeper dive/discussion on some of the concepts)

Our (for now subjective) experience is that people who become familiar with Jolie are much faster at prototyping a service system, which makes it worth pursuing for us. Jolie code requires less boilerplate and state management for interesting scenarios. Two examples: communications can be natively composed in structures, e.g., the code

  open()
  close()
mandates that only the open operation is available at first and then only close is available (in object-oriented languages, you must encode this state with a private data field and manage it with if-then-else, etc.); likewise, streams in Jolie are consumed by writing

  provide
    [next(element)] { ..manage element here.. }
  until
    [end()] // stream ended here
which means "provide the operation next to invokers until operation end is called". A syntactically manifest approach to reactive programming and state machines, if you like.

Another big reason for exploring languages is discipline. Languages discipline how you write code. An example: in Jolie, you decompose software in terms of services. Many of these run locally as libraries, and are optimised by the interpreter by using hidden shared memory. But the language enforces that if you ever decide that a component should become an external, independent services, you can do it by updating a few references (input/output ports, our access points). See also https://fmontesi.github.io/2015/06/09/non-distributed-micros... Another example: Jolie discipline also gives you the ability of reusing the same business logic under multiple access points with different protocols.

This is the tip of the iceberg. In general, programming in terms of service abstractions is showing to be an interesting experience for us.

Phew, that was quite a bit for a "in a nutshell".. I hope that it's clear, otherwise, just write below.

Comment · 5 years ago
It's Jolie as in pretty, not as in Angelina.

But I don't wanna stop you from making all these languages... (o:

Comment · 5 years ago
IIRC, in industry, there is at least one big system with 50-ish microservices that includes electronic invoices. (See https://www.conf-micro.services/2019/papers/Microservices_20...)

At our place, we have a few websites written in Jolie and a system of services for evaluating software projects (for exams).

Feel free to drop in our chat if you're interested in chatting more about this with others as well: https://discord.gg/yQRTMNX

Comment · 5 years ago
Cool project, I'll check it out.
Comment · 5 years ago
Thanks for the kind words, I'll share them with the rest of the team.
Comment · 5 years ago
Yeah, we have SOAP because... SOAP (just because of interoperability).

Our SOAP is quite palatable at least, because of reduced boilerplate. AFAIK Jolie devs don't typically use it (I don't at least), unless it's really necessary (interoperability with legacy web services, business requirements, etc.).

Comment · 5 years ago
PS: We support integration with Java, so you hack your way around this by using some Java code for grpc, but it doesn't feel "native" and require some boilerplate.
Comment · 5 years ago
Jolie and SODEP predate grpc, so we don't have grpc just because we had no need for it (we already had a binary protocol with expressive interfaces).

It's definitely something we'll get around doing sooner or later though, since so many people use it, and we do care about interoperability. Contributions towards this would certainly be welcomed warmly.

Comment · 5 years ago
Comment · 5 years ago
Woah, so this happened. Maintainer here. I'll do my best to reply to all questions/doubts that get posted about an hour from now, since there is some valid feedback and there are some good questions in here.
Comment · 8 years ago
Here's also Github. It's resource-oriented instead of verb-oriented (like Telegraph), so we use Jor instead of Jo (both are provided by the same library).

Jor["users/fmontesi/repos"].get().then( response => ... );

Notice that using ["users/fmontesi/repos"] is the "alternative" syntax. If the resource path is a valid method name in JavaScript, e.g., "/users", you can just write this:

Jor.users.get().then( response => ... );

I'm still wondering what's the best way of offering resource paths. Using a string is fine, but another option would be to have an extension of JavaScript, like JSX in react, but that would add a dependency (on Babel, for example). So we could do something like:

Jor.users/fmontesi/repos.get().then( response => ... );

Another option could be to use an in-between method, for example:

Jor.users._.fmontesi._.repos.get().then( response => ... );

But this looks a bit clunky. So the design space is a bit larger here. Mumble mumble. :-)

Comment · 8 years ago

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton