News for hackers. Stuff that matters.
Re:From Java to Go, and Back Again (2016) by daenz on Saturday June 23, 2018 @01:55PM (#17382417)
>Go’s lack of generics means that you have to write mapStringToString as a mapper between collections of two fixed types – you can’t write a generic map from an array of T to an array of R, as you can in almost any other strongly-typed modern language.

That's not true. Here's their example written to be more generic:

  func mapThingToThing(inSlice interface{}, mapperFn interface{}) []interface{} {
  	mapper := reflect.ValueOf(mapperFn)
  	input := reflect.ValueOf(inSlice)
  	output := make([]interface{}, input.Len())
  	for i := 0; i < input.Len(); i++ {
  		item := input.Index(i)
  		output[i] = mapper.Call([]reflect.Value{item})[0]
  	}
  	return output
  }
and calling:

  fn := func(item string) string {
  	return item + "!"
  }
  res := mapThingToThing([]string{"a", "b", "c"}, fn)
  for _, item := range res {
  	fmt.Printf("item = %+v\n", item)
  }
I didn't say it was pretty or good, but it can be done. Really confused by the downvotes.
Re:From Java to Go, and Back Again (2016) by stephen on Saturday June 23, 2018 @02:53PM (#17382759)
> Really confused by the downvotes

It's not type safe. Any other modern/static language would use generics to ensure inSlice and mapperFn both operate on the same types.

People downvoting you probably see this as obvious for programmers that want/choose a static language like Go/Java/TypeScript/etc.

Re:From Java to Go, and Back Again (2016) by daenz on Saturday June 23, 2018 @03:06PM (#17382819)
>It's not type safe.

Yes, I get that, but that's also moving the goalpost. The post claimed that "you can’t write a generic map from an array of T to an array of R", but you can (if you take generic to mean "general" and not "specifically using the mechanism of generics").

I think the author just didn't know that this was possible, or his concern would have been about the lack of type safety with the reflection method.

Re:From Java to Go, and Back Again (2016) by nostalgeek on Saturday June 23, 2018 @03:12PM (#17382860)
> Yes, I get that, but that's also moving the goalpost.

no it is not. The whole point of generic programming is compile time type safety for incomplete types.

> but you can (if you take generic to mean "general" and not "specifically using the mechanism of generics").

not in a compile time type safe way. Again, you can't negate the whole point of generics, that's a cop-out. You just wrote Python like dynamic code in Go here, with reflection (AKA runtime behavior) which incures a severe performance penalty.

And let's not get started on the fact that you're returning []interface{} which is often pretty useless when the type of the element matters. You introduced some serious code smell with that function since you threw away type safety.

If you really want to write a generic mapper the only serious way to do that in go is to use reflect.MakeFunc then a function variable of the choosen signature. But again reflection is so slow it's not even worth to begin with.

Re:From Java to Go, and Back Again (2016) by daenz on Saturday June 23, 2018 @03:17PM (#17382881)
>no it is not. The whole point of generic programming is compile time type safety for incomplete types.

Except that's not what the post's gripe was about. His gripe was that you need to write a new function for every type you want to map, because there's no way to write one that is generic for all types. He doesn't mention type safety at all, so yes, the solution I posted meets the goal of his complaint.

>And let's not get started on the fact that you're returning []interface{} which is often pretty useless when the type of the element matters. You introduced some serious code smell with that function since you threw away type safety.

Did you miss the point where I said "it's not good or pretty" ? Or do you just want to bitch about everything? Your whole post reads like someone who has never written a container type in Go. Guess how you do it? You use interface{} and cast in the caller!

Re:From Java to Go, and Back Again (2016) by dang on Saturday June 23, 2018 @09:56PM (#17384534)
You crossed into incivility repeatedly in this thread. That's not ok on HN, regardless of how little someone knows (or seems to know) about container types. Please (re-)read https://news.ycombinator.com/newsguidelines.html and abide by the rules when commenting here.
Re:From Java to Go, and Back Again (2016) by daenz on Sunday June 24, 2018 @03:48AM (#17385482)
Sorry. Every response to me has essentially been "this is useless" when it is idiomatic Go. I'm sure you can see how that can be frustrating. I'll try not to be so snarky.
Re:From Java to Go, and Back Again (2016) by nostalgeek on Saturday June 23, 2018 @03:21PM (#17382897)
> Did you miss the point where I said "it's not good or pretty" ? Or do you just want to bitch about everything?

I'm not bitching about anything (you don't need to use this kind of language here, it is not reddit), I'm telling you that piece of code you wrote is pretty useless.

It is not compile time type safe and it is slow due to the use of reflection. This is not an alternative to generics or generic functions in the language. It fixes nothing.

Re:From Java to Go, and Back Again (2016) by daenz on Saturday June 23, 2018 @03:30PM (#17382953)
>This is not an alternative to generics or generic functions in the language. It fixes nothing.

When it comes to Go, you don't know what you're talking about. Learn to write a container type and then get back to me. Here's a Heap https://golang.org/src/container/heap/heap.go?s=2105:2138#L5... See the return type? interface{}. This is how it's done in Go. How did you think it was done without generics? IntHeap, StringHeap, FloatHeap, etc?

"You can't do X because Go doesn't have Y" was the original point. My response was "you do X with Z." Whether or not Z is good or bad is completely orthogonal to the original point seeing as how it's idiomatic in Go.

Re:From Java to Go, and Back Again (2016) by piano on Saturday June 23, 2018 @05:17PM (#17383499)
> "You can't do X because Go doesn't have Y" was the original point. My response was "you do X with Z." Whether or not Z is good or bad is completely orthogonal to the original point seeing as how it's idiomatic in Go.

No, it's not orthogonal. The part you cited even mentions strong typing, thereby IMO it is pretty obvious type-safety is a requirement here. Otherwise what would even be the point of the exercise? Mapping of some data to some other data? You can do that in _any_ turing-complete language.

The comment said "you can’t write a generic map from an array of T to an array of R" and, indeed, you can't do that in Go. Your code maps a slice of dynamic values to a slice of dynamic values. It doesn't map array of T to array of R, as requested, because there's simply no way to express that in Go.

Besides, I think think it even actually _is_ idiomatic since you used reflection.

Re:From Java to Go, and Back Again (2016) by daenz on Sunday June 24, 2018 @02:50AM (#17385334)
>Besides, I think think it even actually _is_ idiomatic since you used reflection.

https://appliedgo.net/generics/

See point 4 and 5. It is idiomatic.

Re:From Java to Go, and Back Again (2016) by piano on Sunday June 24, 2018 @03:00PM (#17387839)
Are you joking / trolling? The article clearly instructs to _avoid_ refleciton...
Re:From Java to Go, and Back Again (2016) by daenz on Monday June 25, 2018 @10:10AM (#17392536)
That's the author's personal opinion, but it doesn't make it any less idiomatic. There's a difference. And point 4 isn't reflection at all, it's type assertions.
Re:From Java to Go, and Back Again (2016) by dagss on Saturday June 23, 2018 @02:22PM (#17382586)
Well technically this is reflection which is something else than generics. You say "that's not true" but it IS true that go lack generics (or metaprogramming in general). You point out that it supports reflection which is something else... it is a bit like coding in Python, you loose compile time type safety.
Re:From Java to Go, and Back Again (2016) by daenz on Saturday June 23, 2018 @02:43PM (#17382709)
No, it's not generics, but it enables you to write a generic function, which is what the article claimed was not possible in Go.
Re:From Java to Go, and Back Again (2016) by ecnahc515 on Saturday June 23, 2018 @04:56PM (#17383403)
Unfortunately, to do anything with the results you have to iterate over them again to convert back into a slice of non-empty interfaces, making this implementation basically useless.
Re:From Java to Go, and Back Again (2016) by daenz on Sunday June 24, 2018 @03:42AM (#17385458)
>basically useless

It is how container types are done in Go.

Re:From Java to Go, and Back Again (2016) by nostalgeek on Sunday June 24, 2018 @07:00AM (#17386016)
> It is how container types are done in Go.

You can't define your own compile type safe container types in Go at first place. You demonstrated nothing with your piece of code, you just wrote some dynamic stuff that doesn't care about types, this isn't a container type, you ignore the type of the element.

Re:From Java to Go, and Back Again (2016) by daenz on Monday June 25, 2018 @10:09AM (#17392525)
>You demonstrated nothing with your piece of code

I've demonstrated how you map a function over a list containing any type. How would you do it? Provide a solution.

Re:From Java to Go, and Back Again (2016) by nostalgeek on Monday June 25, 2018 @11:46AM (#17393296)
> I've demonstrated how you map a function over a list containing any type. How would you do it? Provide a solution.

you've demonstrated you are unable to do it while conserving the type of an element.

You iterate over an array with a range loop which allows the code to stay compile time safe. That's the only thing one can call idiomatic go code here. You threw out compile time safety for nothing trying to prove some point that makes no sense to begin with.