Các ngôn ngữ động luôn được giải thích?


18

Nhìn vào hầu hết (nếu không phải tất cả) các ngôn ngữ động (ví dụ: Python, PHP, Perl và Ruby), tất cả chúng đều được diễn giải. Sửa lỗi cho tôi nếu tôi sai. Có ví dụ nào về ngôn ngữ động trải qua giai đoạn biên dịch không? Là ngôn ngữ động giống hệt với ngôn ngữ giải thích?


4
Xác định ngôn ngữ động, nó có được gõ động không?
BenjaminB

3
Objective-C thể hiện nhiều tính chất "động".
Edward Strange

4
@Job, người ta có thể làm điều đó với Lisp trong nhiều thập kỷ. Và nó được biên dịch và đánh máy động. Vì vậy, chưa bao giờ có một ranh giới chính xác giữa biên dịch và giải thích.
SK-logic

2
@Darien Bạn cũng có thể biên dịch nó vào thời gian chạy và thực thi mã sau đó. Nói đúng ra, đó không phải là giải thích.
xmm0

3
@Darien Không có gì ngăn cản trình biên dịch lưu trữ thông tin bảng ký hiệu trong tệp nhị phân được biên dịch và tạo mã để truy cập vào thời gian chạy. Đúng là một số ngôn ngữ cho vay để giải thích nhiều hơn là biên dịch, nhưng toàn bộ vấn đề là có thể có một trình biên dịch cho ngôn ngữ đó. Một điều quan trọng khác cần lưu ý là một số người cho rằng trình biên dịch phải tạo ra một số loại mã máy. Trong thực tế, có các trình biên dịch chỉ đơn giản thực hiện chuyển đổi mức nguồn qua hai ngôn ngữ (hoặc thậm chí cùng một ngôn ngữ, như một số trình khai thác Javascript).
xmm0

Câu trả lời:


33

Nhìn vào hầu hết (nếu không phải tất cả) các ngôn ngữ động [ví dụ Python, PHP, Perl và Ruby], tất cả chúng đều được diễn giải.

Không đúng. Bạn có thể biên dịch nguồn Python. Đó là một bằng chứng hiện sinh.

Có các thông dịch viên cho các ngôn ngữ gõ tĩnh và trình biên dịch cho các ngôn ngữ gõ động. Hai khái niệm là trực giao.

Lưu ý bên lề: Nói chung, một ngôn ngữ chỉ là: một ngôn ngữ, với một tập hợp các cấu trúc cú pháp để diễn đạt ngữ nghĩa. Nếu bạn viết Python trên bảng trắng, nó vẫn được gọi là Python! Đó là việc thực hiện có thể là một trình thông dịch hoặc trình biên dịch. Được gõ tĩnh hoặc gõ động (thuộc loại kết hợp cả hai) là một thuộc tính của ngôn ngữ, trong khi thực hiện chương trình bằng cách diễn giải hoặc biên dịch là một thuộc tính của việc thực hiện.


19
Độ chính xác phải thụt lề phù hợp trên bảng trắng để Python có giá trị cú pháp? ;)
edA-qa mort-ora-y

1
Bạn không thể biên dịch Python. PYC chỉ tăng tốc tải của mô-đun. Và py2exe chỉ cần nhúng trình thông dịch vào exe với tệp nguồn.
BenjaminB

8
@ Ubiquité: .pyctập tin là mã byte. Mã nguồn Python đã được phân tích cú pháp, tối ưu hóa và biên dịch để tạo ra chúng. Các hướng dẫn mã byte tương đối ở mức độ cao và cách triển khai phổ biến nhất của nó là một trình thông dịch đơn giản (ngược lại, hãy xem PyPy mà JIT biên dịch mã byte thành mã máy rất thông minh trong thời gian chạy) nhưng Python không được biên dịch ít hơn Java hoặc C #. Python chỉ "không được biên dịch" nếu "biên dịch" bị giới hạn trong quá trình biên dịch trước thời gian , nhưng không ai nói gì về điều đó và nói chung nó có thể đề cập đến bất kỳ chuyển đổi ngôn ngữ nào sang ngôn ngữ.

