Julia

De Cerlab Wiki
Revisión del 17:21 8 sep 2020 de Joseal9706 (discusión | contribuciones) (Manejo de Archivos)
Saltar a: navegación, buscar

Julia es un lenguaje de programacion que busca tener la versatilidad y facilidad de uso de Python y la velocidad de C/C++...

Instalación de Julia

Para instalar Julia primero se debe ir a la página oficial lenguaje, luego a su parte de descargas Julia Downloads. Una vez ahí se descarga la versión pertinente al sistema operativo del usuario. Para instalar Julia en Linux se pueden utilizar los siguientes comandos con la versión actual es ese momento (los comandos mostrados aplican para la versión 1.5.0):

wget https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.0-linux-x86_64.tar.gz
tar -xvzf julia-1.5.0-linux-x86\_64.tar.gz
ln -s "$PWD"/julia-1.5.0/bin/julia ~/.local/bin/

Una vez instalado Julia se puede correr utilizando el comando "julia" en la terminal de Linux, o abriendo la aplicación instalada en macOS o Windows. Si por alguna razón no se abre o se muestra un mensaje que desconoce el comando, significa que Julia no se ha agregado al PATH y se puede agregar con el siguiente comando:

export PATH="$PATH:/path/to/<Julia directory>/bin"

Donde dice "/path/to/<Julia directory>" se debe cambiar por el lugar de instalación de Julia. Para más información actualizada de los comandos e instalación en cada sistema operativo se puede acceder a [1].

Cómo correr un programa en Julia

Para poder correr un programa en Julia los archivos se guardan con la extensión .jl, por ejemplo programa.jl. Como primer ejemplo se crea un archivo de nombre hola_mundo.jl con la siguiente línea de código solamente:

println("Hola mundo!!")

Una vez creado para correr el programa se corre el siguiente comando en terminal:

julia hola_mundo.jl

En la misma terminal debería aparecer el mensaje:

Hola mundo!!

De esta misma forma se pueden correr todos los programas de Julia, usando el mismo comando con el nombre del archivo del programa deseado.

¿Por qué utilizar Jupyter?

Jupyter es una aplicación de Web la cual entre otras cosas permite el uso de Notebooks los cuales son documentos interactivos donde se pueden explicar conceptos o ejemplos de forma amplia con imágenes y demás en conjunto con código interactivo que se puede correr ahí mismo. Jupyter soporta más de 40 lenguajes diferentes entre ellos Julia [2].

La idea de instalar Jupyter surge dado que permite correr código de Julia de forma interactiva, donde se puede correr cada línea de forma separada si se deseara. Además, de poder agregar explicaciones amplias escritas de varias formas, por ejemplo, LaTeX. La mayoría de partes del tutorial de Julia tendrán un cuaderno de Jupyter específico para cada parte donde se brindan ejemplos y explicaciones de los conceptos explicados acá.

Instalación de Jupyter

Empezando con la instalación, los detalles de instalación de pueden encontrar aquí. En general se requiere de tener instalado conda o pip, luego por medio de estos se puede instalar Jupyter fácilmente. Anaconda o conda es un programa el cual incluye muchos paquetes útiles de Python por tanto es la opción recomendada, las instrucciones de instalación se encuentran en install . Una vez ahí solo se siguen las instrucciones de instalación del sistema operativo respectivo. Por otro lado, pip en general se instala automáticamente con Python, en las versiones recientes.

Para instalar Jupyter con conda se corre el siguiente comando en terminal, en Windows se corre en la terminal de conda:

conda install -c conda-forge notebook

Si se utiliza pip se utiliza este comando:

pip install notebook

Correr Jupyter

Una vez instalado para abrir un cuaderno de Jupyter en blanco se utiliza el siguiente comando en terminal:

jupyter notebook

Cuando se inicia Jupyter se abre sobre el directorio que denomina home donde se pueden abrir cuadernos, o crear uno con la pestaña new. Para poder abrir un cuaderno en específico se puede correr el comando:

jupyter notebook cuaderno_a_abrir.ipynb

Si se desea más información se puede encontrar en la página oficial en la parte de correr cuadernos. Cuando se crea un cuaderno nuevo se puede elegir el lenguaje de programación a utilizar. Antes de poder utilizar Jupyter con Julia se debe instalar el paquete IJulia.

Instalación de Paquetes en Julia

Para instalar paquetes en Julia, el proceso se hace por medio de la terminal de Julia. En Windows y macOS se puede abrir la terminal de Julia corriendo el programa instalado en su computadora, en Linux se puede correr el comando julia en la terminal. Una vez en la terminal de Julia se debe correr el siguiente comando:

using Pkg

Pkg es el manejador de paquetes de Julia y es el encargado de instalar los paquetes que uno desee. Para instalar un paquete solo se debe correr este segundo comando:

Pkg.add("Package Name") 

El primer paquete a instalar se llama IJulia el cual permite usar Julia con Jupyter, para instalarlo se corren estos comandos:

using Pkg
Pkg.add("IJulia")

De la misma forma se pueden instalar paquetes por medio de Jupyter corriendo los mismos comandos anteriores. La mayoría de paquetes soportados por Julia se pueden encontrar en Julia Hub.

  • Algunos paquetes utiles que se van a utilizar son:
    • Plots
    • ControlSystems
    • DifferentialEquations
    • Polynomials

Introducción a Julia

Esta parte de introducción del lenguaje sirve como un tutorial de las cosas más básicas que uno puede necesitar para utilizar Julia. Cubre variados temas desde como la sintaxis básica de cómo crear una variable, funciones, estructuras de datos hasta temas como el manejo de archivos de salida y entrada. Todas las partes se pueden encontrar en diferentes cuadernos de Jupyter donde se pueden encontrar más ejemplos e información sobre el tema, además de que en Jupyter si se puede correr el código para ver los resultados de los ejemplos de forma más dinámica.

Uso de variables en Julia

A la hora de utilizar variables en Julia en general no es necesario especificar un tipo ya sea si es una variable entera, flotante u otra. Lo único que se requiere en Julia es de un nombre y el dato a guardar en dicha variable, Julia automáticamente detecta que tipo es o selecciona el tipo más apropiado para este tipo de dato. Por ejemplo:

test = 1
test2 = 1.5
test3 = "Hola mundo!"

En los ejemplos anteriores en Julia la primera variable seria de tipo Int64, la segunda seria de tipo Float64 y la última sería un String. Para saber explícitamente que tipo tiene una variable se puede utilizar la función:

typeof(var) 

Donde var se reemplaza por la variable a revisar. Por otro lado, si un usuario desea definir el tipo de variable a utilizar, por ejemplo, para ahorrar memoria en contadores que nunca sobrepasan algún valor se puede utilizar la siguiente sintaxis para definir un tipo:

test = Int8(10)
test2 = Float32(1.5) 

Lo anterior crea una variable entera de 8 bits en vez de 64 bits como lo haría en general y una variable de tipo flotante con 32 bits en vez de 64. Otra forma para decidir el tipo de un variable solo sirve en variables locales, por ejemplo, dentro de una función. Las variables globales no soportan selección de tipo excepto por el método anterior. La sintaxis para variables locales es por medio del operador :: con la siguiente sintaxis:

function f()
   test::Float32 = 10
end 


Para más información sobre el manejo de tipos de variables en Julia se puede acceder a su manual de tipos oficial.

Como usar comentarios

Para utilizar comentarios en Julia se hace de la siguiente forma:

# Para comentarios de una linea se utiliza #
#= 
  Para comentarios mas largos de varias lineas se utiliza la combinacion #= texto =#
=#

Como imprimir en terminal

En general en Julia a la hora de desplegar información en terminal se utiliza la función:

println()

La función anterior imprime su contenido en la terminal y deja una línea nueva al final, similar a poner \n al final de un mensaje en otros lenguajes. También existe la función:

print()

La función anterior no deja una línea nueva al final, a diferencia del primer método. Un ejemplo de cómo utilizar las funciones anteriores seria:

println("Hola Mundo!")
print("Hola Mundo!")

Continuando, para poder imprimir variables en medio de un mensaje se utiliza el operador $ con la siguiente sintaxis:

num = 10
println("Han pasado $num días")

Donde dice $num se reemplazaría por el valor de 10 en el ejemplo anterior. El operador $ también se puede utilizar para realizar operaciones en medio de la impresión, por ejemplo:

a = 5
b = 10
println("La suma de a + b es $(a+b)")

Lo anterior despliega el mensaje más el resultado de la operación. Por último, la función println() permite impresión de comparaciones directamente como lo siguiente:

println(1 == '1')

Lo anterior mostraría en terminal el resultado de la comparación, en este caso false.

Manejo de Strings

En Julia para declarar un carácter o char se utiliza la comilla simple '.

soy_un_char = 'a'

Por otro lado, para declarar un string se utiliza la doble comilla ".

soy_un_string = "Hola!"

Si se desea crear un string con comillas dentro de él se puede utilizar la triple doble comilla """, por ejemplo:

soy_otro_string = """Acá no hay ningún "error" solo otro string"""

Una característica de los strings en Julia es que pueden ser accesados elemento por elemento como un arreglo:

println(soy_otro_string[5])

Lo anterior imprimiría la letra n del mensaje en terminal. Por otro lado, existen varias formas de combinar strings en Julia, una forma es por el operador *:

string_a = "Soy "
string_b = "un "
string_c = "ejemplo"
string_resultado = string_a * string_b * string_c

Si se corriera el código anterior lo guardado en string_resultado seria la combinación de los tres strings anteriores en ese orden. Por tanto, el resultado sería Soy un ejemplo. La segunda opción es utilizar la función string() de la siguiente manera:

string(string_a, string_b, string_c) 

La función anterior retornaría un string conformado por las tres partes en ese orden.

Estructuras de datos básicos

Esta sección cubre las estructuras más básicas del lenguaje, cada una es importante conocer por sus posibles usos y utilidad en diferentes escenarios.

Dictionaries

Un diccionario consiste en una estructura de datos la cual contiene palabras claves llamadas keywords asociadas a un dato, similar a un libro telefónico. En el libro telefónico la palabra clave o keyword sería el nombre de la persona y dato sería el numero telefónico. Para crear un diccionario se hace de la siguiente forma:

phone_book = Dict("Jose" => 20061234, "Marco" => "23456789", "María" => 98765432)

El ejemplo anterior crea un diccionario con 3 entradas similar a un libro telefónico, Jose y María son palabras claves cuyos valores son Int mientras que el valor asociado a Marco es un string. Los datos de un diccionario pueden ser de diferentes tipos. Para agregar un nuevo valor a un diccionario se utiliza la siguiente sintaxis:

phone_book["Emergencias"] = "911"

Lo anterior crea una nueva entrada llamada Emergencias. Para accesar los datos asociados a una palabra clave en un diccionario se hace de la siguiente forma:

phone_book["Marco"]

Por ultimo, los diccionarios no pueden ser accesados como un arreglo:

phone_book[1] 

Lo anterior no daría la primera entrada del diccionario, sino más bien buscaría un keyword de 1.

Tuples

Los Tuples son similar a un arreglo, su diferencia principal es el hecho que sus contenidos no pueden ser modificados, para crear un Tuple se utilizan los paréntesis ( ), por ejemplo:

tuple = ("Lunes", "Martes", "Miércoles", "Jueves", "Viernes")

Se pueden accesar los índices como un arreglo:

tuple[4] 

Lo anterior retornaría la entrada que dice jueves.

Arrays

Un arreglo es una estructura de datos la cual contiene una serie de datos de forma ordenada la cual puede ser accesada por índices y sus contenidos pueden ser modificados. En Julia a diferencia de otros lenguajes la primera entrada de un arreglo no inicia en la posición 0, en Julia inicia en la posición 1. Para crear un arreglo en Julia se utilizan los paréntesis cuadrados [ ]. Por ejemplo:

array1 = [1,2,3,4,5]
array2 = ["Jose","Marco',"María","Marta"]

En Julia también se pueden crear arreglos con diferentes tipos de variables:

array3 = [1.5, 10,"123"] 

Para accesar un arreglo se hace por medio de su índice:

array1[1] 

Lo anterior retornaría la primera entrada que contiene el número 1. Para modificar el contenido de una entrada se hace de la siguiente forma:

array1[1] = 30

En Julia la función rand() genera números al azar entre 0 y 1. Sin embargo, entre otras cosas permite crear arreglos de longitud n con la siguientes sintaxis:

array = rand(100)

Esto crea un arreglo con números aleatorios entre 0 y 1 de 100 valores.

Funciones Útiles

Algunas funciones útiles para el manejo de arrays son:

  • push!(array_or_vector_to_push, arg) Agrega un valor o dato arg al final del arreglo.
  • pop!(array_or_vector) Retorna y elimina el ultimo valor de la lista ordenada.
  • popat!(array_or_vector_to_pop ,index) Retorna y elimina el valor en algún índice, luego reajusta los contenidos del arreglo.
  • insert!(array_or_vector, index, arg) Inserta un valor en la posición indicada.

Nota: Para este tipo de funciones se debe siempre utilizar el operador !, esto se explica en la parte de funciones. En resumen, lo que hace es indicar que las funciones pueden realizar modificaciones a la estructura de datos. Para documentación sobre estas funciones se pueden acceder en la documentación oficial.

Por otro lado, la función rand() permite crear arreglos con valores aleatorios dentro de un rango de valores, por ejemplo un arreglo de tamaño 5 con valores aleatorios entre 0 y 20. Por ejemplo:

arr = rand(0:20, 5)

Lo anterior crea un arreglo de 5 entradas con valores aleatorios entre 0 y 20. La documentación oficial de la función rand() se puede encontrar acá.

Control de Flujo

While loop

Un loop de tipo while es un pedazo de codigo el cual se repite infinitamente hasta que ya no se cumpla alguna condicion (en otras palabras cuando ya no es true). La nomenclatura en Julia para un ciclo while tiene las siguientes partes:

while *condition*

   *codigo*

end

En Julia los while siempre terminan con la palabra end. Un ejemplo de un ciclo while seria:

condition = 0 
while condition < 10 
      condition+=1 
      println("Numero de iteracion $condition")
end 

El codigo anterior se ejecuta mientras el valor de condition sea menor a 10 y se va aumentando en pasos de 1 en 1.

For loop

Similar a un lazo while este tipo de loop se repite siempre y cuando se cumple una condicion. La diferencia principal nace de que se puede controlar cuantas veces ejecutar el codigo dentro del loop. La sintaxis para un for loop en Julia es:

for *variable* in *rango o objeto iterable* 
    *codigo*
end

Un objeto iterable son objetos los cuales se pueden ir revisando sus entradas de forma ordenada, como los tres visto anteriormente. Algunos ejemplos de ciclos for en Julia son:

for i in 1:10 #La sintaxis 1:10 crea un rango de valores los cuales iterar. 
    println("Numero de iteracion $i")
end 

Otro ejemplo con arrays:

arr = rand(1:20, 10)
for i in arr
    println("Contenido del array $i")
end

Ejemplo con dictionaries:

dict = Dict("Max"=>1, "Min" => 10, "Med" => 5)
for i in dict
   println(i)
end

Para recorrer matrices en general se utilizan dos for anidados de la siguiente forma:

matrix = zeros(3,3) 
for i in 1:3
   for j in 1:3
       matrix[i, j] = i + j
   end
end

La funcion zeros(m,n) crea una matriz de tamaño mxn entradas llenas de 0. Los rangos numeros comprenden los limites de filas y columnas de la matriz. Otra forma de realizar lo anterior en Julia es con la siguiente sintaxis:

for i in 1:3, j in 1:3
   matrix[i, j] = i+j
end

Dicha sintaxis permite anidar lazos for de forma mas compacta. Por ultimo, Julia permite algo muy similar a lo que se llama em Python como List Comprehensions, en Julia se llaman Array Comprehensions. Su sintaxis es la siguiente:

arr = [2*x for x in 1:10]

Lo anterior crea un arreglo de 10 entradas donde cada entrada es dos veces su posicion. Tambien se ppuede utilizar para crear matrices:

mat = [x+y for x in 1:5, y in 1:2]

Esto crea una matriz 5x2 cuyas entradas son la suma de sus posiciones.

Condicionales if else

Los condiciones if y else sirven para ejercutar diferentes partes del codigo en base a diferentes condiciones. De forma que si la condicion de if se cumple el codigo se ejecuta, sino se realiza el codigo en else. En Julia esto se ve de la siguiente forma:

if *condition*
   *codigo*
else 
   *codigo*
end

Tambien:

if *condition*
   *codigo*
elseif *condition*
   *codigo*
else 
   *codigo*
end 

Algunos ejemplos son:

num1 = rand(1:10)
num2 = rand(1:10)
if num1>num2
   println("El numero 1 es mayor con valor de $num1")
else
   println("El numero 2 es mayor con valor de $num2")
end
num3 = rand(1:10)
if num1>num2
   println("El numero 1 es mayor con valor de $num1")
elseif num3>num2
   println("El numero 3 es mayor con valor de $num3")
else
   println("El numero 2 es mayor con valor de $num2")
end

Para este tipo de condiciones simples donde solo hay dos caminos como en el primer ejemplo existe otra sintaxis más corta la cual se puede utilizar por medio del operador ?. Por ejemplo, si se desea retornar el número más grande:

num1 = rand(1:10)
num2 = rand(1:10)
(num1 > num2) ? num1 : num2 

Si la condicion se cumple se retorna num1 por ser mayor, caso contrario se retorna num2.

Funciones en Julia

Como declarar una función

En Julia las funciones se pueden declarar de varias formas. La forma más general es la siguiente:

function elevar(x,y)
     x^y
end

Lo anterior crea una función con dos entradas x y y, en Julia en general no es necesario declarar el tipo de variable a recibir. Otro ejemplo:

function f(x,y) 
     x/2+y/2
end

En Julia existe la particularidad de que cuando se hace una función la última línea de código es lo que se toma como retorno, por tanto, no siempre es necesario utilizar el keyword return. Para poder llamar la función se hace de la siguiente forma:

elevar(1,2) 

Existe otra sintaxis para funciones como las anteriores que solo realizan una cosa, reescribiendo las funciones anteriores en la nueva sintaxis:

elevar(x,y) = x^y
f(x,y) = x/2 + y/2
Uso de return en Julia

En Julia como se mencionó antes por defecto se retorna el ultimo valor de una función, sin embargo, si fuera una función más completa surge la necesidad de especificar que dato en particular retornar o si se desea terminar la función en algún punto del código, para ello se utiliza el keyword return.

Si uno desea especificar un tipo de variable en específico a retornar, por ejemplo, un Int8 se hace con la siguiente nomenclatura:

function sum(a,b)::Int8
     return a+b
end 

Como detalle final del uso de return, en Julia se pueden retornar varios valores de una función de forma fácil. Cuando se retornan varios valores lo que en realidad hace Julia es retornar un Tuple con los valores retornados. Esto se hace de la siguiente forma como ejemplo:

function calculadora(x,y)
      return x+y, x-y, x*y, x/y

También en Julia se permite asignar a variables cada parte del return de un solo, por ejemplo:

suma, resta, mult, div = calculadora(3,3) 
Significado del operador !

En Julia muchas de las funciones incluidas con el lenguaje tienen dos versiones, por ejemplo la función sort(). Las segunda versión se llama sort!(), el operador ! lo que significa es que dicha función si modifica los contenidos de su argumento. Por ejemplo si uno le pasa un arreglo a dicha función, lo que retorna en general es una copia del arreglo ordenado, pero cuando se utiliza el operador ! el arreglo como tal, es decir el arreglo original si se modifica.

Uso del operador .

El operador de . en Julia funciona similar a como funciona en Matlab. Su función es que cuando se tiene un arreglo y se llama una función sobre este con el operador . la función se corre sobre cada uno de sus elementos. Este concepto se conoce como Broadcasting en Julia. Por ejemplo, digamos que se desea elevar al cuadrado el valor de todos los elementos de un arreglo:

f(x) = x^2
arr = rand(1:10, 10)
f.(arr)

Otro ejemplo puede ser si se desean pasar todos los elementos de una matriz por alguna clase de función, por ejemplo:

Matrix = rand(1:10, (3,3))

Esta nomenclatura le indica a la función rand que debe crear una matriz 3x3 con entradas aleatorias entre 1 y 10.

matrix_func(x) = x^3/3 - 2x + x
Matrix_B = matrix_func.(Matrix)

Si se desea aún más información y detalles sobre funciones en Julia se puede encontrar en el manual de funciones en Julia.

Utilizacion de paquetes

Para utilizar paquetes en Julia se pueden utilizar los keywords import o using los dos realizan lo mismo cuando se trata de paquetes. Por otro lado, cuando se quiere incluir otro archivo se utiliza el keyword include, por ejemplo asumamos que se tiene un archivo llamado area_figuras.jl este contiene algunas funciones para calcular areas. Para incluirlo se haría nada mas:

include("area_figuras.jl")

Mientras que para llamar ciertos paquetes se puede utilizar la siguiente nomenclatura:

using ControlSystems
import Polynomials 
using Plots

Manejo de Archivos

Como abrir y cerrar archivos

Para poder acceder a un archivo en Julia generalmente se utiliza la funcion open(). Dentro de su argumento se coloca el camino al archivo en el caso que el archivo se encuentra un folder diferente al actual. Si se desea saber el folder actual donde se esta trabajando en Julia se puede utilzia la funcion pwd().

A la funcion open() se le pueden pasar varios keywords los cuales indican como se quiere abrir el archivo. Por efecto el archivo se abre solo para lectura.

Tabla de parametros
Keyword Funcion
r lectura
w escritura, creacion
a escritura, creacion, append
r+ escritura, lectura
w+ escritura, creacion, lectura
a+ append, escritura, lectura

Para abrir un archivo se puede hacer:

f = open("test.txt", "r")

Lo anterior abre el archivo para lectura y adjunta a este el nombre f. Para cerrar el archivo se utiliza la funcion close():

close(f)

Uso del bloque do en archivos y lectura

En Julia generalmente se utiliza un bloque do para el manejo de archivos, esto dado que cuando se termine a de realizar el codigo deseado sobre el archivo, este usualmente se cierra. Ademas de que generalmente no se requiere mantener el archivo abierto todo el tiempo que se corre un programa.

Por otro lado, para leer los contenidos de un archivo existen variadas maneras, una es por medio de la funcion read() a esta funcion se le indica el archivo a leer y la el tipo de variable a leer. Por ejemplo si leer un Int un Char, String, etc. La funcion deja de leer cuando encuentra un valor del tipo requerido.

Por ejemplo entonces:

open("test.txt", "r") do f
    read(f, String)
end

El codigo anterior abre el archivo con nombre f. El metodo anterior tiene el defecto de leer todo el archivo completo, si se desea procesar cada linea del texto por separado se necesita otro metodo. Para revisar si un archivo esta abierto se puede utilizar la funcion isopen().

isopen(f)

La funcion read() retorna lo pedido del archivo, en el caso de un String retorna los contenidos de todo el archivo, en el caso de un Int retornaria un valor numerico. Dichos valores pueden ser guardados en variables, por ejemplo para guardar todo el contenido de un archivo en un String se puede hacer:

open("test.txt", "r") do f
     content = read(f, String)
end 

Lo anterior lee todo el archivo como un String y lo guarda en la variable content. Una particularidad de utulizar bloques do es que la variables utilizadas dentro de estos son locales. Para poder utilizar alguna variable en el resto del programa se debe hacer algo como lo siguiente para que sean globales:

content = open("test.txt", "r") do f
       read(f, String)
end 

Los bloques do funcionan similar a las funciones donde la ultima linea contiene lo que se retorna del bloque, en el caso anterior entonces el contenido del archivo se retorna y se asigna a content. Tambien se permite retornar mas de una cosa, por ejemplo:

line1, line2 = open("test.txt", "r") do f
    line1 = readline(f)
    line2 = readline(f)
    (line1, line2)
end

Lo anterior retorna las dos primeras lineas del documento por medio de la funcion readline(), cuando se lee una linea se deja un marcador al inicio de la siguiente linea y por tanto se pueden leer lineas de forma continua agregnando mas funciones readline(). Por otro lado, los valores de las dos lineas se retornan por medio de un Tuple que las contiene. Estas luego se asigan a las variables line1 y line2 respectivamente.

Existen muchas formas para poder leer un archivo linea por linea, un primer ejemplo es por medio de la funcion eof() dicha funcion recibe como argumento el archivo y la funcion indica si ya se ha llegado al final de este por medio de retornar true. Por ejemplo:

open("test.txt", "r") do f
    while(!eof(f))
        println(readline(f))
    end
end

Otra forma de realizar lo mismo es por medio de la funcion eachline() dicha funcion retorna un objeto iterable el cual contiene las lineas del archivo. Por tanto se puede hacer algo como:

open("test.txt", "r") do f 
    for i in eachline(f)
         println(i)
    end
end

Como ultimo ejemplo existe la funcion readlines() dicha funcion retorna un arreglo con las lineas del archivo sobre el cual se puede iterar, muy similar al ejemplo anterior.

open("test.txt", "r") do f
    for i in readlines(f)
        println(i)
    end
end

Escritura de archivos

Paquete DelimitedFiles