A Julia é uma linguagem de programação dinâmica e fortemente tipada. O estilo de programação é sobretudo funcional, embora com mais flexibilidade do que em linguagens como Haskell.
Existe um sistema de tipos forte e versátil, que se tornará importante em conceitos posteriores. Na prática, a Julia infere normalmente um valor predefinido adequado a partir do contexto.
Apesar da ênfase na legibilidade, que a faz parecer uma linguagem de script como Python e Ruby, o código Julia é compilado antes de ser executado. O compilador Just In Time (JIT) produz código altamente otimizado para cada função à medida que esta é encontrada, o que se traduz numa elevada velocidade de execução.
A Julia não é uma linguagem orientada a objetos, e não existe uma hierarquia de classes como a que é central em muitas outras linguagens.
Em vez disso (e não entres em pânico quando leres isto!), a Julia baseia-se em:
Estes termos um pouco confusos tornar-se-ão mais claros à medida que avançamos pelo currículo.
A documentação oficial contém muita informação valiosa para a versão atual, embora possa ser um pouco avassaladora para quem está a começar.
Os vídeos incluem:
Incluir comentários no teu código é extremamente importante para ajudar as pessoas a ler o código e a compreender as tuas intenções: talvez outras pessoas, mas também o teu eu do futuro. São (na sua maioria) ignorados pelo compilador.
Na Julia existem duas opções:
#
#= e terminam com =#. É permitido aninhá-los.# This is a single-line comment
x = 3 # This is an inline comment
#=
Multi-line comments can be used for longer explanations.
They are especially useful to comment out blocks of code during debugging.
=#
Para criar uma variável, basta atribuir-lhe um valor:
julia> myvar = 42 # an integer (in fact, Int64)
42
julia> bigint = 1_234_567_890 # optionally use underscore as digit separator, for readability
1234567890
julia> name = "Maria" # strings are surrounded by double-quotes ""
"Maria"
A atribuição associa um valor à variável.
Especificar um tipo é opcional e, na maior parte dos casos, a Julia infere um valor predefinido adequado a partir do contexto.
Os tipos são um tema importante na Julia. Vamos explorá-los melhor em conceitos posteriores. Por agora, o melhor é não te preocupares com eles.
Ao contrário do que acontece em muitas linguagens funcionais, as variáveis na Julia podem ser reatribuídas, e podes alterar tanto o valor como o tipo associado à variável:
julia> myvar = 3
3
julia> myvar = "now a string"
"now a string"
As variáveis globais, criadas fora de qualquer função, são:
*.jl; o REPL funciona de forma diferente).Se um valor tiver de estar disponível em todo o programa, mas não se esperar que mude, usa antes uma constante.
Colocar a palavra-chave const antes da atribuição permite ao compilador gerar código mais eficiente.
Se tentares alterar o valor de uma const por engano, recebes um aviso:
julia> const answer = 42
42
julia> answer = 24
WARNING: redefinition of constant Main.answer. This may fail, cause incorrect answers, or produce other errors.
24
A aritmética funciona, na sua maioria, da forma habitual:
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
Repara que a divisão com / dá sempre um número de vírgula flutuante.
Voltaremos a este assunto em conceitos posteriores, onde se falará da divisão inteira com div() ou ÷, para truncar, e de //, para obter um número racional.
Para obteres o melhor desempenho em tempo de execução, o melhor é colocar a maior parte do código dentro de funções. Ter muitas funções pequenas é perfeitamente aceitável, ao contrário do que se passa em algumas outras linguagens.
Há duas formas comuns de definir uma função com nome na Julia:
Usar a palavra-chave function
function muladd(x, y, z)
x * y + z
end
A indentação com 4 espaços é convencional para melhorar a legibilidade, mas o compilador ignora-a.
A palavra-chave end é essencial: mais ao estilo de Ruby do que de Python.
Repara que podíamos ter escrito return x * y + z.
No entanto, as funções da Julia devolvem sempre a última expressão avaliada, pelo que a palavra-chave return é opcional.
Muitos programadores preferem incluí-la para tornar as suas intenções mais explícitas.
Usar a "forma de atribuição"
muladd(x, y, z) = x * y + z
Esta forma é usada sobretudo para definições de funções de uma só linha ou para funções matemáticas, em que o corpo da função é uma única expressão.
A palavra-chave return nunca é usada na forma de atribuição.
As duas formas são equivalentes e usam-se exatamente da mesma maneira, por isso escolhe a que for mais legível.
Para invocar uma função, especifica-se o seu nome e passam-se argumentos para cada um dos parâmetros da função:
# invoking a function
muladd(10, 5, 1)
# and of course you can invoke a function within the body of another function:
square_plus_one(x) = muladd(x, x, 1)
Pelo facto de nos referirmos a estas como funções "com nome", podes imaginar que também existem funções "anónimas". Estas serão abordadas num conceito posterior.
Como muitas linguagens, a Julia exige que os nomes (de variáveis, funções e muitas outras coisas) comecem por uma letra, seguida de qualquer combinação de letras, algarismos e underscores.
Por convenção, os nomes de variáveis, constantes e funções escrevem-se em minúsculas, evitando-se os underscores exceto quando são necessários para evitar confusão.
No entanto, a Julia usa Unicode em todo o lado, pelo que a noção de "letra" é interpretada com bastante flexibilidade.
São suportadas outras línguas além do inglês, bem como emojis (embora, por favor, usa bom gosto e escolhe algo apropriado).
Em particular, estão disponíveis todas as letras gregas adoradas pelos matemáticos (e vários valores úteis estão predefinidos):
julia> π # a built-in constant
π = 3.1415926535897...
Os editores que conhecem a Julia, incluindo o REPL, o Pluto.jl e o VS Code com o plugin da Julia, facilitam a introdução destes carateres.
Para o π, escreve \pi e depois prime <Tab>. O que escreveste será substituído pelo caráter grego.
Verás muitos mais exemplos disto em conceitos posteriores.
Na verdade, as abreviaturas com barra invertida não são algo específico da Julia. Vêm do LaTeX, um sistema de composição tipográfica que muitos cientistas e engenheiros usam quase diariamente para escrever relatórios.