2012-06-28 24 views
8

Có sự kết hợp nào giữa việc học các ngôn ngữ Lisp khác nhau không? Tôi hiện đang học Emacs Lisp, vì nó ngay lập tức hữu ích trong việc sử dụng Emacs hàng ngày của tôi, tuy nhiên tôi mê hoặc với tất cả Lisps, vì vậy có lẽ một ngày nào đó tôi sẽ học và sử dụng những người khác. Liệu việc học Emacs Lisp có giúp tôi không, khi tôi bắt đầu đào bới Common Lisp, Scheme hoặc Clojure? Nói cách khác, nó sẽ cho tôi như học một ngôn ngữ hoàn toàn mới, hoặc một số khái niệm và mô hình là phổ biến? Tôi cũng quan tâm đến việc so sánh sự khác biệt duy nhất giữa Lisps, đó sẽ là một vấn đề, khi tôi đến từ một Lisp khác.Có phải học một trong những Lisp giúp đỡ trong việc học khác?

Trong How to go about learning Common Lisp and Emacs Lisp? nó được đề cập rằng sẽ có "lãng phí", nhưng nó không được xây dựng, đến mức độ nào.

+4

* Thực hiện * Lisp của bạn chắc chắn sẽ giúp ích trong việc học các Lisps khác. –

Trả lời

15

- việc nhận một Lisp mới mới dễ dàng hơn nếu bạn biết.

Lý do:

  • Bạn sẽ hiểu khái niệm về "mã là dữ liệu" và Lập trình meta trong một ngôn ngữ homoiconic (điều này được cho là điều duy nhất lớn nhất mà làm cho Lisps độc đáo/độc đáo từ các ngôn ngữ khác)
  • Bạn sẽ có thể đọc cú pháp Lisp dễ dàng hơn nhiều. Phải mất một vài tuần để có được đến điểm mà bạn "nhìn thấy" cấu trúc của mã Lisp, nhưng sau thời điểm đó nó được dễ dàng hơn nhiều. Bạn bắt đầu bỏ qua các dấu ngoặc đơn sau một thời gian.
  • Kiểu phát triển tương tự, tương tác với môi trường đang chạy bằng cách sử dụng REPL
  • Chúng có chung thành ngữ chung, ví dụ: việc sử dụng danh sách và các kỹ thuật lập trình chức năng khác nhau
18

Nếu bạn muốn tìm hiểu một số thông tin cơ bản cũ hơn của Lisp, thì Emacs Lisp vẫn ổn.

  • Emacs Lisp: có thể được sử dụng trong Emacs. Môi trường phát triển bao gồm. Phương ngữ cũ hơn của dòng chính Lisp. Thiếu rất nhiều khái niệm. Có nhiều phần mở rộng cho lập trình soạn thảo. Lisp và Emacs Lisp thường chia sẻ một số di sản trực tiếp (đặt tên, khái niệm, ...).

  • Lisp thông thường. Rất nhiều sách hay để học hỏi. Rất nhiều khái niệm Lisp (bao gồm lập trình OO) có thể học được với Common Lisp. Rat khuyen khich. Lisp thường có các cơ sở Lisp quan trọng nhất được xây dựng trong và các thư viện cung cấp phần còn lại. Có một lượng lớn thứ có thể học được xung quanh nó.

  • Đề án: phương ngữ Lisp khác nhau được tạo trong thập niên 70. Không tương thích trực tiếp với Emacs Lisp hoặc Common Lisp. Rất nhiều sách hay và tài liệu hướng dẫn khác. Rất khuyến khích cho việc học cơ bản Lisp và một số điều cao cấp hơn. Bạn càng đào sâu vào Scheme thì nó càng khác với Emacs Lisp hoặc thậm chí là Common Lisp.

  • Clojure: phương ngữ Lisp rất khác. Không tương thích với Common Lisp, Emacs Lisp hoặc Scheme. Chia sẻ một số khái niệm, một số khái niệm hoạt động khác nhau. Nhưng quyển sách tốt. Đề nghị nếu bạn muốn tìm hiểu một số Lisp hoặc Clojure đặc biệt. Clojure nhấn mạnh vào lập trình chức năng và đồng thời - các chủ đề rất có liên quan.

Nếu bạn muốn tìm hiểu Lisp chủ đạo hơn (một Lisp rằng với một cái nhìn và cảm nhận của một phương ngữ Lisp điển hình), tôi muốn giới thiệu Common Lisp hoặc Đề án.

tuỳ chọn ngôn ngữ của tôi cho việc học Lisp sẽ được (!):

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

Để cung cấp cho bạn một ví dụ:

