My two cents

December 19th, 2007

Common Lisp is the most fun programming language I’ve ever programmed in.And I’ve programmed in a few:

  • C
  • Java
  • Python
  • Perl
  • BASIC
  • Haskell
  • Pascal
  • C#

I like Lisp. I think it has a lot to offer. I also think it has a lot of room to grow — so much potential!

People criticize Lisp a lot, especially those who haven’t used it. I also hear a lot of people getting defensive about Lisp, even when someone is trying to give constructive feedback. But I think that we in the Common Lisp community can boost the power and scope of Common Lisp through incremental improvement.

Common Lisp was one of the first high-level languages. Many smart people worked on it throughout its lifetime. It’s no wonder it has been an inspiration for many popular and well-loved programming languages:

  • Smalltalk
  • C
  • Java
  • Perl
  • Python
  • Ruby
  • Haskell
  • and many others . . .

But somehow, a large portion of the community focuses on the fact that other languages are more popular/get more attention. Let’s not focus on such a waste of time. Let’s use the brilliant minds (many of whom were very influential in the history of Lisp) available in the community to actively discover what’s so great about Lisp. And using those discoveries, we can forge new paths down which other languages will eventually follow.

I would like to start with a request for comments.

I’m looking for these things:

  • great features of Lisp — no matter how common, uncommon, big, or small
  • stories that showcase what Lisp has to offer — the stories can be as specific or as general as you like

Popularity: 4% [?]

My XO

December 18th, 2007

I just got my XO on Saturday.

It’s pretty neat.  It’s the lightest computer I’ve ever held.

More about it later . . .

Popularity: 4% [?]

Toolchest: Shortcuts for higher-order functions

December 17th, 2007

Introduction

There’s a balance that a programmer has to find. A good programmer finds the method of expression that best fits his/her need. When there’s a need for the fastest possible code, the programmer finds it. When there’s a need for readable code, he/she will make forgo clever solutions and opt for clarity. When power or expressiveness is required, he/she will use the tools at his/her disposal in harmonious combination.

To know this balance, one must inventory the different methods available. One must know each method’s strengths and weaknesses. And one must be able to see the problem in many ways.

I’m quite interested in the study of the art of programming. I know I try to better myself continually. I often try out different ways of expressing the same functions.

I would like to present some higher-order functions in different representations and analyse the pros and cons of using each type of form. There are some macros used below. I’ve stored the code for them. This post was inspired by (code) vs ‘(data).

(mapcar #'(lambda (x)
		  (* 2 x))
        '(1 2 3))

Plus

  • This is the standard, canonical form for representing one-use functions. Most everyone will understand it.
  • It can represent any kind of function definable, except recursive functions.

Minus

  • It is long-winded for what it does.
  • With the same amount of writing, you might as well do a defun
(loop for x in '(1 2 3)
      collect (* 2 x))

Plus

  • Also a standard. Everyone will understand it.
  • More succinct and direct than the map-lambda.

Minus

  • It neglects the higher-order possibilities.
  • It could be more simple and direct.

Interesting

  • Since this is a simple example, it doesn’t demonstrate the power of the loop macro.
(mapcar #L(* 2 _) '(1 2 3))

Plus

  • Shorter and more succinct.
  • Can work on any form, even a macro. #L(if (evenp _) _ (* 2 _))
  • Most lambdas are single-argument (think find-if, remove-if, mapcar of one list, etc)
  • Recommended by Peter Norvig

Minus

  • It’s not widely used, so it might be hard for someone to understand at first glance.
  • Can only be used for functions of one argument.

Interesting

  • Could someone write one that could figure out _1 _2 . . . _N variables?
(defun double (x)
  (* 2 x))

(mapcar #'double '(1 2 3))

Plus

  • The DEFUN of course will be away from the MAPCAR form — the MAPCAR form is nice and clean.
  • DOUBLE can be used elsewhere.
  • Very readable

Minus

  • Very long for one-off functions.
  • Need a #’ or at minimum ‘

Interesting

  • This is the kind of thing that results from refactoring code.
(mapcar (curry #'* 2) '(1 2 3))

Plus

  • CURRY expresses this function perfectly.

Minus

  • Not very common, so it’s not readable by all.
  • #’ syntax gets in the way.
  • I wouldn’t use it since the form is a bit clunky.

Interesting

  • Curry is a mathematical idea.
;; Where #R expands to a CURRY form.
(mapcar #R(* 2) '(1 2 3))

Plus

  • No #’.
  • (* 2) looks like a function call
  • Very short
  • Composable with COMPOSE macro below
  • I would use this

Minus

  • Not widely used — it makes it harder for others to understand it at first glance.

I would also like to analyze

(mapcar #'(lambda (x y)
            (abs (/ x y)))
        '(1 -2 3 -4)
        '(2 -9 -8 2))

Compared to

(mapcar (compose #'abs #'/)
        '(1 -2 3 -4)
        '(2 -9 -8 2))

Plus

  • COMPOSE expresses this function perfectly. Function composition is precisely what you want.

Minus

  • Not very common, so it’s not readable by all at first glance.
  • #’ syntax gets in the way.
  • I wouldn’t use this, either

Interesting

  • Function composition is also a mathematical idea.
;; #M expands to compose form
(mapcar #M(abs /)
        '(1 -2 3 -4)
        '(2 -9 -8 2))

Plus

  • COMPOSE expresses this function perfectly.
  • Smaller and simpler than the full COMPOSE form
  • No #’
  • I would use this.
  • Composabe with CURRY macro above

Minus

  • Not very common, so it’s not readable by all.

Related Posts

My two cents

My XO

Popularity: 4% [?]