Những tranh luận có lợi cho việc gõ yếu?


40

Điều này xuất hiện trong một cuộc thảo luận với một người bạn và tôi thấy mình thật khó khăn để nghĩ ra bất kỳ lý lẽ tốt nào. Những lợi ích nào khi gõ yếu confer?


17
Kỹ thuật của Cooper và Torczon là Trình biên dịch định nghĩa kiểu gõ yếu là sử dụng hệ thống loại được thiết kế kém. Điều đó chắc chắn không có vẻ như nó sẽ có lợi cho bất cứ ai.
Corbin ngày

@Corbin Tháng ba: Đẹp một. Tôi cần thêm nó vào danh sách của tôi.
Jörg W Mittag

5
Lập luận tốt nhất có thể được đưa ra bởi các giám đốc điều hành của công ty: nó cho phép tôi thuê những người giá rẻ để xây dựng các hệ thống của mình
Vector

Câu trả lời:


46

Vấn đề với loại thảo luận này chỉ đơn giản là các thuật ngữ "gõ yếu" và "gõ mạnh" không được xác định, không giống như các thuật ngữ "gõ tĩnh", "gõ động", "gõ rõ ràng", "gõ ngầm", "gõ" gõ vịt "," gõ cấu trúc "hoặc" gõ danh nghĩa ". Heck, ngay cả các thuật ngữ "gõ biểu hiện" và "gõ tiềm ẩn", vẫn là các lĩnh vực nghiên cứu và thảo luận mở có lẽ được xác định tốt hơn.

Vì vậy, cho đến khi bạn của bạn cung cấp định nghĩa về thuật ngữ "gõ yếu" đủ ổn định để làm cơ sở cho một cuộc thảo luận, thậm chí không có ý nghĩa gì để trả lời câu hỏi này.

Thật không may, ngoài câu trả lời của Nick , không ai trong số những người trả lời bận tâm đưa ra định nghĩa của họ, và bạn có thể thấy sự nhầm lẫn tạo ra trong một số ý kiến. Thật khó để nói, vì không ai thực sự cung cấp định nghĩa của họ, nhưng tôi nghĩ rằng tôi đếm ít nhất ba cái khác nhau, chỉ trên chính trang này.

Một số định nghĩa được sử dụng phổ biến hơn là (và vâng, tôi biết rằng hầu như không có định nghĩa nào trong số chúng có ý nghĩa, nhưng đó là những định nghĩa tôi thấy mọi người thực sự sử dụng):

  • gõ yếu = gõ không an toàn / gõ mạnh = gõ an toàn
  • gõ yếu = gõ động / gõ mạnh = gõ tĩnh
  • gõ yếu = gõ vịt / gõ mạnh = gõ danh nghĩa
  • gõ yếu = gõ cấu trúc / gõ mạnh = gõ danh nghĩa
  • gõ yếu = gõ ngầm / gõ mạnh = gõ rõ ràng
  • gõ yếu = gõ tiềm ẩn / gõ mạnh = gõ biểu hiện
  • gõ yếu = không gõ / gõ mạnh = gõ
  • gõ yếu = phôi ẩn / gõ mạnh = chỉ phôi rõ ràng
  • gõ yếu = phôi ngầm hoặc rõ ràng / gõ mạnh = không có phôi nào cả
  • gõ yếu = chuyển đổi ngầm định / gõ mạnh = chỉ chuyển đổi rõ ràng
  • gõ yếu = chuyển đổi ngầm định hoặc rõ ràng / gõ mạnh = không có chuyển đổi nào cả
  • gõ yếu = giải thích / gõ mạnh = biên dịch
  • gõ yếu = chậm / gõ mạnh = nhanh
  • gõ yếu = thu gom rác / gõ mạnh = quản lý bộ nhớ thủ công
  • gõ yếu = quản lý bộ nhớ thủ công / gõ mạnh = thu gom rác
  • Giáo dục và nhiều người khác

