Hacker News new | past | comments | ask | show | jobs | submit login
Bubble Tea: fun, functional and stateful way to build terminal apps (github.com/charmbracelet)
308 points by ingve 14 days ago | hide | past | favorite | 113 comments

I've been using dialoguer [1], indicatif [2], and colour [3] for the rust ecosystem. Really high quality libraries:

[1] https://docs.rs/dialoguer/latest/dialoguer/ [2] https://github.com/console-rs/indicatif [3] https://docs.rs/colour/latest/colour/

I enjoyed using https://github.com/fdehau/tui-rs on a few side projects.

Thanks. I keep looking for Bubble Tea alternatives in rust. I am glad to have some handles to a few.

After seeing some recent posts on HN, I've been fantasizing about a Turbo Rust project.

I spent a good chunk of time last week looking for a solid cross-platform GUI toolkit. I came to the conclusion that the terminal is the most portable GUI platform available. You can create an app that has windows, buttons, mouse support, etc, statically compile it for Windows, Linux, and Mac, and run it over SSH. The closest you can get to that with real graphics is using a toolkit built on OpenGL, and you'll be forced to dynamically link to X11 or Wayland on Linux.

The achilles heel of terminal UIs is that they can't display images.

This is so sad. Every time I boot up Plan9 for fun I'm reminded their remoting solution (drawterm) does graphics just fine (since everything is just files, and graphics is done by writing to a software framebuffer device file).

Sure, it's something you can do with SSH via X11 forwarding since forever, but it seems the ecosystem never quite stuck the landing, and now we're here trying to figure out how to make CLI more like GUI for our own sanity.

Maybe we should give it another shot? It seems Windows is trying to do something similar with WSLg to achieve seamless integration of Linux apps within Windows 11 (using RDP under the hood), what is everyone else doing?

I'm actually kind of glad that X11 forwarding didn't stick. TUIs are generally efficiently navigatable using just the keyboard, a property I very much enjoy and frequently miss in "real GUI" apps.

Something else that doesn't seem to get a lot of attention in terminal UI is screen reader accessibility. I'm not a regular screen reader user but I've tried a few TUI programs in GNOME Terminal with Orca and it was a mixed bag. Some simple programs were actually usable, more complex layouts not so much. It seems GNOME Terminal outputs the line where the cursor is when it changes so it also depends on if the program puts the cursor somewhere relevant when it finishes updating the screen.

The cross-platform GUI toolkit I personally prefer is Qt. Bein' I'ma "Python guy" I tend to interact with Qt mainly via PyQt/PySide, but there's handy bindings for a ton of other cross-platform programming languages as well. I've also recently(ish) discovered and been thoroughly impressed by Will McGugan's "Rich" library and the "Textual" TUI library he built for it. Been sprucing up all my terminal output to be more modern using those two lately.

> "The achilles heel of terminal UIs is that they can't display images."

That statement is not entirely 100% accurate these days, thanks to some really creative hacks over the years. I'll list a few links where some fun examples live. ;)

[1] https://github.com/atanunq/viu

[2] https://github.com/stefanhaustein/TerminalImageViewer

[3] https://askubuntu.com/questions/97542/how-do-i-make-my-termi...

[4] https://unix.stackexchange.com/questions/35333/what-is-the-f...

Qt is solid, no doubt. But it's rather high level and bloated. Plus the company appears to be actively be trying to pull away from open source.

I'd look at Qt or Electron if you need to do cross-platform desktop apps, if for no other reason than accessibility. Sure you can make wacky midnight commander like GUIs in the console, but no screen reader is going to be able to make heads or tails of them and you'll shut out users.

Curses is screen reader compatible!

JAWS might have dumped all their TUI accessibility features now that they think blind users should only use the GUI, but BRLTTY is based around the console. Orca does assume Gnome and/or a web browser, but it's no worse than usual with a console. (That is to say - I hate Orca, no matter where I'm using it.)

If you're making your own TUIs, there's a few things that curses sneaks in to make things a nicer experience. It uses the start of heading, start of text, file/group/record/unit separators from the invisible portion at the start of the ASCII table, which your sighted users can't see, but things like BRLTTY announce.

