4 ms·
I like this a lot! For several years I've been pondering the exact same idea of using linear types this way, combined with some kind of Rust-style borrowing. I'
by atombender 4y ago
I like this a lot! For several years I've been pondering the exact same idea of using linear types this way, combined with some kind of Rust-style borrowing. I've never really had any serious ambitions to create a programming language, though, so I'm happy to see someone finally doing this for real.
I love many of the choices here, like removing implicit type coercion, type inference, and operator precedence. I do worry that it could go too far. One thing we see with Go is that the simplicity of the language, while it has many virtues, also leads to some crude designs that feel regressive. For example, treating errors as values is a fine idea, but the language is too rudimentary to express sum types, so the handling of errors becomes crude and cluttered. Not bad enough to ruin the language, but bad enough to be an annoying wart. I hope that Austral can avoid falling into such traps when it needs to tackle more advanced concepts such as concurrency (I don't know how this is done today?). Not having async/await is fine, for example, provided that there is some other mechanism that doesn't lead to spaghetti code or too much repetition.
The part I'm the least enthusiastic about is the Algol/Ada-style syntax. I'm not sure the added verbosity of that syntax is superior to C-style syntax. The language I use the most these days, Go, is essentially Modula/Oberon with C-style syntax and no semi colons, both of which I think improve the ergonomics.
- dureuill 4y ago^ this. there's a lot i like from Austral, but I think I disagree on some fundamental level with the "simplicity" goal. I simply don't think it is necessarily conductive to less errors, and expressivity of a language matters. There is a balance to be found. For example, Rust-style iterators are "complex", yet they cause less errors than explicit indexing. Their combinators, that afford a lot of their expressivity, would cause very difficult to write types without type inference. There's a similar tale of expressivity vs simplicity in the current implementation of the borrow checker in rust that is not using lexical (tied to a syntactic scope) lifetimes. For having used rust before non lexical lifetimes were a thing I can guarantee that from a user's point of view it is worth all the complexity in the rules and the implementation. I also have a hard time to imagine a serialization framework like serde without the ability to derive traits with an annotation. Separating interface and implementation opens up to (compile time, fortunately) errors when they don't match, and brings no gain: the public interface can be generated by tools like cargo doc. Ada style syntax I find difficult to read (I prefer braces) but this is purely a product of familiarity I think The document also says the language does not feature unwinding panics. What does it has then? The capability system is interesting, but I am surprised in the hello world example that printing to the console doesn't seem to require a dedicated capability. I think an extension to this capability system would be some sort of tie-in with the OS so that a given process can start with only a subset of the root capability
- boardwaalk 4y agoAgree separating the interface and implementation is not a great idea. It seems like a decision that's designed to waste time (in copying definitions from one place to another, in compilation errors). It's half the reason to dislike C/C++'s module... err, text inclusion system. The other half being horrible build systems/times. The only way it'd be halfway reasonable is if there was very good editor support for syncing the two copies. And even then, what's the point of denormalizing your source code? Like you said, you can always generate docs from source or an interface file from source (if for some reason you were building a closed source module -- which seems very much not the norm these days).