Làm thế nào bạn sẽ thiết kế một ngôn ngữ lập trình? [đóng cửa]


41

Nếu bạn thiết kế một ngôn ngữ lập trình, bạn sẽ làm thế nào? Những tính năng bạn sẽ đưa vào? Những gì bạn sẽ rời khỏi? Gõ tĩnh hay động? Đánh máy mạnh hay yếu? Biên soạn hay giải thích? Biện minh cho câu trả lời của bạn


12
Câu hỏi này quá mơ hồ. Các tính năng ngôn ngữ thực sự không thể được thảo luận cho đến khi mục đích của ngôn ngữ được xác định.
blucz

1
Nếu bạn có thể bỏ phiếu và nghĩ rằng đây là một câu hỏi hữu ích hoặc nó có câu trả lời hữu ích dưới đây, vui lòng bỏ phiếu. Các trang web StackExchange cần phiếu bầu để xây dựng một cộng đồng tốt. Bạn có thể cho 30 phiếu mỗi ngày, đừng lãng phí chúng. Người dùng đặc biệt có uy tín cao và số phiếu bầu thấp được đưa ra xin vui lòng đọc này: meta.programmers.stackexchange.com/questions/393/ Kẻ
Maniero

3
Tôi sẽ tạo một ngôn ngữ cấp cao với một phương thức: public void DoWhatIMeant ();
Dave

6
ngôn ngữ lập trình lý tưởng? ... Tôi sẽ khiến trình biên dịch đọc được suy nghĩ của mình và tạo ra một chương trình chính xác như tôi muốn .. :) có thể mất một lúc nhưng nó sẽ có giá trị.
WalterJ89

2
Biên dịch và giải thích là những đặc điểm của ... tốt, trình biên dịch hoặc trình thông dịch (duh), không phải ngôn ngữ. Tất cả các ngôn ngữ có thể được thực hiện bởi một trình biên dịch hoặc một trình thông dịch. Và trên thực tế, khá nhiều trong số chúng là. Có các trình biên dịch cho Ruby, Python, ECMAScript, PHP, có các trình thông dịch cho C, C ++, Java, Haskell, ...
Jörg W Mittag

Câu trả lời:


55
  • Tôi chắc chắn nghĩ rằng các ngôn ngữ lập trình chức năng sẽ bắt kịp, vì vậy ngôn ngữ của tôi sẽ có chức năng. Xem hiệu ứng thuần hóa với lập trình hàm

  • Tôi nghĩ rằng các CPU sẽ sớm có vô số lõi và các luồng sẽ là một địa ngục để quản lý. Vì vậy, Mô hình diễn viên là phải thay vì chủ đề. Xem Erlang - phần mềm cho một thế giới đồng thời

  • Tôi cũng nghĩ rằng OOP đã thất bại, giao tiếp giữa các đối tượng được giả định là không đồng bộ . Vì vậy, tôi nghĩ rằng chúng ta cần thông điệp đi qua , với những thông điệp bất di bất dịch. Gửi và quên đi. Như trong mô hình diễn viên. Xem lập trình hướng đối tượng: Con đường sai?

  • Tôi nghĩ rằng sẽ rất tốt nếu gõ tĩnh , vì vậy các lỗi được bắt sớm hơn trong chu kỳ phát triển. Nhưng tôi sẽ sử dụng suy luận kiểu như trong Haskell, để nhà phát triển không cần phải viết kiểu ở mọi nơi trong mã như trong C, C # và Java. Xem Tìm hiểu bạn một Haskell cho Great Good

  • Tôi cũng sẽ thiết kế một thư viện UI tuyệt vời , với bố cục khai báo , như trong WPF và Android. Nhưng tôi muốn có nó như trong Lập trình phản ứng chức năng .

Vì vậy, ngôn ngữ của tôi sẽ giống như đồng thời trong Erlang nhưng với cách gõ như trong Haskell và khung GUI như trong WPF.NET.


4
Nghe có vẻ giống Scala, ngoại trừ có thể là thư viện UI tuyệt vời.
Ape-inago

Tôi nghĩ rằng scala đã thông qua và diễn viên. Tôi đoán tôi không liên quan đến OOP như thế nào.
Ape-inago

@Jonas: trông rất tuyệt :) Tôi không biết nhiều về Mô hình diễn viên, nó có giống với những gì Go đã làm với những con khỉ đột không?
Matthieu M.

1
Điều duy nhất tôi nghi ngờ là gõ tĩnh. Tôi chắc chắn thích mạnh hơn thay vì gõ yếu, nhưng đôi khi gõ tĩnh quá hạn chế. Nhưng tôi không quen với Haskell và tôi chỉ nghe thấy những điều hay về hệ thống đánh máy của nó :)
sakisk

1
Thất bại của OOP, thật lòng mà nói, hầu như không có ngôn ngữ "hướng đối tượng" nào thực sự thực hiện nó. Hầu hết chỉ đơn giản là đánh giày mô hình đối tượng thành ngôn ngữ thủ tục và gọi nó là một ngày. Tôi ước rằng Smalltalk đã tự mình nắm bắt nhiều hơn, thay vì khiến mọi weenie nói ngôn ngữ thủ tục nói "Ơ, chúng ta có thể làm điều gì đó tương tự - có thể như thế" và hoàn toàn bỏ lỡ quan điểm của OOP.
cHao

22

Lưu ý: Tôi đã sử dụng cú pháp giống như C để mô tả các tính năng trong bài đăng này, nhưng tôi không kén chọn chính cú pháp đó miễn là nó không phải là một điều gì đó vô lý như tất cả các từ khóa là CAPS.

1. Hệ thống đánh máy

Tính năng số một mà tôi muốn có trong một ngôn ngữ là gõ tĩnh với kiểu gõ động tùy chọn . Lý do là việc gõ tĩnh cho phép bạn a) bắt lỗi sớm hơn là muộn và b) hầu hết các mã được ngầm định gõ, cho dù ngôn ngữ có phân biệt hay không. Tuy nhiên, có một số trường hợp sử dụng trong đó gõ động là cực kỳ hữu ích. Ví dụ: khi đọc dữ liệu từ một tệp, bạn thường có các trường thuộc các loại khác nhau và việc gõ động làm cho các thùng chứa không đồng nhất trở nên dễ dàng. Vì vậy, ngôn ngữ lý tưởng của tôi sẽ có một cái gì đó như thế này:

//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future

//function definitions
int countElements(Collection c)
{
  return c.count();
} 

//c HAS to be a collection, since countElements doesn't make sense otherwise

void addToCollection(Collection& c, vartype v) 
{
  c.append(v)
}

//c is passed by reference here

2. Biên dịch so với phiên dịch

Tôi muốn ngôn ngữ được biên dịch trước thời hạn hoặc JIT được biên dịch, nhưng không hoàn toàn được giải thích, tốc độ là lý do. Điều này liên kết đến điểm 1 , vì trình biên dịch / jitter tối ưu hóa sẽ có thời gian tối ưu hóa mã được nhập tĩnh dễ dàng hơn nhiều và mã được gõ động có thể chỉ còn nguyên trạng.

3. Đóng cửa

Ngôn ngữ phải hỗ trợ các cấu trúc lập trình chức năng và các hàm phải là các đối tượng hạng nhất.

4. Hướng đối tượng

Ngôn ngữ sẽ cho phép bạn viết mã hướng đối tượng, nhưng mã mệnh lệnh đơn giản cũng được cho phép. tức là, có thể viết một chương trình hello world như vậy:

int main(string<> args=null)
{
  printf("hello, world"); 
  return 0;
}

// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)

5. Không gian tên

Không gian tên là một điều tốt. Rất ít thứ nên đi vào không gian tên toàn cầu. Nhưng nếu bạn phải đặt công cụ vào không gian tên toàn cầu, bạn có thể (ala C ++).

6. Kiểu dữ liệu tích hợp

Ngôn ngữ phải có, như các kiểu dữ liệu tích hợp, các cấu trúc sau:

  • Một intkiểu dữ liệu hoặc các loại. Nếu chỉ có một intloại, nó sẽ có phạm vi không giới hạn. Nếu có nhiều hơn, nên ẩn ý ngầm vào loại nhỏ nhất có khả năng giữ kết quả tính toán, với loại phạm vi không giới hạn là lớn nhất.
  • Một floatloại nhị phân tích hợp sẵn , tương đương với một loại IEEE 754double
  • Một listloại có thể thay đổi được thực hiện như một danh sách liên kết đôi hoặc một khối các con trỏ giữ bộ nhớ liền kề cho mỗi phần tử
  • Một listloại không thay đổi hoạt động như một mảng nhưng kích thước của chúng không thể thay đổi sau khi tạo
  • Các stringloại có thể thay đổi và bất biến , với mặc định là bất biến.
  • Một maphoặc dictloại có thể thay đổi và giữ các khóa bất biến và các giá trị có thể thay đổi và / hoặc bất biến.
  • Các loại bộ sưu tập tích hợp phải được nhập đồng nhất theo mặc định, nhưng có thể là vartyped nếu được yêu cầu
  • Một booleanloại
  • Một nullhoặc noneloại có thể được gán cho một biến của bất kỳ loại nào.
  • Các setloại đột biến và bất biến
  • Một decimalkiểu thực hiện các biến dấu phẩy động thập phân
  • Một fixedloại, thực hiện một số điểm cố định

Các decimal, floatfixedloại nên chia sẻ chính xác public interface cùng (hoặc thông qua thừa kế hoặc gõ vịt), cho phép chúng được minh bạch thông qua đến và trở về từ chức năng. Kiểu cha mẹ có thể được gọi real.

7. Gọi theo giá trị và theo tham chiếu

Bạn sẽ có thể gọi các hàm theo cả giá trị và tham chiếu, với giá trị mặc định là giá trị (nghĩa là một bản sao của đối số được tạo và vận hành theo hàm).

8. Con trỏ

Ngôn ngữ nên có con trỏ và cho phép số học con trỏ. Con trỏ chỉ có thể được gõ tĩnh (để tránh cơn ác mộng là a void*). vartypecon trỏ rõ ràng không được phép. Có con trỏ và số học con trỏ cho phép ngôn ngữ được sử dụng nghiêm túc như ngôn ngữ lập trình hệ thống.

9. Lắp ráp nội tuyến

Liên quan đến 8. , Ngôn ngữ sẽ cho phép mã ngôn ngữ lắp ráp nội tuyến cho những tình huống cần thiết.

10. An toàn

Ngôn ngữ nên chủ yếu là an toàn để sử dụng, hỗ trợ xử lý ngoại lệ, vv Việc lắp ráp số học và nội tuyến của con trỏ có thể được chuyển thành các phần của mã được đánh dấu rõ ràng là không an toàn. Mã không an toàn được cho phép, nhưng không khuyến khích mạnh mẽ.

11. Hành vi không xác định

Tiêu chuẩn ngôn ngữ nên chỉ định cách chương trình ứng xử trong mọi trường hợp ngoại trừ trong mã được đánh dấu rõ ràng không an toàn, nghĩa là, không nên có hành vi không xác định bên ngoài các khối không an toàn. Điều này cho phép ngôn ngữ được sử dụng làm ngôn ngữ phát triển ứng dụng khả thi, trong khi vẫn cho phép bạn nói, viết một HĐH trong đó.

Đó là tất cả những gì tôi có thể nghĩ ra vào lúc này, nhưng tôi sẽ chỉnh sửa / cập nhật bài viết khi tôi nghĩ về nhiều thứ hơn.


5
Hãy xem "Ngôn ngữ lập trình D": digitalmars.com/d
Wizard79

Theo như tôi có thể nhớ, D không có kiểu gõ động tùy chọn hoặc loại số nguyên phạm vi không giới hạn tích hợp. Kiểu số nguyên không quá nhiều vấn đề, nhưng việc thiếu kiểu gõ động tùy chọn làm cho nó khá kém hấp dẫn.
Chinmay Kanchi

1
Tôi thực sự sẽ thêm một decimalloại ở đây.
cấu hình

3
Một loại null hoặc không có loại nào có thể được gán cho một biến thuộc bất kỳ loại nào. Rà - Bao gồm boolean? :-p
Timwi

1
Tôi không thấy "linh hoạt" trong bài viết gốc. Trình biên dịch nội tuyến sẽ không xuất hiện trong đầu tôi vì yêu cầu hàng đầu đối với ngôn ngữ lập trình. Có lẽ đó là theo Felix von Leitner ngày nay viết Trình biên dịch phần lớn cho bạn kết quả chậm không chính xác.
LennyProgrammer