(Note: I don't use BRLTTY with an actual Braille display. I use it with espeak.)

Less modern systems have been running cross platform forever. Eg Free Pascal/lazarus.

TUI/GUI (qt,gtk,cocoa,...) & even has pas2js

Tk is my goto for cross-platform desktop apps; it's unreasonably good for them. However non-desktop support was essentially nonexistent last time I checked.

Lately I'm all in on LÖVE (https://love2d.org). No dynamic linking required, cross-platform, less bloat than mainstream toolkits. Anything it can't do I just accept as a constraint I can't change.

Game engines (at least the lightweight ones) seem good for cross-platform graphical apps in general but the idea of redrawing a static GUI at 30 FPS just sounds too inefficient to me.

You're absolutely right. So I do without 30 FPS.

We're all up this tree where we want all the features we're used to and we're willing to put up with software bloat and insecure software and sprawling supply chains to get it. I'm not. So I start with something minimalist and do what I can within it.

One of my inspirations is http://akkartik.name/illich.pdf

Does this mean that you're rendering at 1fps, 10fps or something?

Is it an artificial limit you put on rendering?

Do you have button animations at 30 FPS?

All I meant is, if drawing too many things overloads the system so it can't render at 30fps, that's fine, I build things that don't look bad if the rate drops. I can't do action games, high-speed video, a few other things. That's fine, I can still do lots of things.

You can lower the frame rate when the window is not focused, or entirely avoid drawing if it's not visible.

Well, that's certainly an interesting approach!

I believe game engines usually draw to a texture then display the texture, reusing it on subsequent frames, but if they don't, that wouldn't surprise me. UIs don't take long to draw, so drawing at 60fps is often quite cheap.

Some terminals have custom protocols for displaying images.

The real achilles heel is they're not accessible. There is no terminal protocol for denoting actual objects being drawn in the window such that they can be exposed to accessibility APIs. Standard CLI tools are usable, but TUIs are not.

I have previously seen someone state that for this reason, every TUI program should have an optional CLI mode.

Also, if every UI is a TUI then the OS task switcher becomes useless, terminal programs don't have access to the full set of key modifiers, mouse support is spotty, etc.

I feel like I've seen TUI's from a completely different angle, including full use of modifier keys , full mouse support, etc.

Its amazing how one persons perspective can completely disagree with anothers.

What did you mean by the "OS task switcher becomes useless" ?

TUIs cannot have full use of modifier keys as the full set of modifiers is not sent to processes running in a terminal.

As for the OS task switcher, if everything is a TUI then you only have one app, which is your terminal, and so your OS task switcher cannot help you switch between apps anymore. You have to switch between windows belonging to the same process. It’s the same problem that you run into by doing everything inside a browser.

> TUIs cannot have full use of modifier keys as the full set of modifiers is not sent to processes running in a terminal.

I have hyper meta super and ctrl work, sent through to my curses app. Are you referring to something like gnome or something else intercepting the keys ?

Command on macOS doesn't work, ctrl+shift doesn't work, ctrl alone doesn't work with most non-letters, etc. Terminals typically let you add explicit key mappings but that's really tedious and you have to map each individual key, and then ensure that the programs you want to use understand the mapped values. And not all terminals allow for freeform key mapping either.

I do see on https://invisible-island.net/xterm/ctlseqs/ctlseqs.html that xterm has a resource modifyOtherKeys that is documented to turn keys like like alt-tab turn into CSI 2 7 ; 3 ; 9 ~, but this doesn't appear to work on Terminal.app, iTerm.app, or Kitty. Similarly there's a documented sequence that's supposed to make xterm set the 8th bit for meta instead of prefixing with ESC, but that also doesn't work on these three terminal emulators. I am not set up right now to try xterm itself (I don't have an X11 server).

Ultimately, the ways keys are sent to terminal processes by default disallow many modifier combinations (and may also have multiple key chords that send the same input). Some terminals may allow for customizing this on a key-by-key basis but most CLI apps won't understand the resulting input, and won't have a way to declare whether or not the terminal should do this. xterm documents a way to do this for most keys, but that isn't supported on the terminals I have access to on macOS.

CSI-u mode solves all of those problems and is supported by iTerm.

It doesn't pass command through, which I don't personally consider a problem since I want the command key to do things to my terminal (like opening new tabs) but ymmv on that one.

Interesting, I hadn't seen CSI-u mode before. It looks like it's a toggle for the whole profile though, rather than something the CLI tool can opt in to, which means it will break any tools that expect existing keys like C-M-e to be ^[^E, and that seems rather unfortunate.

It looks like kitty actually has a means of requesting this stuff dynamically with CSI = flags ; mode u (and a push/pop stack). It also says it will use CSI-u mode automatically for keys that don't have a "legacy" escape, but I didn't see this before because stuff like C-M-3 does not in fact echo as CSI-u but instead that inputs as just 3 instead of CSI 5 1 ; 7 u. Even using Kitty's "progressive enhancement" mode to request disambiguation of escape codes leaves C-M-3 broken which is rather confusing. Versus iTerm where its profile-wide CSI-u mode toggle does report C-M-3 correctly.

In any case, Terminal.app doesn't support this, and I'm not sure what else does. Looking at Alacritty right now, I don't see any direct support for this, the closest I've found is some issue comments suggesting setting up custom key bindings to simulate it (which I guess means defining every single combination of modifiers for every single keyboard key?).

As for Command, yes, it should be for actions _to_ my terminal. But for GUI apps they go to that app, and so replacing GUIs with TUIs means losing the ability to use Command for this sort of thing. For example, in MacVim I can press ⌘N to open a new MacVim window. In vim I can't, because that just opens a new Terminal window. Or ⌘A to select all, which doesn't even have an equivalent CLI key shortcut (e.g. in Vim I'd have to type something like ggv<C-End>, exiting insert mode first if necessary).

And of course proper usability of the terminal typically requires binding Alt to Meta, but doing that means losing the ability to type non-ASCII chars on macOS. This is another thing that GUIs don't have to worry about.

> As for Command, yes, it should be for actions _to_ my terminal. But for GUI apps they go to that app,

I don't see a way to split the difference between ⌘N for a new terminal window and ⌘N for a new application window. It has to do one of those things because it can't to two, and speaking personally, I want it to open the new terminal window. It's a tradeoff.

CSIu mode is new, it's pretty well supported though.

> And of course proper usability of the terminal typically requires binding Alt to Meta, but doing that means losing the ability to type non-ASCII chars on macOS. This is another thing that GUIs don't have to worry about.

This doesn't happen to be true though, right Option can be the compose key and left Option can be Meta/Alt aka prepend-with-Escape. I also use Karabiner to set pressing left Alt to send Escape for even more faithful terminal fidelity, but that's optional. Having both Compose and Alt as right and left Option is perfectly straightforward, and I suggest it, because much like with Command, it does have to do one or the other, but this time, we have two keys.

It's probably possible to split the left and right command keys but again, personally, I don't want the terminal app to see my command keys and am comfortable with the mere six(!) combinations of modifier + key I can send without it.

> I don't see a way to split the difference between ⌘N for a new terminal window and ⌘N for a new application window. It has to do one of those things because it can't to two, and speaking personally, I want it to open the new terminal window. It's a tradeoff.

Right. I'm not saying CLI tools should be able to get command-keys, I'm saying using a TUI instead of a GUI means you cannot use command-keys. It's a notable limitation inherent to TUIs, and it's one I'm talking about since the context here is "the terminal is the most portable GUI platform available".

> Having both Compose and Alt as right and left Option is perfectly straightforward, and I suggest it, because much like with Command, it does have to do one or the other, but this time, we have two keys.

I like that this is an option in some terminal emulators. Unfortunately it's not an option in Terminal.app, and for me personally I'm using right-option for something else system-wide (though I may have chosen differently if Terminal.app offered this).

Did you consider Web Browsers + Javascript?

Requires installing a web browser and having access to the computer’s renderer on some level

So does any other GUI program....

He was looking for a cross-platform GUI toolkit.

I've settled in the last few years on using JUCE for all my apps. It has everything I need, and provides more than ample features for adding new GUI elements. I strongly encourage anyone looking for a cross-platform GUI solution to consider JUCE very carefully - it says "for Audio plugins" on the box, but in fact it is perfectly cromulant way of doing 'normal apps' too ..


Just why? At that point just get a plain old framebuffer and plot individual pixels to it in serial code. How is it better to hack a use-case terminals were not meant to handle? They will have all the other complexities of GUIs still to solve, you just now has a hacky render path to worry about as well.

It's cool stuff but unfortunately I need icons.

That's really impressive, but does it run on Windows, Mac, and Linux including image support? Do you have a link to any examples of more traditional application UI as opposed to demo flavored?

Disagree, there are a ton of differences, especially when it comes to fancier stuff like ncurses provides for example.

QT and Electron are the most capable cross platform tools for building UIs in my opinion. Both have their drawbacks of course, QT is a pain to work with and electron is famous for being not responsive enough for some users

They can display images, though the resolution is not very high, even with sixels.

Almost every language has an ncurses library or module. Isn't ncurses fairly cross-platform?

The cross-platform GUI is WWW.

I've seen the charm suite on HN before, and everytime I see them I wish they had bindings to other languages. I'm just not interested in Go, but I'm really interested in learning to create ssh applications. Its an application runtime with a lot of potential for the dev space, but almost no quick-start frameworks!

Why not? There's a lot to hate about every language, but one advantage about Go is that it's fairly easy to context switch in/out of, which makes it great for side projects, because it's cognitive load while using it is really low.

Unlike say, Rust. I do love Rust though.

I'm only really interested in learning a language if it excites me, or if I'm getting paid to do it. I don't hate Go, and would be fine to learn it on company time for company projects, but there is no spark that would lead me to learn the language on my own. I've written some basic Go, but if I'm using it in personal projects, I'd would have to invest time to understand the ecosystem, runtime, standard lib, best practices, etc.

> but there is no spark that would lead me to learn the language on my own.

you just said you wanted to write SSH apps. is that not enough of a spark?

This is roughly my take. Between Nim and Rust, I have no purpose for Go that isn't covered by a language that's flat-out better.

They’re not better.

People tend to disagree on that. But it depends on what you value. If you like a language that helps you write robust and expressive code, Go doesn't score as high as any language with sum types, and good "generics" support (which 1.18 does not have).

Being boring is one of Golang's strongest suits. There just isn't a whole lot you need to learn compared to most languages.

It's not exciting but it is pleasing. The ecosystem is refining well (e.g., $GOPATH deprecated and workspaces just added).

Now with generics there's even less to complain about.

It's not really very pleasant if you are used to modern type systems. It feels antiquated in a limiting way, for no good reason.

With C at least it's clear to me that it's literally (very literally) a 50 years old language, and I've gotten used to it after decades. It's far from ideal, but at least there's some deep familiarity, and that coupled with the fact that it's everywhere makes me feel more tolerant of it.

But learning a new language which is, in some ways, stuck in the same past as that established 50 years old language is not very pleasing.

> for no good reason

When a language has some property that surprises you, consider whether it might have been designed that way on purpose, not simply because the creators were ignorant/lazy/negligent/drunk/lost a bet/etc.

I did. Rob Pike said that Go was purposefully made similar to C (and by extension other languages similar to C), in order to be familiar and get new engineers who are already familiar with C or C-like languages to become productive without having to learn too much.

And while I can totally understand how that makes sense in the intended setting, I don't consider that pleasing at all. "Pleasing" for me implies that I like a thing because I like the thing itself, not because external constraints impose (perceived) limitations on other choices. Especially in this context, where we were talking about learning and using a programming language by choice, instead of assembling a team of programmers from an already common pool.

I think your critique, if you examine it closely and deeply, is fundamentally an arrogant one. Sorry for the harsh claim, but I truly do believe this.

You are a new developer too. Everyone is. When it’s easy to learn something, it’s easy to relearn it, and it’s easy to learn things around it (because you don’t devote as much brain to the language).

All languages should target new, dumb devs, because all devs (including Rob pike) are new and dumb.

I’ve certainly learned things that were harder and more time consuming to learn, for a payoff that was and continues to be well worth the effort. Including programming languages. I did not claim it was easier for me, so how is that arrogant?

And I absolutely reject the notion that an easy to learn programming language is better. Especially so because Go was made “easier to learn” in large parts by its similarity to C, so it’s really easier for people already and only familiar with C, and that was explicitly stated by the creators.

> creators were ignorant/lazy/negligent/drunk/lost a bet/etc.

This is not a well-intended comment, but then why didn't they add generics at the start? It's not like it was a surprise to anyone even remotely familiar with PLs that they will have to retrofit it sooner or later. Also, function-scoped defers instead of surrounding braces-based one? Come on...

Not adding generics, if you dig through the archives, was a pragmatic choice. Partly it was to help the process of language design, partly it was project management, and partly it was due to technical constraints. Generics is a big, complex feature. The team was prioritizing getting the most immediately valuable features shipped first, and didn’t want the introduction of generics to hit their limited resources too hard or distract from getting the fundamentals right. Generics implementations in existing languages at the time also made trade offs/interactions that weren’t appropriate for go.

That’s not how language design works. You can’t just postpone such an elementary feature with a TODO, it will interact with every other feature of the language, and if you haven’t left a place for the interactions you have to introduce breaking changes, which will shook the whole ecosystem.

There is zero point in postponing a feature so that you can build a community, which you will burn down later. It’s not a startup that has to be ready in X months or it will fail.

They were very clear about why generics weren't there for a long time -- they weren't sure how to do it and keep things simple and build quickly. I'm just a simple code monkey but I think they did a decent job with it.

Obviously we all have our preferences. I think of Go as the love child of C and Python. It's simple, batteries included, and has good tooling and is "good enough" for a lot of tasks (as evidenced by its adoption).

It is simple enough to learn quickly so the investment isn't that demanding. I'd like to learn Rust but the learning curve is much steeper and it seemed to be subject to changes. I'm not shitting on it, just lazy with too many distractions to hunker down and do a real investment of time into it. Someday.

I just can't get past the fact that Go doesn't have sum types. As someone who dabbles in category theory, it makes no sense to me that so many popular languages have product types but not their categorical dual. The lack of sum types leads to so many hacks and weird design patterns in the language, like returning two values when you only want the caller to read one of them (that is actually Go's error handling strategy!). To work around the limitations of not having sum types, Go has a "zero" value for every type so you can for example only set the fields relevant to your particular use case, and just hope that no one reads the fields you didn't set.

The problem is that sometimes the zero value is valid, but not special in any way and doesn't make sense as the default. Go has arbitrarily decided that one particular value is special without your blessing or the ability to override it. This leads to bugs in which the zero value shows up in places where you don't expect it, simply because there is some code which doesn't explicitly set it. That's a very easy mistake to make, which makes writing Go an error prone activity.

I shudder to think that there's probably some Go program that deals with money, and a user's balance might be cleared to zero simply because some operation forgot to explicitly set it in some struct.

In order to implement "optional" fields in Go where you want to distinguish between zero (a valid value) and none (a missing value), the common solution is to either put the integer behind a pointer (which can be null) or use some "sentinel" value like -1 to indicate that the value is missing (as long as that sentinel value isn't actually valid in the domain of discourse). These are terrible hacks, but exactly what you'd expect from programmers who spent the majority of their careers writing C.

This design also leads to another kind of issue: sometimes you don't want people to be able to construct values of a particular type without going through a constructor which ensures the relevant invariants hold. This concept ("smart constructors") is widely used in other programming languages, but it's impossible in Go because Go allows anyone to construct an inhabitant of any type simply by declaring a variable of that type.

A simple example of that kind of issue is pointers: in (safe) Rust, references are guaranteed to be non-null, and you use sum types to implement optionality. This is great because you can always dereference a reference and not worry about handling the null case. In Go, all pointer types have that nasty zero value (null), and there's nothing you can do about it. The billion dollar mistake.

I like the fact that Go encourages simplicity, and for the most part the language is fine. But I'm convinced that having every type be pointed rather than supporting proper sum types is actually more complex in terms of the implications it has on writing and reasoning about code. They have mistaken minimality for simplicity.

> These are terrible hacks, but exactly what you'd expect from programmers who spent the majority of their careers writing C.

As an embedded firmware guy, I'll try not to be offended by that line :) I agree with you, though. C is a really good language when you consider its original purpose and the time period in which it was created. Ignoring 50 years of progress in type theory/category theory in the name of "simplicity" is inexcusable.

> but exactly what you'd expect from programmers who spent the majority of their careers writing C

Writing C is an understatement given that Go and C were created by the same person (with help, of course).

Edge case. Maybe make a library to solve this?

If it causes errors in monetary calculations that can hardly be described as an edge case.

What exactly is hard to switch in/out of Rust, context-wise...?

You get interrupted every time a post is made about Go and you have to comment on Rust's superiority.

We both know that's not what I did, and I'm not taking the bait. Have a good day. ;)

Not directed at you, but here we are in a post about a CLI for Go, discussing Rust. It seems like every discussion of something related to Go requires someone to screech about safety (again, not you) and how Go is a terrible choice.

I use both weekly, for different things. There are numerous people who don't use Go at all that are in Go specific forums. They read Go specific threads here on HN just to make their Rust points. I poke fun at them with my statement. You just gave me the hook.

:) smiley face for you

if you need a fun language to learn to make TUIs, haskell has the brick library :) . I've heard very good things about it, it's declarative, only downside is that it doesn't support windows.

One of my favorite TUI frameworks. I made https://github.com/mathaou/termdbms with it. A very pleasant experience.

Ha, I checked it out and it was definitely worthy of a star -- then I noticed I'd already done so. Now I just need to get around to playing with it.

That looks pretty cool, but as most/all DBMSs come with a TUI utility*, what is the advantage?

*(psql, sqlplus, isql, etc....)

looks pretty and I think its pretty easy to use. Didn't look at what anyone else had done, tho.

One thing that I like about this is the implementation of returning state from the Update function. My only experience with Elm-style architecture is with react / redux which involves meticulously copying pieces of the state object to return two distinct before / after states. Using a Go struct with copy semantics makes this extremely easy and more natural to write in an imperative fashion. One limitation of this is that the model structure can only contain value type (e.g. no pointers, arrays, or maps).

Just curious, I'm not familiar with Go. Will it copy the references anyway, meaning both structures now have a pointer to the same object? That's the way it works in other languages I'm familiar with, so you have to be careful about what you copy and how you use it.

Yes, but it doesn't actually matter. You can use pointers for models, return the same pointer, and it will re-render fine. We do this for our CLI at https://www.inngest.com for creating new serverless functions via a quick walkthrough.

It's actually the `tea.Msg` that causes re-renders. Here's the code: https://github.com/charmbracelet/bubbletea/blob/v0.20.0/tea.....

tea.Msg is, in Redux land, an "action" that triggers some state updates and _always_ triggers a re-render, even if nothing changes.

This is elm-like, but we have to understand the limitations of what we're working with: a terminal with no way of (nicely) updating elements in place. It's essentially an immediate-mode UI, and so it always paints.

Well, it does matter, or rather, it could matter.

For example, say you needed an undo/redo mechanism. If the model were guaranteed to be immutable model, you could simply hang on to the previous models as a sequence of state changes; undoing/redoing is trivial. If the model is mutable, then the undo/redo system has to defensively make a copy before update is called

Do note, however, that paints will only occur if the output changes, and only lines that have changed will be redrawn.

>Will it copy the references anyway, meaning both structures now have a pointer to the same object?

Correct. A value copy is a simple shallow copy. Deep copy requires use of reflection (if you don't want to manually manage copying).

yes, that's what it does in go

>One limitation of this is that the model structure can only contain value type (e.g. no pointers, arrays, or maps)

How does one manage dynamically sized lists of elements, if arrays are disallowed?

You can use arrays, but if you want to maintain the Elm-like model of before and after states, then you need to explicitly copy the array into the new state rather than rely on Go copying just the pointer.

This and the surrounding ecosystem was recently featured on an episode of The Changelog podcast. https://changelog.com/podcast/481

Thanks for sharing the show! Here's a transcript for those who'd rather read:


And a couple audiogram snippets from the conversation:



Hey it’s our Internet friend!

Loved this framework as it helped me build my ssh app idea really quickly (https://github.com/ivantsepp/ssh-slides)! In fact, it pushed me to finally learn golang haha. Would love seeing more and more ssh apps in the wild.

This looks like a really cool project, however I have to say that the Go language seems like a terrible match for the Elm architecture.

I’m not overly familiar with Go and would be curious to hear more details about this.

Some of the features that make Elm and Elm architecture work so well together:

- Light-weight lambda syntax

- Sum types and records

- Global type inference

- Exhaustive match expressions

- Powerful generics

- Immutability by default

- Partial application / currying

- Modules

- Ecosystem of packages built around pure functions

Clippy: It looks like you're trying to make a GUI, would you like help with that?

We recently did a quick POC with py-cui for a TUI app. It worked pretty well but you quickly see the limits.

This looks really interesting and could be a fun way to get into the Go landscape!

I don't like things that pollute our natural language namespace. Couldn't you have named it something unique?

An overwhelming number of programming-related things "pollute our natural language namespace". Off the top of my head:

Ruby, Python, Java, Rails, React, Go, Rust, Elm, Dart, C, C#, Node, Next, Nest, Kafka, LaTeX, bash, fish, cat, Android, Apple, Windows…

I'd be happy to search for this with "bubble tea framework" or "bubble tea tui" or similar and it doesn't bother me.

I'm having trouble thinking of a single example of a language, library, or piece of technology that is not either an acronym, a name of something that exists, or a combination of such names. Be it an object (Flask), a concept (Scheme), a letter (C), a person (Sinatra), or an animal (Python).

Maybe we need explicit namespacing in English? I'll start saying stuff like "programming languages colon colon ruby" so people can be absolutely sure what I'm talking about.

Alas, people might get the wrong idea about what kind of colon you mean.


Named after Danish mathematician Agner Krarup Erlang[0] who invented queuing theory & telephone network analysis, but they told management that it stood for "Ericsson language" (at least that's what I remember from a Joe Armstrong presentation, but I can't find it right now.)

[0] https://en.wikipedia.org/wiki/Agner_Krarup_Erlang

I’m almost embarrassed to admit this, but I was today days old when I realized that “clang” and “erlang” were really C-lang and Er-lang, much like Go-lang.

All Terrible.


It’s a type of tree.

Yes, an elm is a kind of tree.

I bet you HATE the Go language name.

I myself just don't understand why any reasonable person would pick an existing common word for a project in 2022 instead of using the plethora of name generators that can give you something original without even trying.

But like, people that work for Google surely know something about search term collision. Or just don't care about making anything else that has "Go" in the query gets confusing results. Which is an odd stance for Google employees, but none of my business I guess.

Of course it's common anyway, I just don't see why you'd do this to yourself. You either bury your own project, or you are so successful with branding that no one can find what used to have that name. Google can push something hard enough with perfect SEO to make sure that Go the language shows up. A github page?

I mean, it's not Google but: https://duckduckgo.com/?t=ffab&q=go&ia=web First hit -- https://go.dev

https://duckduckgo.com/?t=ffab&q=bubble+tea&ia=places This project is not anywhere near the front page and I can't imagine it ever being. Too many different companies are selling boba tea.

I never really like it when companies use existing common words, but unless you're a huge project or a company that can push the SEO and marketing it's actively burying your work from anyone finding it.

The number one reason is that I can spell Bubble Tea. Something like "imgur" leaves open a lot of possibilities.

People are also pretty good at disambiguating things. Fewer than 7% of people ordering from Amazon have ended up in Brazil on accident.

Eh, if I search "bubble tea go" on Google this library is the first hit. Same for "bubble tea interface", "bubble tea library", and "bubble tea tui". That's good enough for me. It's not the name I would've picked, necessarily, but it's better than a name that's hard to spell, type, or remember.

I call it "Golang". I also _hate_ the use of 1 letter variables in Golang. Give me three and make it easy to search for symbol names in my no-frills editor.


Golang for written communication when you want it to be searchable but day to day usage Go works just fine.

The single letter variable approach is sensible and not dogmatic -- e.g., `i` in a tight for loop makes sense.

I do.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact