Làm thế nào là tác dụng phụ xử lý trong ngữ nghĩa?


19

Trong phần "Giới thiệu về ngôn ngữ lập trình" của Anthony Aaby về ngữ nghĩa , ông đưa ra nhận xét sau:

Phần lớn công việc trong ngữ nghĩa của các ngôn ngữ lập trình được thúc đẩy bởi các vấn đề gặp phải khi cố gắng xây dựng và hiểu các chương trình bắt buộc --- các chương trình với các lệnh gán. Vì lệnh gán gán lại giá trị cho các biến, nên việc gán có thể có tác dụng không mong muốn ở các phần xa của chương trình.

Điều này gây ấn tượng với tôi như một sự thừa nhận đáng chú ý, rằng việc cho phép các tác dụng phụ sẽ thúc đẩy một phần chính của công việc trong ngữ nghĩa.

Làm thế nào để tồn tại các tác dụng phụ trong ngôn ngữ lập trình ảnh hưởng đến khả năng ánh xạ chương trình sang mô hình tính toán? Có cách tiếp cận nào để quản lý nhà nước có thể cải thiện quá trình này trong khi vẫn cho phép tác dụng phụ không?


Điều này có nên được gắn thẻ như một câu hỏi mềm? Vì "phần lớn công việc trong ngữ nghĩa [...] được thúc đẩy bởi [tác dụng phụ]", nên chắc chắn bạn không thể mong đợi một câu trả lời ngắn gọn và nghiêm ngặt.
Radu GRIGore

1
@Radu: Trên MO, điều này có thể sẽ được gắn thẻ [hình ảnh lớn], mà hầu hết không phải là [câu hỏi mềm] hoặc CW ở đó.
Charles Stewart

Thẻ hình ảnh lớn thậm chí còn tốt hơn. Tôi đã quên điều đó.
Radu GRIGore

Gợi ý tốt; Tôi đã thêm thẻ.
Shane

Câu trả lời:


18

Dựa trên câu trả lời của Charles, khó khăn chính trong lý thuyết về ngôn ngữ lập trình là khái niệm tự nhiên về sự tương đương của các chương trình thường không phải là sự bình đẳng nghiêm ngặt trong ngữ nghĩa toán học đơn giản nhất mà bạn có thể đưa ra, hoặc trong mô hình máy cơ bản. Ví dụ, hãy xem xét bit sau của mã giống như Java:

Object x = new Object();
Object y = new Object();
... some more code ...

Vì vậy, chương trình này tạo một đối tượng và đặt tên là x, sau đó tạo một đối tượng thứ hai có tên y, và sau đó tiếp tục thực thi thêm một số mã. Bây giờ, giả sử rằng một lập trình viên quyết định lật thứ tự phân bổ của hai đối tượng này:

Object y = new Object();
Object x = new Object();
... some more code ...

Bây giờ, đặt câu hỏi: việc tái cấu trúc này có thay đổi hành vi của chương trình không? Một mặt, trên máy bên dưới, x và y sẽ được phân bổ tại các vị trí khác nhau trong hai lần chạy chương trình. Vì vậy, trong ý nghĩa này, chương trình hành xử khác nhau.

Nhưng trong một ngôn ngữ giống như Java, bạn chỉ có thể kiểm tra các tham chiếu cho sự bằng nhau chứ không phải theo thứ tự, vì vậy đây là một sự khác biệt mà "một số mã nữa" không thể quan sát được . Do đó, hầu hết các lập trình viên sẽ mong đợi rằng việc đảo ngược thứ tự sẽ không có gì khác biệt với câu trả lời cuối cùng, và hầu hết các nhà văn biên dịch đều mong muốn có thể thực hiện sắp xếp lại và tối ưu hóa trên cơ sở này. (Mặt khác, trong ngôn ngữ giống như C, bạn có thể so sánh các con trỏ để đặt hàng, bằng cách chuyển chúng thành các số nguyên trước, và do đó, việc sắp xếp lại này không nhất thiết bảo tồn hành vi có thể quan sát được.)

