Monads and monoids in julia

I am trying to get a grip on how to think in terms of functional programming concepts thru Scott Wlaschin’s videos and implement them in julia

  1. The Functional Toolkit - Scott Wlaschin - YouTube
  2. Functional programming design patterns by Scott Wlaschin - YouTube

Can someone give examples on how to write the following concepts from video in julia and they fit in julia’s type system ?

  1. monad
  2. monoid
2 Likes

The Julia compiler currently does no static checking. So you can’t statically check that something is a monoid or monad. However you have multiple dispatch and it is easy to overload *,+ or whatever symbol you find appropriate for multiplication or composition. Also you could use macros for special syntax. See for instance Monadic.jl.

5 Likes

thanks for the information. Does julia conform to Railway oriented programming (ROP) ? Like examples from scott wlaschin F# videos ?

1 Like

Not sure, what Railway programming is or what conforming with it means. From a quick look at the slides, it seems that Railway programming means replacing standard function composition by some monad. I will use the term Railway programming in this sense below.

Anyway, Julia is extremely flexible and expressive. So I am pretty sure you can write julia programs that have railway syntax + semantics. However Julia does no static checking and if you try to compose apples with oranges, you will only get an error at runtime.

Also Railway programming is not so mainstream in Julia. For instance we typically use try catch and such instead of returning an error.

2 Likes

So julia is a functional dynamic typed interpreted programming language that does not follow hard functional programming conventions :slight_smile:

Nope.

5 Likes

In Julia we mostly try to not even specify the types that functions can or cant accept - and what they will return is not actually specified. So the Railway Oriented kind of model doesn’t really make sense. There are often multiple tracks with the same methods.

But I think it’s still good to avoid try/catch.

Instead of using bind and guards as in the talk, in Julia you can just define one-line methods that dispatch on the error type and just pass it through without doing anything else. As a trivial example a bunch of Base functions like findfirst will return nothing if they fail to find anything - so in small related functions you can just add methods that dispatch on Nothing and return nothing - and eventually handle that further out wherever you deal with errors. Then you can just pipe them all and nothing will be on another “track” - it will pass through all the methods that just just pass through Nothing, instead of causing some other kind of error.

To me it seems so trivial in julia it’s hardly worth having a name like “Railway Oriented”. I may be missing the point but I don’t see what using functional concepts like map and bind and lift add - the julia code will be cleaner than the F# with bind as there is no need for Result.bind in your piping. You could of course use more explicit types than Nothing to propagate errors cleanly and explicitly.

Edit: watching that really took me back to how hard a lot of these things were to learn in Haskell, and how much more intuitively you can implement those patterns in julia without ever needing to think about lift or bind or that we are constantly doing “world crossing”

3 Likes

trying to fit a programming language into a box like that tends not to workout well.
Every language is its own thing.
Think less: a taxononmy of paradigms,
and more a milkshake from one of those fancy places where you can be like “Strawberry + Mint + thrown in some crushed biscuits and chocolate chips”.
Not only is the resulting milkshake not strawberry or mint, but infact you probably can’t even use the same straw any more.
And its a bit more confusing still, because there isn’t even a clear common definition of what any of the ingredients are.
E.g. does a Strawberry milkshake have to have fresh strawberries?
Don’t try too hand to make it fit the mould of a Mint Milkshape, and just enjoy it for what it is.
Probably with a spoon, to get those last bits that sink th the bottom.

Here is a video on this theme that comes from thinking that F# and Haskell should be used similarly.
And note that F# and Haskell are much closer related than Julia and Erlang (Erlang being what i would think of as the canonical example of a functional dynamic typed interpreted programming language )

3 Likes

oops. julis is fucntions dynamic type jited programming language that does not follow hard functional programming conventions ? :slight_smile:

I notice there is not much materials on julia design pattern.
I managed to find one talk

  1. JuliaCon 2020 | Dispatching Design Patterns | Aaron Christianson - YouTube

These functional programming language talks helps me think of creative ways in coming up with invariant functions to achieve sequential logics. I am just looking for such materials with reference to julia or trying to see if these talks apply to julia. You already know how to solve almost all the ideas from the talk :slight_smile: ; but still hard for my imperative mind to comprehend.

2 Likes

I agree - I think knowing Haskell prior to julia helped me a lot - map/fold/recursion and basic functional patterns are great to know. But mostly you don’t need anything related to lift/bind/monad, just as you drop most OOP patterns like Visitor etc.

After using julia for a few years I get the feeling that a lot of programming patterns are really crutches to work around limitations of a langage. Most of the common patterns people talk about are for solving problems that we don’t have in Julia - because compilation happens at runtime and can be dynamic if the compiler can’t resolve the type, and because of multiple dispatch.

There are some other pattern crutches like Holy traits that julia has that have developed for Julias’ own unique inadequacies. Those things are probably better to focus on! Learning the type system, multiple dispatch and holy traits will give you a lot.

Maybe you should also check out (but I haven’t actually read it yet):

https://discourse.julialang.org/t/new-book-hands-on-design-patterns-and-best-practices-with-julia/

5 Likes

Effective functional programming in Julia is much closer to the way it’s done in a Lisp without tail call optimization ( e.g. clojure ).

See https://github.com/JuliaFolds and most notably GitHub - JuliaFolds/Transducers.jl: Efficient transducers for Julia

1 Like

Thanks i started reading, will keep posted on my thoughts.

2 Likes