Hi all.
I'm trying to implement a Linq-alike for Go, mainly for practice but also because I find Enumerables really easy to work with. Unfortunately, I have hit several walls, all due to missing features in the language.
- Generics. Yeah, I know Google doesn't like them. But how else are you gonna define a function that takes a parameter of type T along with a function that takes a T and returns a T? Answer: You can't. It must take an interface{} and a function that takes an interface{} and returns an interface{}. And then you can't call this function and pass in an int and a function taking an int and returning an int. No, you have to write a specifically non-type-safe function and pass that in, even if you had a perfectly good int->int function kicking around. Madness!
- Overloading. I decided to start by writing Ana, Cata and Bind, a la MinLINQ. Unfortunately, due to the lack of generics, I need to write an Ana() that deals with interface{}s, along with specialised versions for ints, strings and floats. But... you can't have functions with the same name and different parameters, so that's out too.
- Methods. So, I figured I'd make each overload of Ana be a method on the relevant type, but the compiler spits out "cannot define new methods on non-local type int". So I can't do that either.
Don't get me wrong: It's great to see the number of modern native-compiled languages exceed "1", but seriously guys, how's a fellow supposed to get anything done without generics?
I want a function like this:func Ana(seed T, condition func(T) bool, next func(T) T) FEnumerable<T> {
... code ...
}
Is that really so unreasonable? Are you seriously telling me that writing out loops and such at the call site is better than having a reusable *cough* "class library"? I don't want to be declaring lists and slices all over the place every time I want to query something. I want to simply say "From(something).Where(filter).Select(transformation)". You can do that in C++, C#, D, VB.NET and pretty much any other modern language. If you're going to have types, you must also have generics. Period. Otherwise we're just back in the dark ages casting everything back and forth, or writing the same code over and over again.
Again, let me say that I'm not knocking Go specifically. I'm sick of being locked into C++ whether I like it or not (yeah, I know there's D, but it's riddled with bugs). But what use are "first-class functions" when you have neither generics nor polymorphism? The whole point of first-class functions is to plug specific strongly-typed sorting or filtering functionality into an otherwise generic untyped process. In other words, the function you're calling doesn't need to know or care what kind of objects its dealing with, because you've provided a function object that can do the type-specific bit of work. But here I can't, because a func(int)int won't be accepted by a function expecting a func(interface{})interface{}.
Troll detected
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
No one is likely to debate this with you: http://golang.org/doc/faq#genericsThere may be generics is the future, but in the meantime most of us are happy with no generics vs poor generics.
I'm not going to pretend that Go is good at this, because it's not.
But you actually can do this: http://play.golang.org/p/emiuPJwfCS .
Troll detected
Not really.
http://play.golang.org/p/TgB_pRVBdP
There goes type safety, and, consequently, a core feature.
On Friday, May 17, 2013 9:43:03 PM UTC+1, Aaron France wrote:Troll detected
Troll yourself. Didn't you read what I wrote? As I said, I'm in favour of new native languages and would like to use Go, but I feel my objections are valid. If you disagree, why not explain why you think generics aren't necessary, rather than just sitting there and hurling insults for no reason.
Look at how the standard library does Sort: http://golang.org/pkg/sort/
Oh geez, I was hoping a polite pointer to the FAQ (which covers overloading too BTW) would be enough to prevent this usual progression.
For the record, though you may not intend too, you are coming off as very antagonistic.
It's not going to lead to a useful discussion.
Lot's of useful things are done with go without using generics. Maybe there's something we can help with.
Another method for "generifying" code is to wrap things in interfaces. See the code in Sort for an example: http://golang.org/pkg/sort/
If nobody ever complained about the shortcomings of anything, nothing would ever get done.
Unanimously, though,
everybody would appreciate having a beautiful implementation of
generics in the language,
On Friday, May 17, 2013 10:08:29 PM UTC+1, Gustavo Niemeyer wrote:Unanimously, though,
everybody would appreciate having a beautiful implementation of
generics in the language,
So explain why people tried to lynch me as soon as I mentioned it.
You think this "beautiful implementation" is going to fall out of the sky? No, it'll happen by people discussing it, and repeatedly
demanding it on forums, until it gradually filters through the head of the developers.
but you don't seems to propose an implementation of generic, only complained the lack of it,and that's why people consistently refer you to the FAQ.
I'm saying that 3000 people wrote before they read, did before they thought and failed before they started.They came from other languages, read about Go, realized the "lack" of generics, immediately posted to the list. Left in less than an hour.
Don't get me wrong: It's great to see the number of modern native-compiled languages exceed "1", but seriously guys, how's a fellow supposed to get anything done without generics?
If you read before you wrote you would have noticed that Aaron France quoted Ian Lance Tailor as a troll. Not you.
Just stick around bro. Read the list - get to know the language, we're a fine community.
I'm not surprised. They were probably called trolls. They probably figured that a language without generics was a poorly designed language. They were probably put off by the "no can't do" attitude.
As I see it there is a third way. One that has been taken before.Create a wrapper/preprocessor language, ala Groovy, coffescript, etc...Then the developer could choose which tradeoff they want to make (compile speed, executabel size, and runtime speed) and then choose the appropriate wrapper language.
Probably you want to see how embedding can be used here. You can do extremely subtle things by wrapping your type in a struct with additional data and a changed Less method.
Oooh, another native language! I googled for native languages recently and never encountered Rust. Thanks for pointing it out. I'll take a look.
The only other natives I know of are D (buggy as hell), C++, AutoIt (a bit lacking) and Red (afaik, not yet in a usable condition). Any more?
Do you really not know? If this has occurred to you multiple times,
and it's not intentional, then perhaps you should investigate your
style of communication. Much as you said yourself farther down the
thread, if many people tell you something, then perhaps it is true.
Even if it's hard for you to see it yourself.
In this case, since you said it so nicely, I'll give you a couple of tips.
In describing what you have to do in Go to work around the lack of
generics, you said "Madness!" Exclamation points are seen as
aggressive. Accusing people and/or projects of insanity is seen as
aggressive.
You said "seriously guys, how's a fellow supposed to get anything done
without generics?" Here you are posting in a forum for people who use
Go, and saying, not just that one can't use Go without generic, but
that the lack of generics means that the language is not serious. You
may very well believe that; it may even be true; but when you come
into a forum and tell people that they can not do what they are doing,
it is seen as aggressive.
You said "Is that really so unreasonable? Are you seriously telling me
that...." Same sort of thing here. Rather than phrasing the issues
in a neutral or helpful way, you are phrasing them in a way that
implies that the people who use Go are unreasonable and unserious.
This is seen as aggressive.
The language developers WANT to add generics to the language.
However, they don't want to rush it.
If at all possible they would like to avoid the tradeoffs found in C++ and Java:1. The C++ templates while powerful slow down the compiler.2. The Java/.NET generics while powerful, slowdown the runtime.As I see it there is a third way. One that has been taken before.Create a wrapper/preprocessor language, ala Groovy, coffescript, etc...Then the developer could choose which tradeoff they want to make (compile speed, executabel size, and runtime speed) and then choose the appropriate wrapper language.
As another apporach to your question, similar to Ian's would be to take a pointer to an interface{} and plase the results in that. This is used in a number of places in the standard library. This would depend on reflection, but you could take an interfaced-based approach like Foo(a, b Interface, c SetInterface) where a and b satisfy the behaviours you need to het the inputs and SetInterface satisfies the behaviour of storing that result. Potentially no type assertions are needed under this scheme.
I encourage you to reflect on your post and how people respond to it.
It's not a matter of what you are trying to say. It's a matter of how
you say it.
I'm trying to say something not about what you are saying, but about
how you are saying it. You are responding by reasserting what you are
trying to say. That's not the point. It's not about the content.
It's about the presentation.
I get that. However, from my point of view, the content is 99% of the message. If I say "people who use Go are idiots", well, that's rude. If I say "Seriously? I can't even do this?" - well, in my native language, incredulity at the limitations of a system does not equal an insult to the people using it. I call my native language "English". Apparently it's not the same as what everyone else is using, however.
Telling me that the presentation is important, while informative and appreciated, doesn't actually enable me to do anything about it. I look at my "presentation", as you call it, and see nothing wrong. (Except when I'm replying to unhelpful posts, of course.) While I'm aware that the majority of people in this world react badly to how I say things, I honestly can't do anything about it. Or, at least, haven't been able to thus far. Given that I'm in my thirties, I don't see that changing overmuch.
On Friday, May 17, 2013 10:54:57 PM UTC+1, Tad Glines wrote:The language developers WANT to add generics to the language.However, they don't want to rush it.
Well bugger me! A sensible rational discussion on the subject! ;)
If at all possible they would like to avoid the tradeoffs found in C++ and Java:1. The C++ templates while powerful slow down the compiler.2. The Java/.NET generics while powerful, slowdown the runtime.As I see it there is a third way. One that has been taken before.Create a wrapper/preprocessor language, ala Groovy, coffescript, etc...Then the developer could choose which tradeoff they want to make (compile speed, executabel size, and runtime speed) and then choose the appropriate wrapper language.
Hmm...I wasn't aware that generics were that slow. I'll have to write a test program in .NET or something and benchmark it somehow. I'm not familiar with the preprocessors you mention; not being a Java developer. Isn't a preprocessor just another version of option 1, though?
You might want to try a Snickers. Or a weekend reflectingwhat and why was said.
As for options 2, the problem isn't necessarily in the way they are designed but in the way they would translate. For example, Java generics use type erasure. That is, in the source you might have Map<String, String>, but in the byte code you end up with Map<Object,Object>. In the case of Map, this works out ok because the only methods Map needs are available in the Object interface so there is no need to create a separate compiled version like in C++. But, because Go doesn't have a type hierarchy with a root type, and none of the types have methods, the Java style isn't really possible without making significant changes to the language. If a particular function/algorithm needs certain methods (e.g. Equals and Less) then the algorithm can require an interface as input then any type that implements those methods can be passed to that function/algorithm. This is sort of like the way C++ templates work but not quite as expressive because you have to do a bit more explicit casting depending on how the interface is used.
I feel obligated to point out the irony that you want to implement LINQ while having the opinion you do about Haskell (and functional languages, more generally). The contrast tickled me.
I don't see the problem. If you have no class hierarchy, then you have no need for covariance or translation. Suppose I declare a function as follows:
func Foo<T>( a T, b T, comparer func(T,T) bool )
It doesn't matter what T is. Just compile a version of Foo where T is whatever type I'm passing:
Foo(1, 2, func(a int, b int) { return a == b })
If we specify a type limitation (e.g. func Foo<T:interface{ ...some methods... }>) then just don't allow a version of that function to be compiled where T doesn't implement the interface. I honestly don't see the problem.
On Fri, May 17, 2013 at 3:51 PM, Sod Almighty <sod.al...@gmail.com> wrote:
You don't intend an insult. But you are implying that the system is
not merely deficient but obviously and fragrantly deficient.
You are
implying that no ordinary person would want to use it. It follows
that you are implying that the people who do use it are not ordinary.
It's a pretty short step from there to think that you are calling the
people who do use it stupid. The step may not be warranted, but many
people will take it. And at that point, it's an insult.
> Telling me that the presentation is important, while informative and
> appreciated, doesn't actually enable me to do anything about it. I look at
> my "presentation", as you call it, and see nothing wrong. (Except when I'm
> replying to unhelpful posts, of course.) While I'm aware that the majority
> of people in this world react badly to how I say things, I honestly can't do
> anything about it. Or, at least, haven't been able to thus far. Given that
> I'm in my thirties, I don't see that changing overmuch.
If you really want to learn and change your communication patterns,
you can do so.
If you don't want to, then you must simply accept the
fallout. There are many things about ourselves we can not change.
This is not one of them.
You can't change how you feel. But you can
change how you communicate, especially over a medium like e-mail that
permits time for reflection.
Remove any exclamation points. Remove any sentence that seems to call
for an exclamation point.
Remember that on the Internet people come from many different
backgrounds and cultures. Sometimes it helps to think of your e-mail
as being written to a timid child. You want to explain something to
him. Maybe you want to explain why he shouldn't go out into the
street. But you want to do it without scaring him. If you yell he
will start to cry, and moreover he may be afraid to ever leave the
house again, which is not what you want. What words would you use?
Now pretend that the people reading your e-mail are timid children.
You want to convince them without scaring them.
Remember that on the Internet people come from many different
backgrounds and cultures.
It's normally done because 1) language developers tend to be compiler
writers, and tend to be interested in languages that are good for
writing compilers; 2) writing a compiler in a language ensures that
the language is powerful enough to write a reasonable complex program.
Also, the later case you gave "func Foo<T:interface{ ...some methods... }>" is already more or less supported in Go (e.g. func (t *T) Foo(value SomeInterface) SomeOtherInterface).
I didn't realise a period was easier to type than a new line.
Also, you
are of course correct that I'm being insulting. I'm just doing it
politely. The difference between what you wrote and what I wrote is
that you had to think for a bit before you realized the insult,
whereas a number of people spotted that you were being insulting
(which you were, even if you did not mean to be) in your original
post.
Mayhap, but there is an obvious list of candidates for doing something like what you want just a google away:
On Friday, May 17, 2013 11:15:58 PM UTC+1, kortschak wrote:
As another apporach to your question, similar to Ian's would be to take a pointer to an interface{} and plase the results in that. This is used in a number of places in the standard library. This would depend on reflection, but you could take an interfaced-based approach like Foo(a, b Interface, c SetInterface) where a and b satisfy the behaviours you need to het the inputs and SetInterface satisfies the behaviour of storing that result. Potentially no type assertions are needed under this scheme.
Yeah, but you can't do:results := values.where( ...filter function... ).orderby( ...sorting function... ).select( ...transformation function... )
With your Foo function, it's a laborious job of one-operation-per-line, plus a bunch of typecasts. Yeah, I realise that with enough work and messing about it's possible to write a function Foo(), but that's not what I intended here. My intention was to allow for a simple SQL-like query syntax, in the style of .NET LINQ. Because doing it imperatively is hard work and less readable. Also potentially slower (if it resolves the queries immediately).
On Friday, May 17, 2013 11:04:41 PM UTC+1, Ziad Hatahet wrote:On Fri, May 17, 2013 at 2:59 PM, Sod Almighty <sod.al...@gmail.com> wrote:Objective-C and Haskell, to name a couple.Oooh, another native language! I googled for native languages recently and never encountered Rust. Thanks for pointing it out. I'll take a look.
The only other natives I know of are D (buggy as hell), C++, AutoIt (a bit lacking) and Red (afaik, not yet in a usable condition). Any more?
I'm not an expert, but Objective-C would appear (at a casual glance) to suffer from the same problems as C++. For example, it has header files, which I personally consider the absolute most stupid and awkward feature of C/C++. I just googled and apparently it does have a GC, which I didn't realise. But it's primarily a Mac-targeted language. I'm not sure how feasible it'd be to write Windows software in it. Guess I'll take a look. It looks mighty strange at a casual glance, though. Trying to think of it as a parallel universe version of C++ just isn't working for me ;)
Haskell? Are you serious? It's a purely functional language - which in my opinion means it's totally useless - and, as far as I'm aware, totally dead except amongst mathematicians.
On Fri, May 17, 2013 at 1:57 PM, Sean Russell <seaner...@gmail.com> wrote:
> Not really.
>
> http://play.golang.org/p/TgB_pRVBdP
>
> There goes type safety, and, consequently, a core feature.
The language still has type safety, of course--that's why your code panics.
What this approach lacks is compile-time type safety. It's a serious
problem. I just want to make sure we give it the right name.
On Friday, May 17, 2013 9:57:16 PM UTC+1, Sean Russell wrote:Not really.
http://play.golang.org/p/TgB_pRVBdP
There goes type safety, and, consequently, a core feature.
What type safety? The type safety that forces you to write a different function for every type you want to use it with; while simultaneously forcing you to give each function a different name?
On Saturday, May 18, 2013 12:15:49 AM UTC+1, Ian Lance Taylor wrote:On Fri, May 17, 2013 at 3:51 PM, Sod Almighty <sod.al...@gmail.com> wrote:
You don't intend an insult. But you are implying that the system is
not merely deficient but obviously and fragrantly deficient.
I think perhaps you mean "flagrantly deficient". I didn't say anything about how it smells.
You are
implying that no ordinary person would want to use it. It follows
that you are implying that the people who do use it are not ordinary.
It's a pretty short step from there to think that you are calling the
people who do use it stupid. The step may not be warranted, but many
people will take it. And at that point, it's an insult.
Well, if you're gonna read several layers of indirection into my words, sure. Thing is, I mean what I say and, conversely, say what I mean. I don't imply that people are stupid - if I think they're stupid, I say so. And I honestly have no idea how to say exactly what I said in my original post but "presented" in a different way that happens to prevent people performing indirection on it and ending up insulted.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Haskell? Are you serious? It's a purely functional language - which in my opinion means it's totally useless - and, as far as I'm aware, totally dead except amongst mathematicians.
On Fri, May 17, 2013 at 4:32 PM, Sod Almighty <sod.al...@gmail.com> wrote:
Well, if you're gonna read several layers of indirection into my words, sure. Thing is, I mean what I say and, conversely, say what I mean. I don't imply that people are stupid - if I think they're stupid, I say so. And I honestly have no idea how to say exactly what I said in my original post but "presented" in a different way that happens to prevent people performing indirection on it and ending up insulted.
Hmm. I would like to try my hand at a rewrite.
C#'s async in Go would be quite superfluous, as far as I can tell. In Go, all blocking operations are implicitly marked async, and whenever you call these operations, you are implicitly calling await. The keyword `go' is roughly equivalent to creating and running a Task.
On Saturday, May 18, 2013 12:08:36 AM UTC+1, Sanjay wrote:I feel obligated to point out the irony that you want to implement LINQ while having the opinion you do about Haskell (and functional languages, more generally). The contrast tickled me.
No irony at all. The functional paradigm has its uses - e.g. LINQ - and can make code far more readable. Some programming problems just lend themselves better to the functional style. I never said I didn't approve of the functional style.
The problem with Haskell is - correct me if I'm wrong - it's functional only. And that's neither use nor ornament to anything who isn't a maths prof. Try writing a Windows application in a pure functional language. Even F# supports imperative statements.
This allows the the compiler to know a priori which generic specifications need to be instantiated and what type combinations they need to be instantiated for.This allows the concrete calling sequences to be known when the callers are being compiled.This allows the compiler to emit the instantiations just once, at its discretion in terms of when.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
The problem with Haskell is - correct me if I'm wrong - it's functional only. And that's neither use nor ornament to anything who isn't a maths prof. Try writing a Windows application in a pure functional language. Even F# supports imperative statements.
On Fri, 2013-05-17 at 14:59 -0700, Sod Almighty wrote:
[…]
> The only other natives I know of are D (buggy as hell), C++, AutoIt (a bit
> lacking) and Red (afaik, not yet in a usable condition). Any more?
This is the second time you have made the claim that D is unusable due
to bugs. Can I suggest that rather than just making unsubstantiated
claims to go to the D mailing list and debate the actual issues you
have.
http://stackoverflow.com/a/16127029/2267702If you want generics, post your proposal here, and then read to this link: http://goo.gl/1j8Cs
We want to have sane generics in go too.
Go has some nice features; but I draw the line at writing boilerplate code everywhere. That's what we're supposed to be avoiding. Personally, I think you should just decide on a damn implementation, and do it. You're never gonna find a perfect solution, and having no solution is worse than having a less-than-perfect one.
Have you ever considered the possibility that your Go experience might be bad because you use Go is exactly like you use a completely different language even though the language features don't match? All your rambling here moved around the topic of not having generics. Instead of trying to get generics into Go with all force and much insulting of developers, you should rather consider trying to embrace Go's language feature set. Most Go users managed to do so without having to produce much or any boilerplate, so you should manage, too.
s := simpleSorter{
LessFunc: less,
Indices: make([]int, length),
}
and the code looks like a dense block of
difficult to read things (mostly because of Go's closure syntax, but
the debate is about generics, not closure syntax).
Alright. How would I go about filtering, sorting and transforming a list of arbitrary objects without all this faffing about? Is there some nifty Go solution that I'm missing? Some way to avoid having to write a new type every time I want to change how something is sorted, perhaps?