7

Đây là cách ngôn ngữ lập trình giấc mơ của tôi sẽ như thế nào:

  • Một hệ thống kiểu tĩnh mạnh mẽ với một số hỗ trợ cho việc gõ phụ thuộc.
  • Tùy chọn gõ động.
  • Tháp số a la Lisp nhưng gõ tĩnh.
  • Macros a la Lisp.
  • Chủ yếu là ngôn ngữ lập trình hàm với sự hỗ trợ cơ bản cho lập trình mệnh lệnh (như gia đình ML).
  • Thu gom rác thải.
  • Kiểu suy luận.
  • Tiếp tục.
  • Tùy chọn ngữ nghĩa lười biếng.
  • Tất cả các cấu trúc điều khiển sẽ được cung cấp dưới dạng các hàm thư viện. (Điều này có thể được thực hiện bằng cách sử dụng hai tính năng mới nhất.)
  • Cú pháp tối thiểu (không nhỏ như Lisps, nhưng một cái gì đó thuộc loại Ioke / Seph.)

Âm thanh tốt. Mặc dù vậy, tôi chưa thực sự thấy một cách tốt để thực hiện các macro an toàn kiểu tĩnh.
Jörg W Mittag

@ Jörg: Người da đen?
missingfaktor

Trong Smalltalk, tất cả các cấu trúc điều khiển thực sự là các phương thức và nó không sử dụng các phần tiếp theo trong quá trình thực hiện. Một cái không cần thiết cho cái kia.
Sồi

@Oak, bạn có thể triển khai Python's yieldtrong Smalltalk không? Nên sạch sẽ để sử dụng.
missingfaktor

Một cơ chế giống như năng suất đã được triển khai trong smalltalk như một phương thức thư viện, không có sự tiếp nối.
Oak

6

Tôi đã thiết kế nó khá giống C #, nhưng Microsoft đã đánh bại tôi. :)

(Tất nhiên ngoại trừ việc tôi sẽ ít suy nghĩ thấu đáo hơn và nghiệp dư hơn.)

Tôi không quan tâm nhiều đến việc nó được biên dịch hay diễn giải, vì vậy tôi không cần phải biện minh cho điều đó.

Liên quan đến gõ tĩnh mạnh mẽ, tôi thấy khó để đánh giá cao tại sao điều này thậm chí đòi hỏi sự biện minh. Gõ tĩnh là một tính năng bắt lỗi trong thời gian biên dịch. Gõ động là thiếu tính năng đó và trì hoãn các lỗi cho đến khi chạy. Theo kinh nghiệm cá nhân của tôi, tôi đã có một vài trường hợp sử dụng trong đó công văn động có ý nghĩa và hữu ích, do đó, các kết luận tôi phải trải qua trong C # trước 4.0 để có được điều đó dễ dàng được chứng minh sau đó. Với C # 4.0, tôi thậm chí không cần phải biện minh điều đó nữa bởi vì hiện tại chúng tôi có công văn động.

Tuy nhiên, tôi có thể đã tạo ra một cú pháp mới thay vì gắn bó với cú pháp C cũ như C # đã làm. Tuyên bố chuyển đổi là đặc biệt khủng khiếp, và tôi cũng không thích cú pháp cast (đó là cách sai xung quanh). Mặc dù vậy, tôi không làm ầm ĩ về các chi tiết của cú pháp, vì vậy tôi không cần phải chứng minh chi tiết về nó, ngoại trừ việc tôi không muốn nó dài dòng như Visual Basic.

Còn điều gì bạn muốn tôi biện minh?


+1 Câu trả lời hay! Tôi cũng sẽ đăng lên một trong những của riêng tôi sau này.
Chinmay Kanchi

4
C # là một ngôn ngữ mạnh mẽ, nhưng cú pháp thường lộn xộn. Tôi nghĩ điều này là do rất nhiều tính năng này không có trong thiết kế ban đầu.
Casebash

Do đó "4.0", tôi đoán vậy.
Đánh dấu C

5

Vâng đây là danh sách các tính năng tôi sẽ đưa vào:


Cú pháp như Lisp

Phong cách Lisp

Ưu điểm :

  • Dễ dàng mở rộng cú pháp. Bạn đã bao giờ thử thực hiện một vòng lặp foreach trong C chưa? Nó không chính xác dễ dàng. (Tâm trí bạn, tôi đã làm điều đó ).
  • Đồng âm. Bạn có thể đơn giản(eval "your data files")

Nhược điểm :

  • Ký hiệu đánh bóng lồng nhau thường khó đọc

Lập trình chức năng

Phong cách Haskell

Ưu điểm :

  • Đồng thời dễ dàng, tất cả các mã là chủ đề an toàn.

Nhược điểm :

  • Khó thực hiện các tác dụng phụ trong mã chức năng thuần túy, mặc dù các đơn vị dường như làm rất tốt.

Đánh máy năng động

Phong cách Python

Ưu điểm :

  • Gõ động giúp mã dễ đọc, gõ mạnh có thể loại bỏ lỗi loại

Thực hiện :

Cho phép nạp chồng hàm dựa trên các loại, tương tự như CL defgeneric:

(define (+ (a <int>) (b <int>))
  (ints-add a b))

(define (+ (a <string>) (b <string>))
  (string-concat a b))

(define (+ a b)
  (add-generic a b))

Có thể biên dịch và giải thích

Ưu điểm :

  • Tăng hiệu suất nếu được biên dịch (thường là đúng, không phải luôn luôn)

Nhược điểm :

  • Có thể giới hạn các tính năng trong ngôn ngữ, llvm sẽ được hỗ trợ tốt.

Lập trình hệ thống

Phong cách C

Ưu điểm :

  • Kháng cáo cho một, rất ít, phạm vi người dùng rộng hơn.
  • Các ứng dụng, trình điều khiển hạt nhân và thiết bị dễ dàng tương tác hơn nếu tất cả chúng được viết bằng cùng một ngôn ngữ

Nhược điểm :

  • Hạn chế sự trừu tượng trong ngôn ngữ, gõ động thường không phù hợp.

Macro vệ sinh (kiểu CL và kiểu Scheme)

