35 ms·
Go is a particularly good language for CLI's I have found. At least compared to Java/C#/Python. It's reasonably fast, compiles down to a simple to distribute b
by boyter 6y ago
Go is a particularly good language for CLI's I have found. At least compared to Java/C#/Python.
It's reasonably fast, compiles down to a simple to distribute binary, and the language is forgiving enough that you can do exploratory programming in it. Go-routines make it especially easy to deal with network calls in it as well. For anything that needs absolute performance though look elsewhere, but even then Go might be a good choice for prototyping.
I actually started learning Go with CLI applications. I have found that https://github.com/spf13/cobra https://github.com/spf13/cobra tends to be one of the better CLI helpers you can get into but https://github.com/jpillora/opts https://github.com/jpillora/opts is one I have been meaning to try following a presentation I saw on it once.
- throwaway894345 6y agoNot sure why this is downvoted. Java, C#, and Python all tend to have slow CLIs. This is very much in-line with my experience. Even if the VMs do start up quickly, people tend to do a lot of expensive initialization, class loading, etc before the program starts. Go’s runtime is minimal by comparison and there is much less work done at initialization (by convention) than in Python, Java, etc.
- Groxx 6y agoCLIs are sorta my ideal use-case for Go. Goroutines are so error-prone to control since you don't have many options for abstraction, so it's relatively difficult to build long-running highly-stable programs... But CLIs don't usually need that. They can be ctrl-C'd if they go off the rails, and any dangling goroutines just die when the process dies. The simple distribution, fast startup, simple type system, and yolo-concurrency really pay off in pleasantly small and performant tools. And the stdlib is cross platform, quite capable, and very friendly to use. It's almost exactly what you want when you need to go beyond a tiny bash script, to something that might be a up to a couple thousand lines. I do wish the built-in flags lib wasn't so abhorrent though. Pulling in a replacement lib is step 1 for any CLI.
- boyter 6y agoInterestingly my current CLI project https://github.com/boyter/cs/ https://github.com/boyter/cs/ does need to be stable because I am putting a TUI mode into it... and yes dealing with the dangling goroutines in it for the TUI mode itself is especially painful. Generally if you just stick to fan-out-in processing though I find goroutines not too bad.
- VexorLoophole 6y agoAs the typical SysAdmin who likes to automate stuff, I have to agree. I am not experienced enough to talk about language designs. But I can say, that writing some small CLI application and deploying it onto some server is way less work with go. Simply because you can crosscompile the application and generate a standalone binary. Everytime I deploy some Python3.7 Flask Application on RHEL7 I start to scream. You were talking about long running applications and broken goroutines: What is the best alternative? I liked to stumble around in Elixir but I feel bad about deploying some application probably nobody at my office will ever be able to 'fix/update'. Python feels too "sluggish". Since I am no Python Pro I have often the feeling, that I am doing something wrong because the language doesn't show any borders.
- mpfundstein 6y agogo is great for long running programs. in fact a large portion of the modern cloudstack is written in it. think of k8s, docker, nomad, etcd... of course one needs to understand how go routines work in order to use them correctly, but thats probably true for everything, right?
- apta 6y ago> go is great for long running programs golang's gc is non-compacting. I wouldn't be surprised if there are cases where fragmentation becomes too much for a golang service to continue behaving properly. This becomes more likely in long running services.
- Groxx 6y agoAlternative: I'd say Java (or similar), since it has the language abilities and sophisticated static analysis tools are readily available. But startup time is still not interactively-fast, so for CLIs it's sorta a no. For long-running processes tho I mostly like it, and stuff like compacting GCs keeps it running healthier much more easily than Go. Beyond that, dunno - I usually reach for Python since I've written it professionally for a few years and it's pleasantly terse. But it's a fair bit of work to make actually fast and I don't generally think it's worth that effort. Go is much easier there... as long as it's kept simple. I have some strong hope for Rust, but I think it's fair to label it as "still maturing", though it's already very far of ahead many langs in some areas. And I just don't have much experience with it yet, so have no real conclusions ¯\_(ツ)_/¯
- pansa2 6y ago> [Go] is forgiving enough that you can do exploratory programming in it. I agree with most of your post, but I’m not sure I would describe Go as “forgiving”. In fact, it’s well known for being strict. For example, exploratory programming would be significantly easier if the Go compiler could (optionally) ignore unused variables and unreachable code. I’ve also found exploratory programming in Go is hindered by needing to frequently cast between different integer types. Maybe I’m doing something wrong, but my Go code is often littered with casts between different integer sizes and signedness. It’s much easier with Python’s arbitrary-precision integers.
- boyter 6y agoWhat I mean is that while the compiler is strict its fairly easy to throw something together that mostly works. The large standard library really helps there. It's certainly not as easy as in Python though.
- rob74 6y agoOk, let's say that it's more suitable to exploratory programming than other compiled languages? On one hand, yes it's strict about unused variables, but other features (e.g. fast compile times) more than make up for the disadvantages.
- kstenerud 6y agoI maintain a modified compiler (https://github.com/kstenerud/go/blob/master/README.md#the-go-programming-language https://github.com/kstenerud/go/blob/master/README.md#the-go...) that can issue warnings instead for unused things. I use it as my daily driver for go development. main.go: package main import "fmt" func main() { var start int = 1 breakOuter: // for x := start; x < 10; x++ { for x := 3; x < 10; x++ { for y := 0; y < 10; y++ { result := y * 10 + x // fmt.Printf("Result: %d\n", result) // if result == 42 { // fmt.Printf("Breaking") // break breakOuter // } } } } Building: $ go build # example ./main.go:3:8: imported and not used: "fmt" ./main.go:8:5: label breakOuter defined and not used (compilation fails) $ go build -gcflags=-warnunused # example ./main.go:8:5: Warning: label breakOuter defined and not used ./main.go:3:8: Warning: imported and not used: "fmt" ./main.go:6:9: Warning: start declared and not used ./main.go:12:13: Warning: result declared and not used (compilation succeeds)
- Fiahil 6y agoI've found Rust to be more interesting for CLIs than go. Especially when using https://clap.rs https://clap.rs
- surfsvammel 6y agoI agree. I think Rust is also excellent for CLI apps. Also better than the other languages you mention.
- sagichmal 6y agoCobra is actually probably the worst CLI package to choose, because it encourages/forces you into a globals-based architecture. https://pkg.go.dev/github.com/peterbourgon/ff/v3/ffcli https://pkg.go.dev/github.com/peterbourgon/ff/v3/ffcli is one that I've been using recently, which has been a lot nicer.
- hunal 6y agocan you please elaborate what is "globals-based architecture" and its disadvantages?
- jjice 6y agoMaybe I'm just unreasonable, but it always slightly bothered me when a JS or Python CLI utility has that half second of startup before doing anything, even displaying help. I can't be too annoyed, since in reality it's only a fraction of a second and they're spinning up the entire interpreter. Single binary is also another one that really shouldn't matter to me, but still does. Especially for small utilities or web services, it's just really nice to know that I can `scp` to my server and just run it if I wanted to, even though, in reality, I always use a Docker container.
- calebkaiser 6y agoI work on ML infrastructure (https://github.com/cortexlabs/cortex https://github.com/cortexlabs/cortex) and we originally wrote our CLI in Python. Rewriting it in Go has been a major win both in terms of performance and cross-platform support.
- crawdog 6y agoCobra is great, I created a test project long ago if anyone wants some sample code: https://github.com/rickcrawford/commandline https://github.com/rickcrawford/commandline