5 ms·
Is it possible to write Go in a functional way? Are there first class functions? Anonymous functions? If so it seems it would be possible to write highly functi
by MatthewPhillips 13y ago
Is it possible to write Go in a functional way? Are there first class functions? Anonymous functions? If so it seems it would be possible to write highly functional code given the flexibility of interface{}
- deleted 13y ago[deleted]
- lmm 13y agoUp to a point, but go's limited datatypes make it difficult to write the kind of code you're used to writing in haskell/f#/etc.
- payload 13y agoA haskell version with the Warp server performs just a little bit worse than the go version (6 secs vs 7 secs) with a little bigger minimal latency (68 ms vs 71 ms). go version go1.0.2 runghc 7.6.2 cabal packages of today Runned with "runhaskell main.hs" on localhost over loopback :) import qualified Network.Wai as Wai import qualified Network.Wai.Handler.Warp as Warp import qualified Network.HTTP.Types as HTTP import qualified Data.ByteString as ByteString import Blaze.ByteString.Builder.ByteString (fromByteString) main = do let port = 8000 Warp.run port app app req = do let n = 1024*1024 let bytes = fromByteString $ ByteString.replicate n 100 return $ Wai.ResponseBuilder HTTP.status200 [] bytes
- strager 13y agoHave you tried precompiling with -O2? IIRC runhaskell runs code like GHCi: interpreted bytecode by default (for source .hs files).
- payload 13y agoYes I have and I invite you to do it also by yourself to check it. There is no significant difference in this benchmark between "ghc -O2" and "runhaskell". I didn't investigated why... but I would be very interested in the details :) Also "-threaded" gives the usual penalty of bookkeeping and bad caching and stuff. You don't need threads in such a benchmark. Though I am mildly surprised that "node" runs faster with multiple processes :)
- cgag 13y agoAm I right in thinking that Haskell servers will likely be winning on these benchmarks after Mio is released in 7.8.1? https://news.ycombinator.com/item?id=6198068 https://news.ycombinator.com/item?id=6198068
- Peaker 13y agoSince Warp seems to use many light-weight(green) threads behind the scenes, and Mio is mainly about improving multithreaded performance on actual multi-core set ups, the answer seems to be yes. However, it would probably only help if you use -threaded (which you should, anyways).
- Peaker 13y agoDon't use "runhaskell", it's more of a "script mode". Use: ghc -threaded -O2 main.hs && ./main
- payload 13y agoThere is no significant difference in this benchmark. Do you measure something different?
- dons 13y agoIt is monomorphically typed, however, which limits the use of higher-order functions.
- zemo 13y agothere are first class functions, and closures work the way you would expect. Since it's statically typed and there are no generics, there's no way to implement something like a left fold; you'd have to implement it on a per-type basis, but you could certainly do that. I believe the answer you're looking for is "no", but Go's functions are nothing to sneeze at. http://jordanorelli.tumblr.com/post/42369331748/function-types-in-go-golang http://jordanorelli.tumblr.com/post/42369331748/function-typ...
- masklinn 13y ago> you'd have to implement it on a per-type basis Alternatively you can implement everything on interface{} and force the user of the higher-order function to use type assertions everywhere.
- masklinn 13y ago> Are there first class functions? Anonymous functions? Yes. > If so it seems it would be possible to write highly functional code given the flexibility of interface{} Not really, you'd have to add type assertions everywhere as go has neither generic functions nor user-defined generic types (only a handful of special-status types get to have type parameters, IIRC they're chans, arrays, slices and maps). That makes higher-order operations extremely cumbersome. I'm also uncertain whether scalars (e.g. integral types) can be used through interface{}.
- pcwalton 13y ago> I'm also uncertain whether scalars (e.g. integral types) can be used through interface{}. They can (and there are optimizations to avoid heap allocation in some cases when you do use them), but you still have to write downcasts everywhere.
- miloshadzic 13y agoIt seems to me that Go is incredibly crappy for writing in a functional style. Have a look at Rust if that's what you're after.
- eblume 13y agoI wrote a library for Go that makes functional programming with channels-as-streams very comfortable, for me[1]. There is a problem with needing to box and unbox variables from the 'empty interface{}' type all the time but it's a minor wart IMO. It's a really small library that was made in response to my own intuition (similar to yours) that the Go standard library wasn't really embracing a functional style. I haven't used it in any major projects but for small one-off things it's proved pretty useful. It basically works like pipes on the command line. 1: https://github.com/eblume/proto https://github.com/eblume/proto
- burntsushi 13y agoIf you're interested, I did an in depth write up on how to do it. [1] [1] - http://blog.burntsushi.net/type-parametric-functions-golang http://blog.burntsushi.net/type-parametric-functions-golang