Tăng năng suất được cho là của gõ động là gì? [đóng cửa]


82

Tôi thường nghe tuyên bố rằng các ngôn ngữ gõ động có năng suất cao hơn các ngôn ngữ gõ tĩnh. Những lý do cho tuyên bố này là gì? Không phải nó chỉ là công cụ với các khái niệm hiện đại như quy ước về cấu hình, sử dụng lập trình chức năng, mô hình lập trình tiên tiến và sử dụng trừu tượng nhất quán sao? Phải thừa nhận rằng có ít sự lộn xộn hơn vì (ví dụ trong Java) thường không cần khai báo kiểu dự phòng, nhưng bạn cũng có thể bỏ qua hầu hết các khai báo kiểu trong các ngôn ngữ gõ tĩnh sử dụng suy luận kiểu, mà không làm mất đi các lợi thế khác của gõ tĩnh. Và tất cả những thứ này đều có sẵn cho các ngôn ngữ gõ tĩnh hiện đại như Scala.

Vậy: có gì để nói về năng suất với kiểu gõ động thực sự là một lợi thế của chính kiểu máy?

Làm rõ: Tôi quan tâm đến các dự án lớn / vừa hơn là hack nhanh. :-)


10
Bạn có mong đợi "bộ đôi tĩnh" sẽ nhanh hơn hoặc năng suất hơn so với "bộ đôi năng động" không?
Steve314

Bạn có ý nghĩa gì với bộ đôi này? Dù sao: Tôi có thể nghĩ ra một vài lý do khiến việc gõ tĩnh hiệu quả hơn so với gõ động: nhiều trình biên dịch kiểm tra lỗi, hoàn thành mã, nhiều thông tin hơn về ý định của lập trình viên trong mã. Đó là lý do tại sao tôi hỏi về chuyện ngược lại.
Hans-Peter Störr

11
Đó là một trò đùa với một điểm. "Bộ đôi năng động" là Batman và Robin. Họ sẽ không tấn công gần như nỗi sợ hãi vào thế giới ngầm tội phạm của Thành phố Gotham nếu họ được gọi là "bộ đôi tĩnh". Vì các nhà phát triển là con người, những thứ hời hợt có thể tạo ra sự khác biệt bất kể ý nghĩa của các điều khoản.
Steve314

Câu hỏi đầu tiên của tôi là liệu tôi có biết tôi đang làm gì hay không. Nếu tôi làm, sau đó tôi có thể thiết kế mọi thứ trước thời hạn và gõ tĩnh có ý nghĩa. Nếu tôi không, thì tôi sẽ phải thay đổi rất nhiều thứ một cách nhanh chóng và việc gõ động sẽ dễ dàng hơn. Lisp thông dụng là ngôn ngữ tốt nhất tôi tìm thấy khi tôi không biết mình đang làm gì. (Hãy cẩn thận: Tôi chỉ bị trầy xước Haskell, và do đó không có cảm giác tốt cho việc gõ tĩnh được suy luận.)
David Thornley

2
Tôi hoàn toàn đồng ý với John Skeet msmvps.com/bloss/jon_skeet/archive/2009/11/17/ mẹo
người dùng

Câu trả lời:


99

Tôi thực sự nghĩ rằng đó là một cuộc gọi khá gần. Cả gõ động và gõ tĩnh đều có ưu điểm của chúng.

Lý do để gõ động năng suất hơn:

  • Nó ngắn gọn hơn - Rất nhiều mã soạn sẵn không liên quan có thể được loại bỏ nếu mọi thứ được gõ động - khai báo kiểu, logic đánh máy, v.v. Tất cả những thứ khác đều bằng nhau, mã ngắn hơn được viết nhanh hơn một chút duy trì (vì bạn không cần phải lội qua nhiều trang mã để nắm bắt những gì đang xảy ra)
  • Các kỹ thuật "hack" dễ dàng hơn như gõ vịt và vá khỉ có thể giúp bạn có kết quả rất nhanh (mặc dù có thể khiến bạn nhầm lẫn sau này ...)
  • Tương tác nhiều hơn - gõ động được cho là phù hợp hơn cho lập trình tương tác, giống như REPL để tạo mẫu nhanh, gỡ lỗi thời gian thực của các phiên bản chương trình đang chạy hoặc thậm chí mã hóa trực tiếp.
  • Các trường hợp kiểm thử có thể bắt lỗi thời gian chạy - giả sử bạn đang sử dụng TDD hoặc ít nhất có một bộ kiểm tra tốt, điều này sẽ nhận bất kỳ vấn đề gõ nào trong mã của bạn.
  • Tính đa hình tốt hơn - các ngôn ngữ động có khả năng khuyến khích việc tạo ra các hàm đa hình và trừu tượng, có thể tăng năng suất và tái sử dụng mã. Clojure chẳng hạn sử dụng đa hình động trong nhiều khái niệm trừu tượng của nó .
  • Nguyên mẫu - mô hình dữ liệu / đối tượng dựa trên nguyên mẫu theo quan điểm của tôi mạnh mẽ và linh hoạt hơn so với các chế độ thừa kế được nhập tĩnh. Các ngôn ngữ động có nhiều khả năng cho phép hoặc khuyến khích cách tiếp cận dựa trên nguyên mẫu, Javascript là một ví dụ tuyệt vời.

