dx-spec icon indicating copy to clipboard operation
dx-spec copied to clipboard

Simplified namepaths: dropping 'inner', using JS syntax for instance members

Open tmcw opened this issue 8 years ago • 1 comments

Namepaths are a JSDoc'ism - a feature that documentarians use to refer to different parts of their exported API.

Their examples:

myFunction
MyConstructor
MyConstructor#instanceMember
MyConstructor.staticMember
MyConstructor~innerMember // note that JSDoc 2 uses a dash

You'll notice that the syntax for instanceMember and innerMember aren't valid JavaScript, and 'inner' is not a JavaScript concept.

I'd like to not support inner.

Inner is used for things that are not exported. Imho, this project should focus entirely on documenting the exported interface of a project, and should have no special syntax for 'private' or 'inner' members.

Instead of #, I'd like to just use .prototype.

@ELLIOTTCABLE suggested to stop using # because it is not JavaScript, and I agree: I think we should only support .prototype as a means of documenting and linking to instance members. The disadvantage is that it's more verbose, but the advantage is that it "does what it says on the tin": instance members are members of a prototype.

tmcw avatar Oct 15 '17 21:10 tmcw

Just a 2¢: my views have evolved since the original thread, and I no longer believe “inner” members are useless-enough that support for them is entirely unnecessary.

From a project-focus standpoint, they're by far the lease important of the above, and thus it totally makes sense to triage them first — but that said, triage aside, they do need some sort of support. Documentation can be complex — especially when it's internal documentation (which should be equally supported by any “language” for expressing documentation, even if a public-documentation-generating-tool doesn't necessarily need to support, understand, or use that part of the language!¹) Towards that, some random thoughts:

The real problem here, is that ‘inner’ is extremely generic, and can be used to refer to several subtly different things (as far as I can tell):

  1. Simply a way to refer to (as opposed to type-generically depend-on, in a structural description) an otherwise-private value in another context, during a human explanation of an algorithm or interface:

    class Something {
       process(list){
          const filtered = list.foo.widget.filter(a => a.b).fwidgjle
    
          return filtered.forEach(e => doStuff(e))
       }
    }
    
    
    /**
     * For each element, while {@link Something.prototype.process~filtered} contains ...
     */
    function widget(list){ ... }
    

    (I've ~Opinions™~ on the {@link …} syntax, in particular about there being nothing I would more love to watch rot in hell, but that's a conversation for another thread … but the relevancy here is, assuming a shorter and more natural syntax could be agreed upon — my horse being to simply link any resolvable namepath in Markdown `backticks` — it suddenly becomes extremely useful to litter your documentation with semantic hyperlinks between blocks of documentation, even if they're private!)

  2. Values ‘lent’ out to a public context, by a public interface, that are otherwise private (can't be arsed to type out an example of this, but you get what I mean),

  3. … and private-looking values that compose a part of a structural type that we wish to build upon in another type signature

    /** @constructor */
    function Something(){
       /**
        * Doificate the thingamabob.
        */
       this.doificate = function(){
          // ...
          return function(theTypeParam){ ... }
       }
    
       /**
        * This can be parameterized by whatever value the *other* interface
        * *asynchronously returns*; that is,
        * {@link Something.doificate~theTypeParam}:
        *
        *     const s = new Something
        *     s.doificate(function(t){
        *        s.widgetify(t)
        *     })
        *
        * @arg {Something.doificate~theTypeParam} A type-parameter in the current doification context ...
        */
       this.wigetify = function(theGivenTypeParam){
          // ...
       }
    }
    

Now, each of these cases (as well as others I'm probably missing) has different relevance to a documentation-generating tool, and a developer when they're writing arbitrary code that they wish to locally document in the JSdoc (or should I say “dx”?) syntax. It's up to you how much you wish to support the latter case, but I'd like to throw in my (wow, getting-very-long-winded) 2¢: I think the spec should include room for such situations, even if a given implementation opts not to implement it!


  1. I don't want to be writing two different “languages” for internal and external documentation, y'know? The language should be like Markdown: universal, simple, easy to remember (hence .prototype., etc — we want it to work Just Like JavaScript not because that's a value in-and-of-itself, but because that means nobody needs to refer to any damn documentation to write their documentation, lmao); but it should also support anything you need to do, so that you don't have to make up arbitrary syntax on-the-fly … and then remember, communicate, and maintain that syntax throughout your codebase.

ELLIOTTCABLE avatar Oct 18 '17 16:10 ELLIOTTCABLE