2009-04-29 16 views
6

Vì vậy, tôi hiện đang làm việc trên một ngôn ngữ lập trình mới. Lấy cảm hứng từ những ý tưởng từ lập trình đồng thời và Haskell, một trong những mục tiêu chính của ngôn ngữ là quản lý các tác dụng phụ. Nhiều hơn hoặc ít hơn, mỗi mô-đun sẽ được yêu cầu để xác định tác dụng phụ nào nó cho phép. Vì vậy, nếu tôi đang thực hiện một trò chơi, mô-đun đồ họa sẽ không có khả năng làm IO. Mô-đun đầu vào sẽ không có khả năng vẽ lên màn hình. Mô-đun AI sẽ được yêu cầu phải hoàn toàn thuần khiết. Các tập lệnh và plugin cho trò chơi sẽ có quyền truy cập vào một tập hợp con rất hạn chế của IO để đọc các tệp cấu hình. Vân vân.Tôi nên quản lý các tác dụng phụ trong thiết kế ngôn ngữ mới như thế nào?

Tuy nhiên, những gì cấu thành một tác dụng phụ không rõ ràng. Tôi đang tìm kiếm bất kỳ suy nghĩ hoặc đề xuất nào về chủ đề mà tôi có thể muốn xem xét bằng ngôn ngữ của mình. Đây là suy nghĩ hiện tại của tôi.

Một số tác dụng phụ là trắng trợn. Cho dù việc in ấn vào bảng điều khiển của người dùng hoặc khởi chạy tên lửa của bạn, bất kỳ hành động nào đọc hoặc ghi vào tệp do người dùng sở hữu hoặc tương tác với phần cứng bên ngoài đều là tác dụng phụ. Đây là những thứ như nhận được một số ngẫu nhiên, nhận được thời gian hệ thống, ngủ một sợi, thực hiện bộ nhớ giao dịch phần mềm, hoặc thậm chí một cái gì đó rất cơ bản như vậy như phân bổ bộ nhớ.

Không giống như các ngôn ngữ khác được xây dựng để kiểm soát các tác dụng phụ (nhìn vào bạn Haskell), tôi muốn thiết kế ngôn ngữ của tôi là thực dụng và thiết thực. Các hạn chế về tác dụng phụ phải phục vụ hai mục đích:

  • Để hỗ trợ trong việc phân tách các mối quan tâm. (Không một mô-đun nào có thể làm được mọi thứ).
  • Để sandbox từng mô-đun trong ứng dụng. (Bất kỳ mô-đun nào cũng có thể được sử dụng làm plugin)

Với điều này, tôi nên xử lý các hiệu ứng "giả" như số ngẫu nhiên và ngủ như tôi đã đề cập ở trên? Tôi có thể bỏ lỡ những gì khác? Tôi có thể quản lý việc sử dụng bộ nhớ và thời gian làm tài nguyên theo cách nào?

+0

+1 Wow. Tôi đã thực sự chỉ hỏi một câu hỏi tương tự. Tôi đang thiết kế một ngôn ngữ giống lai FP/OOP. – Zifre

Trả lời

0

Đưa ra giao diện nghiêm trọng cho Clojure và việc sử dụng chúng software transactional memory, agents, and atoms để giữ các tác dụng phụ được kiểm soát.

+0

Tôi sẽ thừa nhận tôi đã tẩy trang Clojure vào ngày đầu tiên họ thông báo trên Reddit. Tôi nghĩ ngôn ngữ thực sự rất tuyệt. Tôi muốn có được sự phát triển của họ, nhưng có điều gì đó về những ngôn ngữ đáng sợ mà tôi hoàn toàn không hấp dẫn. Tôi sẽ chắc chắn để kiểm tra những gì họ đã thực hiện tiến bộ kể từ đó cho những ý tưởng! –

+0

Tôi là loại tò mò những gì bạn đầy đủ không phải là pracgmatic và thực tế về Haskell. Đó là * khác nhau *, chắc chắn, bt có một chút phần mềm thực sự được viết trong đó. Bạn cũng có thể nhìn vào Erlang, mà chắc chắn là nhìn thấy sử dụng thực tế. –

+0

Hoặc bằng tiếng Anh, "những gì bạn cảm thấy không thực dụng và thực tế". –

1

Tác dụng phụ có ảnh hưởng đến bất kỳ thứ gì trên thế giới ngoài việc trả về một giá trị, tức là thay đổi thứ gì đó có thể hiển thị theo cách nào đó bên ngoài hàm.

Chức năng thuần túy không phụ thuộc vào hoặc ảnh hưởng đến bất kỳ trạng thái có thể thay đổi nào ngoài phạm vi yêu cầu hàm đó, điều đó có nghĩa là đầu ra của chức năng chỉ phụ thuộc vào hằng số và đầu vào của hàm. Điều này ngụ ý rằng nếu bạn gọi một hàm hai lần với cùng một đối số, bạn được bảo đảm nhận được kết quả tương tự cả hai lần, bất kể hàm được viết như thế nào.

