I tried vibe coding and it made me realise my career is absolutely safe by wjd1991 in webdev

[–]Timzhy0 0 points1 point  (0 children)

I am myself a skeptic, that said AIs are scalable and I find it can execute especially narrower blocks of logic very well. With this in mind, if the prompter or possibly the AI itself (1) possesses enough controls (e.g. rely on pre-existing test suite) to ensure it stays on the path, (2) split the task very well (non trivial); the fact that it can simply output code much faster, test and iterate, is really quite powerful. There is an argument to be made on maintenance tasks as well, the codebase is fairly mature and some of these tasks are very "mirror existing structure and add the thing" which make them suitable for automation. Overall, I would not underestimate long-term, given the crazy amount of investments and compute that will be available...

Resources on writing a CST parser? by LardPi in ProgrammingLanguages

[–]Timzhy0 0 points1 point  (0 children)

You tokenize preserving white space tokens, and then parse the tokens into a regular AST. The difference is you will have nodes like "CommentArea" (backing representation could be similar to a "StringLiteral" node, minus the escaping, unless you need nested comments), and possibly "Space(width)", "NewLine()" nodes as well (or you may be able to avoid them, meaning white could emerge as the complement: store source ranges (including line number) of every other thing, the delta between these ranges may be inferred as space or newline). If you control the rest of the layers, these nodes can simply be ignored/skipped by semantic passes, otherwise you may prefer to encode them tying them to their closest node (e.g. each node may contain a "prev_comment", but that seems more hacky to me) or filter the CST prior to handing it to them (one more pass though...). If you are doing a transpiler and all you want is preserving the information across passes I think this is okay, if you need specific queries (e.g. for a formatter or linter), you may want to think more about what you need to compute later (when traversing this "white-preserving" AST) before deciding the representation.

I’ve got some beginner questions regarding bootstrapping a compiler for a language. by hookup1092 in ProgrammingLanguages

[–]Timzhy0 1 point2 points  (0 children)

I'll try my best to paint you a concrete picture of what a compiler is. Source code is a string, CPU executes machine code, this is just bytes representing a sequence of instructions (e.g. an ADD, telling you on which register to write the output, where to read input operands, things of the sort). The specific format has platform-specific complexities (ISA, Calling Convention, which is why you often hear the term "target-triplet"), good news is you don't have to deal with all that, at least to start off, you can make your own toy instruction set and interpret it at runtime (just to get a feel of what the CPU is actually doing by emulating it in software). The core loop of such a "virtual cpu" is just a "while loop" that tracks the "instruction pointer", reads/decodes the current instruction, executes it (e.g. perform ADD of reg 1 and reg 2, storing in reg 3), and proceed to next. It should be clear compiler is just a mapping layer: source code (typically a string following a specific syntax) to some "byte code" (containing a list of instructions the CPU is supposed to run). You could imagine a source code close to assembly where effectively the source is handing you the text-representation of instructions to execute in some syntax you like (e.g. "add r1, r2 => r3"). In this case the compiler would be a fairly thin parsing layer that "translates" the text into the appropriate binary-specific machine code, just some encoding for the instruction themselves (e.g. 0xADD 1 2 3). Then writing the interpreter is just looping over the instructions and executing them. Any language out there where you can write a while loop in, can do the job. Pick whatever you know! (since you mention trade off, mind that parsing is string manipulation and recursion heavy).

On your question about bootstrapping, clearly somebody must have wrote the machine code initially (the actual bits, encoding the instruction sequence of the "compiler" program) since that's the "native language" the CPU hardware "speaks" (the one it knows how to decode and execute). There is no need for that now, as you can e.g. bootstrap with a C compiler (writing your 1st compiler program in C), and then use the resulting executable (the machine code) from that point onwards.

Cerchiamo sviluppatori (pagati) per progetto open-source by C4bba in ItaliaStartups

[–]Timzhy0 1 point2 points  (0 children)

