17 ms·
Show HN: Alumina Programming Language
Alumina is a programming language I have been working on for a while. Alumina may be for you if you like the control that C gives you but miss goodies from higher level programming languages.
It is mostly for fun and exercise in language design, I don't have any grand aspirations for it. It is however, by this time, a usable general-purpose language.
Alumina borrows (zing) heavily from Rust, except for its raison d'être (memory safety). Syntax is a blatant rip-off of Rust, but so is the standard library scope and structure.
Alumina bootstrap compiler currently compiles to ugly C, but a self-hosted compiler is early stages that will target LLVM as backend.
If that sounds interesting, give it a try. I appreciate any feedback!
Standard library documentation:
https://docs.alumina-lang.net/ https://docs.alumina-lang.net/
Online compiler playground:
https://play.alumina-lang.net/ https://play.alumina-lang.net/
- pipeline_peak 4y ago
- wtetzner 4y agoWhat an odd comment when the post contains this: > It is mostly for fun and exercise in language design, I don't have any grand aspirations for it.
- xpe 4y ago> What an odd comment when the post contains this "It is mostly for fun and exercise in language design, I don't have any grand aspirations for it." You are being quite generous in calling the comment "odd". Here are five words to summarize that comment: disparaging, out of context, cruel, speculative, and pessimistic. pipeline_peak can do better. The HN guidelines are a good start. >> pipeline_peak : Another Rust lookalike to reinvent the wheel, I wonder what’s gonna happen to it in 10 years.
- pipeline_peak 4y agoAaaaaand no response from wtetzner I gotta say getting this much coverage from one individual over my little comment is pretty odd, or is that “quite generous”?
- wtetzner 4y agoYes, it's all of the things you mentioned. I just meant that it's odd someone would go out of their way to write a comment like this, especially when the original post says it's just for fun/practice.
- xpe 4y agoPlease try to offer some kindness. Or at least accept that people have various motivations and goals. Languages are regularly remixed. Also, "language designer" is not an elite term -- it can be a hobby, a way to learn, and even a way to inspire others. Perhaps I could invent a spoken language where disparaging remarks are possible but extremely lengthy, thereby discouraging negativity from people in bad moods.
- pipeline_peak 4y ago> thereby discouraging negativity from people in bad moods A little tough praising kindness with a whiff of passive aggression, not very “HN guideline like”.
- xpe 4y ago> A little tough praising kindness with a whiff of passive aggression, not very “HN guideline like”. A counter punch from someone who feels attacked, right? Alternatively, you could accept the well-intentioned and fair criticism.
- deleted 4y ago[deleted]
- xpe 4y ago> Perhaps I could invent a spoken language where disparaging remarks are possible but extremely lengthy, thereby discouraging negativity from people in bad moods. I can see how you might think think my comment is passive aggressive, but it is not. Passive aggression is "the expression of anger, hostility, or resentment through indirect means, especially obstructive or uncooperative behavior: those who expected him to lambast his foes were always going to be disappointed; passive aggression is more his style." (Apple dictionary) First, if you take my comment as a whole, you can see I was not indirect in my criticism of your comment. Second, I do not feel anger, hostility, or resentment about you or your comment. Rather, I feel disappointment that this kind of thing happens so often. It is not just you (or any one person) that disparages creativity -- many people have done it, including myself. The language design comment is sincere. It was a sort of thought experiment. I can also recognize that it is a pointed comment that led to some reflection (I hope), which is why it might have felt like an attack. Still, remember I criticized your behavior, not you. The comment had the additional purpose of highlighting that language design has broad applicability, and perhaps might reduce some kinds of unwelcome behavior, whether it be bad-mood inspired negativity or error-prone programming abstractions. Rust and Alumina aim to have more expressive types than C, for example. Human language shapes culture and thought -- at least according to many linguists.
- MontyCarloHall 4y agoI get that this is mostly for fun, but this is as good a place as any to bring up an issue I rarely see discussed with any post about a new language. Well-established languages have tons of widely used, highly vetted libraries implementing functionality that doesn’t exist in the new language and would be totally impractical for an individual to implement themselves. For example, if I’m doing scientific computing, I need a good linear algebra library like Eigen or Armadillo (or Numpy/PyTorch/Tensorflow), all of which would be impossible for me to implement myself. Therefore, for a new language to catch on, it needs a good foreign function interface. Yet FFIs are almost never brought up whenever new languages are discussed on HN. (Again, I realize that this is just a fun project and widespread adoption is not a goal.)
- tibordp 4y agoTotally agreed about FFI. I wanted to make it easy to interop with C code and write expressive bindings. Check for example the language bindings to LLVM's C API (fairly low level) and Tree-Sitter which is used internally (a bit higher level bindings) https://github.com/tibordp/alumina/tree/master/libraries/llvm https://github.com/tibordp/alumina/tree/master/libraries/llv... https://github.com/tibordp/alumina/blob/master/libraries/tree_sitter.alu https://github.com/tibordp/alumina/blob/master/libraries/tre... I think UFCS makes it quite nice for bindings, since external C functions can be used as if they were methods if the object is passed as the first parameter. So in many cases there might not even be a need to write wrapper structs for bindings that feel native. Of course, it's still a manual process and since Alumina is just a compiler and stdlib for now (no llibrary ecosystem, no compiler driver), it's a bit cumbersome. But I like the approach Rust has with bindgen and cc crates, to automatically create bindings for C and C++ code.
- girvo 4y agoUFCS making C bindings a hell of a lot nicer is one of the things I love about Nim, so I’m happy to see another language try it!
- danias 4y agoWe are building a new language that is not for fun and we have thought of this important issue. We solve it with a Package Ports and Package Adapters. The Bitloops Language (BL) is a transpiled language with support for only TypeScript at the moment. Nonetheless, if it picks up we will be adding support for Java, C#, and C++ so that people can leverage their investments in their existing packages. https://github.com/bitloops/bitloops-language https://github.com/bitloops/bitloops-language
- revskill 4y agoLove this. What if Rust provide a separate analyzer to analyze potential memory leak from this language.
- tibordp 4y agoValgrind and Sanitizers should work on Alumina. I have not actually tried them myself yet, but I don't see any reason why they couldn't work. The only potential problem I see that with the current C backend, the debugging information is very hard to trace back to the original Alumina source code, so it might be hard to see where the leaks are coming from. This is something I plan to address in the self-hosted compiler, once it is functional.
- renox 4y agoSo, as far as I understand its main feature is that it has a Rust-like syntax?
- tibordp 4y agoAs far as I know it doesn't have a single feature that is really unique. It's more like a combination of things I like from other languages, like syntax and expressions from Rust, defer expressions from Go, UFCS from D. The overarching theme is to see how far you can go making a language that feels high level without having a garbage collector or RAII. I used to use Deplhi/Pascal a lot when I was younger and it was this kind of language.
- mhd 4y agoI thought people got along with Rust due to its features and semantics and learned to live with the syntax. Not it being something one would copy. (I'm personally still hoping for a Ratfor/Coffeescript transpiler) Also, wonder how long it'll take until we see a "Aluminia" fork...
- jimbob45 4y agoWhat is it that people hate about Rust syntax beyond the terrible lifetime syntax? Seems pretty reasonable to me.
- xigoi 4y agoSemicolons, braces, double colons Using "<" and ">" as both operators and delimiters Turbofish Symbols instead of words (ref -> &, and -> &&, not -> !, …) Inconsistency (Why [i64; 5] and not something like array<i64, 5>?)
- aaaaaaaaaaab 4y agoThe community.
- dhosek 4y agoWhat I’ve found is that Rust people on stackoverflow not so great, Rust people on Reddit pretty pretty good.
- Surfactant7 4y ago> Unlike Rust, however, Alumina is not memory-safe and it requires manual memory management. From what I gather, it might be more accurate to say that Alumina has no ownership model. Rust requires manual memory management, but offers the ownership model as a compile-time tool for doing so. It would actually be pretty interesting to see some experimentation around alternative ownership models.
- ducktective 4y agoAwesome! How difficult was it for you to design a whole programming language? Do you have a theoretical CS background? If I want to design my own, would learning Racket and other LISPs help? I'm interested in formal methods and embedded systems.
- tibordp 4y agoI wouldn't say it was very difficult, but it did take quite a bit of time. Apart from some basic principles (no GC, no RAII, "everything is an expression"), I basically kept adding features whenever I hit some pain point trying to write actual programs in Alumina. If I were to do it again, I'd probably be more methodical, but anyway, here we are :) Protocols were probably the trickiest feature of the language to figure out. As for the compiler itself, surprisingly, the biggest hurdle to get over was the name resolution. It's a tiny part of the compiler today, but everything else was much more straightforward. I don't have formal CS background, but I have been coding for a long time. I read the Dragon Book and would recommend it to anyone writing a compiler, even though it's a bit dated. I don't know Racket or LISP myself so I cannot comment on that part.
- noncoml 4y agoI really don’t like the cognitive load of having to remember to use defer. We already have the scope defined, why add something extra? IMHO the way it’s used in Go is a workaround, of luck of destructors, not a feature. Edit: not a criticism on your language OP, which is better than what I could have ever built. Just a comment in the “defer” trend.
- tibordp 4y agoScoped destruction is awesome in general, and I agree that it is superior to defer. I think one case where defer might be nicer is for things that are not strictly memory, e.g. inserting some element into a container and removing it after the function finishes (or setting a flag and restoring it). This can be done with a guard object in RAII languages, but it's a bit unintuitive. Defer makes it very clear what is going on.
- noncoml 4y ago> This can be done with a guard object in RAII languages, but it's a bit unintuitive Some syntactic sugar, like Python’s “with” should help with that, shouldn’t it?
- tibordp 4y agoPython context managers are actually very similar to guard objects in C++ and Rust. What I meant was something like this (could also be done with `contextlib`, but it's also verbose) seen_names = {} class EnsureUnique: def __init__(self, name: str): self.name = name def __enter__(self): if self.name in seen_names: raise ValueError(f"Duplicate name: {self.name}") seen_names.add(self.name) def __exit__(self, exc_type, exc_value, traceback): seen_names.remove(self.name) def bar(): with EnsureUnique("foo"): do_something() ... With defer this could be simplified to static seen_names: HashSet<&[u8]> = HashSet::new(); fn bar() { if !seen_names.insert("foo") { panic!("Duplicate name: foo") } defer seen_names.remove("foo"); do_something(); }
- Eliah_Lakhin 4y agoI'm currently working on a project similar to Tree-Sitter. Basically, it is going to be a full-featured Compiler front-end foundation library with incremental parsing capabilities, error recovering, AST manipulations, etc, but written entirely in Rust, and hopefully with more user-friendly API for Rust devs. May I ask you to give me some feedback on your experience with Tree Sitter, and the challenges you faced during the development of your compiler's front-end? Thanks in advance!
- tibordp 4y agoHonestly, Tree Sitter is fantastic, I can highly recommend it. By far the most user friendly and powerful parser generator I've worked with. The C API is very nice. The only two pain point I had is that the `node-types.json` that's generated only contains the names of the nodes, not the numerical IDs. This means that if you have some codegen generating Rust enums is difficult if you want to avoid matching nodes by string. I wrote https://github.com/tibordp/tree-sitter-visitor https://github.com/tibordp/tree-sitter-visitor for generating visitor traits in Rust for a given grammar. I actually did it a bit differently in the end for Alumina, but it might come useful.
- nnoitra 4y agoNew language posts have to stop. There are tons of other CS topics to talk about but instead LIPSs ()()()()((((())))) and random langs taka the spotlight on HN.
- nicoburns 4y agoWell we'll always need language designers and compiler developers, and new ones have got to learn somehow. Creating a toy language seems like a pretty decent way to go about it.
- lolinder 4y agoI upvote any new language post I see because I find them very interesting and want more of them. The nice thing about HN is you can just scroll past posts you don't find interesting. The "tons of other CS topics" are also discussed on HN.
- chaosprint 4y agoOnline playground! So it compiles to WASM? If you are gonna look like Rust. Please, no unwrap() everywhere.
- tibordp 4y agoNo native compilation to WASM yet, but since the compiler outputs self-contained C, it should be fairly easy to do it with Emscripten. The sandbox is running the code server-side in a nsjail container. As for unwrap, I feel you! the try expression (expr?) is supported, which makes it look a bit nicer, but I'm still trying to figure out a good idiom for when you actually want to do specific things based on whether the result is ok or err. Alumina does not have Rust-style enums (tagged unions) or the match construct, which makes it a bit tricky.
- chrismsimpson 4y agoInteresting no one here is discussing “Jakt”, which looks very similar in style and approach. Jakt is the language attempted by the SerenityOS team, which itself dispels the notion you can’t building something of substance from scratch without outside libraries. Jakt also implements fairly lightweight reference counting, making it memory safe. I think the potential of SerenityOS/Jakt can’t be overstated and strikes me as comparable to the excitement surrounding Linux in the early ‘90s.
- lolinder 4y agoJakt's #1 design goal is memory safety. The very first paragraph of Alumina's docs says that it intentionally keeps C-style memory-unsafety. For systems programming languages, that makes them philosophically quite at odds with each other. Were there similarities besides "syntax inspired by Rust"?