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
Coffee Mugshot
Jun 26, 2010

by Lowtax

Ghost of Reagan Past posted:

I'm writing a lovely, bare-bones NES emulator for shits and giggles. What's a good library for graphics for someone who doesn't do graphics?

EDIT: Basically I'd just like the ability to draw pixels on a screen. I don't need much, but I also don't know exactly what I need, and I don't work with graphics at all professionally. I ALSO don't really know Go and I'm using this as a way to learn some.

EDIT #2: As a Python programmer I want to scream at some of this. Why is there no 'in' operator? Why does writing a for each loop require extra syntax? Why is gofmt such a dick? Give me the gun to shoot my own face off, please, I'm a competent programmer, I swear.

First of all, I agree with MALE SHOEGAZE completely. However, if you did want to learn Go this way you might want to start from some of the graphics libraries the community has been working on: https://github.com/golang/go/wiki/Projects#graphics-and-audio. It's true that the Go team, proper, hasn't blessed a particular solution for cross-platform APIs for low level graphics and audio and it's extremely awkward to write this code the way you'd expect as a Python or Rust programmer, I think. Of course, some of these libraries involve compiling a C library with cgo (https://golang.org/cmd/cgo/) which is done automatically by the go tool for these libraries, which are basically idiomatic-esque looking wrappers of the underlying C library. You might also use something like SWIG for this if you have C++ code you'd like to call from Go. SWIG has bindings for Go types and convenience wrappers for string to std::string-like type conversion across the languages.

Anyways, if I had to suggest something to your first edit, I'd start by using something like: https://godoc.org/github.com/fogleman/gg. The examples seemed straightforward enough to build on.

Coffee Mugshot fucked around with this message at 06:45 on Jan 13, 2018

Adbot
ADBOT LOVES YOU

Startyde
Apr 19, 2007

come post with us, forever and ever and ever
I've a not dissimilar question, terminal ui. I'm guessing people don't just use ncurses c bindings but have no idea. Is there a standard lib for console menus, simple tiled windowing?

Coffee Mugshot
Jun 26, 2010

by Lowtax

Startyde posted:

I've a not dissimilar question, terminal ui. I'm guessing people don't just use ncurses c bindings but have no idea. Is there a standard lib for console menus, simple tiled windowing?

To answer your immediate question: there is no standard library for console menus or tiled windowing. Based on your description, you might find luck with https://github.com/gizak/termui.

spiritual bypass
Feb 19, 2008

Grimey Drawer
In Java-like languages, I'm accustomed to catching exceptions, then throwing a new exception in a "chain" so that I get information about every level of the stack trace. Does Go have this capability? I haven't found one, so I've created this pattern in my modules instead:

code:
if err != nil {
		return errors.New("mail API request failed: " + err.Error())
	}
This provides an error specific to this particular function while preserving the error from the function it called. Is there a better way to do it?

Eela6
May 25, 2007
Shredded Hen

rt4 posted:

In Java-like languages, I'm accustomed to catching exceptions, then throwing a new exception in a "chain" so that I get information about every level of the stack trace. Does Go have this capability? I haven't found one, so I've created this pattern in my modules instead:

code:
if err != nil {
		return errors.New("mail API request failed: " + err.Error())
	}
This provides an error specific to this particular function while preserving the error from the function it called. Is there a better way to do it?

Sort of. The traditional golang way is to use fmt.Errorf for the same purpose, so you don't gave to call err.Error()

Eg,
code:

return fmt.Errorf("mail api request failed: %v", err)

You still have to build your trace manually, though.

waffle enthusiast
Nov 16, 2007



https://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package might be worth a read.

spiritual bypass
Feb 19, 2008

Grimey Drawer
Those are helpful, thanks. I knew I couldn't be the only person who wants to do this.

homercles
Feb 14, 2010

I'm building a tool that does a lot of computation through lots of goroutines, and pipelining chunks of work in N:M relations. Before I start optimising, I want to know, for each goroutine:
  • How much time it is waiting on channels to return data
  • How much time it is running
  • How much time it is pending to run because other goroutines are currently running
Is it possible to get these goroutine stats in a concise manner?

Hadlock
Nov 9, 2004

I don't think this directly solves your problem but I always thought this was a novel tool:

https://github.com/uber/go-torch

We had a critical app that was written by a sophmore/junior level developer, when we scaled up, were able to use this to find pain points quickly.

Eela6
May 25, 2007
Shredded Hen

homercles posted:

