Có phải tất cả các ngôn ngữ về cơ bản là giống nhau?


39

Gần đây, tôi phải hiểu thiết kế của một chương trình nhỏ được viết bằng ngôn ngữ mà tôi không biết ( ABAP , nếu bạn phải biết). Tôi có thể tìm ra nó mà không gặp quá nhiều khó khăn.

Tôi nhận ra rằng việc thành thạo một ngôn ngữ mới là một trò chơi bóng hoàn toàn khác, nhưng hoàn toàn hiểu được ý định của mã (cụ thể là mã tiêu chuẩn sản xuất, không nhất thiết phải phức tạp) trong bất kỳ ngôn ngữ nào, nếu bạn đã biết một vài ngôn ngữ (tốt nhất là một thủ tục / OO và một chức năng).

Điều này nói chung có đúng không? Có phải tất cả các ngôn ngữ lập trình được tạo thành từ các cấu trúc tương tự như vòng lặp, câu lệnh điều kiện và thông điệp truyền giữa các hàm? Có ngôn ngữ phi bí truyền nào mà một lập trình viên Java / Ruby / Haskell điển hình sẽ không thể hiểu được không? Có phải tất cả các ngôn ngữ có nguồn gốc chung?


4
Tôi sẽ hướng bạn đến việc đánh bại mức trung bình của Paul Graham. Bạn có thể hoặc không muốn đọc toàn bộ, nhưng đối với phần tìm kiếm có liên quan cho tiêu đề "Nghịch lý Blub". Ông Graham không thể bận tâm đặt neo vào tường văn bản của mình, vì vậy tôi không thể liên kết trực tiếp với nó.
kwatford

4
Ngôn ngữ không có nguồn gốc chung. Nhưng tất cả các ngôn ngữ cố gắng giải quyết một số vấn đề. Tôi nghĩ nó hơi giống với ngôn ngữ nói. Mục đích là để thể hiện bản thân. Tôi không thể nói rằng việc hiểu ngôn ngữ dựa trên kiến ​​thức về 1 thủ tục / OO / chức năng là điều dễ hiểu. Tôi đã không làm điều này nhưng nếu tôi hỏi câu hỏi này, tôi sẽ xem xét perl hoặc lisp với rất nhiều dấu ngoặc và tôi sẽ không thể nói rằng biết 1 ngôn ngữ thuộc mọi loại là đủ.
shahkalpesh

1
Trong trường hợp đó: Lambda tính toán. Có lẽ không phải là ngôn ngữ 'thực', nhưng nó là mẹ của tất cả các ngôn ngữ lập trình theo một nghĩa nào đó. Tôi đã từng phải thực hiện một ngôn ngữ chức năng sao cho nó được biên dịch thành các biểu thức lambda (sau đó được giải thích trực tiếp). Kết quả là (với tôi, ít nhất) không thể đọc được mặc dù vẫn giữ được tất cả các định danh liên quan. Đặc biệt là các hàm đệ quy sử dụng bộ kết hợp Y. Cách thực tế duy nhất để tìm ra những gì một số biểu thức mẫu đã làm là đánh giá chúng bằng tay. Những thứ đơn giản như fibonnaci và sắp xếp hợp nhất là không thể đọc được.
kwatford

2
Nếu bạn biết các ngôn ngữ chức năng, bạn nên biết rằng các vòng lặp không thể có trong mọi ngôn ngữ.
jalf

Piet là khá khác nhau. :)

Câu trả lời:


88

Cơ bản của hầu hết các ngôn ngữ thủ tục là khá giống nhau.

Họ cung cấp:

  • Kiểu dữ liệu vô hướng: thường là boolean, số nguyên, float và ký tự
  • Kiểu dữ liệu tổng hợp: mảng (chuỗi là trường hợp đặc biệt) và cấu trúc
  • Các cấu trúc mã cơ bản: số học trên vô hướng, truy cập mảng / cấu trúc, bài tập
  • Các cấu trúc điều khiển đơn giản: if-then, if-then-other, while, cho các vòng lặp
  • Gói khối mã: hàm, thủ tục với tham số
  • Phạm vi: các khu vực trong đó định danh có ý nghĩa cụ thể

Nếu bạn hiểu điều này, bạn đã nắm bắt tốt 90% ngôn ngữ trên hành tinh. Điều làm cho các ngôn ngữ này hơi khó hiểu hơn là sự đa dạng đáng kinh ngạc của cú pháp kỳ lạ mà mọi người sử dụng để nói những điều cơ bản giống nhau. Một số sử dụng ký hiệu ngắn gọn liên quan đến dấu câu lẻ (APL là một cực trị). Một số sử dụng rất nhiều từ khóa (COBOL là một đại diện xuất sắc). Điều đó không quan trọng lắm. Điều quan trọng là nếu ngôn ngữ đã hoàn thành đủ để tự thực hiện các nhiệm vụ phức tạp mà không khiến bạn xé tóc ra. (Hãy thử mã hóa một số hack chuỗi nghiêm trọng trong kịch bản shell của Window DOS: đó là Turing có khả năng nhưng thực sự rất tệ ở mọi thứ).

Ngôn ngữ thủ tục thú vị hơn cung cấp

  • Phạm vi lồng nhau hoặc từ vựng, không gian tên
  • Con trỏ cho phép một thực thể tham chiếu đến một thực thể khác, với phân bổ lưu trữ động
  • Bao bì của mã liên quan: gói, đối tượng với phương thức, đặc điểm
  • Kiểm soát tinh vi hơn: đệ quy, tiếp tục, đóng cửa
  • Toán tử chuyên biệt: hoạt động chuỗi và mảng, hàm toán học

Mặc dù về mặt kỹ thuật không phải là một thuộc tính của ngôn ngữ, mà là một thuộc tính của hệ sinh thái nơi các ngôn ngữ đó sinh sống, là các thư viện có thể truy cập dễ dàng hoặc được cung cấp với ngôn ngữ như một phần của công cụ phát triển. Việc có một loạt các cơ sở thư viện đơn giản hóa / tăng tốc độ viết các ứng dụng chỉ vì người ta không phải phát minh lại những gì các thư viện làm. Mặc dù Java và C # được cho là rộng rãi và là ngôn ngữ tốt, nhưng điều làm cho chúng thực sự hữu ích là các thư viện khổng lồ đi kèm với chúng và các thư viện mở rộng có thể dễ dàng lấy được.

Các ngôn ngữ khó hiểu hơn là những ngôn ngữ không mang tính thủ tục:

  • Các ngôn ngữ chức năng thuần túy, không có bài tập hoặc tác dụng phụ
  • Các ngôn ngữ logic, như Prolog, trong đó tính toán và thống nhất biểu tượng xảy ra
  • Các ngôn ngữ khớp mẫu, trong đó bạn chỉ định các hình phù hợp với vấn đề và thường các hành động được kích hoạt bằng một kết quả khớp
  • Các ngôn ngữ ràng buộc, cho phép bạn chỉ định các quan hệ và tự động giải các phương trình
  • Ngôn ngữ mô tả phần cứng, trong đó mọi thứ thực thi song song
  • Các ngôn ngữ dành riêng cho tên miền, như SQL, Màu Petri Nets, v.v.

Có hai phong cách biểu diễn chính cho các ngôn ngữ:

  • Dựa trên văn bản, trong đó các định danh tên thực thể và luồng thông tin được mã hóa hoàn toàn trong các công thức sử dụng mã định danh để đặt tên cho các thực thể (Java, APL, ...)
  • Về mặt đồ họa, trong đó các thực thể được vẽ dưới dạng các nút và quan hệ giữa các thực thể được vẽ dưới dạng các cung rõ ràng giữa các nút đó (UML, Simulink, LabView)

Các ngôn ngữ đồ họa thường cho phép các ngôn ngữ văn bản dưới dạng chú thích trong các nút và trên các cung. Các ngôn ngữ đồ họa kỳ lạ cho phép đệ quy đồ thị (có văn bản :) trong các nút và trên các cung. Các ngôn ngữ đồ họa thực sự kỳ quặc cho phép các biểu đồ chú thích trỏ đến các biểu đồ được chú thích.

Hầu hết các ngôn ngữ này dựa trên một số lượng rất nhỏ các mô hình tính toán:

  • Phép tính lambda (cơ sở cho Lisp và tất cả các ngôn ngữ chức năng)
  • Hệ thống bài (hoặc kỹ thuật viết lại chuỗi / cây / biểu đồ)
  • Máy Turing (sửa đổi trạng thái và lựa chọn các ô nhớ mới)

Được hầu hết các ngành công nghiệp tập trung vào các ngôn ngữ thủ tục và các cấu trúc điều khiển phức tạp, bạn sẽ được phục vụ tốt nếu bạn học tốt một trong những ngôn ngữ thú vị hơn trong danh mục này, đặc biệt nếu nó bao gồm một số loại hướng đối tượng.

Tôi đặc biệt khuyên bạn nên học Scheme, đặc biệt từ một cuốn sách thực sự tuyệt vời: Cấu trúc và diễn giải các chương trình máy tính . Điều này mô tả tất cả các khái niệm cơ bản. Nếu bạn biết công cụ này, các ngôn ngữ khác sẽ có vẻ khá đơn giản ngoại trừ cú pháp ngớ ngẩn.


3
Câu trả lời chính xác! Theo dõi (có cách nào để đặt câu hỏi tiếp theo trong SO không?), Có ngôn ngữ nào tôi có thể thành thạo và yêu cầu hiểu tất cả các khái niệm trong phần mềm lập trình không? Nó sẽ là Lisp (hay một phương ngữ như Scheme)?

@Anirudh: Không có cơ chế theo dõi chính thức, nhưng bạn có thể mở một câu hỏi mới. Nếu nó chứa một lý do và một liên kết đến câu hỏi này, nó thậm chí có thể không được đóng lại. ;) Để trả lời theo dõi của bạn, tôi hoàn toàn tin rằng không chỉ có một ngôn ngữ, vì các mô hình quá khác nhau.

@Anirudh: Đồng ý với John Y, không chỉ có một. Nhưng nếu bạn tương đối mới với lĩnh vực này, bạn nên dành năng lượng đáng kể để nắm vững mô hình thủ tục (tôi coi OO chỉ là một chuyên ngành). Sẽ không hại gì khi nhìn vào các mô hình khác (logic, ràng buộc, dataflow) để hiểu được cách chúng hoạt động, nhưng đối với hầu hết các công việc công nghiệp hàng ngày, ngôn ngữ thủ tục là vua khá nhiều.
Ira Baxter

1
Cũng giống như với các ngôn ngữ tự nhiên, "khó hiểu hơn" là chủ quan và phụ thuộc vào ngôn ngữ đầu tiên bạn học.
NullUserException

1
@NullUserException: Điều này cho thấy bạn nên chọn ngôn ngữ đầu tiên của mình một cách cẩn thận, để tối đa hóa sự dễ hiểu của người khác. Đó là quan điểm của Đề án, và đặc biệt là cuốn sách SICP.
Ira Baxter

6

Ngôn ngữ mô tả phần cứng là ngôn ngữ lập trình, nhưng về mặt khái niệm thì rất khác nhau. Hãy thử VHDL hoặc Verilog về kích thước. Chúng là phổ biến cho lập trình đồ họa. (Ok, vì vậy chúng không phải là bộ xử lý, nhưng chúng là thiết bị điện toán có mục đích chung. Và như vậy nên được coi là phần cứng hợp lệ cho các chủ đề khoa học máy tính.) Bạn phải làm cho mọi thứ diễn ra một cách rõ ràng. Đó là một mô hình hoàn toàn khác. Bạn đã nghĩ về những điều xảy ra song song như quy tắc không phải là ngoại lệ. Đối với các vòng lặp trong verilog mở rộng thành phần cứng song song. Vì vậy, hành vi "mong đợi" có thể không phải là những gì bạn mong đợi.


Đó là một điểm hay. Tôi sẽ tra cứu Verilog / VHDL.

Tôi đã luôn nghĩ rằng các ngôn ngữ lập trình thông thường chỉ là những cách thực sự khó khăn để mã hóa các chương trình song song tự nhiên, chẳng hạn như VHDL. Khi bạn bắt đầu là một nhà thiết kế phần cứng, phần này về mọi thứ xảy ra theo kiểu nối tiếp có vẻ vô cùng vụng về. (Chúng tôi đang dạy các ngôn ngữ lập trình sai cho mọi người như ngôn ngữ đầu tiên của họ: đó phải là Verilog!).
Ira Baxter

4

Phụ thuộc vào những gì bạn có nghĩa là "về cơ bản." Tất cả các ngôn ngữ của bất kỳ linh hoạt là Turing-hoàn thành. Theo nghĩa đó: có, tất cả chúng đều giống nhau.

Ở mức độ thấp, tất cả chúng đều thực hiện các chuỗi hoạt động tương tự và tất cả các công cụ OS X của Windows, Linux và (gần đây) đều chạy trên các bộ xử lý tương thích Intel sử dụng cùng một bộ hướng dẫn. Theo cách đó họ cũng cơ bản giống nhau.

Tôi nhận ra rằng bạn sắp xếp "cơ bản" trong câu hỏi của bạn, nhưng để thực sự trả lời nó, định nghĩa đó sẽ phải được tinh chỉnh hơn nhiều. Theo nhiều cách, tất cả đều giống nhau. Theo nhiều cách, chúng là khác biệt. Thật quá dễ dàng để nói "nó phụ thuộc." Nếu bạn thực hiện một trong hai thái cực, câu hỏi có thể sẽ không trả lời bạn dự định nó như thế nào, nơi dòng đó được rút ra là rất quan trọng để trả lời câu hỏi của bạn như bạn dự định.


3

Tôi muốn nói rằng một ngôn ngữ mã hóa ý nghĩa. Nếu ý nghĩa có bất kỳ ý nghĩa nào trong một số ngữ cảnh thì tất cả các ngôn ngữ có thể diễn đạt ý nghĩa có thể được coi là tương đương bị giới hạn bởi ý nghĩa và bối cảnh.

