Skip to content

Latest commit

 

History

History
85 lines (59 loc) · 3.04 KB

generalized-string-iteration.md

File metadata and controls

85 lines (59 loc) · 3.04 KB

Generalized String Iteration

Summary

Introduce support for iterating over strings without using string.split/gmatch/sub by defining a default __iter implementation for strings.

Motivation

Luau recently introduced an __iter metamethod to create a generic iteration fashion for arrays, dictionaries, and custom objects. However, strings were overlooked during the initial implementation of this feature and do not support generalized iteration like other objects.

This proposal allows strings to be supported in generalized iteration for performance enhancement, consistent __iter behavior, and easier code for iteration through strings.

Design

Because __iter already exists, implementing this behavior should be very easy. The most simple and proper approach would be to add an __iter metamethod to the string metatable that allows iterating through strings as if they are a character array. The current string metatable only consists of an __index field that points to the string library, and no __iter method is defined.

Behavior

As stated before, the iterator will treat strings as if they are a character array:

for position: number, character: string in "Luau" do
	print(position, character)
end

Output:

1	L
2	u
3	a
4	u

Drawbacks

This implementation should have no known drawbacks and checks all the boxes. The behavior follows similar generalized-iteration behavior to other objects. Additionally, many other languages support direct iteration through strings (C#, etc.), so it will be recognizable by those transferring from other languages to Luau. Finally, __iter already exists and there is no current __iter method for strings.

Alternatives

This behavior can be implemented in Lua, but there are multiple problems with this:

  1. Code that emulates this behavior is much slower than a native C iterator would be.
  2. Code that emulates this behavior is more complicated to write and harder for beginners.

Lua Implementations

1. string.sub Iteration

local myString = "Luau"
for position = 1, #myString do
	local character = string.sub(myString, position, position)
	....
end

2. string.gmatch Iteration

local position = 1
for character in string.gmatch("Luau", ".") do
	....
	position += 1
end

3. string.split Iteration

for position, character in string.split("Luau", "") do 
	....
end

Results

char[]        	0.6009999999998854
string.sub    	5.2380000000000560
string.gmatch 	8.6480000000001380
string.split  	12.916999999999916

In a benchmark of 1,000,000 iterations of the previously listed alternatives versus an iteration over an array of the same characters, the generalized iteration outperformed the Lua implementations in every case. Not only do the alternatives require more potentially unfamiliar syntax & functions, but they also have significantly lower performance. While this benchmark isn't perfect, it is still reasonable to assume that a dedicated and optimized C __iter method for strings will outperform all alternatives.