I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick
Afficher les réponses par date
I can't be there on Wednesday. Can we reschedule for 10AM on Thursday 27th?
Marc
On 2010-05-24, at 4:27 PM, Erick Lavoie wrote:
I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Fine for me
Erick
Le 10-05-24 16:33 , Marc Feeley a écrit :
I can't be there on Wednesday. Can we reschedule for 10AM on Thursday 27th?
Marc
On 2010-05-24, at 4:27 PM, Erick Lavoie wrote:
I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
This conflicts with my availability time for the IFT1025 course... I could do 12:00, or after the group meeting on Thursday... Unless you guys don't mind meeting in the lab, with the (relatively unlikely) possibility that a student might come asking me for help.
- Maxime
Marc Feeley wrote:
I can't be there on Wednesday. Can we reschedule for 10AM on Thursday 27th?
Marc
On 2010-05-24, at 4:27 PM, Erick Lavoie wrote:
I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
On 2010-05-24, at 23:20 , Maxime Chevalier-Boisvert wrote:
This conflicts with my availability time for the IFT1025 course... I could do 12:00, or after the group meeting on Thursday... Unless you guys don't mind meeting in the lab, with the (relatively unlikely) possibility that a student might come asking me for help.
Actually, I have a conflict too. I have research meetings from 10:00-12:00 on thursdays, as well as from 15:00-16:00. Some of these meetings can end early but I can't be sure. 12:00 on thursday works for me.
Bruno
- Maxime
Marc Feeley wrote:
I can't be there on Wednesday. Can we reschedule for 10AM on Thursday 27th?
Marc
On 2010-05-24, at 4:27 PM, Erick Lavoie wrote:
I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Then can we all meet at noon on thursday?
Marc
On 2010-05-24, at 11:43 PM, Bruno Dufour wrote:
On 2010-05-24, at 23:20 , Maxime Chevalier-Boisvert wrote:
This conflicts with my availability time for the IFT1025 course... I could do 12:00, or after the group meeting on Thursday... Unless you guys don't mind meeting in the lab, with the (relatively unlikely) possibility that a student might come asking me for help.
Actually, I have a conflict too. I have research meetings from 10:00-12:00 on thursdays, as well as from 15:00-16:00. Some of these meetings can end early but I can't be sure. 12:00 on thursday works for me.
Bruno
- Maxime
Marc Feeley wrote:
I can't be there on Wednesday. Can we reschedule for 10AM on Thursday 27th?
Marc
On 2010-05-24, at 4:27 PM, Erick Lavoie wrote:
I just want to confirm our meeting next Wednesday at 10am. Is it all right for everybody?
Erick _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Works for me too.
- Maxime
Bruno Dufour wrote:
On 2010-05-25, at 16:51 , Marc Feeley wrote:
Then can we all meet at noon on thursday?
Works for me.
Bruno _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
me too.
Erick
Le 10-05-26 9:36 , Maxime Chevalier-Boisvert a écrit :
Works for me too.
- Maxime
Bruno Dufour wrote:
On 2010-05-25, at 16:51 , Marc Feeley wrote:
Then can we all meet at noon on thursday?
Works for me.
Bruno _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Someone apparently wrote a Flash emulator in JavaScript, with its own bytecode interpreter and all. It's probably the kind of benchmark we ought to be looking at testing, performance-wise, because it will easily become very slow for demanding flash apps.
http://apple.slashdot.org/story/10/06/01/1748200/Smokescreen-a-JavaScript-Ba...
http://smokescreen.us/demos/sb45demo.html
- Maxime
Really neat! I agree, this is a kind of JS application that will increasingly become common on the web.
Marc
On 2010-06-01, at 7:10 PM, Maxime Chevalier-Boisvert wrote:
Someone apparently wrote a Flash emulator in JavaScript, with its own bytecode interpreter and all. It's probably the kind of benchmark we ought to be looking at testing, performance-wise, because it will easily become very slow for demanding flash apps.
http://apple.slashdot.org/story/10/06/01/1748200/Smokescreen-a-JavaScript-Ba...
http://smokescreen.us/demos/sb45demo.html
- Maxime
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Hello Marc & Bruno,
Erick and I were discussing the representation of boxed values (inside objects and on stack frames), with tag bits, etc.
We were wondering whether you thought we should use 32 or 64 bit pointers/values. I was thinking that 64 bit pointers would be desirable, as they are more future proof (think JS in a server environment), and perhaps better for 64 bit hardware. However, if we assume that all boxed values are 64 bits, this could possibly have performance penalties, since objects and stack frames would be bigger, and so there could be more memory traffic.
What's your opinion on this matter?
- Maxime
Just to say that we moved the "parser" directory code in the tachyon repository to the "source/parser" directory, in anticipation that we will eventually have other things besides source code in there. Erick and I are also considering moving all test code to a "tests" directory.
- Maxime
OK. I've now pushed my latest changes to the parser to the repo.
Check out the files "js2scm*" (the JavaScript to Scheme compiler) to see how the AST can be traversed.
Marc
On 2010-06-06, at 4:37 PM, chevalma@iro.umontreal.ca wrote:
Just to say that we moved the "parser" directory code in the tachyon repository to the "source/parser" directory, in anticipation that we will eventually have other things besides source code in there. Erick and I are also considering moving all test code to a "tests" directory.
- Maxime
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Why not make it work on both 32 and 64 bit machines. Desktops are moving to 64 bit processors, but there are plenty of smaller machines (iPad, Android, etc) which are 32 bits.
What can be gained by restricting words to be 64 bits? Can't we simply have that as a parameter? The intel code generator I've written support 32 and 64 bit architectures.
Marc
On 2010-06-04, at 11:33 PM, chevalma@iro.umontreal.ca wrote:
Hello Marc & Bruno,
Erick and I were discussing the representation of boxed values (inside objects and on stack frames), with tag bits, etc.
We were wondering whether you thought we should use 32 or 64 bit pointers/values. I was thinking that 64 bit pointers would be desirable, as they are more future proof (think JS in a server environment), and perhaps better for 64 bit hardware. However, if we assume that all boxed values are 64 bits, this could possibly have performance penalties, since objects and stack frames would be bigger, and so there could be more memory traffic.
What's your opinion on this matter?
- Maxime
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Erick and I would like to use the JsDoc tool to generate code documentation based on annotations inside comments. This would require that our file headers and functions/constructors be annotated according to the JsDoc annotation tags.
See the wiki at: http://code.google.com/p/jsdoc-toolkit/
I've annotated some sample files in the repository (see lowlevel/memory.js and ir/instructions.js), and updated the coding guidelines on Google Docs to explain how to do this.
Marc, do you have an opinion on this? It would imply adding annotations to your parser code.
What can be gained by restricting words to be 64 bits? Can't we simply have that as a parameter? The intel code generator I've written support 32 and 64 bit architectures.
That's the conclusion Erick and I came to as well. Perhaps we should simply have a configuration file that sets these sort of platform-specific behaviors... And if 32 bit pointers/values are faster even on 64 bit machines, we can set that by default, while still allowing 64 bit pointers/values.
- Maxime
On 2010-06-06, at 10:10 PM, chevalma@iro.umontreal.ca wrote:
Erick and I would like to use the JsDoc tool to generate code documentation based on annotations inside comments. This would require that our file headers and functions/constructors be annotated according to the JsDoc annotation tags.
See the wiki at: http://code.google.com/p/jsdoc-toolkit/
I've annotated some sample files in the repository (see lowlevel/memory.js and ir/instructions.js), and updated the coding guidelines on Google Docs to explain how to do this.
I've looked at your samples, and it seems verbose. I have a hard time reading the comments because of all the markup around them. Is there a shortcut for "description" tags, since they are really frequent? It would be nice if by default (no tag) a /** comment was a description. Is it necessary to repeat the "author" information for each class? If we really need to know who wrote what, we have the git history.
Marc, do you have an opinion on this? It would imply adding annotations to your parser code.
Yes I will update my source files when we agree on a particular documentation style.
What can be gained by restricting words to be 64 bits? Can't we simply have that as a parameter? The intel code generator I've written support 32 and 64 bit architectures.
That's the conclusion Erick and I came to as well. Perhaps we should simply have a configuration file that sets these sort of platform-specific behaviors... And if 32 bit pointers/values are faster even on 64 bit machines, we can set that by default, while still allowing 64 bit pointers/values.
Yes, I should have mentioned also that with 64 bit references (a better term than pointers/values) a heap can be up to twice the size of a heap with 32 bit references for the same objects. That means that if a computer has less than 8 GB of RAM it is better to use 32 bit references (i.e. with 32 bit refs you can have as many objects in 4 GB of the RAM as with 64 bit refs with 8 GB of RAM). I've encountered this problem with Gambit on one of my machines which has 6 GB of RAM. Even on a machine with slightly more than 8 GB of RAM it is likely that the 32 bit refs will be desirable because it leaves more free RAM for the OS and other applications. Let's not neglect the fact that currently it is very rare to see applications which need more than 4 GB of RAM (regardless of the language they are written in). 32 bit architectures are not dead yet!
Note that with 32 bit refs we may have to align objects on multiples of 64 bits (i.e. 8 bytes) because boxed floating point numbers will be accessed faster (on some processors it is even required that 64 bit values are aligned on multiples of 8 bytes). This means that the address of objects has the low 3 bits equal to 0. We can thus stuff 8 different type tags in the lower 3 bits.
One neat trick we could use with 64 bit references is to use (some of) the NaN encodings to represent object references. Then there is no difference between a boxed and an unboxed floating point value. Accessing objects may however be slower (it remains to be seen how clever we can be with the encoding... perhaps the low 32 bits of a NaN can be used as an address).
I hope we will be able to abstract and modularize the object representation of the system so that it is easy to switch from one representation to another without major changes to the system. That way we can explore different representations easily.
Marc
On 2010-06-07, at 9:29 AM, Marc Feeley wrote:
Is there a shortcut for "description" tags, since they are really frequent? It would be nice if by default (no tag) a /** comment was a description.
I just checked and JSDoc does exactly this. I.e. if the comment does not start with a tag, a "description" tag is assumed.
Marc
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?
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?
- Maxime
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
Fine with me as long as we don't over do it with tags (i.e. KISS).
We start with just a minimal description, we document parameters and return values which are non-obvious, and we can always add more information about a given function's purpose later on. I doubt overdocumentation will be an issue.
- 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?
As I said, we can make memory a read-only global object property, and we can make any of its properties read-only as well, in the worst case, to completely enforce non-redefinability, so performance is a non-issue.
- It obfuscates the code. I think it is much clearer (and in fact
somewhat shorter and with less indenting) to use identifier prefixing
That's because you're very used to this naming *scheme*.
- 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.
That's a good point. However, we could also use a different syntax where we define the module first as the empty object, and add functions later. This would address that issue, you then simply have to make sure that functions were defined before calling them. And as I've just said, these could be made read-only.
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.").
It's mostly a problem with JsDoc. It doesn't separate functions by file, or sort them by name, as far as I've noticed... Because JavaScript programmers don't tend to just write all functions in the top level.
So I propose this notation instead:
/** @namespace */ memory = {}
/** Adds a signed offset to a pointer value @param ptr pointer to raw memory @param val signed offset */ memory.ptrAdd = function(ptr, offset) { }
/** Computes the difference between two pointers */ memory.ptrSub = function(ptr1, ptr2) { }
Because: - JsDoc can document this effectively - It's easy to understand - Solves the ordering issue you mentioned - It's also a clearer, more sensible style - It's more in line with the way people actually use JavaScript
So I propose we *KISS* and not worry about premature optimization. We should hope that our compiler will be able to properly optimize such a simple case, and if not, we can fall back to making the modules and their function properties read-only.
- Maxime
On 2010-06-07, at 9:30 PM, chevalma@iro.umontreal.ca wrote:
- 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.
That's a good point. However, we could also use a different syntax where we define the module first as the empty object, and add functions later. This would address that issue, you then simply have to make sure that functions were defined before calling them. And as I've just said, these could be made read-only.
Did you try to do this (i.e. make properties read-only)? You hinted at a way (which does not work as is) and the spec is not clear and I can't get it to work (because [[Writable]] is an internal property).
You did not answer this important question: how will a *client* module know that mem is a namespace with read-only fields (thus enabling the compiler to perform direct jumps)?
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.").
It's mostly a problem with JsDoc. It doesn't separate functions by file, or sort them by name, as far as I've noticed... Because JavaScript programmers don't tend to just write all functions in the top level.
If it sorts by name then all the mem_xxx functions will be together. What's the problem?
So I propose this notation instead:
/** @namespace */ memory = {}
/** Adds a signed offset to a pointer value @param ptr pointer to raw memory @param val signed offset */ memory.ptrAdd = function(ptr, offset) { }
/** Computes the difference between two pointers */ memory.ptrSub = function(ptr1, ptr2) { }
Because:
- JsDoc can document this effectively
Same for mem_xxx.
- It's easy to understand
Same for mem_xxx.
- Solves the ordering issue you mentioned
It is not an issue with mem_xxx. But with mem.xxx you will be calling methods in the mem object before the fields are made read-only. How will tachyon deal with such a case (a namespace being used in the middle of its initialization)? This will cause problems with the static analysis. In other words, how will the compiler know which fields of the namespace object have been defined when the code reaches the call mem.xxx ? Also, where will the field "xxx" be in the mem object, after all we are incrementally adding fields to a hash-table, so the hash-table may have to be resized, which will move the fields around during the initialization. Not a good thing!
- It's also a clearer, more sensible style
"more sensible"!!!! come on!!!!!
- It's more in line with the way people actually use JavaScript
That's true, but lets put things into perspective... We are talking about a single character in the "function name", either a "_" or a ".". This is not exactly a big change in style! On the other hand we can expect a factor of 2 speed difference between "_" and ".". That's significant.
The mem_xxx style is clearly more KISS than the mem.xxx style.
Marc
Did you try to do this (i.e. make properties read-only)? You hinted at a way (which does not work as is) and the spec is not clear and I can't get it to work (because [[Writable]] is an internal property).
I believe the appropriate method is:
15.2.3.6 Object.defineProperty ( O, P, Attributes )
This isn't supported by V8 (not ECMAScript 5), but will be supported by our compiler, thus, when we can bootstrap ourselves, we can take advantage of it.
You did not answer this important question: how will a *client* module know that mem is a namespace with read-only fields (thus enabling the compiler to perform direct jumps)?
There are many ways to achieve this. One is a naive analysis. Only one write to mem.foo + no evals + we trust our own code, means a single point of definition.
Another is to have the compiler detect patterns such as defineProperty(mem, "foo", {writable: false}) (I'm not sure of the actual syntax). We could even have a shorthand method to make attributes read-only in our compiler. defReadOnly(obj, field, val) or makeReadOnly(obj, field).
A third way is annotations. Have some JsDoc-style comment @readonly, or something, just above things we want to be read-only.
If it sorts by name then all the mem_xxx functions will be together. What's the problem?
It's still annoying to have to browse a huge file.
It is not an issue with mem_xxx. But with mem.xxx you will be calling methods in the mem object before the fields are made read-only. How will tachyon deal with such a case (a namespace being used in the middle of its initialization)?
mem.xxx = function() {} makeReadOnly(mem, "xxx");
// Use xxx after this point
This will cause problems with the static analysis. In other words, how will the compiler know which fields of the namespace object have been defined when the code reaches the call mem.xxx ? Also, where will the field "xxx" be in the mem object, after all we are incrementally adding fields to a hash-table, so the hash-table may have to be resized, which will move the fields around during the initialization. Not a good thing!
If we have some kind of mechanism to indicate that mem.xxx will not be redefined, any call to mem.xxx can be resolved to whatever mem.xxx points to at the point of the call.
That's true, but lets put things into perspective... We are talking about a single character in the "function name", either a "_" or a ".". This is not exactly a big change in style! On the other hand we can expect a factor of 2 speed difference between "_" and ".". That's significant.
1. We can easily make sure this speed difference does not occur in Tachyon.
2. We should not prematurely optimize. Performance is hardly an issue when we don't even have a remotely working compiler.
3. We aren't just talking about this one issue. There are plenty of other cases where I'm sure you'll advocate a more "old-school", procedural, C-like design. Using JavaScript this way takes us away from the main benefit of using JavsScript: simpler, more readable code.
The mem_xxx style is clearly more KISS than the mem.xxx style.
I disagree. JavaScript is an OOP language. Using an OOP language in the most procedural way possible because you're worried that our optimizations will be so weak they won't be able to inline such trivial cases, even when we can guarantee that our compilee *will* in fact optimize these cases (because we can force it to, *if needed*), clearly goes against the KISS principle.
*Premature optimization is also not KISS*... And this is clearly your main argument here, avoiding OOP/dynamic features as much as possible because you're worried about performance and want to constrain our design when we aren't remotely near the point where we can even run any benchmarks.
I say, let's write simple, organized code, using the sensible features of the language. There are some obvious compromises I'm willing to make (no eval, for example), but please, let us organize the code nicely and tidily, let us benefits from some of the most useful JavaScript features, and let us refactor for performance and/or add annotations to the Tachyon code only if/when performance issues surface.
- Maxime
On 2010-06-09, at 15:21 , chevalma@iro.umontreal.ca wrote:
You did not answer this important question: how will a *client* module know that mem is a namespace with read-only fields (thus enabling the compiler to perform direct jumps)?
There are many ways to achieve this. One is a naive analysis. Only one write to mem.foo + no evals + we trust our own code, means a single point of definition.
There is also a general principle that aims to keep the trusted code base as small as possible. Sure, the initial tachyon devs might follow the guidelines perfectly, but more devs will be added to the project in the future (and replace some other devs). I don't think we can guarantee that this will *never* become a problem...
Another is to have the compiler detect patterns such as defineProperty(mem, "foo", {writable: false}) (I'm not sure of the actual syntax). We could even have a shorthand method to make attributes read-only in our compiler. defReadOnly(obj, field, val) or makeReadOnly(obj, field).
Introducing special cases adds more complexity. In general, I tend to avoid that as much as possible.
A third way is annotations. Have some JsDoc-style comment @readonly, or something, just above things we want to be read-only.
If it sorts by name then all the mem_xxx functions will be together. What's the problem?
It's still annoying to have to browse a huge file.
I don't see how the implementations issues with a *documentation tool* constitute valid arguments that affect the coding standards we use. If JsDoc is too naive to produce correct documentation, we use another tool, write our own, tweak this one, or even better yet, submit a feature request to the JsDoc devs.
It is not an issue with mem_xxx. But with mem.xxx you will be calling methods in the mem object before the fields are made read-only. How will tachyon deal with such a case (a namespace being used in the middle of its initialization)?
mem.xxx = function() {} makeReadOnly(mem, "xxx");
// Use xxx after this point
And you argue that this is simpler than the mem_xxx naming scheme? If programmers have to type it, it clearly isn't. If the compiler takes care of it, it introduces complexity in the compiler that shouldn't be there. To me, it's pretty much a lose-lose situation. Just my opinion though...
That's true, but lets put things into perspective... We are talking about a single character in the "function name", either a "_" or a ".". This is not exactly a big change in style! On the other hand we can expect a factor of 2 speed difference between "_" and ".". That's significant.
- We can easily make sure this speed difference does not occur in Tachyon.
Granted, we can introduce mechanisms to address this problem, but at a cost in terms of "clean" design, as I argued above.
- We should not prematurely optimize. Performance is hardly an issue when
we don't even have a remotely working compiler.
Given the nature of the task performed tachyon, performance is very much an inherent part of the design constraints. I wouldn't brush it off so quickly and easily. As Marc said many times, we could always switch to using namespaces later if we really want to. It would be very easy to automate the conversion.
- We aren't just talking about this one issue. There are plenty of other
cases where I'm sure you'll advocate a more "old-school", procedural, C-like design. Using JavaScript this way takes us away from the main benefit of using JavsScript: simpler, more readable code.
Readability is subjective, I personally find the mem_xxx syntax simpler and more readable than the @namespace annotations etc, which seem rather verbose in your small examples. I'm not trying to start a debate on defining the readability of code, but just pointing out that this is a rather weak argument and, in my mind, less important than others.
The mem_xxx style is clearly more KISS than the mem.xxx style.
I disagree. JavaScript is an OOP language. Using an OOP language in the most procedural way possible because you're worried that our optimizations will be so weak they won't be able to inline such trivial cases, even when we can guarantee that our compilee *will* in fact optimize these cases (because we can force it to, *if needed*), clearly goes against the KISS principle.
There's a difference between OO code and your namespace proposal. The namespaces are not objects per say, they don't represent the same abstractions objects normally do. There are no brownie points for using this so-called object syntax in arbitrary situations. On the other hand, we will encounter situations where objects will and should be the natural way to write the code.
Moreover, there's also a difference between believing that tachyon will eventually be able to optimize such code and completely eliminate the performance hit, and placing ourselves voluntarily in a situation where we have to do it before tachyon can be really useful. There are other features of the language that we will avoid using for similar reasons, I don't see this one as being special in any way.
*Premature optimization is also not KISS*... And this is clearly your main argument here, avoiding OOP/dynamic features as much as possible because you're worried about performance and want to constrain our design when we aren't remotely near the point where we can even run any benchmarks.
Again, I fail to see the namespace = OOP argument. As far as I am concerned, there is nothing conceptually OO with either syntax, so they shouldn't be compared this way.
I say, let's write simple, organized code, using the sensible features of the language. There are some obvious compromises I'm willing to make (no eval, for example), but please, let us organize the code nicely and tidily, let us benefits from some of the most useful JavaScript features, and let us refactor for performance and/or add annotations to the Tachyon code only if/when performance issues surface.
I simple, organized code is the aim of both proposals. We just need to carefully examine the costs and benefits on each side. So far, I favour the mem_xxx syntax because it offers the best cost/benefits compromise (and in my opinion, by a large margin). That being said, if you have really compelling arguments in favour of namespaces, I'll gladly reconsider my position.
Bruno
mem.xxx = function() {} makeReadOnly(mem, "xxx");
// Use xxx after this point
And you argue that this is simpler than the mem_xxx naming scheme? If programmers have to type it, it clearly isn't. If the compiler takes care of it, it introduces complexity in the compiler that shouldn't be there.
As I've been arguing, I don't think that we should even be making those fields read only for now. That would be a fallback if our compiler can't optimize the code, if we establish that we somehow can't inline some functions and that is a performance issue. I suggest writing simple code and seeing how things go.
Granted, we can introduce mechanisms to address this problem, but at a cost in terms of "clean" design, as I argued above.
Please also note: for bootstrapping, it might be useful to do things of this sort:
for (name in namespace) if (name isinstance Function()) copyFunctionIntoBootStrapCode()
Do you think Mark's solution of recognizing prefixes in compiler function names is cleaner than what I propose?
As Marc said many times, we could always switch to using namespaces later if we really want to. It would be very easy to automate the conversion.
But the reverse argument holds too. We could go from . to _ with scripts as well.
There's a difference between OO code and your namespace proposal. The namespaces are not objects per say, they don't represent the same abstractions objects normally do. There are no brownie points for using this so-called object syntax in arbitrary situations.
My proposal allows to treat namespaces as objects (which they are), and to have nested namespaces. This is useful if we ever need to enforce properties for code in a given namespace. Mark has made the argument before that we should avoid the object method notation x.foo(v) and use global methods someclass_foo(x, v) whenever possible, again, for "performance" reasons. I feel that he wants us to adopt avoid many JS features that would be helpful for productivity, thereby negating alot of the benefits of doing this in a dynamic language to begin with. Don't forget I wanted to write this VM in C++ at the start. Performance is one of my main concerns too, but not in this case. Here, I say productivity first.
Moreover, there's also a difference between believing that tachyon will eventually be able to optimize such code and completely eliminate the performance hit, and placing ourselves voluntarily in a situation where we have to do it before tachyon can be really useful.
I'm not sure what Mark even believes in terms of performance anyways. I gave a system to *guarantee* non-rewritability and inlining *if needed*, he thinks we should stick to global methods why? Because "simple analyses" will automatically guarantee inlining of global methods? Please consider:
d8> function foo() { return 2; } d8> foo() 2 d8> function getglob() { return this; } d8> g = getglob() [object global] d8> g["f" + "o" + "o"] = 3 3 d8> foo(2) Uncaught: "TypeError: Property 'foo' of object [object global] is not a function", (d8) line 1 column 1 foo(2)
The performance guarantees mark seems to imply are potentially illusory (see example above) and based on a premature worry about performance (there may well be no cost with proper optimizations in place). Hacks will be needed to prevent method redefinition at the global scope without ECMAScript 5 annotations as I suggested before.
There are other features of the language that we will avoid using for similar reasons, I don't see this one as being special in any way.
Some features, like eval, are notoriously hard to optimize unnecessary almost all the time, and should definitely be avoided. Others, like classes, methods on objects, etc., are just convenient OOP practices.
That being said, if you have really compelling arguments in favour of
namespaces, I'll gladly reconsider my position.
1. It's the common JavaScript way. 2. Nested namespaces are possible. 3, No need for namespace prefix hacks. We have an implicit list of the members of each namespace on which we can iterate. 4. Read-only flag can be set if ever needed, where needed. 5. Nobody will want to switch to namespaces a year from now, with a large codebase. Programmer lazyness will prevent it from happening. 6. Performance is something we should mostly worry about in terms of how we design the VM's optimizations, IR, stack frame and object layout, etc. Not in terms of premature optimizations that impair productivity.
Hence, we could just do it the JavaScript way, and change it later *if it doesn't work well*, instead of imposing ourselves constraints based on nearsighted fear.
- Maxime
On 2010-06-09, at 7:11 PM, chevalma@iro.umontreal.ca wrote:
...many things removed...
I feel this debate has reached its limits... at least the limits of email conversation and my patience.
You can bring the subject up at the next tachyon meeting, but let's not spend too much time on this as there is plenty of work to be done to reach our end-of-summer objective.
Marc
Perhaps we could meet this evening on Google Wave? I've never used it, but if everyone is available, it might be the next best thing to meeting in person.
- Maxime
Sorry, I'm also busy tonight.
Marc
On 2010-06-10, at 6:43 PM, Maxime Chevalier-Boisvert wrote:
Perhaps we could meet this evening on Google Wave? I've never used it, but if everyone is available, it might be the next best thing to meeting in person.
- Maxime
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Erick setup a repository with a script to setup JsDoc and other tools (js_tools.git).
After toying some more with small bits of JavaScript and JsDoc, I will have to agree with Marc and Bruno regarding the module prefixes. It seems that JsDoc doesn't document modules very well even when they are objects. We should possibly consider trying to improve the tool ourself. If we could have a per-file summary, it would already be better.
I have also discovered that there are problems due to the initialization order. Functions in all JavaScript files are globally defined before anything else, but only if they are defined using the function somename() syntax, not if we assign them to a variable. Hence, defining functions globally saves us the trouble of having to figure out in what order we have to define functions.
However, I would propose, as a compromise, that we still name the functions themselves using hungarian notation, eg:
mem_ptrSub ast_prettyPrint
As for class names, unless there are collisions, I suggest we name them with Hungarian notation, starting with a capital letter, eg:
BaseInstr Parser
Does this sound like a reasonable compromise?
- Maxime
On 2010-06-10, at 21:07 , Maxime Chevalier-Boisvert wrote:
As for class names, unless there are collisions, I suggest we name them with Hungarian notation, starting with a capital letter, eg:
BaseInstr Parser
Pardon my ignorance, but what do you mean by Hungarian notation for classes?
Bruno
On 2010-06-11, at 10:16 AM, Bruno Dufour wrote:
On 2010-06-10, at 21:07 , Maxime Chevalier-Boisvert wrote:
As for class names, unless there are collisions, I suggest we name them with Hungarian notation, starting with a capital letter, eg:
BaseInstr Parser
Pardon my ignorance, but what do you mean by Hungarian notation for classes?
I think Maxime meant CamelCase (http://en.wikipedia.org/wiki/CamelCase). Here's a description of Hungarian notation:
http://en.wikipedia.org/wiki/Hungarian_notation
Marc
On 2010-06-11, at 10:34 , Marc Feeley wrote:
On 2010-06-11, at 10:16 AM, Bruno Dufour wrote:
On 2010-06-10, at 21:07 , Maxime Chevalier-Boisvert wrote:
As for class names, unless there are collisions, I suggest we name them with Hungarian notation, starting with a capital letter, eg:
BaseInstr Parser
Pardon my ignorance, but what do you mean by Hungarian notation for classes?
I think Maxime meant CamelCase (http://en.wikipedia.org/wiki/CamelCase).
That would make much more sense indeed.
Bruno
I finished my demo session earlier than anticipated and would be able to meet around 12:00, if you are around.
I'm available. Is Erick there?
Marc
On 2010-06-11, at 11:47 AM, chevalma@iro.umontreal.ca wrote:
I finished my demo session earlier than anticipated and would be able to meet around 12:00, if you are around. _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Not at the moment.
I'm available. Is Erick there?
Marc
On 2010-06-11, at 11:47 AM, chevalma@iro.umontreal.ca wrote:
I finished my demo session earlier than anticipated and would be able to meet around 12:00, if you are around. _______________________________________________ Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
On 2010-06-10, at 9:07 PM, Maxime Chevalier-Boisvert wrote:
Erick setup a repository with a script to setup JsDoc and other tools (js_tools.git).
After toying some more with small bits of JavaScript and JsDoc, I will have to agree with Marc and Bruno regarding the module prefixes. It seems that JsDoc doesn't document modules very well even when they are objects. We should possibly consider trying to improve the tool ourself. If we could have a per-file summary, it would already be better.
I have also discovered that there are problems due to the initialization order. Functions in all JavaScript files are globally defined before anything else, but only if they are defined using the function somename() syntax, not if we assign them to a variable. Hence, defining functions globally saves us the trouble of having to figure out in what order we have to define functions.
Fine.
However, I would propose, as a compromise, that we still name the functions themselves using hungarian notation, eg:
As a compromise to what? Is this a technical compromise or a political one? I'm all for technical compromises which can be argued on their objective merits, but political compromises make me feel uneasy. Coding style has some aspects which can be evaluated objectively, but for the most part it is a question of taste and thus depends on the people in contact with it (i.e. the programmers).
I'm not a big fan of CamelCase. I find it hard to read and the rules can lead to inconsistencies (should is_ASCII_EOF be mapped to isAsciiEOF or isAsciiEof or isASCIIEOF?). When writing the parser I started using CamelCase, but I abandoned it when I realized that I could not use it consistently because some functions are generated automatically from the grammar definitions and also because part of the code is a translation from Scheme code (where it was natural to use underscores instead of dashes). I do however like the rule of capitalizing functions which are constructors (which is what C++ does).
So I'm not quite sure what to do with this issue. We can bring it up for a vote among us after some more discussion. For the time being each one should just use the notation that they are most comfortable with. We'll refactor if need be. At this point what is important is that we advance the implementation... i.e. code!
Marc
On 2010-06-10, at 9:07 PM, Maxime Chevalier-Boisvert wrote:
As a compromise to what? Is this a technical compromise or a political one? I'm all for technical compromises which can be argued on their objective merits, but political compromises make me feel uneasy. Coding style has some aspects which can be evaluated objectively, but for the most part it is a question of taste and thus depends on the people in contact with it (i.e. the programmers).
It's both. My experiments with JS and JsDoc lead me to conclude that we should probably avoid using objects as namespaces for now, for technical reasons. They simply aren't proper namespaces. Once JavaScript gets proper namespaces, we might want to look into them, but right now, we pretty much would need to use hacks to make it work.
It's also a political compromise because, as you say, coding style is a matter of taste. Everyone has their own taste, but we want to pick some kind of convention and have everyone use it.
I'm not a big fan of CamelCase. I find it hard to read and the rules can lead to inconsistencies (should is_ASCII_EOF be mapped to isAsciiEOF or isAsciiEof or isASCIIEOF?).
I suppose this issue should also be treated in our conventions document. I would personally go with isAsciiEof. Capital at the beginning of each word/lexical unit.
There is also the issue of whether class names should be preceded by a module name, e.g.: ir_InstructionFoo or just InstructionFoo.
So I'm not quite sure what to do with this issue. We can bring it up for a vote among us after some more discussion. For the time being each one should just use the notation that they are most comfortable with. We'll refactor if need be. At this point what is important is that we advance the implementation... i.e. code!
Erick and I would like to propose that perhaps you should let us two take the final decisions as to the coding conventions and source code organizagion. Simply because those things are subjective, and we will be the ones who end up spending the most time working with this codebase.
We would rather spend time discussing with more objective technical issues, like the layout of stack frames and objects. However, perhaps it should simply be agreed that once Erick and I have spent a little more time working with the codebase, we will decide on the conventions we find more practical, to be used by all contributors.
- Maxime
On 2010-06-11, at 12:04 PM, chevalma@iro.umontreal.ca wrote:
So I'm not quite sure what to do with this issue. We can bring it up for a vote among us after some more discussion. For the time being each one should just use the notation that they are most comfortable with. We'll refactor if need be. At this point what is important is that we advance the implementation... i.e. code!
Erick and I would like to propose that perhaps you should let us two take the final decisions as to the coding conventions and source code organizagion. Simply because those things are subjective, and we will be the ones who end up spending the most time working with this codebase.
I do plan to contribute to the source code base in non-trivial ways. In fact at this point I've written over 6000 lines of JavaScript for the project (which is about 95% of all the code we have!). But as I say, just go ahead and code in CamelCase if that is what you are comfortable with. To me it is not a major issue as it does not affect the quality of the end-product. I'm more interested in coding style issues that affect performance (not limited to speed of execution).
Marc
On 2010-06-07, at 9:29 , Marc Feeley wrote:
On 2010-06-06, at 10:10 PM, chevalma@iro.umontreal.ca wrote:
Erick and I would like to use the JsDoc tool to generate code documentation based on annotations inside comments. This would require that our file headers and functions/constructors be annotated according to the JsDoc annotation tags.
See the wiki at: http://code.google.com/p/jsdoc-toolkit/
I've annotated some sample files in the repository (see lowlevel/memory.js and ir/instructions.js), and updated the coding guidelines on Google Docs to explain how to do this.
I've looked at your samples, and it seems verbose. I have a hard time reading the comments because of all the markup around them. Is there a shortcut for "description" tags, since they are really frequent? It would be nice if by default (no tag) a /** comment was a description. Is it necessary to repeat the "author" information for each class? If we really need to know who wrote what, we have the git history.
I agree with Marc here. The @description tag is really unnecessary; it should just be the default. The @author for each class could be replaced with a @author for the file, and possibly overridden in individual classes in the (unlikely) event that a different author inserts classes in the file.
Marc, do you have an opinion on this? It would imply adding annotations to your parser code.
Yes I will update my source files when we agree on a particular documentation style.
What can be gained by restricting words to be 64 bits? Can't we simply have that as a parameter? The intel code generator I've written support 32 and 64 bit architectures.
That's the conclusion Erick and I came to as well. Perhaps we should simply have a configuration file that sets these sort of platform-specific behaviors... And if 32 bit pointers/values are faster even on 64 bit machines, we can set that by default, while still allowing 64 bit pointers/values.
Yes, I should have mentioned also that with 64 bit references (a better term than pointers/values) a heap can be up to twice the size of a heap with 32 bit references for the same objects. That means that if a computer has less than 8 GB of RAM it is better to use 32 bit references (i.e. with 32 bit refs you can have as many objects in 4 GB of the RAM as with 64 bit refs with 8 GB of RAM). I've encountered this problem with Gambit on one of my machines which has 6 GB of RAM. Even on a machine with slightly more than 8 GB of RAM it is likely that the 32 bit refs will be desirable because it leaves more free RAM for the OS and other applications. Let's not neglect the fact that currently it is very rare to see applications which need more than 4 GB of RAM (regardless of the language they are written in). 32 bit architectures are not dead yet!
I have to say that in Java VMs, we have had better success using the 'compressed addressing mode' (i.e. 32-bit pointers on 64-bit arch). Memory usage, in particular, was a huge problem when using 64-bit pointers on regular desktop machines. I therefore support allowing both 32 and 64 bit pointers in tachyon as well.
Bruno