microsoft / microsoft/typespec
Calling functions in template instantiations
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
See https://github.com/microsoft/cadl/issues/462
Here we have a problem that KeysOf and ParentKeysOf are distinct types that we process twice. It would be nice if we could write:
```
alias ParentKeysOf = KeysOf>
```
However, we don't have currently have a way to author `Parent`. We have a JS function exported `getParentResource` but we don't have a way to call it. It would be nice if we somehow could.
# Brainstormed options
### 1. Allow calling exported functions in type references.
```
alias ParentKeysOf = KeysOf
```
This seems very powerful, but I have some concerns:
* **Tooling**: I once had a bug where I offered all exported functions in type reference completion and it got quite cluttered:

* **Caching**: I think it would be nice if we could cache these calls in the same way that template instantiations are cached so that you can do complex computation only once for a given set of type arguments.
### 2. Allow calling exported functions using template instantiation syntax
```
alias ParentKeysOf = KeysOf>
```
Here the `< >` parses this as a template instantiation, and when we resolve `getParentResource` to a function, we call it with the type arguments, and cache it like any other template instantiation. This solves the caching, but not the completion noise.
### 3. Explicit template to function bridge
```
alias Parent is getParentResource(T);
```
I struggled with the syntax here so consider this a straw-man. I want something that is different than `alias =`. I first had `model is` but realized it would be useful if this could return a non-model, and then realized it really is equivalent to a templated alias! But if we use `alias =` we are really back to (1). The idea here is that you can make a 1:1 between an alias and a function. So I landed at `alias is` but I don't like it.
But syntax aside this solves the intellisense pollution and allows for idiomatic type (Pascal cased, noun) and function (camel case, verb) names.
### 4. Explicit opt-in of functions as templates
```js
export function $$Parent(program: Program, type: Type) {
return getParentResource(program, type);
}
```
Here we borrow from decorators and have some way to opt a function into becoming a template on the Cadl side. Straw man: `$` is a decorator `$$` is a template. This also solves the intellisense pollution. It could further allow one fewer declaration if you imagine having `getParentResource` implementation inlined into `$$Parent`.
Contributor guide
Assessment
This issue has not been assessed yet.