1. 1

    This may be pedantic, but I actually think it’s worth pointing out that this is part of the reason why it’s recommended not to add content to a submission in most cases.

    The actual solution to this in APL is +/ι36 (i.e., for the sequence of numbers from ⎕IO to 36 (inclusive), reduce it with +.) Using ¨ (map) will not get you the result you are interested in.

    All the best,

    -HG

    1. 1

      The code I posted works in the interpreter I was using, but yours gives a value error.

      Yours,

      asthasr

    1. 1

      @hwayne, I love your article. I have two recommendations for you:

      1. If you’re ever on Linux again and you’re looking for intuitive unicode input, look into XCompose. It makes typing unicode characters dramatically better.
      2. If you found the above really tempting, I have great news! Someone effectively made a compatibility layer between AHK and Compose. So you can use the same Compose configuration for Windows as you might use for linux, and have the same style of phenomenally-intuitive input!

      AHK is incredibly powerful. And being able to use Compose on Windows makes it dramatically more bearable. :)

      Tangentially related: I love all of your work, particularly on formal methods. If you ever take a look at frama-c, I would love to chat with someone about it!

      All the best,

      -HG

      1. 1

        This looks like a lovely introduction to list-oriented programming in Java. Thank you for sharing!

        I have a nitpick for you: RO is not a mineral, or something that you inject into water. It’s a process. Reverse Osmosis, to be precise. It’s technically not a version of filtration (because of how that term is defined), but to the lay person, referring to it as a filtering process is not too far from accurate.

        I recognize this is definitely a small thing overall, but when a speaker/author uses a vehicle to demonstrate their point, I always find it really distracting if the vehicle experiences mechanical difficulties.

        1. 3

          A more interesting question is, does the test code shown in the article (comparison of an uninitialized value to itself) invoke undefined behavior?

          1. 1

            yes it does. in this case it’s dereferencing an uninitialized pointer. if we would make the array global/static it would be dereferencing a null pointer.

            1. 1

              This is not correct. Uninitialized static arrays have every element initialized to zero, it’s fine to access any element of them: http://port70.net/~nsz/c/c99/n1256.html#6.7.8p10

              10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then: …

              • if it is an aggregate, every member is initialized (recursively) according to these rules;

              and furthermore

              21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

              Aggregate means struct or array (6.2.5, http://port70.net/~nsz/c/c99/n1256.html#6.2.5p21):

              21 Arithmetic types and pointer types are collectively called scalar types. Array and structure types are collectively called aggregate types.

              1. 3

                The example code shows a non-static (automatic) array with a declaration and no initializer. You’ll note that the sections you quoted refer to what happens when an array (or other aggregate) has fewer items specified in their initializer than the aggregate has members. In this case, there is no initializer. Indeed, this is undefined behavior.

                All the best,

                -HG

                1. 1

                  You appear to only have read the 2nd quote in my comment. Here’s the first one again:

                  If an object that has static storage duration is not initialized explicitly, then: …

                  • if it is an aggregate, every member is initialized (recursively) according to these rules;

                  I agree this UB for an array with automatic storage, though.

                  1. 1

                    @jyn514, the array in the example code is not declared static.

                2. 2

                  I stand corrected. in the case that the array has static duration, all elements are indeed initialized to zero. thank you.

                  edit: and my whole sentence is wrong. a, the pointer to the head of the array is actually initialized, it is only the array elements that aren’t initialized in the case of automatic duration. so the UB is caused by using the elements and not by dereferencing.

                3. 1

                  It has nothing to do with pointers. I’m talking about the uninitialized memory. Would the following code invoke UB ?

                  int x;
                  if (x == x)
                      ...
                  

                  I do not master the definition of UB, but it seems that if “int” can be initialized with a trap representation (highly unlikely in current implementations), it would be reasonable for this code to crash.

                  1. 1

                    yes this is UB, as far as the standard is concerned the value of x is indeterminate, and using that value in any form is undefined behaviour.

                    from http://port70.net/~nsz/c/c99/n1256.html#J.2:

                    The value of an object with automatic storage duration is used while it is indeterminate

              1. 25

                Go: the basic idea behind defer is excellent.

                Rust: memory-safety without GC is an amazingly wonderful goal.

                Java: pioneered one of the (now) most prevalent strategies for write-once/run-everywhere (bytecode VM).

                C#: fixed a lot of boiler-plate and ergonomic problems from Java.

                Ruby: prizing developer ergonomics is lovely.

                Javascript: making programming accessible to everyone (essentially every computer ships with a fully-functional IDE) is awesome.

                C++: offering blessed, zero-cost abstractions is a lovely gift.

                Python: the idea of only having one way to accomplish a task is the dynamically-typed version of my C++ comment above.

                PHP: what would we even do without wikipedia?

                Excel: phenomenally-intuitive in a way that no other modern GUI programming has managed to rival

                1. 10

                  Java: pioneered one of the (now) most prevalent strategies for write-once/run-everywhere (bytecode VM).

                  I enjoyed your list. Except this was popularized by UCSD Pascal which you might find interesting. I think Wirth said this design got Pascal ported to over 70+ architectures in 2 years with diversity ranging from 8-bit personals to odd-sized mainframes. System/38, later AS/400, also had platform-neutral code it compiled to to make it future-proof. See this for it among others.

                  1. 2

                    Python: the idea of only having one way to accomplish a task is the dynamically-typed version of my C++ comment above.

                    I truly enjoyed this idea of Python 20 years ago.

                  1. 2

                    Awesome work, and congratulations on taking the step! Any analytics platform that aims to be open and privacy-respecting should be lauded.

                    My website is phenomenally small at the moment, and I don’t feel the need to use any analytics right now, but I will keep you in mind if ever I head that route for any of my personal projects!

                    I wish you all the best of luck!

                    1. 3

                      Looks like an awesome idea. I love the concept of having a really small terminal multiplexer. It is unfortunate that it fails to pass through sixel though. I would love to see more wide support for sixel.

                      1. 4

                        Been a minute, here’s an update.

                        • The vast majority of the yard work is complete, only a bit left to do
                          • The raised beds are all in and filled with soil and planted
                          • The fire pit is effectively operational (a few more stones needed for aesthetics)
                          • The only things left to be planted are a rose bush ground-cover in one of the front boulevards and a few more raspberries (the ones already planted have started to fruit already)
                          • This last weekend, everything took off; the plants are huge and producing massively. I see a lot of salads in my future :P
                        • Dove-tailing from the above, we are going to try and setup a little free pantry in the near future; we are going to avoid stocking it with anything that is likely to spoil (unless the neighborhood gets really enthusiastic about what we’re growing), but we will be getting a vaccuum sealer and stock it with staples and things and hopefully the whole neighborhood gets into it!
                        • I gave my crash-course intro to undefined behavior at the local C meetup, and I think it went reasonably well
                          • The full PDF of my slides is available on my site (cf. https://halosgho.st/talks)
                          • I still want to do an idlewords-style transcript of the slides and talk so that people can reasonably experience the talk having not been there (and as there is no recording available); hopefully, that can happen in the next week or so.
                        • Because I have almost nothing on my todo list (read: the backlog is daunting…), I’ve decided to take on another project: writing my own very basic window manager starting from tinywm as a base. I have lots of plans, but this (as with many of my projects) is meant to be for me, so I am unsure if it will ever be something that other people might want to use
                        • I am looking for new job opportunities (resume and cv)
                        • My backlight brightness management utility (enlighten) is approaching its 1.0 release
                          • I still want to add a couple more tests
                          • I want to make the test-suite a little less gross so that others can add more tests as an easy place for new contributors to add value
                          • I am looking into the possibility of formally proving much of the actual management code with frama-c (I have some of the preliminaries done, but there’s a bit of a refactor needed to accomplish this goal)
                        1. 11

                          My deploy is a target in a Makefile (make deploy) that builds system-installable packages (for archlinux, because that’s what I deploy on, but it could reasonably be adapted for anything else if the tooling exists), copies the packages over to my machine via scp, and uses ssh to both install the packages and restart the necessary services on the target.

                          Pros:

                          • very minimal and easy to understand (it’s a few lines of bash)
                          • easily retargetable (all I need to do is shift my credentials and the machine specification and it can deploy to a different target)

                          Cons:

                          • it is not through CI/CD (though it could easily be if I actually set a runner up, as all the CD step needs to do is run make deploy)
                          • if you don’t like using system package-managers, that’s a con (personally, I like them)

                          This has worked really well for me for quite some time. Though, to be fair, my website isn’t hugely complex.

                          All the best,

                          -HG

                          1. 2

                            I do all of this except I don’t do system packages anymore because I want a repo of my deployed built artifacts. Also I use a CI/CD system.

                            1. 1

                              This sounds interesting, thank you. When you say that you “restart the necessary services on the target”, are those services part of the package that you’ve just installed?

                              So you have some services continuously running, serving HTTP or FastCGI or something behind nginx? And you use the OS’s service management to restart them when you deploy? Is that systemd on ArchLinux these days?

                              1. 3

                                A little more detail should clear things up. My website is written in plain C using a library called lwan. I authored some very small .service files (for systemd, because that’s what Arch uses) which control the site(s). One of the packages my deploy target builds includes all the files for the site (assets, .service files, and the C programs themselves). The services that are being restarted are the website itself.

                                So, in answer to your specific questions: yes, the service files are provided by one of the packages. The services are not FastCGI, but they are indeed running an HTTP server. And yes, I use systemd, because of Arch.

                                This is a topic for another thread and another time, but I may be on the cusp of switching away from archlinux, and the place I move will likely not have systemd (though that’s not the reason I am switching), so part of this infrastructure may need to be rewritten. Though, admittedly, not much: really just the service files themselves and this deploy procedure to operate with the new, analogous tooling.

                                All the best,

                                -HG

                                1. 2

                                  Is that Lwan Web Server that you use as a library? I forgot the web site said it can be used that way. Looking at minimalist and securable servers, it was one of the most exciting things I found. I keep mentioning it in different threads so more people try or review it.

                                  If that’s it, what’s its setup difficulty and performance like compared to Nginx? And I mean Nginx if you install a package followed by one of the setup guides out there that try to make it easy.

                                  1. 4

                                    @nickpsecurity, indeed it is. I do not know if the official website documents this functionality. Actually, one of the only things that I do not love about lwan is its lack of documentation (for the most part, it is more useful to read the code).

                                    I think it is excellent for performance, and it did quite well in the techempower benchmarks; though, I should say explicitly that I have not done exhaustive performance tests or comparisons with nginx. If using the binary form, it is quite simple to use (and configurable via lua, which is a usability plus in many ways). When used as a library, it is a bit more work, but the result is that you only have installed exactly what you need (which is something that speaks to me more and more).

                                    If you are interested in how I set my site up, you can find the site itself at https://halosgho.st and the source-code (including the Makefile with deploy target) on my github. I also idle on freenode much of the time (freenode account halosghost); please feel free to ping me if you wish to have a more thorough discussion.

                                    1. 2

                                      Appreciate it. Yeah, I like the install just what you need philosophy. Better docs is actually an easy area for folks to contribute. I’ll try to remember your offer if I do anything with it. :)

                                  2. 2

                                    Thank you for going into detail - much appreciated!

                              1. 4

                                Been a while since I’ve posted in one of these, and a lot has happened since the last one. So, here’s a dump.

                                In not-tech news:

                                • Moving 1.5 tons of cinderblocks to complete our raised beds
                                • Moving, transporting the soil/compost to fill the raised beds
                                • Starting this weekend, planting things in the raised beds (among other things, I get to grow Carolina Reapers! :D)
                                • Continuing to fight with our former contractor so we can actually finish the renovation we started more than a year and a half ago
                                • Getting back into rock climbing; my partner’s knee surgery went well and they can start doing some climbing again (not lead or bouldering, but top-rope is fine), which is super-exciting
                                • Shopping for a new racquetball racquet (I’ve broken the strings on two racquets in the last two months, and fractured the frame on another)…

                                Meanwhile, on the digital farm:

                                • Looking for other jobs
                                • Continuing to work on a for-fun prototype of a plugin/addon system implemented as a shared library in C (leveraging libdl) (repo here if interested: libplug)
                                • Continuing to work on a pastebin implemented atop lwan (need to buy a domain and start hosting the reference instance so development can move faster and so that it’s actually available for people)
                                • Getting deeper and more familiar with dependent typing and formal proofs (by following plfa)
                                • Continuing to poke around with making my fork of an untyped lambda-calculus interpreter into a more “usable” programming language (next up is adding rudimentary module support (probably more like C-style #include)). (repo if interested: lci)
                                • Starting to work on an outline and abstract for a talk I have been invited to give on the topic of Undefined Behavior in C

                                Phew. I think that’s a reasonable summary of life at the moment. Here’s hoping it gets a little less hectic soon. :)

                                1. 3

                                  I was wondering if you slept on compost for a while, but then I realized what “beds” meant. facepalm

                                1. 10

                                  Note: some controversial, and somewhat decisive, opinions follow.

                                  Some of the changes in this list are really exciting:

                                  • redefinition of {u,}intmax_t to allow implementations some leeway for bigints and extended integer types (maybe I can finally have uint128_t!)
                                  • enum type-specifiers for better control over storage allocation (I get moar control!)
                                  • clarification that anonymous structures inside unions maintain their structure (an ambiguity that’s nice to have resolved since the committee seems to have a consensus that this was always intended)
                                  • decimal floating-point arithmetic extensions (kiss some rounding error goodbye!)

                                  I am incredibly excited for some of these (and I have a few things I’d like to eventually propose to the committee myself, though I don’t think I’ll even have them hammered out by the time C2x is standardized). But there’s something that, to me, feels almost sinister going on underneath some of the proposals; namely, N2269 and nullptr.

                                  So, here’s what happened, WG14 (the working group behind the C standard) stated in the C2x charter a renewed set of principles to guide the language moving forward. One of those principles was minimizing deviations from modern C++. This, to me, is a horrible idea. C++ hasn’t been a strict superset of C since C99. Maintaining source-code compatibility is strictly impossible without changes to the C++ standard or removals from the C language which are widely used. Furthermore, if C balloons into C++, it will be a tragedy.

                                  • N2269 (adding attributes) is an interesting idea but explicitly chooses to not to just use _Pragma (already part of the language) because it’s too limited in power, nor _Attribute (the natural choice) because it would deviate from C++ in favor of new syntax (taken from C++) that includes a construct :: that doesn’t exist anywhere else in C.
                                  • nullptr. C’s definition of NULL has changed a couple of times, and now matches C++’s definition ((void * )0). As I understand it, C++ benefits from nullptr because C++ has multiple types of pointers (references, unique_ptr, etc.), templating, overloading and a variety of other tools that make using NULL ambiguous or unsuitable. C has exactly none of these, and I seriously hope it never shall.

                                  These changes are not yet voted on, as far as I know, but I seriously hope the Committee is wise enough to not take “minimize deviations from C++” to mean “implement everything that a C++ programmer might want in C”. The affects would be disastrous otherwise.

                                  1. 6

                                    I mostly agree – although I think that decimal floating point is also a mistake. It seems appealing, but it’s almost never what you want. The #1 thing that I want from the C committee – the gradual removal of undefined behavior – also seems to be missing here.

                                    1. 3

                                      Not only are they not removing undefined behavior, but they are adding all sorts of unthought out extensions to C, like decimal floating point each on of which comes with additional prospects of undefined behavior.

                                  1. 4

                                    This is an interesting idea, and has been pursued before.

                                    For example, verbal expressions (in particular, since this is python: PythonVerbalExpressions, which does support Python 3).

                                    What is the benefit of cursive_re over verbal expressions (which, though perhaps not standardized in a formal document, already has many implementations among many languages)? More than that, I do have to wonder where the line is between verbosity and terseness where gaining clarity levels off.

                                    Regex are notoriously difficult for new-comers to grok (though I have several arguments about why that might be unrelated to their construction and lexicon); but there are always diminishing returns on clarity when you increase verbosity.

                                    OP, where is the line for you? What led you to choose particular names over other (perhaps shorter) ones? For example, why name . anything() instead of any_single_character()?

                                    This is not meant as an attack on this project, or any other that aims to make a terse language more readable. Rather, I am interested in the wider implication. Some programmers (e.g., APLers and Haskellers) clearly prefer greater information density; others (e.g., Java) tend to prefer the maximal verbosity so there can be no misinterpretation. I do not believe we have found a reasonable resolution to this dichotomy yet.

                                    To inject my own thoughts now: I tend to err toward concision. Higher information density requires higher overhead for both reading and writing, but “sends less bits over the wire” (metaphorically and mechanically speaking), and results in fewer lines of code (and thus hopefully, fewer places where bugs can arise).

                                    1. 3

                                      For example, verbal expressions (in particular, since this is python: PythonVerbalExpressions, which does support Python 3).

                                      What is the benefit of cursive_re over verbal expressions (which, though perhaps not standardized in a formal document, already has many implementations among many languages)? More than that, I do have to wonder where the line is between verbosity and terseness where gaining clarity levels off.

                                      I had been vaguely aware of verbal expressions but never dove in because I don’t feel like mutability is a good fit for this sort of solution (because it doesn’t compose). cursive_re is closer in spirit to something like Emacs’ rx module.

                                      OP, where is the line for you? What led you to choose particular names over other (perhaps shorter) ones? For example, why name . anything() instead of any_single_character()?

                                      On the one hand I wanted to avoid clashing with names of builtin functions, so I couldn’t go with any for anything and on the other it’s just my personal preference for things to have meaningful names. My benchmark is: with minimal context, can I get a sense of what this thing does just by reading its name? I do the same regardless of whether I’m working in a terse language like Haskell or something like Java or Python in this case.

                                      To inject my own thoughts now: I tend to err toward concision. Higher information density requires higher overhead for both reading and writing, but “sends less bits over the wire” (metaphorically and mechanically speaking), and results in fewer lines of code (and thus hopefully, fewer places where bugs can arise).

                                      Code is read more often than it is written and maximally terse code tends to require maximum effort to read and change down the line. That’s not to say that ergonomics don’t matter (I’ve often argued that they do!), only that, oftentimes, being more verbose is a better strategy in the long run.

                                      1. 2

                                        Thank you for the thoughtful and clarifying response.

                                        I had been vaguely aware of verbal expressions but never dove in because I don’t feel like mutability is a good fit for this sort of solution (because it doesn’t compose). cursive_re is closer in spirit to something like Emacs’ rx module.

                                        Fair enough! I am not aware of Emacs’s rx module, nor am I familiar enough with PythonVerbalExpressions to speak on its use of mutability or its lack of composability.

                                        Code is read more often than it is written and maximally terse code tends to require maximum effort to read and change down the line.

                                        In that case, do you think Literate Programming in concert with concision is a reasonable solution, or would you prefer as you seem to have aimed for with cursive_re “self-documenting code”?

                                        1. 3

                                          In that case, do you think Literate Programming in concert with concision is a reasonable solution, or would you prefer as you seem to have aimed for with cursive_re “self-documenting code”?

                                          My preference would be for self-documenting code. I think of comments as a means of documenting the whys of an implementation, which is similar to how literate programming is generally used, but most code doesn’t need that level of “documentation” (I’m using quotes here because I think this is different from reference documentation or guides (i.e. “docs”)). Additionally, code interacts with code: when you interact with a library written in a literate programming style, you most likely won’t have the literate part readily available to you to inspect.

                                    1. 8

                                      A while back (looking at git history, early 2011 it appears) I hacked an alternate mode into bash to have it output equivalent C code instead executing commands. It only supported a small subset of the language, but worked well enough to bootstrap itself into a shell-to-ELF compiler from a shell script – digging it out of the dusty attic, it even appears to have been sufficiently bitrot-resistant to still work today!

                                      $ cat compiler.sh 
                                      ./bash --compile /dev/stdout /dev/stdin | gcc -xc - -xnone libbashc.o
                                      $ ./bash compiler.sh < compiler.sh 
                                      $ mv a.out shtoelf
                                      $ echo '/bin/echo hello world' | ./shtoelf 
                                      $ ./a.out 
                                      hello world
                                      

                                      (Note that this generates a standalone executable that calls fork, execve, etc. itself, without any runtime dependency on bash.)

                                      1. 1

                                        This sounds like great fun! Do you have the work for this available online anywhere? I would love to poke around with it!

                                        1. 1

                                          Haha, thanks – it was pretty fun to play with…I’ve just now rebased it onto an upstream git version of bash (when I originally wrote it I think bash hadn’t yet adopted git, so it just had a full-source-tree import as its first commit), and tossed it up here: https://github.com/zevweiss/bashc

                                          (And of course, as with any code more than a few months old, I look back at it now and immediately find things to be embarrassed about, but such is life…)

                                      1. 6
                                        • $DAYJOB is slowly making progress towards an internal release of the project we have been working on for 2+ years. Hopefully, we should get it launched within the next few months.
                                        • House renovation is nearing completion as well (hopefully finished before the end of October?)
                                          • Get the radiators hooked back up
                                          • Build the vanity for the full-bath once the radiator is back in
                                          • Build the molds and pour the concrete for the counter-tops (this week?)
                                          • Get the electrician out to do some really basic work
                                          • Get the plumbers back out to hook up the sinks
                                        • Leveraging lwan’s straitjackets (read: chroot jail + privilege drops) for my website (MOAR SECURITY)
                                        • Starting on the rewrite of my pastebin with all that I’ve learned from setting up my personal website
                                        • Hopefully getting started on some of the basic code / DB work for a business idea I have (don’t want to say too much yet, but could hopefully be a reasonable self-employment option)
                                        • Heading down to New Mexico to see the Balloon Festival this weekend!
                                        1. 2

                                          Leveraging lwan’s straitjackets (read: chroot jail + privilege drops) for my website (MOAR SECURITY)

                                          Appreciate the reminder about lwan. People are often talking about language rewrites or compiler transformations for stuff like Nginx that’s 100+ kloc. The lwan codebase was doing really good on fuzzing, is supposedly easy to read, and page says about 10kloc or so. Also, any improvement might benefit embedded since it’s used there. SCADA and IoT that hackers are currently focusing on a lot. So, lwan seems like much better target for people wanting to use PL research or security tools to improve a web server.

                                        1. 15

                                          Okay, time for a freak-out of excitement.

                                          0.3 includes a litany of things that seem like they were designed specifically to make me love it:

                                          • zig fmt - nice! One thing I will say Go has going for it is that wars over formatting are a thing of the past.
                                          • zig run - nice! I can totally foresee leveraging tcc-style shebangs to have Zig scripts!
                                          • pointer reform:
                                            • Zig is now in-line with some of what C’s syntax is for pointer-to and address-of which makes it less jarring and more rigorous on meaning
                                            • explicit separation between pointer-to-single-item and pointer-to-aggregate is awesome; more explicit intention revelation!
                                            • “all control flow occurs exclusively via keywords” - I love it. This ends the vast majority of syntax misgivings I have had about Zig in the past. It reads better, it’s less overloading of particular symbol meanings; it’s just universally better
                                          • try is reasonable for all error-handling cases now, including across async/await suspends. Having a single go-to practice for error-handling is lovely
                                          • @typeInfo - say hello to compile-time reflection! I do not often find myself in need of these things, but having the ability to makes Zig much more widely-usable for higher-level things
                                          • compatibility with valgrind and gdb - Thank you! Keeping the tools I am already familiar with for debugging is such a boon to my performance

                                          And last, but absolutely not least:

                                          • all integer sizes are primitives: arbitrarily-sized, fixed-width integers are now a reality, and their usability is vastly improved. It looks like 0.4 will involve some more huge improvements to this, making them nearly seamless. But they behave so beautifully now already. This is a feature that I want in every language ever.

                                          I have no words to adequately describe my excitement for this release. I am impatiently awaiting 0.3’s release to the AUR so I can start playing with all the new toys!

                                          1. 4

                                            I am continuing work on my personal website. I have most of the security stuff done (still a couple more to go). It is meant to serve as a replacement for all the social media I have left behind as kind of a public profile, but also to serve as a portfolio of my work. Next up: project pages! I’ll be able to have some information about many of my personal projects without people needing to leave my domain.

                                            I also started a small organization aiming for easing accessibility in open-source software, the PDF Accessibility Initiative. Still very early days (exploring what’s available—spoiler: not much), but any and all help is welcome! The goals are to, eventually, be able to test a PDF for accessibility standards compliance, possibly provide libraries that help document authoring software (e.g., LaTeX) to generate accessible documents, and to provide a tool that will allow taking a non-accessible PDF and correct it; all from open-source/libre software.

                                            There are several other personal projects that are finally getting close to getting back on my radar. Namely, my pastebin (which my personal website is serving as a staging ground for).

                                            1. 28

                                              Possibly unpopular opinions (and a large block of text) incoming:

                                              C++, Go, Swift, D and Rust all fail to adequately replace C for me. When given the choice, I would likely choose to just stick with C (for the moment; I’ll talk about what I’m considering at the end).

                                              C++ has so much historical baggage and issues, it’s already an immediate turn-off. More than that, it’s explicitly understood that you should carve out a subset of C++ to use as your language because trying to use the whole thing is a mess of sadness (given that it’s massive at this point). I appreciate the goal of zero-cost abstraction and having pleasant defaults in the standard library, but there are just too many problems for me to take it as a serious choice. Plus, I still have to deal with much of the unfortunate UB from C (not all of it, and honestly, I don’t mind UB in some cases; but a lot of the cases of UB in C that just make no reasonable sense come across to C++). It should be noted that I do still consider C++ occasionally in a C-with-templates style, but it’s still definitely not my preference.

                                              Despite how often people place it here, I do not believe Go belongs in this group of candidates The garbage collection alone makes it unfit for systems programming. I see Go as a very reasonable choice to replace Java (but I don’t use Java whenever I have the choice, so I might not be the best person to ask). There are many other parts of this language that rub me the wrong way, but mostly, I just think it’s not a good systems language (but is instead a great intro language for higher-level stuff).

                                              Swift is really easy to rule out: It’s not cross-platform. Even if it were, it has all sorts of terrible issues (have they fixed the massive compile times yet?) that make it a no-go.

                                              D, as far as I can tell, manages to be C++ without the warts in a really lovely way. Having said that, it seems like we’re talking about good replacements for C, not C++, and D just doesn’t cut it for me. GC by-default (being able to turn that off is good, but I’ll still have to do it every time), keeping name mangling by-default, etc. -betterC helps with some of this, but at that point, there’s just not enough reason for me to switch (especially with all the weirdness of there being two de facto standard libraries from different organizations, one of which I think is still closed-source? sounds like I might need to take another look at D; though, again, its emulation of C++ still suggests to me that it won’t quite cut it).

                                              Rust is the only language in this list that I think is actually a reasonable contender. Sadly, it still bites a lot of these issues: names are still mangled by-default, the generated binaries are huge (I’m still a little bugged that C’s hello-world with glibc dynamically links to 6KB), et al.

                                              But more than all of these things I’ve listed, the problems I have with these languages is that they all have a pretty big agenda (to borrow a term from Jon Blow). They all (aside from C++ which has wandered in the desert for many years) have pretty specific goals with how they are designed to try and carve out their ideal of what programming should be instead of providing tools that allow for people to build what they need.

                                              So, as for languages that I think might (someday, not soon really) actually replace C (for me):

                                              Zig strikes a balance between C (plus compile-time execution to replace the preprocessor) and LLVM IR internals which allow for incredibly fine-grained control (Hello arbitrarily-sized, fixed-width integers, how are you doing?). It also manages to have the best C interop story I have ever seen in a language so far (you can import from C header files no problem, and zig libraries can have their code called from C also no problem; astounding).

                                              Myr is still really new (so is Zig really), and has a lot left to figure out (e.g., its C interop story is not quite so nice yet). However, it manages to be incredibly simple and terse for a braced language. My guess is that, in the long run, myr will actually replace shell languages for me, but not C.

                                              Jai looks incredibly cool and embraces a lot of what I’ve mentioned above in that it is not a big agenda language, but provides a lot of really useful tools so that you can use what you make of it. However, it’s been in development for four years and there is no publicly available implementation (and I am worried that it may end up being closed-source when it is released, if ever). I’m hoping for the best here, but am expecting dark storms ahead.

                                              Okay, sorry for the massive post; let me just wrap up a few things. I do not mean to imply with this post that any of the languages above are inherently bad or wrong, only that they do not meet my expectations and needs in replacing C. For a brief sampling of languages that I love which suffer from all the problems I mentioned above and more, see here:

                                              • Haskell and Idris, but really Agda
                                              • Ada
                                              • Lua
                                              • APL (specifically, the unicode variants)
                                              • Pony

                                              They are all great and have brilliant ideas; they’re just not good for replacing C. :)

                                              Now then, I’ll leave you all to it. :)

                                              1. 15

                                                (especially with all the weirdness of there being two de facto standard libraries from different organizations, one of which I think is still closed-source?)

                                                That was resolved a few years ago. D just has one stdlib, it’s fairly comprehensive, and keeps getting better with each release.

                                                1. 12

                                                  a few years ago

                                                  a bit of an understatement! The competing library was dropped in 2007.

                                                2. 10

                                                  Despite how often people place it here, I do not believe Go belongs in this group of candidates The garbage collection alone makes it unfit for systems programming. I see Go as a very reasonable choice to replace Java (but I don’t use Java whenever I have the choice, so I might not be the best person to ask). There are many other parts of this language that rub me the wrong way, but mostly, I just think it’s not a good systems language (but is instead a great intro language for higher-level stuff).

                                                  Agreed with this. Go is my go-to when I need to introduce dependencies to a Python script (and thus fuck with pip --user or virtualenv or blah blah blah) for high level glue code between various systems (e.g. AWS APIs, etc.)

                                                  I think there’s a reason Go is dominating the operations/devops tooling world - benefits of static compilation, high level, easy to write.

                                                  Look at the amount of hacks Docker needs to do things like reexec etc. to work properly in Go, that would be trivial to do in C.

                                                  1. 3

                                                    Note that Zig is x86-only at the moment. Check “Support Table” on Zig’s README.

                                                    For that matter, Rust is x86-only too, if you want Tier-1 support.

                                                    1. 3

                                                      I’m a big d fan, but I agree that it’s the wrong thing to replace c. Betterc doesn’t really help in this respect, because it doesn’t address the root reason of why d is the wrong thing to replace c (which being that the language itself is big, not that the runtime or standard library are). Personally, I think zig is the future, but rust has a better shot at ‘making it’, and the most likely outcome is that c stays exactly where it currently is (which I’m okay with). I haven’t looked at myr (yet), and afaik isn’t jai targeted at game development? It might be used for systems programming, but I think it might not necessarily do well there.

                                                      It also manages to have the best C interop story I have ever seen in a language so far (you can import from C header files no problem, and zig libraries can have their code called from C also no problem; astounding)

                                                      I think nim does this, and d for sure does, with d++ (I think this may also help with the c++ emulation? Also, I’m not sure why you’re knocking it for its lack of quality c++ emulation when it’s afaik the only language that does even a mediocre job at c++).

                                                      1. 1

                                                        I agree!

                                                        As for knocking D for emulating C++, I did not mean to suggest that doing so is a count against D as a language, but rather just as a count against replacing C. I already ruled out C++, if a given language is pretty close to C++, it’s probably also going to be ruled out.

                                                        It’s been a long time since I looked at nim, but generating C code leaves a really poor taste in my mouth, especially because of some decisions made in the language design early on (again, I haven’t looked in a while, perhaps some of those are better now).

                                                        As for Jai, yes it’s definitely targeted at game development; however, the more I look at it, the more it looks like it might be reasonable for a lot of other programming tasks. Again though, at the moment, it’s just vaporware, so I offer no guarantee on that point. :)

                                                      2. 2

                                                        However, it’s been in development for four years and there is no publicly available implementation

                                                        I’m amazed that behind the project is Jonathan Blow, he is a legend programming original video games.

                                                      1. 4

                                                        I remember being really unhappy about journals being binary for a long time.

                                                        Eventually though, I stumbled upon the fact that you can actually call something like strings $thejournalfile | grep MESSAGE on a journal and get the whole log in a more recognizable format. With just a bit more effort, you can actually recover the full log to plaintext in no time.

                                                        It would be nice if there were a convenience script like this provided with systemd, but that realization (i.e., in a pinch when the system has all but died, I can still go look at the logs because strings) pretty much ended any qualm I had with the journal.

                                                        I recognize that systemd is (still, somehow) pretty divisive, but ime, it has made system administration dramatically simpler and more pleasurable. I’ll use it till someone shows me something better.

                                                        1. 3

                                                          I’d like to think I’ve a fair bit about UB in C (both recently, and over the years I’ve worked with the language), but I’m not familiar with the oldest version of the standard (C89) and was unaware of this difference from that version and its modern descendants.

                                                          I must say, many of the proposals I’ve heard online lately about fixing UB in C I’ve found either ill-informed, over-zealous or in some other way objectionable; but this seems to not only offer a much friendlier environment for the programmer, but also seems completely reasonable. It does not curtail a compiler’s ability to avoid having to care about the difficult-to-catch situations (as they can just ignore the case), which is one of the only general benefits of UB (to implementors).

                                                          I’m not a member of the C Committee (if only wishing made it so), but if I were, I’d love to hear this proposal.

                                                          1. 3

                                                            I did not write this module, but I know the author and we’ve discussed this concept. His goal is to make programming more accessible and translating documentation is just one step towards this. I also know that the current implementation, using Google Translate, is more or less a proof of concept. The ideal scenario would be a help system for Python packages that supports localisation, i.e., provides ways in which people can document their modules in multiple languages, and perhaps optionally defaults to automatic translation for missing languages.

                                                            I’d be curious to know what other people think.

                                                            1. 1

                                                              come up with some way to combine a wiki system to let people contribute translations perhaps?

                                                              1. 2

                                                                This is an awesome idea, and there has already been some work done in this space.

                                                                I don’t know how translations are handled in python (and since this tool is using google translate, I’m not sure how portable this idea is), but in C (and many other languages), GNU’s gettext is the standard. One of the benefits is that there are some great tools available for accepting translations; e.g., poedit. And there are online editors available too (though I cannot vouch for them).

                                                                Allowing a public translation effort (probably with review from someone) in a wiki style would be incredibly cool!

                                                                @achilleas, awesome project; I ope the author keeps it up!