Vous êtes sur la page 1sur 13

A linguagem de programao funcional Sloth

Diego Fernandes Nehab Roberto Ierusalimschy

Departamento de Informtica, PUC-Rio R. Marqus de So Vicente 225, Gvea, Rio de Janeiro, 22453-900
{diego,roberto}@inf.puc-rio.br

Abstract. Sloth is a simple, easy to learn, non-strict, purely functional programming language, designed to be a test bed for research on the compilation of functional programming languages. Its hybrid architecture innovates on the different programming languages chosen for its construction and resulted in the creation of a concise, self contained and portable implementation. This article introduces Sloth as a programming language, describes part of the research work currently taking advantage of the system and details its implementation, about to be completed. Resumo. Sloth uma linguagem de programao simples, de fcil aprendizagem, funcional pura e no estrita, projetada para servir como ambiente de testes para pesquisas sobre a compilaco de linguagens de programao funcionais. Sua arquitetura hbrida inova com relao s diferentes linguagens de programao escolhidas para sua construo e resultou na criao de uma implementao concisa, autocontida e porttil. Este artigo apresenta a linguagem de programao Sloth, descreve o trabalho de pesquisa que atualmente se benecia do sistema e detalha sua implementao, prestes a ser concluda.

1 Introduo
Sloth uma linguagem de programao concisa e de fcil aprendizagem que surgiu da necessidade de uma anlise concreta da ecincia de novas tcnicas a serem usadas na compilao de programas funcionais. A deciso pela criao de uma nova linguagem, em oposio a adaptao de uma linguagem existente, teve como fatores determinantes a grande complexidade das implementaes disponveis, bem como a maior liberdade obtida com o projeto de todos os aspectos da linguagem. Por isso, mesmo oferecendo muitos dos recursos bsicos existentes em linguagens de programao semelhantes, Sloth, uma linguagem funcional pura, no estrita e com tipagem parametricamente polimrca, destaca-se por sua simplicidade. As tcnicas de compilao investigadas baseiam-se no uso de rvores combinatrias como cdigo-objeto para programas funcionais [Turner, 1979b]. Os Combinadores Microprogramados, desenvolvidos pela pesquisa em andamento, capturam e estendem a essncia dos combinadores de longo alcance descritos por [Turner, 1979a]. Sloth foi criada para auxiliar na anlise da ecincia da codicao de programas funcionais com o uso dos novos combinadores e para simplicar o estudo de seu efeito sobre o tamanho das rvores combinatrias resultantes. 1

A experincia adquirida com a implementao de uma primeira verso de Sloth e o estudo de implementaes de outras linguagens orientou a adoo de uma arquitetura hbrida pouco convencional para a construo da nova verso do sistema. Para a implementao de todas as fases intermedirias, nas quais a expressividade da linguagem de programao usada tem grande impacto, foi escolhida uma linguagem interpretada, com tipagem fraca e gerncia automtica de memria (Lua). J para a construo das etapas executadas durante a avaliao do programa, nas quais se faz necessria uma maior preocupao com ecincia, foi escolhida uma linguagem de programao tradicional, compilada (ANSI C). A associao entre as vantagens das duas linguagens vem apresentando bons resultados medida que a construo do sistema se aproxima de sua concluso. Dentre as preocupaes que mais inuenciaram os rumos do projeto de Sloth, destacam-se a simplicidade, ecincia, a portabilidade e a disponibilidade. A simplicidade permeia tanto sua especicao quanto sua implementao. Sloth no visa o estabelecimento de um novo padro para programao funcional e tampouco ruma criao de uma nova linguagem de uso genrico. A preocupao com a ecincia vem do desejo de que Sloth seja til na prtica, principalmente em atividades didticas que tirem partido da simplicidade de sua especicao. A portabilidade permite que Sloth opere em uma grande variedade de sistemas operacionais e processadores. Finalmente, a licena de Sloth no restringe seu uso gratuito em aplicaes acadmicas e comerciais, e as ferramentas usadas em seu desenvolvimento so amplamente disponveis. Ocasionalmente, alguns desses quesitos entram em conito. Nesses casos, o compromisso com a simplicidade acaba determinando a direo seguida. 1.1 Panorama do artigo Este artigo prossegue com a apresentao de Sloth como uma linguagem de programao, na Seo 2. A Seo 3 descreve brevemente as novas tcnicas de compilao usadas em Sloth. Em seguida, a Seo 4 detalha a arquitetura escolhida para a implementao do sistema. Por m, a Seo 5 discute os rumos futuros da pesquisa e conclui o artigo.

