Những ngôn ngữ lập trình mệnh lệnh nào không hỗ trợ đệ quy?


21

Theo hiểu biết của tôi, tất cả các ngôn ngữ lập trình mệnh lệnh hiện đại đều hỗ trợ đệ quy theo nghĩa là một thủ tục có thể tự gọi nó. Điều này không phải lúc nào cũng đúng, nhưng tôi không thể tìm thấy bất kỳ sự thật khó khăn nào bằng một tìm kiếm nhanh trên Google. Vì vậy, câu hỏi của tôi là:

Những ngôn ngữ nào không hỗ trợ đệ quy ngay từ đầu và khi nào hỗ trợ đó được thêm vào?

Câu trả lời:


21

Tôi không chắc là COBOL làm điều đó (chắc chắn nó đã không xảy ra cùng một lúc), nhưng tôi hoàn toàn không thể tưởng tượng được ai quan tâm nhiều.

Fortran có từ Fortran 90, nhưng yêu cầu bạn sử dụng recursivetừ khóa để nói với nó rằng một chương trình con là đệ quy.

PL / Tôi khá giống nhau - đệ quy được hỗ trợ, nhưng bạn phải nói rõ cho nó biết thủ tục nào được đệ quy.

Tôi nghi ngờ có nhiều hơn thế mặc dù. Khi bạn bắt đầu, việc cấm đệ quy chủ yếu là điều IBM đã làm trong các thiết kế ngôn ngữ của họ, vì lý do đơn giản là các máy tính lớn của IBM (360/370/3090 / ...) không hỗ trợ một phần cứng. Khi hầu hết các ngôn ngữ đến từ IBM, họ chủ yếu cấm đệ quy. Bây giờ tất cả đều đến từ những nơi khác, luôn luôn cho phép đệ quy (mặc dù tôi nên thêm rằng một số máy khác, đáng chú ý là Cray 1 ban đầu, cũng không có hỗ trợ phần cứng cho ngăn xếp).


Các máy tính dữ liệu điều khiển trong giai đoạn này cũng không hỗ trợ đệ quy (các lệnh gọi chương trình con được thực hiện với một lệnh đã sửa đổi mã để chèn một bước nhảy vào lệnh gọi + 1). Khi Wirth phát triển Pascal vào năm 6600, có lẽ anh ta đã phải nghĩ ra một cách mới để gọi chương trình con.
David Thornley

@David: có - và không phải ngẫu nhiên, chúng cũng được thiết kế bởi Seymour Cray. Tôi đã từng xem qua trình biên dịch Pascal 6000, nhưng không nhớ là đã xem những gì nó đã làm để tạo ra các khung xếp chồng (mô phỏng?).
Jerry Coffin

notably the original cray 1Vì vậy, bạn không cần đệ quy để nhân bản khủng long? Tôi đoán nó thực sự là tùy thuộc vào chúng tôi khỉ để đu qua cây.
Normanthesquid

2
ngay cả CAML (và OCAML, F #) cũng cần các hàm đệ quy được đánh dấu rõ ràng.
jk.

1
@Panzercrisis: Tôi không chắc liệu IBM có tham gia vào x86 hay không, nhưng các máy tính lớn hiện tại của họ có liên quan trực tiếp đến IBM 360, xuất hiện trên thị trường vào năm 1964, vì vậy thiết kế cơ bản có trước x86 vài thập kỷ hoặc lâu hơn.
Jerry Coffin

16

Wikipedia nói:

Các ngôn ngữ ban đầu như Fortran ban đầu không hỗ trợ đệ quy vì các biến được phân bổ tĩnh, cũng như vị trí cho địa chỉ trả về.

http://en.wikipedia.org/wiki/Subroutine#Local_variables.2C_recursion_and_V-entrancy

FORTRAN 77 không cho phép đệ quy, Fortran 90 cũng vậy, (các thói quen đệ quy phải được khai báo rõ ràng như vậy).

Hầu hết các trình biên dịch FORTRAN 77 cho phép đệ quy, một số (ví dụ: DEC) yêu cầu sử dụng tùy chọn trình biên dịch (xem chương tùy chọn trình biên dịch). GNU g77, tuân thủ nghiêm ngặt tiêu chuẩn Fortran 77, hoàn toàn không cho phép đệ quy.

http://www.ibiblio.org/pub/lacular/fortran/ch1-12.html


iirc có ít nhất một trình biên dịch FORTRAN 77, trong khi về mặt kỹ thuật hỗ trợ đệ quy, tổng số khung stack bạn có thể có đệ quy nhỏ không thể sử dụng hiệu quả cho nhiều vấn đề
jk.

6

Ngôn ngữ lập trình OpenCL không hỗ trợ đệ quy. (xem phần 6.8 của Thông số OpenCL )

Động lực hiện tại cho điều đó là a) thiếu không gian cho các ngăn xếp sâu b) mong muốn được biết, về mặt tĩnh, tổng số phân bổ cần thiết để tối ưu hóa hiệu suất với sự hiện diện của các bộ đăng ký lớn và lớp lót rộng rãi.

Điều này cũng có thể áp dụng cho các ngôn ngữ lập trình GPU khác, ví dụ ngôn ngữ shader.


2

Một số trình biên dịch c cho các bộ vi điều khiển nhỏ không hỗ trợ đệ quy, có lẽ vì chúng có kích thước ngăn xếp cực kỳ hạn chế.


Một số trong các bộ vi điều khiển (ví dụ: họ PIC16) chỉ có ngăn xếp cuộc gọi phần cứng (không thể truy cập theo hướng dẫn) và không có bất kỳ hình thức ngăn xếp nào khác, vì vậy các hàm không thể có biến cục bộ khi sử dụng đệ quy (vì rõ ràng cần một ngăn xếp dữ liệu cho điều đó ...) Tham khảo: vi.wikipedia.org/wiki/PIC_microcontler#Stacks
Ale

1

BASIC, trong những ngày của số dòng, có xu hướng có hỗ trợ đệ quy kém. Nhiều (tất cả?) BASIC thời đó hỗ trợ các cuộc gọi gosub lồng nhau, nhưng không hỗ trợ một cách dễ dàng để truyền tham số hoặc trả về giá trị theo cách có ích để tự gọi.

Nhiều máy tính ban đầu gặp vấn đề với đệ quy, vì chúng đã sử dụng các lệnh gọi ghi địa chỉ trả lại vào đầu của thói quen được gọi là (PDP8, họ máy IAS, có lẽ nhiều kiến ​​trúc mà tôi không quen), thường là theo cách mà nó không quen thuộc là mã máy cho "Chuyển đến hướng dẫn sau cái được gọi là thường trình".


1

Nó phụ thuộc vào những gì bạn có nghĩa là " hỗ trợ ". Để hỗ trợ đệ quy, bạn cần một ngăn xếp để khởi tạo lại các biến cục bộ ở mỗi lần nhập lại.

Ngay cả khi ngôn ngữ không có khái niệm về biến cục bộ, nếu ngôn ngữ đó có khái niệm "chương trình con" và có cách quản lý chỉ mục giữa các biến giống nhau (còn gọi là mảng), bạn có thể tăng / giảm chỉ số toàn cầu sau mỗi lần nhập / thoát của một hàm và truy cập thông qua nó một thành viên của một hoặc nhiều mảng.

Tôi không biết nếu điều này có thể được gọi là "hỗ trợ". Sự thật là tôi đã viết chức năng đệ quy với ZX-Spectrum BASIC, như tôi đã làm trong Fortran77 như trong COBOL ... luôn luôn với thủ thuật đó.


1

Ngôn ngữ hội không hỗ trợ trực tiếp đệ quy - bạn phải "tự làm", thường bằng cách đẩy các tham số lên ngăn xếp máy.


2
Nó hỗ trợ đệ quy cho đến khi nó hỗ trợ các cuộc gọi phương thức. Thường có một CALLlệnh, tự động đẩy IP lên ngăn xếp trước khi nhảy đến chương trình con và một REThướng dẫn bật địa chỉ trả lại vào IP. Không có lý do gì bạn không thể CALLnhập điểm của riêng bạn.
Blorgbeard

@Blorgbeard - hoàn toàn đúng, mặc dù tôi cho rằng điều này không đủ để tính là "hỗ trợ đệ quy" theo nghĩa thông thường vì nó không xử lý các tham số cần thiết cho cuộc gọi đệ quy.
mikera

1
Chà, các cuộc gọi đệ quy không cần kỹ thuật, phải không? void f() { f(); }là đệ quy.
Blorgbeard

Về mặt kỹ thuật, không. Nhưng việc có thể mã hóa một trường hợp tầm thường không IMHO có nghĩa là bạn nên mô tả lắp ráp là "đệ quy hỗ trợ". Hầu hết các sử dụng thực tế của đệ quy yêu cầu tham số.
mikera

Tôi cho rằng bạn có thể nói rằng. Nhưng trong trường hợp đó, lắp ráp cũng không hỗ trợ các vòng lặp (bạn phải thủ công CMP và JNZ). Tôi đoán đó là vấn đề của những gì bạn gọi là "hỗ trợ".
Blorgbeard
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.