function!
Как вы уже догадались, function!
s являются пользовательскими функциями, которые поддерживают уточнения и проверку типов, а также могут содержать встроенные строки документов.
Как правило, function!
значения создаются с помощью конструкторов func
, function
, does
и has
и используют так называемый диалект spec ;но, теоретически, ничто не мешает вам создавать свои собственные конструкторы или разрабатывать собственные форматы спецификаций.
Стоит также отметить, что function!
s полностью поддерживает отражение.
op!
op!
s являются инфиксными оболочками поверх других 4 типов функций - они принимают одно значение слева и результат выражения справа, а также имеют преимущество перед другими функциями во время оценки.
*Значения 1024 *
op!
ограничены двумя аргументами, не поддерживают уточнения и имеют ограниченную поддержку отражения (например, вы не можете проверять их тела с помощью
body-of
).
routine!
routines!
существуют в обеих сферах Красного и Красного / Системного (низкоуровневый диалект, поверх которого строится среда выполнения Красного).Их спецификации написаны на диалекте spec , но их тела содержат красный / системный код.Да, и они поддерживают рефлексию.
Обычно они используются для привязки библиотек (например, упомянутой вами библиотеки SQL), взаимодействия со средой выполнения или для устранения узких мест в производительности (Red / System - скомпилированный язык, поэтому переписываемкритичные к производительности части вашего приложения в виде набора routine!
s дадут вам значительный прирост за счет обязательной компиляции.
native!
native!
sфункции, написанные на Red / System (по причинам производительности, простоты или осуществимости) и скомпилированные в собственный код (отсюда и название).Не уверен, что еще можно сказать о них, кроме деталей реализации.native!
не очень удобны для пользователя, поэтому вы можете изучить исходный код Red на случай, если у вас остались какие-либо вопросы.
action!
action!
s являются стандартизированныминабор функций, написанных на Red / System (точно так же как native!
s), которые каждый тип данных реализует (или наследует) как свой «метод».action!
полиморфны в том смысле, что они отправляют свой первый аргумент:
>> add 1 2%
== 1.02
>> add 2% 1
== 102%
>> append [1] "2"
== [1 "2"]
>> append "1" [2]
== "12"
В основных языках это обычно выглядит как "1".append([2])
или что-то в этом роде.
Различие между action!
s и native!
s сводятся к выбору дизайна:
вы можете иметь столько native!
, сколько хотите, но action!
s, для эффективности, имеют фиксированныйТаблица отправки размера (это означает, что максимальное число action!
с на тип данных ограничено; минимальное число равно двум: make
[для создания значения] и mold
[для сериализации значения в string!
]).
логически, action!
s организованы вокруг типа данных, к которому они принадлежат, в одном файле, тогда как native!
s на самом деле не имеют отношения к типам данных и реализуют поток управления, тригонометрические функции,операции над сетами и т. д.
Совсем недавно, совсем недавно, у нас подобное обсуждение о action!
с и native!
с в чате нашего сообщества, который вы можете прочитать.Я также могу порекомендовать просмотреть черновик спецификации Рудольфа Мейера Red и, конечно, официальную справочную документацию .
Что касается "почему" в вашем вопросе - различиемежду 5 типами - это просто деталь реализации, унаследованная от Rebol.Логически все они реализуют то, что вы могли бы назвать «функцией» с концептуальной точки зрения, и попадают в any-function!
camp.