Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function chaining in Julia

Tags:

julia

Is it possible to write multiple function calls as a chain?

sum(
  map(parseIgFloat, 
    map((row) -> row.PL_Amount, 
      filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", 
        collect(ts)
      )
    )
  )
)

Turn it into something like:

ts 
  |> collect
  |> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In")
  |> map((row) -> row.PL_Amount)
  |> map(parseIgFloat)
  |> sum
like image 710
Alex Craft Avatar asked Apr 13 '26 05:04

Alex Craft


2 Answers

After searching, this seems to be the best option available

ts |> 
  collect |> 
  (list -> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", list)) |>
  (list -> map((row) -> row.PL_Amount, list)) |>
  (list -> map(parseIgFloat, list)) |>
  sum

or with the Pipe package with the macros

@pipe ts |> 
  collect |> 
  filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", _) |>
  map((row) -> row.PL_Amount, _) |>
  map(parseIgFloat, _) |>
  sum
like image 51
Alex Craft Avatar answered Apr 15 '26 21:04

Alex Craft


In general, what you ask is difficult, since whatever construct you came up with, you would have to guarantee the order of arguments as passed is the order expected by the function, so there is no general enough method to allow you to do this without defining explicit types and operations for it.

However, with respect to map and filter specifically, it is trivial to create 'curried' versions of these functions and apply chaining to them. E.g.

# Create curried versions of map and filter for use in 'chaining'
import Base.map;    function    map(f); return L ->    map(f,L); end;
import Base.filter; function filter(f); return L -> filter(f,L); end;


f  = x -> x ^ 2;
ts = range(1, stop=10);

( ts
  |>  collect          
  |>  map(f)             # square the collection
  |>  filter(iseven)     # keep only even results
  |>  sum              
)

Output:

220


PS: Chaining is mostly about ease of readability, and is most useful when you have a succession of individually simple and visually straightforward commands, as above. If you're going to have complicated expressions in your 'chain', like the ones in your proposed solution, then it's not really worth it in my opinion. Either wrap your complicated expressions into appropriately named functions that make the chain read like plain english, or avoid chaining in the first place, and rely on clear steps using temporary variables instead.

PS2: Also note that, the |> operator is a valid target for broadcasting, like any function. Therefore |> map(f) above could also have been written more simply as .|> f instead.

like image 33
Tasos Papastylianou Avatar answered Apr 15 '26 19:04

Tasos Papastylianou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!