[HN Gopher] Some were meant for C [pdf]
___________________________________________________________________
Some were meant for C [pdf]
Author : craigkerstiens
Score : 111 points
Date : 2023-06-21 17:19 UTC (5 hours ago)
(HTM) web link (www.humprog.org)
(TXT) w3m dump (www.humprog.org)
| jcranmer wrote:
| I think the main weakness of this paper is that it doesn't really
| address why C is used in lieu of other "better-C" non-managed
| languages, such as C++, D, Nim, Rust, or Zig--it's almost
| entirely focused on the idea that the competitors to C are
| inherently managed languages, framing the question essentially as
| a "why C instead of Java?" which is a frustrating approach when
| you're asking "why not <language which is not Java in the same
| way C is not Java>?"
| faiD9Eet wrote:
| I would like to attempt an explanation. It boils down to
| learning complexity.
|
| > why C is used in lieu of other "better-C" non-managed
| languages, such as C++, D, Nim, Rust, or Zig
|
| I am a system admin. I do not earn my income writing code and
| therefore spend at most a few hours a week programming. I've
| spent about 1000 hours writing C code in my life. About 200
| hours of Golang. Years of Posix Shell. Years of Perl 5. I've
| had a little exposure to Java and C++ and Haskell. I have read
| a few examples of Rust.
|
| C++ has a higher complexity than C. C++'s syntax is more
| powerful, it has an additional paradigm (the C++ template
| system), and if you mix in QT you have one more paradigm (QT
| preprocessor), it has a very wide ranging standard lib (which
| data structure do you use for lists? vector, dequeue, ...)
| augmented by QT and augmented by boost. C++ is huge. There is
| no way I will learn that in my professional life, I simply do
| not have enough hours of training left. C++ is not a valid
| successor to C, because its complexity hinders acquiring the
| language. Rust suffers the same complexity as C++. I will not
| have enough hours on my learning schedule to acquire a
| proficient level of Rust.
|
| Golang is nice for me personally. The book "The Golang
| programming language" is only double the size of "The C
| programming language", which makes them comparable in
| complexity. I get stuff in Golang done faster than in C since I
| find debugging easier.
|
| I have neither used NIM, nor D, nor Zig. All I can tell you is
| that C is sexy because the language is small and therefore one
| can acquire it in a life time -- without being a full time
| programmer.
| throwawaymaths wrote:
| 2017, so zig was very much a baby. Rust was still young.
| Joel_Mckay wrote:
| The historical answer was fairly simple:
|
| 1. C was slightly more understandable than existing options at
| the time
|
| 2. The compiled objects could be manually verified/debugged
| with relative ease
|
| 3. There was no mystery/interpretation between the runtime and
| the hardware, but this isn't technically true anymore for many
| platforms.
|
| 4. The simplified environment demands simplified structural
| design. Try anything fancy, and C can be very unforgiving to
| the uninitiated (easier to write bad code). Do a one liner in
| high level languages instead =)
|
| 5. Due to the well-defined simpler syntax of standard C89, the
| GNU groups were able to bring opensource/free compilers to many
| new platforms. ARM popularity, Linux, android, and most IT
| infrastructure owe their existence to these compilers... even
| if it was just bootstrapping the new environment.
|
| 6. All languages have use-case specific tradeoffs. I have
| worked with over 54 different languages, and have observed the
| following: if your code still builds and runs on a 5 year old
| OS, than it will likely not need refactored for another 5
| years.
|
| As Intel begins to deprecate x86 legacy features, there will be
| a lot of drivers that will need rewritten.
|
| Have a wonderful day =)
| anacrolix wrote:
| The Lindy Effect for programming languages.
| arghwhat wrote:
| I like Rust, but I wouldn't categorize it as a "better-C". It
| is a whole different world, and some things work well in Rust
| but not in C, and vice versa. Many things are flat out
| uncomfortable to express in Rust, and the number of times you
| need to bail out and just Rc<RefCell<T>> or Arc<Mutex<T>>
| random things is a bit high.
|
| Interacting with anything but basic C is also horrible,
| requiring significant engineering efforts to hide the glue in a
| binding crate when possible, and sometimes it just doesn't work
| out. Many C libraries are heavy on linked lists of linked lists
| with their own lifetimes, and that's Rust's kryptonite.
|
| Zig is definitely a "better-C", but also young and not nearly
| as widely adopted.
| jcranmer wrote:
| > the number of times you need to bail out and just
| Rc<RefCell<Box<T>>> or Arc<Mutex<Box<T>>> random things is a
| bit high.
|
| People keep saying this, but in all the Rust I've written,
| I've never needed to reach for this. Indeed, from what I've
| seen in the community, this kind of nesting is often a code
| smell that maybe you should think about the architecture of
| your system a bit more.
|
| > Many C libraries are heavy on linked lists of linked lists
| with their own lifetimes, and that's Rust's kryptonite.
|
| One article that was on here earlier today discussed what's
| the usual Rust salve to this problem, handles:
| https://news.ycombinator.com/item?id=36419739. That is to
| say, instead of saying that everything is a pointer, instead
| make an arena (an array) of allocations and use indexes into
| that array instead. This is the solution in petgraph, for
| example.
| arghwhat wrote:
| The issue is not just architecture, it is also what you
| need to interact with.
|
| In my experience, if you're making practical applications
| that interact with the outside world where this is _not_
| the case, it 's because you're using libraries made of the
| broken dreams of it's authors, giving it's best to hide all
| the pain from you.
|
| I tend to end up writing that code for system integration,
| so I don't get to see a world of pure type system bliss.
|
| > That is to say, instead of saying that everything is a
| pointer, instead make an arena (an array) of allocations
| and use indexes into that array instead
|
| An index into an arena is the very definition of a pointer,
| but I get the idea.
|
| Unfortunately, you cannot redefine how to deal with types
| defined and allocated by C, nor how C should interpret and
| deference types allocated by Rust that must integrate into
| C-esque designs such as being a node in a C-defined linked
| list.
|
| Teaching existing C to be anything else is not an option,
| but Rust is not - and is not meant to be - good a acting
| like C. The glue is not pretty to neither C nor Rust devs.
|
| Zig is a middle ground that gives up some things from Rust
| in order to let C paradigms still work, while still having
| improvements.
| steveklabnik wrote:
| (You'd never want the box in either of those situations, as
| the data is already boxed by the Arc or Rc)
| arghwhat wrote:
| Yeah got a bit carried away, and was stuck in C-ffi land
| where things get weird - Box::leak, ManualDrop, PhantomPin
| wrappers, all that.
| quelsolaar wrote:
| C is better because it doesn't try to program for you, it isn't
| clever, convenient, or have any ideas about how you structure
| or solve a particular problem. It gives you basic functionality
| and then gets out of your hair and lets you ge on with
| programming without making a grand statement about computer
| science. For people who actually like to program and don't want
| the language to do it for you that is pretty attractive.
|
| It also turns out that if you remove all the fancy abstraction
| and write everything out, the code becomes very maintainable
| and easy to manage. The fact that its about as portable as a
| program can be helps. I find that most people don't want to
| write C, but almost everyone is pretty happy interacting with C
| code written by others, because its simple, fast, portable,
| easy to integrate, and bind to other languages, and most non-C
| programmers can read it and have a rough idea of what is going
| on.
| bitwize wrote:
| I think it's high time to bury the myth of the "bondage and
| discipline language".
|
| Study after study has shown that, comparing development of
| the same application in C vs. a language with a very strong
| type system such as Ada, the application in the language with
| the very strong type system costs less to develop and has far
| fewer errors.
|
| The fact that C "gets out of your hair", i.e., doesn't
| provide checking for certain kinds of correctness, is an
| anti-feature.
| steveklabnik wrote:
| I do think you've identified a significant rift between those
| that prefer C and those who do not. I think you're being
| downvoted for the value judgement you're injecting, though.
|
| > gets out of your hair and lets you ge on with programming
|
| This is the divergence, I think. For me, the method in which
| c "gets out of my hair" means that more burden is placed on
| me, the developer. Which means I have to work more slowly,
| cautiously, and remember things that a good type system could
| have been checking for me. And the lack of features means I
| spend time working around that lack rather than getting real
| work done.
|
| I suspect these preferences are irreconcilable.
| hudon wrote:
| How is the C type system slowing you down? I thought the
| complaints around C productivity were around memory
| management and low-level APIs (both of which can be
| mitigated using libraries: you can "abstract away" these
| problems and stay in C).
| Hirrolot wrote:
| The need to express polymorphism manually in C, the need
| to remember to check errors returned by functions
| (instead of the monadic style of computation), the need
| to define closure's environment structures (those that
| are passed via something like `void *arg`), etc.
|
| All these things are pretty tedious. And all these things
| are what other languages are doing under the hood. The
| difference is that C gives you a choice of _how_ to do
| (more) things; other languages do not.
| steveklabnik wrote:
| Like Walter Bright, I would love to have some sort of
| "span" or "slice" primitive. I would love language level
| tagged unions rather than writing them out each time.
| Pattern matching isn't _exactly_ a type system feature,
| but relies on it to work, and would make those more
| useful. The lack of destructors means a lot of manual
| handling of errors. The lack of generics makes it
| difficult to write generic data structures without losing
| type safety. There's no _real_ const.
|
| There are ways to do all of these things, but they're
| more manual, more error prone, and get in the way of
| doing the actual work you're trying to do.
| ho_schi wrote:
| That describes the basic feature set of C++ very well.
|
| People complain about C++ that it can do much more. Yea.
| But there is no need to use template meta-programming,
| multiple inheritance and other special features. Actually
| I think programmers shouldn't use them in productive
| code.
|
| Recently some projects switched the compiler to 'g++' and
| use the basic subset of C++. Makes sense? Maybe Herb
| Sutters "C++2" will evolve, main features are safety and
| simplicity.
|
| I'm fine with both C and C++. They do a good job.
| Address-Sanitizer is a game changer! But I want more.
| steveklabnik wrote:
| Yeah, kinda:
|
| > I would love to have some sort of "span" or "slice"
| primitive.
|
| This was recently added!
|
| > I would love language level tagged unions rather than
| writing them out each time.
|
| There is std::variant, but it's not as nice as a language
| provided solution, both to use and the generated code.
|
| > Pattern matching isn't exactly a type system feature,
| but relies on it to work, and would make those more
| useful.
|
| This is not in C++, and my understanding is that the
| proposals are nowhere near close.
|
| > The lack of destructors means a lot of manual handling
| of errors.
|
| The huge C++ feature. Yes, a clear win. I think a version
| of RAII closer to Rust than to C++ would make more sense
| for C, though.
|
| > The lack of generics makes it difficult to write
| generic data structures without losing type safety.
|
| Yep, absolutely.
|
| > There's no real const.
|
| There isn't in C++ either.
| pornel wrote:
| Inability to specify non-nullable pointers, or truly
| immutable data, or ownership, or thread-safety of objects
| on the type system level means I have to remember these
| unwritten invariants in every case, and/or code
| defensively.
|
| Libraries can't specify these things in a compiler-
| enforced way either, so they remain "RTFM" problems for
| programmers to deal with manually.
| retrac wrote:
| Sum types. In C they can be constructed out of unions and
| structs with lots of checks (and possibility for error)
| but it's painful.
|
| There's really no excuse for C not having them, other
| than C being designed before algebraic types became
| mainstream. They make certain programming errors
| impossible, particularly with null values and misusing a
| union with the wrong type. It is possible to compile them
| as a zero-cost abstraction, and essentially all recent
| languages aimed at the same domain as C (Rust, D, Go,
| Zig, Hare, etc.) include them.
| anacrolix wrote:
| Go goes NOT have sum types. I'm not sure Zig technically
| does, but is close enough.
| quelsolaar wrote:
| > I do think you've identified a significant rift between
| those that prefer C and those who do not.
|
| I agree. I think the article is very right in identifying
| that C developers look at programming differently. I think
| that is a good thing. Even as a Die-Hard C programmer, I
| celebrate that people use other languages and especially
| that people are developing new languages like Rust, Odin,
| Zig and so on. I don't think it wrong for someone to reject
| C, if its not right for them. Do what works for you. I do
| think that given Cs massive success, people should perhaps
| be a bit more interested to figure out why, instead of just
| dismissing it so fast.
| comfypotato wrote:
| Your comments on this thread up to this point sound like
| a religious fanatic.
|
| I greatly enjoyed reading.
|
| Goes to show why it's called "The C Religion".
| PartiallyTyped wrote:
| > It also turns out that if you remove all the fancy
| abstraction and write everything out, the code becomes very
| maintainable and easy to manage.
|
| I was with you on everything until this part. I just don't
| see how reducing soundness via a weaker type system, and
| needing to explicitly manage memory vs e.g. Rust, uniq_ptr,
| shared_ptr, and so on makes things easier to maintain. I also
| don't see how absence of generics helps here either.
| westoque wrote:
| this.
|
| properly made abstractions are actually more maintainable
| and easier to manage. for ex, take anybody learning
| programming about writing to a file, if you write your code
| using ruby, it would be a lot safer and maintainable than
| the C counterpart even though the latter is more powerful.
| rudedogg wrote:
| Abstractions hide details, and you'll likely need to
| interact with something the abstraction hides eventually.
| So then you end up doing one of two things:
|
| 1. Learning every detail of the abstraction and the thing
| it's abstracting, fighting it until you persevere and get
| it to do what you want
|
| 2. Write something from scratch that does exactly what
| you need
|
| Going the #2 route from the start isn't such a bad idea,
| and has a lot of advantages IMO.
|
| The hard thing about all this is that abstractions are
| beautiful at first. It's not until you're far into a
| project, or doing something _unusual_ that it all falls
| apart.
| Conscat wrote:
| Uh oh I wrote C code and just multiplied meters by yards
| and now the program exploded help
| jcranmer wrote:
| > C is better because it doesn't try to program for you, it
| isn't clever, convenient, or have any ideas about how you
| structure or solve a particular problem.
|
| Oh, C very much does have ideas. One of the big problems I
| have with C is that it has a surprisingly limited feature set
| that makes it difficult or impossible to express certain
| programming styles. Want to describe a function that returns
| multiple values? Well, you can't really do that (especially
| if you want this to mean "use two registers"). How about
| using unwind to express exceptional control flow? Can't do
| that either. Or if you want a function with multiple entry
| points? Or coroutines? C's fundamental inability to express
| certain kinds of control flow [1] greatly limit your ability
| to structure your code in ways that might make the code
| clearer.
|
| > It also turns out that if you remove all the fancy
| abstraction and write everything out, the code becomes very
| maintainable and easy to manage.
|
| I think experience has shown that _this is not the case_. The
| closest kernel of truth you might find is that if writing
| code requires a certain amount of tedium, that tends to limit
| the scale you can grow a codebase to, and size is one of the
| largest drivers of complexity. While it 's definitely the
| case that abstraction can decrease maintainability, it is a
| mistake to think that it necessarily does so. Indeed,
| abstraction is often necessary to make code more
| maintainable. For example, when I design APIs, I think very
| hard about how to design it in such a way that it's
| impossible to misuse the API. So I make my APIs distinguish
| between UTF-8 strings and Latin-1 strings, so you can't be
| confused as to what's in them, or even distinguish between a
| row number and a column number.
|
| The other thing to bring up is that we know quite well that
| humans are pretty bad at doing tedious, repetitive tasks with
| high accuracy. And computers are pretty good at that! What
| this suggests is that languages should be designed so that
| things that are tedious and repetitive--such as propagating
| errors up a stack, or cleaning up resources on failure--can
| be done by the compiler and not the programmer. As we've seen
| with things like gotofail, C is a language which lacks
| features that enable work to be pushed onto the compiler and
| not the programmer, and code written in C suffers as a result
| of that.
|
| [1] And there's even more exotic kinds that I could get into
| --this is merely the list of features available in languages
| you've probably heard of, maybe even used!
| JohnFen wrote:
| > C is better because it doesn't try to program for you, it
| isn't clever, convenient, or have any ideas about how you
| structure or solve a particular problem.
|
| This is much of why I prefer to use C (well, I actually
| prefer to use C++-as-a-better-C, but since I'll omit almost
| all of of what C++ brings, it's still C for all intents and
| purposes).
|
| Other reasons I prefer C include producing small executables
| (and, more importantly, being able to effectively control
| executable size), that it is the most portable language (in
| the sense that there are C compilers for just about every
| computer platform in existence), and it is both readable and
| concise.
| jjnoakes wrote:
| > C is better because it doesn't try to program for you, it
| isn't clever, convenient, or have any ideas about how you
| structure or solve a particular problem
|
| Why is that better though? I personally appreciate it when
| cleverness and convenience make my life easier, my programs
| less buggy and less likely to end up in a CVE, or point me
| toward better structure.
|
| > It also turns out that if you remove all the fancy
| abstraction and write everything out, the code becomes very
| maintainable and easy to manage
|
| History shows that this isn't true though, not in all cases.
| quelsolaar wrote:
| > Why is that better though?
|
| Some people think so. Hence some where meant for C.
|
| > History shows that this isn't true though, not in all
| cases
|
| Not in all cases? I had no idea it was possible to write
| bad code in C, I must immediately switch to language where
| all code is always perfect no matter what the programmer
| does.
|
| History does show that most of the largest, longest
| running, most depended on open source projects like Linux,
| Apache, Git, MySQL, CPyton, OpenSSL, Gcc, Curl are written
| in C, so its hard to argue that the language isn't
| maintainable.
| PartiallyTyped wrote:
| The oxidizing of the Linux kernel has already begun, many
| of the core-tools have been rewritten in rust, large
| segments of firefox are written in rust, chromium is
| getting oxidized [1].
|
| I don't think this is a sound argument because of
| survivorship bias.
|
| [1] https://security.googleblog.com/2023/01/supporting-
| use-of-ru...
| quelsolaar wrote:
| Funny that you would bring up survivor bias. I tend to
| think the oposit. If C is so bad, why does only C
| programs survive? Is issues are more visible, because it
| is so success full, and so much of the world uses C.
|
| One thing i have considered is the importance of the "fun
| factor" a language. C is seen as a "Fun" language to
| program by many C programmers, where as Rust is seen more
| as the "correct" and "responsible" language to use by
| Rust users. Are Rust developers going to find enough joy
| in maintaining large open source projects for decades?
| Time will tell.
| placesalt wrote:
| >> History does show that most of the largest, longest
| running, most depended on open source projects like
| Linux, Apache, Git, MySQL, CPyton, OpenSSL, Gcc, Curl are
| written in C, so its hard to argue that the language
| isn't maintainable.
|
| > I don't think this is a sound argument because of
| survivorship bias.
|
| The argument is that those projects prove large C
| programs/systems are maintainable. 'Survivorship bias'
| doesn't enter into it; they are large and have been well
| maintained.
|
| Edit: I remember a time when "correlation is not
| causation" was the endlessly-repeated phrase. La plus ca
| change, la plus c'est la meme.
| PartiallyTyped wrote:
| > The argument is that those projects prove large C
| programs/systems are maintainable. 'Survivorship bias'
| doesn't enter into it; they are large and have been well
| maintained.
|
| It shows that large C programs / systems can be
| maintainable. My claim is that the projects became
| maintainable out of necessity, that is, despite C, not
| because of C.
|
| Had C been opinioned around certain things and enforced
| maintainability out of the box to some degree, then and
| only then you could claim that C is maintainable, because
| this speaks for the general case.
|
| On the other hand, C is not opinionated about things, so
| you must enforce maintainability and high standards to
| get around all the footguns. This is what makes it
| unwieldy and why Rust is so loved.
|
| This plays greatly into the survivorship bias. You claim
| that C is maintainable because of all the large C
| projects that were forced to become maintainable. Had
| they not been maintainable they would not be as large or
| survive the test of time, and thus you wouldn't be able
| to cite them as evidence to your claim.
|
| In contrast, the oxidification of a lot of software, and
| the rise of "better C"s that have picked up steam shows
| that there are languages that are more maintainable and
| arguably better approaches for most software as they
| avoid all the footguns.
|
| NASA has strict requirements to make it maintainable,
| e.g. no heap alloc, so when you force yourself to not use
| language features, it appears that those features make
| things worse for you.
| PartiallyTyped wrote:
| +5 to -2, something is sus.
| coldtea wrote:
| > _Why is that better though?_
|
| Doesn't have to be better, preferable is enough. Plus, it
| is more flexible...
| em-bee wrote:
| i haven't come across a single language that would limit me
| in how i structure my code. that is, i didn't feel limited.
| whether it was python, ruby, smalltalk or even lisp. heck,
| once i translated a program from pike to common lisp. the
| structure of both programs was identical despite everyone
| claiming that lisp is so much different. it can be, but it
| doesn't force you to be.
|
| _most non-C programmers can read it and have a rough idea of
| what is going on_
|
| that's because most programmers can read most other languages
| and have an idea what's going on. that's not at all a special
| feature of C.
| qsantos wrote:
| The crux of the argument of this article seems to be that C
| allows working directly with raw memory, which is necessary for
| some low-level tasks, such as communication with memory-mapped
| devices. This is not possible in pure managed language, due to
| the additional level of abstraction.
|
| However, the author themselves state that this is not something
| that implies that undefined behavior are unavoidable when working
| close to the metal: In fact, the very
| "unsafety" of C is based on an unfortunate conflation of the
| language itself with how it is implemented. Working from first
| principles, it is not hard to imagine a safe C.13 As
| Krishnamurthi and Felleisen [1999] elaborated, safety is about
| catching errors immediately and cleanly rather than gradually and
| corruptingly
|
| I would say that, what they are describing is essentially what
| Rust has achieved, or at least what it is meant to do.
| quelsolaar wrote:
| C, is high level language that happens to map really well to
| hardware. Much of UB is UB simply because it difficult to
| effectively detect when something goes in to a state of UB.
| Writing to a memory address can be done in one instruction, but
| figuring out if that address is legal to write to is a slow and
| complicated process. The C standard let an implementation
| ignore that problem, but it is also does not stopping the
| implementation from making sure the address is valid before
| writing to it. Almost no one tries to make such an
| implementation, because the users have decided they would
| rather have speed, but anyone can write a ISO compliant
| implementation without any UB if that's what they want.
| bandrami wrote:
| It maps well to hardware from the 1970s and 1980s. It has
| very little to do with modern hardware, and for that matter
| modern hardware does some somersaults to present an interface
| that C "expects".
| AlexAndScripts wrote:
| What are the specific differences?
| throwaway17_17 wrote:
| The easiest read on this topic is Chris Chisnall's 'C is
| not a Low Level Language' article [1]. It is a good read
| in general and not all that long. It addresses vectors,
| out-of-order execution, pipelining, and plenty of other
| topics along the way.
|
| 1 - https://dl.acm.org/doi/10.1145/3212477.3212479
| quelsolaar wrote:
| Modern hardware is designed to map to C rather than the
| other way around. Turns out people want to buy hardware
| that can run existing software.
| quackulus wrote:
| Any good docs on memory and data structures for c?
| steveklabnik wrote:
| While I don't fully disagree with you, I think the author would
| disagree. This line of argument is also repeated in recent C++
| standards papers around "safety," that is, this argument is
| explicitly saying "memory safety != safety, and safety is more
| important, and therefore focus on memory safety is bad for
| safety."
|
| I have two responses to this that aren't "back on script."
|
| > it is not hard to imagine
|
| (from your quote)
|
| Sure, we can imagine this language, but it does not exist. Yes
| in theory maybe if we all did what the author said, C could be
| that language, but it is simply not today. When people say "C"
| they mean the C that actually exists, not an alternative
| implementation that would technically conform to the standard.
| Pushes have been made in this direction a number of times, from
| a number of different people, yet the market has spoken.
|
| Second,
|
| > Consider unchecked array accesses. Nowhere does C define that
| array accesses are unchecked. It just happens that
| implementations don't check them. This is an implementation
| norm, not a fact of the language.
|
| This is just factually incorrect. Let's examine both C89:
| https://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf and
| C99: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
|
| > J.2 Undefined behavior
|
| > An array subscript is out of range, even if an object is
| apparently accessible with the given subscript (as in the
| lvalue expression a[1][7] given the declaration int a[4][5])
| (6.5.6).
|
| It is literally defined as undefined behavior. While sure, that
| does mean a particular compiler could implement and document
| semantics for this, it's by definition not portable, because it
| is stated as such by the standard.
| avgcorrection wrote:
| Sentimental.
| diego_sandoval wrote:
| I have a trivial, superficial gripe with modern languages. I hate
| this syntax: let variable_name : type = value;
|
| I find it extremely ugly.
|
| I know that people here have disdain for discussions about syntax
| [1], and I know that once compiled, the specific syntax doesn't
| matter that much.
|
| But I think that language aesthetics _do_ matter.
|
| People say that languages are "just tools", and the output
| quality is all that matters. But, personally, I would want the
| tool that I'm going to be spending a significant amount of time
| working with to be beautiful and feel good.
|
| And that's one point where I consider C to be superior:
| aesthetics. If I start a hobby project, I may start in C, because
| programming in it makes me feel good, even if it's unsafe.
|
| I'm not a language expert, so I don't know if there are good
| technical reasons for this modern syntax to have replaced C-style
| initialization, but I think there must be some way to avoid using
| this modern syntax without losing whatever feature is made
| possible by it.
|
| So, my point is: We shouldn't discard aesthetic considerations so
| lightly. Languages are not "just [ugly] tools", they can be a
| medium of artistic expression to some people.
|
| [1] https://wiki.c2.com/?WadlersLaw
| fasterik wrote:
| I'm with you until type inference comes into play. For example,
| I find the proliferation of "auto" in C++ code far uglier than
| Go's "foo := expression" syntax where most of the time you
| don't even need to specify a type. Since most modern languages
| include type inference, I can see why they are moving away from
| C-like syntax, even though I still prefer it in most cases.
| justinpombrio wrote:
| I agree that syntax matters, but I like that syntax so much
| better. Here are some reasons:
|
| - The variable name comes before the type. Thus if the type
| name is large it makes it difficult to scan for the variable.
| This isn't _too_ bad for `let`s in a language like C, but my
| day job is C++ right now and the fact that the return type for
| functions comes first is _terrible_. It 's inevitably enormous,
| so it makes it bloody impossible to quickly see what the damn
| function is called.
|
| - The keyword `let` is first, so with syntax highlighting you
| can easily visually see the structure of the code, and which
| lines declare variables vs. call functions.
|
| Are there reasons to like the C style type
| variable = value;
|
| besides familiarity, and it being slightly shorter?
| steveklabnik wrote:
| There are good technical reasons. That said, I don't expect
| them to be persuasive, but the main reason for doing so is
| that:
|
| 1. It doesn't require as much context to parse, making tooling
| easier.
|
| 2. It plays nicer with type inference or deduction.
|
| These reasons generally trump aesthetics for new language
| developers, and so I wouldn't expect to be seeing the C style
| in newer languages. Also, not everyone agrees aesthetically; I
| am the polar opposite of you.
| jjice wrote:
| I don't think that more modern variable declaration syntax is
| used because it allows for other things to be expressed
| syntactically (although maybe it does, like for type
| inference), but I think a lot of us just think it _does_ look
| better. I don't mind the C and friends type
| variable_name = value;
|
| style, but I do like the type coming afterwards. I don't feel
| like there's a tradeoff, I think it's just better across the
| board, and I assume a lot of people are in that boat as well
| due to its popularity.
| abnercoimbre wrote:
| I appreciate this kind of discussion. It's important to note C
| programmers these days effectively avoid the inherent risks of
| unsafety by deploying solid memory strategies.
|
| For example (self-plug incoming) we're hosting a workshop this
| summer [0] teaching people to replace a rat's nest of mallocs and
| frees with an arena-based memory allocator.
|
| These sorts of techniques eliminate the common memory bugs. We
| don't do C programming the way we did back in the 80's and 90's.
|
| [0] https://handmadecities.com/boston
| Kokichi wrote:
| Nice plug! Just signed up
| chubot wrote:
| Arenas were pervasively used in the 80s, 90s, 2000s, ... and
| are still widely used
|
| Using Malloc and free in the naive way was the exception, not
| the rule
|
| They can be the cause of memory safety problems in some cases,
| as well as a partial solution in others
| abnercoimbre wrote:
| This is at odds with my understanding of how C programming
| was (typically) done. We might also be defining arena usage
| differently - that's one way I can reconcile our mismatched
| outlooks.
| jakeinspace wrote:
| Or better yet, don't use dynamic allocation at all! Very happy
| when I'm on a firmware/embedded project with no dynamic
| allocation, it makes C halfway enjoyable... though extremely
| boring.
| saboot wrote:
| Very interested to hear more, will be registering virtually!
| [deleted]
| yoyohello13 wrote:
| Wow! I'm really interested in the Boston event. I'm a little
| afraid I may not be experienced enough though. How master are
| we talking with these masterclasses?
| abnercoimbre wrote:
| If you are comfortable programming in any systems language
| and not a _complete_ beginner, this conference is a legit
| opportunity for growth (and mentorship.) There is no elitism
| or judgment here--imo you shouldn 't miss out!
| shrimp_emoji wrote:
| What is "solid memory"? Is that what I call "contiguous
| memory"? (Allocating a big block and doing all your memory
| stuff in that one block, using metadata to know how much of the
| block is "free"?)
| jjnoakes wrote:
| I'd be curious if there were any studies done on how much
| effect this kind of approach has on the number or severity of
| bugs or security issues in a code base.
| steveklabnik wrote:
| (2017)
|
| This always gets 0 comments or hundreds of comments. Some
| previous ones with more than a handful of comments:
|
| * https://news.ycombinator.com/item?id=34640233
|
| * https://news.ycombinator.com/item?id=26300199
|
| * https://news.ycombinator.com/item?id=19736214
|
| * https://news.ycombinator.com/item?id=15179188
| Joker_vD wrote:
| Some of those comments are pure hilarity: "C got popular
| because it turned out to be ideally suited for DOS. C could
| deal with near/far pointers. No other language could". Yes, C
| was very good at having two (or even three, "huge" being fully-
| normalized far pointers) completely differently sized kinds of
| pointers, without any proprietary extensions, absolutely, and
| it caused no problems whatsoever because C memory model indeed
| presupposes a segmented address space.
| tedunangst wrote:
| Escaped the dupe detector because four months ago there was an
| extra slash in the url.
| booleandilemma wrote:
| The article that introduced me to "Priest with Balloons", by Tiny
| Ruins.
|
| Based on a true story:
| https://en.wikipedia.org/wiki/Adelir_Ant%C3%B4nio_de_Carli
___________________________________________________________________
(page generated 2023-06-21 23:00 UTC)