Ưu điểm :

  • Dễ dàng mở rộng ngôn ngữ, đặc biệt là với cú pháp Lispy ™
  • Tôi đã nói điều này trước đây, phải không?

Nhược điểm :

  • Không nhiều nếu được thực hiện với cú pháp Lispy ™

Hãy nghĩ về nó, điều này ít nhiều xác định sơ đồ, ngoại trừ bit biên dịch và lập trình hệ thống. Điều đó có thể được giải quyết bằng cách sử dụng libguile và viết các bit đó vào C.


1
Hãy nhìn vào Ioke và Seph. Thật đáng ngạc nhiên khi một ngôn ngữ có thể dễ đọc hơn nhiều bằng cách chỉ thêm một lượng cú pháp nhỏ so với S-Expressions và vẫn có các khả năng macro đầy đủ. (Về cơ bản, thay vì "mọi cuộc gọi chức năng là một danh sách và danh sách là hạng nhất" đó là "tất cả mọi thứ là một gửi tin nhắn và chuỗi nhắn là lớp đầu tiên". Thay vì một danh sách mà carlà chức năng và cdrlà các đối số, bạn có một đối tượng có nametrường là phương thức và argumentstrường có đối số. Và thay vì lồng nhau, bạn có prevnextcác trường con trỏ.)
Jörg W Mittag

Âm thanh khá giống với Clojure (giả sử bạn sử dụng Mjolnir cho việc tạo mã gốc trên LLVM cho phần lập trình hệ thống - github.com/halgari/mjolnir )
mikera

3

