Quy tắc thứ mười của Greensasta, mọi dự án lớn có bao gồm trình thông dịch Lisp không? [đóng cửa]


12

Quy tắc thứ mười của Greensasta (thực ra là quy tắc duy nhất) nói rằng:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Ký ức của tôi là có một số bài viết về chủ đề này, có lẽ là cho dự án Quattro (bảng tính) của Borland và có thể cả những thứ khác. Google là không hữu ích, có thể các thuật ngữ tìm kiếm đúng không xuất hiện trong tâm trí. Tôi đang tìm kiếm các giấy tờ hoặc bài viết hỗ trợ cho yêu cầu này, nếu có.


8
Bạn đã đọc giải thích về ý nghĩa của quy tắc trên bài viết Wikipedia chưa? Tôi nghi ngờ sẽ có nỗ lực nghiêm túc để xác nhận hoặc từ chối yêu cầu, nó thực sự không có ý nghĩa nghiêm trọng .
yannis

3
Điều buồn cười là trong khi quy tắc của Greensasta chỉ là một trò đùa, tôi thực sự đã làm việc trên phần mềm mô phỏng có trình thông dịch LISP nhúng. Tất cả cấu hình của phần mềm được thực hiện thông qua S-Expressions và người ta có thể viết mã LISP có thể hiểu được để làm nhiều việc khác nhau trong cấu hình.
wkl

@YannisRizos - Theo nghĩa đen, cả hai liên kết của bạn đều khẳng định Quy tắc là một trò đùa. Mặc dù vậy, Luật của Morris được đóng khung như vậy. Bây giờ, theo nghĩa bóng ....
giản dị

2
@casualcoder "Thật mỉa mai là điều này, sau cái chết của tôi, có lẽ là điều mà bất cứ ai cũng nhớ từ bài viết của tôi." và việc đặt tên cho các quy tắc gợi ý rằng nó được viết theo cách nhẹ nhàng ...
yannis

Không có một trích dẫn tương tự về Erlang và các chương trình đồng thời?
Giorgio

Câu trả lời:


15

Các tuyên bố là cường điệu. Nhưng có những dấu hiệu rõ ràng về sự ghen tị của Lisp trong các ngôn ngữ khác. Nhìn vào C # và làm thế nào nó trở nên có chức năng hơn trong tự nhiên. Nhìn vào các quy trình quản lý quy trình nghiệp vụ, quy trình làm việc và các khung EAI khác nhau để có thể lập trình hệ thống mà không cần thay đổi chương trình.

Có một cuốn sách về Ngôn ngữ cụ thể miền của Martin Fowler nói về cách lập trình meta trong các ngôn ngữ hướng đối tượng. Vì vậy, có một số sự thật cho hyperbole.

Paul Graham gọi Lisp là ngôn ngữ mạnh mẽ nhất nhìn vào danh sách các ngôn ngữ đầu tiên đi kèm với Lisp , thật dễ dàng để biết lý do tại sao nhiều ngôn ngữ nhạt so với.

Cách xung quanh quy tắc thứ mười là lập trình polyglot. Nhận ra rằng một ngôn ngữ / khung không phải là cái búa vàng. Sau đó, thay vì tạo ra một triển khai Lisp kém, đặc biệt, bạn chỉ có thể sử dụng Lisp.


4
Quyền lực và tuổi tác là độc lập. Nó thực sự khá không liên quan đến việc LISP tốt hay xấu vào thời điểm nó được tạo ra, vấn đề là nó so sánh với các ngôn ngữ ngày nay như thế nào. Đầu tiên là hoàn toàn không quan trọng.
DeadMG

2
@DeadMG, những "lần đầu tiên" này không là gì so với những điều chưa được chuyển từ Lisp sang các ngôn ngữ khác.
SK-logic

1
@DeadMG, bạn nói đúng. Một trong những điều mọi người yêu thích về Ruby sau khi họ bắt đầu tìm hiểu về nó là khía cạnh Metaprogramming của nó. Lisp đã tích hợp sẵn. Các nhà phát triển C # yêu thích LINQ (với lý do chính đáng) và những hàm ý mà lập trình khai báo có trên đồng thời. Lisp có điều đó trong thuổng. Khi các hệ thống trở nên phức tạp hơn, chúng trở nên nhiều hơn về các nút phản ứng với các thông điệp và ít hơn về các đối tượng. Lisp bắt đầu từ đó, hầu hết các ngôn ngữ khác phải giải quyết nó trên ad hoc (do đó là quy tắc) hoặc thông qua một khung (ví dụ: Biztalk, Tibco, v.v.).
Michael Brown

2
"Thay vì tạo ra một triển khai Lisp kém, không thường xuyên, bạn chỉ có thể sử dụng Lisp" nhưng hệ quả của Morris có nghĩa là bạn vẫn đang sử dụng một triển khai ad hoc kém;)
jk.

1
Sidenote hoàn hảo cho mục nhập đó "toàn bộ văn hóa hacker thường bị các hacker coi là nghiêm trọng, chỉ coi nó là quá nhẹ hoặc quá nghiêm trọng đánh dấu một người là người ngoài cuộc, một kẻ lang thang hoặc trong giai đoạn ấu trùng . "
Michael Brown

10

"Quy tắc thứ mười" của Greensasta là một chút vụng trộm. Khi được kéo dài đủ xa, nếu bạn làm cho nó bao trùm "bất kỳ hệ thống kịch bản hoặc cấu hình nào", thì rõ ràng câu trả lời cho câu hỏi này sẽ phải là "có", vì cấu hình là thứ mà bất kỳ chương trình không tầm thường nào cũng yêu cầu ở một mức độ nào đó và kịch bản chỉ hơi ít phổ biến khi bạn di chuyển lên thang độ phức tạp.

Mặt khác, hãy xem GOAL , một biến thể Lisp được phát minh bởi Naughty Dog để lập trình trò chơi. Nó trông không giống Lisp "cổ điển" chút nào. Đây là một hệ thống theo phong cách rất cấp bách, với chức năng hướng đối tượng, không có trình thông dịch, hỗ trợ tối thiểu cho việc thu gom rác (thay vào đó là các phương tiện dọn dẹp ở mức thời gian chạy) và hỗ trợ rộng rãi cho lắp ráp nội tuyến.

Nói cách khác, khi họ cố gắng sử dụng Lisp cho một dự án đủ phức tạp, họ thấy rằng để làm bất cứ điều gì hữu ích, họ phải biến ngôn ngữ thành một triển khai được chỉ định một cách không chính thức của một nửa C ++! ;) (Và cuối cùng họ đã phải ngừng sử dụng nó sau khi anh chàng thiết kế GOAL rời đi, vì không ai có thể hiểu được mã của anh ta.)


Tôi đoán câu hỏi của tôi là về các phần cụ thể của một hệ thống lớn. Cuối cùng, hệ thống sẽ có các phần được mã hóa tốt hơn bằng ngôn ngữ khác do các quá trình suy nghĩ hoặc kỹ thuật liên quan đến việc sử dụng ngôn ngữ đó, thay vì tốc độ hoặc ưu thế vốn có. Câu chuyện của ông Lenaghan là một ví dụ.
Casualcoder

Trên thực tế, họ đã ngừng sử dụng GOAL vì họ đã được mua bởi công ty có codebase ở C ++. Ngoài ra, GOAL là khá tốt. Đừng cho rằng hướng dẫn trực tuyến mẫu số thấp nhất và bài giảng đại học là chính xác :)
p_l

9

Thật kỳ lạ, một câu trả lời cho câu hỏi này đã có trong Lập trình viên SE .

Để trích dẫn phần có liên quan:

Quan điểm của Greensasta là (một phần) rằng nhiều chương trình phức tạp có trình thông dịch tích hợp. Thay vì xây dựng một trình thông dịch thành một ngôn ngữ, ông cho rằng việc sử dụng một ngôn ngữ như Lisp đã có sẵn một trình thông dịch (hoặc trình biên dịch) có ý nghĩa hơn.

Lúc đó tôi đang làm việc trên một ứng dụng khá lớn thực hiện các tính toán do người dùng xác định bằng trình thông dịch tùy chỉnh cho ngôn ngữ tùy chỉnh. Tôi quyết định thử viết lại cốt lõi của nó trong Lisp như một thử nghiệm quy mô lớn.

