Các loại trong Lisp và Scheme


10

Tôi thấy bây giờ vợt có các loại. Thoạt nhìn có vẻ gần giống với cách gõ Haskell. Nhưng CLOS của Lisp có bao gồm một số loại Haskell không gian không? Tạo một loại Haskell rất nghiêm ngặt và một đối tượng trong bất kỳ ngôn ngữ OO nào có vẻ giống nhau một cách mơ hồ. Chỉ là tôi đã uống một số dụng cụ hỗ trợ Haskell và tôi hoàn toàn hoang tưởng rằng nếu tôi đi trên con đường Lisp, tôi sẽ bị say do gõ động.

Câu trả lời:


6

Hệ thống loại CL có tính biểu cảm cao hơn hệ thống Haskell, ví dụ: bạn có thể có một loại (or (integer 1 10) (integer 20 30))cho một giá trị 1,2,...9,10,20,21,...,30.

Tuy nhiên, trình biên dịch Lisp không buộc sự hiểu biết của họ về loại an toàn xuống cổ họng của bạn, vì vậy bạn có thể bỏ qua "ghi chú" của họ - có nguy cơ của riêng bạn .

Điều này có nghĩa là bạn có thể viết Haskell bằng Lisp (có thể nói) bằng cách khai báo tất cả các loại giá trị và cẩn thận đảm bảo rằng tất cả các loại cần thiết được suy ra, nhưng sau đó sử dụng Haskell sẽ dễ dàng hơn.

Về cơ bản, nếu bạn muốn gõ tĩnh mạnh, hãy sử dụng Haskell hoặc OCaml, nếu bạn muốn gõ động mạnh, hãy sử dụng Lisp. Nếu bạn muốn gõ tĩnh yếu, hãy sử dụng C, nếu bạn muốn gõ động yếu, hãy sử dụng Perl / Python. Mỗi con đường đều có ưu điểm (và nhiệt tâm) và nhược điểm (và gièm pha), vì vậy bạn sẽ được hưởng lợi từ việc học tất cả chúng.


19
Bất cứ ai sử dụng các thuật ngữ như "an toàn loại lực xuống cổ họng" không hiểu loại an toàn là gì hoặc tại sao nó hữu ích.
Mason Wheeler

11
@MasonWheeler: bất cứ ai đưa ra kết luận sâu rộng từ một cụm từ duy nhất sẽ thấy mình sai thường xuyên hơn so với khác. Giống như, ví dụ, trong trường hợp này.
sds

4
Vì chủ đề là ngôn ngữ, thuật ngữ "xuống cổ họng" là hình ảnh phù hợp và thích hợp.
luser droog 17/213

1
@KChaloux: Tôi có nghĩa là "biểu cảm", như được làm rõ bằng ví dụ.
sds

4
Bạn đã có tất cả về phía sau. Gõ động là trường hợp đặc biệt của gõ tĩnh, trong đó bạn buộc lập trình viên sử dụng 1 loại cho mọi thứ. Tôi có thể làm điều tương tự (bằng lời nói) trong hầu hết các ngôn ngữ được gõ tĩnh bằng cách khai báo mọi biến là kiểu Objecthoặc bất kỳ gốc của cây kiểu gì. Điều này ít biểu cảm hơn , bởi vì bạn khôngtùy chọn nói rằng các biến nhất định chỉ có thể chứa các giá trị nhất định.
Doval

5

Gõ vợt rất khác với Haskell. Các hệ thống loại trong Lisp và Scheme, và thực sự là các hệ thống trong các hệ sinh thái ngôn ngữ chưa được truyền thống nói chung, có một mục tiêu cơ bản là các hệ thống loại khác không - tương tác với mã chưa được mã hóa hiện có . Ví dụ, đánh máy vợt đã giới thiệu các quy tắc đánh máy hoàn toàn mới để phù hợp với các thành ngữ vợt khác nhau. Hãy xem xét chức năng này:

