Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Pham Nuwen
Oct 30, 2010



etatoby posted:

If by "package management" you mean the fact that you have to pull all the sources for the libraries you use inside your project's source tree, or use your version control "linked repo" feature, and then it compiles everything down to a static binary that you can deploy anywhere, then I believe Go has the best package management I've ever seen.

Everyone wants a "go get"-able repo, but that's not the best way to manage a large project. IIRC this is at least part of what killed that Haunts game: they had external dependencies, and then all of a sudden github.com/dickhole/poo is gone because dickhole decided to delete his repo, or maybe he just completely changed the API and now your code doesn't build anymore.

We've started managing our Go code similarly to a well-run C project: You have a src/ directory under your top-level which includes subdirectories for your code AND for the external libraries you need. There's a script at the top level which sets GOPATH to the current directory and builds your code, compiling the dependencies in the process. This keeps you safe from dickhole deleting his repository, and it lets you adapt to an updated API on your own schedule, not at 4 p.m. on a Friday when dickhole decides to push his changes. When you're ready to update your library dependencies, you just check out the latest version of their repo, copy it in, make sure it builds, and commit.

Adbot
ADBOT LOVES YOU

Pham Nuwen
Oct 30, 2010



Bozart posted:

It works in more environments than just linux. You could add 3rd party packages to the docker image, and then use that image for dev work. Then all of the devs are using the same version of each of the packages, which may alleviate the problem he described of multiple devs coordinating multiple packages. The downside may be as Look Around You mentioned being "frowned upon" but I don't know one way or the other, because as I said, I haven't used it professionally.

This sounds like the equivalent of distributing a full Python installation with your program because of Python's version hell. (This is a thing people actually do)

Pham Nuwen
Oct 30, 2010



To keep the thread from falling into the archives I'll just job-brag a little. I started with Go when I took a seminar class on it in 2010, back when the language changed so fast you might not be able to compile last week's assignments if you've updated since then, back when we still had netchans and (for the first part of the quarter, anyway) compiled using Makefiles.

I got to write a lot of Go in my post-college job in 2011 (along with C and eww C++), with increasing quantities of Go through the years.

Last fall, I took a job at a startup founded by an old work colleague. We're 100% Go, except for the web UI which is your standard Javascript/HTML5 setup. I get to hack on Go distributed systems all day, which is great.

Editor-chat was last year but I'll mention that I use Acme (https://research.swtch.com/acme) which deeply frustrates my vim-using colleagues.

Pham Nuwen
Oct 30, 2010



Seat Safety Switch posted:

I don't think even the guys I know who are into 9front use Acme daily.

9front users use 9front so they can post about using 9front, cinap's about the only legit hacker in the group.

In the course of implementing a new feature or tracking down a bug I might go through half a dozen packages just within our own source code, which means I'm poking through a lot of different files at the same time. I just set up Acme fullscreen, open 4 columns, directories go in the left column, program outputs go in the right column, and files go in the middle two columns; I can keep about 30 files/directories on-screen and easily accessible at the same time.

delve and acme work well together. I'll run 'win' within acme to get a shell, then run delve within that. The file:line# printed when you do e.g. 'goroutine 10 bt' plumbs properly with acme, so it integrates well. I like to run "goroutines" in delve, then delete each goroutine's line as I check its backtrace and eliminate it as the source of the problem.

Pham Nuwen fucked around with this message at 05:37 on Apr 3, 2018

Pham Nuwen
Oct 30, 2010



Pollyanna posted:

This may or may not be the best place to ask, but:

We have a protobuf defined that represents a particular set of data, most of it nested. We want to expose filters based on that data, such that given a particular protobuf instance you know you can say “I want to filter on this message’s value between X and Y” or “I want to filter on this enum being of either value Foo or value Bar, and allow any others”.

We currently have to define these filters manually by being aware of these data “leaves” and what type they are, and manually changing what our filters do and allow based on that. What I’m wondering is, is there a way to list all data leaves and their type so we can programmatically filter on them? I’m hoping there’s a way to know when a protobuf message has a new age value and thereby programmatically generate a filter on that new value, without having to manually do so.

