Programming thread

  • 🐕 I am attempting to get the site runnning as fast as possible. If you are experiencing slow page load times, please report it.
Learn to weld.
No, been there done that. The blue collar shit is just a meme.

One time I busted my ass working as a maintenance guy and got promoted to supervisor then they laid off half the company.

I did construction too. They made us work over time every day and somehow I only ever took home an extra $50 and I watched someone try to kill another guy by beating him with a hammer.
 
Yes, and for almost everything it's a huge mistake.
So the answer to basically a skill issue is making every allocation cleanup in a program happen "at some point™" completely invisible to the user. That's going to make profiling fun, let alone the memory fragmentation it will cause over time,
This is a lie. Many of the languages I enjoy existed beforehand
Keyword "borrow". I'm talking about languages post C. I'm not denying the existence of FORTRAN and Pascal.
I can't think of a single good reason for someone to learn the C language for these things over a machine code. The machine code is simpler, and really does lack training wheels. Someone who wants to learn about the machine implementation of concepts like indirection should write a simple machine code program, if he wants practical experience at all. I may not have a good perspective here, because I did all of this anyway, but I can easily envision someone just as competent who didn't need it.
Complete strawman. I clarify immediately in my post that I understand that the binary will not represent 1 - 1 the code I expect, however, my point wasn't that you need to know exactly what micro-ops your CPU generates from the instructions in your binary but rather the fact that you should have at least basic knowledge about what buffers look like in memory ( Vital for debugging ) Stack vs the heap, how calling functions works with abstracted languages. Without these concepts your data structures and algorithms are fundamentally going to be terrible

I do want to clarify my position a bit further on this, I don't think "higher level" languages should never be used.

Without people having learned C I just think newcomers will fall into traps and develop terrible habits contributing to the already terrible state of software
 
Last edited:
>working on my retarded video game project
>Don't want to add every single frame from 2d walking animation in Godot because Im trying to learn coding.
>Try figuring out how to write a script in c# that just inserts each frame of the animations into their proper track on start up
>Nothing seems to work
>See if anyone has done something similar online
>Godot forums and reddit all give poorly explained solutions written in GD script.

6176071-939db28f45f5d6ff2625c902931b244d.png
If I was in a room with a rapist pedophile and a redditor, and I had a gun with two bullets, I would shoot the rapist pedophile twice and choke the redditor to death with my bare hands.
 
my point wasn't that you need to know exactly what micro-ops your CPU generates from the instructions in your binary but rather the fact that you should have at least basic knowledge about what buffers look like in memory ( Vital for debugging ) Stack vs the heap, how calling functions works with abstracted languages.
Serious question: What exactly do you learn about buffers and function calls in C that you don't in other languages? I also question that stack vs heap is that useful since the stack is a convention and I've repeatedly seen idiots allocate like 4MB on the stack "because the stack is faster than the heap".
 
Serious question: What exactly do you learn about buffers and function calls in C that you don't in other languages? I also question that stack vs heap is that useful since the stack is a convention and I've repeatedly seen idiots allocate like 4MB on the stack "because the stack is faster than the heap".
For functions, There's understanding that there are calling conventions I'm not going to be so drastic to say that you need to understand the actual differences but understand that they are different

Inline vs non inline functions is important ESPECIALLY with recursion. Calling a function isn't free, there are function prologues and epilogues to consider but most importantly you have to push registers to the stack, with deep enough recursion you can actually overflow the stack.

Buffers, I suppose overlaps with pointers, you need to know the address of a buffer to inspect in a debugger.

The stack IS faster than the heap. The Stack not only has better cache locality but is far faster to allocate as all the CPU does is adjust the stack pointer register. Allocating on the heap, even with the best implementation is incredibly slow. Not to mention for micro allocations your introduce potential memory fragmentation.

Allocating 4MB is ridiculous though. I assume that's hyperbole as it would surely overflow

Inb4 someone says: "stack and the heap are still both pageable memory from the OS"
 
What's the best way to dive headfirst into learning cooooooooooding?

