Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ModelParameters ergonomics with functors and Julia's pipe operator |> #73

Closed
iago-lito opened this issue Nov 7, 2022 · 3 comments · Fixed by #131
Closed

Improve ModelParameters ergonomics with functors and Julia's pipe operator |> #73

iago-lito opened this issue Nov 7, 2022 · 3 comments · Fixed by #131

Comments

@iago-lito
Copy link
Collaborator

We've gone a good way along our "builder" pattern to create ModelParameter values without the user needing to input all content at once, with good defaults etc.

Today I think I've found the last piece of it, so it could becomes really comfy for user. Here is an example with a simplified version of ModelParameters:

mutable struct FoodWeb
    network::Matrix{Bool}
end

mutable struct Biorates
    a::Float64
    b::Float64
end

mutable struct Environment
    c::Float64
    d::Float64
end

mutable struct ModelParameters
    foodweb::FoodWeb
    biorates::Biorates
    environment::Environment
end

# Construct with all default values.
function ModelParameters(fw::FoodWeb)
    ModelParameters(fw, Biorates(1, 1), Environment(0, 0))
end

What we do today is to write functions supposed to edit the various fields in ModelParameters the correct way, without the user having to manually edit the biorates.a or environment.d values by themself:

# One modifier to address `biorates` field,
# but the user only needs to input `e`.
function set_biorates!(p::ModelParameters, e)
    p.biorates.a += e
    p.biorates.b = 2*e
    p
end

# One modifier to address all fields,
# but the user only needs to input `x` and `y`.
function set_climate!(p::ModelParameters, x, y)
    p.biorates.a -= x
    p.environment.d -= y + p.biorates.b
    p
end

Or set_stochasticity!, set_temperature!, set_nontrophic_interactions!, set_mortality! or whatever. The advantage of these functions is that they abstract details of ModelParameters away from the user, so they can focus on what they are actually doing.

The problem is that using them is not very comfortable.

  • Version 1:
parameters = set_climate!(set_biorates!(ModelParameters(FoodWeb([0 0; 1 0])), 5), 8, 13)

(very hard to write and to read correctly)

  • Version 2: breaking down the process for better readability:
foodweb = FoodWeb([0 0; 1 0])
parameters = ModelParameters(foodweb)
set_biorates!(parameters, 5)
set_climate!(parameters, 8, 13)

Nice and readable, but verbose, and it's annoying that the parameters variable needs to be passed around all the time.

Now, I've just realized that, with the following simple additions to the package:

set_biorates(e) = (p) -> set_biorates!(p, e)
set_climate(x, y) = (p) -> set_climate!(p, x, y)
  • Version 3 now also becomes possible:
parameters = ModelParameters(foodweb) |> set_biorates(5) |> set_climate(8, 13)

With all similar functions correctly adapted, sophisticated models settings would become very neat to read and write:

parameters = (
    ModelParameters(foodweb) |>
    set_biorates(5) |>
    set_climate(8, 13) |>
    set_stochasticity(44) |>
    set_temperature(25)
)

Maybe I can craft that along the next sequence of merges :)

@iago-lito
Copy link
Collaborator Author

(big up to @ilajaait for having made use of this fancy |> operator which I had never been really interested about before. While reviewing his code, I realized that |> may be the solution to the fact that Julia does not support parameters.set_biorates(5).set_climate(8, 13) syntax ;)

@iago-lito
Copy link
Collaborator Author

iago-lito commented Jan 16, 2023

Better implement this after #84 have been addressed.

@iago-lito iago-lito linked a pull request Sep 14, 2023 that will close this issue
16 tasks
@iago-lito iago-lito removed a link to a pull request Mar 15, 2024
16 tasks
@iago-lito iago-lito linked a pull request Mar 15, 2024 that will close this issue
16 tasks
@iago-lito
Copy link
Collaborator Author

Update: #131 adresses ergonomics, although not exactly using |> operators. Closing in favour of #131.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant