To recap I have already written four blogs regarding my notes whilst reading this book.
And just to be clear, this is the book we are talking about: –
And this is how to avoid Huge Ships: –
I had heard of TypeScript, but I had no idea at all what it was.
If you pass a string into a variable, then that variable is now a string type. In the next line you pass an integer into that same variable, the variable is now an integer type. In the same way you can pass a string, or an object, or anything at all, into a parameter that really was intended to receive an integer.
This is not an accident; it is not like building a house and then forgetting the gaps for the windows and doors. This design was 100% intentional, I am sure that presumably there is some enormous benefit in having an untyped language, even if I cannot see what it is. I am probably blinkered by having spent so long programming in strongly typed languages.
Some people do not think that way (untyped is good) however. A lot of people say that strongly typed languages like ABAP are far better because – for example – you cannot pass a string into a parameter that is expecting an integer. In FORM routines in ABAP, you could have untyped parameters, but you got a warning. It was worse in function modules, you would get a dump if you passed in the wrong type of value, but the static syntax check did not warn you. In methods you must type your parameters. Typing your parameters avoids dumps at runtime which cannot be detected statically.
It seems to be full of translation errors (German to English) but that does not matter in the grand scheme of things, and I report any I find to SAP Press.
One thing in the Clean UI5 book, right at the start, cleared up something that had been bothering me. That is, the keyword CONST. I had presumed this to be equivalent to the ABAP keyword CONSTANT.
In ABAP the IS_INSTANCE_OF construct is a bit naughty as it is a violation of one of the SOLID principles which says the caller should not need to know or care about the concrete class of the object being processed, so long as it can do the job at hand.
One interesting thing is that if you have GET/SET methods for object attributes then I think (and this is a guess even after reading two descriptions of this from two books) every time you read/write to/from the variable in the code then the getter/setter is called implicitly.
Here is the next big difference from ABAP – at runtime you can add new attributes or methods to an object definition, or indeed remove existing ones. This is veering towards LISP where code is the same as a variable, that is the definition of the code can change as the program runs. That was supposed to make AI possible – that is the way you think can change over time, when faced with new data, so why not make computer programs work the same way? That was the idea, it does not seem to have worked too well until now, when it could be argued it is working far too well, with things like ChatGPT telling big fat lies because that is what humans do.
Because of this dynamic behaviour it is very difficult to do a syntax check – that is in one line you delete an attribute from an object, in the next line you try to read that attribute, there is no syntax error you just get an “undefined” value.
FOR goodness’ sake, I’ve got the Hippy Hippy Shake
I hit the jackpot the other day. In train stations you have a book exchange type of thing, and whilst waiting for the train to work I found a computer magazine from about 1981 which had a review of both the ZX81 and the VIC-20. The former got a thumbs up, the latter a thumbs down.
I don’t find UNSHIFT() a very intuitive keyword – it means add records at the start of an array. I will say the examples in this book are very good because they are not generic – instead of manipulating values like A, B and C, the array example is a to-do list with tasks like mowing the lawn, which makes things a billion times easier to understand.
On the Good Ship Lolly POP()
Have you ever tried to debug ME21N? It is agony because most of the code are calls to PUSH() and POP() methods with no code that seems to do anything. That seemed to be to be trying to replicate how things work in other languages just for the sake of it. SAPMV45A is much easier to debug, even if the technology is archaic. In the end, a program needs to be easy to debug and that simulated PUSH/POP thing in ABAP just does not cut the mustard.
Hurry up ARRAY
I had written “Oh Dear!” next to a box which said that if you call an ARRAY() constructor with one argument then that becomes the length of the constructor, but if you call it with two arguments, than the length becomes two and the contents are the two arguments. I am starting to see why the clean code people do not like optional parameters in methods.
There are a whole bunch of methods that can be used to manipulate and read arrays, far, far, more than the internal table equivalents in ABAP. Some of these have made their way into the ABAP language in recent years like REDUCE or to be able to loop through a table backwards or just read every fifth record of an internal table (never found a use case for that one either).
Out of SORTS
It is claimed no other language can do anything remotely similar, but I suppose the nearest equivalent in ABAP is when you define a custom ASSERTION via an interface and then during a unit test and pass that in.to CL_ABAP_UNIT_ASSERT=>ASSERT_THAT as a “custom constraint”.
The concept of a “stack” is very simple – an array where the last value in is the first value out, but as I have said when I have seen this implemented in ABAP (as in ME21N) it is somewhat horrific. You just do not need it in ABAP so jumping through hoops trying to replicate this and therefore making the code impossible to understand/debug seems a not very value-adding task.
In the JS book there was a generic example with A, B, C, E etc. as the values and then a practical example where you have a series of actions, which if the transaction is cancelled have to be reversed in order. Guess which example I liked best?
Here is something that will make an ABAP persons head spin. The reverse of a stack is a QUEUE (First in, first out). You add an element using the keyword ENQUEUE() and remove an element using DEQUEUE(). Apparently, this is normal in all non-ABAP languages, but as we know in ABAP those terms have a very different meaning.
I am wondering if any of these array types have the equivalent of the ABAP SORTED or HASHED concept to improve performance. They might have, but it is not mentioned.
MAP the Knife
Now we move onto a sort of array which is a KEY/VA:LUE pair and is called a MAP in other languages. There are lots of ABAP structures and table types like this, one is used in Web Dynpro quite a lot by Fred Flintstone. He loves Web Dynpro. In SAP configuration tables often do this sort of thing, as do “constant interfaces” so you have a meaningful name like BANANA against a value like 5.
Wrong Plaice makes things Fishy
There was a huge section on the destructing of arrays and especially objects, and the more I read the more confused I got about why you would want to do such a thing, that is, create a bunch of variables to mirror the object attributes. Right at the end of this huge section was a box saying do not do any of the above, it is far better just to access the object attribute. That is correct, but I think the warning should be at the start of the section as in – I am going to explain how to do something but DO NOT DO IT. That is what I do in my book regarding TEST_SEAMS in ABAP which are an abomination. The warning should not be in a box as often people do not read boxes, and it should be at the start because people might stop reading 90% of the way through, move onto the next chapter and not realise they had just read a giant explanation of what NOT to do.
Then we have a suggestion to make the code more compact by shortening the variables down to one letter e.g. “l” instead of “lastName” by which I wrote “No, just NO!”. I am not a huge fan of one letter variables name, no matter what the context.
Then you have two almost identical named functions SUBSTRING and SUBSTR which sometimes behave the same as each other and sometimes behave differently depending on what you pass in. That must confuse newcomers to the language.
I will say that “toLowerCase()” is a better name than “TO_LOWER”. People have a go at ABAP for being too verbose but in my mind the whole point of fourth generation languages is to read as much like English as possible as opposed to machine code, and if you suddenly start truncating things or move from ADD 1 TO COUNT to COUNT =+1 then that is a huge backwards step, and it always reminds me of “Newspeak” in the novel “1984”.
No SETS please, we are British
A SET is liked a hashed table in ABAP – that is, the array entries have a unique key and there cannot be duplicates.
We all live in a Yellow SY-SUBRC
All us ABAP types know that when it comes to SY-SUBRC the value of zero means TRUE (success) and the value of 4 means failure (FALSE). In fact, usually any value other than zero means FALSE. All well and good, but that is not very intuitive, especially as in many languages 0 means FALSE and 1 means TRUE, and every language apart from ABAP has a true Boolean data type. Why it is so difficult to add such a thing to ABAP if every other language has managed it? SAP would argue the 54 million different data elements with BOOL in their name can do the job, but it is not the same.
As a final point in the book at the end of the huge section of arrays there is an example where six constants are declared, each one the name of a singer or group, and then the first five are added to the array (WEAK SET) and not the sixth value, and then when you try to see if the sixth value is in the array it is not there, and of course it is not there, because it was not added. I struggle to see what this example is trying to tell me.
Measles, Scarlet Fever, and MONTHS
I may have said I find the USA date system crazy i.e., MM/DD/YYYY which is a random series of values as opposed to ascending DD/MM/YYYY or descending YYYY/MM/DD. But at least in the USA system January has the value 1, and December has the value 12, which is what I hope anyone would reasonably expect.
Two things about that
- Even if that is how lists are stored in arrays, that is, first value has the index 0 rather than 1, that is not how humans think about the months of the year.
- But even if you are going to do that, why not be consistent and do it for the dates as well, that is have the first day of the month as zero, if the first month of the year is zero?
With minutes and seconds that makes sense, as a human would never say the time is 14:60:60, they would say it is 15:00:00 even if the two values represent the exact same point in time. So GETMINUTES and GETSECONDS start at 0 and end at 59 that is fine by me.
I now have a hundred pages of the “Clean UI5” book I have made notes on, but it is probably best not to mention any of that here, as that would muddy the waters.
End of Part Five
New Orleans, here I come!