Một ngữ nghĩa của một chương trình là một mô hình hành vi của nó, giống như bất kỳ mô hình khoa học nào, bỏ qua các khía cạnh mà bạn không muốn nghiên cứu.
Một mô hình cực kỳ chi tiết về việc thực hiện chương trình sẽ mô hình hóa hành vi vật lý của máy tính thực thi nó, bao gồm thời gian thực hiện, tiêu thụ năng lượng, bức xạ điện từ, v.v. Các khía cạnh như vậy rất hiếm khi được tính đến vì chúng rất hiếm khi liên quan. Tuy nhiên, đôi khi chúng có vấn đề: một mô hình hữu ích của máy bay tự động cần bao gồm thông tin thời gian chạy, một mô hình hữu ích về bảo mật của thẻ tín dụng cần bao gồm bức xạ điện từ, ...
Trong ngữ nghĩa điển hình, các tác dụng phụ như thời gian và tiêu thụ năng lượng bị bỏ qua. Ngay cả khi trong một cài đặt trần tục nơi bạn nhập một biểu thức tại dấu nhắc của trình thông dịch Haskell, việc in kết quả là một tác dụng phụ (nếu bạn cố in ra một đối tượng vô hạn, thì đó là vấn đề). Nếu trình thông dịch Haskell hết bộ nhớ, thì đây cũng là một hiệu ứng phụ có thể quan sát được trong mô hình thế giới thực của trực tuyến, nhưng không phải trong một mô hình lý tưởng của Haskell cho phép tính toán không bị ràng buộc.
Một tác dụng phụ có thể quan sát là một tác dụng được mô hình hóa trong ngữ nghĩa. Trong các mô hình điển hình của ngôn ngữ lập trình, mức tiêu thụ bộ nhớ không được mô hình hóa, do đó, một tính toán cần 1TB dung lượng lưu trữ có thể là thuần túy, ngay cả khi bạn cố chạy nó trên PC thì điều đó có thể thất bại.
Một loại tác dụng phụ không thể quan sát được là một tác dụng bên trong của chức năng. Tôi nghĩ, đây là điều mà hầu hết các nhà ngữ nghĩa học sẽ nghĩ đến khi nói về các tác dụng phụ không thể quan sát được. Xem xét một tính toán sử dụng dữ liệu có thể thay đổi trong nội bộ, nhưng không chia sẻ dữ liệu có thể thay đổi này với bất kỳ phần nào khác của chương trình. Ví dụ, một hàm sắp xếp danh sách xây dựng một mảng có các phần tử giống như danh sách, sắp xếp mảng đó và trả về một danh sách chứa các phần tử dưới dạng mảng theo thứ tự cuối cùng của chúng: một mô hình ngữ nghĩa của biểu thức con của hàm này thể hiện bên hiệu ứng (sửa đổi của mảng), nhưng bản thân hàm không có tác dụng phụ bên ngoài, vì vậy nó là thuần túy.
Đối với một ví dụ tinh tế hơn, hãy xem xét một hàm ghi một số dữ liệu vào một tệp tạm thời và tự dọn sạch sau đó. Trong một ngữ nghĩa nơi luôn có đủ chỗ cho các tệp tạm thời và các chương trình không chia sẻ các tệp tạm thời, chức năng này không có tác dụng phụ; tệp tạm thời đóng vai trò là bộ nhớ phụ được sử dụng bởi hàm. Trong một ngữ nghĩa có tính đến các điều kiện đầy đủ của hệ thống tập tin, hàm có tác dụng phụ - nó có thể bị lỗi do hoàn cảnh bên ngoài. Trong một ngữ nghĩa cho phép máy gặp sự cố, chức năng có tác dụng phụ: nếu có sự cố trong quá trình thực thi chức năng, tệp tạm thời có thể bị bỏ lại. Trong một ngữ nghĩa cho phép các chương trình được thực thi đồng thời nhìn thấy và có thể sửa đổi tệp tạm thời, hàm này có tác dụng phụ.