2 A linguagem de programao
A sintaxe de Sloth inspirada na sintaxe de Haskell, na qual alguns recursos foram omitidos de modo a simplicar sua especicao. A lista abaixo resume as principais caractersticas da linguagem de programao Sloth, buscando situ-la frente s demais linguagens de programao funcionais. Sloth uma linguagem aplicativa, funcional pura; Sloth no estrita e preguiosa; Sloth suporta tipos de dados estruturados; A tipagem de Sloth dinmica e parametricamente polimrca; Funes de qualquer ordem so valores de primeira classe; Funes podem ter denies mltiplas baseadas em casamento de padres; O sistema de escopo de Sloth esttico.

Lexicamente, Sloth uma linguagem sensvel a caixas alta e baixa, de com denies convencionais para identicadores, constantes numricas, caracteres e seqncias 2

de caracteres. Comentrios so iniciados pela seqncia -- e continuam at o m da linha. Uma das principais diferenas entre a sintaxe de Sloth e a de Haskell reside no fato de Sloth ser uma linguagem de formato livre. Assim sendo, a indentao do cdigo ca a critrio do programador, e no tem inuncia no resultado nal. A seguir, uma breve exposio da sintaxe da linguagem ser apresentada com o auxlio de exemplos. Os nicos tipos de dados primitivos em Sloth so os tipos Number e Char. Os tipos Bool e List so predenidos. Os demais tipos de dados so declarados a partir dos tipos primitivos, seguindo-se a sintaxe usual para declaraes na forma de soma de produtos.
type Tree a = leaf a | branch (Tree a) (Tree a);

Sloth suporta funes com denies mltiplas baseadas no casamento de padres sobre seus argumentos. O casamento de padres se d pela anlise dos construtores ou valores dos argumentos e se estende a tipos estruturados denidos pelo usurio.
fat 0 = 1 | x = x * fat (x-1); sign x = -1, | x = 0, | x = 1, x < 0 x == 0 otherwise;

cond true e2 e3 = e2 | false e2 e3 = e3; reflect (leaf x) = leaf x | (branch a b) = branch (reflect b) (reflect a);

A linguagem suporta ainda operadores inxados como uma alternativa mais confortvel para a construo de expresses complexas, seguindo as precedncias usuais. Tambm so aceitas expresses na forma prexada, usada internamente pela linguagem, com literais representando cada operao. Listas podem ser denidas das formas tradicionalmente encontradas em outras linguagens funcionais, sendo que as listas de caracteres, por serem to comuns, podem ser denidas entre aspas duplas. Sloth tambm suporta funes annimas, denies locais recursivas ou no e expresses case, conforme ilustram as declaraes abaixo:
length = \list -> (case list of nil -> 0 | cons x xs -> 1 + length xs); gcd x y = letrec gcd x 0 = x | x y = gcd y (x % y) in gcd (floor (abs x)) (floor (abs y));

Por m, apresentamos um exemplo completo com o intuito de demonstrar que a simplicidade da especicao da linguagem no prejudica sua expressividade na realizao de tarefas relevantes. 3

Nmeros primos Dene a lista de todos os nmeros primos pelo Crivo de Eratstenes.
sequence n = n : sequence (n + 1); filter f [] = [] | f (x:xs) = let r = filter f xs in if f x then x : r else r; sieve (p:xs) = p : sieve (filter (\x -> x % p != 0) xs);

primes = sieve (sequence 2);

