Skip to content
Pyrula

IList and IMap

IList and IMap are immutable. Every operation returns a new collection and leaves the original alone. They’re structurally shared under the hood, so the copies are cheap rather than full clones.

These are for correctness and immutability, not raw speed. For plain iteration and element-wise map/filter, IList/IMap run roughly 10-25x slower than a built-in list/dict - the cost of persistent structure and the Python/Rust boundary per element. Reach for them when immutability, safe sharing, and the functional API earn that cost; in a hot numeric loop, use a built-in list/dict, or the typed numeric lists (IntList, FloatList, BytesList), which keep their data in Rust and avoid the per-element boxing.

from pyrula import IList
nums = IList([1, 2, 3, 4])
nums.map(lambda n: n * 2) # IList([2, 4, 6, 8])
nums.filter(lambda n: n % 2 == 0) # IList([2, 4])
nums.fold_left(0, lambda acc, n: acc + n) # 10
nums.append(5) # new IList; nums is still length 4

Heads and lookups return an Option, so an empty list doesn’t throw:

nums.head() # Some(1)
IList([]).head() # Nothing
nums.find(lambda n: n > 2) # Some(3)

Other operations: tail, last, take, drop, distinct, prepend, concat, flat_map, to_list, length, is_empty. IList is iterable, so for x in nums and comprehensions work.

When you have an IList of Either, split or collect them without a manual loop:

results.collect_ok() # IList of the Ok values
results.collect_err() # IList of the Err values
results.partition_either() # (IList[ok], IList[err])
from pyrula import IMap
m = IMap({"a": 1, "b": 2})
m.get("a") # Some(1)
m.get("z") # Nothing
m.set("c", 3) # new IMap; m still has two keys
m.remove("a") # new IMap without "a"
m.contains("b") # True

keys, values, and items return an IList. map_values and filter_values transform the values, merge combines two maps, and to_dict gives you a plain dict back.

Because nothing mutates in place, you can hand these to other code without defensive copies, and they’re safe to share across threads.

IList is Scala’s immutable List/Vector and IMap is its immutable Map, both persistent and structurally shared. The methods match: map, filter, fold_left (foldLeft), and head/find returning an Option instead of throwing.