Rcjp's Weblog

July 23, 2006

Creating Functions

Filed under: c, lisp — rcjp @ 2:34 pm

In the introduction of Paul Graham’s ANSI Common Lisp he writes that you can’t do the following in C


(defun addn (n)
  #'(lambda (x) (+ x n)))

(setf add-ten (addn 10))
(setf add-twenty (addn 20))

(format t "value ~d~%" (funcall add-ten 4))
(format t "value ~d~%" (funcall add-twenty 4))

(This will print 14 and 24). Although you can have function pointers in C, there isn’t really a convenient place to store the captured n variable. You can use a global variable, but that will get overridden by another function


#include <stdio.h>

int nglobal = 0;
int addn(int n) { return (n+nglobal); }

int main()
{
    int (* myfunc)(int);

    nglobal = 10;
    myfunc = addn;

    printf("value %d\n", (* myfunc)(4));
    return 0;
}

you can get further with C++ though by using a class instance variable


#include <iostream>

class addn
{
  int nInstance;
public:
  addn(int n) : nInstance(n) {}
  int operator()(int i) {return nInstance + i;}
};

int main()
{
  addn add_ten(10);
  addn add_twenty(20);

  std::cout << "value " << add_ten(4) << std::endl;
  std::cout << "value " << add_twenty(4) << std::endl;
  return 0;
}

but it is clumsy compared to the Common Lisp. The C++ function objects in the standard library aren’t particularly pretty either, compare:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;
    v.push_back(5);
    v.push_back(4);
    v.push_back(11);
    v.push_back(14);

    // count numbers less than 10

    std::cout << count_if(v.begin(),  v.end(),
                 bind2nd(std::less<int>(),  10)) << std::endl;
}


in python

In [9]: sum(itertools.imap(lambda x: x<10, [5,4,11,14]))
Out[9]: 2


and in Common Lisp this is just

(count-if (lambda (x) (< x 10)) '(5 4 11 14))

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: