nevalang / neva

🌊 Flow-based programming language with static types and implicit parallelism. Compiles to native code and Go
https://nevalang.org
MIT License
85 stars 7 forks source link

`Find` component #647

Open emil14 opened 1 month ago

emil14 commented 1 month ago

Almost same as #289 except

  1. Emits single elements instead of stream(s)
  2. Emits result as soon as first element found and skips other elements

API

pub interface IFindHandler<T>(data T) (res bool)

pub component Find<T>(data stream<T>) (res T, miss any)) {
  nodes { handler IFindHandler<T> }
  // ...
}

Example usage

type Obj struct {
    id int
    name string
}

const objs list<Obj> = [
    { id: 1, name: "a" }
    { id: 2, name: "b" }
    { id: 3, name: "c" }
    { id: 42, name: "You found me!" }
    { id: 4, name: "d" }
]

component Main(start) (stop) {
    nodes {
        Find<Obj>{IsID42},
        Println
    }
    :start -> ($objs -> find)
    find:res -> println
    find:miss -> ("not found :(" -> println)
    println -> :stop
}

component IsID42(data Obj) (res bool) {
    nodes { Eq }
    :data.id -> eq:actual
    42 -> eq:expected
    eq -> :res
}

Output should be "You found me!"

emil14 commented 1 month ago

[Idea] Add idx to API

type FindResult<T> struct {
  idx int
  data T
}

Find<T>(data stream<T>) (res FindResult, miss any)

Alternative Idx component

Alternative could be having Idx or Index component for cases where you need index.

However, if you need both idx and data you'll have to chain it with some "Get" component.

Problem is we currently only have lists.Get (I think?) and to use it with Idx one have to pack stream into list which kinda defats the purpose of the stream