it-swarm-vi.com

Đây có phải là một thiết kế tồi cho ngôn ngữ lập trình để cho phép khoảng trắng trong định danh không?

Một số ( liên kết 1 , liên kết 2 ) ngôn ngữ lập trình cho phép khoảng trắng trong mã định danh của họ (ví dụ: biến, quy trình) nhưng hầu hết chúng không sử dụng và thay vào đó, lập trình viên thường sử dụng trường hợp lạc đà , trường hợp rắn và các cách khác để phân tách các từ trong tên.

Để hỗ trợ các khoảng trắng hoặc thậm chí các ký tự Unicode khác, một số ngôn ngữ lập trình cho phép đóng gói tên với một ký tự nhất định để phân định bắt đầu và kết thúc của nó.

Đó có phải là một ý tưởng tồi khi cho phép các không gian hay chỉ thường không được phép vì lý do lịch sử (khi có nhiều hạn chế hơn bây giờ hoặc đơn giản là được quyết định không có giá trị thực hiện)?

Câu hỏi là nhiều hơn về những ưu và nhược điểm chính của việc thực hiện nó trong các ngôn ngữ lập trình mới được tạo.

Các trang liên quan: liên kết 1 , liên kết 2 .

51
user7393973

Hãy xem xét những điều sau đây.

 var [Example Number] = 5;
 [Example Number] = [Example Number] + 5;
 print([Example Number]);

 int[] [Examples Array] = new int[25];
 [Examples Array][[Example Number]] = [Example Number]

So sánh nó với ví dụ truyền thống hơn:

 var ExampleNumber = 5;
 ExampleNumber = ExampleNumber + 5;
 print(ExampleNumber);

 int[] ExamplesArray = new int[25];
 ExamplesArray[ExampleNumber] = ExampleNumber;

Tôi khá chắc chắn rằng bạn nhận thấy rằng sự căng thẳng cho bộ não của bạn để đọc ví dụ thứ hai thấp hơn nhiều.

Nếu bạn cho phép khoảng trắng trên một mã định danh, bạn sẽ cần đặt một số yếu tố ngôn ngữ khác để đánh dấu điểm bắt đầu và điểm dừng của một từ. Những dấu phân cách đó buộc bộ não phải thực hiện một số phân tích bổ sung và tùy thuộc vào cái bạn chọn, tạo ra một loạt các vấn đề mơ hồ mới cho bộ não con người.

Nếu bạn không đặt dấu phân cách và cố gắng suy ra định danh nào bạn đang nói đến khi chỉ nhập mã theo ngữ cảnh, bạn mời một loại sâu khác:

 var Example = 5;
 var Number = 10;
 var Example Number = Example + Number;

 int[] Examples Array = new int[25];
 Examples Array[Example Number] = Example Number;

 Example Number = Example Number + Example + Number;
 print text(Example Number);

Hoàn toàn có thể làm được.

Một nỗi đau hoàn toàn cho mô hình phù hợp với não của bạn.

Những ví dụ đó gây đau đớn khi đọc không chỉ vì lựa chọn từ tôi đang chọn, mà còn bởi vì bộ não của bạn mất thêm thời gian để xác định những gì là mỗi định danh.

Hãy xem xét định dạng thường xuyên hơn, một lần nữa:

 var Example = 5;
 var Number = 10;
 var ExampleNumber = Example + Number;

 int[] ExamplesArray = new int[25];
 ExamplesArray[ExampleNumber] = ExampleNumber;

 ExampleNumber = ExampleNumber + Example + Number;
 printText(ExampleNumber);

Bạn có nhận thấy điều gì không?

Tên của các biến vẫn còn khủng khiếp, nhưng sự căng thẳng để đọc nó đã đi xuống. Điều đó xảy ra bởi vì bộ não của bạn bây giờ có một mỏ neo tự nhiên để xác định sự bắt đầu và kết thúc của mỗi từ, cho phép bạn trừu tượng hóa phần suy nghĩ đó. Bạn không cần phải lo lắng về bối cảnh đó nữa - bạn thấy một sự phá vỡ trong văn bản, bạn biết đó là một định danh mới sắp tới.

