Собственные функции
Если вы часто повторяете одну формулу с разными числами, создайте функцию. Один раз задайте её имя и параметры, затем вызывайте там, где нужен результат: для чаевых, ИМТ, прогноза накоплений или счёта клиенту.
Здесь описаны определение и вызов функций, использование других имён из заметки, условия, рекурсия и ограничения. О встроенных функциях Varlig, таких как sqrt и round, см. Справочник встроенных функций.
Определение и вызов функции
Запишите имя функции, параметры в круглых скобках, знак равенства и формулу. Затем вызывайте её со значениями в том же порядке:
tip(bill, pct) = bill * pcttip($48, 15%) даёт $7.20tip($120, 12.5%) даёт $15.00tip($36 + $12, 15%) даёт $7.20Строка определения не показывает результат. Каждый вызов подставляет ваши значения вместо bill и pct и вычисляет формулу. Аргументом может быть целое выражение, например $36 + $12 выше.
Аргументы могут содержать не только числа: единицы измерения и валюты сохраняются при вычислении формулы:
bmi(weight, height) = weight / height^2bmi(81 kg, 1.8 m) даёт 25 kg/m²Единицы сохраняются такими, как переданы: bmi(81 kg, 180 cm) даёт результат в кг/см². Чтобы единица результата не зависела от входных данных, выполняйте перевод внутри функции:
bmi(weight, height) = (weight / height^2) in kg/m^2bmi(81 kg, 180 cm) даёт 25 kg/m²bmi(80 kg, 5.9 ft) даёт 24.7375131668 kg/m²Функция также может не иметь параметров. Напишите пустые скобки как при определении, так и при вызове:
standard_vat() = 20%£120 * standard_vat() даёт £24.00Обычная переменная, такая как standard_vat = 20%, обычно выполняет ту же работу с меньшим количеством ввода.
Имена и параметры
- Имена функций и параметров состоят из одного слова без пробелов. Используйте буквы, цифры и подчёркивания, например
net_payилиbmi2. Для записиarea of circle(r) = pi * r^2строка предложит подходящее имя:area_of_circle. - Имена функций игнорируют регистр: после определения
Tip(bill, pct)вы можете вызватьtip($48, 15%). - Каждому параметру нужно собственное имя.
f(a, a) = a- это ошибка. - Функция может иметь до 32 параметров.
- Вы не можете повторно использовать имя встроенной функции.
round(x) = …илиsqrt(x) = …отображают ошибку вместо её замены. Простой переменной всё ещё может использовать одно из этих имен, напримерfloor = 12 m²; см. Имена. - Имена
avg,totalиstdev, знакомые по электронным таблицам, разрешены для собственных функций. Если определитьtotal(order), будет вызываться ваша версия. - Функция и переменная могут иметь одно имя. Запись
rateчитает переменную, аrate(5)вызывает функцию. - Всегда вызывайте функцию в скобках. Имя функции само по себе, без переменной с тем же именем, ничего не показывает. Исключениями являются
sum,total,subtotal,grand total,average,maxиmin, которые вычисляют эту цифру для строк над ними; см. Сложение строк выше.
Запятые в аргументах
Запятая, за которой следует пробел, разделяет аргументы, а запятая, за которой следуют ровно три цифры, объединяет тысячи, поэтому вы можете писать суммы так, как обычно:
tip(bill, pct) = bill * pcttip($1,200, 15%) даёт $180.00tip($1200,15%) даёт $180.00Если функции нужно больше аргументов, чем получается при разделении запятыми с пробелами, все запятые трактуются как разделители, как во втором вызове. Дробную часть отделяйте точкой, например tip($48, 12.5%).
Использование других имен в вашей заметке
Функция может использовать переменные заметки. При каждом вызове она читает их текущие значения:
vat = 20%with_vat(price) = price * (1 + vat)with_vat(£50) даёт £60.00vat = 5%with_vat(£50) даёт £52.50Переменная должна уже существовать, когда вы определяете функцию, поэтому поставьте vat = 20% выше with_vat. Если он еще не существует, строка определения показывает ошибку.
Параметры являются локальными для функции. Параметр под названием price не читает и не изменяет переменную под названием price в другом месте примечания:
price = £10double(price) = price * 2double(£3) даёт £6.00price даёт £10.00Как и переменные, функцию из одного блока вычислений можно использовать в последующих блоках той же заметки. Varlig обрабатывает заметку сверху вниз, поэтому определение должно стоять выше первого вызова. Вызов до определения не показывает результат.
Функции, которые вызывают другие функции
Небольшие функции могут быть построены друг на друге:
day_rate = £400fee(days) = days * day_rateinvoice(days) = fee(days) * 1.2invoice(5) даёт £2,400.00Функция запоминает ту версию вспомогательной функции, которая существовала при её определении. Если ниже определить вспомогательную функцию заново, ранее созданные функции продолжат использовать старую версию:
shipping(order) = £4.95total(order) = order + shipping(order)shipping(order) = £2.95total(£30) даёт £34.95shipping(£30) даёт £2.95Чтобы использовать новую shipping, определите total заново ниже неё. При редактировании исходного определения на месте такой проблемы нет: Varlig пересчитывает заметку сверху, и все последующие строки используют обновлённую версию.
Функция также может вызывать вспомогательную функцию, определённую ниже. В этом случае используется версия, действующая в момент вызова. Поэтому вспомогательная функция должна существовать к моменту вызова внешней:
checkout(order) = order + delivery(order)delivery(order) = if order >= £40 then £0 else £3.50checkout(£25) даёт £28.50checkout(£60) даёт £60.00Условия
Используйте if … then … else …, чтобы выбрать между результатами. Добавьте еще один if после else, чтобы обработать более двух случаев:
postage(weight) = if weight <= 100 g then £0.85 else if weight <= 750 g then £1.55 else £3.20postage(90 g) даёт £0.85postage(500 g) даёт £1.55postage(1.2 kg) даёт £3.20Вычисляется только выбранная ветвь. Это позволяет защититься от недопустимых операций, например деления на ноль:
per_person(total, people) = if people > 0 then total / people else £0per_person(£90, 3) даёт £30.00per_person(£90, 0) даёт £0.00Рекурсия
Функция может вызвать себя, если условие в конечном итоге останавливает ее. Этот подсчитывает рукопожатие, когда все в группе пожимают друг другу руки один раз:
handshakes(people) = if people <= 1 then 0 else (people - 1) + handshakes(people - 1)handshakes(6) даёт 15handshakes(10) даёт 45Каждый вызов увеличивает глубину вложенности на один; разрешено не более 12 уровней. handshakes(12) работает, а handshakes(13) выдаёт Error: calculation limit. Функцию без достижимого условия остановки можно определить, но при вызове она достигнет того же ограничения. Две функции могут вызывать друг друга в пределах того же лимита.
Для повседневного подсчета встроенные функции быстрее работают и не имеют такого ограничения. combination(10, 2) также выдает 45, а factorial(n), или n!, охватывает классический рекурсивный пример.
Списки, матрицы и многое другое
Аргументы могут быть списками, матрицами или комплексными числами, а тело может использовать любую встроенную функцию:
spread(scores) = max(scores) - min(scores)spread([12, 18, 9, 21]) даёт 12Тело также может содержать суммирование или решение уравнений со своей собственной локальной переменной. См. Списки и статистика и Суммирование, решение уравнений и исчисление.
Подводные камни
- Записывайте степени через
^. Записьx²внутри функции не поддерживается. Кроме того, короткое имя параметра может совпасть с единицей: вw / h²выражениеh²означает часы в квадрате, а не параметрh. Используйтеw / h^2. - Проверьте количество аргументов. Вызов функции
tip($48), когда она ожидает два значения, приводит к ошибке. - Цена без явной единицы может трактоваться как цена за единицу. В
oats(amount) = amount / 1 kg * £0.95сумма £0.95 считается ценой за килограмм. Каждый вызов сообщает об этом: наведите указатель, чтобы увидеть пояснение «£0.95 в oats трактуется как цена за кг. Напишите £0.95/kg, чтобы указать это явно». Явная запись ставки в определении убирает подсказку. - Одна строка, одна формула. Определение — это одно выражение на одной строке. Для расчета с несколькими шагами определите небольшую функцию для каждого шага и объедините их.
- Ошибочное переопределение сохраняет прежнюю версию. Если новое определение
tipсодержит ошибку, строка сообщает о ней, а предыдущая рабочаяtipостаётся доступной. - Ответы могут измениться, когда заметка пересчитает данные. Вызовы рассчитываются снова каждый раз, поэтому функция, использующая
randomили сегодняшнюю дату, может дать новый ответ. - Ошибки передаются вызывающей строке. Если аргумент приводит к недопустимому вычислению, например делению на ноль, вызов показывает эту ошибку.
Ограничения
| Параметр | Ограничение |
|---|---|
| Параметры для каждой функции | 32 |
| Вложенные вызовы: функция вызывает себя или другую функцию | 12 |
| Число вызовов при вычислении одного вызова верхнего уровня | 16,384 |
| Функции, определённые в заметке | 1,024 |
При достижении ограничения появляется Error: calculation limit. Остальная заметка продолжает работать. Полный список — в разделе Ошибки, диагностика и ограничения.
Всё вместе
Пример счёта фрилансера. Дневная ставка и НДС заданы именованными значениями в начале, а вычисления выполняют три небольшие функции:
# March invoiceday_rate = £450vat = 20%fee(days) = days * day_ratewith_vat(amount) = amount * (1 + vat)late_fee(amount, days_late) = if days_late > 30 then amount * 2% else £0design = fee(8) даёт £3,600.00build = fee(4.5) даёт £2,025.00subtotal = design + build даёт £5,625.00with_vat(subtotal) даёт £6,750.00late_fee(with_vat(subtotal), 45) даёт £135.00Измените day_rate или vat, и все последующие строки обновятся. Если клиент задержал оплату, один вызов добавит сбор.