Live data from Hacker News

Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

cl.cam.ac.uk

141–150 of 253 posts

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#141
post #86

Earlier quoted context omitted.

I think the article helps to explain why C was able to leverage network effects so well. Neither C nor Unix came out of the gate in a dominating position. Indeed, it's arguably only in the past 20 years that it clearly dominated. Fortran, Pascal, and a bevy of other languages were at times much more widespread and influential. Even today C isn't the most used language. And yet it's influence continues to be outsized.…

C wasn't useless and unsafe at the time it became dominant. It was quite state-of-the-art at the time. We've just learned more about what works well and what doesn't in programming languages since 1978, which is why C is no longer as dominant as it once was.

It was quite state-of-the-art at the time.

Most of the criticisms you hear about C today (type safety, memory safety, no garbage collection) were criticisms that C got when it was first invented.

In fact there are fewer criticisms of C than there used to be: a lot of the early criticism centered around syntax, but the C syntax kind of won, so you don't hear that anymore.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#142
post #66

Earlier quoted context omitted.

When I checked out rust a year ago, I tried to implement three things: - Some OT code. This went ok, but I still have no idea which of the 6 string types I should use for a library like that. I think I ended up settling for Rc > or something, but it still wasn't ideal. Swift, Go and C all each have a canonical string type. - First I tried to make a skip list with performance matching the performance of my C implement…

> This went ok, but I still have no idea which of the 6 string types I should use for a library like that. None of Swift, Go or C have this problem. There are two string types: a string that owns its contents and a string that references its contents. This is the same as in any language that uses smart pointers for resource management. Can you name a string type that you think should be removed, and explain why? > Fi…

> There are two string types: a string that owns its contents and a string that references its contents. This is the same as in any language that uses smart pointers for resource management.

There's String, &str, Cow, Rc and other variants. None is canonical. I spent about 2 hours reading documentation trying to pick the right type to use and I think I ended up with Rc>. But in this instance my strings represent character edits in a document. 90% of the time they're >) }, but encapsulated behind a common string interface. Coincidentally, this is exactly how the canonical string implementation works in obj-c and (I think) swift. Despite having 6 different options maybe the string type I actually want is buried in Cargo. I'm not sure - at this point I was tired and I stopped trying.

To me this is a classic symptom of a language trying to do too much. Having all this choice is great for systems development, but for application-level development I don't want X different string options. You want 1. And I want it to be good. Having lots of options would be fine if the language was more opinionated - "Unless you know what you're doing you should just use String, which is efficient, immutable, copy-on-write and ref counted. Click here (link to advanced section of book) to read about your other options if you want more control over allocations."

> Yes, you can. You can make a one element array and allocate and deallocate manually, just as you do in C. The offset method on pointers allows for arbitrary pointer arithmetic.

Does it? At the time even with unsafe there was no way to directly call malloc. Maybe I just couldn't find it in the docs, or maybe thats changed now. I spent weeks on and off trying to get it working, including reading the rust unsafe nomicon and writing dozens of linked list implementations. I tried out all sorts of weird ways to allocate and initialize the array. I kept thinking of new ideas, only to find out a critical piece of syntax was missing. In the end I could allocate the struct I wanted but discovered it was syntactically impossible to initialize, or something silly like that. And at that point I gave up. Maybe this problem has been fixed since. And maybe if I spent even more time trying I would have figured it out. But I was tired and I had work to do.

> I haven't used Tokio, but couldn't you use a boxed trait?

I don't know what that is. Frankly I'm still confused why Rc didn't work. I got about 6 different answers when I asked the rust subreddit how to fix this. Some people suggested things that also didn't compile. Some people said I should make my object 'static (no thanks). And others said the problem would be fixed when trait impl lands (whatever that is - is that what you're talking about?). This use case is literally the 'hello world' of nodejs code - attach an event handler to an object, interact with local variables each time the event fires. At least as of a year ago the tokio devs clearly thought all network servers only did request/response style interaction. All the examples on their website were either an echo server or an http server. I need streams.

I really want to be able to use rust. But so far my only experience with it has been one of frustration. It seems too immature to replace C as a systems language, and tokio seems too immature to replace Nodejs for network services. Maybe I'll revisit it in a few years, but at this point I'm more hopeful either someone will bolt decent syntax on top of Go a la coffeescript, or that Swift will add language level support for concurrency. (I'd be happy with either async or go's actor model.)

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#143
post #103

Earlier quoted context omitted.

> There's a third kind, which uses indexes into arrays containing the nodes and edges Pointers are still faster. Also with arrays it’s expensive to reduce RAM usage after a lot of nodes were removed. > Can any of these protect against the scenario where a block of memory is freed, allocated again for another purpose, but still accessed through the old dangling pointer? No 100% guarantee, but AFAIR CRT debug heap take…

> Pointers are still faster. Depending on cache effects, indexes might or might not be faster than pointers. With indexes into an array, the nodes or edges will be sequential in memory, which depending on their size and access patterns might increase the cache hit rate. Furthermore, while pointers will always be 8 or 4 bytes, indexes can be as small as 2 or even 1 byte for smaller graphs (reducing structure sizes and…

[deleted]

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#144
post #113
post #5

This is a long paper and the author has 2 main claims: 1) C Language popularity is more to do with cognitive ease of memory addresses as a conceptual model for inspection and change. Author claims memory address mental model overshadows runtime performance . 2) switching to "safe" languages like Java/C#/Rust is not necessary. With no changes/violations to existing C Language specification, a new/different implementat…