Khi đọc mã, não bạn không có nhiều đọc các từ nhiều như nó khớp với nó với những gì bạn có trong tâm trí của bạn ngay bây giờ. Bạn không thực sự dừng lại để đọc "exampleWord". Bạn thấy hình dạng quá mức của sự vật, ExxxxxxWxxd, khớp với bất cứ thứ gì bạn đã cất trong đống tinh thần của mình và họ tiếp tục đọc. Đó là lý do tại sao rất dễ bỏ lỡ những lỗi như "exampleWord = ExapmleWord" - bộ não của bạn không thực sự đọc nó. Bạn chỉ cần kết hợp với những thứ tương tự.

Một lần nữa, hãy xem xét những điều sau đây:

 Example Word += Example  Word + 1;

Bây giờ hãy tưởng tượng bạn đang cố gắng gỡ lỗi mã đó. Hãy tưởng tượng bạn sẽ bỏ lỡ bao nhiêu lần khoảng trống đó trên "Word Word". Một lá thư bị thất lạc đã khó như cái nĩa để phát hiện từ cái nhìn đầu tiên; một không gian thêm là một thứ tự cường độ tồi tệ hơn.

Cuối cùng, thật khó để nói rằng việc cho phép khoảng trắng sẽ làm cho văn bản dễ đọc hơn . Tôi cảm thấy khó tin rằng sự rắc rối thêm của các đầu mối phụ và chi phí hoạt động thêm trong não của tôi sẽ đáng để sử dụng loại chức năng này nếu ngôn ngữ tôi đang làm việc có nó.

Cá nhân, tôi coi đó là thiết kế tồi - không phải vì rắc rối về trình biên dịch, trình thông dịch hay bất cứ điều gì, mà bởi vì bộ não của tôi đi trên những không gian đó nghĩ rằng nó là một định danh mới sắp bắt đầu, khi nó chưa.

Theo một nghĩa nào đó, não của chúng ta chịu những vấn đề tương tự như bộ xử lý của chúng ta, khi nói đến dự đoán nhánh .

Vì vậy, xin vui lòng, hãy tử tế với các chuyến tàu suy nghĩ của chúng tôi. Đừng đặt khoảng trắng trên số nhận dạng của bạn.

101
T. Sar

Đây có phải là một thiết kế tồi cho ngôn ngữ lập trình để cho phép khoảng trắng trong định danh không?

Câu trả lời ngắn :

Có lẽ.

Câu trả lời dài hơn một chút :

Thiết kế là quá trình xác định và cân nhắc các giải pháp xung đột cho các vấn đề phức tạp và thực hiện các thỏa hiệp tốt đáp ứng nhu cầu của các bên liên quan. Không có "thiết kế xấu" hay "thiết kế tốt" ngoại trừ trong bối cảnh mục tiêu của các bên liên quan đó và bạn chưa nói những mục tiêu đó là gì , vì vậy câu hỏi quá mơ hồ để trả lời.

Câu trả lời dài hơn :

Như tôi đã nói ở trên, nó phụ thuộc vào mục tiêu của khu vực bầu cử mà nhà thiết kế ngôn ngữ đang giải quyết. Chúng ta hãy xem xét hai ngôn ngữ mà tôi quen thuộc: dạng MSIL có thể đọc được của con người, "ngôn ngữ trung gian" cấp thấp mà C # biên dịch và C #.

C # được dự định là ngôn ngữ giúp các nhà phát triển kinh doanh trực tuyến có năng suất cao trong các môi trường mà Microsoft coi là quan trọng về mặt chiến lược. Trong C #, một định danh là một chuỗi gồm một hoặc nhiều ký tự UTF-16 trong đó tất cả các ký tự được phân loại là chữ và số hoặc _, và ký tự đầu tiên không phải là số.

