Showing posts with label Seaside critics. Show all posts
Showing posts with label Seaside critics. Show all posts

Wednesday, 20 May 2009

Seaside is not multi-lingual

Most business web sites outside the USA are multilingual, because the world is and always will be multilingual.

Seaside offers no support for multiple languages, which is a natural requirement for any web server, because different users (sessions) require different languages simultaneously.

Unfortunately, the same lack of language support is true for VisualWorks Smalltalk as such, which does not offer any support either for language-free code that receives its user visible text from translation libraries (the latest version I know is 7.4).

This is the old problem with Anglo-Saxons, especially with USAmericans who are trying to impose their own minimal language on other people! Language imperialism at the finest!

Therefore, my advice to new Seaside users is to take into account that it will need substantial efforts to make Seaside truly multi-lingual without having code redundancies.

The problem is simple: These naive (and often stupid in the sense of uneducated) North Americans really expect that one writes language dependent text into the code making it impossible to serve different languages from the same source code. What a stupid US ignorance ignoring and trying to suppress this wonderful diversity of different people, languages and cultures!

And the fact that the main author of Seaside, Avi Bryant, is of Canadian origin makes this ignorant mono-lingual implementation even morally worse, as he is denying the natural human rights of his own French-Canadian fellow countrymen, not to mention the many Spanish people in the US of A who are raped to use English .

Thursday, 14 May 2009

Proposal 12: Rename WATagBrush "class"

A CSS "class" is not real a class in the sense of object-oriented design. It just has "same taste" of a class.

I find this term in Seaside misleading and somewhat confusing for a Smalltalker.

Therefore, it would be much better to call this attribute and its accessors "cssClasses:". This tells exactly what it is:
a) CSS related
b) More than one are possible.
c) The term "class" is used so often in Smalltalk that this alone is another reason to distinguish this special cssClass(es).

Note: It is not good to adopt existing terms even if (or because?) they are widespread, if they are imprecise.

Tuesday, 12 May 2009

Seaside fools you with amateurish junk code

Never trust what you see in Seaside:

WASession->application
^parent

WASession owns the instance variables 'parent' and 'application' and for some unknown reason the user is fooled by the above code - of course without any explanation as always.

This is so extremely insane and it's only one out of many similar imbecillities in Seaside!

Now this seems like a little problem but in reality it is (and was for me) a very big problem, because this stupid Seaside bug was the reason for many wasted hours searching a bug that I thought to be in our own code.

The background: We had to introduce 'release' methods to ensure proper garbage collection. One of these was also removing the dependency between aWASession and its holder WAApplication. This is where we were so baldy fooled, because "self application" did not answer what it pretended.

You are lost in Seaside if you don't read all of the code that you are calling! Disgusting! This is the first such library that I have ever come about where one is forced to really control and read all of the (completely undocumented) code!

If the law of karma really exists, then these insane stupid Seaside developers will have to suffer badly in their next lives for what they did to their users and how they wasted our time!

These coding sins in Seaside are screaming for a most humbly "I beg your pardon, please forgive us!" to all those who were fooled by this amateurish junk code!

Wednesday, 6 May 2009

Seaside - amateurish circle-jerk mentality ?

There were two comments given to my posts, which could explain the problems of Seaside from a completely different perspective and much better than I did:

Richard Kulisz commented my post "Seaside standing outperforms facts":

"It seems Seaside has been infected with the same amateurish circle-jerk mentality that's corrupted Squeak from which it was spawned. It also seems to me that this has little to do with national differences and everything to do with professional vs amateur efforts. In professional circles, standards vary from place to place, but in amateur circles (eg, FLOSS) they seem to be uniformly poor."

Richard also commented my post: "Laws of life in a community":

"The conscious or unconscious selection of Leaders and their defense at all costs is a normal (even if utterly repugnant, vile and disgusting) part of every community. I've been in quite a few and I've observed this behaviour in nearly all of them. The Creators always, ALWAYS get defended.

