14 ms·
One nice thing these examples also do is make it really simple for detractors to point out what they don't like about it. My #1 gripe about go, for example, is
by jamesaguilar 13y ago
One nice thing these examples also do is make it really simple for detractors to point out what they don't like about it. My #1 gripe about go, for example, is this: https://gobyexample.com/sorting-by-functions https://gobyexample.com/sorting-by-functions
In a few other languages:
// C++
sort(vs.begin(), vs.end(),
[](const string& l, const string& r) -> bool {
return l.size() < r.size();
});
# Python
vs.sort(key=lambda s: len(s))
When they fix this, Go might be the perfect language for me. Until then, I'm not touching it with a pole.
- L8D 13y agoYou do realize that go has lambda expressions (anonymous, in-line, functions) right?
- jamesaguilar 13y agoI do know this, but it is not sufficient to solve the problem we are discussing. (Or, to put the statement in the form of a question, how do you propose solving the problem using lambdas?)
- skybrian 13y agoYou could pass the length and two functions for lessThan and swap.
- shurcooL 13y agoThis article's for you. http://go.c800colon5.com/blog/2014/01/09/a-grumpy-guy-complains-about-complaining/ http://go.c800colon5.com/blog/2014/01/09/a-grumpy-guy-compla...
- jamesaguilar 13y agoSeems like he's set up quite a strawman of his opponents. He's made some very complicated and unfounded assumptions about people who criticize the language he likes.
- aabalkan 13y agoI have a blog post about this: http://alp.im/blog/go-linq/ http://alp.im/blog/go-linq/
- a-nom-a-ly 13y agoYou can do this just as easily in Go as well, using reflection.
- burntsushi 13y agoYup! Here ya go: // Sort a slice of structs with first class functions. type Album struct { Title string Year int } albums := []Album{ {"Born to Run", 1975}, {"WIESS", 1973}, {"Darkness", 1978}, {"Greetings", 1973}, } less := func(a, b Album) bool { return a.Year < b.Year }, sorted := QuickSort(less, albums).([]Album) For more fun things, see: http://godoc.org/github.com/BurntSushi/ty/fun http://godoc.org/github.com/BurntSushi/ty/fun
- mwhite 13y agoHey, don't sell Python short! vs.sort(key=len)
- d0mine 13y agolambda is redundant redundant here: L.sort(key=len)
- bstamour 13y agoWith C++14 this becomes sort(begin(vs), end(vs), [](auto const& l, auto const& r) { return l.size() < r.size(); }); Even simpler.
- dfrey 13y agoWhy are "begin" and "end" functions now instead of methods on the iterator? Do they consider it better because now you can pass around functions, but not methods?
- fauigerzigerk 13y agoBecause it works with arrays.
- bstamour 13y agoMore than that, actually. Because of argument dependent lookup, this will work for any container that has begin and end functions in the same namespace.
- dmunoz 13y agoWhat are the C++14 parts here? I haven't been paying much attention to the C++14 standards shaking out. dfrey already asked about why begin/end are functions now. I see auto being used inside the lambda. Was that not allowed in C++11? I got sucked into the "use auto everywhere" mantra, so I just imagined it was possible, but could easily see if it were not. That is probably the biggest decrease in size to the original code posted. I see return type inference. That is one thing I have heard about being new in C++14. To be honest, I would rather see the explicit return type there. Inference is always nice, though.
- bstamour 13y agoI omitted the return type (which is allowed for lambdas in C++11, and now arbitrary functions (with some conditions) in C++14) because it was a 1-liner. The bool return type can be deduced by the compiler automatically (or else it would fail to compile) and by the human by the operator < in use, the fact that it's being passed to sort, etc.
- dsymonds 13y agoA few extra lines for sorting means you won't touch Go with a pole? That's a bit extreme. Do you really do custom sorting so often that this is a major problem? There's plenty of other ways in which Go is shorter than the equivalent C++ (e.g. with type inference, or channel operations), but no-one's trying to claim that the shortest code wins.
- masklinn 13y ago> A few extra lines for sorting It's not just sorting, it's any parametric polymorphism: generic operations or non-built-in containers (not just in the sense of "array", an atomic ref is also a container) for instance. Go only lets do these in verbose, clunky ways, and losing much of the type safety Go is supposed to provide (what with being a statically typed language) > no-one's trying to claim that the shortest code wins. No one is indeed, so that's an irrelevant strawman.
- dsymonds 13y agoThe post I replied to didn't explicitly say what he disliked about sorting in Go, and what "this" means in "When they fix this". I guessed that it was because the Go code is a bit longer. What else could it be? I guess it's a little clunkier, and it's true that writing generic containers in Go isn't so great, but is that sufficient to elicit a reaction of "I'm not touching it with a pole"? Nobody claims it's perfect, but is it really sufficiently horrible to warrant that?
- masklinn 13y ago> it's true that writing generic containers in Go isn't so great That's one hell of an understatement. > is it really sufficiently horrible to warrant that? A number of people obviously and repeatedly say that yes, a statically typed language without parametric polymorphism is sufficiently painful to use something else instead.
- dsymonds 13y ago
- natural219 13y agoWow, yeah. This is pretty bad. The example doesn't even make logical sense. Why is ByLength a type? Shouldn't you just want to pass in an array? Can any "idiomatic" Go programmers here give a better example of how you would do this?
- colin_mccabe 13y agoCan any "idiomatic" Go programmers here give a better example of how you would do this? Sure. sort.Sort(sort.Reverse(sort.StringSlice(vs)));
- colin_mccabe 13y agoOops, I looked at the Python code again, and it seems to be sorting the strings by their length, not reversing the sort order like I did. Sorry, I didn't look at it very carefully earlier. Anyway, the easiest thing to do is probably write a wrapper type around StringSlice using Go's anonymous struct syntax. You only need to implement LessThan, since StringSlice already implements the other two. type StringSliceByLength struct { sort.StringSlice; } func (s StringSliceByLength) LessThan(i, j int) bool { return len(s.StringSlice[i]) < len(s.StringSlice[j]); } Sort.sort(StringSliceByLength(vs))
- frou_dh 13y agoYou can't put methods on a type from a different package (or in this case a builtin type). Instead of methods, you could of course write normal functions taking []string, but only methods can fulfil interfaces.
- jamesaguilar 13y agoThis is the idiomatic way. It's actually the only way.
- jamra 13y agoWhy not make an interface called iCompare that has a single function: compare, which takes an object of type interface{}. You can then implement that single compare function, attached to your type of choice. Problem solved.
- masklinn 13y agoYou're only solving the example (painfully and incompletely as well, because now you can't sort your collection twice using different criteria, and I believe you can't sort objects you don't fully control since you can't add methods to somebody else's types — let alone a builtin, woe is you if you're attempting to sort maps). How do you handle a non-inplace sort? How do you handle implementing a treeset or a b-tree? A reference with compare-and-set semantics? Your interface won't save you from the devil of having to up- and down-cast all over the place and throw type safety into the trash.
- jamra 13y ago1. You can add methods to other people's types. 2. My solution is not incomplete. It solves the stated problem exactly. If you need to sort the objects with a different criteria, implement the interface with whichever criteria you want. It's not so difficult. Generics will not save you from having to implement some kind of comparison criteria in other languages. 3. You can add more methods to the interface for an out of place sort. 4. If you need to implement a b-tree, add the methods to whichever type you need to sort appropriately. It's not that big of a problem. You will not have to up and down cast. You only have to cast a type of interface{} to your type once and only once while you are comparing. Is your problem ideological or specific to this example?