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

Содержимое удалено Содержимое добавлено
мНет описания правки
мНет описания правки
Строка 5:
 
== Введение в синтаксис==
Начнём с того, чтоСперва познакомимся с несколько необычным порядком слов этого языка: <«действие объект объект ...>предмет». Но необычен он только в сравнении с популярными языками программирования. В русском языке предложения вполне часто строятсятакая подобнымпоследовательность образомнередка:
*<«Сумма трёх и пяти.>»
*<«Произведение пяти, шести и семи.>»
*<«Купи в булочной батон.>»
Каждая законченная фраза на этом языке должна быть окружена парой круглых скобок.
Запишем сказанное выше на [[w:Scheme|Scheme]]Скиме:
<source lang=scheme>(+ 3 5)
(* 5 6 7)
(kupitj bulochnaja baton)</source>
Можно записать выражения и посложнее:
<source lang=scheme>(+kupitj 2bulochnaja 3baton (+ 52 61) )</source>
<Сумма«Купи двух,в трёхбулочной ибатоны: суммыдва пятиплюс иещё шестиодин.>» Просто, не правда ли? Давайте двигаться дальше. Фраза <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 - их текущие значения.
 
Переменная задаётся следующей конструкцией языка:
Строка 24:
(define height 7)
(* 2 (+ width height))</source>
Прочитаем записанное по-русски: <«Положим ширина - это 3, высота - это 7, подсчитаем произведение двух и суммы ширины и высоты (например, периметр прямоугольника)>». Результат такого вычисления в нашем случае будет 20.
 
Продолжим совершенствовать конструкции. ДопустимПоложим, нам требуется подсчитать сумму квадратов двух чисел. Это можно сделать, например, так:
<source lang=scheme>(define a 3)
(define b 4)
(+ (* a a) (* b b))</source>
Что-то не так; мы обычно вместо «помножь переменную на саму себя» говорим «возведи в квадрат эту переменную», на Скиме — <code>square</code>:
Не правда ли, что-то режет глаз? Cлишком громоздко - так мы никогда не говорим. Если в русском был бы глагол <квадрат числа>, то последнее выражение звучало бы:
<source lang=scheme>(+ (square a) (square b))</source>
«Сумма квадрата <var>a</var> и квадрата <var>b</var>.» Есть задача - есть её решение. Мы можем объявить новое слово-функцию, назвать её <code>square</code>. Функция будет принимать в качестве параметра число и возвращать его квадрат. Делается это следующим образом:
Согласитесь, что так лучше.
Есть задача - есть её решение. Мы можем объявить новое слово-функцию, назвать её square. Функция будет принимать в качестве параметра число и возвращать его квадрат. Делается это следующим образом:
<source lang=scheme>(define (square x) (* x x))</source>
Общий формат:
<source lang=scheme>(define (название параметр параметр...) тело функции)</source>
Функция возвращает последнее вычисленное значение. Это означает, что следующая функция square2:
<source lang=scheme>(define (square2 x) (+* x2 x2) (* x x))</source>
вернёт тот же результат, что и square, толькоперед попутноэтим сделаетумножив ещёдва однона ненужноедва делобезо -всякого удвоение числаэффекта.
Перепишем пример с суммой квадратов чисел заново:
<source lang=scheme>(define a 3)
Строка 45 ⟶ 44 :
(define (square x) (* x x))
(+ (square a) (square b))</source>
Нам не хватало слов в языке - мы их добавили. Вообще, когда вы пишете программу на [[w:Лисп|Лисп]]Лиспе, выВы описываете не алгоритм, а сначала создаёте язык, а потом на нём формулируете исходную задачу. Несколько точнее - вы <«подгоняете>» данный вам язык [[w:Scheme|Scheme]] язык до тех пор, пока он не станет совпадать с языком, на котором задача формулируется легко.
 