In the case of programmers, no community of programmers can ever be diverse enough to avoid appointing gods. Wiki wiki (c2) wasn't. It's because programmers are on the whole nothing but mindless robots incapable of genuinely original thought. What's worse, the overwhelming majority LIKE this status quo.

Also, in the case of programmers, the Creator is almost always going to be a member of the community. This creates incestuous inbreeding, up to and including mutated deformed offspring."

----------------------------------------
Well, Richard, thank you very much for these interesting and valuable aspects. I feel that there is a lot of truth in these words, although I cannot judge myself, because Seaside is my first and only "community project" experience. Not a good one, though. Nor did I ever use Squeak beyond a little playing.

It all sounds very logical - taking into account that most people choose being part of a herd, a malfunction that I have never suffered from.

Seeing Seasiders as amateurish sheeples is an interesting aspect, which explains the fierce rejection of my proposals by most, without even discussing the technical facts. And it also explains why my heretic blasphemy of their gods made all my good technical arguments worthless for them.

Thank you for these insights, which, in essence, is much stronger a critique than mine.

Wednesday, 29 April 2009

Proposal 10: Move it all to WARequest

Handling requests is one of the most important atomic tasks of Seaside, because this governs all the rest.

Currently, the knowledge about requests is scattered over different classes. Just two example out of many:

WABrowser -> initialRequest
aRequest fields at: 'class' :.............
(A string used as key and, even worse, one which is impossible to track, because there are so many.)

WAApplication handleRequest:
aRequest fields at: self handlerField..........

This violates encapsulation and it's no object-oriented design. Only the class WARequest should know about its internals, it's data, keys etc. and it should be interrogated by other classes via clear protocols, which hide all internals from these other classes.

I have mentioned this before, but because this bad design was essentially the cause for having to search for a bug yesterday I am bringing this up again.

Tuesday, 28 April 2009

I fucked-up Seaside again

I have made it again: I fucked-up my entire Seaside application! Rien ne vas plus!

This block has much of a diary, because I'm reporting my daily experiences with the Seaside web server library.

One of the main problems, aside from the many others, is that the logic and the control flow is so extremely scattered over different classes and very inconsistent terminology so that it is extremely hard to track down errors.

I had to make a couple of changes related to the special types of requests. As a consequence major features don't work anymore. This alone would not be a problem if it wasn't so very extremely difficult to follow the flow of actions that Seaside performs.

These problems are essentially caused by these characteristics of Seaside:

1) Very scattered responsibilities
Several different classes perform actions directly on instance variables of others, in this case of the WARequest (see also my post "Proposal 1: WARequest"). This makes it very difficult to track down what happens where and why.

Because of this alone Seaside is not really object-oriented, as the law of encapsulation is regularly violated.

2) Inconsistent terminology
Especially class and method names are inconsistent and often misleading. This makes it even more difficult to understand what is going on where.

3) Debugging is extremely difficult
And it's also very time-consuming, because Seaside always accesses the current session via signalling. This can be seen as a nice technical feature but it makes the developer's work very inefficient. More about this soon in a separate post.

I am not yet sure about the following statement, because I'm still (after several weeks) in the phase of learning Seaside, but I have the strong feeling that there are simpler, more concise and probably also more efficient ways of accessing the current session.

If I had known the full scope of these problems when the decision for Seaside was made, we would not have decided to use Seaside! It's a nightmare!

Don't expect censored language from me. I am not US American and I detest
self-censoring called "political correctness". In Europe most people still speak out the truth!

----------------------------------------------------------------------------------------
Update: Problem solved!

Here is the solution: What caused yesterday's confusion was written by myself and therefore, of course, my own mistake.

However, this was still an indirect consequence from Seaside's distributed responsibilities regarding the handling of request types. To avoid this, I have added a couple of methods to class WARequest, because this class should be the only one to know about the internals and types of its data. When writing these additional methods I had a misconception about the meanings and priorities of key fields, which are spread all over other classes in the original Seaside code.

Because I consider this situation very important, I am giving a practical example in a separate post.

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!

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"!