Lý do để gõ tĩnh có năng suất cao hơn:

  • Thiết kế tốt hơn - bị buộc phải suy nghĩ về các loại giá trị trong phần mềm của bạn lên phía trước có thể đẩy bạn tới các giải pháp hợp lý hơn, sạch hơn. (Tôi nói có thể - vẫn có thể thiết kế mã thực sự xấu ...)
  • Kiểm tra thời gian biên dịch tốt hơn - gõ tĩnh có thể cho phép bắt được nhiều lỗi hơn tại thời gian biên dịch. Đây là một lợi thế rất lớn và được cho là điều tốt nhất về ngôn ngữ gõ tĩnh nói chung.
  • Tự động hoàn thành - gõ tĩnh cũng có thể cung cấp thêm thông tin cho IDE để tự động hoàn tất mã hoặc tra cứu tài liệu hiệu quả hơn.
  • Không khuyến khích hack - bạn phải giữ kỷ luật loại trong mã của mình, đây có thể là một lợi thế cho khả năng duy trì lâu dài.
  • Kiểu suy luận - trong một số ngôn ngữ (ví dụ Scala), điều này có thể mang lại cho bạn nhiều lợi ích về tính đồng nhất của các ngôn ngữ động sẽ vẫn duy trì kỷ luật loại.

Trung bình, kết luận của tôi (sau nhiều năm kinh nghiệm ở cả hai phía của hàng rào) là việc gõ động có thể hiệu quả hơn trong thời gian ngắn, nhưng cuối cùng nó trở nên khó duy trì trừ khi bạn có bộ kiểm tra và kỷ luật kiểm tra rất tốt.

Mặt khác, tôi thực sự thích cách tiếp cận gõ tĩnh nói chung, bởi vì tôi nghĩ rằng lợi ích chính xác và hỗ trợ công cụ mang lại cho bạn năng suất tốt hơn trong dài hạn.


14
+1, câu trả lời rất chi tiết. Giá trị của điểm "Kiểm tra thời gian biên dịch tốt hơn" không thể được nhấn mạnh đủ.
NoChance

8
Cùng với Kiểu suy luận, cũng có tình trạng quá tải kiểu Haskell, các mẫu C ++, khái quát và có thể một số tính năng ngôn ngữ khác cung cấp một số lợi thế của gõ vịt trong khung gõ tĩnh - miễn là đối tượng cung cấp giao diện cần thiết (nó "Quacks like a duck") bạn có thể sử dụng nó, gần như không phân biệt đối tượng đó là loại danh nghĩa. "Gần như" là bởi vì một số cách tiếp cận yêu cầu một số loại "khai báo kiểu này giống như loại vịt" có liên quan - ví dụ: khai báo "lớp" trong Haskell.
Steve314

45
Tôi phải không đồng ý mạnh mẽ với khẳng định của bạn rằng "mã ngắn hơn ... nhanh hơn để đọc và duy trì." Có một bước trung gian, hiểu mã. Tôi đã phải duy trì mã của người khác bằng cả Delphi và JavaScript và mã Delphi dễ hiểu hơn nhiều vì nó dài dòng hơn. Và đặc biệt nhất là vì mã Delphi có khai báo kiểu và JavaScript thì không. Khi xử lý bất cứ điều gì phức tạp hơn so với nguyên thủy, khai báo kiểu làm cho việc xem biến của bạn là gì và chúng có thể làm gì, đó là kiến ​​thức cần thiết cho công việc bảo trì.
Mason Wheeler

21
Tôi xin không đồng ý với hầu hết các lý do được đưa ra ở đây. Lấy Haskell, có lẽ có hệ thống loại nghiêm ngặt nhất hiện có. Nó có REPL (thực tế ít nhất là hai), nó có tính đa hình rất mạnh bằng cách thực hiện khớp mẫu trên các hàm tạo và nó ngắn gọn như người ta có thể hy vọng - nhiều hơn Javascript hoặc Python. Vì vậy, tôi đoán một số lý do bạn đề cập là tình cờ thay vì cố hữu với các ngôn ngữ được gõ lỏng lẻo.
Andrea

15
Tôi sẽ không đặt quá nhiều niềm tin vào "các trường hợp thử nghiệm". Bạn không thể so sánh chúng với một hệ thống loại tốt. Một hệ thống loại cung cấp một bằng chứng rằng chức năng của bạn sẽ được gọi với ít nhất là các tham số chính xác, trong khi các trường hợp thử nghiệm chỉ có thể cung cấp bằng chứng thực nghiệm. Tuy nhiên, ngay cả bằng chứng này được thu thập từ một thiết lập nhân tạo.
Ingo

56

Với các ngôn ngữ động, bạn có thể viết mã crappy nhanh hơn so với khi sử dụng ngôn ngữ đã nhập.

Một khi bạn đã nhanh chóng tạo ra đống công cụ năng động khổng lồ của mình, bạn có thể chuyển sang dự án khác một cách an toàn mà không cần phải quan tâm đến việc bảo trì dài hạn.

Đây là tăng năng suất :)

Tôi nói đùa, nhưng sau khi tham gia vào một dự án sử dụng 'ngôn ngữ động', tôi đã bị hoảng sợ bởi số lượng thử nghiệm, tài liệu và quy ước không cần thiết mà bạn phải giải quyết nếu bạn muốn có một sản phẩm hoạt động.
Và với niềm vui của rất nhiều lỗi thời gian chạy có thể đã bị bắt khi biên dịch.
Ồ, tôi cũng đã quên nói về tất cả những hack và voodoos mà lập trình meta cho phép bạn giới thiệu trong mã của mình!

