Dylan (linguagem de programação)

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar

Dylan é uma linguagem de programação multiparadigma que inclui suporte para programação funcional e orientada a objetos (OOP), e é dinâmica e reflexiva ao fornecer um modelo de programação projetado para suportar a geração de código de máquina eficiente, incluindo controle refinado sobre comportamentos dinâmicos e estáticos. Foi criado no início dos anos 90 por um grupo liderado pela Apple Computer.

Dylan deriva de Scheme e Common Lisp e adiciona um sistema de objeto integrado derivado do Common Lisp Object System (CLOS). Em Dylan, todos os valores (incluindo números, caracteres, funções e classes) são objetos de primeira classe. Dylan suporta herança múltipla, polimorfismo, despacho múltiplo, argumentos de palavra-chave, introspecção de objetos, macros de extensão de sintaxe baseada em padrão e muitos outros recursos avançados. Os programas podem expressar um controle refinado sobre o dinamismo, admitindo programas que ocupam um continuum entre programação dinâmica e estática e apoiando o desenvolvimento evolutivo (permitindo prototipagem rápida seguida de refinamento e otimização incrementais).

O principal objetivo do projeto de Dylan é ser uma linguagem dinâmica adequada para o desenvolvimento de software comercial. Dylan tenta resolver possíveis problemas de desempenho, introduzindo técnicas "naturais" limita a total flexibilidade dos sistemas Lisp, permitindo que o compilador entenda claramente as unidades compiláveis, como bibliotecas.

Dylan deriva muito de sua semântica de Scheme e outros Lisps; algumas implementações de Dylan foram inicialmente construídas dentro de sistemas Lisp existentes. No entanto, Dylan tem uma sintaxe semelhante a ALGOL em vez de uma sintaxe de prefixo semelhante a Lisp.

História

Dylan foi criado no início dos anos 90 por um grupo liderado pela Apple Computer. Em um momento de seu desenvolvimento, ele foi planejado para uso com o computador Apple Newton, mas a implementação de Dylan não atingiu maturidade suficiente com o tempo, e Newton usou uma mistura de C e NewtonScript desenvolvido por Walter Smith. A Apple encerrou seu esforço de desenvolvimento de Dylan em 1995, embora tenha feito um "lançamento de tecnologia" versão disponível (Apple Dylan TR1) que incluía um ambiente de desenvolvimento integrado avançado (IDE).

Dois outros grupos contribuíram para o design da linguagem e desenvolveram implementações: Harlequin lançou um IDE comercial para Microsoft Windows e Carnegie Mellon University lançou um compilador de código aberto para sistemas Unix chamado Gwydion Dylan. Ambas as implementações agora são de código aberto. A implementação do Harlequin agora se chama Open Dylan e é mantida por um grupo de voluntários, os Dylan Hackers.

A linguagem de Dylan tinha o codinome Ralph. James Joaquin escolheu o nome Dylan para "DYnamic LANguage."

Sintaxe

Muitos dos recursos de sintaxe de Dylan vêm de sua herança Lisp. Originalmente, Dylan usava uma sintaxe de prefixo semelhante a Lisp, baseada em expressões s. No momento em que o projeto da linguagem foi concluído, a sintaxe foi alterada para uma sintaxe do tipo ALGOL, com a expectativa de que fosse mais familiar para um público mais amplo de programadores. A sintaxe foi projetada por Michael Kahl. É descrito em grande detalhe no Dylan Reference Manual.

Sintaxe lexical

Dylan não diferencia maiúsculas de minúsculas. A sintaxe léxica de Dylan permite o uso de uma convenção de nomenclatura em que os sinais de hífen (menos) são usados para conectar as partes de identificadores de várias palavras (às vezes chamados de "lisp-case" ou "kebab caso"). Essa convenção é comum em linguagens Lisp.

Além de caracteres alfanuméricos e sinais de menos hífen, Dylan permite uma variedade de caracteres não alfanuméricos como parte dos identificadores. Os identificadores podem não consistir apenas nesses caracteres não alfanuméricos. Se houver alguma ambigüidade, o espaço em branco será usado.

Exemplo de código

Uma classe simples com vários slots:

definição classe  () fenda de fenda Ponto-x : , palavra-chave necessária: x:; fenda de fenda - Sim. : , palavra-chave necessária: Sim.;fim classe ;

Por convenção, as classes são nomeadas com sinais de menor e maior usados como colchetes angulares, por exemplo a classe denominada <point> no exemplo de código.

Em end class <point> tanto class quanto <point> são opcionais. Isso é verdadeiro para todas as cláusulas end. Por exemplo, você pode escrever end if ou apenas end para encerrar uma instrução if.

Para criar uma instância de <point>:

fazer(, x: 100., Sim. 200)


A mesma classe, reescrita da forma mais mínima possível:

definição classe  () fenda de fenda Ponto-x; fenda de fenda - Sim.;fim;

Os slots agora são digitados como <object>. Os slots devem ser inicializados manualmente:

Deixa-me. p = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = fazer();Ponto-x(p) ? 100.; // ou p.point-x:= 100;- Sim.(p) ? 200; // ou p.point-y:= 200;

