Bill Gosper có ý gì khi nói cấu trúc dữ liệu chỉ là một ngôn ngữ lập trình ngu ngốc? [đóng cửa]


16

Có một trích dẫn của Ralph William Gosper, Jr nói rằng:

Một cấu trúc dữ liệu chỉ là một ngôn ngữ lập trình ngu ngốc.

Ông ấy có ý gì bởi điều này? Than ôi, tất cả những gì tôi có thể tìm thấy trong Google về nó là bản sao / dán không ngừng của trích dẫn, mà không có bất kỳ bối cảnh nào.



1
Loại câu hỏi này hiện đang được thảo luận trên trang web thảo luận meta của chúng tôi .

Có các ngôn ngữ với hệ thống loại Turing-Complete. Một số trong số họ là ngu ngốc.
SK-logic

@ SK-logic: Các hệ thống loại, Turing hoàn chỉnh hay nói cách khác, phải làm gì với trích dẫn này?
năm11

1
@RehnoLindeque, bạn đã bao giờ thấy Agda hay Coq chưa? Các loại có thể là Turing-đầy đủ.
SK-logic

Câu trả lời:


10

Chà, có vẻ như trung tâm của tuyên bố là:

Cấu trúc dữ liệu chỉ là một ... ngôn ngữ lập trình

Điều này khá đúng nếu bạn nghĩ về nó. Rốt cuộc, trình biên dịch dựa vào tính siêu việt này mọi lúc; họ lấy ngôn ngữ lập trình, chuyển đổi nó thành cấu trúc dữ liệu, thực hiện một số biến đổi trên dữ liệu đó và sau đó biến kết quả thành ngôn ngữ lập trình khác.

Trên thực tế, nếu bạn muốn, bạn thậm chí có thể tạo ra thứ gì đó điên rồ như cấu trúc dữ liệu C, cho phép bạn viết mã C bằng cách gọi các phương thức khác nhau của nó - ví dụ (trong loại C #, vì đó là những gì tôi đang sử dụng ngay bây giờ):

var C = new Hor khiếpCObject ();
C.Chức năng <int> ("chính", typeof (char [] []), typeof (int))
  .Variable ("i", typeof (int), 0)
  .While ("i", Func (i) => i <10))
     .Call ("printf", "% d", "i")
     .PostIncrement ("i")
  .EndWhile ();
  . Trả về (0)
 .EndFactor ();

Bây giờ, như trích dẫn đầy đủ: tại sao một cái gì đó như thế lại ngu ngốc so với (nói) viết bằng chính C? Một điều khá rõ ràng là đây là dài dòng và không dễ đọc như tương đương với C (và, trong thực tế, có thể không hỗ trợ toàn bộ phạm vi của những gì C có thể làm - typedefs sẽ khó khăn); do đó, cấu trúc dữ liệu này chỉ là một ngôn ngữ lập trình "ngu ngốc", được nhúng trong một ngôn ngữ lập trình "thực". Logic tương tự có thể được khái quát cho bất kỳ cấu trúc dữ liệu nào bạn có thể nghĩ đến; danh sách được liên kết chỉ là phiên bản "ngu ngốc" của Lisp và bản đồ băm chỉ là phiên bản "ngu ngốc" của một số Ngôn ngữ lập trình Hash lý thuyết (Hasp?).

Mặc dù vậy, vấn đề là chúng ta không luôn muốn viết Hasp để tương tác với các bản đồ băm của mình. Đó là vấn đề mà tất cả các ngôn ngữ cụ thể của miền đều có - một mặt, DSL được triển khai tốt đủ mạnh để thể hiện mọi thứ mà mô hình cơ bản có thể làm; mặt khác, bạn phải triển khai DSL ngay từ đầu và sau đó những người khác phải học nó. Điều đó làm mất thời gian và công sức mà có lẽ họ không muốn bỏ ra; Rốt cuộc, tôi chỉ muốn đặt mọi thứ vào bản đồ băm của mình và sau đó kiểm tra những thứ khác có trong đó, tôi không muốn tìm hiểu tất cả những điều phức tạp của Lập trình định hướng Hash.

Vì vậy, gần như không nghĩ về nó, chúng tôi sử dụng các ngôn ngữ lập trình rất thông minh và rất cụ thể về mặt lý thuyết này và chắt lọc chúng thành một số ít, các hoạt động ngu ngốc được thể hiện trong cấu trúc dữ liệu. Một danh sách liên kết có một bộ sưu tập nhỏ các phương thức đơn giản; một bản đồ băm có một số người khác. Chúng tôi bỏ qua các hoạt động mạnh mẽ khác mà bạn có thể thực hiện trên cấu trúc dữ liệu (hầu hết các triển khai LinkedList không có chức năng .Map hoặc .ororach, và tôi thậm chí không thể tưởng tượng bạn sẽ làm gì trong Hasp), ủng hộ việc thực hiện chúng một cách rõ ràng bằng ngôn ngữ lập trình cha mẹ - đó là điều mà hầu hết các lập trình viên sẽ quen thuộc.

Các cấu trúc dữ liệu về cơ bản là một phần mở rộng ngu ngốc của ngôn ngữ gốc của chúng vào không gian vấn đề mà chúng đại diện về mặt khái niệm. Một tiện ích mở rộng đủ thông minh sẽ yêu cầu ngôn ngữ lập trình mới, cụ thể và hầu hết mọi người sẽ không muốn học điều đó.


2