(I want to learn all the common C languages)
I can give specific recommendations if you tell me what you want to achieve with coding.
In my experience, it's the mechanics behind pointers (memory addressing, dereferencing, etc.) that trip most students up. It takes a certain mindset to work with, and most people simply aren't well equipped to work within that mindset. It's arguably a good filter to weed out the people who don't take the time to practice and learn this shit. You can abstract away the idea of pointers entirely, and most languages these days do, but we're starting to see the deleterious effects of permitting this sort of intellectual laziness where people don't care to learn how things work and what the best practices are by extension. If you have no clue how memory management works, memory is effectively a magic resource that appears out of thin air and manages itself.
I don't think anyone would demand that someone using Excel knows how it manages memory. Using Python or R can be very much like Excel but with for loops, (better) functions etc. Why would that distinction require firm knowledge of memory management?
 
  • Like
Reactions: UERISIMILITUDO
I don't think anyone would demand that someone using Excel knows how it manages memory. Using Python or R can be very much like Excel but with for loops, (better) functions etc. Why would that distinction require firm knowledge of memory management?
I'm not sure I understand the question. I was speaking in reference to those who want to be competent programmers in general, and particularly those who should be competent (i.e. "professionals"). There are all sorts of ways for those less serious about programming to get shit done without requiring years of background knowledge, but that's beyond the scope of what I'm getting at.
 
I'm not sure I understand the question. I was speaking in reference to those who want to be competent programmers in general, and particularly those who should be competent (i.e. "professionals"). There are all sorts of ways for those less serious about programming to get shit done without requiring years of background knowledge, but that's beyond the scope of what I'm getting at.
A lot of scientific computing tools are the way they are precisely because they let you avoid things like (direct) memory management. You can get very serious work done at that level of understanding nonetheless.
 
For functions, There's understanding that there are calling conventions I'm not going to be so drastic to say that you need to understand the actual differences but understand that they are different

Inline vs non inline functions is important ESPECIALLY with recursion. Calling a function isn't free, there are function prologues and epilogues to consider but most importantly you have to push registers to the stack, with deep enough recursion you can actually overflow the stack.

Buffers, I suppose overlaps with pointers, you need to know the address of a buffer to inspect in a debugger.
I legitimately don't remember when I last had to think about calling conventions in C despite using it daily for years. It's an implementation detail, the sort of thing you learn while dabbling with assembly languages or tinkering with your system implementation, not while learning C. Call stack exhaustion is something that affects every language, so you don't need C for that either. As for buffers, every debugger I've used let me look at buffers without knowing their addresses. How would you even know the address in advance?
The stack IS faster than the heap. The Stack not only has better cache locality but is far faster to allocate as all the CPU does is adjust the stack pointer register. Allocating on the heap, even with the best implementation is incredibly slow. Not to mention for micro allocations your introduce potential memory fragmentation.

Allocating 4MB is ridiculous though. I assume that's hyperbole as it would surely overflow

Inb4 someone says: "stack and the heap are still both pageable memory from the OS"
Allocating on the heap with malloc is incredibly slow compared to the stack because that's the tradeoff most mallocs make. In a generational GC, allocating many small objects (the case of interest; big objects wouldn't fit the stack and rare allocations are irrelevant) is typically also just incrementing a counter. This is specifically not some kind of computing fundamental.

After double-checking the case I was thinking of, apparently it was 0.5MB; I mistakenly thought that allocation happened multiple times. Still ridiculous, fucking GNOME.
 
I question if the same sort of thing happens cognitively if we start abstracting too much away.
I don't know the ins and outs of how water or power arrive at my house. They've been abstracted away from me. Do I need to know how they work? What about the telephone system? What about the Internet? What about oil refining?

