Live data from Hacker News

Simple apply/filter/reduce package in Go

github.com

51–60 of 68 posts

Re: Simple apply/filter/reduce package in Go

#51
post #50
post #4

I don't get why someone would rather write a for loop than use declarative data syntax. If I want to get the names of all administrators doing `users.Where(user => user.isAdmin()).Select(user => user.Name)` is so much nicer than using a for loop - or maybe he's suggesting we start writing FOR loops instead of SQL for our databases too?

var admins = users.Where(user => user.isAdmin()).Select(user => user.Name) vs var admins []string for _, user := range users { if user.IsAdmin() { admins = append(admins, user.Name) } } So, at the end of the day, these two pieces of code do the exact same thing, and have mostly the exact same meaning. I read them almost identically... Make a list of admins. iterate through the users, if the user is an admin, append i…

I humbly disagree - in the C# code I can pass an IQueryable and reuse the same code to make an SQL query, or a RavenDB query, or an XML query and it works just the same - there is a unified way to access data in the language.

As for your query:

``` var admins = users.Where(u => u.IsAdmin()).Select(u => u.Name); var stars = admins.Select(name => name + "*"); ```

Like you said, you don't get paid per line feed - it's ok to have multiple lines and you can keep the nice syntax. It's ok to not like complicated code - no one likes complicated code - which is why I don't like for loops - I don't _care_ how something is iterated I just want to map every object.

Re: Simple apply/filter/reduce package in Go

#53
post #17

Earlier quoted context omitted.

I was pretty confused by this post for a minute until I remembered I've been on VS2015 since the first preview release. This problem is greatly reduced there.

I saw that in June, and I'm interested in how effective it is, and what the usability characteristics are (it looked complex at the time, but it was an early demo). But going from 2010 to 2013 was a painful, and I don't want to throw this in a VM, so I'll just wait for RTM.

Super useful. Debugging Select/Where is now as easy as debugging for loops. Also remember that the pain point for debugging is the laziness and not the declarative syntax and you can just use `.ToList()` to get rid of it.

Re: Simple apply/filter/reduce package in Go

#54

Earlier quoted context omitted.

.NET implements them on iterators, too, but that's not an inherently fast approach. .NET iterators are objects that implement a specific interface, and iterating over them involves two function calls per element - one to move to the next item, and one to retrieve the current item. Those two function calls introduce an overhead that may be significant in a "tight loop", and that may not exist in a hand-coded for loop.…

> .NET iterators are objects that implement a specific interface, and iterating over them involves two function calls per element - one to move to the next item, and one to retrieve the current item. Any optimizing compiler will inline those functions. "Avoid function calls for performance" hasn't been relevant optimization advice for at least a decade.

In particular - the Microsoft .NET JIT will gladly make them as fast as loops in most cases - there might be overhead involving closures but that's mostly taken care of.

Re: Simple apply/filter/reduce package in Go

#55
post #7
post #4

I don't get why someone would rather write a for loop than use declarative data syntax. If I want to get the names of all administrators doing `users.Where(user => user.isAdmin()).Select(user => user.Name)` is so much nicer than using a for loop - or maybe he's suggesting we start writing FOR loops instead of SQL for our databases too?

It's easy to dismiss an opinion but that doesn't mean it's wrong. For example, if you like filter/reduce you may criticize languages that don't encourage it (Go, Python, etc). But often this leads to copying ideas from one language resulting in code that's hard to maintain in another language which encourages different ways of expressing the same logic.

Python is a bad example since it has declarative data manipulation syntax. You'd use a comprehension and not a for loop which is practically the same thing in my opinion.

Re: Simple apply/filter/reduce package in Go

#56
post #50
post #4

I don't get why someone would rather write a for loop than use declarative data syntax. If I want to get the names of all administrators doing `users.Where(user => user.isAdmin()).Select(user => user.Name)` is so much nicer than using a for loop - or maybe he's suggesting we start writing FOR loops instead of SQL for our databases too?

var admins = users.Where(user => user.isAdmin()).Select(user => user.Name) vs var admins []string for _, user := range users { if user.IsAdmin() { admins = append(admins, user.Name) } } So, at the end of the day, these two pieces of code do the exact same thing, and have mostly the exact same meaning. I read them almost identically... Make a list of admins. iterate through the users, if the user is an admin, append i…

I'm not familiar specifically with LINQ but in most languages that implement map/reduce/filter operations, the "*" requirement could be clearly expressed using a map.

What happens when you need an alphabetical list of admins who have logged in during the last week? The for-loop approach becomes progressively more and more cluttered with implementation cruft, while a declarative approach just adds a filter and a sort.

And, to be frank, even the example you present is clearer to me in LINQ than in Go, and I am much more familiar with Go.

Re: Simple apply/filter/reduce package in Go

#57
post #2

But you can't write generic functions in Go! Oh, wait. He just did. As a caveat to my exasperated sarcasm, I do realize he's using reflection to identify and type the data at runtime, as opposed to compile time as with C++ templating, but this is kind of generalization is still quite useful when writing general purpose library code. Personally, I'd not be inclined to use this either, the number of times I've actually…

> But you can't write generic functions in Go!

Did anyone claim this? What I heard was that you can't write generic data structures (and I guess that really means type-checked, parameterized data structures). I don't know though, I've never used Go.

Re: Simple apply/filter/reduce package in Go

#58

Earlier quoted context omitted.

This only handles functions of type a -> a -> a ( https://github.com/robpike/filter/blob/master/reduce.go ), whereas a generic reduce takes functions of type a -> a -> b. So this is certainly not proof that you can write generics in go. See also pmahoney's comment in this thread: https://news.ycombinator.com/item?id=9315721 .

Minor nitpick: a generic reduce should take functions of type a -> b -> a, where a is the type of the reduced values, and b is the type of the elements in the sequence to be reduced.

Ah, of course.

Re: Simple apply/filter/reduce package in Go

#59
post #2

But you can't write generic functions in Go! Oh, wait. He just did. As a caveat to my exasperated sarcasm, I do realize he's using reflection to identify and type the data at runtime, as opposed to compile time as with C++ templating, but this is kind of generalization is still quite useful when writing general purpose library code. Personally, I'd not be inclined to use this either, the number of times I've actually…

It's 30 lines long (the equivalent in Haskell would be 1 fairly simple line of code). Type errors are detected at runtime instead of at compile type, and it's not as generic as actual reduce.

In fairness not only in Haskell. I think Go is just not a great choice for this sort of effort. On Haskell though, languages are not a single dimension thing, so it is very easy to say that X is better in Y and leave out all the other dimensions, but that just oversimplification of the problem.

Re: Simple apply/filter/reduce package in Go

#60

Earlier quoted context omitted.

.NET implements them on iterators, too, but that's not an inherently fast approach. .NET iterators are objects that implement a specific interface, and iterating over them involves two function calls per element - one to move to the next item, and one to retrieve the current item. Those two function calls introduce an overhead that may be significant in a "tight loop", and that may not exist in a hand-coded for loop.…

> .NET iterators are objects that implement a specific interface, and iterating over them involves two function calls per element - one to move to the next item, and one to retrieve the current item. Any optimizing compiler will inline those functions. "Avoid function calls for performance" hasn't been relevant optimization advice for at least a decade.

A good optimizer can inline those functions, but that doesn't necessarily mean it will. .NET JIT is conservative in what it decides to inline. There's even a special hint you can use to ask it to be more aggressive about inlining a method. You can't necessarily apply that hint to every function, though. Anonymous ones, for example.
Post reply on HN