Io/DocumentationSystem

edit
revisions

what's new
search
help

kiwi


A draft for a Io documentation system

Introduction

The Io programming language does not come by default with a documentation system. Adocumentation system (or a package systems) aims at allowing developers to documenttheir code while they are writing it, and users/developers to consult the documentationunder various formats (on-line, printed or using the Io interpreter). A documentationsystem can also be used to enrich the code with annotations (meta-information) such asstatus (deprecation), version, authors, visibility (private, public, etc).

Having a documentation system allows the language to be more accessible to newbies,provides a convenient way for the developer to get information about available objects,and generally renders Io more visible and understandable.

Related pages:


Requirements

Here is a short unordered list of requirements for a documentation system adpated to theIo language:

  • Allows to document every object
  • Allow to express various meta-information on the documentation (author, version) aswell as rich content (parameters, references, deprecation, etc) -- this implies akind of tag system.
  • Documentation should be easily accessible by programs
  • Distinguish objects by their role (module, prototype, attribute, method, etc)
  • Allow to free/compress all documentation for low-memory VMs?
  • Indicate what is not documented in an object
  • Generate HTML, PS and PDF documents from documentation
  • Interactively query documentation from the interpreter (like pydoc)
  • Integrate well with possible module systems

Proposition

1. Documentation entities

The Io language allows to express the following basic entities:

  • Prototypes: they are the equivalent of class, in Io prototype-based inheritance.
  • Methods, blocks: are objects that represent an sequence of expressions, with a

specific scope and arguments.

  • Properties: properties are the equivalent of attributes, they correspond to slots that were not assigned a method or block.
  • Arguments: arguments are named, ordered values that are given to a block or method when it is executed.

We could also extend the documentation entities with possible extensions to the Io language, most notably a module system:

  • Package: a package is a collection of packages and/or modules -- package help to structure modules
  • Module: a module is a collection of prototypes -- package help to group prototypes

2. Documentation properties

All those document entities share some common properties:

  • Author(s) (name, email, url)*
  • Version (Minor, Major )
  • State = {"release", "experimental", "deprecated", "broken"}
  • Visibility = {"public", "private"}
  • ToDo?? (TEXT*)
  • FixMe?? (TEXT*)

Those properties are rather general, so specific documentation entities require more properties.

The Prototype documentation entity could have:

The Block/Method documentation entity could have:

The last group property allows to group blocks and method together within an obejct. Objects usually have various methods, some which share a common activity (utility methods, accessors, specific operation methods, etc).


3. The documentation API

The Documentation prototype:

  • Expresses information related to the documentation of an object including, but not restricted to, its classification ( Prototype, Attribute, Method, Etc. ), and its description. More specialized descendants of Documentation can also express helpful information about method arguments, etc.

The Object `document' operation:

  • Creates an descendant of Documentation that describes an object.

The Object `documentation' operation:

  • Returns the Documentation, if any, associated with a given object.

Documenting an Object:

  
  MyObject = Object clone setDoc(Prototype, "MyObject is ....")

  #It is nice to have the documentation before the code
  MyObject setDoc(Attribute, "anAttribute", "anAttribute is ...")
  MyObject anAttribute = 1

  #NOTE: it would not be possible to do
  MyObject anAttribute = 1 setDoc(Attribute, "anAttribute", "...")
  #Because this would document 1, and not the "anAttribute" slot of MyObject?
  #if we do
  MyObject anAttribute = 2
  #we would lose the documentation
  
Critics: the code is rather long compared to comment-based documentation, it makes writing documentation a rather tiring task. However, comments is code, which really facilitates the processing of documentation. --> Possible solution: Improve setDoc so that it is way shorter:
  MyObject setDoc("anAttribute", "@attr anAttribute is)

this would simply mean putting the information within the documentation string, but this would imply that the documentation string should be parsed...


Comments

??? How will automatic document generators recognize objects produced by a given module? Implementation of this may be reliant on also coming up with a standard for well behaved modules. --sdunlop

It's clear that a module system is also another thing to develop for Io (see

ModuleSystem), but I think the documentation system should be at first abstract from any module system. For instance, we could simply begin by knowing how to document an Object, and how to access this documentation. Then, we can think on documenting modules and such. -- sebastien

??? Well behaved modules will need to ensure that they simply create their prototype objects, describe themselves, then wait for the importing routine to invoke their 'init' method, or suchlike, to allow programs like the automatic document generator to load them without incurring unwanted side effects, i.e. initializing a GUI library, initializing a network listener, etc. --sdunlop

The creation of prototypes is equivalent to the decleration of class, prototypes should not initiate an activity, otherwise (as you say) some unwanted side effects could occur -- this should be left to the module initialisation method. To me, the creation of documentation should be made in the creation of the prototype. --sebastien

