1. 6

    As much as I would like for this to be true, there have been many claims of decipherment, and all have pretty strong counterarguments. I’m curious to see the responses from the community.

    1. 6

      Especially claiming that it’s written in an otherwise completely unattested Romance language in a unique orthography that derives from Latin alphabet is… dubious at best. I’d love to be proven wrong, of course.

      My pet theory is that it’s a written entirely in some scribe’s own custom shorthand, perhaps purposefully obfuscated. Arbitrary use of abbreviations (and their numerous variant forms) would also make it really difficult to decipher in that case.

      1. 3

        A completely unattested Romance language that was also apparently a lingua franca of southern Europe, but everyone just sort of…forgot.

        1. 2

          Something something Albigensian Crusade and gnosticism.

          1. 2

            To be fair, the Gnostics were about keeping their stuff secret…

    1. 1

      This seems like a blurb that reiterates the myth that garbage collected languages are inherently bad for performance, wrapped around a paper that reinvents hardware-assisted garbage collection, an idea that existed since ’80s.

      1. 16

        The fact that an idea has existed since the ’80s should not be grounds for dismissal.

        From the article, regarding prior work:

        While the idea of a hardware-assisted GC is not new [5]–[8], none of these approaches have been widely adopted. We believe there are three reasons:

        1. Moore’s Law: Most work on hardware-assisted GC was done in the 1990s and 2000s when Moore’s Law meant that next-generation general-purpose processors would typically outperform specialized chips for lan- guages such as Java [9], even on the workloads they were designed for. This gave a substantial edge to non-specialized processors. However, with the end of Moore’s Law, there is now a renewed interest in accelerators for common workloads.
        2. Server Setting: The workloads that would have benefitted the most from hardware-assisted garbage collection were server workloads with large heaps. These workloads typically run in data centers, which are cost-sensitive and, for a long time, were built from commodity components. This approach is changing, with an increasing amount of custom hardware in data centers, including custom silicon (such as Google’s Tensor Processing Unit [10]).
        3. Invasiveness: Most hardware-assisted GC designs were invasive and required re-architecting the memory system [8], [11]. However, modern accelerators (such as those in mobile SoCs) are typically integrated as memory-mapped devices, without invasive changes.
        1. 3

          You’re right, I didn’t mean to dismiss the paper, just the article that makes it sound like a novel idea. On the contrary, I’m glad that HWAGC is getting attention at this age.

        2. 3

          Is it a myth? There seems to be a trend here that the non-garbage-collected languages are faster: https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html

          1. 5

            It’s got a bit of truth in it, in that most garbage collectors commonly used are mediocre at best and our modern processors are optimised towards dynamic allocation.

            jwz has a good summary of the GC ordeal.

            1. 3

              I don’t understand your citation. I have read that article, but what does it have to do with dynamic allocation?

              Although I generally like jwz’s writing, I’m not convinced by the second citation either, because it’s over 20 years old and basically saying that at that time the only good GCs were in Lisp implementations. Something that surveys the current state of the art would be more convincing.

              Personally I think GC’s are invaluable, but you can always do better by applying some application-specific knowledge to the problem of deallocation. There are also many common applications and common styles of programming that create large amounts of (arguably unnecessary) garbage.

            2. 8

              Garbage collected environments can—and often do—have higher overall throughout than manually managed memory environments. It’s the classic batch processing trade off, if you do a lot of work at once it’s more efficient, but it won’t have the best latency. In memory management terms, that means memory won’t be freed right away. So GCs need some memory overhead to continue allocating before they perform the next batch free.

              This is one of the reasons iPhones circa 2014 ran smoothly with 1GB RAM, but flagship Androids had 2-3GB. Nowadays both have 4GB, as the RAM needed to process input from high resolution cameras dwarfs the memory concerns of most applications on either phone.

              Note the latency from batching frees (i.e. garbage collection) doesn’t refer to GC pause time. So called “stop the world” collection phases exist only in mediocre GC systems, like Java’s, because they’re relatively easy to implement. ZGC looks promising, 10+ year old GC technology is finally making it to the JVM!

              C/C++ also make it easier to control memory layout and locality, which massively improves performance in some cases. But as jwz points out in the post linked by @erkin, GC languages could provide similar tools to control allocations. No mainstream GC language does, probably since the industry already turns to C/C++ for that by default. Unity comes close, they made a compiler for a C# subset they call HPC#, which allows allocation and vectorization control. And I think D has some features for doing this kind of thing, but I wouldn’t call D mainstream.

              1. 5

                Chicken Scheme, uses stack for the ‘minor’ garbage collection.

                https://www.more-magic.net/posts/internals-gc.html “… This minor GC is where the novelty lies: objects are allocated on the stack. … “

                Stack memory, by itself is typically a contiguous block (an well optimized part of virtual memory). I think in general, the trend in GC is to have ‘categories’ of memory allocation models, where the optimizations is done per category. The determination of categories is done at compile time, with a possibility of a memory allocation to graduate (or move) from one type/category to another (not using ‘categories’ in algebraic sense here).

                1. 1

                  I’m not sure I buy that argument, because GC inherently does more work than manual memory management. It has to walk the entire heap (or parts of it for generational GC), and that’s expensive. You don’t need to do that when manually managing memory. Huge heaps are still an “unsolved problem” in GC world, but they aren’t in manual world.

                  I’m a fan of GC, but I think the problem is that you can only compare the two strategies with identical/similar big applications, because that’s where GC really shines. But such pairs of applications don’t exist AFAICT.

                  1. 4

                    It has to walk the entire heap

                    No. There are many more interesting strategies than simple generational heaps.

                    You don’t need to do that when manually managing memory

                    Instead you just call malloc and free all the time, functions that lock, can contend with other threads, and needs to manipulate data structures. Compare to alloc in a GC world: atomic increment of arena pointer.

                    Huge heaps are still an “unsolved problem” in GC world

                    Azul’s GC manages hundreds of GBs without any global pauses. Huge enough for you? ZGC uses similar strategies, copying many of those ideas that have been around since 2008 (to my knowledge, likely earlier).

                    Unimplemented in common open source languages != unsolved.

                    But such pairs of applications don’t exist AFAICT

                    Compare IntelliJ and Qt Creator. Only it’s not a fair comparison, since IntelliJ runs on Oracle / OpenJDK Java, and that JVM still doesn’t have any good garbage collectors (ZGC is still in development / who knows if it will ever actually ship).

                    P.S. I love all the work you’re doing on Oil, and your blog posts are fantastic!

                    1. 4

                      Eh your reply reads very defensively, like I’m attacking GC. In fact most of my posts on this thread are arguing for GC for lots of applications, and I plan to use it for Oil. (Thanks for the compliment on the blog posts. I’ve been on a hiatus trying to polish it up for general use!)

                      I’m just pointing out that GC has to do work proportional to every objects on the heap. What are the other strategies that don’t need to do this? Whether the GC is generational, incremental, or both, you still have to periodically do some work for every single heap object. I think the article points out that incremental GC increases the overhead in exchange for reducing pauses, and I saw a recent retrospective on the new Lua GC where they ran into that same issue in practice.

                      (In Go, I think it’s a bit worse than that, because Go allows pointers to the middle of objects. Although Go also has escape analysis, so it’s probably a good engineering tradeoff, like many things Go.)

                      I also think you’re comparing the most naive manual memory management with the most sophisticated GC. Allocators in the 90’s weren’t very aware of threads but now they certainly are (tcmalloc, jemalloc, etc.)

                      Many (most?) large C applications use some kind of arena allocation for at least some of their data structures. For example, the Python interpreter does for it’s parse tree. It’s not just malloc/free everywhere, which is indeed slow.

                      Anyway, my point is that the batch processing argument tells some of the story, but is missing big parts of it. It’s not convincing to me in general, despite my own preference for GC.

                      Unsurprisingly, the comparison is very complex and very application-specific. It’s hard to make general arguments without respect to an application, but if you want to, you can also make them against GC because it fundamentally does more work!

                      1. 5

                        I don’t think you’re attacking GC, but I think you’re wrong about performance. Comparing jemalloc to G1GC, and similar generational collectors in common dynamic languages, you’re spot on. Generational collection shines in web application servers, which allocate loads of young garbage and throw it all away at the end of a request. But for long lived applications like IntelliJ it’s not so hot. Last I checked (which was a while ago) IntelliJ’s launcher forced the concurrent mark and sweep GC. Stuff like Cassandra and Spark are really poorly served by either of those GCs, since neither prevents long pauses when the heap is really large.

                        Batching pretty much does cover the argument. Assume you have a page of memory with dozens of small object allocations. Which is faster, individually calling free on 90% of them, or doing a GC scan that wastes work on 10% of them? As long as you can densely pack allocations, GC does very well.

                        Arenas are certainly a big win, but in many ways a page in the young generation is like an arena. Yes, manual memory management will always win if you perform all of your allocations in arenas, freeing them in groups as the application allows. Commercial databases do so as much as possible. gRPC supports per-request arenas for request and response protos, a clever answer to the young generation advantage for short stateless request / response cycles.

                        I might be wrong, but I don’t think you’re considering that GCs can use MMU trickery just as much as anyone else. Suppose instead of periodically scanning the old generation, you occasionally set 2mb hugeages of old objects as no read no write. If it’s accessed, catch the segfault, enable the page again, and restart the access. If it’s not accessed after a while, scan it for GC. Having access statistics gives you a lot of extra information.

                        Now imagine that instead of the random musings of some internet commenters, you have really clever people working full time on doing this sort of thing. There’s a whole world of complex strategies enabled by taking advantage of the memory virtualization meant to emulate a PDP-11 for naive programs. Normal incremental collection has more overhead because the GC has to redo more work. ZGC avoids lots of this because it maps 4 separate extents of virtual memory over the same single contiguous extent of physical RAM, and the GC swaps out pointers it’s looking at for different virtual addresses to the same physical address. Trap handlers then patch up access to objects the GC is moving.

                        The whole “GC is linear wrt total heap size” conventional wisdom is a myth, perpetuated by mainstream GCs not doing any better.

                        [GC] fundamentally does more work!

                        It’s still a win for a GC if executing more instructions results in fewer memory accesses. CPUs are wicked fast, memory is slow. Back when I worked on a commercial database engine, loads of our code paths treated heap memory like most people treat disk.

                        1. 1

                          The whole “GC is linear wrt total heap size” conventional wisdom is a myth, perpetuated by mainstream GCs not doing any better.

                          Which GCs avoid doing work linear in the # objects on the heap? Are you saying that ZGC and Azul avoid this?

                          This isn’t something I’m familiar with, and would be interested in citations.

                          I still think you’re comparing the most advanced possible GC with the status quo in manual memory management, or more likely lots of old C and C++ code. (There is apparently still work on manual memory management like [1].)

                          The status quo in GC is basically what JVM, .NET and various dynamic language VMs have.

                          But I’m interested to hear more about the advanced GCs. How do they avoid doing work for every object?

                          The permanent generation is something I’ve seen in a few designs, and the idea makes sense, although I don’t know the details. I don’t think it’s free, because whenever you have generations, you have to solve the problem of pointers across them, e.g. with write barriers. Write barriers incur a cost that doesn’t exist in manual management schemes. How much I don’t know, but it’s not zero.

                          I’d rather see concrete use cases and measurements, but if we’re making general non-quantitative arguments, there’s another one against GC.

                          [1] https://news.ycombinator.com/item?id=19182779


                          EDIT: To see another reason why the batch argument doesn’t work, consider Rust. Roughly speaking, the Rust compiler does static analysis and inserts deallocation at the “right” points.

                          It does not “batch” the deallocation or allocation, as far as I know. Are you saying that Rust programs are slower than the equivalent garbage collected programs because of that? Maybe they would be if marking the heap were free? But it’s not free.

                          Anyway, my goal isn’t to get into a long abstract argument. I’d be more interested in hearing about GC strategies to minimize the total overhead of scanning the heap.

                          1. 2

                            Which GCs avoid doing work linear in the # objects on the heap?

                            There are lots of ways to skip work. As you said, the Go GC handles pointers to the middle of objects. Using similar principles a GC can handle pointers to a page of objects, and free the whole page together. You also mentioned Go’s escape analysis at compile time. Do the same escape analysis and count the number of escaped objects for an entire region of memory, dump it when it hits zero. Mark regions that contain external references: if a page never had objects with pointer fields, or if all the pointer fields reference within the page, why scan its pointers before releasing the memory?

                            I still think you’re comparing the most advanced possible GC with the status quo in manual memory management, […] The status quo in GC is basically what JVM, .NET and various dynamic language VMs have.

                            I’m refuting your claims that “GC inherently does more work than manual memory management” and that large heaps are an “unsolved problem.” Large heaps aren’t unsolved. GC doesn’t “inherently” do more work. And regardless, number of operations doesn’t equal efficiency.

                            It does not “batch” the deallocation or allocation, as far as I know. Are you saying that Rust programs are slower than the equivalent garbage collected programs because of that?

                            Of course Rust programs aren’t always slower. But garbaged collected programs aren’t always slower either, that’s my entire point here.

                      2. 3

                        Instead you just call malloc and free all the time, functions that lock, can contend with other threads, and needs to manipulate data structures. Compare to alloc in a GC world: atomic increment of arena pointer.

                        I’m not an expert in GC theory but this looks like a bold statement to me. I think that efficient allocation schemes in multithreaded environment are both doable and rather common, and I think that memory allocation in most GC implementations is far more expensive than a single atomic pointer increment. I totally understand that in some cases, state-of-the-art GC can match the performance of manual memory allocation, but I have yet to see a proof that GC is always better than no GC.

                        1. 4

                          I’m not saying GC is always better, just that it can be, and often is. Plenty of C/C++ code does ordinary per-object malloc and free, especially C++ when virtual classes come into play. For those applications I claim a sufficiently advanced GC would have higher throughput.

                          As I discussed in my other comment, you can optimize manual memory code to only allocate into arenas, and free arenas at exactly the right time. Having domain knowledge about when an arena can be freed will certainly be better than the GC guessing and checking.

                          allocation in most GC implementations is far more expensive than a single atomic pointer increment

                          Correct. But I also claim most mainstream GC implementations are mediocre. If the environment doesn’t support object relocation by the GC, the allocator needs to fill gaps in a fragmented heap. When the GC can compact a fragmented heap and release large chunks of contiguous memory, the allocator barely has to do anything.

                  2. 4

                    The problem is that such benchmarks usually compare hand-tuned, optimized-to-death code examples, which are simply not representative of the way code is written in the wild.

                    If you have unlimited time to tune and optimize, the fewer amenities the language/runtime has, the better, so non-GC-languages will always have an edge in this scenario.

                    BUT: 99.9% of the time, this is not the scenario anyone is operating under.

                    1. 2

                      I don’t think it’s a myth either – the issue is more complex than than that. It depends a lot on the application, etc.

                      But I also don’t think the benchmarksgame is a strong indication either way, because those programs are all 10 or 100 lines long. You can always do better on small programs without garbage collection – i.e. by applying some problem-specific knowledge to the code.

                      Large applications are where garbage collection shines, because I think the number/probability of memory bugs like use-after-free or memory leaks scales nonlinearly with application size. But that’s exactly where it’s hard to do any meaningful comparison, because we don’t have 2 independent implementations of large applications.

                      My suspicion is that GC / manual memory management isn’t really a useful variable to separate good and bad performance. It’s kind of like how the language doesn’t have too much bearing on how good an application is. There are good and bad apps in C, in Java, in Python, in Lisp, etc. The difference between good and bad apps is very large, and whether they use garbage collection probably isn’t the most salient factor. You can be very sloppy about memory with GC, or you can be disciplined.


                      Also, FWIW I have been making a list of C and C++ programs that use some kind of garbage collection / automatic memory management. So far I have

                      If anyone knows of others, I’m interested! I’ve been thinking about garbage collection in Oil’s implementation (both for its own structures and user structures, but more of the former right now.)

                      1. 3

                        You are incorrect about that GCC link. One, it links to a very old version of the docs, ore modern docs are here: https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Garbage-Collection.html Two, it IS a feature for the programs it compiles, using the Objective C runtime.

                        1. 2

                          Hm it looks like I have the wrong link, but GCC does do some garbage collection?

                          https://dmalcolm.fedorapeople.org/gcc/newbies-guide/memory-management.html

                          I’ve never worked on GCC, but I think I read a comment on Hacker News that said it used GC which led me to Google for it.


                          Yeah I just checked the source and this looks like it’s in the compiler itself and not the runtime library:

                          ~/src/languages/gcc-9.1.0/gcc$ wc -l ggc*
                            1018 ggc-common.c
                             322 ggc.h
                             118 ggc-internal.h
                              74 ggc-none.c
                            2647 ggc-page.c
                             525 ggc-tests.c
                            4704 total
                          

                          This garbage-collecting allocator allocates objects on one of a set of pages. Each page can allocate objects of a single size only; available sizes are powers of two starting at four bytes. The size of an allocation request is rounded up to the next power of two (`order’), and satisfied from the appropriate page.

                          And it looks like it’s used for a lot of core data structures:

                          tree-phinodes.c:      phi = static_cast <gphi *> (ggc_internal_alloc (size));
                          tree-ssanames.c:      ri = static_cast<range_info_def *> (ggc_internal_alloc (size));
                          tree-ssanames.c:  new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size));
                          tree-ssa-operands.c:      ptr = (ssa_operand_memory_d *) ggc_internal_alloc
                          

                          This isn’t surprising to me because I have found memory management for hueg tree/graph data structures in compilers to be a big pain in the butt, and just this subdir of gcc is 1M+ lines of code. You really do want a garbage collector for that class of problems. However Clang/LLVM appears to use the C++ “ownership” style without GC. It seems very verbose though.

                        2. 3

                          If anyone knows of others,

                          Some game engines have their own garbage collection. I did not use any myself, but check https://wiki.unrealengine.com/Garbage_Collection_%26_Dynamic_Memory_Allocation

                          probably other C++ game engines offer something in this area too.

                          1. 2

                            Thanks that’s a great example! I found this link to be pretty good:

                            https://wiki.unrealengine.com/Garbage_Collection_Overview

                            I think the commonality is that games have huge graph data structures, just like compilers. On the other hand, scientific programs have more flat arrays. And web servers written in C++ have request-level parallelism / isolation, so memory management can be simpler. So yeah it depends on the app, and for certain apps garbage collection is a huge win, even in C++.

                    1. 13

                      The behavior this allows for (each window taking over its parent’s window, rather than spawning a new window) has been something I wanted to demonstrate on Wayland for a very long time. This is a good demonstration of how Wayland’s fundamentally different and conservative design allows for some interesting use-cases which aren’t possible at all on X11.

                      It’s not entirely impossible. I hacked together something with dwm to allow a terminals to swallow graphical programs: https://dwm.suckless.org/patches/swallow/

                      It abuses the X Resource Extension for fun and profit.

                      1. 6

                        You can achieve the same effect and separation with Xorg, even on the lower levels (3d acceleration). Few distributions enable it by default, but build with ‘Xephyr’ and spawn that instead of Xserver through your outer WM (so dwm in this case) with a kiosk-like WM (ratpoison) that fullscreens the latest connected client. Unlink, randomise -display “number”, preload-interpose or otherwise namespace-out the socket path that DISPLAY=:xx would normally resolve to and there is your client isolation as well.

                        1. 4

                          Wow, very impressive. I was wondering if this was feasible with X11 after seeing Arcan do it. It seems much more useable than 9wm.

                          1. 2

                            Floodgap’s web proxy uses Windows-1252 encoding by default for, what I presume to be, compatibility reasons. Most clients default to UTF-8, however.

                            1. 2

                              In my gopher clients it seems to work as intended: https://i.postimg.cc/dVq5pDVj/Screenshot-20190421-160850-Pocket-Gopher.png and https://i.postimg.cc/C1jDwHvB/Screenshot-20190421-161321-Diggie-Dog.png Lynx on the client as well. Have you tried a Gopher client?

                              The browser expects an encoding and I’m not sure how the floodgap proxy handles that for plain text files that don’t specify one.

                              1. 1

                                Interesting, so gopher clients assume all content is UTF-8 (or whatever encoding you’ve used here)?

                                1. 2

                                  I guess so? The python script explicitly does UTF-8 and the clients I test with seem to as well. For the filenames I do strip out all except a-zA-Z.

                                  1. 1

                                    Why not allow numbers? Right now there are names like Queen_Attends_Easter_Service_on___rd_Birthday.

                                    1. 1

                                      No specific reason. I changed the regex so numbers are allowed now.

                                  2. 1

                                    The one I wrote assume UTF-8 as I found more pages using that than ISO-8859-1 or Windows-1252. It’s also pretty clear that UTF-8 is the way forward for encoding.

                                    1. 1

                                      Hey you’re behind the Boston diaries, but rumor goes, not even from, in or near Boston! I like reading your site and Gopherhole

                                      1. 1

                                        Thanks. There is a story behind the name.

                                        1. 1

                                          I’m amused to see a number of people I’ve started following on gopher I’ve already seen on Lobste.rs or Mastodon and didn’t know it.

                                1. 4

                                  It is great to see more services supporting dvcs other than git. Can someone who prefers to use Mercurial share some.of their experiences wirh it and what makes it better for them? Not trying to start a flamewar, just being curious about it

                                  1. 17

                                    I’ll just C&P and update the last time I wrote what was so awesome about hg:

                                    Here’s a list of Mercurial features that I think are really cool:

                                    • Revsets – a domain-specific language for querying your commits
                                    • Filesets – a domain-specific language for selecting files
                                    • Templates – a domain-specific language for altering the output of almost every command. Putting these together you can do things like this.
                                    • Evolution – a distributed and safe way to share rewrites (think automatically recovering from upstream rebase without any git reset –hard and no git push –force).
                                    • Absorb – automatically amends an entire stack of WIP commits at once by picking the right diffs from your working directory based on which commits’ contexts they fit best.
                                    • Curses interface for hunk-picking – a unified interface for splitting diffs for any purpose: whether to revert working-directory changes, write a new commit, uncommit parts of a commit, or amend a commit with more diffs. Just add –interactive to any of those commands and start picking hunks!
                                    • Curses interface for redrafting your commits – think git rebase -i with a curses interface (this is quite new, in the lastest relase; I’ve made a few UI tweaks to it that should show up in the next release)
                                    • A fairly rich built-in web interface – hg serve and point your browser to http://localhost:8000 and you’re good to go.
                                    • Lots of support for monorepos – indeed, this is the main reason that Google, Facebook, and Mozilla are all pouring work into hg and are using it.
                                    • A consistent UI – this one is more subjective but often-touted feature of Mercurial. If a command accepts a revision/hash/tag/bookmark; it always uses the -r/–rev flag for it (and you can also always use a revset for any command that accepts a revision). If a command allows hunk selection, it always uses the -i/–interactive flag for it. The help for every command fits in about a screenful; no never-ending man pages full of arcane flags and explanations you don’t understand nor care about.

                                    Give it a try! Mercurial is neat!

                                    1. 4

                                      For 90% of your workflow, there’s no big difference. The other 10% can be painful to get used to. For instance, Mercurial does not have Git’s concepts of “staging area” and “tracking branch”, which simplifies things.

                                      I’m more comfortable with Git purely because I’m used to it but I’ve recently taken a liking for Mercurial. It feels sturdier and more consistent.

                                      Edit: I forgot to mention that Mercurial is very modular. Not only are there various extensions to simplify your workflow, you can write your own extensions to suit the needs of your project.

                                      1. 2

                                        mostly a sane UI/UX. But also it’s easily extensible with python, and it has neat things like revsets.

                                        1. 2

                                          I wrote an article about it, to copy/paste some relevant parts:

                                          My chief gripe with git is its user interface. With ‘user interface’ I mean the commandline user interface. Let me show by example:

                                          $ git help commit | wc -l
                                          506
                                          $ hg help commit | wc -l
                                          59
                                          $ hg help commit -v | wc -l
                                          96
                                          

                                          Currently my git installation has 169 “core” commands:

                                          $ find /usr/lib/git-core -maxdepth 1 -type f -executable | wc -l
                                          169
                                          

                                          Compare this to mercurial’s 50 built-in commands (from hg help), a number which has remained constant since I wrote this article (whereas git had 160 commands when I first wrote this 2 years ago).

                                          “But git commit has so many more features”, well, perhaps. But how many of those are actually used by most users? Mercurial can be easily extended, and most “missing” features are implemented in extensions (many are shipped with the base mercurial install). For better or worse, git is bloatware, and like most bloatware it comes with a [notoriously difficult to understand manual][git-man].

                                          Mercurial has a manual and user interface that I understand without too much effort, and this is by far the biggest reason I much prefer mercurial over git. If I need to know something from mercurial I can just read the documentation and go ‘ah’, with git … not so much. There’s a reason so many of the [top Stack Overflow questions][so-top] are about git.

                                          Some might say (and indeed, have said) that I’m lazy and just need to spend more time and effort learning git. Well, perhaps, but the thing is, git doesn’t really do anything. Unlike a programming language or API I can’t really build anything with it. It’s merely logistics to facilitate the actual building of stuff.
                                          It seems to me that ideally you want to spend as little as possible time on logistics, and as much possible time on actually building stuff. I know enough git to get by, but not enough to deal with rare exceptional situations that occur only a few times a year.

                                          1. 1

                                            Broadly, they both have comparable functionality (at least for what I need), but mercurial is more friendly where git is more flexible. By and large, hg stops you from doing things that you probably don’t want to do, and makes the most common actions easy.

                                            That said, I switched to git a few years a back and am happy with the move. It seems trivial, but one thing that I prefer in git to hg is the ability to manipulate branches. In git a branch is just a reference to a commit, and so can be moved, renamed, deleted. In hg branches are a core part of how the repo is structured and can’t be changed. If you use a feature-branch strategy, this leads to either a) a lot of old, essentially dead branches or b) hacky workarounds using bookmarks.

                                            This is somewhat indicative of the overall experience - hg is simple if you use it the expected way, but gets messy otherwise. Git is always a bit fiddly but is far less prescriptive.

                                            1. 2

                                              The hg analog to a git branch is called a bookmark. The difference in nomenclature is unfortunate and an artifact of history but the same functionality exists.

                                              1. 1

                                                Yes, I know. I mentioned bookmarks in my reply. Perhaps it’s just my experience, but bookmarks (especially when used in conjunction with branches) tends to be rather clunky compared to branches in git.

                                                1. 2

                                                  I don’t know very many people who actually use the hg branch feature. Pretty much everyone just uses bookmarks. I don’t personally find the clunky but they’ve been improved quite a bit since their first appearance. They are pretty close to a one to one match with a git branch for my needs.

                                                  1. 1

                                                    In fairness, I haven’t used hg for around 5 years (maybe longer). Back then, hg branch was idiomatic - we tacked on bookmarks to our workflow to handle temporary branches, but it was never smooth.

                                          1. 2

                                            I could understand liking vi’s command set, I suppose, but I don’t share in the lauding of the program itself. Not only is it nothing special, but it’s not an enviable design to start with.

                                            These relevant passages from chapter six, ’‘Terminal Insanity’’, of the ’‘The UNIX-HATERS Handbook’’ come to mind:

                                            Unix (through the hand of Bill Joy) took a third approach. The techniques for manipulating a video display terminal were written and bundled together into a library, but then this library, instead of being linked into the kernel where it belonged (or put in a shared library), was linked with every single application program.

                                            As a result, Unix never developed a rational plan or model for programs to interact with a VDT.

                                            If the Unix aficionados are right, and there really are many users for each Unix box (versus one user per DOS box), then well over two-thirds of the people using Unix are stuck doing so on poorly supported VDTs. The most interactive tool they’re using is probably vi.

                                            I’ve thought the ’‘editor war’’ has long been solved, because most people don’t use vi, they use vim, and vim may as well be a far worse Emacs. Emacs also has a first-class notion of an interface that isn’t a terminal, with my understanding that Vim’s is a hack in comparison. In any case, the relatively uncustomizable and ’‘traditional’’ vi has largely been left. I’m not claiming Emacs is by any means perfect or even ideal, merely clearly better; does Vim even have an online help system as Emacs does?

                                            Wouldn’t you agree that lauding a program originally written in 1976, a text editor at that, shows a severe lack of progress?

                                            1. 6

                                              Emacs also has a first-class notion of an interface that isn’t a terminal, with my understanding that Vim’s is a hack in comparison

                                              Indeed. Neovim forked Vim and rewrote the UI subsystem, decoupling the layout from the terminal display. This means that Neovim’s terminal UI is merely a client to the Neovim UI server, just like all other Neovim UIs.

                                              Emacs has nothing like this. This architecture later inspired xi editor.

                                              does Vim even have an online help system as Emacs does?

                                              Vim has :help, although Emacs’ help is more “alive” (I seem to recall it having orgmode-like code execution).

                                              Wouldn’t you agree that lauding a program originally written in 1976, a text editor at that, shows a severe lack of progress?

                                              If progress were made, would you notice it? Vim has online help, but you didn’t notice that…

                                              1. 2

                                                Emacs has nothing like this.

                                                Emacs does have a client-server system. You start the server and spawn clients whenever you want to use it. You can even remotely connect to a headless Emacs server through TCP (although it’s a hack, you’re better off just sshing).

                                                It’s just that there’s no alternative client written to communicate with the server. Decoupling the interface from the underlying software is a good idea though.

                                                1. 3

                                                  Emacs does have a client-server system

                                                  Obviously. But it does not have a UI protocol, it is not possible to write an alternative Emacs UI via RPC.

                                                  1. 1

                                                    It’s not possible at all. It’s just never done so far because it’s not meant to be used outside Emacs itself and the protocol is undocumented. After all, it’s all done through Unix domain sockets (or plain TCP).

                                                    1. 1

                                                      “I could do that, I just don’t want to” is the standard response that I found in my 12 months in the Emacs community. What specifically are you referring to? I hope something other than emacsclient.

                                                      After all, it’s all done through Unix domain sockets (or plain TCP).

                                                      emacsclient -t receives literal terminal sequences sent from the emacs --daemon. This is not a decoupled UI, it is quite literally the opposite.

                                                      Here’s a sample from strace showing the emacs server sending a blob of terminal sequences, representing the statusline and minibuffer:

                                                      write(7, "\33[10;1H\33[30m\33[47m-UUU:@----F2  \33[39;49m\33[1m\33[30m\33[47m*scratch*   \33[0m\33[39;49m\33[30m\33[47m   All (5,0)      (
                                                      

                                                      That fd 7 refers to -tty /dev/pts/9 which was sent by the client to the server, so the server itself is writing to the tty, that doesn’t even go over the socket.

                                                      1. 1

                                                        “I could do that, I just don’t want to” is the standard response that I found in my 12 months in the Emacs community.

                                                        Okay, you’re right about that one. I don’t like it one bit myself either. It’s harder to write an actual program to work outside Emacs itself than just writing Emacs Lisp scripts.

                                                        emacsclient -t receives literal terminal sequences sent from the emacs --daemon. This is not a decoupled UI, it is quite literally the opposite.

                                                        Yes, the server keeps the text data you’re working on. The client is literally just a detached UI, meaning you can work with separate clients working on different buffers held in the same Emacs server. (Or on the same buffer. The clients update simultaneously when the buffer is edited.) I don’t see how this disqualifies it from being a UI.

                                                        1. 1

                                                          Yes, the server keeps the text data you’re working on.

                                                          I didn’t say anything about text. Terminal sequences are much more than “text data”.

                                                          The client is literally just a detached UI,

                                                          I showed above that emacsclient -t only tells the server which tty to connect-to, and then the server itself writes directly to the tty.

                                                          So emacsclient is not a UI–but this was never the central point (nor did I even make that claim), merely a funny result found on closer inspection.

                                                          I don’t see how this disqualifies it from being a UI.

                                                          “Decoupled” is the operative word, not “UI”. Emacs server renders the UI, rather than sending a logical representation of the UI. Supporting multiple clients was never in question.

                                                          Neovim server does not send terminal sequences to the client, it sends structured data with a well-defined protocol so that UIs can use any rendering engine or even layout. Emacs has nothing like this.

                                                          1. 2

                                                            Neovim server does not send terminal sequences to the client, it sends structured data with a well-defined protocol so that UIs can use any rendering engine or even layout. Emacs has nothing like this.

                                                            I think I see what you mean now. Yes, Emacs has nothing like that. Whilst it’s very modular in terms of functionality, its actual display code is notoriously monolithic and tied up. I don’t think the UI can be separated that deeply without a total rewrite of display code, something everyone wants since ’90s but no one actually does.

                                              2. 4

                                                Wouldn’t you agree that lauding a program originally written in 1976, a text editor at that, shows a severe lack of progress?

                                                …wasn’t Emacs also released in 1976?

                                                1. 3

                                                  Yes, in its original incarnation. The version most people would use today is GNU Emacs, which is from 1985 (the second time rms was involved with creating Emacs).

                                                  But I agree that a program dating from 1976 doesn’t tell us anything about progress. Part of why Emacs is so good is because it’s been around for so long.

                                              1. 6

                                                It’s a bit of a losing battle to fight against client side applications since the Web’s evolving to be more of an application platform instead of a document layer.

                                                It hurts but it’s true. The web is considered to be a “cross-platform application framework” since every platform is assumed to have a compliant-enough web browser. Then again, the web is so complicated now that it’s nigh impossible to write an adequately compliant web engine from scratch. Most platforms just port a C compiler and then WebKit to get a working web browser. At this point, I daresay early web was closer to gopher than it would be to today’s web.

                                                Still, I won’t give up any time soon, even if it means rowing against the current.

                                                1. 2

                                                  I really like the way it handles memory management. RAII, borrow checker with garbage collection? Yes, please!

                                                  Although, I suppose I’m overlooking the most notable part of the project: the fact that it was created for 3D graphics for web, through LLVM’s WebAssembly backend. Quite interesting.

                                                  1. 2

                                                    And let’s not forget that C++ was a hoax as well.

                                                    1. 1

                                                      Forgot about that one! Thanks for the link. :)

                                                    1. 2

                                                      Is “Gopher Hole” the term the gopher community uses for a Gopher server? Or is it a gateway to a Gopher server from the WWW?

                                                      1. 3

                                                        “gopherhole” and “gopherspace” are gopher’s counterparts of web’s “website”.

                                                        1. 1

                                                          Ah, that makes sense, thanks!

                                                      1. 3

                                                        I had a stack-based Lispy language idea myself but looks like I got beaten to the punch. Pretty neat. Looks like it’s suitable for general-purpose scripting.

                                                        1. 7

                                                          Oh hell yes. I’m very tempted to host my own personal Pleroma instance now, just for gopher and BBS. I wonder if it’s possible to disable HTTP.

                                                          1. 4

                                                            Not really unless you don’t want federation. That still has to happen over HTTPS.

                                                            1. 2

                                                              Fair point. I was only thinking of the web interface.

                                                          1. 5

                                                            Whether an IBM hater or UNIX lover, I still recommend you check out the AS/400 or IBM i architecture. It was a very, forward-looking design from very, long ago. I found some slides to make it more accessible to busy or lazy folks. :) It was also resilient to attack in first form as a capability-based, computer system. This book has many examples with AS/400 predecessor being “System/38” if yall want to check those out.

                                                            1. 2

                                                              I always wondered why technologies used in IBM i aren’t more common. For instance, single-level store is a fascinating idea, yet no one has heard of it.

                                                              1. 2

                                                                Total speculation, but maybe patents?

                                                                1. 2

                                                                  It’s possible but I think it’s cultural. Growing up listening to UNIX hackers, most talked down about stuff like AS/400 and VMS without highlighting many good parts. Example missing cross-language support, file versioning, clustering, etc. IBM and Microsoft bashing were expected. Jobs always talked crap about them, too. So, it wouldn’t surprise me if Mac people knew less about alternative designs due to being pushed away from looking at them.

                                                                  1. 1

                                                                    That’s entirely possible, considering it’s IBM we’re talking about. Then again, SLS was first implemented in Multics and (if my memory serves me right) building a “single address-space, persistent memory, single-level store operating system” was one of the goals of the hypothetical LispOS.

                                                              1. 13

                                                                I may as well join in.

                                                                I’ve had a light conversation with SirCmpwn before and he doesn’t care for macros either, which I find foolhardy, but I’ll focus on just this article.

                                                                The inertia of “what I’m used to” comes to a violent stop when they try to use Go. People affected by this frustration interpret it as a problem with Go, that Go is missing some crucial feature - such as generics. But this lack of features is itself a feature, not a bug.

                                                                I use a number of wildly different languages, including Common Lisp, APL, and most recently Ada; each of these languages is lacking things the other has, but it also vastly more suited to other tasks than the rest. I’ve never used Go. Unlike these three languages I’ve mentioned, which have perfectly good reasons for lacking whatever it is they lack, Go very often has poor reasons or perhaps even no reasons, although I don’t skulk around the mailing lists or whatnot.

                                                                For a good example, take a look at this; it’s my understanding Go lacked a proper mechanism for determining time and many people critiqued this, but daddy Google didn’t care until someone important was hit by it. This is a good example of the problems caused by a language that is not only uncustomizable by the users, but is designed by people who don’t care and won’t care. Unless you’re someone, Google doesn’t care about what you think and the language certainly doesn’t, considering it is designed at every point to take away programmer choice.

                                                                Go strikes me as one of the most conservative programming languages available today. It’s small and simple, and every detail is carefully thought out. There are very few dusty corners of Go - in large part because Go has fewer corners in general than most programming languages.

                                                                This isn’t equivalent to a language that is good for writing programs in. Ofttimes, a lack of edge cases in the world of the language doesn’t correspond to a lack of edge cases in real use. Take a look at Ada for a counterexample; the rules may not have a nice technical explanation, but the corresponding real world explanation is very simple, because it’s usually to prevent some manner of error.

                                                                I feel that this applies to generics. In my opinion, generics are an imperfect solution to an unsolved problem in computer science.

                                                                Dynamic typing as in Lisp is one solution. Ada has a nice generic system, but again, Ada was designed not for theoretical prettiness, but to actually make large systems easier to write without flaws, so generics were of course there because otherwise you get people copying and pasting code, which makes maintenance and everything else harder because you can’t tell if one of the copies is wrong or otherwise changed easily or quickly.

                                                                I used to sneer at the Go maintainers alongside everyone else whenever they’d punt on generics. With so many people pining after it, why haven’t they seen sense yet? How can they know better than all of these people?

                                                                Have you ever considered these people don’t know better than anyone else. Have you considered that Go is just an extension of the UNIX and C religion and people like Rob Pike are just playing their part as a priest over scared people who don’t know any better and want a panacea and a movement to join?

                                                                I don’t think programming languages should compete with each other in an attempt to become the perfect solution to every problem. This is impossible, and attempts will just create a messy kitchen sink that solves every problem poorly.

                                                                I’d prefer to think that’s common sense. APL and its family is the clear choice for array problems, but will fall flat against many other types of problems. What is Go actually good for? I find that poor languages, typically ALGOL clones, tend to differentiate themselves on purpose rather than anything intrinsic. You see this with Perl being a ’‘scripting’’ language, Ruby being for ’‘web services’’, Python being ’‘glue code’’, and, what, Go being for ’‘scalable programs with a focus on internet-connected services’’? The key detail to observe is these languages are all rather the same and, utterly lacking originality, attempt to dominate in a particular usage, because that’s the only way they can really be differentiated.

                                                                If you disagree with this, compare Perl to PHP to Go to Python and compare those differences to those between comparing Common Lisp to Forth to APL to Ada.

                                                                If you’re fighting Go’s lack of generics trying to do something Your Way, you might want to step back and consider a solution to the problem which embraces the limitations of Go instead. Often when I do this the new solution is a much better design.

                                                                I felt something similar when I was writing an Ada program and, wanting to use the package system properly, was forced to structure my program in a different, albeit natural and better way. Tell me if there’s a document that lists all of Go’s design decisions and why they were taken, or am I only going to find the typical UNIX and C response of ’‘We know better. It’s better this way. Don’t consider other ways. Our way is the one true way.’’?

                                                                So it’s my hope that Go will hold out until the right solution presents itself, and it hasn’t yet. Rushing into it to appease the unwashed masses is a bad idea.

                                                                Go was designed for the ’‘unwashed masses’’, I mean those ’‘not capable of understanding a brilliant language, but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.’’, straight from Rob Pike’s mouth. Go is designed to use programmers as unintelligent implementing machines, which is why it’s so opinionated. Its opinions have little or nothing to do with good programs and apparently everything to do with preventing the damage any single fool they want to use can cause or, worse, prevent a new hire who isn’t a fool from writing a good program that makes them more valuable than their peers and harder to fire. There’s no macros in Go, only the same thing, everywhere, no matter how poorly suited it is to the problem. If everyone writes Go the same, it’s easy to fire and interchange employees without friction.

                                                                I could keep going on about how Go is just a continuation of UNIX, C, and so also Plan9, UTF-8, and whatever else those malign idiots create, but I believe this gets the point across well enough. The only ’‘philosophy’’ these things espouse is that the computer isn’t a tool for leveraging the mind.

                                                                1. 10

                                                                  ’‘We know better. It’s better this way. Don’t consider other ways. Our way is the one true way.’’

                                                                  Hilariously, a pro-Go commenter just said to me that Go is an anti-“we know better” language.

                                                                  Go is just an extension of the UNIX and C religion

                                                                  And yet it goes against everything in the actual modern Unix world. Go likes static linking (because Linux distros), has custom syscall wrappers, a custom assembler (!), custom calling convention and weird stack setup… As a result, calling non-Go code requires either overhead (cgo) or ridiculous hacks (c2goasm), LD_PRELOAD hooks don’t work, and porting the main official Go implementation to a new OS/CPUarch combo is utter hell.

                                                                  1. 9

                                                                    Go being for ’‘scalable programs with a focus on internet-connected services’’?

                                                                    Two comments: the two wins go has over other languages is

                                                                    • (1) build/link - that its build system is fast, and it produces reasonably small static binaries, suitable for deploying into containers. This requires a fair bit of fiddling in other languages and with fairly large binaries in the outcome. Not infeasible, but certainly more than plug and play.

                                                                    • (2) it aligns with the sensibilities of python and ruby programmers in general, but in a typed manner, so improved maintainability with a fairly simple semantic.

                                                                    I’m not a go fan, but these are key good things for go.

                                                                    Rather write in something like Haskell or Common Lisp, but ce la vie…

                                                                    1. 9

                                                                      I had you until the last paragraph. What the heck do you find bad in UTF-8?

                                                                      1. 1

                                                                        I don’t want that to turn into its own discussion, but I have reasons aplenty and I’ll list all those that currently come to mind.

                                                                        Firstly, I have my own thoughts about machine text. I find the goal of Unicode, being able to have all languages in one character set, to be fundamentally misguided. It’s similar to the general UNIX attitude: ’‘Should we have the ability to support multiple standards and have rich facilities for doing so transparently? No, we should adopt a single, universal standard and solve the problem that way. The universal standard is the one true way and you’re holding back progress if you disagree!’’.

                                                                        Operating systems can support multiple newline conventions, as VMS did, and it would be trivial to have a format for incorporating multiple character sets into a single document without issue, but that’s not what is done. Instead, Unicode is forced and there are multiple Unicode encodings. Unicode is also filled with dead languages, emojis, and graphics-building characters, the latter being there, I think in part, because GUIs under UNIX are so poor and so turning the character set into the GUI toolkit is such an easy ’‘solution’’. I’m fully aware the other reasoning is likely to encompass graphics from other character sets, however.

                                                                        UTF-8 is a large, variable-length character set that can have parsing errors, which I find unacceptable. It’s backwards compatible with ASCII, which I also dislike, but at least ASCII has the advantage of being small. UTF-8 takes pains to avoid containing the zeroeth character, so as to avoid offending C’s delicate sensibilities, since C is similarly designed to not accommodate anything and expect everything to accommodate it instead. It is as if Ken Thompson thought: ’‘I haven’t done enough damage.’’

                                                                        UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.), by being larger than a single-minded encoding, leading several such peoples to prefer their own custom encodings, anyway. You can only add UTF-8 support to a program transparently in trivial cases, as anything more such as a text editor will break in subtle ways.

                                                                        There’s also that Unicode makes the distinction between characters, graphemes, and other such things that turn a simple problem into an unmanageable one. I use Common Lisp implementations that support Unicode characters, but don’t actually support Unicode, because there are so many combining characters and other such things that have no meaning to Common Lisp and so can’t be implemented ’‘correctly’’, as they would violate the semantics of the language.

                                                                        There are other reasons I can list, but this is sufficient.

                                                                        1. 10

                                                                          multiple standards and have rich facilities for doing so transparently

                                                                          Well, looks like getting everyone to agree on a way of selecting encodings turned out to be way harder than getting everyone to agree on one encoding :)

                                                                          And sure — we have Content-Type: what/ever;charset=MyAwesomeEncoding on the web, we can have file formats with specified encodings inside, but there’s nothing you can do about something as fundamental as plain text files. You could never get everyone to agree to use something like extended FS attributes for this, and to make it work when moving a file across filesystems… that’s just not happening.

                                                                          format for incorporating multiple character sets into a single document without issue

                                                                          Again, some format that software has to agree on. Plain, zero-metadata text fields and files are a thing that’s not going away, as much as you’d like it to.

                                                                          UTF-8 disadvantages other languages, such as Japanese and Chinese

                                                                          They often include ASCII pieces like HTML tags, brand names, whatever; you should use an actual compressor if you care about the size so much; and every character in these languages conveys more information than a Latin/Greek/Cyrillic/etc character anyway.

                                                                          1. 7

                                                                            It seems like you don’t actually know what UTF-8 is. UTF-8 is not Unicode. Rob Pike did not design Unicode, or have anything really do to with Unicode. Those guys designed UTF-8, which is an encoding for Unicode, and it’s an encoding that has many wonderful properties.

                                                                            One of those properties is backwards compatibility. It’s compatible with ASCII. You ‘dislike’ this, apparently. Why? It’s one of the most important features of UTF-8! It’s why UTF-8 has been adopted into network protocols and operating systems seamlessly and UTF-16 hasn’t.

                                                                            UTF-8 doesn’t ‘disadvantage’ other languages either. It doesn’t ‘disadvantage’ Japanese or Chinese at all. Most web pages with Japanese and Chinese text are smaller in UTF-8 than UTF-16, despite the actual Japanese and Chinese text taking up 3 bytes instead of 2, because all the other bytes (metadata, tags, etc.) are smaller.

                                                                            The fact is that anyone that says that Unicode ‘makes the distinction between characters, graphemes, and other such things that turn a simple problem into an unmanageable one’ doesn’t know what they’re talking about. Unicode did not create those problems, Unicode simply represents that problem. That problem exists regardless of the encoding. Code units, code points, characters, graphemes.. they’re all inherently different things.

                                                                            Unicode does not have any GUI characters.

                                                                            1. 2

                                                                              Could you maybe elaborate the following quote?

                                                                              UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.)

                                                                              1. 6

                                                                                I reckon it refers to the controversial Han unification, which was in China’s favour.

                                                                              2. 1

                                                                                It’s similar to the general UNIX attitude: ’‘Should we have the ability to support multiple standards and have rich facilities for doing so transparently? No, we should adopt a single, universal standard and solve the problem that way. The universal standard is the one true way and you’re holding back progress if you disagree!’’.

                                                                                What precisely does UNIX force you into? Are you sure this isn’t also the LISP attitude as well? For example, Lispers usually sternly glare over the interwebs if you dare you use anything but EMACS and SLIME.

                                                                                Operating systems can support multiple newline conventions, as VMS did, and it would be trivial to have a format for incorporating multiple character sets into a single document without issue, but that’s not what is done.

                                                                                You’re confusing multiple newlines in a single character encoding with multiple newlines across character encodings. You say that it would be trivial to have multiple character sets in a single document, but you clearly have not tried your hand at the problem, or you would know it to be false.

                                                                                Give me twenty individual sequences of bytes that are all ‘invalid’ in twenty different character encodings, and then give me 200 individual sequences of bytes that are all ‘invalid’ in 200 different character encodings. Otherwise there is ambiguity on how to interpret the text and what encoding is used.

                                                                                This problem can be seen by the people who are trying to revamp the c2 wiki. Reworking it has stalled because there are around 150 files with multiple different character encodings, and they cannot be identified, separated, and unified by the machine.

                                                                                Unicode is also filled with dead languages, […]

                                                                                Right, because Unicode is supposed to be a superset of all encodings. The fact it supports languages that are not used anymore is a feature, not a bug. It is important to people working in linguistics (you know, that field outside of computer science…) that any computer encoding format has a method of displaying the text that they are working with. This is important to language archival efforts.

                                                                                UTF-8 disadvantages other languages, such as Japanese and Chinese (This isn’t even mentioning the Eastern character controversy.

                                                                                This is outright false, but someone else has already mentioned that.

                                                                                I use Common Lisp implementations that support Unicode characters, but don’t actually support Unicode, because there are so many combining characters and other such things that have no meaning to Common Lisp and so can’t be implemented ’‘correctly’’, as they would violate the semantics of the language.

                                                                                Unicode allows language implementations to disallow some sets of characters for ‘security’ reasons: http://www.unicode.org/reports/tr31/

                                                                                This entire rant remined me of Steve Yegge’s post “Lisp is not an acceptable Lisp”:

                                                                                But what’s wrong with Common Lisp? Do I really need to say it? Every single non-standard extension, everything not in the spec, is “wrong” with Common Lisp. This includes any support for threads, filesystem access, processes and IPC, operating system interoperability, a GUI, Unicode, and the long list of other features missing from the latest hyperspec.

                                                                                Effectively, everything that can’t be solved from within Lisp is a target. Lisp is really powerful, sure, but some features can only be effective if they’re handled by the implementation.

                                                                            2. -4

                                                                              I could keep going on about how Go is just a continuation of UNIX, C, and so also Plan9, UTF-8, and whatever else those malign idiots create

                                                                              The difference is that Plan9, UNIX, C, UTF-8 and Go are all absolutely wonderful and have all had far more positive effect on the world than anything you will ever create. That’s not because they got lucky, it’s because they were designed by people that actually understand what makes things successful.

                                                                              1. -5

                                                                                He’s just a butthurt Lisper who’s mad his elegant, beautiful language is ignored by people who actually get stuff done. UNIX-haters and that.

                                                                            1. 3

                                                                              I’ve been using mu4e for years (first with offlineimap then with isync) and it’s quite nifty and convenient. It integrates well into Emacs’s existing mail tools too.

                                                                              1. 3

                                                                                I used Gnus years ago and it was pretty good for dealing with mailing lists, but also kind of clunky in some ways… then I used Emacs built-in Rmail with an mbox file, which was simple and nice, but a bit slow with a large email archive. Now a few weeks ago I finally switched to mu with mu4e and isync and I’m very happy with it.

                                                                                Actually isync isn’t super fast with Gmail; it takes around a second per mailbox to synchronize, but I can live with that…

                                                                                I love the thoughtful design of the default mu4e main screen where you choose between simple query bookmarks like “unread messages”, “today’s messages”, and “last 7 days.” I added a query like file:/pdf$/ to show me all emails with PDF attachments, which is extremely useful for finding receipts and invoices.

                                                                                And just a minute ago I realized I could get HTML messages to display as plain text by customizing the shr group to disable colors and fonts, so now I’m even happier.

                                                                              1. 4

                                                                                I don’t see how Forth derives from LISP.

                                                                                1. 2

                                                                                  It doesn’t, but in spirit it does. It’s as if you write Lisp backwards without the parentheses. There’s also a fairly small core with the rest written in terms of itself. You can also write Forth code that can be run at compile time (in Lisp you do this with macros).

                                                                                  1. 3

                                                                                    I don’t think “in spirit it does” makes any sense. It’s a completely different syntax for a completely different language with a completely different paradigm: you can’t modify the interpreter or compiler, there’s no stack, no return stack, Lisp has lexical scoping, garbage collection, etc etc etc…

                                                                                    1. 5

                                                                                      Arrows only indicate strong influences, direct derivation is unsurprisingly rare amongst languages.

                                                                                      That aside, Lisp, being Moore’s first language, carries clear influences on Forth. (IIRC Moore himself admitted to this in an interview.)

                                                                                      There’s more to Lisp than just S-expressions (which Dylan lacks), garbage collection (which Carp lacks), lexical scoping (which Emacs Lisp lacked until very recently, so did nearly every Lisp until around Scheme), functional paradigm (most Lisp Machine code reads like Algol) etc.

                                                                                      The most obvious similarity is that they both treat code as data and allow for self-manipulating programs. There aren’t many high-level languages that can run on bare metal, after all.

                                                                                      But, in my opinion, the biggest similarity is the approach to development. In both Forth and Lisp, you consider the problem at hand, create a mini development ecosystem and build an ad hoc language specific to the problem within that ecosystem.

                                                                                      1. 1

                                                                                        I’d love to read this interview if you can find it. Thanks

                                                                                        1. 2

                                                                                          I’ll take a look once I get home. I faintly remember reading it on Slashdot some years ago but I might be mistaken. Cheers.

                                                                                          1. 1

                                                                                            I couldn’t find the one I was looking for. Ah well. I can’t edit the comment now.

                                                                                1. 2

                                                                                  I am a bit confused why Joy is supposedly descendent of FP, while Factor descends from FORTH. I haven’t used FP but Joy as a concatenative language feels very similar to Factor (or rather, the other way round) and I suspect there is some inspiration going on in some way.

                                                                                  Also, JavaScript descends directly from first order logic, instead of a bastardized Scheme with bits of syntax stolen from Java?

                                                                                  Still, I spend a lot of time staring at the diagram and it was fun.

                                                                                  1. 2

                                                                                    Supposedly, the concatenative approach was a parallel evolution rather than direct influence. The author talks about the origins of his language here. Forth influence is still notated with dashed lines in the complex version. But I should indeed note that Joy influenced Factor.

                                                                                  1. 6

                                                                                    I think D should probably be a child of C++, not C.

                                                                                    1. 2

                                                                                      Good point. I’ll change it once I get home.

                                                                                    1. 3

                                                                                      I’m loving these Lisp-in-your-pocket projects coming up lately. Here’s another interesting one, although working on a much lower level.

                                                                                      1. 6

                                                                                        I was learning SQL over the summer, and I found the venn diagrams very confusing. Unlike /u/pab, I think the visualization from this article explains it much better.

                                                                                        1. 8

                                                                                          Referencing users on lobste.rs is done with @, not /u/, e.g. @Forty-Bot.

                                                                                          1. 2

                                                                                            hm, well profile pages are still at lobste.rs/u/<username> so I don’t know why they changed it.

                                                                                            1. 6

                                                                                              What do you mean changed it? @ is the de facto standard way to mention usernames. It has always been that way on lobste.rs and everywhere else I can think of, the only place /u/ works is reddit.

                                                                                              1. 2

                                                                                                @ originated on Twitter & has been widely copied but I suppose that Reddit is actually now more widely used than Twitter.

                                                                                                1. 5

                                                                                                  @username format predates Twitter.

                                                                                                  1. 4

                                                                                                    @name was around before Twitter (as plaintext markers in emails), and @name references are common on many social media sites (including Facebook).

                                                                                                    1. 1

                                                                                                      What’s a plaintext marker in email? Never heard of it.

                                                                                                      Some MUAs with html email allowing you to embed simple text or something?

                                                                                                      1. 4

                                                                                                        I mean literally including @Name in the text of an email when sending a message to a group of people and including parts directed at specific people. Not specially parsed by software at all.

                                                                                                      2. 1

                                                                                                        Facebook copied it from Twitter, as I said.

                                                                                                        1. 2

                                                                                                          My point is that @name is in far, far more common usage than /u/name. I should have been clearer.

                                                                                                      3. 3

                                                                                                        I suppose that Reddit is actually now more widely used than Twitter.

                                                                                                        Citation most definitely needed.

                                                                                                        Maybe in raw “engagement numbers” or whatever weird metrics ad people use to track site sizes, but Twitter is more mainstream than Reddit. A lot of Redditisms don’t even make sense to people outside it: the /r/ and /u/ prefixes, the distinction between link and self posts, and the threading (believe it or not, most people find threading super-confusing).

                                                                                                        The gosh-darn POTUS has a Twitter account. I doubt he’s even heard of Reddit.

                                                                                                        And in any case, it’s not whether /u/username or @username is more “popular”, the plain fact of the matter is that this site uses @username, and nothing else. As does Twitter, Discord, MS Teams, and for all I know Slack. Reddit is the outlier in this case.

                                                                                                        And finally, there’s no reddit,com/u/username page, it redirects to reddit.com/user/username.

                                                                                                        (Edit removed over-use of the word “definitely”).

                                                                                                        1. 2

                                                                                                          You are correct on all counts. I was even mistaken about my belief that Reddit is more popular than Twitter; evidently that’s only true in the US: https://www.alexa.com/topsites/countries/US

                                                                                                          1. 1

                                                                                                            I appreciate your response.

                                                                                                          2. 1

                                                                                                            And finally, there’s no reddit,com/u/username page, it redirects to reddit.com/user/username.

                                                                                                            Writing /u/username in on reddit does several things. First, it sends a notification to that user. Second, it is displayed as if it was written [/u/username](https://reddit.com/user/username). There is similar behaviour for referencing subreddits with /r/subreddit. This native support strongly suggests that reddit considers reddit.com/u/username as a valid way to refer to a user’s profile, and to mention them on the website.

                                                                                                          3. 2

                                                                                                            But lobsters is written in ruby like Twitter and Reddit is python.

                                                                                                            1. 1

                                                                                                              I’m pretty sure there’s an implied sarcasm identifier that’s not printed there.

                                                                                                              At least I really hope there is.