atheorist (atheorist) wrote,

dataflow / class diagram duality

Class diagrams in UML (for my purposes) have boxes, two kinds of arrows (isa and hasa) between boxes, and methods, which are essentially strings, inside the boxes. Class diagrams correspond to object-oriented code in that each box probably has a section of code corresponding to it, each method probably has a section of code corresponding to it, and each arrow leaving a box indicates a collaborator that will need to be considered.

Objects can be encoded into functional languages like ML or Haskell by an object-closure correspondence. Where the object-oriented code creates a new object, the functional code would define a new functional value, using a lambda. Where the object-oriented code invokes a method on an object, the functional code calls a function value. In order to model method dispatch, the functional code might call a function value representing the object as a whole, passing a known-at-compile-time value of an enumerated type as an argument, and then call the returned (function) value with the arguments of the method, something like this:

  v(PRINT)('hello %s', {'world'});

If you have functional code, but you need object-oriented code, then you can go the other way. (This is called defunctionalization, and the experts to google and read are Danvy and Reynolds.) For each function value constructed in the source code, you need a constructor, and usually a class. (Multiple constructors on the same class is possible, but dubious if you're shoehorning, and unlikely if you're not shoehorning.) The lexically-scoped variables Then you need to study the dataflow, and find out where the function value will be consumed (applied). That will give you your method name. Generally the dataflow looks like a river - several tributaries coming together to one port where the river ends. In statically typed object-oriented languages like C++ or Java, that means that you will need an interface (or pure virtual abstract class, same difference), corresponding to the consumption point. Then each of the origin points will need to declare that they implement that interface.

tl;dr - you can recognize "wannabe-functional" code in an OO language from the class diagram - it has a bunch of one-method classes, often in little groups (an interface and its several concrete implementations).

  • Post a new comment


    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.