1. 5

    I’m working on a hobby programming project that I’m very excited about: A build tool.

    1. 3

      Any plans for features you want to include? or is it to recreate something as a learning experience?

      1. 5

        My aim is to replace make. I have the core algorithm done, it takes a very plain tab separated format as input. I think there needs to be a good UI to describe builds. I’m proving it by building existing projects with it.

        1. 10

          Within a few weeks of writing Make, I already had a dozen friends who were using it.

          So even though I knew that “tab in column 1” was a bad idea, I didn’t want to disrupt my user base.

          So instead I wrought havoc on tens of millions.

          (from https://beebo.org/haycorn/2015-04-20_tabs-and-makefiles.html)

          1. 6

            The side-note is even better:

            Side note: I was awarded the ACM Soft­ware Systems Award for Make a decade ago. In my one minute talk on stage, I began “I would like to apologize”. The au­di­ence then split in two - half started laughing, the other half looked at the laughers. A perfect bi­par­tite graph of pro­gram­mers and non-programmers.

    1. 4

      The irony of his manufacturing analogy is delicious.

      1. 1

        I like split, ortho-linear (or rather, staggered columnar) keyboards, but I also like having lots of keys (5 rows, 14 columns), so I use a Diverge (2, the 3 is out now) from UniKeyboard: https://unikeyboard.io/product/diverge/

        I modified mine to have a fixed base and mounted a trackball in the middle: https://imgur.com/AIW3vzy

        1. 1

          Recording two comedy shows for producing my buddy’s album!

          Recording two (1, 2) podcasts because they are fun!

          I don’t program for fun anymore and it really doesn’t bother me.

          1. 2

            As an after-hours audio guy, I wish you good cables and low noise floors.

          1. 1

            For a very well-done video walk-through, see https://www.youtube.com/watch?v=a9xAKttWgP4

            1. 4

              This person misses the point of their own collection.

              1. 5

                Sounds like a language that doesn’t try to waste my time :) Speaking of which, i think it might be interesting to think about what an “iteration” in the language might look like - something to address “I changed some stuff, what is the result?”.

                Now, there are people who use “tests” for this purpose, but that term comes with a lot of baggage, much of which results in my time being wasted, at least in the short term. So perhaps it’s possible to factor out the quality-assurance/maintainability/code-monkey-metrics aspects and find something that a) is in-between a REPL and a test suite and b) has a simple, baggage-free term for a name.

                Perhaps “examples”? As in, some sort of collection of inputs and their previous/expected/possible results together with short-term time-saving automation. Could be as simple as recording stdout on each run and showing a diff on the next re-run. Or something very clever with generators and fuzzing.

                (Edit) Adding on to the diff idea, having useful “diffs” for (nested) maps, lists, and primitive types out-of-the-box might already go a long way.

                1. 3

                  I think this is a fantastic idea. I can’t speak for other developers, but even when I don’t write full tests for a piece of code, I always run it on some example input, in a REPL or a scratch executable file, and “eyeball” the results to see if they match my expectations. Even though these “examples,” as you call them, don’t come with a machine-checkable criterion for their correctness, they are still valuable in their own right as a first step towards validating that a codebase behaves as intend, and also serve as a kind of executable documentation that future developers can use to understand how a project’s APIs work in practice. Current tooling seems to lack first-class support for this kind of example code, and in some cases (e.g. REPLs) actually actively works to ensure it never lasts beyond a single session, but I think it would be valuable to treat it as an important persistent artifact of the development process; an asset to stand alongside code, documentation, and tests.

                  1. 4

                    I take this approach much further than this. And make every single key on my keyboard a custom modifier key. 🙂

                    1. 1

                      That keyboard mapping is something else. I’m not sure it would work for me, but I’m going to keep that idea in my pocket.

                    1. 14

                      “A perfect keyboard would look something like this”

                      [an image of a keyboard with a spacebar that’s 6x as big as every other key]

                      I think … maybe we could do better than that?

                      1. 4

                        My 1u space key suggests you might be right.

                      1. 1

                        Nice!

                        I do something similar, but the other way around: I select a file (and optional line number) and then switch to my editor and hit a hotkey that parses the current selection to find the file and line and navigate there.

                        1. 3

                          Before writing this I was awkwardly opening files by hand, which was slow error prone and awful, though I refused to install language specific, or even editor specific plugins just to add this sort of simple functionality.

                        1. 2

                          One thing that worries me slightly about nesting helper functions inside of other functions is that it can break up the flow for the reader. Generally when I read a function, I expect to see a list of statements that will be executed, creating code flows. Nesting a helper around these statements always trips me up a bit, because I have to skip over its declaration and find its usages to trace the code execution correctly.

                          That being said I think it’s fine for small one- or two-liner helpers, especially in languages that have a concise syntax for lambdas. And I definitely agree that polluting the top-level scope with lots of helpers can make your code feel really cluttered and messy. So there’s a balance(as with everything style-related).

                          1. 2

                            It’s also problematic if you want to test the nested function. Most languages don’t provide (sane) ways of accessing them.

                          1. 19

                            I’ve seen this argument a lot that you CAN do one in the other, however syntax matters and defaults matter.

                            1. 3

                              Case in point:

                                 (assoc map :key value)
                              

                              In JavaScript:

                                 Object.assign({}, {key: value})
                              

                              Which is both more complex, less obvious and less efficient.

                              1. 2

                                Redux apps can use ES6 spreads for this: { ...map, key: value } - less efficient but certainly not too onerous syntax wise.

                                1. 1

                                  This is not ES2015 (ES6) but ES2017. ;)

                                  1. 1

                                    Actually, it is not standardized at all. It is still a stage 3 proposal.

                                    https://github.com/tc39/proposal-object-rest-spread
                                    https://github.com/tc39/proposals

                                2. 2

                                  Would anyone do that in real JS? (I don’t write JS, but if the answer is “no”, then I don’t see the point)

                                  As time goes on I have to admit that FP hype gets on my nerves. I enjoy the functional combinators as much as the next person, I love getting work done in Erlang, I am sometimes grouchy when writing Go when I can’t just map over a container, I love testing pure functions in any language, but maybe it has been python and rust that have made me a little happier in general to fall back on the boring procedural control structures (they support both paradigms, and yet people tend to use explicit iteration instead of the combinators pretty frequently). Readability is nice.

                                  1. 5

                                    Would anyone do that in real JS? (I don’t write JS, but if the answer is “no”, then I don’t see the point)

                                    Can’t speak for others, but we do that a lot in our React/Redux app to avoid mutation of objects from spreading.

                                    I have been using Python in a functional style, with LCs, map, filter and just about everything from the itertools and operator modules, but it was just not idiomatic. So when I switched to Clojure where this is the dominant way to do things it feels like coming home. I think the procedural control structures, especially when used in places where a map or fold would suffice makes it more difficult to understand what is going on because they could do anything.

                                    1. 3

                                      You might be interested in Coconut (http://coconut-lang.org).

                                      1. 1

                                        We should use the abstractions that minimize incidental complexity. I like using combinators when they fit on a single clean line. I tend to get lost when reading code that nests them, or is like a chain of 4+ combinators that hasn’t been documented more thoroughly than average. While I enjoy writing clojure and erlang (languages heavily reliant on combinators) they tend to be languages that I despise reading other people’s code for the most. I’m happy when people spend the time to make their stuff clean and fucrs-compliant, but it’s so damn painful for me to follow a nasty chain of nested combinators.

                                      2. 2

                                        Oh yeah, I have a React/Redux project that sometimes felt like half my code was calls to Object.assign. It’s the easiest way to do a shallow copy of an object so you’re not inadvertently passing references to the same object around and mutating them.

                                        Python does cause you to use more of the “boring procedural” control structures, and it does nominally support some functional programming, but some of it is more because of inconvenience than anything else. For example, I write far too many nested for/if loops where filter would be more natural if filter/map/lambda was less clunky and faster. I don’t think this makes it easier to read. I also think its reliance on list comprehensions is wrongheaded, because even now, after knowing Python for… ugh, nearly twenty years… I can never remember the order for iterating through nested lists in a list comprehension.

                                  1. 1

                                    This usage of the else keyword seems like an occasional useful but of semantic sugar, but dang, could they have at least chosen a different keyword? The word “else” makes absolutely no sense here! Fully exhausting a for loop doesn’t seem like an “else,” that seems like the normal usage of a for loop. In my opinion, it should have been called something like “then” to make it clear that it’s a continuation. Before I read this article, I assumed that the else keyword after a for loop would only execute if the loop never ran.

                                    1. 3

                                      The most common use case is searching for a particular value using the for loop. If found, a break is then executed and the else block is skipped. If no value is found, the else block is executed. This makes “else” make a little more sense as the keyword.

                                      1. 3

                                        Think of for/else like an if statement where the condition is evaluated multiple times. It’s basically just a more expressive version of:

                                        if any(c for c in conditions):
                                            # at least one condition is True
                                        else:
                                            # no condition is True
                                        

                                        In your mind, just replace for with if and it makes a sort of sense.

                                        1. 2

                                          I can’t seem to find a link, but I vaguely remember Guido remarking that he wishes he’d named it “nobreak”, which makes a lot more sense for me.

                                          1. 1

                                            Python is unfortunately heavy with syntax. Expressing for/else in a language like Haskell, Ocaml, and I assume Rust, is something more likely (and easily) done in a library.

                                          1. 2

                                            As a long-time Python lover, I now prefer Pony’s for/else construct which executes the else block if the for block did not execute at all.

                                            It would be really nice for a language to have both.

                                            1. 4

                                              This article reminds me that I want to play with Coconut (http://coconut-lang.org/) some more.

                                              1. 2

                                                Tangential question: do they make ortholinear keyboards with a normal number of rows? I’d really like to try one, but I’m not interested in giving up an actual spacebar, or number keys, or whatever else. I haven’t found any.

                                                1. 2

                                                  I too really like a normal-ish number of rows (and columns), so I bought a Diverge (see https://unikeyboard.io/product/diverge/). It has four rows and 14 columns in a split form-factor. I recently decided that I’d like it better as a one-piece keyboard and modified it like so: http://imgur.com/a/bqeDf.

                                                  You can check out my key map at http://www.keyboard-layout-editor.com/#/gists/86e0ada3e9525f5aa7edc202223b3e24

                                                  1. 2

                                                    olkb do also sell the Preonic, though there is also the option to cut your own plate and handwire/design your own PCB :P

                                                    To be fair, I could have used a 2u spacebar, I just wanted single buttons so I could reprogram one if I wanted.

                                                  1. 1

                                                    Lots of good advice, though I think tests would slow everything down too much when my types already enforce the same invariants in a better way.

                                                    1. 3

                                                      Perhaps your types are more sophisticated than I envision, but it seems that there are contracts that the types can not represent and would benefit from test verification.

                                                      1. 2

                                                        Occasionally there’s actual logic that you can’t confidently describe in general and need to give specific example cases for - that’s the scenario where I find tests useful. But I find such cases are very much the exception rather than the rule; most of the time once you structure the problem in the right way the answer ends up following directly, to the point that it never seems like you actually needed any logic at all.

                                                    1. 2

                                                      At the most recent PyCon there was a good presentation entitled “Constructive Code Review”: http://pyvideo.org/pycon-us-2017/constructive-code-review.html

                                                      1. 2

                                                        I hope he does well, I wonder if there have been similar projects like this in the past, and if they have ever actually reached the goals.

                                                        1. 2
                                                        1. 8

                                                          Some enterprising soul out there… please mass manufacture this! I’m dying for an Ergo Dox replacement that doesn’t presume the owner has extremely large hands (the thumb clusters are placed way out of my normal hand reach!)

                                                          1. 4

                                                            You might like the Diverge (now at version III with silly LEDs): https://unikeyboard.io/product/diverge/

                                                            I have a Diverge II and love it. The more natural thumb placement is one of the reasons I went with it over an ErgoDox. Also, I offset my key map “inward” by one column (i.e., g and h are the keys on the inward side of my home row) so that the thumb clusters are even more convenient and so that the outside columns can be used for symbols and meta keys akin to a standard layout.

                                                            1. 2

                                                              Hi; I sell assembled and DIY kits that don’t require a lot of hand movement:

                                                              https://atreus.technomancy.us

                                                              Not exactly mass-produced of course, since the demand isn’t there in terms of volume. Mine is similar to the one in the link except as a one-piece, so it’s easier to travel with. Also it has a wooden case instead of just using the bare PCB.