Skip to content

[Idea] Syntactic sugar for channel data converter/adapter #1973

@mikex-oss

Description

@mikex-oss

What's hard to do? (limit 100 words)

When the channel data type (and semantics) match up exactly, it's convenient to just take the two channel ends and pass them along to child procs for "direct" connectivity inside proc config. You don't need to worry about introducing ordering complexity into proc next.

However, suppose you have two IPs (procs) to integrate where the output of one proc feeds the input of the other proc. The catch is that their types are only nominally compatible, e.g. (1) they may be structurally equivalent but not identical, or (2) be the same bits type but one is binary encoded and the other is Gray encoded.

Without touching either sub-proc, you now need to write another "adapter" proc to do an explicit conversion. Then the child proc 1 output channel feeds into the adapter proc, and the output of the adapter proc can feed into child proc 2.

Writing and integrating another child proc to spawn is cumbersome with not much interesting going on besides the actual data conversion logic.

Current best alternative workaround (limit 100 words)

You can write an adapter proc like:

proc FooBarAdapter {
  foo: chan<Foo> in;
  bar: chan<Bar> out;

config(foo: chan<Foo> in, bar: chan<Bar> out) {
  (foo, bar)
}

next(state: ()) {
  // recv on foo
  // convert foo to bar
  // send on bar
}

and pass the corresponding channel ends to this adapter proc:

proc Parent {

  config() {
        let (foo_s, foo_r) = chan<Foo>("foo");
        let (bar_s, bar_r) = chan<Bar>("bar");
        spawn Child1(foo_s);
        spawn FooBarAdapter(foo_r, bar_s);
        spawn Child2(bar_r);
  }
}

Your view of the "best case XLS enhancement" (limit 100 words)

It would be nice to have some built-in that allows you to write a conversion function and connect up different typed channel ends.

A couple brainstormed ideas:

fn foo_to_bar(x: Foo) -> Bar { ... }

proc Parent {

  config() {
        let (foo_s, bar_r) =
            chan_adapter<Foo, Bar>("foobar", foo_to_bar);
        spawn Child1(foo_s);
        spawn Child2(bar_r);
  }
}

or @grebe's more incremental version:

proc Parent {

  config() {
        let (foo_s, foo_r) = chan<Foo>("foo");
        let (bar_s, bar_r) = chan<Bar>("bar");
        spawn Child1(foo_s);
        spawn Child2(bar_r);
        connect(foo_r, bar_s, foo_to_bar);
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    dslxDSLX (domain specific language) implementation / front-endenhancementNew feature or request

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions