5 ms·
Other commenters gave excellent and actionable answers to your question. I want to quibble about your reaction to C. > I do not enjoy working with C at all. It
by gregjor 2y ago
Other commenters gave excellent and actionable answers to your question. I want to quibble about your reaction to C.
> I do not enjoy working with C at all. Its esoteric and difficult to understand, and just overall feels like I'm using a tool from the 70s.
Esoteric means "intended for or likely to be understood by only a small number of people with a specialized knowledge or interest." That does not describe C, a language widely understood and used by a large number of programmers, across application domains and programming interests.
Difficult to understand describes a reaction you have to learning C, not a property of the language. Again a very large number of programmers understand and use C, have for decades, and a huge amount of C code gets written and maintained constantly. The C language includes very few keywords and a simple syntax, and a small standard library compared to Python. People new to C usually trip over memory management, pointers, and the overall philosophy behind C, not learning the language itself.
C does date back to the late 1970s, but so does most hardware and software technology we use today. Newer does not equal better, and C has remained relevant and popular despite its age because it works so well. Toyota introduced the Corolla in the mid-1960s and it remains relevant and widely-used today, not to mention influential in the automobile industry. C occupies a similar position, a language that works so well it has staying power and has undergone relatively minor updates over time, unless you count derivative languages that expand on and perhaps improve on C -- C++, Go, Rust, Zig, many others.
Good luck with your project.
- megaloblasto 2y agoThanks for your reply. "likely to be understood by only a small number of people with a specialized knowledge or interest" is the meaning I was trying to convey here. I think C is more difficult that it should be, but it persists for two main reasons. First, many domain experts seem to regard it in an overly positive light, and secondly, there is a huge amount of fundamental software written in C (as you pointed out) which has inertia sustaining the languages importance. Difficult to understand describes a reaction you have to learning C, not a property of the language I think this is true to an extent. Take the following example. I have a C API that requires me to write a callback function, and pass it as an argument to a function called boundaryConditions. boundaryCondtions can actually take a list of functions, but by far the most common use is to pass it a single function. As you probably know, to pass a function as an parameter in C you have to use function pointers. That means that if I want to pass a callback function to boundaryConditions, I need to create a function, then create a pointer to that function, then create an array of function pointers that contains my function pointer, and pass that as my argument. I don't see a world where this is the optimal way of doing things (If I'm wrong, please enlighten me), and I tend to find strange, quirky behavior like this all the time when writing C. This phenomenon of a bad language sticking around is not unheard of in programing (JavaScript for example). I think the Corolla is still around because it is a great car, and people want it. I think C is still around because of inertia and overly positive views of the tool.
- gregjor 2y ago> I think C is more difficult that it should be I think if you view C as a cross-platform macro assembler it makes more sense. You can read the origin story of the C language. The main author or inventor of C, Dennis Ritchie, intended to make a language that targeted the capabilities of hardware available at the time (circa 1972). The goal was to write a reasonably high-level language that did not create significant performance issues compared to assembly language or other languages available at the time. If you go back to that era (my career started in the late '70s) every computer manufacturer had their own instruction set architecture (ISA) and their own proprietary languages and tools (frequently variants of FORTRAN, COBOL, etc.). To make a cross-platform operating system (what we now know as Unix) the team needed a cross-platform language that could express what the hardware of the day could do. C models how almost all digital computers work at a low level, but not as low as the architecture-dependent assembly language. The authors of C and Unix did optimize the language and OS and associated tools, but they optimized them for the available hardware, out of necessity. They did not optimize for programmers who didn't know assembly language or struggled to understand pointers. C has remained relevant in part because of what you call inertia -- huge amounts of code already written. The language has evolved and changed over time, but not much, because the underlying principles of digital computers that C models have not changed much. > As you probably know, to pass a function as an parameter in C you have to use function pointers Yes. C does not have first-class functions. It doesn't have first-class strings or arrays either. C has primitive data types -- char, int, float, pointer -- that correspond directly to the kinds of things CPUs work with. Again the author of C did not set out to make a general-purpose language for application programmers like us. Languages with first-class functions already existed at the time (Lisp predates C by almost two decades). Functions don't exist at the assembly language level, so while C has functions it does not let you pass them around other than with pointers -- the same way it lets you pass "strings" around. Of course anyone used to using a language like Python or Javascript, which do not intend to model CPUs in a way that minimizes performance cost, will find C frustrating because it leaves it to the programmer to do things like get a pointer to a function and put it into an array. Many modern languages have syntactic sugar so we can pass functions around, which makes C look primitive and clunky by comparison. > I don't see a world where this is the optimal way of doing things I tried to describe that world. You can look at it a couple of ways. C comes close to optimally modeling ISAs, which rely heavily on indirection (pointers) and a small number of primitive data types. Other languages from the same era did that less optimally and we've mostly forgotten them. C also gives programmers just enough expressive power to write code that directly translates to assembly language but hides a large amount of CPU ISA-specific details. Compare how C passes an array of function pointers to trying to do the same thing from Python (to a C API). You probably have some helper functions that can handle the significant mismatch between Python data types and functions (in an interpreted language) to C functions, but if you had to roll that yourself it would look a lot more baroque and fragile than the C version. C abstracts CPU instruction set architectures just enough to make programming an order of magnitude easier without imposing a big penalty. Python, Javascript, and many other higher-level languages abstract and wrap C code to make programming easier as well, but impose significant performance penalties. Sometimes we don't care about or can live with those penalties, sometimes we can't, as in the problem you described in the original post.