2011-09-15 32 views
6

F # 3.0 đã thêm type providers.Thành ngữ/mô hình/tính năng ngôn ngữ nào làm cho việc thêm hỗ trợ cho "nhà cung cấp loại" trở nên khó khăn?

Tôi tự hỏi liệu có thể thêm tính năng ngôn ngữ này vào các ngôn ngữ khác chạy trên CLR như C# hoặc nếu tính năng này chỉ hoạt động tốt theo kiểu lập trình OO ít chức năng hơn?

+3

Nó sẽ là thú vị hơn để hỏi về các tính năng ngôn ngữ mà làm cho loại này dễ dàng hơn để thực hiện. Và câu trả lời là: lập trình meta thời gian biên dịch (như trong Lisp, MetaOCaml, Nemerle, Mẫu Haskell, v.v.). Tôi tự hỏi tại sao họ đã triển khai các nhà cung cấp kiểu như một nguyên thủy trong F #, thay vì cho phép một giải pháp chung chung hơn. Và điều metaprogramming này là hoàn toàn trực giao với OO, chức năng, bắt buộc, bất cứ điều gì, bạn có thể chơi trò chơi này với bất kỳ ngôn ngữ có thể. –

+0

@ SK-logic - Tôi nghĩ rằng các nhà cung cấp loại _are_ một dạng lập trình meta thời gian biên dịch. Bên cạnh đó, các giải pháp "tổng quát hơn" mà bạn khen ngợi cũng có bộ cân bằng riêng của họ. Ví dụ, MetaOCaml làm cho hệ thống kiểu phức tạp hơn bằng cách giới thiệu ý tưởng dàn dựng (và theo như tôi biết cho phép trích dẫn/nối/chỉ chạy các biểu thức, không phải định nghĩa kiểu). – kvb

+1

@kvb, vâng, chúng thực sự là một dạng lập trình meta thời gian biên dịch. Nhưng tôi muốn có một metaprogramming toàn diện thay vì một loạt các "hình thức" cụ thể của nó. Và, vâng, MetaOCaml không phải là lý tưởng - có nhiều cách để làm điều tương tự, dễ dàng hơn nhiều. –

Trả lời

7

Như Brian và Tomas đã chỉ ra, không có gì đặc biệt là "chức năng" về tính năng này. Nó chỉ là một cách đặc biệt khéo léo để cung cấp siêu dữ liệu cho trình biên dịch.

Đội ngũ thiết kế của C# đã khởi động các ý tưởng như thế này trong một thời gian dài. Đã có một đề xuất vài năm trước khi tôi gia nhập nhóm C# cho một tính năng được gọi là "loại bản thiết kế" (hoặc một cái gì đó tương tự), nhờ đó kết hợp các tài liệu XML, lược đồ XML và mã tùy chỉnh. được sử dụng bởi trình biên dịch C#. Tôi không nhớ lại chi tiết và nó không bao giờ thành hiện thực, rõ ràng. (Mặc dù nó đã ảnh hưởng đến thiết kế và việc triển khai Visual Studio Tools cho định dạng tài liệu Office, mà tôi đang làm việc vào thời điểm đó.)

Trong mọi trường hợp, chúng tôi không có kế hoạch trước mắt để bổ sung thêm tính năng C#, nhưng chúng tôi đang theo dõi với sự quan tâm lớn để xem liệu nó có phải là một công việc tốt trong việc giải quyết các vấn đề của khách hàng trong F # hay không.

(Như mọi khi, suy tưởng của Eric về các tính năng có thể tương lai của sản phẩm unnannounced và hoàn toàn giả chỉ nhằm mục đích giải trí.)

+0

cũng sẽ thú vị như thế nào nó hoạt động ra cho scala (siq) và gosu (ots) ... – soc

+0

Tôi sẽ nói rằng bạn hoàn toàn cần phải cải thiện mô hình biên dịch phụ thuộc. đây là tất cả quá tiềm ẩn, và không thể tổng hợp được. tôi đoán điều này cản trở rất nhiều sự tiến hóa tôi có thể tưởng tượng cho nền tảng của bạn. – nicolas

5

Tôi không thấy bất kỳ lý do kỹ thuật nào tại sao một số nhà cung cấp loại như không thể thêm vào C# hoặc các ngôn ngữ tương tự. Gia đình langauges duy nhất gây khó khăn cho việc thêm nhà cung cấp loại (theo cách tương tự như trong F #) là ngôn ngữ được nhập động.

Nhà cung cấp loại F # dựa vào thực tế là thông tin loại được tạo bởi nhà cung cấp độc đáo tuyên truyền thông qua chương trình và trình chỉnh sửa có thể sử dụng chúng để hiển thị IntelliSense hữu ích. Trong các ngôn ngữ được gõ động, điều này đòi hỏi sự hỗ trợ IDE phức tạp hơn (và "các nhà cung cấp kiểu" cho các langau động giảm xuống chỉ là IDE hoặc IntelliSense).

Tại sao chúng được triển khai trực tiếp dưới dạng tính năng của F #? Tôi nghĩ rằng hệ thống lập trình meta sẽ phải thực sự phức tạp (lưu ý rằng các loại không phải là thực sự là được tạo) để hỗ trợ điều này. Những thứ khác có thể được thực hiện bằng cách sử dụng nó sẽ không đóng góp cho ngôn ngữ F # nhiều (chúng sẽ chỉ làm cho nó quá phức tạp, đó là một điều xấu). Tuy nhiên, bạn có thể nhận được điều tương tự nếu bạn có một số loại mở rộng trình biên dịch.

Trong thực tế, tôi nghĩ rằng đây là cách # nhóm C sẽ thêm một cái gì đó giống như các nhà cung cấp loại trong tương lai (họ nói về trình biên dịch mở rộng trong một thời gian bây giờ).

+1

Tôi nghi ngờ rằng một hệ thống con lập trình meta có thể phức tạp. Trong thực tế, bất kỳ ngôn ngữ nào với một metaprogramming khá nhiều, đơn giản hơn nhiều so với một ngôn ngữ nguyên khối, vì nó cho phép xác định các tính năng ngôn ngữ trong một thư viện thay vì lõi của trình biên dịch. Ví dụ, xem ngôn ngữ cốt lõi của Nemerle nhỏ như thế nào. –

+0

Lập trình meta là không cần thiết cho điều đó. – soc

+1

@ SK-logic - hãy nhớ rằng phần meta của chương trình cần được gọi từ IDE, có thể với một số hạn chế bảo mật. Ngoài ra nó không thể chỉ "tạo ra" tất cả các loại từ http://www.programmableweb.com/, bởi vì nó sẽ không có đủ bộ nhớ cho điều đó. Nó cần phải tạo ra các loại lazily. Toàn bộ hệ thống meta vẫn sẽ phải biên dịch sang .NET mặc dù ... Tôi chắc rằng điều này sẽ phát triển nhiều hơn một phiên bản của F #. –

8

Như Tomas nói, về mặt lý thuyết thì việc thêm loại đối tượng địa lý này vào bất kỳ ngôn ngữ tĩnh nào (mặc dù vẫn còn rất nhiều công việc).

Tôi không phải là chuyên gia meta-lập trình, nhưng @ SK-logic hỏi tại sao không phải là một thời gian biên dịch hệ thống meta-lập trình nói chung thay vào đó, và tôi sẽ cố gắng trả lời. Tôi không nghĩ rằng bạn có thể dễ dàng đạt được những gì bạn có thể làm với các nhà cung cấp loại F # bằng cách sử dụng lập trình meta, bởi vì các nhà cung cấp kiểu F # có thể lười biếng và tương tác động tại thời điểm thiết kế. Hãy đưa ra một ví dụ mà Don có demo-ed trong một trong các video trước đó của mình: một nhà cung cấp loại Freebase. Freebase là loại giống như một wikipedia, có thể lập trình, nó có dữ liệu về mọi thứ. Vì vậy, bạn có thể kết thúc việc viết mã dọc theo dòng của

for e in Freebase.Science.``Chemical Elements`` do 
    printfn "%d: %s - %s" e.``Atomic number`` e.Name e.Discoverer.Name 

hoặc không có điều gì (Tôi không có mã ngay chính xác), nhưng chỉ cần một cách dễ dàng viết mã mà được thông tin về các thống kê bóng chày, hoặc khi diễn viên nổi tiếng có ở trong các cơ sở cai nghiện ma túy, hoặc một triệu loại thông tin khác có sẵn thông qua Freebase.

