From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Fri, 27 May 2005 12:30:52 +0400 From: Stanislav Ievlev To: devel@altlinux.ru Message-ID: <20050527083052.GA18766@basalt.office.altlinux.org> Mime-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: 8bit Subject: [devel] I: alterator internals - 2 X-BeenThere: devel@altlinux.ru X-Mailman-Version: 2.1.5 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 May 2005 08:30:54 -0000 Archived-At: List-Archive: List-Post: Продолжение. 2.2 Немного про alterator На пару минут отвлечёмся от увлекательного мира Scheme и попробуем поприменять полученные знания в alterator - ведь именно он является основной темой повествования. Как вы должно быть уже заметили в предыдущий раз, на схеме как думается, так и пишется. Попробуем например описать интерфейс. По-русски мы бы это сказали например так: "Кнопка 'Quit'".В alterator это выглядит: (button "Quit") Ещё вариант: "Горизонтальная группа из кнопки 'Yes' и кнопки 'No'". В alterator это: (hbox (button "Yes") (button "No")) Продолжаем: "Вертикальная группа из метки 'Hello, world!' и кнопки 'Quit'". (vbox (label "Hello, world!") (button "Quit")) Вот видите, как всё просто! Мы уже умеем описывать интерфейсы, заодно познакомились с тем что в схеме бывают не только целые числа, но и строки. 2.3 Имена Выражение: (* 10 50) хорошо, а: (* width height) лучше. (3.1415926 * 10.5 * 10.5) - интригующе, а (* pi radius radius) - всё же понятнее, (+ 2/3 5/7) - какие-то невзрачные действия с дробями, а (+ my-piece-of-cake your-piece-of-cake) - уже обретает смысл. Хочется сделать выражения более осмысленные и читаемые. Сказано - сделано. Фраза "Опеределим b как 5", записывается (define b 5). Сразу несколько примеров: (define a 3) (define b 4.5) ; b - это действительное число 4,5 (define c 2/3) ; c - это рациональное число 2/3 (две третих) (define str "some string") ; str - это строка "some string" (define width (+ 2 5)) ; width - это сумма 2 и 5, то есть width - это 7 Если при определении встречается какое-либо выражение, например сумма двух целых чисел из последнего примера, то это выражение вычисляется и переменная полагается равной уже его результату. Кстати a,b,c,str и width - действительно называются переменными. Вас это совершенно не должно смущать ибо с переменными вы сталкивались ещё в курсе школьной алгебры. Итак, записать (define w (+ 1 3)) совершенно равносильно тому что записать (define w 4). Либо вы подсчитаете в уме, либо за вас это сделает Scheme. Ну уж коли мы вспомнили про школу, то теперь мы можем записать известные нам выражения. (+ a b) ; это a + b, где a и b какие-то переменные (* 2 a) ; это 2a, где a какая-то переменная (* a a) ; это квадрат a (* c c c) ; это куб c (+ (* a a) (* b b)) ; это сумма квадратов a и b. Теперь вооружившись полученными знаниями мы можем записывать уже гораздо более сложные программы на Scheme, например такую: (define width 3) (define height 5) (* width height) ; умножить ширину на высоту Наверное вы заметили, что комментарии к коду я пишу начиная их с ";". Это не случайно, все комментарии в тексте программы начинаются с символа ';'. Когда интерпретатор или компилятор читает наш код, весь текст начинающийся с ';' и до конца строки он игнорирует. Ещё одна программа: (define pi 3.1415926) (define radius 15) (* pi radius radius) 2.4 Про истину Если говорить кратко "всё есть истина кроме лжи", то есть 3 - это истина 3.5 - это истина "test" - это истина Вообще все другие типы, которые мы ещё не изучили - это истина. Все кроме лжи, которая имеет обозначение #f. Сразу познакомимся с простейшими логическими операциями: Результат (not 3) - это #f, Результат (not "test") - это тоже #f. Интересно, а какой должен быть результат (not #f) . Истин-то у нас много ;) На этот случай есть истина в первой инстанции, обозначаемая #t. Стало быть результат (not #f) - это #t. 2.5 Разделяй и влавствуй Ещё для счастья нам не хватает объединять повторяющиеся фрагменты в функции, которые можно было бы потом вызывать. Это очень важный и интересный момент в Схеме. Вы наверное часто замечали, что разделение многоэтапной операции на составляющие очень полезно. Например, создание нового процесса, можно разделить на два этапа. Клонирование - fork и замена содержимого клона на другой процесс - exec. Такое разделение позволяет не запускать например новый процесс, когда это не нужно (сразу exec) или не пророждать новый процесс, если клон сам справится с задачей (сразу fork). Вот так и с функциями. Создание функции, например f от одного аргумента, делится на собственно создание одноаргументной функции и на присваивании ей имени f. Как присваивать имена, мы уже знаем - через define, а создание функции описывается следующей конструкцией (lambda (<аргументы>) <инструкции>) Если аргументов нет, то они просто не пишутся. Результат вычисления последней инструкции возвращается в качестве ответа. Примеры: (lambda () (+ 2 5)) ; создать безаргументную функцию, которая вернёт результат суммирования 2 и 5, то есть 7. (lambda () 7) ;тоже самое, функция которая возращает 7. (lambda (x) (* x x)) ;создать одноаргументную функцию от параметра x, которая вернёт результат умножения x на x, то есть вернёт квадрат x. (lambda (x y) (+ x y)) ;создать двухаргументную функцию от параметра x, которая вернёт результат сложения x и y. Теперь совместим создание функции с присваиванием ей имени (define f (lambda() 7)) ;f - это функция без аргументов, которая возвращает 7 (define square (lambda (x) (* x x))) ;square - это функция с одним аргуметном, которая возвращает квадрат переданного ей числа. (define sum (lambda (x y) (+ x y))) ;sum - это функция с двумя аргументами, которая возращает сумму переданных ей двух чисел. Вызываются созданные функции точно также как мы это делали ранее: (имя аргументы) Как я говорил уже синтаксис в Схеме очень регулярный, нет лишних синтаксических конструкций если они не требуются. Ну вот, теперь мы можем ещё больше усовершенствовать наши программы: (define a 3) (define b 5) (define square (lambda (x) (* x x))) (define sum (lambda (x y) (+ x y))) (square 3) ;подсчитать квадрат числа 3, ответ будет 9. (square a) ;подсчитать квадрат a, где a - это 3, то есть ответ будет опять 9. (sum 5 6) ;подсчитать сумму 5 и 6, ответ будет 11 (sum a 7) ;подсчитать сумму a и 7, ответ будет 10 (sum a b) ;подсчитать сумму a и b, ответ будет 8 Продолжение следует .... -- Станислав Иевлев.