I’ve updated The Two-phase Data Load and Render Pattern in Go after Roman pointed out that if we swap the position of two generic parameters in Render
, another generic parameter can be inferred, and every invocation gets considerably cleaner.
Previously, Render
looked like this:
func Render[TLoadBundle any, TRenderable Renderable[TLoadBundle, TModel, TRenderable], TModel any](
ctx context.Context, e db.Executor, baseParams *pbaseparam.BaseParams, model TModel,
) (TRenderable, error)
And was invoked like:
resource, err := apiresource.Render[*apiresourcekind.ProductLoadBundle, *apiresourcekind.Product](
ctx, tx, svc.BaseParams, product
)
In the updated version, the positions of the first two generic parameters are swapped:
func Render[TRenderable Renderable[TLoadBundle, TModel, TRenderable], TLoadBundle any, TModel any](
ctx context.Context, e db.Executor, baseParams *pbaseparam.BaseParams, model TModel,
) (TRenderable, error) {
And the function can now be invoked like this:
resource, err := apiresource.Render[*apiresourcekind.Product](
ctx, tx, svc.BaseParams, product
)
Much cleaner. A caller no longer even needs to know that the load bundle exists. At work I applied the fix to our hundreds of lines of existing calls, and the difference in readability is night and day.