Có một số ngôn ngữ ngoài kia mà tôi cho là khá tốt (C # là yêu thích hiện tại của tôi). Vì đây là ngôn ngữ tưởng tượng của tôi, đây là thứ tôi thực sự muốn nó có:

  • Kick-ass tài liệu api chính thức. API Java là tốt như thế này và C # /. NET là khá tốt. Ruby / Rails là khá khủng khiếp ở đây.
  • Tài liệu chung chính thức của Kick-ass (cách sử dụng, cách sử dụng phổ biến, rất nhiều mã ví dụ). C # /. Net là tốt cho việc này.
  • Một cộng đồng lớn gồm các tài liệu dựa trên blog và người giải quyết vấn đề StackOverflow để giúp tôi thoát khỏi những điểm khó khăn
  • Một loạt các plugin / thư viện / tiện ích mở rộng được hỗ trợ tốt, được tài liệu tốt và mạnh mẽ (Ruby / Rails có 'mạnh mẽ' nhưng không phải là cả hai).
  • Là ổn định hợp lý - không thay đổi mọi thứ để phá vỡ hầu hết các mã hiện có trên cơ sở hàng năm (nhìn vào bạn, Ruby / Rails).
  • Không quá ổn định - có thể thích ứng với những tiến bộ trong thiết kế ngôn ngữ (nhìn vào bạn, c ++)

2
Điểm "tài liệu Kick-ass" phải bao gồm PHP: D
Corey

3

Gợi ý trình biên dịch

Tôi đang nói chuyện với tôi vì tôi không biết nhiều về thiết kế ngôn ngữ, nhưng tôi nghĩ tính năng mà tôi đang nói đến được gọi là gợi ý trong các ngôn ngữ khác. Gợi ý trình biên dịch , có thể?

Tôi không biết nếu tôi đọc điều này trong một bản nháp Perl6 hay chỉ ở mức cao vào thời điểm đó, nhưng tôi tưởng tượng một ngôn ngữ mà mọi thứ theo mặc định là loosy loosy và tự động. Nhưng nếu bạn muốn thực sự giảm hiệu suất và nói, giá trị này luôn luôn là một số nguyên hoặc nó không bao giờ là null hoặc điều này có thể song song hoặc điều này là không trạng thái, những thứ như thế ... Trình biên dịch có thể tự động đi đến thị trấn trên các khu vực được đánh dấu cụ thể.

E: Tôi đánh giá cao những bình luận làm rõ những gì tôi yêu cầu hoặc trích dẫn các ví dụ nơi điều này đã tồn tại.


1
Bạn có thể làm một số điều này trong Common Lisp. Ví dụ, bạn có thể nói với trình biên dịch rằng i là một số nguyên có kích thước hợp lý. Một điều hữu ích là, bằng cách thay đổi giá trị safetyspeedgiá trị, bạn thường có thể kiểm tra và thực thi trình biên dịch (để tìm các vấn đề) hoặc giả sử những gì bạn nói là đúng (và biên dịch mã nhanh hơn).
David Thornley

2

Để thử những ý tưởng mới:

Tôi sẽ tạo một ngôn ngữ lập trình hàm được gõ động, nó cho phép bạn thực hiện tất cả các thủ thuật biểu thức câu lệnh và cú pháp lambda đơn giản nhất với khớp mẫu. Quy tắc phụ được kích hoạt.

// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def

// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
  p "Hello, \{name}!"

(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value

Đây là một lời giải thích:

default =thiết lập lưu trữ, \def valbắt đầu một hàm được nén với hai đối số, val.Typegiống như Type[val], !!chuyển đổi thành boolean và boolean có thể được áp dụng, vì vậy valdef are after it.

f x= f[x]= x.f .f= =f[]

và trong greet, nó được sử dụng name<(default "world")hasType Str>, nó có nghĩa là mô hình default "world"sẽ được sử dụng và ràng buộc name. Mẫu mặc định chỉ định một giá trị mặc định. andlà một mẫu khác xâu chuỗi hai mẫu với nhau. các defaultmô hình không thể thất bại trong khi hasTypecó thể thất bại. Trong trường hợp đó, nó ném một ngoại lệ.

Các biến thực sự là các kho lưu trữ, có thể được truyền qua chức năng và các bảng lưu trữ có thể là các tham chiếu, được tạo và hủy khi phạm vi thay đổi.

Băm và như vậy sẽ giống như trong Lua và JavaScript.

Nếu tôi sẽ tạo một ngôn ngữ được biên dịch, tôi sẽ tạo một F # cho Java, với các tính năng giống như Haskell. Đó là một ngôn ngữ chức năng thuần túy, ngoại trừ có một tính năng kết hợp các Báo giá và Comp Exprs với nhau để đạt được lập trình bắt buộc bằng cách viết các khối giống như mã giả.


1
Nghe có vẻ hơi giống Erlang, một ngôn ngữ lập trình hàm được gõ động và thêm vào đó là một cấu trúc ngôn ngữ đồng thời khá độc đáo.
Jonas

2

Hãy nhớ rằng các ngôn ngữ duy nhất tôi biết là PHP và javascript và tôi thực sự nên tìm hiểu thêm một chút trước khi thiết kế ngôn ngữ:

Cú pháp: Hãy suy nghĩ cẩn thận về tên hàm và thứ tự đối số (nghĩa là ít lộn xộn hơn PHP).

Các tính năng: Có một tập hợp các stringhàm, hoạt động trên các biến dưới dạng một chuỗi byte, nhưng không hiểu văn bản và một tập hợp các texthàm, hiểu rất nhiều mã hóa và có thể hoạt động trên UTF-8 và các chuỗi đa chuỗi khác. (Và có các kiểm tra độ chính xác mã hóa được tích hợp vào ngôn ngữ, với một chức năng như text.isValidEncoding(text, encoding)sẽ cho bạn biết nếu một chuỗi byte không đúng định dạng và không an toàn để coi là văn bản.

Tôi nghĩ rằng tôi thích ý tưởng gõ tĩnh mạnh mẽ, nhưng tôi chưa bao giờ sử dụng nó, vì vậy tôi thực sự không thể nói.


2

Trước khi thiết kế một ngôn ngữ lập trình, tôi sẽ tìm thấy một câu trả lời hay cho câu hỏi: tại sao chúng ta cần một ngôn ngữ lập trình khác? Mã Rosetta tại thời điểm viết bài này liệt kê 344 ngôn ngữ. Nếu không ai trong số họ đáp ứng nhu cầu của tôi, thì chi tiết cụ thể tại sao họ không xác định điểm bắt đầu (ngôn ngữ gần nhất) và những gì sẽ được thêm vào đó.

Nếu tôi trúng xổ số và vì một lý do nào đó không có gì tốt hơn, tôi sẽ bắt đầu với Liskell và biến nó thành ngôn ngữ chính thức trái ngược với giao diện GHC, sau đó làm cho FFI dễ dàng hơn (và tự động) để tôi có thể sử dụng bất kỳ Thư viện C / C ++.


2

Một ngôn ngữ tốt là một ngôn ngữ:

  • dễ dàng để lý do về (không có cú pháp tối nghĩa)
  • cho phép bạn thể hiện ý tưởng của mình với sự biến dạng tối thiểu
  • ẩn các chi tiết gritty nitty từ bạn (tối ưu hóa / quản lý tài nguyên)
  • dễ dàng song song hóa (nhiều lõi, tính toán phân tán)

Thật khó để biến điều này thành một danh sách các tính năng, nhưng tôi nghĩ Lập trình chức năng, mặc dù không cảm thấy tự nhiên , gần với điều này hơn là lập trình bắt buộc (đặc biệt là trong việc che giấu các chi tiết khó chịu)

  • Giao diện C: C là ngôn ngữ chung của ngôn ngữ lập trình và số lượng thư viện được phát triển trong C là đáng kinh ngạc. Bằng cách có giao diện dễ dàng (như Python) đến C, ngôn ngữ sẽ tự động hưởng lợi từ tất cả các thư viện đó và nó cũng cho phép gửi các tác vụ nặng không thể tối ưu hóa đủ gần với ngôn ngữ kim loại.
  • Phân phối : Tôi thích Go đi đa luồng, với các thói quen nhẹ mà thời gian chạy gửi trên các luồng tùy thuộc vào hoạt động của chúng. Một ngôn ngữ như vậy khuyến khích lập trình viên suy luận về các nhiệm vụ và cách ly chúng với nhau.
  • Bộ sưu tập rác : không cần phải nói ngày nay;)
  • Bất biến : dễ dàng hơn nhiều để lý giải về một thứ không bao giờ có thể đột biến, cũng dễ thực hiện tính toán đa luồng / phân tán hơn (bạn chỉ cần đồng bộ hóa để xử lý trọn đời, đó là nhiệm vụ của trình biên dịch)
  • Lambdas : đi với các chức năng hạng nhất tôi đoán
  • Truyền tin nhắn : bất biến có nghĩa là không có đột biến, do đó chúng tôi làm theo đề xuất của Tony Hoares
  • Các mô-đun : hơi giống với không gian tên, nhưng được đóng gói tốt hơn
  • Phản xạ : tính toán phân tán đòi hỏi phải tuần tự hóa, cần để lại cho trình biên dịch, và quá trình khử lưu huỳnh dễ dàng đạt được hơn với một số dạng phản xạ.
  • Gõ mạnh tĩnh : phát hiện lỗi sớm hơn, chi phí ít nhất

Hiện tại, ngôn ngữ gần với danh sách này có lẽ là Haskell, mặc dù:

  • nó thiếu các thói quen: Tôi chưa thấy một cách tự nhiên nào để thể hiện sự song song trong Haskell (mặc dù đó có thể là sự thiếu hiểu biết của tôi ...)
  • nó có một Cú pháp tối nghĩa: bằng cách nào đó, có vẻ như các lập trình viên Haskell phát triển mạnh khi sử dụng các toán tử lạ thay vì từ. Nó có vẻ lắt léo, nhưng nó không giúp nhiều để hiểu những gì đang xảy ra.

2

Đối với câu hỏi đầu tiên của bạn, "bạn sẽ làm như thế nào" - câu trả lời ngắn gọn, tôi sẽ không làm thế. Tôi không có đủ lý thuyết trình phân tích cú pháp / trình biên dịch để thực hiện điều đó. Nhưng tôi đã lập trình được 25 năm, vì vậy tôi có một số ý tưởng và ý kiến ​​để chia sẻ.

Trước hết, tôi sẽ cố gắng đưa ra một phương pháp OOP cho phép bạn tạo các mô hình thực sự được kết nối. Ý tôi là, mô hình là một trong những điều quan trọng nhất trong hầu hết mọi loại dự án lập trình - nó luôn có rất nhiều công việc lặt vặt và tái cấu trúc liên tục để làm cho đúng, và tôi đổ lỗi rằng thiếu kết nối thực sự trong Ngôn ngữ OO.

Cho phép tôi chứng minh. Giả sử một ngôi nhà đẳng cấp có tài sản Cửa.

var door = house.Door;

Bây giờ bạn có một biến cục bộ có tham chiếu đến thể hiện của Door.

Nhưng hãy xem xét những gì vừa xảy ra: Bạn vừa xé Cánh cửa ra khỏi Nhà, và bây giờ bạn khá hạnh phúc khi đi qua Cánh cửa xung quanh, và phần còn lại của mã của bạn không biết gì về việc Cửa này thực sự được gắn vào Nhà.

Đối với tôi, điều này về cơ bản là sai.

Và vâng, tôi biết, điều này "dễ dàng" được khắc phục trong từng trường hợp cụ thể - trong trường hợp này bằng cách duy trì một tham chiếu ngược từ mọi Cửa đến Nhà mà nó hiện đang gắn liền. Điều này tất nhiên mở ra mô hình của bạn có lỗi, vì giờ đây bạn có nhiệm vụ duy trì chính xác hai tham chiếu ngược, vì vậy bạn đặt các thuộc tính House.Doors và Door.House riêng tư và bạn thêm các phương thức như House.AddDoor (), House.RemoveDoor ( ), Door.SetHouse (), v.v. và kết nối tất cả, và kiểm tra đơn vị để đảm bảo nó thực sự hoạt động.

Đây không phải là bắt đầu nghe có vẻ như rất nhiều công việc để mô hình một mối quan hệ đơn giản như vậy? Rất nhiều mã để duy trì? Rất nhiều mã để cấu trúc lại khi mô hình phát triển?

Vấn đề là con trỏ. Mọi ngôn ngữ OO mà tôi đã thấy, vốn đã bị ảnh hưởng bởi thực tế là một tham chiếu đối tượng thực sự là một con trỏ, bởi vì đó là những gì máy tính sử dụng.

Con trỏ không phải là một cách tốt để mô hình hóa thế giới thực. Bất kể thế giới nào bạn đang cố gắng mô hình hóa, gần như đảm bảo rằng bất kỳ mối quan hệ nào trong thế giới đó sẽ là mối quan hệ hai chiều. Con trỏ chỉ theo một hướng.

Tôi muốn thấy một ngôn ngữ trong đó mô hình dữ liệu cơ bản là một biểu đồ - nơi tất cả các mối quan hệ, theo mặc định, có hai đầu. Điều này gần như chắc chắn sẽ cung cấp một sự phù hợp tự nhiên hơn nhiều để mô hình hóa thế giới thực, đó thực sự là điều duy nhất chúng ta cần máy tính cho lần đầu tiên. (đó và trò chơi video.)

Tôi không biết cú pháp cho một ngôn ngữ như vậy sẽ như thế nào, hoặc liệu nó có thể được diễn đạt bằng văn bản hay không. (Tôi đã tự hỏi nếu một ngôn ngữ như vậy sẽ phải là đồ họa, bằng cách nào đó ...)

Tôi cũng muốn thấy tất cả các hình thức nhà nước tình cờ bị loại bỏ.

Ví dụ, trong phát triển web, chúng tôi dành nhiều thời gian để định hình dữ liệu từ cơ sở dữ liệu, thành mô hình kinh doanh, mô hình xem để trình bày ... sau đó một số dữ liệu đó được trình bày trên các biểu mẫu, thực sự chỉ là một chuyển đổi khác. .. và trạng thái quay trở lại từ các bài đăng mẫu, và sau đó chúng tôi định hình lại dữ liệu đó và chiếu nó trở lại mô hình xem, ví dụ như các ràng buộc mô hình xem và như vậy ... sau đó chúng tôi chiếu từ mô hình xem trở lại doanh nghiệp- mô hình ... sau đó chúng tôi sử dụng các trình ánh xạ quan hệ đối tượng (hoặc công việc grunt) để chuyển đổi dữ liệu từ mô hình khung nhìn và chiếu nó vào cơ sở dữ liệu quan hệ ...

Đây có phải là bắt đầu âm thanh dư thừa? Tại thời điểm nào trong tất cả sự điên rồ này, chúng ta đã thực sự hoàn thành bất cứ điều gì hữu ích? Và ý tôi là hữu ích, một cái gì đó hữu hình - thứ mà người dùng cuối có thể hiểu và quan tâm. Vào cuối ngày, số giờ bạn đã thực sự xây dựng một cái gì đó mà người dùng thậm chí có thể hiểu, thực sự là những giờ duy nhất được chi tiêu tốt. Mọi thứ khác là tác dụng phụ.

Tôi muốn có một ngôn ngữ rất năng động. Chu kỳ ghi / biên dịch / chạy là một sự lãng phí thời gian. Lý tưởng nhất, ngôn ngữ chỉ nên tìm ra những gì đã thay đổi và biên dịch / tải trong suốt, trong nền, khi cần thiết.

Lý tưởng nhất là bạn thậm chí không cần phải nhấn "chạy" - mọi thứ sẽ diễn ra trên màn hình, khi bạn thực hiện thay đổi, ngay lập tức phản ánh những thay đổi bạn thực hiện. Vấn đề với chu trình ghi / biên dịch / chạy, hoặc thậm chí đối với vấn đề đó là chu trình ghi / chạy trực tiếp nhiều hơn, là bạn quá mất kết nối với những gì bạn đang làm - để cảm thấy được kết nối với công việc của chúng tôi, chúng tôi cần phản hồi ngay lập tức, kết quả ngay lập tức. Bất kỳ chờ đợi là quá dài!

Một lần nữa, tôi thậm chí không biết liệu điều này có thể được thực hiện với một IDE truyền thống hay không, nếu điều này đòi hỏi một loại giao diện hoàn toàn mới.

Bạn sẽ có thể sử dụng kết hợp gõ yếu và mạnh, bất cứ điều gì phù hợp nhất cho vấn đề bạn đang làm việc.

Nhà nước nói chung nên là một cái gì đó ngôn ngữ quản lý đầy đủ cho bạn. Tại sao bạn cần phải dựa vào cơ sở dữ liệu để kiên trì? Lý tưởng nhất, tôi muốn có thể chỉ định đơn giản thời hạn sử dụng của bất kỳ biến nào trong mô hình: một yêu cầu web, một phiên, 24 giờ, vĩnh viễn.

Tại sao chúng ta phải lựa chọn giữa một loạt các giải pháp lưu trữ cho các phương tiện truyền thông và cuộc sống khác nhau? - không đề cập đến việc chuyển đổi và định hình dữ liệu để phù hợp với từng phương tiện; bộ nhớ cache của trình duyệt, cơ sở dữ liệu, bộ nhớ, đĩa, ai quan tâm! Dữ liệu là dữ liệu. Nơi bạn lưu trữ dữ liệu của mình (và trong bao lâu) sẽ là một lựa chọn đơn giản, không phải là một trận chiến chống lại các vị thần!

Vâng, chúc may mắn với điều đó.


1

Nó có thể là một ngôn ngữ đa mô hình, hỗ trợ như sau:

  • Cấu trúc / lập trình thủ tục
  • Lập trình hướng đối tượng
  • Lập trình chức năng

Tại sao những điều này? Hướng đối tượng vì đó là một cách tuyệt vời để tổ chức các chương trình lớn, đặc biệt là tổ chức dữ liệu. Có cấu trúc vì bạn không luôn muốn / cần điều đó (OOP), mọi người nên có sự lựa chọn. Chức năng bởi vì nó giúp các lập trình viên dễ dàng gỡ lỗi và nó làm cho các chương trình rõ ràng hơn.

Tôi sẽ sử dụng mô hình của Python với các khối thụt lề để đánh dấu các khối mã. Nó là rất clen và tốt đẹp để đọc.

Tôi thực sự sẽ đánh cắp khá nhiều ý tưởng từ Python vì Python là một ngôn ngữ rất hay. Tôi sẽ lấy nó để tuyên bố và tôi sẽ sao chép bản đồ, danh sách và bộ dữ liệu của nó.

Bây giờ, tôi có lẽ sẽ không lấy các khái niệm động từ Python: vì một điều, nó có thể sẽ được gõ một cách rõ ràng và tĩnh. Tôi nghĩ rằng các chương trình trở nên rõ ràng hơn với điều đó. Các biến có thể tất cả sẽ là các đối tượng với các phương thức, sau đó bạn có thể làm một cái gì đó như str.length()để có được độ dài của một chuỗi. Trong các định nghĩa hàm, bạn sẽ phải chỉ định kiểu trả về và các loại đối số (cũng hỗ trợ một số loại chung chung).

Hãy quay lại sao chép từ Python ;-). Tôi thích cách có các đối số thủ tục tùy chọn vì vậy tôi có thể có điều đó. Tuy nhiên Python không hỗ trợ quá tải thủ tục, tôi muốn điều đó.

Hãy nhìn vào các lớp học, tôi sẽ bỏ qua nhiều kế thừa; để dễ lạm dụng. Tôi sẽ triển khai phạm vi riêng tư và tương tự và có lẽ tôi sẽ thực hiện theo cách nó được thực hiện trong C ++. Tôi cũng sẽ có các lớp và giao diện trừu tượng; Tôi không tin Python có cái đó.

Nó sẽ hỗ trợ các lớp bên trong, trên thực tế, tôi muốn có một ngôn ngữ hướng đối tượng rất mạnh.

Nó có thể sẽ được giải thích. Có thể làm cho nó thực sự nhanh bằng cách sử dụng trình biên dịch JIT tốt (tôi muốn có một ngôn ngữ nhanh, mặc dù năng suất của lập trình viên sẽ đến trước) và việc biên dịch chỉ có hại cho năng suất nhiều lần. Các ngôn ngữ được giải thích cũng thúc đẩy sự độc lập nền tảng, một thứ quan trọng hơn và nhiều hơn cho mỗi ngày.

Nó sẽ có hỗ trợ Unicode tích hợp; những ngày này quốc tế hóa rất nhiều vấn đề.

Nó chắc chắn sẽ được thu gom rác. Chết tiệt, tôi ghét tự mình quản lý bộ nhớ; cũng không tốt cho năng suất.

Cuối cùng, nó sẽ có một thư viện tiêu chuẩn tốt.

Wow, mới nhận ra tôi thực sự yêu Python đến mức nào.


Tại sao Interpreted languages also promote platform independance? Tôi đoán có nhiều trình thông dịch đa nền tảng hơn là trình biên dịch (phần trăm), nhưng không thể hiểu tại sao câu này phải đúng? Tôi nghĩ rằng không có sự khác biệt giữa chúng, liên quan đến khả năng đa nền tảng.
Mahdi

1

Trước hết, tôi sẽ mua một vài cuốn sách về trình biên dịch, một vài tiêu chuẩn và tham gia một hoặc hai khóa học về ngôn ngữ và trình biên dịch. Tôi sẽ đóng góp PEP và tham dự các cuộc họp của ủy ban tiêu chuẩn C ++. Tôi muốn đóng góp các bản vá cho trình biên dịch mà tôi sử dụng, hy vọng cả về tính năng và lỗi.

Sau đó, tôi sẽ quay lại và nhìn vào nỗi kinh hoàng trong danh sách này mà tôi đã đến bây giờ, đó là hướng đi mà tôi sẽ đi với một ngôn ngữ nếu tôi bắt đầu ngay bây giờ:

  • Về mặt chức năng , bởi vì hiện tại tôi không thành thạo bất kỳ ngôn ngữ chức năng nào và tạo ra một ngôn ngữ sẽ là một cách tuyệt vời để học một ngôn ngữ. Trong trường hợp nó không theo trực tiếp: mọi thứ đều không đổi .
  • Tôi sẽ điền nó với càng nhiều Kiểu suy luận càng tốt, nhưng với tùy chọn chỉ định giao diện rõ ràng. Không chắc chắn về các loại khác. Điều này tăng gấp đôi vì tất cả các chức năng là chung theo mặc định.
  • Như bạn có thể đoán, với Giao diện ; đó là, với các loại chỉ cung cấp lời hứa về các hoạt động có sẵn.
  • Nói rằng ngôn ngữ được gõ mạnh hay yếu không có ý nghĩa gì trong trường hợp này, theo như tôi có thể nói. Tôi sẽ gọi nó là đánh máy mạnh mẽ, vì mọi thứ không bao giờ thay đổi giao diện họ thực hiện .
  • Nó sẽ có rất nhiều Thiết kế bởi Hợp đồng hỗ trợ. Một lần nữa, nhiều nhất tôi có thể phù hợp: điều kiện tiên quyết và hậu điều kiện là phải; Tôi không biết có bao nhiêu bất biến quan trọng khi nói đến lập trình chức năng.
  • Trong khi tôi đang ở đó, tôi sẽ xem xét các ngôn ngữ nơi bạn có thể chính thức chứng minh tính đúng đắn và xem liệu tôi có thể nhận bất cứ thứ gì từ đó không.
  • Tôi sẽ đi ra ngoài và viết một thư viện thử nghiệm tuyệt vời . Ngay cả trong trường hợp tôi không làm cho nó tuyệt vời, ít nhất tôi sẽ dành một lượng thời gian đáng kể để làm việc đó vì tôi nghĩ đó là thứ mà mọi ngôn ngữ nên có.
  • Đối với cú pháp, ngôn ngữ sẽ có khoảng trắng đáng kể và trông rất giống Python , hoặc nó sẽ dựa trên Lojban và chia sẻ rất nhiều ngữ pháp và từ vựng. Trong trường hợp đầu tiên, tôi sẽ làm hết sức mình để làm cho ngữ pháp càng gần với CFG càng tốt.
  • Tôi sẽ không quan tâm liệu những người thực hiện ngôn ngữ sẽ biên dịch nó trước đó, JIT nó, giải thích nó, tụng nó trong lửa trại hay trả tiền cho những đứa trẻ học đại học để thực hiện nó cho họ. Việc triển khai của riêng tôi có thể bắt đầu như một trình thông dịch hoặc trình biên dịch C, và cuối cùng chuyển sang một JITter.

Nhìn thấy ngay cả những điểm khá rộng này có thể sẽ nhanh chóng thay đổi nếu tôi bắt đầu thực hiện ngôn ngữ, vì vậy tôi nghĩ rằng việc đi sâu vào chi tiết là không cần thiết.


0

Nếu có thời gian, tôi sẽ thiết kế một ngôn ngữ lập trình có thể bản địa hóa dựa trên Scala, vì vậy nó sẽ có hầu hết các tính năng của nó, ngoại trừ có lẽ là XML. Mục tiêu của tôi là tạo ra một ngôn ngữ đọc gần như tự nhiên trong các ngôn ngữ có cấu trúc khác với tiếng Anh, chẳng hạn như tiếng Ả Rập (tiếng mẹ đẻ của tôi). Tôi đang nghĩ về các tính năng sau:

  • Một #langchỉ thị tiền xử lý , được sử dụng để thông báo cho bộ xử lý trước ngôn ngữ của con người được sử dụng để lập trình. Ví dụ: #lang arsẽ cho phép sử dụng từ فئةthay vì class, عرفthay vì def, v.v. Các từ khóa dành riêng cho ngôn ngữ của con người sẽ được xác định trong các tệp tiền xử lý tiêu chuẩn.
  • Bộ xử lý trước sẽ loại bỏ một số từ khóa tùy chọn với mục đích duy nhất là thêm sự rõ ràng vào mã. Ví dụ, nó sẽ loại bỏ "được cấu thành từ" class MyClass is composed of {để trở thành class MyClass {và loại bỏ "như" def MyMethod(x: Int) as {để trở thành def MyMethod(x: Int) {. Trong một số ngôn ngữ (con người), điều này sẽ làm cho mã dễ hiểu hơn nhiều, đặc biệt là đối với sinh viên.
  • Trình biên dịch sẽ cho phép sử dụng ký hiệu tiền tố để truy cập thuộc tính. Điều này có thể không có ý nghĩa đối với hầu hết những người nói ngôn ngữ gốc Latinh, nhưng đối với một số ngôn ngữ khác, nó có ý nghĩa hoàn hảo. Ví dụ: quyền truy cập thuộc tính trong tiếng Ả Rập thường là tiền tố, như trong اعرض طول اسم محمد, tương đương với print(length(name(Mohammad)))tiếng Anh lập trình. (Dấu ngoặc đơn cho rõ ràng.)

Tôi tin rằng những thay đổi tối thiểu này đối với bộ xử lý trước và trình biên dịch sẽ giúp việc lập trình trở nên đơn giản hơn nhiều đối với những người không nói tiếng Anh.


5
Microsoft (và một số người khác trước đây) đã tạo các phiên bản VBA (Visual Basic cho các ứng dụng Office) đã bản địa hóa. Nó là một mớ hỗn độn. Mặc dù nó là tốt cho người mới, những người trẻ tuổi và những người không biết tiếng Anh để đọc mã bằng tiếng mẹ đẻ của họ, nhưng rất khó để chia sẻ mã với những người bên ngoài đất nước của bạn. Trong thời đại Internet của chúng ta, làm việc trong sự cô lập không hiệu quả lắm. Nếu tôi chỉ phải dựa vào các nguồn tiếng Pháp (bài viết trên blog, sách, v.v.) để học Scala (như tôi hiện tại), tôi sẽ bỏ lỡ nhiều thông tin hữu ích. Chưa kể đến khó khăn / số lượng công việc để bản địa hóa các thư viện ...
PhiLho

1
@PhiLho: Bạn chắc chắn đúng. Nhưng mục đích chính của tôi khi tạo ra một ngôn ngữ như vậy là để có thể giới thiệu lập trình cho nhiều đối tượng hơn, bao gồm cả sinh viên K-12 và người già có thể không thành thạo tiếng Anh. Ở cấp độ giới thiệu, có lẽ họ không cần sử dụng các thư viện bên ngoài và tạo các trình bao bọc cục bộ cho một số thư viện nhỏ (ví dụ print) sẽ không bị tổn thương.
Hosam Aly

1
Điểm khác là nhiều người đã sử dụng ngôn ngữ mẹ đẻ của họ cho tên lớp và phương thức. Nó không giúp họ rằng các từ khóa bằng tiếng Anh, cũng không tạo ra sự khác biệt với người khác, vì các từ khóa không đủ để hiểu mã không phải tiếng Anh. Tuy nhiên, bộ xử lý trước luôn có thể thay thế các từ khóa trở lại tiếng Anh và sau đó sang bất kỳ ngôn ngữ nào khác nếu cần.
Hosam Aly
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.