3 Combinadores Microprogramados
Apesar de ser usada por tericos desde a dcada de 1920, a Lgica Combinatria [Curry et al., 1972] ganhou maior divulgao a partir do nal da dcada de 1970, quando passou a ser usada na prtica para a implementao de linguagens funcionais [Turner, 1979b]. Alm de ser de fcil implementao, a tcnica permite, com grande naturalidade, funes no estritas e realiza avaliao preguiosa. Na poca, implementaes com essas propriedades eram muito mais complexas e muito menos ecientes. Infelizmente, em sua formulao original, o processo de abstrao de variveis sucessivas pela introduo de combinadores pode causar uma exploso no tamanho da expresso resultante. Por conseqncia, o processo de reduo torna-se muito custoso, tanto em tempo quanto em espao. Para tornar a tcnica vivel, Turner adicionou os combinadores de longo alcance S , B e C [Turner, 1979a] aos tradicionais S, K, I, B e C (veja a Tabela 1). Ainda assim, o tamanho de uma expresso, medido pelo nmero de constantes e variveis, pode crescer de forma (n2 ) [Kennaway, 1982]. Alm disso, a ao de cada combinador muito restrita e o processo de reduo tende a ser composto por uma grande quantidade de pequenos passos, o que pode prejudicar o uso do cache e sobrecarregar o coletor de lixo.
S K I B f f x f g x = g x = f x (g x) = f x x = f (g x) C S B C f c c c g f f f x g g g = x x x f = = = x c c c g (f x) (g x) f (g x) (f x) g

Tabela 1: Combinadores de Turner.

Ao longo dos anos seguintes, tentativas de solucionar esses problemas deram origem a varias alternativas. O balanceamento das expresses antes que sejam submetidas abstrao de variveis consegue garantir tamanhos O (n log n) [Burton, 1982]. O agrupamento de combinadores referentes a abstraes de variveis sucessivas em seqncias diretoras, quando representadas de forma compactada (counting director strings) [Kennaway and Sleep, 1987], alcana resultado semelhante. Como, no pior caso, o tamanho de uma expresso compilada sob um conjunto nito de combinadores est limitado por (n log n) [Joy et al., 1985], no h muito espao para melhorias nessa linha. 4

Tirando partido de um conjunto innito de combinadores, os supercombinadores [Johnsson, 1985, Hughes, 1982], possvel obter resultados que variam, em mdia, linearmente com o tamanho da expresso. A representao de supercombinadores por um conjunto linear de instrues (G-Machine) [Johnsson, 1984] aumenta a granularidade dos passos e diminui o tamanho nal da representao, levando a uma das mais ecientes tcnicas para a implementao de linguagens funcionais [Jones, 1992]. O sucesso desta tcnica foi provavelmente um dos responsveis pela recente perda de interesse nos combinadores de Turner, que passaram a ser mais respeitados por sua simplicidade que por sua ecincia. Outros mtodos, mais eis s idias de Turner, so tambm baseados em conjuntos innitos de combinadores, porm mais restritivos. As restries muitas vezes facilitam a representao dos combinadores possveis. Representaes parametrizadas por nmeros podem ser encontradas em [Noshita, 1985] e [Abdali, 1976]. Os Combinadores Microprogramados, propostos neste artigo, adotam uma estratgia semelhante, buscando uma soluo mais eciente que os combinadores de Turner porm sem a complexidade dos supercombinadores. A parametrizao, entretanto, feita por seqncias de operaes primitivas, que resultam de uma decomposio das alteraes realizadas pela reduo dos combinadores de Turner em operaes mais bsicas. A nova codicao, alm de representar uniformemente todos os combinadores da Tabela 1, d origem a uma famlia innita de combinadores com alcance ilimitado. Dado que os combinadores de Turner podem ser vistos como instrues a serem executadas por uma mquina redutora de grafos, a nova codicao pode ser associada a um nvel de abstrao mais baixo, correspondente ao do microcdigo. Da o nome Combinadores Microprogramados. 3.1 A famlia de combinadores L A avaliao de qualquer um dos combinadores da Tabela 1 afeta apenas uma pequena vizinhana da espinha da expresso na qual se encontram. Em cada n da espinha, as alteraes realizadas podem ser descritas por apenas trs operaes primitivas. A famlia de combinadores L representa os combinadores que podem ser parametrizados por seqncias dessas operaes. @ @ @ @ @ L t1
(a)

@ x @ @ @ T1 T2
(b)

Tn1 T3

tn1 t3

t2

Figura 1: L . (b) mostra o resultado da avaliao de L em (a).

Na Figura 1, o parmetro de L controla a forma de cada Ti , determinando se assumir o valor ti ou (ti x). L capaz ainda de introduzir o parmetro x nas posies determinadas por , entre os Ti . Essas trs operaes primitivas so representadas pelos seguintes smbolos: p Ti = (ti x) d T i = ti i insero de x

A distino entre o tratamento dado primeira subrvore, que posicionada esquerda de um n de aplicao, e s demais, que so posicionadas direita, feita pelo uso de smbolos maisculos e minsculos, respectivamente. A Figura 2 mostra o resultado da avaliao de um Combinador Microprogramado, sem correspondente no conjunto usado por Turner, que aparece frequentemente no cdigo objeto gerado por Sloth. @ @ @ LDpi t1
(a)

@ x @ t1 t2
(b)

x @ x

t2

Figura 2: LDpi . (b) mostra o resultado da avaliao de LDpi em (a).

A avaliao do Combinador Microprogramado feita por uma mquina muito simples que, aps certicar-se que o nmero necessrio de argumentos est presente (3 no caso da Figura 2), executa as microinstrues presentes no parmetro do combinador e substitui a expresso original pela a expresso avaliada. A denio recursiva para o processo de abstrao de variveis com o uso de Combinadores Microprogramados dada abaixo sem grandes preocupaes com formalismos1 Apesar do compilador de Sloth utilizar um mtodo iterativo mais direto para a abstrao de variveis, a representao recursiva costuma ser til no estabelecimento de resultados tericos e de denio mais simples.
Abst(x, x) = LI Abst(x, E ) = LD E, x o c E Abst(x, E x) = E, x o c E Abst(x, E ) = Trim(Left(x, E, E )) Left(x, x, G) = L(x, G) Left(x, E, G) = L(x, G) E, x o c E Left(x, E x, G) = L(x, G) E, x o c E Left(x, E F, G) = Left(x, E, G) Abst(x, F ), x oc F Left(x, E F, G) = Left(x, E, G) F, x o c F (x, x) = I (x, E ) = D, x o c E (x, E x) = P, x o c E (x, F x) = (x, F ) i, x oc F (x, F E ) = (x, F ) d, x o c E (x, F E ) = (x, F ) p, x oc E Trim(E LI ) = Trim(E ) Trim(E F ) = Trim(E ) F Trim(E ) = E

A transformao Abst(x, E ) abstrai a varivel x da expresso E , fazendo uso das auxiliares Left e Trim. A transformao Left(x, E, E ) cria um combinador apropriado para a espinha da expresso E , empregando a auxiliar , e abstrai a varivel x ao longo da espinha de argumentos de E , usando Abst. A funo (x, E ) determina o microcdigo
Nas equaes, x oc E deve ser lido como x ocorre livre em E sendo que x o c E a negao deste predicado.
1

para o combinador a ser usado na espinha de E (o operador representa a concatenao de seqncias de microcdigo). Por m, a transformao Trim(E ) elimina os combinadores LI (identidade) ao longo da espinha de argumentos de E , j que os mesmos esto codicados de forma mais eciente dentro do prprio microcdigo. 3.2 Exemplos Combinadores Microprogramados com alcance maior que o dos combinadores de Turner surgem naturalmente na abstrao de variveis em programas usuais. A tabela abaixo mostra os combinadores que surgem durante a compilao das funes da biblioteca padro de Sloth, seguidos pela freqncia de suas ocorrncias. Note que os Combinadores Microprogramados LPp , LPd , LDp , LDpp e LDpd so respectivamente equivalentes aos combinadores de Turner S, C, B, S e C .
LDp LPp LDppdd LDppi LDpppd 222 37 7 3 1 LDpp LPdp LDpdp LDpdi LDpdpd 95 31 7 3 1 LPd LPdd LDppp LPpp LDpddp 75 14 5 2 1 LDpd LDppd LDpddd LDpip 75 11 4 2 LDpdd LDpi LPi LDpppdd 48 11 3 1

