19

Tôi nghĩ Coffeescript là một ngôn ngữ tuyệt vời! Tôi đang tìm kiếm một số dự án/vấn đề/tính năng thêm Phân tích tĩnh vào Coffeescript. Tuy nhiên sau khi tìm kiếm một số tôi thấy rằng Coffeescript faqthis page cho thấy rằng phân tích tĩnh có thể không khả thi. Tôi đã tự hỏi rằng nếu có một vấn đề cơ bản trong việc thực hiện phân tích tĩnh/kiểm tra kiểu tĩnh trong Coffeescript, bởi vì cái gì của loại này không tồn tại trong trình biên dịch thì sao?Coffeescript Static Analysis/Static Typechecking - Roadblock

Ngoài ra, có điều gì đó không thể thực hiện cho các kiểm tra không tầm thường nhưng có thể chỉ hoạt động để phân tích đơn giản không? Khi tôi nói đơn giản, tôi có nghĩa là kiểm tra những thứ tầm thường như, cho dù người dùng đã định nghĩa một hàm hai lần cùng tên (trong một lớp) hay ở cấp cao nhất (hoặc có thể ở cấp cao nhất trong tập hợp các tệp .coffee có liên quan) .

Tôi sẽ đánh giá cao nếu có ai có thể vui lòng chỉ ra một số ví dụ cho thấy lý do tại sao triển khai phân tích tĩnh/kiểm tra loại không đơn giản/có thể/đáng để dành thời gian?

Cảm ơn bạn rất nhiều!

+0

Làm cách nào để chạy jshint trên các tệp JS được tạo? Cà phê biên dịch JS và JS công cụ mà làm những gì bạn đang tìm kiếm là không chính xác không phổ biến. –

Trả lời

13

Câu trả lời này là một chút của một bãi chứa não kể từ khi tôi quan tâm đến điều này cũng. Hy vọng nó giúp.

Tôi sử dụng Trình biên dịch đóng cửa của Google để phân tích tĩnh mã mà CoffeeScript tạo. Nó có một máy phân tích tĩnh thực sự tốt, và tôi không chắc chắn nếu có một lý do tốt để phát minh lại bánh xe ở đây. Cách đơn giản là chỉ cần viết các chú thích bằng tay:

###* 
    * @param {number} x 
    * @param {number} y 
    * @return {number} 
### 
adder = (x, y) -> x + y 

Đó là một chút dài dòng, nhưng mặt khác bạn đang mượn khả năng phân tích tĩnh của trình biên dịch đóng cửa mà là thực sự mạnh mẽ và có khả năng kiểm tra rất nhiều. Tôi thực sự viết chú thích kiểu một cách ngắn gọn hơn một chút, sau đó có một kịch bản để viết lại tệp cà phê. Mã của tôi kết thúc như sau:

#! {number} x {number} y @return {number} 
adder = (x, y) -> x + y 

Tôi chắc chắn bạn có thể thấy rằng trình viết lại khá đơn giản.

Lưu ý nhanh trước khi tôi tiếp tục. Đảm bảo biên dịch mã của bạn bằng -b (trần) nếu bạn đang chạy nó thông qua trình biên dịch đóng. Trình biên dịch đóng là khá tốt, nhưng nó không đủ thông minh để phân tích lưu lượng dữ liệu. CoffeeScript kết thúc tốt đẹp mã của bạn trong một hàm ẩn danh theo mặc định, nó sẽ làm tăng trình biên dịch.

Một tùy chọn khác dọc theo con đường tương tự (điều này sẽ phá vỡ tính tương thích với CoffeeScript, nhưng sẽ là một mát rất nhiều) sẽ có trình biên dịch cà phê biên dịch một cái gì đó như thế này:

adder = (number x, number y): number -> x + y 

vào JS như thế này:

/*** 
    * @param {number} x 
    * @param {number} y 
    * @return {number 
    */ 
var adder = function(x, y) { 
    return x + y; 
}; 

sau đó có thể được đưa vào trình biên dịch đóng trên biên dịch - nếu không có lỗi thì trình biên dịch có thể xóa tất cả nhận xét ra.

Thật vậy, this guy dường như đang thực hiện chính xác việc này. Đáng buồn thay, công việc của anh ta dường như đang ở trạng thái không đầy đủ.

Trong tất cả các trường hợp này, chúng tôi trì hoãn công việc khó khăn - kiểm tra lỗi tĩnh - đến trình biên dịch đóng. Nếu bạn không muốn làm điều này, tôi sẽ hiểu, nhưng thật khó để thuyết phục tôi rằng thật đáng giá để xây dựng một công cụ phân tích tĩnh hoàn toàn mới từ đầu. :)

CHỈNH SỬA một năm sau: Tôi chỉ sử dụng kiểu chữ những ngày này. :)

+4

Đường cú pháp để đánh dấu stativ tùy chọn sẽ là kẻ giết người :) –

+0

@MikkoOhtamaa: Tôi đồng ý. Jashkenas đáng buồn, người tạo ra CoffeeScript, khá mãnh liệt trong việc giữ CoffeeScript rất gần với JavaScript và các nhánh của ngôn ngữ có xu hướng yếu đi trong sự tối tăm. Tôi ước có một số cách để có được những điều tốt nhất của cả hai thế giới. – thedayturns

8

Tôi không phải là chuyên gia về CoffeeScript, vì vậy đây có thể là câu trả lời hoàn toàn sai, nhưng về cơ bản nó là một ngôn ngữ rất rõ ràng, với hầu hết các ngữ nghĩa được xác định động). Điều này là trái ngược với các ngôn ngữ như Standard ML, trong đó có một ngữ nghĩa được xác định chặt chẽ hơn nhiều. Nói chung, phân tích tĩnh trên các ngôn ngữ đặt hàng cao hơn được coi là rất khó. Tức là, phân tích tĩnh về các chương trình bậc cao thực (Haskell, ML, đặc biệt là javascript vì những thứ như eval) chỉ là khó vì luồng điều khiển linh hoạt hơn nhiều. Trên thực tế, các giải pháp phân tích tĩnh cho các ngôn ngữ bậc cao hơn chỉ thực sự được khám phá trong vòng 20 năm qua. (Đáng chú ý, xem bài viết Matt Might về a tutorial style description of CFA.)

Về cơ bản, lý do là đây:

  • Để làm phân tích, bạn phải đối phó với các vấn đề của ngữ nghĩa biểu cảm hình thức đến sự kiểm soát dòng chảy bạn nhận được bằng cách đập xung quanh các chức năng bậc cao hơn.
  • Để làm nhập, thường những ngôn ngữ này có nhiều loại tập hợp phong phú hơn có sẵn. Ví dụ, có những trường hợp rất thường xảy ra nếu bạn cố gắng gán một kiểu tĩnh cho một biến trong Ruby (như trong C, Java, ML, v.v ...), bạn sẽ gặp lỗi, nhưng vì một số đường dẫn chương trình của bạn không bao giờ thực hiện, tất cả đều ổn. Cùng với đó, các ngôn ngữ như những người khác của Ruby thêm một loạt các chuyển đổi loại tiềm ẩn là thực sự đã sử dụng để lập trình làm mát. Các công việc đáng chú ý trong lĩnh vực này mà tôi familar (dynamic analysis of static types for Ruby) đến từ một số người tôi làm việc với, nhưng chắc chắn có những ví dụ khác.
  • Về cơ bản, ngôn ngữ được sử dụng theo cách động hơn, với nhiều ngữ nghĩa hơn biểu cảm và lý do về tính chất này khó hơn nhiều và dễ bị không chính xác. Mặt trước cơ bản của việc tiếp cận này (những ngày này) đang bắt đầu nhìn lai: bạn có thể phân tích tĩnh một phần của một chương trình, và hơn cũng yêu cầu lập trình viên đưa ra một số trường hợp thử nghiệm để thực hiện một số loại phân tích tinh vi.

Tôi hy vọng điều này phần nào giải đáp thắc mắc của bạn, một lần nữa, xin lỗi tôi không thể giải quyết trực tiếp những mối quan tâm trực tiếp của câu hỏi của bạn vì nó áp dụng cho CoffeeScript, nhưng có một nhiều công việc đang diễn ra trong việc phân tích những thứ như JavaScript ngay bây giờ. Tôi sẽ lưu ý rằng một số vấn đề thực sự với Javascript đến từ ngữ nghĩa kỳ lạ của nó, sự thừa kế nguyên mẫu khó có thể giải thích được, và đặc biệt làeval()! Thông thường phân tích chương trình cho các ngôn ngữ này áp đặt các hạn chế nhất định (ví dụ, ném ra đánh giá hoàn toàn!) Để làm cho việc phân tích khả thi hơn!

+0

Chỉ cần cập nhật trong lĩnh vực ngôn ngữ động "đánh máy": Tôi đoán bạn đã biết các dự án như Typecript và Flowjs. Chúc mừng! –