1. 8
  1.  

  2. 3

    There’s an analogous, more compelling post for this to be had for OCaml and Haskell.

    Not to mention what we do with free monads in Haskell.

    Edit: Since I got an upvote, I’m going to expand on this a little.

    In the case of OCaml, there’s baked-in support for structural typing of ADTs, this means an analogous post would have a pretty direct correlate with the Golang stuff. However, it’d be more type-safe and a fair bit nicer.

    With Haskell there’s…a lot I could draw from. Free monads can be used all over the place, but have the most direct application when we’re working with something that can be modeled as an AST. The AST itself is just a vanilla Haskell data type and not stringly Map[String, Blah] nonsense. From there, we can separate our “transformation” from our “reduction” (execution).

    In so doing, we can lift the possibility of side effects out of transformation-oriented code and implement multiple alternate reductions for the same ADT. In so doing, we’ve essentially achieved a (rare) non-masturbatory form of mocking.

    How/why? Because with multiple reductions for the same free monadic ADT, the “live” version can perform side effects, but we can interpret the ADT in a different way in testing.

    Imagine a data type for a networking library. Instead of having the reduction of instructions to fire off data into real TCP sockets baked into all the code, that could just be one reduction. Another could just log who sent what and received what. That “pure” reduction of the networking code could then be used to simulate and test hypothetical scenarios like delays, packet loss, all kinds of things by running the log through a supervisor that decides who sees what.

    Better explained by Gabriel here: http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html

    Anyway, Haskell has typeclasses too and they’re, for the purposes of people that don’t know any better, like a better interface. So yeah, you could test stubbing via typeclasses as well.

    Though, Haskellers generally don’t do everything in terms of final encodings unless they’re anticipating a lot of representational variability in their data types.

    1. 0

      How is this different than any other model that allows interfaces?

      EDIT:

      For those downvoting me, the article implies there is something unique about Go’s solution. The first paragraph states:

      Go’s “object-orientation” approach is through interfaces. Interfaces provide a way of specifying the behavior expected of an object, but rather than saying what an object itself can do, they specify what’s expected of an object. If any object meets the interface specification it can be used anywhere that interface is expected.

      Except for the last sentence, you could replace Go with Java and this would be true. Java has heavily pushed interfaces since its first appearance in 1995. And in the context of the article, the structural typing is mostly irrelevant anyways.

      This is hardly a knock against Go, however it is false to imply that this is a feature special to Go or popularized or made easier by it.

      1. 3

        I did this last Wednesday in Java, which makes it very clear why Golang’s approach is superior. I have a network client library from a service vendor that provides a Client class that talks to their server, and I was writing a Thing that runs on top of the Client. I wanted to write tests to make sure my Thing does the right things to their Client, but without actually sending any messages to their server.

        Problem is, the methods my Thing wants to call on their Client aren’t declared in any interface. And there are 48 of them. What are my options?

        1. Write a script in Perl or Python to generate a ClientWrapper class that does implement a new IClient interface (with 48 methods; I can generate this either with the same Perl script, or by using Eclipse’s Extract Interface) and passes through calls to all of these methods to the corresponding method of the Client. Then I can write a TestClient that also implements IClient.
        2. Use Java reflection to do the same thing, but dynamically. I’m not even sure if this is possible using the standard reflection interfaces. I think I’d end up generating JVM bytecode.
        3. Munge the vendor-provided code by running Eclipse’s Extract Interface on it, so that I don’t need a wrapper class, and repeat the exercise every time we update the vendor library.

        I took the last option. Fortunately I had the source code. Doing this without the source code would be even more of a pain.

        And yes, it’s true that in OCaml’s OO subset, this would be even easier; the compiler simply infers the interface if you don’t specify it. But I think it’s quite fair to say that this is a feature both popularized and made easier by Golang.

        1. 3

          For those downvoting me, the article implies there is something unique about Go’s solution.

          Does it? I sure missed that - to me, this read as a pretty basic article that says “here’s how you can easily stub out a test in Go.”

          however it is false to imply that this is a feature special to Go or popularized or made easier by it.

          The title doesn’t claim that and the article doesn’t claim that. While I can’t speak for jpadilla, I don’t think they are implying it either.

          Who is making that implication?

          1. [Comment removed by author]

            1. 5

              Actually, I take this last post back. This is an example of me being a pretentious unhelpful asshole. I think it would have been great if the author framed it in terms of the strengths of structural typing, which is available in a few languages in different forms, but my post was pretty douchey IMO. Sorry everyone.

              1. 1

                We all get grouchy sometimes, especially when we feel like the contributions of Our Tribe (be it functional programmers, recruiters, or Chinese-Americans) are being minimized or ignored.