As vantagens da representao por Combinadores Microprogramados sobre a representao por combinadores de Turner cam especialmente evidentes quando a expresso sendo transformada possui uma longa espinha, e podem ser ainda maiores na abstrao de variveis sucessivas. Os exemplos abaixo, nos quais so exibidos os resultados da abstrao de variveis por ambos os mtodos, demonstram o maior poder de sntese dos Combinadores Microprogramados:
f x = a x (b x) c x f = S (C (S a b) c) I f = LPpdi a b c g a b c d e = e d c b a g = C (C (C C)) (C (C C) (C C (C I))) g = LPd (LPdd (LPddd LIdddd ))

A implementao do clculo da raiz quadrada de um nmero pelo mtodo de Newton, apresentada a seguir, serve como um exemplo real. Apesar da transformao de improve por Combinadores Microprogramados e por combinadores de Turner resultar em estruturas idnticas, as transformaes de satis, until e sqrt do origem aos combinadores LPi , LDpip , LDpi e LDppi , que tornam a representao por Combinadores Microprogramados mais concisa.
satis x y = y*y == x; satis = C eq (S mul I); satis = LDpd eq (LPi mul); improve x y = (y + x/y)/2; improve = C (C div) (B (S add) div) 2; improve = LDpd (LDpd div) (LDp (LPp add) div) 2; until p f x = if p x then x else until p f (f x); until = S B (B S (C (S cond) I)) (C (S B) until I); until = LDpp LDp (LDpip cond) (LDp (LDpi LDp ) until); sqrt x = until (satis x) (improve x) x; sqrt = S (S until satis improve) I; sqrt = LDppi until satis improve;

Por usar menos combinadores, a avaliao de funes pelo mtodo dos Combinadores Microprogramados alcana o resultado em um nmero menor de passos. Por 7

exemplo, o clculo da expresso sqrt 2 pelo mtodo de Turner realiza 146 redues, das quais 79 so combinadores. O clculo da mesma expresso por Combinadores Microprogramados realiza 108 redues, das quais apenas 48 so combinadores. Como conseqncia, no caso especco da expresso sqrt 2, o tempo de avaliao reduzido em 17%. Alm de realizar a instanciao preguiosa de grafos, os Combinadores Microprogramados mantm a avaliao totalmente preguiosa de expresses, assim como fazem os combinadores de Turner. A implementao da abstrao de variveis e do interpretador para as seqncias de microinstrues pode ser feita em poucas linhas de cdigo. Alm disso, os combinadores de maior alcance representam um aumento na granularidade das etapas realizadas pelo redutor de grafos. Uma anlise detalhada sobre os efeitos dessas vantagens na ecincia da avaliao de programas funcionais se encontra em andamento.

4 A arquitetura
A Figura 3 mostra as etapas pelas quais passa um programa Sloth desde sua leitura at sua avaliao. Estas etapas podem ser encontradas, com pequenas variaes, na maioria das implementaes de linguagens funcionais.
Anlise Sinttica Lua/C/Yacc Avaliao C Anlise Esttica Lua Concretizao e Linquedio Lua/C Compilao de Casamento de Padres Lua Compilao Lua

Figura 3: As principais etapas pelas quais passa um programa Sloth e as ferramentas usadas na construo de cada uma delas.

No diagrama acima, a anlise sinttica engloba a leitura do programa e a construo da rvore sinttica correspondente. A anlise esttica submete a rvore sinttica do programa a vericaes adicionais que escapam anlise sinttica. A compilao de casamento de padres substitui declaraes mltiplas de funes por declaraes simples equivalentes. A compilao transforma funes em uma representao que torna mais eciente sua avaliao com diferentes argumentos. A fase de concretizao converte as expresses compiladas do formato interno usado pelo compilador para o formato nal utilizado durante sua avaliao. A linquedio substitui ocorrncias de variveis livres pelas expresses compiladas correspondentes, segundo as regras de escopo vigentes. Por m, a etapa de avaliao realiza as computaes necessrias para a exibio dos resultados. No caso especco de Sloth, a pesquisa que est sendo realizada exige que as expresses sejam compiladas para rvores combinatrias, linqueditadas para a forma de grafos e avaliadas por um redutor de grafos. Na tentativa de conciliar portabilidade, disponibilidade e ecincia, foi escolhida a linguagem ANSI C para a implementao do avaliador. Essa deciso serviu como ponto de partida para a denio da arquitetura do restante do sistema. 8

