How is it flawed?
Perhaps you just don't understand how it works?
"other" isn't a variable, it's a keyword and it behaves exactly like a constant with value -2.
Whenever you write other.varName, it gets replaced by -2.varName and this is left to the executing instance to interprete.
How it will interprete this, is by looking if the code it's executing is called by a with structure.
If so, it will look for the variable in the instance that called the with structure.
Otherwise, it will look for the variable in itself.
The reason you can use other in collision events is because you can treat collision events to be internally called through with structures in GameMaker:
Code:
// Collision event of obj1 with obj2
// This happens inbetween the step and end step events
// It is a simplified version though, as e.g. solid behaviour isn't taken into account
with obj2
if place_meeting(x, y, other)
with other
event_perform(ev_collision, obj2);
Now that that's explained, it would actually be counter intuitive if functions (and scripts) could set the value for "other".
This means that every time you execute a function, you can expect "other" to be something different and not necessarilly useful.
For example, someone creating a script could use collision functions and forget that they change the value of "other", leaving the value of "other" on something undefined,
which can cause various bugs that are hard to find.
Meanwhile, those functions could have just returned their result (what you think "other" should contain) and left the GameMaker user with more control and cleaner code.
This is the way GameMaker does its collision functions and it is the way it should be done.
Now, as to why every DnD action has an option to select "other", it's meant to use in collision events
to e.g. destroy the colliding instance or to subtract hp from it (letting both instances do this themselves can cause synchronisation issues, as the destroying might happen first and dealing damage might never happen).
Other does get "filled" when using "with structures" or collision events.
And on a final note, making other not be a constant would actually take away functionality,
as you can now do everything it could do otherwise by using (other.id).varName
and you can do more by saving special references in datastructures for example.
The only unfortunate thing, is that you can't stack multiple "other"s like this: other.other.varName.