Cuộc gọi / cc của Scheme có thể thực hiện tất cả các cấu trúc luồng điều khiển đã biết không?


12

Trang "Lược đồ nâng cao: Một số bit nghịch ngợm" nêu rõ:

Continuations là một cấu trúc luồng điều khiển mạnh mẽ mà từ đó gần như bất kỳ cấu trúc luồng điều khiển nào khác [...] có thể được bắt nguồn.

Tôi nghĩ rằng Scheme call/cc, có liên quan (*) với nhà điều hành J của Peter Landin, có thể được sử dụng để thực hiện bất kỳ cấu trúc dòng điều khiển đã biết nào không?

Với "cấu trúc dòng điều khiển", tôi đặc biệt suy nghĩ về mô tả của Wikipedia về chúng, ví dụ như các trường hợp ngoại lệ, coroutines, chủ đề xanh, v.v.

Cụ thể, có bất kỳ ví dụ nào về cấu trúc dòng điều khiển không thể được thực hiện bằng cách sử dụng call/cckhông?

(*) Tôi chưa thể đào bất kỳ bài báo nào thiết lập call/ccmạnh như toán tử J. Một bài báo của Felleisen (mà tôi chưa đọc và thừa nhận có vấn đề hiểu nó đầy đủ) điều tra điều này, và dường như kết luận rằng mặc dù chúng thuộc các lớp phức tạp khác nhau, nhưng chúng chính thức tương đương nhau.

(Cũng lưu ý rằng tôi đã cập nhật câu hỏi dựa trên các bình luận bên dưới)

Cập nhật

Dựa trên câu trả lời xuất sắc của @Neel bên dưới, tôi đã xem các trang web nhận xét về các phần tiếp theo được phân tách và không bị giới hạn , và thực sự có vẻ như trong khi call/cc, không bị giới hạn, là không đủ. Trong khi đó, dường như, các phần tiếp theo được phân tách (như shift/reset) có thể được sử dụng để thể hiện bất kỳ cấu trúc dòng điều khiển nào.


5
Định nghĩa chính thức của "cấu trúc dòng điều khiển" là gì?
Huck Bennett

4
Re: tiếp tục không giới hạn. Bạn đã đọc bài tham khảo của Hayo Thielecke? Yêu cầu thực tế là các phần tiếp theocall/cc không bị giới hạn như được cung cấp bởi không thể thể hiện các ngoại lệ trong trường hợp không có nhà nước . (Như Thielecke tiếp tục chỉ ra, các trường hợp ngoại lệ có thể được thực hiện bằng cách chuyển qua hai phần tiếp theo, một cho chương trình và phần còn lại cho trình xử lý ngoại lệ, nhưng điều đó đòi hỏi nhiều hơn chỉ call/cc.)
rici

@Rici: Tôi chỉ đọc lướt qua vài trang đầu tiên. (Đọc bài làm tôi mất nhiều thời gian). Cảm ơn các bình luận!
csl

@HuckBennett Tôi không có một định nghĩa chính thức, nhưng không chính thức tôi có nghĩa là những gì nó được mô tả tại en.wikipedia.org/wiki/Control_flow - đặc biệt là tôi có nghĩa là bạn có thể sử dụng continuations để thể hiện, và quan trọng hơn, để thực hiện, coroutines, chủ đề màu xanh lá cây, ngoại lệ, báo cáo thoát, trình điều khiển amb, và như vậy.
csl

2
@csl Ngoài việc làm chính xác hơn "cấu trúc dòng điều khiển" nghĩa là gì, bạn cũng cần phải nói rõ hơn ý nghĩa của việc "diễn đạt" một cái gì đó. Đây là một vấn đề khó khăn và câu trả lời cho câu hỏi của bạn phụ thuộc mạnh mẽ vào những gì bạn được coi là biểu hiện. Rốt cuộc, bạn luôn có thể mã hóa bằng cách nào đó một máy Turing mã hóa trình thông dịch của ngôn ngữ có ngoại lệ (ví dụ: Java). Nhưng đó có lẽ không phải là những gì bạn có trong đầu, vì vậy bạn cần đặt ra những ràng buộc mạnh mẽ đối với khái niệm "biểu hiện" (ví dụ: thành phần và / hoặc trừu tượng hóa hoàn toàn).
Martin Berger

Câu trả lời:


10

Trong câu trả lời này, tôi sẽ dùng "có thể biểu thị" thành "biểu hiện vĩ mô" theo nghĩa của Felleisen 1991, Về sức mạnh biểu cảm của ngôn ngữ lập trình . (Theo trực giác, một tính năng ngôn ngữ có thể biểu thị vĩ mô nếu bạn có thể định nghĩa nó là một chuyển đổi nguồn cục bộ, mà không sử dụng chuyển đổi toàn bộ chương trình.)

Với định nghĩa này, câu trả lời là không : điều khiển phân cách không thể biểu thị vĩ mô trong lambda-tính toán + cuộc gọi / cc. Để thể hiện các toán tử điều khiển phân cách bằng cách sử dụng cuộc gọi / cc. Để thực hiện các dấu phân cách điều khiển (phần thiết lập lại của shift / reset), bạn cần một số trạng thái để mô phỏng các dấu tiếp tục, về cơ bản là mã hóa một ngăn xếp để mô phỏng vòng đời động của các dấu tiếp tục.

Tuy nhiên, kiểm soát giới hạn là một hiệu ứng phổ quát, theo nghĩa sau đây. Trong luận án tiến sĩ của mình , Andrzej Filinski đã chỉ ra rằng bất kỳ tác dụng phụ rõ rệt nào đều được mã hóa bằng cách sử dụng các phần tiếp theo được phân tách hoặc gọi / cc và một ô trạng thái. Roughly, một "hiệu ứng phụ rõ ràng" là bất kỳ hiệu ứng nào mà loại đơn âm có thể được định nghĩa theo các loại ngôn ngữ lập trình.

Đáng ngạc nhiên, ý tưởng này có vẻ khá thú vị trong thực tế. Trong thập kỷ qua, Gordon Plotkin và John Power đã ủng hộ ý tưởng lấy một ngữ nghĩa đại số của các lý thuyết hiệu ứng : ý tưởng là bạn xác định các hoạt động tác dụng phụ mà bạn quan tâm và các phương trình mà bạn mong đợi chúng thỏa mãn, và sau đó bạn thường có thể có được một ngữ nghĩa bằng cách lấy đơn nguyên miễn phí trên lý thuyết này.

Matija Pretnar và Andrej Bauer đã sử dụng phương pháp toán học này, và sau đó triển khai nó bằng ngôn ngữ Eff của họ để phát minh ra một ngôn ngữ mới có tên là "trình xử lý hiệu ứng": bạn có thể viết mã sử dụng một tập hợp các tính năng bắt buộc, sau đó cung cấp cho các tính năng bắt buộc một ngữ nghĩa bằng cách viết một bộ xử lý cho biết cách thực hiện từng thao tác hiệu quả.


Nhưng nếu định nghĩa là: "Bạn có thể thực hiện bất kỳ cấu trúc luồng điều khiển nào bằng cách sử dụng Scheme và gọi / cc" (không có mô phỏng), thì câu trả lời phải là ? Nhìn vào cuộc thảo luận của LtU lambda-the-ultimate.org/node/966 , có vẻ như Oleg Kiselyouv đã triển khai tất cả bốn toán tử F trong Scheme với lệnh gọi / cc: okmij.org/ftp/continuations/ tựa - đoạn trích "Đoạn mã dựa trên trên cuộc gọi / cc để ghi lại các phần tiếp theo không bị giới hạn và sử dụng một ô có thể thay đổi toàn cầu. Hóa ra, điều này đủ để thực hiện [...] các toán tử F khác ". ... "-F- đến + F + F".
csl

Tôi thừa nhận việc bạn sử dụng "biểu cảm vĩ mô" của Felleisen làm khung cho câu trả lời của bạn, nhưng như bạn có thể thấy tôi đã thay đổi câu hỏi của mình thành "thực hiện [trong Đề án] bằng cách sử dụng cuộc gọi / cc". Và trong khi Oleg Kiselyov cần giới thiệu một tế bào có thể thay đổi toàn cầu để triển khai cả bốn toán tử F cho các phần tiếp theo được phân định, thì tôi không nghĩ rằng điều này có nghĩa là "tái cấu trúc toàn cầu, chính của chương trình"
csl

Tôi sẽ chấp nhận câu trả lời này. Tôi cũng muốn trỏ đến văn bản tại okmij.org/ftp/continuations/undelrict.html#d006-vs-und006 có thêm con trỏ. Dường như cũng thể sử dụng các lớp tiếp theo được phân tách , hạng nhất như shift / reset để thực hiện bất kỳ cấu trúc luồng điều khiển nào. Từ liên kết: "Các phần tiếp theo được phân định bằng hạng nhất có thể biểu thị bất kỳ hiệu ứng tính toán rõ ràng nào, bao gồm các trường hợp ngoại lệ và trạng thái có thể thay đổi."
csl
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.