Давайте начнём с использования Scheme в качестве простого калькулятора, запустите итерпритатор Scheme в режиме
Для того чтобы вычислить выражение типа "1 + 4" нужно просто набрать строку:
(+ 1 4)
и нажать на ввод. В результате интерпритатор выведет число "5"
Обратите внимание на то, что символ "+" отделяется от числа пробелом -- это важно, так как в Scheme строка "+1" является допустимым именем переменной.
А для того чтобы вычислить более сложное выражение, например "1 + 2 * 3" нужно разобраться с так называемой "польской нотацией" (нотация -- это правила записи о???).
Начнём с того, что расставим скобки по правилам принятым в обычной школьной математике:
(1 + (2 * 3))
А затем поставим знак арифмитической операций слева от операндов, т.е. сразу после левой скобки, начнём с (2 * 3), в результате мы получим "(* 2 3)", затем мы переходим к знаку сложения и в результате получаем
(+ 1 (* 2 3))
А теперь рассмотрим более сложное выражение, например:
"1 + 2 * 3 - 4 / 5"
Расставляем скобки и получаем:
"((1 + (2 * 3)) - (4 / 5))"
Смотрим какие операции обладают более высоким приоритетом, в нашем случае это умножение и деление, и получаем (* 2 3) и (/ 4 5) соответственно,
затем переходим к плюсу:
(+ 1 (* 2 3))
а затем добавляем минус:
(- (+ 1 (* 2 3)) (/ 4 5))
в результате получаем число "31/5".
В нашем случае знаки "+", "-", "*" и "/" являются именами функции, такими же как "abs", "length" или "string-length", в Scheme допустимо использовать следующие символы в названиях переменных:
- любые буквы (в том числе и Русские)
- цифры (0, 1, 2 ... 9)
- символы Юникода относящиеся к категориям Nd, Mc или Me.
Проще говоря, названия переменных и функций могут включать в себя все буквы, цифры и различные символы, включая "+-!$%&*/:<=>?^_~", попробуйте исполнить слудующее выражение:
(define +-!$%&*/:<=>?^_~ 111)
а затем набрать:
+-!$%&*/:<=>?^_~
В результате вы получите "11", да, "+-!$%&*/:<=>?^_" является вполне допустимым именем переменной.
Названия переменных не могут содержать:
- скобок "(){}[]"
- символов пробела, табуляции, новой строки или перевода строки.
Функция "+" выполняет сложение, но в отличие от обычного арифметическоко действия сложения, может принимать любое количество переменных:
(+ 1 2 3 4 5 6 7 8 9)
->45
Или даже просто:
(+)
->0
Тоже самое относится и к функции "-"
(- 1 2 3 4 5 6 7 8 9)
->-43
(-)
->0
А вот функция "*" работает немного не так, если количество аргументов больше одного, она возвратит произведение всех этих аргументов:
(* 1 2 3 4 5 6 7 8 9)
->362880
1*2*3*4*5*6*7*8*9
если аргумент только один, она его и вернёт:
(* 2)
-> 2
А если аргументов нет она возвратит "1"
(*)
->1
Для функции деления "/" требуется хотя бы один аргумент, иначе вы получите ошибку
(/)
->/dev/stdin:25:1: call to '/' has too few arguments (0; min=1)
Другие арифметические функции:
* (abs a-number)
(abs -15)
->15
* (max number-1 .. number-n) максимальное значение
(max 1 2 3 4 5 6 7 6 5 4 3 2 1)
->7
(min number-1 .. number-n) -- минимальное значение
(round number) -- округляет до ближайшего целого
(round 1.2)
-> 1.0
(round -1.9)
->2.0
(ceiling number) округляет число до ближайшего большего целого числа
(ceiling -0.9)
->-0.0
(ceiling 0.1)
->1.0
(floor number) округляет число до ближайшего меньшего целого числа
(floor -0.9)
->-1.0
(floor 0.1)
-> 0.0
(truncate number) возвращает целую часть числа
(truncate -1.5)
->-1.0
(truncate 1.5)
->1.0
(sqrt number) возвращает квадратный корень числа (число не дольжно быть отрицательным)
(sqrt 4)
->2.0
(expt n1 n2) возводит число n1 возведённое в степень n2
(expt 4 3)
->64
В качестве аргумента при вызове функции можно использовать результат вызова другой функции. Давайте рассмотрим это на примере нахождения длинны гипотенузы в треугольнике со сторонами 10 и 2.
(sqrt (+ (expt 10 2) (* 2 2)))
->10.198039027185569
В данном случае функция "sqrt" получает в качестве аргумента результат выполнения функции "+", которая, в свою очередь, получает два аргумента в виде результатов выполнения двух разных функций "expt" и "*".
Упражнения
Запишите на Scheme следующие математические выражения:
a) 10 * 30 / 60
->5
b) (5 + 100) * (1 - 200)
->-99500
c) (10 + 13)/(10 * 13)
->23/130
d) 4^2 * 5^3 * 6*4
->2592000
e) 1/(2 + 5)
->1/7