4
@ Ubiquité: Vâng, điều đó đúng, nhưng điều đó không liên quan đến tuyên bố của bạn rằng "Bạn không thể biên dịch Python" hoặc liệu có thể biên dịch Python hay không. Đầu tiên và quan trọng nhất, bạn đang pha trộn PythonCPython, trong khi cái sau là một triển khai của cái trước, cũng vậy PyPy.
phant0m

2
@ClemC TẤT CẢ các thuộc tính của ngôn ngữ được tích hợp vào trình biên dịch hoặc trình thông dịch, nếu không thì trình thông dịch hoặc trình biên dịch là thứ dành cho ngôn ngữ khác.
Pieter B

15

Lisp thông thường được gõ động (và mạnh) và thường được biên dịch .

Vì tính năng động này đạt được trong thời gian chạy, nên có một số lệnh bạn có thể sử dụng trong mã nguồn để đảm bảo trình biên dịch rằng một ký hiệu sẽ chỉ giữ một loại giá trị nhất định, để trình biên dịch có thể tối ưu hóa mã được tạo và tăng hiệu suất.


12

C # 4.0 hỗ trợ các loại động (liên kết muộn) và nó được biên dịch.


4

node.js dựa trên công cụ javascript V8 của Google. V8 không biên dịch thời gian chạy. V8 nhanh chóng được đưa ra thực tế đó. Chỉ cần xem http://shootout.alioth.debian.org và so sánh V8 với bất kỳ ngôn ngữ nào được giải thích ở trên.


3

Không - chắc chắn có thể biên dịch các ngôn ngữ động.

Thậm chí có một số ngôn ngữ động luôn được biên soạn theo thiết kế (ví dụ Clojure).

Tuy nhiên, câu hỏi chạm vào một điểm quan trọng liên quan: mặc dù các ngôn ngữ động có thể được biên dịch, nhưng thường thì các ngôn ngữ động không thể được biên dịch thành mã có hiệu quả như ngôn ngữ gõ tĩnh . Điều này là do có một số tính năng vốn có trong các ngôn ngữ động yêu cầu kiểm tra thời gian chạy sẽ không cần thiết trong ngôn ngữ được biên dịch tĩnh.

Một ví dụ về điều này: các ngôn ngữ cho phép vá thời gian chạy các đối tượng (ví dụ: Ruby) thường yêu cầu đối tượng được kiểm tra (với tra cứu có thể băm hoặc tương tự) bất cứ khi nào bạn gọi một phương thức trên đối tượng. Ngay cả khi điều này được biên dịch, trình biên dịch sẽ phải tạo mã để thực hiện tra cứu phương thức trong thời gian chạy. Ở một mức độ nào đó, việc tra cứu phương pháp này không giống với những gì một thông dịch viên sẽ phải làm.

Điều này thêm một chi phí đáng kể khi so sánh với một cuộc gọi phương thức trong một ngôn ngữ như Java, trong đó phương thức đúng có thể được xác định tĩnh bởi trình biên dịch từ định nghĩa lớp và được rút gọn thành một lệnh gọi hàm đơn giản trong mã gốc.

Tôi tin rằng hiệu ứng này nhiều hơn bất kỳ thứ gì khác dẫn đến các ngôn ngữ động có hiệu suất trung bình chậm hơn so với các đối tác được biên dịch tĩnh của chúng. Như bạn có thể thấy từ các điểm chuẩn còn thiếu sót , đó là các ngôn ngữ được nhập tĩnh (C, Java, Fortran, v.v.) có xu hướng nhanh nhất với các ngôn ngữ động (Perl, Python, Ruby, PHP, v.v.) ở cuối bảng xếp hạng.


2

Ngày xửa ngày xưa, BASIC đã được giải thích. Và một số biến thể của BASIC có kiểu gõ động. Và bạn có thể nhận được trình biên dịch cho chúng là tốt.

(Điều này đã trở lại vào thời của các ổ đĩa mềm 100K, khi khủng long vẫn đi lang thang trên trái đất và ăn các nhà phát triển s / w không nghi ngờ cho bữa sáng.)


... nhưng chỉ khi họ sử dụng GOTO. (Tất nhiên, điều này khá phổ biến nếu họ đang phát triển trong BASIC. AHA! Điều đó giải thích điều đó!)
Mason Wheeler

BASIC tại thời điểm thiết kế của nó là một ngôn ngữ được biên dịch.
AProgrammer

