Basic documentation for Struct Classes - #603
JeffersGlass wants to merge 7 commits into
Conversation
|
antocuni
left a comment
There was a problem hiding this comment.
LGTM.
One note: you might want to add two things:
- structs are passed BY VALUE, meaning that they are copied around, and thus big structs might have a penalty;
gc_ref[S]exists, although at this time it's considered a low-level primitive and end users should not use it explicitly. Later, we will provide better absrtractions on top of this. - you might want to document that if you
raw_alloc/gc_alloca struct, THEN you can mutate its content.
You might also want to mention the __ll__: gc_ptr[S] pattern, although this might be material for another PR.
| @@ -0,0 +1,157 @@ | |||
| title: Struct Classes | |||
There was a problem hiding this comment.
I'd call them just "Structs".
The fact that we need a "class" statement is a necessary evil because of Python grammar.
If/when we will be ready to deviate more from CPython grammar, I'd like to be able to write this:
type MyMetaclass Foo:
x: int
y: intand then Foo will be created by calling MyMetaclass (this is already true in ASTFrame.exec_ClassDef). In this scheme, class and struct will be just two builtin metaclasses, and class Foo would be kept as a syntax sugar for type class.
Anyway, that's the far future, but I think it shows why we shouldn't call them "struct classes"
There was a problem hiding this comment.
Makes sense! I've changed struct class to just struct everywhere.
|
I've addressed all the comments - thank you for them! I'm not super happy with my description of the |
antocuni
left a comment
There was a problem hiding this comment.
LGTM!
I tried to write an expanded section about the "new type" idiom and the __ll__ idiom, I hope you like it.
| print(p.name, "has", len(p.books), "books") # Alice has 0 books | ||
| ``` | ||
|
|
||
| By convention, if a struct is simply being used to wrap a lower-level type (to add constructors, methods, etc), that lower level type is denoted as `__ll__`. |
There was a problem hiding this comment.
What about something like this:
## "New type" pattern
A common idiom is to have a struct with a single field of type `T`: this creates a zero-overhead wrapper around `T`, which is a completely new type and makes it possible to enforce compile time type guarantees and/or to add methods and special methods to it.
The zero-overhead is guaranteed by the fact that structs are allocated "on the stack", passed by value, and translated into C structs by the C backend.
This is similar and inspired by the [newtype idiom in rust](https://doc.rust-lang.org/rust-by-example/generics/new_types.html):
```python
@struct
class Kilometers:
v: float
def to_miles(self) -> Miles:
return Miles(self.v * 1.609344)
@struct
class Miles:
v: float
def to_kilometers(self) -> Kilometers:
return Kilometers(self.v * 1.609344)
def is_a_marathon(distance: Miles) -> bool:
return distance.v >= 26.2
def main() -> None:
distance = Miles(30.0)
distance_km = distance.to_kilometers()
print("Is a marathon?", is_a_marathon(distance))
print("Is a marathon?", is_a_marathon(distance_km.to_miles()))
# print("Is a marathon?", is_a_marathon(distance_km)) ## TypeError
```
## `__ll__` pattern
This is a special case of the "new type pattern". It is used when you want to create a high-level type in terms of a low-level, possibly unsafe, implementation which is hidden to the end user.
Currently, `__ll__` is just a naming convention but in the future it might become special-cased by the compiler to make it truly private.
INSERT THE BookData example
Note that in this example, `BookData` is potentially a big struct, while `Book` is a wrapper around a *pointer* to it, so more efficient to pass around.
Normal `class`es will be (automatically) implemented using this idiom, but currently they are not supported and must be done manually.
This is also how many builtin types are implemented: `list[T]` is a pointer to `ListData[T]`, `str` is a pointer to `StrObject`, etc. See `stdlib/*.spy` for more examples.
Adds the beginnings of documentation for struct classes. (Documentation Preview Page)
I'm working on expansions to this - special methods like
__convert_to/from__,__getattr__/__getattribute__, methods that are similar to CPython (__eq__,__add__etc), which are more like CPython's data model documentation. But I wanted to get this out there before it got too big to conveniently review.