Em geral, durante as fases intermedirias, a natureza e quantidade das transformaes pelas quais a estrutura do programa submetida acabam por exigir do programador tamanha disciplina com a gerncia das diversas estruturas dinmicas alocadas que o uso da linguagem C torna-se inconveniente. Evidncias desse fato podem ser encontradas em outras implementaes, notavelmente Hugs e Gofer [Jones, 1994], que decidiram pela criao de um sistema de coleta automtica de lixo atuando dentro da prpria linguagem C. Apesar de engenhosa, essa soluo aumenta consideravelmente a complexidade do sistema e no pode ser implementada de forma porttil, tendo sido por essas razes descartada para a construo de Sloth. Foi considerada tambm a alternativa adotada pela principal referncia na implementao de linguagens funcionais [Jones, 1987] e por uma implementao consagrada da linguagem Haskell [Jones, 1992] que consiste na escolha de uma linguagem de programao funcional para sua construo. Essa soluo se encaixa perfeitamente em sistemas que dispensam avaliadores, por traduzirem programas funcionais diretamente para linguagem de mquina ou outra linguagem de programao, como o caso de alguns compiladores de Haskell. No caso de Sloth, entretanto, programas so avaliados por um interpretador. Para permitir que, do ponto de vista do usurio, o processo seja executado como uma nica operao, necessria uma grande integrao entre o compilador e o avaliador. Infelizmente, no foi possvel encontrar-se uma linguagem funcional que se integrasse bem linguagem C, na qual escrito o avaliador, sem que restringisse a portabilidade e a disponibilidade de Sloth. A escolha da linguagem de programao Lua [Ierusalimschy et al., 1996] para a construo de Sloth representa uma soluo intermediria entre as duas alternativas analisadas. Lua uma linguagem procedural que, alm de oferecer os recursos desejados (como a coleta automtica de lixo), integra-se transparentemente linguagem C na forma de uma biblioteca. Lua uma linguagem leve, implementada em menos de dez mil linhas de cdigo, extremamente porttil por ser totalmente escrita em ANSI C e gratuitamente disponvel em cdigo fonte. 4.1 Entrando em detalhes Conforme descrito na Figura 3, o analisador sinttico de Sloth escrito em C, com o auxlio da ferramenta Yacc. As aes semnticas associadas a cada regra, entretanto, limitam-se criao da rvore sinttica do programa sendo analisado. A rvore sinttica diretamente criada como uma estrutura Lua, com o uso da API C oferecida pela linguagem. Desta forma, aps a anlise sinttica, o programa succ x = x + 1, por exemplo, representado em Lua pela hierarquia de vetores associativos abaixo:
{tag = varid, value = succ} = { tag = lambda, var = {tag = varid, value = x}, body = { tag = app, func = { tag = app, arg = {tag = varid, value = x}, func = {tag = varid, value = add}, }, arg = {tag = number, value = 1}, }, }

As fases seguintes, at a compilao, so totalmente escritas em Lua, de modo que podem tirar partido da maior expressividade e da gerncia automtica de memria presentes na linguagem. Em vrias ocasies, essas vantagens permitem solues que seriam, talvez, ousadas demais caso fossem implementadas na linguagem C. Por exemplo, o processo de abstrao de variveis com o uso dos combinadores de Turner muitas vezes descrito por um conjunto de transformaes, como as abaixo:
Abst(x, f1 f2 ) = Opt(S Abst(x, f1 ) Abst(x, f2 )) Abst(x, x) = I Abst(x, c) = K c Opt(S (K p) (K q )) = K p q Opt(S (K p) I)) = p Opt(S (K p) q ) = B p q Opt(S (B p q ) (K r)) = C p q r Opt(S p (K q )) = C p q Opt(S (B p q ) r) = S p q r