Nếu bạn có chức năng sửa đổi biến mà nó đã được chuyển, sửa đổi đó là một tác dụng phụ vì nó có thể nhìn thấy đầu ra từ hàm khác với giá trị trả về. Một hàm void không phải là một no-op phải có các tác dụng phụ, bởi vì nó không có cách nào khác ảnh hưởng đến thế giới.

Chức năng có thể có biến riêng chỉ hiển thị với chức năng mà nó đọc và sửa đổi và gọi nó sẽ vẫn có tác dụng phụ thay đổi cách hoạt động của hàm trong tương lai. Là phương tiện thuần túy có chính xác một kênh cho đầu ra dưới bất kỳ hình thức nào: giá trị trả về.

Có thể tạo ra các số ngẫu nhiên hoàn toàn, nhưng bạn phải di chuyển xung quanh hạt giống ngẫu nhiên theo cách thủ công.Hầu hết các hàm ngẫu nhiên đều giữ giá trị hạt giống riêng được cập nhật mỗi khi được gọi để bạn nhận ngẫu nhiên khác nhau mỗi lần. Dưới đây là một Haskell Đoạn sử dụng System.Random:

randomColor    :: StdGen -> (Color, Int, StdGen) 
randomColor gen1   = (color, intensity, gen2) 
where (color, gen2)  = random gen1 
     (intensity, gen3) = randomR (1, 100) gen2 

Các chức năng ngẫu nhiên mỗi trả về giá trị ngẫu nhiên và một máy phát điện mới với một hạt giống mới (dựa trên một trước). Để có được một giá trị mới mỗi lần, chuỗi các máy phát điện mới (gen1, gen2, gen3) phải được truyền đi. Máy phát điện ngầm chỉ sử dụng biến nội bộ để lưu trữ giá trị gen1 .. ở chế độ nền.

Thực hiện việc này theo cách thủ công là một nỗi đau và trong Haskell bạn có thể sử dụng một đơn nguyên trạng thái để làm cho nó dễ dàng hơn nhiều. Bạn sẽ muốn thực hiện một cái gì đó ít tinh khiết hoặc sử dụng một cơ sở như monads, mũi tên hoặc các giá trị duy nhất để trừu tượng hóa nó đi.

Bắt thời gian hệ thống không rõ ràng vì thời gian có thể khác nhau mỗi khi bạn yêu cầu.

Ngủ mờ vì giấc ngủ không ảnh hưởng đến kết quả của hàm, và bạn luôn có thể trì hoãn thực hiện bằng vòng lặp bận và điều đó sẽ không ảnh hưởng đến độ tinh khiết. Vấn đề là ngủ được thực hiện vì mục đích khác, đó là một tác dụng phụ.

Phân bổ bộ nhớ bằng ngôn ngữ thuần túy phải xảy ra ngầm, vì phân bổ rõ ràng và giải phóng bộ nhớ là các tác dụng phụ nếu bạn có thể thực hiện bất kỳ loại so sánh con trỏ nào. Nếu không, việc tạo hai đối tượng mới với cùng các tham số sẽ vẫn tạo ra các giá trị khác nhau vì chúng sẽ có các định danh khác nhau (ví dụ: không bằng toán tử == của Java).

Tôi biết tôi đã đánh bạc một chút, nhưng hy vọng điều đó giải thích tác dụng phụ là gì.

+0

Tôi biết rõ tác dụng phụ là gì. Quan điểm của tôi là tác dụng phụ không được xác định hoàn toàn. Lưu ý rằng tôi đang nói nhiều hơn một chút so với định nghĩa Haskellesque mà bạn đã đưa ra ở trên. Ngôn ngữ của tôi sẽ KHÔNG thuần khiết. Điều này có nghĩa là việc gọi cùng một chức năng hai lần không bao giờ được đảm bảo là không có giá trị. Điều quan trọng đối với tôi trong thiết kế của tôi đơn giản là ngăn chặn các tác dụng phụ. Có một thế giới khác biệt giữa triết lý mọi giá trị và bất biến của Haskell và đơn giản là ngăn cản bất kỳ Joe cũ nào phóng tên lửa của mình. –

4

Vấn đề về cách mô tả và kiểm soát hiệu ứng hiện đang chiếm một số tâm trí khoa học tốt nhất trong ngôn ngữ lập trình, bao gồm những người như Greg Morrisett của Đại học Harvard. Theo hiểu biết của tôi, công việc tiên phong nhất trong lĩnh vực này được David Gifford và Pierre Jouvelot thực hiện bằng ngôn ngữ lập trình FX bắt đầu vào năm 1987. language definition là trực tuyến, nhưng bạn có thể hiểu rõ hơn về ý tưởng bằng cách đọc số 1991 POPL paper.

2

Đây là một câu hỏi thực sự thú vị, và nó đại diện cho một trong những giai đoạn tôi đã trải qua và, thẳng thắn, vượt ra ngoài.

