Go Down

Topic: Arduino the Object Oriented way (Read 29858 times) previous topic - next topic

PaulMurrayCbr

That said, I always have the feeling that OOP is bolted onto C as an afterthought.
You are absolutely right - it was. C++ was originally a preprocessor that generated C, back in the day. I learned C back in '85 from the K&R blue book - no fancy objects and constructors back then. Likewise, closures and streams are bolt-ons to Java. Things change.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

Camel

C++ is certainly not 'C with extras' any more. Modern C++ features such as ranged loops, lambda functions, auto type deduction and so on really make C++ a high-level language without really sacrificing much, if anything, in terms of performance.

Robin2

You're opinions are just as valid as the next persons.

I'm not criticising you personally,
When you use the words "Yes Robin, we have all heard many times" and "Your very biased attitude" it is hard to escape the feeling that the comments are personal, and will be seen as such by others.

It would not have been difficult to say "I disagree with XX and I prefer to do things YYY"

I am quite happy to accept that there is no personal animosity.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

westfw

Quote
In justification: the arduino is a 16-bit processor
No, it's an 8 bit processor (except for the ones that are 32bit processors.)



Quote
Modern C++ features such as ranged loops, lambda functions, auto type deduction and so on really make C++ a high-level language without really sacrificing much, if anything, in terms of performance.
I'd like to see an Arduino example using one or more of those.  An awful lot of the time, for C++ programmers, "no performance sacrifice" means "if your actual data was 1MB, encapsulating it all in a useful and elegant C++ container only adds another 100k, and obviously 10% is not very significant" rather than "the object overhead fits in 2k with plenty of room for actual data."


msssltd

Don't know if it's any use to anyone, but I'd like to hope so.
As an OOP tutorial held up to novices, the article is highly opinionated, dubious even, in places.

Especially.
  • Neglecting to mention the cost of OOP.
  • Overuse of private properties
  • brightnessClicker 'should' [not] be a property of headlamp - Breaks the MVC pattern.
  • Calling millis() repeatedly
  • Blocking a refresh method for 800,000 clock cycles.


"The problem is that there are then two places [where a click is started]"
The redundancy can be reduced logically, by sticking to a read/modify/write pattern.

I see no tangible benefit in the Runnable class.  As such, the class adds unnecessary complexity, consuming RAM and clock cycles needlessly.

Personally I would not call simple inheritance polymorphism, even with virtual functions - It's simply, inheritance.   Multiple inheritance and overriding methods, would be examples of polymorphism, to my mind.

"It's called 'time-slicing'"
No, not really.  Time-slicing is an established term, which implies pre-empting, by a scheduler.


As a set of notes documeting your thought process, I think the article is great.

"Writing this stuff is much quicker and easier than writing about it."
On which, we are in full agreement.



pYro_65

#20
Dec 29, 2015, 05:46 pm Last Edit: Dec 29, 2015, 05:49 pm by pYro_65
Personally I would not call simple inheritance polymorphism, even with virtual functions - It's simply, inheritance.   Multiple inheritance and overriding methods, would be examples of polymorphism, to my mind.
Using virtual functions is by definition polymorphic behavior. The derived class is overriding the virtual functions declared in the base.

If you were simply extending another class by using it as a base and adding further functionality in the derived class, then its just simple inheritance.

The write up is not bad, but I think the examples could be far simpler. The functionality inside the classes is going to draw attention away from the actual points the article is trying to explain.
Forum Mod anyone?
https://arduino.land/Moduino/

PaulMurrayCbr

As an OOP tutorial held up to novices, the article is highly opinionated, dubious even, in places.
Agreed. It's my opinion, it's the way I write things, it's a specific way I use OO with arduino (specifically: giving everything a setup and a loop). Maybe I should put a caveat to that effect towards the beginning.

Especially.
  • Neglecting to mention the cost of OOP.
  • Overuse of private properties
  • brightnessClicker 'should' [not] be a property of headlamp - Breaks the MVC pattern.
  • Calling millis() repeatedly
  • Blocking a refresh method for 800,000 clock cycles.

I don't see what's wrong with making things private.

And it doesn't make sense to complain that OOP is expensive, and to be peevish that I don't use MVC everywhere. Yes, you can do make event queues and whatnot that malloc space for event objects. Not worth it. And in any case, I state repeatedly that this sort of stuff is not suitable for anything where cycles are important.

