noir-lang / noir

Noir is a domain specific language for zero knowledge proofs
https://noir-lang.org
Apache License 2.0
821 stars 177 forks source link

Epic: Metaprogramming #4594

Open jfecher opened 3 months ago

jfecher commented 3 months ago

Proposal: https://hackmd.io/Tkzo_ryvTsWMPESmWHPiZw?view

### Core Tasks for Noir 1.0
- [ ] https://github.com/noir-lang/noir/issues/4586
- [ ] https://github.com/noir-lang/noir/issues/4587
- [ ] https://github.com/noir-lang/noir/issues/4588
- [ ] https://github.com/noir-lang/noir/issues/4589
- [ ] https://github.com/noir-lang/noir/issues/4590
- [ ] https://github.com/noir-lang/noir/issues/4591
- [ ] https://github.com/noir-lang/noir/issues/4796
- [ ] https://github.com/noir-lang/noir/issues/4916
- [ ] https://github.com/noir-lang/noir/issues/4917
- [ ] https://github.com/noir-lang/noir/issues/4924
- [ ] https://github.com/noir-lang/noir/issues/4925
- [ ] https://github.com/noir-lang/noir/issues/4953
- [ ] https://github.com/noir-lang/noir/issues/4954
- [ ] https://github.com/noir-lang/noir/issues/5146
- [ ] https://github.com/noir-lang/noir/issues/5168
- [ ] https://github.com/noir-lang/noir/issues/5201
- [ ] https://github.com/noir-lang/noir/issues/5255
- [ ] https://github.com/noir-lang/noir/issues/5285
- [ ] https://github.com/noir-lang/noir/issues/5284
### Bugs for Noir 1.0
- [ ] https://github.com/noir-lang/noir/issues/4879
- [ ] https://github.com/noir-lang/noir/issues/4915
- [ ] https://github.com/noir-lang/noir/issues/4922
- [ ] https://github.com/noir-lang/noir/issues/5194
- [ ] https://github.com/noir-lang/noir/issues/5333
### Nice-to-haves for Noir 1.0+
- [ ] https://github.com/noir-lang/noir/issues/3379
- [ ] https://github.com/noir-lang/noir/issues/4592
jfecher commented 1 week ago

Current goal is to get a vertical slice of metaprogramming working to support deriving a trait impl of a simple type on a simple trait like Default:

comptime fn derive_default(typ: TypeDefinition) -> Quoted {
    let generics: [Quoted] = typ.generics();
    assert(generics.is_empty(), "derive_default: Deriving Default on generic types is currently unimplemented");

    let type_name: Type = typ.as_type();
    let fields: [(Quoted, Type)] = typ.fields();

    let fields: Quoted = fields.map(|(name, _)| quote { $name : Default::default(), })
        .join();

    quote {
        impl Default for $type_name {
            fn default() -> Self {
                Self { $fields }
            }
        }
    }
}

#[derive_default]
struct Foo {
    x: Field
}

// Expected output:
//
// impl Default for Foo {
//     fn default(this: Self) -> Self {
//         Foo {
//             x: Default::default(),
//         }
//     }
// }

Required unimplemented features:

Edit: We used to have a Code type for quoted code. Maybe we should use that name over Quoted?