1. 1

    I emailed the author a comment to be edited into the page, as the page instructs, but I’ll also post it here, since I have no idea how long the author will take to perform that edit.


    Ruby and avoiding accidental mutation

    I think you characterize Ruby wrong in your Traits section. The reason my_uhoh.value changes and my_num doesn’t has nothing to do with copy semantics. Ruby passes both my_num and my_uhoh by reference – it doesn’t implicitly copy only the number as you claim. The reason my_uhoh.value changes is that the UhOh#floor method explicitly mutates @value = @value.floor.

    I think your confusion is due to an assumption that Float#floor mutates the number it is called on. You think that my_num was only left unchanged because a copy was provided to nasty_function. In fact, #floor does not mutate the number. A demonstration in irb:

    my_num = 0.5
    my_num
    # => 0.5
    my_num.floor
    # => 0
    my_num
    # => 0.5
    

    If floor mutated the number, I would expect it to be called floor! according to Ruby convention. That is why your example feels to contrived to me, despite your assurance that it is not. If I had written the UhOh class, I would have named the method floor!, and the bug never would have happened.

    Apart from naming the method differently, if you wanted to achieve the same effect in Ruby as the Perl 6 rw trait that you demonstrate, you could call the #freeze method on the object after constructing it:

    class Mutable
      attr_accessor :value
      def change
        @value += 1
      end
    end
    
    mut = Mutable.new
    # => #<Mutable:0x00007fc5ae26cc78>
    mut.value = 3
    # => 3
    mut.change
    # => 4
    mut.value
    # => 4
    
    mut.freeze
    # => #<Mutable:0x00007fc5ae26cc78 @value=4>
    mut.change
    # Traceback (most recent call last):
    # …
    # FrozenError (can't modify frozen Mutable)
    mut.value
    # => 4
    

    I called mut.freeze manually above, but you can even override .new so that #freeze is called automatically on every new instance of your object.

    Anyway, that is a corrected description of how Ruby can help you prevent unintended mutation. It’s good that Perl 6 has a solution for that problem too.

    Ruby and Smartmatch

    This is a feature that is so inherently Perl that I cannot imagine it ever being implemented in another language.

    In fact, Ruby has a very similar feature too – probably inspired by Perl, as many of Ruby’s features are. Ruby’s casewhen construct calls a custom operator === on each “when” expression to compare it to the “case” value. This sounds the same as your description of Perl 6 calling .ACCEPTS on the “when” expression to compare it to the “given” value.

    Ruby’s #=== method (because operators are just method calls in Ruby) is defined for various types as doing some sort of matching – for example, equality for strings, inclusion for ranges, and matching for regexes. And it can be used for type matching as well. Thanks to the Module#=== implementation, MyClass === some_obj will return true only if some_obj is an instance of MyClass or one of its descendants. Ruby doesn’t have an object representation of function signatures, though, so you can’t check whether an object would be accepted as a parameter to a method as you demonstrated you can in Perl 6.

    1. 13

      I had no idea this kinda thing even existed. It probably does make sense to disable it by default, as I’m not sure there is a good use case. But then again, you can achieve the same thing with JavaScript.

      1. 14

        IMO that makes this all the more pernicious - this is the kind of behavior people who go to the lengths of disabling Javascript are trying to avoid I’d think.

        1. 4

          That’s the thing: Google et al will try to track your clicks anyhow. They’ve always done that with Javascript and/or link rewriting – which works by default and has to be blocked on a site-by-site basis. You want them to do it with a standard feature instead because then you can block all of them the same way. But if they can expect the standard feature to be disabled by default then it’s useless to them and they’ll just keep right on doing what they were doing before. So for you to be able to meaningfully disable the standard click tracking feature, it must be enabled by default…

          I expect the whole idea to not work out in the long run because the incentive structure is metastable by a razor’s edge in the best case. It’s marginally more favourable but broadly similar to the Do Not Track header – which died a quiet death not long ago.

          1. 3

            You can still try to defend yourself: https://github.com/Rob--W/dont-track-me-google

            1. 2

              I use a different extension, “Avoid Google Search redirects” (Firefox Add-ons page). I hadn’t heard of the one you linked. There is probably no significant difference.

              1. 2

                … on a site-by-site basis, yes, as I already said. Getting them to use ping would mean there’d be no “try” about it and it’d be called “dont-track-me” instead of “dont-track-me-google”. And that is the point I was making – not that it’s impossible to defend yourself against the non-ping approaches. If they used ping exclusively, you’d have a cheap, reliable, broad defence, rather than the only intermittently reliable and hard-to-scale defences we have today.

              2. 3

                The Do Not Track header didn’t work out because it cost site authors to implement, and didn’t provide any direct benefit.

                This HTML5 link tracking costs site authors about the same as what they’re doing already (set up a server-side script to collect pings, swizzle elements on rendered pages), but provides them some benefits: it makes external links load quicker (because they don’t go through a redirection), so their site is more pleasant to use, and it doesn’t obscure the Referer header — which they don’t much care about for outgoing links, but they care very much about for incoming links.

                The fact that it can also be easily neutered by the browser is irrelevant to them, as long as not many installed browsers are doing it.

                1. 2

                  It did provide some legal cover for tracking, so it did have some benefit, albeit a much weaker one. But that alone wasn’t its death knell. What did it in was when Microsoft flipped to sending it by default in their browsers, since that undermined its benefit (however weak) as a signal of conscious user intent.

                  It had the same “asking sites to make their invasiveness easy to defend against by promising that users will have to consciously choose to defend themselves (which most won’t)” incentive structure. It was just worse – as I’d already said – for the reason you gave, that it was harder to implement than ping is, and had murkier benefits to site owners – which I skimmed over (as I was only referencing it tangentially as a parallel).

                  I don’t expect ping to ever kill off or even broadly supplant non-ping click tracking techniques, even if it doesn’t vanish as quickly and completely as DNT did. I’m pretty sure it cannot serve its intended purpose because site owners will always have reason to agitate for less user control over it and users will always have reason to agitate for more, both of which undermine it – and I don’t see how that tug of war can ever settle into a stable configuration for long.

                  1. 3

                    What did [the Do Not Track header] in was when Microsoft flipped to sending it by default in their browsers, since that undermined its benefit (however weak) as a signal of conscious user intent.

                    The second half of that sentence is partly wrong – the most important conscious user signal remained available. Advertisers lost a strong opt-out signal (DNT: 1 and DNT: null became indistinguishable), but the strong opt-in signal (DNT: 0) remained available and strong. Is opt-in required to track somebody, or is lack of opt-out sufficient? Advertisers were banally pushing for the latter, of course.

                    ‘User consciously opts in to tracking’ is famously the standard that the GDPR requires. The IE 10 DNT kerfuffle pre-dates the GDPR. It took place in late 2012; in 2015 Microsoft announced it would go back to null-DNT by default; the GDPR was adopted on 14 April 2016, and became enforceable beginning 25 May 2018. If the GDPR had already been in place to give Microsoft’s ‘opt-out is the default’ stance extra, legal, force, that might have been interesting in ways that this margin is too narrow to contain are too off-topic to type out on my phone.

            1. 2

              A bit off-topic, but I love how it’s officially

              The Glorious Glasgow Haskell Compiler.

              1. 1

                Not quite – the alternate name is the “Glorious Glasgow Haskell Compilation System”. ¹ ²

              1. 11

                I like the argument about the intuitiveness of hashtagging and linking as a layer on top of plaintext, but couldn’t the same be done with bolding for example like **bold** i.e. the markup is not stripped.

                1. 9

                  Good idea. You could do this with other formatting too, such as making # headers bigger while still showing the #s.

                  You can see an example of this style of formatting in the screenshot of the Mou Markdown editor on its home page. The editor pane on the left shows some of this hybrid formatting. (To try it yourself, download the open-source MacDown editor.)

                  Taken to its conclusion, this style of formatting is just really good syntax highlighting.

                  1. 5

                    and a really nice thing about it is you can copy and paste it just fine!

                  2. 4

                    That’s possible, but it still has the factor that you can accidentally invoke the markdown syntax. Let’s say, for example, that you want to place a shruggie onto a platform like this:

                    If you do not implement escape characters at all, then you wind up with ¯\_(ツ)_/¯ where the anatomy is all visible, but the face is tilted sideways.

                    If you do implement escape characters, and you hide the escape characters, then you wind up with ¯_(ツ)_/¯ the classic “missing arm” broken shruggie.

                    If you implement escape characters, and show them, then you wind up with a correct ¯\_(ツ)_/¯. This is the outcome we want, but that policy is NOT generally good. I had to use escape characters extensively in this site, and I would not have benefited from such a policy.

                    1. 3

                      You can accidentally invoke the hashtag syntax on Twitter, by using the number sign in front of a number as per normal (see post #1). All the rest of this is just a matter of degree.

                      1. 3

                        You can accidentally write an unintentional url, too. Twitter also makes it hard to write a url that will appear as text without mangling and truncation, so even knowing what will happen may not help.

                      2. 2

                        How about (sic)? I imagine it as an escape mechanism which nullifies the special formatting of whatever directly precedes it. And, it is already considered “transparent, not part of the text” by most English readers. (Does something like it exist for non-English readers?)

                        So:

                        The robot prefers to be addressed as 345ART0.

                        vs.

                        The robot prefers to be addressed as 345*ART*0 (sic).

                        I will abstain from speculating about how to handle edge cases, like, a sentence that contains the names of ten robots…

                        1. 1

                          You could have it only format whole words. Then users can invent their own ad-hoc ._escaping_, or prepend with any other character to disable formatting. Sure, they then can’t format within words (I almost never do), but it avoids the inadvertent formatting problem.

                          Or have [formatting _not apply_ within square brackets] or some other infrequent character sequence.

                          I really like this whole concept, by the way.

                          1. 2

                            Or have [formatting not apply within square brackets] or some other infrequent character sequence.

                            Sadly that would go against markdown (or at least commonmark, to be exact), which I think is worth preserving, especially since it has proliferated itself to become the default limited-markup for websites. And compared to alternatives like bbcode or the markup wikis use, I find it a lot more comfortable.

                        2. 3

                          Yeah, that’s generally how Emacs handles styling (‘font-locking’) for Org-mode markup.

                          1. 2

                            If you have a look at the Ulysses app on macOS it does this. It’s a writing app that lets you write in markdown. But what it does is for instance for headings, it has a gutter on the left like a code editor which shows the heading level while still retaining the markdown syntax in the view and stying it based on the heading level selection or markdown. It also extends certains items with inline controls like images, etc…

                            You can see an example on their features page https://ulysses.app/features/ it’s a paid product though. I bought it years ago, then it went to subscription and the version I bought was left to rot and constantly crashed and got worse on subsequent versions of macOS.

                          1. 2

                            Reddit has a WYSIWYG editor now. It lets you switch between the “Fancy Pants Editor” (WYSIWYG HTML) and Markdown as you write your post, which I like – you can write in “preview mode” most of the time, then switch to Markdown temporarily when you want to type some tricky formatting.

                            The community hasn’t completely adjusted to it, though. Every now and then I see someone typing Enter twice between paragraphs as if they are typing Markdown, but in fact they are in the WYSIWYG editor. This means their text has a blank paragraph between each paragraph, which looks silly. The main cause of this is Reddit’s paragraph styling – their space between paragraphs is short enough that someone could think they only typed a newline.

                            1. 3

                              WYSIWYG editors have their own problems. I’ve had trouble getting the desired formatting out of Microsoft Word, and so has everyone else I’ve ever seen use it. A lot of people intentionally try to bypass Word’s auto-formatting features, in favor of just “typewriter-formatting” their text. It’s a real mess.

                              I guess part of it is that, for people who don’t want to spend time learning your app, it’s better to make something impossible than hard. If it’s impossible, then nobody does it, and you’re not expected to do it. If it’s hard, then other people are doing it, and now you’re expected to figure it out, too.

                            1. 2

                              Why Netlify? If you’re compiling down to static HTML and CSS, you can rsync those files to any box that runs a web server and you’re done. 100% generic web hosting is all you need, and you can point your DNS elsewhere anytime you feel like it.

                              1. 5

                                Probably because of its free plan. The only other service that I know has free static site hosting on a custom domain is GitHub Pages.

                              1. 10

                                Glad that this exists. Making the tutorial interactive is a great idea. A couple of things that could be improved:

                                • The zoom level is all over the place on mobile (iPhone) and even when zoomed out it looks slightly wrong: https://imgur.com/a/HLbCd92
                                • Navigating between sections breaks the back button (at least on my phone). The URL doesn’t change with each step and pressing back leaves the site entirely (returning to Lobsters in my case)
                                1. 4

                                  I see the same problems with the zoom level and the back button in Firefox for Android.

                                1. 1

                                  If you want to create an mdn shortcut for searching MDN, I recommend using the open-source mdn.io service to perform the search. Just give your bookmark the URL https://mdn.io/%s and the keyword mdn, and then searching mdn test will bring you directly to RegExp.prototype.test() instead of an MDN search results page.

                                  The service works by redirecting you to a Google “I’m Feeling Lucky” search restricted to the MDN site. The downside is that Google or the mdn.io operators could theoretically track your searches.

                                  1. 1

                                    If you use this feature for searching through developer documentation, consider using the website devdocs.io or Dash for macOS instead.

                                    Those tools are able to provide a better experience by being specialized for developer documentation. For example, they can store documentation and let you search through it while offline. Dash even has similar keyword feature – for example, type js:test to find the JavaScript method RegExp.prototype.test().

                                    1. 3

                                      Did you end up using a state management library for the frontend? If so, how did you get it populated by the backend? I’m just wondering if there are some well known patterns for syncing frontend state to the backend, perhaps especially with a REST API.

                                      1. 1

                                        The JSON:API standard for REST API design has a lot of implementations for both the server (e.g. Rails) and the client (e.g. Redux or framework-less JS). From the documentation, it looks like those libraries handle some of the work of transmitting states through the API. I’ve never used JSON:API myself, though.

                                        1. 1

                                          I have vuex installed with vapi that does that but I haven’t found a reason why I would need it yet

                                        1. 29

                                          Did you know that you can search all open tabs (even across synced devices) if you prefix your search term in the urlbar with a percent sign (%)?

                                          There are also other modifiers to restrict results to bookmarks, history etc. See https://support.mozilla.org/en-US/kb/awesome-bar-search-firefox-bookmarks-history-tabs#w_changing-results-on-the-fly

                                          (N.B. We actually call it the “awesome bar” instead of address or search bar, because of all these extra features:))

                                          1. 6

                                            Oh wow, I had no idea! The fact that it works across synced devices too is incredible. I’ll be using all of those extensively from now on; thank you!

                                            1. 3

                                              Wow, thanks! This is like half of the reason why I use the Vimium plugin and, nowadays, qutebrowser! God, I wish “advanced user” features were more well documented. Just a list of productivity tips in a concise format. At this point, I’ll have to write it myself.

                                              1. 2

                                                Start a draft and I’m happy to proof read (and maybe even contribute a few tips). Would be a great guide to have.

                                                1. 1

                                                  God, I wish “advanced user” features were more well documented.

                                                  Firefox 66, released 9 days ago, documented that % feature. Specifically, that version added a Search Tabs menu item to the ‘⌵’ tab overflow menu. When activated, that menu item just moves focus to the Awesome Bar and prepends “% ” for you.

                                                  I found that an elegant way to teach me the shortcut syntax without having to display help text anywhere. But now that I think about it, the interface could be even better if the Awesome Bar results popover displayed “searching in tabs” somewhere whenever the text contained %. And I didn’t realize until reading that linked help article that the % could be anywhere in the text, not just at the start.

                                              1. 1

                                                The article mentions I-expressions as a later attempt to make a mathier Lisp syntax. An even more recent attempt is “sweet-expressions”, which adds more traditional syntax for nesting (with indentation), function calls, and infix expressions. For example, these S-expressions:

                                                (let* ((x 1)
                                                       (y (+ x 1)))
                                                  (list y x))
                                                

                                                could be written as these sweet-expressions:

                                                let*
                                                  \\
                                                    x 1
                                                    y {x + 1}
                                                  list(y x)
                                                

                                                I once looked into porting sweet-expressions for use with Clojure. Sadly, Clojure has optimized its forms to be easy to write in S-expressions by removing nested lists where possible. This means that sweet-expressions’ indentation rules, which are optimized for the high amount of nesting in Scheme forms, are not very useful for writing Clojure. Clojure’s significant brackets ()/[]/{} reduce the usefulness of indentation rules too, and make it impossible to use {} for infix as sweet-expressions do.

                                                1. 2

                                                  The video does a far better explanation than what I am capable of describing in writing.

                                                  To save people from needing to watch the video, here’s a summary:

                                                  The plugin provides two commands: “capture” and “run”. These commands can be executed with a keybinding that you set up yourself, by clicking on a button in the status bar, or from the Command Palette.

                                                  First, you capture a command by selecting a string of text within an editor. So wherever you like, you could write date or | sort -u and then select and capture it. Any single command you could run from the command line would work. You might keep an editor on the side specifically for writing and reusing commands.

                                                  Then you run the captured command. If the command starts with |, the selected text will be used as its input. Whatever the command outputs will be inserted at the cursor, or in place of the current selection.

                                                  1. 1

                                                    Actually pipelines work too, thanks for writing a summary.

                                                  1. 3

                                                    …but why? Just don’t click it…

                                                    1. 0

                                                      If you want a site where you do all the work of skipping things you don’t like, then Lobsters might not be for you.

                                                      1. 0

                                                        Cool story. Nobody is here to talk about whether Lobsters is for me or not. Since we’re here though, filtering is optional. Since I can choose not to filter, looks like it’s just fine for me.

                                                        Thanks for the unsolicited advice, though. I guess?

                                                        1. 2

                                                          Lobsters is fundamentally a sorting and filtering site for web pages. Even when you don’t enable tag filters, the home page of Lobsters is filtered to show only the highest-ranked stories (where ranking mostly depend on votes and time). So filtering is not optional, it is the goal of Lobsters. I think that’s why @nil said that if you don’t like filtering, you shouldn’t be on Lobsters.

                                                          1. 2

                                                            Why do you assume that everyone only uses the homepage? There’s also a “/recent”, which is a pretty chill place. :)

                                                            Also, the problem isn’t what nil said. Like, off-topic unsolicited advice sucks, but unfortunately that’s the kind of attitude that tech culture spews. The issue is that telling people they don’t belong here is shitty, toxic behavior and in this case that it’s also completely off topic.

                                                            That’s some HackerNews level bullshit. If I ever don’t belong here, it’ll be for the same reason I stopped using HackerNews. Because it’s full of people like that.

                                                            1. 3

                                                              Oh yeah… I forgot that the Recent page existed, because I never visit it. I thought that story lists only appeared on the home page and on searches. Now that I see that Lobsters has prominent support for viewing its links without filtering/ranking, I agree that the argument I ascribed to @nil is a bad argument.

                                                              Edit: I can see that you saw @nil’s reply as rude. That surprises me, because I interpreted “you” in nil’s comment to mean “one”, so that the comment was not specifically urging you to leave. I heard it more like “if one didn’t like filtering, one wouldn’t be on Lobsters – therefore, all Lobsters users, including you, should be okay with this filtering too”. I don’t actually know in which sense nil meant their comment, but it might not have been as aggressive as you are interpreting it.

                                                              1. 1

                                                                <3

                                                    1. 4

                                                      It seems that regardless of actual availability, this is a feature people seem to want. Is this something the mods are willing to implement?

                                                        1. 1

                                                          It’s open source. Literally anyone here can implement it… Why is it the mods’ jobs?

                                                          1. 2

                                                            Anyone here can implement it… on their own instance. For it to be implemented here the mods would presumably have to accept and deploy submitted changes.

                                                            1. 2

                                                              It’s a good question whether the mods will allow this feature, but I would call that question whether they will “accept”, “merge”, or “deploy” the feature. In the usage I’m used to, the word “implementing” means writing the actual code.

                                                        1. 31

                                                          There is no way to filter domains. If anyone was interested in adding this feature, you would need to add another scope to Story like we do for flags then update the StoryRepository.

                                                          1. 3

                                                            Exactly this, lobste.rs is opensource, make a PR and done :D

                                                            1. 6

                                                              There’s no point in making a PR if the admins will refuse to merge it afterwards. That happened to me when I tried to improve character escaping in Lobsters’ custom Markdown dialect, years ago. So it’s good to discuss and get approval for significant features before trying to implement them.

                                                            2. 3

                                                              I’m generally okay with all such features. It’s a per-user thing and I think people should be free to have as many ways to control their experience as they want and use.

                                                            1. 3

                                                              IMO, Vim help is the most underestimated feature of Vim

                                                              I have been using vi/vim since .. 1999(?) and it took me a looong time to get beyond beginner. The fact that we still have to learn vim tips by sharing configs and articles speaks to how poorly the documentation is presented. My primary sources for going beyond beginner were vimcasts and more recently greg hurrell’s screencasts.

                                                              It’s fine that help is built in for powerusers, but in a typical terminal window, :help gets half the width or height. Good luck reading new material like that while trying it out. I have never been able to find an up-to-date vim documentation in HTML format. I just now discovered that neovim has documentation available in browsable HTML format.

                                                              Also, I cannot find Vim changelogs anywhere. I learned about packs and async by accident. I still don’t know how to use async. Looking at neovim.org, I see the latest news is from 2017, so I assume nothing worthwhile has happened since then.

                                                              1. 5

                                                                Looking at neovim.org, I see the latest news is from 2017, so I assume nothing worthwhile has happened since then.

                                                                Plenty has happened. Newsletter is coming soon.

                                                                There’s also a releases page that makes it pretty clear that several major releases have occurred, not to mention the pulse page.

                                                                1. 4

                                                                  Thanks.

                                                                  You will probably want to include releases with changelogs under the news headline. For example, on OpenBSD.org, it only takes one click from the front page to get a list of changes in the most recent release.

                                                                2. 4

                                                                  I agree that Vim documentation is hard for newcomers. But for me it was invaluable.

                                                                  Also, I’ve used https://vimhelp.org/ as up-to-date online doc. Currently it’s built for Vim 8.1.

                                                                  1. 2

                                                                    Also, I cannot find Vim changelogs anywhere. I learned about packs and async by accident.

                                                                    The Vim changelogs are within its help system, linked from within the Versions section in the top-level help. The most recent file describing changes is at :help version8.txt – it describes packages, async I/O, and more in its New Features section. (Note that Vim’s async implementation works differently from NeoVim’s.)

                                                                  1. 11

                                                                    It’s getting to the point where lobsters needs a gopher tag, and this is a good thing.

                                                                    1. 2

                                                                      Yes I couldn’t find one so #web it was. @alynpost what is the procedure to get a new tag?

                                                                      1. 2

                                                                        From the history of posts in the meta tag, it looks like you submit a meta-tagged tag suggestion text story to Lobsters to gauge interest. If the mods think there is enough interest after seeing the responses and upvotes on that thread, they manually edit the list of tags to include it.

                                                                        1. 5

                                                                          That is correct. It’s optional, but if you want to also prepare a list of existing stories that you think would benefit from the tag, that’s a great way to make the case.

                                                                    1. 3

                                                                      Another relevant part of logging bugs that this article overlooks is the third-party site Open Radar (About/FAQ). When you submit a bug to Apple, if it doesn’t contain sensitive information, you can also post it to Open Radar. This can help other developers to find and understand relevant bugs, know their status, and intentionally file duplicates that reference a Radar number.

                                                                      1. 6

                                                                        I don’t think this resumé makes for a good showcase of skills, because React is the wrong tool for showing a resumé like this in a browser.

                                                                        React could be justified by needing interactivity, but in this site, the interactivity hurts more than it helps. I would rather see your skills, education, and contact information within a normal, scrollable document than with your current UI of clicking on buttons to open pop-ups. As well as requiring extra clicks, that design is confusing because one button is a tab and the rest are pop-ups, though they look the same. And when I rotate my tablet to landscape mode, the pop-up UI model is no longer used, but the tabs don’t scroll with inertia like a normal web page. All of these problems could be fixed by displaying a static HTML page, without JavaScript.

                                                                        Now, your feature of generating your resumé from a resume.json file could still be valuable and worth showing off. You can keep this feature while presenting your resumé as a nice static document by writing a standalone program that converts the JSON to HTML, which will then be served as the page. You could have a link on the resumé like “this resume generated by this tool I wrote”. The tool could even reuse parts of your current React app – I know there are static site generators out there that can work with React. I think MDX is one.

                                                                        Looking at just the website and not the content, I would say your current resumé shows your enthusiasm for React, but both the use of React and the unnecessarily difficult UI give me the impression that you don’t know when to say “no” to a cool feature. I’m just saying that to warn you that a prospective employer might get the same impression.