https://julialang.org/learning/tryjulia/ julia online
https://en.wikibooks.org/wiki/Introducing_Julia livro online
ocupa o nicho de linguagens para aplicaçoes numericas (Fortran, Python+Numpy, Mathlab)
2009/2012
tipagem dinamica mas com hints que sao obedecidos
compilado
sintaxe bem parecida com Python (mas veja https://docs.julialang.org/en/v1/manual/noteworthy-differences/#Noteworthy-Differences-from-other-Languages
indexacao começa do 1 ( e não 0)
if
e for
(e outros criadores de blocos)
terminam com um end
for x in [1, 2, 3]
ou
for x = [1,2,3]
https://en.wikibooks.org/wiki/Introducing_Julia/Controlling_the_flow
vairaveis de controle do for
e variaveis setadas dentro
do loop nao sobrevivem ao fim do loop
for i = 1:10
z1 = 99+i
print(i)
end
12345678910
i
z1
mas se z1 for definida (usada) fora ela sobrevive. Ou declarada no
loop como global z1
no loop
2 tipos de dicionário
Dict
tipado ( tipos fixos para chave e valor)julia> Dict("A"=>1, "B"=>2)
Dict{String, Int64} with 2 entries:
"B" => 2
"A" => 1
IdDict
não tipado, como no Pythonjulia> Dict(true => "yes", 1 => "no", 1.0 => "maybe")
Dict{Real, String} with 1 entry:
1.0 => "maybe"
julia> IdDict(true => "yes", 1 => "no", 1.0 => "maybe")
IdDict{Any, String} with 3 entries:
true => "yes"
1.0 => "maybe"
1 => "no"
O tipo Any
é um supertipo para qq coisa
mesma sintaxe para acessar e colocar um par no dic
c = Dict{String,Any}()
c["f"] = (1,2,3)
c["qwerty"] = 99.0
c["qwerty"]+10
https://en.wikibooks.org/wiki/Introducing_Julia/Arrays_and_tuples
julia> a = [1,2,3,4]
4-element Vector{Int64}:
1
2
3
4
tem uma formatação extra para arrays 2D (branco -> na mesma linha, ; -> muda de linha)
julia> [1 2 3 4 ; 5 6 7 8]
2x4 Array{Int64,2}:
1 2 3 4
5 6 7 8
note
julia> [1, 2, 3, 4, 5]
5-element Array{Int64,1}:
1
2
3
4
5
julia> [1 2 3 4 5]
1x5 Array{Int64,2}:
1 2 3 4 5
julia> [n^2 for n in 1:5]
5-element Vector{Int64}:
1
4
9
16
25
julia> [r * c for r in 1:5, c in 1:5]
5×5 Matrix{Int64}:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
;
inibe a saida
a[1]
a[end]
a[end-2]
a[[2,1,2]]
a[1:4]
vetoriozacao (automática) de funções e operadores
f(a,b) = a+2*b
f(4,5)
f([1 2 3; 4 5 6], [10 11 12; 13 14 15])
[1,2,3] - [6,7,8]
[1,2,3] * [6,7,8]
vetorizacao explicita (usando o .)
[1,2,3] .* [6,7,8]
existe broadcast mas não vou cobrir os detalhes
julia> [1 2 3 ; 4 5 6] ./ [1 2 3]
2×3 Matrix{Float64}:
1.0 1.0 1.0
4.0 2.5 2.0
julia> [1 2 3 ; 4 5 6] / [1, 2 ,3]
ERROR: DimensionMismatch: Both inputs should have the same number of columns
Stacktrace:
referencia https://docs.julialang.org/en/v1/manual/metaprogramming/
outra fonte https://en.wikibooks.org/wiki/Introducing_Julia/Metaprogramming
uso:
@time [sin(cos(i)) for i in 1:100000];
x = 78 + @show sum([sin(cos(i)) for i in 1:100000])
define novos tipos de dados para isso
simbolo (nome de variaveis) :velocidade
expressao (que é um array de simbolos ou outras expressoes)
um blog sobre escrever uma macro simples https://giordano.github.io/blog/2022-06-18-first-macro/
wikipedia https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
video https://www.youtube.com/watch?v=lEYtWcuVylc
Problemas de genrenciamento manual (malloc e free do C)
dangling pointers (apontadores para regioes de memoria que foram free)
double free (chama o free numa regiao que ja foi free - e que ja esta sendo usado para outra coisa)
memory leak ( esquece de chamar o free num programa de longa duracao)
um thread em paralelo que marca todas as posicoes de memoria que podem ser alcançadas a partir de uma raiz (lista de variavies, lista de simbolos). Ha varias variacoes: Por exemplo generational GC
Aloca dados na area (generation) 0. Quando a area 0 enche, os dados sao coletados. Os que nao forem coletados vao para a area 1. Quando a area 1 enche, a mesma coisa usando a area 2.
Tracing CG tem um custo em tempo medio - o GC tem que rodar de vez em quando e interromper o programa
cada dado mantem um contador do numeros de caminhos que podem alcançar os dados. Quando o contador chega a 0, o dado é coletado. Usado no Python
a = [1,2,3] --> a lista tem contador 1
b = a --> contador = 1
a = 3 --> decrementa o contador antes de a apontar para o novo valor
b = "qwerty" --> contador chega a 0
Reference counter tem um custo no tempo de execuçao. cada nova atribuicao tem que decrementar o contado do dado velho.
o compilador analisa o codigo e verifica que o dado nao é usado apos o fim de uma funcao. Entao vc pode alocar o dado no stack da funcao e nao no heap!