Functional programming in Julia

I’m recently interested in functional programming (FP) style.

I sometimes felt that Julia has probably been inspired by FP but it seems that Julia does not officially provide FP tools, for example, lazy evaluation.

I found Lazy.jl but it looks not being maintained.

Is there any project for FP style coding in Julia? Or, FP style in Julia has been disappeared?

3 Likes

Maybe you will find this package interesting: https://github.com/thautwarm/MLStyle.jl .

5 Likes

Some things that don’t directly allow functional syntax, but still support a functional style:

  • Underscores.jl gives you better syntax for lambdas, Chain.jl is a similar alternative
  • Base.Iterators and IterTools.jl give you some lazy evaluation, e.g. when combined with Underscores.jl you can write things like
function k_digit_numbers_from_sequence(k, my_sequence_fn)
    nums = @_ Iterators.countfrom() |> 
    IterTools.imap(my_sequence_fn(_), __) |> 
    Iterators.takewhile(<(10^k), __) |> 
    Iterators.filter(>=(10^(k-1), __) |> 
    collect
    return nums
end
  • Transducers.jl is an alternative to Iterators, inspired by Clojure
  • ThreadsX.jl makes it easy to parallelize functional code, especially with ThreadsX.map
8 Likes

Just to nitpick, my understanding is that Transducers aren’t an alternative to iterators, so much as a powerful tool for optimizing the traversal and nesting of iterators.

To be a bit more precise, transducers replace the iterate function on an iterator, but do not replace the role iterators play in giving a lazy description of a set of computations.

2 Likes

Good point, and I should have clarified: the Transducers package can do a lot of the same things as the Iterators + IterTools packages, but the underlying mechanisms are quite different. Rich Hickey’s talk is always a good source for details: "Transducers" by Rich Hickey - YouTube

3 Likes

Can Transducers.jl deal with infinite iterator (like Iterators.countfrom()) for lazy evaluation?

EDIT: It works as Underscores.jl does as follows.

julia> Iterators.countfrom() |> Map(x -> 2x) |> TakeWhile(x -> x < 10) |> collect
4-element Array{Int64,1}:
 2
 4
 6
 8
3 Likes