# APL (linguagem de programação)

APL é uma linguagem de programação destinada a operações matemáticas.
Ela nasceu do trabalho do professor de matemática canadense Kenneth Iverson. A linguagem APL foi formalmente definida e introduzida por Iverson em seu livro A Programming Language, de 1962. Sua proposta original era a de produzir uma nova notação matemática, menos sujeita às ambiguidades da notação convencional. Segundo Iverson, foi projetada com o objetivo de ser matematicamente concisa, simples, precisa e executável.
Na década de 1960, trabalhando na IBM em conjunto com Adin Falkoff, ambos produziram a primeira versão de APL, de 1966, quando um interpretador da linguagem ficou disponível.
APL tem diversos dialetos, mas há uma versão internacional padronizada pela ISO/IEC 13751:2001. Outra referência importante é APL2 Programming: Language Reference, da IBM.

## O Conjunto de Caracteres APL

Uma das principais características de APL é o uso de um conjunto especial de caracteres que incluem algumas letras gregas (⍴ − rho, ⍳ − iota…), símbolos matemáticos convencionais (o sinal × de vezes, o ÷ de dividido…) e alguns símbolos especialmente inventados (como ⍋ e ⍟). Este fato sempre limitou a disseminação da linguagem. Até o advento das interfaces gráficas (Windows, por exemplo), exigia-se um hardware especial para programar em APL.
A linguagem APL recebeu muitas críticas pelo fato de usar este conjunto de caracteres não padronizado. Tal número de caracteres adicionais pode levar a um grau de complexidade alto resultando em uma baixa legibilidade. Por outro lado, o conjunto adicional de caracteres dá a linguagem uma elegância e a tornam concisa, o que é mais difícil de se conseguir em linguagens com um conjunto de caracteres reduzido.
A dificuldade criada pelos caracteres especiais de APL foi um dos motivos para que, ao conceber a linguagem J no início dos anos 1990, Kenneth E. Iverson (criador de APL), decidisse nela usar apenas caracteres convencionais ASCII.
Este (abaixo) é um subconjunto da lista de caracteres APL usados pelo interpretador GNU APL, gerado pelo comando ,¨7 32⍴32↓⎕AV .

### Unicode e fontes

O padrão Unicode contém os símbolos especiais de APL (pontos de código U+2336 a U+237A e U+2395) no bloco Miscellaneous Technical.
Algumas fontes tipográficas que incluem os símbolos requeridos por APL conforme o padrão Unicode são:
* APL385 Unicode
* Dejavu Sans Mono
* FreeMono
* GNU Unifont
* Quivira
* Rursus Compact Mono (N.B. Na versão 1.10, ⊥ U+22a5 e ⊤ U+22a4 estão trocados de lugar!)
* SImPL
* Symbola

### Símbolos APL e Layouts de Teclado

Para solucionar o problema da falta de caracteres especiais nos conjuntos padrão (como o ASCII, por exemplo), alguns interpretadores APL têm mapeamentos ou conjuntos de teclas simultâneas para a entrada destes. Uma das associações que se procurou fazer, para facilitar a busca, é relacionar os símbolos com as suas respectivas letras iniciais como no caso do símbolo de interrogação '?' em cima da letra 'Q' (Em inglês question mark) ou o símbolo '∇' em cima da letra 'G' (Em inglês: gradient).
As figuras ao lado ilustram dois exemplos de teclados com os símbolos APL e APL2.

#### Configuração de teclado em X Window System (GNU/Linux e outros sistemas)

Em sistemas GNU/Linux com X Window System, pode-se ativar o layout apl com o programa setxkbmap. No exemplo a seguir, definem-se os layouts Brasil(ABNT2) e APL(Dyalog), de modo que a tecla Caps_Lock passa a ativar o modo APL enquanto estiver pressionada (o comportamento normal dessa tecla passa a Alt+Caps_Lock).