Ngữ pháp từ vựng này đã được lựa chọn cẩn thận để có các đặc điểm phù hợp với nhu cầu của các nhà phát triển LOB quan trọng chiến lược này:

  • Nó rõ ràng có thể lexable như một định danh; 1e10 ví dụ không phải là định danh hợp pháp vì nó không rõ ràng về mặt từ vựng với một số kép.
  • Nó hỗ trợ các thành ngữ thường được sử dụng trong C, C++ và Java, như đặt tên một trường riêng _foo. C # được thiết kế để thu hút các nhà phát triển đã biết một ngôn ngữ LOB phổ biến.
  • Nó hỗ trợ các định danh được viết bằng hầu hết mọi ngôn ngữ của con người. Bạn muốn viết var φωτογραφία = @"C:\Photos"; trong C #, bạn đi thẳng về phía trước. Điều này làm cho ngôn ngữ dễ tiếp cận hơn đối với các nhà phát triển không phải là người nói tiếng Anh bản ngữ.

Tuy nhiên, C # không hỗ trợ khoảng trắng trong mã định danh.

  • Nó sẽ làm phức tạp ngữ pháp từ vựng và đưa ra sự mơ hồ mà sau đó phải được giải quyết.
  • Trong phần lớn các tình huống xen kẽ, không cần thiết. Không ai đặt tên cho các thành viên công cộng của họ để có không gian trong đó.

Đó là một ý tưởng tốt để không cho phép các ký tự khác với các chữ cái và số trong số nhận dạng C #.

Ngược lại, trong MSIL, bạn có thể đặt tên cho một hàm gần như mọi thứ, kể cả đặt dấu cách hoặc các ký tự "lạ" khác trong tên phương thức. Và trên thực tế, trình biên dịch C # tận dụng lợi thế này! Nó sẽ tạo ra "tên không thể nói" cho các phương thức do trình biên dịch tạo ra mà mã người dùng không được gọi trực tiếp.

Tại sao đây là một ý tưởng tốt cho MSIL mà không phải C #? Bởi vì các trường hợp sử dụng MSIL hoàn toàn khác nhau:

  • MSIL không được thiết kế như một ngôn ngữ phát triển chính; nó là một ngôn ngữ trung gian, vì vậy trường hợp sử dụng chính cho nó là dành cho các nhà phát triển trình biên dịch đang cố gắng hiểu đầu ra của trình biên dịch của họ.
  • MSIL được thiết kế để có thể tương tác với bất kỳ môi trường phát triển Microsoft nào bao gồm pre-.NET Visual Basic và khác OLE = Tự động hóa máy khách, cho phép không gian trong định danh.
  • Như đã lưu ý ở trên, việc có thể tạo một tên "không thể nói được" cho một chức năng là một tính năng, không phải là một lỗi.

Vì vậy, nó là một ý tưởng tốt để cho phép không gian trong định danh? Nó phụ thuộc vào các trường hợp sử dụng ngôn ngữ. Nếu bạn có một trường hợp sử dụng vững chắc để cho phép nó, bằng mọi cách cho phép nó. Nếu bạn không, đừng.

Đọc thêm : Nếu bạn muốn có một ví dụ về ngôn ngữ hấp dẫn sử dụng tuyệt vời các số nhận dạng phức tạp, hãy xem Inform7 , DSL cho các trò chơi phiêu lưu dựa trên văn bản:

The Open Plain is a room. 
"A wide-open grassy expanse, from which you could really go any way at all."

Điều này khai báo một đối tượng mới thuộc loại room được gọi là The Open Plain, và đối tượng đó sau đó có thể được gọi như vậy trong suốt chương trình. Inform7 có một trình phân tích cú pháp rất phong phú và phức tạp, như bạn có thể tưởng tượng.

Đây là một ví dụ phức tạp hơn:

Before going a direction (called way) when a room (called next location) is not visited:
  let further place be the room the way from the location;
  if further place is a room, continue the action;
  change the way exit of the location to the next location;
  let reverse be the opposite of the way;
  change the reverse exit of the next location to the location.

