Laziness as a good thing

Lots of time I see people say they hack and hack at code until it “works”
But those accumulated hacks and patches can be troublesome down the road as you may not remember why you did something that way

And comments are, for the most part, obsolete the moment you write them.
And, unless you have some kind of enforced policy, either personally or corporately, they probably do not get maintained as code gets updated.

So how to avoid this situation where comments are useful and you cant read the code you wrote 6 months ago because you wrote it in a hurry and didnt bother with good names for anything ?

Quite honestly I find I like to be lazy.

By that I mean – slow down ! Take the time to do it once. And do it right. Or as right as you can make it at the time. Use long descriptive variable names. Give your methods good names. And then at least your code will maybe read more like english and actually self document the intent of the code.

Code you quickly hack together today and have to go back and decipher in a month or more does you no favours. In the long run having to revisit that code more than once will cost you both time & effort. And if it isnt carefully thought out you may introduce subtle side effects by making changes to your code.

Repeated studies have shown that the sooner to find and fix bugs and errors in code the less they cost to fix. Quickly written hacked together code is still early enough in the overall process that it can cost a ton to fix later (if you can fix it at all) Design flaws that arent caught can be horribly expensive to fix once a product rolls out – or worse cant be fixed without such a huge change that for all intents & purposes it will never happen.

My advice. Be lazy. Do it once. Do it right.

HTML still isnt a programming language

Some random guy writes he thinks it is. Whatever.

Build me an app in HTML.
NO CSS, NO JS. Those aren’t HTML
Plain jane old pure and simple HTML.

Oh but you say I can submit forms and – yeah to the SERVER that is served from. But then what ? The server won’t DO anything with that form or the data on it unless its running PHP or Java or something that can DO something with the data (even just stuff it in a file !)

HTML on its own can’t process data, make decisions (no if then else or select case) or DO much beyond show you data (text, images, etc) from whatever web server its served from on.

Lets go look at what the W3 schools has to say about it

HTML is the standard markup language for Web pages.

https://www.w3schools.com/html/

The HyperText Markup Language, or HTML is the standard markup language for documents designed to be displayed in a web browser

https://en.wikipedia.org/wiki/HTML


Note they do not say “programming language” – its a MARKUP language
The tags you insert tell a browser how to display things in bold underline lists etc etc etc

HTML describes the structure of a web page semantically and originally included cues for the appearance of the document.

It is structure and appearance. NOT behaviour. Thats up to a browser. Or maybe up to something else you add to a page that IS a programming language – JavaScript.

Yes HTML, CSS and JavaScript are usually used together

But on its own HTML is not a “programming language”

Still πŸ˜›

EDIT : as for the twitter replies lets just say that might hurt if the opinion were from someone that I respect. I dont. So no harm (no name calling required)
Next !

EDIT: if someone is looking for a job a & says they are a coder they better know more than HTML

Thanks to an astute reader

EDIT: Using nothing but html add two numbers and print the result πŸ˜›
Ready ! Set ! Go !

Numbers

Not the app. Just the crazy numbers of covid infections and such we’re seeing here.

I’ve been keeping track of the numbers on my own as the published numbers on the AHS site are spread around in a way they dont present a clear picture.

This is my graph lately

NOT GOOD

Heads up

Been getting weird reports from friends that Xojo 2021r1 isnt quite as “native” on M1’s as expected

If you do NOT install Rosetta the IDE runs – but you cannot debug or build anything

Poking around it appears the linkers, ld, ldarm and lld are all only built as x86_64 binaries meaning that you MUST install Rosetta for Xojo to be able to debug or build

EDIT : I wrote Geoff after I heard of this and said “someone should look into this ASAP”. The reply I got doesnt surprise me; nor impress me.

We are aware of this. We will be making the linker native but for now it requires Rosetta. This is rarely an issue because nearly everyone installs Rosetta anyway since they almost certainly have some software that requires it at this point. Linking is a tiny fraction of the run/build time at this point.

While I can’t tell you when, it is a priority to get the linker to be native and thus not require Rosetta.

EDIT II : I replied, as follows, quoting the press release

So this claim is not entirely true

With this release Xojo itself is native on Apple Silicon, as well as XojoScript and Worker, which builds native Apple Silicon helper apps. In the previous release from November 2020, native compilation for the Apple Silicon (M1) Macs was added, which made Xojo the first cross-platform development tool to support Macs with this new processor technology.

And I received another reply

We said the IDE, XojoScript, Worker and compilation are native. We did NOT say linking is native. That may be a distinction without a difference but it is what we said. Regardless, linking is a tiny fraction of the entire process. And for a lot of users, linking is an implementation detail. As I said we are working on making the linker native as well. But just to make the point even stronger, I wouldn’t add that as a bullet item for a release because for most users linking is an implementation detail.