Đây là hàm COLLAPSE từ Lispy của McCarthy, được viết vào năm 1960 (từ Lisp I Programmer's manual, 1960, trang 101). Đó là cơ bản những gì trong nhiều bài tập Lisp là chức năng FLATTEN. Nó lấy một danh sách lồng nhau và trả về một danh sách mới với các nguyên tử trong một danh sách duy nhất.

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))))) 
)))))) 

Đây là phiên bản Common Lisp. Bạn có thể giữ nó trong chữ hoa hoặc chuyển đổi nó thành chữ thường. Cả hai đều hoạt động.

(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)))))) 

Về cơ bản, nó giống nhau. Chỉ có biểu mẫu để xác định hàm có tên và cú pháp khác. Nếu không, mã hoàn toàn giống nhau.

Hãy thử ví dụ McCarthy trong Common Lisp:

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

Nó chạy.

Bây giờ, hãy thử trong Emacs Lisp, sử dụng GNU Emacs. Emacs Lisp có định danh chữ thường:

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) 

Nó chạy trong Emacs Lisp mà không cần thay đổi.

Bạn có thể nhận các phiên bản tương tự như trong Đề án (các lần đổi mới nhỏ):.

đây trong 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))))))) 

Chúng ta có thể sử dụng DEFINE để xác định một hàm. COND trông hơi khác một chút. () là danh sách trống. Những người có dự án được thêm ?.

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

Chạy.

Trong Clojure nó sẽ trông khác nhau. Về cơ bản bạn phải suy nghĩ lại nhiều mã.

Đây là thực hiện riêng Clojure của flatten:

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

Bạn có thể viết một flatten trong tinh thần của phiên bản Lisp - nó vẫn sẽ trông khác nhau.

Từ 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))))))) 

tên khác nhau, cú pháp là khác nhau, ngữ nghĩa là khác nhau (hoạt động trên các chuỗi lười biếng thay vì danh sách).

Các phương ngữ như Common Lisp, Emacs Lisp, Visual Lisp, ISLISP và những người khác cố gắng giữ cho di sản.

Các phương ngữ như Đề án hoặc Clojure cảm thấy không bị ràng buộc với tên và cú pháp. Họ đổi mới theo nhiều hướng khác nhau. Đề án vẫn cung cấp các phiên bản trực tiếp của chức năng cũ. Clojure thì không. Các lập trình viên Clojure sẽ không coi đây là một bất lợi.

+2

Hmm. Vấn đề duy nhất tôi thực hiện với thứ tự ưu tiên này là nó dường như không ưu tiên khả năng sử dụng ngay lập tức - một khu vực mà Clojure tỏa sáng; thật dễ dàng để tìm các cơ hội thực tế để sử dụng ngôn ngữ dựa trên JVM tại nơi làm việc (và trong khi một số triển khai Đề án dựa trên JVM tồn tại, rất ít nếu có tương tác tương đương) và chiều rộng của thư viện có sẵn cho Clojure tốt hơn nhiều so với những gì có sẵn cho bất kỳ việc thực hiện Đề án cụ thể nào (phân mảnh trong thế giới đó trở nên khá đáng tiếc khi một người bắt đầu cố gắng thực hiện công việc thực tế). –

+6

Vâng, tôi mạnh mẽ không đồng ý với Rainer rằng Common Lisp/Scheme là "chính thống hơn" Lisp. Đừng làm cho tôi sai, tôi yêu CL, nhưng Clojure là xa nhất "thế giới thực" Lisp những ngày này. So sánh ví dụ khó khăn của việc sử dụng ASDF với sự dễ dàng của Leiningen/Clojars (và truy cập đơn giản như nhau đối với tất cả các bản repo của Java). CL thực hành phát triển là một chút lạc hậu, ví dụ tất cả mọi người sử dụng thân cây mới nhất của mỗi lib. Clojure libs có xu hướng được thử nghiệm tốt, được phiên bản, trên github/đơn giản để đóng góp. CL libs thường là các dự án sở thích đơn độc, cập nhật lần cuối vài năm trước – rplevy

+2

@CharlesDuffy: Tôi rất không đồng ý, Common Lisp tập trung vào khả năng sử dụng. Nếu bạn muốn tương tác với JVM, hãy xem [ABCL] (http://common-lisp.net/project/armedbear/), nếu bạn muốn tương tác với C, hãy xem [CFFI] (http: // common-lisp .net/project/cffi /). Và [Thực tiễn chung Lisp] (http://common-lisp.net/project/cffi/) là một hướng dẫn tuyệt vời. – Daimrod

Các vấn đề liên quan