2009-05-16 35 views
22

Tôi vừa bắt gặp một ý tưởng trong The Structure And Interpretation of Computer Programs:“Dữ liệu chỉ là mã ngu ngốc, và mã chỉ là dữ liệu thông minh” nghĩa là gì?

dữ liệu là chỉ là mã câm, và mã chỉ là dữ liệu thông minh

Tôi không hiểu ý nghĩa của nó. Một số người có thể giúp tôi hiểu nó tốt hơn không?

+5

Làm thế nào bạn có thể nói rằng nó "phrased thanh lịch" nếu bạn không biết ý nghĩa của nó? – sykora

+3

Đầu tiên tôi nghĩ rằng đó là một chiasmus nhưng bây giờ tôi nghĩ rằng nó là một antimetabole. – tuinstoel

+2

http://en.wikipedia.org/wiki/Von_Neumann_architecture –

Trả lời

37

Đây là một trong những bài học cơ bản về SICP và một trong những ý tưởng mạnh mẽ nhất của khoa học máy tính. Nó hoạt động như thế này:

Điều chúng tôi nghĩ là "mã" không thực sự có khả năng tự làm bất cứ điều gì. Mã xác định một chương trình chỉ trong một ngữ cảnh diễn giải - bên ngoài ngữ cảnh đó, nó chỉ là một dòng ký tự. (Thực sự là một dòng bit, mà thực sự là một dòng xung điện. Nhưng hãy giữ nó đơn giản.) nghĩa là mã được xác định bởi hệ thống mà bạn chạy nó - và hệ thống này chỉ xử lý mã của bạn dưới dạng dữ liệu mà nói với nó những gì bạn muốn làm. Mã nguồn C được giải thích bởi trình biên dịch C dưới dạng dữ liệu mô tả một tệp đối tượng mà bạn muốn nó tạo. Một tệp đối tượng được trình xử lý tải xuống dưới dạng dữ liệu mô tả một số hướng dẫn của máy mà bạn muốn xếp hàng để thực thi. Các lệnh máy được giải thích bởi CPU như là dữ liệu xác định chuỗi chuyển tiếp trạng thái mà nó cần phải trải qua.

ngôn ngữ thông dịch thường chứa các cơ chế để điều trị dữ liệu dưới dạng mã, có nghĩa là bạn có thể vượt qua mã vào một chức năng trong một số hình thức và sau đó thực hiện nó - hoặc thậm chí tạo ra mã tại thời gian chạy:

#!/usr/bin/perl 
# Note that the above line explicitly defines the interpretive context for the 
# rest of this file. Without the context of a Perl interpreter, this script 
# doesn't do anything. 
sub foo { 
    my ($expression) = @_; 
    # $expression is just a string that happens to be valid Perl 

    print "$expression = " . eval("$expression") . "\n"; 
} 

foo("1 + 1 + 2 + 3 + 5 + 8");    # sum of first six Fibonacci numbers 
foo(join(' + ', map { $_ * $_ } (1..10))); # sum of first ten squares 

Một số ngôn ngữ giống như lược đồ có khái niệm về "hàm hạng nhất", có nghĩa là bạn có thể coi một hàm là dữ liệu và truyền nó đi mà không đánh giá nó cho đến khi bạn thực sự muốn.

Kết quả là phân chia giữa "mã" và "dữ liệu" là khá nhiều tùy ý, chỉ là một chức năng của phối cảnh. Mức trừu tượng càng thấp, mã "thông minh hơn" phải là: nó phải chứa thêm thông tin về cách nó nên được thực thi. Mặt khác, thông tin càng nhiều mà người thông dịch cung cấp, mã càng câm, cho đến khi nó bắt đầu trông giống như dữ liệu không có chút thông minh nào cả.

Một trong những cách mạnh mẽ nhất để viết mã là mô tả đơn giản về những gì bạn cần: Dữ liệu sẽ được chuyển thành mã mô tả cách giúp bạn hiểu những gì bạn cần theo ngữ cảnh diễn giải. Chúng tôi gọi đây là "declarative programming".

Ví dụ cụ thể, hãy xem xét HTML. HTML không mô tả ngôn ngữ lập trình hoàn chỉnh Turing. Nó chỉ là dữ liệu có cấu trúc. Cấu trúc của nó chứa một số thông minh cho phép nó kiểm soát hành vi của ngữ cảnh diễn giải của nó - nhưng không phải là rất nhiều thông minh. Mặt khác, nó chứa nhiều thông minh hơn các đoạn văn bản xuất hiện trên một trang web trung bình: Đó là những dữ liệu khá câm.

+0

bằng cách này ... http://stackoverflow.com/questions/2497146/is-css-turing-complete – n611x007