??? If we use a form like:

  
  myObject myMethod = method( myFirstArg, mySecondArg, ... )
  myObject setDoc( "myMethod", "Method", "My method performs..." )
  

We run into some interesting questions about how documentation should be accessed. What if another object overrides myMethod with its own implementation? What if myMethod is copied, using getSlot and setSlot, for whatever reason? I believe it would be preferable to make sure that the documentation for an object be set in a special slot on the object. i.e.

  myObject myMethod = method( myFirstArg, mySecondArg, ... ) setDoc ( "Method",  "This method performs..." )

This would keep the documentation closely coupled with the value, instead of the container. This also simplifies setDoc, somewhat, since we can eliminate the use of Prototype, Method, etc, by overloading the setDoc method on Method, Module. This system breaks down when we start documenting property/attributes of a module, however. By convention in Python, only the methods of a class are documented, as it is considered bad form to directly access an object's attributes. If an object is designed to allow tampering with its attributes, the docstring for the class will explain what properties can be modified. Perhaps an instance of Documentation specialized for Prototypes could have the ability to document accessible non-method slots.

  
  MyPrototype = Object clone
  MyPrototype documentPrototype ( """
  This prototype ...
  ...
  """) documentProperty ("myProperty", """
  This property may be accessed for ...
  """) documentProperty ("otherProperty", """
  This other property my optionally be set to ...
  """)


  MyPrototype init = method( ... ) document ("Initializes MyPrototype.")
  MyPrototype doNothing = method( myArg, self ) document( "myArg",
  "Does   absolutely nothing with myArg, then returns self." )
  

"MyPrototype? documentation asString" would therefore yield:

  
  SYNOPSIS:
    This prototype ...

  PROPERTIES:
    myProperty -- This property may be accessed for ...
    otherProperty -- This other property may be accessed for ...

  METHODS:
   init() -- Initializes my prototype.
   doNothing(myArg) -- Does absolutely nothing with myArg, then returns self.
  

--sdunlop

I think that Scott presented the problem very well : for methods, documentation should be thightly bound to the IoBlock?? objects, while attributes require to document the slot rather than the assigned value. I (once again ;) toatally agree with Scott proposition, including the use of `document' rather than `setDoc'. The only problem I see with this new naming is how the Documentation object is accessed (that is which slot will give access to the documentation... I propose "documentation").

If it seems interesting to document properties (attributes), then we have another alternative to what Scott proposed : if a slot is reified into an object (called, hum... Slot), then we can document the slot rather than the documentation itself. This solution however seems not that appealing, as it would probably imply some important changes in Io VM.

Also, there is something that I find disturbing in assigning the documentation to the value (a method) : it leads to writing the code first, and then document it... (which may be a good thing, after all) and it also breaks the convention of having the documentation first.

Anyway, I think Scott's proposal is a rather good start.

--sebastien

If we were to use document<Element> to create documentation, and documentation to

retrieve it, I would suggest that we rename Documentation, the prototype, to something else. I dislike differentiating between slots simply on basis of casing. What would be a suitable name for the Documentation proto? --sdunlop

I don't really understand what you mean by differentiating between slots ? If the `document' method allows to create a `Documentation' clone and `documentation' returns it, I do not see any problem. It's rather coherent that the `documentation' slot returns a `Documentation' instance, isn't it ? --sebastien

??? C Functions for Primitives, and primitives themselves should be also be documentable. How could we do this without adding more complexity to the VM? --sdunlop

Maybe I got it wrong, but it seems like the new VM does not have primitives anymore, and only uses Objects, so we basically only have to extend the Object proto. --sebastien
The new VM stil has cfun's for implementing primitive methods, and primitive objects are still built and specified inside the Io VM, although it is possible to add new To methods to an existing primitive. If, when a new cfunc is bound to the tag, we also specified a constant string for documentation, an automatic document generator could also document the cfunc's. This would require a change to the VM, so I am not entirely sure how pleased I am with the idea. --sdunlop
CFunctions? are objets, so I think it would be possible to simply add a documentation to them separately. For instance, we could think of a Io module that would simply add the documentation to the primitive prototypes. Maybe I misunderstood something, as you would surely have already thought of something similar... --sebastien

Instead of making a complex builtin documentation system, why not just make it a convention to use the doc slot of everything to store documentation in? Then we can use something similar to reST to generate documentation from Io source code. Example:

  
  adder := Object clone
  adder doc := "sum finds the result of adding a and b together."
  adder a := 1
  adder a doc := "first thing to be added"
  adder b := 2
  adder b doc := "second thing to be added"
  adder sum := method(return a+b)
  adder getSlot("sum") doc := "main function of adder"
  .....
last modified on September 27, 2005, at 03:35 PM

© type-z.org and its contributing authors, 2001-2004.
Content is licensed under a Creative Commons License.