Tuy nhiên, ba định nghĩa dường như được sử dụng rộng rãi nhất

  • gõ yếu = ngôn ngữ lập trình ngu ngốc của bạn / gõ mạnh = ngôn ngữ lập trình siêu tuyệt vời của tôi
  • gõ yếu = mọi ngôn ngữ lập trình khác / gõ mạnh = ngôn ngữ lập trình duy nhất tôi từng học (thường là Java, C # hoặc C ++; lạ thay, những người học ví dụ như Haskell hoặc Scheme là ngôn ngữ đầu tiên và duy nhất của họ dường như không chia sẻ thế giới quan này)
  • gõ yếu = mọi ngôn ngữ tôi không hiểu / gõ mạnh = Java (thay thế bằng C # hoặc C ++ tùy ý)

Trừ khi tất cả mọi người đồng ý về một định nghĩa về "gõ yếu" là gì , thậm chí không có ý nghĩa gì để nghĩ về những lợi thế của nó có thể là gì. Ưu điểm của cái gì? Thậm chí tệ hơn, nếu không có định nghĩa nào cả , thì mọi người chỉ có thể thay đổi định nghĩa của mình để phù hợp với lập luận của họ, và mọi cuộc thảo luận đều được đảm bảo khá nhiều để biến thành một flamewar.

Bản thân tôi đã tự thay đổi định nghĩa của mình nhiều lần trong nhiều năm và giờ đã đạt đến mức tôi thậm chí không còn xem xét các điều khoản hữu ích nữa. Tôi cũng từng nghĩ rằng việc gõ yếu (theo nhiều định nghĩa khác nhau) có một vị trí trong kịch bản shell, nhưng bất cứ khi nào tôi phải giải quyết vấn đề tương tự trong Bash và PowerShell, tôi đau đớn nhắc nhở rằng tôi đã sai như thế nào.


5
Câu trả lời khá cay độc! Tôi đến từ nơi bạn đến nhưng tôi cảm thấy "đủ tốt" để đoán rằng bất kỳ ai không đưa ra định nghĩa đều đề cập đến "gõ yếu và / hoặc gõ động", đó là lý do tôi đưa cả hai vào câu trả lời của mình. Tôi biết nó không hoàn hảo, nhưng hầu hết mọi người dường như điều chỉnh khi nói đến việc xác định hệ thống loại.
Nicole

7
@Renesis: Tôi gọi nó là "chủ nghĩa hiện thực" :-) Tôi đã thấy đủ các cuộc thảo luận về hệ thống loại để nhận ra rằng một nửa số người không nhận ra họ đang nói về những điều hoàn toàn khác nhau và người kia không biết họ đang nói gì về ở tất cả . Một vài tháng trước, có một cuộc thảo luận về danh sách phát triển cốt lõi của ngôn ngữ mà tôi sẽ không nêu tên, về việc thêm một hệ thống loại tùy chọn để cải thiện hiệu suất. Cuộc thảo luận đó diễn ra trong một tuần, liên quan đến hàng chục người và hàng trăm thư. Không ai nhận ra rằng một hệ thống loại tùy chọn theo định nghĩa không thể cải thiện hiệu suất. Tiết
kiệm

8
+1 cho sự hoài nghi! Bạn có thể thêm "gõ mạnh = khi IDE biết các loại biến của tôi (Intellisense, v.v.), gõ yếu = khi không)"
user281377

1
Các tên được xác định tốt hơn cho các hệ thống gõ thiếu phán đoán giá trị ngầm định yếumạnh .
Eva

1
Tuyệt đẹp, giải trí, và chính xác. Càng tìm hiểu nhiều về các hệ thống loại, tôi càng nhận ra mình đã phải chịu đựng ảo tưởng rằng một ngôn ngữ khác với ngôn ngữ khác theo cách mà nó hoàn toàn không tồn tại. Thật đáng ngạc nhiên khi khái niệm này gây ra sự nhầm lẫn đến mức nào và tôi thực sự nghĩ rằng không cần thiết nếu chúng ta chấp nhận rằng yếu / mạnh không phải là điều có thật, vì vậy hãy nói về điều gì đó thực sự là và có thể chúng ta sẽ học được điều gì đó.
BrianH

25

Hãy nhớ rằng có hai khái niệm chính thường bị nhầm lẫn:

Gõ động

Một ngôn ngữ lập trình được cho là được gõ động khi phần lớn việc kiểm tra kiểu của nó được thực hiện trong thời gian chạy trái ngược với thời gian biên dịch. Trong kiểu gõ động, các giá trị có kiểu nhưng biến không; có nghĩa là, một biến có thể tham chiếu đến một giá trị của bất kỳ loại nào.

Những ưu điểm ở đây thường bị loại bỏ chỉ dành cho các lập trình viên "mới", nhưng cũng có thể thuận tiện cho bất kỳ lập trình viên nào:

if (!(arr is Array)) arr = [arr]; // is, instanceof, .constructor ==, whatever

Ít mã hơn trong mọi trường hợp nếu bạn phải truyền hoặc gán giá trị mới:

if (data is Array)) {
    i = data.length; // no i = ((Array)data).length or Array myArr=(Array)data;
}

