[HN Gopher] Neut Programming Language
       ___________________________________________________________________
        
       Neut Programming Language
        
       Author : azhenley
       Score  : 104 points
       Date   : 2025-02-24 01:12 UTC (21 hours ago)
        
 (HTM) web link (vekatze.github.io)
 (TXT) w3m dump (vekatze.github.io)
        
       | skulk wrote:
       | I'm currently reading through the automatic memory management
       | claims which look really cool (reminds me of linear types), but
       | the highlighted punctuation (, : =) makes it very painful to
       | read.
        
         | layer8 wrote:
         | Syntax highlighting of the background color is weird. It makes
         | everything look like surrounded by a halo.
        
       | gnabgib wrote:
       | Big in 2020 as a Show HN (456 points, 80 comments)
       | https://news.ycombinator.com/item?id=23283880
        
         | dang wrote:
         | Thanks! Macroexpanded:
         | 
         |  _Show HN: A dependently-typed programming language with static
         | memory management_ -
         | https://news.ycombinator.com/item?id=23283880 - May 2020 (78
         | comments)
         | 
         | I'll see if I can email the author.
        
       | tempodox wrote:
       | As a matter of personal preference, hoisted curlies drive me
       | insane.
        
         | layer8 wrote:
         | What are "hoisted curlies"?
        
           | stronglikedan wrote:
           | If I had to guess, it's putting the opening curly bracket on
           | the same line as the function definition, instead of the next
           | line. And if I'm correct, then I also agree.
        
             | patrickmay wrote:
             | Allman style FTW!
        
         | adrian_b wrote:
         | Obviously the personal preferences about code formatting vary a
         | lot among programmers and it is impossible to reach unanimity.
         | 
         | For instance, I am among those who are annoyed when seeing
         | lines of text wasted with the opening curly brace, reducing
         | thus the number of useful text lines visible on the screen.
         | 
         | Probably it is best to use an automatic code formatter and
         | format the code according to personal preferences while working
         | with it and then reformat it according to project rules when
         | committing the code to the repository.
        
           | mindcrime wrote:
           | > For instance, I am among those who are annoyed when seeing
           | lines of text wasted with the opening curly brace,
           | 
           | Conversely, I'm one of the people who are annoyed when the
           | tokens that represent a block of code don't form a vertical
           | line, making it much harder to see "at a glance" where blocks
           | begin and end.
           | 
           | > Probably it is best to use an automatic code formatter and
           | format the code according to personal preferences while
           | working with it and then reformat it according to project
           | rules when committing the code to the repository.
           | 
           | At the end of the day, I'm convinced there is no "right" way
           | to do this. Everybody has their preferences, and who's to say
           | that one set of preferences is objectively more meaningful
           | than another? You care about wasted vertical space, I don't.
           | I care about tokens lining up, you (probably?) don't (at
           | least not as much as I do). But neither of us is really
           | "right" or "wrong".
        
             | bombela wrote:
             | And I am annoyed with the lack of indentation with a
             | dedicated character (like tab maybe). With spaces, my
             | editor has to guess how much to delete. If I want to
             | tabulate a table. It might fight me. This really irks me.
             | 
             | I want it all. No lines wasted, uniform indentation,
             | dedicated indentation character.
             | 
             | Python with tab for indentation feels right to me.
             | 
             | I also like to set a vertical highlight in my editor to
             | vertically delinate indentation levels.
        
       | sirwhinesalot wrote:
       | The Koka language uses a similar approach to track resource
       | usage, except there they use ref counting and just remove
       | unnecessary ref counting operations. Neat stuff.
        
       | fuzztester wrote:
       | It looks partly like OCaml, with the "let ... in" kind of syntax.
       | Also the "unit" word. I think in OCaml it means a function that
       | doesn't return any value, but why is the word unit used for that?
        
         | chris_pie wrote:
         | It's a standard practice in functional languages:
         | https://en.wikipedia.org/wiki/Unit_type
        
           | fuzztester wrote:
           | That sounds like those corporate types who brush off any
           | complaints by users, by saying "that is corporate policy" :)
           | #sorrycouldntresist
           | 
           | But seriously, according to that link, it seems to me like
           | the zero or empty type is more suitable.
           | 
           | But I am not a PL or type theory expert.
        
         | zamalek wrote:
         | It's more precise to think of unit as an empty tuple. A tuple
         | is like an ad-hoc struct without names for the fields, so
         | `(int, string)` is like `struct MyTuple { int a; string b; }`.
         | An empty tuple would be `()` (which is the syntax for unit in
         | many languages), meaning `struct MyTuple {}`. If you think
         | about it, that's about the closest you can get to "nothing"
         | without invoking type system handwavium (like void, which is
         | basically "unit without the good parts but that can also mean
         | anything").
         | 
         | You can do clever stuff with it, for example `HashMap<string,
         | ()>` is practically identical to `HashSet<string>` (depending
         | on how clever the compiler is, possibly actually identical).
        
           | chills wrote:
           | I don't think it's particularly useful to think of unit as an
           | empty tuple specifically, that is just an arbitrary but
           | convenient definition for it.
           | 
           | Really a unit type is just one that contains only a single
           | value. This is a unit in the same way that 1 is a unit for
           | the integers. With some hand waving it is an identity for
           | product types, for example (int, ()) is the "same"
           | (xxxmorphic yada yada) as int
        
             | winwang wrote:
             | Mildly disagree with your first statement. Well, I mostly
             | agree that it's not particularly helpful for newcomers.
             | 
             | As a 0-tuple, it becomes a specific case of a more general
             | concept -- there is some beauty/usefulness in not having to
             | have a "special" construct for "Unit", which is (in a
             | sense) not just "any" unit type. It also "justifies" the
             | syntax of `()` and notes that it is a product type, all the
             | while fitting into the idea of the "cardinality" of `(a1,
             | a2, ..., an)` being the product of the cardinalities of
             | each of its type params.
        
           | fuzztester wrote:
           | >you think about it, that's about the closest you can get to
           | "nothing"
           | 
           | Some other options could be to use None (like Python does) or
           | Nil or Nothing itself, or even ReturnsNothing to be more
           | explicit, or even the Pascal-style procedure keyword, instead
           | of the function keyword, for a sub routine that returns
           | nothing.
        
         | fuzztester wrote:
         | thanks, guys.
        
       | sestep wrote:
       | For "How Fast is This?" it links to a benchmarks page, which only
       | shows that it's faster than Haskell. It would be more informative
       | to instead compare against a language that is more popular and/or
       | more performant than Haskell.
        
         | hajile wrote:
         | C is usually 1-4x faster than Haskell. This looks to be within
         | 1-2x.
         | 
         | The key takeaway for me is that you're in the range where very
         | slight variations in implementation of the same algorithm make
         | the difference between which is faster.
        
       | asplake wrote:
       | Could someone explain the "Necessity and noema" section [1] or
       | share a reference? Looked like it might be significant but I
       | couldn't make much sense of it
       | 
       | [1] https://vekatze.github.io/neut/terms.html#necessity-and-
       | noem...
        
         | ninalanyon wrote:
         | DDG took me straight to https://en.wikipedia.org/wiki/Noema
        
         | theamk wrote:
         | https://vekatze.github.io/neut/static-memory-management.html is
         | a good explanation.
         | 
         | TL/DR: All functions are pass-by-value. To avoid complete
         | tanking of performance, they have "noema" (same as a reference
         | in other language), which contains pointer to "hyle" (reference
         | target in other languages). Since the language is GC-free, the
         | references cannot escape out of the block they are defined in.
         | 
         | The language authors really like inventing the new programming
         | terms.
        
           | asplake wrote:
           | Ah, thanks
        
       | saghm wrote:
       | From glancing through a few of the pages that piqued my interest,
       | I was somewhat surprised to see this section in "How to Execute
       | Types" (https://vekatze.github.io/neut/how-to-execute-
       | types.html):
       | 
       | > Here, we'll see how a type is translated into a function that
       | discards/copies the terms of the type. To see the basic idea,
       | let's take a simple ADT for example:                   data item
       | {         | New(int, int)         }
       | 
       | > The internal representation of New(10, 20) is something like
       | the below:
       | 
       | > New(10, 20)                   // | (compile)              let v
       | = malloc({2-words}) in         store(10, v[0]);         store(20,
       | v[1]);         v
       | 
       | I suspected that it's not actually heap-allocating every single
       | bit of memory in every program, and from looking around more in
       | the docs, I _think_ the "Allocation Canceling" section here
       | explains what I was missing
       | (https://vekatze.github.io/neut/basis.html#allocation-
       | canceli...):
       | 
       | > When a free is required, Neut looks for a malloc that is the
       | same size and optimizes away such a pair if one exists.
       | 
       | This is a really interesting way of automating memory management
       | at compile time. I imagine there's still a lot of room for
       | different choices in this strategy (e.g. choosing to reuse part
       | of a larger allocation rather than looking for one that's exactly
       | the same size and then leaving behind the remainder to re-use for
       | a future allocation), and I'm super curious about whether this
       | would end up encouraging different patterns than existing memory
       | management systems. Offhand, it almost seems like it could act as
       | a built-in allocation buffer managed by the compiler, and I'm
       | curious if the algorithm for reusing memory is smart enough to
       | handle something like manually allocating the maximum amount of
       | memory needed for the lifetime of the program up front and then
       | re-using that for the duration of the program to avoid needing to
       | allocate anything dynamically at all (although my worry would be
       | that this would devolve into the knapsack problem and not be
       | feasible in practice). If this did work though, my immediate idea
       | would be for some sort of hook where you could specify the
       | maximum amount of memory you'd be willing to use, which could
       | then turn "using too much memory at runtime" into a compiler
       | error. My assumption is that that I'm missing something that
       | would make all of this not work the way I'm thinking though.
        
       ___________________________________________________________________
       (page generated 2025-02-24 23:00 UTC)