Nếu bạn giới hạn bối cảnh đó với một máy Von Neumann tiêu chuẩn thì ý nghĩa tính toán của việc thay đổi bộ nhớ và tính toán trong một cpu có thể được coi là nguồn gốc - và có thể là ý nghĩa duy nhất mà tất cả các ngôn ngữ đều có. Tất cả những thứ khác là trừu tượng được xây dựng trên những điều này.


1
John von Neumann. Và nó KHÔNG được phát âm như "newman", giống như "noyman".

Cảm ơn đã sửa chữa - Tôi phát âm giống như bạn nói.
Preet Sangha

Khi ai đó đề nghị chỉnh sửa, bạn chỉ cần chỉnh sửa bài đăng của mình để phản ánh nó.
Phil Miller

2

Ngôn ngữ lập trình cũng là công cụ để suy nghĩ. Với quan điểm tư duy khác, một số vấn đề biến mất hoặc được chuyển sang loại khác, dễ quản lý hơn (ví dụ: nhiều mẫu thiết kế kiểu C ++ sẽ biến mất khi bạn đang suy nghĩ ở Lisp (ví dụ như bài thuyết trình của Peter Norvik ) và Erlang giải phóng bạn khỏi suy nghĩ của một số cấu trúc đồng thời hoặc cấu trúc điện toán phân tán ở mức độ thấp và cho phép bạn chỉ tập trung vào logic ứng dụng).

Tuy nhiên, lưu ý rằng đôi khi các mô hình "mới" có thể được áp dụng một phần cho các ngôn ngữ lập trình "cũ hơn", điều này giải thích tại sao chúng ta ví dụ có sách dạy lập trình chức năng cho các lập trình viên Java . Nhưng việc hỗ trợ và tích hợp một mô hình mạnh mẽ hơn ở cấp độ ngôn ngữ cho phép ứng dụng mô hình tự nhiên hơn (và do đó không thể hiểu các chương trình bằng ngôn ngữ hỗ trợ mô hình lạ, như được gợi ý bởi các câu trả lời khác - @Ira Baxter liệt kê các ngôn ngữ không theo thủ tục và @kwatford đề cập đến Paul Graham ).


2
+++++++[>+++++++++++<-]>+.<+++++++++++[>+++<-]>.>>+++++++[>++++++<-]>++++.

Ở cấp độ thấp nhất, mọi ngôn ngữ lập trình là "giống nhau", nhưng điều đó không có nghĩa là chúng giống nhau ở cấp độ mà bạn thực sự tương tác. Họ vấn đề trừu tượng cho bạn; điều đó không có nghĩa là họ trừu tượng hóa cùng một vấn đề hoặc họ trừu tượng hóa từng vấn đề theo cùng một cách.


1

Các ngôn ngữ trưởng thành thường có một vài mục tiêu và họ tạo ra sự đánh đổi nơi họ hy sinh thứ này cho thứ khác. Một ngôn ngữ có mục đích chung có thể được sử dụng cho bất cứ điều gì, nhưng không ngôn ngữ nào có thể vượt trội trong mọi lĩnh vực. Một vài ví dụ:

C cố gắng trở thành một ngôn ngữ lập trình hệ thống lý tưởng. Cuối cùng, nó hy sinh khả năng đọc và an toàn cho điều khiển và tốc độ thấp.

Python nhằm mục đích trở thành một ngôn ngữ kịch bản lý tưởng. Cuối cùng, nó hy sinh tốc độ và tính xác minh cho năng suất và tính di động.

Haskell cố gắng trở thành một ngôn ngữ an toàn, thuần túy về mặt toán học. Để kết thúc này, nó hy sinh khả năng học hỏi và quy ước cho tính xác minh và độ tin cậy.

Những hy sinh và lợi ích này tạo ra một sự khác biệt rất lớn trong ngôn ngữ. Có, hầu hết các ngôn ngữ lập trình có thể được sử dụng cho bất kỳ thứ gì có thể được thực hiện bằng máy tính, nhưng không có ngôn ngữ nào trong số đó nên được sử dụng cho mọi thứ. Tất cả các ngôn ngữ trên là những ngôn ngữ tôi sẽ chọn cho một số nhiệm vụ nhất định nhưng không phải cho các ngôn ngữ khác. Nếu tôi đang lập trình một hệ điều hành, tôi sẽ chọn C. Nếu tôi đang viết phần phụ trợ cho trang web, tôi sẽ sử dụng Python. Và nếu tôi đang viết một hệ thống tài chính, tôi sẽ sử dụng Haskell.

Cuối cùng, sự lựa chọn của bạn là một lập trình viên là công cụ phù hợp cho công việc.

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.