Live data from Hacker News

Solod: Go can be a better C

solod.dev

41–50 of 188 posts

Re: Solod: Go can be a better C

#41
post #37
post #35

Earlier quoted context omitted.

The answer is apparently "you don't": - Everything in the language is statically allocated or stack-allocated. You have to call a malloc / free function to get heap allocated things - The language is not memory safe (you can't return slices, pointers, or interface types from a function if the thing was created inside the function, unless you used heap allocation) - Interfaces (the only variable size struct Go has) ar…

It sounds incredibly dangerous in the hands of a usual go programmer who has no idea what the difference between the stack and the heap is.

Been a while since I used go but I remember it being kind of uniquely hard to tell? Like a struct is on the stack, but a *struct is maybe on the heap, depending on escape analysis?

Re: Solod: Go can be a better C

#42
post #8
post #3

How does it deal with pointers if everything is stack based? You can't really return a pointer to something on the stack because it could get overwritten between when you return it and when you access it.

Exactly as well as C does, it seems. func newPerson() *Person { p := Person{Name: "Alice", Age: 30} return &p } becomes static main_Person* newPerson(void) { main_Person p = (main_Person){.Name = so_str("Alice"), .Age = 30}; return &p; } Quoting the FAQ: "So itself has few safeguards other than the default Go type checking. It will panic on out-of-bounds array access, but it won't stop you from returning a dangling p…

That's undefined behavior in C I thought? You're addressing the memory of a stack frame that already collapsed when it returned. I think it's ok for compilers to either segfault or work like you'd think they would for that example in C.

You can pass pointers to earlier frames in the stack, they're still active, but you can't return a pointer to an expired stack frame.

Re: Solod: Go can be a better C

#43
Translating a language into a different language is a popular thing to do these days, but still not a very easy one. I feel it's like peeling an infinite onion of misery. First, you write a parser of your source language, figure out the translation of the instructions, and emit the code in the target language, and you're very happy when your translated Hello world compiles.

Then, a user (like me) tries writing something like

  package main
  
  func main() {
    register := 42
    println(register)
  }
well, oops.

  /tmp/solod_build3904763637/main.c: In function 'main':
  /tmp/solod_build3904763637/main.c:6:21: error: expected identifier or '(' before '=' token
      6 |     so_int register = 42;
        |                     ^
  /tmp/solod_build3904763637/main.c:7:29: error: expected expression before 'register'
      7 |     so_println("%" PRIdINT, register);
        |                             ^~~~~~~~ (exit status 1)
OK, now you grab the list of reserved words of the target language, which is not always an easy thing to do, and rename type names and variables as needed.

The next bad thing is when you step on your own toes and see that the new names you invented, like `so_int` or `so_println`, will inevitably pollute the global namespace. We'll either cross our fingers and hope that no one will create a variable named `so_int`, or we'll need to add all our new kind-of-reserved words to our already big list of exceptions.

I'm sure there are multiple levels of complexity beyond this.

Not trying to say that seeing a bunch of new translators from language A to language B is bad: not at all! It really seems that this is one of the popular usages of the agents, and a rewarding one. But doing it without hidden bugs is kinda hard.

Re: Solod: Go can be a better C

#44
post #28
post #22

Go is a better C already, designed by C authors themselves, with other UNIX key figures. Which while some of the design decisions might be debatable, they actually knew what C is all about, informed by their own experience with what worked in C, Alef and Limbo, across UNIX, Plan 9 and Inferno.

Go is not a better C, in the sense that you cannot write an OS with it. Runtime, GC, etc. But Go is a better language for many programs that were often written in C: network servers, CLI utilities, TUI utilities, etc.

The larger runtime makes bootstrapping go for unsupported architectures more laborious than C, but it's not a hard blocker. The function call overhead for inline assembly feels like more of an issue doing close to hw programming. It can be avoided for the runtime, but user go code can't escape it afaik.

Re: Solod: Go can be a better C

#45
post #29
post #28

Earlier quoted context omitted.

Go is not a better C, in the sense that you cannot write an OS with it. Runtime, GC, etc. But Go is a better language for many programs that were often written in C: network servers, CLI utilities, TUI utilities, etc.

Plenty of OSes, since Xerox PARC days have been written in GC systems languages. Interlisp-D, Smalltalk, Cedar, Topaz, Oberon, Active Oberon, Singularity, Midori, Ironclad Go's runtime is written in Go. The whole compiler toolchain, GC, compiler, linker, Assembler, is written in Go. There are Go compilers for bare metal, no OS needed, like TinyGo, the runtime, written in Go is the OS. I love the "you cannot write an…

> Go's runtime is written in Go. The whole compiler toolchain, GC, compiler, linker, Assembler, is written in Go.

There's some nuance to this. The runtime code uses specific compiler support and restrictions that are not ordinary Go - possible (or even done, like this case) ≠ ergonomic. No doubt of course that for the Go project, this is still a win.

Re: Solod: Go can be a better C

#46

The "a better C" meme needs to die. It's ill defined. Everyone wants something different. For me, GC disqualifies any language as a better C. Bjarne Stroustrup promoted C++ as a better C. But C++ killed off some of C's killer low-level features like type-punning via unions. Indeed it's only in recent years that low-level memory manipulation, such as std::start_lifetime_as and the implicit lifetime rules were standard…

What do you think of Ada's representation clauses and Zig's packed structs? Do they give you the syntax and semantics for arrangement (ordering, padding, widths), endianness, and control of bit order that you want?

Also, thank you for an educational comment.

Edit: I forgot to ask about your thoughts on Ada's and Zig's type punning.

Re: Solod: Go can be a better C

#50
post #43

Translating a language into a different language is a popular thing to do these days, but still not a very easy one. I feel it's like peeling an infinite onion of misery. First, you write a parser of your source language, figure out the translation of the instructions, and emit the code in the target language, and you're very happy when your translated Hello world compiles. Then, a user (like me) tries writing someth…

That seems like a brittle approach to transpilation. A transpiler should translate all of the language's semantics, including resolving identifiers as symbols, and then choose legal names for them in the target language. Also, there is so much more to a language than its surface syntax.

I've never designed a transpiler (I'm not a programmer), but surely the correct approach is to transform the source code into its type-checked AST, and then translate to the target language from there?

Post reply on HN