Thinking in FP vs OOP for large scale apps => Re: [plt-scheme] Imperative programming : missing the flow

From: YC (yinso.chen at gmail.com)
Date: Tue May 15 17:59:43 EDT 2007

Hi all -

thanks for the excellent discussion. I have a related question, but from
probably the opposite perspective, given I come from OOP world:

How to think in FP rather than OOP, especially for large scale apps?

This question is of course general/meta, but would love to hear
commentary/experiences on how to fully think in FP rather than OOP, and also
perhaps, how not to think in types (i.e. the question is about Scheme's
"lack" of types so to speak).

OOP to me provides a nice way to organize related code and data together, in
a stronger relation than module.  The OOP world I am familiar with (i.e. C#,
etc) also has strong notion of typing.  Combined together, one can ensure
that the data in an object is "type safe", i.e. validation/conversion has
taken place as part of object construction.  Once an object is constructed,
it is safe to pass around, etc., and we know that class methods are always
safe to call on an object of the type.

FP on the other hand seems less tightly coupled, and that means a couple of
things to me:

   1. I have to explicitly pass the object around
   2. I have to type check the object if the function can only handle
   some specific types, i.e. (cond ((type-a? obj) ...) ...)

These things are not big deal for small applications, but for bigger apps it
seems to be quite cumbersome to have to do all these different checks
everywhere.  And that gives me a feeling that I don't have it right, yet.

I came across the notion that classes/objects can be modeled by closures and
indeed had some fun trying to write my own class generator as an exercise,
but then I have to wonder if I am missing a big picture somewhere - i.e.
would I do "better" (i.e. fewer lines of code, higher conceptual
abstraction) with raw FP rather than OOP for large scale app?  Would
problems like object-relational mapping go away (a very cumbersome
procedure)? etc.

So perhaps, as an example - an enterprise app with hundreds of tables in a
database.  In OOP each table would be mapped to a class, and the code mostly
deals with converting user input to objects that are then translated to
query for the database.  The business logic then concerns with manipulation
of the objects between the layers.  It is obvious that in such a system
there are a ton of boiler plate code, and that's what Java is famous for.

How does FP model the above example differently?

Any input is appreciated ;)  Thanks,
yinso

On 5/12/07, Anton van Straaten <anton at appsolutions.com> wrote:
>
> John Clements wrote:
> > I'm teaching Java to first-year students, and we're about to walk off  a
> > cliff and start programming imperatively.  I've done this  transition
> > several times now, and it occurs to me that what's most  irritating to
> > me about the imperative style is the lack of "flow".
> >
> > What do I mean by flow?  Simply that each expression produces a  result
> > that is used by another expression.  In imperative  programming, by
> > contrast, I feel that I have a bunch of statements  lying on the floor,
> > and that their order is both important and  difficult to explain
> clearly.
>
> Perhaps this is too obvious to mention in the present company, but since
> you didn't mention it, the world-passing (monadic) view of imperative
> programming might provide a useful perspective.  It provides an easily
> understood theory (at a high level) of imperative programming, which
> lets you compare imperative programs to functional programs using a
> common model.  (Admittedly, the model is skewed in favor of the
> functional approach, but I'm guessing you won't object to that.)
>
> The resulting explanations end up not being all that different from
> those that have already been given, but introducing "the world" as a
> first-class feature of the explanatory model helps to discuss and reason
> about the issues.
>
> For example, the world-passing perspective explains why the imperative
> puzzle pieces (statements) that Joe described are perfect squares: the
> only functional/algebraic dependency between statements is "the world",
> so there's no way to fit statements together based on what kind of value
> they consume and produce -- they all consume and produce a version of
> the world.
>
> Another point is that every statement in an imperative program can
> change the value of any currently visible variable in the world.  In
> contrast, a functional program can only "change" the value of variables
> at function application time.  So every single imperative statement is
> like a function in its own right, which complicates reasoning.
>
> If the students can handle a functional model of an imperative program
> looking something like:
>
>    ((lambda (world) stmt-n)
>     ((lambda (world) ...)
>      ((lambda (world) stmt-1)
>       '())))
>
> ...then there are quite a few concrete points and comparisons that could
> be made with it.  It's also good preparation for teaching monads later...
> :)
>
> Anton
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070515/70f0c10d/attachment.html>

Posted on the users mailing list.