Scheme - це дуже проста мова програмування. Її цілком можна вивчити за один день, але ця простота оманлива. Scheme одночасно і дуже потужна мова. Існує величезна кількість реалізацій, я використовую Guile. Встановити інтерпретатор дуже просто:
sudo apt-get install guile
Програми можна або зберігати у *.scm файлах, або можна використовувати інтерактивний режим інтерпретатору, по аналогії з Python.
Константи та змінні
Отже, приступимо до вивчення основних структур Scheme. Перш за все, визначимося з константами:
123 - ціле число
3.1415926 - дробове число
2+3i - комплексне число
2/3 - дріб
#b1111 - двійкове число
#xFF - шістнадцяткове стаття
#o123 - вісімкове число
#\A - одиничний символ
"Hello, World!" - символьний рядок
'hello - символ
#f - логіче значення
З константами можна здійснювати операції з допомогою операторів або функцій. Врешті решт Scheme є функціональною мовою, а тому у ній все є функцією. З математики ви знайомі з формою запису функцій f(x) або t(a,b). Але те ж саме можна записати і у вигляді (f x) чи (t a b). Саме таку форму запису використовує Scheme. З погляду на це, і арифметичні вирази записуються не у звичній багатьом інфіксній формі, як наприклад 2+3, а у префіксній - (+ 2 3). Наприклад:
guile> (* 2 5)
10
guile> (+ (* 3 4) (/ 5 2))
29/2
guile> (+ 1 1 1 1 1)
5
guile> (/ 2)
1/2
guile> (expt 2 3) - степінь
8
guile> (sqrt 2)
1.4142135623731
Для оголошення змінних використовується конструкція (define ім'я значення)
guile> (define a 2)
guile> (define b 2)
guile> (+ a b)
4
Значення вже існуючої змінної можна змінити з допомогою конструкції (set! ім'я значення)
guile> (set! a 5)
guile> a
5
Функції
Функції оголошуються з допомогою конструкції (define (ім'я параметри) тіло_функції)
guile> (define (square x) (* x x))
guile> (square 3)
9
Для демонстрації рекурсії наведу приклад обчислення факторіалу:
(define (fact x)
(if (= x 1)
1
(* x (fact (- x 1)))))
Як ви вже зрозуміли, перевірку умови можна виконувати з допомогою конструкції (if умова якщо_так якщо_ні)
Введення/виведення
Не заглиблюючись у подробиці, зверну увагу на основні функції
(display "Hello, World!") - вивести рядок
(newline) - перейти на новий рядок
(read) - прочитати ввід з клавіатури
Списки
Для роботи з наборами даних зручно використовувати списки
guile> (define nums (list 1 2 3 4 5 6 7 8 9 10)) - оголошуємо список
guile> (list-ref nums 0) - читаємо елемент з номером 0
1
guile> (car nums) - читаємо перший елемент
1
guile> (cdr nums) - читаємо всі інші елементи
(2 3 4 5 6 7 8 9 10)
Можна також обробити всі елементи списку одним заходом
згенерувати новий список застосувавши функцію для кожного елемента
guile> (map square nums)
(1 4 9 16 25 36 49 64 81 100)
guile> (map (lambda (x) (* x 3)) nums)
(3 6 9 12 15 18 21 24 27 30)
Конструкція lambda дозволяє оголошувати функції по мірі потреби, не даючи їм імен. Якщо ви програмуєте на Python'і, то вже знаєте ці конструкції, саме з Lisp'у вони й були запозичені.
Цикли
Насправді, Scheme не має циклів у тому вигляді як вони є в імперативних мовах. Тут для тих же цілей використовується рекурсія. Наприклад, виведемо у стовпчик вміст списку
(define (print-list lst)
(if (not (null? lst))
(begin (display (car lst))
(newline)
(print-list (cdr lst)))))
Конструкція (begin ...) використовується у тому випадку, якщо потрібно вставити декілька операторів там де по синтаксису допускається лише один.
Наступна конструкція дозволяє змоделювати відомий по іншим мовам програмування цикл for:
(let loop ((i 1))
(display i)
(newline)
(if (<= i 10) (loop (+ i 1))))
Конструкція let використовується у тому випадку коли в рамках виразу потрібно оголосити локальні змінні, або якщо потрібно оголосити вкладену функцію. Таким чином можна реалізовувати практично всі можливі варіанти циклів. Звичайно, завжди можна створити власну функцію для скорочення форми запису, адже функції можна передавати у вигляді параметрів інших функцій, так як і прості дані. Взагалі, Scheme дозволяє підігнати мову під себе так як подобається. Вражаюче гнучка мова.
Для прикладу, можна навести реалізацію функції обчислення визначеного інтегралу
(define (func x)
x)
(define (integrate a b e f)
(define sum 0)
(let loop ((i a))
(if (< i b) (begin
(set! sum (+ sum (* (f i) e)))
(loop (+ i e)))))
sum)
(display (integrate 0 1 0.01 func))
(newline)
Звичайно, можна було б продовжувати далі, але це зайняло б дуже багато місця. Основні ж конструкції ми розглянули. Якщо ви зацікавились Scheme, то додаткову інформацію завжди зможете знайти за наступними адресами:
Офіційний сайт Guile
Введение в язык Scheme для школьников
Сторінка про Scheme на сайті MIT
Schemers.org
Відеозаписи лекцій по курсу The Structure and Interpretation of Computer Programs в університеті Berkeley
Взагалі, оскільки Scheme - мова академічна, то інформації по ній досить багато. У той же час, знання даної мови дозволить не лише по новому глянути на різноманітні конструкції в інших мовах (як Python наприклад). Той же Guile, легко інтегрується в програми на C, що дозволяє виносити код назовні.
Для навчання програмування у школі - однозначно Python або Ruby. Щоб не забивати дітям дурним голову.
ВідповістиВидалитиА для вузу підійде будь-яка мова. Всі вони по-своєму корисні для для тренування мозку. :)
Ще дещо про мови. :)
ВідповістиВидалитиhttp://www.aegisub.net/2008/12/if-programming-languages-were-religions.html
Щодо школи, згоден. Python - ідеальний вибір. Тут же я мав на увазі підготовку програміста у технічному вузі. Це вже повинен бути інший рівень.
ВідповістиВидалитиА креатив про мови сподобався.