Carnap Programming Language

Has any one heard of Carnap Programming Language? Steven Ericsson-Zenith posted a comment on my blog inviting me to take a look. Since LTU is the coolest place to get new language information, I thought I would mention it here. I have been interested in programming multi-core and have been tracking Erlang and a few other developments.

The Link to Carnap Programming Language: http://www.carnap.info/

The first two paras from this page:

Carnap is a general purpose programming language for the next generation of many-core devices, many many-core systems and their applications. It introduces a process oriented programming model that allows programmers to seperate the concerns of data structures and the concurrent processes that act upon them.

"The primitive process of a Carnap program is called an action. An action determines a local or shared state. Actions are assembled by construction to form the component processes of a program. Programs consist of concurrent processes that construct and interact via logically shared data structures and resources called contexts.

Dorai Thodla
www.thodla.com

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Interesting

Thanks for the pointer! Sounds very interesting. Particularly intriguing since Ericsson-Zenith did a lot of work at INMOS on the occam language. Presumably Carnap builds on that experience, along with whatever else he's learned about process-oriented programming in the past 20 years or so.

Allan, Thanks for pointing

Allan,
Thanks for pointing out about OCCAM. Recall browsing through the manual almost two decades ago.

Dorai

link de rigeur

Dorai, there's On-going development of OCCAM-esque things, tho I've never used any of it. (I do find their papers to be written in a quite user friendly style, for whatever that's worth?!)

occam

Occam is (IMHO) a very elegant language, which works extremely well in the context for which it was designed (running concurrently on a single transputer, or transparently across a group of transputers). Occam-pi introduces a number of neat ideas, but is (again IMHO) somewhat hobbled by a desire to preserve occam's syntax. The result is something a little like C++ compared to C - in many ways more powerful, but the price for that power is a much more complex syntax. Occam-pi also introduces transparent networking, which I'm a little skeptical about simply because it defaults to occam's standard rendezvous model of communications (rather than asynchronous messaging) - which I don't think is the best default in light of the notorious "fallacies of distributed systems". Not to say that it hasn't been used to good effect. I'm just not sure how well it would work beyond the LAN environment.

Re: fallacies

Totally. While reading about the latest networking stuff for occam-pi I thought it was really weird that after all the things I've read via LtU that they would go for synchronous messaging and not have a discussion about why they do that (other than "because it is what occam-pi does in the small").

Asynchronous messaging is vulnerable

Asynchronous messaging is vulnerable to denial of service attacks. Synchronous messaging has some vulnerabilities as well, but they are more easily manageable.

Asynchronous messaging is

Asynchronous messaging is vulnerable to denial of service attacks.

How so? Or rather, how so especially?

How so? Or rather, how so

How so? Or rather, how so especially?

Asynchronous messaging means buffering is performed by the trusted computing base (TCB) of the language. This opens the TCB to resource exhaustion attacks. This is a well-known result in operating systems, and is why Mach-style buffering microkernels were abandoned long ago in favour of L4 and EROS-style, synchronous IPC kernels. No conceptual difference between an OS and a language, so the same arguments apply. It's just that languages haven't traditionally worried about resource accounting, to their own detriment I might add. I believe the arguments are reviewed in the paper I cited.

Asynchronous messaging


Asynchronous messaging means buffering is performed by the trusted computing base (TCB) of the language. This opens the TCB to resource exhaustion attacks.

Why can't the sender do the buffering? If (conceptually) the continuation is sent with a response, it's the sender that consumes its own resources to do the buffering. Trickles is an example, but so would any continuation-based web framework that serialises its continuations (instead of sending a handle to the continuation). 'Cool' URIs are exactly that: asynchronous messaging, but with nearly all the buffering resource usage supported by the clients.

Why can't the sender do the

Why can't the sender do the buffering? If (conceptually) the continuation is sent with a response, it's the sender that consumes its own resources to do the buffering.

To a certain extent that's true, with the added disadvantage of increased network traffic. You'll also have to protect your serialized continuation from tampering, but statelessness brings all the advantages of purely functional programming for optimization, scalability, etc.

'Cool' URIs are exactly that: asynchronous messaging, but with nearly all the buffering resource usage supported by the clients.

Yes and no, as the unguessable URI might simply be naming some server-side state; these unguessable URIs are in fact capabilities as in the web-calculus.

What about the web?

The whole web is asynchronous messaging, which seems to work very well. What is the difference between the web and asynchronous messaging as part of a programming language?

The whole web is

The whole web is asynchronous messaging, which seems to work very well.

It doesn't work well when the server retains state to handle potentially malicious clients; it amplifies DoS opportunities. HTTP is stateless simply because it's safer.

See the reply above for more or less how the web should theoretically work.

Naive asynchronous messaging is vulnerable for operating systems

Note that the author has changed his opinion about costs of synchronous vs. asynchronous designs. The next OS he develops is based on asynchronous messaging. See the link for more information.

Guessing from the mailing list the coyotos dev team is still working on this idea, and there are changes to core design ideas from time to time.

Also OS and language design are somewhat different things, so results from one area should not be automatically propagated to another. Some things that are expensive or unfeasible in OS might be cheap in the language.

Note that the author has

Note that the author has changed his opinion about costs of synchronous vs. asynchronous designs. The next OS he develops is based on asynchronous messaging. See the link for more information.

I've been on the Jonathan Shapiro's lists for over 7 years at this point, so I'm well aware of his opinions on the matter. Coyotos is slightly different because they introduced the notion of a first-class receive block (FCRB), which is like a continuation of sorts. The message sending process is still synchronous, and there is no buffering. Also note, that they have removed FCRB's from Coyotos due to the inherent complexity, and reverted back to simple, synchronous endpoints (see the mailing list).

Also OS and language design are somewhat different things, so results from one area should not be automatically propagated to another. Some things that are expensive or unfeasible in OS might be cheap in the language.

Indeed, and the local and remote cases are also quite different. Locally, DoS opportunities, like buffered messages, are amplified due to the low latency and high bandwidth available. Remotely, those factors are both reduced, so buffering is "more acceptable", but maintaining state for potentially malicious clients is still a serious problem for networked services. See the stateless network stack linked above for how statelessness can improve scalability and robustness.

Mechanism design

Asynchronous messaging is vulnerable to denial of service attacks.

Isn't this an issue of improper incentives rather than asynchronous messaging (and buffering) as such? What if cost of maintaining bufferred messages is allocated to sending processes (e.g., by influencing their scheduling)?

As a general note, I continue to see more and more examples of how introduction of mechanism design notions (e.g., incentives) could serve design of PLs (mostly those PLs that already have some notion of agent, to which incentives can be applied).

Isn't this an issue of

Isn't this an issue of improper incentives rather than asynchronous messaging (and buffering) as such?

I should have been more precise; the actual issue is resource accounting. If the TCB buffers messages for you, then the TCB is vulnerable to DoS. If a server allocates resources to you, without properly charging you for it in some way, then it too is vulnerable to DoS.

So as long as the buffers are properly charged to the parties involved, asynchrony adds no additional vulnerability that I can see (as long as scheduling is properly accounted for as well of course). I made an over-generalized statement, because most asynchronous systems currently implement buffering in the TCB, so the TCB can no longer protect individual agents from each other.

I think proper resource accounting is the last unexplored frontier for truly safe and secure computing (resources in the way of memory and cpu). If you can account for resources, and you reify all external authority as references, then you can run unsafe code without worry. See this ongoing discussion I'm having on the capability security lists for how to introduce proper memory accounting in programming languages in programmer-friendly way. I'm hoping we can hash out an implementable design that I might be able to pursue; it's looking like lightweight language processes and a variant of the memory accounting design from the PLT Scheme paper linked in the above message might be workable.

Local only though

While I agree that proper resource accounting is very important, I don't see how it can work when there are external communications: the receiver must allocate buffers to receive the messages..

Sure it's possible to reduce the resource used in the receiving side by using the 'stateless' network protocol which was seen on LTU recently (can't find the URL) but this doesn't solve the problem, just reduce it.

Distributed mechanism design

Sure, distributed mechanism design is much harder than a local one.
Still, the same basic principles apply: just make it profitable to cooperate, and unprofitable to defect (the devil is in the details, of course).

The protocol you meant is probably Trickles.

Another part of equation would be to make bigger units responsible for behavior of smaller units - if you cannot charge bad application, then charge the host that runs it (for example, by sending this host a "bill" with costs incurred per application, and then pushing back host's traffic proportionally to aggregated "unpaid" costs). This will create an incentive for hosts to better enforce charging for resources on the local scale, by pausing or killing misbehaving applications, for example.

As a specific technical means for controlling traffic see, e.g., Preventing Internet Denial-of-Service with Capabilities.

Another part of equation

Another part of equation would be to make bigger units responsible for behavior of smaller units - if you cannot charge bad application, then charge the host that runs it (for example, by sending this host a "bill" with costs incurred per application, and then pushing back host's traffic proportionally to aggregated "unpaid" costs). This will create an incentive for hosts to better enforce charging for resources on the local scale, by pausing or killing misbehaving applications, for example.

Exactly! And that's how it's done now, and I hope it's obvious too, that it's insufficient; the granularity is simply too large to be useful. This is why I consider pushing this accounting as far down into the language, to the granularity of individual objects if possible, the only remaining barrier to safe mobile and distributed computing.

Trusting remote PL runtime?

I am all for PLs to support resources awareness and accountability, but how is this going to help in the distributed case?
Unless PL runtime running on my host is able to verify your host runs a trusted implementation (not necessarily the same), your whole host remains under suspicion.
And how do I verify your implementation all the way down? Even if the bytecode is intact, the VM may be corrupted. Or the processor. Or the silicon :)

I am all for PLs to support

I am all for PLs to support resources awareness and accountability, but how is this going to help in the distributed case?

By giving programmers fine-grained tools to manage resources, something they currently lack.

Unless PL runtime running on my host is able to verify your host runs a trusted implementation (not necessarily the same), your whole host remains under suspicion.
And how do I verify your implementation all the way down? Even if the bytecode is intact, the VM may be corrupted. Or the processor. Or the silicon :)

Indeed; it's possible to verify remote runtimes using crypto, but in general, machines across an insecure network must be mutually suspicious. Exposing distributed objects via cryptographic capabilities as in E and the web-calculus seems the the most promising avenue.

Resource controls help in the distributed case by enabling fine-grained control over resource use, ie. it provides more powerful mechanisms by which a host can implement policies to manage his resources.

the receiver must allocate

the receiver must allocate buffers to receive the messages..

Again, it's not about the allocation so much as the accounting. The party using the storage must be held accountable, ie. it must be within their quota, etc. Otherwise, the host of that code is vulnerable to DoS. Whenever the buffer allocation is implicit, and ownership is ambient, DoS is a very real threat.

Sure it's possible to reduce the resource used in the receiving side by using the 'stateless' network protocol which was seen on LTU recently (can't find the URL) but this doesn't solve the problem, just reduce it.

To a certain extent this is simply a consequence of the network's design; but if you can reduce the problem to absolute physical limitations as dictated by the network, then at least you've shifted the costs back to the malicious parties as much as possible, and incentives for malicious behaviour are minimized.

*scrub*

nothing to see here, please move on...