Vì vậy, tăng năng suất có thể là một huyền thoại cho dự án trung bình / lớn trong suốt cuộc đời của nó.


11
Vâng, kinh nghiệm của tôi là như nhau. Một tập lệnh perl 100 dòng là ổn, và không có các công cụ tuyệt vời như vậy, chúng tôi đã bị mất. Nhưng một dự án perl dòng 100k rất có thể sẽ là một cơn ác mộng.
Ingo

3
... Và sau đó bạn có JavaScript (không chỉ động mà còn được gõ yếu).
Den

16

Cũng có một quan điểm lý thuyết cho vấn đề này: Một hệ thống kiểu tĩnh về cơ bản là một người cung cấp định lý chuyên ngành, chỉ chấp nhận chương trình khi nó có thể chứng minh tính đúng đắn của nó. Tất cả các hệ thống loại tĩnh từ chối một số chương trình hợp lệ vì không có hệ thống loại tĩnh có thể quyết định nào đủ mạnh để chứng minh tất cả các chương trình đúng loại có thể.

Người ta có thể lập luận rằng những chương trình mà máy đánh chữ tĩnh không thể chứng minh được là hack và / hoặc kiểu xấu, nhưng nếu bạn đã có một chương trình hợp lệ và máy đánh chữ không chấp nhận nó, thì chắc chắn nó sẽ làm giảm năng suất của bạn trong thời gian ngắn.

Một số trường hợp mà bạn có thể nhận thấy trình kiểm tra loại đang cản trở với các thùng chứa chung và đồng phạm trong các đối số và kiểu trả về.


18
Ngược lại nếu bạn nhập sai chương trình, trình biên dịch sẽ cho bạn biết ngay lập tức và đánh dấu dòng xấu. điều này cải thiện năng suất của bạn, khi so sánh với việc nhận thấy lỗi chạy thử và gỡ lỗi để tìm lỗi.
MarkJ

5
các thùng chứa chung và đồng phạm rõ ràng có nghĩa là "cản đường bạn" nếu bạn làm sai. lợi ích của việc biên dịch mã sẽ thất bại trong thời gian chạy là gì?
M.Stramm

Thông thường công việc được coi là 0% được thực hiện cho đến khi nó chạy tất cả các bài kiểm tra thành công. Chỉ sau đó tiến bộ của bạn có thể được coi là nhiều hơn không có gì. Với ý nghĩ đó, tôi không nghĩ rằng đáng để đo năng suất của bạn trên một cái gì đó chưa hoàn thành.
Pijusn

-1 Không giải quyết câu hỏi thực tế ("tăng năng suất", nhớ không?) Ngoài ra, bạn có thể thậm chí không muốn viết những "chương trình hợp lệ mà hệ thống loại bỏ". Chỉ vì bạn không thể có nghĩa là bạn nên. Và tại sao bạn thậm chí sẽ có một "chương trình hợp lệ" mà máy đánh chữ từ chối? Cái gì, bạn đang mã hóa một chương trình Javascript và đột nhiên cố gắng làm cho nó biên dịch trong Java?
Andres F.

Các chương trình hợp lệ mà hệ thống loại từ chối có thể giúp rút ngắn mã của bạn, do đó dẫn đến ít lỗi hơn mà hệ thống loại không thể tìm ra (ít mã hơn = ít lỗi hơn). Trình biên dịch / IDE làm nổi bật dòng có thể được thực hiện bằng các ngôn ngữ động với các giá trị thử nghiệm (nghĩa là phát triển theo định hướng REPL) để bạn có thể thấy các giá trị trung gian và chúng có thể nhận các lỗi mà hệ thống loại của bạn không thể cũng như lỗi loại. Bạn cũng có thể sử dụng suy luận kiểu tĩnh để đưa ra cảnh báo kiểu.
aoeu256

15

Một lợi thế tôi đã tìm thấy với hầu hết các ngôn ngữ động là chúng giúp viết mã chung chung dễ dàng hơn. Viết ở mức độ trừu tượng cao hơn nhiều khi bạn không phải chiến đấu với hệ thống loại để làm như vậy.

Bạn không cần phải suy nghĩ nhiều về nó - việc viết mã thực hiện một cái gì đó không cần thiết với bất kỳ đối tượng nào trong Java là khó khăn và có thể yêu cầu sự phản chiếu về cơ bản được gõ động; với một cái gì đó như JavaScript, viết một hàm làm điều gì đó thú vị cho tất cả các đối tượng là bản chất thứ hai. Một ví dụ hoàn hảo sẽ là một hàm mà tôi đã viết gần đây lấy một đối tượng và thay thế tất cả các phương thức của nó bằng các phương thức làm cùng một việc nhưng cũng kích hoạt một sự kiện. Tôi không biết làm thế nào để tiếp cận một cái gì đó như thế này trong Java. Tuy nhiên, tôi không chắc chắn bao nhiêu trong số này là do các hệ thống loại và bao nhiêu là do sự khác biệt ngôn ngữ khác.