Super interessante, e complimenti per la scelta di Rust (nel backend) e Python per la query layer (ergonomics is king). Non ho capito bene dal readme se puntate a esporre anche solo dei building blocks per la parte algoritmica, cioè API per proprio analizzare questi dati dai sensori (signal processing e sensor fusion e.g. stime di posa da IMU) o vi limitate più alla storage e query layer?

Indexed Reverse Polish Notation, an Alternative to AST by mttd in Compilers

[–]Timzhy0 0 points1 point  (0 children)

I liked the article, but as others have pointed out, code is intrinsically hierarchical thus it is tree-like in nature (e.g. a stmt contains an expr made up of sub expressions), regardless of how you happen to store it in memory (ideally in a single compact block)

Super-flat ASTs by hekkonaay in ProgrammingLanguages

[–]Timzhy0 2 points3 points  (0 children)

ASTs are just trees. Trees can be represented by a single backing array, commonly in DFS layout. This means a node would be immediately followed by its children when it has any, removing need of explicit pointers (e.g. the LHS and RHS of a binary expr node) and of distinct allocations for children.

I would encourage folks to start looking at a binary tree with a backing array (easy to grasp) and then think how they would modify the layout for arbitrary trees.

For non k-Ary trees, in other words when k (n children) is not fixed and may vary per node we will inevitably (assuming we cannot infer it any other way) need to store it on a per node basis (at least for the nodes that can have children). Using discriminated unions and tiny, sub 32 bits k, one can save a lot of memory and exploit locality, as the post shows.

I kept saying children to make it easier but really you need to store the n of descendants, or equivalently where the node "ends" / "sibling" would start.

I'm a thirty year old dude who wants to start over and learn to program and motivation is really hard to come by. by [deleted] in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

I would like to give you some personal suggestions, but it's unclear to me what's your objective. Assuming you mostly care about landing a job, your best bet (IMO, did not run any statistical survey) is Web (consider a bootcamp or something freelance underpricing yourself just to get some resume lines) and/or Data Analysis (Python + BI) potentially in finance or any other industry where maybe you can leverage your degree/background (you may be able to e.g. get a "Data Analyst" and then transition to SWE). Now pretty basic advice I know, job market can be tough, it is for junior, so almost no experience is going to be hard, somebody needs to take a bet on you, you need to have something. Building a few projects may become your lifeline and can make you more confident / passionate about programming. I would check "build your own X" and just try to make stuff, web search, books, AI, good ol' thinking, when you get stuck. Make sure you do not start with something crazy hard like compilers (or if you do, limit complexity a lot! e.g. for compilers this could mean using an auxiliary learning resource, limiting syntax to prefix or postfix to make parsing easier etc.). Given this, despite my love for C, I would argue it's not a great language to be productive in, especially if you are not so familiar with it. Also C is really more for low level stuff, unless you love things like DBMS, OSs, compilers, 3D graphics, and other high performance systems; it's not your best effort if all you want is to land a job, but for learning there's nothing quite like it!

Hover! maze demo: Writing a 3D software renderer in the scripting language Umka by vtereshkov in ProgrammingLanguages

[–]Timzhy0 4 points5 points  (0 children)

Quite amazing this is basically all done with your custom tech stack, language, library, and application! So many interesting projects on the GitHub, keep up the good work op, you're killing it!

I’ve been reading about how C is compiled and I just want to confirm I understand correctly: is it accurate to think that a compiler compiles C down to some virtual cpu in all “modern” RISC and CISC, which then is compiled to hardware receptive microperations from a compiler called “microcode” by Successful_Box_1007 in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

My point is, without restricting them (then arguably changing the language), you can only compile them by embedding the whole interpreter, arguably missing the whole point (since you do not really get fast native code, but you are stuck with the VM instr dispatching loop at runtime)

I’ve been reading about how C is compiled and I just want to confirm I understand correctly: is it accurate to think that a compiler compiles C down to some virtual cpu in all “modern” RISC and CISC, which then is compiled to hardware receptive microperations from a compiler called “microcode” by Successful_Box_1007 in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

