Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mratsim/loop-fusion
Loop efficiently over a variadic number of containers
https://github.com/mratsim/loop-fusion
Last synced: 17 days ago
JSON representation
Loop efficiently over a variadic number of containers
- Host: GitHub
- URL: https://github.com/mratsim/loop-fusion
- Owner: mratsim
- License: other
- Created: 2018-03-18T19:51:12.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-05-11T11:59:27.000Z (over 1 year ago)
- Last Synced: 2024-10-16T10:06:17.405Z (23 days ago)
- Language: Nim
- Size: 28.3 KB
- Stars: 40
- Watchers: 6
- Forks: 3
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHEv2
Awesome Lists containing this project
- awesome-nim - loopfusion - Iterate efficiently over a variadic number of containers. (Language Features / Iteration)
README
# Loop Fusion
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![Stability: experimental](https://img.shields.io/badge/stability-experimental-orange.svg)Iterate efficiently over a variadic number of containers.
* The loop structure is generated inline at compile-time.
* There are no temporary allocation.## Status
The containers can be any number of seq, arrays or openarray of any subtype.
You can enumerate on a loop index of your choice, it must be the first parameter.## Usage
```Nim
import loopfusionblock: # Simple
let a = @[1, 2, 3]
let b = @[11, 12, 13]
let c = @[10, 10, 10]forZip x in a, y in b, z in c:
echo (x + y) * z# 120
# 140
# 160block: # With index
let a = @[1, 2, 3]
let b = @[11, 12, 13]
let c = @[10, 10, 10]
var d: seq[int] = @[]forZip i, x in a, y in b, z in c:
d.add i + x + y + zdoAssert d == @[22, 25, 28]
block: # With mutation
var a = @[1, 2, 3]
let b = @[11, 12, 13]
let c = @[10, 10, 10]forZip x in var a, y in b, z in c:
x += y * zdoAssert a == @[111, 122, 133]
block: # With mutation, index and multiple statements
var a = @[1, 2, 3]
let b = @[11, 12, 13]
let c = @[10, 10, 10]forZip i, x in var a, y in b, z in c:
let tmp = i * (y - z)
x += tmpdoAssert a == @[1, 4, 9]
block: # With iteration on seq of different types
let a = @[1, 2, 3]
let b = @[false, true, true]forZip integer in a, boolean in b:
if boolean:
echo integerblock: # With an expression
let a = @[1, 2, 3]
let b = @[4, 5, 6]let c = forZip(x in a, y in b):
x + ydoAssert c == @[5, 7, 9]
block: # With arrays + seq, mutation, index and multiple statements
var a = [1, 2, 3]
let b = [11, 12, 13]
let c = @[10, 10, 10]forZip i, x in var a, y in b, z in c:
let tmp = i * (y - z)
x += tmpdoAssert a == [1, 4, 9]
```
Expressions must return value of the same types, i.e. you can't return `void`/no value at some iterations and a concrete value at other iterations.
Due to parsing limitations, expressions `let foo = forZip(...)` require parenthesis.
## Name
The library name "Loop fusion" might be a bit confusing since there is no loop to fuse at start.
In spirit however, it is similar while "real" loop fusion merge multiple loops over multiple sequences.It's also marketable =) (check loop fusion + \)
## Implementation details
Many would probably be curious why I first generate a zip iterator then a for-loop instead of for-looping directly.
This is because it started as a variadic zip proof of concept for [Arraymancer](https://github.com/mratsim/Arraymancer) for which I need an iterator to abstract iteration details, especially in the context of multithreading.
There should be no performance cost as Nim inlines iterators as if the loop was written manually.