• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Cocoa et al as HCI usability problem
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Cocoa et al as HCI usability problem


  • Subject: Re: Cocoa et al as HCI usability problem
  • From: Peter Duniho <email@hidden>
  • Date: Mon, 19 May 2008 14:49:01 -0700

On May 19, 2008, at 2:05 PM, Greg Titus wrote:

On May 19, 2008, at 12:08 PM, Peter Duniho wrote:
[...]
However, _with_ reflection we can do much of the same kinds of things that Obj-C does, without knowing in advance the classes that might use the NSUndoManager class.

One advantage I see in Cocoa is that, because classes may respond to selectors that they didn't even declare, NSUndoManager can simply set a temporary variable, and then catch a selector to be saved away for later invocation. This makes the reflection aspect ("introspection" in Objective-C) more transparent.

Right. I'm glad you see that. Another place to look for the same type of thing is Distributed Objects in Obj-C. It's another piece of the frameworks that use the ability to catch invocations "in flight". In that case, in order to serialize the method and arguments, send the data across the network or between threads, unserialize on the other side, and invoke in that other machine/ process/thread.

Well, except that this would generally be implemented by the framework, no?


In .NET, it supports remote invocations, and this uses (in part) reflection, but the application writer never needs to know the gory details. I agree that reflection is slightly more awkward than what's been presented in terms of Objective-C's message paradigm, and I accept that as a benefit for the authors of the framework. But the end-user doesn't need any of this, or even need to care how it's implemented. Imposing a particular language on the end-user in order to support the framework author doesn't seem compelling to me.

Thanks very much for the example. The same sort of facility (getting method from name) is available in Objective-C, of course, and Andreas Mayer replied on the list an interesting example of how he uses that in AppleScript handling. What C# seems to be missing is the reverse facility (going from a compiled method call back out to name + arguments), which my sample NSUndoManager code demonstrated.

Well, I didn't show the invocation code because it's trivial. You just use the MethodInfo object along with the target instance and the saved parameters to call the MethodInfo.Invoke() method.


Interestingly, given your earlier remarks about the desirability of compile time checking, in Objective-C [[undoManager prepareWithInvocationTarget:self] setColor:mColor] is type checked. The compiler knows about the -setColor: method declaration it has seen and can check that mColor is an appropriate type.

With reflection, you can have type checking, though it's more explicit. With the anonymous method (as I said, more idiomatic in C# anyway), type checking is implicit.


(Because Obj-C still lets you call any method on any object the result of bad typing here will be a warning rather than an error, but Obj-C programmers generally learn to pay attention to and fix all warnings.) Whereas I suspect that when you are using the reflection facilities in C# in the way you are above, that there is no type checking being performed. Is that correct?

There's no compile-time type checking with reflection, that's correct (though you can certainly include run-time type checking if you want to ensure your program doesn't blow up :) ). That's certainly one reason to avoid reflection if it's not necessary (and it wouldn't be in this particular example...I offered the reflection example as a way of illustrating the more general point).


The fact is, often there are better alternatives to reflection in C#. I simply presented reflection as a "closest match" to the specific Objective-C functionality being shown.

That is one of the advantages of having the dynamism built into the language runtime rather than a reflection API built on top. Another advantage is that code can be written that doesn't need to know whether reflection is being used or not. In the Distributed Objects case, for instance, it is very common to pass around proxies as arguments to code that doesn't have any idea that the methods it is calling on those argument objects actually get forwarded somewhere else entirely.

I haven't had time to look at the Distributed Objects example. However, I suspect that there are equivalent idioms in C#/.NET that don't require the end-user (that is, the application writer) to know about reflection. The reflection aspect would be "under the hood".


In reality, I would (and have) more likely implement an undo manager that uses anonymous methods. Then all you're saving to your undo state is a delegate that does what you want (assumes the "property" semantic I posted):

   undoManager.AddUndo(delegate { color = mColor; });

This is more idiomatic in C# and wouldn't need all that messy reflection stuff. Executing the undo is a simple matter of invoking the delegate that was passed, a simple one-line operation that reads like a method call (note that the use of the name "delegate" is very different in C# than in Cocoa...C# "delegate" is more like a function pointer than an actual object to which some selector has been delegated).

Like I said earlier, I don't know C#, but this doesn't appear to me what the code would actually look like. The trouble is that the whole point is we want to be able to undo a previous -setColor: call. If mColor is a reference to the "this" object's current color, then at the time that the undo happens, the value of the reference "mColor" will be the _new_ color, not the old color that we want to restore.

Sorry, you're right. Typo on my part. The actual code would look like this:


    NSColor colorPrev = color;

    undoManager.AddUndo(delegate { color = colorPrev; });

The local variable "colorPrev" would be "captured" and stored as part of the anonymous method. For a given instance of the anonymous method, it will have the value exactly as it was at the moment that the anonymous method was created (i.e. at the time that AddUndo() was called).

So that line of code will just set it to itself. What is needed is to store the mColor value as it is at the time the anonymous delegate is created, not at the time the delegate is executed. Is it possible for an anonymous method to have its own instance variables (in this case, to store the old color)?

Captured variables are essentially instance variables for the anonymous method.


From looking at the docs it doesn't appear to. Nor does it seem possible to do so with named method delegates.

I don't understand the comments saying that you can't do something similar in Java. Java has the same kind of reflection features that C# has. The anonymous method approach wouldn't work, as Java doesn't have anything equivalent to C# delegates, but Java does have interfaces and using those with anonymous types in lieu of anonymous methods is a common Java idiom that works well.

Only with fixed signatures, though.

Not really. Using an anonymous type in Java in lieu of an anonymous method in C#, you can use local variables (declared "final") in a similar fashion as that used to capture variables in C#. So you'd just need a single interface, and then reference the necessary local variable data from within an anonymous type implementing that interface.


I've yet to run into anything in Java where I could have used an anonymous method in C#, but couldn't get an anonymous type to work in a similar fashion in Java. I find the anonymous method syntax more elegant, but the Java approach is workable and generally feature- identical.

Pete
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Re: Cocoa et al as HCI usability problem (From: Peter Duniho <email@hidden>)
 >Re: Cocoa et al as HCI usability problem (From: Greg Titus <email@hidden>)
 >Re: Cocoa et al as HCI usability problem (From: Peter Duniho <email@hidden>)
 >Re: Cocoa et al as HCI usability problem (From: Greg Titus <email@hidden>)
 >Re: Cocoa et al as HCI usability problem (From: Peter Duniho <email@hidden>)
 >Re: Cocoa et al as HCI usability problem (From: Greg Titus <email@hidden>)

  • Prev by Date: Examples of dynamic language feature exploitation by Cocoa from .Net perspective
  • Next by Date: Dynamic langauge support for fault implementation in Enterpise Objects Framework
  • Previous by thread: Re: Cocoa et al as HCI usability problem
  • Next by thread: Re: Cocoa et al as HCI usability problem
  • Index(es):
    • Date
    • Thread