Từ một thực hiện point-of-view, nó là không khả thi để tạo ra một sơ đồ cho tất cả các Freebase và đưa nó vào NET một tiên nghiệm; bạn không thể chỉ thực hiện một bước biên dịch lúc bắt đầu để thiết lập tất cả điều này. Bạn có thể làm điều này cho các nguồn dữ liệu nhỏ và trên thực tế, nhiều nhà cung cấp loại khác sử dụng chiến lược này, ví dụ: một nhà cung cấp kiểu SQL được chỉ vào một cơ sở dữ liệu và tạo các kiểu .NET cho tất cả các kiểu trong cơ sở dữ liệu đó. Nhưng chiến lược này không không làm việc cho lưu trữ dữ liệu đám mây lớn như Freebase, bởi vì có quá nhiều loại liên quan đến nhau (nếu bạn đã cố gắng để tạo ra NET siêu dữ liệu cho tất cả các Freebase, bạn sẽ thấy rằng có rất nhiều triệu loại (một trong số đó là ChemicalElement với AtomicNumberDiscovererName và nhiều trường khác, nhưng có nghĩa là hàng triệu loại như vậy) mà bạn cần nhiều bộ nhớ hơn khả dụng cho quy trình .NET 32 bit chỉ để đại diện cho toàn bộ lược đồ loại.

Vì vậy, chiến lược F # type-provider là một kiến ​​trúc API cho phép các nhà cung cấp loại cung cấp thông tin theo yêu cầu, chạy vào thời gian thiết kế trong IDE. Cho đến khi bạn nhập, ví dụ: Freebase.Science., nhà cung cấp loại không cần phải biết về các thực thể thuộc danh mục khoa học, nhưng khi bạn nhấn . sau Science, thì nhà cung cấp loại có thể truy cập API để tìm hiểu thêm một cấp sơ đồ tổng thể, biết danh mục nào tồn tại trong Khoa học, một trong số đó là ChemicalElements. Và sau đó khi bạn cố gắng "chấm vào" một trong số đó, nó sẽ khám phá ra rằng các nguyên tố có số nguyên tử và cái gì không. Vì vậy, các nhà cung cấp loại lazily lấy đủ chỉ của lược đồ tổng thể để đối phó với mã chính xác người dùng sẽ xảy ra được gõ vào trình soạn thảo tại thời điểm đó trong thời gian. Kết quả là, người dùng vẫn có quyền tự do khám phá bất kỳ phần nào của vũ trụ thông tin, nhưng bất kỳ tệp mã nguồn hoặc phiên tương tác nào sẽ chỉ khám phá một phần nhỏ của những gì có sẵn. Khi biên dịch/codegen, trình biên dịch chỉ cần tạo mã đủ để chứa chính xác các bit mà người dùng đã thực sự sử dụng trong mã của mình, thay vì các bit thời gian chạy rất lớn để có khả năng nói chuyện với toàn bộ kho dữ liệu.

(Có lẽ bạn có thể làm điều đó với một số cơ sở vật chất meta-lập trình ngày nay bây giờ, tôi không biết, nhưng những cái tôi học được về trong trường một thời gian dài lại không thể nào dễ dàng xử lý này.)

+0

+1 để mô tả sự lười biếng :) – Ankur

+1

Tôi có hiểu chính xác rằng thông tin loại sẽ được tạo _only_ cho các loại được tham chiếu một cách rõ ràng trong mã không? Điều đó có nghĩa là đệ quy đi qua toàn bộ "vũ trụ dữ liệu" của bạn là không thể? – Daniel

+1

Các nhà cung cấp loại có thể chọn để làm những gì nó thích, nhưng trình biên dịch sẽ chỉ nhanh chóng nó với các thông số tĩnh của nó, và sau đó gọi vào nó theo yêu cầu. Vì vậy, ví dụ: nhà cung cấp SQLConnection trong hộp chỉ tạo ra toàn bộ lược đồ dưới dạng .Net kiểu lên phía trước, trong khi nhà cung cấp Freebase phải chờ cho đến khi trình biên dịch gọi nó theo yêu cầu để thực hiện một số lượng nhỏ công việc với mỗi cuộc gọi. – Brian

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