Một trong những câu hỏi trọng tâm của ngữ nghĩa là trả lời câu hỏi khi nào hai chương trình tương đương nhau. Do khái niệm quan sát của chúng tôi phụ thuộc vào các tính năng của ngôn ngữ lập trình, chúng tôi kết thúc với một định nghĩa như "hai chương trình tương đương nhau khi không có chương trình khách hàng nào có thể tính toán các câu trả lời khác nhau dựa trên việc nhận các chương trình đó làm đầu vào". Việc định lượng trên tất cả các chương trình máy khách là điều gây khó khăn cho câu hỏi này - có vẻ như cuối cùng bạn phải nói điều gì đó về tất cả các chương trình khách hàng có thể để nói điều gì đó về hai đoạn mã cụ thể.

Thủ thuật với ngữ nghĩa học biểu thị là đưa ra một diễn giải toán học cho phép bạn tránh sự định lượng phổ quát này - bạn nói rằng ý nghĩa của một đoạn mã là một giá trị toán học nào đó, và bạn so sánh chúng bằng cách kiểm tra xem chúng có bằng nhau về mặt toán học hay không không phải. Đây là cục bộ (nghĩa là thành phần) và không liên quan đến định lượng trên tất cả các khách hàng có thể. .

Nhưng có nghĩa là bạn cần đảm bảo rằng ngữ nghĩa học biểu thị xác nhận những tương đương đó. Vì vậy, trong ví dụ này, nếu bạn muốn đưa ra một ngữ nghĩa biểu thị cho ngôn ngữ giống như Java này, bạn cần đảm bảo không chỉ việc gọi mới mất một đống và trả lại cho bạn một đống mới với đối tượng mới được tạo, mà đó là ý nghĩa của chương trình là bất biến giống nhau dưới mọi hoán vị của heap đầu vào. Điều này có thể liên quan đến các cấu trúc toán học khá phức tạp (ví dụ, trong trường hợp này làm việc trong một thể loại đảm bảo mọi thứ hoạt động theo mô đun một nhóm hoán vị phù hợp).


"hai chương trình tương đương nhau khi không có chương trình khách hàng nào có thể tính toán các câu trả lời khác nhau dựa trên việc nhận các chương trình đó làm đầu vào." Tôi bối rối vì điều này. Nếu bạn có chương trình X và chương trình máy khách Y, thì tôi hiểu nó có nghĩa là Y 'gọi vào' X. Nhưng sau đó bạn dường như nói rằng Y đọc văn bản của X là đầu vào , trong trường hợp đó tôi khó gọi Bạn là 'khách hàng' của X. Bạn có thể vui lòng làm rõ không?
Radu GRIGore

1
Theo "client of X", tôi chỉ có nghĩa giống như "bối cảnh chương trình", đây chỉ là một "chương trình lớn hơn chứa X dưới dạng subterm".
Neel Krishnaswami

Vì vậy, bạn sử dụng 'X là khách hàng của Y' có thể hoán đổi cho nhau với 'X đọc Y là đầu vào' vì bạn nghĩ X là lambda áp dụng cho Y? Nó có ý nghĩa, nhưng nó hơi xoắn khi bạn nói về Java. :)
Radu GRIGore

1
@RaduGRIGore: bối cảnh chương trình có nghĩa là một cái gì đó khác. Bạn đang đọc chính xác bài đăng, nhưng nếu X đọc mã nguồn của Y làm đầu vào (đó là cách tôi diễn giải bài đăng), bạn có thể phân biệt hai chương trình khác nhau về mặt cú pháp; thay vào đó nếu Y là hàm lambda trên X, bạn có thể phân biệt quá ít chương trình. Nhận xét của Neel về "bối cảnh chương trình" là định nghĩa chính xác: bối cảnh chương trình Y là một chương trình có lỗ hổng trong AST của nó, nơi bạn có thể đặt (một cách có ý nghĩa) hai đoạn chương trình khác nhau X1 và X2.
Blaisorblade

@NeelKrishnaswami: bạn có thể làm rõ ý của bạn trong bài viết không? Bạn chỉ có thể tiếp tục sử dụng ví dụ của mình và nói về một chương trình mà bạn có thể chèn một hoặc một đoạn khác.
Blaisorblade

12

Tất nhiên có nhiều cách để đối phó với các hiệu ứng trong ngữ nghĩa (biểu thị). Ví dụ: chúng ta có thể sử dụng ý tưởng của Eugenio Moggi rằng các hiệu ứng tính toán là các đơn nguyên (ý tưởng này cũng đã được sử dụng trong thiết kế của Haskell). Một trong những vấn đề với điều này là các đơn nguyên khó kết hợp. Gordon PlotkinJohn Power đã đề xuất một sự tinh chỉnh các đơn nguyên của Moggi cho các lý thuyết Lawvere , hay các lý thuyết đại số khi chúng còn được gọi, bao gồm các hiệu ứng đại số (hầu hết các hiệu ứng phổ biến là đại số, như trạng thái, I / O, không xác định, nhưng liên tục không phải). Để điều trị toàn diện, xem luận án của Matija Pretnar .