Сразу пример. Пусть перед нами стоит задача сделать программу, которая спрашивает имя пользователя, а потом выводит ему приветствие.
[[w:Scheme|Scheme]] предоставляет нам несколько готовых <«глаголов>»:
;<code>read</code>:для чтения имени
;<code>display</code>:вывод чего-то на дисплее
;<code>newline</code>:вывод перевода строки
Мы бы хотели иметь такие <«глаголы>»:
;<code>privet</code>:для приветствия с одним параметром - именем пользователя
;<code>polzovatel</code>:для получения имени пользователя, без параметров.
Строка 67:
(privet (polzovatel))</source>
 
[[w:Лисп|Лисп]] - полноценный функциональный язык, а поэтому функции - полноправные члены этого языка, независимо от того, определили вы их сами, или они уже были в языке <готовые>. В частности, их можно передавать в качестве параметров в другие функции, а там уже делать с ними всё, что потребуется.
Например, функцию <«модуль числа>» можно определить так:
<source lang=lisp>(define (abs x)
(if (positive? x )
Строка 74:
(- x)))</source>
 
<Если«Определим, аргументчто положителен - возвращаетсяфункция <code>xabs</code> возвращает свой аргумент, если он положителен, иначе минус <codevar>x</code>var>». А можно и так:
<source lang=scheme>(define (abs x)
((if (positive? x) + -) x))</source>
<Если«…если аргумент положителен, то плюс, иначе минус <var>x</var>». Здесь в результате исполнения выражения <code>if</code> возвращается функция <code>+</code> или <code>-</code>, которая затем применяется к аргументу <code>x</code>. Полагаю, что смысл конструкции <code>if</code> вам сразу ясен. Сначала проверяется первый аргумент, если он истинен, то исполняется второй аргумент, иначе третий. Общий формат таков:
<code>(if условие <действие, если условие выполняется> <действие в противном случае>)</code>
 
Строка 86:
 
;[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]].
 
Строка 94 ⟶ 92 :
 
Все перечисленные реализации Scheme — это интерпретаторы. Запускаете интерпретатор — и можно вести с ним диалог на [[w:Scheme|Scheme]]: в ответ на его приглашение вводите конструкции на Scheme, а он будет возвращать результаты вычислений.
<code>{{console|Wecome to Mz Scheme version 208, Copyright (c) 2004 PLT Scheme, Inc.
>1
1
Строка 102 ⟶ 100 :
>(+ a a)
6
></code>}}
Попробуйте «проиграть» все вышеперечисленные примеры. Думаю, вамВам понравится!
 
== Кто в мешке ==
Строка 109 ⟶ 107 :
 
=== Упражнение ===
Посмотрите следующие две реализации функции вычисления [[w:Факториал|факториала]] <math>f(n)=1 \cdot 2 \cdot \cdots \cdot n</math>. Одна из них основана на [[w:Рекурсия|рекурсии]], а другая – на [[w:Итерация|итерациях]]. Напишите на языке [[w:Scheme|Scheme]]Скиме рекурсивную и основанную на итерациях реализации функции возведения в степень <math>f(a,n) = a^n</math>.
 
==== Вариант 1 ====
Строка 126 ⟶ 124 :
 
==Повторение – мать учения==
Приведём небольшую шпаргалку по базовым конструкциям языка программирования [[w:Scheme|Scheme]] для тех, кто еще не ознакомился с первой частью [[Введение в язык Scheme для школьников|статьи]].
 
Базовый синтаксис:
Строка 241 ⟶ 239 :
(+ c 1)</source>
 
А как бы нам сразу взять три числа и увеличить их на единицу одним махом? Для этого надо <«связать>» эти числа вместе. Один из способов склеивания - список. Создаётся список следующей конструкцией:
<source lang=scheme>(list <элемент1> <элемент2> <элемент3> ...)</source>
 
Строка 254 ⟶ 252 :
<source lang=scheme>(map <функция> <список>)</source>
 
Эта функция возвращает список, в котором каждый элемент есть результат применения функции "<функция>" к элементу исходного списка. Пример:
<source lang=scheme>(define (inc x) (+ x 1)); увеличивает число на единицу
(map inc (list 1 1 1)); возвращает список из двоек
Строка 322 ⟶ 320 :
== См. также ==
 
* Викиучебник «[[Лисп]]»
* [[w:Лисп|Лисп]], статья в Википедии
* [[w:Scheme|Scheme]], статья в Википедии