Scheme foi criada em 1975 no laboratório de AI do MIT por Guy L. Steele e Gerald J. Sussman que queriam criar uma linguagem de semântica simples e clara. Scheme foi influenciada pelo cálculo lambda, que é uma das primeiras linguagens de programação funcional no mundo, também teve seu escopo estático herdade de Algol e a sintaxe de Lisp. É uma linguagem muito bem desenhada e de propósito geral. • A flexibilidade de Scheme é gatantida devido a ausência de restrições, assim o porder da linguagem não limitando . • Utilização de sistema de recursão denominado “Tail Recursion” (recursão de cauda). • Homogeneidade com sua notação pré-fixada, ou seja, existe basicamente uma regra que rege a escrita de qualquer expressão: (+ 2 3) (squart 5) (f x y) • A passagem de parâmetros é feita por valor. • Utilização de Listas como mecanismo básico de estruturação de dados. • Suporta multiplos-paradigmas como, programação funcional, imperativa , orientação a objetos, etc. • Boolean: • #t = True (Qualquer coisa diferente de zero e “Lista vazia”). • #f = False (Zero ou “Lista vazia”). • Numbers: • Number = (42). • Complex = (2+3i). • Real = (3.1416), (22/7), (42) • Numbers: • Rational = (3.1416), (22/7) • Integer = (42). • Number = Complex = Real = Rational = Integer. • Characteres: São representados pela prefixo #\ • #\c = caracter (c). • #\newline = (nova linha). • #\space = (espaço em branco). • Symbols: • Apesar de ser tipo simples, ou seja, primitivo como os anteriores, são tratados como identificadores de variáveis, portanto seu valor é o valor contido na mesma. • Para especificarmos um símbolo usamos a palavra reservada quote ou aspa simple antes do símbolo. • Symbols: • (quote xyz) => xyz • ‘E => E • String: • Não é um tipo simples, ou seja, primitivo como os anteriores, é composta pela combinação de caracteres, sendo assim uma seqüência de caracteres de modo estruturado e entre aspas duplas “”. • String: • (string #\h #\e #\l #\l #\o) ) => "hello" • "Hello, World!" => "Hello, World!" • Vectors: • São seqüências como as Strings mas, seus elementos podem ser uma seqüência de qualquer tipo e não apenas de caracteres. • (vector 0 1 2 3 4) => #(0 1 2 3 4) • Dotted pair: • É composto de dois valores arbitrarios, sendo o primeiro chamado de car e o segundo de cdr e sua combinação é realizada com a palavra reservada cons. • Dotted pair: • (cons 1 #t) => (1 . #t) • List: • Listas podem ser construídas simplesmente colocando os valores desejados entre parênteses e utilizando aspa simple antes do primeiro parêntese ou utilizando a palavra reservada list. Listas podem conter qualquer valor inclusive lista de lista. • List: • > ‘(2 4 6 8 10) => (2 4 6 8 10) • > (list 2 4 6 8 10) => (2 4 6 8 10) • List: • Assim como em vetores, podemos utilizar car e cdr para acessarmos o 1º elemento e o restante da lista respectivamente. • > (car (list 2 4 6 8 10)) => 2 • List: • > (cdr (list 2 4 6 8 10)) => (4 6 8 10) • > (car (cdr (list 2 4 6 8 10))) => 4 • List: • Podemos utilizar várias combinações de car e cdr. • > (cadr (list 2 4 6 8 10)) => 4 • > (cddr (list 2 4 6 8 10)) => (6 8 10) • List: •(caar ls) ; • (cadr ls) ; •(cdar ls) ; •(cddr ls) ; •(caaar ls) ; •(caadr ls) ; •(cadar ls) ; •(caddr ls) ; •(cdaar ls) ; •(cdadr ls) ; •(cddar ls) ; •(cdddr ls) ; is the same as (car (car ls)) is the same as (car (cdr ls)) is the same as (cdr (car ls)) is the same as (cdr (cdr ls)) is the same as (car (car (car ls))) is the same as (car (car (cdr ls))) is the same as (car (cdr (car ls))) is the same as (car (cdr (cdr ls))) is the same as (cdr (car (car ls))) is the same as (cdr (car (cdr ls))) is the same as (cdr (cdr (car ls))) is the same as (cdr (cdr (cdr ls))) • List: •(cadaar ls) ; •(cadadr ls) ; •(caddar ls) ; •(cadddr ls) ; •(cdaaar ls) ; •(cdaadr ls) ; •(cdadar ls) ; •(cddadr ls) ; •(cdddar ls) ; •(cddddr ls) ; is the same as (car (cdr (car (car ls)))) is the same as (car (cdr (car (cdr ls)))) is the same as (car (cdr (cdr (car ls)))) is the same as (car (cdr (cdr (cdr ls)))) is the same as (cdr (car (car (car ls)))) is the same as (cdr (car (car (cdr ls)))) is the same as (cdr (car (cdr (car ls)))) is the same as (cdr (cdr (car (cdr ls)))) is the same as (cdr (cdr (cdr (car ls)))) is the same as (cdr (cdr (cdr (cdr ls)))) • Existem três tipos de expressões condicionais: • Usando a palavra reservada If. • Usando a palavra reservada Cond. • Usando a palavra reservada Case. • Expressão condicionail If : • (if condição conseqüência alternativa) • (if condição conseqüência) • Expressão condicionail If : • (if (< a b) (square a) (square b)) • (if (< x1 x2) (> x2 x3) (if (> x1 x2) (< x2 x3) #f)) • Expressão condicionail Cond : • (cond (condição1 conseqüência1) (condição2 conseqüência2) . . . (else alternativa)) • Expressão condicionail Cond : • (cond ((> a b) (square a)) ((> b c) (square b)) . . . (else (square c))) • Expressão condicionail Case : • (case arg expr1 expr2 expr3 ...) • Expressão condicionail Case : • (case (+ 3 4) ((7) 'seven) ((2) 'two) (else 'nothing)) => seven • Expressão condicionail Case : • (case 'a ((a b c d) 'first) ((e f g h) 'second) (else 'rest)) => first • Existem três tipos de expressões lógicas: • Usando a palavra reservada And. • Usando a palavra reservada Or. • Usando a palavra reservada Not. • Expressões lógica com And: • (and expr1 expr2 ... exprn) • Expressões lógica com And: • (and (< 2 5) (< 2 4)) =>#t • Expressões lógica com Or: • (or expr1 expr2 ... exprn) • Expressões lógica com Or: • (or (< 2 5) (< 2 4)) =>#t • Expressões lógica com Not: • (not expr) • Expressões lógica com Not: • (not (< 5 10)) => #f • Utilizamos a palavra reservada define para declarar variáveis globais: • (define a 10) a =>10 • Utilizamos a palavra reservada set! Para alterar variáveis: • (define a 10) a =>10 (set! a 5) a => 5 • Podemos declarar procedures utilizando a palavra reservada define ou lambda. Não existe diferença entre as declarações. • (define square (lambda (x) (* x x))) • Utilizando a palavra reservada define: • (define (square x) (* x x)) • (square 2) => 4 • Utilizando a palavra reservada lambda: • (lambda formal-parâmetros body) • (lambda (x) (* 2x) 5) => 10 • Utilizamos a palavra reservada let e let* para criar variáveis locais. A diferença entre as duas declarações é que let* é um aninhamento de lets, ou seja, uma variável declarada em um let mais a esquerda pode ser usada em um let mais a direita. • (let ((var1 exp1) (var2 exp2) . . . (varn expn)) body) • Utilizando a palavra reservada let. • (let ((x 2) (y 10)) (+ x y)) => 12 • (let ((x 2) (y 10)) (/ y x)) => 5 • Utilizando a palavra reservada let. • (define x 10) (+ (let ((x 5)) (* x (+ x 2))) x) => 45 • (define x 10) (let ((x 5) (y (* x 2))) (+ x y)) => 25 • Utilizando a palavra reservada let*. • (let* ((var1 exp1) (var2 exp2) ... (varn expn)) body) • O que é equivalente a: • (let ((var1 expr1)) (let ((var2 expr2)) (let ... (let ((varn exprn)) body) ... ))) • Utilizando a palavra reservada let*. • (define x 10) (let* ((x 5) (y (* x 2))) (+ x y)) => 15 • Comparando let com let*. • (define x 10) (let ((x 5) (y (* x 2))) (+ x y)) => 25 • (define x 10) (let* ((x 5) (y (* x 2))) (+ x y)) => 15 • Utilizando a palavra reservada do. • É uma construção de iteração complexa, onde algumas variáveis são especificadas, a inicialização de algumas também e o passo, ou seja, um controle de loop. É um loop parecido com o for. • (do ((var1 init1 step1) ...) (test expr ...) command ...) • Utilizando a palavra reservada do. • (do ((str (string #\f #\o #\o #\b #\a #\r)) (i 0 (+ i 1 ))) ((= i (string-length str ) ) str ) (string-set! str i #\b)) • A saída será: • => "bbbbbb" • Utilizando a palavra reservada letrec. • (letrec ((var1 val1) (var2 val2) ... (varn valn)) body) • Utilizando a palavra reservada letrec. • (define factorial (lambda (n) (letrec ((iter (lambda (product counter) (if (> counter n) product (iter (* counter product) (+ counter 1)))))) (iter 1 1))) • Tail recursion. • São chamadas recursivas que não necessitam de alocação dinâmica na memória, ou seja, utilização de empilhamento de chamadas recursivas. Cada chamada já passa a resposta da sua iteração para a próxima iteração, assim não precisamos de fazer o desempilhamento devolvendo a resposta de cada chamada recursiva para combinarmos e encontrarmos a resposta final. • Utilizando Tail recursion. • (define (factorial-tail n) (factorial-helper n 1)) (define (factorial-helper n total) (if (equal? n 0) total (factorial-helper (- n 1) (* n total)))) • Utilizando Tail recursion. • A saída será: • (factorial-tail 5 ) => 120 • Utilizando Recursão normal. • (define (factorial n) ( if (equal? n 0) 1 (* n (factorial (- n 1 ))))) • Utilizando Recursão normal. • A saída será |(factorial 5) | (factorial 4) | |(factorial 3) | | (factorial 2) | | |(factorial 1) | | | (factorial 0) |||1 | | |1 ||2 | |6 | 24 |120 • Para gerarmos a saída “Hello World” usamos o seguinte código: • (display "Hello World!") (newline) => Hello World! => • • • • • • • (define bottles (lambda (n) (cond ((= n 0) (display "No more bottles")) ((= n 1) (display "One bottle")) (else (display n) (display " bottles"))) (display " of beer"))) • (define beer (lambda (n) (if (> n 0) (begin (bottles n) (display " on the wall") (newline) (bottles n) (newline) (display "Take one down, pass it around") (newline) (bottles (- n 1)) (display " on the wall") (newline) (newline) (beer (- n 1)))))) • (beer 99) • • • • • • • • • • • • • http://en.literateprograms.org/Hello_World_(Scheme) http://www.cs.hut.fi/Studies/T-93.210/schemetutorial/node1.html http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html http://pheattarchive.emporia.edu/courses/2002/cs220f02/anotherSchemeTtutorial/default.htm http://www.inf.ufsc.br/~barreto/trabaluno/PF_Geraldo_Maria.pdf Festa com 99 bottles of the beer (youtube) • • • http://www.youtube.com/watch?v=vWKKuBblumo http://www.youtube.com/watch?v=n_C7Rj2qMMs&feature=related http://www.youtube.com/watch?v=PyEMGDa8Jcg&feature=related Concurso Talent Explosion e vídeo no youtube • • http://www.youtube.com/watch?v=lQrOhQhdoQI&feature=related http://www.shawnlam.ca/jackfm/