2

Các triển khai Smalltalk khác nhau xử lý việc này khác nhau, nhưng một vài trong số chúng biên dịch thành mã byte chạy trên máy ảo hiệu năng cao.


2

Trong thực tế, hầu hết các ngôn ngữ được gọi là "diễn giải" đều đi qua / cho phép biên dịch đúng lúc để làm cho nó chạy nhanh hơn. Và một số trong số chúng phải được biên dịch thành mã byte trước khi bạn có thể chạy chúng.

Trong thực tế, năng động và diễn giải hoàn toàn là 2 ý tưởng khác nhau, mặc dù có một mối tương quan. Lý do là những người từng cảm thấy việc gõ động giúp công việc của họ trở nên dễ dàng và nhanh hơn, họ sẽ không bận tâm đến việc mã chạy chậm hơn một chút nhưng có thể mang theo được.


1

Chrome, IE9 và Firefox 3.1+ đều biên dịch JavaScript thành nhị phân gốc và JavaScript được nhập tự động.

Tôi nghĩ lý do mà các ngôn ngữ động trong lịch sử có xu hướng được giải thích là bởi vì gõ và diễn giải động (hay cụ thể hơn là thiếu biên dịch) cả hai đều có xu hướng hữu ích cho các ngôn ngữ kịch bản lệnh và các tác vụ kịch bản nói chung.

Hiệu suất cũng không phải là vấn đề đáng lo ngại đối với các loại chương trình được viết bằng các ngôn ngữ này, do đó, một lần nữa, chi phí cho việc gõ và phiên dịch động không phải là vấn đề lớn như trong ngôn ngữ hiệu suất giá trị đó.


1

Python thường được biên dịch. Được thừa nhận biên dịch thành mã byte sau đó được giải thích.

Perl hoạt động theo cách tương tự.

Thông thường, Lisp sẽ biên dịch thành một trong các mã gốc hoặc byte. Điều này khác nhau giữa các lần triển khai (và, ở một mức độ nào đó, trong một triển khai, tùy thuộc vào các cài đặt tối ưu hóa khác nhau).


-5

Đúng. Tất cả các ngôn ngữ động là ngôn ngữ được diễn giải (nhưng một ngôn ngữ được dịch có thể không động).

Lý do rất đơn giản: nếu nó là động, nó cần một trình thông dịch để thực hiện tính năng động ở cấp độ biên dịch nhị phân.

Ví dụ. : khi chúng tôi đặt dữ liệu vào một biến PHP, sau đó một loại khác thuộc loại khác, chương trình của chúng tôi không thể biên dịch thành mã nhị phân do mỗi loại có định dạng biểu diễn nhị phân riêng; thông dịch viên quản lý các ca ở cấp nhị phân một cách năng động


2
Sai lầm. Các ngôn ngữ động có thể được biên dịch (và đôi khi rất hiệu quả, ví dụ: sử dụng JIT và các kỹ thuật biên dịch thích ứng)
Basile Starynkevitch

"Roughly, trình biên dịch JIT kết hợp tốc độ của mã được biên dịch với tính linh hoạt của phiên dịch, với chi phí của trình thông dịch ..." en.wikipedia.org/wiki/Just-in-time_compilation chương trình của bạn không biên dịch: nó được biên dịch bởi thông dịch viên cho bạn
ClearMind

Đọc các giấy tờ liên quan đến TỰ
TIN

Chắc chắn rồi. Liên kết của bạn đề cập: "Một tính năng của Tự là nó dựa trên cùng loại hệ thống máy ảo mà các hệ thống Smalltalk trước đây đã sử dụng. Đó là, các chương trình không phải là các thực thể độc lập như trong các ngôn ngữ như C, nhưng cần toàn bộ môi trường bộ nhớ để chạy. " không độc lập = không được biên dịch nhị phân, máy ảo là cần thiết để thực hiện quá trình biên dịch nhị phân
ClearMind

1
Định nghĩa của bạn về trình biên dịch là quá hạn chế. Không phải mọi trình biên dịch tạo ra một tập tin thực thi nhị phân. Đối với một ví dụ gần đây, nghiên cứu việc thực hiện SBCL . Đọc Sách Rồng mới nhất và Lisp thành từng mảnh nhỏ
Basile Starynkevitch
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.