1.  

    A few years ago, as part of Cognitect, I helped Defold write their new IDE for building games. Called Editor2, it’s a bit off the beaten path for Clojure, considering the editor is a desktop application using JavaFX with a lot of 3d.

    They wanted to replace their Eclipse-based IDE for a few reasons. One of the subtle ones was the challenge of “undo.” In a text-based environment, undo is pretty straightforward. But they have game objects (edited in one view) that could be composed into collections, which would then appear in scenes. Each of those were different views of the same underlying assets: game objects with textures, scripts, particles, etc. Coordinating undo across those views was an endless source of pain. The project’s sponsor learned about Clojure and immutable values, which sounded like a good way to solve the undo problem… just go back to the previous value.

    The editor we built was essentially one big dataflow graph. Every view is a node. The menu is a node. Game assets are nodes. Nodes have inputs, properties, and outputs. If you’ve seen graphs of shader composition, it’s kind of like that. Every change is an epochal evolution from one state of the graph to another. Undo just means going back to a previous version of the graph… which could be done with an atomic action.

    As an added benefit, the IDE devs got great productivity. A new tool in Eclipse had taken them a few months of a pair to create. Within Editor2, one dev created a platform level editor in about a week… and he had only learned Clojure in the previous month or two.

    1.  

      Nice By the way I clicked on the tool you mentioned and it took me to 404

      1.  

        A corrected link: https://defold.com/

        1.  

          Looks pretty cool

        2.  

          Oops, sorry about that. @roryokane has the right link.

      1. 1

        Yeah, the LCH color space is much more useful than HSL. I wish more software had color pickers that supported it.

        Another useful color space, closely related to LCH, is HSLuv. Its only difference is that instead of an absolute chroma (colorfulness) component, it has a relative saturation component, scaled so that 100% saturation means the maximum possible chroma sRGB allows for that hue and lightness.

        HSLuv’s relative saturation makes it ideal for generating colors for today’s sRGB-restricted CSS, because its colors are always displayable, no matter their saturation value. This avoids LCH’s problem where a color with too high a chroma value must be rounded to the nearest displayable color. The downside of relative saturation is that two different colors with the same saturation value might not look equally colorful.

        HSLuv has a comparison page that compares HSLuv, CIELUV LCh, and other color models. The charts do a good job of helping you understand how each color model works.

        The home page for HSLuv also has a nice color picker that I sometimes use instead of the color picker built into various graphics software. It’s good to learn of the article author’s LCH Colour picker – that’s a much easier-to-use LCH color picker than the other one I’ve seen. But something I prefer about HSLuv’s color picker is that the sliders’ colors show the final color you will get if you move that slider to that position, whereas the article author’s LCH Colour picker seems to do some weird hybrid of that behavior and making the sliders always show the same colors.

        1. 7

          The announcement has an interesting argument, not specific to Haskell, for conservatism in language design:

          We spent a lot of time discussing more expressive options. […] But we chose a more conservative path for now. By making naked record selectors illegal (except in parens) we leave those possibilities open for the future, as we get more experience. (This is one reason for not adopting […] naked record selectors without parens.)

            1. 4

              Yeah, this is the first solution people reach for, and as far as I can see, the docs steer you in that direction, so don’t blame yourself.

              1. 7

                I had a lot of trouble understanding the description of try/except/else. For anyone else who is confused, it works like this:

                try:
                    # Run this first. Exceptions will be caught by `except`.
                except ValueError:
                    # Jump to this if the `try` block threw an exception.
                else:
                    # Run this after the `try` block, only if the `try` block didn't throw an exception.
                    # Exceptions thrown here will *not* be caught.
                
                • How is the else block different from just writing code after the try/except construct?
                  • The else block will only run if an exception was not thrown in the try block.
                • How is the else block different from writing code at the end of the try block?
                  • Exceptions in it will not be caught by the except block. That is, exceptions in it are unexpected and shouldn’t be hidden.
                1. 4

                  It mentions it’s inspired by z and z.lua. There’s also jump or autojump, or twenty more if you search a bit. “It’s in Rust” is the big helper here, I suppose. Jumping to directories is never something I’ve found noticably slow even with z, but there’s always an audience trying to eek out the best performance.

                  1. 10

                    zoxide’s README says it’s mainly trying to speed up displaying the prompt, as opposed to speeding up the actual jumping. All z-like tools delay the prompt a bit because they run code to track the current directory before each prompt.

                    1. 2

                      Ahh, that makes more sense! I used to run some pre-prompt display stuff to get git statuses added into my prompt and that definitely slowed things down. Now I just run a ‘git status’ when I actually want that info and things are snappier. Every little bit adds up on those things.

                      1. 4

                        If you’d still like to do that (and use zsh), check out powerlevel10k. You can have your cake and eat it too…

                  1. 5

                    Is this solving a problem that doesn’t exist?

                    zsh’s autocomplete scrolls through only those previously used commands that match what has been typed so far. So I typically enter cd ./s and then the up arrow takes me through my most recently visited project folders, ./src/project_1, ./src/project_2

                    Even better, it works on any command, not just cd.

                    1. 5

                      History prefix search is a useful feature, but it can’t fully replace tools like z and zoxide. Say your two most recent projects are ~/projects/src/rails/ and ~/projects/src/lobsters/. If you want to jump to lobsters from within ~/projects/, you can type z lob or potentially even z l, both of which are faster to type than cd ./s<up><up>.

                      What’s more, you can always use the same z lob and z rails to jump to those folders from anywhere, whereas the cd command would have to be adjusted if you were within ~ or within rails/. The cd command also requires a different amount of <up> presses depending on which folder you visited most recently, while the z commands can be done from muscle memory.

                      1. 2

                        This usually does not work if your current directory is not the same as the one when you typed the command, except you use absolute paths. Or maybe I misunderstand what you exactly do.

                        Anyway, try it out, I wouldn’t want to miss this kind of instant directory change. Usually, it only takes 4 key presses ‘z [space] [two letters of target dir name]’ and you’re in the target dir - no need to reach for arrow keys or ctrl.

                        So, yes, it does solve a problem that does exists. Maybe it’s not a problem for you. Or maybe you don’t know yet you have that problem, but will once you tried out this (or z, or autojump, or any of the other solutions – I reckon the fact that there are so many alternative implementations should be a pretty good indicator that a non-trivial amount of people think this is a problem…).

                      1. 9

                        Happily, the sigil generator library (online demo), including the symbol alphabet, is open source under the MIT License. So even if you never want anything to do with Urbit, you can still use these pretty symbols as an alternative visual style for Identicons in other contexts. For example, you could use generated sigils as avatars for your app’s users or icons for your company’s internal servers.

                        1. 3

                          It doesn’t surprise me that Jest is slow to start up, but wouldn’t keeping Jest open in --watch mode avoid that problem? How long does Jest take to notice a changed file and output the new results in watch mode, compared to Baretest’s 0.09s in your example?

                          1. 2

                            Baretest is designed to not require watching. However I tried jest with watch mode on my local machine and the “sum” function took 1.566s. Jest also said “estimated 2s”, which I have no idea what that means.

                          1. 1

                            For another unusual idea for syntax highlighting, see “semantic highlighting”, as described in Coding in color. It means coloring each variable’s name with its own unique color, the better to spot where variables are reused. For example, the users variable in a piece of code might be red and the loggedInCount variable might be blue. I would assume semantic highlighting works better when you also use a theme that uses fewer colors of its own.

                            I’ve never tried using semantic highlighting myself, but I see there is a Vim plugin semantic-highlight.vim for it. JetBrains IDEs support it too. VS Code, however, doesn’t support it yet.

                            Another syntax highlighting style to remember when thinking about the ideal system is “rainbow parentheses”, which many people use when editing Lisp-family languages. See this random README for some example screenshots. With rainbow parens, delimiters such as parentheses ( ) are colored differently depending on their level of nesting. Most editors have plugins to support this.

                            1. 2

                              Looks like you’re at wemake. I haven’t had a chance to play [yet], so thought I’d ask: how does the flake8 configuration get along with automated formatters? It’d be nice if it got along easily with yapf (or black, or …).

                              1. 2

                                I found a page that seems to have the information you’re looking for: Auto-formatters – wemake-python-styleguide. To summarize, wemake-python-styleguide is compatible with autopep8, isort, and add-trailing-comma, but it is not compatible with yapf or black.

                                1. 2

                                  Thanks for finding that link, good reading. While they explain why black isn’t going to work,

                                  black itself is actually not compatible with PEP8 and flake8

                                  they only explain that they weren’t able to come up with a yapf configuration that matched their choices

                                  If you have a working configuration for both yapf and wemake-python-styleguide, please, let us know!

                                2. 1

                                  Sorry, I have missed your question.

                                  We don’t support black or any other auto-formatters, but we are compatible with autopep8 and autoflake8 by design.

                                  Why don’t we support auto-formatters? Because we believe that developers should write code and pay maximum attention to the process. And a good linter eliminates the necessity of auto-formatters. Docs: https://wemake-python-stylegui.de/en/latest/pages/usage/integrations/auto-formatters.html

                                1. 10

                                  I found myself telling people about floating point a lot. Now I try to do it in a more “show, don’t tell” way.

                                  This interactive style feels great. It really makes use of the fact that browsers can contain code to make it interactive. Maybe I should do more of that.

                                  If you have Javascript disabled, the evaluation will not work. Any suggestions how to mitigate that?

                                  1. 3

                                    If you have JavaScript disabled, the evaluation will not work. Any suggestions how to mitigate that?

                                    For those users, you can do what the excellent free online textbook Introduction to Computer Science using Java does in each chapter. Divide the article into multiple web pages with Back and Next links. At the bottom of each page, write a question, possibly with multiple parts. At the top of the next page, show the question along with the answer(s), and let the user manually compare their mental answer with the written answer.

                                    The textbook’s FAQ calls its style of writing “programmed learning” and describes it in more detail. The questions at the end of each page made the textbook much more interesting to read back in high school. Though your article’s style is slightly different, I found it more fun to read too because of its questions.

                                    The frequent-quizzing approach works better with smaller questions whose answers are easier to memorize. To aid the reader in memorizing their five boolean answers to each of your quizzes, you can put checkboxes next to each question. The checkboxes don’t have to do anything – their state will be saved in browser history, allowing users to go back and see their answers. As an example, chapter 63 of that textbook uses non-functional text fields in some of its short-answer questions.

                                    You could add server-side logic to cause each checkbox form to display different things on the next page, but for this particular article I actually think it would have been better if I could have clicked “show all answers” to see an explanation for every question, rather than clicking “evaluate” to see explanations next to only the questions I got wrong. It makes me more confident in my answers when I see that I got the answer for the same reason as the author. With the current behavior, it could be that I got the right answer for the wrong reason.

                                    1. 5

                                      No need to create multiple pages, you can just use the <details> HTML5 element.

                                      1. 3

                                        That’s a good place to start. If you (like me) find it to be just… too damned ugly (you can’t style it), you can use the checkbox hack to get the same visual behavior from arbitrary HTML elements.

                                    2. 2

                                      If you have Javascript disabled, the evaluation will not work. Any suggestions how to mitigate that?

                                      If it is you who wrote that site, you could use plain old cgi to display the correct answer without javascript

                                      1. 2

                                        For hiding/unhiding elements without JS, I’ve always used <label>s to <input type="checkbox">. When the user clicks on the label, they toggle the checkbox. The label can be styled any way you want, though I often add cursor: pointer.

                                        The style implication is this. If you place the checkbox before the hidden element, you can hide both the checkbox and any hidden element and use input[type="checkbox"]:checked + #myhiddenelement {display: block} (or similar) to show the hidden element when the preceding checkbox is checked (i.e. when the user clicks the label).

                                        In addition, since most browsers preserve checkbox state across reloads and page navigation, you get to have the state of checkboxes saved, for free!

                                        1. 3

                                          Yep, this is great (though less awesome for screen readers).

                                        2. 2

                                          The interactive part really adds a lot to the article. Does anyone know whether Wordpress has a plugin to create things like that?

                                        1. 1

                                          My .vim directory is published at github.com/roryokane/dotvim/. Its vimrc file is 1143 lines long. I based it off the 150-line Vim Tips wiki example vimrc when I started using Vim 9 years ago, and added to it over time.

                                          My config has a simple structure: it’s a .vim folder containing vimrc and gvimrc files that you can link to your home folder using the commands in the README. Though my vimrc is one big file, headers in comments organize it into sections: must-have features, Vundle plugins, plugin settings, options, indentation options, mapping and commands, mappings that rely on other mappings, autocommands, and a todo list.

                                          Every setting change in my vimrc is accompanied by a descriptive comment. I also have many comments that explain the reason for the change or are TODOs for ways I could improve the behavior of that setting in the future.

                                          I use Vundle for plugin installation. Though dein.vim is newer and some praise it, I’m not convinced that the extra verbosity it requires is worth the small performance improvement.

                                          I do opt into Vim 8’s new defaults with source $VIMRUNTIME/defaults.vim (see :help defaults.vim), but I haven’t removed the redundant settings from my vimrc yet because I haven’t checked which of those defaults Neovim also provides. Though the only client I currently use is MacVim, which is based on Vim 8, I want to keep my vimrc compatible with Neovim to ease migration to it whenever a good GUI for it is finally available.

                                          Though I love Vim’s system of keybindings, I’m getting tired of living without or reimplementing common features of newer text editors, such as easy-to-use Find and Replace and proportional-width fonts. Because of the limitations of Vim I have been noticing, I haven’t been updating my Vim config much recently. (Emacs has similar problems – for example, unlike all other editors, it has no concept of untitled files with no location on disk, so I would have to set up that feature myself.) For large projects I would rather use one of the JetBrains IDEs and the excellent IdeaVim plugin for it, which can understand mappings in my vimrc. For small files that I want to quickly open, I am trying out VS Code. Its modern conveniences may make up for the lack of Vim-compatibility in its Vim keybinding emulations, which makes its Vim emulation worse than the editor’s regular keybindings.

                                          1. 2

                                            I can’t reach this page at all, and the cached version doesn’t seem to work either. It fails saying “The page isn’t redirecting properly / An error occurred during a connection to www.ispreview.co.uk. / This problem can sometimes be caused by disabling or refusing to accept cookies.” But I turned off my ad blocker and “enhanced tracking protection” in Firefox and got the same error.

                                            Brave threw a slightly different error saying “This page isn’t workingwww.ispreview.co.uk redirected you too many times. Try clearing your cookies. ERR_TOO_MANY_REDIRECTS”

                                            1. 2

                                              Both the live page and the cached version are loading fine for me. If they still aren’t working for you, try the Wayback Machine, which also loads for me.

                                              1. 1

                                                Interesting, the Wayback Machine works, but neither the live page nor archive.is are working. At least I can read the article now!

                                                1. 5

                                                  Are you using cloudflare DNS? I remember a recent post here about an issue with archive.is

                                                  1. 2

                                                    Wow, you’re psychic! I am indeed using 1.1.1.1.

                                            1. 3

                                              I think these alerts would look better if the grow-in animation were shorter. The bounce effect is so slow and large (compared to other UI animations) that the movement distracts me for a moment from the content of the alert. This makes the alert feel slow and unsteady instead of fluid.

                                              1. 4

                                                Can we stop describing software as “beautiful” already?

                                                1. 2

                                                  Yeah, every time I see a headline like this, I kind of don’t want to click, because I will be like “meh, nice, but beautiful??”..

                                                  Went through and had a look on these. The popups look nice. Author did a good job.

                                                  1. 1

                                                    I’ve never heard any other software describe itself as beautiful before, but I don’t think calling software beautiful is always bad. For example, I like to think that the code of my Bad Code Rocks contest entry is beautiful in how convoluted it manages to be. However, I agree that when trying the demo of this alerts library, I don’t find the alerts beautiful compared to other modal dialog libraries. Maybe “beautiful” is supposed to be relative to the browser’s built-in alert dialogs?

                                                    1. 0

                                                      Every 2nd app on AppStore says it does the same thing as all other apps in its category, but THIS one is beautiful.

                                                      edit: OK, maybe not exactly every 2nd, but there are a lot of those apps.

                                                    2. 1

                                                      I agree with you. So I changed to “Cool”. Cool is cool? ^^

                                                    1. 5
                                                      My own email troubleshooting story

                                                      I had a similar problem with my Gmail account a few months ago. All email sent (by others) to my personal email on my own domain is forwarded to a Gmail address, from where I read it. At some point, without me having changed my email habits or anything, I noticed that my inbox was missing emails that should have been sent. The emails weren’t in my spam folder – they were just missing. After a few weeks of mild confusion, I checked the mail forwarding logs on my web host and saw that Google was rejecting the forwarded mail.

                                                      I went through the same troubleshooting journey as in the post – finding troubleshooting steps only for G Suite owners, and signing up for Postmaster Tools only to be told that they can’t tell me anything about my domain because I’m not a mass email sender.

                                                      Then, somewhere, I read that Gmail should accept the incoming emails if you verify ownership of that custom-domain address such that you can send email “From” that address. I already had such an authorization from long ago, but I tried deleting it and adding it again, once again verifying my ownership of that address.

                                                      A week or two later, I checked my inbox, and I had received all the emails that I should have received in that period. A week after that, I checked the logs, and found no more bounces. The bounce problem went away as silently as it had arrived. I don’t know if that last re-verification step helped fix the problem or if Google merely improved their spam detection algorithm, but re-verification is worth trying if you haven’t.

                                                      On switching email providers

                                                      I considered switching email providers after that, but eventually decided to stick with Gmail. My main reason was its large amount of free storage for attachments. Another significant reason was that many of the alternative providers (including Fastmail) did not support categorizing emails with (multiple) labels, only with (single) folders. I’m surprised that support for labels is still so rare this long after Gmail popularized the concept.

                                                      I’ve stopped looking for alternative providers for now, but ProtonMail sounds like a good option if you’re willing to pay at least €48.00 / yr for email. It supports labels, its web client is open source, and it has a free plan on which you can try the service first.

                                                      1. 0

                                                        I went through the same troubleshooting journey as in the post – finding troubleshooting steps only for G Suite owners, and signing up for Postmaster Tools only to be told that they can’t tell me anything about my domain because I’m not a mass email and sender.

                                                        This so much. It’s no mistake that not assuming that I’m a G Suite customer is one of the points in my post. Every other commenter on Reddit somehow assumed the very same thing, even though it’s mentioned in my post right away in the second paragraph!


                                                        Then, somewhere, I read that Gmail should accept the incoming emails if you verify ownership of that custom-domain address such that you can send email “From” that address. I already had such an authorization from long ago, but I tried deleting it and adding it again, once again verifying my ownership of that address.

                                                        This is a very bad advice, because they don’t let you add any From email addresses any longer. If you delete yours, you won’t be able to add it back, without giving authentication credentials. And I’m just a bit too lazy to setup separate account just for Google here; and obviously won’t be giving them access to the main ones.

                                                        1. 2

                                                          This is a very bad advice, because they don’t let you add any From email addresses any longer. If you delete yours, you won’t be able to add it back, without giving authentication credentials.

                                                          I’m not sure what you mean by this. I deleted and re-added my custom domain’s email in the middle of June, and Google authenticated my ownership by sending me an email “Gmail Confirmation - Send Mail as roryokane@example.com”. The email contained a numeric confirmation code that I could paste into the appropriate section of Gmail’s settings. I don’t remember having to deal with anything I would call “authentication credentials”. Has the process changed in the last four months?

                                                          1. 2

                                                            Google Mail has started requiring SMTP credentials for any new From addresses since a few years ago or so. It’s not possible to add a new From address without providing the SMTP credentials anymore. It’s quite a bummer, really, because some alias addresses from certain services (like the various OSS projects) don’t even come with outgoing SMTP access.

                                                      1. 17

                                                        Alternatively, you can use repostatus.org’s “Abandoned” or “Unsupported” badges:

                                                        • Abandoned – Initial development has started, but there has not yet been a stable, usable release; the project has been abandoned and the author(s) do not intend on continuing development.
                                                        • Unsupported – The project has reached a stable, usable state but the author(s) have ceased all work on it. A new maintainer may be desired.

                                                        repostatus.org is a similar project that defines eight statuses you can mark repos with: Concept, WIP, Suspended, Abandoned, Active, Inactive, Unsupported, or Moved. Each badge links to a short summary such as the ones above.

                                                        It looks like No Maintenance Intended might explain the project status better with its dedicated web page, while repostatus.org is better for being able to categorize the state of all of one’s projects.

                                                        1. 8

                                                          Repostatus sure feels more thought out. “No Maintenance Intended” is vague and open to interpretation, see this HN thread for the same submission.

                                                          Shouldn’t the badge have a green checkmark to show everything’s ok? Or is no maintenance intended supposed to imply your code is broken?

                                                          1. 1

                                                            Seems like ‘no maintenance intended’ means ‘don’t bother me about it’ – i.e., if it’s broken then fork it.

                                                        1. 2

                                                          A description of Hedgewars and screenshots were harder to find than they should have been.

                                                          Hedgewars is a turn based strategy, artillery, action and comedy game, featuring the antics of pink hedgehogs with attitude as they battle from the depths of hell to the depths of space.

                                                          Basically, it’s an open-source clone of Worms.

                                                          1. 5

                                                            Textual summary:

                                                            • With the Bottle web framework on the back end:

                                                              • Define a route GET /viewcounter?url=… that reads that page’s viewcount from the website.viewcount column in a database and returns it in a JSON response.
                                                              • Define a route POST /viewcounter?url=… that increments the viewcount for that page.
                                                                • The view count is updated probabilistically – incremented by 10, with a 1 in 10 chance. This is presumably to make it harder to detect exactly when other users view the page.
                                                            • In the layout HTML file with the template for all pages, put a script tag that runs at page load. In that script:

                                                              • Read the current URL from window.location to pass to the subsequent requests.
                                                              • Use fetch to hit the GET route defined above, then read the views field from the returned JSON data and put its text on the page inside the #views element.
                                                              • Use navigator.sendBeacon to hit the POST route defined above. (Since this runs on page load, just loading the page registers a view.)
                                                            1. 2

                                                              Thanks for getting it onto writing.

                                                              • Just to give some more info, the data is stored in a Postgresql server.
                                                              • The Bottle web app is running on AWS Lambda, using a custom WSGI wrapper I wrote.