Expand/Shrink

repeat

Definition: sequence s = repeat(object x, integer n)
Description: Create a sequence of length n where each element is x.
pwa/p2js: Prior to version 1.0.0 the repeat function would perform a bulk refcount update and rely on subsequent copy-on-write semantics. For example, repeat(repeat(0,100),100) would use 800ish bytes and an internal refcount of 100, whereas JavaScript and other programming languages, and in fact Phix itself in probably fairly short order, would use 40,000 bytes. While that was a nice idea, and occasionally might improve startup times a tiny fraction, on deeper reflection it is a completely fake saving, and probably reduces overall performance, especially if anything needs reloading to cache just for the clone, as well as being wholly and utterly incompatible with the pass-by-sharing semantics of JavaScript, and hence pwa/p2js. Hence it now performs a deep_copy(x) when needed, and I have yet to notice any significant performance loss. For more details see the Incompatibilities section of the p2js documentation.
Comments: When you repeat a string or a floating-point number the interpreter does not actually make multiple copies in memory, instead a single copy is "pointed to" a number of times, though as above nested sequence elements are now deep_copy()’d.

For efficiency reasons, if the item to be repeated appears to be a character, ie is an integer in the range 7 to 255, a string is created, otherwise a dword-sequence is created. Better overall performance was also observed by making repeat(0,n) create a dword-sequence rather than a string of nulls which was very likely to be auto-expanded to a dword sequence in the near future. Generally speaking, all further handling of the result is completely transparent whether a string or dword-sequence is created, with the following exceptions: performance gains, explicit tests with the string() builtin, #isginfo directives, accessing it using inline assembly, and lastly holding raw binary can be done in a string as one byte per element, rather than 4 or 8, which might need a secondary poke() before use.

Compatibility note: Euphoria allows an atom length/count, whereas Phix requires an integer, since I believe that deliberately trapping say 11.99 (which Euphoria truncates to 11) may help expose the occasional programming error at source, rather than ten minutes later when the sequence turns out to be one element too short.
Example 1:
repeat(0, 10)       -- {0,0,0,0,0,0,0,0,0,0}
Example 2:
repeat("JOHN", 4)   -- {"JOHN", "JOHN", "JOHN", "JOHN"}
-- The interpreter creates only one copy of "JOHN" in memory,
--  and increases the reference count of that one item by 4.
Example 3:
repeat('=', 10)     -- "=========="  (a string)
Implementation: See builtins\repeat.e (an autoinclude) for details of the actual implementation. [Moved from VM\pRepeatN.e in 1.0.0]
There is also a different hand-crafted version in p2js.js which obviously uses native JavaScript functions instead of %:pAllocSeq, etc.
See Also: append, prepend, sequence-formation operator
Expand/Shrink