Faz: uma linguagem funcional didática
Vítor Bujés Ubatuba De Araújo
Prof. Dr. Lucio Mauro Duarte Orientador Prof. Dr. Rodrigo Machado Co-orientador Universidade Federal do Rio Grande do Sul
Instituto de Informática
Motivação
Linguagens funcionais
Diversas aplicações na academia e na indústria
Extensão da álgebra elementar
Composição e aplicação de funções
Interessante no ensino de programação
3/41
Motivação
Racket
How to Design Programs (HtDP)
Ambiente DrRacket
Linguagens didáticas
Problemas recorrentes
Sintaxe
Tipagem dinâmica
Proposta
Faz: nova linguagem
Semântica similar à de Racket
Sintaxe mais familiar
Notação matemática, outras linguagens
Palavras-chave em português
Tipagem semi-estática
Declaração formal dos tipos
Uniões de tipos
Integrada ao ambiente DrRacket
5/41
HtDP – hierarquia de linguagens
Beginning Student
Funções não podem ser argumentos
Operadores como + exigem pelo menos dois argumentos
Sem variáveis locais
...
Beginning Student with List Abbreviations
Introduz sintaxe abreviada para listas
Intermediate Student
Introduz funções como argumentos, variáves locais
Intermediate Student with Lambda
Introduz funções anônimas
Advanced Student
Introduz variáveis/estruturas mutáveis
subconjuntos puramente funcionais
Sintaxe
7/41
Sintaxe – tipos básicos
Números
HtDP
42, -1
355/113, -1/2 3.141592
1+2i, 0+355/113i
(/ 1 2) => 0.5 (ou 1/2) (sqrt 2) => #i1.4142135
Faz
42, -1
355/113, -1/2 3.141592
1+2i, 355i/113 1/2 => 0.5
raiz(2) => 1.4142135
Distinção sintática entre números exatos e inexatos
Eliminada em Faz
Sintaxe – tipos básicos
Strings, caracteres
HtDP
"hello", "\n"
#\h, #\Newline
Faz
"hello", "\n"
'h', '\n'
Sintaxe mais consistente
Similar a C, C++, Java
9/41
Sintaxe – tipos básicos
Booleanos
HtDP
truefalse
Faz
verdadeiro falso
Nomes em português
Sintaxe – tipos básicos
Strings e símbolos
HtDP
"hello world"
'helloworld
Faz
"hello world"
Tipo "símbolos" é redundante no ensino
Representação interna
Substituídos por strings e enumerações em Faz
11/41
Sintaxe – expressões aritméticas
HtDP
(+ 2 3)
(+ (* 2 3) (* 4 5)) (* (+ 2 3) (+ 4 5))
(+ (* a (expt x 2)) (* b x) c)
Faz
2+3
2*3 + 4*5
(2+3) * (4+5) a*x^2 + b*x + c
Operadores infixados
Evitam aninhamento excessivo
Regras de precedência da álgebra
Evitou-se introduzir operadores não familiares
resto(10,3) não 10%3
Sintaxe – expressões lógicas
HtDP
(= 2 3)
(string=? "foo" "bar") (symbol=? 'a 'b)
(char=? #\a #\b) (< x y)
(and (> x 2) (< x 5)) (or (string=? x "foo") (string=? x "bar")) (not (= x 3))
Faz
2 == 3
"foo" == "bar"
"a" == "b"
'a' == 'b' x < y
x>2 e x<5
x=="foo" ou x=="bar"
x != 3 não x==3
HtDP: operadores distintos para cada tipo
Útil para adicionar typechecks em execução
Análise estática em Faz supre essa necessidade
13/41
Sintaxe – variáveis
HtDP
(define x 42)
Faz
seja x = 42
seja x Números = 42∈
Comando seja
Declarações de tipos: conjuntos
Sintaxe – funções
; soma: número número -> número (define (soma x y)
(+ x y)) (soma 2 3)
Declarações de tipos
Posição dos parênteses em HtDP
Diverge da notação matemática
Inconsistente com definição de estrutura
(define (f x y) …)
(define-struct f (x y))
define (não define-function) vs. define-struct
HtDP
Faz função soma(x ∈ Números, y ∈ Números) -> Números devolve x+y
soma(2, 3)
15/41
Sintaxe – condicionais
HtDP
(define (sinal x)
(cond [(< x 0) 'negativo]
[(= x 0) 'neutro]
[else 'positivo]))
Faz
função sinal(x Números) -> Strings∈ se x<0 devolve "negativo"
se x==0 devolve "neutro"
senão devolve "positivo"
Separador explícito entre teste e resultado
Comando explícito de retorno
Testes em série em ambas as linguagens
senão obrigatório em Faz (condicional produz valor)
Serve como delimitador
Sintaxe – estruturas de dados
HtDP
(define-struct pessoa (nome idade))
Faz
tipo Pessoas = { pessoa(nome Strings, idade Números) }∈ ∈
HtDP
(define p
(make-pessoa "Helga" 18)) (pessoa-nome p)
(pessoa-idade p) (pessoa? p)
(pessoa? 5)
Faz
seja p = pessoa("Helga", 18) nome de p
idade de p p Pessoas∈ 5 Pessoas∈
17/41
Sintaxe – enumerações
Faz
tipo Cores = { vermelho, verde, azul }
Suprem principal caso de uso de símbolos
De maneira estruturada
Auxilia detecção de erros
tipo Árvores = { vazia,
nó(valor Números, esq Árvores, dir Árvores) }∈ ∈ ∈
Sintaxe – tipos mistos
HtDP
(define-struct retângulo (lado altura)) (define-struct círculo (raio))
;; Uma forma é:
;; - um retângulo; ou
;; - um círculo.
Faz
tipo Retângulos = { retângulo(lado Números, altura Números) }∈ ∈ tipo Círculos = { círculo(raio Números) }∈
tipo Formas = Retângulos U Círculos
19/41
Sintaxe – tipos mistos
HtDP
;; área: forma -> número
;; Retorna a área de uma forma.
(define (área f) (cond
[(retângulo? f) (* (retângulo-lado f) (retângulo-altura f))]
[(círculo? f) (* PI (expt (círculo-raio f) 2))]
[else (error "Forma desconhecida")]))
Faz
função área(f Formas) -> Números∈ # Retorna a área de uma forma.
se f Retângulos∈
devolve lado de f * altura de f se f Círculos∈
devolve pi * (raio de f)^2 senão
erro "Forma desconhecida"
Sintaxe – listas encadeadas
HtDP
(define lista1
(cons 1 (cons 2 (cons 3 empty)))) (first lista)
(rest lista) (empty? lista) (empty? empty) (cons? lista) (cons? empty) (list? lista) (list? empty) (list? 42)
(define lista2 (list 1 2 3))
Faz
seja lista =
elo(1, elo(2, elo(3, vazio))) primeiro de lista
resto de lista lista == vazio vazio == vazio lista != vazio vazio != vazio
lista Listas de Números∈ vazio Listas de Números∈ 42 Listas de Números∈ seja lista2 = [1,2,3]
Consistência com tipos definidos pelo usuário
21/41
Sintaxe – definições locais
HtDP
(define z 42) (define (foo)
(local ( (define x 1) (define y 2) ) (+ x y)))
Faz
seja z = 42
função foo() -> Números seja x = 1
seja y = 2 devolve x+y
HtDP
Forma especial para declarações locais
Excesso de parênteses, aninhamento
Conceito introduzido no final da disciplina
Faz
Organizada em blocos
Definição local = global (bloco define escopo)
Sintaxe – definições locais
HtDP
(define (bhaskara a b c)
(local ((define delta (- (* b b) (* 4 a c)))) (cond
[(< delta 0) empty]
[else
(local ((define x1 (/ (- (- b) (sqrt delta)) (* 2 a))) (define x2 (/ (+ (- b) (sqrt delta)) (* 2 a)))) (cond
[(= delta 0) (list x1)]
[else (list x1 x2)]))]))
Faz
função bhaskara(a Números, b Números, c Números) -> Números∈ ∈ ∈ seja delta = b^2 - 4*a*c
se delta < 0 devolve []
senão
seja x1 = (-b - raiz(delta)) / (2*a) seja x2 = (-b + raiz(delta)) / (2*a) se delta == 0
devolve [x1]
senão
devolve [x1, x2]
23/41
Sintaxe – comandos e blocos
Faz introduz distinção entre expressões e comandos
Similar a linguagens imperativas
Diferente de outras linguagens funcionais
Blocos definem escopo
Comandos servem como delimitadores implícitos
Faz é uma linguagem funcional
Todo bloco produz um valor
bloco ::= { declarações }* comando-final
teste expr
Sistema de tipos
HtDP: tipagem dinâmica
Dificulta detecção de erros
25/41
Sistema de tipos
HtDP
(define (dobro x) (* 2 x))
(define (f x y) (+ (dobro x) (dobro y))) (f 1 'a)
(f 1 'a)
= (+ (dobro 1) (dobro 'a))
= (+ (* 2 1) (* 2 'a))
= *: expects a number as 2nd argument, given 'a
Faz
função dobro(x Números) -> Números∈ devolve 2*x
função f(x Números, y Números) -> Números∈ ∈ devolve dobro(x) + dobro(y)
f(1, "a")
Sistema de tipos
HtDP: tipagem dinâmica
Dificulta detecção de erros
Tipos documentados por comentários
Mas é flexível
Listas de quaisquer valores
Tipos mistos
Faz
Tipagem semi-estática
Flexibilidade similar a HtDP
Tipos paramétricos (Listas de ?X)
Uniões de tipos
27/41
Sistema de tipos
Tipos básicos
Números
Strings
Caracteres
Booleanos
Tipos especiais
Tudo
Nada
Tipos funcionais
Funções (Números, Números) -> String
Sistema de tipos
tipo Listas de ?X = { vazio,
elo(primeiro ?X, resto Listas de ?X) }∈ ∈ vazio Listas de Nada∈
elo Funções (?X, Listas de ?X) -> Listas de ?X∈
elo(1, [2,3])
Tipos definidos pelo usuário
Pessoas, Cores
Tipos paramétricos
29/41
Sistema de tipos
Uniões de tipos
Números U Strings
Operações válidas sobre um valor do tipo S U T
Abordagem segura vs. flexível
função f(x Números U Strings) -> Números U Strings∈ se x Números∈
devolve x + x se x Strings∈
devolve concatena_strings(x, x) senão
erro "Tipo inválido"
f(5) + 1
Sistema de tipos – uniões vs. polimorfismo
Uniões introduzem subtipagem
Números ⊆ Números U Strings
Quaisquer tipos S e T têm supertipo comum (S U T)
elo(?X, Listas de ?X) -> Listas de ?X
elo(1, ["foo"])
?X = Números U Strings
elo(1, 2)
erro de tipo
31/41
Sistema de tipos – compatibilidade
Tipo de expressão deve ser compatível com contexto
2 + 3
Expressão: 2, tipo Números
Contexto: □+3, tipo Números
S é compatível com T se S T⊆
Números é compatível com Números U Strings
S é parcialmente compatível com T se S T, mas S ∩ T ≠ ⊈ ∅
Números U Strings é parcialmente compatível com Strings U Caracteres
S é incompatível com T se S ∩ T = ∅
Números é incompatível com Strings
Sistema de tipos – compatibilidade
Listas de Números ⊆ Listas de ?X ?
Sim, desde que Números ⊆ ?X
Constraint solving
33/41
Semântica
Faz é traduzido para Racket
Semântica dada pela tradução
Relativamente direta
Tipagem estática perdida na tradução
Regras de tipo triviais em sua maioria
E.g., + espera Números, produz Números
Exceção: seletores
Implementação
1654 linhas de Racket
Integrada ao ambiente DrRacket
35/41
Implementação
1654 linhas de Racket
Integrada ao ambiente DrRacket
Linhas %Total
Integração DrRacket 202 12%
Parsing 364 22%
Semântica 839 51%
Tradução 215 13%
Miscelânea 34 2%
TOTAL 1654 100%
Validação com alunos
Objetivos
Confirmar dificuldades com HtDP
Comparação entre HtDP e Faz
Metodologia
Enquete na lista da graduação da CIC
Formulário anônimo online
60 alunos responderam
Algumas dificuldades relevantes com HtDP
Sintaxe (60% dos alunos)
Tipos de dados (13% dos alunos)
37/41
Validação com alunos
Comparação de linguagens
"Em qual linguagem o programa é mais fácil de compreender e seria mais fácil de escrever?"
Faz Racket Tanto faz Bháskara 92% (55) 3% (2) 5% (3) Grafo 82% (49) 12% (7) 7% (4)
Trabalhos relacionados
Linguagens baseadas no português
Portugol
Linguagens funcionais
De propósito geral
Família LISP (Scheme, Common Lisp, Clojure)
Família ML (Standard ML, OCaml, Miranda, Haskell, Clean)
Didáticas
LOGO, Helium
Outras linguagens didáticas
Pascal
Scratch, Squeak, Etoys
Tipagem estática em Racket
Typed Racket
Faz = português + funcional + didática + tipagem (semi)-estática
39/41
Conclusão
Faz
Linguagem funcional didática baseada no português
Visa a resolver os problemas com Racket, HtDP
Sintaxe
Sistema de tipos
Integrada ao DrRacket
Trabalhos futuros
Ambiente
Error reporting
Indentação e coloração automática
Animação da execução (stepper)
Linguagem
I/O, efeitos colaterais em seqüência
Limitações no uso de polimorfismo
Limitações em testes de pertinência
Formalização do sistema de tipos
41/41