Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×

Comment Re:Not easiest to read, but forgiving... (Score 1) 414

Ironically, you have actually got a few things wrong here.

First of all, delegates are not just function pointers. They're bound method pointers, meaning that they can capture the receiver of the call in addition to the method itself. This makes it possible to create a delegate to an instance method, which is not something you can do with function pointers alone in C++ (there, you need to define a data structure that combines the function pointer with the object pointers; or use something like mem_fn or bind that'll do it for you).

More importantly, when you say that "events are just function pointer lists", this is actually what delegates are, rather than events. Given your definition of Foo, for example, it is possible to say:

Foo f = ...
Foo g = ...
Foo h = f + g; // look, a delegate that references two different methods!

In the most common case, at least when passing them around as arguments, a delegate object will refer to a single method. But it can refer to arbitrarily many methods of different objects, and it's still denoted by the same delegate type. The rules defining what happens when you invoke such a delegate are not obvious (in particular, with respect to return values and out/ref parameters) - order matters, for example, and so do repeated inclusions of the same method (i.e. it's not a set, it's an ordered list).

(In theory, it is possible to have delegate types that are not lists, if you define them as inheriting from Delegate rather than MulticastDelegate on IL level - this is legal per CLI spec. But no .NET language that I know of provides the ability to define such types in practice, so you'd need to use something like ilasm.)

Events, on the other hand, are an entirely different concept altogether. The most crucial difference between an event and a delegate is that event does not define a type, nor is it an object. An event is simply a pattern of two accessor methods - one to add an event handler (represented as a delegate), the other to remove a handler - formalized on language level. When you write something like:

public event EventHandler ShitHappened;

what it does is define two methods named add_ShitHappened and remove_ShitHappened, both taking an argument of type EventHandler. Because you didn't specify the implementation of those methods, it will also automatically generate them as if you wrote it like this:

private EventHandler ShitHappened;
public event EventHandler ShitHappened {
  add { ShitHappened += value; }
  remove { ShitHappened -= value; }
}

(In practice it actually uses atomic operations to ensure that handlers can be registered concurrently from different threads without one overwriting the other, but I've omitted that for the sake of simplicity. For single-threaded case, the above code is equivalent.)

You can't actually write it like that yourself, because it's not legal to have the same name for the field and the event - but for automatically generated accessors it is legal, and distinguishing between them depends on the context where it's done. If you're referencing ShitHappened from the same class, then you're accessing the field. If you're accessing it outside the class, you're accessing the event.

Either way, the important part is that, regardless of whether the event has implicitly defined accessors or not, users of the class only see the add/remove accessors, and do not have access to the backing storage. This means that they cannot, for example, raise the event from the outside, or enumerate the list of subscribers and directly invoke some of them, or remove a delegate from that list that they haven't themselves added (or obtained from elsewhere, which is why it's a good idea to make all event handlers private).

And that is the sole purpose of event: to provide encapsulation for the observer pattern that ensures that code outside of the class can only register and unregister its own handlers, and cannot interfere with handlers from other components, or violate the contract of the class by raising its event at inappropriate times. If you just need a list of function pointers (that anyone can enumerate, mutate and call at will), then that's what delegates are for.

Rough TL;DR version: events are to fields of delegate types what properties are to fields of other types. Both exist for the purpose of encapsulation. An event is not "a list of delegates", though it is a very popular misconception.

Also, while the concepts itself are sound, the actual implementation of all that stuff in CLR and C# could really be better. In particular, the fact that there's Delegate and MulticastDelegate, but then all delegate types actually derive from the latter (and there are no non-multicast delegates in practice). And also the confusion between the event and its backing field for the auto-generated event accessors - it's very common for C# newbies to be confused by the fact that they can do "x.ShitHappened != null" if they're inside the class, but not if they're outside. IMO, they should have completely encapsulated the backing field (like they do for auto-properties), and treat ShitHappened(...) as a special syntax on the event instead of just a direct field access - then they could also add automatic thread-safe null checks that you always have to do anyway. IIRC, that's exactly what VB does.

Comment Re: Yes & the sheer amount of existing code/fr (Score 1) 414

The problem with object.x=4 is that it not overridable, the therefore interferes with both the encapsulation and the specialization concepts within the OO world.

For starters, as noted, it's strictly a language issue - there's no reason why property-style access cannot be made customizable, and it is in C# (just to pick something that's relatively close to Java).

Furthermore, there's no particular reason why you'd really want object.x=4 to be overridable in general. In a language that is designed well, there's simply no observable difference in that operation (and other treatment of 'x') regardless of whether it's a simple field or a code-backed property. Even C# gets it wrong (can't use properties as 'out' or 'ref' arguments of a function, for example), but other languages do it right. In that case, you always start with a field, and you change it to property accessors if and when you actually need it.

Comment Re:More than PR (Score 1) 385

Rand Paul is a grandstander in the Barack Obama mold. He is sound and fury signifies fuck-all but lip-service to a dimwitted ideology that I wonder if he even believes. It's almost as if some consultant told him that the only demographic where he has a chance is bitcoin dudebros and so he has these little events to check off the box.

The only problem with this story is that pandering to "bitcoin dudebros" is widely known to not be a way to electoral success, and if Paul is really just a shrewd grifter that you paint him, he knows that, as well. So what exactly does he stand to gain from participating in the electoral campaign on a platform that practically guarantees a loss?

Comment Re:Incorrect (Score 3, Insightful) 175

I doubt this is really super optimized for size. More likely, it's really just a very, very basic OS with the absolute bare minimum of functionality. Think glorified bootloader for a single process with a bunch of libraries for basic stuff like simple filesystem and TCP/IP networking. Getting all that into 10K is not particularly difficult, and the code is likely pretty straightforward C.

Comment Re: There can be only one. (Score 4, Interesting) 443

C++ is one of the toughest languages for tools to handle - it's crazy complicated even just to parse right. And in case of rename refactoring in particular (and anything else that might implicitly include that), it might not even be possible to do it right. Consider something like this:

struct foo { int x; };
struct bar { float x; };
template<class T> void baz(T t) { t.x; }
baz(foo());
baz(bar());

Now suppose you're asking the editor to rename foo::x to foo::y. Should it also update t.x in baz, since it's referencing foo::x in one of the instantiations? But if it does so, then the other instantiation, the one that takes bar, will stop working. Should it rename bar::x as well? But it's not really related to foo::x in any meaningful way, they just happen to be referenced by the same template.

Comment Re:Minimum Wage (Score 4, Informative) 1094

You know, when that story aired on Fox News, some people have actually went and asked the owners of those closing restaurants whether it's due to the minimum wage. And they have only found one place where that was a factor - and even that one has, ironically, not been in the original report.

At the same time, several new restaurants have opened, or are still planning to open, in the same timeframe.

http://www.forbes.com/sites/ri...

Comment Re:Republicans could... (Score 1) 609

What you're saying, basically, is that Republicans need to become Libertarians to remain competitive.

Which, I think, is largely true. But so long as the evangelical social conservative block is strong, it won't happen. It will take several hard losses, starting with 2016, for the rest of the party to revolt. Even then, I think it may actually manifest as a formal party split rather than an inside takeover, depending on how much socons manage to tarnish the GOP brand by then.

Comment Re:So, when has this not been true? (Score 2) 609

The conventional wisdom is wrong. Well, not quite, but the obvious interpretation isn't accurate.

When they did some polls recently on specific issues that are liberal or conservative, what they found is that people may swing a lot in their earlier years, but once their views solidify, they stay largely the same even as they grow older. In other words, someone who was pro-choice and supported same-sex marriage in 1995, when they were 20, will still support them in 2005 when they are 30, and in 2015 when they are 40.

The reason why people were usually perceived as becoming more conservative, is because the definition of "conservative" changes as society changes. As society trends progressive on the large scale of things (obviously there are upswings and downswings, I'm talking about decades here), what's progressive today becomes centrist tomorrow and conservative next day.

When both parties also chase the societal middle ground, as they normally do in politics, the net effect is that liberal party voters become conservative party voters over time. But when one of the parties decides to draw the line and proclaim that it won't make a single step beyond it, the net effect is that it will drain voters over time, even as the support from the remaining voters grows stronger. This is exactly the position in which GOP has found itself now, and a direct consequence of them betting on the social conservative evangelical vote back in 80s. The millennials who are split 65/36 in favor of Dems today will retain that split even as they grow older, so long as GOP platform remains the same.

Slashdot Top Deals

Physician: One upon whom we set our hopes when ill and our dogs when well. -- Ambrose Bierce

Working...