Lưu ý rằng waynext locationfurther placereverse là các định danh trong ngôn ngữ này. Cũng lưu ý rằng next locationthe next location được đặt bí danh. (Bài tập : Mã này đang làm gì với cấu trúc dữ liệu duy trì bản đồ các phòng trong trò chơi?)

Inform7 có một khu vực bầu cử muốn ngôn ngữ tiếng Anh có vẻ tự nhiên hoàn toàn là mã nguồn. Nó có vẻ lạ khi viết Inform7 này như

  change the way exit of the location to the_next_location;

Đó là sự phá vỡ để làm như vậy. Tương phản điều này với câu trả lời (xuất sắc) của T. Sar, điều làm cho điểm tương phản - đó là sự phá vỡ đối với các nhà phát triển trong các ngôn ngữ LOB để cố gắng phân tích chính xác vị trí của các định danh. Một lần nữa, nó đi vào bối cảnh và mục tiê.

59
Eric Lippert

Một tương đối nổi tiếng ví dụ là một số mã Fortran trong đó một lỗi đánh máy đã thay đổi hoàn toàn ý nghĩa của mã.

Nó được dự định lặp lại một phần của mã 100 lần (với I là bộ đếm vòng lặp):

DO 10 I = 1,100

Tuy nhiên, dấu phẩy bị nhầm thành dấu chấm:

DO 10 I = 1.100

Vì Fortran cho phép khoảng trắng trong mã định danh (và vì nó tự động tạo biến nếu chúng chưa được khai báo), dòng thứ hai hoàn toàn hợp lệ: nó ngầm tạo ra một biến thực giả gọi là DO10I và gán cho nó số 1.1. Vì vậy, chương trình biên dịch tốt không có lỗi; nó chỉ thất bại để chạy vòng lặp.

Mã trong câu hỏi kiểm soát một tên lửa; như bạn có thể tưởng tượng, loại sai lầm đó có thể là thảm họa! May mắn thay, trong trường hợp này, lỗi đã được bắt gặp trong thử nghiệm và không có tàu vũ trụ nào bị tổn hại.

Tôi nghĩ điều này cho thấy khá rõ một trong những mối nguy hiểm trong việc cho phép không gian trong các định danh

15
gidds

Đây có phải là một thiết kế tồi cho ngôn ngữ lập trình để cho phép khoảng trắng trong định danh không?

Bạn đã quên chi tiết thực hiện quan trọng:

là gì mã nguồn cho bạn?