Por convenção, os nomes das constantes começam com "$":

definição constante constante $pi :  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 3.1415927D0;

Uma função fatorial:

definição função factorial (n : ) - Sim. (Não! : ) Processo n < 0 - Sim. erro("Não pode tomar fatoração de inteiro negativo: %dNão.", n); n = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 0 - Sim. 1; caso contrário - Sim. n * factorial(n - Não. 1); fimfim;

Aqui, n! e <integer> são apenas identificadores normais.

Não há declaração de retorno explícita. O resultado de um método ou função é a última expressão avaliada. É um estilo comum deixar de lado o ponto e vírgula após uma expressão na posição de retorno.

Módulos vs. namespace

Em muitas linguagens orientadas a objetos, as classes são os principais meios de encapsulamento e modularidade; cada classe define um namespace e controla quais definições são visíveis externamente. Além disso, classes em muitos idiomas definem uma unidade indivisível que deve ser usada como um todo. Por exemplo, usar uma função de concatenação String requer importação e compilação em todo String.

Algumas linguagens, incluindo Dylan, também incluem um namespace explícito separado ou um sistema de módulo que executa o encapsulamento de uma maneira mais geral.

Em Dylan, os conceitos de unidade de compilação e unidade de importação são separados e as classes não têm nada a ver especificamente com nenhum deles. Uma biblioteca define itens que devem ser compilados e tratados juntos, enquanto um módulo define um namespace. As classes podem ser colocadas juntas em módulos, ou cortadas entre eles, como o programador desejar. Freqüentemente, a definição completa de uma classe não existe em um único módulo, mas está espalhada por vários que são opcionalmente coletados juntos. Diferentes programas podem ter diferentes definições da mesma classe, incluindo apenas o que precisam.

Por exemplo, considere uma biblioteca complementar para suporte a regex em String. Em alguns idiomas, para que a funcionalidade seja incluída em strings, ela deve ser adicionada ao namespace String. Assim que isso ocorre, a classe String se torna maior e as funções que não precisam usar regex ainda devem "pagar" para ele em tamanho de biblioteca aumentado. Por esse motivo, esses tipos de complementos geralmente são colocados em seus próprios namespaces e objetos. A desvantagem dessa abordagem é que as novas funções não são mais uma parte de String; em vez disso, ele é isolado em seu próprio conjunto de funções que devem ser chamadas separadamente. Em vez de myString.parseWith(myPattern), que seria a organização natural do ponto de vista OO, algo como myPattern.parseString(myString) é usado, o que efetivamente reverte a ordem.

Em Dylan, muitas interfaces podem ser definidas para o mesmo código, por exemplo, o método de concatenação String pode ser colocado tanto na interface String quanto na interface "concat" interface que reúne todas as diferentes funções de concatenação de várias classes. Isso é mais comumente usado em bibliotecas matemáticas, onde as funções tendem a ser aplicáveis a tipos de objetos amplamente diferentes.

Um uso mais prático da construção de interface é construir versões públicas e privadas de um módulo, algo que outras linguagens incluem como um recurso bolt on que invariavelmente causa problemas e adiciona sintaxe. Sob Dylan, cada chamada de função pode ser simplesmente colocada na seção "Private" ou "Desenvolvimento" interface e colete funções publicamente acessíveis em Public. Em Java ou C++, a visibilidade de um objeto é definida no código, o que significa que, para suportar uma alteração semelhante, um programador seria forçado a reescrever totalmente as definições e não poderia ter duas versões ao mesmo tempo.

Aulas

Classes em Dylan descrevem slots (membros de dados, campos, ivars, etc.) de objetos de maneira semelhante à maioria das linguagens OO. Todo o acesso aos slots é feito por meio de métodos, como no Smalltalk. Os métodos padrão getter e setter são gerados automaticamente com base nos nomes dos slots. Em contraste com a maioria das outras linguagens OO, outros métodos aplicáveis à classe geralmente são definidos fora da classe e, portanto, as definições de classe em Dylan geralmente incluem apenas a definição do armazenamento. Por exemplo:

definição classe  () fenda de fenda título :  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = "desafiado", init-keyword: título:; fenda de fenda posição : , palavra-chave necessária: posição:;fim classe;

Neste exemplo, a classe "<window>" é definido. O <nome da classe> a sintaxe é apenas uma convenção, para destacar os nomes das classes - os colchetes angulares são meramente parte do nome da classe. Em contraste, em alguns idiomas, a convenção é colocar a primeira letra do nome da classe em maiúscula ou prefixar o nome com C ou T (por exemplo). <window> herda de uma única classe, <view>, e contém dois slots, title contendo uma string para o título da janela, e position segurando um ponto X-Y para um canto da janela. Neste exemplo, o título recebeu um valor padrão, enquanto a posição não. A sintaxe opcional init-keyword permite ao programador especificar o valor inicial do slot ao instanciar um objeto da classe.