Tuesday, 21 April 2009

Malfunctioning file handling in Seaside

Today I wanted to teach my Seaside application to supply files from hard disk and to use what I had read yesterday on the mailing list. It took me the whole day and it's still not working.

The normal assumption in Seaside is that JavaScript, CSS and image files are supplied by code. This is why one needs a programmer just to change the name of a file.

Therefore, this assumption of Seaside is quite unrealistic.

The class WAExternalFileLibrary looks promising. It provides just one protocol different to its super class WAFileLibrary.

Again not one word of documentation!

Aha I thought, finally a good implementation! I was badly disappointed within minutes.

I had to read and understand the whole code in order to assume what I would have to do to make it work. I did that but it still does not work.

Now, I have to admit, I am not a genius, I'm just an average experienced Smalltalker with >10 years of Smalltalk practice. That's probably too little to master Seaside.

Georg Heeg calls it a bug

I then used the search engine to try to find out what's going on and one of the first hits was a comment on the website of Georg Heeg in Dortmund. To those who don't know the name, Heeg is worldwide among the handful of most experienced Smalltalk companies with the very best technical reputation. They have been the representative of Park Place for the German language countries ever since I got to know Smalltalk and that was in the mid 1980-ies. So they should really know!

In a very friendly and polite way it says there that the file handling of Seaside is buggy and was constructed under misleading conceptual assumptions.

In my plain words: It's a crap!

But read yourself!

In the meantime I have succeeded to supply at a least file name to the response object but for some reason the supplied code does not read the file. I have to go very deep inside the low-level code to find out why and to fix this bug.

This lousy implementation of Seaside is costing us weeks and months! Be prepared for many adventures when you choose Seaside. It's a pity because many concepts are really good.

Addition at 23:00: It finally works! But only after digging deep into the internals and then refactoring much of this crap code.

Monday, 20 April 2009

Proposal 8: Use symbolic file names

Not only is the current file handling implementation of Seaside very inefficient (see proposal 7), but it also requires sending long path names to the browser and back.

This makes little sense, it is wasting bandwidth and CPU performance in an environment, which needs the fastest responses possible.

In the current implementation Seaside is not fast.