Tôi thích định nghĩa [~ # ~] fsf [~ # ~] của nó: hình thức ưa thích mà nhà phát triển làm việc. Đó là một định nghĩa xã hội, không phải là một kỹ thuật.

Trong một số ngôn ngữ và cách triển khai những năm 1980 của họ (nghĩ về máy gốc Smalltalk và 1980 Smalltalk), mã nguồn không phải là một chuỗi các ký tự. Đó là một cây cú pháp trừu tượng và được người dùng thao tác, bằng chuột và bàn phím, sử dụng một số GUI.

Theo một nghĩa nào đó, LISP chung chấp nhận khoảng trắng trong các ký hiệu của nó.

Bạn có thể quyết định (đó là a lot công việc) để cùng thiết kế cả ngôn ngữ lập trình của bạn ( tài liệu trong một số báo cáo đưa ra cả cú phápngữ nghĩa ), cách triển khai (như một số phần mềm) và trình chỉnh sửa của nó hoặc [~ # ~] ide [~ # ~] (như một số phần mềm).

Đọc các cuộc thảo luận cũ trên tunes.org . Đọc tác phẩm cũ tại INRIA trên

@TechReport{Jacobs:1992:Centaur,
 author =       {Jacobs, Ian and Rideau-Gallot, Laurence},
 title =        {a {\textsc{Centaur}} Tutorial},
 institution =  {\textsc{Inria} Sophia-Antipolis},
 year =         1992,
 number =       {RT-140},
 month =        {july},
 url =          {ftp://www.inria.fr/pub/rapports/RT-140.ps}
}

@techreport{donzeaugouge:inria-mentor,
 TITLE =        {{Programming environments based on structured
                 editors : the \textsc{Mentor} experience}},
 AUTHOR =       {Donzeau-Gouge, Véronique and Huet, Gérard and Lang,
                 Bernard and Kahn, Gilles},
 URL =          {https://hal.inria.fr/inria-00076535},
 TYPE =         {Research Report},
 NUMBER =       {RR-0026},
 INSTITUTION =  {{INRIA}},
 YEAR =         1980,
 PDF =
              {https://hal.inria.fr/inria-00076535/file/RR-0026.pdf},
 HAL_ID =       {inria-00076535},
 HAL_VERSION =  {v1},
}

Xem thêm báo cáo dự thảo Bismon của tôihttp://refpersys.org/

Ước mơ RefPerSys của tôi là hợp tác thiết kế một ngôn ngữ lập trình khai báo như vậy với Nice IDE cho nó. Tôi biết rằng có thể mất một thập kỷ. chúng tôi là!

Từ quan điểm khả dụng, tô màu cú pháptự động hoàn thành quan trọng hơn khoảng trắng trong mã định danh (nhìn vào cả hai GtkSourceViewCodeMirror cho cảm hứng). Trực quan một dấu gạch dưới _ trông gần giống với một nhân vật không gian. Và nếu bạn viết mã IDE của riêng mình, bạn có thể chấp nhận ctrlspace làm đầu vào cho "khoảng trắng bên trong tên". Ý kiến ​​của tôi là và ∀ nên là "từ khóa", câu hỏi trở thành cách bạn nhập chúng. Tôi đang mơ ước được gõ (lấy cảm hứng từ LaTeX) \forallESC để có được một (và tôi đã nghe nói về một số emacs mã con cho điều đó).

NB: Tôi ghét Python (và Makefile - s) vì khoảng trắng (hoặc tab) có ý nghĩa ở đó.

8
Basile Starynkevitch

Nó không phải là thiết kế xấu để cho phép khoảng trắng trong tên biểu tượng. Điều này có thể được hiển thị với một ví dụ đơn giản.

Kotlin cho phép không gian trong tên. Nó cũng có các quy ước mã hóa chính thức có trạng thái khi sử dụng tính năng này là ổn :

Tên cho phương thức kiểm tra

Trong các thử nghiệm (và chỉ trong các thử nghiệm), có thể chấp nhận sử dụng tên phương thức với khoảng trắng được đặt trong backticks.

Thí dụ:

class MyTestCase {
     @Test fun `ensure everything works`() { /*...*/ }

"Tốt" và "xấu" tất nhiên là chủ quan, nhưng sử dụng khoảng trắng trong tên phương thức kiểm tra giúp mã kiểm tra dễ đọc hơn và cũng kiểm tra kết quả Rất dễ đọc, không cần mã hóa kiểm tra cần lặp lại bằng cách có tên phương thức xấu và một mô tả thử nghiệm có thể đọc được của con người một cách riêng biệt.

Điểm quan trọng ở đây là, các phương thức này thường sẽ không được gọi một cách rõ ràng từ mã được viết bởi con người, vì vậy chỉ có nơi tên xuất hiện là ở định nghĩa phương thức. Tôi nghĩ rằng đây là một sự khác biệt quan trọng để xem xét khi không gian có thể là một ý tưởng tốt trong tên biểu tượng: chỉ khi biểu tượng chỉ được viết bởi một lập trình viên.

6
hyde

Quy tắc của ngón tay cái:

Lỗi tỷ lệ thuận với thời gian đọc mã thành tiếng.

Bất cứ điều gì làm tăng số lượng khung mở, khung đóng, dấu ngoặc nhọn mở, dấu ngoặc nhọn đóng, dấu ngoặc đơn mở, dấu ngoặc đơn đóng ... sẽ làm tăng số lỗi trong mã.

Đây là một lý do tại sao * là ngôi sao hoặc splat, và không phải dấu hoa thị. # là shhh ,! là bang Các nhà toán học tôi nghi ngờ cũng có những biểu hiện bằng lời nói ngắn cho biểu tượng của họ, tôi chắc chắn.

Đó là lý do tại sao các lĩnh vực công nghệ chứa đầy các từ viết tắt và viết tắt: Chúng tôi nghĩ bằng lời. Chúng ta có một khoảng chú ý hữu hạn và chỉ có thể giữ rất nhiều biểu tượng trong đầu. Vì vậy, chúng tôi nhóm và gộp các thứ lại với nhau.

Thực sựReallyLongIdentifier có thể làm điều tương tự. Ở đó, sự đánh đổi là giữa việc ghi nhớ những gì nó làm và bị rối trong quá trình suy nghĩ của chúng ta. Nhưng reallyReallyLongIndentifer vẫn tốt hơn QzslkjfZslk19

Càng xa sự sáng tạo của nó, nó càng được sử dụng, nó càng cần được ghi nhớ. Do đó, i, j, k được sử dụng cho các cấu trúc vòng lặp - giống như loài phù du mà chúng sống trong vòng đời và vòng lặp đó bắt đầu và kết thúc trên cùng một màn hình.

Điều này cũng mở rộng sang mã hóa:

A = FunctionAlpha (21, $ C, $ Q)

B = FunctionBeta ($ A, $ D, $ R)

sạch hơn

B = FunctionBeta (FunctionAlpha (21, $ C, $ Q), $ D, $ R)

Tôi nghĩ rằng đây là một lý do tại sao các bảng tính có tỷ lệ lỗi khủng khiếp như vậy mã hóa xấu: Ngoại trừ bằng cách thêm các ô/hàng/cột tạm thời, không có cách nào để tránh các câu lệnh lồng nhau lộn xộn.

3
Sherwood Botsford

Tôi đã mất một thời gian dài để thực sự mò mẫm rằng sẽ không bao giờ thực sự có một ngôn ngữ tốt nhất. Đối với một nhóm lập trình, các khía cạnh quan trọng nhất là ngôn ngữ được nhiều người biết đến, được hỗ trợ bởi nhiều công cụ, nên có cú pháp ngôn ngữ tối thiểu và sẽ làm bạn ngạc nhiên nhất có thể.

Đối với một lập trình viên, một ngôn ngữ mạnh mẽ cho phép các chu kỳ kiểm tra/chạy nhanh là tuyệt vời.

Đối với quản trị viên, ngôn ngữ được điều chỉnh theo ngôn ngữ Shell của hệ điều hành là rất quan trọng.

Đối với một số ngôn ngữ làm việc được chia sẻ giữa các ngành, DSL có thể là Nice.

Có một nơi cho một ngôn ngữ với không gian - có lẽ. Nó vi phạm các quy tắc không đáng ngạc nhiên nhưng rất phù hợp với các mục tiêu DSL.

Một điều tôi không nghĩ là có ai nhắc đến - với một tùy chỉnh IDE bạn thực sự có thể có một không gian cứng và một không gian mềm. Chúng trông giống nhau (có lẽ có các sắc thái khác nhau trong IDE) .

Đối với vấn đề đó, bạn có thể thực hiện ngay bây giờ với bất kỳ ngôn ngữ nào - chỉ cần đặt một nút bật tắt IDE để có dấu gạch dưới được hiển thị dưới dạng khoảng trắng. Bất kỳ ai tạo ra các trình cắm thêm Eclipse có thể làm điều này trong một giờ .

Bạn cũng có thể chuyển đổi thực tế trường hợp lạc đà thành "từ có khoảng trắng", IDE có thể làm điều đó cho bạn nhưng nó sẽ hơi lạ hơn.

0
Bill K