I'm building a tool that does a lot of computation through lots of goroutines, and pipelining chunks of work in N:M relations. Before I start optimising, I want to know, for each goroutine:
  • How much time it is waiting on channels to return data
  • How much time it is running
  • How much time it is pending to run because other goroutines are currently running
Is it possible to get these goroutine stats in a concise manner?

Sounds like you want to use go test -blockprofile .

The following might be helpful:
https://golang.org/cmd/go/#hdr-Description_of_testing_flags
https://software.intel.com/en-us/blogs/2014/05/10/debugging-performance-issues-in-go-programs
https://golang.org/pkg/runtime/pprof/

homercles
Feb 14, 2010

@hadlock, I do use go-torch already but, while useful, it's not the right tool for showing the lifecycle of a goroutine
@Eela6, those links are extremely my poo poo

Mine GO BOOM
Apr 18, 2002
If it isn't broken, fix it till it is.
And for a video tutorial: https://www.youtube.com/watch?v=ySy3sR1LFCQ

spiritual bypass
Feb 19, 2008

Grimey Drawer
I don't understand why I'm getting a segfault while trying to query my database. Here's a minimal example that segfaults at conn.Exec:

code:
func Add (email string, hash string) error {
	conn, err := sql.Open("mysql", "user:pass@localhost/dbname")

	if err != nil {
		errors.Wrap(err, "could not connect to database")
	}

	_, err = conn.Exec(
		"INSERT INTO users(user_id, email, `password`, date_registered) VALUES (?, ?, ?, NOW())",
		db.MakeId(),
			email,
			hash)

	if err != nil {
		errors.Wrap(err, "could not insert user")
	}

	return err
}
Is there something obvious I've missed here?

e: turns out you have to import _ "github.com/go-sql-driver/mysql"

spiritual bypass fucked around with this message at 02:47 on Feb 26, 2018

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You might find it worthwhile figuring out why it was failing via a segfault on that exec line, as opposed to failing in a way that would have given you more information on what the actual failure was.

Your error-handling code would be better described as "error-ignoring".

nern
Oct 29, 2005

RIDE RIDIN LIKE THE DEMON INSIDE YOUR DREAMS
Just started working on a project at work. We’re rebuilding the backend of a web application. It was all node.js and AWS lambdas. Were rebuilding it as a monolithic Go application.
I loving it.

bonds0097
Oct 23, 2010

I would cry but I don't think I can spare the moisture.
Pillbug

nern posted:

Just started working on a project at work. We’re rebuilding the backend of a web application. It was all node.js and AWS lambdas. Were rebuilding it as a monolithic Go application.
I loving it.

Why the move away from serverless? Performance?

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

bonds0097 posted:

Why the move away from serverless? Performance?

in my experience, lamdas / microservices are a function that maps simple problems to complex distributed systems problems

DONT THREAD ON ME fucked around with this message at 12:04 on Feb 27, 2018

Mao Zedong Thot
Oct 16, 2008


MALE SHOEGAZE posted:

in my experience, lamdas / microservices are a function that maps simple problems to complex distributed systems problems

:vince:

champagne posting
Apr 5, 2006

YOU ARE A BRAIN
IN A BUNKER

MALE SHOEGAZE posted:

in my experience, lamdas / microservices are a function that maps simple problems to complex distributed systems problems

Cancelbot
Nov 22, 2006

Canceling spam since 1928

Hey now; microservices are also great for turning a problem of tight coupling into a problem of network latency and service discovery. Whilst keeping the tight coupling.

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.

Seat Safety Switch
May 27, 2008

MY RELIGION IS THE SMALL BLOCK V8 AND COMMANDMENTS ONE THROUGH TEN ARE NEVER LIFT.

Pillbug

Pham Nuwen posted:

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.

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

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

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
For some reason I decided that Go would be a good fit for my personal project, so I'm playing around with GORM to manage my database connection, and I hit a bit of a snag.

Go code:
type City struct {
	Id int `gorm:"primary_key;unique;column:city_id"`
	Name string `gorm:"size:50;column:city"`
	CountryId int
	LastUpdate time.Time
}

func (City) TableName() string {
	return "city"
}

type Country struct {
	Id int `gorm:"primary_key;unique;column:country_id"`
	Name string `gorm:"size:50;column:country"`
	LastUpdate time.Time
	Cities []City `gorm:"foreignkey:CountryId;association_foreignkey:Id"`
}

func (Country) TableName() string {
	return "country"
}
Now I would expect the foreignkey specification to make GORM look up by CountryId on the City table, but it seems to just ignore it entirely, so the following

