wgsl-tooling-wg / wesl-spec

A portable and modular superset of WGSL
BSD 3-Clause "New" or "Revised" License
29 stars 3 forks source link

Public by default within the package #28

Open mighdoll opened 1 month ago

mighdoll commented 1 month ago

I'd suggest we change the default visibility for elements within the package to be public, and introduce a new keyword 'private' to optionally annotate top level elements. Private elements are visible within the module but not importable by other modules. Private elements cannot be exported outside of the package.

Advantages:

(Some counterarguments are listed in Visibility.md.)

(No change to package visibility - elements are not importable from other packages unless they are explicitly mentioned in export or annotated with @export)

ncthbrt commented 1 month ago

While I agree with public by default, I think interfaces/signatures would be neater replacement than a private keyword.

mighdoll commented 1 month ago

While I agree with public by default, I think interfaces/signatures would be neater replacement than a private keyword.

Perhaps a code sample to explain?

ncthbrt commented 1 month ago

I have an example in my PR: https://github.com/ncthbrt/wesl-spec/blob/load-proposal/ModulesInterfaces.md

ncthbrt commented 1 month ago

Copied from the pr:

// A module signature:

mod sig MathImpl {
    const DEG_TO_RAD: f32;
    type Quat; // An opaque type. It's exact representation is hidden from users
    fn quat_from_euler(xyzRad: vec3<T>) -> Quat;
}

// Another module signature
mod sig Pi {
    const PI: f32;
}

// A third module signature
mod sig MainMath {
    // Here Float conforms to both MathImpl and Pi
    mod Float : MathImpl + Pi;
}

mod sig F32 {
    type T: f32;
}

alias MainMathSig = MainMath;

// This can be type checked to determine 
// whether Math (and consequently Float conform to the provided signature)
mod Math -> MainMathSig {
    mod FloatMath {
        alias T = f32;
        const DEG_TO_RAD: f32 = 0.0174533;
        const PI: f32 = 3.142;
        alias Quat = vec4<f32>;

        fn quat_from_euler(xyzRad: vec3<f32>) -> Quat {
            // Implementation here
        }

        fn private_function() -> f32 {
            // Implementation here
        }
    }
    // An alias for a module that is exposed with the following signatures:
    alias Float : MathImpl + Pi + F32 = FloatMath;
}

// Usage
Math::Float::quat_from_euler(vec4<f32>(90.0 * Math::Float::DEG_TO_RAD))

// Not allowed as the FloatMath module isn't in the interface
// Math::FloatMath::quat_from_euler(vec4<f32>(90.0 * Math::Float::DEG_TO_RAD))

// Not allowed as private_function isn't in the interface
// Math::Float::private_function()
ncthbrt commented 1 month ago

We could probably also invent some syntax to do the same thing for an entire file (or do what ocaml does with optional interface files that sit next to the implementation)

mighdoll commented 1 month ago

I'd suggest we:

  1. change the spec to say public by default
  2. open a new issue for module visibility control (private, or module interfaces, etc.)
  3. open a new issue for package visibility/renaming controls (@public, export, or)
  4. then close this issue
ncthbrt commented 1 month ago

Happy with that

On Wed, 09 Oct 2024 at 21:19, mighdoll @.***> wrote:

I'd suggest we:

  1. change the spec to say public by default
  2. open a new issue for module visibility control (private, or module interfaces, etc.)
  3. open a new issue for package visibility/renaming controls @.***, export, or)
  4. then close this issue

— Reply to this email directly, view it on GitHub https://github.com/wgsl-tooling-wg/wesl-spec/issues/28#issuecomment-2403257580, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACCJEWMCXXQGEN5TPD6CZRDZ2V6TNAVCNFSM6AAAAABOIPBD4SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBTGI2TONJYGA . You are receiving this because you commented.Message ID: @.***>