## ЛЕКЦИЯ 3.

## Функции. Базовые функции.

## Содержание

  3.1 Определение функций.
  3.2 Передача параметров. Глобальные и локальные переменные.
  3.3 Свободные переменные.
  3.4 Расчет сопротивления цепи.
  3.5 Дополнительные функции обработки списков.
  3.5.1 APPEND.
  3.5.1.1 Объединяющие функции.
  3.5.2 REVERSE.
  3.5.3 LAST.
  3.6 Базовые предикаты.
  3.6.1 ATOM.
  3.6.2 EQ.
  3.6.3 =.
  3.6.4 EQL.
  3.6.5 EQUAL.
  3.6.6 NULL.
  3.7 Предикаты типов.
  3.8 Числовые предикаты.

## 3.1 Определение функций.

Необходимо поместить два элемента в начало списка, причем эту операцию мы хотели бы выполнять несколько раз с различными элементами.

Например :

*

( cons ' a (cons ' b ' ( c d ) ) )
( a b c d )

или

*

( cons ' train (cons ' truck ' (bus car boat ) ) )
( train truck bus car boat )

Лучше, если была бы функция:

*

( cons-two ' a ' b ' ( c d ) )
( a b c d )

*

( cons-two ' train ' truck ' ( bus car boat ) )
( train truck bus car boat )

Такую функцию можно определить самим и использовать как встроенную.

Чтобы определить функцию, необходимо:
- Дать имя функции
- Определить параметры функции
- Определить ,что должна делать функция

Для задания новых функций в Лиспе используется специальная форма defun.

### ( defun < имя-функции > < параметры > < тело-функции >)

Для нашего случая:

( defun cons-two ( x y oldlist )
( cons x ( cons y oldlist ) ) ) )

- Имя функции - символ.
- Параметры - список аргументов.
- Tело функции - вычисляемая форма от аргументов.

Значение определения функции defun - имя функции .

*

( defun cons-two ( x y oldlist )
( cons x ( cons y oldlist ) ) ) )
CONS-TWO

Вызов функции:

### ( < имя-функции > < значения аргументов >)

*

( cons-two ' a ' b ' ( c d ) )
( a b c d )

Значение функции - значение тела функции при заданных аргументах.

Примеры:

*

( defun double ( num ) ( * 2 num ) )

*

( double 7 )
14

Определенную функцию можно использовать как встроенную:

*

( setq z ( double ( + 5 10 ) ) )
30

*

( double z )
60

Еще один пример:

Необходимо элемент поместить new на второе место в списке: ( a c d ) станет ( a new c d )

Назовем функцию insert-second. Два аргумента: item oldlist.

Тело функции:
( cons ( car oldlist ) ( cons item ( cdr oldlist ) ) )

Таким образом,определим функцию:

( defun insert-second ( item oldlist )
( cons ( car oldlist ) ( cons item ( cdr oldlist ) ) )

*

( insert-second 'b '( a c d ) )
( a b c d )

## 3.2 Передача параметров. Глобальные и локальные переменные.

| В Лиспе передача параметров производится в функцию по значе- нию, т.е. формальный параметр в функции связывается с тем же значением, что и значение фактического параметра.

Изменение значения формального параметра не оказывает влияния на значения фактических параметров. После вычисления функции, созданные на это время связи параметров ликвидируются и происходит возврат к тому состоянию, которое было до вызова функции . Параметры функции являются локальными переменными , и имеют значение только внутри функции.

Например:

*

( defun f ( x ) ( setq x ' new ) ) ;

меняет значение x
f

*

( setq x ' old )
old

*

x
old

*

( f x )
new

Еще пример:

*

( defun double ( num ) ( * num 2 )
double

*

( setq num 5 )
5

*

( double 2 )
4

* num
5

## 3.3 Свободные переменные.

| Если в теле функции есть переменные, не входящие в число ее формальных параметров - они называются свободными. Значения свободных переменных остается в силе после ее выполнения.

Например:

*

( defun f1 ( y ) (setq x 3 ) )
f1

*

( f1 5 )
3

*

x
3

## 3.4 Расчет сопротивления цепи.

До тех пор пока мы не рассмотрели определение функций, мы не могли приступить к написанию программ на ЛИСПЕ. Теперь можно рассмотреть простейшую.

| Задача: Написать программу расчета сопротивления цепи. r1=r2=r3=10

Последовательное соединение (serial)
R = R1 + R2

функция (s_r R1 R2)

Определение: ( defun s_r ( R1 R2 ) (+ R1 R2 ) )

Параллельное соединение (parallel)
R = ( R1 * R2 ) / ( R1 + R2 )
функция ( p_r R1 R2 )

Определение: ( defun p_r ( R1 R2 ) ( / ( * R1 R2 ) ( + R1 R2 ) ) )

Расчет:

* (s_r 10 ( p_r 10 10 ) )
15

Усложним цепь:

| r1=r2=r3=r4=10 Расчет: *( p_r 10 ( s_r 10 ( p_r 10 10 ) ) ) и т.д.

## 3.5 Дополнительные функции обработки списков.

  APPEND
  REVERSE
  LAST

## 3.5.1 APPEND.

| Функция APPEND объединяет два и более списков в один.

### ( APPEND < список - 1 > < список - 2 > )

Пример:

*

( append ' ( a b ) ' ( c ) )
( a b c )

APPEND

объединяет элементы, не изменяя их.

*

( append ' ( list ) ' ( ' ( a b ) ' ( c ) ) )
( list ( quote ( a b ) ) ( quote ( c ) ) )

## 3.5.1.1 Объединяющие функции.

Рассмотрим несколько примеров,что бы показать отличие APPEND LIST CONS .

Примеры:

*

( list ' ( a b ) ' ( c d ) )
( ( a b ) ( c d ) )

*

( cons ' ( a b ) ' ( c d ) )
( ( a b ) c d )

*

(append ' ( a b ) ' ( c d ) )
( a b c d )

- cons всегда берет два аргумента и помещает первый в начало второго.
- list берет один или больше аргументов и образует список, помещая аргументы в скобки.
- append образует новый список, убирая скобки вокруг аргументов и помещая их в один список.

## Дополнительные сведения об отличии функций.

### Функция

### Аргументы

### Действие

##### LIST

##### s s s ...

##### ( s s s... )

##### CONS

>

##### s ( list )

##### ( s list )

##### APPEND

##### (l) (l) (l)...

##### ( l l l ...)

## 3.5.2 REVERSE.

| Функция REVERSE изменяет порядок элементов в аргументе.

### ( REVERSE < список > )

Пример:

*

( reverse ' ( a b c ) )
( c b a )

- Аргументом reverse должен быть список.
- reverse не меняет порядок в списках более нижнего уровня.

  *

  ( reverse ' ( ( a b c ) e ) )
  ( e ( a b c ) )

  ## 3.5.3 LAST.

  | Функция LAST удаляет из списка все элементы кроме последнего.

  ### ( LAST < список > )

  Пример:

  *

  ( last ' ( a b c ) )
  ( c )

  ## 3.6 Базовые предикаты.

  | Предикат в Лиспе - это функция,которая определяет обладает ли аргумент определенным свойством, и возвращает в качестве значения T или NIL.

  ## 3.6.1 ATOM.

  ATOM проверяет , является ли аргумент атомом.
  Значение будет Т , если атом , и nil в обратном случае.

  ### ( ATOM < s - выражение >)

  Примеры:

  *

  ( atom 'x )
  t

  *

  ( atom '( a b ) )
  nil

  *

  ( atom ( cdr ' ( a b ) ) )
  nil

  *

  ( atom ( car ' ( a b ) ) )
  t

  Предикат atom с пустым списком nil:

  *

  ( atom nil )
  t

  *

  ( atom ( ) )
  t

  ## 3.6.2 EQ.

  | Предикат EQ сравнивает два символа и возвращает Т, если они одинаковые, и nil в обратном случае.

  ### ( EQ < выражение 1 > < выражение 2 > )

  Примеры:

  *

  ( eq ' cat ' cat )
  t

  *

  ( eq ' cat ' dog )
  nil

  *

  ( eq ' cat ( car ' ( cat dog ) )
  t

  *

  ( eq t ' t )
  t

  EQ можно применять к числам, если они представлены одним типом.

  *

  ( eq 123 123 )
  t

  ## 3.6.3 =.

  | Предикат "=" сравнивает числа различного типа.

  ### ( = < число - 1 > < число - 2 > )

  *

  (= 3 3.0 )
  t

  *

  (= 3 0.3F 01 )
  t

  ## 3.6.4 EQL.

  | Сравнивает и числа и символы. ( EQL arg1 arg2 ) Истина только в том случае, если arg1 arg2 эквивалентны по ЕQ ,или это числа одного и того же типа, имеющие одно и тоже значение.

  ### ( EQL < аргумент - 1 > < аргумент - 2 > )

  *

  ( eql ' a ' a )
  t

  *

  ( eql ' 12 ' 12 )
  t

  ## 3.6.5 EQUAL.

  Самый общий предикат. Сравнивает не только символы,числа ну и списки.

  - числа эквивалентны по
  equal
  - символы эквивалентны по
  equal
  - списки эквивалентны по
  equal
  если их изображения совпадают.

  ### ( EQUL < аргумент - 1 > < аргумент - 2 > )

  *

  ( equal ' (a b c ) ' ( a b c ) )
  t

  *

  ( equal nil ' ( ( ) ) )
  nil

  ## 3.6.6 NULL.

  | Предикат NULL проверяет является ли аргумент пустым списком.

  ### ( NULL < аргумент >)

  *

  ( null ' ( ) )
  T

  *

  ( null nil )
  T

  *

  ( null t )
  nil

  ## 3.7 Предикаты типов.

  ## Предикаты типов.

  ### Предикат

  ### Действие

  ### T

  ### NIL

  ##### atom

  ##### аргумент атом?

  ##### ( atom 'a )

  ##### ( atom '( a ) )

  ##### symbolp

  ##### аргумент символ?

  ##### ( symbolp 'a )

  ##### ( symbolp '10 )

  ##### listp

  ##### аргумент список?

  ##### ( listp '( a ) )

  ##### ( listp 'a )

  ##### numberp

  ##### аргумент число?

  ##### ( numberp 10 )

  ##### ( numberp 'a )

  ## 3.8 Числовые предикаты.

  ## Числовые предикаты.

  ### Предикат

  ### Действие

  ### T

  ### NIL

  ##### zerop

  ##### arg = 0

  ##### ( zerop 0 )

  ##### ( zerop 1 )

  ##### plusp

  ##### arg > 0

  ##### ( plusp 1 )

  ##### ( plusp -1 )

  ##### minusp

  ##### arg < 0

  ##### ( minusp -1 )

  ##### ( minusp 1 )

  ##### =

  ##### arg1 = arg2 = arg3 = ...

  ##### ( = 2 2 2 )

  ##### ( = 1 2 3 )

  ##### >

  ##### arg1 > arg2 > arg3 > ...

  ##### ( > 3 2 1 )

  ##### ( > 2 3 1 )

  ##### <

  ##### arg1 < arg2 < arg3 < ...

  ##### ( < 1 2 3 )

  ##### ( < 2 3 1 )

  Содержание