Hope Julia can use some shorter key words!

Technically, one does not actually ever need to use the function or end keywords in julia. For instance, here’s random chunk of julia code I had laying around which uses a wide range of language constructs:


function f(p=0,q=1)                  # define the function
    if rand() < 0.5                  # flip a coin. 
        if p < (q - 1)               # if the coin gives heads, check if p < (q - 1)
            while gcd(p+=1, q) != 1  # increment p while the greatest common divisor or p+1 and q is not equal to 1
            end             
            return f(p, q)           # recursively call f(p, q) (where p has been incremented)
        else
            return f(1, q+1)         # if p is not greater than q - 1, we recursively call f(1, q+1)
        end
    else
        return p//q                  # If the coin flip gives tails, we return the Rational number p//q
    end
end

let
    data = [f() for _ in 1:10_000_000]
    for frac in [(0//1), (1//2), (1//3), (2//3), (1//4), (3//4), (1//5), (2//5), (3//5), (4//5), (1//6), (5//6)]
        freq = count(x -> x == frac, data)/length(data)
        println("P($(frac)) ≈ $freq")
    end  
end 

Now here is me rewriting it without using function or end and I’ll let you be the judge of whether this is preferable:

eval(Expr(:macro, Expr(:call, :while, :cond, :body), :(nothing; esc(Expr(:while, cond, body)))))
eval(Expr(:macro, Expr(:call, :while, :cond       ), :(nothing; esc(Expr(:while, cond, nothing)))))
eval(Expr(:macro, Expr(:call, :for,   :iter, :body), :(nothing; esc(Expr(:for,   iter, body)))))

eval(Expr(:macro, Expr(:call, :let, :body), :(nothing; esc(Expr(:let, Expr(:block), body)))))

f(p=0,q=1) = 
    (rand() < 0.5 ?               # flip a coin. 
     (p < (q - 1) ?               #   if the coin gives heads, check if p < (q - 1)
      (@while(gcd(p+=1, q) != 1); #     increment p while the greatest common divisor or p+1 and q is not equal to 1          
       f(p, q))                   #     recursively call f(p, q) (where p has been incremented)
      : f(1, q+1))                #   if p is not greater than q - 1, we recursively call f(1, q+1)
     : p//q)                      # If the coin flip gives tails, we return the Rational number p//q

@let((data = (_ -> f()).(1:10_000_000);
      @for(frac = [(0//1), (1//2), (1//3), (2//3), (1//4), (3//4), (1//5), (2//5), (3//5), (4//5), (1//6), (5//6)],
           (freq = count(x -> x == frac, data)/length(data);
            println("P($(frac)) ≈ $freq")))))

The eval expressions at the beginning were for creating the macros @while, @for and @let which allowed me to create while, for and let blocks without using the end keyword.

If you don’t like the keywords while, for and let, you could call them @w, @f, and @l.

It should go without saying that writing this sort of code is not a good idea if you want to share it with or get help from anyone who doesn’t share your sensibilities, but I just wanted to demonstrate that this is actually not too hard to do in julia.