News for hackers. Stuff that matters.
Re:Go 1.27 Interactive Tour by baalimago on Sunday August 02, 2026 @03:01AM (#49141859)
This: "(b Box[T]) Map[U any](f func(T) U) Box[U]" is the type of cognitive weight I was happy that Go avoided.
Re:Go 1.27 Interactive Tour by twsted on Sunday August 02, 2026 @04:16AM (#49142241)
I really understand your feeling, I escaped from C++ years ago when I was overwhelmed by meta programming (initially i loved it).

But anyway I find this in Go much more bearable.

Re:Go 1.27 Interactive Tour by zerr on Sunday August 02, 2026 @11:05AM (#49145323)
As a C++ (including modern) developer for more than 20 years, I had written a "template" keyword only for a handful of times. Maybe once in every 5 years on average... :)

Unless you are a compiler/stdlib vendor or contributing to Boost, there are features that you just don't use it daily.

Re:Go 1.27 Interactive Tour by majewsky on Monday August 03, 2026 @05:13AM (#49153194)
But you would still have to deal with the mental load associated with having templates in your stack. I don't know if C++ is still as bad as it was back in my day about vomiting 20-line error messages at you because "std::vector<std::string>" or something has a billion implied template arguments. That was definitely a cost that one had to bear even if one never used the "template" keyword.
Re:Go 1.27 Interactive Tour by zerr on Monday August 03, 2026 @06:22AM (#49153769)
Ah, yes, it is much better now!
Re:Go 1.27 Interactive Tour by kitd on Sunday August 02, 2026 @04:15AM (#49142235)
It looks more reasonable (literally lol) with syntax highlighting though.
Re:Go 1.27 Interactive Tour by fooooor on Sunday August 02, 2026 @10:58AM (#49145268)
Luddites don’t use syntax highlighting though.
Re:Go 1.27 Interactive Tour by adrianmsmith on Sunday August 02, 2026 @03:33AM (#49142010)
I never understood the convention of using single letter names for generic parameters. I guess this started in C++ and every language has copied that convention.

I think that code would be a lot easier to read if the types were called IN and OUT or In and Out or TIn and TOut or something like that.

Re:Go 1.27 Interactive Tour by spockz on Sunday August 02, 2026 @04:04AM (#49142159)
Completely agree and I personally name generic type parameters as I would name types and parameters. It helps a lot.
Re:Go 1.27 Interactive Tour by jiehong on Sunday August 02, 2026 @03:52AM (#49142109)
We all know letters are expensive ^^
Re:Go 1.27 Interactive Tour by phplovesong on Sunday August 02, 2026 @04:02AM (#49142155)
Im pretty sure it came from the MLs, where you usually have a/b/c instrad of the T,U etc combo.

I dont find it confusing, as its pretty clear that it only an placeholder.

In generics the name usually does not matter or is REALLY hard to name so that it makes sense.

More specifically in Go where you have interfaces, concrete types and generics.

Re:Go 1.27 Interactive Tour by asQuirreL on Sunday August 02, 2026 @04:36AM (#49142359)
Fairly sure it would predate even that, and go all the way to lambda calculus, and predicate logic before that, and that's where my knowledge stops and somebody else can tell us where the current conventions around variables in logic and mathematics come from.
Re:Go 1.27 Interactive Tour by teh64 on Sunday August 02, 2026 @06:37AM (#49143120)
In ocaml (and I assume SML) it helps that the generic types have a `'` before them, so

    val map : ('a Box) -> ('a -> 'b) -> 'b Box
Re:Go 1.27 Interactive Tour by Someone on Sunday August 02, 2026 @04:46AM (#49142444)
For maps, a convention is to use K and V for key, respectively Value.

I think that’s best as you’ll soon learn the “single-character capital letter ⇒ generic parameter” convention

Re:Go 1.27 Interactive Tour by Laurel1234 on Sunday August 02, 2026 @05:15AM (#49142620)
In C# this is the convention.
Re:Go 1.27 Interactive Tour by eterm on Sunday August 02, 2026 @09:33AM (#49144560)
It's a mix, because some stuff tends to just use `T`, but there's better descriptors elsewhere.

There's IList<T> but Task<TResult>

There's Action<T1, T2, T3, T4, T5, T6> but also Dictionary<TKey, TValue> and Map<TIn, TOut>

This stuff kind of "makes sense" once you're used to it, because it's difficult to say what IList<T> ought to have been called otherwise, IList<TContainee> is a mouthful, and Action<T1,...> simply suffers from the inability to specify an unknown number of generic parameters.

https://learn.microsoft.com/en-us/dotnet/api/system.collecti...

https://learn.microsoft.com/en-us/dotnet/api/system.action-2...

https://learn.microsoft.com/en-us/dotnet/api/system.collecti...

Re:Go 1.27 Interactive Tour by setopt on Sunday August 02, 2026 @05:25AM (#49142671)
I believe Haskell did that for decades before C++.
Re:Go 1.27 Interactive Tour by logicchains on Sunday August 02, 2026 @06:09AM (#49142938)
Haskell was created in 1990, five years after C++.
Re:Go 1.27 Interactive Tour by hnlmorg on Sunday August 02, 2026 @06:25AM (#49143054)
Haskell had generics from the beginning. Whereas C++ only added templates to its specification in 1998.
Re:Go 1.27 Interactive Tour by jahnu on Sunday August 02, 2026 @10:03AM (#49144820)
I was using the STL in 1994 with Zortech C++
Re:Go 1.27 Interactive Tour by zerr on Sunday August 02, 2026 @10:57AM (#49145252)
Miranda had it since its release in 1985.
Re:Go 1.27 Interactive Tour by toinebeg on Sunday August 02, 2026 @05:58AM (#49142857)
I often use whole word for type annotation, when I can find meaningfull ones. I just type them in all caps to stay close to the convention.

I guess the single letter thing is laziness for a part. It's not simple to find words that represent the abstract idea behind the generic type without narrowing the possibilities. For array function, the Key Value from the sibling comment work but for more complex use case, it get complicated.

Re:Go 1.27 Interactive Tour by wwalexander on Sunday August 02, 2026 @07:21AM (#49143396)
Swift generics tend to idiomatically use longer names, like Element or View or Content.
Re:Go 1.27 Interactive Tour by girvo on Sunday August 02, 2026 @07:49AM (#49143589)
I’ve always done that in my typescript code bases too, and I’ve never regretted it
Re:Go 1.27 Interactive Tour by fooooor on Sunday August 02, 2026 @10:50AM (#49145192)
Lambdas usually have short variable names because the scope is small, typically half a line. And that is fine, even optimal.
Re:Go 1.27 Interactive Tour by fooooor on Sunday August 02, 2026 @10:40AM (#49145107)
What could be more idiomatic than:

for (int i=0; i<10; i++) { printf(”%d\n”, i); }

(Or the very similar Go equivalent)

If you having a hard time parsing that, due to the short variable name, i.e. if it’s a huge cognitive load for you, I suggest you switch career, b/c the IT industry is obviously not a good fit.

With that said, Go is explicit with suggesting short variable names for small scopes, and long variable names for bigger scopes. This a good practice in all languages.

Re:Go 1.27 Interactive Tour by majewsky on Monday August 03, 2026 @05:03AM (#49153106)
I'm not necessarily disagreeing, but I'm following the single-letter convention because "TIn" or "InputType" looks too much like an exported symbol. Whenever I tried to write type arguments like that, this threw me off, so I reverted to single letters.
Re:Go 1.27 Interactive Tour by fauigerzigerk on Sunday August 02, 2026 @04:32AM (#49142333)
It's hard to avoid, because (naming aside) the cognitive load is caused by higher order functions, which are hard avoid without causing massive code duplication.

I understand the desire to keep things concrete and avoid high level abstractions, but it's a decision not to automate stuff that can easily be automated. It runs counter to the basic instincts and purpose of our field/industry. That's why it never sticks.

Re:Go 1.27 Interactive Tour by hnlmorg on Sunday August 02, 2026 @06:18AM (#49143002)
Honestly, I’ve written some applications that, on paper, should be the perfect candidate for generics. And yet I can still count on one hand the number of times generics have saved me from massive code duplication.

Most of the time generics might be useful, I’ve ended up needing reflection too anyway. And at that point, I’m really no better off for generics.

Re:Go 1.27 Interactive Tour by fauigerzigerk on Sunday August 02, 2026 @06:36AM (#49143119)
I understand that this is true for a lot of application code. It's not true for library authors though, and every language needs libraries.
Re:Go 1.27 Interactive Tour by hnlmorg on Sunday August 02, 2026 @07:45AM (#49143556)
I’ve written a lot of libraries too.

The problem is generics only solve a very small part of the equation: compile time checks for composite types. But to use composite types in anything non-trivial in Go, you then need reflection. Which is slow. And if you then need reflection, you’re already passing interface types anyway plus you’re back to having to handle type-handling errors in the runtime.

So if you’re writing a library that’s expected to have any kind of performance, you’re back to code duplication and having a DoSomethingType() function signatures again.

Or you stick with reflection and take that performance hit PLUS the risk of compile time constraints being runtime errors; which is the a lose-lose scenario. And let’s also not forget that reflection can be just as verbose as code duplication, and harder to get right too.

Don’t get me wrong, I’m glad we have generics. But people on HN massively overstate the value of them in a AOT non-dynamic, strictly typed language like Go.

I guess you could argue that Go has other shortcomings that directly result in generics having limited value. But then you’re basically just arguing that you prefer coding in a different language paradigm, and at that point, you’re much better off using that other paradigm instead of complaining that Go isn’t JavaScript or Haskell.

Re:Go 1.27 Interactive Tour by pezo1919 on Sunday August 02, 2026 @10:52AM (#49145215)
Thanks for that, nicely put, interesting angle.
Re:Go 1.27 Interactive Tour by theptip on Sunday August 02, 2026 @11:21AM (#49145438)
Interesting, thanks - is the problem you’re describing solved by Rust’s macros (eg derive) or are there further issues you see even there?
Re:Go 1.27 Interactive Tour by kccqzy on Sunday August 02, 2026 @04:17PM (#49147897)
Yes it is precisely Go’s shortcomings that would require typical use of generics to also require reflection most of the time. You would want Rust traits (or Haskell type classes) or C++ style type traits and then the need for reflection is much reduced. So Go has painted itself into a corner where generics feel bolted on and less useful than generics in other languages. It’s still Go’s fault and people rightfully argue that they should prefer a different language.

The Go language itself is never its strength but it has a good runtime, wonderful standard library and tooling. People never picked Go for being an amazing language, but rather for these other things.

Re:Go 1.27 Interactive Tour by hnlmorg on Monday August 03, 2026 @04:07AM (#49152661)
I picked Go for the language, so your argument is incorrect.

Go’s shortcoming is also its strength. Language design is a constant battle of tradeoffs. And I happen to find many of the decisions C++ and Rust made weren’t analogous with my preferences.

> It’s still Go’s fault and people rightfully argue that they should prefer a different language.

It’s no more Gos fault than it is the people using Go. It’s called an “opinion” and “preference”. Please don’t assuming your preference is some global truth, because it is not.

Re:Go 1.27 Interactive Tour by foldr on Monday August 03, 2026 @10:10AM (#49156027)
>You would want Rust traits

Go generics does have this feature. You can require a generic type to implement an interface.

Re:Go 1.27 Interactive Tour by kccqzy on Monday August 03, 2026 @03:09PM (#49160110)
Requiring the implementation of a Go interface is less powerful than requiring a trait.

It reminded me of early years of Rust where people saw traits and asked, well Java had interfaces for many decades, what’s the innovation?

Re:Go 1.27 Interactive Tour by foldr on Monday August 03, 2026 @04:58PM (#49161363)
I'm not sure you can really argue that Rust's traits are innovative. Haskell typeclasses, OO-style abstract interfaces, and C++-style associated types were already well-known and well-established features. The particular mix of those features in Rust may be new, but the same could be said for Go's, or really any programming language's, particular mix of features.

You're right of course that traits are more powerful than interfaces. Go simply isn't designed to satisfy fans of elaborate type systems. This can be frustrating at times, but it also means that you don't have to deal with overarchitected library code like this: https://github.com/marshallpierce/rust-base64/issues/213 (Yes, you can overarchitect code in Go too, but the simplicity of the language, and the model of the stdlib, do tend to discourage this in practice.)

I've never written Rust professionally, but I did have a Haskell job for a couple of years. IME the sophistication of the type system is a double-edged sword. Sometimes it lets you concisely express important invariants; sometimes you end up spending way too much time writing elaborate types for code that isn't really doing anything very interesting. I understand the appeal of fancy type systems. In practice, I get a productivity boost from any kind of basic static typing, and then rapidly diminishing returns from the fancier stuff.

Re:Go 1.27 Interactive Tour by preg_match on Sunday August 02, 2026 @03:26PM (#49147495)
Generics are supremely useful for containers. They are kind of one trick ponies in that sense in application code. Similar to reflection, I’d say, which is utilized for serialization 99% of the time.

The thing is that one use case is so essential, so foundational, that we really can’t just skip it. You need generic containers, for ergonomics and performance. I mean, compare C qsort to C++ std::sort.

The languages that “get around” generics, like PHP, include god containers in the runtime. The language I’m designing is also that way, I’d like to avoid generics preferably forever.

But there’s a tradeoff there. God containers are very flexible, and we’ve seen the ramifications of untyped PHP arrays.

Re:Go 1.27 Interactive Tour by Pay08 on Sunday August 02, 2026 @04:38AM (#49142382)
Lisp manages it. Even if you do use type annotations.
Re:Go 1.27 Interactive Tour by fauigerzigerk on Sunday August 02, 2026 @04:45AM (#49142426)
No. This cognitive load is conceptual. You can't avoid it by using slightly different syntax.
Re:Go 1.27 Interactive Tour by stingraycharles on Sunday August 02, 2026 @10:52AM (#49145211)
I think the problem is that the Box / Map / any stuff and all the explicit declarations that Go requires makes it harder.

In Haskell as well, you can let the compiler infer a lot of things but that doesn’t appear to be the case with this example.

I’d want the compiler to infer things, but that - I think - is at odds with Go desiring a fast compiler, which I also understand.

Re:Go 1.27 Interactive Tour by Pay08 on Sunday August 02, 2026 @12:29PM (#49145960)
I was about to mention Haskell as well, I feel like it also avoids this sort of cognitive load. Maybe it's something to do with the languages being designed as functional languages instead of languages with functional components.
Re:Go 1.27 Interactive Tour by dvdkon on Sunday August 02, 2026 @04:54AM (#49142497)
Maybe it's just familiarity, but I think it would look a lot more comprehensible with some punctuation. Just because a syntax is formally unambiguous doesn't mean it looks that way to humans.

    func (b: Box[T]).Map[U: any](f: func(T) -> U) -> Box[U]
Re:Go 1.27 Interactive Tour by scotty79 on Sunday August 02, 2026 @06:14AM (#49142972)
> (b Box[T]) Map[U any](f func(T) U) Box[U]

  Map method 
    of b (of type Box[T]) 
      that takes f 
      (of type function that takes value of type T and returns value of type U (which could be any type))
      and returns value of type Box[U]
  is defined as follows
    return Box[U]{v: f(b.v)}

  func[U any] b:Box[T].Map(f:func(T)->U)->Box[U]:
    return {v: f(b.v)}

  func[U any] Box[T].Map(f:func(T)->U)->Box[U]:
    return {v: f(this.v)}

  // maybe all of the types could be inferred from usage?
  func Box[].Map(f):
    return Box[]{v: f(this.v)}
Eh... I think you'd need to avoid generics altogether.
Re:Go 1.27 Interactive Tour by inigyou on Sunday August 02, 2026 @10:20AM (#49144968)
that's literally what Go was supposed to do! If I want a language like C++, I know where to find a language like C++ (it's C++).
Re:Go 1.27 Interactive Tour by wannabe44 on Sunday August 02, 2026 @12:36PM (#49146010)
Map/Filter/Reduce is a bad example for an imperative language. But look at slices and maps packages, or the new proposal for container types. There are many good examples how generics are like salt to food. Another example is errors.AsType.
Re:Go 1.27 Interactive Tour by teh64 on Sunday August 02, 2026 @06:31AM (#49143088)
I think naming conventions might help:

    (b Box[InType]) Map[OutType any](transformFunction func(InType) OutType) Box[OutType]
Same in Python:

    def map[U](self, f: Callable[[T], U]) -> Box[U]
vs

    def map[OutType](self, transform_function: Callable[[InType], OutType]) -> Box[OutType]
and Java:

    public <OutType> Box<OutType> map(Function<InType, OutType> transformFunction)
vs.

    public <U> Box<U> map(Function<T, U> f)
Re:Go 1.27 Interactive Tour by mseepgood on Sunday August 02, 2026 @07:46AM (#49143564)
It's not good Go code anyway. In Go you would use a for loop. Just because Go has generics nowadays doesn't mean you should abandon good taste and write ML/Haskell/Rust/C# in it.
Re:Go 1.27 Interactive Tour by wannabe44 on Sunday August 02, 2026 @12:35PM (#49146003)
Sure it's a bad example. But you can't simplify something like this without losing type safety:

    SortBy[T, K comparable](slice: []T, key: func (T) K)
Re:Go 1.27 Interactive Tour by HumblyTossed on Sunday August 02, 2026 @09:16AM (#49144411)
Right? Sigh. I really dislike this.

There are 37000 programming languages, stop forcing every single one that gets popular to look like this.

Re:Go 1.27 Interactive Tour by majewsky on Monday August 03, 2026 @05:14AM (#49153204)
It's almost as if the choices that make languages "look like this" are the ones that are generally associated with a more productive development workflow.
Re:Go 1.27 Interactive Tour by HumblyTossed on Monday August 03, 2026 @02:55PM (#49159948)
Actually no. It’s dev FOMO. A tremendous amount of go has been written without all this. Go has just gotten more popular so devs want to make it into something they’ve used before instead of learning to use the language the way it is.
Re:Go 1.27 Interactive Tour by JyB on Friday August 07, 2026 @05:53AM (#49208059)
That's funny because that's factually untrue. Go's early popularity and professional adoption were largely driven by its perceived productivity boost linked in part to the small surface area of its spec, long before this subpar generic implementation was forced into it.
Re:Go 1.27 Interactive Tour by zerr on Sunday August 02, 2026 @09:49AM (#49144691)
We often forget that our profession (computer programming) belongs to STEM. Some (like Go 1.0 :)) wish to think it is Arts & Humanities. The sooner we realize that yes, it is OK and actually expected to bear a cognitive weight of "(b Box[T]) Map[U any](f func(T) U) Box[U]" the sooner we get back to reality... :)
Re:Go 1.27 Interactive Tour by red_admiral on Sunday August 02, 2026 @10:11AM (#49144888)
Just because we can, doesn't mean we have to. I'd prefer to have some more brain-cache free to concentrate on the problem I'm trying to debug rather than doing type resolution in my head.
Re:Go 1.27 Interactive Tour by yladiz on Sunday August 02, 2026 @11:05AM (#49145316)
Please. I’m sorry, but you kind of can’t avoid needing to think about types unless you use a language like JavaScript which is super loose with its type conversions, and you especially can’t avoid in a language like Go. With generics in Go you don’t even need to prefill the types like you go with a lot of other cases, so I’m dubious about the cognitive overhead.
Re:Go 1.27 Interactive Tour by kfuse on Sunday August 02, 2026 @02:07PM (#49146826)
No need to insult JavaScript. In two out of three times the "JavaScript" written will be something like:

    interface Box<T> { value: T }

    function map<T, U>(input: Box<T>, func: (value: T) => U): Box<U> {
        return { value: func(input.value) }
    }
Re:Go 1.27 Interactive Tour by thebytefairy on Sunday August 02, 2026 @10:08AM (#49144867)
People should stop using these simplified high level programming languages with low cognitive weight, like Go. I only write assembly. ;)
Re:Go 1.27 Interactive Tour by 4ndrewl on Sunday August 02, 2026 @10:40AM (#49145105)
(b Box[T]) Map[U any](f func(T) U) Box[U] _is_ for the Arts and Humanities.

Unless you're writing assembler in vim you're not STEM.

Re:Go 1.27 Interactive Tour by fragmede on Sunday August 02, 2026 @10:46AM (#49145151)
Why should I, as fallible human of limited short and long term memory, bear that cognitive weight when I have a perfectly good compiler on a computer to offload that particular cognitive weight to?
Re:Go 1.27 Interactive Tour by wannabe44 on Sunday August 02, 2026 @12:33PM (#49145985)
In terms of tooling, Go is one of the few languages which remembers that we are in STEM.
Re:Go 1.27 Interactive Tour by SubjectToChange on Monday August 03, 2026 @04:32AM (#49152861)
I’m not sure if you are complementing or denigrating golang’s tooling. Most “STEM software” packages are horrendous in terms of user/developer experience, to the point of hampering their utility. For instance, MPI really reminds HPC users that we are in “STEM”, but not for a good reason.

Golang has good “implementation level” tooling, but that is still nothing when compared to tooling available to Java and C#. Even if GoLand is closing the gap on the IDE front (idk, I haven’t tried it), golang simply doesn’t offer the features found in OpenJDK or Dotnet (GC parameters/implementations, profiling/introspection data, interoperability/ffi, etc.). It just feels like golang’s tooling looks good when it’s competing against python, ruby, or JS/TS.

Re:Go 1.27 Interactive Tour by wannabe44 on Tuesday August 04, 2026 @12:34AM (#49164390)
Native compilation which is fast enough, green threads, AST and analysis framework, in-built testing and profiling, call graphs, rewrite tooling (go fix), go.work and modules which are far better than maven / gradle mess. There's a good amount of rigour applied to Go tooling that it "just works", even as horrendous the language is.

I agree java is good too, except spring boot manages to undo all the engineering that has gone to Java.

Re:Go 1.27 Interactive Tour by snsjjsjjs on Sunday August 02, 2026 @02:30PM (#49147032)
I wish it was arts & humanities.. those are some actually clever folks.
Re:Go 1.27 Interactive Tour by sirsinsalot on Sunday August 02, 2026 @04:34PM (#49148055)
Programming language evolution has always been the pursuit of abstractions that enable expressiveness and simplicity.

Your comment boils down to "I'm smart", which in the end, isn't terribly smart.

Having simplicity and expressiveness as a goal, and a general direction of achieving things through lazy means is at the heart of mathematics and engineering.

Celebrate laziness and a want for simplicity. True simplicity is hard, but worth going after even where it threatens the notion that you're the smartest person in the room.

Re:Go 1.27 Interactive Tour by SubjectToChange on Monday August 03, 2026 @03:26AM (#49152349)
>Your comment boils down to "I'm smart", which in the end, isn't terribly smart.

They are saying that a programmer should be able to cope with the cognitive dissonance of not immediately understanding something.

>Celebrate laziness and a want for simplicity.

Concepts like generics might be intellectually more challenging, but they are clearly the “lazy” approach for actually writing code. Writing and maintaining multiple versions of the same function, or using code generation, is intellectual lazy but manually intensive.

Re:Go 1.27 Interactive Tour by peterashford on Monday August 03, 2026 @11:10PM (#49164005)
I don't think that comment was necessary. What do you gain by denigrating the Arts?
Re:Go 1.27 Interactive Tour by red_admiral on Sunday August 02, 2026 @10:08AM (#49144868)
Indeed, we're now one step away from monads. I know https://go.dev/doc/effective_go hasn't been updated for while, but it also seems to have been forgotten. "Go is an open-source programming language that focuses on simplicity ..." the page begins.
Re:Go 1.27 Interactive Tour by treyd on Sunday August 02, 2026 @10:21AM (#49144970)
You've already been able to badly implement monads in Go for 10+ years. Why wouldn't you be able to implement them in a way that the compiler can enforce correctness of?

If you don't want it don't use it. It's that simple.

Re:Go 1.27 Interactive Tour by fooooor on Sunday August 02, 2026 @10:57AM (#49145258)
No it’s definitely not that simple. Code are read more often than written, no one works in a vacuum, especially not in open source. Also, when in Rome...
Re:Go 1.27 Interactive Tour by golem14 on Sunday August 02, 2026 @11:17AM (#49145401)
If a project's owner feels that strongly about not using generics, that's a choice. No dependencies using generics, no generics allowed in PRs etc. Perfectly doable.

Also, screw those Romans ;)

Re:Go 1.27 Interactive Tour by inigyou on Sunday August 02, 2026 @10:16AM (#49144930)
Apparently the people responsible for the simplicity retired. Since it's Google, some new people want to be promoted for adding features to Go.
Re:Go 1.27 Interactive Tour by skywhopper on Sunday August 02, 2026 @11:01AM (#49145289)
Is it worse than having to create endless functions for each type pair?

    (b IntBox) MapToStringBox(f func(int) string) StringBox
    (b IntBox) MapToBoolBox(f func(int) bool) BoolBox
    (b StringBox) MapToIntBox(f func(string) int) IntBox
Etc etc etc?

The T, U, and f names are the cognitive load here, because they are meaningless variables. For a specific solution, those would have meaningful names that would make it easier to understand.