Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does learning one Lisp help in learning the other?

Is there any synergy between learning different Lisp languages? I'm currently learning Emacs Lisp, as it is immediately useful in my daily Emacs usage, however i'm fascinated with all Lisps, so maybe someday i will learn and use others. Will learning Emacs Lisp help me, when i start digging in Common Lisp, Scheme or Clojure? In other words, will it be for me like learning a completely new language, or some notions and paradigms are common? I'm also interested in comparison of unique differences between the Lisps, which will be a problem, when i come from one Lisp to another.

In How to go about learning Common Lisp and Emacs Lisp? it is mentioned that there will be "wastage", but it is not elaborated, to what degree.

like image 427
Mirzhan Irkegulov Avatar asked Jun 28 '12 11:06

Mirzhan Irkegulov


People also ask

Is it useful to learn Lisp?

To me, what makes Lisp great is the fact how it generalizes the interaction between you and the machine. Basically everything that we as programmers do is to interact with data (programs being data for compilers), which Lisp makes almost indistinguishable from the code itself.

What makes Lisp so powerful?

Key Points. Lisp empowers programmers to write faster programs faster. An empirical study shows that when programmers tackle the same problems in Lisp, C/C ++ and Java, that the Lisp programs are smaller (and therefore easier to maintain), take less time to develop and run faster.

What is the purpose of inventing Lisp?

Lisp was originally created as a practical mathematical notation for computer programs, influenced by (though not originally derived from) the notation of Alonzo Church's lambda calculus. It quickly became the favored programming language for artificial intelligence (AI) research.

Is Common Lisp faster than C?

It should be possible, however, to draw some generic qualita- tive conclusions. The most important result from these experiments is that Common Lisp may be faster than C for a high number of evaluations, while the situation is the opposite for low num- bers of evaluations.


2 Answers

If you want to learn some older basics of Lisp, then Emacs Lisp is fine.

  • Emacs Lisp: can be used in Emacs. Development environment included. Older dialect of the mainstream Lisp. Lacks a lot of concepts. Has many extensions for editor programming. Common Lisp and Emacs Lisp share some direct heritage (naming, concepts, ...).

  • Common Lisp. Lots of good books to learn from. Lots of Lisp concepts (including OO programming) can be learned with Common Lisp. Highly recommended. Common Lisp has the most important Lisp facilities built-in and libraries provide the rest. There is a large amount of stuff which can be learned around it.

  • Scheme: different Lisp dialect created in the 70s. Not directly compatible with Emacs Lisp or Common Lisp. Lots of excellent books and other tutorial material. Highly recommended for learning Lisp basics and some more advanced things. The deeper you dig into Scheme the more it looks different from Emacs Lisp or even Common Lisp.

  • Clojure: very different Lisp dialect. Not compatible with Common Lisp, Emacs Lisp or Scheme. Shares some concepts, some concepts work differently. Good books. Recommended if you want to learn some Lisp or specially Clojure. Clojure puts emphasis on functional and concurrent programming - very relevant topics.

If you want to learn more mainstream Lisp (a Lisp that with a look and feel of a typical Lisp dialect), I would recommend Common Lisp or Scheme.

My language preference for learning Lisp (!) would be:

  1. Common Lisp
  2. Scheme
  3. Clojure
  4. Emacs Lisp

To give you an example:

This is the COLLAPSE function from McCarthy's Lisp, written in 1960 (from the Lisp I Programmer's manual, 1960, page 101). It is basically what in many Lisp exercises is the FLATTEN function. It takes a nested list and returns a new list with the atoms in a single list.

DEFINE
(((COLLAPSE,(LAMBDA,(L),(COND,
   ((ATOM,L),(CONS,L,NIL))
  ((NULL,(CDR,L)),
     (COND,((ATOM,(CAR,L)),L),(T,(COLLAPSE,(CAR,L)))))
   (T,(APPEND,(COLLAPSE,(CAR,L)),(COLLAPSE,(CDR,L)))))
))))))

This is the Common Lisp version. You can keep it in uppercase or convert it to lowercase. Both works.

(DEFUN COLLAPSE (L)
  (COND 
   ((ATOM L) (CONS L NIL))
   ((NULL (CDR L))
    (COND ((ATOM (CAR L)) L)
          (T (COLLAPSE (CAR L)))))
   (T (APPEND (COLLAPSE (CAR L))
              (COLLAPSE (CDR L))))))

It is basically the same. Only the form for defining functions has a different name and syntax. Otherwise the code is completely identical.

Try McCarthy's example in Common Lisp:

CL-USER > (COLLAPSE '(((A B) ((C))) ((D (E F)) (G) ((H)))))
(A B C D E F G H)

It runs.

Now let's try it in Emacs Lisp, using GNU Emacs. Emacs Lisp has lowercase identifiers:

ELISP> (defun collapse (l)
         (cond 
           ((atom l) (cons l nil))
           ((null (cdr l))
            (cond ((atom (car l)) l)
                  (t (collapse (car l)))))
           (t (append (collapse (car l))
                      (collapse (cdr l))))))

ELISP> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)

It runs in Emacs Lisp without changes.

You can get similar versions going in Scheme (minor renamings):.

Here in Petite Chez Scheme:

> (define collapse
    (lambda (l)
      (cond 
        ((atom? l) (cons l '()))
        ((null? (cdr l))
         (cond ((atom? (car l)) l)
               (else (collapse (car l)))))
        (else (append (collapse (car l))
                      (collapse (cdr l)))))))

We can use DEFINE to define a function. COND looks slightly different. () is the empty list. Predicates have an ? added.

> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)

Runs.

In Clojure it would look different. Basically you have to rethink much of the code.

This is Clojure's own implementation of flatten:

(defn flatten
  [x]
  (filter (complement sequential?)
          (rest (tree-seq sequential? seq x))))

You can write a flatten in spirit of the Lisp version - it would still look different.

From rosetta.org:

(defn flatten [coll]
  (lazy-seq
    (when-let [s  (seq coll)]
      (if (coll? (first s))
        (concat (flatten (first s)) (flatten (rest s)))
        (cons (first s) (flatten (rest s)))))))

Names are different, syntax is different, semantics is different (works on lazy sequences instead of lists).

Dialects like Common Lisp, Emacs Lisp, Visual Lisp, ISLISP and others try to keep the heritage.

Dialects like Scheme or Clojure felt not bound to the names and the syntax. They innovated in various directions. Scheme still provides direct versions of the old functionality. Clojure does not. Clojure programmers won't see this as an disadvantage.

like image 146
Rainer Joswig Avatar answered Sep 20 '22 15:09

Rainer Joswig


Yes - it is significantly easier to pick up a new Lisp if you know one already.

Reasons:

  • You'll understand the concept of "code is data" and metaprogramming in a homoiconic language (this is arguably the biggest single thing that makes Lisps unique / distinctive from other languages)
  • You'll be able to read Lisp syntax much more easily. It takes a few weeks to get to the point where you "see" the structure of Lisp code, but after that point it gets much easier. You start to ignore the parentheses after a while.
  • The development style is similar, interacting with a running environment using a REPL
  • They share common idioms, e.g. the use of lists and various functional programming techniques
like image 25
mikera Avatar answered Sep 18 '22 15:09

mikera