4 ms·
> func (o Option[T]) Map[U any](f func(a T) U) Option[U] { ... } This is totally opinionated, but I better not see code like this on a review. Is there a way t
by SergeAx 5y ago
> func (o Option[T]) Map[U any](f func(a T) U) Option[U] { ... }
This is totally opinionated, but I better not see code like this on a review. Is there a way to make it a bit more readable and a bit less like Perl?
- chrismorgan 5y agoIt only looks messy. It’s not particularly difficult to read, and with what it’s expressing there’s really no way of expressing it in shorter terms. “A method on an Option[T] named Map, generic over type U, taking one argument, a function from a T to a U, and returning an Option[U].” Mind you, I wouldn’t mind colons and arrows as separators which I think make it easier to read; here’s what it’d look like in a somewhat more Rust-like syntax: fn Map<U: any>(self: Option<T>, f: fn(a: T) -> U) -> Option<U> { ... } I would also note that signatures like these are mostly found in foundational types; they take a bit more effort and practice to write, but you don’t often have to do so; and have the outcome that the API is more pleasant to use—no more interface objects and downcasting everywhere, in Go terms.
- SergeAx 5y agoI got your point, and it's worth mentioning that there's that rare moment when Rust looks more readable than Go. Concerning resulting API: isn't code generation solves a problem with interface objects and downcasting?
- chrismorgan 5y agoI’m not sure what you’re asking. Generics are code generation (look into the term monomorphisation), just automatic and managed by the compiler for better convenience than manual code generation by other means, and type safe for better correctness and efficiency than interface objects and downcasting.
- newusertoday 5y agoThank you, i wasn't able to decipher the syntax until i read your comment “A method on an Option[T] named Map, generic over type U, taking one argument, a function from a T to a U, and returning an Option[U].”
- olliej 5y agoI’d argue a lot of the ugliness of this is a product of the basic syntax of genetics in go. The syntax in other languages with generics (C#, Swift, Java, and even c++) for this construct is easy to read. And obviously there’s always Haskell where you often don’t need explicit type annotations at all :D
- deleted 5y ago[deleted]
- EdwardDiego 5y agoI guess in Java, it'd look something like this: public class JavaOption<T> { public <U> JavaOption<U> map(Function<T, U> func) { //todo } } Kotlin might be a closer match in semantics if I use an extension function: fun <T, U> Optional<T>.map(func: (T) -> U): Optional<U> { // todo }
- lenkite 5y agoWhat's un-readable about this ? I haven't even read the article but I can understand this. Probably because of prior experience in C++, Java. But it seems sweet and succint. At the max, one can make a couple of type-aliases for a bit more legibility, but that's all one can squeeze.
- SergeAx 5y agoI want to mention that Go doesn't have a ternary operator, because it is "used too often to create impenetrably complex expressions"[1] [1] https://go.dev/doc/faq#Does_Go_have_a_ternary_form https://go.dev/doc/faq#Does_Go_have_a_ternary_form