Live data from Hacker News

Notes on the Go translation of Reposurgeon (2020)

gitlab.com

51–60 of 155 posts

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

#51
post #37
post #34

Earlier quoted context omitted.

> Except you can't really do this with interfaces Apparently they decided that it would be too confusing to have variant types alongside interfaces for some reason, and they claim that interfaces handle a lot of the use cases of variants: https://go.dev/doc/faq#variant_types

Yeah, "for some reason" is a good summary of many Go decisions. Rust has both (traits are somewhat like interfaces) and I don't feel like it's too painful, though using the trait type in function signatures is a lot more involved than in Go, and I still don't fully understand all the nuances. But the complexity isn't because of any overlap between traits and sum types.

Rust trait objects are surprisingly painful. I've reached for them a lot where I would normally use Go interfaces, but ended up avoiding them. I suspect this has more to do with Rust's memory management model--having sum types and interfaces would almost certainly work out perfectly in Go.

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

#53
post #46

Earlier quoted context omitted.

> A lot of Rustaceans don’t seem to grasp why, when the question is “where do I get feature X?” the answer “oh, there are 23 crates for that” is objectively terrifying. This is exactly the impression I have gotten from the crates system every time I've looked. It happens for things as foundational as mmap. Also terrifying: The plethora of highly-recommended crates that have not yet committed to a stable API (ie, are…

I’m not sure that’s a great example. mmap(2) is a swiss army knife of a function. There are many crates that build all kinds of things on top of mmap, and they’re not all interchangeable. Allocators, file io, gpio, actual virtual memory mappings. My view is that when you develop a product, you have to own everything. The users don’t care if the bug comes from code you wrote, or code in a library, or the language’s st…

>My view is that when you develop a product, you have to own everything. The users don’t care if the bug comes from code you wrote, or code in a library, or the language’s standard library, or the OS. You have to fix the bug no matter what caused it. It doesn’t matter if the code came from a vendor or a language designer or stack overflow; you are the one responsible for fixing it if something goes wrong.

So then using a programing language that has a big standard library and a more rich and stable ecosystem is a big advantage. If I want to do a network request, parse a json file, parse or format a date or some other trivial thing I prefer to have a good enough built in way to do it then evaluate 15 packages or write it myself. Otherwise you get in a shitty situation where you inherit some projects and it has 20 dependencies with vulnerabilities, 20 dependencies abandoned, some dependencies that are incompatible with some new version of the language/ecosystem causing issue if you would like to upgrade.

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

#54

One thing that the people saying "just use a struct for keyword arguments" are missing is that structs should signal intent, i.e. "this is a concrete concept in the system." A Repository, Commit, Message, Person, etc. struct are all concepts in the domain, whereas "the arguments for this particular function" is not. I think Go people are allergic to writing code that does anything other than functionally work.

> I think Go people are allergic to writing code that does anything other than functionally work.

I think that's what Go was designed for, as a language. To be readable, usable. It's uncaring for your personal programming philosophies. I think that's why it's been successful.

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

#55
post #32
post #9

What a delight to read, even as somebody who has barely used Go. I really appreciate the author's self-awareness as demonstrated in things like "Expected problems that weren’t". The bits about exceptions and typing remind me of an open question I have about Go: to me it mainly looks like a language for well-understood problems. Static typing and the lack of ability to do broad, high-level exception catching seem to m…

I feel like strong typing _helps_ when exploring a new domain, as it forces you to really think about the data you're operating on. In a language like Perl or Python, it's so easy to just throw around a bunch of hashes/dicts and that can get messy really quickly. I don't miss _exceptions_ in Go but after using Rust for a while I've come to really love Rust's `Option` and `Result` types. They're more ergonomic and exp…

With generics around the corner I am really hoping we see some flavor of Option & Result coming to Go. But I won't hold my breath for ?.

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

#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 a shell script or Bash history or something.

Unfortunately, I have yet to get Reposurgeon working for us at all. The documentation was inaccurate, in that it referred to things which only existed in the Go version, and the Go version went OOM (on a server with 384 GB of RAM) on every repository I've tried it on. This includes just reading from an existing, pruned svndump file, so it's not resource contention either.

Basically, the tool is great conceptually, but it absolutely does not work for our use case. We had to stick with our existing, messy, multi-component solution, which has worked surprisingly well over the last two years, and since I'm the one doing most of the processing, having kind of a messy system is relatively acceptable for the time being.

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

#57

One thing that the people saying "just use a struct for keyword arguments" are missing is that structs should signal intent, i.e. "this is a concrete concept in the system." A Repository, Commit, Message, Person, etc. struct are all concepts in the domain, whereas "the arguments for this particular function" is not. I think Go people are allergic to writing code that does anything other than functionally work.

> I think Go people are allergic to writing code that does anything other than functionally work. I think that's what Go was designed for, as a language. To be readable, usable. It's uncaring for your personal programming philosophies. I think that's why it's been successful.

Specifically, Go was designed to be effectively and safely writeable and readable by mediocre programmers.

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

#58
post #5

Earlier quoted context omitted.

The major problem I have with that is performance is atrocious [1] if the iterator isn't doing something very nontrivial. Since the vast majority of iterators amount to incrementing at most a handful of things and then returning something indexed by those things, you're paying the cost of channel communication per item but not getting that channel cost amortized over any significant costs in the iteration itself. If…

Hmm, can you provide some examples of how a context based iterator is slow? If you need raw performance and you are just doing some minimal operations on a slice then yeah you’d want to use a simple for loop instead. I typically use this pattern in situations where you have a ton of data coming back where you want to avoid storing all of that data in memory.

The problem with using channels is that these require multiple goroutines and locking for a problem that's inherently singlethreaded. Instead, you can define an iterator as a function that returns a function:

    func intSliceIter(ints []int) func() (int, bool) {
        i := 0
        return func() (int, bool) {
            if i 
Of course, there's not much benefit to a SliceIter; this is a contrived example, but you can apply this pattern in more complicated cases as well. Similarly, you can define an iterator as an interface (which is similar to bufio.Scanner and a few others in the standard library—a closure is an object is a closure):

    type IntIter interface {
        Next() (int, bool)
    }

    type IntSliceIter struct {
        Cursor int
        Ints []int
    }

    func (isi *IntSliceIter) Next() (int, bool) {
        if isi.Cursor 

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

#59

The article mentions that Go, OCaml, or a compiled lisp were considered for this project. I wonder why Rust wasn't on that list. It seems to cover every concern that is raised here except for keyword arguments (which are high on my list of desired Rust features too). I guess maybe they were worried about the lack of GC, but my experience has been that's it's generally quite easy to port code from dynamic languages li…

Two threads from back in the day about this:

https://news.ycombinator.com/item?id=13385530

https://news.ycombinator.com/item?id=13398068

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

#60

One thing that the people saying "just use a struct for keyword arguments" are missing is that structs should signal intent, i.e. "this is a concrete concept in the system." A Repository, Commit, Message, Person, etc. struct are all concepts in the domain, whereas "the arguments for this particular function" is not. I think Go people are allergic to writing code that does anything other than functionally work.

Well, "Command to Create a Repository" could easily be a concept which contains all of the options necessary to create a Repository, which is a different concept.

Now, there is a problem that all of the struct fields have to have sane zero values for this to work, but I think that is a problem which would naturally arise with keyword arguments as well.

Post reply on HN