Live data from Hacker News

Notes on the Go translation of Reposurgeon (2020)

gitlab.com

141–150 of 155 posts

Re: Notes on the Go translation of Reposurgeon (2020)

#141

Earlier quoted context omitted.

I'm not following. I can be explicit without being duplicative. The more I repeat an expression of a single concept, the harder I make refactoring when I discover the concept needs to change. That's why, e.g., copy-paste programming is such a bad idea for most projects.

I'm not sure how this would apply. You'll never refactor away the error handling idioms of the language itself.

Exactly. If the error-handling idioms of the language force me to be duplicative in ways that make useful work harder, then it sounds like it's not the right language for the project in question.

Re: Notes on the Go translation of Reposurgeon (2020)

#142
post #89

Earlier quoted context omitted.

Go treats strings as a sequence of unicode code points.

I believe they’re treated as byte sequences: https://go.dev/ref/spec#String_types

Not treated as, only backed by byte sequences. If you range over them you get a series of rune values that can be multi-byte code points.

There's a few other differences, strings cannot be directly mutated or have the address of their elements taken.

Re: Notes on the Go translation of Reposurgeon (2020)

#143

What I really missed was generic map-function-over-slice, which could be handled by adding a much narrower feature. If one graded possible Go point extensions by a figure of merit in which the numerator is "how much Python expressiveness this keeps" and the denominator is "how simple and self-contained the Go feature would be", I think this one would be top of list. So: map as a functional builtin takes two arguments…

> a real missed opportunity for Go to explore new PL territory But Go was not intended to explore new PL territory. Is that not OK?

I would argue that it is: it's explicitly a language designed "in the service of software engineering," which is something we're still figuring out how to do. It has implemented novel features that serve this end, and left out features that don't. PL design doesn't have to just be about dependent types and borrow checkers, after all.

Re: Notes on the Go translation of Reposurgeon (2020)

#144

Earlier quoted context omitted.

For me, it's not a question of terseness -- it's more about communicating intent, and not polluting the scope with incidental variables. Everyone knows what map/filter/reduce do. When reading new code, seeing "map" is better than seeing a for loop: you don't have to think about the underlying iteration at all, you can skip directly to the essence of the transformation. As a side effect of this, when you do see a for…

> For me, it's not a question of terseness -- it's more about communicating intent, and not polluting the scope with incidental variables. A mapping for loop doesn't pollute scope with incidental variables: results := make([]Result, len(input)) for i := range input { results[i] = callback(input[i]) } ^ This only adds `results` to scope, which is the same as `results := map(input, callback)`. In the for loop example,…

That's exactly the view I express in the Twitter thread lol

Re: Notes on the Go translation of Reposurgeon (2020)

#145

Earlier quoted context omitted.

If you can write the indulgence (permission to sin) into the code it becomes self-documenting and that seems reasonable e.g. #![allow(dinosaur::nonsense)] in Rust tells the tools that you know you're not supposed to do whatever dinosaur::nonsense might be, but you want to do it anyway in the following code and the hypothetical dinosaur linter shouldn't bother you about that. When a maintenance programmer is staring a…

This is fine, in moderation! I'm objecting to the linter tool itself being configurable.

Golint is the worst precisely because it isn’t configurable, and some of the things it looks for are idiotic. “should replace i += 1 with i++” is probably the worst advice I have ever received.

Re: Notes on the Go translation of Reposurgeon (2020)

#146
post #56

Reposurgeon was a pretty enticing option for us, as we're currently in the migration of SVN to Git, and the string of tools we have is kind of complicated to explain to newcomers. Currently the workflow is svn-all-fast-export (SVN to Git) -> git filter-repo (trim content from the repository) -> Git LFS (store large files out-of-band), where each stage has to be manually tested and written, and then hopefully put into…

We’d be interested in hearing more about your situation, so that we can further improve Reposurgeon. If you can profile it as it reads your svn dump (using the `profile start` and `profile save` commands), it could really help us out.

How many commits does your repository have? The largest one we’ve successfully converted from SVN to Git ourselves was 287k commits.

Re: Notes on the Go translation of Reposurgeon (2020)

#147
post #23

Earlier quoted context omitted.

Honestly, you don't notice it once you get into the Go mindset. The exception handling looks onerous, and is a pain at the start. But it doesn't take long to get used to it, and then (for me anyway) it becomes second-nature. Everything returns an error, and you have to handle that error (even if only passing it up again). Static typing is more "fun" when you're exploring new concepts, but interfaces are the key. Defi…

> But it doesn't take long to get used to it I did get used to it, but all the if err != nil { return nil, err } sometimes taking up half or more of the vertical space of a function is still an eyesore to me, even after writing a quite substantial amount of Go.

iferr is one of the worst warts of the language. I recently converted a Pulumi project from golang to Typescript. Code size dropped by 30% just by removing all the iferr checks. The other thing is the compiler doesn’t complain if you forget to check error returns - so it’s easy to make mistakes. This and lack of generics make golang incredibly verbose at times.

Re: Notes on the Go translation of Reposurgeon (2020)

#148
post #97

Earlier quoted context omitted.

> No VM, no interpreter That's not quite accurate; there is a runtime, it just gets statically linked into the binary instead of needing to be externally installed

No, Go literally doesn't have a VM or an interpreter. VMs and interpreters are runtimes, but not all runtimes are VMs or interpreters. Go executes native code.

Any language that performs work not directly specified by the user has a runtime. Go's runtime is minimal and concerned with two important aspects of the language: scheduler, and garbage collection.

Re: Notes on the Go translation of Reposurgeon (2020)

#149
post #145

Earlier quoted context omitted.

This is fine, in moderation! I'm objecting to the linter tool itself being configurable.

Golint is the worst precisely because it isn’t configurable, and some of the things it looks for are idiotic. “should replace i += 1 with i++” is probably the worst advice I have ever received.

I can see Go's point here though. Unlike C-style languages where i++ is an expression, in Go it's only a statement, it has no value, which eliminates some footgun opportunities.

It's a halfway house to a language like Swift or Rust where none of the assignments have value. So, in a context where you don't want a value, arguably i++ is a better choice by eliminating a footgun. I don't hate it.

Re: Notes on the Go translation of Reposurgeon (2020)

#150

Earlier quoted context omitted.

No, Go literally doesn't have a VM or an interpreter. VMs and interpreters are runtimes, but not all runtimes are VMs or interpreters. Go executes native code.

Any language that performs work not directly specified by the user has a runtime. Go's runtime is minimal and concerned with two important aspects of the language: scheduler, and garbage collection.

Yes, I understand. I was responding to someone who was arguing that it was inaccurate to say that Go lacked a VM or interpreter. Yes, Go has a runtime, but that doesn't imply that it has a VM or interpreter (it doesn't).
Post reply on HN