[Scheme ]

Давайте начнём с использования 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 допустимо использовать следующие символы в названиях переменных:

Проще говоря, названия переменных и функций могут включать в себя все буквы, цифры и различные символы, включая "+-!$%&*/:<=>?^_~", попробуйте исполнить слудующее выражение:

(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