вторник, 24 декабря 2019 г.

Функции

    Функция - способ реализации какого либо действия необходимого для работы программы.

    Опять вернёмся к магазину из предыдущих статей. Предположим мы хотим создать программу которая спрашивает у продавца, что он хочет сделать, а затем информацию необходимую для этого действия. Вот пример части такой программы (в этой статье описывается не все аспекты, а только те которые касаются объявления функции):


enums
    action_new //добавить новую модель в базу данных
    action_remove //удалить модель из базы данных
    action_fix //исправить какую либо информацию о модели
    action_arrived //на склад прибыло некоторое количество новых велосипедов одной модели
    action_sold //было продано некоторое количество велосипедов одной модели

//функция принимает данные магазина, действие которое надо выполнить, данные которые ввел пользователь
//возвращает true - если всё прошло успешно, иначе - false
func perfom(shop, action, data)
    rules
        final = shop == Shop & action == UInt64 & data == Data
        result = Bool
    case action of
        action_new
            result = shop:new(data)
        action_remove
            result = shop:remove(data)
        action_fix
            result = shop:fix(data)
        action_arrived
            result = shop:arrived(data)
        action_sold
            result = shop:sold(data)


    Для объявления новой функции необходимо написать ключевое слово func или proc. func - пишется если функция в результате своей работы возвращает какое либо значение, если функция не возвращает никакого значения, то такая функция называется процедурой и вместо func нужно писать proc. После func или proc идёт имя функции, которое должно соответствовать следующим правилам:
  • начинается со строчной буквы
  • содержит только буквы латинского алфавита, цифры и знак подчёркивания (_)
  • последним символом допускается использование "?" или "!"
  • не может содержать два знака подчёркивания идущих подряд
  • не может быть одним из следующих имён:  "func", "proc", "enslave", "select", "if", "case", "for", "return", "result"
  • не может начинаться с "builtIn"
    Если имя  функции заканчивается на "?", то это означает, что функция, проверяет какое-то утверждение и возвращает true если оно верно, иначе false. Если имя функции заканчивается на "!", то это означает, что функция проверяет какое-то утверждение и если оно ложно, то выполняет какое либо действие(например выводит ошибку).
    После имени функции в скобках идет перечисление псевдонимов для данных, с которыми будет работать функция. Такие данные называются аргументами функции, а их псевдонимы - именами аргументов функции.  Имя аргумента функции должно соответствовать следующим правилам:

  • начинается со строчной буквы
  • содержит только буквы латинского алфавита, цифры и знак подчёркивания (_)
  • не может содержать два знака подчёркивания идущих подряд
  • не может быть одним из следующих имён: "if", "case", "flag", "of", "for", "return", "result", "break", "continue", "mif", "parse", "true", "false"
  • не может начинаться с "builtIn"
    Аргументов функции может быть ноль и более. Если имён аргументов больше одного, то они перечисляются через запятую. Если аргумент должен передаваться в функцию как изменяемый, то перед его именем ставится двоеточие.
    После имён опционально объявляется приоритет функции(о приоритетах ниже), объявляется он в формате #уровень приоритета. Уровень приоритета может быть цифрой от 1(наименьший приоритет) до 9(наивысший приоритет), если не указывать приоритет, то он равен 5.
    В cine может быть бесконечное множество функций с одинаковым именем. Для того, чтобы понять какая функция нужна при вызове, вначале сверяется количество аргументов и есть ли у функции возвращаемое значение, если всё совпадает выполняются правила (rules) которые определят, подходит ли функция под передаваемые аргументы. Поиск функций начинается с функций у которых приоритет 9, если ни одна функция не подошла, то приоритет снижается на еденицу и т.д. Если не было найдено ни одной функции даже с приоритетом 1 - ошибка компиляции. Если в процессе поиска на одном уровне была единственная подходящая функция, то поиск завершён, если их было несколько - ошибка компиляции. Так же в правилах определяется тип результата функции.
    Каждая строка написанная после ключевого слова rules и имеющая к отношении к строке где находится слово rules считается правилом. Строение правил: в начале идёт номер правила, если правило последнее  то вместо номера пишется final. От значения final и зависит, будет ли функция подходящей под данные аргументы. Номера начинаются с 1, а каждое последующее правило должно быть больше предыдущего на еденицу. После номера правила идет символ "=" после которого идёт выражение, которое определяет является ли правило истинным или ложным. Допустимые элементы в выражениях:
  • (выражение) - всё что в скобках считается одним операндом текущего выражения
  • !операнд - возвращает операнд, значение которого противоположно указанному операнду
  • операнд & операнд - возвращает операнд значение которого "истина", если значение обоих операндов "истина"
  • операнд | операнд - возвращает операнд значение которого "истина", если значение хотя бы одного операнда "истина"
  • аргумент == шаблон типа - возвращает операнд значение которого "истина", если аргумент функции соответствует шаблону типа(о нём ниже)
  • аргумент != шаблон типа - возвращает операнд значение которого "истина", если аргумент функции не соответствует шаблону типа
  • аргумент > группа - возвращает операнд значение которого "истина", если аргумент функции является членом группы(подробнее в следующей статье)
    Шаблоны типа выглядят так же как типы, но в них допускается вместо аргумента типа использовать знак подчеркивания, который означает - без разницы какой тип. Так же в качестве шаблона, а также в качестве аргумента типа в шаблоне, можно использовать имена аргументов функции, что будет значить "такой же тип как у аргумента функции".
     В правилах везде где можно указывать имя аргумента функции, можно указывать аргумент типа аргумента функции.
    Если какое либо выражение, в принципе не возможно выполнить, то считается что функция не подходит под данные аргументы.
    Если функция всегда выполняется, то правила не обязательно указывать.
    После последнего правила, нужно указать тип возвращаемого результата(к процедурам это не относится). Для этого нужно написать "result = " тип результата. Правила для описания типа результата, такие же как и для шаблона типа, но нельзя использовать знак подчёркивания.
    Для пояснения всего выше сказанного о правилах, вот примеры:

rules
    1 = a == UInt64 //истина если аргумент функции a имеет тип UInt64
    2 = a == b //истина если типы аргументов функции a и b совпадают
    3 = c > Equal //истина если тип аргумента функции c является членом группы Equal
    4 = c == [_] //истина если тип аргумента функции c является слайсом
    5 = d != Pair(_, [a]) //истина если тип аргумента d не является типов Pair
                          //у которого 2-й аргумент типа равен слайсу с таким же
                          //типом элементов как и у аргумента функции a
    6 = d[0][2] == a //истина если третий аргумент типа первого аргумента типа аргумента функции d
                     //равен типу аргумента функции a
    final = (1 | 2 | 3) & !(4 | 5 | 6) //если хотя бы одно из правил 1-3 истинно,
                                       //но при этом все правила 4-6 ложны
                                       //до данная функция считается подходящей под
                                       //данные аргументы
    result = [Pair(c, [UInt8])] //тип результата функции имеет тип Slice
                                //элементы которого имеют тип Pair
                                //первый аргумент типа Pair имеет такой же тип
                                //как и аргумент функции c
                                //второй аргумент типа Pair имеет тип [UInt8]


    После правил идёт код функции, о нём я расскажу в будущих статьях.

Комментариев нет:

Отправить комментарий

Пожалуйста без мата и оскорблений. Если хотите сообщить об ошибках, для этого есть форма обратной связи.