As to not making brightness clicker part of headlamp by direct composition - I just disagree. It's a fine way to do (some) things. Direct composition doesn't in itself break MVC. If this sort of composition does break MVC and composition by reference doesn't, isn't it a little odd that the syntax and method calls you need to make are otherwise identical?

Not sure that calling millis() repeatedly is a problem. How much work is it, compared to passing it around on the stack or leaving it in a sketch-scoped variable? I would have thought that millis() talks pretty directly to the chip somewhere, straight to a hardware port.

I used to take millis() once and pass it into the loop() for everyone, but eventually decided that the whole point is that these things shouldn't need to synchronize.

Quote
"The problem is that there are then two places [where a click is started]"
The redundancy can be reduced logically, by sticking to a read/modify/write pattern.
Yes, my code doesn't strictly adhere to a pattern. I like using an enum for states and having a loop that is strictly that switch statement and nothing else.

Maybe I should pull out and make explicit that some methods are smalltalk-style 'messages' intended to be called by other things, that they comprise an interface to the object.

Quote
I see no tangible benefit in the Runnable class.  As such, the class adds unnecessary complexity, consuming RAM and clock cycles needlessly.
Well, there are intangible benefits to it. Helps clarify what you are doing, I think. Actually, the real reason is that Runnable and its automatically-populated queue in effect provide a higher-level framework than the sturdy old setup() and loop() methods on their own.

Quote
Personally I would not call simple inheritance polymorphism, even with virtual functions - It's simply, inheritance.   Multiple inheritance and overriding methods, would be examples of polymorphism, to my mind.
Perhaps I need to point out that the benefit of the polymorphic button class is that you could write a class that does something different on a long click and short click, and that you wouldn't need to rewrite the "debounce/short/long click" logic again.

Quote
"It's called 'time-slicing'"
No, not really.  Time-slicing is an established term, which implies pre-empting, by a scheduler.
Wikipedia agrees. What do you call multitasking by way of yielding control, then? Actually, I'll ask wikipedia. … Hmm, "co-operative multitasking" seems to be the thing to call it.

http://paulmurraycbr.github.io/ArduinoTheOOWay.html

westfw

Quote
"co-operative multitasking" seems to be the thing to call it.
Also "Run to completion scheduler."


Robin2

#23
Dec 30, 2015, 11:53 am Last Edit: Dec 30, 2015, 05:29 pm by Robin2
I have been a fan of OOP ever since I came across Smalltalk many many years ago - at a time when I could not afford the compiler.

Alas IMHO this discussion has evolved to neatly illustrate a big problem. The people who know OOP can't resist talking about it in technical terms that make it completely inaccessible to beginners.

I do realize that (for example) the engineers who design a motor car need to know a great deal of technical stuff that the average car owner does not even know exists. But the beauty of cars is that their user-interface is easily understood and is the ONLY thing that 99% of the users are aware of.

I also realize that this Forum is used by programmers (the equivalent of the car design engineers) and it is natural that they should converse among themselves in technical jargon.

What is missing here, however, is the layer provided by the marketing system in the motor industry which effectively isolates the user from the engineering jargon.

If @PaulMurrayCbr's contribution is to be useful for newcomers (as I think was the original intention - at least, for newcomers to OOP) then it seems to me there needs to be scope to present it separately from the technical discussion that has been taking place in this Thread.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

msssltd

@pYro_65
Using virtual functions is by definition polymorphic behavior.
Fair comment.

Quote
The write up is not bad,
It's not bad but it's not good either.

Quote
I think the examples could be far simpler.
Agreed.  I started skimming when I got to the tail light.  I think few would read so far, unless they were building exactly the same project.

@Robin2
Quote from: Robin2
The people you know OOP can't resist talking about it in technical terms that make it completely inaccessible to beginners.
When someone says, this is how it should be done, when in truth, this is how it could be done, you are going to end up with a technical discussion.

Quote
What is missing here, however, is the layer provided by the marketing system in the motor industry which effectively isolates the user from the engineering jargon.
Disagree.  What is missing here is technical critique and peer review.





msssltd

#25
Dec 30, 2015, 03:25 pm Last Edit: Dec 30, 2015, 03:26 pm by MattS-UK
Agreed. It's my opinion, it's the way I write things, it's a specific way I use OO with arduino (specifically: giving everything a setup and a loop). Maybe I should put a caveat to that effect towards the beginning.
What you do is not a million miles from what I do.  A caveat is an excellent idea.

