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