1. 21

    I recently discovered and appreciated expand-region.el’s “maintenance warning”:

    I use this package every day, and have been doing so for years. It just works. At least, it works for all my use cases. And if it breaks somehow, I fix it.

    However, it has become painfully clear to me that I don’t have time to fix problems I don’t have. It’s been years since I could keep pace with the issues and pull requests. Whenever I try, I keep getting feedback that my fix isn’t good enough by some standard I don’t particularly care about.

    So, I have closed the issue tracker and the pull requests. I hope you can happily use this package, just like I do. If it doesn’t work for you, then I’m sorry. Thankfully Emacs is infinitely malleable, you can probably fix it yourself.

    TLDR: I am still maintaining this package, but I am no longer crowdsourcing a list of issues.

    1. 4

      At least, it works for all my use cases

      incidentally, there was one thing in expand-region.el that bugged me for quite some time and yesterday I finally sat down and refused to give myself a break until I fixed it.

      ;; Expand region for whatever reason ignores lines when expanding, it should
      ;; start expanding from a word, then to a line, then to a paragraph, and so
      ;; on. But default implementation ignores the line expansion.
      
      (defun er/mark-line ()
        "Marks entire 'logical' line."
        (interactive)
        (evil-end-of-line)
        (set-mark (point))
        (evil-first-non-blank))
      
      (setq
       er/try-expand-list
       '(er/mark-word
         er/mark-symbol
         er/mark-symbol-with-prefix
         er/mark-line
         er/mark-next-accessor
         er/mark-method-call er/mark-inside-quotes
         er/mark-outside-quotes er/mark-inside-pairs
         er/mark-outside-pairs er/mark-comment er/mark-url
         er/mark-email er/mark-defun))
      
    1. 16

      Not sure who told the author of this piece that security by obscurity is bad, but what I have always heard is that security through obscurity is simply not to be relied upon. It’s not that you shouldn’t do it, but you should assume it will be defeated.

      So if you want to change your SSH port, fine, but don’t leave password authentication enabled and go thinking you’re safe

      1. 5

        “Security by obscurity is bad” is the line that is parroted by many who don’t understand.

        1. 1

          There seems to be a consensus that “6!x8GWqufk-EL6tv_A4.E” is a stronger password than “letmein”. The only significant difference I see between these passwords is obscurity.

          I wonder if this can be considered an example of “security by obscurity” that is widely considered neither “bad” nor likely to be defeated?

          1. 19

            There’s a long history of distinguishing obscure information like passwords or cryptographic keys from obscure methods like encryption algorithms. The key difference, I think, is that the only purpose of the secret information is to be secret, and you can measure its properties in that respect; that’s not true of code that’s meant to be secret, and competing requirements like “needs to run on someone else’s machine” make obscurity an unreliable crutch in many situations.

            EDIT: Another key difference is that “obscurity” can be taken as “the information is still present in whatever the adversary can access, it’s just harder to read”, e.g. obfuscated source code in a JavaScript file. That’s also different from a secret like a password, which should be protected by not exposing it at all.

            Like most maxims, “Security through obscurity is bad” is an oversimplification, but in my opinion it’s a good rule of thumb to be disregarded only when you know what you’re doing.

            1. 3

              I think the “security by obscurity is bad” aphorism is quite a bit narrower than the original meaning: security by algorithmic obscurity is bad because one has to presume that a motivated attacker will be able to identify or acquire the algorithm. Therefore, any additional security from algorithmic obscurity is ephemeral, and sacrifices the very real benefit of allowing the cryptographic community to examine the algorithm for weakness (since weaknesses are often non-obvious, especially to the creator). As such, one could say that it’s a corollary to one of Kerchoff’s principles (rephrased by Shannon as simply [assume that] “the enemy knows the system”).

              The aphorism has been adopted by those lacking the technical knowledge to understand the full meaning and generalized further than it should be.

              The artificial distinction between “secrecy” (which is necessary to protect the key) and “obscurity” (which is generally used to apply to the system) is most important to understanding the aphorism and unfortunately the distinction appears non-obvious to the layman and leads to confusion.

              Edit: Ugh, just realized that this is essentially paraphrasing an old Robert Graham blog post: https://blog.erratasec.com/2016/10/cliche-security-through-obscurity-again.html. Also corrected a sentence in which I nonsensically used “security” in place of “obscurity.”

              1. 2

                That definition makes sense and clears up something I had been wondering about for a long time. Thanks!

              2. 3

                I think to rectify these definitions you need to have an idea of the system under test. The system expects, takes in, comments on the quality of its inputs and is required, when assumptions are satisfied, to produce trusted output.

                Security by obscurity says that the system is more difficult to break if the adversary doesn’t know what it is. This is generally true, it at least adds research costs to the adversary and may even substantially increase the effort required to make an attack.

                The general maxim is that security by obscurity should not be relied upon. In other words, you should have confidence that your system is still reliable even in the circumstance where your adversary knows everything about it.

                So, ultimately, the quality of the password isn’t really about the system. The system could, for instance, choose to reject bad passwords and improve its quality. The adversary knowing about the system now knows not to test a certain subset of weak passwords (no chance of success) but the system is still defensible.

                1. 2

                  The difference is not only obscurity; it’s (quantifiable) cryptographic strength.

                  Your website uses 256-bit AES, because it’s impossible to brute-force without using more energy than is contained in our solar system. You wouldn’t use 64-bit AES, though. Is the difference that the former algorithm’s key is more obscure?

                  1. 1

                    An obscure system will be understood, and therefore cracked if its only advantage was obscurity. Passphrase-protected crypto systems are not obscure. Their operation is laid open for all to see, including what they do with passwords. If you can go from that to cracking specific cryptexts, that’s a flaw everyone will admit. However, if you must skip the system entirely and beat a passphrase out of someone in order to break the cryptext, that’s no flaw of the system under discussion. It might be a flaw of some larger system, but I believe it is universally acknowledged that, if you’re beating a passphrase out of someone and will only stop when you get the information you’re looking for or you kill the person you’re beating, the person will almost certainly give the passphrase before they die.

                1. 7

                  Buy a good [~10% of bicycle value] lock

                  I give this same advice to new bike owners (who are likely to underspend on their lock), but this advice now really grates on me. I own a seven thousand dollar bike (bikes that are friendly to people with disabilities aren’t cheap 😞). How do I protect it when I’m away from home? $700 bike locks aren’t really a thing, and if you if you thought bike insurance rates on “cheap” bikes were bad…

                  1. 5

                    Compared to a typical $7k bike, I’d guess that yours is far more difficult to fence. I hear that a stolen bike is usually chopped up for parts, and you have

                    • an asymmetrical wheel set in two unusual sizes
                    • no stem or handlebars
                    • a frame not compatible with typical wheel sets

                    So perhaps it has the theft appeal of an inexpensive bike? (Despite how cool I think it is :)

                    I would still downgrade or lock your rear seat, though!

                    1. 2

                      This comment is a really insightful addition to @calpaterson’s threat model. Even Powertool Percy’s fences might be stymied by, say, a penny farthing. (Or at least, I really hope that’d be the case.)

                      Due to COVID, we haven’t had a situation in the past year where we’ve left our bike outside unattended for any amount of time, but I expect our eventual theft-mitigation efforts will be some combination of:

                      • locks, and more locks
                      • paint the bike to be more distinctive
                      • embed a gps tracker (or two?) in the frame
                      • remove the steering pin when leaving the bike unattended
                      • insure the bike (ugh)

                      Despite how cool I think it is :)

                      It’s awesome. Totally has ruined “normal” bikes for me. The ability to easily maintain conversations with someone on a long ride is a game-changer in itself!

                    2. 4

                      Obviously seven $100 locks. /s

                      1. 2

                        That’s a really cool bike! Unlike a normal recumbent bike, I’m not seeing anywhere for the rider in front to hold onto with their hands. Is there a seatbelt or some other solution so that the rider in front doesn’t fly off during an emergency stop?

                        1. 2

                          There are handles beneath the front seat! You can also order a seatbelt as an accessory, but the font seat feels very secure—even during abrupt braking!

                          1. 1

                            a normal recumbent bike

                            No such thing. An “ordinary” bicycle frame is actually a high-wheeler. The typical diamond frame design is a “safety”. Anyway, USS has been one school of recumbent design since the 1970s at least.

                          2. 2

                            How do I protect it when I’m away from home?

                            The obvious first choice is to bring it into your home. If that’s not an option, maybe you can rent space in a neighbor’s garage or at some nearby storage service? There is no safe way to lock a bike up outside for multiple hours (see Percy, from the article).

                            1. 1

                              There is no safe way to lock a bike up outside for multiple hours (see Percy, from the article).

                              Given a thief with an angle grinder, there isn’t even a safe way to lock a bike up outside for multiple minutes! Of course, I can keep the bike safe at home, but at some point it’s more furniture than bike.

                              1. 1

                                Ah, I read your “when I’m away from home” as “when I’m away and the bike is at home”, which, in hindsight, doesn’t make much sense, oops. Sorry.

                                When I drag my bike into areas where theft is seemingly high, I get very unshy about taking my bike into the building and stashing it next to the receptionist, cashiers, etc. Most of the time they don’t seem to care, but I suspect this could be different if you’re in an area where cyclists are looked down on more than they are here..

                            2. 2

                              $700 bike locks aren’t really a thing

                              https://securityforbikes.com/products.php?cat=Extreme+Security+Chain+and+Lock+deals

                              I bought some of the products from Stephen Briggs (I think was a founder together with his wife Sarah. Company name was Pragmasis), this was about 9-10 years ago or so.

                              I am overall very happy with product, and the quality of interaction I had with Stephen. Thankfully, the chains (I bought several, as had different needs for different weight/length configs) – were not tested.

                            1. 2

                              I really enjoyed this, thank you.

                              Either type of lock can be defeated, but each requires a different large, bulky tool which is useless against the other.

                              I wonder if Sheldon was assuming here that a U-lock is typically defeated with a portable jack?

                              1. 15

                                Sheldon Brown died well before portable angle grinders became common.

                                1. 5

                                  I’m glad you enjoyed it and thanks for saying so.

                                  I agree that he’s probably referring to an airjack. It could be that was common practice among thieves when the article was originally written. All the thefts I have personally heard of in the last few years have used angle grinders - obviously you can tell by looking at the remains of the lock what was used.

                                  1. 2

                                    I’ve bust open (my own) D-lock with a bog standard car jack - makes a satisfying bang when it blows. Interestingly, I did this on a busy Saturday on Slough (a notoriously rubbish UK town) high street, and received no attention whatsoever..

                                  1. 3

                                    Keeping track of your coordinate systems and scaling factors can be difficult, and it’s probably worth doing this in a smart way.

                                    I have recently been enjoying elm-geometry’s approach to tracking coordinate systems using static types. Any type representing a geometric object takes the coordinate system as a type parameter (and the unit of length as another parameter).

                                    1. 2

                                      I’d really like a HTTP proxy inside Emacs so that I can navigate and edit requests and responses with all of the usual text editing tricks. It would be something like a cross between mitmproxy and magit.

                                      1. 2

                                        I’m not sure if this is what you are looking for… Maybe it is! https://github.com/skeeto/skewer-mode

                                      1. 5

                                        Incomplete list of things that are not strings:

                                        • Password

                                        This is the least obvious one to me, and I notice it’s the only one for which you didn’t give examples of typed representations. Do you know of any?

                                        1. 6

                                          I don’t quite agree they’re not strings. They are strings at least from user perspective. However, they would benefit from a type that isn’t a generic string:

                                          • hashing uses bytes, and bytes depend on encoding, so you should be consistent with that (e.g. always hash NFC-normalized UTF-8 bytes)
                                          • you don’t want passwords get printed in logs or data dumps. A non-printable container could help with that.
                                          • for extra level of paranoia you may want to zero out memory when the password object is freed.
                                          1. 5

                                            In Haskell

                                            newtype Password = Password String
                                            

                                            in other words, it’s simply a different type with an identical representation, String.

                                            Why does that matter? In my opinion, you should treat passwords as mostly opaque identifiers. One possible design thought experiment is “Should Password support length operations?”

                                            • Pro: yes, it should, because we must validate the length of passwords
                                            • Con: no, it shouldn’t, because we should validate the length of a string representation of the password prior to legally converting it into a password which is now opaque

                                            Both feel reasonable, slightly different styles. There are other possible paths here too “No, Password should only support entropy evaluations”. But in any case, we can discuss how String and Password differ.

                                            1. 1

                                              Yeah I was slightly confused by this one too. My best guess is that passwords are subject to restrictions (length, requiring non alphanumeric characters, etc.) that a plain string isn’t.

                                              1. 7

                                                Passwords cannot be safely compared for equality using string functions; you can run into timing attacks if you do.

                                                1. 6

                                                  Not that you should ever have to compare the plaintext of a password..

                                            1. 6

                                              What’s important is that the codebase is readable, and keeping a consistent tabbing and bracing style is more

                                              Agree.

                                              If your team does agree to change the tabbing and/or bracing style, don’t do it gradually. … Instead, use an automated tool to reformat the code.

                                              I understand this point of view, but it is also important to mention that this destroys the history in your version control system (mercurial, subversion, git, fossil etc.). The annotate/blame tool will become useless and will point to a single person (often the junior developer who was assigned this boring task), you will lose the information why particular lines were written, by whom and when (of course, the information is still stored somewhere in the history, but is is practically inaccessible now). It will be difficult to distinguish important changes from formatting. And if you develop in multiple branches and merge or cherry-pick across them, the automatic process that usually runs smoothly will fail now and will require expensive human work… just because the older branches/versions have different formatting.

                                              The correct solution would require a complete history rewrite. Literally rewrite every single commit, reformat its code while keeping the author, date and message metadata unmodified. But: this is so many commits, so many years… in a distributed version control system, it changes the hashes, so if someone from outside references to them, this references will become invalid (e.g. links from external websites)… or there might be a bug in the formatting tool that makes some significant/logical changes in the code – then if a customer asks you for a „v3.0.0 with just a small fix“, he might get completely different version with many other changes… I am afraid that the risks are higher than benefits.

                                              Perhaps suggest a style that a well-known open-source project uses, or a well-known style guide published by Microsoft or Apple.

                                              I recommend talking rather about free software than open source and avoid promoting evil corporations.

                                              1. 3

                                                “The good thing about standards is that there are so many to choose from”.

                                                Anecdotally, GNU C formatting is one of the less popular styles.

                                                I’m neutral towards Go but I do appreciate that the language designers shortcircuited a lot of debate and saved countless wasted hours arguing by including a formatter in the language.

                                                1. 1

                                                  of course, the information is still stored somewhere in the history, but is is practically inaccessible now

                                                  Do that many people know enough git to use blame but not enough to know git blame <revision>^ -- path/to/check?

                                                  I don’t expect many people to know how to use blame but I’d (perhaps wrongly) assumed that those who do could navigate more than one layer of history with relative ease.

                                                  1. 2

                                                    You can also

                                                    git config blame.ignoreRevsFile .git-blame-ignore-revs
                                                    

                                                    so that revisions listed in .git-blame-ignore-revs are automatically ignored by git-blame in the future.

                                                    1. 2

                                                      I didn’t know that command line invocation! Looking at github, the blame page looks something like:

                                                      commit header (with link), date, link to blame at that commit, line number, code

                                                      The commit header link, and the previous blame version, are useful in navigating changes.

                                                      1. 1

                                                        I don’t use git blame; my editor always shows the latest change for every line.

                                                    1. 15

                                                      This reminded me of a short story: Before the law sits a Gatekeeper

                                                      1. 4

                                                        This is really nicely assembled. Well worth the click.

                                                      1. 3

                                                        While Nix is still the recommended way to install, we now also have auto-created Docker images for neuron.

                                                        Thanks for doing this! I attempted to try out Neuron once before, and setting up Nix under macOS on an encrypted disk turned out to be a messy and scarcely documented process that I eventually gave up on. I’m looking forward to making another attempt.

                                                        1. 5

                                                          FWIW, if you tried installing Nix on Catalina before June, you may have more luck re-trying it now. There’s still one case the installer doesn’t really solve for–older pre-T2 hardware also using FileVault FDE–but if you don’t fit in that camp the experience shouldn’t be the disaster it was from October to May.

                                                          1. 5

                                                            I unfortunately am in that camp, but thank you for reminding me of exactly what the problematic case is. I may get my hands on a newer Mac soon.

                                                            1. 3

                                                              We got a tip on that case as well, but the only implementation I’m aware of yet is something in Ruby that was written for a company’s dev bootstrap scripts and we haven’t found someone with the time/interest/hardware to translate and test this yet. (TLDR; encrypting the new volume and putting the credential in the system keychain reportedly solves race-condition issues we’ve seen with the login keychain that have kept us from trying to handle that case yet).

                                                              Someone recently expressed interest in tackling it, so I’m hopeful, but until there’s a PR I’ll try to avoid suggesting it’s right around the corner :)

                                                              Oh. Also. A question mark we still have is whether anyone in this camp will object to the installer creating a new volume, generating an encryption passphrase without user input, and putting the credential into the system keychain on its own. Thoughts?

                                                              1. 1

                                                                That sounds great to me, assuming the the installer asks first. I haven’t had time to follow developments this issue on GH, so thank you for the excellent summary!

                                                          2. 3

                                                            Next step, someone needs to build a Whalebrew-friendly image based on Neuron’s or modify it to be compatible with Whalebrew.

                                                            Edit: opened a feature suggestion ticket: https://github.com/srid/neuron/issues/307

                                                          1. 2

                                                            What about key ghosting[1] in such keyboard solution?

                                                            [1] https://drakeirving.github.io/MultiKeyDisplay/

                                                            1. 6

                                                              The usual solution is to add a diode after every switch.

                                                              1. 1

                                                                What @C-Keen said. Each of the blue-gray segments in this wiring diagram corresponds to a diode:

                                                                https://user-images.githubusercontent.com/238331/86537993-b8afa480-beb8-11ea-801e-b35586f2f2f0.png

                                                              1. 6

                                                                I’ve been using Hugo as of late due to ox-hugo, which allows me to write blog posts in Emacs’ Org mode. It’s pretty wonderful for tracking WIP posts and what else to write with Org.

                                                                1. 4

                                                                  The other day I was digging into someone’s personal wiki’s implementation and found that they’re using ox-hugo to generate the wiki from their org-roam notes 👏

                                                                  1. 5

                                                                    That’s not just anyone - that’s actually the maintainer of org-roam, so it makes sense that they’d use it on a personal wiki as well. Cool find.

                                                                1. 1

                                                                  It’s super convenient that Rust has &str (pointer + length, immutable) and types can auto-dereference to it. This works as the lowest common denominator for strings, so using a custom small string type is practical.

                                                                  This is in contrast with languages like ObjC or Swift, where there is one blessed string type. That type has to be everything for everyone, and needs to support small strings, large strings, fast appends, searches, and everything in between, because any other string type would be a second-class citizen.

                                                                  1. 3

                                                                    Did you know that NSString is a class cluster? It has a number of private subclasses which function as alternate implementations.

                                                                    1. 1

                                                                      Yeah, it’s a very clever solution for a type that needs to do a good job for many very different workloads, given that ObjC already pays the cost of dynamic dispatch on every call.

                                                                  1. 3

                                                                    Isn’t caps lock ->control the canonical remap? On the home row, not good for anything else…?

                                                                    1. 2

                                                                      Yeah, I really don’t understand why people are advocating for remapping extremely useful keys like enter or A to control. That seems like it would cause way more problems than it solves.

                                                                      1. 5

                                                                        The article says that it’s a dual-function remap - holding enter causes it to act like control, but merely tapping it causes it to continue to act like enter.

                                                                        1. 2

                                                                          That’ll teach me to skim, I guess.

                                                                          I still dislike this though. I don’t like keys that simultaneously act as regular keys and modifier keys. The Windows key on PCs is a prime example: there are a bunch of shortcuts bound to Windows+, but tapping Windows alone causes the start menu to come up. When using Windows, I frequently find myself going for a keyboard shortcut, typing Windows, changing my mind, releasing Windows, and then having to deal with the annoyance of the Start menu appearing.

                                                                          Given that enter is used as a “submit” key on a huge number of programs, I expect it would be even worse.

                                                                          1. 4

                                                                            That’s an implementation problem, not a conceptual problem. The way that xcape (and theoretically any other implementation of this) works (or could work) is that if you hold down the key long enough, even if you release it without pressing anything else, it acts like the modifier key and doesn’t send the “tap” event. My xcape is configured to have a 250 ms delay - if I press left shift as part of a chord, and then change my mind, if I just make sure that I hold the shift key for the required quarter of a second, the left parenthesis (tap functionality) is not emitted.

                                                                            1. 1

                                                                              The way I see it, the existence (and arbitrariness) of that 250 ms parameter is strong evidence that it is a fundamental conceptual problem. I’m with @Kronopath in that having both modifier and non-modifier functionality on the same physical key drives me thoroughly up the wall.

                                                                              And for anyone else who feels similarly, a Firefox setting I was relieved to stumble across a few years ago: in about:config, set ui.key.menuAccessKeyFocuses to false. And if (as I do) you keep the menu bar hidden, note that it will unfortunately auto-revert this setting to true if you show and then hide the menu bar manually (e.g. via a right-click on the tab bar), though you can use F10 to show it temporarily and avoid that particular quirk (or bug?).

                                                                              1. 1

                                                                                I don’t quite see how the existence of a timeout parameter implies a fundamental conceptual parameter - could you clarify? The universe, and programming, are filled with timing-related parameters, such as the TCP connection timeout parameter, the length of time you have to hold down a key before it is repeated, or the oscillation frequency of a Josephson Junction when exposed to a particular voltage. This particular parameter isn’t actually arbitrary, either - I chose it myself based on my preferences and after some experimentation to find a comfortable value. This is no more arbitrary than you picking your mouse’s DPI.

                                                                                It’s unfortunate that the functionality “drives you up a wall”, but that doesn’t actually mean that it’s a bad idea. For instance, vim-style modal editing is very unpleasant for some people (mostly people who eventually switch to emacs) - but that doesn’t have anything to do with the soundness of the idea, nor its efficiency.

                                                                                1. 1

                                                                                  Sure, it’s not arbitrary for any given individual, but overall it’s a magic number with no clear “right” value, whereas otherwise it’s a simple matter of which keys were pressed and released in which order, no guessing or heuristics involved. Adding time durations as semantically-significant signals where they otherwise didn’t factor in at all is a fundamental change to the signaling mechanism.

                                                                                  And I’m not arguing against time-based behavior in general (certainly there are contexts in which it’s appropriate) but I find predictable, synchronous behavior highly preferable unless there’s a very compelling reason to introduce asynchrony. The sort of time-based behavior you’ve got is, ultimately, a race condition – and for people who are okay with it that’s fine, but I don’t like it when software (e.g. Firefox, or Windows as mentioned upthread) bakes it in.

                                                                                  1. 1

                                                                                    a magic number with no clear “right” value

                                                                                    I don’t think that this is right. I see a clear “right” value - that which works for you. Actually, it’s a range of values, bounded on the lower end by how quickly you tap individual keys, and on the upper end by how long you want to have to hold the modifier key in case you decide to “back out” of a chord.

                                                                                    no guessing or heuristics involved

                                                                                    There’s no guessing or heuristics involved here, either. You know exactly how long you have to press a modifier key for in order to send the “hold” command, as opposed to the “tap” command. The fact that humans don’t have very high precision on their internal timers in order to measure that duration is irrelevant - you can just hold the key until you’re sure it won’t act like a tap. Most people can’t tell the difference between 250 milliseconds and 260, but they sure can tell the difference between 250 and 1000 - and since you can train yourself to rarely decide to back out of key chords, the extra 0.75s is insignificant.

                                                                                    Adding time durations as semantically-significant signals where they otherwise didn’t factor in at all is a fundamental change to the signaling mechanism.

                                                                                    A fundamental change that is useful, makes perfect logical sense, and is easy to adapt to. I cannot recall the last time that I accidentally emitted a parenthesis by accident using space-cadet shift keys (tap to emit parenthesis, hold to act like shift) over the past few weeks, and it’s pretty obviously useful to take a key that does nothing when you tap it by yourself (e.g. shift) and make it do something when tapped by itself, in a way that doesn’t reduce the functionality of your computer in any way whatsoever.

                                                                                    I find predictable, synchronous behavior highly preferable

                                                                                    You can prefer it, but that doesn’t mean that dual-function keys have a “fundamental conceptual problem”. That’s what I’m arguing against - not what you prefer to use, but the idea that there’s somehow something wrong with the idea itself.

                                                                                    a race condition

                                                                                    This isn’t a race condition. The Wikipedia page on race conditions[1] defines it as “the condition of an electronics, software, or other system where the system’s substantive behavior is dependent on the sequence or timing of other uncontrollable events”. The order in which you press keys are not “uncontrollable events”. You have complete control over the order in which you press keys using your fingers - or, rather, that’s the model of human hands that most people operate under.

                                                                                    Edit: I think I see where you might be getting the idea that this is similar to a race condition - you might be thinking that if you don’t hold a key for the threshold e.g. 250 ms, it registers as a tap, even if you press another key. The way that actually it works is that there are three cases: (1) if you press the key and then release it sooner than THRESHOLD later without pressing another, it registers as a tap (2) if you press the key and don’t release it less than THRESHOLD later, it acts as a modifier (nothing happens) (3) if you press the key and then another key (a chord) before letting go of the first, it acts like a normal chord, regardless of whether you held the dual-function key for longer or shorter than the threshold. That is, you do NOT have to hold the chord for the threshold duration in order for the key to be counted as a “hold”/modifier instead of a “tap” - if you hold the key and press another, it acts like a modifier, no matter whether you hold it for longer or shorter than the threshold.

                                                                                    Windows as mentioned upthread

                                                                                    As also mentioned upthread, that’s an implementation problem, not a conceptual problem. You’re taking a bug in an implementation and conflating that with the idea that is represented by the implementation.

                                                                                    [1] https://en.wikipedia.org/wiki/Race_condition

                                                                      2. 2

                                                                        A great many Emacs users remap the infrequently used CapsLock key to Control to alleviate partially the problem with the accessibility of the control keys. That, while useful, is not sufficient for the optimal typing experience, since that way you’re breaking the key symmetry on both sides of your keyboard. Also - your right pinky has to go much further than your left one, while you’re typing. Many people seem to be using only the left Control and I guess they’re not particularly bothered by this, but touch typists like me are generally quite bothered by such things.

                                                                        1. 1

                                                                          Who are you quoting?

                                                                          1. 2

                                                                            @bbatsov in their previous article that they link to in the opening note:

                                                                            Note: Check out my original article from 2013 about the rationale behind this remapping.

                                                                          2. 1

                                                                            Thanks, I missed that link/follow in the original. I still don’t understand though.

                                                                            I don’t see how using Enter instead of capslock is more symmetrical. If anything it is less? the enter key is further from the letter home row than capslock is.

                                                                            Also - your right pinky has to go much further than your left one, while you’re typing

                                                                            So having the left little finger go a little more to the left (for capslock) is more symmetrical, right? And it already does this for shift anyway (just below capslock).

                                                                            Sorry if it seems like I’m trying to pick nits, I’m really not getting the argument.

                                                                        1. 6

                                                                          If someone’s using another approach to achieve the same result I’d love to hear about it!

                                                                          I use a keyboard that runs the QMK firmware, and my dual-function keys are all defined at the firmware level. QMK lets you fine-tune the parameters of tap-hold behavior, but the defaults are good.

                                                                          I chose to remap “;” to Control. It’s been great.

                                                                          1. 2

                                                                            I had a few of these dual function keys set up with my QMK board and I found that getting the timing is tricky because you can’t hit the key in succession very well. Another thing is that if you hit the key and release it, then hit it again without waiting properly, it might register as a tap instead of a hold.

                                                                            I’m sure these things are fixable in firmware. It’s just another thing you might have to adjust.

                                                                          1. 1

                                                                            And since keywords naturally go between their arguments, there is no need for “operators”, as a very different and special syntax form. You just allow some “binary” keywords to look a little different, so instead of 2 multiply:3 you can write 2 * 3.

                                                                            How does this approach support operator precedence?

                                                                            1. 6

                                                                              It doesn’t. Or at least Smalltalk doesn’t, and neither does my baby, Objective-Smalltalk.

                                                                              There is some form of precedence: unary binds stronger than binary binds stronger than keyword.

                                                                              Other than that, evaluation is strictly left-to-right, which apparently was the option that caused the least confusion overall, even if it discarded old conventions.

                                                                              1. 5

                                                                                Operator precedence is a dangerous set of conventions to learn, or just bypass with a lot of parentheses. It is not a feature, but a side effect.

                                                                              1. 7

                                                                                I really liked this article. Having gotten in functional programming with Elm for the last 2 years, the nonEmpty type is brilliant, and I’m going to re-implement it in Elm. The tie in of language theoretic security was a nice touch. I’ve been promoting that at work for a while.

                                                                                it’s extremely easy to forget.

                                                                                Anything that can be forgotten by a developer, will be forgotten.

                                                                                A better solution is to choose a data structure that disallows duplicate keys by construction

                                                                                “Making Impossible States Impossible” by Richard Feldman is a talk on effectively the same concept.

                                                                                1. 9

                                                                                  However, sometimes it is quite annoying to conflate the type and structure of the list with the fact that it is nonempty. For example the functions from Data.List don’t work with the NonEmpty type. I think the paper on “departed proofs” linked near the bottom points to a different approach where various claims about a value are represented as separate proof objects.

                                                                                  1. 4

                                                                                    In this instance, the fact that both [] (lists) and NonEmpty are instances of Foldable will help: http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Foldable.html

                                                                                  2. 2

                                                                                    I ran across a case of the nonempty approach in File.Select.files the other day:

                                                                                    Notice that the function that turns the resulting files into a message takes two arguments: the first file selected and then a list of the other selected files. This guarantees that one file (or more) is available. This way you do not have to handle “no files loaded” in your code. That can never happen!

                                                                                    1. 1

                                                                                      Nice find! I’ve actually used that before but hadn’t made the connection, haha.

                                                                                  1. 13

                                                                                    First, let’s stipulate that lots of people don’t know what they’re doing or why in technology development. Unless you’re coding, it doesn’t really feel as if something is going on, i.e., it’s a waste of time. In most cases, it is. Your instincts are correct.

                                                                                    Second, I did not finish reading the article. I did not finish because the author doesn’t know what they’re talking about, or rather he is responding to the way he’s been taught and observed stand-ups happening, not how they actually work.

                                                                                    ”…The majority of meetings are a waste of time. And in my opinion, one flavor of meeting that tops the charts in uselessness is the “status update” meeting. You know this meeting— the meeting where everyone gets together to share what they’ve been doing…”

                                                                                    Yes. Shoot for meeting-free work areas. The way you do that is dynamically get together and talk about stuff as needed. The way you do that? A stand-ups. Stand-ups are the (in my mind) only fixed time and place where everybody gets together and asks for help. You don’t give status, you don’t report to anybody, you don’t ask or answer questions unless you can’t make out what the person is saying. You just take a minute and verbally review where you are and ask for help if you need it. Then we get to work. Maybe somebody has a problem that is going to be huge, so we hang out for an hour or two trying to solve it. Maybe nothing’s going on. Great! Two minutes later we’re all working on our own stuff. Works either way. It’s dynamic.

                                                                                    The problem here is 1) people are used to status reports so that’s what they gravitate towards doing, 2) there’s pressure to build-up your work and deny having any problems, and 3) when it’s working right there is no positive feedback. It’s like brushing your teeth. You do it, it’s quick, and if you’re doing it right you never think about it. In fact, the more you think about it, probably the worse you’re doing it.

                                                                                    1. 4

                                                                                      In my experience, unless time limits for people talking are heavily enforced, they are largely a waste of time. If no one is willing/able to enforce hard limits for the amount of time any one person has in the stand up to talk, you almost always end up with senior people on the team who enjoy listening to themselves speak taking up 95% of the time, with the remaining 5% of the time given to those who need real help.

                                                                                      1. 9

                                                                                        Yeah they can go wrong in a lot of ways. Turns out having people talk to one another isn’t as simple as writing a for-next loop (grin).

                                                                                        One of the fun things I used to do when teaching standups is a game where a team has to do a standup, but one person is the “ringer” – they’re given a dysfunction to display and the rest of the group has to deal with it. I found it was much easier to teach dysfunctions when people were only playing as opposed to directly addressing them.

                                                                                        There’s also the guy that has to question everything, the one who never needs help, the one talking about nothing to do with work, and so on.

                                                                                        1. 1

                                                                                          That’s a fascinating approach. Thanks for sharing it.

                                                                                    1. 23

                                                                                      For some spooky Halloween times, take a midnight stroll through Google’s graveyard!

                                                                                      There’s a lot of hidden terrors in there that time has forgotten.

                                                                                      1. 4

                                                                                        This list is a really neat blast from the past. It’d be cool to see a category for companies that were literally killed by google (e.g. Kiko, a calendar app made just before Google Calendar came out, which Google squashed like a bug).

                                                                                        1. 8

                                                                                          I don’t think even Google can get away with literally killing competitors. Yet.

                                                                                          1. 4

                                                                                            Depends on the country and if they use third parties that distance their brand from the act. See Betchel Corp vs Bolivian citizens that wanted drinking water as an example. Maybe Coca Cola in Colombia vs union people.

                                                                                            If anything, I’m surprised at how civil things normally are with rich companies. Probably just because they can use lobbyists and lawyers to get away with most stuff. The failures are usually a drop in their bucket of profit.

                                                                                            1. 4

                                                                                              Perhaps not competitors, but certainly people who get in the way of profits get killed, eg see the case of Shell in Nigeria: http://news.bbc.co.uk/2/hi/africa/8090493.stm

                                                                                              Hundreds of activists are killed every year, we just don’t hear about it much.

                                                                                          2. 1

                                                                                            You joke but I recall there was (is?) a “storage graveyard” in their Chicago office filled with CDs, casette tapes, floppies, and other physical media.

                                                                                          1. 3

                                                                                            I clicked through to https://gather.wtf and clicked on an event, then “Attend”. I got an endless spinner and this error in the console:

                                                                                            Error: submitAndWatchExtrinsic (extrinsic: Extrinsic): ExtrinsicStatus:: 1010: Invalid Transaction: Payment

                                                                                            1. 2

                                                                                              Yeah, it’s a hackathon project and though the backend/blockchain is complete, the UI is far from that…

                                                                                              1. 2

                                                                                                Not just an UI has to be added, there also have to be policies about privacy and who gets to see what. Not everyone wants their regular visits to a fetish club recorded on a public, immutable blockchain.