Is this something a protobuf can do? If it helps, we are using the Ruby implementation of gRPC and protobufs.

I was going to say it sounds like you want the reflect package, but apparently you're using Ruby, not Go? Check if Ruby has any reflection capabilities, I guess?

Pham Nuwen
Oct 30, 2010



Eela6 posted:

Let me know your experience. At {CORPORATION} we're still using `dep` and go 1.10, so I haven't played around with it myself.

Yeah switching to go modules from dep is one of my issues for the next major release of {COMMERCIAL SOFTWARE} so I'd be interested in hearing how it goes.

Pham Nuwen
Oct 30, 2010



Russ is also a legit Computer Science guy from way back, so he's going to spend a lot of time talking about algorithms and such. Plus, this is superseding dep, which made some people buttmad, so I don't blame him for exhaustively documenting how it handles corner cases etc. to keep them from bitching

Pham Nuwen
Oct 30, 2010



The second for loop is trying to read from a channel that never closes, so it deadlocks. Here's one way to get around that:

code:
package main

import (
	"fmt"
	"sync"
)

func print_nums(number int, messages chan<- int, wg *sync.WaitGroup) {
	messages <- number
	wg.Done()
}

func main() {
	messages := make(chan int, 10000)

	var wg sync.WaitGroup
	for i := 2; i < 1000; i += 1 {
		wg.Add(1)
		go print_nums(i, messages, &wg)
	}

	wg.Wait()
	close(messages)

	for elem := range messages {
		fmt.Println(elem)
	}
}
Every time we kick off a new processing routine, we increment the waitgroup. Every time a processing goroutine exits, it decrements the waitgroup. The main thread waits until everyone has exited, then closes the channel and then reads all the poo poo off the channel.

Pham Nuwen
Oct 30, 2010



Sylink posted:

Are wait groups the proper way in Go , then, if you need to wait for everything to finish ? I.e. everything isn't contained within the goroutine itself that you need done?


Because I've noticed trying to close the channel before the for loop, or the beginning while checking to see if the channel is still open first, still doesn't work. Like

code:

	c := make(chan int, 10)
	go someshit(...)
	for i := range c {
		_, ok := <-c
		if ok == false {
		close(c)
....


If you're going to use range, somebody needs to close the channel as per the spec: "For channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever. "

Now, since you know how many goroutines you're going to run, you could do this:

code:
c := make(chan int)
for i := 0; i < 1000; i++ {
  go calc(c)
}

for i := 0; i < 1000; i++ {
  fmt.Println(<-c)
}
close(c)
Edit: also, in the example you show above, you're reading from the channel twice in each loop iteration, but you're discarding the value the second time you read it.

Pham Nuwen fucked around with this message at 16:38 on Mar 26, 2019

Pham Nuwen
Oct 30, 2010



The modules system is the hardest-to-understand part of Go imo. It's strict, it's picky, and it can be unintuitive. It's also better than the two previous alternatives (dep, or "just grab latest off github and run with it") so I put up with it, but on our large corporate project we have to fight it from time to time.

On a small project, it should be pretty reasonable to deal with, just follow the wiki.

Pham Nuwen
Oct 30, 2010



FnF posted:

It says this was published in 2015. Is this still "current"? I've been getting the impression that Go is changing & developing as a language quite quickly, and I don't want to accidentally learn out-of-date syntax & conventions as that can lead to me internalising bad practices as "the way you do things in Go". Which would be bad!

2015 was well into Go 1.x territory, which means nothing you learn there should be invalidated by later updates in the 1.x line. Syntax will not change, but syntax is minor anyway. The standard library calls should all work, although the best practices may have shifted on a few things.

Kernighan is the co-author on that book, and I'll always recommend his work. I haven't read it, but I'm sure it will help you get your head around the concept of goroutines and channels, which seems to be the biggest challenge for a lot of new Go programmers. Then, use the online documentation (https://github.com/golang/go/wiki/Modules helps) to learn how to use the modules system, and you'll be in good stead.

Pham Nuwen
Oct 30, 2010



Taking a look at the docs (https://pkg.go.dev/math/big), it seems like those methods all return the result in addition to setting the receiver. So you should be able to use it as you wish; please forgive my slight re-writing:

code:
	xInput := int64(1)
	yInput := int64(2)
	pInput := int64(3)
	x := big.NewInt(xInput)
	y := big.NewInt(yInput)
	p := big.NewInt(pInput)
	z := big.NewInt(0) // use this as the receiver in everything
	out := z.Mod(z.Sub(z.Sub(z.Exp(y, big.NewInt(2), nil), z.Exp(x, big.NewInt(3), nil)), big.NewInt(7)), p)
Personally, I find your example easier to follow; it feels a lot like working on an RPN calculator.

Pham Nuwen
Oct 30, 2010



Breaking Glass posted:

We use it for logs and event analysis of pretty egregiously large streaming datasets (petabytes). I think Segment does too for data, as well as Uber for lots of different things. It's pretty well suited for getting most of the c++ performance with fewer footguns.

pprof is your friend.

Funny, I also use it for logs & event analysis. Do you work on an analysis product, and if so, do you mind sharing which one? If not, that's obviously fine.

Pham Nuwen
Oct 30, 2010



Breaking Glass posted:

The limitation that variadic arguments have to all be the same type is a little frustrating.

I assume Russ Cox has a frustratingly thorough explanation for why this is the only correct choice.

Pham Nuwen
Oct 30, 2010



cruft posted:

Can anybody help me understand what I need to do in order to make "go get github.com/dirtbags/moth/pkg/jsend" work outside of that source tree?

Like, I thought I was setting things up so other software could use that library, but apparently I'm missing something, because it tells me:

code:
go: module github.com/dirtbags/moth@upgrade found (v3.6.3+incompatible), but does not contain package github.com/dirtbags/moth/pkg/jsend
:confused:

So you're trying to write software to use that jsend library? If you've done a `go mod init` in your code, you should be able to do `go get github.com/dirtbags/moth/pkg/jsend@v4.4.9` from within your code dir and it'll Just Work?

edit: oh, they've hosed up their versioning, poo poo, I forget how to fix this

edit 2: yeahhhh they haven't set up their go.mod correctly. They've tagged up through v4.x.x, which means go.mod should say "module github.com/dirtbags/moth/v4" but they didn't do that. See https://go.dev/doc/modules/major-version

edit 3: jsend is just a single small file so just copy it into your own tree, with correct attribution of course (these guys ALSO didn't bother to do copyright headers...)

Pham Nuwen fucked around with this message at 00:27 on Apr 12, 2023

Pham Nuwen
Oct 30, 2010



cruft posted:

Dirtbags is me. I'm trying to fix this :) Your link has me down some sort of path, maybe there's a working import at the end of it.

Regarding copyright headers, what's the preferred way to denote that? I thought you just dropped LICENSE.md in the top level?

lol sorry for ripping on your code, good luck because while go mod is an improvement over what came before, wrestling it is also my least favorite part of the job.

As for headers, I suggest just doing what the Go code does:


code:

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Adbot
ADBOT LOVES YOU

Pham Nuwen
Oct 30, 2010



consensual poster posted:

Memory usage is not the only consideration. Using pointers, you can modify an attendee and you'll see the update no matter how you access that Attendee.

Particularly since each attendee is duplicated 3x in that struct, it makes sense to work with pointers.

Speaking of that, I'd ask if you really expect to have so many attendees and do so many lookups by both email and by username that it makes sense to duplicate them 3 different ways. My first instinct would be to just hold the slice of Attendees, then iterate for lookups. Iteration is cheaper than you think (especially in this case which won't even have nested loops), and a lot easier than mucking around with 3 different stored representations of the same data.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply