Threads for roryokane

    1. 1

      Is it possible to use IDEs like IDEA with Mill?

      1. 1
    2. 9

      Why am I passing x and y to that rectangle at all? They’re never used.

      1. 5

        The “// Getters omitted” line implies there will be a getX() and getY() that read x and y.

    3. 3

      While I’d rather this feature not exist, it’s not as dangerous as it might sound. The Topics API does not give advertisers any powers they don’t currently have with third-party cookies.

      • Normal users who don’t modify their browser settings will be tracked the same amount as before.
      • Expert users who already configured blocking of third-party cookies now have to remember to turn off one more setting in chrome://settings/adPrivacy. It’s merely an annoyance.

      You might assume that Chrome sends to advertisers topics derived from your entire browsing history, but it does not. Chrome sends only topics derived from your history on pages that used that advertiser. So if a user with default settings visits a porn website with its own ad network, then visits a blog that uses Google Ads, Chrome will (still) not tell Google Ads that that user is interested in porn.

      The biggest risk of this change is that it makes it easier for Google to later remove the Chrome setting that allows the user to not send topics. Would they really do that? Even today, Chrome supports blocking of third-party cookies both natively at chrome://settings/cookies and using browser extensions. Then again, Google is in the process of crippling Chrome extensions’ ad-blocking capabilities with Chrome Extension Manifest V3, so they have shown a desire to reduce the browser’s privacy protections when they think they can get away with it.

    4. 7

      Tabular figures are can also be accessed on the web with the CSS property value font-feature-settings: 'tnum'.

      1. 9

        The page you linked recommends using the higher-level font-variant or font-variant-* properties instead of font-feature-settings. In this case, the appropriate property is font-variant-numeric:

        font-variant-numeric: tabular-nums;
    5. 3

      What‘s their (planned) business model?

      1. 2


        Oven will provide incredibly fast serverless hosting & continuous integration for backend & frontend JavaScript apps — and it will be powered by Bun.

        The plan is to run our own servers on the edge in datacenters around the world. Oven will leverage end-to-end integration of the entire JavaScript stack (down to the hardware) to make new things possible.

        As far as I can tell, Bun tooling is to Oven as Deno tooling is to Deno Deploy: a free platform that advertises a paid service.

        1. 3

          Hmm. I think serverless in the heroku sense is great (you provide code, and they worry about deployment, logs, servers, backups, etc), but serverless in the lambda or cloudflare workers sense has been kind of a flop for everything but glue code and hacks.

    6. 3

      I don’t write a ton of go but I feel like using [os.DirFS] to open the uploadsDirectory beforehand would be less error prone than cleaning the path each time?

      1. 3

        Your comment’s link is missing: os.DirFS

    7. 4

      It’s self-contradictory re map key ordering:

      The order of object members in an I-JSON message does not change the meaning of an I-JSON message. A receiving implementation MAY treat two I-JSON messages as equivalent if they differ only in the order of the object members.

      Otherwise it’s not bad at all. (Limited integer range notwithstanding…) I mean, considering. If you have to deal with JSON, this helps.

        1. 5

          I see the contradiction. Despite the first quoted sentence, the second quoted sentence permits an implementation where the “order of object members in an I-JSON message” does “change the meaning of an I-JSON message”. The second sentence would be consistent with the first sentence if it said “MUST” instead of “MAY”.

    8. 3

      I’m using, e.g.:

      <html lang="ar-MA" dir="rtl">

      All elements seem totally fine for RTL? If I add dir="auto" to an <input> field, it makes it LTR again. What am I missing?

      Edit: I was surprised how easy it was to fix this, but of course it wouldn’t be the first time that the easy solution is the wrong solution.

      1. 12

        Yes, if the whole site is RTL, then the individual inputs are RTL as well. The recommendation to set dir="auto" is aimed at authors of LTR websites with some users who write in RTL languages, or, conversely, authors of RTL websites with LTR users.

        For example, a site for managing a library of books might have its navigation and documentation written in LTR English, but might accept book titles in RTL Arabic. If the field to enter a book title is just an <input>, the typed Arabic book title will be LTR in the input field. <input dir="auto"> allows the field to display either English or Arabic book titles with correct directionality.

        Even if the site shows text with the correct directionality in the input field, it would still need to show the rendered book title correctly everywhere else it is used (such as an h1 or a li). I don’t know much about what, if any, extra work is needed for most usages. The one thing I know is that when quoting an arbitrary book title in the same sentence as LTR text, the site should use the <bdi> element, but I think most sites insert user content in their own block elements, where <bdi> is unnecessary.

        1. 1

          Thanks for the extensive explanation! Makes sense now :)

    9. 38

      I’m confused. Why is that not the default? Do web browsers for people configured to use RTL languages really default to LTR text input?

      I honestly don’t know how people in these locales use computers. I had fun recently when someone from Israel sent me a PowerPoint template. First, it turns out the PowerPoint hides the button to toggle the writing direction unless you have both RTL and LTR locales installed (so I couldn’t change it without installing extra system-wide components but they could). Then it turned out that the keyboard shortcuts for text navigation actually did work but they moved the visual indicator to the wrong end until you started typing (and then it flickered between the two locations). And that’s in one of the flagship applications from the dominant desktop OS vendor, I have no idea how much worse it is in more niche things.

      If I worked on mass-market GUI applications I think that I’d live in perpetual fear of some nice folks from Mossad dropping by for a friendly 3am chat.

      1. 7

        Why is that not the default?

        I can at least confirm that this browser behavior matches the HTML spec:

        To solve this problem, that spec would need a rule that the directionality of text-type input elements whose dir attribute is not in a defined state should use the algorithm for dir="auto".

        I don’t know why the spec has no such rule. The spec already says the directionality of <input type="telephone"> will default to LTR even on RTL pages, so some edge cases were considered. Perhaps when the spec was written, there were concerns about performance of scanning each string for a directionality-indicating character?

      2. 3

        Firefox is enormously configurable, so I expected to see a toggle somewhere in about.config, but there doesn’t seem to be an option to do this exactly.

    10. 2

      Other terminal file managers include nnn and ranger. Their user interfaces are more complex, but they have more features. They, too, can be configured to cd on exit (nnn’s docs, ranger examples 1 and 2).

      1. 4

        Two more for the list:

        • broot
        • xplr
        1. 3

          Links: broot, xplr

      2. 4

        Shameless plug for Elvish (, a shell with a built in file system navigation UI (it’s demo 5 on the homepage).

    11. 1

      The page isn’t redirecting properly

      Any one else getting errors with Skip Redirect add-on installed? Why are we going thru

      1. 2

        Medium has always handled sites with their own domains with this crazy redirect path. I don’t know why but I suspect it’s so they can cookie you on their main domain before you read on the custom domain.

        1. 0

          Well, I never got to read it because the writer chose Medium over hosting a blog themselves

          1. 1

            I recommend the front-end, which can proxy any Medium-powered article. loads fine for me even with cookies cleared and JavaScript disabled.

    12. 6

      Dhall is great. I think Nickel might be a better sell tho.

        1. 1

          Dhall doesn’t support lists with mixed types? That’s insane, especially for a language trying to compete with JSON.

          1. 2

            In functional languages heterogeneous lists are not the norm. Competing with a format doesn’t imply compatibility with its ideas.

            1. 2

              IMO the point of a config format is that it is language neutral. One of the reasons JSON won over XML was the simplicity of the type system as values are easy to coerce regardless of the language processing the results.

              A gradually typed config format would let the functional programmers specify heterohomogenously typed lists without ignoring the needs of the vast majority of its potential user base.

              1. 1

                …Or just have primitives for Tuples if you want short heterogeneous lists, or using ADTs to cover the variants makes sense. I don’t mind forcing software makers to think smartly about their choice of types rather than willy-nilly ∀ stuff. List stuff. Even with good design, the reason we end up with heterogeneous lists is because there’s a lack of good primitives so you have to create JSON like [{ "foo": {…} }, { "bar": {…} }] with type List 🤷 instead of what you mean data T = Foo … | Bar … & type List T.

                1. 1

                  OMG I’m so embarrassed I posted that. I’ve been doing web programming for too long and the brain rot is near terminal apparently :P

      1. 1

        One thing that Nickel lacks as far as I know is support for env variable. I quite like having a default value coming from the environment defined in dhall.

        1. 2

          I asked about this in their community this week. I understand that it’s great to not have side effects, but this is a useful one. I used a Bash solution (heredoc importing my file, then merge in env var as a string). They mentioned a possible future solution of allowing an argument you can pass into the CLI.

          1. 0

            Wouldn’t that just be an env variable? It seems like a dumb pendantic argument to reject env because some labels it a side effect. Not supporting a nearly universal need will certainly cripple uptake.

            1. 3

              Reaching out to stateful environment variables ruins reproducibility & caching. It makes sense as a design decision even if it is inconvenient.

              1. 1

                Isn’t that what a config is for, state? env seems to be the concensus on how to handle runtime specific variables. How is that different than parameters passed via the command line arguments?

                1. 1

                  Arguments are passed once on init instead of retrieving a value at runtime where values can change in the middle of execution leading to results that ruin the reproducibility. It may be a more annoying than export FOO="bar" since often you set it without intent of changing, but it makes sense to limit the side effects.

                  1. 1

                    Oh, I totally agree with that! I guess I just assumed env variables would be immutable. But I can see non-functional programmers making such variables mutable by default.

                    1. 1

                      We prefer to call them “dysfunctional programmers”

    13. 3

      This is just a general tip for ASCII art diagrams in general and not specific to the OP, but it’s much easier to edit and maintain diagrams if you can go into a mode in your text editor where when you type it overwrites the existing characters in the buffer, instead of inserting them (which is a big headache in ASCII art because it shifts everything to the right and you’re constantly needing to delete).

      In vim this is typing R in normal mode to enter Replace mode. Emacs has a similar ASCII-art mode IIRC.

      1. 3

        It’s at least a decade old, but there is JavE Java Ascii Versatile Editor, which is a paint-like editor for ASCII art with brushes, fill, rectangles, everything.

      2. 1

        Well if you’re already in vim there’s also a script to draw these with arrow keys:

        1. 1

          Looks like we lobster-clawed the server

          script:Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)

          Can you share the script here?

          1. 2

            The link works fine for me now. There’s also a mirror of that script at

            The vim-scripts GitHub organization mirrors – or rather, used to mirror – every script on It’s handy not just when shows errors but also when you want to install a package using a Git-based Vim plugin manager such as vim-plug.

            1. 1
              +----------+       +------------+
              |''''''''''|       |............|
              |''''''''''|       |............|
              +----------+       +------------+
    14. 2

      I don’t think it makes sense for the Content field to have size “8b min.”. That prevents this format from describing the deletion of all the data. If the Content field could have size 0 bits, one could describe deletion of all the data with this single subdiff:

      • Difference Type: Overwrite
      • Index: one 7-bit chainlet that is all 0s, evaluating to a 0 index
      • Difference End: a chain evaluating to the index of the last byte in the original data
      • Content: empty; 0 bits

      I’m assuming that the first subdiff’s index is relative to the start of the data. It would be nice to make that explicit.

      1. 1

        ty for da note! i fixed it: replaced difference end with content length. now you can make the content length 0 to denote full deletion

        EDIT: i removed content length and specified that the content is a nullable chain

    15. 18

      I’m not surprised that they would largely ignore the work that’s gone into tiling window managers elsewhere over the last 20 years, but I am surprised that there’s no mention of paper wm, a popular tiling extension (with some novel ideas) for today’s gnome, because it’s right in their wheelhouse.

      1. 3

        PaperWM is extremely creative, and I agree that it should have gotten more recognition. It’s very good at solving window positioning on a single screen, especially on a fairly small laptop screen. I don’t actually use it, because the actual implementation is a bit hacky (not their fault; comes mostly from having to keep up with Gnome releases), and it doesn’t really handle multiple screens very well.

        When I use Gnome, I’m pretty much always using the PopShell extension. It does very basic, conventional auto-tiling (spiral), but it’s very well integrated with mouse use and fully controllable and discoverable through the GUI. That’s kind of essential for easing new users into tiling.

      2. 3

        Link: PaperWM. As the screenshots in the Usage docs show, PaperWM’s window management and navigation is based around the three following concepts:

        • Scrollable window tiling
        • The workspace stack & monitors
        • Scratch layer
    16. 3

      Typos I noticed that you may want to fix:

      • unpleasent → unpleasant
      • pleasent → pleasant
      • stiwtched → switched
      • pacakge → package
    17. 10

      I like [String Literal Lists] so much, that I wonder how this is the first time I ever encountered it.

      These languages had similar features before Raku:

      • Perl has qw syntax. The “qw” stands for “quoted words”.
        • qw(foo bar baz) is equivalent to ("foo", "bar", "baz")
      • Ruby has %w and %W string-array literals.
        • %w[foo bar baz] is equivalent to ["foo", "bar", "baz"]
        • %W[foo #{"bar" * 3} baz] is equivalent to ["foo", "barbarbar", "baz"]
      1. 5

        Elixir also has ~w(unquoted words) I believe

        I forgot to highlight in the latest Oils release notes that we changed the syntax to

        var x = :| unquoted words |

        There is a rough analogy to :symbol which is like an unquoted/interned string in Ruby, Elixir, Clojure.

        It used to be %( unquoted words ) in Oils, but I felt that was too similar to

        var x = $(command sub > out)
        var x = @(split command sub | wc -l)

        Those forms have full commands in them, not just words.

        The old syntax is still valid, and I will remove it at some point …

        1. 1

          Yep, it does. I came here to mention elixir ~w(…)

          It also has my favorite multiple dispatch system and can be used with no imports.

      2. 1

        which did make me wonder how much of a try they gave ruby before dismissing it as too python-like

        1. 1

          Honestly, not too much. Not enough to discover ~w. I’m sorry, Ruby

          1. 2

            yeah, not to say raku isn’t a great language too, but ruby has a significant perl/bash influence (in fact in the early perl6 days one of the perl regulars used to joke about a “ruby-o-meter” that kept increasing as perl6 added rubyish features)

    18. 12

      i hate when github hijack my firefox search functionality. and moreover when it doesn’t do it consistently.

      1. 2

        Doesn’t the article say that GitHub considered hijacking the search hotkey, but decided to use the browser’s native search in the end? What’s wrong with their current solution?

      2. 1

        Do they still do it for you? They very recently stopped doing it for me in the non-edit view (even when logged in).

        They also fixed the mismatched tab width issue I had with the new view, so I might have been reverted to the old view.

      3. 1

        They broke ctrl-clicking links in source repos as part of this too. Gotta love it.

    19. 3

      See also the similar project rush, which was last updated in 2012.

    20. 2

      Is it just me, or was the first example hard to understand because of poor naming rather than cleverness? While understanding it, I mentally renamed over half of the identifiers and ended up with something that I am pretty sure I’d have understood from the start (in spite of having less JavaScript experience than a junior engineer working on a JavaScript project).

      1. 1

        Do you mean this example? The names in it are totally normal, k for key, v for value, o for object.

        const extractDataFromResponse = (response) => {
          const [Component, props] = response;
          const resultsEntries = Object.entries({ Component, props });
          const assignIfValueTruthy = (o, [k, v]) => (v
            ? { ...o, [k]: v }
            : o
          return resultsEntries.reduce(assignIfValueTruthy, {});

        It’s fairly contrived example because you get in an object that might have the attributes Component and prop and then you output an object that might have the same attributes, so the whole function should just be const identity = (input) => output;. The only work it does is to turn null, 0, and false values into undefined values, but that’s unlikely to be a useful transformation.

        1. 2

          the whole function should just be const identity = (input) => output;

          The function does more useful work than that. The response parameter is not an object that might have the attributes Component and props; response is an Array, as shown by the use of square brackets in its destructuring. The whole function converts each of the first two array elements, if present, to a named field in the returned object, and it ignores any other array elements.

          1. 2

            response is an Array

            My bad. I noticed that at one point, but then I lost it as I was working through all the convolutions. Anyway, it’s still a sort of useless adaptor. const adapt = ([ Component, props]) => ({ Component, props }); is not quite the same, but close enough for most purposes.

        2. 1

          I was first confused by ‘truthy’, which is used in a way that almost makes sense but implies (at least to me) a different meaning until I understood what it was doing (and then it was too late). Using single letter identifiers was not great, and key and value are not really informative as names here even when expanded.

          1. 2

            “Truthy” is the standard term for values that activate the true branch of an if test in JavaScript. In JavaScript, objects and numbers besides 0 are truthy. In Python, an empty list is not truthy but in JavaScript, an empty Array is truthy. It’s just one of those things you learn about a dynamically typed language.

      2. 1

        I agree – the first example was not a good formulation of the “clever”, generic solution. It could be expressed much more simply by calling filter on the entries instead of defining an inline function assignIfValueTruthy:

        const extractDataFromResponse = (response) => {
          const [Component, props] = response;
          const dataIncludingUndefinedValues = { Component, props };
          return Object.fromEntries(
            Object.entries(dataIncludingUndefinedValues).filter(([_key, val]) => val)

        I still agree with the article that its rewritten version with more duplication is better, but the decision is closer.

        Edit: gcmeplz on Hacker News suggests an even simpler “clever” alternative. It inlines variables and uses _.pickBy from the Lodash library, which many projects already depend on:

        function extractDataFromResponse ([Component, props]) {
          return _.pickBy({ Component, props }, Boolean);