What's your favorite syntactical sugar in Julia

Hi best community!

I’m planning of doing a Julia Lang tutorial series around syntactical sugar in Julia (feel free to steal the idea). Before that I want to ask you the community what your favorite syntactical sugar in Julia is :slight_smile:

I really looking forward for all your answers. Thanks!

13 Likes

I really like the ...-operator. I.e. for

nested = [[1,2,3],[4,5]]
vcat(nested...)

or

plots = [plot(rand(3,1), rand(3,1)) for i in 1:10]
plot([plots...])
6 Likes

XXX"some string"

for

@XXX_str "some string")

14 Likes

xxx |> typeof

xxx |> dump

10 Likes

The broadcast operator really does it for me. It makes code so much more succinct and readable. Has probably saved me days of my life writing code at this point.

27 Likes

If you are considering packages, JuMP.jl has a nice mechanism of choosing the best container for your variables/constrains depending on the range you pass to it (if it is a 1:N range it is a Vector, if it is X:N it is a non-array dense container, if it has holes it is yet another container). Most users never perceive that.

2 Likes

I was just using JuMP yesterday, and I was a little upset finding tutorials with deprecated syntax everywhere. Then I started realizing what changed and why - all I can say is “thank you”. I’ll second the clever and hard work that’s been done to make JuMP more Julian and easy to use.

2 Likes

I second @ckneale’s suggestion broadcasting. One simple . lifts functions into a different realm, invoking an elaborate, customizable framework that can yield huge optimizations.

Also, it is simply the right answer to the question every numerically oriented language faced at some point so far, ie which operations should “vectorize”. The Julian answer is none of them, because f. will “vectorize” every possible function and fuse loops.

Other than that, I think that compared to some languages, Julia has been quite parsimonious with syntactic sugar, and it (again) is the right decision (at this point, astute readers can tell that I happen to like the language). You need a bit of sugar for the important things, otherwise you just want composable zero-cost abstractions.

28 Likes

I enjoy using the do syntax. It makes anonymous functions much more readable to me.

9 Likes

I think the getproperty / getfield methods for dot notation as well as getindex / setindex! for bracket notation are pretty cool and allow a lot of extensions

7 Likes

Yea I agree with dot broadcasting and splatting. My code is littered with these.

I also like generators if we are considering those as sugar as well. Same with @views.

4 Likes

A recent addition I REALLY love:

fun(;name = "John Doe") = println("Hi ", name)
# before
name = "Robert"
fun(;name = name)
# now
fun(;name)
11 Likes

this is nuttier

(xxx, yyy) .|> (typeof, dump) is equivalent to (typeof(xxx), dump(yyy)).

See

[[1,2], [3,4]] .|> (sum, maximum) # give [3, 4]

7 Likes

Packing named arguments is my favorite as well. I would love it they add the natural extention of this to unpacking named arguments too:

# pack named or unnamed arguments
foo(x,y)
foo(;x,y)

# unpack named or unnamed arguments
(x,y) = bar()
(;x,y) = bar()

Currently the first three cases work, it just makes sense to me that the fourth should as well.

4 Likes

how is the fourth different to the 3rd?

It would unpack based on the names rather than based on order, so it’d be equivalent to tmp=bar(); x=tmp.x; y=tmp.y. (currently you can use UnPack.jl’s @unpack x,y = bar() to do this, but I just think this functionality fits into base Julia really well).

4 Likes

f ∘ g

4 Likes
1 ∉ (2, 3)
8 Likes
[1 2
 3 4]

which is sugar for hvcat.

6 Likes
using Distributions

Dist=[LogNormal(), Gamma(), Truncated(Normal(),0,1)]
Stat=[mean, std, entropy]
[f(D) for f ∈ Stat, D ∈ Dist]

:sunglasses: :sunglasses: :sunglasses:

9 Likes