• lobsters__emk@crustaceanson.theshelf.topM
    link
    fedilink
    arrow-up
    0
    ·
    1 month ago

    Skimming through this, I wonder how much overlap it has with something like Mojo, which uses comptime and dependent types to target tiled math operations on multiple GPU and CPU backends.

    Which, you know, they advertise as “AI”, but a lot of their early adopters have been traditional scientific computing.


    score 1 · canonical

    • lobsters__mlochbaum@crustaceanson.theshelf.top
      link
      fedilink
      arrow-up
      0
      ·
      edit-2
      30 days ago

      Singeli is older! But there have always been similar questions about Zig and so on. The way Singeli design differs is that it embraces compile-time programming being a different kind of language than runtime, where other frameworks treat the differences as dirty secrets. So, at compile-time, you have immutable “tuples” and a functional each{} that maps over them. At run-time, you allocate memory and loop over it with load and store operations and go-to (though most of the time you’ll use the compile-time features to wrap these in something more structured). A major split is that compile-time code is dynamically typed. There’s no “what type is Type” theoretical jungle. The type i32 is a first-class value at compile-time which can be compared and inspected and constructed and so on, and you can check kind{i32} which gives 'type' and even kind{kind{i32}} which is 'symbol'—unlike types, kinds aren’t first-class values and we represent them as text.

      Not trying to cram functional tasks into an imperative shape really frees up the compile-time design. I don’t remember the details of Mojo specifically (and it’s probably evolved some since I looked) but I’m always amazed at how many hurdles these languages put in front of what in Singeli is just normal array programming. This article on compile-time SI units in Jai seemed hefty enough to make a nice tutorial, but I got as far as this code for multiplication (which I don’t believe I’ve tested) before deciding it was pretty much a bunch of ceremony around checking that the base types matched and adding exponents. Just, regular programming, and working from that article slowed me down and made it less general (does some weird checked-merge on numerator and denominator instead of anything to do with multiplying them as fractions).

      I would say that where Singeli falls behind is that its type system is very simplistic. There are actually no compound types like structs, instead you work with tuples of types and registers at compile time, and this emits code that operates on their elements individually. This is perfectly comfortable for passing around a struct as a value, but it doesn’t let you write the struct to memory, as you can’t take a pointer to multiple types. Of course we can add such a thing to the language, but designing it is hard and brings in a lot of questions about what range of functionality it should cover that we haven’t resolved. We are also held back quite a bit by compiling to C, and supplementing CBQN’s C code as our primary use case, because C’s semantics are not exactly clean and we need to make the interactions with it well defined.


      score 5 · canonical

      • lobsters__emk@crustaceanson.theshelf.topM
        link
        fedilink
        arrow-up
        0
        ·
        30 days ago

        The way Singeli design differs is that it embraces compile-time programming being a different kind of language than runtime, where other frameworks treat the differences as dirty secrets.

        Interesting! Mojo runs the same language at compile-time and run-time, except that:

        1. The compile-time language can manipulate types as values.
        2. You can do things like comptime if (compile time conditionals) and comptime for (compile time loop unrolling).

        It’s actually a pretty slick system: Quite a bit of power, and vastly simpler than C++ template tricks.

        but I’m always amazed at how many hurdles these languages put in front of what in Singeli is just normal array programming.

        To be fair, Mojo is less interested in arrays (though it does support them) and more interested in tiled tensors. This is the kind of memory-layout optimization you normally expect to see in Fortran and on GPUs, but not in too many other places.


        score 1 · canonical