Tôi đã luôn xem nó như một vấn đề thuận tiện, hơn là về việc một thuật toán có thể hoặc không thể được thể hiện ở tất cả. Nếu tôi thực sự muốn chạy các chương trình như chương trình của Mitchell, tôi chỉ cần viết trình giả lập Turing Machine phù hợp bằng ngôn ngữ gõ tĩnh của mình.
Thủ thuật với một hệ thống kiểu tĩnh là cung cấp các loại linh hoạt phù hợp chỉ trong trường hợp tính linh hoạt cho phép bạn viết mã dễ bảo trì hơn.
Dưới đây là một số ví dụ về các kỹ thuật cấu trúc chương trình đôi khi được cho là dễ quản lý theo cách linh hoạt hơn so với các ngôn ngữ được nhập tĩnh.
Generics và Container
Trong các ngôn ngữ được nhập tĩnh trước ML (c. 1973) và CLU (c. 1974), không khó để tạo ra một chuỗi các chuỗi màu đỏ đen, một cây số nguyên màu đỏ đen, một cây phao màu đỏ đen hoặc một cây đỏ-đen của các yếu tố của loại cụ thể Foo
. Tuy nhiên, rất khó (có thể là không thể) để tạo ra một triển khai duy nhất của một cây đen đỏ vừa được kiểm tra tĩnh và có thể xử lý bất kỳ một trong các loại dữ liệu này. Các cách giải quyết vấn đề là (1) thoát ra khỏi hệ thống loại hoàn toàn (ví dụ: bằng cách sử dụngvoid *
trong C), (2) để tự viết một số loại tiền xử lý macro và sau đó viết các macro tạo mã cho từng loại cụ thể mà bạn muốn hoặc (3) sử dụng phương pháp Lisp / Smalltalk (và Java) để kiểm tra loại trích xuất đối tượng động.
ML và CLU đã đưa ra khái niệm về các loại tham số hóa được suy ra và khai báo rõ ràng (tĩnh), cho phép bạn viết các loại container chung, gõ tĩnh.
Đa hình phụ
Trong các ngôn ngữ được nhập tĩnh trước Simula67 (c. 1967) và Hope (c. 1977), không thể thực hiện cả công văn động và kiểm tra tĩnh xem bạn đã bao quát trường hợp cho mọi kiểu con. Nhiều ngôn ngữ có một số hình thức hợp nhất được gắn thẻ , nhưng trách nhiệm của người lập trình là đảm bảo rằng các câu lệnh case
hoặc switch
câu lệnh của họ, bao gồm mọi thẻ có thể.
Các ngôn ngữ theo mô hình Simula (C ++, Java, C #, Eiffel) cung cấp các lớp trừu tượng với lớp con trong đó trình biên dịch có thể kiểm tra xem mỗi lớp con đã thực hiện tất cả các phương thức được khai báo bởi lớp cha. Các ngôn ngữ theo mô hình Hope (tất cả các biến thể ML, từ SML / NJ đến Haskell) đều có các kiểu con đại số trong đó trình biên dịch có thể kiểm tra xem mọi typecase
câu lệnh có bao gồm tất cả các kiểu con không.
Khỉ vá và lập trình hướng theo khía cạnh
Các hệ thống kiểu động làm cho một loạt các kỹ thuật tạo mẫu dễ dàng hơn nhiều. Trong các ngôn ngữ mà các loại được biểu thị bằng ánh xạ băm từ chuỗi đến hàm (ví dụ: Python, Javascript, Ruby), việc thay đổi toàn cầu hành vi của mỗi mô-đun dựa trên một loại cụ thể là khá dễ dàng kiểu.
Mặc dù có những cách rõ ràng trong đó việc vá khỉ có thể được sử dụng để làm cho các chương trình khó bảo trì hơn, nhưng cũng có những cách mà nó thực sự có thể được sử dụng cho "tốt" thay vì "xấu". Đặc biệt với lập trình hướng theo khía cạnh, người ta có thể sử dụng các kỹ thuật vá khỉ để thực hiện những việc như sửa đổi loại tệp để trỏ đến hệ thống tệp ảo hóa, cho phép xây dựng cơ sở hạ tầng kiểm tra đơn vị cho "miễn phí" hoặc sửa đổi các loại ngoại lệ đơn giản để chúng in thông điệp tường trình mỗi khi chúng bị bắt để có khả năng sửa lỗi tốt hơn.
Không giống như đa hình Generics và Subtype trong đó các ý tưởng kiểm tra tĩnh chính có sẵn trong những năm 1970, kiểm tra tĩnh cho lập trình hướng theo khía cạnh là (tôi nghĩ) là một lĩnh vực nghiên cứu tích cực. Tôi không biết nhiều về nó ngoại trừ việc có một ngôn ngữ gọi là AspectJ kể từ khoảng năm 2001.