Threads for cjh

    1. 1

      The Rust part is a repost from Eric Raymond’s much discussed blog post about how Rust is “severely disappointing”.

      1. 5

        The entire post is written by Eric S. Raymond (ESR), and yes he included a snippet from his other post.

        1. 1

          I wasn’t implying that ESR didn’t write this, too. Sorry if it reads that way. Just wanted to note that this is not all “new”.

    2. 4

      I realize this is about half-a-year old, but ever since this post, I’ve found myself using the term “morbid binding” a lot and realized the original article might not have gotten much circulation.

      1. 8

        The more established term for this is Connascence.

      2. 3

        I have wondered what others called this, I often used “implicit coupling” or “implicit dependencies”.

        Thanks for sharing this.

    3. 8

      I think ESR is right and wrong here. Right because Rust isn’t the right tool for what he’s trying to do. Wrong because Go isn’t a C replacement, and he never needed C in the first place for what he’s doing.

      I think Rust is a great language–I use it for developing the runtime system of a research PL I’m working on–but the community oversells the value of GC-less operation. Most of the “complexity” of Rust stems from having the type system track references. This bugs me because for many people Rust will be their first introduction to a “good” type system, and I don’t want people to get the wrong idea that typeful programming is all pain little gain.

      1. 2

        I don’t think there is anything in particular about an NTP server that requires a GC-less language. Rust sans borrow checker would probably be a fine, easy-to-use choice. I thought about unpredictable GC pauses interfering with synchronization but apparently Go works for him so that can’t be an issue.

        I don’t think writing an OS kernel and a server have much in common. I think Rust is a fine language for developing a kernel in. If by “OS” you meant all of the supplemental stuff that isn’t running in kernel mode, then I agree, but then again I don’t think C is an appropriate language for it either

        1. 5

          Synchronizing your system’s time to millisecond or microsecond precision at least requires a degree of control over your GC, since FOSS real time GC implementations aren’t a thing to my knowledge. Which is why ESR is considering Go.

          There’s nothing special about Go’s language design wrt GC, and its implementation uses a standard collector aggressively optimized for latency at the expense of throughput. The same principles apply to any other language, whether or not existing languages make this trade off in their collectors is irrelevant to my point. The way you word this sounds like it is intended to be a rebuttal, but I see it as supporting my claim that GCed languages are quite appropriate for this domain.

          Not many people want to or need to hack on kernels, I would think servers, including much of “all of the supplemental stuff that isn’t running in kernel mode” would be a much bigger domain for Rust.

          Maybe? I’m not particularly interested in spreading the gospel of Rust.

          Or may I turn this implicit question around? What domains do you think Rust is suited for?

          I would use Rust for anything I would use C for.

          • Embedded programming, where you need tight control over allocation

          • OS kernels & drivers

          • Language runtimes (I include Servo in this)

          • Libraries that need to make minimal assumptions about their runtime environment so they can be used from any language

          • Games, and more generally anything A/V. The people I know in game dev tell me that using C# (Unity, etc) is a pain and they have to be very careful about controlling allocation rates

  1. 3

    I think Rust is a great language–I use it for developing the runtime system of a research PL I’m working on–but the community oversells the value of GC-less operation.

    Is this research PL public? what about the implementation?

    I’m working on a language looking at mutation and aliasing control with some similar ideas to Rust, but focusing on a higher level such that I can afford the overhead of a GC.

    Most of the “complexity” of Rust stems from having the type system track references. Yes! At times it feels like all Rust cares about is gc-less memory safety, and that all the other safety guarantees are happy byproducts.

    I think a similar language with a good gc would be a better fit for most use cases.

    As a mild aside: I also think Rust deals with internal mutability poorly (it is invisible to the user of a potentially internally mutable object).

  • 2

    I generally dislike this sorts of implementation quizzes as I don’t feel they generally help the discussion, however I like how the author ends with

    And at this point I only have to apologize. The test is clearly provocative and may even be a little offensive. I’m sorry, if it causes any aggravation. […] I only hope this little test would help someone like myself from the past to learn this attitude in some 15 minutes and not 15 years.

    Which I actually consider healthy and useful.

    C is a simple language, in so far as the specification is small - but this simplicity has holes and this in turn leads to complexity in implementations.

    My normal answers to quizzes like this is: irrelevant, I wouldn’t accept that code in a project I worked on, and it would be easy to decipher if I had a working implementation to play with.

    In this case though, I think the article is actually interesting in that the author is trying to convey the point of “I don’t know” (undefined / implementation defined).

  • 8

    I lost track of the number of clicks I had to make to actually find an example of Albatross, but here it is:

    1. 2

      This annoyed me, this link in the OP shows me nothing about the language at all, nor does it tell me anything interesting or novel - it doesn’t sell me on why I should spend time clicking around to find out more.

  • 2


    “programming” is a diverse discipline, a large chunk of which doesn’t require any explicit math beyond basic arithmetic.

    I’m looking at doing a master’s degree in type theory and programming language design, I’m learning the math I need as I go along.

    I don’t see how hard prerequisites help - especially since a decent chunk of your class (I would say a majority based on my undergrad experience) will never need more than basic arithmetic.

  • 23

    My favorite tactic for “killing” these is (to use the example from the post):

    # e.g. "hello everyone" => "Hello Everyone"
    def upcase_words(sentence)
      sentence.split(' ').map!{|x| x = x[0..0].upcase << x[1..-1]}.join(' ')

    In an ideal world the name is clear enough that someone reading the code at the call site understands what’s happening, and if they don’t the example alongside the definition hopefully gets them there.

    1. 6

      You mean

      # e.g. "col1\tcol2\n    ^ woah" => "Col1 Col2 ^ Woah"

      Naming it hurts in this case, because the function does not do what you named it (e.g. in a string of tab-separated values, or a string where multiple spaces are used for formatting). If you had to name it, it would be better named as split_on_whitespace_then_upcase_first_letter_and_join or leave it unnamed and hope that everyone on your team knows that split in Ruby doesn’t work as expected.

      The best solution is one that embodies exactly what you intend for it to do, i.e. substitute the first letter of each word with the upper case version of itself. In Ruby, that would be:

      sentence.gsub(/(\b.)/) { |x| x.upcase }
      1. 6

        If you had to name it, it would be better named as splitonwhitespacethenupcasefirstletterandjoin or leave it unnamed and hope that everyone on your team knows that split in Ruby doesn’t work as expected.

        I disagree. You should name functions and methods based on what they’re supposed to do. If it does something else, then everyone can see it is a bug.

      2. 1

        I don’t agree with your naming system. I think the name of your function should describe what it does instead of how it does it. If your function name describes how it’s implemented, you have a leaky abstraction.

    2. 6

      Among other benefits, giving it a name means we can explode the code without worrying about a few extra lines in the middle of the caller.

      words = sentence.split ' '
      words.each { |w| w[0] = w[0].upcase }
      sentence = words.join ' '

      Introducing a variable called ‘words’ is a solid hint about the unit we’re working with. We may not want to pollute the caller with a new variable, but in a subroutine that’s not a problem.

    3. 3

      Naming it does help in this case, but mostly because the reader no longer has to scrutinize over what it’s actually doing. Isn’t this sort of like polishing a turd?

    4. 1

      That only masks the issue.

      Any maintenance on that line will still have the same problems, whereas refactoring it to split it up into smaller segments AND giving it a name avoids that issue.

      1. 3

        It gives the reader a good frame of reference to what the function’s doing. Context helps a lot when trying to read code, and although this isn’t as readable as it could be yet, it’s definitely a lot more readable than minus the function signature.

    5. 1

      A kind of offtopic question based on this comment.

      Would I use Coq to prove this function?

  • 1

    I have started reading (the garbage collection handbook)[] which so far (first few chapters) has been very good.


    I’m still chipping away at my programming language (Icarus)[].

    Last week I added if statements to the language (including both backends), I also added in assignment to the c backend (currently lacking in the interpreter backend) which means I can now do fizzbuzz (using recursion rather than for loops - which my language still lacks) which you can see at ([].

    I’m currently tossing and turning about how assignment should behave, if reassignment to a variable should be allowed - and if so - under what conditions.

    Because my language allows some kinds of mutation through argument I am worried about ambiguity, in c this would be similar to

    void foo(bar *b) {
      if (some-condition){
        b = bar_new();
      b->a = 14; // does this line mutate the local b only or mutate the caller's version? depends on `some-condition`.

    Since Icarus is primarily focused on static verification of ‘mutation contracts’ (that is, mutation being obvious and agreed upon) - this seems like a flaw. So I am leaning towards disallowing argument reassignment.

    However in the case of immutable arguments, again using C as Icarus syntax is unfamiliar to anyone reading htis

    void bar(int i) {
      if (i < 5) {
        i = 5;

    there is no ambiguity at all about mutation, as there is no externally visible mutation possible.

    So I think I might only disallow assignment to arguments that are passed as mutable (roughly equivalent to c pointers).

  • 6

    I’m trying to figure out a reasonable API for a parsing library that provides all parse trees when the grammar is ambiguous. In C. The lack of garbage collection makes seemingly-obvious approaches (e.g. persistent data structures) tricky.

    I’m making a small dent in the big stack of papers I heard about during Papers We Love Conf & Strange Loop.

    I just got a partial laser-cut key tray prototype for a custom mechanical keyboard in the mail – I’m figuring out whether I want to adjust any positioning before I get the full key tray cut and start laying out the PCB.

    Work: Bringing up a bootloader on new dev board, particularly its interactions with a crypto-authentication chip. After that, initial USB support in the firmware.

    1. 1

      I’d be interested in hearing more about this C parsing library API design; both at a high-level and also diving into why lack of GC is making your design hard (I can relate).

      1. 2

        Happy to take it to messages. I’m working on more organized writing (blog posts, documentation), but it’s probably a ways off, and thinking out loud may help.

  • 2

    Over the last two weeks I added the skeleton of a bytecode stack vm for my programming language Icarus, it is able to perform simple arithmetic operations and printing - it currently lacks support for user-defined functions that return values.

    So this week I plan to add support for user-defined functions with return values to the bytecode stack vm backend.

    Earlier this week I started adding if/else statements to my languages - they are now supported all the way from parsing to transformation (into IR), so this week I will be working on adding support for them to my 2 backends (one backend compiles to c, the other is a bytecode stack vm).

    Both of these should them give me turing completeness across both of my backends.

    Although the actual work still has a very long way to go, as my language still lacks many basic essentials.

  • 16

    I read the WSJ article and as someone who really values their CS degree, I disagree with it for the following reasons:

    1. Ideologically, the author (CEO of Dittach) wants college to be a vocational school. He wants things like iOS and Android development classes. I think this is not the value colleges are meant to offer and this is a very short-sighted view of education. iOS and Android being hot will come and go in our lifetime. Being analytical will always be of value, and that is what one should get from a college, IMO. Clearly, some colleges are better than others, but if colleges offered the type of education the author wants, I don’t think we’d be better for it. If someone wants to make a vocational school for developers then, by all means, go for it.
    2. I have worked with people which I feel fit the author’s desired employee and they are good people but, IME, someone with a strong CS degree is needed in the mix to help steer that raw passion. In general, I’ve seen the people that just love to code produce a lot but create a lot of debt along the way. By bringing basic CS concepts to them, I have seen teams I’ve worked with produce better products with better delivery dates and cheaper long-term maintenance cost (sorry, not empirical but just in my experience, so maybe I’m off). That doesn’t mean one should only hire CS majors but rather that I think the author doesn’t recognize the balancing act. Basic things like recognizing what sort of abstraction solves the problem at hand and implementing it can reduce complexity and cost significantly without an equivalent cost in development. You want someone who can do both: think like a CS major and deliver. But that can be hard to get, especially in junior candidates, so being able to mix the two is probably more valuable than just focusing on one.
    3. The best engineer I’ve ever worked with came from a pure CS background and that background made him effective almost immediately. He hadn’t worked with source control or any non esoteric programming language before, or even really written a program before, yet the analytical skills he had acquired in his CS degree allowed him to come up to speed quickly. This person is an outlier but many of the people from his program have also gone on to do similar, working at various unicorns. The point being, don’t discount a CS major.
    4. I think the author is retroactively rationalizing a decision they feel they have been forced into. In the beginning the author makes an economic argument, simply that compared to Facebook or Google, a small startup cannot compete when it comes to salary and bonuses. He then goes on to claim that the education system is broken, 10 years behind, etc. So, which is it? Is it that he cannot afford these CS majors or is it that the education system is broken? The argument seems to come down to “I want to buy some meat” “meat is too expensive” “well nobody should like meat anyways! Veganism is better.”

    I want to stress that I don’t think one type of candidate is objectively superior to the other, it depends on the circumstances and what is needed at the time. I think the author is throwing this nuance away and providing an easy-but-wrong solution. And generating some PR for his startup at the same time.

    1. 8

      You are responding to the original WSJ piece but what I linked to was a response to that, which largely agrees with your comment!

    2. 1

      Very good response.

      In particular I thought the same about your 4th point, it felt like the WSJ article’s author was forced into a decision and then tries to justify it with (what I think are) incorrect or short-sighted statements.

  • 8

    In the footnotes:

    There is a bit of awkwardness around ambiguity between array-like tables and key/value tables, but it is not nearly as awkward as using alists.

    I appreciate Lua’s single data-structure to rule them all, but also believe that a language can support more than 1 core data structure without sacrificing simplicity. As such, I’m kind of surprised that Clojure is the only mainstream Lisp to ever be successful providing actual syntax for an associative data type.

    It also piques my curiosity as to whether or not an efficient deque implementation instead of cons cells makes more sense as a core data structure in a Lisp…

    1. 7

      Some complexity appears in Lua because the language blurs between ordered and unordered/sparse collections, so code needs to explicitly distinguish between them at runtime. (For example, ipairs vs. pairs.) People can create Array or Map constructors that bake that knowledge in with a metatable, but the language explicitly avoids endorsing any conventions for it.

      There’s a lot I like about Lua, but having something like [] vs. {} for collection literals would be helpful.

      1. 2

        Once I started thinking in terms of ordered/unordered/sparse data sets for my Lua programs, things sort of just clicked into place.. also, metatables, but also-also: lua-enumerable.

    2. 1

      It also piques my curiosity as to whether or not an efficient deque implementation instead of cons cells makes more sense as a core data structure in a Lisp…

      I’ve been keen on toying around with writing some small lisps that are only thin wrappers around different possible core datastructures, usually the idea is to output a map (dictionary, hashmap, what have you).

      Keen to see other implementations of this, I have never looked much into Clojure, my exposure to lisps is mostly from Scheme - which has functions works working with alists, but no special syntax.

  • 2

    The SSL cert on this website seem to have expired or something :(

    1. 2

      The site appears to just be hosted off github, so https:// connections are fetching the cert.

      There are issues with the site’s certificate chain (net::ERRCERTCOMMONNAMEINVALID).

      Common Name (CN) Organization (O) Fastly, Inc. Organizational Unit (OU) <Not Part Of Certificate>

  • 3

    Last year I had to study up for an interview so I bought a big pile of algorithms books, the books in this post are in order of my recommendation (stronger recommendation earlier) - although all books should give you a good coverage and keep you nice and busy for your 32 hours worth of flights.

    You should look at all of them on Amazon and inspect the ToC and sample pages to see which fits your interests best.

    Cracking the Coding Interview (soft cover) is superb and also written in a very approachable way, I found it easy to read cover to cover. It is also full of exercises to practice on.

    Elements of Programming Interviews (soft cover, smaller) is likewise good to read cover to cover. It is likewise full of exercises - it is also small enough to carry around in a bag without issue (it is ~ a5 size).

    Both of the above two books are good in that they start from a lower level than most algorithms texts, and walk you up piece by piece.

    The Algorithm Design Manual (hard cover) is quite good, but I think it is a little heavy for reading cover to cover.

    Programming Pearls (soft cover) is a book I highly recommend, although I think it is best reading if you already feel comfortable with general algorithms, and it doesn’t only cover algorithms.

    Introduction to Algorithms (MIT) (hard cover) is generally very highly praised, although I also think it may be hard to read cover to cover.

    Algorithms (Sedgewick) (hard cover) is also very highly regarded, haven’t read enough to give personal opinion on it though - it is the only book here I haven’t read cover to cover - it is sitting at home in my ‘to read’ pile (behind a bunch of other books more relevant to me ATM).

    1. 2

      Hey you have the wrong link for Cracking the Code Interview, should be this

      1. 1

        good catch, will fix, ty. And looks too late to edit T.T

  • 3

    Started reading through Types and Programming Languages. I have started trying to write an implementation for all the languages discussed in the book in a wide array of languages, so far I have a Haskell implementation for the arith language and I plan to add an implementation in ocaml, rust, and go if I can get around to it (I have never written anything in ocaml or rust).

    This week I also plan to read at least 2 papers, top of the pile (and carrying around in my bag) are How to make destructive updates less destructive and The next 700 programming languages.

    I also hope to find time to work on my personal programming language [Icarus]( - in particular the transformation phase from the intermediate form to my bytecode form.

    I managed to get my small Pony documentation change landed, I need to look into a Pony bug I raised about some concerns I had on the String class useability - although a lot of my issues stem from my lack of familiarity with the Pony capability system.

  • 4

    Thanks for this post clarifying the relationship between Pony and Causality, was something I always wondered about - but never enough to look into :)

  • 6

    I see a lot of Pony posts recently. Enough to merit a tag?

    1. 7

      i’d love a Pony tag.

    2. 3

      I think it makes sense to have a Pony tag consider we have them for other languages.

    3. 3

      Yes, why not. It costs nothing and will let users filter them if they’re not interested, or provide better search for those interested.

  • 4

    The errors aren’t bad, but I just can’t get over all the exotic syntax, “magic” semantics, and bizarre operator overloading in Perl6.

    I will admit I don’t really know what real world Perl6 looks like, but all of the articles and blog posts I see sure do a good job of making me want to stay far, far away. Half the time, I read the code blocks and think “WTF is this supposed to do?” So I read the explanations, and it doesn’t help, it just changes the question to, “How is it doing that?”

    I feel like before I can even get started I need to memorize a million arcane rules about practically every non-alpha numeric character (and half of Unicode apparently) and how it behaves in different contexts. It just completely turns me off of the language.

    AFAICT, Perl6 went all in on all of the parts of Perl5 that I disliked the most.

    1. 3

      I would like to second this.

      I spent the first four years of my career as a developer using perl5, I liked to know all the ins-and-outs of every operator, every trick - mostly so I could read some of the code in our codebase, I disliked half of that magic.

      But I did really like sigils…

      But perl6 just feels like it has gone in a very odd direction, to me it feels like the ‘broke’ the original meaning of sigils - and I think their changes are a net negative.

      They have also gone full on down the rabbit hole of crazy syntax, which I think will just further hurt them in the long run - perl5 was already disliked for it’s usage of silly syntax.

      1. 0

        Crazy syntax is the magic of perl, and perl 6 is more magical. Programming languages are interfaces to the computer just like a GUI is.

        It’s all about interface design.

        Most UI experts will say “good” design is what users expect. Same GUI widgets between different programs. etc.

        However, most video games break this mold. They create kick ass interactive and fun interfaces and widgets that may not have any similarity with other games or GUI systems.

        Go, or Java are like classic work horse GUI’s, like windows or mac. Perl 6 is like a video game GUI, fun, exciting, sexy, and novel.

  • 2
    Icarus - my experimental language

    This week I am working on a bytecode stack-based runtime for my experimental programming language Icarus lang, last week I wrote a good chunk of the datastructures I will need, so this week I am looking at writing the actual ‘bytecode compiler’ for a non-turing complete subset of the language.

    So far this has been fun as I have never written code to convert from imperative code to a stack-based machine, I have only ever used stack machines for stack languages, my first-pass algorithm can be seen as a comment here.

    Last week on Icarus I was able to get some simple code snippets (non-turing complete subset) to compile to C and run ‘cleanly’, the most interesting one I have written so far is

    # get_str(String)
    fn get_str(name::String) -> String
        return concat(concat("Hello there ", name), ", very nice to meet you")
    # main()
    fn main() -> Void

    Which outputs

    Hello there Jennifer, very nice to meet you

    If you’re interested in the full process (which shows both transformation and the compiled C) then you can see this in my README here

    So this week’s goal is try make progress on having the same subset also compile to my stack bytecode and then write the runtime for that to actually execute.

    General open source prog lang hacking

    I have some small documentation patches to Pony lang that I want to finish off.

    I’m also hoping to find some time to work on a tool written in Carp lang as a test of the language, doing so will also require me adding a bunch of core library features for dealing with filesystems - this should make Carp appropriate for scripting applications.

    It is likely the Carp work will slip a week or two…


    Last week I also met with a local university programming language research group to discuss me potentially starting a part-time MSc. Computer Science next year, I spoke to some of them about potential projects, so this week I will be reading into one project in particular and hopefully scheduling another meetup.


    All of the above is in my spare time, so it all depends how busy work keeps me, I expect ~ half of this to slip until next week.

    As for actual work I am working on migrating our team’s oncall rotation management from the current pile-of-cards-and-glue solution to something more sane.

  • 5

    I realize that we’re heading toward the ultimate software engineer dream of making a type-checked change that’s run through a proven-correct compiler that does machine-learning driven, whole program optimization…but it’s going the exact opposite of the direction I want. It’s not helping me in my quest for creating fun.

    I actually think a strong type system creates an environment for faster iteration, and also reduces the number and duration of cycles by catching errors quickly - at compile time - rather than later (testing or runtime).

    Things like ‘whole program optimisation’ also probably shouldn’t be part of your core dev cycle.

    They might make things harder though, if they necessitate building a new executable of the entire game for every little change.

    Strong static type checking doesn’t necessitate a full rebuild of the executable, at most only of the module changed and then a re-link.

    Interactivity, I may have to grudgingly accept, is not trendy in computer science circles.

    Also disagree; every modern functional language I have used came with a very powerful REPL, usually more powerful than what I get from weakly/dynamically typed languages.

    At least I assume his interactivity point was in relation to his previous points.

    I don’t get to do much functional programming, and my Haskell is terrible. I fight with the type system, but each cycle is very short - enter a line or two, rerun, see errors, fix, rerun, see errors, … That cycle is far tighter than the dynamic equivalent - change a few lines, run suite of unit tests, see debug/runtime stack trace, trace through code, fix, …