Monday, June 3, 2013

Why I'm happy to live without generics in go (for now)

I was at GoSF last month (9th May) when Andrew Gerrand gave his talk on go 1.1. At the end of the talk a couple of questions came up on the subject of generics. You can see them on this video at 1:09:20 and 1:14:40. (The questions aren't audible, but the answers are)

If you don't want to watch the video (you should) the summary (and I'm paraphrasing alot here) was essentially that it's not that anyone is trying to keep generics out of go, but rather no one has found a nice way of putting them in. Andrew went on to mention that he didn't miss them at the moment as copying and pasting a few for loops and if statements was an ok alternative.

I nodded in agreement at the time, but last week I proved it to myself in code, so I thought I'd blog about it. I found myself wanting to add up the value of some things in a list, here's a very trivial substitute for the actual code:
It's nothing ground breaking, you could say I'm folding (or reducing) over the list, you could also just say I'm adding up the price of all the things. It would be nice to have a generic fold that I could use to explicitly say that I'm folding over the list, but what advantage would this give me?

I probably wouldn't just call fold by iteself, i'd probably still put fold inside the TotalPriceOfBasket function so that I can state the purpose more explicitly, and the reader would be left with a much simpler looking function, but - and here's my point. fold, map, filter should be recognisable as patterns. You should be able to look at a function and say "Of yeah, a fold, ok"

I'm not making any statements here about how useful generics are or aren't. or how useful a fold/map/filter function would be in go, all I'm saying is that I can live without them for now. Especially as the reason they're not currently in the language is that the core contributors haven't found a good way of implementing them. There's a lot to be said for that approach.

9 comments:

  1. I personally would prefer `func (basket Basket) TotalPrice(basket Basket) int {` and then call it like `basket .TotalPrice()`. That makes it more easy to read and program and also reduces the verb `TotalPriceOfBasket` to just `TotalPrice`.
    Just my 2 cents.

    ReplyDelete
    Replies
    1. You must be coming from OOP world, and bringing the concept of messages and objects ;-)

      Delete
    2. Yeah, that isn't the go way. Go is procedural, so a "best practice" such as that doesn't fit

      Delete
    3. Yeah, if it's a feature the language provides, why not?

      Delete
  2. Is it not more efficient to pass a reference to the basket?
    func TotalPriceOfBasket(basket *Basket) int
    or if you will
    func (basket Basket) TotalPrice int

    ReplyDelete
    Replies
    1. I mean of course:
      func (basket *Basket) TotalPrice int

      Delete
  3. So in javascript the code will look like
    ```
    const basket=[{id:"Apples",price:5},{id:"Orange",price:6}]
    const total = basket.reduce((totalPrice,current) => { return totalPrice+=current.price},0)
    console.log(`Total:${total}`)
    ```

    ReplyDelete
  4. const total = basket.reduce( (total,current)=>total+curren.price, 0 );

    ReplyDelete