Tuy nhiên, gần đây tôi đã bắt đầu sử dụng Haskell. Haskell cho phép tôi viết mã trừu tượng, chung chung dễ dàng như bất kỳ ngôn ngữ được gõ động nào tôi đã sử dụng. Ví dụ Java / JavaScript của tôi ở trên không có ý nghĩa gì trong Haskell vì nó không có các đối tượng, phương thức, sự kiện hoặc thậm chí nhiều đột biến, nhưng các loại mã chung khác thực sự dễ viết.

Trên thực tế, Haskell có thể viết một số mã chung mà các ngôn ngữ được gõ động không thể; một ví dụ hoàn hảo là readchức năng cơ bản ngược lại toString. Bạn có thể có được một Inthoặc một Doublehoặc bất kỳ loại nào bạn muốn (miễn là nó thuộc một loại loại nhất định). Bạn thậm chí có thể có đa hình hằng , vì vậy maxBoundcó thể là tối đa Int, Double, Char... vv., Tất cả tùy thuộc vào loại đó là nghĩa vụ phải được.

Lý thuyết của tôi bây giờ là tăng năng suất từ ​​việc sử dụng một ngôn ngữ động luôn luôn so với các ngôn ngữ như Java với các hệ thống loại kém khả năng hơn, dài dòng hơn và kém linh hoạt hơn.

Tuy nhiên, ngay cả hệ thống loại của Haskell cũng có một số vấn đề gây phiền nhiễu mà bạn không có trong ngôn ngữ được gõ động. Cái lớn nhất tôi từng thấy khó chịu là cách xử lý số; ví dụ, bạn phải loay hoay với hệ thống loại để sử dụng length(của một danh sách) như một đôi, một cái gì đó bạn sẽ không gặp vấn đề gì nếu không có hệ thống loại. Một điều khó chịu khác mà tôi gặp phải là làm việc với Word8(một kiểu int không dấu) và các chức năng mong đợi Int.

Vì vậy, cuối cùng, việc không có hệ thống loại giúp viết mã chung dễ dàng hơn mà không phải suy nghĩ quá nhiều và cũng tránh được những cạm bẫy khó chịu của hệ thống loại. Bạn không bao giờ phải chiến đấu với hệ thống loại bằng ngôn ngữ động, nhưng bạn cũng không thể dựa vào nó.


1
Có, vì một số lý do hệ thống số rất khó để có được đúng. Trong scala nó cũng là một mớ hỗn độn. Tôi nghĩ rằng các hệ thống kiểu động sẽ chiến thắng các hệ thống kiểu tĩnh đơn giản về mặt dễ dàng làm việc với nó, nhưng thua các hệ thống tiên tiến hơn (như Scala, Haskell, ML, v.v., tất cả đều sử dụng các biến thể của hệ thống-F ).
Edgar Klerks

3
Câu trả lời của bạn rất có ý nghĩa, nhưng có sai lầm. Đầu tiên, không đúng khi các ngôn ngữ động "không có hệ thống loại", vì vậy đó không thể là lý do chúng "làm cho việc viết mã chung dễ dàng hơn". Chúng không làm cho nó dễ dàng hơn, như mẫu của riêng bạn với các chương trình Haskell (bạn gỡ lỗi khẳng định của chính mình!). "Bạn không bao giờ phải chiến đấu với hệ thống loại" là sai: bạn chiến đấu với nó mỗi khi bạn phải sửa một lỗi gây ra bởi không đủ lỗi đánh máy tĩnh. Cuối cùng, rõ ràng ép buộc Inttrả về bởi một danh sách là tầm thường; ví dụ : 1.0 + fromIntegral (length myList), tức là chỉ sử dụng fromIntegral.
Andres F.

2
Cuối cùng, "viết mã nhanh"! = "Hiệu quả hơn". Mã của bạn phải làm việc! Nếu bạn viết phần mềm lỗi mà sau này bạn phải dành thời gian gỡ lỗi và sửa lỗi, bạn sẽ không làm việc hiệu quả.
Andres F.

"Không suy nghĩ quá nhiều" cờ đỏ cho ý nghĩa của hầu hết mọi người khi họ nói về các ngôn ngữ được gõ động là "năng suất cao hơn"
Ataraxia

Nếu hệ thống loại thực sự cải thiện năng suất, tất cả các ứng dụng hữu ích trong Haskell hoặc Idris là gì? Tôi nghĩ những thứ như dễ hiểu lỗi loại, "khả năng vá" (khả năng chỉnh sửa ứng dụng của bạn theo những cách không thể đoán trước) và kiểm tra lỗi 90% đối với tài liệu & suy luận kiểu có thể quan trọng hơn.
aoeu256

7

H: Tôi thường nghe tuyên bố rằng các ngôn ngữ được gõ động có năng suất cao hơn các ngôn ngữ được nhập tĩnh. Những lý do cho tuyên bố này là gì? "

Điều này có lý do lịch sử. Nếu bạn quay trở lại một vài thập kỷ, các ngôn ngữ động có năng suất cao hơn nhiều so với các ngôn ngữ tĩnh (trong khi cũng chậm hơn đáng kể). Perl rõ ràng có năng suất cao hơn nhiều so với C nếu bạn biết cả hai và nhiệm vụ trong tay cho phép. Nhưng theo thời gian, các ngôn ngữ đã vay mượn rất nhiều lẫn nhau và các ngôn ngữ mới hơn đang thu hẹp khoảng cách (cả về năng suất và hiệu suất).

Dưới đây là một số điểm cần xem xét:

