From bdb0e152903afe4d025cce0127ad456e81355af1 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 8 Feb 2019 15:49:41 +1000 Subject: [PATCH 1/4] Start work on Julep for internal fields --- InternalFields.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 InternalFields.md diff --git a/InternalFields.md b/InternalFields.md new file mode 100644 index 0000000..6fc3997 --- /dev/null +++ b/InternalFields.md @@ -0,0 +1,19 @@ +## The problem + +Julia APIs use a mixture of public and internal fields so it's never syntactically obvious whether a given field access `x.a` violates API boundaries. This makes it hard to detect these problems when reviewing code and hard to write a linter which can tell the difference. That is, a *local* reading of the code can't tell the story; you must read the documentation of whatever package you're using. + +## Goals + +This Julep aims to make the access of internal fields syntactically obvious. Ideally this is just ugly enough to make you think twice but not so bad that it becomes difficult to use the internal structure of types inside internal functions. Some specific goals: + +1. Accessing internal fields should be syntactically obvious. +2. Declaring internal fields in structs should be syntactically obvious and consistent with the notation for access. +3. For use in the originating module it would be nice to have short syntax for `getfield`. +4. Avoid adding syntax and consuming precious ascii characters if possible. +5. Respect existing naming conventions in the ecosystem and aesthetic qualities of the language. + +## Prior discussion + +* See extended discussion of binary `$` as notation for `getfield` over at https://github.com/JuliaLang/julia/issues/25750. +* Binary `@` also appears to be available and was suggested in the discussion of https://github.com/JuliaLang/julia/pull/30646; some of the somewhat off topic musings there led to this julep. +* The meaning of `export` with regard to public symbols has been discussed in many places. From 31731ad1f063435edd53cd94ba9866c9cd285d5b Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 8 Feb 2019 15:50:20 +1000 Subject: [PATCH 2/4] Generalize to internal properties of modules, not just types --- InternalFields.md | 19 ------------------- InternalProperties.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 19 deletions(-) delete mode 100644 InternalFields.md create mode 100644 InternalProperties.md diff --git a/InternalFields.md b/InternalFields.md deleted file mode 100644 index 6fc3997..0000000 --- a/InternalFields.md +++ /dev/null @@ -1,19 +0,0 @@ -## The problem - -Julia APIs use a mixture of public and internal fields so it's never syntactically obvious whether a given field access `x.a` violates API boundaries. This makes it hard to detect these problems when reviewing code and hard to write a linter which can tell the difference. That is, a *local* reading of the code can't tell the story; you must read the documentation of whatever package you're using. - -## Goals - -This Julep aims to make the access of internal fields syntactically obvious. Ideally this is just ugly enough to make you think twice but not so bad that it becomes difficult to use the internal structure of types inside internal functions. Some specific goals: - -1. Accessing internal fields should be syntactically obvious. -2. Declaring internal fields in structs should be syntactically obvious and consistent with the notation for access. -3. For use in the originating module it would be nice to have short syntax for `getfield`. -4. Avoid adding syntax and consuming precious ascii characters if possible. -5. Respect existing naming conventions in the ecosystem and aesthetic qualities of the language. - -## Prior discussion - -* See extended discussion of binary `$` as notation for `getfield` over at https://github.com/JuliaLang/julia/issues/25750. -* Binary `@` also appears to be available and was suggested in the discussion of https://github.com/JuliaLang/julia/pull/30646; some of the somewhat off topic musings there led to this julep. -* The meaning of `export` with regard to public symbols has been discussed in many places. diff --git a/InternalProperties.md b/InternalProperties.md new file mode 100644 index 0000000..2b76e82 --- /dev/null +++ b/InternalProperties.md @@ -0,0 +1,30 @@ +# Julep: Internal Properties + +## The problem + +The julia syntax `x.a` can refer to either a public or internal property `a` of `x`; it is not possible to know from a *local* reading of the syntax. This makes it hard to detect violation of API boundaries in code review and almost impossible with a linter. + +There are two sub cases of this syntactic problem: +* The fields of a type may be public or internal, for example, `.re` and `.im` fields of `Base.Complex`. Access to internal fields may be restricted by overriding `getproperty`, but this solution leaves module implementors stuck with ugly syntax. +* The bindings in a module may be public or internal. Public but non-exported bindings are common in the ecosystem. + +## Goals + +This Julep aims to resolve this problem by making the violation of API boundaries syntactically obvious while respecting Julia's public-by-default aesthetic. Specific goals: + +1. The use of internal properties should be syntactically obvious outside the originating module. +2. The declaration of internal properties should be syntactically clear. +3. `getfield` should be easily accessible with natural syntax in the originating module. +4. Avoid adding syntax and consuming precious ascii characters if possible. +5. Reuse existing naming conventions in the ecosystem +6. Retain the public-by-default aesthetic where the implementation is in easy reach from the right places. + +## Existing conventions and prior discussion + +Many packages in the ecosystem prefix module-internal bindings with an underscore. However, doing this for internal fields of `struct`s is much rarer. Some packages use `getproperty` to add convenient access to computed properties of concrete types. I'm not aware of cases where getproperty is used for access control. + +### Prior discussion + +* See extended discussion of binary `$` as notation for `getfield` over at https://github.com/JuliaLang/julia/issues/25750. +* Binary `@` also appears to be available and was suggested in the discussion of https://github.com/JuliaLang/julia/pull/30646; some of the somewhat off topic musings there led to this julep. +* The meaning of `export` with regard to public symbols has been discussed in many places. From 3b082ad57a674321776e061c29320ff32790cf2f Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 8 Feb 2019 18:13:40 +1000 Subject: [PATCH 3/4] Add additional references to prior discussions --- InternalProperties.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/InternalProperties.md b/InternalProperties.md index 2b76e82..7401a10 100644 --- a/InternalProperties.md +++ b/InternalProperties.md @@ -25,6 +25,9 @@ Many packages in the ecosystem prefix module-internal bindings with an underscor ### Prior discussion +* [JuliaLang/julia#12064](https://github.com/JuliaLang/julia/issues/12064) "Document privacy of type-fields" +* [JuliaLang/julia#12069](https://github.com/JuliaLang/julia/issues/12069) "Only make exported bindings available with `import`" +* [JuliaLang/julia#30204](https://github.com/JuliaLang/julia/issues/30204) "Add export-like keyword for private names in a module" * See extended discussion of binary `$` as notation for `getfield` over at https://github.com/JuliaLang/julia/issues/25750. * Binary `@` also appears to be available and was suggested in the discussion of https://github.com/JuliaLang/julia/pull/30646; some of the somewhat off topic musings there led to this julep. * The meaning of `export` with regard to public symbols has been discussed in many places. From 5e80fe075c4d81a7f1d568954562c719a466cd3d Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Tue, 2 Jul 2019 11:17:36 +1000 Subject: [PATCH 4/4] Mention julia issue 22147 --- InternalProperties.md | 1 + 1 file changed, 1 insertion(+) diff --git a/InternalProperties.md b/InternalProperties.md index 7401a10..73a81a1 100644 --- a/InternalProperties.md +++ b/InternalProperties.md @@ -28,6 +28,7 @@ Many packages in the ecosystem prefix module-internal bindings with an underscor * [JuliaLang/julia#12064](https://github.com/JuliaLang/julia/issues/12064) "Document privacy of type-fields" * [JuliaLang/julia#12069](https://github.com/JuliaLang/julia/issues/12069) "Only make exported bindings available with `import`" * [JuliaLang/julia#30204](https://github.com/JuliaLang/julia/issues/30204) "Add export-like keyword for private names in a module" +* [JuliaLang/julia#22147](https://github.com/JuliaLang/julia/pull/22147) "Make it easier to mark a new module as top" — a change to lowering which allows lowered forms like `Expr(:top, :getproperty)` to resolve to names in the current module. See also [JuliaLang/julia#25750 (comment)](https://github.com/JuliaLang/julia/issues/25750#issuecomment-360840183). * See extended discussion of binary `$` as notation for `getfield` over at https://github.com/JuliaLang/julia/issues/25750. * Binary `@` also appears to be available and was suggested in the discussion of https://github.com/JuliaLang/julia/pull/30646; some of the somewhat off topic musings there led to this julep. * The meaning of `export` with regard to public symbols has been discussed in many places.