Dear Julia colleagues,

In June, I wondered on this newsgroup why Julia lacks an 'inarg' 
specification for functions.  The two major languages used nowadays for 
scientific programming, namely Fortran and C++, both provide mechanisms to 
declare that a function argument is read-only by the function.  Indeed, 
this was added to Fortran late in its life, so one assumes that there is 
some bitter experience underlying the decision to include it in Fortran. 
 (Matlab has only inargs, at least until you get to relatively advanced 
programming techniques, so this is not an issue.)

Stefan Karpinski provided a convincing explanation for why inarg and outarg 
specifications have been omitted from the Julia core.  Now that I am 
slightly more familiar with Julia, I would like to make a proposal for 
inarg that would not require changes to the core language.  The proposal 
would, however, entail substantial additional code, so it is intended for 
some version of Julia in the future.

Here is the proposal: suppose fn is a function that takes an array input 
"a" and wants to declare it to be read-only.  Then at the beginning of the 
function before any of the arguments gets used, there would be an 
assignment statement like this:

function fn(a::AbstractArray{Int,1})
a = readonly(a)

The way this would work is as follows: Julia would have new types, mostly 
invisible to the user, like ReadOnlyArray which would have a setindex! 
method that would throw an error, Then there would be methods like 
readonly{T.N}(a::Array{T,N}) that would use 'reinterpret' to change the 
Array to a ReadOnlyArray.  A programmer who wanted to write a function that 
could take either arrays or readonlyarrays as inputs would have to declare 
abstract argument types like DenseArray or AbstractArray.  The user would 
not, in general, have to worry about the read-only types; the situation 
when a user would have to worry about them is if he/she wants to develop a 
read-only version of his/her own data structure that internally uses the 
standard containers.

This proposal has several advantages:

(1) The above mechanism enforces the read-only property of a since fn no 
longer has access to the initial (writeable) definition of a.

(2) The above mechanism, if adopted as an idiom, could be easily spotted by 
program analysis tools that could then make optimizations based on the fact 
that a is read-only.

(3) There is hardly any performance penalty for this mechanism.

But obviously there is one big disadvantage:

(1) For each of the standard containers, a new read-only version would have 
to be written.  Furthermore, there would also have to be an abstract type 
to serve as a common parent.  E.g. there is currently no abstract parent 
for Set (although there is an open discussion about that matter on github).

and a second minor disadvantage

(2) The enforcement of read-only would probably would not work recursively, 
e.g., if a were an array of arrays.  In fact C++ has a similar gap in its 
'const' mechanism.

-- Steve Vavasis

Reply via email to