Threads for mw

    1. 3

      There is also something incredibly satisfying about powering it through foot pedal switch that also has a string of Christmas lights on it. Would highly recommend.

      1. 6

        There’s a fundamental difference between an error with call stack (information leading up to the error) and an error with wrapped context (information coming temporally after an error). The article advocates that you “add call stacks when you need more info!” but this just isn’t an option for vendor-ed libraries.

        You can only add call stack information (leading up to) a wrapping point, often well after you have lost context of the original error. Sure you can add one, but it often isn’t the call stack you want.

        1. 6

          My first derailleur bike just had levers on the downtube, none of these namby pamby clickers with numbers and presets kids these days apparently need!

          1. 3

            My summer bike was made in 1988, its downtube levers has optional indexing so i can turn the clicking on and off! I found that particularly useful once when I had… well, I don’t remember exactly now, i think that was the day i crashed going up a hill but it was a lot of years ago. Anyway some problem hit me on the road and i had to do some on-the-road adjustments to keep going. Had to just pull on the left cable a bit to get on the front ring then go between clicks to keep the back one aliigned.

            Of course, there’s lots of ways to do it, but manual control is nice to have when you gotta improvise.

            1. 1

              Nice. My current bike is a downtube shifter.

              1. 1

                I call those “suicide shifters”

              2. 7

                Thank you for sharing this! As an engineer I find myself in constant tug and pull with product folks. There’s almost always a misunderstanding, as if one party argues for the user and the other for the machine; but it’s quite the opposite. I trust the user has the ability to learn an intuition well enough for that context’s “more or less,” but only if we prevent ourselves from incurring inane layers of indirection and coddling. They don’t need to study gears, but the fact that there are gears shouldn’t be hidden.

                Andrea diSessa’s Nightmare Bicycle is a keeper.

                1. 4

                  As an engineer I find myself in constant tug and pull with product folks. There’s almost always a misunderstanding, as if one party argues for the user and the other for the machine; but it’s quite the opposite. I trust the user has the ability to learn an intuition well enough for that context’s “more or less,” but only if we prevent ourselves from incurring inane layers of indirection and coddling.

                  This feels like it’s implicit in your positions. You, the engineer, learned how to use the machine so you trust others can too. Often product people are not the most technical people in the room so they have empathy for people who may not understand how things work under the covers. Therefore, they advocate for a simpler interface.

                2. 9

                  Aside from the articles statement that “maybe people who can’t teach shouldn’t do things”; which is easily rebuffed as teaching is an entirely separate skill from doing, great teachers can be terrible do-ers and vice-versa.

                  Juniors are a problem for the mercenary culture that companies have created by attempting to suppress wages of long term staff.

                  Namely, a Junior is an investment, you can get a 10/10 senior who knows your company inside and out. A new vanguard, a repository to store tacit, institutional knowledge; but no sufficiently trained junior who is “good enough” to be validated externally is going to stick around for an abysmal salary.

                  Even if a junior wanted to stick around for his/her mentors; those mentors likely move around often too- and the ones that don’t.. largely can’t due to being poor interviewees.

                  It’s exceedingly rare these days for people to be loyal to companies for more than 3-4 years.

                  So why would I as a company: invest 6-12 months of a seniors time when I have so little of it, for the benefit of someone else’s career? They’re just going to leave once trained after all; it’s pretty rare for companies to have a genuinely altruistic mindset- and it’s not cheap labour you’re getting back either.

                  1. 8

                    The article’s main argument doesn’t seem to rely on company loyalty. The idea is that the company’s overall effectiveness is improved by the cultural focus on coaching, which challenges assumptions and creates psychological safety.

                    This resonates with my own experience. My first software engineering jobs were for companies that had company-wide intern programs, but the teams I ended up on weren’t super invested in teaching/coaching. They were full of seniors who were convinced they knew everything. They were often unable to explain concepts to me and resistant to new ideas (that in hindsight were good ideas). Their ability to “do” was impacted by their inability to “teach”.

                    1. 3

                      This, exactly. It makes me think of the Feynman quote of knowing you must not understanding a topic if you can’t reduce it to a 100 level course. It can be a bit of an ego check, but I had to level with a team once that if a Junior does poorly on this team, it would be more a reflection of this team than of the junior.

                      The other thing that’s lost here, is how insanely huge the software world is. I can have 15 years experience in a domain, and shift to a team where the tools are Just Different. Everything you put in place to support a Junior is also of huge benefit to someone coming from another language/domain/company. You see this a lot when people shift to and from startups and enterprise. Similarly for the shift from embedded technologies and web. Or product vs infra and ops.

                      It’s not just new folks who benefit.

                    2. 1

                      Wow. Capitalism incentives run contrary to bettering other people. Who would have guessed that an ideology rooted in selfish individualism would do that? /s

                      Wait, no, this just in: companies can choose not to engage in exploitative capitalism and actually make life bearable for their employees.

                      Wait, no, I have just been informed that pension funds insist on maximum exploitation. Well, nothing to be done, people in the US are officially masochists.

                    3. 70

                      People writing articles reminiscing about when junior devs just copy-and-pasted code from Stack Overflow is making me feel old.

                      1. 33

                        Same here…kids those days complaining about kids these days. :)

                        I was telling someone recently about what “browsing the literature” was like when I was working on compilers at Apple in 1990: going to the internal library down the road to read some ACM proceedings, copying references from the bibliography in the paper, asking the librarian to call Stanford to ask them to photocopy the papers Apple didn’t have, and waiting for the copies to show up in the interoffice mail. That was just 35 years ago! And getting answers to your questions on demand…if you were lucky enough to know somebody who might know the answer, you used the phone. (The lucky few in the know could try Usenet.)

                        1. 19

                          I think the op is literally 23

                          1. 12

                            Same – I remember when Stack Overflow was brand new[0], and it was introduced as some mixture of (1) a better expertsexchange and (2) a pseudo-wiki to gather and summarize knowledge that was otherwise spread across personal blogs and academic homepages.

                            At some point it transformed from a Q&A site aimed at skilled professionals into a code snippets repository for people new to the industry. Nowadays whenever I’m doing something that leads me to an SO question, usually the question is exactly what I want answered but it’s locked as a duplicate of some completely unrelated topic.

                            [0] Fun(?) story: I created the first Wikipedia article about Stack Overflow, but it got speedy-deleted by a Wikipedia administrator after about ten minutes. A lot of the early SO content was written by people who wanted to contribute computer science information to the public square, but didn’t want to deal with Wikipedia’s opaque deletionist bureaucracy.


                            Also, if you really want to feel old, write some C++ with a whole class of new hires who pronounce #include as “hashtag include”…

                            1. 1

                              who pronounce #include as “hashtag include”…

                              Out of curiosity, how do you pronounce it? :)

                              I took a couple classes in the pre-hashtag era, but I don’t recall if/how it was referred to verbally.

                              I suspect I’d never heard it called anything but a number/pound sign when I took those classes. I’m pretty sure I didn’t know octothorp(e) until years later, and I doubt I would have thought to call it a “hash” until encountering shebangs or hashtags years later.

                              1. 1

                                When I was in school the # character was universally pronounced “pound”, to the point that both students and professors would (jokingly) refer to C# as “C Pound”.

                                Oddly it wasn’t pronounced at all when naming C processor directives: #include was simply “include”. And the justification for that is “the leading pound is silent, like the leading ‘p’ in pterodactyl”. To this day I am not sure whether that professor was serious.

                          2. 20

                            The poetry translations this links to are incredible. I’ve only read the first one and I will certainly read them all. But I’m not sure I have space in my head or heart to read more in one day.

                            1. 13

                              Thank you! I put a lot of work into it, but unfortunately got burnt out/burdened with other things to continue. Maybe one day.

                              1. 2

                                Thank you! The effort shows. They are just beautiful. I have shared them with so many friends and family already.

                                1. 2

                                  They’re marvelous, and the amount of translation you already did is a lot of work.

                                  1. 1

                                    Agreed, very incredible. Thank you for your efforts.

                                  1. 1

                                    aww i really thought i was the 2579th visitor :( it convinced me when i refreshed and it said 2699th (lobsters traffic spike?)

                                  2. 1

                                    I thought it was called Undecimber..

                                    1. 2

                                      Big fan of inoreader

                                      1. 2

                                        Also using it. I am kind of surprised by how well it works across many platforms and OSs.

                                        1. 2

                                          I also use inoreader (paid version). I use it for RSS, email-newsletters, Canned Google, etc. searches, page-watch notification, and so on. It’s been quite solid for me.

                                        2. 1

                                          I tried out Kamal for a deployment job I had but it wasn’t really well suited for Rust and the configuration was extremely shaky/undocumented/obscure. It definitely was not a 2 minute job.

                                          Also I could not for the life of me figure out how to best install a Ruby devtool on my machine and felt it was just a rather anachronistic concept.

                                          1. 4

                                            how to best install a Ruby devtool on my machine

                                            asdf or mise abstract quite a bit of it for you. For Ruby and almost anything else.

                                            1. 1

                                              I stopped using those now preferring just to stick with nvm/uv/rustup.

                                              1. 3

                                                fnm is the better nvm.

                                                It never ends!

                                                1. 1

                                                  And fnm pollutes your filesystem with thousands of symlinks over time. So I switched to mise… uv can detect mise-installed python fwiw.

                                                2. 1

                                                  In that case you’re probably going to get along better with ruby-install+chruby than other install options.

                                              2. 3

                                                I use asdf for all languages on my dev machine. I think it’s been about 5 years straight I’ve been using asdf and to me it’s great. I rarely think about it. To me, it’s solved. You get a single CLI interface instead of having node version manager and ruby version manager.

                                                You can set shell defaults or activate them temporarily just like the single language managers (nvm etc). You can bind projects with .tool_versions so it switches on cd. You get project isolation on the runtime with asdf and dependency isolation with a package manager. My projects don’t get weird and my dev machine doesn’t get weird. I can list all runtimes for all languages, for when security news happens or if I wonder “do I have Python 8.0 installed?”

                                                So, when I wrote an asdf upgrader shell function to replace a language (hey, replace nodejs 42 with nodejs 43) it works for all languages because asdf is a language manager not a node language manager.

                                                1. 1

                                                  Although Haskell is a compiled language and the default build step results in a single binary for a Yesod site, it is not a deployable single binary, because it may still depend on libraries and resources on the machine it was built.

                                                  I’m genuinely curious—and I mean overall, and not just in Haskell, where you need IO to read files from disk—what’s the big advantage in having a single binary rather than a folder with a binary and data files?

                                                  I’m not talking about static linking here, just about where static resources are stored.

                                                  Distributing the typeface separately along with the binary would complicate deployment, because then we need to care for search paths and file system privileges.

                                                  It doesn’t seem very complicated to set the correct WorkingDirectory for your systemd unit. As for filesystem privileges… I guess if your service can write to the disk, there’s always the possibility of a path traversal vulnerability, which would allow an attacker to overwrite the service’s own static files. Having them read-only could help as a mitigation. (But that would not prevent the attacker from overriding any files the server needs writable, such as SQLite databases.)

                                                  1. 8

                                                    what’s the big advantage in having a single binary rather than a folder with a binary and data files?

                                                    I don’t know of a big advantage, but just one less thing that can go out of sync with expectations.

                                                    1. 6

                                                      In my experience the contrast between developing with golang vs ruby is wild, they are two ends of a spectrum. On one end you have a runtime, dynamic system libraries, dependencies with linked dependencies, your actual project’s source files, and potentially a ton of non-ruby source files (data, config, assets, etc). On the other end, you have.. a binary and maybe a few config/data files? And with embed you can just have a single binary?

                                                      The difference between deployment and distribution (as a server bin or user facing cli) is where this difference shows up for me. I simply cannot distribute scripts to people or servers as readily as I can a single binary.

                                                      From what I can tell, this is the ideal the author is working toward. The difference between a single binary and a binary plus a few assets isn’t much, but far down on the opposite end of that spectrum quite is unwieldy.

                                                      Even if there is heavy runtime io, it is solving the distribution problem for me.

                                                      1. 1

                                                        what’s the big advantage in having a single binary rather than a folder with a binary and data files?

                                                        Apparently more and more people are not used to file systems, folders, and specifically file system hierarchies, plausibly because the computers people interact with the most, their phones, hide this structure.

                                                        1. 3

                                                          I can assure you familiarity is not the problem in this case. It’s a function of caring a lot about the availability of my side projects combined with having a full time job, small children, and many competing spare time interests that prevent dropping all prior obligations when something goes wrong.

                                                          1. 3

                                                            You know… for my personal projects the pendulum has swung back and forth between “self host everything on a VM” to “put it in docker containers and host it in K8s” a few times.

                                                            Your comment makes me smile. Producing single-binary builds and pushing them to VMs is probably the happy medium between those two things. K8s has generally worked ok but sometimes things would break in the complexity (eg the nginx-based LetsEncrypt auto-certificate stuff, resulting in a painful debug experience because I hadn’t touched it in a year). The self-host thing would sometimes break because e.g. a system Python package would change or an OS upgrade would be required to get a library version for a new project.

                                                            Thanks for the idea!

                                                            1. 4

                                                              Containers get easier too when everything is built into a single file.

                                                              If it can be a static asset, there should at least be an option to stick it in the binary for easier management.

                                                              Unbidden advice: always make it easy to host your http application at an arbitrary route, not relying on being the top level. That makes life easier too.

                                                              1. 2

                                                                Unbidden advice: always make it easy to host your http application at an arbitrary route, not relying on being the top level. That makes life easier too.

                                                                Sigh. Yes. 100% yes.

                                                        2. 1

                                                          distribution and especially onboarding. It may be only copying one single file. It is with https://seppo.social/en/support/#installation, a single-binary Ocaml web application.

                                                        3. 8

                                                          I love first impressions that include “where the hell are loops? Oh, 10.times do { |i| ... }, sure, why not.” Personally, I find it hilarious.

                                                          That said, there’s a second impression that I wish more people got, where Enumerable/Iterator clicks. Because “everything is an object” you can dot chain laziness into the middle of something like the above.

                                                          An example in Ruby would be

                                                          (1..Float::INFINITY).lazy.map {|i| i**2 }.first(3)
                                                          #=> [1, 4, 9]
                                                          

                                                          An example in Crystal would be

                                                          (1..10_000_000).each.select(&.even?).map { |x| x * 3 }.first(3).to_a
                                                          # => [6, 12, 18]
                                                          

                                                          Kind of neat.

                                                          1. 9

                                                            The author probably didn’t talk about this because we do this in Rust as well, so they’re already used to that being a thing.

                                                            1. 6

                                                              This looks a noisy parody of Haskell.

                                                              • In Haskell you write [1..] instead of (1..Float::INFINITY).lazy or (1..10_000_000).each.
                                                              • You write filter even instead of select(&.even?).
                                                              • A short lambda expression like {|x| x * 3} in Crystal can be abbreviated as an operator section in Haskell: (* 3).
                                                              • You write take 3 instead of `filter(3).
                                                              • No need to write .to_a.

                                                              Unfortunately, the “pipe right” operator isn’t in the Haskell core, you need to load a package. More modern functional languages have it built in (F#, Ocaml, Elixir, etc). The usual ASCII encoding of “pipe right” is |> but I prefer .

                                                              So the nice functional way of writing that Crystal expression is

                                                              [1..] ⊳ filter even ⊳ map (* 3) ⊳ take 3
                                                              
                                                              1. 11

                                                                Unfortunately, the “pipe right” operator isn’t in the Haskell core

                                                                It’s in Data.Function as (&): https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-Function.html#v:-38-

                                                                1. 10

                                                                  Give them time. (To see the wisdom in functional languages.)

                                                                  That said, anything list-based, per your example, is where Haskell’s simplicity shines. Not so much necessarily outside that use-case. See: module management, records, error handling, foldl and unexpectedly explosive memory consumption, Data.Text.IO (and dealing with character encoding in general), the lack of thoughtful namespacing, the need to abstract everything into graduate level mathematics as much as possible regardless of necessity (functors, monads, monoids, applicatives, etc.), updating fields in immutable structs (compare Elixir’s %{person | age: 30} with using the lens library in Haskell, etc.)

                                                                  I’ve been looking at roc-lang and idris lately, which are both inspired by haskell (roc more by way of Elm first), but (hopefully) without the warts.

                                                                  1. 6
                                                                    • There are endless and beginnless ranges in Ruby and Crystal, i.e. (..10) and (1..) works.

                                                                    • In Ruby #filter is the same as #select.

                                                                    • The Crystal example could be written as

                                                                      (1..).each.select(&.even?).map(&.*(3)).first(3).to_a
                                                                      
                                                                    1. 4

                                                                      This looks a noisy parody of Haskell.

                                                                      You mean just like everything else?

                                                                      1. 3

                                                                        If you’re going Unicode, why not go Unicode all the way?

                                                                        [1‥] ⊳ filter even ⊳ map (· 3) ⊳ take 3 
                                                                        
                                                                        1. 1

                                                                          Yes, let’s use proper typography to make code look better on the screen when viewing and editing it. Including proportional fonts. (Note, I prefer × to · for multiplication.)

                                                                          [1‥] ⊳ filter even ⊳ map (× 3) ⊳ take 3

                                                                          Unfortunately, there aren’t many FOSS code editors that support proportional fonts. Emacs has a steep learning curve and intimidating reputation, so I’m experimenting with Kate right now (it has a vi mode).

                                                                        2. 2

                                                                          Very nice!

                                                                          While I’d encountered virtual sequences in Factor (like ranges and <evens>), I hadn’t yet touched lazy lists (or lists at all, apparently). So I used this example to give it a try:

                                                                          1 lfrom [ even? ] lfilter [ 3 * ] lmap-lazy 3 swap ltake list>array
                                                                          
                                                                        3. 4

                                                                          The lack of loops (well, ruby actually has loops but you will be cencured if you use them) solves so many problems and I love it so much

                                                                        4. 5

                                                                          It’s pretty easy to dunk on shitty obscuring code. But I think the resulting conclusion of “therefore, do not use fundamental core language features” missed an opportunity to develop judgment around when to use a core language feature. (The speaker does suggest a collection of heap functions which could ideally be a class, so it wasn’t fully anti-class.)

                                                                          The video’s Conway’s Game of Life example was also a strange choice for an example of “just use a function.” Conway’s GOL can grow to use huge data fast. A class would allow for safe optimizations around mutable data instead of a) duplicating data per iteration, or b) mutating user provided arguments

                                                                          There’s a good chapter in Polished Ruby (Evans) that brings more nuance. The whole book is about nuanced ordering of values and priorities. The main points from the section in mind are:

                                                                          • there is conceptual overhead from any class, this is also true for standard library and core classes, it’s just safer to assume user familiarity with those
                                                                          • one major benefit is state encapsulation, there are things that are safe or not safe to do to the state and the class is responsible for that
                                                                          • the other major benefit is reducing an interface, it provides an example of wrapping array with a class called Stack and only aliasing two methods (push, pop)
                                                                          • then it goes through a few scenarios where those trade offs weigh either in favor or against a custom class
                                                                          1. 26

                                                                            Signal constantly unlinking and intentionally losing logs is an annoyance, especially if you’re surrounded by multiple devices like I am.

                                                                            1. 5

                                                                              For me it’s the “max devices” is laughably low (5 devices per phone). We use Signal at work, and for work I have a laptop with Win/Linux/Linux (for Signal that’s 3 devices), plus a macbook (4th) device. That means I get one personal device. What I’ve had to do instead is keep the macbook open just for Signal while using either Windows or the less frequent Linux on that tri-boot laptop. Which in the grand scheme of things is ridiculous to me because the limit is so low.

                                                                              Edit: Context is I can’t have my cell phone with me at work which is the reason for this nonsense.

                                                                              1. 4

                                                                                I alsi question the choice to have some sim-card-accepting tablets force themselves to act as the “single” phone, and cannot auth as follower applications.

                                                                            2. 4

                                                                              I would like to take a minute to appreciate all the high quality comments from 2008.

                                                                              1. 2

                                                                                One of them says:

                                                                                why does it take 3 seconds to interpret a postscript

                                                                                With a reply of:

                                                                                “Another story from printer-land of 20 years ago” Things were not as fast then.

                                                                                The article was published about when I replaced my first laser, but it could easily take more than three seconds to print a PostScript file. If I sent it PostScript from LaTeX it would print at around two pages per minute. If I ran CUPS on a spare machine and fed it with PCL, it would do ten. It had a fairly slow (50 MHz? 100 MHz?) MIPS processor that did the rasterisation.

                                                                                I also had a PostScript file that was only a dozen or so bytes that drew fractal trees to any depth (controlled by the first line). If I sent it to the printer with a depth above 3, it would just sit there until I got bored and rebooted it (solution to the halting problem: execution time for arbitrary programs is bounded by the patience of the user).

                                                                                1. 2

                                                                                  I had some fun drawing Mandelbrot sets in black and white at 300dpi in 1992/3 ish. The results were pretty but it was a challenge to produce them in reasonable time.

                                                                                  What worked OK was to trace the boundaries of the level sets, since that only required computing a few thousand points instead of a few million, which was doable in PostScript on a LaserWriter II.

                                                                                  I managed to produce a full-page exterior binary decomposition by calculating it on my Archimedes and shipping the bitmap to the printer. I used BBC BASIC V since it had the fastest floating point routines and I lacked an FPU. Took hours to generate the postscript!

                                                                              2. 1

                                                                                Where do refinements land in modern, responsible Ruby usage?

                                                                                1. 1

                                                                                  Technically? Absolutely fantastic. Architecturally, I find them very hard to make use in context with very complex and non deterministic load orders (i.e. when using Zeitwerk, so, Rails). My trouble is when it isn’t my code that uses the broken dependency but the framework’s.

                                                                                  When I meed to modify behavior like this 90% of the time I will

                                                                                  • fork the gem, fix issue on my fork
                                                                                  • swap to depending on my fork
                                                                                  • submit a patch, and add an issue on my repo which links to the patch PR on upstream

                                                                                  If the issue is marked as #wontfix then I will swap dependencies back to the main gem and fix with a monkeypatch or refinement.

                                                                                  At that point is where I think the author’s “Check Gem Versions” section is lacking a bit. I usually deal with upgrades using a tool like dependabot, so I would also have that specific dependency not be grouped with others for upgrades. This will of course be team/project specific, but I don’t think I would rely on a runtime version check.

                                                                                  1. 1

                                                                                    I don’t think I would rely on a runtime version check.

                                                                                    Runtime version checks come up a lot more for developing libraries than applications. Libraries can always try to pin to certain version ranges, but usually try to be as permissive as possible for reasons.

                                                                                2. 5

                                                                                  I’m a fan of the symlink pattern described in the “trials and errors” section. Works more than well enough for most of my use cases.

                                                                                  1. 5

                                                                                    FWIW, chezmoi’s templating features allow users to choose to symlink select files (or all dotfiles, if desired). It is a much more flexible tool than something like GNU stow.

                                                                                    1. 3

                                                                                      The templating is exactly why I switched after years with rcm and GNU stow. It’s surprisingly powerful for maintaining separate configs over multiple machines, especially with multiple OS choices(Mac, NixOS, OpenBSD, Windows) or sections that need to draw from credentials / sensitive info.

                                                                                      1. 2

                                                                                        Oh, totally! The project is awesome, it owns a problem space that I’m grateful to not have to wade.

                                                                                        I like how the write up mentioned two precursors (symlinks, stow) to its usage, one of which works well enough for me. I should have said as much in the original comment. Rereading I see how it can come across as dismissive; apologies there, I hadn’t intended that.

                                                                                      2. 1

                                                                                        Agree. I symlink anything in my source-controlled ~/setup/HOME into my actual $HOME with a small script. It backs up anything that already exists, etc.

                                                                                      3. 9

                                                                                        Exposing current buffer / window state to external programs

                                                                                        Interesting! For the past couple of years, I became convinced that we are missing a “thin waist” roughly in this area, and started sketching out some design (just a very rough outline at this moment): https://github.com/matklad/abont

                                                                                        EDIT: reading the opening paragraph of https://research.swtch.com/acme.pdf is illuminating. Indeed, what I want is acme without mouse and with syntax highlighting.

                                                                                        1. 9

                                                                                          I’ve never used acme myself, but I’ve admired it from afar.

                                                                                          On Unix, if you’re writing code to deal with an interactive program, you can be notified when the program produces output, but you have no idea when the program is waiting for input. You can say “if nothing has been printed in half a second, it’s probably waiting for input” but that’s about as close as you get.

                                                                                          On Plan9, when the interactive program calls read() on stdin, that goes via the VFS and calls your program’s read() handler. You can respond with data, you can twiddle your thumbs, you can wait for the user to type a response, whatever you like.

                                                                                          Because Plan9 provides this intimate connection between interacting programs, a “terminal” on Plan9 is much closer to a Unix pipe than a Unix pty, being just a log of communications in each direction. As a result, the gap between “a terminal” and “an editor buffer” is much smaller, and a tool like acme becomes a lot more straightforward.

                                                                                          There’s tools that try to reproduce parts of the Plan9 system on Unix, like Plan 9 from User Space, 9term, and wily. Unfortunately, because Plan9 semantics aren’t quite like POSIX semantics, either things don’t work reliably, or you’re cut off from the POSIX world and can only talk to “true” Plan9 tools.

                                                                                          1. 6

                                                                                            acme without mouse and with syntax highlighting

                                                                                            This plus modal key bindings was what my starting point was for ad. The current state of the project is also an exercise in “how far can I get using only the standard library” which is why the only dependency other than libc is bitflags (used in the 9p implementation which has now been moved out to another crate).

                                                                                            I’ve had a look at the design you propose in abont and there are quite a few similarities with what I’m aiming for with ad and what I really like about acme. There is a fantastic screencast from Russ Cox that I link to in the README which does a good job of showing the sorts of things that are possible with acme. My main issue with using acme as a daily driver is the heavy focus on relying on the mouse rather than allowing you to define custom key bindings. That side of ad is all working pretty well, but I suspect there’s a fair amount left to do in terms of how the text buffers themselves are managed. I also really need to port the layout logic from Penrose to work with it at some point soon(!)

                                                                                            1. 2

                                                                                              Hm interesting, yeah I’d call both the Abont proposal and Acme “exterior narrow waists” [1] – a narrow waist between processes – IPC and polyglot – rather than the “interior” Emacs Lisp model

                                                                                              Although I don’t understand the Rust point. Isn’t the whole idea of IPC that you can use any language? Using any language makes it more open too

                                                                                              And I agree that say Warp appears to be building an “app” and not an extensible architecture, which seems to be a big difference between open and closed


                                                                                              I think the headless protocol of Oils is naturally complementary to a UI protocol like this:

                                                                                              https://www.oilshell.org/blog/2023/12/screencasts.html#headless-protocol-oils-web_shell

                                                                                              https://www.oilshell.org/blog/tags.html?tag=headless#headless

                                                                                              The slogan for the headless shell is that the shell UI shouldn’t be a terminal – it should have a terminal (for the subprocesses)

                                                                                              So you could make a shell UI in a new paradigm, but reuse the entire shell language, and all existing terminal tools. I’d say you still need a terminal in any new paradigm, unless you are OK with colors in Cargo / Clang / GCC / grep not working.

                                                                                              (And obviously VSCode has a terminal, I think Emacs and neovim do too. Emacs also has its own shell, eshell, but I think that’s not the right approach.)


                                                                                              I mentioned “addition of waists” as a powerful pattern here

                                                                                              https://www.oilshell.org/blog/2022/03/backlog-arch.html#refinements

                                                                                              I am not sure if the headless protocol is an M x N waist yet … I guess we need another shell to implement it ;) But it is an open and tiny protocol, like 200 lines. The main idea is to pass a terminal file descriptor over a Unix socket.

                                                                                              One issue is Windows, and I have been wondering on Zulip how you actually use the new terminal APIs on Windows. I think you can do it with native Win32, and you don’t need WSL. And I think Windows probably has some kind of FD passing between processes too?


                                                                                              [1] or maybe “exterior M x N waist”, because I got feedback from networking engineers about “narrow waist”. I don’t want to “stomp on” the terminology of an adjacent field

                                                                                              1. 1

                                                                                                or maybe “exterior M x N waist”, because I got feedback from networking engineers about “narrow waist”

                                                                                                How about “precise waist”? “Friendly waist”?

                                                                                                1. 2

                                                                                                  stomp on the terminology

                                                                                                  This doesn’t seem like a misuse to me—isn’t IP exactly the same kind of NxM narrow waist? Instead of web, email, video streaming etc all having to implement Ethernet, Wi-Fi, 3g separately, they all sit on top of IP which handles the differences.

                                                                                              2. 1

                                                                                                I don’t feel like I grok what Abont is all about. Is it essentially that you want to create an extensible programming environment (Emacs like) but want to be able to control is via external processes with an API?

                                                                                                1. 2

                                                                                                  Yup, that’s basically it: emacs presentation model, but with IPC instead of mutable global lisp image. I wouldn’t want abont if emacs was good enough for me. But I think there’s a bunch of smaller things which could be done better now:

                                                                                                  • better language for internal extensibility
                                                                                                  • better ways of scaling package ecosystem with less coordination (IPC is a means to that)
                                                                                                  • asynchronous core
                                                                                                  • focus on the shell parts rather than editor parts
                                                                                                  • no unnecessary weird editing model
                                                                                                2. 1

                                                                                                  This is also the most appealing aspect to me. So many editors have a broken “vim mode” where what I really want is:

                                                                                                  • some features of a bulky directory/project editor
                                                                                                  • a proper implementation of my buffer-editor of choice

                                                                                                  And with all open buffers shared. I don’t want to wrestle fs events or polling or some tcp bridge in the middle.