From Go to Rust or Template Hell

Go introduced templates and lost one of its main advantages: easy readability.

I gave a simple example:

package main
import "fmt"

type MyObj[T int] struct{ a T }
type MyObj2[T MyObj[E], E int] struct{ b T }
type MyObj3[T MyObj2[A, E], A MyObj[E], E int] struct{ с T }
type MyObj4[T MyObj3[B, A, E], B MyObj2[A, E], A MyObj[E], E int] struct{ d T }

func main() {
	my := MyObj[int]{a: 10}
	my2 := MyObj2[MyObj[int], int]{b: my}
	my3 := MyObj3[MyObj2[MyObj[int], int], MyObj[int], int]{с: my2}
	my4 := MyObj4[MyObj3[MyObj2[MyObj[int], int], MyObj[int], int], MyObj2[MyObj[int], int], MyObj[int], int]{d: my3}

	fmt.Println("Data: ", my, my2, my3, my4)
}

But in real projects with a bunch of libraries there will be huge lines indicating template parameters. We are no longer talking about easy readability, but here we just want to say that MyObj4.d contains a value of type MyObj3.

How did you manage without templates in Go for 13 years? This didn’t stop us from releasing great libraries and making a good standard library! At the same time, the laconicism and lightness of the language were preserved. And now…

Rust and Go have a lot in common: the absence of classes, interfaces/traits, the principle of error handling, etc. GC aside, Rust seems to be an improved version of Go. Rust gives you a lot more power and flexibility, but comes at a cost in terms of ownership and lifetime that you have to think about. You can also start writing in Go style in Rust, but libraries spoil everything. Go, it seems to me, has excellent core libraries (Gin, Fiber, GORM, etc.) with excellent documentation from which it is immediately clear how to use + due to the easy readability of the language, you can quickly look at the IDE sources of the desired function. And also a standard library that covers almost any need. The interface of all frameworks is very similar and you can quickly change one library to another.

Not so in Rust. The principle here is that there is a very small stdlib, and all additional features should be written by the community, which is why frameworks like Tokio appear. The disadvantage of this approach is that there is no single standard (as in Go) and everyone creates an API at their own discretion (it turns out to be a kind of Python). The documentation is worse than Go, often just method signatures and a couple of examples, without a description of what and how. And also macros. This all adds a lot of complexity at the initial stage of choosing a stack, but once you understand the frameworks and libraries, writing becomes faster and less complex than in Go. (at least due to different error handling, which is why I started looking at Rust instead of Go)

So about the templates. I needed to use ORM in Rust so that when running on the local PC, sqlite would be used, and on the server postgre. And this turned out to be a problem in Rust libraries. To make, for example, a generalized function for sqlx, you need to describe a footcloth from the template parameters, moreover, this is not obvious and you need to spend a long time trying to figure out what is where register. But in Go, for example, there is GORM, which does this without any templates. It turns out that templates complicate the code, but at the same time they are not needed to implement the functionality.

Here is an example of a type from Rust (it’s clear what type it is the first time? sarcasm ):

SelectStatement<FromClause<schema::users::table>, 
diesel::query_builder::select_clause::SelectClause<diesel::expression::select_by::SelectBy<User, _>>, 
diesel::query_builder::distinct_clause::NoDistinctClause, 
diesel::query_builder::where_clause::WhereClause<diesel::expression::grouped::Grouped<diesel::expression::operators::Eq<schema::users::columns::username, 
schema::users::columns::username>>>, diesel::query_builder::order_clause::NoOrderClause, 
LimitOffsetClause<LimitClause<diesel::expression::bound::Bound<BigInt, i64>>, 
NoOffsetClause>>

And this is what Go with templates will become…

Since Go code will now look like Rust, why continue to use Go?
It turns out only because of employers, because… the market requires a lot of Go programmers and not Rust.?

What do you think about generics (templates). Is this good or bad for development?

Note: I am not an expert in Go and Rust and therefore I may be wrong in some points

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *