Threads for singpolyma

  1.  

    This seems like it’s probably misleading, because it’s measuring the overhead of the high-level data structure and not accounting for how the size in memory will vary according to what you put in there. If you only ever store (Python) int and short strings containing code points from the latin-1 range, it’ll look very different than if you store, say, longer strings containing code points outside latin-1 (will at least double the storage for the string) or more complex types like lists or dicts.

    The string storage varies because internally Python always uses a fixed-width encoding, but chooses it per-string as the narrowest one capable of encoding the widest code point in the string — 1, 2, or 4 bytes.

    1.  

      The string storage varies because internally Python always uses a fixed-width encoding, but chooses it per-string as the narrowest one capable of encoding the widest code point in the string — 1, 2, or 4 bytes.

      I thought that python used utf-8 internally. TIL, I guess.

      https://peps.python.org/pep-0393/

      1.  

        As the PEP says, Python used to do either 2-byte (with surrogates) or 4-byte internal Unicode and which one was a compile-time flag baked into the interpreter. Then Python 3.3 switched to the dynamic per-string encoding choice used ever since.

        The advantages of this are that strings are always fixed-width storage — which is convenient for a lot of interactions with them, both at the Python and underlying C level — but without the inefficiency of UTF-32. There are cases where this makes better use of memory than “UTF-8 always” (since Python can get the first 256 code points in 1-byte encoding while UTF-8 can only get the first 128), and cases where it doesn’t (since a single code point past 256 switches the whole string to a wider encoding).

        1.  

          What’s an example of an algorithm where fixed width code points is actually useful?

          1.  

            Iterating is a lot easier with fixed width. Indexing is a lot easier with fixed width. Calculating length is a lot easier with fixed width.

            I know a lot of people really like to say that you shouldn’t be allowed to do those things to Unicode, but there are enough real-world use cases which require them that there’s no reason not to have them be that little bit nicer.

            Also it avoids the issue of how to expose variable-width storage to the programmer; in the old days before PEP 393, a “narrow” (2-byte Unicode) build of Python would leak lone surrogates up to the programmer. But if you’re going to normalize them to avoid that you have a complex API design problem of how to achieve that. Currently Python strings are iterables of code points, not of bytes or code units, which is a cleaner abstraction all around.

      2.  

        Also, I don’t know if it’s still the case, but I know that it at least used to be true that Python dict aggressively resizes to keep the hash table sparse, so even if you use the lowest-memory-overhead container you can find, putting even a single dict inside that container is likely to wipe out all your careful micro-optimizing choices.

      1. 1

        It’s weird that the first thing you criticize in a Critical Retrospective is something syntax-related that you yourself call superficial. It makes it hard to take the rest of the post seriously

        1. 28

          If syntax impacts understandability, is it actually superficial?

          1. 19

            Because I don’t think that’s the fault of the syntax. Huge part of criticism is expectations/preferences and lack of understanding of the trade-offs that made it the way it is. When Rust is different than whatever other language someone is used to, they compare familiar with unfamiliar (see Stroustrup’s Rule). But it’s like saying the Korean alphabet is unreadable, because you can’t read any of it.

            People who don’t like Rust’s syntax usually can’t propose anything better than a bikeshed-level tweak that has other downsides that someone else would equally strongly dislike.

            For example, <> for generics is an eyesore. But if Rust used [] for generics, it’d make array syntax either ambiguous (objectively a big problem) or seem pointlessly weird to anyone used to C-family languages. Whatever else you pick is either ambiguous, clashes with meaning in other languages, or isn’t available in all keyboard layouts.

            The closure syntax || expr may seem like line noise, but in practice it’s important for closures to be easy to write and make it easy to focus on their body. JS went from function { return expr } to () => expr. Double arrow closures aren’t objectively better, and JS users criticize them too. A real serious failure of Rust regarding closures is that they have lifetime elision rules surprisingly different than standalone functions, and that is a problem deeper than the syntax.

            Rust initially didn’t have the ? shortcut for if err != nil { return nil, err } pattern, and it had a problem of a low signal-to-noise ratio. Rust then tried removing boilerplate with a try!() macro, but it worked poorly with chains of fallible function calls (you’d have a line starting with try!(try!(try!(… and then have to figure out where each of them have the other paren). Syntax has lots of trade-offs, and even if the current one isn’t ideal in all aspects, it doesn’t mean alternatives would be better.

            And there are lots of things that Rust got right about the syntax. if doesn’t have a “goto fail” problem. Function definitions are greppable. Syntax of nested types is easy to follow, especially compared to C’s “spiral rule” types.

            1. 14

              I think a lot of criticism about syntax is oblique. People complain about “syntax” because it’s just… the most convenient way to express “I find it hard to learn how to write correct programs, and I find it hard to interpret written programs, even after substantial practice”.

              Lots of people complain that Common Lisp syntax is hard. Lisp syntax is so easy that you can write a parser in a few dozen lines. Common Lisp has a few extra things but, realistically, the syntax is absolutely trivial. But reading programs written in it is not, even after substantial practice, and I get that (as in, I like Common Lisp, and I have the practice, and I get that).

              Same thing here. A lot of thought went into Rust’s syntax, probably more than in, say, C’s syntax, if only because there was a lot more prior art for Rust to consider. So there’s probably not much that can be done to improve Rust’s syntax while not basically inventing another language. That doesn’t take away from the fact that the language is huge, so it has a syntax that’s unambiguous and efficient but also huge, so it’s just a whole lot of it to learn and keep in your head at once. I get it, I’ve been writing Rust on and off but pretty much weekly for more than an year now and I still regularly need to go back to the book when reading existing code. Hell, I still need it when reading existing code that I wrote. You pay a cognitive price for that.

              1. 3

                “I find it hard to learn how to write correct programs . . .

                Do you believe “correctness” is a boolean property of a program?

                1.  

                  I do, as in, I think you can always procure a “correctness oracle” that will tell you if a program’s output is the correct one and which, given a log of the program’s operations, can even tell you if the method through which it achieved the result is the correct one (so it can distinguish between correct code and buggy code that happens to produce correct output). That oracle can be the person writing the program or, in commercial settings, a product manager or even a collective – a focus group, for example. However:

                  • That oracle works by decree. Not everyone may agree with its edicts, especially with user-facing software. IMHO that’s inherent to producing things according to man-made specs. There’s always an “objective” test to the correctness of physics simulation programs, for example, but the correctness of a billing program is obviously tied to whatever the person in charge of billings thinks is correct.
                  • The oracle’s answer may not be immediately comprehensible, and they are not necessarily repeatable (like the Oracle in Delphi, it’s probably best to consider the fact that its answers do come from someone who’s high as a kite). IMHO that’s because not all the factors that determine a program’s correctness are inherent to the program’s source code, and presumably, some of them may even escape our quantitative grasp (e.g. “that warm fuzzy feeling” in games). Consequently, not all the knowledge that determines if a program is correct may reside with the programmer at the time of writing the code.

                  More to the point, I think it’s always possible to say if something is a bug or a feature, yes :-D.

                  1.  

                    Wow! I guess I can just say that I wish I worked in your domain! 😉 I can’t think of more than a handful of programs I’ve written in my entire life which have a well-defined notion of correct, even in part. Almost all of my programs have been approximate models of under-specified concepts that can change at the whims of their stakeholders. Or, as you say it,

                    the correctness of a billing program is obviously tied to whatever the person in charge of billings thinks is correct.

                    Exactly!

                    not all the knowledge that determines if a program is correct may reside with the programmer at the time of writing the code.

                    In my experience it rarely exists anywhere! Not in one person, or many, or even conceptually.

                2. 2

                  Well, there was a lot of prior art even when C was created, and they actively chose to disregard it. They also chose to disregard discoveries in C itself in the 70s and 80s, freezing the language far too early considering the impact it would have in the following decades.

                3. 4

                  it’s like saying the Korean alphabet is unreadable, because you can’t read any of it.

                  But like there is a reasonably objective language difficulty ranking index (from the perspective of English-native speakers) and Korean is squarely in the most-difficult tranche, I guess in no small part due to its complex symbology, at least in comparison to Roman alphabets. Are you saying that this dimension of complexity is, net, irrelevant?

                  1. 11

                    Korean uses the Hangul alphabet, which is very easy to learn. It’s much simpler than our alphabet. You can learn Hangul in a day or two. You’re thinking of Japanese, which is a nightmare based on people writing Chinese characters in cursive and italics while drinking a bottle of sake.

                    1. 1

                      some simplified hanzi does look like kanji, but I would appreciate an example of a japanese character looking like a cursive or italic version of a chinese glyph before I go on to tell your analogy to everyone at parties.

                      1. 1

                        It’s not an analogy. It’s the historical truth of kana: https://en.wikipedia.org/wiki/Kana. Japanese kanji and hanzi are mostly the same modulo some font changes and simplification in the 20th c.

                        1. 1

                          I meant the drunken japanese people part.

                          1. 3

                            We can’t prove they weren’t drunk. :-)

                    2. 11

                      from the perspective of English-native speakers

                      I think that’s what they were getting at; there’s nothing inherently difficult about it but your background as an English speaker makes it look hard to read when objectively speaking it’s dramatically simpler than English due to its regularity and internal logic.

                      1. 2

                        I guess I would say that there is no “objectively speaking” in this domain? Like, there is no superhuman who can look at things invariant of a language background.

                        1. 3

                          If you’re talking about “easy to learn” then I agree.

                          If you’re talking about simplicity, then I disagree. The number of rules, consistency, and prevalence of exceptions can be measured without reference to your background.

                      2. 7

                        I’ve specifically mentioned the Hangul alphabet (a syllabary, strictly speaking), not the language. The Korean language (vocabulary, grammar, spoken communication) may be hard to learn, but the alphabet itself is actually very simple and logical. It’s modern, and it has been specifically designed to be easy to learn and a good fit for the Korean language, rather than being a millennia-old historical borrowed mash-up like many other writing systems.

                        I think it’s a very fitting analogy to having an excellent simple syntax for a complex programming language. You may not understand the syntax/alphabet at all, but it doesn’t mean it’s bad. And the syntax/alphabet may be great, but the language it expresses may still be difficult to learn for other reasons.

                        With Rust I think people complaining about the syntax are shooting the messenger. For example, T: for<'a> Fn(&'a) makes lifetime subtyping contravariant for the loan in the argument of a function item trait in a generic trait bound. Is it really hard because of the syntax? No. Even when it’s expressed in plain English (with no computer language syntax at all) it’s an unintelligible techno-babble you wouldn’t know how to use unless you understand several language features it touches. That for<'a> syntax is obscure even by Rust’s standards, but syntactically it’s not hard. What’s hard is knowing when it needs to be used.

                      3. 4

                        People who don’t like Rust’s syntax usually can’t propose anything better than a bikeshed-level tweak that has other downsides that someone else would equally strongly dislike.

                        The problem with Rust’s syntax isn’t that they made this or that wrong choice for expressing certain features; it’s that there’s simply far too much of it. “Too many notes,” as Joseph II supposedly said.

                        1. 3

                          I agree with this, which is why I object to blaming the syntax for it. For a language that needs to express so many features, Rust’s syntax is doing well.

                          Rust chose to be a language that aims to have strong compile-time safety, low-level control, and nearly zero run-time overhead, while still having higher-level abstractions. Rust could drop a ton of features if it offered less control and/or moved checks to run-time or relaxed safety guarantees, but there are already plenty of languages that do that. Novelty of Rust is in not compromising in any of these, and this came at a cost of having lots of features to control all of these aspects.

                          1. 4

                            You can have many features without a lot of syntax. See Lisp.

                            1.  

                              If you pick the feature set for simplicity. Rust had other goals.

                              1.  

                                I literally just said that simple syntax doesn’t necessitate simple features.

                              2.  

                                I think Lisp gets away here only on a technicality. It can still have plenty of obscure constructs to remember, like the CL’s (loop).

                                The example from the article isn’t really any simpler or more readable if you lispify it:

                                (try (map-result (static-call (def-lifetime a-heavy (:Trying :to-read a-heavy)) 
                                    syntax (lambda (like) (can_be this maddening))) ()))
                                

                                It could be made nicer if it was formatted in multiple lines, but so would the Rust example.

                        2. 11

                          The syntax complexity of Rust is actually a big factor in why I abandoned my effort to learn it. I was only learning on my own time, and came to the realization I had a long way to go before I’d be able to pick apart a line like the author’s example.

                          So for me, it wasn’t just superficial.

                          1. 4

                            The syntax complexity of Rust is actually a big factor in why I abandoned my effort to learn it.

                            Same.

                          2. 3

                            If syntax impacts understandability, is it actually superficial?

                            I’d say so.

                            The problem is that “this syntax is ugly” is a completely subjective judgement largely influenced by the peculiarities of ones’ own background. Coming from Perl and Ruby, I happen to find Rust pleasant to look at and easy to read, whereas I find both Python and Go (which many other people prefer) unreasonably frustrating to read and just generally odd-looking. It’s not that Python and Go are doing anything objectively less understandable, per-se, but they’re certainly have an unfamiliar look, and people react to unfamiliarity as if it were objectively incorrect rather than just, well, making unfamiliar choices with unfamiliar tradeoffs.

                            It’s pure personal preference, and framing ones’ personal preferences as something that has objective reality outside oneself and which some other party is doing “wrong” is, to me, the definition of a superficial complaint.

                            1. 7

                              It’s pure personal preference

                              Is it pure personal preference? I dunno. Personal preference is a part of it, but I don’t think it’s controversial to say that Python is in general easier to understand than the q language, for example. Human cognition and coherence actually abides pretty well-defined rules, at the macro scale. Sigils are harder to grok than words. And so on.

                              1. 12

                                Personal preference is a part of it, but I don’t think it’s controversial to say that Python is in general easier to understand than the q language, for example.

                                Maybe, maybe not. What I do think is that if we’re going to try to make objective claims, we need some real objective measures and measurements. These conversations tend to be nothing but pseudoscience-y assertions and anecdata masquerading as irrefutable facts.

                                Human cognition and coherence actually abides pretty well-defined rules, at the macro scale. Sigils are harder to grok than words.

                                (In no way am I trying to pick on you, but) Case in point: “Sigils are harder to grok than words” feels like a strong objective claim but… is this actually in any way true? 馬 is a much more complicated symbol than $ or @ or ->, but we have something like 1.5 billion people in the world happily reading and writing in languages that require a knowledge of thousands of such symbols to achieve literacy, and they turn out to somehow show lower rates of dyslexia than in alphabet based languages while doing so!

                                Sigil-y writing systems are indeed actually quite common throughout history, so again we have this thing where what feels like a perfectly simple fact actually looks a heck of a lot like a simple case of familiarity when you scratch it just a little bit. The dominance of a few alphabetic writing systems outside of Asia could simply be a historical accident for all we know – there are no strong results from cognitive science supporting any claim that it’s objectively more fit to “human cognition”. We really don’t have any idea whether words are simpler or more efficient than symbols, or whether python is a global maxima of readability, a local minima, or anything in between. There are almost no good studies proving out any of this, just a lot of handwaving and poorly supported claims based on what people happen to like or be most familiar with.

                                1. 2

                                  馬 is a word. It happens to be written as a single character, but that doesn’t make it punctuation.

                                  1.  

                                    I’m aware. I speak Japanese.

                                    “Sigil” does not mean “punctuation”. It actually means something like “symbol with occult powers”, but in a programming context I think we can understand it as “symbol that conveys an important functional meaning”, like -> being the symbol meaning “returns a value of the following type”. The point being that OP was being pretty silly when they wrote that it’s a “rule of the human mind” that it’s easier to understand not written out as “not” rather than ! when the existence of a billion plus people using languages with things like “不” at least weakly implies that a single symbol for not is no more mentally taxing to understand.

                                    (that in many programming languages most sigils are punctuation is mostly just an artifact of what’s easy to type on a western keyboard, but it’s by no means the rule. See: APL, which can be chockfull of non-punctuation sigils)

                                  2. 1

                                    When I speak about “understandability” or whatever I’m not making a claim against an abstract Ur-human raised in a vacuum, I’m speaking about humans as they exist today, including cultural and historical influences, and measured on a demographic (macro) scale, rather than an individual (micro) scale. That is, I’m making a descriptive argument, not a normative one. In this context, “familiarity” is I guess a totally reasonable thing to account for! People understand better the things they are familiar with. Right?

                                    1. 2

                                      That is, I’m making a descriptive argument, not a normative one.

                                      It’s not a very good descriptive argument, though, insofar as you’re really failing to describe a lot of things in order to make your argument fit the conclusion that “sigils are harder to grok than words”.

                                      Even if we confine ourselves to Western English speakers… what about mathematics? Why does almost everyone prefer y = x+1 to Cobol’s ADD 1 TO X GIVING Y? It’s more familiar, right? There doesn’t seem to be any long-term push to make Mathematics more wordy over time (most of the established symbols have hung around for hundreds of years and had ample opportunity to get out-competed by more grokkable approaches, if word-based approaches were found by people to be any more grokkable), so if we’re describing the long-term pressures on artificial languages I don’t think “sigils are harder to grok than words” is an accurate descriptive statement.

                                      In this context, “familiarity” is I guess a totally reasonable thing to account for! People understand better the things they are familiar with. Right?

                                      Well, sure. But “in some contexts words are more familiar than sigils to western audiences” is a much different claim than “sigils are harder to grok than words” in any sense, and it leaves a lot more room to talk about sigils in programming languages in a rational way. Things like “dereferencing pointers” aren’t really familiar to anyone in words or sigils, so it’s not obvious to me that x = valueat y is any more or less “correct”/“intuitive”/“grokable” than x = *y.

                                      If anything, given the relative unpopularity of the Pascal/Ada & Cobol language families, a certain amount of “unfamiliar concepts compressed into sigils” seems to be appreciated by programmers at large. But other people disagree, which seems to point at this mostly being a superficial argument over tastes and perhaps how much maths background one has, rather than some kind of concrete and objective variation in any measurable metric of “understandability”.

                                      1. 2

                                        what about mathematics?

                                        Well, I think this substantiates my point? In the sense that way more people can read prose than can understand nontrivial math. Right?

                                        “in some contexts words are more familiar than sigils to western audiences” is a much different claim than “sigils are harder to grok than words”

                                        Not some but most or even almost all, depending on just how many sigils we’re talking about.

                                        Authors generally don’t invent new languages in order to express their literary works; they take the language(s) they already know, with all their capabilities and constraints, and work within those rules. They do this because their goal is generally not to produce the most precise representation of their vision, but instead to produce something which can be effectively consumed by other humans. The same is true of programming.

                                        1. 2

                                          Well, I think this substantiates my point? In the sense that way more people can read prose than can understand nontrivial math. Right?

                                          More people can read prose (in general) than the prose portions of an advanced Mathematics text (in specific). It’s not the orthography of mathematics that’s the limiting factor here.

                                          Authors generally don’t invent new languages in order to express their literary works; they take the language(s) they already know, with all their capabilities and constraints, and work within those rules. They do this because their goal is generally not to produce the most precise representation of their vision, but instead to produce something which can be effectively consumed by other humans. The same is true of programming.

                                          Which speaks to my point. Programming uses “sigils” because in many cases these sigils are already familiar to the audience, or are at least no less familiar to the audience for the concepts involved than anything else would be, and audiences seem to show some marked preference for sigils like { … } vs begin … end, y = x + 1 seems pretty definitely preferred for effective consumption by audiences over ADD 1 TO X GIVING Y, etc.

                                          At any rate, we seem to have wandered totally away from “sigils are objectively less readable” and fully into “it’s all about familiarity”, which was my original point.

                                          1. 2

                                            I’m not claiming that sigils are objectively less readable than prose. I’m objecting to the notion that syntax is a superficial aspect of comprehension.

                                            1.  

                                              . I’m objecting to the notion that syntax is a superficial aspect of comprehension.

                                              It’s not fully, but “the * operator should be spelled valueat/ {} should be spelled begin end” stuff is a superficial complaint unless and until we have objective, measurable reasons to favor one syntactical presentation over the other. Otherwise it’s just bikeshedding preferences.

                                              But I’m sorry, let’s not continue this. I’m not buying the goalpost move here. You wrote that human cognition obeys “well-defined rules. Sigils are harder to grok than words”. That’s pretty obviously a claim that “sigils are objectively less readable than prose” due to these “well defined rules of cognition”. That’s the kind of handwavey, pseudoscience-as-fact discourse I was objecting to and pointing out these discussions are always full of.

                                              I’ve pointed out that this is, in several ways, basically just a load of hot air inconsistent with any number of things true of humans in general (symbol based writing systems) and western readers in specific.

                                              Now your “well-defined rules of human cognition which include that sigils are less readable than words” weren’t trying to be an objective claim about readability?

                                              Sure. I’m done. Have a good one.

                            2. 23

                              I would warmly suggest making an effort to hit Page Down twice to get past the syntax bit and read the rest of the post though, because it’s a pretty good and pragmatic take, based on the author’s experience writing and maintaining a kernel. Xous is a pretty cool microkernel which runs on actual hardware, it’s actually a pretty good test of Rust’s promises in terms of safety and security.

                              1. 10

                                It’s interesting but also has the weird dichotomy that the only two choices for systems programming are C or Rust. C++ also has a lot of the strengths that the author likes about Rust (easy to write rich generic data structures, for example), and has a bunch of other things that are useful in a kernel, such as support in the standard library for pluggable memory allocators, mechanisms for handling allocation failure, a stable standard library API, and so on.

                                1. 5

                                  I had exactly the same thought. C++ burnt through a lot of good will in the C++98 era where it was admittedly a hot mess (and all the compilers where buggy dumpster fires). Now on one hand we have people who publicly and loudly swore off touching C++ ever again based on this experience (and even more people parroting the “C++ is a mess” statement without any experience) and on the other the excitement of Rust with all the hype making people invest a large amount of effort into learning it. But the result, as this article shows, is often not all roses. I believe oftentimes the result would have been better if people invested the same amount of time into learning modern C++. Oh well.

                                  1. 4

                                    Writing C++ is like writing Rust but with your whole program wrapped in unsafe{}. You have to manage your memory and hope you did it right.

                                    1. 4

                                      As I hope this article clearly demonstrates, there is a lot more to a language chice than memory safety. Also, FWIW, I write fairly large programs and I don’t find memory management particularly challenging in modern C++. At the same time, I highly doubt that these programs can be rewritten in Rust with the result having comparable performance, compilation times, and portability properties.

                                      1.  

                                        What would hinder Rust from having comparable performance, compilation times, and portability properties, in your opinion?

                                    2. 3

                                      string_view of temporaries makes dangling pointers instead of compilation errors. optional allows unchecked dereferencing without warnings, adding more UB to the modern C++. I haven’t met a C++ user who agrees these are fatal design errors. Sorry, but this is not up to safe Rust’s standards. From Rust perspective modern C++ continues to add footguns that Rust was designed to prevent.

                                      1. 1

                                        I haven’t met a C++ user who agrees these are fatal design errors.

                                        I haven’t used string_view much so can’t categorically say it’s not a design error (it very well may be). But for optional I can certainly say it is a trade-off: you have the choice of checked access (optional::value()) or unchecked and you decide what to use. I personally always use unchecked and never had any problems. Probably because I pay attention to what I am writing.

                                        1. 5

                                          This is the difference in approaches of the two languages. In C++ if the code is vulnerable, the blame is on the programmer. In Rust if the code is vulnerable, Rust considers it a failure of the language, and takes responsibility to stop even “bad” programmers from writing vulnerable code. I can’t stress enough how awesome it is that I can be a careless fool, and still write perfectly robust highly multi-threaded code that never crashes.

                                          In terms of capabilities, Rust’s Option is identical, but the the default behavior is safe, and there’s a lot of syntax sugar (match, if let, tons of helper methods) to make the safe usage the preferred option even for “lazy” programmers. The UB-causing version is written unsafe { o.unwrap_unchecked() }, which is deliberately verbose and clunky, so that the dangerous version stands out in code reviews, unlike subtle * or -> that are commonly used everywhere.

                                          Rust’s equivalent of string_view is &str, and it’s practically impossible to use the language without embracing it, and it’s borrow-checked, so it won’t compile if you misuse it.

                                    3. 2

                                      Eh, maybe the author just didn’t write that much low-level/kernel code in C++. I try not to read too much into these things. If I were to start learning F# tomorrow, then tried to write a similar piece two years from now, I’d probably end up with something that would have the weird dichotomy that the only two choices for functional programming are Scheme and F#.

                                      1. 1

                                        Scheme is honestly so hard to do functional in. It’s shockingly imperitive by nature given the reputation.

                                    4. 3

                                      I did read the entire post, but I wanted to voice that focusing on the wrong thing first makes people not take you seriously, especially when the author expresses it doesn’t matter, but they still decided to make it first?

                                      1. 3

                                        I may not be interpreting this correctly but I didn’t take the author qualifying it as a superficial complaint to mean that it doesn’t matter. Based on the issues he mentions regarding the readability of Rust macros, for example, I think it’s superficial as in “superficial velocity”, i.e. occurring or characterising something that occurs at the surface.

                                        (But note that I may be reading too much into it because reviewing and auditing Rust code that uses macros is really not fun so maybe I’m projecting here…)

                                    5. 18

                                      The final sentence of that section said, in summary, “Rust just has a steep learning curve in terms of syntax”. A critical retrospective that does not mention the horrendous syntax or its learning curve would lack credibility.

                                      1. 4

                                        I find Rust’s syntax perfectly clear and sensible. I am not the only one.

                                      2. 9

                                        I liked that it starts with that TBH. Rust’s dense syntax is probably the first impression of the language for many people—it was for me at least. And putting the author’s first impression first in the article makes it read more like a person telling a story, rather then a list of technical observations sorted by importance.

                                        I like to read stories by humans; i feel it easier to connect with the author and therefore to retain some of what they say. YMMV of course.

                                        1. 2

                                          And if they think rust is hard to read, wait until they discover lisp!

                                          (I know this author probably is already familiar with lisp and many other things, but the comparison stands.)

                                          1. 6

                                            I find it the other way around. If you temporarily put aside the issues of special forms and macros, the syntax of Lisp is extremely minimal and regular (it’s almost all lists and atoms). So Lisp stands at kind of an opposite extreme from Rust, with more familiar languages somewhere in between.

                                            1. 5

                                              Nim still has a dumpLisp routine to show you the shape of an AST you may want to manipulate.

                                              Syntax can be very personal, but I strongly prefer Nim’s to Rust’s and see no compelling language feature of Rust to tempt me away, though Nim is not without its own issues.

                                              1. 2

                                                Nim isn’t really comparable is it? More like Go with a GC etc?

                                                1. 2

                                                  “How comparable” mostly depends upon what you mean by “a GC etc”. Nim’s (AutomaticRC/OptimizedRC) memory management seems fairly similar to Rust, but I am no Rust expert and most PLs have quite a few choices either directly or ecosystem-wide. (Even C has Boehm.) There is no “GC thread” like Java/Go. The ORC part is for cycle collection. You can statically specify {.acyclic.}, sink, lent, etc. in Nim to help run-time perf. Some links that go into more detail are: https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc-in-nim.html https://nim-lang.org/blog/2020/12/08/introducing-orc.html

                                                  1. 0

                                                    “Go with a GC” is Go.

                                                    1. 1

                                                      Yes, that’s why I said it

                                                2. 2

                                                  The complaint in the article is about noisy hard to read though, and lisp is definitely that, even if it is simple and regular that simplicity leads everything to look the same.

                                                  1. 3

                                                    I always wondered why indentation-based reader macros (SRFI-49 is a simple one) never became popular. I can see “whys” for big macro writer types since they often want to pick apart parse trees and this adds friction there. Most programmers are not that (in any language). My best guess is a kind of community dynamic where tastes of village elders make beginners adapt more. Or wishful promises/hopes for beginners to become elders? Or a bit of both/etc.?

                                                    Of course, part of the regularity is “prefix notation” which can remain a complaint.

                                              2. 1

                                                It makes it hard to take the rest of the post seriously

                                                As x64k said the post is pretty well made I think and some honest criticism. If anything you can criticize the bad blog layout, which has big white bars on mobile and desktop, giving you a hard time reading it from any device.

                                              1. 4

                                                For a young language, problems and bugs in the base implementations seem quite reasonable.

                                                Problems in community libraries, equally young, I think are similarly reasonable.

                                                If these problems are found, addressed, and never come up again, it would seem the language is maturing, and going in the right direction.

                                                1. 2

                                                  It would also seem such a young and raw language is not ready for production use.

                                                  1. 10

                                                    Since the language is designed for data-crunching on your workstation etc, “production” use is pretty vague an idea.

                                                    1. 2

                                                      The ‘etc’ seems to be doing a lot of work, but I’ll hazard a guess that Julia was designed for more than workstation data crunching, and the intent was to productionize into applications. At least, that’s what I get from blurb on the home page:

                                                      • ‘Julia was designed from the beginning for high performance. Julia programs compile to efficient native code…’
                                                      • ‘One can build entire Applications and Microservices in Julia.’
                                                1. 1

                                                  I always smile when I read about the table tag. The reality was it was great for consistent layouts for a long time as CSS was broken in various ways. If they had called the table tag grid and had another one called “layout” I think we would not have had the same history with CSS.

                                                  1. 3

                                                    Tables are a PITA to style well. It’s fine as long as you can guarantee a screen size, but as soon as you need to have any flexibility at all, it falls over. I’ve had lot of situations where the data I need to style is basically tabular (a list of election candidates, for example), and it’s a headache trying to make it work on a phone. It’s easier to use plain old blocks and fake a table than vice versa. And that’s ignoring flex and grid, which are great.

                                                    1. 1

                                                      I’m older than you and I’m talking about the pre-phone days. 90’s through around 2010.

                                                      1. 1

                                                        I made my first website in 1997. :-)

                                                    2. 1

                                                      What? Tables were a huge source of many of the quirks that make quirks mode - tables were exceedingly broken, just like CSS you had to be very careful what you used, and how you used it, or things would just break. Pixel precise layout with tables required immense effort, and was only used because of how bad the rest of IE’s layout engine was.

                                                      If you’re always smiling I question how much time you actually spent trying to get table layout to match between browsers.

                                                      1. 2

                                                        “Pixel precise” is normally a phrase that indicates doing something horribly wrong. Pixels are not real

                                                        1. 1

                                                          Blame the site designers, they’re the ones making layouts based on absolute pixel positions

                                                          1. 1

                                                            I blame the hiring managers who insist on hiring print designers for web work and the product managers who pretend the print designers should have final say on all design issues. The designers themselves are doing the best they can with a toxic situation.

                                                        2. -3

                                                          If you were trying pixel precise layouts with tables you were doing something wrong. Tables were useful for dynamic flow layouts. I’m sorry you tortured yourself for years. Perhaps you should find another profession.

                                                          1. 1

                                                            No, I spent most of my time ensuring other - very large - sites worked correctly in WebKit, where I did a moderate amount of the layout and rendering logic over the years.

                                                            People expected to be able to do pixel layout in browsers, and so people were able to approximate pixel layout in browsers.

                                                        1. 19

                                                          SQLite is cool, but giving up the great type and integrity features of Postgres just to avoid running one more process seems like a bad trade-off for most of my applications.

                                                          1. 13

                                                            One thing I have learned recently is that SQLite has CREATE TABLE ... STRICT for type checking, because I felt the same pain moving from Postgres for a small CLI application. Could you elaborate on what integrity means here?

                                                            More on STRICT here: https://www.sqlite.org/stricttables.html

                                                            1. 6

                                                              In PostgreSQL one can not only have foreign keys and basic check constraints (all present in one form or another in SQLite), but one can even define his own types (called “domains”) with complex structures and checks. See https://www.postgresql.org/docs/current/sql-createdomain.html

                                                              1. 2

                                                                I haven’t tried this for a very long time but I seem to recall that SQLite provides arbitrary triggers that can run to validate inputs. People were using this to enforce types before STRICT came along and it should allow enforcing any criteria that you can express in a Turing-complete language with access to the input data.

                                                                1. 8

                                                                  Triggers might be functionally equivalent, but with PostgreSQL custom types (i.e. domains) not only is it more easy and practical to use, but it can also be safer because the constraints are applied everywhere that type is used, and the developer isn’t required to make sure he has updated the constraints everywhere. (Kind of like garbage collection vs manual memory management; they both work, both have their issues, but the former might lead to fewer memory allocation issues.)

                                                              2. 1

                                                                Oooh, that’s new. I’ll have to use that.

                                                            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. 4

                                                                    GCC and Clang have an available warning for when you combine some operators that are common causes of precedence bugs — I think one example is == and &. It’ll nag you to add parens to make your intentions clear. I’m pretty sure this is one of the warnings included with -Wall.

                                                                    Yet another good reason to turn on lots of warnings plus -Werror! In fact I’ve taken to opting out of warnings, not in — I include a canned file in my build system (XcodeWarnings.xcconfig) that turns on nearly every available compiler warning, then I follow it with some lines to turn off specific warnings I don’t want.

                                                                    1. 4

                                                                      For a long time, I have used a style rule in my own code that says ‘any sequence containing two operators must be parenthesised’. This means that A op1 B op1 C op1 D is fine but A op1 B op2 C must be written as either (A op1 B) op2 C or A op1 (B op2 C), whichever is intended. Since I started following this rule, I have never had to think about operator precedence. It doesn’t matter if the sequence is unambiguous to the compiler, it must also be unambiguous to the reader. If the reader has some cognitive load from remembering precedence, then that is mental effort that they are not able to spend finding real bugs in my code.

                                                                      1. 2

                                                                        Parsing adjacent (( parentheses and matching them across expressions is also a cognitive load (yes, even if you colour the parentheses). So is having to figure out WHY someone put parentheses in their expression as usually that’s an indication that normal operator precedence wasn’t applicable. Adding parentheses is not zero cost for everyone and I only do it explicitly (in situations where default precedence would otherwise have conveyed the same meaning) when mixing && and || or where & or | are used within a larger expression.

                                                                        The same can be said about useless comments in code, when people comment something it draws the eye and makes the reader pay special attention, when the comments are literally just a translation of the code into English this puts unnecessary cognitive strain on the reader.

                                                                        1. 0

                                                                          Parsing adjacent (( parentheses and matching them across expressions is also a cognitive load (yes, even if you colour the parentheses)

                                                                          Fortunately, most people reading my code use a visual cortex that evolved to recognise predators that have bilateral symmetry. As such, they can offload matching parentheses to some dedicated processing before it reaches their conscious mind.

                                                                      2. 2

                                                                        I’m not a fan of -Werror. I like compiling with -std=c99 -pedantic and there are a few POSIX features that run afoul of that. For example, “ISO C forbids assignment between function pointer and `void *’”, but POSIX requires that.

                                                                        1. 1

                                                                          What’s an example of POSIX requiring it? AFAIK that assignment is undefined behaviour.

                                                                          1. 2

                                                                            Since POSIX specifies the functions, such as dlopen, commonly found in dlfcn.h, and dlopen returns a void * it is therefore required to work on a POSIX compliant system. I think the standard calls it out explicitly somewhere but you’ll have to do your own legwork there.

                                                                            1. 1

                                                                              After a sleep I noticed the mistake, it’s dlsym that matters not dlopen but the point still stands.

                                                                          2. 1

                                                                            Better IMHO to leave -Werror on but turn off the specific warning(s) you don’t like. The warning message includes the name of the flag that controls it.

                                                                        1. 4

                                                                          While Atom is a better choice these days, RSS1 is pretty well supported and a better design than the insanity of XML misunderstanding/abuse that is RSS2.

                                                                          1. 5

                                                                            Yeah, there doesn’t seem to be any downside to Atom, whereas RSS is just… I don’t know how to say it, but if your primary goal is to serve a feed of web pages, and there’s not a well-specified and sane way to include HTML, there’s something wrong with your spec.

                                                                            I only implemented Atom for my blog, and would recommend the same to others.

                                                                            1. 2

                                                                              What do you dislike about RSS 2.0? I just implemented it here, and it was no harder than what I remember from RSS 1.0…

                                                                              1. 8

                                                                                RSS2 doesn’t even have a namespace so it doesn’t mix with other XML well. It also has no officially specified way to include HTML content, with several competing extensions for it, all bad.

                                                                                1. 1

                                                                                  I understand. Yes, those criticisms are quite true. Thanks for sharing :-) I’m offering both RSS and ATOM on my blog, so I guess each user will pick whatever they prefer.

                                                                            1. 1

                                                                              but all modern browsers automatically redirect to HTTPS

                                                                              Just tested it with chromium (version 101.0.4951.41-1~deb11u1) and this is not true.

                                                                              just don’t force an HTTP => HTTPS redirect on your users

                                                                              The problem with this: As soon as you have an service where at least one user has a security requirement you don’t want to break all possibilities to avoid https can used to break his security. So as soon as you allow login on the domain you might want to protect the credentials. But also for content only, you might want to protect the users from getting the contend changed. Injected ads[0] are the one think, but what about replacing your cat pictures with porn? Not to forget about exploits, special for older software with known bugs.

                                                                              Yes a redirect don’t solve this in a proper way, but it makes it harder for an attacker.

                                                                              [0] https://www.pcworld.com/article/435150/comcasts-open-wi-fi-hotspots-inject-ads-into-your-browser.html

                                                                              1. 4

                                                                                As soon as you have an service where at least one user has a security requirement you don’t want to break all possibilities to avoid https can used to break his security

                                                                                Worse, as soon as you provide a support for non-HTTPS connections you introduce a number of ways for people do do downgrade attacks. Someone able to MITM your connection just enough to cause packets to drop can just block the HTTPS port and make normal users fall back to the HTTP URL. A more active adversary can also then rewrite the unencrypted things to prevent you from moving to the HTTPS version.

                                                                                Only enable HTTP if you want to reason about all of these threat models. If you don’t, then just stick to a recent TLS as the only option.

                                                                                1. 2

                                                                                  Relevant to this article, I don’t redirect because I’m supporting very old browsers intentionally. But I suppose that’s the whole point. There’s HSTS available for those who want it.

                                                                                  1. 1

                                                                                    Problem with HSTS is, that it only triggers if you connect with https. Currently some browsers still first try to connect with http, when you only enter a domain. As far as I know there is currently no way to have a site available as http and https while directing all modern clients to the https variant.

                                                                                    I understand what the intention of the article is, I just wanted to point out some downsides of such decisions.

                                                                                    1. 2

                                                                                      You could add your domain to the hsts preload list

                                                                                      1. 1

                                                                                        I’m aware of that and there’s no good solution to it, but if you access it over TLS you’ll get a header, and it will stay secure.

                                                                                1. 9

                                                                                  I’m still sad about the state of messengers. One one hand you have Telegram and Signal which are two walled gardens with a closed-source server. (Signal being slightly worse as the author does not want it to be packaged for fdroid, and released a few versions without publishing the source code prior to integrating his cryptocurrency-scam in it.)

                                                                                  On the other hand, the decentralised alternatives are miles behind WhatsApp/Telegram/Signal. Jami just does not work for me and my friends (messages are not going through) and is a battery killer. (Messages are not being received) Tox has one of the worst UI/UX I’ve ever experienced (let alone push notifications being broken) And Matrix’s support for E2EE is not widespread.

                                                                                  I appreciate the community effort, but unfortunately I still use Telegram :( .

                                                                                  1. 25

                                                                                    I’m not sure it’s fair to place Telegram and Signal in the same category, at least not if E2EE is important to you.

                                                                                    The vast majority of Telegram’s chats are stored in plaintext on their servers. Group chats cannot be end-to-end encrypted, and you have to manually start a secret chat between two people if you want E2EE. In spite of this, Telegram continues to be seen as a secure messenger – which is why a 2017 study found that many Telegram users mistakenly think their chats are end-to-end encrypted when they’re not.

                                                                                    1. 2

                                                                                      I did not realise this and now it makes sense to me that they can delete group chats.

                                                                                      1. 2

                                                                                        Yes. Telegram has to be used with over mitts, I agree. I don’t do any group chat, and only secure chats.

                                                                                      2. 10

                                                                                        I have no expectation that Telegram is actually secure. I just find it moderately interesting it’s one of the few modern IM services with open client APIs.

                                                                                        1. 9

                                                                                          I’m with you on the Telegram and Signal, though I still use both for some contacts. What has been working better for me, though, was setting up a hosted Snikket instance and then I got my family using that. It’s XMPP/Jabber (with OMEMO for the e2ee, which is based on the Signal protocol), and actually has good mobile clients. It’s one of the few ways the iOS family members get consistent notifications and experience. Might be worth a try if you’re ever up for trying another one.

                                                                                          1. 8

                                                                                            matrix works great for me.

                                                                                            1. 12

                                                                                              People keep saying this, but I don’t know when it’ll actually be the case. Every time I try it, I get disappointed by mediocre clients, resource hogging server, and inadequate moderation tools for groups.

                                                                                              1. 6

                                                                                                I tried matrix about 3 years ago I think, it worked, but it wasn’t great. In fact I self-hosted a matrix server, and while playing it filled my server with garbage from IRC-bridges, etc… So after one year or so, I uninstalled matrix, and just used a self-hosted IRC server, and for my group of geeky friends it was ok.

                                                                                                Then, after a while, IRC show some limits, so we’ve tried to use matrix again, about 1 year ago, and there were a lot of progress. The client is a lot better, the server too, I just forgot about it, and it “just works”. The e2ee user interface is a lot better than a few years ago.

                                                                                                So if you haven’t tried matrix in a while you should really try it again. Really, now I think matrix is ready.

                                                                                                1. 4

                                                                                                  resource hogging server

                                                                                                  conduit.rs has been running flawlessly for me, for a couple months now - way less resource-hungry than the Synapse stack (albeit, with some missing features).

                                                                                                  1. 2

                                                                                                    If you haven’t tried element in, say the last 3-4 months, then you aren’t up to date.

                                                                                                    1. 7

                                                                                                      I have and it’s still not great. The interface is a bit confusing (i.e. the multiple levels of hierarchy for chat, the weird spaces thing that’s trying to paper over federation, etc.) and lacks this je ne sais quoi other clients have that makes it feel wrong for lack of a better term.

                                                                                                  2. 6

                                                                                                    just wanted to say: matrix/element has come a long way. Due to it being used across orgs without federation (work vs family) I’d say the biggest downside is that there is no recommended way for multiple accounts on one device (especially mobile). Otherwise it works great.

                                                                                                    1. 5

                                                                                                      It REALLY has. But sadly I think the fact that @acatton did a whole ‘state of messengers’ and didn’t even mention Matrix is a great example of how it’s gaining mindshare, but VERY slowly and not with non technical users.

                                                                                                      The clients are IMO finally ready for that to happen, now we just need more people to actually try the updated versions and figure out how good it can be.e

                                                                                                      Meanwhile sadly 99% of the communities I actually want to chat on are Discord or Slack :(

                                                                                                  3. 6

                                                                                                    If you’re ever in the mood to try again, I suggest exploring Snikket.

                                                                                                    1. 3

                                                                                                      I use prosody xmpp server with Conversations from f-droid on mobile. It works great for me and my friends and family. It is also very fast and easy to setup. Server to server works flawlessly so I can connect with others easily and without creating an account.

                                                                                                      1. 3

                                                                                                        Can you provide more context or links around Signal’s cryptocurrency-scam that you mention? I could only locate a Verge article, but nothing more technical. Thanks.

                                                                                                          1. 2

                                                                                                            Thank you. Yes, it does.

                                                                                                        1. 3

                                                                                                          miles behind WhatsApp/Telegram/Signal.

                                                                                                          I know it wasn’t your intention, but just to clarify, this makes it seem as if these three are of similar quality. However, Telegram is miles ahead of WhatsApp.

                                                                                                          1. 2

                                                                                                            Signal being slightly worse as the author does not want it to be packaged for fdroid

                                                                                                            This is pretty valid though. F-droid’s whole build process is really strange. It also isn’t built with security in mind.

                                                                                                          1. 5

                                                                                                            I always cringe a bit when I read things like:

                                                                                                            However, the most recent major update of text changed its internal string representation from UTF-16 to UTF-8.

                                                                                                            One of the biggest mistakes that a language can make is to have a string representation. Objective-C / OpenStep managed to get this right and I’ve seen large-scale systems doubling their transaction throughput rate by having different string representations for different purposes.

                                                                                                            This is particularly odd for a language such as Haskell, which excels at building abstract data types. This post is odd in that it demonstrates an example of the benefits of choosing a string representation for your workload (most of their data is ASCII, stored as UTF-8 to handle the cases where some bits aren’t), yet the entire post is about moving from one global representation to another.

                                                                                                            For their use, if most of their data is ASCII, then they could likely get some big performance boots from having two string representations:

                                                                                                            • A unicode string stored as UTF-8, with a small (lazily-built - this is Haskell, after all) look-aside structure to identify code points that span multiple code units.
                                                                                                            • A unicode string stored as ASCII, where every code point is exactly one byte.
                                                                                                            1. 6

                                                                                                              One of the biggest mistakes that a language can make is to have a string representation.

                                                                                                              By this optic, we are in luck! Haskell has ~6 commonly used string types. String, Text, lazy Text, ByteString, lazy ByteString, ShortByteString and multiple commonly used string builders! /i

                                                                                                              I am very happy with the text transition to UTF-8. Conversions from ByteString are now just a UTF-8 validity check and buffer copy and in the other direction a zero-copy wrapper change.

                                                                                                              1. 4

                                                                                                                I think what David is saying is that ObjC has one string type (NSString/NSMutableString) with several underlying storage representations, including ones that pack short strings into pointers. That fact does not bubble up into several types at the surface layer.

                                                                                                                1. 3

                                                                                                                  Exactly as @idrougge says: a good string API decouples the abstract data type of a string (a sequence of unicode code points) from the representation of a string and allows you to write efficient code that operates over the abstraction.

                                                                                                                  NSString (OpenStep’s immutable string type) requires you to implement two methods:

                                                                                                                  • length returns the number of UTF-16 code units in the string (this is a bit unfortunate, but OpenStep was standardised just before UCS-2 stopped being able to store all of unicode. This was originally the number of unicode characters.)
                                                                                                                  • characterAtIndex: returns the UTF-16 code unit at a specific point index (again, designing this now, it would be the unicode character).

                                                                                                                  There is also an optional -copyCharacters:inRange:, which amortises Objective-C’s dynamic dispatch cost and bounds checking costs by performing a batched sequence of -characterAtIndex: calls. You don’t have to provide this, but things are a lot faster if you do (the default implementation calls -characterAtIndex: in a loop). You can also provide custom implementations of various other generic methods if you can do them more efficiently in your implementation (for example, searching may be more efficient if you convert the needle to your internal encoding and then search).

                                                                                                                  There are a couple of lessons that ICU learned from this when it introduced UText. The most important is that it’s often useful to be able to elide a copy. The ICU version (and, indeed, the Objective-C fast enumeration protocol, which sadly doesn’t work on strings) provides a buffer and allows you to either copy characters to this buffer, or provide an internal pointer, when asked for a particular range and allows you to return fewer characters than are asked for. If your internal representation is a linked list (or skip list, or tree, or whatever) of arrays of unicode characters then you can return each buffer in turn while iterating over the string.

                                                                                                                  The amount of performance that most languages leave on the floor from mandating that text is either stored in contiguous memory (or users must write their entire set of text-manipulation routines without being able to take advantage of any optimised algorithms in the standard library) is quite staggering.

                                                                                                                  1. 4

                                                                                                                    a good string API decouples the abstract data type of a string (a sequence of unicode code points) from the representation of a string and allows you to write efficient code that operates over the abstraction.

                                                                                                                    How, when different abstractions have different tradeoffs? ASCII is single-byte, UTF-8 and UTF-16 are not, and so indexing into them at random character boundaries is O(1) vs. O(n). The only solution to that I know of is to… write all your code as if it were a variable-length string encoding, at which point your abstract data type can’t do as well as a specialized data type in certain cases.

                                                                                                                    1. 3

                                                                                                                      Tangentially, you can find the start of the next (or previous) valid codepoint from a byte index into a UTF8 or UTF16 string with O(1) work. In UTF8, look for the next byte that doesn’t start with “0b10” in the upper two bits. I’m a known valid UTF-8 string it’ll be occur within at most 6 bytes. :)

                                                                                                                      (Indexing into a unicode string at random codepoint indices is not a great thing to do because it’s blind to grapheme cluster boundaries.)

                                                                                                                      Serious question, have you ever actually indexed randomly into ASCII strings as opposed to consuming them with a parser? I can’t personally think of any cases in my career where fixed-width ASCII formats have come up.

                                                                                                                      1. 2

                                                                                                                        Serious question, have you ever actually indexed randomly into ASCII strings as opposed to consuming them with a parser? I can’t personally think of any cases in my career where fixed-width ASCII formats have come up.

                                                                                                                        I have, yes, but only once for arbitrary strings. I was writing a simple mostly-greedy line-breaking algorithm for fixed-width fonts, which started at character {line length} and then walked forwards and backwards to find word breaks and to find a hyphenation point. Doing this properly with the dynamic programming algorithm from TeX, in contrast, requires iterating over the string, finding potential hyphenation points, assigning a cost to each one, and finally walking the matrix to find the minimal cost for the entire paragraph.

                                                                                                                        I’ve also worked with serialised formats that used fixed-width text records. For these, you want to split each line on fixed character boundaries. These are far less common today, when using something like JSON adds a small amount of size (too much in the ’80s, negligible today) and adds a lot more flexibility.

                                                                                                                        For parallel searching, it’s quite useful to be able to jump to approximately half (/ quarter / eighth / …) of the way along a string, but that can be fuzzy: you don’t need to hit the exact middle, if you can ask for an iterator about half way along then the implementation can pick a point half way along and then scan forwards to find a character boundary.

                                                                                                                        More commonly, I’ve done ‘random access’ into a string because integers were the representation that the string exposed for iterators. It’s very common to iterate over a string, and then want to backtrack to some previous point. The TeX line breaking case is an example of this: For every possible hypenation point, you capture a location in the string when you do the forward scan. You then need to jump to those points later on. For printed output, you probably then do a linear scan to convert the code points to glyphs and display them, so you can just use an integer (and insert the hyphen / line break when you reach it), but if you’re displaying on the screen then you want to lay out the whole paragraph and then skip to the start of the first line that is partially visible.

                                                                                                                        ICU’s UText abstraction is probably the best abstract type that I’ve seen for abstracting over text storage representations. It even differentiates between ‘native’ offsets and code unit offsets, so that you can cache the right thing. The one thing I think NSString does better is to have a notion of the cheapest encoding to access. I’d drop support for anything except the unicode serialisations in this, but allow 7-bit ASCII (in 8-bit integers), UTF-8, UTF-16, UTF-32 (and, in a language that has native U24 support, raw unicode code points in 24-bit integers) so that it’s easy to specialise your algorithm for a small number of cases that should cover any vaguely modern data and just impose a conversion penalty on people bringing data in from legacy encodings. There are good reasons to prefer three of the encodings from that list:

                                                                                                                        • ASCII covers most text from English-speaking countries and is fixed-width, so cheap to index.
                                                                                                                        • UTF-8 is the densest encoding for any alphabetic language (important for cache usage).
                                                                                                                        • UTF-16 is the densest encoding for CJK languages (important for cache usage).

                                                                                                                        UTF-32 and U24 unicode characters are both fixed-width encodings (where accessing a 32-bit integer may be very slightly cheaper than a 24-bit one on modern hardware), though it’s still something of an open question to me why you’d want to be able to jump to a specific unicode code point in a string, even though it might be in the middle of a grapheme cluster.

                                                                                                                        Apple’s NSString implementation has a 6-bit encoding for values stored in a single pointer, which is an index into a tiny table of the 64 most commonly used characters based on some large profiling thing that they’ve run. That gives you a dense fixed-width encoding for a large number of strings. When I added support for hiding small (7-bit ASCII) strings in pointers, I reduced the number of heap allocations in the desktop apps I profiled by over 10% (over 20% of string allocations), I imagine that Apple’s version does even better.

                                                                                                                      2. 1

                                                                                                                        I’ve written code in Julia that uses the generic string functions and then have passed in an ASCIIStr instead of a normal (utf8) string and got speedups for free (i.e. without changing my original code).

                                                                                                                        Obviously if your algorithm’s performance critically depends on e.g. constant time random character access then you’re not going to be able to just ignore the string type, but lots of the time you can.

                                                                                                                        1. 1

                                                                                                                          indexing into them at random character boundaries is O(1) vs. O(n).

                                                                                                                          Raku creates synthetic codepoints for any grapheme that’s represented by multiple codepoints, and so has O(1) indexing. So that’s another option/tradeoff.

                                                                                                                          1. 1

                                                                                                                            Julia similarly allows O(1) indexing into its utf8 strings, but will throw an error if you give an index that is not the start of a codepoint.

                                                                                                                            1. 2

                                                                                                                              But that’s just UTF-8 code units, i.e. bytes; you can do that with C “strings”. :)

                                                                                                                              Not grapheme clusters, not graphemes, not even code points, and not what a human would consider a character.

                                                                                                                              If you have the string "þú getur slegið inn leitarorð eða hakað við ákveðinn valmöguleika" and want to get the [42]nd letter, ð, indexing into bytes isn’t that helpful.

                                                                                                                              1. 1

                                                                                                                                Oh, I see I misunderstood. So Raku is storing vectors of graphemes with multi-codepoint graphemes treated as a codepoint. Do you know how it does that? A vector of 32bit codepoints with the non-codepoint numbers given over to graphemes + maybe an atlas of synthetic codepoint to grapheme string?

                                                                                                                          2. 1

                                                                                                                            How, when different abstractions have different tradeoffs? ASCII is single-byte, UTF-8 and UTF-16 are not, and so indexing into them at random character boundaries is O(1) vs. O(n).

                                                                                                                            Assuming that your data structure is an array, true. For non-trivial uses, that’s rarely the optimal storage format. If you are using an algorithm that wants to do random indexing (rather than small displacements from an iterator), you can build an indexing table. I’ve seen string representations that store a small skip list so that they can rapidly get within a cache line of the boundary and then can do a linear scan (bounded to 64 bytes, so O(1)) to find the indexing point.

                                                                                                                            If you want to be able to handle insertion into the string then a contiguous array is one of the worst data structures because inserting a single character is an O(n) operation in the length of the string. It’s usually better to provide a tree of bounded-length contiguous ranges and split them on insert. This also makes random indexing O(log(n)) because you’re walking down a tree, rather than doing a linear scan.

                                                                                                                          3. 1

                                                                                                                            I really miss working in the NS* world.

                                                                                                                          4. 2

                                                                                                                            ByteString isn’t a string type though, it’s a binary sequence type. You should never use it for text.

                                                                                                                            1. 3

                                                                                                                              ByteString is the type you read UTF-8 encoded data into, then validate it is properly encoded before converting into a Text - it is widely used in places where people use “Strings” in other languages like IO because it is the intermediate representation of specific bytes. It fits very well in with the now common Haskell mantra of parse, don’t validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/) - we know we have some data, and we need a type to represent it; we parse it into a Text which we then know is definitely valid (which these days is just a zero copy validation from a UTF-8 encoded ByteString). It’s all semantics, but we’re quite happy talking about bytestrings as one of the string types, because it represents a point in the process of dealing with textual data. Not all ByteStrings are text, but all texts can be ByteStrings.

                                                                                                                          5. 2

                                                                                                                            This comment reads very much like you’re quite ignorant of the actual state of strings in Haskell, particularly given how many people complain that we have too many representations.

                                                                                                                            Also, this article is specifically about code which relies on internal details of a type, so I’m not sure how your suggestions help at all - this algorithm would need to be written for the specific representations actually used to be efficient.

                                                                                                                            One thing I have wanted to do for a while is add succinct structures to UTF-8 strings which allow actual O(1) indexing into the data, but that’s something that can be built on top of both the Text and ByteString types.

                                                                                                                            1. 1

                                                                                                                              It sounds like you missed the /i in the parent post. I know, it’s subtle ;)

                                                                                                                              1. 1

                                                                                                                                That is not the parent post. Axman6 was replying to David. :)

                                                                                                                                1. 1

                                                                                                                                  argh, thread’s too too long :)

                                                                                                                              2. 1

                                                                                                                                This comment reads very much like you’re quite ignorant of the actual state of strings in Haskell, particularly given how many people complain that we have too many representations.

                                                                                                                                I don’t use Haskell but the complaints that I hear from folks that do are nothing to do with the number of representations, they are to do with the number of abstract data types that you have for strings and the fact that each one is tied to a specific representation.

                                                                                                                                Whether text is stored as a contiguous array of UTF-{8,16,32} or ASCII characters, as a tree of runs of characters in some encoding, embedded in an integer, or in some custom representation specifically tailored to a specific use should affect performance but not semantics of any of the algorithms that are built on top. You can then specialise some of the algorithms for a specific concrete representation if you determine that they are a performance bottleneck in your program.

                                                                                                                                One thing I have wanted to do for a while is add succinct structures to UTF-8 strings which allow actual O(1) indexing into the data, but that’s something that can be built on top of both the Text and ByteString types.

                                                                                                                                It’s something that can be built on top of any string abstract data type but cannot be easily retrofitted to a concrete type that exposes the implementation details without affecting the callers.

                                                                                                                                1. 1

                                                                                                                                  number of abstract data types that you have for strings and the fact that each one is tied to a specific representation

                                                                                                                                  The types are the representations.

                                                                                                                                  You can write algorithms that would work with any of String and Text and Lazy.Text in Haskell using the mono-traversable package.

                                                                                                                                  However, that whole bunch of complexity is only justified if you’re writing a library of complex reusable text algorithms without any advanced perf optimizations. Otherwise in practice there just doesn’t seem to be that much demand for indirection over string representations. Usually a manual rewrite of an algorithm for another string type is faster than adding that whole package.

                                                                                                                            1. 3

                                                                                                                              This suffers from the same issue as most “new shell” languages: it doesn’t have a good interactive story. The progress from typing on CLI to pasting together a script is core to why shell scripting is interesting.

                                                                                                                              So far Xonsh has been something that tries to address both sides. I’m no python fan, but it feels like the right direction.

                                                                                                                              1. 1

                                                                                                                                Obviously different people have different habits and needs, but I don’t need a shell language to have an interactive story at all. When I write shell scripts, I don’t start by typing into an interactive terminal and then move to a script. For me, the start is almost always “I need to run these (5, 10, 50) commands on a whole bunch of files (or directories).” Then I think, “Go is definitely too much, and I don’t want to fiddle with the plumbing required in Python to execute commands, capture stdout and stderr, etc.” For me, a shell scripting language with reasonable defaults and straightforward, simple syntax that makes it easy to run commands is a dream, regardless of whether it has an interactive story or not.

                                                                                                                                1. 1

                                                                                                                                  I completely agree as an end goal (I’ve written countless 10+-liners at the prompt just because fish made it easy), but what’s fixable doesn’t doom the language. So I think it’s fine to focus on the language before adding interactivity.

                                                                                                                                  Related: What really needs replacing is not so much bash, but those “minimal POSIX shells” like dash and busybox ash that don’t even support arrays, which makes anything of substance impossible to write correctly. So I would like to see a really minimal but still correctness-conducive language that could actually succeed on embedded. Here, interactive features are less important. I’m glad someone else did it, so I didn’t have to.

                                                                                                                                1. 2

                                                                                                                                  So as usual, consider not writing Ruby, but if you do, use type signatures, and maybe 100% branch coverage too, as annoying as it seems.

                                                                                                                                  Could someone more into Ruby ecosystem explain why the OP could have written this paragraph about “not writing Ruby”? Is Ruby a dying language?

                                                                                                                                  1. 5

                                                                                                                                    strong opinion syndrome

                                                                                                                                    1. 4

                                                                                                                                      People thinking only strictly typed languages are worthy are prone to not recommend not strictly typed languages like Ruby. I like Ruby and I have made extensive refactors without Sorbet&co by having confidence in my tests. My colleague who swears by C# and Typescript will talk your ears off “proving” how such a thing is impossible.

                                                                                                                                      To each their own and let’s stop trying to find the one size fits all magical tool.

                                                                                                                                      1. 4

                                                                                                                                        OP was a big ruby community member with many contributions to his name, who fell out with ruby for, first, not solving the language and runtime issues he thought were the most important, then, for solving them in a way he likes. He does go now.

                                                                                                                                        1. 3

                                                                                                                                          If you want what this post wants (good types and safety rails) Ruby is a bad choice for those things. Sure there is sorbet and writing a billion tests, but even Crystal would be a better choice if those things are your priority.

                                                                                                                                          If you want is to play with a highly malleable environment and don’t want smalltalk then Ruby is where it’s at, though.

                                                                                                                                          1. 2

                                                                                                                                            I can’t speak about the OP, but Ruby definitely isn’t dying. It might not be growing, but it is keeping a good level and there are new devs coming to Ruby all the time.

                                                                                                                                            1. 1

                                                                                                                                              They are into Go, based on the other posts on the blog.

                                                                                                                                            1. 1

                                                                                                                                              This is a really interesting series and I’m curious to see how it goes for you as I’ve been pondering similar things for a project I’m working on.

                                                                                                                                              One thing that’s crossed my mind is: the GPL is about allowing people to make changes and distribute those changes. What do you think of a scenario where someone buys your app, makes some changes to suit themselves or a different use case then publishes the code on GitHub, which they’re allowed to do? They don’t even really need to make changes, they could just put the code online for whatever reason.


                                                                                                                                              There have been recent issues over at Elementary and one of their founders has mental issues, so not the most stable example, but still, an example.

                                                                                                                                              This seems a little unfair and an unnecessary detail. Elementary has been funding itself for years (at least 7) with this model so any recent events don’t really have an impact.

                                                                                                                                              1. 2

                                                                                                                                                What do you think of a scenario where someone buys your app, makes some changes to suit themselves or a different use case then publishes the code on GitHub, which they’re allowed to do? They don’t even really need to make changes, they could just put the code online for whatever reason.

                                                                                                                                                I’m perfectly fine with that. If I wasn’t, GPL would be a bad licensing choice. My entire GitHub profile is filled with open source, and the plan was to put leafnode there like the rest. But, this is an interesting avenue to explore, both out of curiousity and because it’s different that what I previously did.

                                                                                                                                                This seems a little unfair and an unnecessary detail.

                                                                                                                                                Yes, re-reading that part makes it sound way harsher than I intended. Will remove that once I’m near my workstation again.

                                                                                                                                                1. 2

                                                                                                                                                  What do you think of a scenario where someone buys your app, makes some changes to suit themselves or a different use case then publishes the code on GitHub, which they’re allowed to do? They don’t even really need to make changes, they could just put the code online for whatever reason.

                                                                                                                                                  I’m perfectly fine with that. If I wasn’t, GPL would be a bad licensing choice. My entire GitHub profile is filled with open source, and the plan was to put leafnode there like the rest. But, this is an interesting avenue to explore, both out of curiousity and because it’s different that what I previously did.

                                                                                                                                                  There are two other problems that I’ve seen with folks who try the approach that you’re doing.

                                                                                                                                                  The first is a variant of the innovator’s dilemma. You’re doing the work of creating the thing, and you’re making it a bit harder for folks that don’t pay you to use it. Someone else who packages it has far less work to do than you. There’s nothing stopping someone else from building GPL’d installers and putting instructions somewhere public. They don’t have to spend any of the effort to create the thing in the first place, so they can spend more time on the packaging than you. They can easily produce something easier to install than you can, for the same investment in effort. You’re explicitly framing the sale as the end user paying for you to do the easy thing (packaging), not the difficult thing (writing the code in the first place), so you have to compete with people who do only the easy thing.

                                                                                                                                                  The second problem is if someone extends your code with something under a different but compatible license. For example, if they wrap it in something AGPLv3 (since you didn’t specify a GPL revision, I’m going to assume that you meant the latest version). Their fork is under a more restrictive license, will you want to take their changes? Forking is a fact of life for any open source project but when there’s a paid option then some people will intentionally license their changes under a license that they believe that upstream won’t take so that they’re not releasing work to support a paid product.

                                                                                                                                                  The cases have a lot in common. You’re relying on giving 95% of something away for free and charging people for the remaining 5%. Other people can easily provide that 5% and charge for it, give it away, or give it away in such a way that you’re likely to be unwilling to merge it into your version. In the latter two cases, they can add other things that differentiate their version from yours. What’s your expected strategy here?

                                                                                                                                                  1. 1

                                                                                                                                                    Every libre-non-gratis project sees gratis distribution one way or another. Conversations has several gratis forks, yet the author still makes enough from the official app to keep going. Synergy was the most popular version of their own software for many years. Etc.

                                                                                                                                                    1. 1

                                                                                                                                                      Thanks for mentioning the two. synergy has only an open core left, but I added a section on conversations.im to the page

                                                                                                                                                    2. 1

                                                                                                                                                      Do you have example cases of the scenarios described happening? I already had trouble compiling the list because for sale GPL software is quite rare. I’d love to expand the list. One example has been given in a comment below, another messaging client.

                                                                                                                                                      If people make use of the freedoms the GPL gives them, how is that not a wonderful thing? I do not expect to make a profit, if I a few years the running costs are covered that would be great but I even doubt that that will happen.

                                                                                                                                                      The return value for me if not in the money but in the experience gained. Both with the Qt framework as well as the distribution side. The extra Qt experience has lead to a promotion at work and the appimage / installer part had extended my knowledge which was also directly applicable at work. A few technical challenges gave me more insight in lower level multiplatform threading and concurrency limits with c++, (looking at you, recursive mutexes) which otherwise I wouldn’t have to dive into so deep, so all in all, even without sales I already got a large amount of value back.

                                                                                                                                                      And to be honest, if someone forks my app and changes or extends it, it means it (partly) fills a need they have. Enormously flattering that would be.

                                                                                                                                                    3. 1

                                                                                                                                                      I’m perfectly fine with that. If I wasn’t, GPL would be a bad licensing choice. My entire GitHub profile is filled with open source, and the plan was to put leafnode there like the rest. But, this is an interesting avenue to explore, both out of curiousity and because it’s different that what I previously did.

                                                                                                                                                      Fair enough. I’m curious to see how it works out too. :)

                                                                                                                                                    4. 1

                                                                                                                                                      has mental issues

                                                                                                                                                      Yeah, this feels off-base. Lunduke is not a good-faith arbiter here.

                                                                                                                                                    1. 23

                                                                                                                                                      Maintenance cost of bash scripts is lower

                                                                                                                                                      I would strongly disagree with this. Unless the script is very simple - only single commands, few variables - shell scripts can have many pitfalls that many people don’t realise until things go wrong. Pipelines and subshells and their side effects are not widely understood, for example.

                                                                                                                                                      c.f. https://lobste.rs/s/5ldmtp/pipefail_how_missing_shell_option_slowed -> https://lobste.rs/s/wl6kem/simple_script_is_still_someone_s_bad_day

                                                                                                                                                      Don’t get me wrong, shell scripts do have their place, but for anything even vaguely complex they’re generally the wrong choice. Use the right tool for the job.

                                                                                                                                                      Oh and lastly:

                                                                                                                                                      Every machine has bash installed

                                                                                                                                                      As a BSD user, this is not true. :-)

                                                                                                                                                      1. 4

                                                                                                                                                        Unless the script is very simple

                                                                                                                                                        You can do a lot of useful stuff with simple bash scripts. I probably write one per week. Lets look at an example:

                                                                                                                                                        https://github.com/no-gravity/git-retroamend

                                                                                                                                                        4 lines of code. Saves me a lot of hassle every time I need it.

                                                                                                                                                        Pipelines and subshells and their side effects are not widely understood

                                                                                                                                                        They can even be indeterministic:

                                                                                                                                                        https://www.gibney.org/the_output_of_linux_pipes_can_be_indeter

                                                                                                                                                        1. 2

                                                                                                                                                          You can do a lot of useful stuff with simple bash scripts.

                                                                                                                                                          I’m not disputing that. I’ve been writing shell scripts for a very long time, and I use them where they’re appropriate. What I am disputing is your statement that the maintenance cost of shell scripts is lower compared to other languages. If you’re only ever writing simple scripts this is often true; but if you’re comparing shell to other languages there was probably a need to use the other language in the cases they were used.

                                                                                                                                                          They can even be indeterministic:

                                                                                                                                                          Indeed. You’re kind of making my argument for me. :-)

                                                                                                                                                          1. 5

                                                                                                                                                            With “maintenance cost” I do not mean the cost to change the functionality. I mean that from time to time you have to change your script because the language changes. I expect Bash to have less of these breaking changes than most other languages.

                                                                                                                                                            1. 3

                                                                                                                                                              from time to time you have to change your script because the language changes

                                                                                                                                                              What? I mean, there was python 2 to 3 and Ruby 1.8 to 1.9, but I don’t think breaking language changes are common?

                                                                                                                                                              1. 5

                                                                                                                                                                Python in my opinion is an example for high maintenance cost. They sometimes do backwards-incompatible changes within a major version. For example Python 3.7 introduced “async” as a reserved keyword, breaking code that used “async” as a variable name.

                                                                                                                                                                If you follow each version update of Python, you will probably recognize all breaking changes as deprecations in earlier versions. But if I would just write a script, leave it alone for 10 years and then try to run it with the latest Python version, I would not bet on it running without errors. Whereas for bash scripts I would assume they still work.

                                                                                                                                                                But for bash scripts it totally depends on which programs you call.

                                                                                                                                                                1. 1

                                                                                                                                                                  The needless breaking changes are my least favorite parts of Python and Node.

                                                                                                                                                          2. 2

                                                                                                                                                            You can put this directly in your .gitconfig. I have the following in mine:

                                                                                                                                                              # "commit fix <commit>" - Add index files to given commit without changing
                                                                                                                                                              # its message.  For more control, create a temp commit, then "rebase -i" and
                                                                                                                                                              # use fixup and edit (which lets you change commits msgs)
                                                                                                                                                              cfix =  "!f() { \
                                                                                                                                                                local committofix=${1:-HEAD}; \
                                                                                                                                                                git commit --fixup="$committofix"; \
                                                                                                                                                                git rebase -i --autosquash "$committofix"^; \
                                                                                                                                                              }; f"
                                                                                                                                                            
                                                                                                                                                          3. 0

                                                                                                                                                            Also NixOS.

                                                                                                                                                          1. 1

                                                                                                                                                            I thought they had threads before? What is the change here?

                                                                                                                                                            1. 2

                                                                                                                                                              While you could reply to messages, they weren’t threads. Instead, they were more like regular messages that quoted whatever you replied to. The new threads feature is essentially that plus the ability to group all the replies together.

                                                                                                                                                            1. 6

                                                                                                                                                              This is… pretty half-baked. There’s no mechanism for code in the wasm side to query the liveness of an object, or to contribute liveness from the wasm-side, or to hold weak refs to a JS object, and you should definitely use window.requestIdleCallback() rather than setTimeout() or setInterval()

                                                                                                                                                              Weak refs are an invaluable (and non-substitutable) tool for developing robust systems that stay up for long periods, such as line-of-business GUIs, and to leverage the built-in collection machinery for eventing systems that don’t leak without having to know the gory details of who’s listening, but if they’re done poorly you’ll just get a false sense of security and even weirder bugs and edge cases.

                                                                                                                                                              1. 2

                                                                                                                                                                Yeah; after reading the article my takeaways are:

                                                                                                                                                                • I’m going to need a reference counting mechanism inside the WASM vm, and I call refcount_release(ptr) instead of calling the destructor directly.
                                                                                                                                                                • Let’s wait for FinalizarionRegistry after all.

                                                                                                                                                                The idea of polling memory for release sounds fairly wasteful to me. But even a loop over 10,000 objects is probably no time at all compared to any DOM finagling.

                                                                                                                                                                1. 1

                                                                                                                                                                  Sadly agree that the author didn’t know enough about the topic to really make any case. To pick one example, a weak ref can’t catch cycles, which is one of the basic things a garbage collector does.

                                                                                                                                                                  1. 1

                                                                                                                                                                    Pretty sure the only point here is to feed licenses data from the JS GC back into wasm

                                                                                                                                                                    1. 1

                                                                                                                                                                      That doesn’t make any sense. Weak refs are part of the API of a collector, cycle detection is an implementation detail, and only a thing if you’re reference counting. Mark-and-sweep style collectors don’t need to do it.

                                                                                                                                                                  1. 1

                                                                                                                                                                    That looks cool, I might try. I like org mode in theory but I can’t quit Emacs and the syntax just looks ugly, and is bad ergonomics without tools (like, really? I need to type six *? Get out). But this looks much closer to what I already write by hand, but with additional tooling.

                                                                                                                                                                    If OP makes a version of this to VSCode, I might marry them.

                                                                                                                                                                    1. 2

                                                                                                                                                                      I get the point you’re trying to make, but an asterix denotes a heading, just like # in markdown. You generally wouldn’t go deeper than 3, maybe sometimes 4. And it’d say it’s pretty intuitive to add heading levels using TAB, or use M-RET to add a new item on the list you’re in.

                                                                                                                                                                      1. 1

                                                                                                                                                                        Maybe I’m misremembering org-mode, but I thought that asterixis where for lists? I type new list items, and move then under and out of other items MUCH more often than I add headings.

                                                                                                                                                                        1. 1

                                                                                                                                                                          org-mode asterisks are for headings however headings are used for almost all things you might imagine to be lists

                                                                                                                                                                          1. 1

                                                                                                                                                                            - is unordered list, + is bulletpoints and finally [[:digit:]]+\. is for a numbered list.

                                                                                                                                                                        2. 1

                                                                                                                                                                          (like, really? I need to type six *? Get out)

                                                                                                                                                                          In standard org-mode, you can also go to the line before the one where you want a new line, press alt+enter to get a new line with an equal number of asterisks as the one where you were. Then, press tab to cycle between one more, one less, two less, etc asterisks.

                                                                                                                                                                          There are a shitload of keybindings in org-mode, I don’t even know the tip of the iceberg.

                                                                                                                                                                          1. 1

                                                                                                                                                                            Yeah, but that’s my point. I’m sure it can be pretty easy to use with the tooling, but if I need to edit it somewhere, it’s an annoying format.

                                                                                                                                                                            The one on this post, though, it’s basically how I already write notes and todos.

                                                                                                                                                                            1. 1

                                                                                                                                                                              ah, org-mode being the tooling. Isn’t that the same though with the one in this post? You’d have to indent with spaces (which can be annoying too) and then type a dash. Auto-indentation is also tooling, and if you don’t set it up correctly, the tool you’re using might decide to indent with tabs, which might be even more annoying.

                                                                                                                                                                              1. 1

                                                                                                                                                                                Hmm, ok, you have a point, BUT: auto indentation is much more prevalent, basically any editor I use has it somehow. Even freaking google keep has it. And on top of that, even if there isn’t, typing tabs e faster than typing *

                                                                                                                                                                        1. 22

                                                                                                                                                                          I’ve been complaining to banks for over a decade that they train people to fall for this kind of scam. They cold call their customers and require the customer to authenticate by providing information about the account, before the bank will tell you anything. At the start of the conversation, neither party knows that the other party is who they claim to be but the bank has a bit higher confidence because they’ve called a number that’s on file. The customer has absolutely know information in the other direction: they have the caller ID number, which can be forged, and absolutely nothing else. The burden should be on the bank to prove that they are the bank, at the start of the conversation.

                                                                                                                                                                          In the last year, Barclays has finally started doing something about it. The people that cold call you are now able to send a secure message through the app. If they call you, you log into the app, and see a message saying ‘hello, I am {person} from Barclays, I am talking to you on the phone’ then you know that one of the following is true:

                                                                                                                                                                          • They are from the bank.
                                                                                                                                                                          • They have compromised the bank’s back-end system.
                                                                                                                                                                          • They have compromised the device that you’re running the app on.

                                                                                                                                                                          Of these, the first is probably a safe assumption. If it’s the second, you’re completely screwed anyway in the short term, but it’s definitely the bank’s liability. If it’s the third then they have probably compromised the app to the extent that they could also instruct it to make transactions on your behalf, so there’s not much of a downside to talking to them.

                                                                                                                                                                          1. 5

                                                                                                                                                                            A few years back, a friend of mine was at the bank when he received a phone call from the corporate call centre of that same bank. He did trust the unsolicited call, so he turned it over the the assistant branch manager he was currently speaking with to confirm that this wasn’t a scam.

                                                                                                                                                                            Several weeks later, he got a call back from the branch manager confirming that it had been a legitimate call. It had taken their own security team that long to figure out whether or not their own calls were legit.

                                                                                                                                                                            1. 5

                                                                                                                                                                              My company just switched to SAP Concur for expense reporting. Soon after, I got an email asking me to complete my profile. The link went to “http://links.concurtechnologies.mkt7817.com/els/v2/XXXXXXXXX”. Going to mkt7817.com showed a generic Anti-Spam and Privacy statement. Nothing to do with SAP Concur, although there’s an “abuse@silverpop.com” email listed; silverpop.com gets bounced to “acoustic.com”, which talks about “Curating the Banking Experience.” Despite all appearances, it was a legitimate email.

                                                                                                                                                                              I have no clue why a purportedly experienced and professional company would think this is OK.

                                                                                                                                                                              1. 5

                                                                                                                                                                                100%. I just got a call from my local Chase branch the other day: “Hi this is Jack from Chase, I wanted to discuss your account.” A google of the phone number didn’t even link back to the bank. I told him I needed some verification.

                                                                                                                                                                                He sent me an email from his Chase email account that was verifiable, but I remember having the same feeling like, given the scams that are ongoing why would Chase communicate with customers like this as a policy?

                                                                                                                                                                                1. 4

                                                                                                                                                                                  He sent me an email from his Chase email account that was verifiable

                                                                                                                                                                                  How was it verifiable? I bet most Chase customers aren’t able to verify DKIM signatures reliably…

                                                                                                                                                                                  1. 2

                                                                                                                                                                                    Most are not, I’m a security engineer so it’s not a big deal for me. Actually I have Thunderbird set to verify DKIM automatically.

                                                                                                                                                                                2. 3

                                                                                                                                                                                  The banks here have been doing electronic ID for about 20 years and I don’t recall getting a single call ever.

                                                                                                                                                                                  I wonder what the scams here are like.

                                                                                                                                                                                  1. 1

                                                                                                                                                                                    Here it’s phishing email. The banks I’m with have clear communications, strong paper-based auth since before apps, and perpetual warnings about frauds everywhere.

                                                                                                                                                                                    Their problems are with UX and shitlisting rooted androids/Sailfish’s android support, but scams are easy to pick up on cuz it’s all email.

                                                                                                                                                                                    Or I’ve been lucky and only received those “support” calls from “Microsoft”.

                                                                                                                                                                                  2. 2

                                                                                                                                                                                    I’m not sure my banks have a phone number for me. If they tried to call me they would only get voicemail.