Subject: RE: [hackers-il] Functional Programming to Become the State of th e Art - ?

From: Omer Musaev <[email-masked]>
Date: Mon, 11 Feb 2002 17:03:40 +0200

> -----Original Message-----
> From: Shlomi Fish [mailto:[email-masked]]
> Sent: Monday, February 11, 2002 7:21 AM
> To: Hackers-IL
> Subject: [hackers-il] Functional Programming to Become the 
> State of the
> Art - ?
> 
>
 
> One paradigm that still did not gain global acceptance and 
> recognition
> outside the academia is Functional Programming (or FP for short).

Main reason for that, IMHO, is poor mapping of FP methodologies to
real world problems. For example, if you have IO, you will have side
effects. That limits use of FP practice in real-world problems to 
kernels of programs. In my humble opinion the further computational
abstraction goes from underlying architecture, the less practical 
value it bears. For that reason, FP did not take commercial software
by storm.

> Many languages in use today are FP (Scheme, Perl), and some are 
> even purely FP
> (ML, Haskell). I believe following FP guidelines help make 
> the code more
> modular and maintainable, so I think it eventually will be 
> considered an
> elmentary programming paradigm such as OOP.

What makes you think that FP makes code more modular?
Do you mean typed FP or untyped FP? From my experience, typed FP 
leads to loss of generality, while untyped FP leads to unmaintainble code.
For example:

(define fact
  (lambda (n)
    ((lambda (c)
       (((c (lambda (p)
              (lambda (x)
                ((x (lambda (x)
                      (lambda (y)
                        (x (((p (lambda (x)
                                  (lambda (y) x))) x) y)))))
                 (((lambda (a)
                     (lambda (b)
                       ((b (lambda (b)
                             (lambda (s)
                               (lambda (z)
                                 ((a s) ((b s) z))))))
                        (lambda (x) (lambda (y) y)))))
                   (p (lambda (x) (lambda (y) x))))
                  (p (lambda (x) (lambda (y) y))))))))
 (lambda (x)
 ((x (lambda (x) x)) (lambda (x) x))))
        (lambda (x) (lambda (y) ((y (lambda (x) (+ x 1))) 0)))))
     (((lambda (f)
         ((lambda (m)
            (f (lambda (x) ((m m) x))))
          (lambda (m)
            (f (lambda (x) ((m m) x))))))
       (lambda (f)
         (lambda (n)
           (if (zero? n)
               (lambda (x) (lambda (y) y))
               ((lambda (f)
                  (lambda (x)
                    (lambda (y)
                      (x ((f x) y)))))
                (f (- n 1)))))))
      n))))                            

Note: this code was created by Meir Goldberg from BGU.

> Now for some examples and use cases:
> 
> 1. Pointers to functions in C are a pseudo-FP element. Many C++
> programmers tend to overlook their importance, and think that 
> one should
> inherit a class, in order to create a callback. While callbacks as
> pointers to functions or as derived classes are interchangeable,
> _thinking_ about them as functions is important.

I did not quite understood this statement. C++ has more expressive
power than C, and inheriting a functor interface has much more 
power than implementing a function pointer. I understand that there
are plenty of C++ programmers who do not use C++ fully, but, it's 
their fault...

In other words, passing pointer to function is very rude way to 
compose actions, as far as C++ is used. In C you do not have many
alternatives, but in C++ you do. In that light, I think I can 
understand refusal of using pointer to functions in C++ code. 

> In Freecell Solver for example, I wrote several test functions, each
> performing a different type of moves. The user could choose 
> the order in
> which those tests were performed. Furthermore, several scans 
> were written,
> each one using the tests differently.

This is Command pattern, not FP. 

> 2. It is obvious that coding a map, filter, accumulator, etc -like
> functions in C would have a large amount of overhead. However, one
> could possibly use code generators that abstract such steps into
> combined loops based on a template. I don't remember if the 
> UML standard
> gives way to doing it, but I think it should. It is possible 
> that one can
> read (say) Scheme or Perl code and compile it into an 
> optimized C code.
> (or does Forth supports such constructs?)

However, coding map, filter, accumulator etc in C++ is straightforward
and easy - for example:

;; (define (fabs x)(if (> x 0 ) x (* -1 x ) ) )
;; (set! results (map fabs (list 1 2 3 4 -1 -2 -10 ) ) )

vector< int > ints = { 1, 2, 3, 4, -1, -2, -10 } ;
vector< int > results ;
transform( ints.begin(), ints.end(), back_inserter( results ), fabs ) ;

;; (define (^acc) (let ((sum 0)) 
;;                (lambda (c n) 
;;                   (cond (
;;                           ((equal c '+)(set! sum (+ sum n )))
;;                           ((equal c '=)sum)))))
;; (define acc (^acc))
;; (apply (lambda (x)(acc '+ x))(list 1 2 3 4 5)
;; (acc '= '_ ) 

vector< int > ints = { 1, 2, 3, 4, 5 } ;

template<class T> 
class Acc { 
   T _sum ; 
public: 
   Acc() :_sum(0)       {} 
   void operator()(T x) { _sum += x ; }
   T sum()              { return _sum ; }
 };

Acc<int> acc ;

for_each( ints.begin(), ints.end(),  ); 

Note that the above was not compiled, since I am writing it out of my head.
However, the point is - yes, working with functional entities as data is 
widely used, and therefore accepted:)

> 3. Passing a void * context variable to a function emulates a 
> closure in a
> way. I believe that by having an void * upper_context pointer 
> there, one
> can have a certain lexical scoping-feel to the code. I.e:
> 
> void myfunc(int , void * h)
> {
> 	h = (mystruct *)h
> 	.
> 	.
> 	.
> 	new_context = malloc(sizeof(mynewstruct));
> 	new_context->up_context = h;
> 	/* Fill new_context with other stuff */
> 
> 	newfunc(.... , new_context);
> }
> 
> (can anybody point me to an LC code in C++ or in C, that way?)
> 

In C++ there are functors for that purpose.

> 4. Recursion - obviously an FP methodology, which is now a very common
> practice.
> 
> And it goes on. Naturally, some languages support FP much better than
> other languages. I can easily write FP code in Perl, but will 
> have a hard
> time writing it in COBOL. (it's not impossible to write it there, just
> very hard)

> This is my impression of what will happen. I cannot guarantee 
> that it will
> happen anytime soon, because prophecy was taken from the prophets and
> given to fools. However, I believe knowledge and experience 
> in FP can help
> someone produce better code. (refer to SICP) And naturally, many
> techniques that originated in the functional world, can be 
> applied this
> way or another in real-world apps.
> 

> Regards,
> 
> 	Shlomi Fish
> 
> 
> ----------------------------------------------------------------------
> Shlomi Fish        [email-masked]
> Home Page:         http://t2.technion.ac.il/~shlomif/
> Home E-mail:       [email-masked]
> 
> "Let's suppose you have a table with 2^n cups..."
> "Wait a second - is n a natural number?"
> 
> 
> ------------------------ Yahoo! Groups Sponsor 
> ---------------------~-->
> Tiny Wireless Camera under $80!
> Order Now! FREE VCR Commander!
> Click Here - Only 1 Day Left!
> http://us.click.yahoo.com/nuyOHD/7.PDAA/yigFAA/saFolB/TM
> --------------------------------------------------------------
> -------~->
> 
> To unsubscribe from this group, send an email to:
> [email-masked]
> 
>  
> 
> Your use of Yahoo! Groups is subject to 
> http://docs.yahoo.com/info/terms/ 
> 
>