Style Question - setting a value into another guy's table

Possibly it is, @Ignatz, though it’s a pretty flimsy hook upon which to hang the class hierarchy. And there are other schemes, such as mix-ins, that might be applicable, though I’ve not looked to see if anyone has written much about that sort of thing in Lua.

I am inclined to think that if there is a common dead flag it should be explicit in the code in some say that’s more visible than random bits of code injecting flags into random objects’ tables. It’s tempting to do the random injection just to see what goes wrong. :smile:

@RonJeffries this is a fascinating discussion, but could you tell us more about what your solution would look like?

I am inclined to think that if there is a common dead flag it should be explicit in the code in some say that’s more visible than random bits of code injecting flags into random objects’ tables.

Is this possible in Lua? Aren’t all Lua “interfaces” very easy to break?

Of course they’re easy to break. That’s not the same as coding to break them.

The idea from my buddy was just to jam a dead flag into all the drawn objects, without them knowing, and then to use it. To do that willy-nilly leaves open the possibility that someone (me, in a forgetful moment) would put a dead key in the object from the inside, and then either the outside usage or the inside, or both, would break.

In addition, this would be a violation of the “Law of Demeter”, which is an OO principle also sometimes called “Tell, don’t ask”, meaning that you should favor objects owning and dealing with their own state, over asking them questions and then doing things with them without their collaboration.

One alternative is to provide functions or methods up at the top to add objects to, or remove them from, the “universe”, and when it is time to consider collisions, send messages to (call methods on) the objects, allowing them to decide what to do. If they want to ignore collisions, as a Button might, they do so. If they think they’ve collided and died, they might request to be removed from the “universe”. Or they might do other things.

Either way, there is an interesting issue to be resolved: in principle, you’d like to consider A and B colliding only once, but there’s no really nice way to get all pairs of objects in a collection and process each pair only once. (And an associated concern is which comes first. Since the objects are in no particular order you might get a Ship and a Missile one time and a Missile and a Ship another time through the loop. Looping naively you absolutely will see Ship1 vs Missile1 and Missile1 vs Ship1, so you need to do something to treat that as only one collision.

The basic thing one does is to move responsibility to the object that “should” have that responsibility. The “universe” seems like the right place to consider pairs of objects, and the Ships and Missiles seem like the right guys to decide what to do when they’re in range of each other.

It’s an amusing problem. :smile:

As for the fact that all interfaces are easy to break, well, sure they are, but one programs to make that unlikely, according to my lights, although other people are more comfortable spinning out code and then debugging it. I have come to find any debugging at all to be a sign that I didn’t know what I was doing when I wrote the code. :smile:

@RonJeffries - in defence of us humans, research has shown that we make errors at the rate of about 2-5% in all cognitive work such as programming, and that this applies no matter how careful or experienced we are.

That’s because we have evolved to be “near enough” rather than totally accurate, which gives us a faster reaction time. But it messes up the precision of our programming.

Even with the best agile or other methods, there will still be errors and omissions. I think of the spacecraft that missed Mars because the program written by British people sent instructions in metres to a US written program that expected inches. Or the spacecraft returning with comet dust that slammed into the ground without opening its parachute, because its ground detection system had been installed upside down. There’s always a way to make mistakes. Just look at all the aircraft and (mostly covered up) nuclear accidents.

So some debugging (and peer checking, because research also shows we cannot reliably eliminate our own mistakes) is always likely to be necessary.

I think the best example is the space shuttle software. It was written using the most exhaustive checking process, and when it was done, they used the same software (and hardware to support it) for about 30 years, because they couldn’t face going through that process again.

I worked with (thousands of) spreadsheets over 30 years, and I found exactly the same to be true there…that’s why I researched causes of error, because we needed to improve spreadsheet quality in my firm - and I found it fascinating.

One alternative is to provide functions or methods up at the top to add objects to, or remove them from, the “universe”, and when it is time to consider collisions, send messages to (call methods on) the objects, allowing them to decide what to do.

Are you describing an entity-component-messenger system, like the one here?

http://gameprogrammingpatterns.com/component.html#how-do-components-communicate-with-each-other

@Ignatz yes, there will always be errors. and there is some injection rate that is more or less constant. The question becomes: how quickly do we find them. When we don’t discover that there’s a bug until after weeks of work, debugging takes a long time because it’s not clear where the bug is, and fixing takes a long time because the changes become extensive.

If we could work in such a way that an error showed up within minutes of making it, errors would be easy and rapid to fix: there’d only be a few lines of code to look at.

And it turns out we can work that way. Techniques like TDD make a huge difference to the number of defects that are actually shipped. It is not at all uncommon with good Agile teams to ship one or two bugs a year. Often these same teams were shipping hundreds not that long before.

Causes of error are interesting. The trick is to do something about them. Prevention is sometimes possible. Detection and rapid fixing is, as far as I can tell, always possible.

@yojimbo2000 what i’m talking about is not dissimilar than what the article talks about. i’m not sure i agree with everything being said there.

To me, it all comes back to concerns of cohesion and coupling, which have been around for a half century or more. On the surface, it would seem that cohesion and coupling would trade off, better cohesion leading to more coupling and the opposite.

In practice, people often get cohesion very wrong, putting ideas that belong apart in the same object or module. In that case you can improve both cohesion and coupling at the same time.

One thing that I try to do is to build a good design – evolve one, really – and then if there is a performance reason to tie things together more tightly, back away from good design in the direction of performance, as indicated by measurements.

Of course the question “what is good design” arises. Answering that is beyond our scope here. After doing software for over a half century, sometimes I think I have a bit of a handle on it, though. :smile:

I think the issue here is that Lua doesn’t really do interfaces. I think though that if you have a convention, eg of beginning “private” variables with __ then it’s fairly unlikely that you’ll accidentally overwrite the variable (Codea’s autocomplete should prompt the names of the class’s variables too). So the class’s init would contain self.__to_be_removed = false or whatever. I don’t see that there is a whole lot else that you could do within Lua.

I’m trying to work on OO principles as much as I can, but find I frequently break the rules too.

This discussion reminds me of a youtube vid I recently saw about the strict OO aproach. It’s a bit provocatively named but it does a nice job of setting out the problems when following any principle too strictly.

https://m.youtube.com/watch?v=QM1iUe6IofM

It is a bit wordy, but you can skip to the meat of the message somwhere around 15:50 minutes in. I found it helpfull in structuring my own thoughts about this complex subject matter.

quite interesting, thanks!
He advocares long fonctions, rather that many small ones. But he doesnt emphasizes the testing problem: testing small functions is easier that testing a long one. Specially when you want to change parts of it afterwards.

@Jmv38 +1

I watched all 45 min of it. I can’t say I agree or disagree with what he says. Over my career I’ve been introduced to a lot of different styles. The way I see it, write your code using whatever style is comfortable for you and what you need to accomplish. I have no problem with long functions, but the ones I hate are the ones where the code indents to the right, back to the left, back to the right, etc.

That is exactly how I feel about it, I don’t particularly agree or disagree with anything said there, it really depends on the situation.

But I liked the refresher and the detailed review of the problems we face when choosing any aproach.