A hair splitting detail since the press release makes it seem like the ENTIRE IDE is M1 native when its not. Were the linker a separate application, like it sometimes is in other tools, I could see splitting this out as a separate item. With Xojo, the IDE is editor, compiler, and linker all in one so saying Xojo is native leads one to assume that ALL components of it are. But that is not true.

I’ve asked they add Rosetta to the requirements pages JUST so no one is surprised.

EDIT III : System requirements page HAS been updated, 2021-04-04-02:09:22, to say

macOS Mojave (10.14) or higher is required to build for Apple silicon. See below for iOS requirements.

An SSD is recommended for best performance.

While Xojo itself (and the Xojo compiler) are native on Apple silicon, a small part of the build process still requires Rosetta to be installed in order to run/build apps when using Xojo on Apple silicon. You will be prompted to automatically install Rosetta if it is not present.

EDIT IV : While the requirements are “more correct” its not true that you will be prompted to install it if it is not present. Maybe that will come in a future version – but at the moment the reason this entire thing got started was because there was an error debugging & building ARM only apps from Xojo as they would fail with an obscure error about not being able to start the linker. The Xojo IDE does NOT prompt you to install Rosetta if it is missing.

If you get an error that looks like

know that this error is from the linkers NOT being native and so without Rosetta they will not work. Save your work. Quit the IDE. Install Rosetta and go back to work.

I do just wish they’d been more clear about this requirement

EDIT V : And now another user has experienced this

I still don’t understand what TIME has to do with this issue. The point is not that the linker takes milliseconds, or hours. It’s that, without Rosetta, it wont work AT ALL. Saying linking only takes a short amount of time isnt relevant in any way.

Does it work without Rosetta ? NO. End of story

EDIT VI : This is perhaps one of the most editied posts on my blog in the entire time its been up

The system requirements page has been updated. Again

Now it says

While Xojo itself (and the Xojo compiler) are native on Apple silicon, a small part of the build process still requires Rosetta to be installed in order to run/build apps when using Xojo on Apple silicon. You can easily install Rosetta if needed by pasting the following command into a Terminal:

/usr/sbin/softwareupdate –install-rosetta

Big or small portion isnt really relevant. Nor is how long this portion takes to run.

The entire app bundle is made up of several apps and some were not native. Period. Not fully native and Rosetta is required.

Everything else is hair splitting

A lack of symmetry

This thread illustrates some of the confusion people have with API 2

The documentation doesn’t help clear it up either since it says, quite clearly, that there seems to be a Boolean.ToString method.

I know this isn’t whats meant, but the writer of that thread obviously doesn’t.

Right now code has to look like

dim b as boolean = Boolean.FromString("true)
dim s as string = b.ToString

One line uses a parameter and the other doesn’t. One is defined in a module named for a type and the other isnt. Its a little unsymmetrical and hard to get used to because its not consistent. This confusion is what spawned the original posters post on the forum.

One way to fix this is to just tell people their code is wrong. Thats not likely to garner a lot of “Gee thanks” kind of responses though.

One way to fix this might be to just add operator_convert method to all the data types. But this then smacks of “variant magic” and isnt quite as explicit or obvious. But you could do something like

dim b as boolean = "true" 
dim s as string = b

Another might be to add to the Boolean module, a “ToString” method that takes a boolean as a parameter and returns a string.

Then code could look like

dim b as boolean = Boolean.FromString("true")
dim s as string = Boolean.ToString(b)

which also improves symmetry – except now you use a TO method and FROM method on one data type which is a bit verbose and not quite symmetrical. As well do you then need to add a TO and FROM method to every data type ? Thats a big pile of TO and FROM methods in every data type module.

Maybe this could be improved by putting additional FROM conversion methods in for String, Boolean, and the other data types. Then the code might look like

dim b as boolean = Boolean.FromString("true")
dim s as string = String.FromBoolean(b)

That way at least the conversions are more consistent and you use the data type name as the prefix to know what the conversion will return. A String.From will give you back a string from the passed type. A Boolean.From method will give you a boolean. And if all you have is From methods then its 100% consistent. Everything JUST has Convert From style methods.

Either way the current set up has issues because it isn’t consistent and it apparently confuses the very people who it was intended to help.

Why does this crash ?

A long while back I wrote a quick post about “if you need to crash your app” and how to

Perhaps you need to test some code that reports crashes back to you

Exceptions are easier to catch. crashes a bit harder but they happen

So I had posted a couple lines I got from Joe a zillion years ago

Dunno if anyone ever used them or needed them until recently. Of course it was asked on Xojo’s forums so I cant answer there but I did get the answer to the asker.

And now there is a follow up about WHY does this cause a crash ?

Well lets look at a crash log on macOS from it. on my machine an app with nothing but those two lines in the Window1.open event gives this crash log (I havent included the entire thing just the relevant portions)

Process:               My Application.debug [49041]
Path:                  /private/var/folders/*/My Application.debug.app/Contents/MacOS/My Application.debug
Identifier:            com.mycompany.myapp
Version:               ??? (1.0.0.0.0)
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           My Application.debug [49041]
User ID:               501

Date/Time:             2021-04-02 12:13:31.871 -0600
OS Version:            Mac OS X 10.15.7 (19H1026)
Report Version:        12
Bridge OS Version:     5.3 (18P54555a)
Anonymous UUID:        0F0B83EB-BB66-3337-7E31-C659E43657EB


Time Awake Since Boot: 440000 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [49041]

VM Regions Near 0:
--> 
    __TEXT                 0000000102f15000-0000000103064000 [ 1340K] r-x/rwx SM=COW  /private/var/folders/*/My Application.debug.app/Contents/MacOS/My Application.debug

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   My Application.debug          	0x00000001030483aa Window1.Window1.Event_Open%%o<Window1.Window1> + 122 (/Window1:49)
1   XojoFramework                 	0x00000001033b3d69 FireWindowOpenEvents + 231
2   My Application.debug          	0x0000000102f65f0c Window.Constructor%%o<Window> + 60
3   My Application.debug          	0x00000001030487cd Window1.Window1%o<Window1.Window1>% + 589 (/Window1:61)
4   My Application.debug          	0x000000010304e02a _MakeDefaultView + 106 (/#main:57)
5   My Application.debug          	0x000000010304e28f _LateStartup + 79 (/#main:90)
6   XojoFramework                 	0x000000010321ed1d CocoaFinishApplicationStartup() + 185
7   XojoFramework                 	0x000000010321d97f 0x103134000 + 956799

That this causes a segmentation fault isnt entirely surprising
But why does it do that ?

Well when we start the Ptr is uninitialized. So its DEFAULT value is 0.And then we try to write to offset 0 what this tries to do is WRITE to offset 0 from address 0 of the application and this is NOT permitted.
And so we get

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)

which in THIS case is an attempt to either READ or WRITE to a READ ONLY portion of the application. Most modern processors support this kind of low level protection to protect against malicious software that would modify itself in memory to do harmful things AND avoid detection since what is on disk isnt what being executed.

In this case the ptr is nil (or 0) and trying to write to a ptr that points at 0, or NIL, fails spectacularly.

In fact the relevant code could also be

dim p as ptr
dim i as integer = p.Byte(0)

and it will crash – again because trying to read or write to address 0 fails spectacularly

Hiding your insides from the rest of the world

Xojo has no “friend” scope (see https://www.ibm.com/support/knowledgecenter/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr044.htm)

In other words there is no way to indicate that one class or method can call the protected / private methods of another class. Either the methods are public, and any other code can use them, or they are protected so only the class & subclasses can use them, or private and then only that class can access them.

Sometimes you want “friend” so other classes in a related set of classes can call the protected methods of the other classes in that same set.

I know this all sounds a bit theoretcial but imagine you write a PDF Document Class. And that PDF class has other classes that make up the contents of the PDF – things like PDF Page, and PDF pages might have PDF Text Objects, PDF Graphic Objects, etc

And there could be reasons that a PDF document needs to be able to use methods from PDF Page – but you dont want those methods exposed to every other bit of code in anyones project.

So how do you hide those details from code ?

If all you do it put all the PDF classes ina folder in Xojo then that wont suffice. Folders have no effect as far as the compiler is concerned.

What if you put everything in a module and make all the classes in that module global ?

That would still leave every public method usable and callable by any code.

But, here’s the trick. You CAN put an interface inside the module.
And that interface can be PRIVATE. This means that ONLY classes and code IN the module can access that interface.

And, since interfaces CAN be satisfied using PRIVATE methods you CAN then implement the interface with private methods.

When you combine these two things you get a way for all the classes & code in the module to call the private methods of the classes in the module by casting to the private interfaces and NOTHING outside the module can access them because they can use the private interface, nor can thy directly call the private methos of the classes.

“Friend” scope might still be nice though

The technique outlined only lets you handle hiding within the scope of a single module and if you needed this to work between two separate modules you’re unlikely to find quite such an elegant solution.

Friend would make that much more possible.

Feels good

Took a few minutes last night and helped out another member of the Xojo world.

Seemed like he was a bit stuck and what I pointed out got them back on track.

And then I got several messages :

Norman, you are a FUCKING treasure to this community.

Nobody tries to help as much as you do.

Nobody I’ve ever worked with.

I wont name names but it IS nice to get feedback like this πŸ˜›