Abstraction is a good thing, and enables the modern world. As I stated earlier, the only reason some programmers dislike it is their need to feel special and important.
Kids these days have a very fragmented understanding of how filesystems work, largely thanks to the weird compartmentalized way iOS handles inter-app userspace file sharing (which didn't even exist for many years).
Rob Pike can't imagine machines without filesystems because UNIX has melted his mind:
https://hachyderm.io/@robpike/110863371168631778 (archive)

I recall reading about a difference between block organization under UNIX and a Xerox PARC system: UNIX uses metadata blocks, I believe, whereas the other system stored metadata with each block. This meant that the latter system could recover from failures that would destroy a UNIX filesystem. The latter system also had block sizes larger than a power of two, so that each block had a power of two size for data, and the remainder went to metadata. There's an analogy here: A Lisp or Smalltalk system has self-identifying objects, whereas the typical UNIX program has no dynamic type information, and can very easily be made to go off the rails.
If that abstraction system goes tits up, or they have to deal with something less abstracted, they're basically useless at troubleshooting because they lack any of the fundamentals.
This is an argument for designing a computer system a single human can understand in its entirety. UNIX that isn't.
So the answer to basically a skill issue is making every allocation cleanup in a program happen "at some point™" completely invisible to the user. That's going to make profiling fun, let alone the memory fragmentation it will cause over time,
No one sane gives a fuck about how much memory a program uses unless it's noticeably bad. They care about whether the program works or not. I wanted to give a story from The UNIX-HATERS Handbook about someone who wrote an optimized but incorrect program that wasted more time than it could possibly save, but I can't find it.
Keyword "borrow".
Oh, clarification.
I'm talking about languages post C.
It's still not true, then.
Without these concepts your data structures and algorithms are fundamentally going to be terrible
This is a mathematical topic above all else.
function prologues and epilogues
Where are those in Forth?
Buffers, I suppose overlaps with pointers, you need to know the address of a buffer to inspect in a debugger.
An array is more than a memory address. I'd explain it myself, but I found this nice section from The UNIX-HATERS Handbook that does it just as well, if not better:
Robustness, or "All Lines Are Shorter Than 80 Characters"

There is an amusing article in the December 1990 issue of Communications of the ACM entitled "An Empirical Study of the Reliability of Unix Utilities" by Miller, Fredriksen, and So. They fed random input to a number of Unix utility programs and found that they could make 24-33% (depending on which vendor's Unix was being tested) of the programs crash or hang. Occasionally the entire operating system panicked.

The whole article started out as a joke. One of the authors was trying to get work done over a noisy phone connection, and the line noise kept crashing various utility programs. He decided to do a more systematic investigation of this phenomenon.

Most of the bugs were due to a number of well-known idioms of the C programming language. In fact, much of the inherent brain damage in Unix can be attributed to the C language. Unix's kernel and all its utilities are written in C. The noted linguistic theorist Benjamin Whorf said that our language determines what concepts we can think. C has this effect on Unix; it prevents programmers from writing robust software by making such a thing unthinkable.

The C language is minimal. It was designed to be compiled efficiently on a wide variety of computer hardware and, as a result, has language constructs that map easily onto computer hardware.

At the time Unix was created, writing an operating system's kernel in a high-level language was a revolutionary idea. The time has come to write one in a language that has some form of error checking.

C is a lowest-common-denominator language, built at a time when the lowest common denominator was quite low. If a PDP-11 didn't have it, then C doesn't have it. The last few decades of programming language research have shown that adding linguistic support for things like error handling, automatic memory management, and abstract data types can make it dramatically easier to produce robust, reliable software. C incorporates none of these findings. Because of C's popularity, there has been little motivation to add features such as data tags or hardware support for garbage collection into the last, current and next generation of microprocessors: these features would amount to nothing more than wasted silicon since the majority of programs, written in C, wouldn't use them.

Recall that C has no way to handle integer overflow. The solution when using C is simply to use integers that are larger than the problem you have to deal with-and hope that the problem doesn't get larger during the lifetime of your program.

C doesn't really have arrays either. It has something that looks like an array but is really a pointer to a memory location. There is an array indexing expression, array[index], that is merely shorthand for the expression (*(array + index)). Therefore it's equally valid to write index[array], which is also shorthand for (*(array+index)). Clever, huh? This duality can be commonly seen in the way C programs handle character arrays. Array variables are used interchangeably as pointers and as arrays.

To belabor the point, if you have:
C:
char *str = "bugy";
...then the following equivalencies are also true:
C:
0[str]   == 'b'
*(str+1) == 'u'
*(2+str) == 'g'
str[3]   == 'y'
Isn't C grand?

The problem with this approach is that C doesn't do any automatic bounds checking on the array references. Why should it? The arrays are really just pointers, and you can have pointers to anywhere in memory, right? Well, you might want to ensure that a piece of code doesn't scribble all over arbitrary pieces of memory, especially if the piece of memory in question is important, like the program's stack.

This brings us to the first source of bugs mentioned in the Miller paper. Many of the programs that crashed did so while reading input into a character buffer that was allocated on the call stack. Many C programs do this; the following C function reads a line of input into a stack-allocated array and then calls do_it on the line of input.

...
I don't think anyone would demand that someone using Excel knows how it manages memory.
I agree. Spreadsheets are an excellent model of data-flow programming. Data-flow machines are neat, and I've spent a lot of time wrapping my head around them.

Here's a final quotation from the good book:
Pardon Me, Your Memory Is Leaking...

High-level languages offer built-in solutions to commonly encountered problems. For example, it's well known that the vast majority of program errors have to do with memory mismanagement. Before you can use an object, you have to allocate some space for it, initialize it properly, keep track of it somehow, and dispose of it properly. Of course, each of these tasks is extraordinarily tedious and error-prone, with disastrous consequences for the slightest error. Detecting and correcting these mistakes are notoriously difficult, because they are often sensitive to subtle differences in configuration and usage patterns for different users.

Use a pointer to a structure (but forget to allocate memory for it), and your program will crash. Use an improperly initialized structure, and it corrupts your program, and it will crash, but perhaps not right away. Fail to keep track of an object, and you might deallocate its space while it's still in use. Crash city. Better allocate some more structures to keep track of the structures that you need to allocate space for. But if you're conservative, and never reclaim an object unless you're absolutely sure it's no longer in use, watch out. Pretty soon you'll fill up with unreclaimed objects, run out of memory, and crash. This is the dreaded "memory leak."

What happens when your memory space becomes fragmented? The remedy would normally be to tidy things up by moving the objects around, but you can't in C++-if you forget to update every reference to every object correctly, you corrupt your program and you crash.

Most real high-level languages give you a solution for this-it's called a garbage collector. It tracks all your objects for you, recycles them when they're done, and never makes a mistake. When you use a language with a built-in garbage collector, several wonderful things happen:

  • The vast majority of your bugs immediately disappear. Now, isn't that nice?
  • Your code becomes much smaller and easier to write and understand, because it isn't cluttered with memory-management details.
  • Your code is more likely to run at maximum efficiency on many different platforms in many different configurations.

C++ users, alas, are forced to pick up their garbage manually. Many have been brainwashed into thinking that somehow this is more efficient than using something written by experts especially for the platform they use. These same people probably prefer to create disk files by asking for platter, track, and sector numbers instead of by name. It may be more efficient once or twice on a given configuration, but you sure wouldn't want to use a word processor this way.

You don't even have to take our word for it. Go read The Measured Cost of Conservative Garbage Collection by B. Zorn (Technical Report CU-CS-573-92, University of Colorado at Boulder) which describes the results of a study comparing performance of programmer-optimized memory management techniques in C versus using a standard garbage collector. C programmers get significantly worse performance by rolling their own.

OK, suppose you're one of those enlightened C++ programmers who wants a garbage collector. You're not alone, lots of people agree it's a good idea, and they try to build one. Oh my, guess what. It turns out that you can't add garbage collection to C++ and get anything nearly as good as a language that comes with one built-in. For one thing, (surprise!) the objects in C++ are no longer objects when your code is compiled and running. They're just part of a continuous hexadecimal sludge. There's no dynamic type information-no way any garbage collector (or for that matter, a user with a debugger) can point to any random memory location and tell for sure what object is there, what its type is, and whether someone's using it at the moment.

The second thing is that even if you could write a garbage collector that only detected objects some of the time, you'd still be screwed if you tried to reuse code from anyone else who didn't use your particular system. And since there's no standard garbage collector for C++, this will most assuredly happen. Let's say I write a database with my garbage collector, and you write a window system with yours. When you close one of your windows containing one of my database records, your window wouldn't know how to notify my record that it was no longer being referenced. These objects would just hang around until all available space was filled up-a memory leak, all over again.
Mac OS X still has memory leaks. Isn't that funny?
 
I don't know the ins and outs of how water or power arrive at my house. They've been abstracted away from me. Do I need to know how they work? What about the telephone system? What about the Internet? What about oil refining?

Abstraction is a good thing, and enables the modern world. As I stated earlier, the only reason some programmers dislike it is their need to feel special and important.
Anyone can search this thread for "Whitehead" to see the quote from Alfred North Whitehead about abstraction I used here which is really great but I was also just thinking of the nand2tetris material on Coursera. Like the name suggests, the material encompasses abstract logic gates such as NAND which can be hooked together to implement all other logic gates and then goes all the way to an operating system which can run such fun applications as Tetris. Why stop there though? Indeed there was optional material where Shimon Schocken gave the floor to Noam Nisan, who explained the physical rather than logical nature of the fundamental logic gates involved using transistors. It was all lost on me but I'm sure that a) there is systems or at least embedded programming where such knowledge is crucial and b) getting / not getting said knowledge could be construed as a "filter" to get rid of scrubs. Nonetheless I got the sense that Schocken doesn't have quite as much knowledge in this area and delegated the extra material to Nisan as a result, despite clearly being an excellent computer scientist. Why not just demand everyone who claims to be a programmer know all of that stuff?
Rob Pike can't imagine machines without filesystems because UNIX has melted his mind:
https://hachyderm.io/@robpike/110863371168631778 (archive)
[...]
There's an analogy here: A Lisp or Smalltalk system has self-identifying objects, whereas the typical UNIX program has no dynamic type information, and can very easily be made to go off the rails.
I will freely admit I haven't gotten into Smalltalk (specifically Pharo) anywhere near as much as I'd like mainly because of the overall difficulty with interfacing with the host Unix environment.
I wanted to give a story from The UNIX-HATERS Handbook about someone who wrote an optimized but incorrect program that wasted more time than it could possibly save, but I can't find it.
This one?
Screenshot 2024-10-26 00:27:49.png
I agree. Spreadsheets are an excellent model of data-flow programming. Data-flow machines are neat, and I've spent a lot of time wrapping my head around them.
Sure, but that isn't what I meant exactly. What I was trying to say is that I've had enough experience with using C pointers to pass the "filter" suggested earlier but a lot of these people using some of these scientific computing tools a) might not have that knack but also b) could kick my ass at a lot of other things. I can understand pointers well enough but I'm bad at integral calculus. Perhaps the situation is reversed with other people. Calling them non-experts because of one thing might not be a good idea.
 
