Live data from Hacker News

Go run

breadchris.com

161–170 of 173 posts

Re: Go run

#161
post #6

I don't think it's simple. Just `go run` would be far more simple. Right now I first have to figure out if its `go run .` or `go run cmd/main.go` or some other thing.

'go run cmd/COMMAND' is what I like best. I normally don’t bother descending further than the root of a project in the shell because all my other interactions are in Emacs rather than a terminal (I rarely use the shell in Emacs because the shell is so much less powerful for most stuff). Maybe that’s weird. I think folks who live in vi spend a lot more time bouncing around directories in the shell.

Re: Go run

#162
post #73

Earlier quoted context omitted.

Eh, I still don't get it. Go seems too high level for low level work - use Rust, manage your own memory, no garbage collector. Go also seems too low level for high level work - use TypeScript with all the nifty ES6 features, powerful type system, exceptions, etc.. Where does Go fit in here?

Go makes error handling explcit, which is a very important part of development. Not only this makes you more conscious on thinking what you need to do when something goes wrong, but also makes codes more maintainable in my opinion. I strongly prefer go error handling compared to a throws-type-error-handling language. Also, with this comment I hope to get some pushback: I haven't kept up with the latest typescript, py…

> Also, with this comment I hope to get some pushback

More of a push forward, really: if error-handling guarantees are what's driving you away from dynamically typed langauges, Go is pretty much the worst place you can land that isn't C. It doesn't make you check nils, it doesn't remind you to check error values from functions that you call only for side effects (though the linter will, admittedly), and it doesn't have sum types so there's semantic ambiguity even in the common case - that is, in `data, err := fn()`, it's common to assume that at most one, and perhaps exactly one, of `data` and `err` will end up non-nil, but that's not a constraint you can express with the type system.

Re: Go run

#163
post #157

Earlier quoted context omitted.

Because I don't want the code I'm running to change out from under me when I tell it to run because some dependency got updated (or for any other reason, for that matter). That's a recipe for disaster. Running the code is a separate step from determining what code I am going to run ; the latter includes determining exactly what versions of all dependencies I am going to run. The two should not be combined.

But the versions are locked right ? Similar to what package-lock.json etc does. So whats the issue ?

If the versions are locked, then after the first download, nothing should be downloaded again unless I explicitly change a requirement and/or a version. So after the first time with a given set of requirements and versions, I suppose "go run" would be fine since it won't actually download anything.

But for that first time, I still want to separate the two steps, for the reasons I've given elsewhere in this discussion.

Re: Go run

#164

`go run main.go` breaks if your `main` module is divided into multiple files. Use `go run .` instead - it's shorter and it works with multiple files

This is not a tip. It comes straight from

   go help run
"usage: go run [build flags] [-exec xprog] package [arguments...]

Run compiles and runs the named main Go package. Typically the package is specified as a list of .go source files from a single directory, but it may also be an import path, file system path, or pattern matching a single known package, as in 'go run .' or 'go run my/cmd'."

Nothing is said about go run main.go.

Re: Go run

#165
post #158

Earlier quoted context omitted.

"go mod download && go run ." What's the point in making `go run` error out when it already knows what dependencies to get and how to get them.

> "go mod download && go run ." No: "go mod download" if I want to update dependencies; then look to see what got updated and how it will affect what I'm doing . Then "go run". > What's the point in making `go run` error out when it already knows what dependencies to get and how to get them. Because I don't care what "go run" knows. I care what code is going to run when I say "go run" . I want that code to be the cod…

That is the purpose of go.mod/go.sum. `go mod download` never updates anything unless you change go.mod.

Re: Go run

#166

Earlier quoted context omitted.