Thu gom rác : Thu gom rác là một sự tăng năng suất rất lớn . Tôi tin rằng Java là ngôn ngữ tĩnh chính đầu tiên với GC. Trước đây, tĩnh về cơ bản có nghĩa là quản lý bộ nhớ thủ công. (Lưu ý: Ở đây và sau đây tôi chỉ xem xét các ngôn ngữ chính. Có rất nhiều ngôn ngữ thử nghiệm và ngôn ngữ thích hợp sẽ cung cấp các mẫu đối với bất kỳ điểm nào tôi thực hiện.)

An toàn bộ nhớ : Đó là một cải tiến năng suất mà bạn không phải lo lắng về việc tự bắn vào chân mình. Trước các ngôn ngữ tĩnh "được quản lý" như Java, tĩnh thường có nghĩa là truy cập bộ nhớ trực tiếp. Gỡ lỗi cũng là một phần của năng suất và truy cập bộ nhớ không an toàn có thể dẫn đến các lỗi thực sự tối nghĩa.

Hệ thống loại cồng kềnh. Trước khi giới thiệu các loại tham số hóa (như mẫu hoặc tổng quát) trong các ngôn ngữ tĩnh, các hạn chế của hệ thống loại tĩnh thường là một gánh nặng. Ví dụ, trong Java, bạn phải downcast rõ ràng mỗi khi bạn chọn một mục từ bộ sưu tập. Vì vậy, bạn có chi phí cú pháp của một diễn viên không có loại an toàn. Xem xét các bộ sưu tập phổ biến trong lập trình như thế nào, đây là một nhược điểm lớn.
Phải khai báo kiểu của mọi thứ là rất nhiều kiểu gõ thừa, nhưng với suy luận kiểu hiện đại, điều này có thể được giảm đáng kể.

Thư viện tiêu chuẩn lớn. Python nổi tiếng được quảng cáo là "bao gồm pin" vì thư viện tiêu chuẩn lớn. Điều này so với C có một thư viện tiêu chuẩn rất tối giản. Nhưng với các nền tảng như Java và .net, một thư viện tiêu chuẩn rộng lớn đang trở thành tiêu chuẩn và các ngôn ngữ mới hơn như Scala và F # đang kế thừa "miễn phí" này.

Cấu trúc dữ liệu hạng nhất. Các ngôn ngữ động như Perl và Python có các cấu trúc dữ liệu hạng nhất như danh sách và bản đồ với các phím tắt cú pháp thuận tiện cho các hoạt động chung. So với điều này, C không có bộ sưu tập dựng sẵn ngoại trừ mảng có kích thước cố định.

Các cú pháp đóng và cú pháp lambda - các ngôn ngữ động thường có từ đầu, nhưng các ngôn ngữ tĩnh đã áp dụng điều này, gần đây nhất là Java.

REPL khả năng nhanh chóng kiểm tra các đoạn mã tương tác là một lợi ích rất lớn. Nhưng mặc dù các công cụ IDE, như cửa sổ "ngay lập tức" trong Visual Studio, các ngôn ngữ tĩnh có thể mô phỏng điều này ở một mức độ nào đó.

Công cụ nâng cao - ngoài những điểm trên mà ngôn ngữ tĩnh đang tiến gần hơn đến sự tiện lợi của ngôn ngữ động, các biên tập viên hiện đại đang tận dụng phân tích tĩnh theo cách mà ngôn ngữ động có thời gian phù hợp. Ví dụ, các biên tập viên có thể cung cấp các phép tái cấu trúc tự động an toàn, một điều hoàn toàn không thể nói bằng ngôn ngữ động.

Điểm mấu chốt: Trong lịch sử là đúng, nhưng ngày nay câu trả lời ít rõ ràng hơn.


Q: Vậy: có gì để nói về năng suất với kiểu gõ động thực sự là một lợi thế của chính kiểu máy?

Thật khó để tách mô hình gõ động khỏi các ngôn ngữ động, nhưng như một ví dụ C # đã áp dụng nhiều tính năng động hơn theo thời gian, mặc dù cốt lõi của nó là ngôn ngữ tĩnh. Đây thực sự là một bằng chứng về lợi ích của mô hình kiểu động. Ví dụ:

Reflection Reflection về cơ bản là một tính năng gõ động. Bạn kiểm tra các loại đối tượng tại thời gian chạy hơn thời gian biên dịch. Khi được giới thiệu, nó đã hơi nhăn mặt, nhưng trong C #, việc sử dụng sự phản chiếu ngày càng phổ biến hơn, ví dụ, ASP.Net MVC sử dụng sự phản chiếu rất nhiều.

Các thuộc tính Các thuộc tính là một ví dụ về kiểu gõ động. Bạn có thể thêm các thuộc tính tùy ý vào một lớp tại thời gian biên dịch và sau đó bạn kiểm tra tại thời gian chạy (thông qua sự phản chiếu) và thao tác với các đối tượng dựa trên nó. Một cái gì đó giống như MEP về cơ bản là một khung mở rộng dựa trên mô hình kiểu động.

Linq sang SQL, EF mv. Các biến áp Linq khác nhau kiểm tra các truy vấn như các đối tượng thời gian chạy và tạo sql một cách nhanh chóng. Nó không có được năng động hơn kiểm tra mã trong thời gian chạy. CodeDom là mặt khác của đồng tiền, nơi mã có thể được tạo khi chạy

Roslyn Roslyn về cơ bản thực hiện eval, đã từng được coi là tính năng xác định của một ngôn ngữ thực sự năng động.

Động Các dynamickiểu là tính năng một cách rõ ràng năng động nhất trong C #, và được quảng cáo tại làm cho sự tương tác với các đối tượng bên ngoài và ngôn ngữ đơn giản và hiệu quả hơn. Nhưng nó cũng được sử dụng trong Asp.net MVC để thuận tiện.

Lợi ích của tất cả các tính năng trên cho thấy mô hình động có các lợi thế nhất định ngay cả trong một ngôn ngữ tĩnh với các kiểu tham số, kiểu cấu trúc và suy luận kiểu.


Tôi thực sự không thích câu trả lời này, vì gần như tất cả các điểm không giải quyết được câu hỏi cốt lõi, "mức tăng năng suất được cho là của động là gì?" không phải ngôn ngữ động .
mẫu

@nanny bạn có thể giải thích về sự khác biệt nhận thức của bạn giữa ngôn ngữ gõ động và ngôn ngữ động? (đó là một trong những điều mờ nhạt). Bạn có thể đưa ra một ví dụ về một ngôn ngữ gõ động không phải là ngôn ngữ động, cùng với các định nghĩa rõ ràng về từng ngôn ngữ?

@nanny: Câu hỏi thực sự hỏi về "ngôn ngữ được gõ động", không chỉ là "gõ động".
JacquesB

@MichaelT Xin lỗi tôi không rõ ràng. Gõ động là một khía cạnh của tất cả các ngôn ngữ động. Câu trả lời này đang nói về khía cạnh khác mà về mặt lịch sử, các ngôn ngữ động có xu hướng đi kèm mà không thực sự giải quyết phần gõ động.
mẫu

1
@nanny: Về cơ bản tôi đang trả lời: "Tôi thường nghe tuyên bố rằng các ngôn ngữ được gõ động có năng suất cao hơn các ngôn ngữ được nhập tĩnh. Lý do cho tuyên bố này là gì?" - Tôi tin rằng những lý do cho tuyên bố này là lịch sử và không chỉ liên quan đến việc gõ động mà còn liên quan đến các tính năng cải thiện năng suất khác của các ngôn ngữ động.
JacquesB

6

Toàn bộ tất cả các tính năng ngôn ngữ hiện đại là rất lớn, chỉ riêng việc gõ tĩnh so với động không mang nhiều trọng lượng.

Quy tắc là, tính năng ngôn ngữ của bạn càng tốt, mã của bạn càng ngắn. Điều đó khá đơn giản. Java cho thấy cách gõ tĩnh có thể sai lầm khủng khiếp, điều này mang lại cho đối thủ của nó nhiều thứ để ăn. Các tính năng ngôn ngữ được thiết kế kém thường đi kèm với chi phí và gõ tĩnh trong Java trước hết là một tính năng bắt buộc (nếu không, hầu hết mọi người thậm chí sẽ không sử dụng nó) và thứ hai được thực hiện kém.
Đây là lý do tại sao so sánh hầu hết các ngôn ngữ động đều tỏa sáng, mặc dù tôi cho rằng PHP không thực sự làm cho cuộc sống của bạn tốt hơn trong tổng số lớn (ít nhất là cho đến gần đây), vì nhiều vấn đề khác không liên quan đến các hệ thống loại.

Mặt khác, bạn có rất nhiều ngôn ngữ với các hệ thống loại biểu cảm không cản trở bạn và điều đó thậm chí không bắt buộc. Và một số trong số họ thậm chí cho phép nhúng mã chưa được mã hóa, bất cứ khi nào bạn cần thoát khỏi hệ thống loại.

Cá nhân, tôi sử dụng haXe, một ngôn ngữ có kiểu suy luận, cả phân nhóm danh nghĩa và cấu trúc, mã không được tùy chọn, các loại hàm hạng nhất, các kiểu dữ liệu đại số và các macro từ vựng khá thuần thục nhưng cực kỳ mạnh mẽ, tất cả đều tránh được cú pháp phức tạp. Sau khi sử dụng haXe khoảng 3 năm nay, tôi đã đi đến một kết luận đơn giản:

Lập trình trở nên dễ dàng hơn nhiều, khi ngôn ngữ của bạn không khóa bạn vào các lựa chọn tôn giáo về mô hình nhưng cố gắng trở thành một công cụ tốt. Có một số ngôn ngữ tĩnh và động ngôn ngữ hỗn hợp , đã thành công ở đó. Một số trong số chúng dễ học, khó thành thạo nhất.
Sức mạnh của họ đến từ cách các tính năng cá nhân của họ có thể được sáng tác để dễ dàng tạo ra các giải pháp đơn giản cho các vấn đề phức tạp. Điều này loại trừ một tính trực giao nhất định chỉ có thể đạt được thông qua một sự cân bằng tinh tế bao gồm hoặc bỏ qua tất cả các tính năng ngôn ngữ được khám phá cho đến nay. Nếu bạn đã cố gắng thêm kiểu gõ tĩnh vào Ruby, bạn sẽ làm tê liệt nó, nếu bạn cố gắng đưa nó ra khỏi Haskell, bạn sẽ nghiền nát nó. Ngược lại với điều đó: nếu bạn lấy nó ra khỏi C, mọi người sẽ khó nhận ra và nếu bạn lấy nó khỏi Java, một số người có thể cảm ơn bạn.