Mất khoảng sáu tuần. Mã ban đầu là ~ 100.000 dòng Delphi (một biến thể Pascal). Trong Lisp đã giảm xuống ~ 10.000 dòng. Tuy nhiên, điều đáng ngạc nhiên hơn nữa là thực tế là động cơ Lisp nhanh hơn 3-6 lần. Và hãy nhớ rằng đây là công việc của một tân sinh viên Lisp! Đó là toàn bộ trải nghiệm đối với tôi; lần đầu tiên tôi thấy khả năng kết hợp hiệu suất và biểu cảm trong một ngôn ngữ duy nhất.
- Michael Lenaghan

Để làm rõ hơn phần đó, Michael đã trả lời một bình luận với:

Ồ, đó hẳn là một mã Delphi thực sự khủng khiếp nếu bằng cách nào đó nó có thể thực hiện chậm hơn 3-6 lần so với triển khai Lisp! "Phải, tôi sẽ coi đó là thất bại của mình vì đã không giải thích nó tốt hơn. Việc triển khai Lisp có thể biến đổi biểu thức sử dụng vào biểu Lisp - một quá trình trivially dễ dàng - và sau đó biên dịch các từ ngữ Lisp để mã gốc (với đầy đủ tối ưu hóa) Đó là ý nghĩa của Greenspun của X Rule..
- Michael Lenaghan

Đưa ra câu trả lời này bao gồm câu trả lời của người khác ở nơi khác, đó là wiki cộng đồng.


2

Quy tắc là một trò đùa, nhưng có một chút sự thật trong đó. Bất kỳ hệ thống phức tạp nào cũng sẽ chứa một số phần được diễn giải (xem, làm thế nào "mẫu phiên dịch" phổ biến trong số những người tin vào tất cả các mẫu đó mumbo-jumbo). Bất kỳ hệ thống phức tạp nào cũng phải cung cấp một số phương tiện cấu hình, thường có cấu trúc, thường được diễn giải.

Bất kỳ hệ thống phức tạp nào cũng rất có khả năng có một vài lần tạo mã và các bộ tiền xử lý tùy chỉnh khác nhau trong quá trình xây dựng của nó (nghĩ về những thứ như moctrong Qt hoặc tablegentrong LLVM).

Nhiều hệ thống đang xử lý các cấu trúc dữ liệu giống như cây phức tạp bằng cách sử dụng bộ công cụ chuyển đổi và chuyển đổi cây được thiết kế kém (hầu như luôn luôn) gần giống với chức năng thư viện từ Common Lisp.

Tất cả những điều này đều miễn phí với Lisp, và trong hầu hết các trường hợp, tất cả những gì không liên quan, không có kế hoạch, không được suy nghĩ thấu đáo khi thực hiện đủ sẽ hoàn toàn kém hơn.


2

Bất kỳ hệ thống đủ phức tạp nào cũng sẽ có các khái niệm và yêu cầu cụ thể về miền cực kỳ khó diễn đạt với sự trừu tượng của ngôn ngữ bạn đang làm việc. Điều này vô tình buộc các lập trình viên tạo ra sự trừu tượng hóa miền cụ thể để giảm bớt gánh nặng thu hẹp khoảng cách ngữ nghĩa giữa ngôn ngữ lập trình và tên miền cụ thể. Khi đã có đủ các khái niệm trừu tượng này, về cơ bản bạn có một trình thông dịch của một ngôn ngữ cụ thể theo miền. Đây là một phần không thể tránh khỏi trong việc phát triển phần mềm.


1

Quy tắc có thể chính xác hơn (và ít gây cười hơn) vì "mọi hệ thống dựa trên phần mềm lớn sẽ được yêu cầu để thực hiện hành vi động".

Điều này có thể được thực hiện theo hai cách-

  1. Một tệp cấu hình phức tạp lớn với hàng tá tham số và hàng trăm định nghĩa.

  2. Một ngôn ngữ kịch bản AD-HOC.

"sendmail" có lẽ là ví dụ điển hình của loại "1". Tôi không thể nghĩ ra bất kỳ ví dụ hay nào về loại "2" không liên quan đến việc nhúng ngôn ngữ kịch bản "thực" vào la Warcraft / LUA hoặc thậm chí Netscape / Javascript.

