Can Ada functions return arrays? - arrays

I read somewhere that Ada allows a function only to return a single item. Since an array can hold multiple items does this mean that I can return the array as a whole or must I return only a single index of the array?

Yes, an Ada function can return an array - or a record.
There can be a knack to using it, though. For example, if you are assigning the return value to a variable, the variable must be exactly the right size to hold the array, and there are two common ways of achieving that.
1) Fixed size array - cleanest way is to define an array type, e.g.
type Vector is new Array(1..3) of Integer;
function Unit_Vector return Vector;
A : Vector;
begin
A := Unit_Vector;
...
2) Unconstrained array variables.
These are arrays whose size is determined at runtime by the initial assignment to them. Subsequent assignments to them will fail unless the new value happens to have the same size as the old. The trick is to use a declare block - a new scope - so that each assignment to the unconstrained variable is its first assignment. For example:
for i in 1 .. last_file loop
declare
text : String := Read_File(Filename(i));
-- the size of "text" is determined by the file contents
begin
-- process the text here.
for j in text'range loop
if text(j) = '*' then
...
end loop;
end
end loop;
One warning : if the array size is tens of megabytes or more, it may not be successfully allocated on the stack. So if this construct raises Storage_Error exceptions, and you can't raise the stack size, you may need to use access types, heap allocation via "new" and deallocation as required.

Yes, an Ada function can return an array. For example, an Ada String is "A one-dimensional array type whose component type is a character type." Several of the functions defined in Ada.Strings.Fixed—including Insert, Delete, Head, Tail and Trim—return a String.

Related

In Delphi should I free "array of array of" variables?

Say I have a class field
a : array of array of double;
it is allocated using nested SetLength calls.
SetLength(a,100);
for i := 0 to length(a)-1 do SetLength( a[i], 100 );
On object Destroy is it necessary to loop through the first level of array to free the second level items of it?
for i := 0 to length(a)-1 do a[i] := NIL;
Is it necessary or the compiler handles freeing of multi dimensional dynamic arrays too?
Dynamic arrays are managed by the compiler. When a dynamic array's reference count drops to zero, it is automatically freed.
This is equally true for multidimensional dynamic arrays of any dimension, at every level.
So when your field a goes out of scope, this dynamic array's reference count is reduced by one. If the new reference count is zero, the array is freed, and so the reference counts of all elements a[0], a[1], ..., a[High(a)] are reduced by one. And, again, if they reach zero, they are freed too.
You don't need to do anything.
You can set the size of a multi-dimensional dynamic array with a single SetLength() call. No need to use any loop.
You do this by simply calling
SetLength(DynamicArray, FirstDimensionSize, SecondDimensionSize, ..NthDimensionSize).
So, in your case, you could set the initial size of your dynamic array by simply using:
SetLength(a,100,100);
And then when freeing up the array, you just call:
SetLength(a,0,0);

How does the computer(C compiler, or something else) handle "automatic array declaration"? | C language

