xls icon indicating copy to clipboard operation
xls copied to clipboard

const if / for / match / fn proposal

Open wsipak opened this issue 1 month ago • 2 comments

Related issues: support for const if expr in proc config DSLX Constexpr-If Semantics Conditional proc instantiation based on parameter values

This is a proposal for compile time if expressions. Also match, for and fn keywords are included here to allow a discussion that can lead to a consistent solution for them as well.

Why

The issues reported so far express the need for if expressions that:

  • have the condition evaluated in compile time,
  • allow spawning procs based on the if condition,
  • allow creating branches that use types valid when the branch is chosen, not necessarily otherwise.

This is an example of a (currently unusable) way to spawn procs conditionally:

proc Add3Adv<IN_W: u32, OUT_W: u32 = {IN_W}> {
    type InData = uN[IN_W];
    type OutData = uN[OUT_W];

    config(
        data_r: chan<InData> in,
        data_s: chan<OutData> out
    ) {
        if IN_W != OUT_W {
            let (conn_s, conn_r) = chan<OutData>("conn");
            spawn Adapter<IN_W, OUT_W>(data_r, conn_s);
            spawn Add3<OUT_W>(conn_r, data_s);
        } else {
            spawn Add3<OUT_W>(data_r, data_s)
        };
    }

    init { () }
    next(state: ()) { }
}

Another example, where depending on the parameter value, which is known at compile time, type checking fails on the unused branch:

fn f<A: u32>(a : u32) -> u32 {
  if A == u32:0 {
    a
  } else {
    let b : u32[A] = u32[A]:[u32:1,];
    for (i, acc) in u32:0..A {
      b[i] + acc
    } (u32:0)
  }
}

Solution

  1. Allow using compilation time if expressions, worded as const if, const_if!, constexpr if, if constexpr or another way that may be proposed in discussion here.
  2. Evaluate the condition and drop the unused branch before type checking, or skip type checking for it.
  3. Treat as errors in case the condition is not in fact possible to evaluate.

Considerations about the keywords

As DSLX mimics Rust, it's worth noting that while Rust provides various ways for compile time evaluations see Tracking Issue for inline const patterns, all the existing solutions enforce type checking.

Another issue is open for a const if evaluation that would not perform type checking on the unused branch.

const if / const match / const for / const fn

+ As it's proposed in Rust, we might have the same in DSLX, which has been worded in opinions in the linked issues already. + It would allow consistency with other expressions like const match, const for, const fn. - is not the same as const currently used in DSLX, so the meaning of const would depend on the use (The const keyword is used to define module-level constant values.)

const_if! / const_match! / const_for!

+ Considering Rust, this actually reflects the fact that macros are the construct allowing skipping type checking for unused code. - Using const_fn! to define a function would be unconventional. If we consider const fn for functions, this would be inconsistent. + No need to change the meaning of const in DSLX.

constexpr if / constexpr match / constexpr for / constexpr fn

+ in C++, if constexpr reflects the goal of the proposal here + no need to change the meaning of const in DSLX - longer keyword - doesn't mimic Rust

This issue has been created to encourage discussions about the addition to DSLX, the keywords used, and the existing constructs that might be replaced by this and become legacy (like unroll_for!).

You can see a WIP PR with const if implementation in: https://github.com/google/xls/pull/3268

wsipak avatar Dec 09 '25 12:12 wsipak

FYI @richmckeever @proppy

rw1nkler avatar Dec 09 '25 14:12 rw1nkler

As an additional keyword consideration, it seems that the Rust community is also discussing if const, see https://github.com/rust-lang/rfcs/issues/3582#issuecomment-2100460117

proppy avatar Dec 09 '25 15:12 proppy