-
Notifications
You must be signed in to change notification settings - Fork 173
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
Facilitate default values of optional arguments #62
Comments
I like this a lot. I would flip the order of arguments:
default(base, 10.0)
Sort of like Python's dictionary method get. Regarding the name, here are a few options:
* default
* argget
* optarg
* arg_default
* opt_default
* default_arg
* optval
* optget
Edit: I'll just keep editing this comment to add all the options that we are discussing below.
|
I do like this, but the more frustrating issue for me is that I often need to define two variables in the same scope with identical purpose, in this case This function would let you replace I feel constrained because the optional input is the one which becomes part of the API, and therefore should be the most readable. But it is often the internal variable which will appear the most throughout the function, which can make the function less readable. But this is still an improvement for lots of cases. |
The semantics of optional arguments make the "natural" order a little tricky. If we want the fallback value to come second, callers will have to explicitly make it a keyword arg. That is, consider the two implementations:
versus what is arguably the more natural ordering
So in practice, one would have to write expressions like |
This is a nice option for simple cases.
For such cases, I would clearly prefer to use local variables. But it would be a nice addition in
It seems that a solution for #35 must be found to go forward in many issues. |
I like it! Convenience with no apparent downsides. +1 for name default. I can't think of others. |
Sorry, I misread the very post that I cited in my comment. But I don't think |
The ultimate fix would be to change the language: j3-fortran/fortran_proposals#22 In the meantime, I think this is a great idea for stdlib to at least make it a little bit easier. @marshallward regarding a name: yes, I also think it's too general, but from the alternatives that I listed, I like it the most. Do you have some other ideas for a name? Maybe @nshaffer right. Couldn't using overloaded subroutines somehow make this work? |
@nshaffer this compiles for me with gfortran, but I don't know if it actually works: module stdlib_default
implicit none
interface default_second
module procedure default_second_1
module procedure default_second_2
end interface
contains
function default_first(to, x) result(y)
! Return first arg if second is not present
! default(1, 2) == 2
! default(1) == 1 ("x" not present, so we get the fallback value)
real, intent(in) :: to ! the fallback value
real, intent(in), optional :: x
real :: y
if (present(x)) then
y = x
else
y = to
end if
end function default_first
function default_second_1(to) result(y)
real, intent(in) :: to
real :: y
y = to
end function
function default_second_2(x, to) result(y)
real, intent(in) :: x
real, intent(in) :: to
real :: y
y = x
end function
end module
program A
use stdlib_default, only: default_first, default_second
implicit none
contains
function mylog(x, base) result(y)
real, intent(in) :: x
real, intent(in), optional :: base
real :: y
!y = log(x)/log(default_first(10.0, base))
y = log(x)/log(default_second(base, 10.0))
end function mylog
end Edit: it probably does not work, because it will always call the Edit 2: but this compiles: program A
implicit none
print *, mylog(16.)
print *, mylog(16., 2.)
contains
function default_second(x, to) result(y)
real, intent(in), optional :: x
real, intent(in) :: to
real :: y
if (present(x)) then
y = x
else
y = to
end if
end function
function mylog(x, base) result(y)
real, intent(in) :: x
real, intent(in), optional :: base
real :: y
y = log(x)/log(default_second(base, 10.0))
end function mylog
end and prints:
I think it works! |
Something that refers to the I'm leaning towards I generally feel uncertain about grabbing common keywords like this, which may be prevalent in existing codes or could become part of the language standard in the future. I'll think on it and post if anything else comes to mind. I guess for now this is just a point of caution :). |
I like |
Oh, great! Yes, I see. In practice you will never actually call As for naming, I have a strong preference for |
I'm less concerned about the ability of users to adapt than I am about preserving their right to use commonplace words for their own work. (Users can always rename external functions, but I don't think that's something we ought to encourage.) I also think it's perhaps too general to use But I agree that |
@milancurcic, @jvdp1, @zbeekman, @ivan-pi, @jacobwilliams what would be your preference for naming this? The top two contenders are |
Among the two options, I prefer Following @certik 's comment, |
(@jvdp1 the rest of the options are listed at #62 (comment), if you like any of them better.) |
Of the options above I find |
Note: if j3-fortran/fortran_proposals#22 gets accepted, then this: function mylog(x, base) result(y)
real, intent(in) :: x
real, intent(in), optional :: base
real :: y
y = log(x)/log(optval(base, 10.0))
end function mylog becomes just function mylog(x, base) result(y)
real, intent(in) :: x
real, intent(in), optional, default :: base = 10
real :: y
y = log(x)/log(base)
end function mylog Everybody: if you like the language proposal, make sure you add +1 to it. |
I too like |
Hopefully I won't be shot for saying this, but I think that I also prefer |
Sorry I missed this. I like |
It's in experimental, so we can rename it if we want to. If we all sort all available names based on how we like them, I think there is a "voting system" that allows to select candidates that "most people are ok with". If I am just judging from the above, it seems nobody is very strongly against optval. It seems some people like |
The name should be as short as possible without being cryptic. This is because in practice, the function will often be called as part of a larger expression, e.g., the |
Another idea is |
|
I agree, just few days ago I was thinking the same thing, that |
I started to look into the source code. Would be advisable to put into a single preprocessed format? |
@fiolj I submitted the PR before we'd come to any consensus about preprocessing. If you want to refactor it to use |
@fiolj I think it is a good idea to use a preprocessed format for Regarding |
Implemented in stdlib_optval. |
An annoyance with optional arguments is handling their default values. This usually looks something like:
I propose to introduce a module that exports a generic function
default
which will in many cases allow for the elimination of the local copy of the optional argument. The above example could be rewrittenThis is a convenience, but it's incredibly handy. The module is very simple to write. See, e.g., this CLF post by Beliavsky, where I first learned of this trick. I put this in all my serious codes, as it removes a lot of the tedium and error potential with optional arguments.
I can easily spin up a illustrative PR that can be fleshed out once we've decided how we're going to automate generic interfaces.
The text was updated successfully, but these errors were encountered: