Въведение в схемата

Ken Diki (превод Алексей DESYATNIKOV)

Един алтернативен поглед към света

Във всеки език се определя от гледна точка на света, който го позволява (или не позволява) употреба. Тази серия от статии описва перспективата по света на Схема език за програмиране ( "Схема свят"). Този свят включва много модерен програмни елементи: подкрепа на различни програмни парадигми лесно комбиниращи се използват многократно, абстракции, възможност за създаване на езика "заточени" в дадено приложение, ясно разграничение между преносими и не-преносими части от програмата, мащабируемост от индивидуални средства за сериозен софтуер системи.

Схемата започна като експеримент в език за програмиране проект за тестване на някои от основните разпоредби на теорията на програмирането. Сега тя получава местоположението на много известни университети (като MIT - Масачузетския технически институт) като първи език за програмиране да бъдат проучени. Освен това, схемата се използва в индустрията от компании като декември Texas Instruments. Tektronix. Hewlett Packard и нд

Каква е схемата?

Движеща сила - това е една малка, много "чист" език, който е (много важно!) Fun да използвате. Схемата е проектирана така, че малък брой универсален дизайн може лесно да се използва в различни стилове на програмиране: функционални, обектно-ориентирани и неотложни. Стандартът език отнема само около 50 (!) страници, включително формалното определение за семантика. Схемата се основава на официално модел на ламбда-смятане, така че тук е пълен с функции, лесен за теоретици; Това ви позволява да се изгради много лесно интелигентен софтуер за разработка на приложения.

Схемата има механизъм на лексикалната обхвата, единни правила за изчисляване и еднакво разбиране на типове данни. Схемата няма понятие показалка, неинициализирани променливи, специални циклични структури или подробно за управление на съхранението.

На какво подобна схема? Е, това изглежда като Lisp. Това не бива да плаши: схеми за външен вид могат да бъдат променяни (и с това ние ще направим в бъдеще). Това, което наистина има значение, е на понятията, които са в основата на схеми и възможността за тяхното използване. Така че, нека сравни схемата и някои "класически" език за програмиране - например, Si. Може би вече знаете, че веригата използва префикс бройна система, за разлика от инфикс C:

В схемата, всички видове данни са еднакви. Всичко, което може да се направи с един тип данни може да се направи с всички останали. Това е много по-различен от повечето програмни езици, които имат специални операции за някои типове данни, както и използването на някои други видове данни, специално ограничени. В повечето езици, например, номера имат специални права: те могат да бъдат използвани без възлагане на тях имена (представете си, че, например, че в BASIC всеки номер ще трябва да зададете име преди да го използвате!). Функция, напротив, са ограничени: те трябва да има име.

В схема, функции без име е създаден с помощта на ламбда ключова дума:

(Lambd а (х) (* х х)); резултат - функция!

