Threads for akkartik

  1. 10

    This all seems stupid, but I want to use this opportunity to reiterate something not-stupid: an eco-system that can’t handle people adding new warnings is utterly broken.

    The constraint seems to be that you can raise warnings to ask your users to make changes, but you can’t raise warnings to users of your users. Some thoughts on that:

    • We use libraries and tools for their abstraction, but if your library or tool is transmitting warnings about your code to its consumers, it’s not a very good abstraction.

    • If only we could add constraints to a tool like, “not to be used in published tools.” You may use egrep and fgrep in tools for yourself, but it’s a bad idea to publish such tools. If only people would avoid using – and definitely building more layers atop – scripts by others that are held together with baling wire.

    • If only we had communication channels between zones of ownership. To be able to talk to direct users of your tool without talking to their users, that would be something.

    Did gcc really add -W all in one version and -Wall all in another version? Perhaps they should have called them -W2.8, -W10.2, etc.?

    1. 7

      This all seems stupid, but I want to use this opportunity to reiterate something not-stupid: an eco-system that can’t handle people adding new warnings is utterly broken.

      This is certainly correct but grep, like all Unix tools, doesn’t really have the concept of warnings. At best, there’s a split between conventional data (stdout) and diagnostic output (stderr), although IIRC there’s not a very rigorous distinction between what conventional data and diagnostic output is supposed to mean and there are some practical differences between the two streams anyway (e.g. buffered vs. unbuffered).

      It’s not a good environment but it’s the environment that grep is written for, for better or for worse…

      1. 4

        Yeah, if it was a web server or a daemon or something, who cares, emit more warnings, but the point of (e|f)?grep is to make pipelines of redirected output. You just can’t assume that messing with stderr is okay in that scenario.

      2. 3

        I would agree with the statement that “the cron(8) ecosystem is utterly broken”. We still don’t have ? timespecs.

      1. 2

        Anyone have a good solution for downloading all their Google Photos en masse? Takeout is really not great at the size of media I’ve accumulated on Google Photos.

        1. 2

          I would add that the Google Photos download process simply does not work for some accounts, if they need to “verify that it’s really you” but have blocked any possible verification methods.

          1. 1

            Whoa, rclone also seems much more supercharged than the name would suggest: https://ivymike.dev/upside-down-backups.html

            1. 1

              Somebody in the HN thread mentioned https://github.com/gilesknap/gphotos-sync that I plan to try out.

            1. 2

              I built this a while ago as a sample app on a sandboxed fork of Lua: https://merveilles.town/@akkartik/107319684018301051

              Should be fewer build dependencies.

              1. 2

                Sounds like the first thing to build on this platform is a text editor with programmable abbreviations. I imagine the source code for the existing editor is available.

                You’re farther along than I ever managed to get. Don’t give up!

                1. 1

                  Nursing my RSI after Wheel reinvention jam.

                  1. 4

                    The most subtle reason teams switch tasks, in my experience, is a sub-optimal definition of “task”. Back in the bad ol’ days of manual testing and certification you could have shown this blog post to anyone and people would have nodded furiously along at everything in it. “Of course we understand basic queuing theory, we’re engineers. We minimize context switches and batch size.” But they were still spending weeks in their release process because:

                    • The programmer’s definition of “task” was “get it into trunk”, and
                    • The release engineer’s definition of “task” was “get trunk into production”.

                    The big shift in mindset that happened in the 2000’s was to realize it’s all the same task, to stitch together these workflows and vertically integrate them.

                    My lesson from this story is to constantly ask myself, “where else is division of labor causing muda?”

                    1. 2

                      Well, it’s been a while since I mentioned my project here, so: https://github.com/akkartik/mu

                      (Colorized sources. This is memory-safe code, and most statements map to a single instruction of x86 machine code.)

                      1. 2

                        I was going to link your project in the piece originally :) I will!

                      1. 39

                        Just quoting from the summary:

                        At this time, I would not recommend spending time on V. I would also be very cautious when taking claims made by the authors at face value.

                        So, still the same as before, please move along, nothing new here. Why do we even still spend time on this, is something I just can’t understand. I mean, I get it that the density of buzz and hopes in the self-proclaimed ads is hard to resist even for me, but come on, haven’t we all seen and learnt from a healthy dose of snake oil peddlers in our lifetimes?. “Way too good to be true” is a tell-tale sign that is seductive yet costly to ignore. Even if assuming good intentions and naivete, there’s unfortunately a level of naivete that crosses the border to a territory of “it’s dangerous to stay close to them”.

                        1. 28

                          I really appreciate the balanced tone of OP and the restraint in not bringing up past history in the current evaluation.

                          1. 7

                            I’d love to see such a review if things changed for the better in a useful way. That said, I guess it’s important to publish negative results. Maybe that’s the perspective I should employ when looking on this article. That’s an interesting angle; also, thanks for the reply. Knowing that you’re yourself an author of a language lends a lot more meaning to your words.

                            I love so much how interesting the discussions here on lobste.rs often become!

                            1. 3

                              Oh, I totally agreed with your top comment! Me building a language has nothing to do with it.

                          2. 8

                            Why do we even still spend time on this, is something I just can’t understand.

                            I also cannot understand how people hung onto this language after the initial exposure of unfounded claims and lies.

                            1. 4

                              Not everybody thinks critically.

                          1. 5

                            To the extent possible, features must be pay to play. If a user isn’t using a given feature, it should not impact performance, security, or reliability.

                            It’s worth explicitly calling out the supply chain here. If a feature is adding to your list of dependencies, it’s not pay-to-play.

                            1. 2

                              I dislike such blanket pooh-pooing of dependencies. There are plenty of fantastic dependencies that give you advantage of other people’s time and expertise. Even for not-so-fantastic dependencies it’s very often much quicker to review their code than to write your own from scratch. Your own code is a liability too, so you have to weigh on case-by-case basis whether risks and benefits of a dependency are better than your own development and maintenance cost, and your lost opportunity on reinventing something that has already been done.

                              1. 2

                                My statement is in OP’s frame of reference to the point of tautology, so I don’t understand what blanket pooh-poohing you’re reading into it. If you write your own code you’ll be more likely to know if somebody inserts malicious code into it. You don’t need to download it from a third party, subscribe to a new mailing list for security patches. Therefore you’re introducing a new kind of risk compared to ambient first-party liability. If it’s doing so for a reason only a subset of your users care about, it’s not pay-to-play. All your users are paying the cost. This reasoning isn’t helped by a disclaimer about how fantastic some possible dependencies might be.

                            1. 14

                              Terrible article. The author simply mashes together concepts while apparently having only a superficial understanding of any of them. The comparison of uxn to urbit is particularly hilarious, considering that they have totally different goals. Well, yes, both are virtual machines and that is where it ends.

                              Simplicity and elegance have appeals beyond performance, like ease of understanding and implementation, like straightforward development tool design. Judging the performance of a VM that (from what I see) has never been intended to be high-speed based on some arbitrary micro benchmark also doesn’t really demonstrate a particularly thorough methodology (the pervasive use of “we” does make the article sound somewhat scientific, I do grant that…)

                              I suggest the author invests some serious effort into studying C. Moore’s CPU designs, the true meaning of “simplicity”, the fact that it can be very liberating to understand a software system inside out and that not everybody has the same goals when it comes to envisioning the ideal piece of software. The article just critizes, which is easy, but doesn’t present anything beyond that.

                              1. 13

                                Terrible article. The author simply mashes together concepts while apparently having only a superficial understanding of any of them.

                                I suggest the author invests some serious effort into studying C. Moore’s CPU designs, the true meaning of “simplicity”, the fact that it can be very liberating to understand a software system inside out

                                I don’t exactly agree with the author’s criticism of uxn (probably because I see it purely as a fun project, and not a serious endeavor), but let’s not descend into personal attacks please.

                                1. 15

                                  Thanks.

                                  Now, with that out of way - this is not at all personal, the author is simply misrepresenting or confused, because there are numerous claims that have no basis;

                                  It is claimed this assembler is like Forth, but it is not interactive, nor it have the ability to define new immediate words; calling and returning are explicit instructions. The uxntal language is merely an assembler for a stack machine.

                                  Must Forth be interactive? What sense make immediate words in an assembler? Returning is an explicit instruction in Forth (EXIT, ;). That sentence suggests some wild claim has been made, but I can’t see where.

                                  Using software design techniques to reduce power usage, and to allow continued use of old computers is a good idea, but the uxn machine has quite the opposite effect, due to inefficient implementations and a poorly designed virtual machine, which does not lend itself to writing an efficient implementation easily.

                                  Again, I suggest studying Moore’s works, Koopman’s book and checking out the “Mill” to see that stacks can be very fast. The encoding scheme is possibly the simplest I’ve ever seen, the instruction set is fully orthogonal. A hardware implementation of the design would be orders of magnitude simpler than any other VM/CPU. Dynamic translation (which seems to be the author’s technique of choice) would be particularly straightforward. I see no poor design here.

                                  The uxn platform has been ported to other non-Unix-like systems, but it is still not self-hosting, which has been routinely ignored as a part of bootstrapping.

                                  This makes no sense. Why self-host a VM? “Routinely ignored”? What is he trying to say?

                                  After that the author discusses the performance of the uxn VM implementation, somehow assuming that is the only metric important enough to warrant an assessment of the quality of uxn (the “disaster”).

                                  Vectorisation is also out of the question, because there are no compilers for uxn code, let alone vectorising compilers.

                                  What does the author expect here?

                                  We can only conclude that the provided instruction sizes are arbitrary, and not optimised for performance or portability, yet they are not suitable for many applications either.

                                  (I assume data sizes are meant here, not instruction sizes, as the latter are totally uniform) Uxn is a 8/16 bit CPU model and supports the same data sizes as any historical CPU with similar word size. Again, I get the impression the author is just trying very hard to find things to complain about.

                                  Next the author goes to great lengths to evaluate uxn assembly as a high level programming tool, naturally finding numerous flaws in the untyped nature of assembly (surprise!).

                                  a performant implementation of uxn requires much of the complexity of modern optimising compilers.

                                  The same could be said about the JVM, I guess.

                                  To get to the end, I can only say this article is an overly strenous attempt to find shortcomings, of whatever nature, mixing design issues, implementation details, the authors idea of VM implementation, security topics, at one moment taking uxn as a VM design, then as a language, then as a compiler target, then as a particular VM implementation, then as a general computing platform.

                                  I like writing compilers, I have written compilers that target uxn, it is as good a target as any other (small) CPU (in fact, it is much easier than, say, the 6502). Claiming that “the design of uxn makes it unsuitable for personal computing, be it on new or old hardware” is simply false, as I can say from personal experience. This article is pure rambling, especially the end, where sentences like this that somehow let me doubt whether the author is capable of the required mental detachment to discuss technical issues:

                                  Minimalist computing is theoretically about “more with less”, but rather than being provided with “more”, we are instead being guilt-tripped and told that any “more” is sinful: that it is going to cause the collapse of civilisation, that it is going to ruin the environment, that it increases the labour required by programmers, and so on. Yet it is precisely those minimalist devices which are committing these sins right now; the hypocritical Church of Minimalism calls us the sinners, while it harbours its most sinful priests, and gives them a promotion every so often.

                                  No, brother, they are not out there to get you. They just want simple systems, that’s all. Relax.

                                  As O’Keefe said about Prolog: “Elegance is not optional”. This also applies to CPU and VM design. You can write an uxn assembler in 20 lines of Forth. There you have a direct proof that simplicity and elegance have engineering implications in terms of maintenance, understandability and (a certain measure of) performance.

                                  1. 16

                                    I agree with you in the sense that doing something for fun is obviously allowed, but I feel like the criticism in the article is not that you shouldn’t build anything simple and minimalist for fun, but that the things we build are usually not as revolutionary as some may claim just because they’re simple. Now, if the author of uxn made no such claims then that’s fine; however, that doesn’t mean something cannot be criticized for its perceived flaws (whether you agree with the style and tone of the criticism or not).

                                    I also agree that the Church of Minimalism stuff is a bit over-the-top.

                                    1. 6

                                      FWIW I had exactly the same reaction to this article as you, and I haven’t even heard of any of these projects. The article seems like it is in bad faith.

                                      Minimalist computing is theoretically about “more with less”, but rather than being provided with “more”, we are instead being guilt-tripped and told that any “more” is sinful: that it is going to cause the collapse of civilisation, that it is going to ruin the environment, that it increases the labour required by programmers, and so on. Yet it is precisely those minimalist devices which are committing these sins right now; the hypocritical Church of Minimalism calls us the sinners, while it harbours its most sinful priests, and gives them a promotion every so often.

                                      This part in particular is so hyperbolic as to be absurd. Completely unnecessary. Still, I guess if your goal is to garner attention, hyperbole sells.

                                      1. 12

                                        This part in particular is so hyperbolic as to be absurd. Completely unnecessary. Still, I guess if your goal is to garner attention, hyperbole sells.

                                        I wouldn’t say so. I’ve had folks tell me on tech news aggregators that the only way to make computing ethical is for computing to be reimplemented on uxn stacks so that we can all understand our code, or else the code we use can be used for exploitation. Now this may not be the actual uxn project’s stance on the matter at all, but much like Rust seems to have a bit of a reputation of really pushy fans, I think it’s fair to say that uxn has attracted a fanbase that often pushes this narrative of “sinful computing”.

                                        1. 2

                                          Oh interesting, do you have any links? I’m intrigued by this insanity.

                                          Edit: though presumably this is a vocal minority, making this still quite a hyperbolic statement.

                                          1. 3

                                            I did a light search and found nothing off-hand. I’ll DM you if I manage to find this since I don’t like naming and shaming in public.

                                            Edit: And yeah I’m not saying this has been my experience with a majority at all. The folks I’ve heard talk about uxn have been mixed with most having fun with the architecture the same way folks seem to like writing PICO-8. It just has some… pushy folks involved also.

                                            1. 7

                                              I believe the only way to make computing ethical is to reinvent computing to do more with less. I also believe uxn is trying to reinvent computing (for a very specific use case) to do more with less. But those two statements still don’t add up to any claim that it’s the only way out, or even that it’s been shown to work in broader use cases.

                                              Disclaimer: I’ve also tried to reinvent computing to do more with less. So I have a knife in this fight.

                                        2. 4

                                          Actually, we regularly get posts here on lobste.rs espousing exactly that sort of ideology. I think there’s one or two trending right now. perhaps you’ve hit on the right set of tag filters so you never see them?

                                      2. 2

                                        “C. Moore…” as in Chuck Moore…

                                        1. 1

                                          The paste was cut off. Fixed.

                                      3. 13

                                        The comparison of uxn to urbit is particularly hilarious, considering that they have totally different goals.

                                        they both market themselves as “clean-slate computing stacks”, they both begin with a basic admission that no new OS will ever exist (so you have to host your OS on something else), they both are supported by a cult of personality, they both are obsessed with ‘simplicity’ to the point of losing pragmatic use and speed. I’d say they’re pretty similar!

                                        1. 3

                                          they both are supported by a cult of personality

                                          Strong disagree, from someone who’s been moderately involved with uxn community previously. Who is the cult leader in this scenario?

                                      1. 2

                                        I’m not familiar with Elixir, and I can’t figure out the semantics of with even after a few minutes of effort..

                                        1. 6

                                          It’s repeated matches that fall through to the else clayse on the first mismatch, giving the mismatched value, which can then also be pattern matched against.

                                        1. 20

                                          It’s important to say out loud the sordid incentives that keep people from bumping major versions. You spend a lot of time making a change to your software. You want people to use it and find out how awesome it is. If you bump the major version they often have to opt in to using it, which makes it harder to find out about new features. If you don’t bump the major version you can just foist it on them and they’ll be more likely to run into new features they never asked for.

                                          Even though open source software is often in principle a gift economy, it often isn’t that different from commercial software in practice. You end up with the same incentives of competing on features, wanting to avoid fragmentation, etc. It’s almost like there’s an emergent PM somewhere tracking engagement metrics for the new feature.

                                          1. 4

                                            I think there are a few reasons why the treatment of major versions is still the same with semver:

                                            • Breaking change is often a price for making big improvements: fixing an old design mistake that turned out to be limiting, switching to a better but incompatible third-party library, fixing a bug that erroneously allowed invalid inputs…
                                            • Few people will want to adopt a release that offers them nothing in exchange for spending time on breaking changes, so grouping incompatible changes with big improvements is a good strategy for removing old cruft without ruining your relationship with downstream users.
                                            • Software marketing is a big deal: you have to compete for people’s attention, now more than ever.

                                            Sometimes I wonder if Debian’s idea of a “versioning epoch” could be more widely applicable and more fitting than the current semver. Semver even calls version components major.minor.patch—features, no matter how big, are seen as a “minor” change. From the compatibility point of view, they are indeed minor, but for users, compatibility and improvement are equally important when they decide whether to upgrade or not.

                                            Debian uses an epoch number when a package changes its versioning scheme, e.g. there can be foo 2001.08 and foo 2:1.2.3 if a package switched to semver from a custom versioning scheme. It looks quite ugly, but it would definitely draw attention to a breaking change instantly, if it was used as a compatibility flag (like 1.2.3 going to 2:1.2.4).

                                          1. 4

                                            This article makes me about https://prog21.dadgum.com/38.html, about how Forth is among a set of puzzle languages, or https://prog21.dadgum.com/33.html about how writing Forth can be akin to Sudoku.

                                            I know for me, I’m the sort of person who, when it comes to programming outside of work, wants to reach an end-point without having to implement much of the standard things along the way. And so, for me, forth tends to be a bit too low-level. But it does have a certain intellectual appeal.

                                            1. 7

                                              I kind of feel that using several different integer sizes is “cheating”, even though I’m not really sure if cheating is a thing that can apply to this. I don’t know. As a reader, when I see “4 integers are enough to write a snake game”, I expect at least 4 uint16_ts, or 4 uint8_ts, or something smaller than a 64 bit integer. Really the title should be “136 bits is enough to write a snake game”.

                                              Like, I clicked on this to see if I could apply a similar technique in some bootloader code I’m writing, but the technique is just - “use really large integers” and “use bitmasks”. That feels anti-climactic and disappointing.

                                              At the same time, I don’t feel that this is the author’s fault, or the fault of the article. It’s just a dissonance of what I expected when I clicked on the article, which the author couldn’t have possibly known. At the same time, I can’t get past the fact that I feel cheated by this - “I made a snake game in 17 8-bit integers” isn’t nearly as interesting an article title, and it feels clickbaity because of that.

                                              1. 2

                                                I normally expect integer to mean 32 bits, but I guess it’s been long enough that 64 really is the standard now.

                                                1. 2

                                                  Funnily enough, the total bits (32 + 64 + 20 + 2 + 8) do add up to less than 4 * 32. So perhaps you would have preferred it to be phrased as:

                                                  • We will store the game map in a uint32_t where 1s will form the reptile’s body. The map will contain 4x8 positions. Enough to have fun!
                                                  • We will keep two more uint32_ts as a directions array - this will be useful to move the snake around, while keeping its growing shape intact;
                                                  • In the final uint32_t we will squeeze in:
                                                    • four 5-bit integers for the positions of the head, the tail, the apple, and the (current) length.
                                                    • 2 bits for input from the keyboard
                                                    • 8 bits for looping.
                                                  1. 2

                                                    You are right, I believe that would’ve been a better choice of words.

                                                  2. 2

                                                    I think the title was unintentionally click baity, and may have created fake epectations. Didn’t meant to be extra-clever, I just wanted to use as few variables as possible and squeeze everything in as little as possible, just like some people in the embedded world are doing.

                                                    The same feeling feeling of dissonance was shared by other people on Reddit, who downvoted the hell out of me and wrote some negative comments. Some guy even hate message me in the PM. Next time I will be more attentive with the titles.

                                                    1. 2

                                                      Yeah I mean, like I said I don’t blame you for this at all – it’s entirely me doing the leverage here. I’m really sorry you saw abuse from Reddit. TBH it’s not unexpected because I regard Reddit as a complete trashfire anyway and keep tabs on the SA thread mocking the hell out of them / alternately getting super shocked about the shit Redditors do. Fucked up that they went to your DMs too. Urgh.

                                                  1. 3

                                                    Just something I did for fun last weekend. The output of this code can be viewed here: https://alopex.li/temp/palette.html

                                                    1. 2

                                                      Nice. Here’s a visualization I did a while ago for the VGA palette on x86: http://akkartik.github.io/mu/html/vga_palette.html

                                                      1. 1

                                                        comfy. thanks for sharing

                                                      1. 8

                                                        What is a good use case for versioning a single file at a time? I was trying to find one for myself and coming up bare. Even the stated use case of “all those little scripts in your ~/bin directory” seems improved by the conventional approach of a dotfiles repo. Context matters, and every now and then I need to bundle a change to my .zshrc along with a script. Maybe HOWTOs are a good example, but what if you need to include a screenshot? And HOWTOs are intrinsically public; why would you not want to include authors in them in preparation for the time when the baton passes on?

                                                        1. 20

                                                          Hey, Fennel lead dev here, ask me anything. We also have a fairly active chat on Libera/Matrix, #fennel / #fennel:matrix.org if you want to discuss there.

                                                          1. 8

                                                            Hi Phil, I just learned about Fennel’s shared heritage with Janet. I’m curious how you think about the pros and cons between the two.

                                                            1. 12

                                                              I haven’t used Janet myself, but from what I can tell they are very similar from a language perspective. Fennel is completely written in Fennel while Janet is mostly written in C. But the main difference is the runtime.

                                                              Fennel is solely a compiler, so we use the pre-existing Lua runtime which gives us access to existing platforms like love2d, TIC-80, Minetest, Neovim, OpenResty, etc. Since we don’t have to develop a VM, we can focus 100% of our efforts on making the compiler as powerful and as polished as possible. We have access to a world-class JIT compiler while Janet only has a bytecode engine. Lua released a generational garbage collector a couple years ago that we got for free without having to do anything.

                                                              On the other hand, having control of the runtime has other benefits. For one, it can be a lot of fun to hack on. You also don’t have to worry about source mapping. (We have some solutions in Fennel but they have some limitations.) The other main difference is that Janet includes immutable data structures out of the box, while with Fennel they require some hacks that have a significant performance penalty.

                                                              Maybe someone who’s used Janet can offer another perspective.

                                                            2. 3

                                                              As someone who had never worked with a lisp, do you recommend fennel or should I look elsewhere First?

                                                              1. 6

                                                                I’d say this really depends on your learning style and what you’re hoping to accomplish. Some people like to learn from books, and they’d be much better off reading SICP or How to Design Programs.

                                                                IMO Lua and Scheme are roughly equivalent in difficulty for learners. The difference is that Scheme on its own is hard to accomplish much in standalone; typically real programs target dramatically larger systems like Racket and Guile. I would also say that Scheme’s hygenic macros are notoriously difficult to understand, but Fennel’s macros (while being more difficult than other parts of the language) are comparatively straightforward: https://fennel-lang.org/macros

                                                                Meanwhile Lua has already been embedded in hundreds of widely-used programs, and loading Fennel into them tends to be trivial. (see https://p.hagelb.org/hello-powdertoy.fnl.html) If you’re interested in learning by creating a game, (which I highly recommend!) Fennel has a huge advantage; it’s easy to use with TIC-80 and Love2d; in fact, most Fennel programs are games.

                                                                It’s true that learning Fennel does require learning Lua and Fennel at the same time to some degree, but Fennel mostly maps 1:1 to Lua in a way that’s really easy (IMO) to internalize. This sounds trickier than it actually is. If you’re ever reading the docs for a Lua library and wonder what it would look like in Fennel; it’s easy to drop it in https://fennel-lang.org/see to understand what a Fennel version of that code would look like. Compared to learning Java and Clojure at the same time, or Erlang and Elixir, it’s much easier.

                                                            1. 18

                                                              I kind of gave up on this dream, I now use https://obsidian.md to maintain my notes in markdown (with vim key bindings enabled).

                                                              If I need to I can just edit the pages directly in vim, otherwise obsidian does a nice job of rending the notes and allowing for easy navigation and editing.

                                                              By playing around with some configuration and limiting what obsidian features you use, you might be able to get obsidian and vimwiki to play nice together as well.

                                                              1. 6

                                                                I think I’m only interested in a FOSS approach. The Community section all linking to proprietary communications only is a turn-off as well that tells me a lot about who the target audience is. Markdown-based is a turn-off as well as its syntax is inferior to AsciiDoc in every way–which is by no means perfect–so something without a specific lightweight markup language is preferred.

                                                                1. 3

                                                                  When I first read this thread I found myself wishing you had provided some criteria. My vim+version control setup is.. using vim+version control? :)

                                                                  1. 3

                                                                    Lobsters, I’d expect FOSS options to have the most upvotes :P

                                                                  2. 1

                                                                    You might like Tiddlywiki, in that case.

                                                                  3. 2

                                                                    I similarly gave up in favor of Obsidian (some of the extensions, including the graph view and syncing, were nice enough to get me to convert).

                                                                    That said, if you use Neovim, there’s a surprisingly good org-mode implementation available and steadily gaining functionality: https://github.com/nvim-orgmode/orgmode. It’s probably (I haven’t comprehensively tested) not as strong as “real” Org, but I have enjoyed using it for basic note-taking in Neovim.

                                                                  1. 1

                                                                    Did you consider Ocaml? It seems to have cannibalized most of SML’s audience these days.

                                                                    1. 7

                                                                      Ok, f-strings just jumped to the head of my list of candidates for one of those huge vulnerabilities that affects 40% of the internet.

                                                                      1. 8

                                                                        But why?

                                                                        1. 6

                                                                          f-strings are not eval workhouse, this is literally the same as passing user data to .format.

                                                                          1. 2

                                                                            Which makes it a perfect candidate for the next ‘oh, did I need to sanitize my data?’ vulnerability. SQL injections, XSS, and so on typically all start with a primitive of a simple API that lets you embed user data in some other string and then pass it to some other code that makes some assumptions about it. Anything that makes it easier to do this without thinking is a good candidate for vulnerabilities.

                                                                            SQL injections largely went away in non-terrible languages / frameworks / systems by removing string concatenation entirely and providing format-string-like APIs and by making people use them because they were faster (they could pre-compile the query if it’s a constant string and just provide the query identifier + arguments to the RDBMS) and easier to use (the SQL could be in a single place). Anything that makes combining data from different sources into a string easier is likely to make lazy or inexperienced programmers reach for that instead of a tool that guarantees proper escaping.

                                                                            1. 2

                                                                              Well put. Notice the word “powerful” too. Which is, in my opinion, symptomatic.

                                                                              Powerful as in including many features with intricate behaviours that most developers are not aware of. Rather than having a well defined straightforward scope.