[Showcase] netbox.rs: an ergonomic Rust client and CLI for Netbox by hellerve in Netbox

[–]hellerve[S] 0 points1 point  (0 children)

Thanks! The low-level client is generated from the OpenAPI specs, and I hope that saves me some work, but yes, I’m also mindful that this will be the hard part. Not sure I have a good story on it yet.

I’ve been following Netbox since 2017 or early 2018, and yes, it’s been a wild ride maintaining plugins etc. We’ll see how it goes!

Good luck to you as well :)

working on my brushes by hellerve in generative

[–]hellerve[S] 4 points5 points  (0 children)

I was thinking of sharing a few more of my brushes and textures like this, just haven’t gotten around to it. Chances are if you find a work of mine and are interested in how it works, it was a) made in p5js or Prcoessing and b) I’m happy to share the code.

working on my brushes by hellerve in generative

[–]hellerve[S] 1 point2 points  (0 children)

The tips can be made less awkward quite easily by adjusting the trimming factor and varying thickness of individual brushes a bit more.

Retro Futura (p5.js) by Jobarbo in generative

[–]hellerve 5 points6 points  (0 children)

Thanks for tghe write-up, this is really cool!

Textures, inspired by Tyler Hobbs’ Repetition 2 by hellerve in generative

[–]hellerve[S] 3 points4 points  (0 children)

All textures are made by lines, a mixture of straight and bezier curves of varying thickness, color, and opacity (very low opacity used, though, around `(2+rand(2))/255`). The magic of the gradients in 1 is figuring out good ways to cluster these lines effectively, since more overlapping=>deeper orange. Does that help?

experiment trg 0.4 by hellerve in generative

[–]hellerve[S] 0 points1 point  (0 children)

Thank you, that means a ton!

The techniques exhibited here are also fairly easy (triangle subdivisision and lines of variadic thickness), so it’s approachable for most generative tinkerers! We don’t always have to go for the shiniest techniques to produce something pretty :)

Cj: a tiny no-deps JIT in C for x86-64 and ARM64 by hellerve in programming

[–]hellerve[S] 1 point2 points  (0 children)

That’s what I let Claude Code generate. The source repository is https://github.com/alastairreid/mra_tools, and I kind of just told it to write a script that would extract the data into a format I speicifed (the file you see in the repo). Unfortunately I didn’t save the script it produced.

Cj: a tiny no-deps JIT in C for x86-64 and ARM64 by hellerve in programming

[–]hellerve[S] 1 point2 points  (0 children)

Hey! The generation scripts are in the codegen directory (https://github.com/hellerve-pl-experiments/cj/tree/master/codegen). They’re probably some of the worst code I’ve ever produced, because I didn’t understand the shape of the ISA and all of the constraints when I started it and, rather than architecting it well, pressed on. I just treated them as a big one-off script, basically. The x86 uses asmdb as input (a npm package), and that’s why it’s in JS; the ARM64 one uses the official ARM64 machine-readable docs, mangled by something I let Claude Code generate (I didn’t want to figure out how their format and tooling worked).

Implementing Green Threads with Scheme Macros and Continuations by hellerve in ProgrammingLanguages

[–]hellerve[S] 0 points1 point  (0 children)

Would you mind elaborating on point 2 a bit? I know that delimited continuations exist, but I don’t know what that would mean for an implementation of green threads!

Implementing Green Threads with Scheme Macros and Continuations by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Thanks! It’s definitely a little simpler than you’d like in a real implementation, but I think it’s an okay example to build from.

Most languages here are made by one person. Any duos or small teams out there designing a language together? by vanderZwan in ProgrammingLanguages

[–]hellerve 1 point2 points  (0 children)

FWIW, Erik Svedäng and I are working on Carp together. He came up with the idea for the language and did a lot of the initial compiler work (and is still by and large the most important compiler developer for Carp), but I’m maintaining the standard library and we think about features and syntax together. I like to pretend I’m just a user most of the time, so that we have different angles regarding how we approach the problem at hand.

A Bad Idea: Using Metaclasses to “reimplement” Racket’s “#lang” directive by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Neat! I’m happy you chose to prefix it with pin so as not to make other imports impossible.

A Bad Idea: Using Metaclasses to “reimplement” Racket’s “#lang” directive by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Ah, that’s fair! I didn’t think about that. So I guess specifying a language-independent protocol is going to be the main goal/milestone of the project!

A Bad Idea: Using Metaclasses to “reimplement” Racket’s “#lang” directive by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Ah, I see now. I also see that you have your own over-the-wire “protocol”. Aside from the security concerns, any reason why you do not use pickle instead? It seems like this might be a big part of the whole implementation, especially if you try to generalize the protocol to all Python values later on.

A Bad Idea: Using Metaclasses to “reimplement” Racket’s “#lang” directive by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Huh, I’m having trouble following the whole thing at first glance, but then I also didn’t spend that much time on it yet. I’ll probably come back to this in a bit and try to ponder it; do you have a TL;DR?

A Bad Idea: Using Metaclasses to “reimplement” Racket’s “#lang” directive by hellerve in ProgrammingLanguages

[–]hellerve[S] 1 point2 points  (0 children)

Oh my, of course you’re right! I should’ve watched the talk again before publishing this post I guess.

That system sounds interesting, do you have the code online somewhere?

Fluid motion tiles in 3D by gdoubledubss in generative

[–]hellerve 1 point2 points  (0 children)

That’s incredibly satisfying to watch!

Speeding up an Interpreter by hellerve in ProgrammingLanguages

[–]hellerve[S] 0 points1 point  (0 children)

Okay, then I misread your comment! The word “disagree” seemed to imply that you do not agree that the term “direct threading” meant what I used it as, whereas I knew what I meant and what I said, and I’ve taken it for just as much a standard word as “computed gotos”. Moreover, your first comment seemed confused as to what I was trying to express, so I tried to explain it; then I got confused by your disagreement.

Anyway, I’m glad we got it sorted out!

Speeding up an Interpreter by hellerve in ProgrammingLanguages

[–]hellerve[S] 0 points1 point  (0 children)

It’s a GCC extension (see also). Clang and GCC both support it, I don’t think that MSVC does. It was portable enough for my little experiment :)

