Tại sao một số ngôn ngữ chức năng cần bộ nhớ giao dịch phần mềm?


24

Các ngôn ngữ chức năng, theo định nghĩa, không nên duy trì các biến trạng thái. Tại sao, sau đó, Haskell, Clojure và những người khác cung cấp triển khai bộ nhớ giao dịch phần mềm (STM)? Có mâu thuẫn giữa hai cách tiếp cận?


Tôi chỉ muốn liên kết bài báo thú vị này giải thích khá nhiều.
Falcon

1
Để rõ ràng, tất cả các ngôn ngữ chức năng duy trì trạng thái, nhưng độ tinh khiết chỉ ra rằng giá trị của một biến không thay đổi một khi nó được đặt.
Robert Harvey

Câu trả lời:


13

Không có gì sai với một ngôn ngữ chức năng duy trì trạng thái có thể thay đổi. Ngay cả các ngôn ngữ chức năng "thuần túy" như Haskell cũng cần duy trì trạng thái để tương tác với thế giới thực. Các ngôn ngữ chức năng "không tinh khiết" như Clojure cho phép các tác dụng phụ có thể bao gồm trạng thái đột biến.

Điểm chính là các ngôn ngữ chức năng không khuyến khích trạng thái có thể thay đổi trừ khi bạn thực sự cần nó . Kiểu chung là lập trình bằng cách sử dụng các hàm thuần túy và dữ liệu không thay đổi và chỉ tương tác với trạng thái có thể thay đổi "không trong sạch" trong các phần cụ thể của mã yêu cầu. Bằng cách đó, bạn có thể giữ phần còn lại của cơ sở mã của mình "thuần túy".

Tôi nghĩ rằng có một số lý do tại sao STM phổ biến hơn trong các ngôn ngữ chức năng:

  • Nghiên cứu : STM là một chủ đề nghiên cứu nóng và các nhà nghiên cứu ngôn ngữ lập trình thường thích làm việc với các langau chức năng (bản thân một chủ đề nghiên cứu, cộng với việc tạo ra "bằng chứng" về hành vi chương trình dễ dàng hơn)
  • Khóa không sáng tác : STM có thể được coi là một giải pháp thay thế cho các cách tiếp cận dựa trên khóa để đồng thời, nó bắt đầu gặp vấn đề khi bạn mở rộng quy mô lên các hệ thống phức tạp bằng cách soạn thảo các thành phần khác nhau. Đây được cho là lý do "thực dụng" chính cho STM
  • STM phù hợp với tính bất biến : Nếu bạn có cấu trúc bất biến lớn, bạn muốn chắc chắn rằng nó không thay đổi, vì vậy bạn không muốn một số luồng khác đến và biến đổi một số yếu tố phụ. Tương tự như vậy, nếu bạn có thể đảm bảo tính bất biến của cấu trúc dữ liệu đã nói, bạn có thể coi đó là một "giá trị" ổn định trong hệ thống STM của mình.

Cá nhân tôi thích cách tiếp cận của Clojure về việc cho phép tính đột biến, nhưng chỉ trong bối cảnh các "tài liệu tham khảo được quản lý" được kiểm soát chặt chẽ có thể tham gia vào các giao dịch STM. Tất cả mọi thứ khác trong ngôn ngữ là "hoàn toàn chức năng".

  ;; define two accounts as managed references
  (def account-a (ref 100))
  (def account-b (ref 100))

  ;; define a transactional "transfer" function
  (defn transfer [ref-1 ref-2 amount]
    (dosync
      (if (>= @ref-1 amount)
        (do 
          (alter ref-1 - amount)
          (alter ref-2 + amount))
        (throw (Error. "Insufficient balance!")))))

  ;; make a stranfer
  (transfer account-a account-b 75)

  ;; inspect the accounts
  @account-a
  => 25

  @account-b
  => 175

Lưu ý mã trên là hoàn toàn giao dịch và nguyên tử - một người quan sát bên ngoài đọc hai số dư trong một giao dịch khác sẽ luôn thấy trạng thái nguyên tử nhất quán, tức là hai số dư sẽ luôn đạt tới 200. Với đồng thời dựa trên khóa, đây là một vấn đề khó khăn đáng ngạc nhiên để giải quyết trong một hệ thống phức tạp lớn với nhiều thực thể giao dịch.

Để có thêm sự giác ngộ, Rich Hickey thực hiện công việc tuyệt vời để giải thích STM của Clojure trong video này


3

Theo định nghĩa, các ngôn ngữ chức năng không nên duy trì các biến trạng thái

Định nghĩa của bạn là sai. Ngôn ngữ không thể duy trì trạng thái đơn giản là không thể được sử dụng.

Sự khác biệt giữa các ngôn ngữ chức năng và mệnh lệnh không phải là một trong số chúng có trạng thái còn ngôn ngữ kia thì không. Đó là một cách họ duy trì nhà nước.

Ngôn ngữ bắt buộc có trạng thái lan truyền khắp chương trình.

Các ngôn ngữ chức năng cô lập và duy trì trạng thái rõ ràng thông qua chữ ký loại. Và đó là lý do họ cung cấp các cơ chế quản lý nhà nước tinh vi như STM.


2

Đôi khi một chương trình yêu cầu trạng thái có thể thay đổi (ví dụ: nội dung cơ sở dữ liệu cho ứng dụng web) và thật tuyệt vời khi có thể sử dụng nó mà không làm mất lợi ích của lập trình chức năng. Trong các ngôn ngữ phi chức năng, trạng thái có thể thay đổi thấm vào mọi thứ. Nếu bạn làm cho nó rõ ràng với một số loại API đặc biệt , thì bạn có thể giới hạn nó trong một khu vực nhỏ có thể xác định được trong khi mọi thứ khác vẫn hoàn toàn hoạt động. Lợi ích của FP bao gồm gỡ lỗi dễ dàng hơn, kiểm tra đơn vị lặp lại, đồng thời không đau và thân thiện với đa lõi / GPU.


Bạn có thể có nghĩa là trạng thái đột biến. Tất cả các chương trình duy trì nhà nước, ngay cả những chức năng.
Robert Harvey

Bạn đúng. Rõ ràng tôi không dành đủ thời gian để lập trình chức năng, đã bỏ lỡ điều đó.
Sẽ Ware
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.