Tôi cũng nên đề cập đến ngữ nghĩa thế giới có thể có cho nhà nước địa phương, được phát triển bởi Frank Oles và John Reynold (xin lỗi, không thể tìm thấy một liên kết tốt hơn, công cụ này là từ năm 1982), trước các đơn vị của Moggi. Họ đã sử dụng các loại presheaves để cung cấp một ngữ nghĩa của ngôn ngữ giống như algol, mô hình chính xác nhiều khía cạnh của trạng thái địa phương (nhưng không phải tất cả chúng, tôi nghĩ rằng mô hình cho phép snapback, nhưng có lẽ bộ nhớ của tôi phục vụ cho tôi sai).


1
Đúng, ngữ nghĩa loại functor không xác nhận tất cả các tương đương Meyer-Sieber. Peter O'Hearn và Robert Tennant đã phát triển một phiên bản tham số của ngữ nghĩa loại functor vào giữa những năm 90 mà (IIRC) có tất cả các ví dụ Meyer-Sieber, nhưng tôi không biết liệu nó có hoàn toàn trừu tượng hay không.
Neel Krishnaswami

Mô hình O'Hearn và Tennent không hoàn toàn trừu tượng. Điều đó được thảo luận trong bài báo. Nhưng sự tinh chỉnh của O'Hearn và Reynold bằng phép tính lambda tuyến tính hoàn toàn trừu tượng lên đến bậc hai. Nó phá vỡ thứ tự thứ ba, các ví dụ là tương đương được nghiên cứu bởi Ahmed, Dreyer, Birkedal et al.
Uday Reddy

12

Matthias Felleisen đã trình bày một giải pháp hấp dẫn cho vấn đề tác dụng phụ trong ngữ nghĩa trong loạt bài về "Lý thuyết cú pháp kiểm soát và nhà nước".

Dòng công việc đó dẫn đến máy CESK, một khung máy trừu tượng đơn giản có khả năng mô hình hóa chính xác các ngôn ngữ chức năng, hướng đối tượng, mệnh lệnh và thậm chí logic. Khung CESK xử lý không chỉ các tác dụng phụ, mà cả các cấu trúc điều khiển "phức tạp" như ngoại lệ, tiếp tục, lười biếng và thậm chí là các luồng.

Máy CESK, và ngữ nghĩa hoạt động bước nhỏ rộng hơn, là tiêu chuẩn thực tế trong lý thuyết ngôn ngữ lập trình trong khoảng hai thập kỷ.

Nói tóm lại, máy CESK là một máy bước nhỏ với bốn thành phần để mô tả mọi trạng thái máy: chuỗi điều khiển (tổng quát của bộ đếm chương trình), môi trường, cửa hàng (còn gọi là heap) và tiếp tục hiện tại.

Môi trường ánh xạ các biến đến địa chỉ; các cửa hàng ánh xạ địa chỉ đến các giá trị.

Điều này làm cho nó đơn giản để mô hình các biến có thể thay đổi: chỉ cần thay đổi giá trị tại địa chỉ của nó.

Nó cũng giúp dễ dàng mô hình hóa con trỏ và phân bổ động: chỉ cần tạo địa chỉ cửa hàng cho các giá trị hạng nhất.

Theo cách tương tự, các phần tiếp theo hạng nhất là kết quả của việc biến chúng thành các giá trị có thể định địa chỉ.


6

Làm thế nào để tồn tại các tác dụng phụ trong ngôn ngữ lập trình ảnh hưởng đến khả năng ánh xạ chương trình sang mô hình tính toán?

Nó không nhất thiết gây khó khăn, nhưng nó áp đặt các hạn chế về cách ngữ nghĩa của các biểu thức lớn hơn có thể được xây dựng từ các biểu thức nhỏ hơn. Chẳng hạn, nó có thể tương tác rất tệ với một số cấu trúc lập trình khác, nếu người ta muốn đưa ra một ngữ nghĩa biểu thị theo kiểu Scott cho một ngôn ngữ cho phép gán các hàm bậc cao hơn cho các tham chiếu toàn cục.