Gõ lỏng hoặc yếu

Gõ yếu có nghĩa là một ngôn ngữ ngầm chuyển đổi các loại (hoặc phôi) khi sử dụng.

Lợi ích:

  • Truyền bất kỳ giá trị loại nào dưới dạng tham số cho hàm . Hữu ích cho các cuộc gọi lại, API linh hoạt và giúp cho việc thực hiện các bao đóng đơn giản hơn.
  • Đánh giá boolean tiềm ẩn . Bất kỳ loại có thể được đánh giá là một boolean. Điều này cũng có các lợi ích phụ như một phần của một ||có thể được sử dụng trong chuyển nhượng mà không cần chuyển đổi sang boolean:

    var a = param || defaultValue;
    
  • Một lần nữa, ít mã hơn:

    var num = 5;
    var str = "Hello";
    input.innerHTML = input.value = num;
    for (var i=0; i < input.value; i++) { ... }
    

    Ngay cả Java cũng phải đi một phần, với lời gọi ngầm .toString()khi kết hợp các đối tượng với a String; nếu không thì các lập trình viên Java sẽ chửi rủa nó suốt cả ngày (các câu lệnh log sẽ vượt khỏi tầm kiểm soát).


Cả hai định nghĩa đều từ http://en.wikipedia.org/wiki/Type_system . Nó nói nó tốt hơn tôi có thể.


1
Gõ động cũng có lợi khi cần tạo nhiều mã bằng ngôn ngữ gõ tĩnh. So sánh số lượng tạo mã cần thiết cho, ví dụ, Entity Framework trong thư viện C # với ORM bằng các ngôn ngữ được nhập động (PHP, Python, v.v.). Mặc dù một số người có thể lập luận rằng những lợi ích về IDE IntelliSense vượt xa chi phí của tất cả việc tạo mã đó ...
Dean Harding

3
Nhận xét của bạn "// no i = ((Array) data) .length hoặc Array myArr = (Array) data;" thực sự không có gì để làm với kiểu gõ động, bởi vì tính chất của dữ liệu có thể chứng minh được ở thời gian biên dịch. Một ngôn ngữ gõ tĩnh có thể truyền bá kiến ​​thức thu được từ instanceof.
Peter Taylor

@Peter Taylor, tôi cho rằng điều đó đúng trong những trường hợp đơn giản, bạn có biết điều gì làm như vậy không? Nó không liên quan đến việc gõ động ở chỗ cho dù một ifkhối được sử dụng hay một số logic phức tạp khác (thậm chí thời gian chạy hoặc động), dòng tiếp theo sẽ hợp pháp và an toàn không có lỗi.
Nicole

@Renesis, tôi không, không. Nhưng họ ngôn ngữ ML được gõ tĩnh và sử dụng suy luận kiểu nên bạn hiếm khi phải nói rõ loại biến.
Peter Taylor

1
@Peter Taylor đã đúng. Nhiều lợi ích của việc gõ động có sẵn trong các ngôn ngữ có hệ thống gõ tĩnh tốt hơn, như Haskell, Scala hoặc thậm chí C # trong một số trường hợp. Tôi muốn nói rằng ưu điểm chính của việc gõ động là xử lý những thứ vốn không có chữ, như HTML DOM. Tại sao lại viết nút ["attr"] thay vì node.attr? Chúng luôn luôn được giải quyết trong thời gian chạy.
Matt Olenik

7

Đối số chính cho gõ yếu là một trong hiệu suất. (điều này là để trả lời câu hỏi OP như đã nêu). Có rất nhiều cuộc thảo luận tốt về động so với tĩnh, ẩn so với rõ ràng. v.v.

C là ngôn ngữ gõ yếu nổi tiếng nhất và nó không thực hiện bất kỳ kiểm tra thời gian chạy hoặc biên dịch kiểm tra thời gian của loại biến. Về bản chất, bạn có thể char *chuyển sang một int *và ngôn ngữ sẽ không quan tâm. Vậy tại sao bạn lại làm điều này?

Lập trình C khá gần với cách bạn sẽ làm mọi thứ với lắp ráp, vì vậy có những lúc bạn chỉ quan tâm đến một địa chỉ. Không có gì lạ khi bỏ hoặc chuyển một void *tài liệu tham khảo cho chính lý do đó. Nếu bạn biết cách tổ chức bộ nhớ (lại là mối quan tâm của C và lắp ráp), bạn có thể thực hiện một số tính toán khá thú vị dựa trên địa chỉ void *để lấy thông tin bạn cần. Điều này có thể cho phép bạn làm ngắn mạch quá trình bạn sẽ phải trải qua trong Java chẳng hạn.

Mặc dù kiểm tra loại thời gian chạy không có một chút chi phí bất thường, nhưng có những lúc nó chỉ đủ để khiến một phần quan trọng trở nên quá chậm. Tôi đang suy nghĩ chủ yếu về lập trình nhúng và hệ thống thời gian thực trong trường hợp này.

Điều đó nói rằng, trong hầu hết các trường hợp có một hệ thống loại mạnh là kiểm tra thời gian biên dịch hoặc kiểm tra thời gian chạy sẽ giúp thường xuyên hơn nó gây tổn thương.


2
Tôi không thấy lý do tại sao một ngôn ngữ được gõ mạnh không thể biên dịch hiệu quả như C. Nhưng trình biên dịch sẽ phức tạp hơn nhiều.
9000

2
C ++ là một ví dụ về một ngôn ngữ như vậy. Trong C ++, tất cả các loại kiểm tra được thực hiện tại thời gian biên dịch và không có gì được thực hiện trong thời gian chạy ... KHÔNG GIỚI HẠN bạn đã kích hoạt RTTI.
Berin Loritsch

2
Không chắc chắn tôi đồng ý với đối số hiệu suất này, nhưng đó một quan điểm thú vị.
Martin Ba

2

Việc gõ yếu thường dễ dàng hơn cho người mới nắm bắt, ví dụ như trong những thứ như excel, javascript và vbscript. Bạn cũng đánh đổi một số tốc độ phát triển cho các lỗi tiềm ẩn.

Bài viết hay về chủ đề: Đánh máy mạnh vs Thử nghiệm mạnh


1
Tôi không nghĩ có sự tương ứng mạnh mẽ giữa các ngôn ngữ được đánh máy yếu và các ngôn ngữ thân thiện với người mới. Ruby và python được đánh máy mạnh mẽ và thường được coi là thân thiện với người mới. C được đánh máy yếu và thường được coi là kẻ thù mới.
sepp2k

Không, không phải ngôn ngữ nói chung, tôi chỉ nói về việc đánh máy
Homde

2
Năng động và đánh máy mạnh mẽ là sự kết hợp thân thiện với người mới. Mặc dù tôi đã thấy rằng khi mọi người chuyển từ ngôn ngữ gõ tĩnh sang ngôn ngữ được gõ động, họ cũng thực sự bối rối. Tôi chưa bao giờ thấy ai đó bắt đầu bằng cách gõ động mặc dù các trường cuối cùng đã dạy C hoặc Java hầu hết thời gian.
jsternberg

3
@Mchl: điều đó không liên quan gì đến việc gõ tĩnh / động hay gõ mạnh / yếu. Phải khai báo các kiểu là về gõ rõ ràng / ẩn.
Jörg W Mittag

1
Cũng có thể như vậy;) Vì vậy, tôi cũng chuyển từ ngôn ngữ được gõ một cách rõ ràng. Sửa lỗi cho tôi nếu tôi sai Pascal được gõ một cách tĩnh, mạnh mẽ và rõ ràng, trong khi PHP là động, gõ yếu và ngầm, phải không?
Mchl
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.