I am attempting to return a dynamically declared array from a function; thus far I am returning a structure to hold a pointer to the memory block that malloc() assigned for the array AND an integer to store the length of the array.
This made me wonder; How does the C Compiler(or whatever) handle an automatic array declared in a program?
eg.
main()
{
//delcare an array holding 3 elements
int array[] = {1,2,3};
/*variable to hold length of array
*size of array / size of 1st element in the array == length of the array
*this will == 3
*/
int array_Length = (sizeof(array))/(sizeof(*array));
//call malloc for a block of memory to hold 3 integers(worth of memory)
int* ptr = malloc(3*(sizeof(int)));
/*not exactly sure what this formula means when using a pointer???
*but it seems to always == 1
*/
int dynamic_array_length = (sizeof(ptr))/(sizeof(*ptr));
return 0;
}
My point is, the sizeof() operator somehow knows that the automatically declared array has 3 integers within it.
Or more generally:
sizeof(array)
where array is (N x type_size)
N is the number of elements within the array
type_size is the number of bytes of memory used to store the data type
Are automatic arrays stored with additional information about their size/length?
Are dynamic arrays stored differently? (I know that we control when a dynamic variable is freed from memory)
Operator sizeof is a compile-time construct (with the exception of VLA arguments). It tells you the object size in bytes because it knows the exact compile-time object type. And when you know the exact type the size is also immediately known. There's no need to separately store the number of elements anywhere.
Your declaration
int array[] = {1,2,3};
is equivalent to
int array[3] = {1,2,3};
meaning that array has type int[3]. So your sizeof(array) is interpreted as sizeof(int[3]), which is immediately known to the compiler.
sizeof does not know and does not care about any "dynamic arrays" of yours. All it cares about is that in sizeof(ptr) operator sizeof is applied to a pointer. So it evaluates to pointer size.
sizeof(...) is not a function call. It doesn't actually execute at runtime - that value is replaced at the compile time, so what's actually compiled is:
int array_length = 3;
The calculation of dynamic_array_length is incorrect. You divide the size of a pointer by the size of int. Which in your case happens to be the same and get 1 as a result.
Your dynamic array is stored differently - the pointer (on the stack) is separate from the data (on the heap). The first array is just data on the stack - the memory address is constant (for that stack frame) and gets used where needed.
Disregarding VLAs, the array size of an automatic array is a fact completely known at compile time, and is actually a part of the type of the variable. sizeof is a query (resolved at compile time) to the type system, which is a thing that exists only in the compiler internal data structures while it is compiling. The result is the actual variable size, which is treated essentially as if it was directly written in the source code.
Things about sizeof has been discussed enough, and we know it is a compile-time action.
But in fact, It is true that there is something about size is stored and used in run-time for dynamic variables. Otherwise the free can not do its work correctly.
Here is a good reference: how-do-malloc-and-free-work
You are hitting one of the inconsistencies of C. An array is just a pointer, except where it has been declared. The result of sizeof (somearray) is different, depending upon whether or not sizeof is used in the function defining somearray. In, C, as soon as you move away from the definition, there is no knowledge of anything other than the type of object in the array. That is just one of the many reasons why C programming is so error prone.
Most programming languages other than C or those derived from C, maintain an array descriptor that includes the number of dimensions, the number of elements, and, in some cases, the array bounds.
In the case of dynamic arrays, the library adds overhead, usually before, to the memory returned (sometimes additional overhead is added at the end). This is used so that library can know how much memory is freed.

How to allocate a non-constant sized array in Go

How do you allocate an array in Go with a run-time size?
The following code is illegal:
n := 1
var a [n]int
you get the message prog.go:12: invalid array bound n (or similar), whereas this works fine:
const n = 1
var a [n]int
The trouble is, I might not know the size of the array I want until run-time.
(By the way, I first looked in the question How to implement resizable arrays in Go for an answer, but that is a different question.)
The answer is you don't allocate an array directly, you get Go to allocate one for you when creating a slice.
The built-in function make([]T, length, capacity) creates a slice and the array behind it, and there is no (silly) compile-time-constant-restriction on the values of length and capacity. As it says in the Go language specification:
A slice created with make always allocates a new, hidden array to which the returned slice value refers.
So we can write:
n := 12
s := make([]int, n, 2*n)
and have an array allocated size 2*n, with s a slice initialised to be the first half of it.
I'm not sure why Go doesn't allocate the array [n]int directly, given that you can do it indirectly, but the answer is clear: "In Go, use slices rather than arrays (most of the time)."

Compatibility of the tricky dynamic arrays with dynamic arrays

Considering the old trick to make an array
Type
IntArray = Array Of Integer;
PIntArray = ^IntArray
PTDynIntArray = ^TDynIntArray;
TDynIntArray = Array[0..0] Of Integer;
{later...}
GetMem(APTDynIntArray,100*SizeOf(Integer));
APTDynIntArray^[49] := 50
Is There a way to make this tricky array compatible with a standard dynamic array ?
For example, If I want to translate an old (lets say from 1999) unit with
Procedure DoSomething(Data: PTDynIntArray);
And considering that the data will be processed using the above syntax (dataname-dereference-index in brackets), Delphi compiler will not stop if I pass a PIntArray as argument, however I get an AV at run-time (I guess that Delphi considers, in this case, that PIntArray Is the same as PTDynIntArray)
So can these two types (PIntArray and PTDynIntArray) be combined, type casted, inter-changed ? How ?
You can convert an IntArray (note: not PIntArray) to a PTDynIntArray. The reverse is not generally possible.
An IntArray is stored as a pointer to the first element of the array. The array is preceded by information about the array's length and such, but if your procedure only accesses the array elements, they won't do any harm.
You may, to be explicit, also write it as #IntArray[0].

When to use array and when to use cell array?

In Matlab, I was trying to put anonymous functions in an array:
>> a=[#(k)0.1/(k+1) #(k)0.1/(k+1)^0.501]
??? Error using ==> horzcat
Nonscalar arrays of function handles are not allowed; use cell arrays
instead.
So I wonder what kinds of elements are allowed in an array, and in a cell array?
For example, I know that in an array, the elements can be numerical or strings. What else?
In short: Cell array is a heterogeneous container, regular array is homogeneous. This means that in a regular array all of the elements are of the same type, whereas in cell array, they can be different. You can read more about cell array here.
Use cell array when:
You have different types in your array
You are not sure whether in the future you might extend it to another types
You are working with objects that have an inheritance pattern
You are working with an array of strings - almost in any occasion it is preferable to char(n,m)
You have a large array, and you often update a single element in a function - Due to Matlabs copy-on-write policy
You are working with function handles (as #Pursuit explained)
Prefer regular array when:
All of the elements have the same type
You are updating the whole array in one shot - like mathematical operations.
You want to have type safety
You will not change the data type of the array in the future
You are working with mathematical matrices.
You are working with objects that have no inheritance
More explanation about copy-on-write:
When you pass an array to a function, a pointer/reference is passed.
function foo(x)
disp(x);
end
x= [1 2 3 4 5];
foo(x); %No copy is done here! A pointer is passed.
But when you change it (or a part of it), a copy is created.
function foo(x)
x(4) = x(4) + 1;
end
x= [1 2 3 4 5];
foo(x); %x is being copied! At least twice memory amount is needed.
In a cell array, only the cell is copied.
function foo(x)
x{4} = x{4} + 1;
end
x= {1 2 3 4 5}; %Only x{4} will be copied
Thus, if you call a function that changes a single element on a large array, you are making a lot of copies - that makes it slower. But in a cell array, it is not the case.
Function handles are actually the exception here, and the reason is that the Matlab syntax becomes surprising if you allow function handles to be a part of non-cell array. For example
a = #(x)x+1;
a(2); %This returns 2
But, if arrays of function handles were supported, then
b = [#(x)x+1, #(x)x+2];
b(2); %This would return #(x)x+2
b(3) = #(x)x+3; %This would extend the size of the array
So then would this be allowed?
a(2) = #(x)x+2; %Would this extend the size of the previously scalar array
Longwinded edit: This is documented in the release notes accompanying release R14, which was the first release allowing anonymous functions. Prior to R14 you could create function handles as references to m-file functions, and they could be placed in non-cell arrays. These could only be called using feval (e.g.: fnSin = #sin; output = feval(fnSin, pi)).
When anonymous functions were introduced, the Mathworks updated the syntax to allow a simpler calling convention (e.g. fnSin = #sin; output = fnSin(pi)) which had the effect of causing an ambiguity when using non-cell array of function handles. It looks like they did their best to grandfather this new behavior in, but those grandfathered conditions have certainly expired (this was 2004).
The arrays can store only data with a fixed length. For instance, double, single, char, logical, integer.
The reason is that (I guess) they are stored directly in a block of memory. On the other hand cells are stored as a list of pointers, each pointer can point to a data of different size.
That's why arrays cannot store strings, function handle, arrays, and multiple data types.
Those type can have different length. For instance 'bla' has 3 bytes, 'blabla' has 6 bytes. Therefore if they are stored in the same memory block, if you want to change 'bla' into 'blabla' you would have to shift all the rest of the memory, which would be very slow, and so it's not handled.

Resources