Hacker News new | ask | show | jobs
by jarrett 4444 days ago
Perhaps we have different definitions of OOP. To me, it's not OOP without subclasses and private mutable state. What does OOP mean to you? I'm guessing you're thinking of Haskell's typeclasses as an analogue to Java's interfaces. Any other features?
1 comments

You can implement private mutable state (and dynamic polymorphism behind an interface) with records of closures. Depending on what you mean by "subclasses" here, they may follow trivially. Haskell typeclasses are a poor match to OOP, as you say.
> with records of closures.

Interesting. Can you point me to an example?

http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent

http://okmij.org/ftp/Scheme/oop-in-fp.txt

http://stackoverflow.com/questions/2954642/methods-and-prope...

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-20.html

Some examples. The first is a discussion on it. The second and third have examples in scheme. I'd type more but I'm on my iPad. If I get time later I'll steal time on someone's computer to type up more.

Jtsummers gave some links, but in the interest of having something here:

    data Surface = Surface -- presumably provided by drawing backend
    data Shape = Shape
        { shapeGetCenter :: (Int, Int)
        , shapeSetCenter :: Int -> Int -> Shape
        , shapeDraw :: Surface -> IO ()
        , shapeScale :: Double -> Shape
        , shapeGetAABB :: (Int, Int, Int, Int)
        , shapeShow :: String
        }

    instance Show Shape where
        show = shapeShow

    circle r x y = Shape
        { shapeGetCenter = (x, y)
        , shapeSetCenter = circle r
        , shapeDraw = undefined -- draw shape to surface
        , shapeScale = \ f -> circle (f * r) x y
        , shapeGetAABB =
            ( floor $ fromIntegral x - r/2
            , floor $ fromIntegral y - r/2
            , ceiling $ fromIntegral x + r/2
            , ceiling $ fromIntegral y + r/2
            )
        , shapeShow = unwords [ "circle", show r, show x, show y ]
        }

    box w h theta x y = Shape
        { shapeGetCenter = (x, y)
        , shapeSetCenter = box w h theta
        , shapeDraw = undefined -- draw shape to surface
        , shapeScale = \ f -> box (w * f) (h * f) theta x y
        , shapeGetAABB =
            let w' = h * abs (sin theta)
                    + w * abs (cos theta)
                h' = w * abs (sin theta)
                    + h * abs (cos theta)
             in ( floor $ fromIntegral x - w'/2
                , floor $ fromIntegral y - h'/2
                , ceiling $ fromIntegral x + w'/2
                , ceiling $ fromIntegral y + h'/2
                )
        , shapeShow = unwords [ "box", show w, show theta, show x, show y ]
        }