Why are some people cautious about using sender() in Qt programming? The typical answer is that it violates the principle of modularity of code. From the Qt documentation about pitfalls in PySide:
If you want to get the object that emitted a signal, you can do so
using QtCore.QObject.sender(), although you should really think twice
before using it (see the API docs of QObject for details). If you
really, really decide that you have to use it, be aware that right
now, you cannot call it as a static method, but only from within a
QObject slot.
As a new PySide programmer, I wouldn't consider using sender in anything but a slot, so the second concern seems almost moot.
The first reason suggests examining the API of the doc. Let's look at that. From the API docs for sender:
This function violates the object-oriented principle of modularity.
This caveat is also mentioned in Summerfield's book on PyQt, where he writes
Some programmers don’t like using sender() because they feel that it
isn’t good object-oriented style.
That's all he says.
What makes sender particularly non-modular compared to the rest of the standard practices in using PyQt/PySide/Qt? In PySide we are constantly invoking things like internalPointers in our model/view frameworks, or sneaking arguments to use in methods by making them attributes of self (effectively treating them as global variables). These and other such practices seem to technically violate modularity, and seem to be ubiquitous in GUI programming.
So why do people think sender deserves to be singled out as especially worrisome wrt modularity? Or perhaps equivalently, what is so modular about Qt programming anyway?
Overall, sender seems like an extremely useful, simple method. It is easier to use and teach others to use than things like partial functions or lambda expressions or QSignalMapper. So I can see the upside of using sender, and frankly have little grasp of the downsides that have merited their inclusion in official Qt documentation.
Generally speaking, an object's slot can be invoked by no signal at all, or by any compatible signal. In the former case, there is no such thing as a sender - for example, when using QMetaObject::invokeMethod. When the slot is activated through a signal, the sender object can be of any class. The most you can expect from the sender() is that it is-a QObject, if it is anything at all.
The signal-slot mechanism is designed to decouple objects, but by depending on the sender() you're reversing this and are coupling to the sending object. This has some applications when such coupling is expected by design, say when you implement a widget hider, or when you want to taylor the slot's action to the particular instance of a related object. Outside of such limited circumstances, where coupling-by-design is desirable, the use of sender() indicates bad design and coupling for no good reason.
The documentation merely means that you should understand the purpose of the signal-slot mechanism and the benefits of decoupling in software design before you choose to introduce coupling into your design.
Lambda expressions in fact completely obviate the need for the sender() and QSignalMapper, so you are arguing against yourself there:
connect(foo, &Foo::aSignal, [&foo]{ foo.method(); });
// as opposed to
connect(foo, &Foo::aSignal, [&foo]{ qobject_cast<Foo*>(sender())->method(); });
// and also
QList<QPushButton*> buttons;
QPointer<QLabel> label;
for (int i = 0; i < buttons; ++i)
connect(buttons[i], &QAbstractButton::clicked, [i, label] {
label->setText(QString("Button %i was clicked.").arg(i+1);
});
On another note, the reasons for QSignalMapper's existence are a tad overstated anyway, since you've got the property system that you can leverage in Qt4-style code.
class Helper : public QObject {
Q_OBJECT
QPointer<QLabel> m_label;
public:
Helper(QLabel * label, QObject * parent = 0) : QObject(parent), m_label(label) {}
Q_SLOT void showIndex() {
m_label->setText(
QString("Button %i was clicked.").arg(sender()->property("index").toInt())
);
}
};
void setup(QList<QAbstractButton*> buttons) {
int i = 1;
foreach (QAbstractButton* button, buttons) {
button->setProperty("index", i++);
connect(button, SIGNAL(clicked()), helper, SLOT(showIndex());
}
}
The "internal" pointer of the QModelIndex is merely a way to carry model-specific data in the index subject to following reasonable constraints at the time it was designed and released:
broken C++ compilers (VC6!) that choked on some template uses,
poor size optimization of linked binaries that further precluded template parametrization of consumers of the index type,
pass-by-value semantics without overhead of a pimpl,
no overhead of a vtable pointer,
don't expose the hapless user to the object slicing problem.
It is a product of an era it was designed in. Sure it could be made better nowadays, without exposing the internalXxx methods to the wide public, but that's why those methods are called internal in the first place. Ultimately, if you really wish to shoot yourself in the foot, nobody's stopping you. As a consumer of the index, you're supposed to pretend that those methods aren't there. That's all there's to it.
Yes, even back in VC6 times, one could have used a dedicated pool allocator to do low-overhead pimpl for the index and similar classes. Said pool allocator could have even been leveraged to determine the runtime type of the derived classes and implement a virtual destructor mechanism without the vtable pointer overhead. Sure. But it wasn't done that way, and the decision is with us. Given the amount of explaining needed for the model implementer to safely leverage such "magic", I think the internal pointer mechanism is a tad safer bet.
Related
I'm a long-time Java guy, but in recent years I've been trying to adopt a more purely functional programming style. I found RxJava a good complement to the ideas of functional programming, and most of my code these days can probably be described as functional-reactive in nature.
The only thing that is not sitting quite right with me is the side-effect-ridden way of subscribing/unsubscribing to/from an observable via
void subscribe(Observer<? super T> observer)
or
Disposable subscribe(Consumer<? super T> onNext)
In my mind, the void return type in the signature is already a dead giveaway that we're dealing with something non-functional (or at least non-pure) here: since the subscribe method does not return a value it can only contribute a side effect (which, in turn, implies the existence of mutable state). The methods in Consumer and Observer are also all void methods, as is the dispose() method in Disposable. So, clearly, all these methods are relying on side effects.
In practical coding, I sidestep this issue by keeping most of my code pure (i.e., a series of map/flatMap/filter/... operations), while extracting the subscription logic to a special "edge" area of the code, where I handle side effects like printing a message to the console or sending an HTTP response.
Of course, Java is not a purely functional programming language, so there is no real problem in implementing these side effects. However, I'm wondering, if one were constrained by a purely functional language, how would one subscribe to an observable or implement an onNext()? Is there a purely functional way of handling subscriptions?
Problem
I need to overwrite the method
#Override protected final void layoutChartChildren(double top, double left, double width, double height)
of the XYChart class. Obviously I'm not allowed to.
Question
Why do people declare methods as "final"? Is there any benefit in that?
This answer is just a verbatim quote of text by Richard Bair, one of the JavaFX API designers, which was posted on a mailing list in response to the question: "Why is almost everything in the [JavaFX] API final?"
Subclassing breaks encapsulation. That's the fundamental reason why
you must design with care to allow for subclassing, or prohibit it.
Making all the fields of a class public would give developers
increased power -- but of course this breaks encapsulation, so we
avoid it.
We broke people all the time in Swing. It was very difficult to make
even modest bug fixes in Swing without breaking somebody. Changing the
order of calls in a method, broke people. When your framework or API
is being used by millions of programs and the program authors have no
way of knowing which version of your framework they might be running
on (the curse of a shared install of the JRE!), then you find an awful
lot of wisdom in making everything final you possibly can. It isn't
just to protect your own freedom, it actually creates a better product
for everybody. You think you want to subclass and override, but this
comes with a significant downside. The framework author isn't going to
be able to make things better for you in the future.
There's more to it though. When you design an API, you have to think
about the combinations of all things allowed by a developer. When you
allow subclassing, you open up a tremendous number of additional
possible failure modes, so you need to do so with care. Allowing a
subclass but limiting what a superclass allows for redefinition
reduces failure modes. One of my ideals in API design is to create an
API with as much power as possible while reducing the number of
failure modes. It is challenging to do so while also providing enough
flexibility for developers to do what they need to do, and if I have
to choose, I will always err on the side of giving less API in a
release, because you can always add more API later, but once you've
released an API you're stuck with it, or you will break people. And in
this case, API doesn't just mean the method signature, it means the
behavior when certain methods are invoked (as Josh points out in
Effective Java).
The getter / setter method problem Jonathan described is a perfect
example. If we make those methods non-final, then indeed it allows a
subclass to override and log calls. But that's about all it is good
for. If the subclass were to never call super, then we will be broken
(and their app as well!). They think they're disallowing a certain
input value, but they're not. Or the getter returns a value other than
what the property object holds. Or listener notification doesn't
happen right or at the right time. Or the wrong instance of the
property object is returned.
Two things I really like: final, and immutability. GUI's however tend
to favor big class hierarchies and mutable state :-). But we use final
and immutability as much as we can.
Some information:
Best practice since JavaFX setters/getters are final?
Sometimes I have to implement a feature like customized drag & drop. The code may goes like this:
bool mouse_down = false;
Vec2 mouse_pos;
void on_mouse_down() {
mouse_down = true;
mouse_pos = cursor_pos();
}
void on_mouse_move() {
if(mouse_down) {
Vec2f c = cursor_pos();
Vec2f d = c - mouse_pos;
// dragging. make objects tracing the cursor.
// ...
}
}
void on_mouse_up() {
mouse_down = false;
// dropped
// ...
}
I know this works fine, but I donnot like redundant variables and separated procedures for something like this at all. In IP(imperative programming) maybe it's unavoidable; my question is, is there a better way to deal with this kinda thing in FP(functional programming)? Any ideas and suggestions are appreciated, no matter whatever programming languages, Lisp, Scheme, F#, Ruby, etc. or some better way to do this in IP?
Since nobody attempted an answer for a day, I'll give it a shot. I understand the problem that you are discussing, but the answer should likely depend on the operating system, language and its runtime library.
The general idea would be that when mouse goes down, you spawn off an asynchronous computation. This computation "blocks" on events, and processes them in its own loop as fetched, doing what you need to do; it exists when the mouse button does up. While this looks like it works like an imperative thread, in reality, when the computation gets "blocked", it just yields control to where it was started from (the main GUI thread invoking the mouse down event, presumably). In such a way, the state is encapsulated into what looks like a lexically local scope of the computation. That magic has to be handled by the runtime of the language, so this is as far as we can get with the answer in a language ans OS-agnostic way.
As for an example of such implementation, check this answer and an article by Tomas Petricek, both discussing your question but in a narrow setting of Windows, .NET and F#. There is a book by the same Perticek, Real World Functional Programming: With Examples in F# and C#, where the same ideas are expressed, surprisingly, in C#, not usually regarded a functional language. Chapter 16, if my memory serves me, is yours.
As for encapsulating the state in an IP/OO language program, you can create an instance of a class in your mouse_down handler. The instance would register itself with the runtime to receive other mouse and UI events, process them, do all the work and, when needed (mouse goes up or the windowing system cancels capture mode), unregisters and destroy itself. Not as elegant as a functional language would allow, but still much better that keeping mutable state in a general UI class.
Ok so I was just thinking to myself why do programmers stress so much when it comes down to Access Modifiers within OOP.
Lets take this code for example / PHP!
class StackOverflow
{
private var $web_address;
public function setWebAddress(){/*...*/}
}
Because web_address is private it cannot be changed by $object->web_address = 'w.e.', but the fact that that Variable will only ever change is if your programme does $object->web_address = 'w.e.';
If within my application I wanted a variable not to be changed, then I would make my application so that my programming does not have the code to change it, therefore it would never be changed ?
So my question is: What are the major rules and reasons in using private / protected / non-public entities
Because (ideally), a class should have two parts:
an interface exposed to the rest of the world, a manifest of how others can talk to it. Example in a filehandle class: String read(int bytes). Of course this has to be public, (one/the) main purpose of our class is to provide this functionality.
internal state, which noone but the instance itself should (have to) care about. Example in a filehandle class: private String buffer. This can and should be hidden from the rest of the world: They have no buisness with it, it's an implementation detail.
This is even done in language without access modifiers, e.g. Python - except that we don't force people to respect privacy (and remember, they can always use reflection anyway - encapsulation can never be 100% enforced) but prefix private members with _ to indicate "you shouldn't touch this; if you want to mess with it, do at your own risk".
Because you might not be the only developer in your project and the other developers might not know that they shouldn't change it. Or you might forget etc.
It makes it easy to spot (even the compiler can spot it) when you're doing something that someone has said would be a bad idea.
So my question is: What are the major rules and reasons in using private / protected / non-public entities
In Python, there are no access modifiers.
So the reasons are actually language-specific. You might want to update your question slightly to reflect this.
It's a fairly common question about Python. Many programmers from Java or C++ (or other) backgrounds like to think deeply about this. When they learn Python, there's really no deep thinking. The operating principle is
We're all adults here
It's not clear who -- precisely -- the access modifiers help. In Lakos' book, Large-Scale Software Design, there's a long discussion of "protected", since the semantics of protected make subclasses and client interfaces a bit murky.
http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620
Access modifiers is a tool for defensive programming strategy. You protect your code consciously against your own stupid errors (when you forget something after a while, didn't understand something correctly or just haven't had enough coffee).
You keep yourself from accidentally executing $object->web_address = 'w.e.';. This might seem unnecessary at the moment, but it won't be unnecessary if
two month later you want to change something in the project (and forgot all about the fact that web_address should not be changed directly) or
your project has many thousand lines of code and you simply cannot remember which field you are "allowed" to set directly and which ones require a setter method.
Just because a class has "something" doesn't mean it should expose that something. The class should implement its contract/interface/whatever you want to call it, but in doing so it could easily have all kinds of internal members/methods that don't need to be (and by all rights shouldn't be) known outside of that class.
Sure, you could write the rest of your application to just deal with it anyway, but that's not really considered good design.
I was reading Joel On Software today and ran across this quote:
Without understanding functional
programming, you can't invent
MapReduce, the algorithm that makes
Google so massively scalable. The
terms Map and Reduce come from Lisp
and functional programming. MapReduce
is, in retrospect, obvious to anyone
who remembers from their
6.001-equivalent programming class that purely functional programs have
no side effects and are thus trivially
parallelizable.
What does he mean when he says functional programs have no side effects? And how does this make parallelizing trivial?
What does he mean when he says
functional programs have no side
effects?
Most people think of programming as creating variables, assigning them values, adding things to lists, etc. Variables "vary", hence the name.
Functional programming is a style of designing programs to eliminate variables -- everything is a constant or readonly.
When Joel says functional programs have no side-effects, there's a lot of hand-waving involved since its perfectly easy to write functional programs which do modify variables -- but largely, when people talk about functional programming, they mean programs which don't hold any modifiable state.
"But Juliet! How can write a useful program if it can't modify anything"
Good question!
You "modify" things by creating a new instance of your object with modified state. For example:
class Customer
{
public string Id { get; private set; }
public string Name { get; private set; }
public Customer(string id, string name)
{
this.Id = id;
this.Name = name;
}
public Customer SetName(string name)
{
// returns a new customer with the given name
return new Customer(this.Id, name);
}
}
So all the initialization take place in the constructor, and we can't modify the object ever again -- we create new instances with our modifications passed into the constructor.
You'll be surprised how far you can carry this style of programming.
"But Juliet!? How can this possibly be efficient with all this copying?"
The trick is realizing that you don't have to copy your entire object graph, only the parts which have changed. If parts of your object graph haven't changed, can reuse it in your new object (copy the pointer, don't new up a new instance of any objects in that part of the graph).
You'll be surprised how far you can carry this style of programming. In fact, its extremely easy to write immutable versions of many common data structures -- like immutable Avl Trees, red-black trees, many kinds of heaps, etc. See here for an implementation of an immutable treap.
In most cases, the immutable version of a data structure has the same computational complexity for insert/lookup/delete as its mutable counterparts. The only difference is that inserting returns a new version of your data structure without modifying the original one.
And how does this make parallelizing
trivial?
Think about it: if you have an immutable tree or any other data structure, then you can two threads inserting, removing, and lookup up items in the tree without needing to take a lock. Since the tree is immutable, its not possible for one thread to put the object in an invalid state under another thread's nose -- so we eliminate a whole class of multithreading errors related to race conditions. Since we don't have race-conditions, we don't have any need for locks, so we also eliminate a whole class of errors related to deadlocking.
Because immutable objects are intrinsically thread-safe, they're said to make concurrency "trivial". But that's only really half the story. There are times when we need changes in one thread to be visible to another - so how do we do that with immutable objects?
The trick is to re-think our concurrency model. Instead of having two threads sharing state with one another, we think of threads as being a kind of mailbox which can send and receive messages.
So if thread A has a pointer to thread B, it can pass a message -- the updated data structure -- to thread B, where thread B merges its copy with the data structure with the copy in the message it received. Its also possible for a thread to pass itself as a message, so that Thread A sends itself to Thread B, then thread B sends a message back to Thread A via the pointer it received.
Believe me, the strategy above makes concurrent programming 1000x easier than locks on mutable state. So the important part of Joel's comment: "Without understanding functional programming, you can't invent MapReduce, the algorithm that makes Google so massively scalable."
Traditional locking doesn't scale well because, in order to lock an object, you need to have a reference to its pointer -- the locked object needs to be in the same memory as the object doing the locking. You can't obtain a lock on an object across processes.
But think about the message passing model above: threads are passing messages two and from one another. Is there really a difference between passing a message to a thread in the same process vs passing a message to thread listening on some IP address? Not really. And its exactly because threads can send and receive messages across the process boundary that message passing scales as well as it does, because its not bound to a single machine, you can have your app running across as many machines as needed.
(For what its worth, you can implement message passing using mutable messages, its just that no one ever wants to because a thread can't do anything to the message without locking it -- which we already know is full of problems. So immutable is the default way to go when you're using message passing concurrency.)
Although its very high level and glosses over a lot of actual implementation detail, the principles above are exactly how Google's MapReduce can scale pretty much indefinitely.
See also: http://www.defmacro.org/ramblings/fp.html
Let me wikipedia it for you
In brief, a pure function is one that calculate things based only on its given arguments and returns a result.
Writing something to the screen or changing a global variable (or a data member) is a side effect. Relying on data other than that given in an argument also makes your function non-pure although it is not a side effect.
Writing a "pure function" makes it easier to invoke many instances of it in parallel. That's mainly because being pure, you can be sure it doesn't effect the outside world and doesn't rely on outside information.
Functional programming aims to create functions that are dependent only on their inputs, and do not change state elsewhere in the system (ie, do not have side-effects to their execution).
This means, among other things, that they are idempotent: the same function can be run many times over the same input, and since it has no side-effects you don't care how many times it's run. This is good for parallelization, because it means that you don't have to create a lot of overhead to keep track of whether a particular node crashes.
Of course, in the real world, it's hard to keep side-effects out of your programs (ie, writing to a file). So real-world programs tend to be a combination of functional and non-functional portions.
Units of functional programs have only their input and their output, no internal state. This lack of internal state means that you can put the functional modules on any number of cores/nodes, without having to worry about having the previous calculation in the module affecting the next.
I believe what he means is that purely functional code makes explicit the flow of data through the program. Side-effects allow portions of the code to "communicate" in ways that are difficult to analyze.
Without side-effects in play, the runtime environment can determine how to best decompose the code into parallelism according to the structure of the functional code.
This would be a simplification of the reality, because there is also an issue of decomposing the code into "chunks" which amount to approximately equal "effort." This requires a human to write the functional code in such a way that it will decompose reasonably when parallelized.