## Elementos da linguagem

Iverson descrevia a linguagem APL usando termos das linguagens naturais, como, por exemplo:
* substantivos (nouns): constantes, como 3 ou ¯2 (numéricas) e 't' ou '1' (caracteres);
* pronomes (pronouns): identificadores (nomes associados a substantivos);
* verbos (verbs): funções;
* advérbios (adverbs): operadores que modificam a aplicação de funções;
* conjunções (conjunctions): operadores que combinam funções;
* verbo de ligação (copula): é o operador de atribuição ←;
* comparativos (comparatives): operadores como =, ≠ ou ≤.

### Vetorização

O tipo principal de estrutura de dados de APL é o arranjo ou array, com zero, uma ou mais dimensões. Tipicamente, as operações aplicam-se tanto a escalares (sem dimensão) quanto a vetores (uma dimensão), matrizes (duas dimensões) e arranjos multidimensionais (com qualquer número de dimensões suportado pela implementação). Dessa forma, dispensam-se laços explícitos na maioria dos casos. O funcionamento é similar ao do MATLAB, cuja linguagem teve em APL um de seus modelos.
Veja-se o exemplo de sessão interativa abaixo, em que as instruções da pessoa operadora estão recuadas por 6 espaços, e as respostas do programa começam na margem esquerda.

### Ambivalência dos símbolos

Em APL, cada um dos símbolos pode ter duas funções a ele associadas. Segundo Kenneth Iverson, o motivo para isso é representar um grande número de funções através de um pequeno vocabulário de símbolos:
   Uma economia significativa de símbolos, em oposição a economia de funções, é atingida ao se permitir que cada símbolo represente tanto uma função unária [i.e., uma função de um argumento] quanto uma função binária, da mesma maneira como o sinal de menos é comumente usado para ambas subtração e negação. Podendo as duas funções serem relacionadas entre si, como no caso do sinal de menos, a memorização dos símbolos fica facilitada.
Por exemplo, o símbolo ⍳ (iota), na forma unária (prefixa), é um gerador de índices. Ele gera uma sequência de números inteiros em ordem ascendente, conforme o número à sua direita. Já na forma binária, o operador ⍳ é infixo (sintaxe X⍳E), e sua função é localizar o índice da primeira ocorrência do elemento E em X:
Outros exemplos:
⌈ e ⌊

### Ordem de avaliação de expressões

Em APL, as expressões são avaliadas da direita para a esquerda, e todas as funções têm a mesma precedência. Parênteses podem ser necessários para determinar a prioridade de avaliação:

### “Advérbios”

O operador ⍨ permuta os operandos de uma função binária:
Quando o operando esquerdo é omitido, ⍨ usa o operando direito em seu lugar:
/ e ⌿ intercalam a função entre os elementos do arranjo, retornando o resultado final (tal como o operador reduce em LISP):
\ e ⍀ atuam de maneira similar, mas incluem os resultados parciais:

### Estruturas de controle de fluxo
#### Sintaxe

Exceto em alguns dialetos, APL não contém instruções como if, if/else, switch/case, for, repeat. O controle do fluxo de execução é feito através de saltos (branching = ramificação) e chamadas de funções.
Ramificações (→) são permitidas apenas dentro da definição de funções, através de uma instrução do tipo → NUMLINHA ou → (CONDICAO)/NUMLINHA. O código → 0 (escape) termina a execução da função. Laços raramente são necessários, por a linguagem ser especialmente projetada para o tratamento de arranjos (arrays). Assim, o principal uso de → é para execução condicional.
Outra forma de execução condicional pode ser obtida com o operador ⍎ (execute), que avalia uma cadeia de caracteres como uma instrução em APL:

#### Organização do código