Quote
I don't see what's wrong with making things private.
As you say in your comments,
    // make these slow for testing
If you can think of a need to change the values, the properties should not be private.  Further, private properties block inheritance and code reuse, which can be very frustrating.

Quote
And it doesn't make sense to complain that OOP is expensive,
I'm not complaining.  Abstraction costs RAM and clock cycles, it's a fact.

Quote
As to not making brightness clicker part of headlamp by direct composition - I just disagree. It's a fine way to do (some) things. Direct composition doesn't in itself break MVC. If this sort of composition does break MVC and composition by reference doesn't, isn't it a little odd that the syntax and method calls you need to make are otherwise identical?
I think it odd that a second instance of headlamp comes with a second instance of brightnessClicker - That would be the proof of MVC being broken.

Quote
Not sure that calling millis() repeatedly is a problem.
Concurrency is, or could be, the problem.

Quote
Yes, my code doesn't strictly adhere to a pattern.
I don't have a problem with your code.  I am contending your use of 'should' and 'of course.'  MVC is about the most common hardware control rationale out there.  OOP can make MVC implementation much easier.  The onus would be on you to explain why MVC 'should' be ignored.  Alternatively, you could mention it exists and point out your example is too trivial to warrant strict adherence.

Quote
Well, there are intangible benefits to it [the runnable class].
On an 8 bit micro?  No, I don't think there are any benefits, intangible or otherwise.  Art for art's sake.  Complication for complication sake, in my opinion.

Quote
Hmm, "co-operative multitasking" seems to be the thing to call it.
I almost called it co-operative tasking.  I very deliberately did not call it multitasking, of any kind.



Robin2

Quote
What is missing here, however, is the layer provided by the marketing system in the motor industry which effectively isolates the user from the engineering jargon.
Disagree.  What is missing here is technical critique and peer review.
Disagree. What you have said is correct. But it is quite different from the needed separation between users and developers - for the benefit and convenience of users.

In my experience it can be very difficult to get developers (in any field) to appreciate the very different perspective of users.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

msssltd

Disagree. What you have said is correct. But it is quite different from the needed separation between users and developers - for the benefit and convenience of users.
Reading the article infers one is, or wishes to be, a developer.  Hence, I believe the issue is one of education and not separation.  My point would be, materials offered up as being educational, need to be technically correct.  Matters of opinion maybe unavoidable but they should be clearly delineated, from matters of fact and established, expert consensus.

I completely agree the conceptual language, which sometimes obscures OOP, should be kept to a minimum within introductory tutorials.  However, I see no reason to avoid the terminology, during review of such articles.  I am aware of the, not in front the children, school of thought but I do not agree with it.

Quote
In my experience it can be very difficult to get developers (in any field) to appreciate the very different perspective of users.
Careful with that stereotype, Eugene ;)



pYro_65

#28
Dec 31, 2015, 12:27 pm Last Edit: Dec 31, 2015, 12:28 pm by pYro_65
Modern C++ features such as ranged loops, lambda functions, auto type deduction and so on really make C++ a high-level language...
I'd like to see an Arduino example using one or more of those.  An awful lot of the time, for C++ programmers, "no performance sacrifice" means "if your actual data was 1MB, encapsulating it all in a useful and elegant C++ container only adds another 100k, and obviously 10% is not very significant" rather than "the object overhead fits in 2k with plenty of room for actual data."
The items mentioned by Camel have little to do with container classes. They are just features in C++11, that containers can of course use.

Here is an Arduino based example that contains a ranged loop and auto type deduction. It also uses one of my 'container' classes called BitBool (in library manager).

This example provides a more efficient method printing binary than provided by the core. And it can be used to print 64bit binary which is not even implemented in the core (max 32bits).

The code to use it is very simple, and its quite efficient.

Code: [Select]

#include <BitBool.h>

void setup() {

  uint64_t data = 0xAABBCCDD00112233;

  Serial.begin(9600);
  Serial.print( "Printed as binary: " );

  auto &bits = toBitBool<REVERSE_BOTH>(data);

  for( auto bit : bits ){
    Serial.write( '0' + (bit ? 1 : 0) );
  }
}

void loop() {}


As for lambdas, they can be viewed as simply functions that you can declare inline, or inside another function.
Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

Careful with that stereotype, Eugene ;)
Genuinely don't know what you had in mind when you wrote that.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up