Từ kinh nghiệm cá nhân của tôi, tôi có thể nói với bạn điều này: Tôi thích Ruby. Nó mở rộng tầm nhìn của tôi và cách tôi thiết kế hệ thống. IMHO nó nên được sử dụng để dạy mọi người lập trình ở nơi đầu tiên. Nó là không phô trương, mạnh mẽ, súc tích, vui vẻ. Tôi hiểu tại sao ai đó đến từ một ngôn ngữ chính thống sẽ thích nó.
Tuy nhiên, về lâu dài, việc gõ tĩnh cho phép trì hoãn hoạt động đối với máy phân tích tĩnh và với suy luận kiểu này về cơ bản không mất phí. Kết quả là mã dễ bảo trì hơn và thường chạy nhanh hơn.

Nhưng một lần nữa, gõ tĩnh một mình không thể làm một điều. Đó là vấn đề kết hợp. Tôi nghĩ ở đâu đó giữa F #, Scala, Nemerle, OCaml hoặc haXe bạn có thể tìm thấy sự tối ưu của chính mình. Nhưng điều đó cuối cùng phụ thuộc vào bạn, bởi vì ngôn ngữ sẽ cho phép bạn nhúng suy nghĩ của mình mà không cần nỗ lực, thay vì buộc bạn phải uốn cong chúng xung quanh nó. Và sau tất cả, không có gì mang lại năng suất cao hơn, nếu lập trình là niềm vui.


"Quy tắc là, tính năng ngôn ngữ của bạn càng tốt, mã của bạn càng ngắn." Điều này có thể xuống theo ý kiến ​​ở một mức độ nào đó, nhưng tôi không nghĩ tuyên bố này là chính xác. Mã ngắn hơn không tự cung cấp quá nhiều lợi thế, ngoài việc liên quan đến việc gõ ít hơn tại thời điểm ghi và có thể chiếm ít dung lượng đĩa hơn (dù sao cũng không phải là yếu tố trong ngôn ngữ được biên dịch). Tôi nghĩ rằng dấu ấn của một ngôn ngữ tốt đang truyền tải càng nhiều thông tin về những gì nó đang làm theo cách ngắn gọn nhất có thể. Gõ động không phải là tự viết tài liệu và mất khả năng bảo trì do kết quả là imo
Ataraxia

Bạn có thể bổ sung mã gõ động bằng thông tin như giá trị mặc định / đối số từ khóa, loại nhận được từ suy luận kiểu, suy luận kiểu động từ trình biên dịch JIT hoặc chỉ ghi nhật ký tất cả các hàm [đi qua mọi hàm hoặc lớp trong chương trình đang chạy và thay thế chúng bằng phiên bản của hàm ghi lại các đối số / kết quả của nó). Sau đó, bạn có thể thấy nhật ký của các lần chạy trước của một chức năng. Một ý tưởng khác là từ chối mã không có chú thích loại, hợp đồng thời gian chạy hoặc kiểm tra phiên REPL mẫu nhưng cung cấp cho nhà phát triển tùy chọn chọn bất kỳ trong số ba.
aoeu256

3

Cá nhân, lý do duy nhất để gõ động sẽ giúp ích nếu bạn là một người đánh máy thực sự chậm hoặc bạn xây dựng các hàm / phương thức / trình duyệt khổng lồ khó điều hướng. Bạn cũng phải đi vào vấn đề kiểm tra toàn bộ đơn vị. Các loại động yêu cầu (trừ khi bạn thích viết mã bị hỏng) kiểm tra đơn vị mạnh mẽ (Để đảm bảo rằng các loại động của bạn không bị nổ bất ngờ (ví dụ: biến chủ yếu là vịt, nhưng đôi khi vô tình dcuk)). Statics sẽ cố gắng hơn nhiều để ngăn chặn điều này (Và vâng, bạn có thể đưa ra lập luận cho các bài kiểm tra đơn vị mạnh mẽ)


0

Tôi nghĩ trước hết bạn cần xác định "năng suất". "Năng suất" có nghĩa là gì và bao gồm những gì?

Nếu "hiệu quả hơn", bạn có nghĩa là viết ít dòng mã hơn để thực hiện tính năng tương tự, thì đúng, ngôn ngữ lập trình gõ động sẽ "hiệu quả" hơn so với ngôn ngữ gõ tĩnh.

Tuy nhiên, nếu bạn cũng xem xét thời gian dành cho gỡ lỗi và sửa lỗi, thì các ngôn ngữ gõ động có thể không hiệu quả, vì các ngôn ngữ gõ động có xu hướng đẩy việc kiểm tra lỗi sang thời gian chạy, ngược lại, các ngôn ngữ gõ tĩnh có thể thực hiện một số kiểm tra lỗi trong thời gian biên dịch. Vì người ta thường chấp nhận rằng, thông thường, lỗi phát hiện càng muộn thì càng tốn kém để sửa lỗi đó. Do đó, mã gõ động có thể dẫn đến kết quả chung bằng hoặc thậm chí thấp hơn năng suất so với mã gõ tĩnh.


Nói chung, không đúng khi bạn có thể viết một tính năng trong ít dòng hơn bằng ngôn ngữ động. Những ngôn ngữ bạn đang so sánh, dù sao?
Andres F.

@AresresF. Ồ, tôi chủ yếu sử dụng Python và C ++.
yaobin

1
Ok, nhưng bạn không thể khái quát hóa động và tĩnh khi bạn thực sự so sánh Python và C ++. C ++ không phải là một ví dụ đại diện đặc biệt của ngôn ngữ với kiểu gõ tĩnh. Có những ngôn ngữ gõ tĩnh cực kỳ súc tích, ít nhiều cho phép bạn viết chương trình ngắn gọn như với Python. Vì vậy, nói chung, khẳng định của bạn là sai.
Andres F.

Vâng, nhưng nếu bạn chỉnh sửa chương trình của bạn trong khi nó vẫn đang chạy thì sao? Bất kỳ vấn đề thời gian chạy sẽ chỉ xảy ra và bạn có thể khắc phục chúng ngay tại đó. Trong Lisp, bất cứ khi nào bạn gặp lỗi, bạn chỉ có thể sửa chương trình của mình và sau đó tiếp tục chạy nó ... Vâng đối với các chú thích loại đường dẫn phức tạp hơn sẽ tốt [có thể bạn có thể sử dụng cách gõ dần dần như mypy & lisp], nhưng những đường dẫn phức tạp hơn đó cũng có khả năng xảy ra lỗi không phải loại nên việc tránh các đường dẫn phức tạp trong bất kỳ ngôn ngữ nào có thể là một ý tưởng hay.
aoeu256

-1

Ưu điểm lớn của gõ động là năng suất.

Python, Ruby, v.v. có rất nhiều tên lửa đẩy năng suất khác bên cạnh việc gõ động (tham số mặc định, từ điển như được xây dựng trong các loại, v.v.), hiệu ứng tích lũy đối với năng suất của lập trình viên rất ấn tượng.

Các hình phạt về tốc độ (hoặc thiếu!) Và tiêu thụ tài nguyên không tệ như bạn mong đợi và trong hầu hết các trường hợp được bù đắp nhiều hơn bởi tốc độ phát triển và tính linh hoạt.

Có một (rất cũ!) Giấy về đề tài này ở đây. Đây là một trong số ít các nghiên cứu được thực hiện đúng về năng suất lập trình viên và nhiều kết luận vẫn còn hiệu lực.

Điều mà (có lẽ) sẽ khác là nghiên cứu được thực hiện ngày hôm nay: -

  1. Các JVM Java đã được cải thiện ngoài sự công nhận.
  2. Các IDE hiện đại sẽ cải thiện năng suất của các lập trình viên C ++ và Java, nhưng, tạo ra rất ít sự khác biệt đối với các ngôn ngữ kịch bản lệnh.
  3. C # sẽ được bao gồm và có thể ở trong cùng một công viên bóng với Java nhưng tốt hơn một chút.

Vì vậy, thông điệp là trừ khi hiệu suất là một vấn đề thực sự nghiêm trọng, ngôn ngữ động sẽ tăng năng suất của bạn.


2
Sự không rõ ràng của tôi là chính xác những gì mà gõ động làm để tăng năng suất của bạn. Bài viết này rất thú vị, tuy nhiên đó là về một chương trình rất nhỏ và tôi không chắc cách thức này mang đến hàng ngàn dòng mã trong hầu hết các chương trình.
Hans-Peter Störr

5
Nghiên cứu đó chỉ sử dụng C, C ++ và Java làm ví dụ về ngôn ngữ tĩnh và sau đó cố gắng áp dụng các kết luận được tìm thấy cho các ngôn ngữ lập trình truyền thống nói chung. Tất cả ba ngôn ngữ đều có chung một cú pháp cơ bản, với cùng một lỗ hổng vốn có, giảm dần, làm cho sự so sánh không hợp lệ. Không phải ngôn ngữ tĩnh là không hiệu quả, mà là họ C không sinh sản. Nếu họ bao gồm một phương ngữ Pascal trong các thử nghiệm của họ, rất có thể họ đã đạt được một số kết luận khác nhau.
Mason Wheeler

@mason - Có rất ít nghiên cứu khách quan thực tế trong lĩnh vực này. Đây là một trong số ít các nghiên cứu thực tế với con số thực tế, vv Chương trình "mẫu" không tầm thường! Nó kết hợp các yếu tố xử lý từ điển, thuật toán phức tạp và khối lượng dữ liệu lớn. Tỷ lệ cao của các nỗ lực thất bại và sụp đổ xác nhận tính chất không tầm thường của nhiệm vụ.
James Anderson

2
-1 Bạn không nói nhiều về những gì làm cho ngôn ngữ gõ động hiệu quả hơn. Các tham số và từ điển mặc định có thể được tìm thấy trong các ngôn ngữ gõ tĩnh như Scala.
Jonas

1
@JamesAnderson Thậm chí tệ hơn, bài báo bạn liên kết đến thậm chí không hỗ trợ quan điểm của bạn. Nó so sánh "ngôn ngữ kịch bản" (thường là động) với " ngôn ngữ thông thường " (thường là tĩnh). Bây giờ, cho tôi biết, những gì chính xác ngôn ngữ "truyền thống"? Bạn có nghĩ rằng nó giống như tập hợp các ngôn ngữ với kiểu gõ tĩnh không? Thậm chí tệ hơn, giấy không phải cũ. Vào năm 2000, rất nhiều ngôn ngữ tuyệt vời với kiểu gõ tĩnh có năng suất cao hơn nhiều so với các ngôn ngữ động đã tồn tại.
Andres F.
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.