Thuật ngữ minh bạch tham chiếu có nghĩa là gì? Tôi đã nghe nó được mô tả là "nó có nghĩa là bạn có thể thay thế bằng bằng" nhưng điều này có vẻ như là một lời giải thích không thỏa đáng.
Thuật ngữ minh bạch tham chiếu có nghĩa là gì? Tôi đã nghe nó được mô tả là "nó có nghĩa là bạn có thể thay thế bằng bằng" nhưng điều này có vẻ như là một lời giải thích không thỏa đáng.
Câu trả lời:
Thuật ngữ "minh bạch tham chiếu" xuất phát từ triết học phân tích , nhánh của triết học phân tích các cấu trúc ngôn ngữ tự nhiên, các phát biểu và lập luận dựa trên các phương pháp logic và toán học. Nói cách khác, nó là môn học gần nhất ngoài khoa học máy tính với cái mà chúng ta gọi là ngữ nghĩa lập trình ngôn ngữ . Nhà triết học Willard Quine chịu trách nhiệm khởi xướng khái niệm về tính minh bạch tham chiếu, nhưng nó cũng tiềm ẩn trong cách tiếp cận của Bertrand Russell và Alfred Whitehead.
Tại cốt lõi của nó, "minh bạch tham chiếu" là một ý tưởng rất đơn giản và rõ ràng. Thuật ngữ "người giới thiệu" được sử dụng trong triết học phân tích để nói về điều mà một biểu thức đề cập đến . Nó gần giống như những gì chúng ta muốn nói là "nghĩa" hay "ký hiệu" trong ngữ nghĩa ngôn ngữ lập trình. Sử dụng ví dụ của Andrew Birkett ( bài đăng trên blog ), thuật ngữ "thủ đô của Scotland" dùng để chỉ thành phố Edinburgh. Đó là một ví dụ đơn giản về "người giới thiệu".
Một ngữ cảnh trong câu là "minh bạch tham chiếu" nếu thay thế một thuật ngữ trong ngữ cảnh đó bằng một thuật ngữ khác đề cập đến cùng một thực thể không làm thay đổi nghĩa. Ví dụ
Quốc hội Scotland họp tại thủ đô của Scotland.
có nghĩa giống như
Quốc hội Scotland họp tại Edinburgh.
Vì vậy, bối cảnh "Quốc hội Scotland họp tại ..." là một bối cảnh minh bạch tham chiếu. Chúng ta có thể thay thế "thủ đô của Scotland" bằng "Edinburgh" mà không làm thay đổi ý nghĩa. Nói cách khác, bối cảnh chỉ quan tâm đến những gì thuật ngữ này đề cập đến và không có gì khác. Đó là ý nghĩa trong đó bối cảnh là "minh bạch tham chiếu."
Mặt khác, trong câu,
Edinburgh là thủ đô của Scotland từ năm 1999.
chúng ta không thể thay thế như vậy. Nếu chúng ta làm như vậy, chúng ta sẽ nhận được "Edinburgh đã là Edinburgh từ năm 1999", đó là một điều thú vị để nói, và không truyền đạt ý nghĩa tương tự như câu gốc. Vì vậy, có vẻ như bối cảnh "Edinburgh đã ... từ năm 1999" bị mờ đục (ngược lại với tính minh bạch tham chiếu). Nó rõ ràng quan tâm đến một cái gì đó nhiều hơn những gì thuật ngữ này đề cập đến. Nó là gì?
Những thứ như "thủ đô của Scotland" được gọi là các thuật ngữ xác định và chúng không gây đau đầu cho các nhà logic học và triết học trong một thời gian dài. Russell và Quine đã sắp xếp chúng ra nói rằng chúng không thực sự là "tham chiếu", nghĩa là, thật sai lầm khi nghĩ rằng các ví dụ trên được sử dụng để chỉ các thực thể. Cách hiểu đúng "Edinburgh là thủ đô của Scotland từ năm 1999" là nói
Scotland đã có một thủ đô từ năm 1999 và thủ đô đó là Edinburgh.
Câu này không thể được chuyển thành một câu hạt dẻ. Vấn đề được giải quyết! Quan điểm của Quine là nói rằng ngôn ngữ tự nhiên lộn xộn, hoặc ít nhất là phức tạp, bởi vì nó được tạo ra để thuận tiện cho việc sử dụng thực tế, nhưng các nhà triết học và logic nên mang lại sự rõ ràng bằng cách hiểu chúng đúng cách. Tính minh bạch tham chiếu là một công cụ được sử dụng để mang lại ý nghĩa rõ ràng như vậy .
Tất cả những điều này có liên quan gì đến lập trình? Thật ra không nhiều lắm. Như chúng ta đã nói, tính minh bạch tham chiếu là một công cụ được sử dụng để hiểu ngôn ngữ, nghĩa là trong việc gán nghĩa . Christopher Strachey , người sáng lập lĩnh vực ngữ nghĩa ngôn ngữ lập trình, đã sử dụng nó trong nghiên cứu về ý nghĩa của mình. Bài viết nền tảng của ông " Các khái niệm cơ bản trong ngôn ngữ lập trình " có sẵn trên web. Đó là một bài báo đẹp và mọi người đều có thể đọc và hiểu nó. Vì vậy, xin vui lòng làm như vậy. Bạn sẽ được giác ngộ nhiều. Ông giới thiệu thuật ngữ "minh bạch tham chiếu" trong đoạn này:
Một trong những thuộc tính hữu ích nhất của biểu thức là được gọi bởi tính minh bạch tham chiếu Quine. Về bản chất, điều này có nghĩa là nếu chúng ta muốn tìm giá trị của biểu thức có chứa biểu thức con, điều duy nhất chúng ta cần biết về biểu thức con là giá trị của biểu thức. Bất kỳ tính năng nào khác của biểu thức phụ, chẳng hạn như cấu trúc bên trong của nó, số lượng và tính chất của các thành phần của nó, thứ tự chúng được đánh giá hoặc màu mực mà chúng được viết, không liên quan đến giá trị của chính biểu hiện.
Việc sử dụng "về bản chất" cho thấy Strachey đang diễn giải nó để giải thích nó bằng những thuật ngữ đơn giản. Các lập trình viên chức năng dường như hiểu đoạn này theo cách riêng của họ. Có 9 sự xuất hiện khác của "tính minh bạch tham chiếu" trong bài báo, nhưng dường như họ không bận tâm về bất kỳ vấn đề nào khác. Trên thực tế, toàn bộ bài viết của Strachey được dành để giải thích ý nghĩa của các ngôn ngữ lập trình mệnh lệnh . Nhưng, ngày nay, các lập trình viên chức năng tuyên bố rằng các ngôn ngữ lập trình mệnh lệnh không minh bạch về mặt tham chiếu. Strachey sẽ trở lại trong mộ của mình.
Chúng tôi có thể cứu vãn tình hình. Chúng tôi đã nói rằng ngôn ngữ tự nhiên là "lộn xộn, hoặc ít nhất là phức tạp" bởi vì nó được tạo ra để thuận tiện cho việc sử dụng thực tế. Ngôn ngữ lập trình là cùng một cách. Chúng "lộn xộn, hoặc ít nhất là phức tạp" bởi vì chúng được tạo ra để thuận tiện cho việc sử dụng thực tế. Điều đó không có nghĩa là họ cần nhầm lẫn chúng tôi. Họ chỉ cần được hiểu đúng cách, sử dụng một ngôn ngữ meta được minh bạch tham chiếu để chúng ta có sự rõ ràng về ý nghĩa. Trong bài báo tôi đã trích dẫn, Strachey thực hiện chính xác điều đó. Ông giải thích ý nghĩa của các ngôn ngữ lập trình mệnh lệnh bằng cách chia chúng thành các khái niệm cơ bản, không bao giờ mất đi sự rõ ràng ở bất cứ đâu. Một phần quan trọng trong phân tích của ông là chỉ ra rằng các biểu thức trong ngôn ngữ lập trình có hai loại "giá trị",giá trị r . Trước bài báo của Strachey, điều này không được hiểu và sự nhầm lẫn ngự trị tối cao. Ngày nay, định nghĩa của C đề cập đến nó thường xuyên và mọi lập trình viên C đều hiểu sự khác biệt. (Việc các lập trình viên trong các ngôn ngữ khác có hiểu nó tốt như nhau hay không là điều khó nói.)
Cả Quine và Strachey đều quan tâm đến ý nghĩa của các cấu trúc ngôn ngữ liên quan đến một số hình thức phụ thuộc vào ngữ cảnh. Ví dụ, ví dụ của chúng tôi "Edinburgh là thủ đô của Scotland từ năm 1999" biểu thị thực tế rằng "thủ đô của Scotland" phụ thuộc vào thời gian mà nó đang được xem xét. Sự phụ thuộc vào bối cảnh như vậy là một thực tế, cả trong ngôn ngữ tự nhiên và ngôn ngữ lập trình. Ngay cả trong lập trình chức năng, các biến tự do và ràng buộc phải được giải thích liên quan đến bối cảnh mà chúng xuất hiện. Sự phụ thuộc bối cảnh của bất kỳ loại nào ngăn chặn tính minh bạch tham chiếu theo cách này hay cách khác. Nếu bạn cố gắng hiểu ý nghĩa của các thuật ngữ mà không quan tâm đến bối cảnh mà chúng phụ thuộc, bạn sẽ lại bị nhầm lẫn. Quine quan tâm đến ý nghĩa của logic phương thức. Ông giữ điều đólogic phương thức bị mờ đục về mặt tham chiếu và nó cần được làm sạch bằng cách dịch nó thành một khung trong suốt tham chiếu (ví dụ, bằng cách coi sự cần thiết là khả năng chứng minh). Ông đã mất phần lớn cuộc tranh luận này. Các nhà logic học và các nhà triết học cũng nhận thấy ngữ nghĩa thế giới có thể của Kripke là hoàn toàn phù hợp. Tình hình tương tự cũng ngự trị với lập trình mệnh lệnh. Sự phụ thuộc vào nhà nước được giải thích bởi Strachey và sự phụ thuộc vào cửa hàng được giải thích bởi Reynold (theo cách tương tự như ngữ nghĩa thế giới có thể của Kripke) là hoàn toàn phù hợp. Các lập trình viên chức năng không biết nhiều về nghiên cứu này. Ý tưởng của họ về tính minh bạch tham chiếu sẽ được thực hiện với một hạt muối lớn.
[Ghi chú bổ sung: Các ví dụ trên minh họa rằng một cụm từ đơn giản như "thủ đô của Scotland" có nhiều cấp độ ý nghĩa. Ở một cấp độ, chúng ta có thể nói về thủ đô tại thời điểm hiện tại. Ở một cấp độ khác, chúng ta có thể nói về tất cả các thủ đô có thể mà Scotland có thể đã có trong suốt thời gian. Chúng ta có thể "phóng to" một bối cảnh cụ thể và "thu nhỏ" để mở rộng tất cả các bối cảnh khá dễ dàng trong thực tế thông thường. Hiệu quả của ngôn ngữ tự nhiên sử dụng khả năng của chúng tôi để làm như vậy. Các ngôn ngữ lập trình mệnh lệnh rất hiệu quả theo cùng một cách. Chúng ta có thể sử dụng một biến x ở phía bên phải của một bài tập ( giá trị r ) để nói về giá trị của nó trong một trạng thái cụ thể. Hoặc, chúng ta có thể nói về giá trị l của nómà kéo dài tất cả các tiểu bang. Mọi người hiếm khi bối rối bởi những điều như vậy. Tuy nhiên, họ có thể hoặc không thể giải thích chính xác tất cả các lớp ý nghĩa vốn có trong các cấu trúc ngôn ngữ. Tất cả các lớp ý nghĩa như vậy không nhất thiết là 'hiển nhiên' và vấn đề khoa học là nghiên cứu chúng đúng cách. Tuy nhiên, sự vô cảm của những người bình thường để giải thích những ý nghĩa phân lớp như vậy không có nghĩa là họ bối rối về chúng.]
Một "phần tái bút" riêng biệt dưới đây liên quan đến cuộc thảo luận này với các mối quan tâm của lập trình chức năng và mệnh lệnh .
Độ trong suốt tham chiếu, một thuật ngữ thường được sử dụng trong lập trình chức năng, có nghĩa là với một hàm và giá trị đầu vào, bạn sẽ luôn nhận được cùng một đầu ra. Đó là để nói rằng không có trạng thái bên ngoài được sử dụng trong chức năng.
Dưới đây là một ví dụ về chức năng minh bạch tham chiếu:
int plusOne(int x)
{
return x+1;
}
Với hàm minh bạch tham chiếu, được cung cấp đầu vào và hàm, bạn có thể thay thế nó bằng một giá trị thay vì gọi hàm. Vì vậy, thay vì gọi plusOne với tham số là 5, chúng ta chỉ có thể thay thế bằng 6.
Một ví dụ điển hình khác là toán học nói chung. Trong toán học đã cho một hàm và một giá trị đầu vào, nó sẽ luôn ánh xạ tới cùng một giá trị đầu ra. f (x) = x + 1. Do đó, các hàm trong toán học được minh bạch tham chiếu.
Khái niệm này rất quan trọng đối với các nhà nghiên cứu bởi vì nó có nghĩa là khi bạn có một chức năng minh bạch tham chiếu, nó tự cho vay để tự động song song hóa và bộ nhớ đệm dễ dàng.
Độ trong suốt tham chiếu được sử dụng luôn trong các ngôn ngữ chức năng như Haskell.
-
Ngược lại có khái niệm về độ mờ đục tham chiếu. Điều này có nghĩa ngược lại. Gọi hàm có thể không luôn luôn tạo ra cùng một đầu ra.
//global G
int G = 10;
int plusG(int x)
{//G can be modified externally returning different values.
return x + G;
}
Một ví dụ khác, là một hàm thành viên trong ngôn ngữ lập trình hướng đối tượng. Các hàm thành viên thường hoạt động trên các biến thành viên của nó và do đó sẽ mờ đục tham chiếu. Chức năng thành viên tất nhiên có thể được tham chiếu minh bạch.
Một ví dụ khác là một chức năng đọc từ tệp văn bản và in kết quả đầu ra. Tệp văn bản bên ngoài này có thể thay đổi bất cứ lúc nào vì vậy chức năng sẽ bị mờ đục.
Hàm trong suốt tham chiếu là một hàm chỉ phụ thuộc vào đầu vào của nó.
[Đây là một phần tái bút cho câu trả lời của tôi từ ngày 25 tháng 3, trong nỗ lực đưa cuộc thảo luận đến gần hơn với các mối quan tâm của lập trình chức năng / mệnh lệnh.]
Ý tưởng về tính minh bạch tham chiếu của các lập trình viên chức năng dường như khác với khái niệm tiêu chuẩn theo ba cách:
Trong khi các nhà triết học / logic sử dụng các thuật ngữ như "tham chiếu", "biểu thị", "chỉ định" và " bedeutung " (thuật ngữ tiếng Đức của Frege), các lập trình viên chức năng sử dụng thuật ngữ "giá trị". (Đây không hoàn toàn là việc họ làm. Tôi nhận thấy rằng Landin, Strachey và con cháu của họ cũng sử dụng thuật ngữ "giá trị" để nói về tham chiếu / ký hiệu. Nó có thể chỉ là một cách đơn giản về thuật ngữ mà Landin và Strachey đã giới thiệu, nhưng nó dường như tạo ra một sự khác biệt lớn khi được sử dụng một cách ngây thơ.)
Các lập trình viên chức năng dường như tin rằng những "giá trị" này tồn tại trong ngôn ngữ lập trình chứ không phải bên ngoài. Khi làm điều này, họ khác với cả các nhà triết học và các nhà ngữ nghĩa ngôn ngữ lập trình.
Họ dường như tin rằng những "giá trị" này được cho là có được bằng cách đánh giá.
Ví dụ, bài viết Wikipedia về tính minh bạch tham chiếu cho biết, sáng nay:
Một biểu thức được cho là minh bạch tham chiếu nếu nó có thể được thay thế bằng giá trị của nó mà không thay đổi hành vi của một chương trình (nói cách khác, mang lại một chương trình có cùng hiệu ứng và đầu ra trên cùng một đầu vào).
Điều này hoàn toàn trái ngược với những gì các nhà triết học / logic nói. Họ nói rằng một bối cảnh là tham chiếu hoặc minh bạch tham chiếu nếu một biểu thức trong ngữ cảnh đó có thể được thay thế bằng một biểu thức khác đề cập đến cùng một điều (một biểu thức cốt lõi ). Những triết gia / nhà logic học này là ai? Họ bao gồm Frege , Russell , Whitehead , Carnap , Quine , Nhà thờvà vô số người khác. Mỗi người trong số họ là một nhân vật cao chót vót. Sức mạnh trí tuệ kết hợp của các nhà logic học này là ít nói nhất. Tất cả đều nhất trí ở vị trí mà người giới thiệu / ký hiệu tồn tại bên ngoài ngôn ngữ chính thức và các biểu thức trong ngôn ngữ chỉ có thể nói về họ. Vì vậy, tất cả những gì người ta có thể làm trong ngôn ngữ là thay thế một biểu thức bằng một biểu thức khác đề cập đến cùng một thực thể. Bản thân các tham chiếu / ký hiệu không tồn tại trong ngôn ngữ. Tại sao các lập trình viên chức năng đi chệch khỏi truyền thống được thiết lập tốt này?
Người ta có thể cho rằng các nhà ngữ nghĩa học ngôn ngữ lập trình có thể đã đánh lừa họ. Nhưng họ đã không làm thế.
Landin :
(a) mỗi biểu thức có cấu trúc biểu thức phụ lồng nhau, (b) mỗi biểu thức phụ biểu thị một cái gì đó (thường là một số, giá trị thật hoặc hàm số) , (c) biểu thức biểu thị, nghĩa là "giá trị" của nó các giá trị của biểu thức con của nó, không phải trên các thuộc tính khác của chúng. [Đã nhấn mạnh]
Stoy :
Điều duy nhất quan trọng về một biểu thức là giá trị của nó và bất kỳ biểu thức con nào cũng có thể được thay thế bằng bất kỳ giá trị bằng nào khác [Nhấn mạnh thêm]. Hơn nữa, giá trị của một biểu thức là, trong các giới hạn nhất định, giống nhau bất cứ khi nào nó xuất hiện ".
giá trị của một biểu thức chỉ phụ thuộc vào các giá trị của các biểu thức cấu thành của nó (nếu có) và các biểu thức con này có thể được thay thế tự do bởi các biểu thức khác có cùng giá trị [Nhấn mạnh thêm].
Vì vậy, khi nhìn lại, những nỗ lực của Landin và Strachey để đơn giản hóa thuật ngữ bằng cách thay thế "tham chiếu" / "ký hiệu" bằng "giá trị" có thể đã gây hại. Ngay khi nghe về một "giá trị", sẽ có một sự cám dỗ khi nghĩ về một quy trình đánh giá dẫn đến nó. Thật hấp dẫn không kém khi nghĩ về bất cứ điều gì mà đánh giá tạo ra là "giá trị", mặc dù có thể khá rõ ràng rằng đó không phải là biểu thị. Đó là những gì tôi thu thập được đã xảy ra với khái niệm "minh bạch tham chiếu" trong mắt các lập trình viên chức năng. Nhưng "giá trị" được nói bởi các nhà ngữ nghĩa học ban đầu không phải là kết quả của một đánh giá hoặc đầu ra của một chức năng hoặc bất kỳ điều gì như vậy. Đó là ký hiệu của thuật ngữ.
Một khi chúng ta hiểu cái gọi là "giá trị" của một biểu thức ("tham chiếu" hoặc "biểu thị" trong diễn ngôn của các nhà triết học cổ điển) như một đối tượng toán học / khái niệm phức tạp, tất cả các loại khả năng sẽ mở ra.
Sự miễn cưỡng của các lập trình viên chức năng gọi các ngôn ngữ đó là "minh bạch tham chiếu" chỉ ngụ ý rằng họ miễn cưỡng thừa nhận các đối tượng toán học / khái niệm phức tạp như vậy là "giá trị". Mặt khác, họ dường như hoàn toàn sẵn sàng gọi một biến áp trạng thái là "giá trị" khi nó được đặt theo cú pháp yêu thích của riêng họ và mặc quần áo với một từ buzz như "monad". Tôi phải nói rằng họ đang hoàn toàn không nhất quán, ngay cả khi chúng tôi cấp cho họ rằng ý tưởng "minh bạch tham chiếu" của họ có sự gắn kết.
Một chút lịch sử có thể làm sáng tỏ về cách những nhầm lẫn này ra đời. Giai đoạn từ 1962 đến 1967 là một giai đoạn rất nặng nề đối với Christopher Strachey. Trong khoảng thời gian 1962-65, ông đã làm một công việc bán thời gian với tư cách là trợ lý nghiên cứu với Maurice Wilkes để thiết kế và thực hiện ngôn ngữ lập trình được gọi là CPL. Đây là một ngôn ngữ lập trình bắt buộc nhưng cũng có nghĩa là có khả năng ngôn ngữ lập trình chức năng mạnh mẽ. Landin, một nhân viên của Strachey trong công ty tư vấn của mình, có ảnh hưởng rất lớn đến quan điểm của Strachey về ngôn ngữ lập trình. Trong bài viết nổi bật năm 1969 " 700 ngôn ngữ lập trình tiếp theo ", Landin không ngừng quảng bá các ngôn ngữ lập trình chức năng (gọi chúng là biểu thịngôn ngữ) và mô tả các ngôn ngữ lập trình mệnh lệnh là "phản đề" của chúng. Trong cuộc thảo luận tiếp theo, chúng tôi thấy Strachey đặt ra nghi ngờ về vị thế mạnh mẽ của Landin.
... DLs tạo thành một tập hợp con của tất cả các ngôn ngữ. Chúng là một tập hợp con thú vị, nhưng là một tập hợp bất tiện khi sử dụng trừ khi bạn đã quen với nó. Chúng tôi cần chúng bởi vì hiện tại chúng tôi không biết cách xây dựng bằng chứng với các ngôn ngữ bao gồm mệnh lệnh và bước nhảy. [Đã nhấn mạnh]
Năm 1965, Strachey đảm nhận vị trí Độc giả tại Oxford và dường như đã làm việc chủ yếu toàn thời gian để phát triển một lý thuyết về mệnh lệnh và bước nhảy. Đến năm 1967, anh đã sẵn sàng với một lý thuyết, mà anh đã dạy trong khóa học về " Khái niệm cơ bản trong ngôn ngữ lập trình " tại một trường học hè ở Copenhagen. Các ghi chú bài giảng được cho là đã được xuất bản nhưng "thật không may, vì chỉnh sửa mở rộng, các thủ tục tố tụng không bao giờ được thực hiện, giống như nhiều công việc của Strachey tại Oxford, tuy nhiên, bài báo có lưu hành tư nhân có ảnh hưởng." ( Martin Campbell-Kelly )
Khó khăn trong việc có được các tác phẩm của Strachey có thể đã dẫn đến sự nhầm lẫn được truyền bá, với những người dựa vào các nguồn thứ cấp và tin đồn. Nhưng, bây giờ " Các khái niệm cơ bản " đã có sẵn trên web, không cần phải dùng đến công việc đoán. Chúng ta nên đọc nó và tạo nên suy nghĩ của riêng mình về ý nghĩa của Strachey. Đặc biệt:
Bất kỳ cuộc nói chuyện nào về "tính minh bạch tham chiếu" mà không hiểu sự khác biệt giữa giá trị L, giá trị R và các đối tượng phức tạp khác tạo ra vũ trụ khái niệm của lập trình viên mệnh lệnh đều bị nhầm lẫn về cơ bản.
Hàm minh bạch tham chiếu là hàm hoạt động như hàm toán học; với cùng một đầu vào, nó sẽ luôn tạo ra các đầu ra giống nhau. Nó ngụ ý rằng trạng thái được truyền vào không được sửa đổi và hàm không có trạng thái của chính nó.
Đối với những người cần một lời giải thích ngắn gọn, tôi sẽ mạo hiểm một (nhưng đọc phần tiết lộ dưới đây).
Tính minh bạch tham chiếu trong ngôn ngữ lập trình thúc đẩy lý luận bằng phương trình - tính minh bạch tham chiếu càng nhiều thì càng dễ thực hiện lý luận tương đương. Ví dụ: với định nghĩa hàm (giả),
fx = x + x,
sự dễ dàng mà bạn có thể (một cách an toàn) thay thế f (foo) bằng foo + foo trong phạm vi định nghĩa này, mà không có quá nhiều ràng buộc về nơi bạn có thể thực hiện việc giảm này, là một dấu hiệu tốt về mức độ minh bạch của ngôn ngữ lập trình tham chiếu của bạn có.
Ví dụ: nếu foo là x ++ theo nghĩa lập trình C thì bạn không thể thực hiện việc giảm này một cách an toàn (nghĩa là, nếu bạn thực hiện việc giảm này, bạn sẽ không kết thúc với cùng một chương trình mà bạn đã bắt đầu).
Trong các ngôn ngữ lập trình thực tế, bạn sẽ không thấy tính minh bạch tham chiếu hoàn hảo nhưng các lập trình viên chức năng quan tâm đến nó nhiều hơn hầu hết (cf Haskell, trong đó mục tiêu cốt lõi).
(Tiết lộ đầy đủ: Tôi là một lập trình viên chức năng vì vậy theo câu trả lời hàng đầu, bạn nên đưa ra lời giải thích này với một hạt muối.)
Trong 1 có một sự rõ ràng của hai ngôn ngữ trong câu hỏi:
Trong 2, nhờ sự gần gũi của vật thể và kim loại, chúng có thể bị nhầm lẫn.
Là một người thực hiện ngôn ngữ, tôi thấy rằng tôi cần liên tục ghi nhớ sự khác biệt này.
Vì vậy, giáo sư Reddy có thể diễn giải bạn như vậy :-)
Trong bối cảnh của lập trình chức năng và ngữ nghĩa, thuật ngữ Minh bạch tham chiếu không tham chiếu minh bạch.
Câu trả lời sau đây tôi hy vọng sẽ bổ sung và đủ điều kiện cho câu trả lời thứ 1 và thứ 3 gây tranh cãi.
Chúng ta hãy cho rằng một biểu thức biểu thị hoặc đề cập đến một số người giới thiệu. Tuy nhiên, một câu hỏi là liệu các tham chiếu này có thể được mã hóa một cách đồng hình như là một phần của chính các biểu thức hay không, gọi các biểu thức đó là 'giá trị'. Ví dụ, các giá trị số bằng chữ là một tập hợp con của tập hợp các biểu thức số học, các giá trị chân lý là tập con của tập hợp các biểu thức boolean, v.v. Ý tưởng là đánh giá một biểu thức cho giá trị của nó (nếu nó có một biểu thức). Vì vậy, từ 'giá trị' có thể đề cập đến một ký hiệu hoặc một yếu tố phân biệt của tập hợp các biểu thức. Nhưng nếu có một sự đẳng cấu (một mệnh đề) giữa người giới thiệu và giá trị chúng ta có thể nói chúng là cùng một thứ. (Điều này nói rằng, người ta phải cẩn thận để xác định các tham chiếu và đẳng cấu, như đã được chứng minh bởi lĩnh vực ngữ nghĩa học biểu thị.data Nat = Zero | Suc Nat
không tương ứng như mong đợi với tập hợp các số tự nhiên.)
Hãy để chúng tôi viết E[·]
cho một biểu thức có một lỗ, còn được gọi là "bối cảnh" trong một số phần tư. Hai ví dụ bối cảnh cho các biểu thức giống như C là [·]+1
và
[·]++
.
Chúng ta hãy viết [[·]]
cho hàm có một biểu thức (không có lỗ) và cung cấp ý nghĩa của nó (tham chiếu, ký hiệu, v.v.) trong một số vũ trụ cung cấp ý nghĩa. (Tôi đang mượn ký hiệu từ lĩnh vực ngữ nghĩa học.)
Chúng ta hãy điều chỉnh định nghĩa của Quine một cách chính thức như sau: một bối cảnh E[·]
được minh bạch tham chiếu với hai biểu thức E1
và E2
(không có lỗ hổng nào) sao cho [[E1]] = [[E2]]
(nghĩa là các biểu thức biểu thị / tham chiếu đến cùng một tham chiếu) thì đó là trường hợp [[E[E1]]] = [[E[E2]]]
(nghĩa là điền vào -trong lỗ với một trong hai E1
hoặc E2
kết quả trong các biểu thức cũng biểu thị cùng một tham chiếu).
Nguyên tắc thay thế bình đẳng cho equals Leibniz thường thể hiện dưới dạng 'nếu
E1 = E2
sau đó E[E1] = E[E2]
', mà nói rằng E[·]
là một hàm. Hàm (hoặc đối với vấn đề đó là chương trình tính toán hàm) là ánh xạ từ nguồn tới đích để có nhiều nhất một phần tử đích cho mỗi phần tử nguồn. Chức năng không xác định là misnomers, họ là một trong hai quan hệ, chức năng cung cấp bộ, vv Nếu trong quy tắc Leibniz sự bình đẳng =
là denotational thì đôi dấu ngoặc chỉ đơn giản là đưa cho các cấp và elided. Vì vậy, một bối cảnh minh bạch tham chiếu là một chức năng. Và quy tắc của Leibniz là thành phần chính của lý luận tương đương, vì vậy lý luận phương trình chắc chắn có liên quan đến tính minh bạch tham chiếu.
Mặc dù [[·]]
là một hàm từ biểu thức đến ký hiệu, nó có thể là hàm từ biểu thức đến 'giá trị' được hiểu là tập con hạn chế của biểu thức và [[·]]
có thể hiểu là đánh giá.
Bây giờ, nếu E1
là một biểu thức và E2
là một giá trị chúng ta có những gì tôi nghĩ có nghĩa là hầu hết mọi người khi xác định tính minh bạch tham chiếu về mặt biểu thức, giá trị và đánh giá. Nhưng như được minh họa bởi câu trả lời thứ 1 và thứ 3 trong trang này, đây là một định nghĩa không chính xác.
Vấn đề với các bối cảnh như [·]++
không phải là tác dụng phụ, mà là giá trị của nó không được định nghĩa trong C về mặt đồng nghĩa với ý nghĩa của nó. Hàm không phải là giá trị (tốt, con trỏ tới hàm là) trong khi đó trong ngôn ngữ lập trình hàm. Landin, Strachey và những người tiên phong về ngữ nghĩa học phi nghĩa là khá thông minh trong việc sử dụng các thế giới chức năng để cung cấp ý nghĩa.
Đối với các ngôn ngữ giống như C bắt buộc, chúng ta có thể (đại khái) cung cấp ngữ nghĩa cho các biểu thức bằng cách sử dụng hàm [[·]] : Expression -> (State -> State x Value)
.
Value
là một tập hợp con của Expression
. State
chứa các cặp (định danh, giá trị). Hàm ngữ nghĩa nhận một biểu thức và cung cấp theo nghĩa của nó là một hàm từ trạng thái hiện tại đến cặp với trạng thái được cập nhật và một giá trị. Ví dụ, [[x]]
là hàm từ trạng thái hiện tại đến cặp có thành phần đầu tiên là trạng thái hiện tại và thành phần thứ hai là giá trị của x. Ngược lại, [[x++]]
là hàm từ trạng thái hiện tại đến cặp có thành phần đầu tiên là trạng thái trong đó giá trị của x được tăng lên và thành phần thứ hai có giá trị rất cao. Theo nghĩa này, bối cảnh [·]++
được minh bạch tham chiếu nếu nó thỏa mãn định nghĩa được đưa ra ở trên.
Tôi nghĩ rằng các lập trình viên chức năng có quyền sử dụng tính minh bạch tham chiếu theo nghĩa họ phục hồi tự nhiên [[·]]
như một hàm từ biểu thức đến giá trị. Các hàm là các giá trị hạng nhất và trạng thái cũng có thể là một giá trị, không phải là một biểu thị. Các đơn vị trạng thái là (một phần) một cơ chế sạch để chuyển (hoặc phân luồng) trạng thái.
Lưu ý rằng khái niệm "ý nghĩa" này là một cái gì đó xảy ra trong tâm trí của người quan sát. Do đó, cùng một "tham chiếu" có thể có nghĩa là những điều khác nhau cho những người khác nhau. Vì vậy, ví dụ, chúng ta có một trang định hướng ở Edinburgh trong Wikipedia.
Một vấn đề liên quan có thể xuất hiện trong bối cảnh lập trình có thể là đa hình.
Và có lẽ chúng ta nên đặt tên cho trường hợp đặc biệt của đa hình (hoặc thậm chí là đúc) trong đó với mục đích của chúng ta, các trường hợp đa hình khác nhau là tương đương về mặt ngữ nghĩa (trái ngược với chỉ là tương tự. Ví dụ, số 1 - có thể được biểu diễn sử dụng một loại số nguyên, hoặc một loại phức tạp hoặc bất kỳ loại nào khác - có thể được xử lý đa hình).
Tôi thấy định nghĩa về tính minh bạch tham chiếu trong cuốn sách " Cấu trúc và triển khai các chương trình máy tính " (Sách hướng dẫn) hữu ích vì nó được bổ sung bởi một lời giải thích về cách thức minh bạch tham chiếu bị vi phạm bằng cách giới thiệu hoạt động chuyển nhượng . Kiểm tra các boong trượt sau tôi đã thực hiện về chủ đề này: https://www.slideshare.net/pjschwarz/introducing-assignment-invalidates-the-substitution-model-of-evaluation-and-violates-referential-transparency-as- giải thích trong sicp-the-wizard-book
Tính minh bạch tham chiếu có thể được chỉ định đơn giản là:
Ví dụ, ngôn ngữ lập trình Haskell là ngôn ngữ chức năng thuần túy; có nghĩa là nó được minh bạch tham chiếu.