What's your favorite syntactical sugar in Julia

Some code I wrote in May for MLJ.jl:

function err(ŷ, y)
    return ŷ - y
end

function perr(ŷ, y; tol = eps())
    e = err(ŷ, y)
    p = 100 * e[y .!= 0] ./ y[y .!= 0]
    return p
end

using Statistics
mse(ŷ, y)  = err(ŷ, y) |> (x)->x.^2 |> mean
rmse(ŷ, y) = err(ŷ, y) |> x -> x.^2 |> mean |> sqrt
mae(ŷ, y)  = err(ŷ, y) |> x -> abs.(x) |> mean
mdae(ŷ, y) = err(ŷ, y) |> x -> abs.(x) |> median
rmdse(ŷ, y) = err(ŷ, y) |> x -> x.^2 |> median |> sqrt
maxae(ŷ, y) = err(ŷ, y) |> x -> abs.(x) |> maximum

# tutorial     Root   mean    square     error
rmse2(ŷ, y) = (sqrt ∘ mean ∘ (x->x.^2) ∘ err)(ŷ, y)
# tutorial     mean    absolute      error
mae2(ŷ, y)  = (mean ∘ (x->abs.(x)) ∘ err)(ŷ, y)


rmsl(ŷ, y) = err(log.(ŷ), log.(y)) |> x->x.^2 |> mean |> sqrt
rmslp1(ŷ, y) = err(log.(ŷ.+1), log.(y.+1)) |> x->x.^2 |> mean |> sqrt

rss(ŷ, y)  = err(ŷ, y) |> (x)->x.^2 |> sum  # AKA SSE
tss(ŷ, y)  = err(zero(y) .+ mean(y), y) |> (x)->x.^2 |> sum 
ess(ŷ, y)  = err(ŷ, zero(y) .+ mean(y)) |> (x)->x.^2 |> sum 

tss2(ŷ, y)  = mean(y) .- y |> (x)->x.^2 |> sum 
ess2(ŷ, y)  = mean(y) .- ŷ |> (x)->x.^2 |> sum 
rss2(ŷ, y)  = y .- ŷ       |> (x)->x.^2 |> sum 
rsq2(ŷ, y)  = ess2(ŷ, y) / tss2(ŷ, y)

# linear model verify 

# Mean Percentage Error (MPE) is a measure of bias
mpe(ŷ, y)    = perr(ŷ, y) |> mean

mape(ŷ, y)    = perr(ŷ, y) |> x -> abs.(x) |> mean
mdape(ŷ, y)   = perr(ŷ, y) |> x -> abs.(x) |> median
rmspe(ŷ, y)   = perr(ŷ, y) |> x -> x.^2 |> mean |> sqrt
rmdspe(ŷ, y)  = perr(ŷ, y) |> x -> x.^2 |> median |> sqrt

3 Likes
  1. Customization of for loops through iterate
  2. . for broadcast
  3. do
  4. Tuple unpacking, e.g.
a, = (1, 2) # set a to 1
foo(x, (y, z)) = x + 2y + 3z

foo((_, x)) = x # returns second element of any iterable, wow
12 Likes

Swapping two variables: x, y = y, x

12 Likes

Can we encode second_to_last, third_to_last … as nicely, without using reverse?

1 Like
"julia"^3 > "julia" ? println("That's true!") : println("That's false.")
That's true!
2 Likes

Yes, we can in the upcoming 1.6. You can just write foo((_, x...)) = x. Consuming the rest starting from the third item works similarly.

7 Likes

I had my share of anguish about local scoping in loops, but this sort of thing is compensation:

x = LinRange(-1,1,60)
y = copy(x)
U = [ sin(3x+2y) for x in x, y in y ]

Perhaps like the example by @josePereiro, we will someday just do

U = [ sin(3x+2y) for x,y ]
7 Likes

First one is recorded. I hope you enjoy it and maybe learn one new thing :slight_smile:

6 Likes

Is it possible to put the repl side by side with the code?

2 Likes

Yes, you can just drag’n’drop the terminal to the sidebar.

1 Like

Nice. I leave it as a suggestion for further videos, since the fonts need to be large and the ammount of output in the repl becomes very limited.

Agreed. I wonder why vertical stacking of panes always seems to be the default in editors, when there is so much horizontal space, and so little vertical space.

2 Likes

Though I get the argument you’re making, personally, I like the default, because I prefer to have multiple coding columns side by side with a repl below these.

Based on: https://twitter.com/fermatslibrary/status/1364580859202965512?s=20

julia> using Primes
julia> isprime(82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321)
true

or

julia> ss=""
""
julia> for x = 82:-1:1; ss = ss * string(x); end
julia> ii = parse(BigInt, ss)
82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321
julia> isprime(ii)
true
3 Likes

Not my favourite favourite, but nobody has mentioned

open("filename.ext", "w") do f
    println(f,"no need to worry about closing file")
end
7 Likes

that’s from python and ruby? right?

I don’t know where it’s from, but it’s nice.

Ruby has it, but Python does not, if I am not wrong.

1 Like

Python has something similar:

with open('file.txt', 'a') as f:
    f.write("hello there!\n")

This feature is much less general / useful and much more complicated than julia’s do blocks. On the surface, they appear to do similar things, but they’re actually quite different.

Julia’s do blocks are just syntax sugar for working with higher order functions. This makes them useful in almost any context, unlike python’s with blocks.

8 Likes