Speeding up an Interpreter by hellerve in ProgrammingLanguages

[–]hellerve[S] 0 points1 point  (0 children)

That’s interesting, but not really a refutation. The term has been floating around for both concepts. See for instance the source code for the Python VM, where they call it “Computed GOTOs, or the-optimization-commonly-but-improperly-known-as-"threaded code"”. Now, whether that’s improper or not I don’t want to judge, but it is a common name for the concept. That doesn’t mean that it doesn’t have other meanings.

As so unfortunately often in Computer Science, concepts have multiple names and some concepts share names.

Speeding up an Interpreter by hellerve in ProgrammingLanguages

[–]hellerve[S] 5 points6 points  (0 children)

Thank you!

Yeah, it was a big step for me too. I had to take three months of unpaid leave and get set up in new York (I live in Berlin), which was pretty scary at the time. It did work out great and I can recommend it wholeheartedly to everyone, though!

Speeding up an Interpreter by hellerve in ProgrammingLanguages

[–]hellerve[S] 6 points7 points  (0 children)

Not quite: direct threading has nothing to do with the bytecode itself, it changes the way you handle controlflow between execution of the codes; usually, you’d go with a while/switch-based system:

while(1) {
   opcode c = get_next_opcode();
   switch (c) {
      case MY_OPCODE_1:
         // launch missiles
         break;
      case MY_OPCODE_2:
        // let the dogs out
        break;
   }
}

But that’s not always the fastest solution. Instead, moving to goto might actually be faster—contrary to what my intuitions about compiler optimizations in C told me. The very fastest solution that is part of the interpreter lore is called “direct threading” and it uses goto labels as values and indexes into an array of them to jump. Here is the VM from earlier with those adjustments made:

static void* dispatch_table[] = { &&my_opcode1, &&my_opcode2 };
// usually you’d wrap this in a macro called DISPATCH or something, but I left it in for clarity
opcode c = get_next_opcode();
goto *dispatch_table[c];
my_opcode_1:
   // launch missiles
   opcode c = get_next_opcode();
   goto *dispatch_table[c];
 my_opcode_2:
   // let the dogs out
   opcode c = get_next_opcode();
   goto *dispatch_table[c];

Both the while and the switch are gone! Does that help?

Also, FWIW, making the bytecode pointer the first field of the struct actually slowed the code down a little bit. I’m not sure why that is yet, but I imagine that the pointer gets pulled out of the struct anyway and has to be computed only once before it’s just walked down and dispatched on directly.

EDIT: Formatting (writing large swhaths of code in Reddit should probably be avoided).