On 2010-06-07, at 1:42 PM, chevalma@iro.umontreal.ca wrote:
I just checked and JSDoc does exactly this. I.e. if the comment does not start with a tag, a "description" tag is assumed.
Well, that makes it less verbose then. All the tags are entirely optional, in fact. I would still like for at least a minimal (one liner) description to be provided for every function, and for arguments and return values to be documented wherever they are not obvious.
Can we agree on this, and on the use of JsDoc?
Fine with me as long as we don't over do it with tags (i.e. KISS).
Also, Erick and I were also thinking that it might be good to subdivide our code into modules, instead of dumping everything into the global scope. We could do this by creating global objects and having functions as properties. These can then be documented using the @namespace tag inside JsDoc.
For example, I can modify memory.js as such:
/** @namespace */ memory = {
/** Adds a signed offset to a pointer value */ ptrAdd : function(ptr, offset) { }
/** Computes the difference between two pointers */ ptrSub : function(ptr1, ptr2) { } }
The functions can then be called by doing memory.ptrAdd, etc., and show up under the memory module in JsDoc. Note that this imposes a "one file per module definition" limitation, but I still think it's a fairly nice paradigm, as it allows our code to be better organized, and it implicitly allows us to check, say, that function foo is part of module bar, which could have special properties associated to it.
I also don't think it's a significant constraint on a naive optimizer. We can simply assume that functions inside global objects of the tachyon code never get redefined, and voilà (note that optionally, we could even explicitly make them read only properties if it's any kind of issue).
What do you think about that idea?
I am worried about 3 things:
1) Execution speed. I don't think it is easy for a naive, or not so naive, compiler to make direct calls to the functions. Say you have a module foo which calls memory.ptrAdd(x,y). How will you tell the compiler in foo that "memory" is a namespace object? In other words what form will the annotation take in foo? A whole program compilation would eliminate the need for an annotation, but it may be unusable for a large program like the tachyon compiler itself.
2) It obfuscates the code. I think it is much clearer (and in fact somewhat shorter and with less indenting) to use identifier prefixing and write:
function memory_ptrAdd(ptr, offset) { }
function memory_ptrSub(ptr1, ptr2) { }
memory_ptrAdd(x, y);
rather than
memory = {
ptrAdd: function (ptr, offset) { },
ptrSub: function (ptr1, ptr2) { }
};
memory.ptrAdd(x, y);
Note that at a call it is a question of replacing a "." by a "_" (we could also use "$" if that is more mnemonic... but I find $ too distracting).
The use of object literals as namespace objects is also error prone (for example in your example you forgot to put the comma after the definition of ptrAdd).
3) You can only use functions from that namespace once the whole namespace object is constructed. This will make the construction of constant tables awkward (when the elements of the table are objects whose constructor is defined in the namespace). This happens for example in scanner.js, and I expect it to occur in many other places in the compiler.
KISS... so I propose we use identifier prefixing at first. If it becomes a problem we can refactor the code (changing client code is trivial... a sed script to map "memory_" to "memory.").
Marc