TweetFollow Us on Twitter

September 93 - Reflection


Mikel Evins

Many Object-Oriented Dynamic Languages (OODLs) provide support for a facility called reflection. Reflection in programming is the process of using programming language operations to examine parts of the program and make decisions about what to do on the basis of the information gathered. Examples of reflection in programs include asking an object what its class is, asking a class what its superclasses are, and asking an object whether it responds to a particular message.

More traditional static languages such as Object Pascal and C++ provide no support for reflection. Such support would be inconsistent with the minimalist philosophy that the static languages have regarding the language runtime; reflection requires that support for certain language-level features be present in the program at runtime, and static languages avoid mechanisms that require such support because of the overhead associated with them.

Reflection, therefore, is naturally more commonly supported in programs written in dynamic languages, and particularly in OODLs. Reflective operations serve natural and useful purposes in object-oriented programs, and so OODLs such as Smalltalk, CLOS, and Dylan have always provided reflective operations as part of their standard semantics. More recently, reflection has become a subject of research as programming-language theorists try to understand how much and what kind of support for reflection is practical and useful.

A language that supports reflection provides operations on language elements that return information useful to a running program. The program can then use the returned information to control its execution. Information provided by reflective operations might include the data type of an object, the name, superclasses, and defined methods of a class, the methods defined as specializations of a generic function, and so on.

A common use of reflection is in providing programming tools. It should be obvious that a language in which a program can query runtime data structures about their structure makes it easier to write tools such as browsers, inspectors, and editors. As an example, it is quite a bit easier to query an object for its list of superclasses than to write a tool that searches and maintains a database of header definitions in order to present an object's superclass list to the programmer. Commonly used OODL development environments provide tools that make extensive use of reflective facilities.

We will consider several other examples of the use of reflection in the following sections.

Examples of Reflection

Reflection is a somewhat abstract idea; it may be hard to see what concrete benefits it offers a working programmer. Like many unfamiliar features of dynamic programming languages, reflection is probably best explained by presenting examples. We'll use the reflective facilities of the languages Smalltalk and Dylan to illustrate the uses of reflection.


Smalltalk programmers have several reflective facilities available to them. The message respondsTo: aSymbol asks an object if it has a method whose name is aSymbol. The message isMemberOf: aClass asks whether an object is an instance of the specified class. The message isKindOf: aClass asks the receiver, a class object, whether it is a subclass of the specified class.

One way to enhance the configurability of an application or system is to package various parts of its behavior in separate objects. A Smalltalk program can use Smalltalk's reflective facilities to support a delegation scheme for distributing func-tionality among objects. When an object receives a request for a service it does not implement, it can pass the request to another object. This re-routing of requests is called delegation. Reflective facilities can simplify the implementation of a delegation scheme by making the calling logic simple. Let's examine several alternatives that would enable us to provide a flexible software module, and see what advantages reflection can offer.

Suppose you want to provide a terminal emulation object that offers programmers the ability to incorporate terminal or message windows into their applications. You know the general requirements of terminal windows, and in fact they are fairly stereotypical, but you also know that the range of applications in which programmers might want to use them is large and so you expect that users of your terminal object will want to customize its behavior for their own uses.

One solution that is fairly widely used is to heavily parameterize the behavior of the object. The Macintosh Toolbox and X Windows are both examples of systems in which the behavior of every major component is parameterized by a large number of configurable options. Problems with this approach are that, first, it is difficult to foresee the needs of users well enough to provide adequate parameterization for all reasonable uses, and, second, that the large number of options tends to make such components confusing and difficult to use correctly. There are simply so many parameter values to specify in a well-parameterized example of this kind of component that it's hard to get all the values right for any particular use.

Another approach that solves many of the problems of the parameterized approach is to provide an abstract class that encapsulates the most general useful behavior and permits its users to customize its functionality by writing subclasses. This approach has great advantages, but it also has some problems. In particular, a user of such a class may end up overriding enough of the class definition such that he or she has to rewrite substantial parts of the class just to make minor additions to its behavior. In addition, this approach some-times leads to unfortunate proliferation of specialized subclasses, most of which make only minor additions or changes to their ancestors. Users of static object-oriented frameworks can appreciate how difficult it is to design sets of classes that interoperate adequately with user-defined subclasses.

In some cases problems like these can be addressed by designing classes to use delegates that implement additional behavior. In our terminal emulation example, we could design our object to check for the existence of a delegate and, if it finds it, to call methods that we provide as hooks for extensibility. For example, our terminal emulation object could call a post-initialization method to let the delegate know that it started up and was initialized, character-entered and other editing methods to give the delegate a chance to preprocess input and to respond to changes in the text buffer, line condition methods to permit the delegate to handle status changes in the connection to a communications or interprocess communications stream, and so on.

A scheme like this can make our terminal object very flexible at somewhat the same cost as the parameterization strategy. We can make it much easier to use, however, using reflective facilities. If we start up the terminal object without a delegate then it can omit all its messages to the delegate. Alternatively, we could define all the delegate methods on the object nil, making them no-ops. The object nil is the value of uninitialized instance variables, and so method calls with no delegate present would do nothing.

When a delegate object is present we can use respondsTo: to query it before sending each delegate message, ensuring that we only send those messages that are implemented by the delegate. With this approach we enable users of our terminal object to extend its behavior by implementing only those methods that define the needed behavior; they don't need to provide definitions for any other methods, because when respondsTo: returns false the terminal object skips the corresponding message.

In this case we have used reflection to extend the capability of a general purpose terminal object, while keeping its API as simple as possible. Notice that if we use the delegation strategy along with Smalltalk's reflective facilities we can ensure that the API is as simple as a terminal object with no extensibility in the case where we want to use it just as it is. In the cases where we want to extend the behavior of the object the API only becomes as complex as we need for the behavior we want to modify. We never need to see any part of the API except what we want to use, which is a considerably simpler approach than that of the parameterized object, and even simpler than the abstract superclass strategy, since we can use the terminal class directly in many cases rather than needing to define a concrete subclass. Note that the delegation approach also permits delegates to centralize related behaviors that are used by several objects in an application; many related objects that need to provide extensibility can share a single delegate object at runtime.

Dylan and CLOS

Dylan, a new OODL, uses an object model that is more like that of the Common Lisp Object System (CLOS) than Smalltalk. In the Dylan and CLOS object systems, classes may inherit from several ancestors and may select methods using several objects at once to discriminate among alternatives. Instead of message-passing, Dylan and CLOS rely on generic functions, whose behaviors are determined by the classes of their parameters. In these languages, then, we use reflective functions, rather than reflective messages, to gather information about the data and functions in a program.

Dylan includes reflective functions for examining objects, classes, and functions. You can determine the class of an object by calling object-class, and can test whether an object is an instance of a particular class using instance?. The function direct-superclasses returns a sequence of all the classes that the specified class inherits from directly, and all-superclasses returns a sequence of all classes from which it inherits.

Because Dylan uses generic functions instead of message-passing, polymorphic operations are selected by one or more parameters to a function, not by a message receiver. As a result, there is no precise equivalent in Dylan to the Smalltalk respondsTo: message. Instead, Dylan provides the function find-method. When you pass the name of a function and a list of classes to find-method, it returns the method associated with the function that corresponds to the given list of classes. For example, the following code returns the Dylan method that adds two instances of <small-integer>:

(find-method binary+ (list <small-integer> <small-integer>))

The Dylan function find-method can be used in the same way as the Smalltalk respondsTo: message; if there is no method that corresponds to a particular list of classes then it returns the Boolean false value, enabling the programmer to conditionalize code in the same way as with the Smalltalk mechanism. Dylan, however, treats functions and methods as first-class data values, and so can provide some additional reflective functions. The function generic-function-methods returns a sequence of all the methods defined on a generic function. method-specializers returns a sequence of the specializers for a particular method. A method's specializers are the objects used to select the method when its generic function is called; in most cases this sequence will consist of classes, but in Dylan it is possible to specialize a method on an individual instance, and so method-specializers may in some cases return objects that are not classes. function-arguments returns three values: the number of arguments required by the specified function, a Boolean that indicates whether the function can accept additional optional arguments, and a (possibly empty) sequence of keywords used as keyword parameters, or Boolean false if the function does not accept keyword parameters. applicable-method? returns true if there is a method defined on a function that corresponds to a specified set of sample arguments, and sorted-applicable-methods returns all methods that could apply to a set of sample arguments.

We can imagine an event-handling system similar to that of the Macintosh, but which provides support for extended sets of events using the reflective capabilities of Dylan. If the event system were implemented in an object-oriented fashion then we would expect the event queue to be filled with objects of various event classes. We handle events by removing them from the queue and passing them to a generic event handler which accomplishes the same purpose as the Macintosh event handler. We could define an additional queue of handlers that would store event-handling functions. When the generic handler gets an event it can extract the parameter information from the event and search the handler queue for a function that is applicable to the event parameters; it can determine whether a particular handler is applicable by using the applicable-method? or sorted-applicable-methods function.

The event-processing loop might look something like the following Dylan code (oversimplified, of course, for clarity's sake). First we define the function that finds an appropriate handler:

(define-method find-event-handler (type    time 
    (any? (method (handler)
          (applicable-method?   (object-class type)
                        (object-class time)
                        (object-class location)
                        (object-class message)))

The function any? returns the first element of the sequence *event-handler-queue* for which applicable-method? returns a true value. Our function therefore searches the event-handler queue, returning the first handler that is appropriate to the event parameters that we pass to it.

Following is the actual event loop:

(define-method event-loop ()
(for ((continue #t (test-whether-to-continue)))
        ((not continue) 'done)
    (bind ((current-event (pop-event-queue))
                (event-type event-time 
                 event-location event-message
                    (event-params current-event))
                (handler (find-event-handler    event-type
            (if handler
                (apply handler current-event)
                (apply *default-event-handler* current-event)))))

Our event loop uses the special iterating form for to establish an infinite loop that exits when something sets the variable continue to a false value. The bind form creates the local variable current-event to hold the first item in the event queue, and then binds local variables to the parameters returned by the event-params function. It then binds handler to the result of a call to our find-event-handler function. Finally, if find-event-handler found an appropriate handler then the if form applies that handler to the current event; otherwise it applies the default system-defined handler.

An event system like this one could be quite flexible and extensible; programmers would have a great deal of freedom to define new event types and handlers, and applications could enable users to add new event types to be handled by application-defined handlers or user scripts.

Dylan's object system was heavily influenced by the design of CLOS, and CLOS provides much the same reflection support as Dylan, although under different function names. In fact, CLOS goes further than Dylan in providing facilities for redefining class and function structure. For example, the CLOS generic function change-class enables the programmer to dynamically change the class of an instance, and the reinitialize-instance function re-executes the object's initialization code.

Browsers and Inspectors

Browsers and inspectors, programming tools that were invented for use with LISP and Smalltalk environments, have become familiar tools to programmers working in static languages such as C and Pascal. They are very helpful in managing complex programs and in identifying problems in working code.

Reflection provides a straightforward language-level facility for examining program structures in the runtime. Browsing and inspecting tools for C and Pascal usually use separately maintained metadata files such as symbol tables and interfaces, but because OODLs can return useful information from a query about object classes, inheritance relationships, defined methods, and so on, browsers and inspectors can simply query the runtime data structures in place. In addition, it's easy to make OODL inspectors and browsers interact directly with the data structures, providing live updating and editing in place (such facilities are also possible in static languages, although, if your programs run under a system that protects memory, such as UNIX, then you may have to link special libraries to your application in order to get support for editing in place).

Using reflection

In the previous sections we discussed in some detail some examples of how you might use reflection to advantage. In this section we will just briefly consider a few more examples of how reflection can be useful.

Data-directed Programming

One practical use of reflection is in a programming technique called data-directed programming: data-directed programs structure the flow of control in terms of tables of alternative executions. The program selects a particular execution path based upon the data it receives as input. Programs that map input data to output data for example, can use data-directed techniques to organize execution in terms of the type of data object that appears on input. By using reflective facilities to identify the input objects and organizing execution as a table whose entries are keyed on the type of object a programmer can simplify the runtime logic of the program. In addition, data-directed programs are often easier to maintain and extend than programs that use more explicit control logic because the programmer can simply add or change table entries in order to modify the program or add new features.


Another practical use of reflection is in the implementation of error-handling code. OODLs often provide good support for error-handling in the form of signaling or condition systems. These facilities make it easy to properly handle the transfer of control in the case of an error or exception, but there is still the problem of what to do once control has been transferred out of the context in which the exception occurred. Reflective facilities can help by providing a way to examine the relevant data. Using reflective facilities an error-handler can determine the type of an object and other information about it. Depending on the specific nature of the reflective facilities, it may also be able to determine whether the function in which the exception occurred was the correct one for the data provided as input, or other such relevant information. Using reflection, an error-handling system can provide a programmer with substantial information about how an error occurred and in what state it left the runtime. The error-handling system can also have more flexibility in handling errors in a delivered product so that, even when errors occur, they are less likely to cause the program to fail. In this way reflective capabilities can help programmers to deliver more bulletproof applications.

Enforcing protocols

System designers and application designers whose applications provide interoperation and extensibility features must concern themselves with the public points of entry offered to other programs and systems. These public points of entry may be regarded as protocols by analogy with network protocols or with protocols in object-oriented languages such as Smalltalk.

Reflective features in a programming language offer another level of protection for a running system in that it can use them to enforce its protocols. Rather than relying upon a client's adherence to the published protocols, a system with reflective capabilities can actually query its clients to test whether they actually obey the protocols. If a protocol consists of such and such functions operating on such and such types then the system can enforce its protocol by asking clients what their types are and whether they implement the required functions.

In addition, a system could support several alternative protocols for reasons of compatibility or convenience. In this case the reflective facilities provide a way for the system to determine which protocol is needed by a client and to ensure that the client actually supports it.

The cost of reflection

Of course, support for reflection must cost something. Whenever we add capabilities to a software system we must pay either in space or in CPU cycles or both. In the case of reflection, we pay in both ways. The cost might be high or low, depending upon how you look at it; most importantly, perhaps, your assessment of the cost will depend upon whether you need other features of dynamic languages besides reflection. Much of the runtime support used by reflective operations is also used by other OODL features such as automatic memory management and dynamic polymorphic dispatching. If you have concluded that you need those features then reflection is very cheap. If, on the other hand, you have no need of those other features then the price of reflection may seem very high.

Reflective operations must have information to work with, and, as we would expect in a dynamic language, that information must be stored in the runtime. For example, Smalltalk's respondsTo: methods must have some place to look to determine whether the symbol parameter names a method on the receiving object. This fact implies that the runtime must store tables that map symbols to methods. Similarly, Dylan's direct-superclasses function must have some place to look to determine the classes that a specified class inherits from, and must even distinguish direct superclasses from indirect.

As it turns out, the semantics of Smalltalk and Dylan require that classes are first-class data objects anyway, and so the use of either language implies that there will be class objects in the runtime. If you are using one of the languages already then the fact that reflective operations need such class objects is a happy coincidence. In such cases the price of reflection is very low, though you might not choose them just for their reflective capabilities.

The requirement that the runtime include such metainformation about the program may seem like extravagance to those accustomed to static languages. Parsimonious C programmers might be reluctant to admit to a need for any significant runtime overhead at all, but most authors of significant applications will probably agree that a certain amount of such overhead is inevitable anyway in any non-trivial application. The interesting question for a developer is whether the particular overhead for a particular language or library is justified in context of a particular application.

As you can see, determining the exact cost of reflective capabilities is not very easy, because they use runtime features that are present in OODLs anyway. If we removed the overhead of features that support reflection then we would be removing substantial parts of the OODL languages along with them. The only way, then, to measure the real cost of reflection is to compare the size and speed of a given application written in a reflective OODL to that of a comparable one written in a language like C or Pascal. In general we can say that if you expect your application to weigh in at around 10 to 100 Kbytes and to be absolutely blazing fast then the price of reflection is probably too high. If, on the other hand, you expect your application to be in the range of 400K to two megabytes, and you expect the performance to depend more on correct choice

of algorithms than on the absolute number of instructions in each function, then languages that support reflection will probably be realistic options. The area in-between is more problematic; the question of whether to use reflective languages will come down to a tradeoff between absolute execution speed and program reliability.

Approximating reflection

You might decide that for a particular application reflective capabilities simply cost too much in terms of space and CPU time. In such cases it may be worth your while to approximate reflective features by implementing some portion of reflection as a supplement to your application code. Depending on your requirements your solution might vary from a few functions that work on a certain data type to an elaborate and fairly complete reflection facility (although if you find yourself implementing something at this scale then you might consider whether it would have been better just to use a language with reflective facilities built in).

Your first decision will be whether to implement full reflection or just a simple subset tailored to a particular use. We will assume here that you want to implement a subset of full reflective capabilities because if you need full reflection it is much easier just to use an OODL for your project.

One reasonable approach to providing just enough reflection for an application is to implement a set of classes that represent the data types central to your application and include in them support for reflective capabilities. For example, if you are working in C++ then you can implement a class, call it MReflector, that supports reflective operations much like those of Smalltalk. You can use MReflector as a mixin, taking advantage of C++ multiple inheritance support to combine MReflector with any other inheritance relationships your classes need. (A mixin is a class that implements a small, specific bit of functionality, designed to supplement other classes by being added to their inheritance graphs. The concept originated in the Flavors object-oriented programming system for Lisp, and continues to be widely used in CLOS and other Lisp-like object systems). MReflector can support the three Smalltalk reflective operations, respondsTo:, isMemberOf:, and isKindOf:, but you will have to ensure that objects that inherit from MReflector are initialized with the appropriate values so that your versions of these operations return the right values. Instances of each reflective class will need to have access to a list of the identifiers that make up its public protocol so that your version of respondsTo: can test whether a given identifier is in the protocol. They will also need access to a list of superclass identifiers so that your versions of isMemberOf: and isKindOf: can test whether the an instance belongs to the specified class or whether a class inherits from another class.

Once you have support for these operations built into an MReflector class you may have the feeling that you have the best of both worlds: you have reflective capabilities, but you don't have to pay the overhead of an OODL. Just to keep things in perspective, however, you should remember, first of all, that the difference in space and speed cost between C++ and modern OODLs is measured in small percentages rather than orders of magnitude for most large programming projects. Secondly, although you have an approximation of reflective capabilities, it works only on those classes that inherit from MReflector , and you have to manage initialization of the instance explicitly or else the reflective operations will return incorrect results. In an OODL the reflective facilities work correctly on all objects automatically.

Example: Objective-C

Objective-C, an object-oriented extension to C, provides the same three reflective messages provided by Smalltalk. Although not a fully dynamic object-oriented language, Objective-C implements some useful features of OODLs, while retaining most of the efficiency of C. The design of Objective-C is one good example of a way to provide select parts of the features of an OODL when you need or prefer to work in a static language. Because the reflective operations are defined on Object, the common ancestor of all Objective-C classes, Objective-C avoids the problem of reflection that works only on select classes.

The Nextstep application framework, which was written in Objective-C, makes extensive use of a delegation mechanism like that we described in the Smalltalk section. By building a flexible delegation mechanism into the application framework using Objective-C's reflective features, the Nextstep engineers made it easy for third-party developers to incrementally change and enhance the framework's standard behavior.


This article presents only a brief introduction to a few simple but useful reflective facilities. Reflection in programming languages is a whole field of study for programming language theorists. Reflection is acknowledged to be a useful tool for working programmers, but it isn't clear yet how much reflection is practical; some experimental languages go to extremes, making reflection central to the design of most programming idioms. It will be a while before the results of such research directly affect most working programmers, but in the meantime we can take advantage of some reflective capabilities where they are appropriate. OODL programmers, especially, can benefit from the built-in support for reflection offered by object-oriented dynamic languages.

Community Search:
MacTech Search:

Software Updates via MacUpdate

Dropbox 37.4.29 - Cloud backup and synch...
Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more
iClock Pro 3.8 - Customize your menubar...
iClock Pro is a menu-bar replacement for Apple's default clock. iClock Pro is an update, total rewrite, and improvement to the popular iClock. Have the day, date, and time in different fonts and... Read more
A Better Finder Attributes 6.06 - Change...
A Better Finder Attributes is the ultimate file-tweaking tool for OS X. It combines photo-shooting date and file date changing along with a few unique tricks of its own. Change EXIF Timestamps at... Read more
Chromium 62.0.3202.62 - Fast and stable...
Chromium is an open-source browser project that aims to build a safer, faster, and more stable way for all Internet users to experience the web. Version 62.0.3202.62: High CVE-2017-5124: UXSS with... Read more
Things 3.2.1 - Elegant personal task man...
Things is a task management solution that helps to organize your tasks in an elegant and intuitive way. Things combines powerful features with simplicity through the use of tags and its intelligent... Read more
MacCleanse 6.0.5 - $29.95
MacCleanse is the product of thousands of hours of intense research and development. It meticulously scans all of the nooks and crannies of a computer for unnecessary junk that can take up huge... Read more
Fantastical 2.4.3 - Create calendar even...
Fantastical 2 is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event... Read more
Google Chrome 62.0.3202.62 - Modern and...
Google Chrome is a Web browser by Google, created to be a modern platform for Web pages and applications. It utilizes very fast loading of Web pages and has a V8 engine, which is a custom built... Read more
VirtualBox 5.2.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more
iClock Pro 3.8 - Customize your menubar...
iClock Pro is a menu-bar replacement for Apple's default clock. iClock Pro is an update, total rewrite, and improvement to the popular iClock. Have the day, date, and time in different fonts and... Read more

Warhammer Quest 2 (Games)
Warhammer Quest 2 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Dungeon adventures in the Warhammer World are back! | Read more »
4 of the best Halloween updates for mobi...
Halloween is certainly one of our favorite times for mobile game updates. Many popular titles celebrate this spooky season with fun festivities that can stretch from one week to even the whole month. As we draw closer and closer to Halloween, we'... | Read more »
Fire Rides guide - how to swing to succe...
It's another day, which means another Voodoo game has come to glue our hands to our mobile phones. Yes, it's been an especially prolific month for this particular mobile publisher, but we're certainly not complaining. Fire Rides is yet another... | Read more »
Time Recoil (Games)
Time Recoil 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: Time Recoil is a top-down shooter where you kill to slow time, dominate slow motion gunfights, and trigger devastating special... | Read more »
Campfire Cooking (Games)
Campfire Cooking 1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0 (iTunes) Description: | Read more »
Returner 77 (Games)
Returner 77 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Returner 77 is a cinematic space mystery puzzle game. You are in a giant alien spaceship hovering above Earth, after everything... | Read more »
Dune! guide - how to toe the line and ge...
Publisher Voodoo is at it again with an all new high score chaser -- Dune! In this fast-paced arcade game, you have to propel yourself along sand dunes, gaining enough momentum to jump above the line to score points, while making sure you have... | Read more »
The best deals on the App Store this wee...
Happy Tuesday, dear readers. Your favorite part of the week as officially arrived. It's time to take a look at the best deals in games. Things are admittedly a bit sparse, but there are a few diamonds in the rough to see you through if you're... | Read more »
Be the last person standing in Legacy of...
Yoozoo Games’ popular action MMO Legacy of Discord is getting a huge new update to celebrate its first anniversary. Perhaps the biggest change is the addition of an exciting survival mode titled Last Guardian. This new survival mode will pit you... | Read more »
Home Street guide - how to make friends...
From the creators of Food Street comes Home Street, a new simulation game that tasks you with building a social network and designing a beautiful home. It's a bit like The Sims, but you won't have to worry about the daily chores involved (feeding,... | Read more »

Price Scanner via

13″ MacBook Pros on sale for up to $120 off M...
B&H Photo has 2017 13″ MacBook Pros in stock today and on sale for up to $120 off MSRP, each including free shipping plus NY & NJ sales tax only: – 13-inch 2.3GHz/128GB Space Gray MacBook... Read more
15″ MacBook Pros on sale for up to $200 off M...
B&H Photo has 15″ MacBook Pros on sale for up to $200 off MSRP. Shipping is free, and B&H charges sales tax in NY & NJ only: – 15″ 2.8GHz MacBook Pro Space Gray (MPTR2LL/A): $2249, $150... Read more
Roundup of Apple Certified Refurbished iMacs,...
Apple has a full line of Certified Refurbished 2017 21″ and 27″ iMacs available starting at $1019 and ranging up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free... Read more
Sale! 27″ 3.8GHz 5K iMac for $2098, save $201...
Amazon has the 27″ 3.8GHz 5K iMac (MNED2LL/A) on sale today for $2098 including free shipping. Their price is $201 off MSRP, and it’s the lowest price available for this model (Apple’s $1949... Read more
Sale! 10″ Apple WiFi iPad Pros for up to $100...
B&H Photo has 10.5″ WiFi iPad Pros in stock today and on sale for $50-$100 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $... Read more
Apple iMacs on sale for up to $130 off MSRP w...
B&H Photo has 21-inch and 27-inch iMacs in stock and on sale for up to $130 off MSRP including free shipping. B&H charges sales tax in NY & NJ only: – 27″ 3.8GHz iMac (MNED2LL/A): $2179 $... Read more
2017 3.5GHz 6-Core Mac Pro on sale for $2799,...
B&H Photo has the 2017 3.5GHz 6-Core Mac Pro (MD878LL/A) on sale today for $2799 including free shipping plus NY & NJ sales tax only . Their price is $200 off MSRP. Read more
12″ 1.2GHz Space Gray MacBook on sale for $11...
Amazon has the 2017 12″ 1.2GHz Space Gray Retina MacBook on sale for $100 off MSRP. Shipping is free: 12″ 1.2GHz Space Gray MacBook: $1199.99 $100 off MSRP Read more
Bare Bones Software Releases macOS High Sierr...
Bare Bones Software has announced the release and immediate availability of BBEdit 12.0, a significant upgrade to its professional strength text and code editor. BBEdit 12 introduces a new foundation... Read more
Yale Announces Availability of Apple HomeKit-...
Yale Locks & Hardware has announced that Apple HomeKit support for its Assure Lock family is available this month. The new Yale iM1 Network Module, which provides support for the Apple Home app... Read more

Jobs Board

Frameworks Engineer, *Apple* Watch - Apple...
Job Summary Join the team that is shaping the future of software development for Apple Watch! As a software engineer on the Apple Watch Frameworks team you will Read more
*Apple* News Product Marketing Mgr., Publish...
Job Summary The Apple News Product Marketing Manager will work closely with a cross-functional group to assist in defining and marketing new features and services. Read more
Fraud Analyst, *Apple* Advertising Platform...
Job Summary Apple Ad Platforms has an opportunity to redefine advertising on mobile devices. Apple reaches hundreds of millions of iPhone, iPod touch, and iPad Read more
*Apple* Information Security - Security Data...
Job Summary This role is responsible for helping to strengthen Apple 's information security posture through the identification and curation of security event data. Read more
Lead *Apple* Solution Consultant - Apple In...
…develop a team of diverse partner employees focusing on excellence to deliver the Apple story. Even when you're not present, you will maintain a consistent influence Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.