

Function types in Go - zemo
http://jordanorelli.tumblr.com/post/42369331748/function-types-in-go-golang

======
jeremyjh
Go's support for first-class functions definitely sparked my interest in the
language. But one thing that Javascript, Python and Ruby programmers would
expect of higher order function support is the ability to use the general
collection methods such as map, reduce, filter (or inject, collect, fold -
whatever they are called in your language). So far as I can tell, generalized
functions of these types are not really possible. You could write some that
were typed interface{} and then did explicit casts in the closures you passed,
but that would not be nearly as elegant as what other languages provide. I
believe in a static type system without generics this is not really possible,
and this is really (to me) the most painful cost from the lack of generic
support.

~~~
koenigdavidmj
Go is an opinionated language. Go people would just tell you to write the
loop; that's what it's there for.

~~~
jerf
The loop was a trivial example. Less trivial examples are not possible either.
For instance, I'd like to write a function that takes in a channel and returns
a (directional) channel that has been turned asynchronous, by running a
goroutine that manages a queue and doing some other things above and beyond
what a merely buffered channel does (emulating Erlang's way of managing async
messages with backoff timeouts), but I can't do that correctly and safely. I
haven't completely written this function in fact but it's certainly at least
20 lines.

I'm making a list of the things that I tried to do in the language, then
couldn't; I'm up to four right now, each of which are not trivial examples,
but are instances of code that I must repeat because I can not refactor it.
This is not a plus. (My list is at home and I'm not, and I'm sort of saving it
for a blog post anyhow, but this is representative; not _killer_ , but the
issues compound as the program gets large.)

Mind you, I know the language is young, etc etc, and I support the idea of
doing it right rather than doing it sooner, nor am I attached to "generics" as
the only possible solution. However, there is a real problem here for
refactorability, and I would not want the Go community to build too much of a
metaphorical callous around this issue and get to the point where they just
reflexively respond with annoyance. There _is_ a problem here.

~~~
burntsushi
What you're after here is called parametric polymorphism (commonly known as
"generics"). Go does not have it. Debates still rage on the ML about whether
to have it or not, but nobody has yet come up with an implementation makes
most happy.

Go does have polymorphism though, in the form of subtype polymorphism. In Go,
it is achieved using interfaces.

Subtype polymorphism typically has more programmer overhead than parametric
polymorphism, so it is not used for simpler things like a generic map, fold,
etc. However, it can be used to reduce code duplication in other cases, like
sorting (among many other things).

~~~
aaronblohowiak
I almost missed your ML pun. To the uninitiated, ML was the first language
supporting parametric polymorphism around 1976.

What is interesting about Go's subtype polymorphism is that it is structurally
subtyped.. so A is a subtype of B if it fits the description of B, it does not
need to explicitly declare that it "supports" or "implements" B.

------
sirclueless
I really liked this treatment of first-class functions. It started off slow,
with a lot of trivial, contrived examples that should be obvious to anyone who
has ever seen first-class functions in any language. But then there were some
very pragmatic patterns, with standard library examples, that used recursive
function types and methods on function types to build some very neat APIs.
Building a lexer out of a recursive function type actually sounds like a
really cool thing to try, if I find some free time I want to try it without
looking at Go's standard library `text/template` lexer and see how it
compares.

~~~
jbarham
> Building a lexer out of a recursive function type actually sounds like a
> really cool thing to try

Rob Pike did just that for Go's text/template package
(<http://golang.org/pkg/text/template/>).

See the source lexer source code at
<http://golang.org/src/pkg/text/template/parse/lex.go> and note that _stateFn_
is defined recursively.

There's a video by Pike describing how he built the parser at
<http://www.youtube.com/watch?v=HxaD_trXwRE>.

------
dualogy
"Function types in Go can also have methods."

Wow, blew my mind... this has never occurred to me but, of course, why not?

Not sure yet how I am going to abuse that feature, but already looking forward
to it.

~~~
dsymonds
The HandlerFunc type in net/http
(<http://golang.org/pkg/net/http/#HandlerFunc>) does this.

------
pjonesdotca
Probably my favourite thing about Go. The ability to create a DSL with a
systems level language is kind of amazing.

------
quarterto
I never really noticed how similar Go's function expressions are to
JavaScript's before, but I'm now pretty certain they were one of the
(subconscious) factors that got me into Go.

------
melvinmt
Anonymous functions as an expression do have their purpose, unlike the author
has stated, especially when you want to isolate different blocks of code from
each other by putting them each in a different scope.

------
mieubrisse
Always fun to see examples of first-class functions; thank you for the read!