You have to do that work anyway... Why not encode it in your build system? (Admittedly I have never tried this with a modern build system. My real world approach for that would be a janky phony rule in a Makefile, with a bunch of MAKE_VARS the user has to set on the cmdline/in the environment to set up the toolchain/serial port etc. But in principle I have always believed it should be possible to make this process as…

Are those vars discoverable? As in can you infer what they should be? If you can’t, or are building for all unknown possibilities, wouldn’t it be safer to enumerate known var values to perform that? Why must everything be explicit? Wrap it all up into one var. cmake -DBUILD_FOR=esp32 . Then provide your own little runtime.sh . For other languages and build systems, a runtime run sourcefile is the easiest way to get s…

No, you have to manually document them and then the docs go out of date and you can't realistically set up CI for this little runner script so certain use cases get broken and blah blah blah and it sucks!

Same for runtime.sh.

This is why the 'runtime run source' is so useful! I'm totally on board with it. I just don't think we need one implementation per ecosystem.

One runner per project (the 'make run' approach) is worse than one per ecosystem, which is in turn worse than just having one for everything!

Re: Go run

#167
Frankly I put all the correct command in in package.json file based on project

npm run dev is what I run all the time

It was never a blocker for me

Re: Go run

#168
post #15

combined with gosh - a golang shell interpreter it's pretty easy to create scripts that run on all the platforms and architectures, even future targets go run mvdan.cc/sh/v3/cmd/gosh@latest -c ' go run github.com/mikefarah/yq/v3@latest n foo.bar.hello world | go run github.com/cezarsa/glolcat@latest'

Gosh is a dead project currently, right ?

Are you assuming that based on visiting the vanity import path in a browser?

https://github.com/mvdan/sh is the repo looks like v3.8.0 was released 2 weeks ago.

Re: Go run

#169
post #97

Earlier quoted context omitted.

> Also, with this comment I hope to get some pushback: I haven't kept up with the latest typescript, python or any other language features. I'm talking from almost a purely ignorant perspective so I hope to learn a bit more on how developing with other languages feels like. Can't push back there - every other language I'm aware of uses at least one (and often both) of "throwing exceptions" or "returning Result types…

how does that work with try/catch? try/catch is significantly more verbose than just if err != nil // do something imo, and also much more brittle. Agree re: Results type in Rust and Ocaml, etc. Those are better in my view too. And yes, you can define a Result return type in Typescript as well (and in fact that's what I mostly when I write typescript and works ok) but unlike Rust this is definitely not 'idiomatic typ…

> try/catch is significantly more verbose than just if err != nil // do something imo...

Further to what the other replier said (about the ability to bubble-up errors), try-catch also lets you handle multiple errors in one block:

``` try { fileOutput1 = getSomethingFromFileSystem() fileOutput2 = getSomethingElseFromFileSystem() fileOutput3 = ... } catch (FileSystemException e) { // handle } ```

If I understand it correctly, GoLang's idiom would claim that this is a bad thing to do, and each error should be handled individually. Which - sure! That's _usually_ a reasonable, defensible, and safe position. But that means that GoLang's approach is always as verbose as its possible to be, whereas try/catch at least has the _possibility_ to condense handling.

> ...and also much more brittle

Can you be specific about what you mean by "brittle"? To me, it denotes a lack of flexibility - that is, if thing1 changes in an unexpected-but-still-legal way, then thing2 is likely to break. I can't see how that applies to try/catch-vs err-check - in both cases:

* The exception/error is bound to a variable

* (in most well-typed languages) the Type of the exception is checked by the type system, and/or (in every language, inc. GoLang) properties of the exception are checked by code

* Something is done (a standard code action, a return/throw of an exception, or a program termination)

You can write a brittle GoLang check (only checking for, say, `if e.message = "a very specific error message"`), and you can write a very flexible try/catch block (with a fallback `catch (Exception e) {doSomethingGeneric()}` - or, indeed, the _most_ flexible "try-catch" is "don't even catch it, let it bubble-up and let your framework/application handle it")

Re: Go run

#170
post #107

"go run" was a great way to run go code as scripts. But maybe it is not now. Why? because Go 1.22 introduced a change that breaks backwards compatibility (changing the semantics of "for;;" loops). Without language version specified (such as in go.mod files), the change will often cause unintended damage.

It's quite rare to find any Go repos without go.mod nowadays. So what's the problem again?
Post reply on HN