C's popularity is due to the fact that it is predictable within certain bounds (single thread or limited concurrency). No GC pauses, no weird runtime crashes due to a strange constructor, no gigantic exception chains, etc. The only languages in the TIOBE index that can even try to make that claim are: C at #2, C++(if you subset it) at #3, Objective-C/Swift(#18/#11), Assembly at #14, Ada at #29, and maybe FORTRAN(#35)…

The fact that there are these other languages with the same properties means that predictability isn't the real reason, right? It's that it also is sparse in its specification and easy to implement a compiler for.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#145
post #5

This is a long paper and the author has 2 main claims: 1) C Language popularity is more to do with cognitive ease of memory addresses as a conceptual model for inspection and change. Author claims memory address mental model overshadows runtime performance . 2) switching to "safe" languages like Java/C#/Rust is not necessary. With no changes/violations to existing C Language specification, a new/different implementat…

> mental ease I'm a long time C programmer, and I was struck by how clumsy and error-prone any manipulation of C strings turns into. It's really hard to look at a mass of strlen/strcpy/memcpy/etc. and see just what is happening. Contrast that with, say, BASIC or Javascript, where string manipulation is easy, natural, and bug-free. I'm going to disagree about the mental ease of programming in C, and a large part of th…

I think the mental model isn't the issue, it's that the C Standard Library is very anemic. When writing a C application either you're using a big library like APR or GLib or you're rolling your own, and since rolling your own is a pretty big, complicated, and fraught proposition it's no surprise bugs creep in. Furthermore you can't really interop with other libraries if they also rolled their own data structures because theirs probably aren't like yours. Consequently libraries tend not to do that at all, setting for things like NULL-terminated lists and special, opaque data structures.

I feel like if someone wants to throw C a life vest, they should start with a meaningful standard library that engineers can build on to provide functionality we pretty much consider standard now (HTTP libraries, JSON libraries, database libraries) with a consistent interface.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#146

Earlier quoted context omitted.

That particular problem (strlen/strcpy/memcpy) comes from the problems of the standard library string functions. It can be solved by creating your own string library. Then string manipulation is easy.

That falls over as soon as you integrate with anybody else's C code, including the operating system APIs, and with C string literals :-( If it was as easy as you say, it would have happened. And heaven knows I wrote my own string packages, one after the other, and so did everyone else. I eventually abandoned all of them. C's abstraction abilities are simply not good enough to do a decent string encapsulation.

shrug It doesn't fall over. I've done it, the openBSD team has done it. DJB has done it. Maybe something is wrong with your implementation that I can help you with?

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#147

Earlier quoted context omitted.

That falls over as soon as you integrate with anybody else's C code, including the operating system APIs, and with C string literals :-( If it was as easy as you say, it would have happened. And heaven knows I wrote my own string packages, one after the other, and so did everyone else. I eventually abandoned all of them. C's abstraction abilities are simply not good enough to do a decent string encapsulation.

shrug It doesn't fall over. I've done it, the openBSD team has done it. DJB has done it. Maybe something is wrong with your implementation that I can help you with?

I'm curious. Got links?

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#148

Earlier quoted context omitted.

That falls over as soon as you integrate with anybody else's C code, including the operating system APIs, and with C string literals :-( If it was as easy as you say, it would have happened. And heaven knows I wrote my own string packages, one after the other, and so did everyone else. I eventually abandoned all of them. C's abstraction abilities are simply not good enough to do a decent string encapsulation.

shrug It doesn't fall over. I've done it, the openBSD team has done it. DJB has done it. Maybe something is wrong with your implementation that I can help you with?

[deleted]

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#149
post #129

Earlier quoted context omitted.

> Even if I manage to extract an unsafe pointer from that Rust collection, It's easy, just get the & or &mut to the value (as if you were acessing it), and cast it to respectively * const or * mut. > I don’t know for how long will it work. For C++ collections, iterator invalidation rules tell me that. It's the same in Rust. Whenever the iterator would be invalidated in C++, the pointer you stashed above might point t…

> keeping the values in a Box > for keeping a value in more than one collection would be to use a Rc Indeed, both methods are simple and elegant ways to approach the problems. The bad thing with both of them is performance. Box means when I need to iterate through all values in a collection, I’ll get random memory access for each item. Rc is even worse, not only it’s RAM read latency per item, also ref.counting overh…

> also ref.counting overhead per item (AFAIK even when reading stuff).

That's the beauty of the borrow checker: no, there's no reference counting overhead when reading stuff. The borrow checker guarantees that the reference you used to access the value won't go away until you're done with it, so it doesn't have to increment the reference counter.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#150

Earlier quoted context omitted.

There is no inherent benefit in C that, for example, a somewhat modified version of Pascal or Algol wouldn't have inherited. I happen to like C and think it has a lot going for it, but you're definitely right about this. The original Mac OS was written in Pascal (and assembly), not C. And Turbo Pascal was deservedly popular for a good while. In an alternate universe, Pascal rather than C could be the incumbent legacy…

Pascal suffered because its standard was woefully incomplete, and every implementation added mutually incompatible proprietary extensions. Turbo Pascal and all the TP developed code died when DOS died.

You can revive Turbo Pascal code with Free Pascal. Here's a port guide:

https://www.freepascal.org/port.var

Post reply on HN