[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: reading material?
From: |
Julian Squires |
Subject: |
Re: reading material? |
Date: |
Mon, 22 Mar 2004 14:41:44 -0500 |
User-agent: |
Mutt/1.4.1i |
On Mon, Mar 22, 2004 at 12:51:12PM -0600, Douglas A Linhardt wrote:
> Agreed. We're off target. And I'm not trying to start a flame war.
> I really don't want to start an argument. I just want to I promise
> not to post any more to this thread (unless, of course I change my
> mind ;) ).
Please don't take any of my comments on this as being flames in any way,
either. But I can't resist a good language debate.
> > First-class means first-class citizens, that is, objects of that type
> > can be used in all language constructs just like other objects. For
> > example, a function that returns a function in Scheme is natural,
> >
> > (define (iterate func k)
> > "Produce the function x -> FUNC(FUNC .. (x) .. ) "
> > (if (> k 0)
> > (lambda (x) (func ((iterate func (1- k)) x)))
> > (lambda (x) x)))
> >
> > (define to-6th-power (iterate sqr 3))
...
> The C++ solution is both natural and elegant. Two example solutions
> follow, the first not using templates, the second using templates. By
> the way, my favorite reference for using the Standard Template
> library, as well as things like these functor classes, is Nicolai M.
> Josuttis, "The C++ Standard Library", 1999.
Frankly, I would suggest that after studying some of these languages
more, particularly ocaml, haskell, and common lisp, you might have a
different attitude.
What you did idiomatically in 34 lines, he did idiomatically in 7 lines,
counting whitespace and comments. Also, his version has no problems if
the function takes a string instead of an int, for example. And, if it
were written in ocaml, like so:
let rec iterate f k =
if k == 0 then fun x -> x
else iterate (fun x -> f x) (k - 1)
;;
let sqr x = x * x;;
let laugh x = x ^ "ha";;
Then one can do:
let pow_8 = iterate sqr 3;;
let guffaw = iterate laugh 5;;
Printf.printf "%d %s\n" (pow_8 2) (guffaw "bwa");;
and yet, (guffaw 2) or (pow_8 "bwa") will be detected as an error at
compile time, not run-time.
Now imagine you'd like to iterate (really, composite) functions with
various type signatures. Or partially apply a function, like:
let nonsense prefix suffix = prefix ^ "bar" ^ suffix;;
let n = nonsense "foo";;
Printf.printf "%s\n" (n "baz");;
These are just a few things among many that are much more arduous to do
in C++, certainly more lengthy, when one's time is better spent on
better tasks than housekeeping.
[Let's hope all that code is correct, I haven't checked it carefully...
hopefully you get the point. ;-)]
Arguments like these can go on forever, but truly, (and I feel sad for
saying this, as I'll explain momentarily,) I recommend some of Paul
Graham's essays:
http://www.paulgraham.com/avg.html
or
http://www.paulgraham.com/icad.html
I give the caveat that when I came across the first, I was highly
skeptical, and though I still don't agree entirely with what Graham is
saying, it wasn't until I spent a while writing some serious code in a
few languages more expressive than C++ that I finally conceded that he
has a point.
I still have to write a lot of C++ at work, but at least now I know
better than to propose it when I have the choice.
Cheers.
--
Julian Squires
Re: reading material?, Heikki Johannes Junes, 2004/03/23
Re: reading material?, Heikki Johannes Junes, 2004/03/24