Go code:
var country Country
var cities []City

db.Debug().First(&country).Related(&cities)
produces this:
SQL code:
(C:/Users/snip/stuff.go:43) 
[2018-04-22 18:54:01]  [10.99ms]  SELECT * FROM "country"   ORDER BY "country"."country_id" ASC LIMIT 1  
[1 rows affected or returned ] 

(C:/Users/snip/stuff.go:43) 
[2018-04-22 18:54:01]  [14.99ms]  SELECT * FROM "city"  WHERE ("city_id" = '1') ORDER BY "city"."city_id" ASC  
[1 rows affected or returned ] 
I would've thought that since I specified a foreign key it would have done this in stead on the second line:
SQL code:
SELECT * FROM "city"  WHERE ("country_id" = '1') ORDER BY "city"."city_id" ASC 
or something to that effect. What am I missing?

Note: I tried removing the association foreign key to no avail. I also tried specifying the actual column name as the foreign key, and it still does that selection.

Joda fucked around with this message at 18:01 on Apr 22, 2018

luchadornado
Oct 7, 2004

A boombox is not a toy!

Confluent's Kafka client has me a little confused. When producing a message to the topic, the topic name is a pointer to the string type and I have no idea why this would be useful. Why can't it just be a string?

code:
type TopicPartition struct {
	Topic     *string
	Partition int32
	Offset    Offset
	Error     error
}

DARPA
Apr 24, 2005
We know what happens to people who stay in the middle of the road. They get run over.
Guessing as I just started writing Go for real this morning, but Go doesn't allow nil strings, so if you want to differentiate between the empty string and nil string, you need to use *string.

Some fun today realizing bufio Reader.ReadLine() doesn't guarantee it will actually read an entire line, even if one is available, so you still need to loop to assemble a complete line until isPrefix is false.

luchadornado
Oct 7, 2004

A boombox is not a toy!

That seems to be why - the struct I pasted is a placeholder for various pieces of data that may or may not be present.

edit, some info on the "why": https://dhdersch.github.io/golang/2016/01/23/golang-when-to-use-string-pointers.html

Seat Safety Switch
May 27, 2008

MY RELIGION IS THE SMALL BLOCK V8 AND COMMANDMENTS ONE THROUGH TEN ARE NEVER LIFT.

Pillbug

DARPA posted:

Some fun today realizing bufio Reader.ReadLine() doesn't guarantee it will actually read an entire line, even if one is available, so you still need to loop to assemble a complete line until isPrefix is false.

The docs say not to use ReadLine:

quote:

ReadLine is a low-level line-reading primitive. Most callers should use ReadBytes('\n') or ReadString('\n') instead or use a Scanner.

Not sure how that deals with an EOF though.

2nd Rate Poster
Mar 25, 2004

i started a joke

Helicity posted:

Confluent's Kafka client has me a little confused. When producing a message to the topic, the topic name is a pointer to the string type and I have no idea why this would be useful. Why can't it just be a string?

code:
type TopicPartition struct {
	Topic     *string
	Partition int32
	Offset    Offset
	Error     error
}

I'm guessing a bit here, I've not looked through the code, but it's probably for reuse in the Message struct. With lots of messages flying around you're likely to have a lot of structs all having the same value, so you'd want to just use a pointer to avoid an allocation and to save on the memories.

Coffee Mugshot
Jun 26, 2010

by Lowtax
Like the other poster says, that's an idiom to differentiate between a valid empty string and an actually non valid string. I'd guess they're trying to save allocations when sending s bunch of error messages and the default value of pointers is nil.

spiritual bypass
Feb 19, 2008

Grimey Drawer
Anyone encountered a problem where pprof starts in interactive mode and then quits immediately without providing a prompt?

code:
$ go tool pprof mysql.test cpu.out           
File: mysql.test
Type: cpu
Time: Jun 10, 2018 at 10:46am (EDT)
Duration: 4.81s, Total samples = 4.60s (95.70%)
Entering interactive mode (type "help" for commands, "o" for options)
That's all I get and it quits.

I'm trying to figure out why a short set of database tests take about 1s each to perform some basic inserts and reads on an empty MySQL database. It seems absurdly slow compared to what I'd expect from other languages and how the database performs at an interactive prompt.

Mine GO BOOM
Apr 18, 2002
If it isn't broken, fix it till it is.

rt4 posted:

It seems absurdly slow compared to what I'd expect from other languages and how the database performs at an interactive prompt.