Tôi nhớ các cuộc hội thảo, trong đó Carl Hewitt, khi nói về chủ nghĩa hình thức diễn viên của mình, đã thảo luận về điều này. Ông đã định nghĩa nó theo phương pháp đưa ra một phản ứng chỉ là một hàm của các đối số của nó, hoặc có thể đưa ra các câu trả lời khác nhau vào những thời điểm khác nhau.

Tôi nói rằng tôi đã vượt xa điều này vì nó làm cho chính ngôn ngữ (hoặc mô hình tính toán) là chủ thể chính, trái ngược với (các) vấn đề cần giải quyết. Nó dựa trên ý tưởng rằng ngôn ngữ nên có một mô hình cơ bản chính thức để các thuộc tính của nó dễ xác minh. Đó là tốt, nhưng vẫn còn một mục tiêu xa xôi, bởi vì vẫn không có ngôn ngữ (theo hiểu biết của tôi), trong đó tính chính xác của một thứ đơn giản như bong bóng là dễ dàng để chứng minh, hãy để một mình hệ thống phức tạp hơn.

Ở trên là mục tiêu tốt, nhưng hướng tôi đã đi là xem xét hệ thống thông tin theo lý thuyết thông tin. Cụ thể, giả định một hệ thống bắt đầu với một bộ các yêu cầu (trên giấy hoặc trong đầu của ai đó), các yêu cầu đó có thể được truyền tới một máy viết chương trình (cho dù là tự động hoặc con người) để tạo mã nguồn cho một thực thi làm việc. THÌ, khi các thay đổi xảy ra với các yêu cầu, các thay đổi được xử lý thông qua các thay đổi delta đối với mã nguồn thực hiện.

Sau đó, câu hỏi đặt ra là: Thuộc tính nào của mã nguồn (và ngôn ngữ được mã hóa trong) tạo thuận lợi cho quá trình này? Rõ ràng là tùy thuộc vào loại vấn đề đang được giải quyết, loại thông tin nào đi vào và ra (và khi), thông tin phải được lưu giữ trong bao lâu và cần xử lý loại nào. Từ này có thể xác định mức độ chính thức của ngôn ngữ cần thiết cho vấn đề đó.

Tôi nhận ra quá trình quây thông qua thay đổi đồng bằng của yêu cầu đối với mã nguồn được thực hiện dễ dàng hơn khi định dạng mã đến hơn giống với yêu cầu và có cách định lượng tốt để đo sự giống nhau này, chứ không phải trong các điều khoản của sự giống nhau bề ngoài, nhưng về mặt hành động chỉnh sửa. Công nghệ nổi tiếng thể hiện tốt nhất đây là các ngôn ngữ cụ thể của miền (DSL). Vì vậy, tôi đã nhận ra rằng những gì tôi tìm kiếm nhiều nhất trong một ngôn ngữ có mục đích chung là khả năng tạo ra các ngôn ngữ có mục đích đặc biệt.

Tùy thuộc vào ứng dụng, các ngôn ngữ chuyên dụng có thể có hoặc không cần các tính năng chính thức cụ thể như ký hiệu chức năng, kiểm soát tác dụng phụ, song song, v.v. Thực tế, có nhiều cách để tạo ngôn ngữ đặc biệt, từ phân tích cú pháp, diễn giải, biên dịch, xuống chỉ các macro bằng một ngôn ngữ hiện có, xuống để chỉ định nghĩa các lớp, các biến và các phương thức bằng một ngôn ngữ hiện có. Ngay sau khi bạn khai báo một biến hoặc chương trình con, bạn đã tạo ra từ vựng mới và do đó, một ngôn ngữ mới để giải quyết vấn đề của bạn. Trong thực tế, theo nghĩa rộng này, tôi không nghĩ rằng bạn có thể giải quyết bất kỳ vấn đề lập trình nào mà không cần, ở một mức độ nào đó, một nhà thiết kế ngôn ngữ.

Rất may mắn và tôi hy vọng nó sẽ mở ra khung cảnh mới cho bạn.

+0

Cảm ơn bạn đã trả lời. Tôi sẽ xem nếu tôi không thể đào bới bất cứ điều gì về các cuộc hội thảo của Carl Hewitt. Tôi sẽ không nói rằng ngôn ngữ chính là trọng tâm. Tôi thực sự không biết tôi sẽ viết loại ngôn ngữ nào. Tôi có thể sẽ tập trung vào việc viết một máy ảo thay vì một ngôn ngữ và sau đó đưa ra một ngôn ngữ demo đơn giản để thể hiện thành tích của nó. DSL và các mối quan tâm về năng suất ngôn ngữ không quan trọng lắm ở giai đoạn này (cuối cùng, nhưng chưa hoàn toàn!), Nhưng các mô hình luồng và bộ nhớ của tôi cực kỳ quan trọng. –

+0

Chúc may mắn. Đây là một sự khởi đầu: http://en.wikipedia.org/wiki/Carl_Hewitt Anh ấy là một anh chàng thông minh. –

Các vấn đề liên quan