This implementation also makes the software relatively inflexible, because practice shows that people tend to include these absolute path names in strings, that constitute CSS or JavaScript. (This is not the fault of Seaside, of course, but a normal human reaction resulting from Seaside's design.)

This problem could be very easily solved as a side-effect of my proposal 7, if one only sends the real or symbolic file names without any paths to the browser.

When a file request comes in, these symbolic file names (of CSS, JavaScript, images etc) are used for a look-up in the dictionary mentioned in proposal 8. The library path and the related method name come from this dictionary. All it needs is one:
classFromDict perform: methFromDict and it's all done.

- Much faster than today
- Much simpler to implement and change
- Shorter file strings sent out (not a must, but de-facto)
- Symbolic file names can be switched depending on user or system settings
- Simpler to debug
- and a few more.

Of course:
- The new static must be reset before starting an app
- It must provide lazy init (see my post: "To lazy for lazy initialization")

Proposal 7: On inefficient Seaside file handling

During my work today I detected how inefficiently Seaside handles file requests.

I was deeply shocked to see this highly complicated implementation, which over and over again makes the Smalltalk VM busy with inefficient operations, which could easily be handled in a much simpler fashion.

It does not need to be discussed that a web server must be extremely efficient and fast. This is not the case for Seaside!

As I was corrected by a comment, Seaside is not a web server in the precise technical sense. That is correct. Nevertheless, one generally speaks also of PHP as a web server although typically the actual server work is done by a front-end Apache. Therefore, I still stick to this term "web server" for Seaside even if it is not absolutely precise.

When a file requests comes in, the class WAFileHandler loops recursively through all the subclasses of all of those library classes, which were registered as "root classes" and executes aBlock on each of them.

This is not only highly inefficient and wasting a lot of CPU performance but it is also very difficult to debug (like Seaside in general) and to step through. Probably another intention to keep Seaside as a cryptic black box!

My concrete proposal, which is by no means perfect but involves minimum changes to the current situation: Introduce a static in class WAFileHandler, which answers a correlation (library name and method name) for every incoming file request.

A dictionary look up is extremely fast in Smalltalk (at least in VisualWorks) and certainly multiple times faster than the current implementation. At the same time one could also solve the problem that I am discussing in my next proposal.

That has another good side-effect: It would be much easier than today to switch between different libraries - even at run-time when a user wants to select his user-specific skin.

Proposal 6: Seaside stop lying to us!

Seaside seems designed and coded intentionally in a very cryptic style presumably with a goal to make it difficult for new users to understand it and to become productive without consultancy of specialists!

Here is another argument:

There are plenty of methods with extremely misleading names and this is, apart from the totally missing documentation, a main reason why it will be very difficult, labourious and time-consuming for new users to really understand and properly use Seaside!

Here is a perfect example:

In the class WARenderContinuation there is the method "newHtmlRoot:". From general Smalltalk conventions one would expect that this answers some new instance with data of the HTML root.

That is not false but not correct either, because unfortunately this method does a lot more: It starts a main generation loop through all child classes and sends them the very important message "updateRoot:"

When reading the message "newHtmlRoot" one would never expect that this factory method also immediately performs such important and vital actions, which are hidden behind a false name. In most libraries it is common practice to keep factory methods clean from such important actions.

I consider this extremely bad style and it makes me very angry that they are stealing my time with such highly individual and extremely uncommon bundling of functionalities behind false and lying method names! If at least they had given it some correct name like "newHtmlRootAndCollectFiles:" then I would just argue about this fancy but at least honest method name.

By the way: the method name "updateRoot:" is also a bad choice in my view. What it really does is collect references to script and css files etc, which are added to the new WAHtmlRoot instance that is created in newHtmlRoot:.

The semantics of "update" imply that some content is changed with some newer content (more "up-to-date"). This is not the case here. What happens is that some data is collected and added for the first time to that new instance. That is clearly not an update!

In my view, something like "collectFilesForRoot" or "initializeRootWithFiles" would be much clearer and much simpler to understand.

I would not discuss this if there were not many dozens of other wrong names. Nobody always and immediately finds the right words. That is why I regularly change ("update") method names when I see that they were not well selected or because their purpose and actions have changed over time.

I don't know why the authors of Seaside have made such a bullshit (remember: I promised open words and no false politeness)! I can only think of three reasons:

1) Either their goal was to sell their consultancy by making it hard for new users to become productive without external consultancy!

2) Maybe these people are verbally so limited in their capabilities of expressing their thoughts that they simply couldn't do any better. This would not be unusual for highly mathematical people and it is by no means any disqualification. I have never met anybody who is equally good in mathematical and in verbal logic. I myself have often my great problems with maths, for example, but never with open words.

3) Or these people are so self-assured and regards themselves so ingenious that they just give a shit on what other people think and don't understand.

I don't know but I would bet on a combination of the first and the third reason.

In any case, I think that these many substantial problems must be resolved quickly to make Seaside easily usable. Currently, this is unfortunately not the case.

For a quick start it would help a lot if all classes and methods had clear and concise documentation inside the code.

Unfortunately, there is almost nothing!

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!

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!

Friday, 17 April 2009

Proposal 1: Class WARequest

With this posting I am starting a series of concrete proposals for improving Seaside. Of course, the documentation has absolutely the topmost and very first and highest priority, because:

There is never any excuse for not documenting!

In my view class WARequest is of the most important classes, especially in debugging and while getting to know the functionality of the system. This is why I start with this class.

I therefore propose to enhance this class as follows:

1) All responsibilities to WARequest
Among experienced Smalltalkers it should be out of any discussion that responsibilities about implementation details (how and where to store data) are solely responsibilities of the respective class.

In Seaside, this is not the case. Instead, the knowledge about internals of WARequest is regularly and frequently spread over many other classes.

See my example further below where a request is tested for some state. You will find many such tests in different classes and this is just very bad coding style.

It is programming at best with objects (or may be programming around objects) but not object-oriented programming!

Therefore, all such method that are checking or manipulating data inside WARequest must be moved into WARequest, which responds by a Boolean answers or via delivering or accepting the data.

2) Introduce states of requests
In the beginning it was extremely difficult for us to find out where what happens inside Seaside,which was worsened by the fact that no stringent naming conventions for the methods were used (that is another subject not for now).

This essential class WARequest must be enabled to answer its states, i.e. what type of request it is etc. All of this must be checkable via testing methods in a stringent syntax like "isReqestBlahBlah" so that it is easy to find out all available test methods.

3) Add a language code
As for the moment I'm leaving out all my heavy claims on this Anglo-Saxon ignorance about multilingualism. Also, the language code is even more important in WASession, but I will come to that later.

Add an instance variable to WARequest, which can be interrogated by all consumer methods, which need to process or query the requests instance. Many of these are language dependent (Anglo-Saxons: You are not alone in this world and this world is not yours!) and it is often simpler to ask the request instead of the session. Also, the requests can be often reached directly while the current session needs this fancy event, which is much more difficult to use while debugging (and also slower).

4) Add a starting and ending time
We have invested some work in a set of classes, which are recording not only the time but also the events (including menus, forms, errors, missing translations etc), which are processed through a request. In order to be able to report such data, the request must be able to deliver its starting and its ending time, which (in our case) will be recorded when the response is sent to the client.

5) Use setter and get a methods only!
I know that this is an academic subject, to which many Smalltalkers will oppose, but in our work we hardly ever use instance variables directly even inside a class. I personally consider this as bad style (with some very few exceptions like Semaphores). Getters and setters are very much better in many respects!

In concrete words, this does not mean what is implemented today: aRequest fields at: #someValue -> very bad!

But instead this means one of these three much better tractable versions:
a) aRequest fieldsAt: #someValue
b) aRequest get: #someValue
c) aRequest someValue
where the third one has the advantage that the implementation of the storage of this symbol inside WARequest is even better hidden. We have implemented b) and c) depending on the situation.

6) Accessors for nativeRequest
Often one needs to query the instance of nativeRequest, which sits inside WARequest. This is an implementation detail, which should be hidden inside WARequest without consumers (other classes) having to know this internal of WARequest.

Therefore, I recommend you to include accessor methods to WARequest for all services supplied by the nativeRequest, so that consumers only have to deal with WARequest.

7) Accessors for other internals
Of course, the same as stated in 6) is true for all other instances held by WARequest in its instances. It is never good to let foreigners (classes outside WARequest) know about implementation details inside another class!

To reming you: This is what is called encapsulation in the schooldays for Smalltalk. The authors of Seaside have forgotten most of these lessons.

8) All WARequest key fields on the class side
There are various keys handled essentially (not only but mainly) by WARequest. Currently, they are spread all over many places in several other classes. Very bad!

Create unique accessors with the stringent naming syntax (proposed: requestkeyForBlaBlah) on the class side of WARequest. All other classes where these keys are used, must refer to these unique identifiers. Alternatively and a little bit more liberally one could use these identifiers as symbols elsewhere, but I would prefer the first version (we have done it that way).

9) Testing methods for all WARequest keys
in order to ease the life of consumers of WARequest, there should be testing methods with the stringent syntax (isRequestForBlahBla) inside class WARequest. I've shown this already in my first example further below.

Résumée:

Please see this as my first very constructive contribution to improving Seaside.

I hope that the critical voices in the mailing list who knew nothing better then making their fun about my blogging will now start to understand slowly that I mean it very seriously and that my proposals come from a very long time in the software industry.

Best regards from Mr. Cucumber
(as you called me in the mailing list)
(my gilfriend happily agrees *ggg*)
...more to come soon!

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.

Thursday, 16 April 2009

