Added recent discussions #16

Merged
sb10q merged 1 commits from pca into master 2024-08-17 17:37:23 +08:00
1 changed files with 18 additions and 0 deletions

View File

@ -47,6 +47,24 @@ def fail_write() -> None:
self.a = a
self.b = b
```
* Instance variables not used would be warned by the compiler, except for those
preceded by the pseudocomment `# nac3:no_warn_unused`. (#9) The comment can
either be placed on top of the variable or next to the variable. Example:
```python
class Foo:
# nac3:no_warn_unused
pca006132 marked this conversation as resolved Outdated
Outdated
Review

We can probably also support:

a: int  # nac3:no_warn_unused

The rule would be that the comment applies to the next line if the comment is the first thing on the line, and it applies to the current line if there is something before it.

We can probably also support: ``` a: int # nac3:no_warn_unused ``` The rule would be that the comment applies to the next line if the comment is the first thing on the line, and it applies to the current line if there is something before it.
a: int
b: int # nac3:no_warn_unused
def __init__(self):
pass
```
* Use-before-define:
pca006132 marked this conversation as resolved Outdated
Outdated
Review

What if they are created on the host?

What if they are created on the host?

One way would be to check if the value is used, and if the constructor defines it. If not, see whether the result of executing build would assign to it.

Another direction would be to make build a static method with signature () -> Self, and pass the parameters to the constructor. IMO this is a more principled approach. Example:

class Foo(EnvExperiment):
    a: int
    def __init__(self, a: int):
        self.a = a
        
    # static, would not get self as argument
    def build():
        return Foo(1)
One way would be to check if the value is used, and if the constructor defines it. If not, see whether the result of executing `build` would assign to it. Another direction would be to make `build` a static method with signature `() -> Self`, and pass the parameters to the constructor. IMO this is a more principled approach. Example: ```python class Foo(EnvExperiment): a: int def __init__(self, a: int): self.a = a # static, would not get self as argument def build(): return Foo(1) ```
Outdated
Review

One way would be to check if the value is used, and if the constructor defines it. If not, see whether the result of executing build would assign to it.

No, again I would not put ARTIQ-specific features into the core of the compiler.
And build() in ARTIQ is called by the constructor anyway. https://github.com/m-labs/artiq/blob/master/artiq/language/environment.py#L244

> One way would be to check if the value is used, and if the constructor defines it. If not, see whether the result of executing build would assign to it. No, again I would not put ARTIQ-specific features into the core of the compiler. And build() in ARTIQ is called by the constructor anyway. https://github.com/m-labs/artiq/blob/master/artiq/language/environment.py#L244

The problem is that we cannot really analyze host code statically, we can only run it. What about the second option?

The problem is that we cannot really analyze host code statically, we can only run it. What about the second option?

I'm mainly thinking about static analyze without actually executing the constructor. We can also let the host execute the constructor and then check for field definition when we create the kernel object (and in fact we must do so if the kernel is host only). Should I document this?

I'm mainly thinking about static analyze without actually executing the constructor. We can also let the host execute the constructor and then check for field definition when we create the kernel object (and in fact we must do so if the kernel is host only). Should I document this?
Outdated
Review

We can also let the host execute the constructor and then check for field definition when we create the kernel object

Yes, that sounds like the only viable option in my opinion.

Should I document this?

I think so. And also explain the situation with objects that are created in kernels (with @kernel or @portable on __init__).

> We can also let the host execute the constructor and then check for field definition when we create the kernel object Yes, that sounds like the only viable option in my opinion. > Should I document this? I think so. And also explain the situation with objects that are created in kernels (with ``@kernel`` or ``@portable`` on ``__init__``).
* Host-only constructor: Error if a certain field `f` is
pca006132 marked this conversation as resolved Outdated
Outdated
Review

The build() method is ARTIQ-specific and just something that is called by the EnvExperiment constructor, which may or may not be used to build compilable objects. When it is, we are simply in the "object fields were defined by host" case.
Special handling of the build() method has no place in the compiler.

The ``build()`` method is ARTIQ-specific and just something that is called by the ``EnvExperiment`` constructor, which may or may not be used to build compilable objects. When it is, we are simply in the "object fields were defined by host" case. Special handling of the ``build()`` method has no place in the compiler.
used in other kernel methods but missing from the object constructed in the
host.
* `@portable`/`@kernel` constructor: Error if a certain
pca006132 marked this conversation as resolved Outdated
Outdated
Review

Shouldn't it error out and not just warn? Calling any method on uninitialized memory sounds like certain trouble.

Shouldn't it error out and not just warn? Calling any method on uninitialized memory sounds like certain trouble.
field `f` is used in other kernel methods but not defined in the
constructor, or used in the constructor before definition.
* Three types of instance variables: (Issue #5)
* Host only variables: Do not add type annotation for it in the class.
* Kernel only variables: Denoted with type `Kernel[T]`.