Nó không chỉ đơn giản là tác dụng phụ như trạng thái gây ra rắc rối. Các ngôn ngữ mệnh lệnh đơn giản như ngôn ngữ lệnh được bảo vệ của Dijkstra có các loại tác dụng phụ này và có ngữ nghĩa tốt. Rắc rối nảy sinh với việc mở rộng tính toán lambda với loại ngữ nghĩa hoạt động được mong đợi của các ngôn ngữ lập trình ngay cả khi không có tác dụng phụ: PCF của Plotkin sớm nhất, đã được đưa ra các mô hình biểu thị tương đối sớm, nhưng ngữ nghĩa không hoàn toàn trừu tượng, có nghĩa là ngữ nghĩa học biểu thị là quá chung chung, không chính xác tương ứng với ngữ nghĩa hoạt động của họ. PCF cuối cùng đã nhận được một ngữ nghĩa biểu thị hoàn toàn trừu tượng vào cuối những năm 1980 với ngữ nghĩa trò chơi, hoàn toàn không giống như ngữ nghĩa lý thuyết trật tự của Scott. Đồng thời vẫn chưa nhận được một điều trị biểu thị đầy đủ.

Nhiều người đặt câu hỏi về tầm quan trọng của loại ngữ nghĩa này. Chúng tôi luôn có thể cung cấp một số loại ngữ nghĩa hoạt động, ngay cả khi "ngữ nghĩa" đó chỉ là nguồn chương trình và tên của một số máy đã biên dịch và chạy chương trình: vì lý do này, Strachey đã lên án ngữ nghĩa hoạt động. Nhưng ngữ nghĩa hoạt động cấu trúc của Plotkin đã chỉ ra cách thức ngữ nghĩa hoạt động có thể tách rời khỏi các mô hình máy móc và công việc của Pitt đã cho thấy ngữ nghĩa như vậy có thể hỗ trợ lý luận tương tự về các chương trình và ngôn ngữ lập trình cho ngữ nghĩa học. Do đó, ngữ nghĩa hoạt động là một thay thế khả thi cho ngữ nghĩa học biểu thị, và đã được áp dụng thành công cho một số lượng đáng kể các ngôn ngữ lập trình như ML chuẩn.

Có cách tiếp cận nào để quản lý nhà nước có thể cải thiện quá trình này trong khi vẫn cho phép tác dụng phụ không?

Ở một mức độ nào đó, những khó khăn trong việc cung cấp ngữ nghĩa tương ứng với khó khăn trong việc cung cấp các ngôn ngữ lập trình mạnh mẽ, hành xử theo cách mà người ta mong đợi. Các quyết định thiết kế được thúc đẩy một cách thực tế như là tránh việc sử dụng trạng thái toàn cầu cùng với đồng thời, thông thường thông qua đồng thời truyền thông điệp giúp cho việc cung cấp ngữ nghĩa dễ dàng hơn.


PCF của Scott không có nhà nước và cũng không phải là Scott, phải không? Xem en.wikipedia.org/wiki/iêu
Andrej Bauer

@Andrej: Err, khá, cho rằng Luke Ong giám sát D.Phil của tôi, tôi không nên phạm sai lầm đó. Tôi đã đăng một bản tóm tắt của PCF của Milner và LCF của Scott, đó là ... không thua gì WP như là một câu chuyện LtU : lambda-the-ultimate.org/node/2196 Tôi nhận thấy rằng bạn có thể truy cập vào Scott bị mất tích (1969) bản thảo ...
Charles Stewart

Đó sẽ là PCF của Plotkin, tôi nghĩ :-) Tôi có thể cố gắng giữ bản thảo, nhưng tôi thực sự không có nó.
Andrej Bauer

Nhưng vấn đề vẫn là PCF không có nhà nước. "Lý do" nào mà bạn nói rằng Strachey lên án ngữ nghĩa hoạt động? Nó không rõ ràng với tôi. Đoạn cuối mâu thuẫn với những gì bạn đã nói trước đó, viz., Các lệnh được bảo vệ có ngữ nghĩa tốt nhưng PCF thì không!
Uday Reddy

@Andrej, Uday: Tôi đã sửa bài viết của mình, chưa đầy ba năm sau.
Charles Stewart
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.