I'll take it in the opposite direction of uniformity, and point out that
another useful approach is to pass the optional output in as an argument:
function myfunction!(output2, input1, input2, ...)
# do some calculations
if !isa(output2, Nothing)
for i = 1:n
output2[i] = ...
end
end
output1
end
output1 = myfunction!(nothing, x, params)
g = Array(T, sz)
output1 = myfunction!(g, x, params)
This is used extensively in optimization, where output2 might be storage for
the gradient.
Best,
--Tim
On Friday, March 06, 2015 08:24:08 PM Milan Bouchet-Valat wrote:
> Le jeudi 05 mars 2015 à 11:59 -0800, Pooya a écrit :
> > Thanks for this clear explanation. If I do the following, is my
> > function type still unstable? How do you compare the following
> > solution to yours in terms of efficiency, style, etc?
> >
> > function compute_outputs(..., output2Flag)
> >
> > # do some stuff, get x, y, and z
> > # compute output 1
> > output1 = ...
> > if output2Flag
> >
> > # compute output 2
> > output2 = ...
> >
> > else
> >
> > output2 = SparseMatrixCSC[] # the same type as output2 when it is
> >
> > computed
> >
> > end
> > return output1, output2
> >
> > end
>
> This version indeed appears to be type-stable, so it should be quite
> efficient. Users will also be able to write
> a, b = compute_outputs(..., false)
> or
> a, = compute_outputs(..., false)
> when they don't care about the second output. So it's not a bad design,
> but returning a second output even when not needed isn't super
> satisfying.
>
> Thus, maybe Steven's suggestion to create two separate functions is
> better. Do you have any reason to think it's not practical for your
> case?
>
> We should probably decide what's the most idiomatic solution, and
> document it to ensure consistency. What do other people think?
>
>
> Regards
>
> > On Thursday, March 5, 2015 at 10:58:02 AM UTC-5, Steven G. Johnson
> >
> > wrote:
> > On Wednesday, March 4, 2015 at 6:38:28 PM UTC-5, Pooya wrote:
> > Thanks for your response. I am not sure what you mean
> > by a lower-level subroutine. Is that a function inside
> > another one? If yes, How does the scope of variables
> > work for that?
> >
> > From your description, right now you have:
> >
> >
> > function compute_two_outputs(...)
> >
> > ...do some stuff, get x, y, and z....
> > ....use x, y, and z to compute output1....
> > ....use output1, x, y, and z to compute output2....
> >
> > return output1, output2
> >
> > end
> >
> >
> > Instead, if you don't always want to compute both outputs, but
> > still want to write the shared computations only once, you can
> > refactor the code to pull out the shared computations into
> > another function (that is "lower level" in the sense that
> > users won't normally call it directly):
> >
> >
> > function some_stuff(...)
> >
> > ...do some stuff, get x, y, and z....
> > ....use x, y, and z to compute output1....
> > return output1,x,y,z
> >
> > end
> >
> >
> > function compute_output1(...)
> >
> > return some_stuff(...)[1]
> >
> > end
> >
> >
> > function compute_two_outputs(...)
> >
> > output1,x,y,z = some_stuff(...)
> > ....use output1, x, y, and z to compute output2....
> >
> > return output1, output2
> >
> > end