Cấu trúc dữ liệu là ĐẠI DIỆN của ngôn ngữ lập trình. Nhưng không phải là một "đặc biệt" sắc nét.

Điều này có thể được nhìn thấy từ một "sơ đồ nút" giống như trong bài viết wiki dưới đây:

http://en.wikipedia.org/wiki/Root_node#Terminology

Tuy nhiên, một cấu trúc dữ liệu là TUYỆT VỜI như một ngôn ngữ lập trình, bởi vì nó thiếu cú ​​pháp và những suy nghĩ hoàn chỉnh có thể hiểu được đối với một lập trình viên. "Ngôn ngữ" của cấu trúc dữ liệu có thể được so sánh với một đứa trẻ nói điều gì đó như "Tôi, lạnh. Lấy áo khoác."

"Ngôn ngữ" bị rạn nứt, nhưng có thể hiểu được. Đứa trẻ đang nói rằng "nó lạnh và muốn mặc nhiều quần áo hơn." Cách nói của trẻ là một phiên bản "ngu ngốc" của ngôn ngữ tiếng Anh và cấu trúc dữ liệu tương tự như vậy liên quan đến ngôn ngữ lập trình.


1

Tôi tin rằng những gì Bill Gosper dự định là tất cả các cấu trúc dữ liệu chỉ là các cấu trúc lập trình với khả năng ứng dụng hạn chế . Điều này cũng liên quan đến ý tưởng rằng "Thiết kế ngôn ngữ là thiết kế thư viện và thiết kế thư viện là thiết kế ngôn ngữ" [1].

Một cách nghĩ về vấn đề này là xem xét các cấu trúc dữ liệu chỉ trên cơ sở thuật toán. Hãy quên các yêu cầu lưu trữ hoặc chú thích loại hiện tại vì chúng chỉ đơn giản là phụ trợ.

Ví dụ: bạn có thể mã hóa một mảng kết hợp (được gọi là một maptrong một số ngôn ngữ) theo hai cách: Hoặc bằng cách sử dụng một số loại chỉ mục được lưu trữ trong bộ nhớ hoặc bằng cách sử dụng một biểu thức trường hợp đơn giản.

Trong Haskell, bạn có thể mã hóa một mảng kết hợp thành một cấu trúc dữ liệu ...

let assocArray = [("a", 1),("b", 2),("c", 3)]
let key = "b"
lookup key assocArray

... hoặc bằng cách sử dụng một biểu thức trường hợp ...

let key = "b"
case key of 
  "a" -> 1
  "b" -> 2
  "c" -> 3

... hoặc thậm chí trực tiếp hơn ...

let key = "b"
if key == "a" 
  then 1 
  else if key == "b"
    then 2
    else if key == "c"
      then 3
      else undefined

Có thể dễ dàng nhận thấy rằng loại phản chiếu này giữa các cấu trúc dữ liệu và mã là có thể bằng cách nhìn vào phép tính lambda. Bất kỳ giá trị nào cũng có thể được biểu diễn bằng một hàm trong phép tính lambda và phép tính chính nó là phổ quát (hoàn thành turing).

[1] Câu trích dẫn là nhờ Bjarne Stroustrup.


0

Hãy xem xét Javascript, nơi tất cả dữ liệu là mã. Hãy xem xét LISP, trong đó tất cả dữ liệu là mã và tất cả mã là dữ liệu.

Ban đầu, kết thúc và mọi nơi ở giữa, dữ liệu chỉ là bit. Rằng chúng ta cố gắng ontologize bit bằng văn bản và ký hiệu để làm cho chúng dễ đọc và dễ biến đổi con người là một lớp trừu tượng đòi hỏi a) Bạn học ngôn ngữ định nghĩa và b) bạn học được sự rò rỉ của sự trừu tượng.

Ví dụ, trong C #, việc tìm hiểu sự khác biệt giữa một cấu trúc và lớp yêu cầu bạn tìm hiểu sự khác biệt trong so sánh đẳng thức giữa các loại giá trị và loại tham chiếu. Mỗi bản thể dữ liệu đòi hỏi phải có bộ quy tắc riêng mà bạn phải học và tuân thủ. Và, giống như bất kỳ ngôn ngữ nào, nó cho phép bạn nhanh chóng đi đến ý tưởng chung, nhưng bạn càng muốn tiếp cận gần hơn với sự thật thực tế của vấn đề, bạn càng nên nhìn vào nhị phân.

Cuối cùng, khi người ta xem xét một cây B hoặc cấu trúc dữ liệu tương tự, điều hướng cấu trúc của cây và thực hiện các loại hoạt động khác trên nó đòi hỏi một loại cú pháp chuyên biệt không nhất thiết phải chuyển qua cây, cấu trúc hoặc ngôn ngữ.


3
Tôi không chắc điều này thực sự đi vào trung tâm của nó. Chẳng hạn, lập trình chung là đặc biệt về cấu trúc dữ liệu Thuật toán bất khả tri (điển hình là với các trình vòng lặp hoặc phạm vi).
Jon Purdy

4
Bạn có chắc đây là ý nghĩa của Ralph William Gosper, Jr.
Robert Harvey

Trong Common Lisp, không phải tất cả dữ liệu có thể được biên dịch thành mã, nhưng tất cả mã có thể được coi là dữ liệu. Không có nhiều quy tắc cú pháp, nhưng tất cả các mã phải là biểu thức S, ít nhất là sau khi xử lý macro và không phải tất cả dữ liệu đều là biểu thức S.
David Thornley
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.