Give the tracer a try. Good example from justforfunc guy on youtube: https://www.youtube.com/watch?v=ySy3sR1LFCQ

spiritual bypass
Feb 19, 2008

Grimey Drawer
Thanks, I wasn't even aware of that option.

e: After using trace, it turns out it wasn't even the database access. I'd written tests that all involve checking user passwords and I'd forgotten that bcrypt is, of course, very slow. In fact, it involves something called expensiveBlowfishSetup

spiritual bypass fucked around with this message at 00:44 on Jun 21, 2018

limaCAT
Dec 22, 2007

il pistone e male
Slippery Tilde
I was going to ask about the usual "ok but what about 'missing feature X'" (mostly exception handling and generics) but this talk (and some slides on currency and channels) convinced me about looking a bit deeper at Go as a serious language: https://www.youtube.com/watch?v=29LLRKIL_TI.

Khorne
May 1, 2002

limaCAT posted:

I was going to ask about the usual "ok but what about 'missing feature X'" (mostly exception handling and generics) but this talk (and some slides on currency and channels) convinced me about looking a bit deeper at Go as a serious language:
Go is good tool for web services and similar applications. I've used it off and on since 2014 and as long as you don't venture too far from that realm it's truly well designed. It's also not bad for command-line/one-off programs that most people would probably reach for Python/bash/perl/whatever to make. Its portability, single day learning curve, ease of developing in, and ease of setting up its environment are all great. It has similar level performance to pretty much anything for web stuff. It's not slow and carrying five tons of baggage like lots of the common web backend languages, and it doesn't require significant developer investment like C++ or functional languages. It also doesn't require consuming a bloated corpse like the JVM languages.

Its package management left a lot to be desired last time I used it, but it was supposed to be fixed at some ambiguous time in the future which may have already happened.

Due to the positives, people often use it for things it's real bad at. It is missing language features that are very useful for certain types of applications, but it's mostly intentional to make the language better at what it's good at. It's a current-gen tool for a specific type of program and a drat good one.

Khorne fucked around with this message at 01:21 on Aug 6, 2018

waffle enthusiast
Nov 16, 2007



^^ a good post.

The package management piece is in the process of being baked now. I won’t go into the craziness, but there was “dep” for a while, which is now in the process of being replaced with vgo.

Mao Zedong Thot
Oct 16, 2008


Dangerllama posted:

^^ a good post.

The package management piece is in the process of being baked now. I won’t go into the craziness, but there was “dep” for a while, which is now in the process of being replaced with vgo.

Vendoring has worked really well for like multiple years. Go's biggest mistake was showing people `go get` without bashing into their head that it's not how you actually do anything besides "randomly install some cool thing to run".

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
The prototype was called vgo (for versioned go) but it's baked in at tip and just called modules now. It lands with 1.11 which should be coming out shortly.

You can play with it now by getting the vgo prototype, which I believe is still being kept in sync, or you can grab the latest beta: https://golang.org/dl/#go1.11beta3

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

Khorne posted:

Go is good tool for web services and similar applications. I've used it off and on since 2014 and as long as you don't venture too far from that realm it's truly well designed. It's also not bad for command-line/one-off programs that most people would probably reach for Python/bash/perl/whatever to make. Its portability, single day learning curve, ease of developing in, and ease of setting up its environment are all great. It has similar level performance to pretty much anything for web stuff. It's not slow and carrying five tons of baggage like lots of the common web backend languages, and it doesn't require significant developer investment like C++ or functional languages. It also doesn't require consuming a bloated corpse like the JVM languages.

Its package management left a lot to be desired last time I used it, but it was supposed to be fixed at some ambiguous time in the future which may have already happened.

Due to the positives, people often use it for things it's real bad at. It is missing language features that are very useful for certain types of applications, but it's mostly intentional to make the language better at what it's good at. It's a current-gen tool for a specific type of program and a drat good one.

Can't quote this hard enough.

Adbot
ADBOT LOVES YOU

luchadornado
Oct 7, 2004

A boombox is not a toy!

I personally disagree with the "web services" part unless you're only responsible for a small API footprint. Serialization/deserialization feels tedious to me for a few reasons, and web services are one of the best places to lean heavily on functional programming ideas and patterns since the whole request/response pipeline is essentially a mapreduce.

edit: Golang would be a lot more fun for me on certain things if there was an equivalent of JS's lodash library, or even better, Kotlin+arrow. Is there such a thing?

luchadornado fucked around with this message at 17:14 on Aug 12, 2018

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