Why do we need openArray? Rather what is the difference between openArray and seq?
var
fruits: seq[string] # reference to a sequence of strings that is initialized with '@[]'
capitals: array[3, string] # array of strings with a fixed size
capitals = ["New York", "London", "Berlin"] # array 'capitals' allows assignment of only three elements
fruits.add("Banana") # sequence 'fruits' is dynamically expandable during runtime
fruits.add("Mango")
proc openArraySize(oa: openArray[string]): int =
oa.len
assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter
assert openArraySize(capitals) == 3 # but also an array type
However the same can be achieved using seq as well. Like
var
fruits: seq[string] # reference to a sequence of strings that is initialized with '@[]'
capitals: array[3, string] # array of strings with a fixed size
capitals = ["New York", "London", "Berlin"] # array 'capitals' allows assignment of only three elements
fruits.add("Banana") # sequence 'fruits' is dynamically expandable during runtime
fruits.add("Mango")
proc openArraySize(oa: seq[string]): int =
oa.len
assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter
assert openArraySize(@capitals) == 3 # but also an array type
Isn't openArray redundant?
Maybe you are my first customer?
I tried to explain openArray here:
http://ssalewski.de/nimprogramming.html#_special_argument_types_openarray_and_varargs
In modern Nim we have also the toOpenArray() routine, so I recently added this:
http://ssalewski.de/nimprogramming.html#_slices
See end of that section.
Let me know if something is still not explained well, I may improve that in winter.
First of all openArray is compatible with array and seq isn't.
Secondly, the difference becomes more apparent in this snippet:
proc p[T](x: var openArray[T])
## can mutate x's contents but x cannot grow or shrink.
proc p[T](x: var seq[T])
## can mutate x's contents and maybe x can grow or shrink.
This can be crucial for memory safety and iteration invalidations.
But I can very well use
proc p[T](x: var array[T])
## can mutate x's contents but x cannot grow or shrink.
can't I? If yes, then openArray seems redundant.
I have not seen Stefan's response yet. Will be going through it now.
Absolutely :)
I am your first customer. I was following Rust until I really got fed up with their strange syn and quote used in procedural macros. I googled about nim and it sounds promising.
Hoping for a nice experience in using the language and interacting with the community.
I will go through your response and get back to you if I dont understand anything. Thanks
Rather what is the difference between openArray and seq?
This is explained clearly in the manual (emphasis added):
"Often fixed size arrays turn out to be too inflexible; procedures should be able to deal with arrays of different sizes. The openarray type allows this; it can only be used for parameters. Openarrays are always indexed with an int starting at position 0. The len, low and high operations are available for open arrays too. Any array with a compatible base type can be passed to an openarray parameter, the index type does not matter. In addition to arrays sequences can also be passed to an open array parameter."
Isn't openArray redundant?
With what? You can't replace an openArray parameter with array, which isn't compatible with seq. And you can't replace it with seq, which isn't compatible with arrays.
First of all openArray is compatible with array and seq isn't.
But I can very well use ... array ... can't I? If yes, then openArray seems redundant.
Um, so you took Araq's statement to mean that openArray is compatible with array but not to mean that it is also compatible with seq? Or do you plan to always write separate procs to handle array and seq arguments?
The idea that openArray (which can only occur as a parameter) is compatible with both (one-dimensional) arrays and seqs is a very simple one. Stop fighting it.
A more descriptive name like "contiguous_slice" or even "ptr_and_len"
Ugh. These are terrible names. There are already slices in Nim, and what would a non-contiguous slice be? And ptr_and_len is implementation-on-the-brain ... it's the wrong descriptive level. And what language are you writing in? The names you want are continguousSlice and ptrAndLen.
would be answer most openArray questions directly
They really wouldn't.
Term openArray is well known from Modula and Oberon
And Pascal, but I'd argue that Modula and Oberon are not well known and the common term nowadays are views, slices (Rust) and spans (C++17 or C++20).
Ugh. These are terrible names. There are already slices in Nim, and what would a non-contiguous slice be?
All names are terrible, some are more informative. But I already admitted the ship has sailed.
A non contiguous slice would be anything that's x[a..b] (or one of the other slicing variants), if it is not contiguously mapped.
And ptr_and_len is implementation-on-the-brain ... it's the wrong descriptive level.
Unfortunately, that's the level of concept that openArray is - something could be passed as an open array if and only if it can be represented as a ptr+len in the C backend. (I actually have no idea what the equivalent is in the JS backend ...)
And what language are you writing in? The names you want are continguousSlice and ptrAndLen.
I am writing in a language in which contiguousSlice and contiguous_slice are equivalent. Which language are you writing in? :)
Hoping for a nice experience in using the language and interacting with the community.
Welcome! :)
My advice about openarray is to just get used to it. IMHO it's an ugly wart in the language, needed only because array and seq aren't type-compatible. Every language has its warts...