Переменные и области видимости

Сегодня небольшой обзор переменных, областей видимости и типов данных. Не смотря на то, что lisp это динамически-типизированный язык и, по сути все переменные это ссылки на значения, у значений есть тип. А значит стоит об этом знать. Теперь обо всё по порядку.

Переменные и области видимости

Переменные бывают глобальные, лексические и динамические. Глобальные объявляются так:

(defvar *a* 1)
(defparameter *b* 2)

Разница тут в том, что если *b* была объявлена, то её значение поменяется, а у *a* оно изменится лишь в случае если *a* не было ранее.

Лексические переменные объявляются так:

(let ((var1 value1) (var2 value2)) body)
(let* ((var1 value1) (var2 var1)) body)

Разница здесь в том, что в let со звёздочкой первые переменные видны следующим. Как будто это много вложенных let.

И, наконец, динамические. Это тоже что и лексические, но называться они будут так как глобальные.

(defvar *a* 5)
(defun foo () (print *a*))
(defun baz ()
    (foo)
    (let ((*a* 12)) (foo))
    (foo))

Данный код выведет 5, 12, 5. Что было бы удивительно в других языках. Т.е. переменная в let скрывает глобальную. Когда мы выходим из let, то глобальную снова видно. Вот такая магия.

Ещё одна магия это замыкания:

(let ((count 5)) #'(lambda () (incf count)))

Данный блок возвращает анонимную функцию, которая работает с переменной count. Как ни странно, из блока мы вышли, а доступ к ней всё ещё есть. Это не баг, а фича функциональных языков.

Константы

Константы в lisp тоже есть, а как же без них! Задаются довольно просто:

(defconstant +name+ (init-form) "Description")

Символы плюса — это менее строгое соглашение по именованию констант. Строку с описанием можно опускать.

Переменные и типы данных

Кратко про типы данных. Числа могут быть рациональными или с плавающей точкой. Примеры:

;;Рациональные
10     ;10
1/2    ;1/2
#xA    ;10
#o12   ;10
#b1010 ;10
#9r11  ;10 2-36r

;;С плавающей точкой
1d0     ;1.0d0
123d20  ;1.23d+22
.12     ;0.12
123e-3  ;0.123

 

Для чисел с плавающей точкой есть несколько префиксов — s(single), f(float), d(double), l(long), e(default = single). Эти префиксы задают точность.

Ещё один тип чисел — комплексные задаются через #c

#c(1 2)     ;#c(1 2)
#c(1d 2.1d) ;#c(1.0d0 2.1d0)

Математические операции

Над числами можно совершать математические операции, сразу напишу примеры для базовых операций и операций округления. Функции высшей математики синусы/косинусы тоже есть, но их перечень давать трудозатратно.

(+ 10 15) ;сложение
(- 10 15) ;вычитание
(* 10 15) ;умножение
(/ 10 15) ;деление

;;округление
(floor (/ 7 6))      ;1
(ceiling (/ 7 6))    ;2
(truncate (/ 7 6))   ;1
(round (/ 7 6))      ;1

;;модуль и остаток
(mod 7 6)  ;1
(rem 7 6)  ;1
(mod -7 6) ;5
(rem -7 6) ;-1

Переменные и области видимости: 2 комментария

    1. Да, это только соглашение, которое не является обязательным. Однако, лучше ему следовать, для большего порядка в программах

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.