r/ProgrammingLanguages • u/Rich-Engineer2670 • 1d ago
Discussion Agile Programming Languages
No, not that type of Agile....
With cloud-based computation now the rage, I'd like to see a language construct where I could declare methods that were "cloud eligible". Imagine code with the following method in it
promotable func MethodX(in int X, int int Y, out Z) { code }
This says "I have a method MethodX with defined input and output parameters (we'll need to have a common marshalling standard), and, this method can be transmitted Erlang-style to a defined cloud endpoint. When you invoke MethodX, it can run locally or remotely. You don't care -- that's a configuration detail.
It seems to me Erlang is almost there, but I'd like it to be a more general interface. Think something on the JVM. Serverless done right?
2
u/Inconstant_Moo 🧿 Pipefish 21h ago
It sounds like my external keyword covers what you want to do, though not how you want to do it.
A Pipefish app can either do import "filepath/to/service/foo.pf" or external "url/path/to/service/foo" and then can call public functions the same way, foo.qux(x), with the functions in the external service working syntactically and semantically as though you'd imported the library foo. You can decompose your monolith into microservices in minutes (and, better still, put it back together again just as quickly when your manager learns what "latency" is).
The reason this is possible is that all values in Pipefish are immutable, otherwise you'd have a problem where service foo tells the client "You know that mutable value you gave me yesterday? I just mutated it ... oh, you're offline? Welp, I'm off to share the news with all the other services I passed it to", and then things become stupid.
1
u/nimrag_is_coming 23h ago
You can do that with C# function attributes, most unity game engine multiplayer packages do this. Google RPC, and its pretty much this
1
u/rosholger 23h ago
You could probably do this with java annotations and a custom annotation processor too
1
u/initial-algebra 20h ago
The actual term is "mobile code". There are a few examples, although usually specialized to client/server Web applications: Links, ML5, Opa, Ur/Web, and more.
1
u/mamcx 19h ago
the problem with that is what is the "topology" of the interface.
Thinking just on the method/function is not enough, a remote interface has tons of stuff that need to be deal with (see how for example https://swagger.io), so this alone not buy much.
Erlang has the concept of https://www.erlang.org/doc/apps/stdlib/gen_server.html that I think is much better as starting point of something like this.
1
u/--predecrement 17h ago
promotable func MethodX
The promotable would color the function. cf async. While some people like coloring functions, I'd say the majority whose opinion is not colored by their language preferences are part of a consensus of the neutral that coloring leads to increasingly unwieldy codebase evolution.
My own PL bias is toward Raku. So I don't count as part of that consensus of the neutral, but I consider it fortunate that Raku does not use function coloring to determine any details of execution of a call of a function (including of methods).
Instead, in Raku, it's an invocant of a method call that controls what handles that method, and how it is handled. (All methods have an invocant, even if the method call is really just a call of a function playing the role of a method, treating what would normally be talked of as being the function's first or only argument.)
By default, what handles a method call is determined by the invocant's WHAT object. The latter is an object that determines What Handles A Type.
(Many (most?) PLs have their equivalent, though in Raku's case, any value can be a type, and any type can be a value, which is unusual.)
In contrast, how a method call is handled -- which is central to your idea -- is determined by the invocants HOW object. A HOW object is an object that determines How Objects Work.
(Many (most?) PLs conflate what a type is with how operations on that type are handled, in which case implementing your idea will have to be done by building a shim and accepting that the host language doesn't even know that its methods are being processed in an unusual way. Raku's "core" is unusual. It boils down to a single self-describing primitive that knows how to be and do just one thing -- to be the sole KnowHOW from which both itself and all else can be bootstrapped. This makes it relatively simple to construct arbitrary shims that intervene in function execution and also to ensure languages used in a system know about each other and those shims.)
These WHAT and HOW objects correspond to architecturally pervasive deferences, deferring key decisions that other PLs tend to resolve early, which, relative to your scenario, is too early. In Raku these deferences map to indirections/dereferences. The standard language and library provide a default decision for when the indirections are resolved, with almost all happening early, at compile time, but Raku user code can intervene as users see fit. This makes your idea of seamlessly blending local compute with the distributed cloud easy to build in principle.
That trailing in principle hides a world of pain. I could get into the many challenges that arise but I'll defer getting into that for now.
1
u/Royal_Pin_1971 1h ago
Whether a function runs locally or remotely becomes a configuration detail once values are immutable and functions are identified by content hash, as in Unison, so every function is cloud eligible and marking it promotable adds nothing; only the code that decides where functions run needs to know about remoteness.
2
u/Valuable_Leopard_799 22h ago
Unison also has this natively.