back

by raphlinus·8y ago·view on hn ↗
I don't think there are good arguments against it, and I agree it would be great to fix it. But I think it's very important to understand the reasons why Regehr's proposal failed. I also think it's incumbent on new proposals to argue why their effort is likely to succeed where Regehr's did not.

If I were more cynical, I'd say that the C-standards community has simply ceded the ecosystem niche of a low-level language which has common-sense behavior, creating an opportunity for other languages such as Rust, D, Zig, etc. But I don't really believe that. Almost everything we do relies on C at the bottom, and it's pretty much the only viable way to publish an API that can be consumed by multiple languages.

2 comments
> Almost everything we do relies on C at the bottom, and it's pretty much the only viable way to publish an API that can be consumed by multiple languages.

I think it's true that almost everything we do relies on the C ABI at the bottom. That's different from relying on C, and I think these are actually the same problem: the C ABI is straightforward and has been implicitly stable (whereas e.g. the Rust ABI is explicitly not stable) because the C ABI has very few types and very little information in types (aliasing, ownership, alignment, thread-safety, parameter types of functions, etc.) and the more common-sense lower-level languages are obligated to have meaningful types.

You can certainly publish a C API / ABI from a Rust library and consume it from a D program without either side knowing that the other side isn't actually written in C.

I am curious what is the next meaningful step beyond the C ABI and the C type system: even stabilizing the Rust ABI (which I would love to see) isn't going to help a lot for writing D libraries that implement them or Python programs that consume them, partly because Rust has unique ideas of things like lifetimes that don't immediately translate to other languages. What's the subset of stuff that's in all these languages' type systems that isn't in the C ABI?

I'm reminded of Vala (which I kind of miss), which was GNOME's attempt a couple years ago at a better-than-C language that was very explicitly C-ABI-compatible. It used the GObject protocols for types - is GObject the shape of thing to standardize?

> I am curious what is the next meaningful step beyond the C ABI and the C type system

The C ABI and type system omits a lot of stuff that could be useful. Some points off the top of my head:

* Vector types

* Multiple return values

* Functions with bound environments

* Coroutines

* Dynamically-sized callee-allocated structures (most notably lists)

* Distinguishing between "byte array" and "string" types

* Vtables

* Something that lets GC'd languages cooperate more nicely. I'm not sure how exactly to specify this, but this is the sort of thing we could have if we stopped insisting that everything must be in terms of C ABI.

Hm, are there any cases of two GC'd languages that interop well that were not designed to interop from day one (that is, JVM languages don't count)?

The only one that comes to mind is https://research.mozilla.org/2014/08/26/javascript-servos-on... , which is Rust (pre-1.0) and JavaScript, but that somewhat doesn't count because Rust isn't really a GC'd language. (This article was written about a year after the special syntax for garbage-collected references was removed and Gc<T> became just a thing in the standard library, and about a month before that type was also removed because it wasn't a very good GC.)

It seems to me that if you make your GC a purely refcounting system this is easier: you just need to specify how to incref and decref objects, and put a well-known function in the vtable for destroying and deallocating the object. I'd guess that's how things like GObject or Qt bindings in Python or similar languages work.

COM was an example of using refcounting to drive a richer cross-language object model. And these days, WinRT is another take on the same (and, indeed, is COM under the hood, but with a richer type system and metadata). So you can have e.g. JS interop with C# via WinRT, but only because their shared view of the world is all refcount-based.
If you codify things that some vendors (notably Microsoft) are already doing with their calling conventions, that would give you alignment specifiers, and vector types passed in SIMD registers.

I personally think ownership is a biggie. If I pass in a pointer, is it expected to outlive the call?

And buffer sizes, of course.

Most of those features are available on UWP.
> Almost everything we do relies on C at the bottom, and it's pretty much the only viable way to publish an API that can be consumed by multiple languages.

Not quite true, on Windows it is called COM, WinRT or UWP as of Windows 10. Or MSIL in alternative.

On IBM i, IBM z, Unisys ClearPath, takes a variation of what is known as language environment.

On Android you will have more luck targeting DEX than C.

On browsers better compile to JavaScript in some way.