Por motivos de ecincia, mas principalmente por diculdades relacionadas com a alocao dinmica das representaes temporrias, uma implementao em C evitaria uma realizao explcita das transformaes descritas pela funo Opt acima. O mesmo no ocorre em uma linguagem com coleta automtica de lixo, como Lua. O cdigo abaixo, que pode ser usado para transformaes mais genricas em rvores sintticas, traduz essas transformaes diretamente:
function abstract(var, expr) if isExprApp(expr) then return optimize(app( app(S, abstract(var, expr.func)), abstract(var, expr.arg))) elseif expr == var then return I else return app(K, expr) end end function optimize(expr) expr = transform(expr, {{S, {K, "*"}}, {K, "*"}}, {K, {1, 2}}) expr = transform(expr, {{S, {K, "*"}}, I}, 1) expr = transform(expr, {{S, {K, "*"}}, "*"}, {{B, 1}, 2}) expr = transform(expr, {{S, {{B, "*"}, "*"}}, {K, "*"}}, {{{Cprime, 1}, 2}, 3}) expr = transform(expr, {{S, "*"}, {K, "*"}}, {{C, 1}, 2}) return transform(expr, {{S, {{B, "*"}, "*"}}, "*"}, {{{Sprime, 1}, 2}, 3}) end function transform(expr, pat, repl) local cap = match(expr, pat, {}) if cap then return replace(cap, repl) else return expr end end

10

function match(expr, pat, cap) if pat == "*" then append(cap, expr) return cap elseif expr == pat then return cap elseif isPatApp(pat) and isExprApp(expr) then return match(expr.func, pat[1], cap) and match(expr.arg, pat[2], cap) else return nil end end function replace(cap, repl) if isPatApp(repl) then return app(replace(cap, repl[1]), replace(cap, repl[2])) elseif isPatNumber(repl) then return cap[repl] else return repl end end

A funes abstract e optimize realizam literalmente as funes Abst e Opt, respectivamente. A funo transform tenta casar uma expresso com o padro denido pelo argumento pat, com o uso da auxiliar match. Durante o processo de casamento, a localizao de um n "*" no padro resulta na captura da expresso correspondente. Aps o casamento, a funo replace constri uma nova expresso, tendo como base o esqueleto denido por repl, na qual os ns numricos so substitudos pelas expresses capturadas correspondentes. Aps a compilao, durante a fase de concretizao, o programa transformado de sua representao em Lua para uma srie de rvores equivalentes alocadas dinamicamente em C. A fase de linquedio percorre as rvores resultantes para eliminar as variveis livres restantes, substituindo-as por referncias s expresses correspondentes, tambm concretizadas. J em sua forma nal, representado por um grafo, o programa ento interpretado pelo avaliador, totalmente escrito em C. Tendo conseguido associar as vantagens das duas linguagens de programao usadas em sua implementao, Sloth est prestes a atingir todos os objetivos apresentados na Seo 1. 4.2 Alcanando os objetivos Nossa primeira implementao de Sloth [Nehab, 1999] suportava uma verso simplicada da linguagem. Mais especicamente, no havia suporte a tipos de dados estruturados e a casamento de padres. Implementada em 5000 linhas de cdigo C, foi criada com o intuito de validar as tcnicas de compilao descritas na Seo 3 e acabou motivando uma nova implementao, mais completa. A nova implementao, com todos os recursos descritos na Seo 2 e baseada na arquitetura descrita acima, est prestes a ser concluda, em menos de 6000 linhas de cdigo. Esto incompletas as fases de Concretizao e Linquedio. Considerando-se o modesto tamanho da implementao e a pequena especicao da linguagem, pode-se armar que Sloth manteve-se el ao seu compromisso com a simplicidade. Sua portabilidade est assegurada pelo uso exclusivo das linguagem de 11

