-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wing libraries #130
Comments
Hi, This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. |
Hi, This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. |
Hi, This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. |
This PR introduces an up-to-date language reference - all wishlist/roadmap feature mentions were deleted and instead put into new/existing issues, with a link in a newly added "Roadmap" paragraph at the end of relevant sections.. All code samples (Wing and TypeScript) were tested and should successfully compile. [Rendered version of the language reference](https://github.com/winglang/wing/blob/urib/lang-ref/docs/docs/03-language-guide/90-reference.md#1149-roadmap). Fixes #2420 ### TODO - [ ] I'll remove all typescript code samples in a follow-up PR ### Misc - [x] Changed the rust debugger to debug the current open `.w` file by default (relevant contributor guide doc updated). - [x] Small fix of a couple of tree-sitter test headlines. - [x] Fixes #2696 - by defining the behavior of `for` loops. ### I simply removed the following spec features/requirements: 1. In 1.1.4.8 Json logging “It is also legal to just log a json object” 2. In 1.2 Utility Functions: “The above functions can accept variadic arguments of any type except `throw` which only accepts one argument and that is the message to be contained in the error.” 3. In 1.4 Storage modifiers: “The name of any static data member and static member function must be different from the name of the containing class regardless of the casing.” 4. In 2.6 For: “Type annotation after an iteratee (left hand side of **in**) is optional.” 5. In 3.2 Classes: “Optionals are initialized to `nil` if omitted, unless the type is `nil?`, which in that case, absent initialization is a compile error.<br/> Member function and field access in constructor with the "this" keyword before all fields are initialized is invalid and would throw a compile error.<br/> In other words, the `this` keyword is immutable to its field access operator `.` before all the member fields are properly initialized. The behavior is similar to JavaScript and TypeScript in their "strict" mode.” 6. In 3.3 Preflight classes: Scope and ID are “both overrideable by user-defined ones in constructor.” 7. In 3.8 Enumeration: “Last comma is optional in single line definitions but required in multi line definitions.” “`nameof` operator” 8. Entire section: 6.1.2 Shell strings 9. Entire section: 6.4 Kitchen Sink 10. Entire section: Inspiration (last section) ### Issues opened/changed to track spec completeness: - [x] Opened issues: - [x] #3121 - [x] #3123 - [x] #3129 - [x] #3139 - [x] #3140 - [x] #3142 - [x] Changed description: - [x] #108 - [x] #2103 - [x] #116 - [x] #125 - [x] #128 - [x] #129 - [x] #130 - [x] #1737 ## Checklist - [x] Title matches [Winglang's style guide](https://docs.winglang.io/contributors/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [ ] Tests added (always) - [x] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Monada Contribution License](https://docs.winglang.io/terms-and-policies/contribution-license.html)*.
This PR introduces an up-to-date language reference - all wishlist/roadmap feature mentions were deleted and instead put into new/existing issues, with a link in a newly added "Roadmap" paragraph at the end of relevant sections.. All code samples (Wing and TypeScript) were tested and should successfully compile. [Rendered version of the language reference](https://github.com/winglang/wing/blob/urib/lang-ref/docs/docs/03-language-guide/90-reference.md#1149-roadmap). Fixes #2420 ### TODO - [ ] I'll remove all typescript code samples in a follow-up PR ### Misc - [x] Changed the rust debugger to debug the current open `.w` file by default (relevant contributor guide doc updated). - [x] Small fix of a couple of tree-sitter test headlines. - [x] Fixes #2696 - by defining the behavior of `for` loops. ### I simply removed the following spec features/requirements: 1. In 1.1.4.8 Json logging “It is also legal to just log a json object” 2. In 1.2 Utility Functions: “The above functions can accept variadic arguments of any type except `throw` which only accepts one argument and that is the message to be contained in the error.” 3. In 1.4 Storage modifiers: “The name of any static data member and static member function must be different from the name of the containing class regardless of the casing.” 4. In 2.6 For: “Type annotation after an iteratee (left hand side of **in**) is optional.” 5. In 3.2 Classes: “Optionals are initialized to `nil` if omitted, unless the type is `nil?`, which in that case, absent initialization is a compile error.<br/> Member function and field access in constructor with the "this" keyword before all fields are initialized is invalid and would throw a compile error.<br/> In other words, the `this` keyword is immutable to its field access operator `.` before all the member fields are properly initialized. The behavior is similar to JavaScript and TypeScript in their "strict" mode.” 6. In 3.3 Preflight classes: Scope and ID are “both overrideable by user-defined ones in constructor.” 7. In 3.8 Enumeration: “Last comma is optional in single line definitions but required in multi line definitions.” “`nameof` operator” 8. Entire section: 6.1.2 Shell strings 9. Entire section: 6.4 Kitchen Sink 10. Entire section: Inspiration (last section) ### Issues opened/changed to track spec completeness: - [x] Opened issues: - [x] #3121 - [x] #3123 - [x] #3129 - [x] #3139 - [x] #3140 - [x] #3142 - [x] Changed description: - [x] #108 - [x] #2103 - [x] #116 - [x] #125 - [x] #128 - [x] #129 - [x] #130 - [x] #1737 ## Checklist - [x] Title matches [Winglang's style guide](https://docs.winglang.io/contributors/pull_requests#how-are-pull-request-titles-formatted) - [x] Description explains motivation and solution - [ ] Tests added (always) - [x] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Monada Contribution License](https://docs.winglang.io/terms-and-policies/contribution-license.html)*.
Initial thoughts... At a high level, supporting Wing libraries can be broken into two parts: packaging and publishing. Packaging means turning a Wing module (collection of classes, interfaces, structs, etc.) into a shareable artifact. We have several options:
The downsides of approaches (2) and (3) are that they also don't move us towards the goal of making Wing libraries usable in other JSII languages. (3) would also likely result in worse compilation and language server performance for users. (1) is my current recommendation. Publishing means actually sharing the Wing library artifact in a way that others can consume it. Some options:
Some previous discussion about hosting libraries in a central place can be found here. In options (2) and (3), we could publish libraries to npm (under a common namespace, like It might be worth to support support a combination of options, like (1 and 2) or (1 and 3). (1) is the easiest support since it doesn't require any extra work to implement assuming our packaging strategy involves producing an npm tarball. (2) could add some friction to library authors (for example, Wing maintainers may need to approve pull requests and library authors may be unable to run E2E tests in our library monorepo) - but it might be good enough to start with and then switch to (3) once there are more growing pains. Footnotes
|
|
Aligning on the designFirst, I wanted to asynchronously try to align on the motivation for this design for my own understanding, and to make the design motivations easier to understand by others for docs and so on. For me, sharing these thoughts in a GitHub comment seemed like a good enough place to make it available to everyone (and to give the opportunity to be corrected, and for others to ask questions). Before digging into details, I want to call out that deciding how to "modules" and "libraries" are organized and authored in Wing is subjective, to an extent. I say that because users may wish to express the same kinds of libraries with the same end-user semantics (i.e. with public and private API elements, grouped into hierarchies). The main differences and tradeoffs are about the authorship experience -- like how many lines of code the user will have to write, how they're able to organize files, and so on.
So far, the existing compiler implementation treats each file as its own module. When you write a bring "./foo.w" as foo; If two Wing files have classes with the same names, there isn't any issue since each module is independent, so there can't be name collisions. (One consequence of this is that today, it's not possible for two Wing files to There isn't a way today to define submodules (e.g. I want
In Elad's current design, each module is simply defined by a directory - so any files within the same directory will be part of the same module. Modules could be used with a similar syntax that we have today (though the syntax isn't critical): bring "./foo" as foo; // expects `foo` to be a directory My understanding of the benefits of this approach:
My understanding of the potential drawbacks of this approach:
Unresolved questionsHow are API elements made available between files in a module?Suppose a module contains two sibling files,
How do
|
Aside - how might the compiler implementation work?Today the compiler starts by parsing all files in the Wing project. It creates a stack of files to parse, and then does the following:
A graph of files is built during this process -- if files "bring" each other in a cycle, this is caught during parsing. Then, it type checks all of the files in a topological order, using the fact that each file is an independent module. Each file's symbol environment is stored in a lookup table, and when a "bring" statement is encountered, the lookup table is used to load types from a previously type checked file. In the new module system, the compiler needs to support modules being spread across multiple files and directories (that might never reference each other!) Since a file like
Then, files need to be type checked. The order type checking happens matters because it's possible a project has two sibling modules, After compiling each module, the compiler could combine the symbol environments together, and check that no API elements with the same name are created within the same module (regardless of whether they are public or not). From the LSP side, updating a file will cause that one file to be re-parsed, and for now the entire project will be re-type checked, though we can improve on this in the future. |
(sharing more thoughts out loud) There's one more unanswered question on my mind, which is around how we should model compilation entrypoints. When a user opens a Wing file while using the language server today, since each file is its own module, the compiler treats that as the entrypoint for generating error diagnostics. When you open more files (perhaps they depend on the original file, or the new files depend on the first file you opened), it incrementally builds this compilation graph of the files relevant at the moment. But with the directory-as-a-module design, we instead need to treat the file's parent directory as an entrypoint. This gets a little tricky if the file you open isn't at the root of your project -- e.g. it could be in a subfolder. We would need to pretend that file's directory is the root and compile it like that, and then change it if the compiler suddenly All of these rules for how to incrementally compile different directories of files based on what you've opened seem a bit complex and error-prone to me. For example, it opens up the possibility for bugs that only appear if you open files in a certain order. I'm starting to think it might be simpler if we define some convention for identifying the "root" of a Wing project (like |
The following section should be added to the language reference:
5.1.2 Internal Libraries
Wing libraries themselves are JSII modules. They can be used in all other JSII
supported languages.
The text was updated successfully, but these errors were encountered: