I would like to point the readers to an interesting discussion, which can be found in the comments to this post.
There are some interesting arguments discussed for and against different forms of implementing Smalltalk code as well as contradictory perceptions of encapsulation.
Showing posts with label Smalltalk style. Show all posts
Showing posts with label Smalltalk style. Show all posts
Sunday, 3 May 2009
Sunday, 26 April 2009
Big is ugly and evil - at least in Smalltalk code
This is an old wisdom that every experienced Smalltalker knows and should be aware of. Unfortunately, there are still experienced Smalltalkers who don't practice this wisdom, mainly because they are not capable of thoroughly abstracting and delegating.
Today I came across such an example of code developed by one of our code contributors with about 6 years of Smalltalk. I had to rework this code completely to make it clean and to delegate responsibilities to those classes where they really belong.
There was a method in an UI controller class that is part of our Seaside application classes, which is supposed to create a new user login instance for certain types of requests. This involves the incoming WARequest, which contains most of the needed data.
The original implementation did all the relevant logical checking in one big method of about 20 lines of code in the UI controller instance. This method was messaging to three different model classes plus the WARequest instance.
I did the following:
1) All request related checking was moved to WARequest, which now answers to one new method "isRequestWithLoginObj". Only the request class should know about its internals and about its type of request. Alternatively, one could also delegate this to the login model, but for various reasons I preferred the first choice.
Unfortunately, all of this had to be added by us to WARequest, because the standard Seaside class does not provide any such services. In the Seaside library the responsibilities and knowledge about request internals is spread over many other classes, which directly interrogate the "fields" instVar of WARequest. Therefore knowledge of many request internals, which should really be hidden inside WARequest, is spread widely.
2) All other logical checking, whether or not a new UserLogin model is to be created, was moved to the login model class together with passing the request instance. Now these two model classes make this up entirely among themselves.
3) Two other model classes, which are related to this procedure, are no longer touched by the UI controller. Instead, only the UserLogin factory code talks directly to its related model classes.
The result:
From 20 down to just 3 lines of code left in the UI controller method, two of which are related to internals of the UI controller.
Most important is the clear delegation of responsibilities to the respective classes and the much greater modularisation of the code through potentially re-usable small methods.
I made the experience that it is much wiser to put work into re-factoring such code, because modular code is much better to maintain, much simpler to modify and therefore also cheaper over the life cycle of a project and typically also less error prone.
I wish the authors of Seaside would regularly undergo similar re-factoring, not because the Seaside methods are too big, but primarily because the responsibilities in the Seaside code are not sufficiently encapsulated in the respective classes.
See also my post: "Proposal 1: Class WARequest!
Today I came across such an example of code developed by one of our code contributors with about 6 years of Smalltalk. I had to rework this code completely to make it clean and to delegate responsibilities to those classes where they really belong.
There was a method in an UI controller class that is part of our Seaside application classes, which is supposed to create a new user login instance for certain types of requests. This involves the incoming WARequest, which contains most of the needed data.
The original implementation did all the relevant logical checking in one big method of about 20 lines of code in the UI controller instance. This method was messaging to three different model classes plus the WARequest instance.
I did the following:
1) All request related checking was moved to WARequest, which now answers to one new method "isRequestWithLoginObj". Only the request class should know about its internals and about its type of request. Alternatively, one could also delegate this to the login model, but for various reasons I preferred the first choice.
Unfortunately, all of this had to be added by us to WARequest, because the standard Seaside class does not provide any such services. In the Seaside library the responsibilities and knowledge about request internals is spread over many other classes, which directly interrogate the "fields" instVar of WARequest. Therefore knowledge of many request internals, which should really be hidden inside WARequest, is spread widely.
2) All other logical checking, whether or not a new UserLogin model is to be created, was moved to the login model class together with passing the request instance. Now these two model classes make this up entirely among themselves.
3) Two other model classes, which are related to this procedure, are no longer touched by the UI controller. Instead, only the UserLogin factory code talks directly to its related model classes.
The result:
From 20 down to just 3 lines of code left in the UI controller method, two of which are related to internals of the UI controller.
Most important is the clear delegation of responsibilities to the respective classes and the much greater modularisation of the code through potentially re-usable small methods.
I made the experience that it is much wiser to put work into re-factoring such code, because modular code is much better to maintain, much simpler to modify and therefore also cheaper over the life cycle of a project and typically also less error prone.
I wish the authors of Seaside would regularly undergo similar re-factoring, not because the Seaside methods are too big, but primarily because the responsibilities in the Seaside code are not sufficiently encapsulated in the respective classes.
See also my post: "Proposal 1: Class WARequest!
Thursday, 23 April 2009
PrintString Mysterious Scriptaculous Seaside
Well, you have to be an insider to guess what that means or you read this post about some mysterious internals of Seaside.
Scriptaculous is a widespread JavaScript library, for which there is a Smalltalk interface to Seaside and which is used frequently by Smalltalkers using Seaside (as for as I know). This post is only about the interface between Seaside and Scriptaculous and this has nothing to do with Scriptaculous itself.
Today I was debugging some JavaScript code and I therefore had to frequently look into the inspector. For most classes we have modified the display messages for the inspector so that all vital information (instVars) is presented right in the inspector without having to dig into details.
I did the same to three Scriptaculous interface classes by changing the "printString" to my needs. I then continued with testing and suddenly: Rien ne vas plus! Everything was broken, nothing worked anymore.
I looked at it and found out that the authors of this Seaside to Scriptaculous interface used the "printString" for writing JavaScript, for directly converting the values of instances to JavaScript!
What a nuisance!
There is just no sense in this! Why not implement a special "asString", "asStringJS" or some "valueForJavaScript" or a "asJavaScript" or whatever. Buch why the fuck use this common printString, which is used by inspectors, debuggers and so forth and which is modified by many programmers to their taste!?
This is a self-destructive Seaside programming style. The worst I have ever seen in Smalltalk!
Scriptaculous is a widespread JavaScript library, for which there is a Smalltalk interface to Seaside and which is used frequently by Smalltalkers using Seaside (as for as I know). This post is only about the interface between Seaside and Scriptaculous and this has nothing to do with Scriptaculous itself.
Today I was debugging some JavaScript code and I therefore had to frequently look into the inspector. For most classes we have modified the display messages for the inspector so that all vital information (instVars) is presented right in the inspector without having to dig into details.
I did the same to three Scriptaculous interface classes by changing the "printString" to my needs. I then continued with testing and suddenly: Rien ne vas plus! Everything was broken, nothing worked anymore.
I looked at it and found out that the authors of this Seaside to Scriptaculous interface used the "printString" for writing JavaScript, for directly converting the values of instances to JavaScript!
What a nuisance!
There is just no sense in this! Why not implement a special "asString", "asStringJS" or some "valueForJavaScript" or a "asJavaScript" or whatever. Buch why the fuck use this common printString, which is used by inspectors, debuggers and so forth and which is modified by many programmers to their taste!?
This is a self-destructive Seaside programming style. The worst I have ever seen in Smalltalk!
Wednesday, 22 April 2009
Smalltalk without inheritance
Ever heard of that? Well, it's neither the 1. April, nor am I drunk.
Parts of Seaside is Smalltalk without inheritance! That's what I just found out.
It's only a small part but still: The file library tree is searched by a very special, cryptic and really "hacked" code for method names and this code intentionally ignores inheritance.
If you want to inherit code from some super class in the Seaside file library you must implement the same accessors in every sub-class or they will be ignored.
In case you don't trust me and want to look it up yourself (2.8), have a look at these two methods:
WALibrary -> documentAt:ifAbsent:
WALibrary -> fileSelectors
The mistake is in looping through all selectors of aClass instead of just sending this famous message "perform: selector".
Also, I am quite sure that this current implementation is much slower than "perform:", which is extremely fast.
I can't see any reason for such an implementation and in my >10 years Smalltalk I have never come about such an imbecillity. Again: Seaside has no documentation in the code! If there was any sense in this fancy implementation, a warning would be the minimum one could expect. But there is nothing!
You must read and understand the very cryptic Seaside code yourself to find out what's going on - and that will cost you weeks!
Don't get me wrong: Smalltalk is the most productive and brilliant programming language but even here applies: "Give a foul a tool"!
Parts of Seaside is Smalltalk without inheritance! That's what I just found out.
It's only a small part but still: The file library tree is searched by a very special, cryptic and really "hacked" code for method names and this code intentionally ignores inheritance.
If you want to inherit code from some super class in the Seaside file library you must implement the same accessors in every sub-class or they will be ignored.
In case you don't trust me and want to look it up yourself (2.8), have a look at these two methods:
WALibrary -> documentAt:ifAbsent:
WALibrary -> fileSelectors
The mistake is in looping through all selectors of aClass instead of just sending this famous message "perform: selector".
Also, I am quite sure that this current implementation is much slower than "perform:", which is extremely fast.
I can't see any reason for such an implementation and in my >10 years Smalltalk I have never come about such an imbecillity. Again: Seaside has no documentation in the code! If there was any sense in this fancy implementation, a warning would be the minimum one could expect. But there is nothing!
You must read and understand the very cryptic Seaside code yourself to find out what's going on - and that will cost you weeks!
Don't get me wrong: Smalltalk is the most productive and brilliant programming language but even here applies: "Give a foul a tool"!
Saturday, 18 April 2009
Proposal 5: Too lazy for lazy initialisation?
This is rather a general Smalltalk subject than solely related to Seaside but it is still an important subject that strikes us regularly.
The general Smalltalk concept assumes that a class is filed into an image and that during this file-in process various initialisations are performed, which henceforth stay valid during the entire life cycle of a class inside an image.
I am absolutely sure from our own experience that this is a very bad concept, which caused us a great number of wasted working days for fixing the results of this unrealistic assumption.
I don't want to waste your and my time on discussing why this initialisation at file-in time often doesn't work. The plain fact is that this is not sufficient and there are very many good reasons for it.
Therefore, I state the requirement that in general all variables but especially all statics and class variables must perform lazy initialisation, which is the only way to safely ensure that their values are correct when they are used for the first time.
Of course, this requires using getter methods as I already demanded in my porposal 4.
Expecting a programmer to think of manually initializing classes, which is often found in how initialize methods are implemented, is completely unrealistic. This must be automated and securely insured that all unneeded variables are in the expected state when a class is used.
All of our own classes work exclusively with lazy initialisation and I can't remember a single case where this simple and absolutely secure procedure did not fit.
For all imported libraries we have gone through the hard way of writing special initialisation methods that ensure that all statics and class variables are properly initialised when an image is started (typically the application). Additionally, we had to change many situations where instance variables were not properly initialized, which was typically due to implementation mistakes (we all make mistakes and this is why lazy initialisation is the by far securest form).
I have never come about any good arguments against lazy initialisation and from my really comprehensive experience (even beyond Smalltalk) I know for sure that there is no alternative.
Therefore I am asking not only the authors of the Seaside library but all Smalltalk class library developers in general to please adhere to lazy initialisation especially for statics and class variables.
You will save all of us who are using your libraries an awful lot of time!
The general Smalltalk concept assumes that a class is filed into an image and that during this file-in process various initialisations are performed, which henceforth stay valid during the entire life cycle of a class inside an image.
I am absolutely sure from our own experience that this is a very bad concept, which caused us a great number of wasted working days for fixing the results of this unrealistic assumption.
I don't want to waste your and my time on discussing why this initialisation at file-in time often doesn't work. The plain fact is that this is not sufficient and there are very many good reasons for it.
Therefore, I state the requirement that in general all variables but especially all statics and class variables must perform lazy initialisation, which is the only way to safely ensure that their values are correct when they are used for the first time.
Of course, this requires using getter methods as I already demanded in my porposal 4.
Expecting a programmer to think of manually initializing classes, which is often found in how initialize methods are implemented, is completely unrealistic. This must be automated and securely insured that all unneeded variables are in the expected state when a class is used.
All of our own classes work exclusively with lazy initialisation and I can't remember a single case where this simple and absolutely secure procedure did not fit.
For all imported libraries we have gone through the hard way of writing special initialisation methods that ensure that all statics and class variables are properly initialised when an image is started (typically the application). Additionally, we had to change many situations where instance variables were not properly initialized, which was typically due to implementation mistakes (we all make mistakes and this is why lazy initialisation is the by far securest form).
I have never come about any good arguments against lazy initialisation and from my really comprehensive experience (even beyond Smalltalk) I know for sure that there is no alternative.
Therefore I am asking not only the authors of the Seaside library but all Smalltalk class library developers in general to please adhere to lazy initialisation especially for statics and class variables.
You will save all of us who are using your libraries an awful lot of time!
Labels:
Seaside critics,
Seaside proposals,
Smalltalk style
Proposal 4: Documention - the Holy Grail
This is the absolute topmost and primary subject!
I have mentioned this before and I'm here giving some more details on what a good documentation should comprise of. Here I am only discussing the internal documentation, leaving general overviews and tutorials etc. completely aside.
1) Class comments
This is the most rudimentary documentation, which gives programmers an overview on the purpose and the responsibility of a particular class. This together with a clear and concise class name is absolutely mandatory in order to understand what a class does. It is not acceptable to force a user (programmer) to read the code in order to acquire the knowledge of what a class does. This is currently the case in Seaside.
For several reasons it has proven to be very practical to put the class comments into a separate method, which should be in a separate category. In my view this is far better than placing the comment into the class comment view (which is the default in VisualWorks).
There are many advantages in putting the comment into separate methods, which contain nothing but the comment and which have the same method name through old all class.
We are using the following convention, which applies to absolutely every (of our and most of the imported) classes:
In category "documentation" on the instance side there is a method called "documenationOnClass", which holds the documentation for this class.
In many cases there are additional methods in the same category, which then start with something like "documentationOnBlahBlah" where "BlahBah" characterises a particular subject, which is worth having its own separate documentation method.
The class comments should be short, concise but complete. This is difficult to achieve, I know!
Another advantage of these class documenting methods is that they can be exported easily and made available to new members of the team or used for a separate plain text documentation. However, in such cases it is always wise to keep the original texts inside the code, because life experience shows that external documentation is typically not updated when changes are made to a system.
2) Documenting instance variables
The standard practice in VisualWorks adds the instance variables to the class comment view.
I don't think that this is a good idea, especially since many instance variables are not handled as instance variables in the technical sense but are rather stored in some dictionary. In fact, we primarily use dictionaries for user application data, because they are far more flexible and easier to configure. There is hardly any speed difference in VW. Dictionaries are extremely fast.
We are documenting all instance variables in their getter methods.
This has been a good practice for my teams for far more than 20 years (I was in OOD technology for many years before my Smalltalk times). As I wrote before, we are typically not using instance variables directly in the code but we almost always access them via get and set methods (with some very few and well justified exceptions like for Semaphores or in the very rare cases where instance variables should be protected from being accessible from outside a class).
We always place the instance variable documentation into the getter methods. The setter methods typically do not contain any regular documentation except in cases where some special handling is implemented.
This has proven to be practical also because one looks at the getter methods far more often than at the setter methods.
3) Documenting methods in general
Now, let us face the facts: Many Smalltalkers believe that because their language and development environment is so brilliant and because they themselves are so brilliant as well, there is no need to document their code!
This is stupid ignorant bullshit!
Documenting Smalltalk code is just as mandatory as for code in any other language!
By the way: You can call me intolerant or whatever else you prefer but this subject is something that I am not willing to discuss, because I consider this the highest and most holy rule of software development at all! And you can take it very personal if I am stating that I cannot take anybody seriously who objects to comment his code!
Virtually every method must be documented!
The documentation text may not consist of the method name itself but it should substantially enhance the semantics of the method name. Ideally, the method name explains already the most important facts but in reality this is often not the case. This is where the method documentation comes in.
The way of phrasing this method documentation should be as consistent throughout the entire system as possible. The words themselves should be short, concise but still complete and cover all important aspects.
The method documentation must under all circumstances tell what the method answers.
Ideally, this method documentation should fully explain what a method does without having to show the code itself.
4) Special documentation inside methods
There are regularly cases where methods, especially longer multi-line methods, need additional documentation of certain statements. This is especially the case where the reason for a statement is not obvious and requires knowledge of outside or additional facts or circumstances.
Such special documentation should be placed above the respective lines of code, typically with an empty row above, so that it is clearly visually separated from the rest of the code. All other rules for documentation apply accordingly.
Please remember the first commandment:
Thou shall document thy code!
I have mentioned this before and I'm here giving some more details on what a good documentation should comprise of. Here I am only discussing the internal documentation, leaving general overviews and tutorials etc. completely aside.
1) Class comments
This is the most rudimentary documentation, which gives programmers an overview on the purpose and the responsibility of a particular class. This together with a clear and concise class name is absolutely mandatory in order to understand what a class does. It is not acceptable to force a user (programmer) to read the code in order to acquire the knowledge of what a class does. This is currently the case in Seaside.
For several reasons it has proven to be very practical to put the class comments into a separate method, which should be in a separate category. In my view this is far better than placing the comment into the class comment view (which is the default in VisualWorks).
There are many advantages in putting the comment into separate methods, which contain nothing but the comment and which have the same method name through old all class.
We are using the following convention, which applies to absolutely every (of our and most of the imported) classes:
In category "documentation" on the instance side there is a method called "documenationOnClass", which holds the documentation for this class.
In many cases there are additional methods in the same category, which then start with something like "documentationOnBlahBlah" where "BlahBah" characterises a particular subject, which is worth having its own separate documentation method.
The class comments should be short, concise but complete. This is difficult to achieve, I know!
Another advantage of these class documenting methods is that they can be exported easily and made available to new members of the team or used for a separate plain text documentation. However, in such cases it is always wise to keep the original texts inside the code, because life experience shows that external documentation is typically not updated when changes are made to a system.
2) Documenting instance variables
The standard practice in VisualWorks adds the instance variables to the class comment view.
I don't think that this is a good idea, especially since many instance variables are not handled as instance variables in the technical sense but are rather stored in some dictionary. In fact, we primarily use dictionaries for user application data, because they are far more flexible and easier to configure. There is hardly any speed difference in VW. Dictionaries are extremely fast.
We are documenting all instance variables in their getter methods.
This has been a good practice for my teams for far more than 20 years (I was in OOD technology for many years before my Smalltalk times). As I wrote before, we are typically not using instance variables directly in the code but we almost always access them via get and set methods (with some very few and well justified exceptions like for Semaphores or in the very rare cases where instance variables should be protected from being accessible from outside a class).
We always place the instance variable documentation into the getter methods. The setter methods typically do not contain any regular documentation except in cases where some special handling is implemented.
This has proven to be practical also because one looks at the getter methods far more often than at the setter methods.
3) Documenting methods in general
Now, let us face the facts: Many Smalltalkers believe that because their language and development environment is so brilliant and because they themselves are so brilliant as well, there is no need to document their code!
This is stupid ignorant bullshit!
Documenting Smalltalk code is just as mandatory as for code in any other language!
By the way: You can call me intolerant or whatever else you prefer but this subject is something that I am not willing to discuss, because I consider this the highest and most holy rule of software development at all! And you can take it very personal if I am stating that I cannot take anybody seriously who objects to comment his code!
Virtually every method must be documented!
The documentation text may not consist of the method name itself but it should substantially enhance the semantics of the method name. Ideally, the method name explains already the most important facts but in reality this is often not the case. This is where the method documentation comes in.
The way of phrasing this method documentation should be as consistent throughout the entire system as possible. The words themselves should be short, concise but still complete and cover all important aspects.
The method documentation must under all circumstances tell what the method answers.
Ideally, this method documentation should fully explain what a method does without having to show the code itself.
4) Special documentation inside methods
There are regularly cases where methods, especially longer multi-line methods, need additional documentation of certain statements. This is especially the case where the reason for a statement is not obvious and requires knowledge of outside or additional facts or circumstances.
Such special documentation should be placed above the respective lines of code, typically with an empty row above, so that it is clearly visually separated from the rest of the code. All other rules for documentation apply accordingly.
Please remember the first commandment:
Thou shall document thy code!
Labels:
Seaside critics,
Seaside proposals,
Smalltalk style
Friday, 17 April 2009
Proposal 3: Stick to Smalltalk naming conventions
The authors of Seaside violated the general Smalltalk naming conventions in a huge number of cases! Actually, they far more often violate them than adhered to them.
One of the great things about Smalltalk is that most of the developers of class libraries adhere to common coding conventions. That makes it much easier for others to reuse these class libraries. This is one of the most powerful "de facto" features of Smalltalk!
One of the most commonly used and undisputed convention says that a factory method, which creates a new instance, should start with the word "new".
This common convention is consistently ignored in Seaside!
This is very very bad style! Absolutely amateurish and far away from "engineering"!
This extremely bad habit makes it very difficult for a user (developer) of the Seaside library to understand the code. It forces the developer to look up the code, typically over several methods, to understand what is really going on.
Actually, these wrong method names really lie to us! And there are far more such cases than discussed here.
In most cases, the method names just don't say what they do! And the worst situation of this is regarding factory methods!
For example: in WATree root: anObject really creates a new instance! How the fuck shall one know this?
This is against all Smalltalk rules! I have to read to code to know what's going on.
Must better would be:
WATree -> newWithRoot: anObject
This makes clear:
a) A new instance is created.
b) The root is set.
Why the hell can't you adhere to what the great majority of Smalltalkers has been successfully doing for more than 25 years?!
Therefore, I strongly urge you to finally adhere to what is commonly regarded as Smalltalk convention! You are definitely not any cleverer or better than the forefathers of Smalltalk at PARC (and, of course, neither am I)! You are most likely some bright but rather young guys with little experience.
So forget your pride and try to learn from the elder Smaltalkers
(I mean the general conventions. They are good and make much sense!).
Please do rename all factory methods to start with "newBlahBlah" instead of just using what you had in your mind when first writing this code.
A general recommendation from my experience:
Polymorphism is a great thing - but not always! Polymorphism for methods like "new" or "initialize" hurts more than it helps, because it is almost impossible to track the senders, because there are simply far too many!
Therefore, it has proven to be a good practice to combine the general convention "new" with some information about what is created or initialized. This can either be a shortcut of the class, which receives this message, or some other essential information related to this factory method.
In such cases it is very simple to track down the senders without having to go via the class names, which is often not so precise and which is always very much slower (at least in VisualWorks and in our images, which have typically between 60 and 80 MB in the development versions.
...more to follow soon! I have a very long list to go through!
One of the great things about Smalltalk is that most of the developers of class libraries adhere to common coding conventions. That makes it much easier for others to reuse these class libraries. This is one of the most powerful "de facto" features of Smalltalk!
One of the most commonly used and undisputed convention says that a factory method, which creates a new instance, should start with the word "new".
This common convention is consistently ignored in Seaside!
This is very very bad style! Absolutely amateurish and far away from "engineering"!
This extremely bad habit makes it very difficult for a user (developer) of the Seaside library to understand the code. It forces the developer to look up the code, typically over several methods, to understand what is really going on.
Actually, these wrong method names really lie to us! And there are far more such cases than discussed here.
In most cases, the method names just don't say what they do! And the worst situation of this is regarding factory methods!
For example: in WATree root: anObject really creates a new instance! How the fuck shall one know this?
This is against all Smalltalk rules! I have to read to code to know what's going on.
Must better would be:
WATree -> newWithRoot: anObject
This makes clear:
a) A new instance is created.
b) The root is set.
Why the hell can't you adhere to what the great majority of Smalltalkers has been successfully doing for more than 25 years?!
Therefore, I strongly urge you to finally adhere to what is commonly regarded as Smalltalk convention! You are definitely not any cleverer or better than the forefathers of Smalltalk at PARC (and, of course, neither am I)! You are most likely some bright but rather young guys with little experience.
So forget your pride and try to learn from the elder Smaltalkers
(I mean the general conventions. They are good and make much sense!).
Please do rename all factory methods to start with "newBlahBlah" instead of just using what you had in your mind when first writing this code.
A general recommendation from my experience:
Polymorphism is a great thing - but not always! Polymorphism for methods like "new" or "initialize" hurts more than it helps, because it is almost impossible to track the senders, because there are simply far too many!
Therefore, it has proven to be a good practice to combine the general convention "new" with some information about what is created or initialized. This can either be a shortcut of the class, which receives this message, or some other essential information related to this factory method.
In such cases it is very simple to track down the senders without having to go via the class names, which is often not so precise and which is always very much slower (at least in VisualWorks and in our images, which have typically between 60 and 80 MB in the development versions.
...more to follow soon! I have a very long list to go through!
To document or not to be
The first of the 10 commandments for software developers says:
"Thou shall document thy code"!
And this is unfortunately also the most frequently violated rule! Which also applies to Smalltalk developers!
The Seaside authors have constantly violated this rule!
There is virtually no documentation inside the code or for the classes. This is even worsened by the fact that many class names, method names and instance variable names are simply wrong. They don't do or deliver what their names promise. They are misleading any potential user of the Seaside library and stealing their time!
I think that this cannot be tolerated!
If one wants to build products on Seaside, there must be some good documentation inside the code, which allows a developer to understand quickly what is going on without reading the code.
I think that it is very amateurish and ignorant not to document such a complex class library at all! There is no excuse for it!
I can only assume that it is either or both of these reasons:
The authors planned to sell their experience and advise instead of providing a documentation. I think that this would be fair enough provided that it is openly stated (which it is not).
Alternatively it could be this frequently found ignorance of primarily younger and rather mathematically minded developers who just ignore elder people's experience that it always pays back to invest into proper documentation even for the original developer himself. Many of these mathematical people have simply problems to express their thoughts in clear words.
In my team and my work such an ignorance was never tolerated! And I am not willing to waste my time discussing this unconditionally mandatory requirement of documenting code!
By the way: The original PARC Smalltalk library was and still is a piece of art and the perfect example for well documented and concise code. Unfortunately, the newer VW classes are nowhere near this high standard.
Lucas Renggli was most ignorant when I offered my help to document Seaside. See more in: "On the darker side of Seaside".
I therefore propose a Seaside documentation community to exchange our documentation work. My team and I have already done a lot in this respect and I am offering this to everybody who is willing to contribute to this vital subject.
Of course, I also invite the Seaside authors to collaborate with us in this respect. Just drop me a line and I will come back to you with my proposals.
"Thou shall document thy code"!
And this is unfortunately also the most frequently violated rule! Which also applies to Smalltalk developers!
The Seaside authors have constantly violated this rule!
There is virtually no documentation inside the code or for the classes. This is even worsened by the fact that many class names, method names and instance variable names are simply wrong. They don't do or deliver what their names promise. They are misleading any potential user of the Seaside library and stealing their time!
I think that this cannot be tolerated!
If one wants to build products on Seaside, there must be some good documentation inside the code, which allows a developer to understand quickly what is going on without reading the code.
I think that it is very amateurish and ignorant not to document such a complex class library at all! There is no excuse for it!
I can only assume that it is either or both of these reasons:
The authors planned to sell their experience and advise instead of providing a documentation. I think that this would be fair enough provided that it is openly stated (which it is not).
Alternatively it could be this frequently found ignorance of primarily younger and rather mathematically minded developers who just ignore elder people's experience that it always pays back to invest into proper documentation even for the original developer himself. Many of these mathematical people have simply problems to express their thoughts in clear words.
In my team and my work such an ignorance was never tolerated! And I am not willing to waste my time discussing this unconditionally mandatory requirement of documenting code!
By the way: The original PARC Smalltalk library was and still is a piece of art and the perfect example for well documented and concise code. Unfortunately, the newer VW classes are nowhere near this high standard.
Lucas Renggli was most ignorant when I offered my help to document Seaside. See more in: "On the darker side of Seaside".
I therefore propose a Seaside documentation community to exchange our documentation work. My team and I have already done a lot in this respect and I am offering this to everybody who is willing to contribute to this vital subject.
Of course, I also invite the Seaside authors to collaborate with us in this respect. Just drop me a line and I will come back to you with my proposals.
Subscribe to:
Posts (Atom)