+0

Câu trả lời của bạn thật tuyệt vời khi giải thích câu có nghĩa là gì ở cấp độ lý thuyết, nhưng tôi nghĩ có một số chỗ để che ý nghĩa của việc thay đổi cách thức bạn đối xử với các chương trình. Bạn có thể cũng muốn bao gồm các ý tưởng về cách tối đa này là cái nhìn sâu sắc cốt lõi của OOP. tức là sức mạnh của việc đóng gói mã và dữ liệu có liên quan với nhau, xử lý semnantically accessors như thể chúng là dữ liệu underlaying từ POV của ngữ cảnh gọi, vv – Racheet

2

Vì vậy, trong một ngôn ngữ như Đề án, thậm chí mã được coi là dữ liệu lớp học đầu tiên. Bạn có thể xử lý các hàm và các biểu thức lambda giống như bạn đối xử với các mã khác, nói rằng chuyển chúng thành các hàm khác và các biểu thức lambda. Tôi khuyên bạn nên tiếp tục với các văn bản như thế này tất cả sẽ trở nên khá rõ ràng.

2

Đây là điều bạn nên hiểu khi viết trong trình biên dịch.

Một bước phổ biến trong trình biên dịch là chuyển đổi chương trình thành một cây cú pháp trừu tượng. Việc biểu diễn thường sẽ giống như các cây như [+, 2, 3] trong đó + là gốc và 2, 3 là con cái.

Ngôn ngữ Lisp chỉ coi đây là dữ liệu của nó. Vì vậy, không có sự tách biệt giữa dữ liệu và mã mà cả hai danh sách giống như cây AST.

7

Trong bối cảnh bảo mật: Do tràn bộ đệm, những gì bạn nghĩ là dữ liệu và do đó vô hại (như hình ảnh) có thể được thực hiện dưới dạng mã và p0wn máy của bạn.

Trong bối cảnh phát triển phần mềm: Nhiều nhà phát triển rất sợ "hardcoding" mọi thứ và rất quan tâm đến việc trích xuất các tham số có thể phải thay đổi thành tệp cấu hình. Điều này thường dựa trên ý tưởng rằng các tập tin cấu hình chỉ là "dữ liệu" và do đó có thể được thay đổi dễ dàng (perhapy của khách hàng) mà không làm tăng các vấn đề (biên dịch, triển khai, thử nghiệm) mà thay đổi bất cứ điều gì trong mã sẽ.

Điều mà các nhà phát triển này không nhận ra là vì "dữ liệu" này ảnh hưởng đến hành vi của chương trình, nó thực sự là mã; nó có thể phá vỡ chương trình và lý do duy nhất không yêu cầu kiểm tra hoàn chỉnh sau khi thay đổi như vậy, nếu được thực hiện đúng, các giá trị có thể cấu hình có hiệu ứng rất cụ thể và được ghi lại tốt và bất kỳ giá trị không hợp lệ hoặc cấu trúc tệp bị hỏng sẽ bị bắt chương trình. Tuy nhiên, điều thường xảy ra là cấu trúc tập tin cấu hình trở thành ngôn ngữ lập trình theo đúng nghĩa của nó, hoàn chỉnh với luồng điều khiển và mọi thứ - một tài liệu được ghi chép kém, có cú pháp và trình phân tích cú pháp và chỉ có nhiều kinh nghiệm nhất các nhà phát triển trong nhóm có thể chạm vào mà không vi phạm hoàn toàn ứng dụng.

+0

+1. Có một xu hướng toàn cầu đáng lo ngại ngày nay để lưu trữ mọi thứ vào các tệp XML xấu xí, theo thời gian ngày càng trở nên phức tạp và khó hiểu. Như bạn đã nói, nó cho thấy sự thiếu hiểu biết của một lập trình viên trung bình về sự khác biệt giữa mã và dữ liệu. –

+0

Bạn đã có một điểm tốt ở đó, tôi sẽ suy nghĩ về điều đó khi thiết kế siêu lớn tiếp theo của tôi tuyệt vời có thể làm tất cả các hệ thống linh hoạt ;-) –

0

Mã chắc chắn là dữ liệu, nhưng dữ liệu chắc chắn là không phải lúc nào cũng là mã. Hãy lấy một ví dụ cơ bản - tên khách hàng. Không có gì liên quan đến mã, đó là chức năng (cần thiết), trái ngược với một khía cạnh vô tình của một ứng dụng kỹ thuật (vô tình).

Bạn có thể nói rằng bất kỳ dữ liệu kỹ thuật/tình cờ nào là mã và dữ liệu chức năng/cần thiết đó không phải là.

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