Commands have no return values (except maybe through a macro).

Yup, that's how I've always viewed the differences.

Almost all commands (other than language intrinsics like flow control statements) should IMO be functions.

Ok, so maybe you are not interested if something like Sleep fails (though maybe you should be) but you almost certainly are interested if MD, CD, DEL and so-on fail. @ERROR is set so that you can determine success, but for language consistency you might reasonably expect to be able to do "If Not MD('c:\temp\mynewdir')"

KiXtart is full of odd language anomolies, introduced as it has been developed. "GetS" is a command, but "ReadLine" is a function. "Del" and "Move" are commands, but "SetFileAttr" is a function.

I'd guess that the strange syntaxes are for early commands which emulate DOS batch commands. They have persisted because of backwards compatibility.

I'm sure if Ruud started KiXtart again, we would have "$Input=GetS()" rather than "GetS $Input". It would certainly make the parser simpler