Para escrever programas em APL de maneira estruturada, sugere-se evitar ramificações e laços, e, quando não for possível evitá-los, organizar o código em blocos delimitados por rótulos (B#: ... E#:, BE:), imitando-se a sintaxe begin ... end das linguagens de programação estruturada.
Alguns exemplos:
If
While
Ciclo em uma linha (⎕LC é o número da linha atual do código-fonte)
Switch/Case

#### Uso de ramificações e ciclos

Gary Bergquist faz uma análise aprofundada de ramificações e ciclos em APL no capítulo 2 (Branching and Looping) de APL − Advanced Techniques and Utilities. São abordados critérios como velocidade de execução, requerimento de memória, legibilidade, limitações e compatibilidade.
Bergquist recomenda:
* Evitar ciclos em APL quando possível (p.16);
* Quando ciclos forem necessários, devem ter apenas o mínimo possível de código (p.16);
* Todavia, não perder tempo buscando obsessivamente um algoritmo sem ciclos, a não ser que haja motivos suficientes para tal (p.18−19).
Há também no livro de Bergquist (p.8−9) a sugestão de se criarem as funções como IF ("se") e UNLESS ("a menos que", "a não ser que"), para facilitar a legibilidade do código, permitindo-se assim as construções:

## Expressões idiomáticas

Ao estudar os processos de leitura e escrita de programas em APL, Alan J. Perlis e Spencer Rugaber notaram que certas expressões se repetiam em diversos contextos. Tais expressões são chamadas em inglês de idioms (expressões idiomáticas). Uma vez aprendidas, essas expressões passam a ser reconhecidas como uma unidade, dispensando a necessidade de se analizá-las caracter por caracter. Por isso, os autores defendem que expressões idiomáticas em APL devem ser ensinadas desde o início da experiência com essa linguagem.
Na introdução de APL2 IDIOMS Library, Stan Cason destaca que a utilidade das coleções de expressões idiomáticas não se limita apenas em acelerar o processo de aprendizagem de APL por iniciantes. Essas coleções também servem como fonte de consulta para programadores experientes nessa linguagem, que podem não se recordar de um algoritmo que não tenham utilizado recentemente.
Exemplos:

## Exemplos de código
### Função Fatorial

Este código é apenas para exemplo, pois APL já contém em si a função fatorial (!).
Versão longa, usando recursão:
Versão curta, usando vetor com N elementos:
Exemplo usando função direta (GNU APL):

### Soma dos Elementos de um Vetor

O somatório de um vetor é expresso por +/:
Função SV (versão longa, irrealista):
Versão curta:

### Média dos elementos de um vetor

Este código computa a média aritmética dos elementos de um vetor, inseridos via teclado em tempo de execução. O vetor é armazenado na variável x. A função unária ⍴x retorna o número de elementos de x, pelo qual é dividida a soma dos elementos (+/x). Os parênteses são necessários porque APL é interpretada da direita para a esquerda.
As versões seguintes produzem o mesmo resultado, mas não utilizam nenhuma variável explícita.

### Algoritmo de Trabb Pardo-Knuth

Esta é uma versão compacta, que usa apenas uma variável (A):

## Implementações

* https://www.gnu.org/software/apl/ GNU APL - software livre. GNU APL Online: try-GNU-APL http://juergen-sauermann.de/try-GNU-APL .
* http://www.nars2000.org/ NARS2000 (Nested Arrays Research System) - software livre.
* https://tryapl.org/ TryAPL - Versão online do Dyalog APL para aprendizado da linguagem.
* https://gitlab.com/n9n/apl ngn APL - Implementação de APL em Javascript, que roda em um navegador ou em um shell (como node.js ou Mozilla SpiderMonkey js) - software livre. A implementação NGN APL é apresentada no artigo Compiling APL to JavaScript de Nick Nickolov: http://archive.vector.org.uk/art10501160 (Vector, Vol.26, n.1, 2013). APL.js é uma versão estendida de NGN APL: https://github.com/plj541/APL.js (Ver https://plj541.github.io/APL.js/Help/Notes.html)