Four mistakes in one line of code

Here is a first and good example of the very bad coding style in Seaside. There is one line of code with four severe mistakes in it:

WARenderContinuation -> shouldRedirect: aRequest
^ aRequest isGet not or: [(aRequest fields includesKey: '_n') not]

1) There is no sense in castrating Smalltalk and forcing the developer to use a text editor for finding the occurrences of the key '_n' by placing this value into a string. Smalltalk has this great feature of showing the references to symbols! So why does one use a string for something, which is really a symbol (a key)? This is very bad style! Amateurish! Just stupid!

2) There are several places where the key '_n' is used. Therefore, the actual key should not only be a symbol but it should also be stored at one central place, in something like a config class, which acts as the holder of all such symbols. From there on, the references can be tracked easily.

3) The knowledge about where the value for this key is to be found is spread over many other classes (in this case WARenderContinuation). That is very bad, too. Only the class WARequest should know where the value for this key is implemented. Therefore, WARenderContinuation should not know anything about somebody else's instVar 'fields'.

4) The knowledge about how the value of this key is stored (in this case in a dictionary) should also not be spread over other classes. Therefore, the usage of "includesKey:" in another class is another bad mistake in this case. Solely the class WARequest should know how this key is stored in its instances.

There is a very simple solution for these bad style codings:

^ aRequest isGet not or: [
(aRequest isTypeOfRequestForRedirect) not]

All we need is one additional little method in class WARequest:

isTypeOfRequestForRedirect
^self fields includesKey: self class requestKeyForRedirect

This method hides the place and the form of storing the key inside itself and that is where it should (only) be. In this case, the key itself is taken from a central definition method on the class side, because this key is used by other methods within the class WARequest and possibly also from by classes.

Unfortunately, similar occurrences of very bad coding style are spread all over the Seaside classes.

Obviously, the authors of Seaside have not a good clue of encapsulating class behaviour and class data into the particular classes. Instead, they spread this knowledge freely all over other classes and then even in the form of strings, which cannot be tracked by the brilliant Smalltalk development environments.

This is just one example of many for the very bad coding style in Seaside. It's more "structured programming with objects" rather than object-oriented design. From my developers I would not tolerate such basic mistakes.

Wednesday, 15 April 2009

On the darker side of Seaside

The Seaside web server library has often been praised to give Smalltalk a new boost. This is certainly true but things look a lot different when it comes to the practical usage and implementation of Seaside.

This is why this blog is primarily discussing the darker aspects of the Seaside design and implementation besides discussing general aspects of programming in Smalltalk.

Therefore, please don't expect too much of praise from me. You will primarily read critics and a lot of concrete engineering proposals to improve your work in Seaside and Smalltalk.

Of course, I first called Lukas Renggli, the European Seaside advocate, offering my help for documentation and improvement of the "object-orientability" of the Seaside code.

Lukas Renggli showed to be totally immune to advice. He did not even listen to my arguments! After my first critics (missing doc) he immediately said that this was one of the best pieces of code that exists in Smalltalk (I will prove him wrong in this blog) and he recommended me to use Ruby if I was "incapable" of using this "brilliant" (but undocumented) code. I have rarely spoken to someone so unconditionally arrogant and ignorant.

This is how I came to write this blog.

Another subject: Don't expect me to be politically correct!

This stupid "PC" is a US American invention that nobody needs with a goal to control, manipulate and spiritually suppress open minded people by trying to enforce them to lie or at least to deny the truth. I will never allow anybody to manipulate me like that and I will speak out open and free words and withstand this dangerous epidemic political correctness.

Therefore, from me people still die and do not "pass away" (what a stupid term!) and they are victims of genocide and murder instead of "ethnical cleansing". Don't worry, this blog is not on politics but this is where one finds the most drastic examples of this mental sickness called PC.

Last technical aspect: I am dictating these texts with voice recognition, which is a very fast and efficient way to write down my thoughts but which often leads to being careless when proofreading the text. Also, English is not my primary language.