(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Đối với danh sách không trống, điều này trả về phần tử đầu tiên. Đối với danh sách trống, điều này trả về sai. Điều này là phổ biến trong các ngôn ngữ chưa được kiểm tra; một ngôn ngữ được nhập sẽ sử dụng một số loại trình bao bọc như Maybehoặc ném lỗi trong trường hợp trống. Nếu chúng ta muốn thêm một loại cho chức năng này, loại nào nên được sử dụng? Nó không phải [a] -> a(theo ký hiệu Haskell), vì nó có thể trả về false. Điều đó cũng không phải [a] -> Either a Boolean, bởi vì (1) nó luôn trả về false trong trường hợp trống, không phải là một boolean tùy ý và (2) một loại Hoặc sẽ bao bọc các phần tử trong Leftvà false Rightvà yêu cầu bạn "mở khóa" hoặc để lấy phần tử thực tế. Thay vào đó, giá trị trả về một liên minh thực sự- không có hàm tạo, nó chỉ trả về một kiểu trong một số trường hợp và một kiểu khác trong các trường hợp khác. Trong Typed Vợt, điều này được thể hiện với hàm tạo kiểu kết hợp:

(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Kiểu này (U A #f)cho biết hàm có thể trả về một phần tử của danh sách hoặc false mà không có bất kỳ Eithertrường hợp gói nào . Trình kiểm tra loại có thể suy ra đó some-listlà loại (Pair A (Listof A))hoặc danh sách trống, và hơn nữa nó kiểm tra rằng trong hai nhánh của câu lệnh if, nó được biết là trường hợp nào trong số đó là trường hợp . Trình kiểm tra kiểu biết rằng trong (car some-list)biểu thức, danh sách phải có kiểu (Pair A (Listof A))vì điều kiện if đảm bảo nó. Điều này được gọi là gõ xuất hiện và được thiết kế để dễ dàng chuyển đổi từ mã chưa được gõ sang mã đã nhập.

Vấn đề là di cư. Có rất nhiều mã vợt chưa được đánh dấu ở ngoài đó và Typed Vợt không thể buộc bạn phải từ bỏ tất cả các thư viện chưa được yêu thích và dành một tháng để thêm các loại vào cơ sở mã của bạn nếu bạn muốn sử dụng nó. Vấn đề này áp dụng bất cứ khi nào bạn thêm các loại dần dần vào một cơ sở mã hiện có, hãy xem TypeScript và bất kỳ loại nào cho ứng dụng javascript của những ý tưởng này.

Một hệ thống loại dần dần phải cung cấp các công cụ để xử lý các thành ngữ chưa được xử lý phổ biến và tương tác với mã chưa được mã hóa hiện có. Sử dụng nó sẽ khá đau nếu không, hãy xem "Tại sao chúng tôi không còn sử dụng Core.typed" để biết ví dụ về Clojure.


1
Trong kinh tế học, điều này được gọi là Định luật Gresham : tiền xấu đẩy ra tốt. Nó có xu hướng tìm thấy các ứng dụng trong kỹ thuật quá. Khi bạn có hai hệ thống con tương đương về mặt lý thuyết trong hệ thống của mình, tất cả quá thường xuyên, hệ thống xấu hơn sẽ gây ra quá nhiều vấn đề để làm cho hệ thống tốt hơn đáng sử dụng, như chúng ta đang thấy ở đây.
Mason Wheeler

"một ví dụ về thiết kế một hệ thống kiểu": câu này chưa hoàn thành
coredump

@MasonWheeler Điều tồi tệ hơn là, hãy để tôi đoán, kiểm tra kiểu động. Vì vậy, ngay khi bạn giới thiệu nó, nó không đáng để thực hiện một số phân tích tĩnh?
coredump

1
@coredump - Gõ dần dần có giá trị, trừ khi bạn tương tác với mã chưa được gõ kém. Ví dụ, bất kỳ loại nào trong TypeScript chỉ yêu cầu người đánh máy từ bỏ, về cơ bản sẽ loại bỏ các lợi ích của hệ thống loại vì nó có thể khiến giá trị xấu lan truyền qua một lượng lớn mã được kiểm tra tĩnh. Typed Vợt sử dụng hợp đồng và ranh giới mô-đun để tránh vấn đề này.
Jack

1
@coredump Đọc bài viết Clojure. Việc gõ động xung quanh, đặc biệt là với tất cả các mã của bên thứ ba không có sẵn kiểu tĩnh, thực sự làm hỏng mọi thứ vì nỗ lực cải thiện cơ sở mã của họ bằng các loại tĩnh.
Mason Wheeler
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.