(Определяне кв.м (ламбда (X) (* х х))

((М- (х) (* х х)) 9); 27

((If (Фу х) * +) 2 3 4); ако (Foo? х) е вярно.

(Дефиниране (къри-добавка х) (ламбда (у) (+ х у))

(Определяне add3 (къри-добавя 3)); add3 - функция

((Къри-добавя 3) 7); 10

- променлива може да включва всякакъв вид стойност;

- имена се отнасят за ценности; Имената не са необходими;

- изразяване - една или повече форми в скоби;

- с цел да се направи оценка на изразяване, трябва първо да се изчисли стойността на всички форми между скобите, след което се прилага стойността на първата форма на останалата част; вложени изрази също се считат форми;

- когато функцията се изчислява, че "помни" състояние "околна среда", в който е създадена (така се добавя 3 спомня, че X е равно на три в неговото начало, т.е. по време на изчисление на експресията (ламбда (у) (+ XY)) 7)).

(Определяне кв.м (ламбда (X) (* х х))

Има седем вида изрази:

- постоянно: "Foo # \ Z 3" низ "

- процедури приложение: (cube37)

- състояние. (Ако (

(Разбира се, този списък съдържа не във всички варианти на изразяване)

Веригата има нормален набор от типове данни:

- букви (характер): # \ а # \ A \ #space # \ нов ред

- низ (стринг): "текстов низ"

- масиви (вектори - векторни): # (от февруари 1 "низ" # \ х5)

- списъци (списък): (малко (списък с) (списъци))

- номер (номера): 47 1/3 2.3 4.3e14 1 + 3i

- логически стойности (.. булева вярно и фалшиво съответно): # т # е

- портове (например отворени файлове или мрежови връзки)

- символи (символ обикновено се използват за означаване на променливи.): това-е-а-symbolfooa32> adfasf23 @ # $%!<

- векторът може да се състои от всеки от тези обекти;

- символ може да съдържа букви от английската азбука, цифри и букви + -. * / <=>. $% _

- символи не е от значение (т.е., символи Символ и идентични символ)

- символи се използват за означаване на променливи (но не само това!)

- по споразумение (за удобство) предикати (прояви на тест стойности) завършват с въпросителен знак, както и "опасен" (промяна на стойността на променливата) функции, завършват с удивителен знак

Numbers са особено интересни в схема: всеки число (число) е фракция (рационално), фракция - реално число (реално) и реално число - комплекса (комплекс). Числата са класифицирани въз основа на точност (точния или приблизителния - точна / неточен):

Схема Философия

Един от най-хубавите черти на схемата, която първоначално много объркващо - няма ограничения. Схемата е много изразителен: програмист може да "говори" на езика една мисъл (действие) в напълно различни начини. В схема програмист има свободата - и отговорността - "говори" точно така, както той иска. В много други програмни езици понякога е необходимо да търсите някои "заобиколни", за да ги стигнем до желаното, а в схемата, просто не е необходимо.

За да "затопли" нека да се изгради структурата на данните "чифт" (чифт). Двойката се състои от два елемента, получени чрез функции за достъп първата и втората (първата и втората, съответно). Функцията ще се нарича сдвояване двойка. Следващите отношения трябва да притежават: (първи (pair12)) е равен на 1, (втора (pair1 2)) е равно на 2. За тези, които знаят Lisp това не е нищо необичайно. Въпреки това, колко различни начина, чрез които може да реализира това трио: двойка. ПЪРВИ. ВТОРИ?

; можете просто да (се определят PAIR вектор). но стилистично по-добре

(Определяне (двойка б) (вектор б))

(Определяне (първи aPair) (вектор-лит aPair 0))

(Определяне (ВТОРО aPair) (вектор-лит aPair 1))

; 2. Функции на избор

; Да не забравяме и лексикален обхват:

; всяка функция за създаване на функции PAIR, ще запомни

; стойности на А и Б по време на

(Определяне (двойка б) (ламбда (BOOL) (ако BOOL а б)))

(Определяне (първи aPair) (aPair #t))

(Определяне (ВТОРО aPair) (aPair #f))

; 3. Съобщения

(Определяне (PAIR (а б)

(Дело съобщ; случай дизайн за всяка стойност съобщ

; взема съответни мерки

((Първи) а); ако съобщението - символ на първо място.

; апостроф ( ') символ, за да се изчисли стойността забранява

; (Без него би било грешка "не е променлива")

(Определяне (ПЪРВИ aPair) (aPair "първо))

(Определяне (ВТОРО aPair) (aPair "втори))

; 4. Псевдоними: вече в схемата има тип "двойка" данни!

(Определяне PAIR минуси)

(Определяне на първата кола)

(Определяне Второ CDR)

; 5. Lambda функции (предавателни функции като другите параметри

(Определяне (двойка б) (ламбда (Proc) (Proc а б)))

(Определяне (първи aPair) (aPair (ламбда (х у) х)))

(Определяне (ВТОРО aPair) (aPair (ламбда (х у) у)))

Целта на всички по-горе: дори и най-простите неща могат да бъдат направени по много различни начини.

Сега, когато сме затопля, нека да разгледаме добрата стара факториел (не забравяйте: факториел - продуктът на всички числа от 1 до даденото число).

Да започнем с това - рекурсивно определение:

Когато (Кен Diki) първо учи рекурсивно определение по този начин, най-трудно да се разбере как латентно състояние функции се съхранява в стека. Малък преобразуване код, като стека видими.

; функция идентичност просто връща аргумента си,

(Определяне (стойност идентичност) стойност)

; Запазване форма, функция факта, че

; (Сега тя просто причинява CFACT функция)

(Определяне (действителност п) (п CFACT идентичност))

; А CFACT функция - Изчислява факториела

(Определяне (CFACT п к)

(М- (резултат) (к (* п резултат))))))

Функция CFACT - версия всъщност функция. Използвайте "продължаване". Вместо да върне резултат всеки път, функция с допълнителен аргумент за "продължаване", който се нарича с резултатите от функцията.

Нека да видим как ще се превърне разговора (fact3):

(Факт 3) става (CFACT 3 идентичност)

(CFACT 3 идентичност) става

(Идентичност (* 3 резултат)))); к "

Това от своя страна се превръща в

(М- (резултат) ;; к ''

(Идентичност (* 3 резултат))); функция к "

(* 2 резултат ")); аргумент подаден к "

((М- (резултат) ;; к ''

(Идентичност (* 3 резултат))) (* 2 резултат "))

((М- (резултат) (идентичност (* 3 резултат))) (* 02 януари))

(Идентичност (* 3 (* 2 1)))

Това е - не е пример за това как просто нещата могат лесно да се направи ужасно сложно. Защо правим това? Идеята, че можем да контролираме, което обикновено се крие в стека. Това ви позволява да се направят някои интересни неща. Ние можем да пренебрегнем едно ", продължи", а вместо това да използвате повече. Ние можем да контролираме, например, дългосрочно изчисления. Ако те отнеме повече време от очакваното, ние можем да поддържаме продължение ( "къде сме") и се опитайте различен подход към решаването на проблема. Ако новият вариант е по-лошо, ние можем да се върне към спасен "продължава" и да продължи изчисляването. Разбира се, можем да поддържаме нашите усилия да направят по-добре в случай, че ако наистина се получи по-добре ...

По този начин, използването на "продължение" ви позволява да се изгради много интересни и гъвкави контролни структури. Нека сега да разгледаме факториела на другата страна. Всеки рекурсивно повикване просто поставя в стека е друг фактор. Но не можем да използваме стека, ако се въведе допълнителен peremennuyu- "батерия". Разбира се, преди изчисляване на батерията трябва да бъде 1 (от х * 1 = Х).

; Ще дефинираме функция за изчисляване на батерия

(Определяне (CFACT _n ACC)

(CFACT (- _n 1) (* _n ACC))

; Ние наричаме тази функция с батерия от 1

Външно, тази функция изглежда е рекурсивно. Въпреки това, той не е така. Схемата има понятието "опашка рекурсия", който елиминира нуждата от конвенционалните цикли. Всяка функция, която нарича себе си в положение "опашка" (т.е., като последното действие) - това е просто един цикъл.

Така че, ние превръща рекурсивни функции в един повтарящ се, цикличен. Има официално (теоретично "правилно") по пътя на тази трансформация; но една хубава черта на схемата е, че тези промени са прости и интуитивни. Правилно работни програми могат да бъдат написани бързо, дори ако на пръв те могат да работят бавно и изисква много памет. След отстраняване на грешки им алгоритъм е лесно да се превърне в много по-ефективен - и също така да работи правилно! Трансформацията програми за опитен програмист в схема се превръща във втора природа.

Веригата има няколко важни предимства пред други езици. Нейният елегантен проста, хомогенна структура и тривиално синтаксис избягва различни "специални случаи". Изражението й дава възможност да не се губи време в търсене на временни решения: програмист може да се съсредоточи върху това, което той трябва да направи, но не и как да го направя. Схемата поддържа множество програмни стилове, включително хип днес, обектно-ориентиран, - така че програмистът не трябва да се коригира по схемата; той може да използва стил или начин на решаване на проблеми, които се използват за. Официалното схема прави доказателство за правилността на програми много по-лесно. Мощен абстракция ви позволи да се отделят части от програмата, които могат да се използват повторно, отчасти, "заточени" под специфичен проблем / изпълнение език / операционната система. Лекотата на комбиниране на различни функции и да се създаде на тяхна основа на нови дизайни ви позволява да създавате цели библиотеки са добре установени, универсални компоненти.

С други думи, ако искате да напишете сложни, коригиране на програмата, но не искам да прекарам годините на плана - това, което трябва да успеем!

Кратък списък на най-известната от схемата.

Схема Chez и MacScheme - някои от най-добрите търговски реализации; Въпреки това има много безплатни компилатори и схеми за преводачи за образователни цели и за сериозна работа.

Един от най-добрите системи за Windows и Linux - MzScheme. и изграден въз основа на нея MrEd (преносима система за създаване на графичен потребителски интерфейс) и DrScheme (може би най-удобният среда за развитие на съществуващи такива).

Така че, тук е частичен списък на схемата: