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

complete unpacking of Named Tuples #114

Closed
rvignolo opened this issue Dec 18, 2019 · 4 comments
Closed

complete unpacking of Named Tuples #114

rvignolo opened this issue Dec 18, 2019 · 4 comments

Comments

@rvignolo
Copy link

rvignolo commented Dec 18, 2019

Hi @mauro3!

I just wanted to know why there is no macro for named tuples like the following for structs:

@unpack_P1 mt

I would need a similar macro for unpacking a named tuple.

I would like to explain to you the motivation of my request, so you can tell me if this is a good or a bad approach or if I could make it differently.

I would like non-programmers or novice programmers users to be able to define some parameters in a block, just by typing something like:

T = 1.0
K = 0.5
M = T + K
v = zeros(2)
d = 0.1
t = [i * dt for i in 0:10]

As I am aware, Parameters.jl allow to define such structure using:

@with_kw struct TermSheetParamsStruct
  T = 1.0
  K = 0.5
  M = T + K
  v = zeros(2)
  d = 0.1
  t = [i * d for i in 0:10]
end

However, this struct code is type unstable and it would have a terrible performance in many circumstances. We can solve this issue by writing the following code instead:

@with_kw struct TermSheetParamsStruct{T1, T2, T3, T4, T5, T6}
  T::T1 = 1.0
  K::T2 = 0.5
  M::T3 = T + K
  v::T4 = zeros(2)
  d::T5 = 0.1
  t::T6 = [i * d for i in 0:10]
end

However, this means that I have to modify the input block provided by the user and it seems odd.

So, at this point I started investigating about named tuples in Parameters.jl. We can define it as:

TermSheetParamsNamedTuple = @with_kw (
  T = 1.0,
  K = 0.5,
  M = T + K,
  v = zeros(2),
  d = 0.1,
  t = [i * d for i in 0:10]
)

where I still have to add commas to each line of code provided by the user, but that seems simpler. Finally, an instance pstruct of TermSheetParamsStruct or an instance pntuple of TermSheetParamsNamedTuple would be received as argument of a solver function. In this function, I need to unpack all the content. This can be done for the struct object using:

@unpack_TermSheetParamsStruct pstruct

which is great, because I will be able to evaluate any expression provided by the user depending on the parameters, inside the solver function. So, the solver function would be something like:

function solver(p::TermSheetParamsStruct)
  @unpack_TermSheetParamsStruct pstruct
  # compute a value using parameters
  return T + K + sum(v) + sum(t) + sin(d)
end

Since I won't be aware of the names and number of parameters that the user will provide, I cannot write:

function solver(p::TermSheetParamsStruct)
  @unpack T, K, M, v,  d, t = pstruct
  # compute a value using parameters
  return T + K + sum(v) + sum(t) + sin(d)
end

Finally, I would like to use named tuples because I would just have to add commas.

Thanks!

@mauro3
Copy link
Owner

mauro3 commented Dec 19, 2019

Yes, a specific unpack could be generated for the named tuple. You can make a PR for that. However, I don't think this would be the solution to your problem because you'd need to eval the expression that the user passes in; and eval works in the global scope. Plus it's bad and slow.

Why not let the user pass in a function instead? (of a specified signature) This is how most packages do this kind of stuff.

@rvignolo
Copy link
Author

rvignolo commented Dec 19, 2019

Hi @mauro3, thanks for your reply!

Well, I am not sure how to deal with the expression that the user provides yet. But your comment is correct. Maybe I would ask the user to write the parameters as:

TermSheetParamsNamedTuple = @with_kw (
  T = 1.0,
  K = 0.5,
  M = T + K,
  v = zeros(2),
  d = 0.1,
  t = [i * d for i in 0:10]
)

which is much easier than:

@with_kw struct TermSheetParamsStruct{T1, T2, T3, T4, T5, T6}
  T::T1 = 1.0
  K::T2 = 0.5
  M::T3 = T + K
  v::T4 = zeros(2)
  d::T5 = 0.1
  t::T6 = [i * d for i in 0:10]
end

Why not let the user pass in a function instead? (of a specified signature) This is how most packages do this kind of stuff.

Do you mean this:

function solver()
  T = 1.0
  K = 0.5
  M = T + K
  v = zeros(2)
  d = 0.1
  t = [i * d for i in 0:10]

  return T + K + sum(v) + sum(t) + sin(d)
end

Well, that is a great idea haha 😃!

@mauro3
Copy link
Owner

mauro3 commented Dec 22, 2019

Ok, presumably you're all set here. Feel free to ask more questions.

@rvignolo
Copy link
Author

Hi Mauro! I hope you are having a great day!

I won't be using the named tuple complete unpacking this time, because of your suggestions. Nevertheless, it would be a good addition to Parameters.jl, right? However, at the moment I won't do a PR because of two reasons:

  1. I already have an infinite amount of work 😄
  2. I have started coding in Julia a month ago, so maybe I don't have the skill set yet haha.

Again, thanks for your kind help!
Ramiro.

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

No branches or pull requests

2 participants