Vấn đề là đối với một vài tham số, nó nhanh chóng và đơn giản để thực hiện với tệp cấu hình, nhưng, giải pháp này không thực sự mở rộng. Tuy nhiên, sẽ không kinh tế nếu bỏ tập tin cấu hình theo hướng tiếp cận tập lệnh khi thêm một hoặc hai tùy chọn vào tập tin cấu hình. Vì vậy, mã thông dịch tập tin cấu hình cuối cùng chỉ là một trình thông dịch được viết rất tệ.


0

Điều đó có thể đúng, như những người khác đã nêu, nhiều chương trình yêu cầu cấu hình và do đó có chứa các trình thông dịch giống như lisp khác nhau.

Tuy nhiên, tuyên bố cũng ngụ ý với một nụ cười nhếch mép rằng tất cả những gì bạn cần để thực hiện một chương trình là Lisp, và tất cả các ngôn ngữ khác đều kém hơn nó.

Nhưng điều đó là sai, Lisp có thể biểu cảm, nhưng nó cũng quá trừu tượng, nó cố gắng che giấu các chi tiết của một nền tảng và giả vờ không có gì ngoài danh sách tồn tại trong thế giới máy tính.

Thực tế của lập trình hiệu suất cao là đôi khi chúng ta cần trộn lẫn các bit và byte và thực hiện các công cụ cụ thể của hệ điều hành, do đó không thể thực hiện mọi thứ chỉ với Lisp như tuyên bố ngụ ý.

Nó đúng hơn là cách khác, bất kể ngôn ngữ bạn phát minh phức tạp, thông minh hay phức tạp đến mức nào, tất cả những gì nó kết thúc chỉ là một cách khác để viết lắp ráp.


Có vẻ như chỉ liên quan đến các môi trường lisp cổ xưa nhất vào cuối những năm 50. Cá nhân, tôi thấy các hàm Common Lisp để xử lý các bit có lẽ là một trong những chức năng tốt nhất (với đối thủ chính là Erlang). Mảng, hashtables, structs đều phổ biến.
p_l

Thật dễ dàng để viết trình biên dịch cho Lisp vì bạn không cần phải phân tích cú pháp. Các hàm Lisp có thể được tạo và một trình biên dịch macro (giống như trình đánh giá Lisp chỉ từ một đến nửa trang mã khi bắt đầu) biến các biểu thức Danh sách đó thành C và bạn đang viết bằng C trong Lisp nhưng với tất cả sức mạnh của macro và tính toán lambda nếu bạn muốn.
aoeu256

0

Cho dù nó có được thực hiện nghiêm túc hay không, điều đó đúng với các dự án C và C ++ lớn nhất mà tôi đã làm.

Điều không đúng là các ngôn ngữ kịch bản tùy chỉnh giống với Common Lisp. Các ví dụ tích cực giống với Scheme (vì các nhà thiết kế thông minh hơn đã tích hợp Guile, SpiderMonkey và Lua thay vì phát minh ra ngôn ngữ của họ.) Các ví dụ đáng giá nhất DailyWTF là ngôn ngữ giống Forth và ngôn ngữ giống MUMPS.

Một ví dụ khác (không chắc nó có được tính là Greenspasty không, nhưng chắc chắn là WTF) là một trình thông dịch XSLT được sử dụng cho kịch bản mục đích chung. Điều này giống với Lisp hơn khi họ thêm một vòng phản hồi trong đó đầu ra sẽ được chuyển đổi XSLT lần thứ hai - vì vậy bây giờ bạn thực sự có macro.
Động cơ ở đây mặc dù không phải là để có quyền truy cập vào các tính năng lispy mà là để vượt qua các quy trình QA mã của công ty (đã thêm 3 tuần độ trễ cho mọi sửa lỗi. XML được coi là "dữ liệu" và được miễn trừ khỏi quy trình.)


-1

Không may măn!

Mặc dù tốt nhất là chỉ cần nhúng một trình thông dịch lisp (y) thực sự (javascript hoặc lua alos làm rất tốt), thêm 4gl homebrew vào một dự án làm giảm kích thước tổng thể trong khi tăng tính linh hoạt.

Các dự án "mã hóa mọi thứ" có số lượng mô-đun lớn hơn rất nhiều và trở nên khó sử dụng và không linh hoạt.

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.