this post was submitted on 19 Jun 2025
87 points (86.0% liked)

Programmer Humor

36811 readers
128 users here now

Post funny things about programming here! (Or just rant about your favourite programming language.)

Rules:

founded 5 years ago
MODERATORS
 

Made with KolourPaint and screenshots from Kate (with the GitHub theme).

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 3 points 1 week ago* (last edited 1 week ago) (7 children)

Go's syntax is vastly superior once you have more complicated signatures, then the left-to-right truly matters. For example a variable that contains a pointer to a function that takes a function and an int and returns another function (like a decorator).

In C the order becomes very hard to understand and you really have to read the thing several times to understand the type of fp:

int (*(*fp)(int (*)(int, int), int))(int, int)

In Go, you can just read from left to right and you can easily understand what f's type is:

f func(func(int,int) int, int) func(int, int) int

It's just much more readable.

See: https://go.dev/blog/declaration-syntax

[–] phlegmy 3 points 1 week ago (4 children)

If you actually use code like this you're insane.

[–] [email protected] 4 points 1 week ago* (last edited 1 week ago) (2 children)

This obviously just illustrates a point, but callbacks and decorators are not uncommon. And iterators are exactly like that:

type (
	Seq[V any]     func(yield func(V) bool)
	Seq2[K, V any] func(yield func(K, V) bool)
)

Which is very readable.

[–] phlegmy 4 points 1 week ago (1 children)

Callbacks and decorators are fine, but callbacks/decorators to a function which itself takes a function pointer and returns another function pointer are crazy.

I've thankfully never had to use recursive callbacks or decorators, but it seems like it could very quickly become difficult to keep track of.

[–] [email protected] 3 points 1 week ago* (last edited 1 week ago)

I don't think it's that uncommon. Let's say you have a function that handles a request. A common use case is to add permission checks before applying that function. You can write a generic permission check a bit like this:

func NeedsPermission(f func(Request) (Response, error), perm string) func(Request) (Response, error) {
    return func(r Request) (Response, error) {
        if !check(r, perm) {
            return nil, NewPermError(perm)
        }
        return f(r)
    }
}

// elsewhere
Bar := NeedsPermission(Foo, "superman")

This would allow you to separate the permission check logic from the business logic. Though to be fair, in Go they prefer to keep things as simple as possible but it's just to illustrate that these concepts are not that alien.

load more comments (1 replies)
load more comments (3 replies)