Привет! Представляю вашему вниманию перевод поста Стивена Вольфрама "The Wolfram Function Repository: Launching an Open Platform for Extending the Wolfram Language".
Предпосылки состоятельности языка Wolfram
Сегодня мы стоим на пороге великих свершений вместе с языком программирования Wolfram Language. Всего три недели назад мы запустили бесплатный движок Wolfram для разработчиков, чтобы помочь нашим пользователям интегрировать язык Wolfram Language в их масштабные программные проекты. Именно сегодня мы запускаем репозиторий функций Wolfram, для того чтобы предоставить скоординированную платформу для функций, созданных для расширения языка Wolfram, а также мы открываем репозиторий функций для каждого, кто может внести свой вклад в развитие нашего программного продукта.
Репозиторий функций (Function Repository) Wolfram — это то, что стало возможным благодаря уникальной специфике Wolfram Language не только как языка программирования, но и как полномасштабного вычислительного языка. В традиционных языках программирования добавление значительных новых функций обычно включает в себя создание целых дополнительных библиотек, которые могут работать или не работать при совместном использовании. Однако в языке Wolfram Language так много уже встроено в сам язык, что существует возможность значительно расширять его функциональность, просто добавляя новые функции, незамедлительно интегрирующиеся в целостную структуру всего языка.
Например, уже сейчас в репозитории функций Wolfram содержится 532 новых функции структурированных по 26 тематическим категориям:
Аналогично более чем 6000 стандартных функций, встроенным в язык Wolfram, каждая функция из репозитория имеет страницу документации с подробным их описанием и примерами работы:
Для перехода на страницу скопируйте приведенный выше объект (функциональный BLOB), вставьте его в строку ввода и затем запустите функцию – она уже встроена в язык Wolfram и поддерживается по умолчанию, начиная с версии 12.0:
Здесь следует отметить, что при обработке LogoQRCode Вам не нужно, например, настраивать «библиотеку для обработки изображений» — так как в языке Wolfram Language нами уже реализован последовательный и тщательно алгоритмизированный способ обработки изображений, которые незамедлительно могут быть обработаны различными графическими функциями языка:
Надеюсь, что при поддержке замечательного и талантливого сообщества, которое растет и расширяется (на базе языка Wolfram Language) на протяжении последних нескольких десятилетий. Репозиторий функций Wolfram позволит в обозримом будущем значительно расширить диапазон (возможно потенциально значительных, специализированных в различных областях знаний науки и техники) функций, доступных в языке. Таким образом, появляется возможность использовать как содержание языка (его встроенные функции), так и принципы развития, которые реализуются на базе языка. (Здесь следует отметить, что Wolfram Language имеет уже более чем 30-летнюю историю развития и стабильного роста).
Внутри функций из репозитория могут быть небольшие или достаточно объемные фрагменты кода, написанного на языке Wolfram Language. Например, это могут быть вызовы внешних API и сервисов или внешних библиотек на других языках. Уникальной особенностью данного подхода является то, что, когда Вы переходите к функциональности на уровне пользователя, будут отсутствовать возможные нестыковки по причине того, что данный подход построен на базе согласованной структуры языка Wolfram Language — и каждая функция автоматически будет работать правильно — именно так, как ей и надлежит.
Оболочка и программная структура репозитория функций Wolfram настроены таким образом, чтобы каждый мог внести свой вклад в общее дело максимально простым и удобным для него путем — по сути, просто заполнив текстовый файл блокнота (с расширением nb) WL. Встроенные автоматические функции позволяют выполнять проверку новых добавляемых в репозиторий функций с целью их гарантированной интеграции в язык. Наша компания делает ставку на обширный круг пользователей, которые могут интегрировать свои функции в язык, а не на большие сложности новых функций — и хотя здесь реализован процесс проверки, мы не настаиваем на чем — то вроде кропотливого анализа конструкции или строгих стандартов полноты и надежности новых функций пользователей, в отличие от более тщательных проверок функций, встроенных в ядро языка, которые мы применяем.
В данном подходе существует множество компромиссов и деталей, но наша цель состоит в том, чтобы оптимизировать репозиторий функций Wolfram как для удобства пользователей, так и для того, чтобы новые функции пользователей давали ощутимый вклад в развитие языка. По мере роста, я не сомневаюсь, что нам придется изобретать новые методы обработки и проверки встраиваемых в репозиторий функций, и это не в последнюю очередь для организации большого количества функций и поиска тех, которые нужны пользователям. Однако, не может не обнадеживать то, что выбранный нами путь — это хорошее начало. Я собственноручно добавил несколько функций в первоначальную базу. Многие из них основаны на коде, который я лично разрабатывал в течение достаточно долгого времени. И я затратил всего несколько минут, чтобы переслать их в репозиторий. Теперь, когда они находятся в репозитории, я могу наконец – незамедлительно и в любое время использовать данные функции по мере необходимости, не беспокоясь при этом о поиске файлов, загрузке пакетов и т. п.
Повышение эффективности при снижении затрат
Еще до появления в Интернета существовали способы обмениваться кодом Wolfram Language (нашим первым крупным централизованным проектом был MathSource, созданный для Mathematica в 1991 году на базе CD-ROM и т. п.). Безусловно, предлагаемый к реализации подход на базе репозитория функций Wolfram является более мощным и надежным средством для реализации вышеперечисленных задач.
Более 30 лет наша компания усердно работала над поддержанием целостности структуры языка Wolfram, и это очень важно для того, чтобы язык Wolfram стал не просто языком программирования, но и полноценным вычислительным языком. И таким образом, суть подхода к реализации репозитория функций Wolfram — это использование единого подхода к программированию и разработке новых функций, которые последовательно добавляются и вписываются в рамки языка для возможности его развития и совместной эволюции.
В структуре реализации каждой функции происходят различные вычислительные процессы. Здесь следует отметить, что при этом необходимо, чтобы для пользователя функция имела четкий и однообразный вид и наглядную читаемость. В данном контексте встроенные функции языка Wolfram Language представлены более чем 6000 последовательных примеров того, как надлежит правильно программировать функции (это наши видеообзоры по программированию в прямом эфире, которые включают сотни часов процесса создания типовых программ). Этот подход в конечном итоге позволяет делать репозиторий функций Wolfram способным к хорошей работе, именно структурный характер языка Wolfram Language с его большим количеством дополнительных и разнообразных библиотек, которые уже встроены в язык. Например, если у Вас есть функция, обрабатывающая изображения, или разреженные массивы, или молекулярные структуры, а также географические данные или какие-то другие — в языке уже существует их согласованное символьное представление, и благодаря этому Ваша функция сразу же становится совместимой с другими функциями в языке.
Создание репозитория, который бы действительно хорошо работал, является интересной задачей мета-программирования. Например, избыток ограничений в программе не сможет позволить получить требуемую унификацию и универсальность работы алгоритма. Так же, как и при недостаточном количестве функциональных ограничений Вы не сможете реализовать достаточно правильную последовательность выполнения алгоритма. Несколько предыдущих примеров реализации компромисса данных подходов, реализованных нашей компанией, сработали достаточно стабильно — это: Проект Вольфрам Демонстрации, запущенный в 2007 году и теперь работающий в интерактивном режиме в сети Интернет и содержащий более 12000 пользовательских интерактивных демонстраций. В базе данных Wolfram имеется более 600 готовых баз данных, которые можно использовать в языке Wolfram Language, а хранилище нейронных сетей Wolfram пополняется новыми нейронными сетями практически каждую неделю (сейчас их уже 118) и они сразу же подключаются через функцию NetModel в языке Wolfram Language.
Все вышеперечисленные примеры имеют принципиальную особенность — собираемые в проект объекты и функции имеют очень высокую степень структурирования и распределения процессов. Безусловно, детализация структуры того, что является демонстрацией или нейронной сетью или чем-то другим, могут сильно различаться, но фундаментальная структура для любого текущего репозитория всегда остается неизменной. Так какое же Ваше мнение, уважаемый пользователь, по поводу создании такого репозитория, который добавляет расширения к языку Wolfram? Язык Wolfram Language спроектирован таким образом, чтобы быть чрезвычайно гибким, поэтому его можно расширять и видоизменять любым способом. Данное обстоятельство является чрезвычайно важным для возможности быстро создавать различные крупномасштабные программные проекты на языке Wolfram Language. Здесь следует отметить, что с ростом гибкости языка неизбежно возрастет и стоимость проектов, реализуемых на таком языке. Это происходит по причине того, что чем больше пользователь применяет такой язык, тем больше он получает выделенной функциональности, но не следует забывать, что данный подход может иметь и негативные стороны в части невозможности обеспечения последовательной согласованности программных модулей.
В традиционных языках программирования существует распространенная проблема с библиотеками — если Вы, например, используете одну библиотеку, то код работает корректно, но, если Вы попытаетесь использовать несколько библиотек, нет гарантии, что они будут корректно взаимодействовать друг с другом. Также в традиционных языках программирования — в отличие от полноценного языка вычислений – отсутствуют возможности гарантировано контролировать наличие согласованных встроенных представлений, для каких-либо функций или типов данных, кроме их базовых структур. Но, по сути, проблема еще больше, чем представляется на первый взгляд: если кто-то строит крупномасштабную вертикаль функциональности, то без огромных затрат по централизованному программированию проекта, которые мы вложили в язык Wolfram, невозможно достичь согласованности. Поэтому важным является то, чтобы все программные модули всегда корректно работали совместно.
Таким образом, идея репозитория функций Wolfram состоит в том, чтобы избежать проблемы, озвученной выше — просто добавляя расширения к языку в виде сравнительно небольших элементов программного кода посредством отдельных функций, разработка которых в виде согласованных модулей является более простой задачей. При этом существуют особенности программирования, которые невозможно сделать удобными при помощи отдельных функций (и наша компания в ближайшем будущем собирается выпустить оптимизированный программный алгоритм для помощи в реализации крупномасштабных программных пакетов). Однако, на базе уже встроенных в язык Wolfram Language функций, существует множество возможностей для программирования, которые реализованы на базе отдельных функций. Здесь мысль заключается в том, чтобы при сравнительно небольших программных усилиях можно было создать ряд новых и очень полезных функций, которые обеспечат достаточную согласованность проекта, при этом они будут хорошо согласованы друг с другом, а также, помимо этого, они будут иметь возможность легко и широко использоваться в языке в дальнейшем.
Данный подход, безусловно, является компромиссом. При условии реализации более масштабного пакета можно вообразить себе совершенно новый мир функциональности, который станет чрезвычайно мощным и полезным. В случае если существует необходимость получать новые функциональные возможности, которые будут вписываться во все остальное, но при этом Вы не готовы тратить огромные усилия на разработку проекта, это, к сожалению, может привести к снижению масштаба Вашего проекта. Идея репозитория функций Wolfram заключается в том, чтобы обеспечить функциональностью определяющую часть проекта, данный подход позволит добавить мощный функционал, вместе с тем, упрощая поддержание хорошей согласованности проекта программирования.
Помощь при добавлении пользовательских функций в репозиторий функций
Специалисты нашей компании упорно работали над тем, чтобы сделать свой вклад в функции репозтитория Wolfram достаточно легким для пользователей. На рабочем столе (уже в версии 12.0), Вы можете просто последовательно перейти по вкладкам основного меню: File > New > RepositoryItem > Function Repository Item и Вы получите «Definition Notebook» (программно внутри рабочей среды. Вы можете также использовать функцию аналог — CreateNotebook["FunctionResource"]):
Существуют два основных действия, которые Вы должны будете выполнить: во-первых, фактически записать код Вашей функции и, во-вторых, записать документацию, иллюстрирующую, как должна работать Ваша функция.
Нажмите кнопку «Открыть образец» вверху, чтобы увидеть пример того, что Вам нужно сделать:
Фактически, Вы пытаетесь создать нечто похожее на встроенную функцию в языке Wolfram Language. За исключением того, что она может делать что-то гораздо более конкретное, чем встроенная функция. При этом ожидания относительно ее полноты и надежности будут намного ниже.
Вам необходимо задать имя для Вашей функции, которое будет соответствовать принципам именования функций Wolfram Language. Кроме этого Вам понадобится разработать документацию для Вашей функции, по аналогии со встроенными функциями языка. Более подробно я расскажу об этом позже. Сейчас просто обратите внимание на то, что в ряду кнопок в верхней части файла блокнота определений есть кнопка «Рекомендации по стилю», в которой объясняется, что делать, и кнопка «Инструменты», которая предоставляет инструментарий для форматирования документации Вашей функции.
Когда Вы убедитесь, что все заполнено должным образом и Вы готовы, нажмите кнопку «Check» («Проверить»). Совершенно нормальным является то, что Вы еще не разобрались во всех деталях. Поэтому функция «Check» будет автоматически выполняться и делать много проверок стиля и согласованности. Часто она сразу же предложит Вам подтвердить и принять исправления (Например: «Эта строка должна заканчиваться двоеточием», и она предложит ввести двоеточие). Иногда она попросит Вас добавить или изменить что-то самостоятельно. Мы будем постоянно добавлять новые возможности к автоматической функциональности кнопки «Check», но в основном его цель состоит в том, чтобы гарантировать — все, что вы отправляете в репозиторий функций, уже точно соответствует как можно большему количеству рекомендаций по стилю
Итак, после запуска «Check» вы можете использовать «Preview» («Предпросмотр»). «Preview» создает предварительный просмотр страницы документации, которую Вы определили для своей функции. Вы также можете создать предварительный просмотр для файла, созданного на Вашем компьютере или для файла, находящегося в облачном хранилище. Если Вас, по каким-то причинам, не устраивает то, что Вы увидите в предварительном просмотре, просто вернитесь назад и выполните необходимые исправления, а затем снова нажмите кнопку Preview.
Теперь Вы готовы разместить свою функцию в репозитории. Кнопка Deploy предоставляет Вам четыре варианта действий:
На данном шаге важным является то, что Вы можете отправить свою функцию в репозиторий функций Wolfram, для того чтобы она была доступна любому пользователю. При этом Вы также можете разместить свою функцию, для ограниченного количества пользователей. Например, Вы можете создать функцию, размещенную локально на Вашем компьютере, таким образом, чтобы она была доступна, когда Вы используете данный конкретный компьютер. Или Вы можете разместить ее в своей облачной учетной записи, чтобы она была доступна Вам, когда Вы подключены к облаку. Вы также можете публично разместить (развернуть) функцию через свою облачную учетную запись. При этом ее не будет в центральном репозитории функций Wolfram, но вы сможете дать кому-нибудь URL-адрес, который позволит им получить Вашу функцию из Вашей учетной записи. (В будущем мы также будем поддерживать центральные репозитории в масштабах всей нашей компании).
Итак, допустим, Вы хотите фактически передать свою функцию в базу знаний функций Wolfram. Для этого Вы нажимаете кнопку "Отправить" в репозиторий. Так что же тогда происходит в данный момент? Ваша заявка сразу же попадает в очередь для рассмотрения и утверждения нашей специальной командой кураторов.
По мере того, как Ваша заявка проходит через процесс согласования (который обычно занимает несколько дней), Вы будете получать сообщения о состоянии ее рассмотрения, а также, возможно, предложения по ее дальнейшему использованию. Но как только ваша функция будет одобрена, она будет немедленно опубликована в репозитории функций Wolfram и станет доступной для любого использования. (И это будет отображаться в дайджестах новостей новых функций и т. д.)
Что же должно быть в хранилище?
Следует отметить, что в нашей компании очень высокие стандарты полноты, надежности и общего качества, из 6000+ функций, которые мы уже встроили в язык Wolfram за последние 30 с лишним лет все соответствуют вышеперечисленным требованиям. Цель репозитория функций Wolfram заключается в том, чтобы использовать всю структуру и функциональные возможности, которые уже существуют в языке Wolfram Language, для того чтобы добавить как можно больше гораздо более легких функций (то есть функций с более высокой производительностью).
Безусловно, функции в репозитории функций Wolfram должны соответствовать принципам разработки языка Wolfram Language — чтобы они могли полноценно взаимодействовать с другим функциям и ожиданиям пользователей относительно того, как функции надлежит правильно работать. Однако при этом функции не должны иметь одинаковую полноту или надежность.
Во встроенных функциях языка Wolfram, мы упорно работаем над тем, чтобы сделать программные функции как можно более общими. При этом при нахождении в репозитории функций Wolfram нет ничего плохого в том, чтобы в него попала функция, которая просто обрабатывает какой-то очень конкретный, но полезный случай. Например, функция SendMailFromNotebook может получать файлы в одном определенном формате и создавать почту одним определенным способом. PolygonalDiagram создает диаграммы только с определенными цветами и маркировкой и т. д.
Еще одним моментом, связанным со встроенными функциями, является то, что наша компания прилагает все усилия для обработки всех нетиповых случаев, для правильной обработки некорректного ввода и так далее. В репозитории функций совершенно нормальным является случай, когда в нем существует специальная функция, которая обрабатывает основные случаи решения задачи и игнорирует все остальные.
Очевидным является тот факт, что лучше иметь функции, которые делают больше, и делают это лучше, но оптимизация для репозитория функций — в отличие от встроенных функций языка Wolfram — должна иметь больше функций, перевязанных с большим количеством функций, нежели углубляться в процессы реализации каждой конкретной функции.
Теперь давайте рассмотрим пример тестирования функций в репозитории. Ожидания согласованности для таких функций естественно гораздо ниже, чем для встроенных функций языка. Это тем более актуально в случаях, когда функции зависят от внешних ресурсов, таких как API, важно постоянно проводить последовательные тесты, что автоматически происходит внутри алгоритмов проверки. В файле nb вы можете явно указать определения (в разделе «Дополнительная информация») и задать столько тестов, определяемых либо строками ввода и вывода, либо полными символьными объектами типа VerificationTest, сколько посчитаете нужным. Кроме того, система постоянно пытается превратить приведенные Вами примеры документации в процесс проверки (при этом иногда это может быть довольно ресурсоемко, например, для функции, результат которой зависит от случайных чисел или времени суток).
В итоге в репозитории функций будет целый ряд сложностей реализации. Некоторые будут просто одной строкой кода, другие могут включать тысячи или десятки тысяч строк, вероятно с использованием множества вспомогательных функций. В каких случаях стоит добавить функцию, для определения которой требуется очень мало кода? В принципе, если для функции есть хорошее мнемоническое название, которое пользователи с готовностью поняли бы, увидев это в части кода, то ее уже можно добавить. В противном случае, вероятно, лучше просто снова дописать к Вашей программе код каждый раз, в тех случаях, когда Вам нужно его использовать.
Основная цель репозитория функций (как следует из его названия) состоит в том, чтобы вводить в функционал языка новые функции. Если Вы хотите добавить новые данные или новые сущности, используйте репозиторий Wolfram Data. Но что делать, если Вы хотите ввести новые виды объектов для Ваших вычислений?
На самом деле есть два пути. Возможно, Вы захотите ввести новый тип объекта, который будет использоваться в новых функциях в репозитории функций. И в этом случае Вы всегда можете просто записать его символьное представление и использовать его при вводе или выводе функций в репозитории функций.
Но что делать, если Вы хотите представить объект, а затем определить, через существующие функции в языке Wolfram Language, которые должны работать вместе с ним? Для этого у Wolfram Language всегда был легкий механизм, который называется UpValues. С некоторыми ограничениями (особенно для функций, которые не могут оценивать свои аргументы), репозиторий функций позволяет Вам просто представить функцию и определить значения для нее. (Чтобы повысить ожидание согласованности при создании новой важной конструкции, полностью интегрированной везде в языке Wolfram Language, — это, как правило, очень важная процедура, которая не может быть достигнута только с помощью повышения стоимости проекта и это то, что наша компания делает в рамках проектов долгосрочного развития языка, данная задача не является целью, которая ставится в рамках развития репозитория).
Итак, что же может быть в коде функций в репозитории функций? Все, что встроено в язык Wolfram Language, конечно (по крайней мере, если это не представляет угрозы для безопасности и работоспособности самой программы, как вычислительной среды) также как и любая функция из репозитория функций. При этом существуют и другие возможности функционирования: функция в репозитории функций может вызывать API, либо в Wolfram Cloud, либо из другого источника. Конечно, существуют некоторые риски, связанные с этим. По причине того, что отсутствуют гарантии, что API не изменится, а функция в хранилище функций при этом перестанет работать. Для выявления подобных проблем существует примечание на странице документации (в разделе «Требования») для любой функции, которая опирается не только на встроенную функциональность Wolfram Language. (Конечно, когда речь идет о реальных данных, могут быть проблемы даже с такой функциональностью — потому что реальные данные о мире постоянно меняются, а иногда даже меняют их определения и структура.)
Должен ли весь код для репозитория функций Wolfram быть написан на языке Wolfram? Определенно, код внутри внешнего API не должен быть написан на языке Wolfram, что собственно даже не делает код языка. На самом деле, если Вы найдете функцию практически на любом внешнем языке или библиотеке, вы сможете создать оболочку, которая позволит использовать ее в репозитории функций Wolfram. (Обычно для этого следует использовать встроенные функции ExternalEvaluate или ExternalFunction в коде языка Wolfram.)
Так какой же смысл делать это? По сути, это позволяет использовать всю интегрированную систему Wolfram Language и весь ее унифицированный набор программных возможностей. В случае если Вы получаете базовую реализацию из внешней библиотеки или языка, то затем Вы можете использовать богатую символьную структуру языка Wolfram Language для создания удобной функции верхнего уровня, которая позволяет пользователям достаточно легко использовать любую уже реализованную функциональность. По крайней мере, это должно иметь возможность реализации в идеальном мире, где существуют все составные элементы загрузки библиотек и т. п., в данном случае они будут автоматически решаться с помощью Wolfram Language. (Следует отметить, что на практике могут возникнуть проблемы с настройкой внешних языков в конкретной компьютерной системе, а в облачном хранилище могут возникнуть дополнительные проблемы с безопасностью).
Кстати, когда вы первый раз анализируете типовые внешние библиотеки, они часто кажутся слишком сложными, чтобы их можно было охватить лишь несколькими функциями, но во многих случаях большая часть сложности возникает из-за создания инфраструктуры, необходимой для библиотеки, и всех функций для ее поддержки. Однако при использовании языка Wolfram Language, инфраструктура, как правило, уже встроена в пакеты, и поэтому не нужно подробно раскрывать все эти функции поддержки, а нужно лишь создать функции для нескольких «самых верхних» функций, ориентированных на приложение в библиотеке.
«Экосистема» базы знаний
Если Вы написали функции, которые используете постоянно, то отправьте их в репозиторий функций Wolfram! Если из этого в итоге не получится что-то большее (развитие языка), то и тогда Вам будет гораздо удобнее использовать функции для личного пользования. Однако логично предположить, что, если Вы используете функции постоянно, возможно и другие пользователи также найдут их полезными.
Естественно, что Вы можете оказаться в ситуации, когда вы не имеете возможности — или не хотите — делиться своими функциями или в случае получения доступа к частным информационным ресурсам. Даже в таких случаях Вы можете просто развернуть функции в своей собственной учетной записи в облаке, указав права доступа к ним. (Если в Вашей организации есть частное облако Wolfram Enterprise, то вскоре оно сможет разместить собственный частный репозиторий функций, который можно администрировать из Вашей организации и устанавливать принудительный просмотр представлений или нет для сторонних пользователей.)
Функции, которые Вы отправляете в репозиторий функций Wolfram, не обязательно должны быть идеальными; они просто должны быть полезными. Это немного похоже на раздел «Ошибки» в классической документации Unix — в «Разделе определений» есть раздел «Заметки автора», в котором Вы можете описать ограничения, проблемы и т. п., о которых Вы уже знаете о своей функции. Кроме того, когда вы отправляете свою функцию в репозиторий, Вы можете добавить примечания к отправке, которые будут прочитаны специальной командой кураторов.
После публикации функции ее страница всегда имеет две ссылки внизу: «Отправить сообщение об этой функции» и «Обсудить в сообществе Wolfram». Если Вы прикрепляете пометку (например, сообщать мне об ошибках), Вы можете установить флажок, в котором говорится, что вы хотите, чтобы Ваше сообщение и контактная информация были переданы автору функции.
Иногда возникает необходимость просто использовать функции из репозитория функций Wolfram, например встроенные функции, не заглядывая в их код. Однако если вы хотите «заглянуть внутрь», в верхней части всегда есть кнопка «Блокнот». Нажмите на нее, и Вы получите собственную копию оригинальной тетради определения, которая была отправлена в репозиторий функций. Иногда Вы можете просто использовать ее в качестве примера для своих нужд. При этом Вы также можете разработать Вашу собственную модификацию данной функции. Возможно, Вы захотите разместить эти найденные Вами функции из репозитория на своем компьютере или в своей учетной записи в Вашем облачном хранилище тли, может быть, Вы захотите отправить их в базу знаний функций, возможно, в качестве улучшенной, дополненной версии исходной функции.
В будущем мы планируем поддерживать разветвление в стиле Git для репозиториев функций, но сейчас мы стараемся сделать это проще, и у нас всегда есть только одна общепринятая версия каждой функции, встроенной в язык. Чаще всего (если разработчики не отказываются от поддержания разработанных ими функций и отвечают на сообщения пользователей), первоначальный автор функции получает контроль над обновлениями к ней и отправляет новые версии, которые затем проверяются и, если проходят процесс проверки, публикуются в языке.
Рассмотрим вопрос, как работает «версионность» разработанных функций. Прямо сейчас, когда Вы используете функцию из репозитория функций, ее определение будет постоянно храниться на вашем компьютере (или в вашей облачной учетной записи, если вы используете облако). Если появилась новая версия функции, то при следующем ее использовании вы получите сообщение, извещающее Вас об этом. И если Вы хотите обновить функцию до новой версии, Вы можете сделать это с помощью команды ResourceUpdate. («Функциональный BLOB-объект» на самом деле хранит больше информации о версиях, и в будущем мы планируем сделать это более доступным для наших пользователей.)
Одной из прекрасных особенностей репозитория функций Wolfram является то, что любая программа Wolfram Language в любом месте может использовать функции из него. Если программа появляется в блокноте, часто бывает удобно отформатировать функции репозитория в виде функций легко читаемых «функциональных двоичных объектов» (возможно, с соответствующим набором версий).
Вы всегда можете обратиться к любой функции репозитория функций, используя текстовую ResourceFunction [...]. И это очень удобно, если Вы пишете код или сценарии непосредственно для Wolfram Engine, например, с помощью IDE или текстового редактора кода (cледует особо отметить, что репозиторий функций полностью совместим с Free Wolfram Engine для разработчиков).
Как это работает?
Внутри функций в репозитории Wolfram это возможно с использованием точно такой же системы ресурсов базы, как и во всех других наших существующих репозиториях (хранилище данных, Neural Net Repository, коллекция демонстрационных проектов и т.д.), как и все остальные системные ресурсы Wolfram, ResourceFunction в конечном счете основан на функции ResourceObject.
Рассмотрим ResourceFunction:
Внутри Вы можете увидеть некоторую информацию, используя функция Information:
Как работает настройка функции ресурса? Самый простой — это чисто локальный случай. Вот пример, который берет функцию (в данном случае просто чистую функцию) и определяет ее как функцию ресурса для данного сеанса работы в программе:
После того как Вы сделали определение, вы можете использовать функцию ресурса:
Обратите внимание, что в этом BLOB-объекте функции есть черный значок . Это означает, что BLOB-функция относится к функции ресурсов в памяти, определенной для текущего сеанса. Для функции ресурса, которая постоянно хранится на Вашем компьютере или в облачной учетной записи, есть серый значок . А для официальной функции ресурса в репозитории функций Wolfram есть оранжевый значок .
Итак, что происходит, когда вы используете меню «Развертывание» в блокноте определения? Во-первых, он берет все определения в блокноте и из них создает символьный ResourceObject). (А если Вы используете текстовую IDE или программу, то тогда Вы также можете явно создать ResourceObject)
Локальное развертывание функции из репозитория на Вашем компьютере выполняется при помощи команды LocalCache для объекта ресурса, чтобы сохранить его как LocalObject в Вашей файловой системе. Развертывание в облачной учетной записи выполняется при помощи команды CloudDeploy для объекта ресурса, а публичное развертывание в облаке — CloudPublish. Во всех случаях ResourceRegister также используется для регистрации имени функции ресурса, так что ResourceFunction["name"] будет работать.
Если нажать кнопку Submit для Function Repository, то, что под ним происходит ResourceSubmit вызывается на объект ресурса. (И если Вы используете текстовый интерфейс ввода, Вы также можете вызвать ResourceSubmit напрямую.)
По умолчанию отправка выполняется под именем, связанным с вашим идентификатором Wolfram ID. Но если вы отправляете заявку от имени группы разработчиков или организации, Вы можете установить отдельный идентификатор издателя и вместо этого использовать его в качестве имени для взаимодействия с Вашими представлениями.
После того, как Вы отправили любую Вашу функций в базу знаний функций, оно попадет в очередь на проверку. Если Вы получите комментарии в ответ, они обычно будут в форме текстового файла с добавленными дополнительными «ячейками комментариев». Вы всегда можете проверить статус своей заявки, зайдя на портал участника системы ресурсов. Но как только Ваша функция будет одобрена, Вы будете уведомлены (по электронной почте), и Ваша функция будет размещена в репозитории функций Wolfram.
Некоторые тонкости в работе
На первый взгляд может сложиться впечатление, что можно просто взять блокнот определения и дословно поместить его в репозиторий функций, однако, на самом деле есть довольно много тонкостей — и для их обработки требуется выполнить довольно сложное мета-программирование, символьное обрабатывая как код, определяющий функцию, так и сам Блокнот определения. Большая часть этого происходит внутри, то есть «за кадром», но это может иметь некоторые последствия, которые стоит понять, если Вы собираетесь внести свой вклад в базу знаний функций.
Первая непосредственная тонкость: Когда Вы заполняете «Блокнот определений», Вы можете просто ссылаться на свою функцию везде, используя имя, подобное MyFunction, которое выглядит как обычное имя для функции в языке Wolfram Language, но для документации репозитория функций это заменяется ResourceFunction["MyFunction"] – это именно то, что пользователи фактически будут использовать при работе с функцией.
Вторая тонкость: когда вы создаете функцию ресурса из Блокнота определения, то все зависимости, вовлеченные в определение функции, должны быть зафиксированы и явно включены. Однако чтобы гарантировать, что определения остаются модульными, нужно поместить все в уникальное пространство имен. (Разумеется, что функции, которые делают все это, находятся в репозитории функций.)
Обычно Вы никогда не увидите никаких следов работы кода, используемого для настройки этого пространства имен. Но если по какой-то причине Вы вызовите недовыполненный символ внутри вашей функции, то вы увидите, что этот символ находится во внутреннем контексте функции. Однако при обработке Блокнота определения, по меньшей мере, символ, соответствующий самой функции, настраивается для наилучшего отображения в виде функционального BLOB, а не необработанного символа во внутреннем контексте.
Репозиторий функций предназначен для определения новых функций. И эти функции могут иметь опции. Часто эти параметры (например, Method или ImageSize) будут иметь возможность использования для встроенных функций, а также для тех, для которых уже существуют встроенные символы. Но иногда новой функции могут потребоваться и новые опции. Для того чтобы сохранить модульность, необходимо, чтобы эти параметры были символами, определенными в уникальном внутреннем контексте (или что-то вроде целых функций ресурса, то есть сами по себе). Для простоты репозиторий функций позволяет задавать новые опции в определениях в виде строк. И для удобства пользователю, эти определения (при условии, что они использовали OptionValue и OptionsPattern) также обрабатываются так, что при использовании функций параметры могут быть заданы не только как строки, но и как глобальные символы с теми же именами.
Большинство функций просто делают то, что они должны делать каждый раз, когда их вызывают, но некоторые функции нуждаются в инициализации, прежде чем они смогут работать в определенном сеансе — и для решения этой проблемы в разделе «Определение» есть раздел «Инициализация».
Функции из репозитория могут использовать другие функции, которые уже находятся в репозитории, для того чтобы настроить определения для репозитория функций, включающие две (или более) функции, которые ссылаются друг на друга необходимо развернуть их в своем сеансе работы с программой, чтобы Вы могли ссылаться на них как ResourceFunction["name"], затем Вы можете создать нужные Вам комбинации этих функций примеры (не поняла) и добавить в репозиторий новую функцию на базе уже размещенных ранее. (или уже или ранее – оба слова коряво)
Перспективы развития. Что должно произойти, когда репозиторий станет по-настоящему большим?
Сегодня мы только запускаем репозиторий функций Wolfram, но со временем мы ожидаем, что он(удалить) его объем и функциональность может резко возрасти, и по мере его роста развития возникнут появятся различные проблемы, которые, как мы уже догадываемся предвидим, могут возникнуть.
Первая проблема касается имен функций и их уникальности. Репозиторий функций спроектирован таким образом, что в нем, как и для встроенных функций в языке Wolfram Language, можно ссылаться на любую данную функцию, просто указав ее имя. Но это неизбежно означает, что имена функций должны быть глобально уникальными по всему репозиторию, так что, например, в репозитории может быть только одна ResourceFunction["MyFavoriteFunction"].
На первый взгляд это может показаться большой проблемой, но стоит понимать, что это в основном та же проблема, что и для таких вещей, как интернет-домены или маркеры социальных сетей. И дело в том, что в системе просто необходимо иметь регистратора — и это одна из ролей, которую наша компания будет выполнять для базы знаний функций Wolfram. (Для частных версий репозитория их регистраторами могут быть администраторы.) Конечно, интернет-домен может быть зарегистрирован, не имея ничего на нем, но в репозитории функций имя функции может быть зарегистрировано только при наличии фактического определения функции.
Частью нашей роли в управлении базой знаний функций Wolfram является обеспечение того, чтобы имя, выбранное для функции, было логичным с учетом определения функции, а также, чтобы оно соответствовало соглашениям об именах Wolfram Language. У нас уже более 30 лет опыта по именованию встроенных функций на языке Wolfram Language, и наша команда курирования (кураторов?) перенесет этот опыт также в репозиторий функций. Безусловно, всегда есть исключения. Например, может показаться более предпочтительным иметь короткое имя для некоторой функции, но лучше «защищаться» с более длинным, более конкретным именем, потому что при этом меньше шансов столкнуться с тем, что кто-то хочет сделать похожее имя функции в будущем.
(Здесь следует отметить, что простое добавление какого-либо тега участника для устранения неоднозначности функций не принесет ожидаемого эффекта. Потому что, если не настаивать на том, чтобы всегда присваивался тег, нужно будет определять тег по умолчанию для любой заданной функции, а также выделять теги автора, что снова потребует глобальной координации.)
По мере роста объема базы знаний функций Wolfram одна из проблем, которые наверняка возникнут — это обнаруживаемость функций, для этого в системе предусмотрена функция поиска (а файлы определения могут включать ключевые слова и т. п.). Для встроенных функций в языке Wolfram Language в документации есть все виды перекрестных ссылок, которые помогают «рекламировать» функции. Функции в репозитории функций могут ссылаться на встроенные функции. А как же наоборот? Для этого мы собираемся экспериментировать с различными схемами, чтобы представить функции репозитория на страницах документации для встроенных функций.
Для встроенных функций в языке Wolfram Language существует так называемый уровень обнаружения, обеспечиваемый сетью «справочных страниц», которые предоставляют организованные списки функций, относящихся к конкретным областям. Всегда сложно надлежащим образом сбалансировать страницы справочника и по мере роста языка Wolfram, страницы справочника часто должны быть полностью реорганизованы. Довольно просто поместить функции из репозитория в широкие категории и даже последовательно разбивать эти категории, но гораздо ценнее иметь правильно организованные страницы справочника языка. Пока не ясно, как лучше всего создать их для всей базы знаний функций. Например, CreateResourceObjectGallery в репозитории функций каждый может разместить веб-страницу, содержащую свои «выборы» из репозитория:
Репозиторий функций Wolfram настроен как постоянное хранилище функций, где любая функция в нем всегда будет работать. Безусловно, могут появиться и новые версии функций, и мы ожидаем, что некоторые функции со временем конечно устареют. Функции будут работать, если они используются в программах, но их страницы документации будут ссылаться на новые, более продвинутые функции.
Репозиторий функций Wolfram предназначен для быстрого получения новых функций и изучения новых возможностей использования языка Wolfram. С большой долей оптимизма мы надеемся, что часть того, что было исследовано в репозитории функций, в конечном итоге будет иметь смысл стать встроенными частями основного языка Wolfram Language. За последнее десятилетие у нас был похожий набор функций, которые были изначально представлены в Wolfram | Alpha. И один из уроков, полученны на основании этого опыта, заключается в том, что для достижения стандартов качества и согласованности, на которых мы делаем упор во всем, что встроено в язык Wolfram, требуется много работы, которая чаще всего сложнее, чем первоначальные усилия по внедрению идеи. Но даже в этом случае функция в базе знаний функций может служить очень полезным доказательством концепции будущей функции, которая в итоге может быть встроена в язык Wolfram.
Здесь самое главное то, что функция в репозитории функций — это то, что доступно каждому пользователю для использования прямо сейчас. Возможно, встроенная функция языка может быть намного лучше и производительнее, но репозиторий функций позволит пользователям сразу получить доступ ко всем новым функциям. И, что особенно важно, эта концепция позволяет каждому добавлять любые свои новые функции.
Раньше в истории языка Wolfram эта идея не заработала бы так хорошо как сейчас, но на данном этапе в язык уже заложено столько усилий, а также настолько глубокое понимание принципов проектирования языка, что теперь видится весьма возможным, чтобы большое сообщество пользователей добавляло функции, которые будут поддерживать согласованность проекта, чтобы сделать их полезными для широкого круга пользователей.
В сообществе пользователей Wolfram Language есть невероятный дух таланта(?). (Разумеется, в это сообщество входят многие ведущие специалисты в области исследований и разработок в самых разных областях.) Надеюсь, что репозиторий функций Wolfram предоставит эффективную платформу для раскрытия и распространения этого духа таланта. Только вместе мы сможем создать нечто, что значительно расширит область, к которой может быть применена вычислительная парадигма языка Wolfram.
За 30 с лишним лет мы прошли долгий путь по языку Wolfram. Теперь вместе, давайте же пойдем еще дальше. Настоятельно призываю всех уважаемых пользователей языка Wolfram во всем мире, использовать в качестве платформы для этого функциональный репозиторий, а также такой новый программный проект, как Free Wolfram Engine для разработчиков.
Автор: Пётр Тенишев