Как говорит Томас, теоретически просто добавить такую функцию к любому языку со статической типизацией (хотя это все еще большая работа).
Я не специалист по метапрограммированию, но @ SK-logic спрашивает, почему бы не использовать общую систему метапрограммирования во время компиляции, и я постараюсь ответить. Я не думаю, что вы можете легко добиться того, что вы можете сделать с поставщиками F # -типа, используя метапрограммирование, потому что поставщики F # -типа могут быть ленивыми и динамически интерактивными во время разработки. Давайте приведем пример, который Дон продемонстрировал в одном из своих предыдущих видео: провайдер типа Freebase . Freebase вроде схематизированной, программируемой википедии, она содержит данные обо всем. Таким образом, вы можете в конечном итоге написать код в соответствии с
for e in Freebase.Science.``Chemical Elements`` do
printfn "%d: %s - %s" e.``Atomic number`` e.Name e.Discoverer.Name
или еще много чего (точного кода у меня нет), но так же легко написать код, который получает информацию о статистике бейсбола, или когда известные актеры были в учреждениях реабилитации наркоманов, или миллионы других типов информации, доступных через Freebase.
С точки зрения реализации, невозможно создать схему для всей Freebase и перенести ее в .NET a-priori; Вы не можете просто сделать один шаг во время компиляции в начале, чтобы настроить все это. Вы можете сделать это для небольших источников данных, и на самом деле многие другие провайдеры типов используют эту стратегию, например, поставщик типов SQL указывает на базу данных и генерирует типы .NET для всех типов в этой базе данных. Но эта стратегия не работает для больших облачных хранилищ данных, таких как Freebase, потому что существует слишком много взаимосвязанных типов (если вы попытаетесь сгенерировать метаданные .NET для всех Freebase, вы обнаружите, что их так много миллионы типов (один из которых ChemicalElement
с AtomicNumber
и Discoverer
и Name
и многие другие поля, но есть буквально миллионы таких типов), которым требуется больше памяти, чем доступно для 32-разрядного Процесс .NET просто для представления всей схемы типов.
Таким образом, стратегия провайдера типов F # - это архитектура API, которая позволяет провайдерам типов предоставлять информацию по запросу, работая во время разработки в среде IDE. Пока вы не наберете, например, Freebase.Science.
, провайдеру типов не нужно знать о сущностях под научными категориями, но как только вы нажмете .
после Science
, провайдер типов может пойти и запросить API, чтобы узнать еще один уровень из общей схемы, чтобы знать, какие категории существуют в науке, одна из которых ChemicalElements
. И затем, когда вы попытаетесь «разбить» одну из них, она обнаружит, что элементы имеют атомные номера, а что нет. Таким образом, поставщик типов лениво выбирает достаточно всей схемы, чтобы иметь дело с точным кодом, который пользователь вводит в редактор в данный момент времени. В результате у пользователя все еще есть свобода исследовать любую часть вселенной информации, но любой один файл исходного кода или интерактивный сеанс будут исследовать только крошечную часть того, что доступно. Когда приходит время для компиляции / кодирования, компилятору нужно только сгенерировать достаточно кода, чтобы вместить именно те биты, которые пользователь фактически использовал в своем коде, а не потенциально огромные биты времени выполнения, позволяющие общаться со всем хранилищем данных.
(Может быть, вы можете сделать это с некоторыми современными средствами метапрограммирования, я не знаю, но те, о которых я узнал в школе давным-давно, не могли легко справиться с этим.)