I have seen some courses on Coursera and edX regarding R Programming in Data Science, and I’m actually thinking on getting a certificate in it just for fun.

You don’t hear most talk about this specific programming language:

 
Last edited:
I have seen some courses on Coursera and edX regarding R Programming in Data Science, and I’m actually thinking on getting a certificate in just for fun.

You don’t hear most talk about this specific programming language:

You can get a lot done with R quickly and I have used it in the past and will continue using it in the future but the language itself is kinda shitty. What I really advocate is having a bunch of different tools at your disposal. For instance, I want to learn time series forecasting. I was using the R-based textbook Forecasting: Principles and Practice, 3rd Edition but a) the pedagogy was really not quite working for me b) more importantly, the documentation all seemed to be coming from the same very few places and c) a lot of time series forecasting these days is based on deep learning, where Python has a clear edge. (My understanding is that R once had an edge with Auto ARIMA, which is a way of automating the clumsy process of fitting the traditional time series model known as ARIMA but now Python has at least two implementations of Auto ARIMA through the darts library.) If I think R or Python sucks for a given use case I can abandon ship pretty easily. Eventually I want to learn Julia so I have even a third major option and so forth.
 
Last edited:
I can give specific recommendations if you tell me what you want to achieve with coding.
Anything related to game development (Shaders, physics, yada yada) I got the C language book but I can't manage to get an enviorment running to process my code...
 
Back