Em linguagens como C++ ou Java, a classe também definiria sua interface. Neste caso, a definição acima não possui instruções explícitas, portanto, em ambas as linguagens, o acesso aos slots e métodos é considerado protegido, ou seja, eles podem ser usados apenas por subclasses. Para permitir que códigos não relacionados usem instâncias de janela, elas devem ser declaradas como public.

Em Dylan, esses tipos de regras de visibilidade não são considerados parte do código, mas do sistema de módulo/interface. Isso adiciona uma flexibilidade considerável. Por exemplo, uma interface usada durante o desenvolvimento inicial pode declarar tudo público, enquanto uma usada em testes e implantação pode limitar isso. Com C++ ou Java, essas alterações exigiriam alterações no código-fonte, para que as pessoas não o fizessem, enquanto em Dylan esse é um conceito totalmente não relacionado.

Embora este exemplo não o use, Dylan também suporta herança múltipla.

Métodos e funções genéricas

Em Dylan, os métodos não estão intrinsecamente associados a nenhuma classe específica; os métodos podem ser pensados como existindo fora das classes. Assim como o CLOS, o Dylan é baseado no despacho múltiplo (multimétodos), onde o método específico a ser chamado é escolhido com base nos tipos de todos os seus argumentos. O método não precisa ser conhecido em tempo de compilação, entendendo-se que a função necessária pode estar disponível, ou não, com base nas preferências do usuário.

Em Java, os mesmos métodos seriam isolados em uma classe específica. Para usar essa funcionalidade, o programador é forçado a importar essa classe e referir-se a ela explicitamente para chamar o método. Se essa classe estiver indisponível ou desconhecida no momento da compilação, o aplicativo simplesmente não compilará.

Em Dylan, o código é isolado do armazenamento em funções. Muitas classes têm métodos que chamam suas próprias funções, portanto, parecendo e se comportando como a maioria das outras linguagens OO. No entanto, o código também pode estar localizado em funções genéricas, o que significa que elas não estão vinculadas a uma classe específica e podem ser chamadas nativamente por qualquer pessoa. Vincular uma função genérica específica a um método em uma classe é feito da seguinte forma:

definição método virar azul (O quê? : ) O quê?.cor da cor ? $blue;fim método;

Esta definição é semelhante às de outras linguagens e provavelmente seria encapsulada na classe <window>. Observe a chamada:= setter, que é um açúcar sintático para color-setter($blue, w).

A utilidade dos métodos genéricos se destaca quando você considera métodos mais "genéricos" exemplos. Por exemplo, uma função comum na maioria das linguagens é to-string, que retorna alguma forma legível para o objeto. Por exemplo, uma janela pode retornar seu título e sua posição entre parênteses, enquanto uma string retornaria a si mesma. Em Dylan, todos esses métodos podem ser reunidos em um único módulo chamado "to-string", removendo assim esse código da definição da própria classe. Se um objeto específico não suportasse um to-string, ele poderia ser facilmente adicionado ao módulo to-string.

Extensibilidade

Todo esse conceito pode parecer muito estranho para alguns leitores. O código para lidar com para string para uma janela não está definido em <window>? Isso pode não fazer sentido até que você considere como Dylan lida com a chamada do to-string. Na maioria dos idiomas, quando o programa é compilado, o to-string para <window> é pesquisado e substituído por um ponteiro (mais ou menos) para o método. Em Dylan, isso ocorre quando o programa é executado pela primeira vez; o tempo de execução cria uma tabela de detalhes de nomes de métodos/parâmetros e procura métodos dinamicamente por meio dessa tabela. Isso significa que uma função para um método específico pode ser localizada em qualquer lugar, não apenas na unidade de tempo de compilação. No final, o programador recebe flexibilidade considerável em termos de onde colocar seu código, coletando-o ao longo das linhas de classe onde apropriado e linhas funcionais onde não é.

A implicação aqui é que um programador pode adicionar funcionalidade a classes existentes definindo funções em um arquivo separado. Por exemplo, você pode querer adicionar verificação ortográfica a todos os <string>s, que em C++ ou Java exigiriam acesso ao código-fonte da classe string—e tais classes básicas raramente são fornecidas na forma de fonte. Em Dylan (e outras "linguagens extensíveis") o método de verificação ortográfica pode ser adicionado no módulo spell-check, definindo todas as classes nas quais pode ser aplicado através do define o método construção. Nesse caso, a funcionalidade real pode ser definida em uma única função genérica, que recebe uma string e retorna os erros. Quando o módulo spell-check for compilado em seu programa, todas as strings (e outros objetos) terão a funcionalidade adicionada.

Apple Dylan

Apple Dylan é a implementação de Dylan produzida pela Apple Computer. Foi originalmente desenvolvido para o produto Apple Newton.

Contenido relacionado

Núcleo

Kernel pode referir-se...

Telecomunicações no Kuwait

Telecomunicações no Kuwait fornece informações sobre a infra-estrutura de telefonia, Internet, rádio e televisão no...

Cinema digital

Cinema digital refere-se à adoção da tecnologia digital na indústria cinematográfica para distribuir ou projetar filmes, em oposição ao uso histórico...
Más resultados...
Tamaño del texto:
  • Copiar
  • Editar
  • Resumir
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save