mighdoll
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee
  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # WESL imports and :: vs /. _Update: We're planning to use `::` syntax for WESL imports and inline identifiers._ We're debating what syntax WESL should use for `import` and inline identifiers. <table> <tr> <td> :: </td> <td> /. </td> </tr> <tr> <td> ```wgsl import super::util::zip; import rand_pkg as rand; fn main() { let color = rand::pcg(1.0); return zip.zap(color); } ``` </td> <td> ```wgsl import ./util/zip; import rand_pkg as rand; fn main() { let color = rand.pcg(1.0); return zip.zap(color); } ``` </td> </tr> </table> One approach uses `::` for both import statements and inline identifiers, another uses `/` for import statements and `.` for inline identifiers. (Also see below for a [combination approach](https://hackmd.io/ljkByEcnQa2NdNLWed2M6Q?both=&stext=3042%3A20%3A0%3A1732054639%3AhUj1wy)). ## WESL Module System Background ### Imports WESL will support `import` statements so programmers can mix in code from other files or from external libraries. ### Shaders in Files (or Strings) WESL programmers may store shader source code in files or strings, but shader code in files will be much more mainstream. ### Module Hierarchy Starts From File Hierarchy Code in files and libraries are addressable in a 'module hierarchy'. File and directory names names in applications map automatically into the module hierarchy. Future features like `namespace` would also be placed into the module hierarchy. <img src="https://docs.google.com/drawings/d/e/2PACX-1vQ-zjogxndAvpcqu5NXVY-fXgxQHylIvkV7o2PC6YYgrDm_JE7UDhmmdfjGsE7DXxJvbwRQhXGkqbfS/pub?w=1300&amp;h=374"> Programmers storing shader code in strings can specify the module address with the string. ### Identifiers with Separators WESL will support inline identifiers with separators to address the module hierarchy. Programmers will be able to write something like `utils::random()` or `utils.random()`. ### Visibility Control WESL will support marking WGSL elements as private. Private elements will not be visible for import from other modules. ### Notable Future Development Outside the Module System WESL is likely to eventually support some form of `namespace` scoping declaration within files. Namespaces should be addressable from import statements and inline identifiers. WESL is likely to eventually support some form of web served shader code like other web native languages. Import statements will need to be translated to relative or absolute URLs. ## Feature Details Import `zip.wgsl`. - `import super::util::zip;` - `import ./util/zip;` Inline use after importing `zip`. - `zip::bar();` - `zip.bar();` Import `fn bar` from `zip.wgsl`. - `import super::util::zip::bar;` - `import ./util/zip/bar;` Inline use after importing `bar`. - `bar();` - `bar();` Import a library `rand_pkg`. - `import rand_pkg;` - `import rand_pkg;` Inline use after importing `rand_pkg`. - `rand_pkg::pcg();` - `rand_pkg.pcg();` Densely nested imports for concision. - ```wgsl import bevy_pbr::{ forward_io::VertexOutput, pbr_types::{PbrInput, pbr_input_new}, }; ``` - ```wgsl import bevy_pbr/{ forward_io/VertexOutput, pbr_types/{PbrInput, pbr_input_new}, }; ``` Combination approach, with `/` for imports and `::` inline. - ```wgsl import ./util/zip; import rand_pkg as rand; fn main() { let color = rand::pcg(1.0); return zip::zap(color); } ``` ### Possible Future Features in the Module System #### root shortcut for import statements Import from the root of the current package. - `import package::util::zip::bar;` - `import /util/zip/bar;` #### root shortcut for inline separators Inline separator addresses the root of the current package. - `package::util::zip::bar();` - `package.util.zip.bar();` #### namespaces If `zip.wgsl` has a future namespace construct like `namespace dig { fn bar() {} }`, the namespace would map into the same addressable hierarchy. - `import super::util::zip::dig::bar;` - `import ./util/zip/dig/bar;` - If a namespace name matches a file (or directory) name at the same place in the module hierarchy, both can be imported. Names conflicts can happen. #### like named files Allow `util.wgsl` and `util/` both exist in the filesystem. - Allow for both to be imported, similar to above #### inline relative imports Inline references to `super` are also possible. - `super::zip::bar()` - `super.zip.bar()` #### hierarchy remapping (aka re-exporting) Allow grafting subtrees into the module hierarchy from WESL. For example, let's say the file system contains `other/bar/zig.wesl` and `other/bar/zag.wesl`. We've discussed `namespace` variations that place a namespace in the module hierarchy. We might put a statement like this in `util/stuff.wesl`: - `namespace foo = package::other::bar;` - `namespace foo = /other/bar;` Then you could write: - `import /util/stuff/foo/zig` - `import package::util::stuff::foo::zig` #### library view Libraries may want to remap the module hierarchy for library consumers. For example, a library may wish to publish a flat view of public library functions that are developed internally in a file/module hierarchy. We've discussed a variety of approaches to creating library views, some based on hierarchy remapping. #### filesystem vs module system character sets The character set for filesystem identifiers isn't quite the same as the character set for WGSL identifiers we're planning to use in import statements and inline paths. - We could specify a smaller set of characters for use in import specifiers, but the current thinking is to simply use WGSL identifiers, and expect users to avoid using odd characters in their shader files and directories. #### Mapping imports to files Language servers and linkers will refer to the `wesl.toml` file to find the the root directory containing `.wesl` source files. Import statements map to files with minimal searching. - Each segment in an `import` path can either be a file, a directory, a namespace within a file, or wgsl element (for trailing segments). - Proceding left to right through the path segments, consider the segments `prev` and `seg`. 1. if `prev.wesl` exists and includes WESL elements, check if `seg` is one of those elements, e.g.`fn seg` or `namespace seg`. 1. else if the directory `prev/` exists, check to see if the file `seg.wesl` or the directory `seg/` is in the `prev/` directory; 1. error if a `seg` is not found. If `seg` is an element in the module, and an ambiguously named file/directory, emit an extra warning. #### Are const_assert statements included? Generally, WGSL elements are included if they are recursively referenced from the root module (use analysis). But `const_assert` statements are also included if they are in the same module or namespace as a referenced element. - ```wgsl // main.wgsl: import foo/bar; fn main() { bar(); } // foo.wgsl: import ./zig; const_assert(1 > 0); // included in link because bar is used fn bar() { } fn miz() { zig.zag() } // zig.wgsl: const_assert(2 < 0); // not included in link fn zag() { } ``` ## Arguments for :: vs /. - (`::`) Consistency with imports vs. identifier separators. - Having `/` for imports and `.` for identifiers means programmers need to mentally map from one to the other when using imports and inline references with separators. - (`::`) Suporting `.` syntax in identifiers is not ambiguous, but it's a bigger WGSL grammar change because . is used in the syntax already. (I gather it's trivial for lookahead parsers, but requires a bigger grammar change for LR(1) parsers.) - e.g. parse `var x = foo.bar.baz++;` as struct dereferncing vs parse `var x = foo.bar.baz;` as a module path. - e.g. parsing `foo.bar.baz()`. (`ident` branch in the `statement` grammar.) And parse `foo.bar.baz++` as an increment. (`variable_updating_statement` in the `statement` grammar.) Requires bigger grammar change, or arbitrary lookahead. - (`::`) With `::` syntax for inline identifiers, language servers can quickly recognize identifiers that refer to in-scope module/namsepace references vs. e.g. struct member references. - may make hover tooltips and go-to-reference easier to implement. - (`/.`) Consistency with the file system and urls. - Having `::` for imports means that users need to mentally map `super::foo` to `../foo` for local file paths and urls. - (`/.`) The `::` syntax is a bit scary looking to web programmers, which hurts new user adoption slightly. - (`/.`) The `/.` syntax is more concise. - (`/.`) The `.` syntax conflates struct membership with module membership. - Combining two relatable membership concepts into the same syntax is simpler for the user. Less to learn and remember how to distinguish. - Variables may shadow modules with `.` syntax. - Ben Clayton [writes](https://github.com/gpuweb/gpuweb/issues/2426#issuecomment-1032391500) that combining may simplify user understanding of variable shadowing: ```wgsl import pkg/blah; // or import pkg::blah; fn f() { var blah : B; blah.x = 1; // Obvious (to me) that this is dealing with the var blah::x = 1; // Where as I'm not sure whether this would be allowed? } ``` - Mathis had a different interpretation of a similar case of shadowing: ```wgsl // shadowing can impact your code remotely. // we have a foo/bar/x that we could import // access var x from foo/bar.wgsl. foo.bar.x is an identifier. fn main() { foo.bar.x = 10; } // now say I introduce this statement // suddenly the semantics will change var foo = bird(vec3f(0.0)); struct bird { bar: vec3f } // access component x of member bar of struct bird in foo instance fn main() { foo.bar.x = 10; } ``` ## Still to Consider ### Runtime linking unbundled shader modules Mapping import paths to files is a little more difficult for a future runtime linker fetching shader files individually over the network, because the [algorithm](#Mapping-imports-to-files) requires checking for files that may not exist. - Probably we'd expect users to supply a manifest file listing the source files (or an Import Map) to relieve the linker of making unnecessary network requests. ### Separate Syntax for Importing WGSL Elements Both the `::` and `/.` syntaxes address WGSL language elements with the same syntax as files, directories, and namespaces. Some other module syntaxes intentionally provide a separate syntax for language elements for clarity. e.g. Gleam requires brackets `import gleam/option.{Some, None}` to intentionally clarify the difference between langauge elements and paths. JavaScript also has a similar distinction with `import foo from "bar"`. - Should WESL imports should address WGSL elements differently from modules? ### root module to wesl.toml? Should `wesl.toml` need to mention the root module file or files for the sake of the language server?

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully