Введение в язык Scheme для школьников: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
мНет описания правки
Строка 4:
Вы хорошо знаете русский, возможно, неплохо уже говорите по-английски, в школе вас научили несколько необычному языку математики.
Предлагаю вам выучить ещё один — [[W:LISP|LISP]]. Точнее, один из его самых интересных диалектов — [[w:Scheme|Scheme]] (правильно произносится название как «ским», однако можно говорить и проще — «схема»)
 
Начнём с того, что познакомимся с несколько необычным порядком слов этого языка: «действие объект объект ...». Хотя почему необычным? Вот несколько фраз на русском языке, организованных по тому же принципу:
*«Сумма трёх и пяти.»
*«Произведение пяти, шести и семи.»
*«Купи в магазине хлеб.»
Каждая законченная фраза на этом языке должна быть окружена парой круглых скобок.
Запишем сказанное выше на [[w:Scheme|Scheme]]:
<code>(+ 3 5)
(* 5 6 7)
(buy shop bread)</code>
Можно записать выражения и посложнее:
<code>(+ 2 3 (+ 5 6) )</code>
(+ 2 3 (+ 5 6) ) - «Сумма двух, трёх и суммы пяти и шести.»
«Сумма двух, трёх и суммы пяти и шести.» Просто, не правда ли? Давайте двигаться дальше. Фраза <code>(* 3 5)</code> хороша, а <code>(* width height)</code> — лучше. Выражение <code>(* 2 3.1415926 5)</code> — интригующе, а <code>(* 2 pi radius)</code> гораздо более осмысленно. Здесь <code>width</code>, <code>height</code> — переменные, а 3 и 5 — их текущие значения.
Просто, не правда ли?
 
Давайте двигаться дальше. Фраза «<tt>(* 3 5)</tt> — хороша, а «<tt>(* width height)</tt>» лучше. Выражение «<tt>(* 2 3.1415926 5)</tt>» — интригующе, а
«<tt>(* 2 pi radius)</tt>» гораздо более осмысленно. Здесь <tt>width</tt>, <tt>height</tt> — переменные, а 3 и 5 — их текущие значения.
Переменная задаётся следующей конструкцией языка:
<code>(define имя «первоначальное значение»)</code>
Пример:
<code>(define width 3)
(define height 7)
(* 2 (+ width height))</code>
Прочитаем записанное по-русски: «Положим ширина — это 3, высота — это 7, подсчитаем произведение двух и суммы ширины и высоты (например, периметр прямоугольника)». Результат такого вычисления в нашем случае будет 20.
 
Продолжим совершенствовать конструкции. Допустим, нам требуется подсчитать сумму квадратов двух чисел. Это можно сделать например так:
<code>(define a 3)
(define b 4)
(+ (* a a) (* b b))</code>
Не правда ли, что-то режет глаз? Cлишком громоздко — так мы никогда не говорим. Если бы у нас был в языке глагол который, означал бы «квадрат числа», то последнее выражение звучало бы:
<code>(+ (square a) (square b))</code>
Согласитесь, что так гораздо лучше.
Есть задача — есть её решение. Мы можем объявить новое слово-функцию, назвать её square. Функция будет принимать в качестве параметра число и возвращать его квадрат. Делается это следующим образом:
<code>(define (square x) (* x x))</code>
Общий формат:
<code>(define (название параметр параметр...) тело функции)</code>
Функция возвращает последнее вычисленное значение. Это означает, что следующая функция square2:
<code>(define (square2 x) (+ x x) (* x x))</code>
вернёт тот же результат, что и square, только попутно сделает ещё одно ненужное дело — удвоение числа.
Перепишем пример с суммой квадратов чисел заново:
<code>(define a 3)
(define b 4)
(define (square x) (* x x))
(+ (square a) (square b))</code>
Нам не хватало слов в языке — мы их добавили. Вообще, когда вы пишете программу на [[W:LISP|LISP]], вы описываете не алгоритм, а сначала создаёте язык, а потом на нём формулируете исходную задачу. Несколько точнее — вы «подгоняете» данный вам [[w:Scheme|Scheme]] язык до тех пор, пока он не станет совпадать с языком, на котором задача формулируется легко.
Сразу пример. Пусть перед нами стоит задача сделать программу, которая спрашивает имя пользователя, а потом выводит ему приветствие.
Строка 54 ⟶ 55 :
*username — для получения имени пользователя, без параметров.
На таком языке наша задача выглядела бы следующим образом:
<code>(hello (username))</code>
Дело за малым — определить hello и username. Нет проблем. Вот полный текст программы.
<code>(define (hello name)
(display "Hello ")
(display name)
Строка 64 ⟶ 65 :
(write "Enter your name:")
(read))
(hello (username))</code>
 
[[W:LISP|LISP]] — полноценный функциональный язык, а поэтому функции — полноправные члены этого языка, независимо от того, определили вы их сами, или они уже были в языке «готовые». В частности, их можно передавать в качестве параметров в другие функции, а там уже делать с ними всё, что потребуется.
Например, функцию «модуль числа» можно определить так:
<code>(define (abs x)
(if (positive? x )
x
(- x)))</code>
 
«Если аргумент положителен — возвращается x, иначе минус x».
 
А можно и так:
 
«Если аргумент положителен — возвращается x, иначе минус x». А можно и так:
<code>(define (abs x)
((if (positive? x) + -) x))</code>
«Если аргумент положителен, то плюс, иначе минус x». Здесь в результате исполнения выражения if возвращается функция + или -, которая затем применяется к аргументу x. Кстати, обратите внимание на новую конструкцию if — полагаю, что её назначение вам сразу ясно. Сначала проверяется первый аргумент, если он истинен, то исполняется второй аргумент, иначе третий. Общий формат следующий:
<code>(if условие «действие, если условие выполняется» «действие в противном случае»)</code>
 
== Где посмотреть и попробовать ==
Строка 87 ⟶ 85 :
Вот названия нескольких самых распространённых реализаций:
 
;[http://www.plt-Scheme.org/ Plt Scheme] : одна из самых полных реализаций, включает в себя удобную обучающую среду Dr.Scheme. Есть версии для платформ [[w:Windows|Windows]], [[w:Linux|Linux]], [[w:Mac OS|Mac OS]].
 
;[http://www-sop.inria.fr/mimosa/fp/Bigloo/ Bigloo]: — тоже достаточно полная реализация. Доступна для платформ [[w:Windows|Windows]], [[w:Linux|Linux]].
 
;[http://www.lispme.de/index.html LispMe]: — версия для карманных компьютеров с операционной системой [[w:Palm OS|Palm OS]].
 
Также ещё посмотрите '''[http://www.iro.umontreal.ca/~gambit/ Gambit-C]''' — один из самых быстрых компиляторов [[w:Scheme|Scheme]].
 
Все перечисленные реализации [[w:Scheme|Scheme]] — это интерпретаторы. Запускаете интерпретатор — и можно вести с ним диалог на [[w:Scheme|Scheme]]: в ответ на его приглашение вводите конструкции на [[w:Scheme|Scheme]], а он будет возвращать результаты вычислений.
<code>Wecome to Mz Scheme version 208, Copyright (c) 2004 PLT Scheme, Inc.
>1
1
Строка 104 ⟶ 102 :
>(+ a a)
6
></code>
Попробуйте «проиграть» все вышеперечисленные примеры. Думаю, вам понравится!