programao ANSI C e Lua (que por sua vez implementada em ANSI C). Sua disponibilidade est garantida, j que Lua distribuda livremente e nenhuma outra ferramenta se faz necessria (alm de um compilador de C, naturalmente). Por m, a experincia adquirida com a primeira verso da linguagem descarta a possibilidade de fracasso no que diz respeito ecincia. Como o cdigo gerado pelo novo compilador e as tcnicas usadas pelo novo avaliador (baseado no trabalho [Koopman and Lee, 1989]) so ainda mais ecientes, os resultados s podem melhorar.

5 Concluses
Este artigo apresentou a linguagem de programao Sloth. Sua especicao modesta facilita sua aprendizagem sem priv-la dos recursos mais comuns s linguagens de programao funcionais. A arquitetura escolhida para sua construo d origem a uma implementao concisa, que distribui entre linguagens de programao distintas as etapas s quais melhor se adaptam. Finalmente, os Combinadores Microprogramados, nos quais se baseiam seu compilador e seu avaliador, podem trazer um aumento de ecincia em relao aos combinadores de Turner sem comprometer suas vantagens e sua simplicidade. Dando prosseguimento ao trabalho j realizado, sero implementadas as etapas que restam para a concluso de Sloth. Com o sistema completo, a ecincia dos Combinadores Microprogramados ser comparada, na prtica, com os combinadores de Turner. Logo em seguida, a ecincia de Sloth ser comparada com a de outras linguagens, como Gofer e Hugs. Por m, uma anlise terica tentar obter estimativas mais precisas quanto ao tamanho das rvores combinatrias geradas pela abstrao de variveis com o uso de Combinadores Microprogramados, j que os estudos feitos com base nos combinadores de Turner no se aplicam diretamente aos novos combinadores.

Referncias
Abdali, S. K. (1976). An abstraction algorithm for combinatory logic. Journal of Symbolic Logic, 41(1):222224. Burton, F. W. (1982). A linear space translation of functional programs to Turner combinators. Information processing letters, 14(5):201204. Curry, H. B.; Hindley, J. R.; Seldin, J. P. (1972). Combinatory Logic, Volume I. NorthHolland, Amsterdam. Hughes, R. J. M. (1982). Supercombinators: A new implementation method for applicative languages. In Proc. of the ACM Conf. on Lisp and Functional Programming, pp. 110. Ierusalimschy, R.; de Figueiredo, L. H.; Celes, W. (1996). Luaan extensible extension language. Software: Practice and Experience, 26(6):635652. Johnsson, T. (1984). Efcient compilation of lazy evaluation. In Proc. of the ACM SIGPLAN84 Symposium on Compiler Construction, pp. 5869. Johnsson, T. (1985). Lambda lifting: transforming programs to recursive equations. In Proc. of the Conf. on Functional Programming Languages and Computer Architecture, Nancy, France. 12

Jones, M. P. (1994). The implementation of the Gofer functional programming system. Technical report, Yale University, Department of Computer Science. Jones, S. L. P. (1987). The implementation of functional programming languages. Prentice Hall International series in computer science. Jones, S. L. P. (1992). Implementing lazy functional languages on stock hardware: the spineless tagless G-machine. Journal of Functional Programming 2(2). Joy, M. S.; Rayward-Smith, V. J.; Burton, F. W. (1985). Efcient combinator code. Computer Languages, 10(3/4):211224. Kennaway, J. R. (1982). The complexity of a translation of lambda-calculus to combinators. Internal report CS/82/023/E, University of East Anglia, Norwich. Kennaway, J. R.; Sleep, M. R. (1987). Variable abstraction in O (n log n) space. Information processing letters, 24(5):343349. Koopman, P.; Lee, P. (1989). A fresh look at combinator graph reduction. In Proc. of the SIGPLAN89 Conf. on Programming Language Design and Implementation, pp. 2123. Nehab, D. F. (1999). Sloth: Uma generalizao dos combinadores SK. Trabalho nal de curso, PUC-Rio, Departamento de Informtica. Noshita, K. (1985). Translation of turner combinators in O (n log n) space. Information processing letters, 20(2):7174. Turner, D. A. (1979a). Another algorithm for bracket abstraction. Journal of Symbolic Logic, 44(2):267270. Turner, D. A. (1979b). A new implementation technique for applicative languages. Software - Practice and Experience, 9(1):3149.

13