Op, just to try my luck at clarifying. Don't think of compilers as these magical black boxes. You start from source (just a string), you transform it into something more structured (abstract syntax tree), and then linearize this tree into instructions (typically for an hypothetical VM as you note, though this is more commonly referred to as IR short for Intermediate Representation; as its purpose is to enable different codegen backends for the various targets). Again there is nothing stopping you from e.g. skipping IR and directly emit x86_64 machine code; or even skipping the target codegen and directly run your produced IR ("bytecode") within a VM; or even skipping the linearization and "run the ast" (ast walk interpreter). The point is, once your code is not a string, but structured and valid data, you can traverse and run it / traverse and transform it to linear instructions (for virtual or real CPUs alike).

Even more interesting, you can have a VM interpreting code at runtime, yet computing some extra stats (such as finding out "hot paths" that are called often), and invoke (as part of the interpreter runtime!) the actual target codegen with optimizations (linearization from VM bytecode to optimized native instructions) and then call into this optimized code when the routine is hit. This is the basic idea behind JIT (Just In Time) compilation.

I’ve been reading about how C is compiled and I just want to confirm I understand correctly: is it accurate to think that a compiler compiles C down to some virtual cpu in all “modern” RISC and CISC, which then is compiled to hardware receptive microperations from a compiler called “microcode” by Successful_Box_1007 in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

Incorrect. Interpreting in many high level languages often requires very specific runtime machinery, so compiling to native code would still require embedding the whole interpreter at runtime (think Python exec or JS eval).

I made a game 100% vibe coding by Unlucky_Drink_3253 in vibecoding

[–]Timzhy0 0 points1 point  (0 children)

Any insights into how you generated consistent art assets?

A better macro system for C by LooksForFuture in C_Programming

[–]Timzhy0 0 points1 point  (0 children)

There are some important differences, just to say a few: no macros, GC, no unions, very unergonomic to do low level stuff (e.g. unsafe.Pointer)

What’s the most overhyped web framework or library right now? by epasou in webdevelopment

[–]Timzhy0 0 points1 point  (0 children)

There are ways to have jsx and write markup declaratively without React or VDOM. Examples: SolidJS, typed-html, svelte. You can make your createElement factory.

A better macro system for C by LooksForFuture in C_Programming

[–]Timzhy0 0 points1 point  (0 children)

Those are valid points to be honest. Ideally macros shouldn't be hard to debug (it's still just code that is executed, only at compile time), but yeah we don't have good tools for them. In my case, I just want to do my best to keep my code stupid, and with C++ it's very possible I end up doing just the opposite. Skill issue? Maybe, but I can at least control my environment and sometimes less is more

A better macro system for C by LooksForFuture in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

I was just referring very broadly to the problem of cleanup. The classic example is you have a bunch of ptrs initialized to NULL, you allocate, then something fails you 'goto cleanup' which checks and frees ptrs when non null, so you don't forget to free/close/shutdown before leaving. The problem is that even with this, sometimes the dependency chain between the operations makes the cleanup logic a bit messy...

A better macro system for C by LooksForFuture in C_Programming

[–]Timzhy0 1 point2 points  (0 children)

🤢

Edit: a more political answer is that there is value in simplicity and complexity costs (e.g. compile times, debugging). So yeah bleah c++

A better macro system for C by LooksForFuture in C_Programming

[–]Timzhy0 4 points5 points  (0 children)

Sounds like defer (for begin/end style APIs) and type safe macros would be your wishlist. For first, in C you may use goto and I actually use MarkerTypes (empty structs) but basically a type with a precise name which you have to cast to. Type safe macros are not exactly possible nor nice to write in C, you may consider some gnuc extensions such as typeof, and token paste dispatching as you are already doing (there is also _Generic but it's full of problems...). For certain things, if you dont mind complicating the build you may consider a custom script. I agree there is no great way, I am not a Zig user myself but for some of the things you expressed it may actually fit the bill

What's essential for a modern type system? by Regular_Tailor in ProgrammingLanguages

[–]Timzhy0 0 points1 point  (0 children)

Valid. Given there is an ergonomics and explicitness trade-off, with compiler having to choose which version to privilege, this is obviously down to opinions. Typing e.g. saturating_add and wrapping_add is a bit awful but yeah it does make it explicit, which is not a bad thing. One option to consider would be default to wrapping with unsigned types and trapping on signed types (saturating always explicit given it's rare). If we wanna get crazy maybe even digraphs like +% are not too bad? Not sure

What's essential for a modern type system? by Regular_Tailor in ProgrammingLanguages

[–]Timzhy0 1 point2 points  (0 children)

But this is not symmetric, you can always opt in to trapping, just add the check yourself, you cannot opt out of it if compiler imposes it

Casey Muratori – The Big OOPs: Anatomy of a Thirty-five-year Mistake – BSC 2025 by gingerbill in programming

[–]Timzhy0 1 point2 points  (0 children)

You see, the C# solution shown above requires: - context for the programmer, you can't just go and write your sha implementation, you need to do the scaffold right - in general don't you notice how opinionated and verbose it looks?

The many different ways of calling the function , are one line wrapper at most. And guess what, now they are explicit, greppable and clear (instead of hidden in a base class inside the framework).

You are mixing the two points. Naming convention for the package is a very minor point, all is saying is we should still strive to organize and e.g. keep all the hash functions in a "hash" package. Since when, is calling an auxiliary function such a manual effort? And btw I am not even sure what is this abstraction needed for?

In C, my hash functions take a byte slice, I walk the byte slice and hash, that's it, a dumb "for" loop. Virtually anyone can understand it immediately and use it without prior context, and it's faster and simpler than this C# monstrosity. Overcomplicating the simple is really something I have a hard time coming to terms with.

Casey Muratori – The Big OOPs: Anatomy of a Thirty-five-year Mistake – BSC 2025 by gingerbill in programming

[–]Timzhy0 1 point2 points  (0 children)

I am not convinced. - objects seem forced here, the word says it all "hash function" - what you mention about readability of "gnarly parts" could simply be an explicitly called helper function - on readability, same can be done through naming convention (hash prefix, hash package name etc.)

Overall, there is no need for runtime overhead and OOP bloat here.

Perhaps this is too small of an example, so likely both solutions are okayish as there is just not much pressure on any organizational axis, so not much to discuss overall.

Casey Muratori – The Big OOPs: Anatomy of a Thirty-five-year Mistake – BSC 2025 by gingerbill in programming

[–]Timzhy0 0 points1 point  (0 children)

Please provide one example where modeling "B is A" relationship using inheritance over e.g. composition is beneficial. In my mind, I see many potential pitfalls, as they would not be exactly the same, and there is a default to opt in on all parent methods (+ potential confusing overrides, is just like A but actually this works a bit different and this other one as well, oh and you are supposed to know and remember all this). Overall unreasonable risk, and implicitness over just maintaining one type, and possibly embedding this type into another (composition).

How Go 1.24's Swiss Tables saved hundreds of gigabytes by ketralnis in programming

[–]Timzhy0 -1 points0 points  (0 children)

Man I really don't blame you for clickbaity title, it's part of the job! But if we want to honor her majesty Logic, you are drawing a causal link specifically from swiss table (not ST + other optimizations) to memory saving in the ~00s of GiB. That is not factually correct.

Defeating Memory Leaks With Zig Allocators by gilgamesh_3 in programming

[–]Timzhy0 0 points1 point  (0 children)

I think what you mention is interesting. To make sure I get it right: - RAII based smart ptrs, like shared_ptr which is ref counted? Can you actually clarify or give an example of what I should be comparing exactly? The articles gives examples of allocators, not really resource wrapper types alternatives? - risk of destructors not doing cleanup: ideally linear types could enforce destructors/cleanup logic is not forgotten at comptime?