4 ms·
I think the Go team would still like to understand your production uses that caused you to write off Go. What is your problem domain? How would you accomplish t
by kardianos 9y ago
I think the Go team would still like to understand your production uses that caused you to write off Go. What is your problem domain? How would you accomplish that in Go? How did you actually solve your problem with a different language?
For me, user provided data structures are the only thing that comes to mind (sync.Map for example) in my production use of Go. But even then, my pain (time spent, errors made) due to a lack of generics is low.
You may have written off Go. But if you're willing, I bet the Go team would still like to read your production code use-cases that caused you to do so.
- eropple 9y agoMy "problem domain" is "good, correct code". I write code in many different spaces, from web software to mobile apps to (a lot of) devops tools to (less these days) games. My criticism of Go isn't "it's not good at code for my problem domain," it's "it's not good at code for your problem domain, either, and your workarounds shouldn't need to exist." User-provided data structures are a big one. (A language where I have to copypaste to have typesafe trees is a bad language.) But, beyond that, I build stuff to be compiler-verified. Here's a trivial example that I did yesterday that I straight-up can't do in Go, but did in C# as part of a object graph rehydration routine (where object A required pointers to object B from a different data set, and since it's 2017 we aren't using singletons so the JSON deserializer takes in converters that look up objects based on keys in object A's JSON representation): public interface IKeyed<T> { T Key { get; } } Just being able to do that on an object is powerful. C# has reified types; I know what T is at runtime. (I can't specialize on the type in C#, but I can fake it.) But I also know what it is at compile-time, and so I can't accidentally pass `IKeyed<String>` and `IDictionary<Int32, DependentObject>` to the same function because type constraints, yo. I don't really care about fast code, because computers are all future-computers-from-beyond-the-moon. If I'm using a statically-typed language, I care about correct. Duplicated code is code that will--not may--lead to bugs. State I have to maintain in my head (like "this is an int map, talking to an int-keyed object set") is state that will--not may--lead to bugs. If you're a statically-typed language that isn't helping me avoid bugs, you might as well not exist. You don't have to be whomping around stuff like Scala's Shapeless--I would argue that you shouldn't--but you have to provide at least a basic level of sanity and the difficulty of expressing stuff outside of parameterized types (even when there are workarounds) makes it not worth the hassle. I'll cape up for damned near everything in at least some context, from dynamic languages like Ruby and ES6 to Java (well, Kotlin) or C# to Modern C++ to Scheme or a Lisp. My no-buenos on programming languages are limited pretty exclusively to C and Go because both languages encourage me, encourage all of us who use them, to write bad code.
- deleted 9y ago[deleted]
- I_am_tiberius 9y agoI'm new to Go and actually and don't do professional IT work but I immediately felt the need for having a type that allowed me to store any type. My use case was/(still is) writing a spreadsheet where a user can enter different stuff in a cell and I want to store the value in an underlying data type. I now ended up storing everything as string because I couldn't figure out an efficient way to implement it. My goal would have been to have one generic type that can store the cell types text and number which I can store in an array. This generic type could then implement an interface method like format() which calls a different format method depending on the type the cell has. I played around with interface and reflect.TypeOf but lost too much performance compared to just storing everything in a string. Strings on the other hand now fill up my memory with stuff I don't need - at least that is my impression. I don't have programming experiences so maybe I misunderstand the discussion or just overlooked a way to solve my issue in an efficient way. So sorry if the example I mentioned something easily doable in go.
- masklinn 9y ago> My goal would have been to have one generic type that can store the cell types text and number which I can store in an array. FWIW generics wouldn't help you with that, "sum types" would. A sum type is a souped-up enum which can store associated data alongside the "enum tag", so you can have e.g. enum Foo { Bar(String), Baz(u8, u32), Qux, } and at runtime you ask which "value" is in your enum: match foo { Bar(s) => // got a Bar with as string inside Baz(n, _) => // got a Baz, took the first number Qux => // Got a Qux, it stores no data } (and in most languages the compiler will yell at you if you forget one of the variants). So for your use case you'd have e.g. enum Value { Boolean(bool), Integer(u32), String(String), // etc… } > I played around with interface and reflect.TypeOf but lost too much performance compared to just storing everything in a string. Maybe try a struct with an explicit tag rather than reflection? e.g. type ValueType int const ( TYPE1 ValueType = iota TYPE2 TYPE3 // … one for each concrete type you want to wrap ) struct Value { type ValueType value interface {} } and then you can switch value.type { case TYPE1: value.value.(Type1) case TYPE2: value.value.(Type2) // etc... I'd expect reflect.TypeOf to be very expensive, this is a check + a cast.