Ctrl+P again to print, arrows/tab to navigate results, enter to confirm

    Check CGSE Julia golfing tips

    Imperative/functional/array

    Julia syntax is flexible enough to allow different programming styles. A simple task as printing the numbers from 1 to 10 each on a new line can be written in several ways.

    The classic imperative style reads

    # 29 bytes
    for i=1:10
        println(i)
    end
    

    This can be easily golfed by removing all the indentation

    # 24 bytes
    for i=1:10;println(i)end
    

    Note that no space is required between the closing bracket and end.

    Julia supports list comprehension as well, therefore we may write also

    # 23 bytes
    [println(i) for i=1:10]
    

    A more functional approach would use map as

    # 23 bytes
    map(i->println(i),1:10)
    

    where -> is used to define an anonymous function. The previous can be even shorter:

    # 20 bytes
    map(println,1:10)
    

    However, julia really shines when we start broadcasting functions over arrays. Every function can be applied to all the elements of an array by postpending a ., hence

    # 14 bytes
    println.(1:10)
    

    Broadcasting

    You can use the broadcast operator + pipe operator to save parentheses. (x->x^2+1).([1,2,3]) => [1,2,3].|>x->x^2+1

    Comparison chaining

    Julia supports comparison chaining like Python, so this also means you can sometimes save a character by replacing && with or similar:

    x>0&&println(x) # 15 chars, 15 bytes
    x>0≠println(x) # 14 chars, 16 bytes
    

    Symbols instead of string literals

    Using a symbol instead of a string literal can save one byte:

    println("FizzBuzz")
    println(:FizzBuzz)
    

    Python-like operators

    Julia uses C-like % / ÷, to get Python-like results use mod and fld.

    Using first

    When applying some transformation on every value, it can be beneficial to use a longer function and broadcasting:

    first.(a)
    a.|>n->n[1]
    

    Getting the first value of a length-1 list

    When getting the first value from a list of one element, list[] saves one byte instead of list[1].

    Grouping expressions

    You can use (...;...) as a way to group expressions that return the value of the last expression. Example: sum(j->(x+=...;b+=...;s),list) to sum s (x and b is ignored, but you can do calculations inside without counting towards that sum).

    Case study

    Here is a weird program to demonstrate julia's strangest features.

    n<* =0n,10>n+1<*
    1<println
    

    What's going on? Even though we redefined *, julia will still understand 0n as 0*n. Julia can use symbols as arguments when defining a function. We need a space between * and =. The symbol ~ is usually more useful, since no space is required after ~.

    Renaming * to p:

    n<p=p(0,n),10>n+1<p
    1<println
    

    Next we can rewrite that chained comparison as 10>n+1 && n+1<p, and rename < to f. Even though we have redefined <, the rules of comparison chains still apply!

    f(n,p)=p(0,n),10>n && f(n+1,p)
    f(1,println)
    

    So, the initial program defines a recursive function, which we use to iterate from 1 to 9, printing each number with a leading 0. Redefining a comparison operator in this fashion is often the shortest way to iterate in julia. Additionally passing auxiliary functions as symbols can save bytes in many situations.

    ! and ~

    These are useful operators to re-define as you don't need to specify their argument. For example, say we have the following

    my_long_string = "this is a long string I want to split in words"
    s(n)=split(n)
    words = s(my_long_string)
    

    this is equivalent to

    ! =split # note the space before =
    words = !my_long_string
    

    or

    ~=split
    words = ~my_long_string
    

    But it gets better as ~ is both a unary and binary operator. Hence

    another_long_string = "this_time_I'm_using_undescore_as_a_delimiter"
    ~=split
    words = ~(another_long_string,"_") # meh...
    words = another_long_string~"_"    # better
    

    Finally, say you have two functions to rename, split and join, you can pack the assignment as

    ~=split;! =join # 15B
    !,~=join,split  # -1B
    

    various

    f=popfirst!(l)
    f=popat!(l,1)   # -1B
    f,l...=l        # -5B
    
    e=pop!(l)
    l...,e=l   # -1B