Double dispatch

Last updated

In software engineering, double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call. In most object-oriented systems, the concrete function that is called from a function call in the code depends on the dynamic type of a single object and therefore they are known as single dispatch calls, or simply virtual function calls.

Contents

Dan Ingalls first described how to use double dispatching in Smalltalk, calling it multiple polymorphism. [1]

Overview

The general problem addressed is how to dispatch a message to different methods depending not only on the receiver but also on the arguments.

To that end, systems like CLOS implement multiple dispatch. Double dispatch is another solution that gradually reduces the polymorphism on systems that do not support multiple dispatch.

Use cases

Double dispatch is useful in situations where the choice of computation depends on the runtime types of its arguments. For example, a programmer could use double dispatch in the following situations:

A common idiom

The common idiom, as in the examples presented above, is that the selection of the appropriate algorithm is based on the call's argument types at runtime. The call is therefore subject to all the usual additional performance costs that are associated with dynamic resolution of calls, usually more than in a language supporting only single method dispatch. In C++, for example, a dynamic function call is usually resolved by a single offset calculation - which is possible because the compiler knows the location of the function in the object's method table and so can statically calculate the offset. In a language supporting double dispatch, this is slightly more costly, because the compiler must generate code to calculate the method's offset in the method table at runtime, thereby increasing the overall instruction path length (by an amount that is likely to be no more than the total number of calls to the function, which may not be very significant).

Example in Ruby

A common use case is displaying an object on a display port which can be a screen or a printer, or something else entirely that doesn't exist yet. This is a naive implementation of how to deal with those different media.

classRectangledefdisplay_on(port)# selects the right code based on the object classcaseportwhenDisplayPort# code for displaying on DisplayPortwhenPrinterPort# code for displaying on PrinterPortwhenRemotePort# code for displaying on RemotePortendendend

The same would need to be written for Oval, Triangle and any other object that wants to display itself on a medium, and all would need to be rewritten if a new type of port were to be created. The problem is that more than one degree of polymorphism exist: one for dispatching the display_on method to an object and another for selecting the right code (or method) for displaying.

A much cleaner and more maintainable solution is then to do a second dispatch, this time for selecting the right method for displaying the object on the medium:

classRectangledefdisplay_on(port)# second dispatchport.display_rectangle(self)endendclassOvaldefdisplay_on(port)# second dispatchport.display_oval(self)endendclassDisplayPortdefdisplay_rectangle(object)# code for displaying a rectangle on a DisplayPortenddefdisplay_oval(object)# code for displaying an oval on a DisplayPortend# ...endclassPrinterPortdefdisplay_rectangle(object)# code for displaying a rectangle on a PrinterPortenddefdisplay_oval(object)# code for displaying an oval on a PrinterPortend# ...end

Double dispatch in C++

At first glance, double dispatch appears to be a natural result of function overloading. Function overloading allows the function called to depend on the type of the argument. Function overloading, however, is done at compile time using "name mangling" where the internal name of the function encodes the argument's type. For example, a function foo(int) may internally be called __foo_i and the function foo(double) may be called __foo_d. Thus, there is no name collision, and no virtual table lookup. By contrast, dynamic dispatch is based on the type of the calling object, meaning it uses virtual functions (overriding) instead of function overloading, and does result in a vtable lookup. Consider the following example, written in C++, of collisions in a game:

classSpaceShip{};classApolloSpacecraft:publicSpaceShip{};classAsteroid{public:virtualvoidCollideWith(SpaceShip&){std::cout<<"Asteroid hit a SpaceShip\n";}virtualvoidCollideWith(ApolloSpacecraft&){std::cout<<"Asteroid hit an ApolloSpacecraft\n";}};classExplodingAsteroid:publicAsteroid{public:voidCollideWith(SpaceShip&)override{std::cout<<"ExplodingAsteroid hit a SpaceShip\n";}voidCollideWith(ApolloSpacecraft&)override{std::cout<<"ExplodingAsteroid hit an ApolloSpacecraft\n";}};

If you have:

AsteroidtheAsteroid;SpaceShiptheSpaceShip;ApolloSpacecrafttheApolloSpacecraft;

then, because of function overloading,

theAsteroid.CollideWith(theSpaceShip);theAsteroid.CollideWith(theApolloSpacecraft);

will print, respectively, Asteroid hit a SpaceShip and Asteroid hit an ApolloSpacecraft, without using any dynamic dispatch. Furthermore:

ExplodingAsteroidtheExplodingAsteroid;theExplodingAsteroid.CollideWith(theSpaceShip);theExplodingAsteroid.CollideWith(theApolloSpacecraft);

will print ExplodingAsteroid hit a SpaceShip and ExplodingAsteroid hit an ApolloSpacecraft respectively, again without dynamic dispatch.

With a reference to an Asteroid, dynamic dispatch is used, and this code:

Asteroid&theAsteroidReference=theExplodingAsteroid;theAsteroidReference.CollideWith(theSpaceShip);theAsteroidReference.CollideWith(theApolloSpacecraft);

prints ExplodingAsteroid hit a SpaceShip and ExplodingAsteroid hit an ApolloSpacecraft, again as expected. However, the following code does not work as desired:

SpaceShip&theSpaceShipReference=theApolloSpacecraft;theAsteroid.CollideWith(theSpaceShipReference);theAsteroidReference.CollideWith(theSpaceShipReference);

The desired behaviour is to bind these calls to the function that takes theApolloSpacecraft as its argument, as that is the instantiated type of the variable, meaning the expected output would be Asteroid hit an ApolloSpacecraft and ExplodingAsteroid hit an ApolloSpacecraft. However, the output is actually Asteroid hit a SpaceShip and ExplodingAsteroid hit a SpaceShip. The problem is that, while virtual functions are dispatched dynamically in C++, function overloading is done statically.

The problem described above can be resolved by simulating double dispatch, for example by using a visitor pattern. Suppose the existing code is extended so that both SpaceShip and ApolloSpacecraft are given the function

virtualvoidCollideWith(Asteroid&inAsteroid){inAsteroid.CollideWith(*this);}

Then, while the previous example still does not work correctly, reframing the calls so that the spaceship is the agent gives us the desired behaviour:

SpaceShip&theSpaceShipReference=theApolloSpacecraft;Asteroid&theAsteroidReference=theExplodingAsteroid;theSpaceShipReference.CollideWith(theAsteroid);theSpaceShipReference.CollideWith(theAsteroidReference);

It prints out Asteroid hit an ApolloSpacecraft and ExplodingAsteroid hit an ApolloSpacecraft, as expected. The key is that theSpaceShipReference.CollideWith(theAsteroidReference); does the following at run time:

  1. theSpaceShipReference is a reference, so C++ looks up the correct method in the vtable. In this case, it will call ApolloSpacecraft::CollideWith(Asteroid&).
  2. Within ApolloSpacecraft::CollideWith(Asteroid&), inAsteroid is a reference, so inAsteroid.CollideWith(*this) will result in another vtable lookup. In this case, inAsteroid is a reference to an ExplodingAsteroid so ExplodingAsteroid::CollideWith(ApolloSpacecraft&) will be called.

Double dispatch in C#

In C#, when calling an instance method accepting an argument, multiple dispatch can be achieved without employing the visitor pattern. This is done by using traditional polymorphism while also casting the argument to dynamic. [3] The run-time binder will choose the appropriate method overload at run-time. This decision will take into consideration the run-time type of the object instance (polymorphism) as well as the run-time type of the argument.

Double dispatch in Eiffel

The Eiffel programming language can bring the concept of agents to bear on the double-dispatch problem. The example below applies the agent language construct to the double-dispatch problem.

Consider a problem domain with various forms of SHAPE and of drawing SURFACE upon which to draw a SHAPE. Both SHAPE and SURFACE know about a function called `draw' in themselves, but not in each other. We want objects of the two types to co-variantly interact with each other in a double-dispatch using a visitor pattern.

The challenge is to get a polymorphic SURFACE to draw a polymorphic SHAPE on itself.

Output

The output example below shows the results of two SURFACE visitor objects being polymorphically passed over a list of polymorphic SHAPE objects. The visitor code pattern is only aware of SHAPE and SURFACE generically and not of the specific type of either. Instead, the code relies on run-time polymorphism and the mechanics of agents to achieve a highly flexible co-variant relationship between these two deferred classes and their descendants.

draw a red POLYGON on ETCHASKETCH draw a red POLYGON on GRAFFITI_WALL draw a grey RECTANGLE on ETCHASKETCH draw a grey RECTANGLE on GRAFFITI_WALL draw a green QUADRILATERAL on ETCHASKETCH draw a green QUADRILATERAL on GRAFFITI_WALL draw a blue PARALLELOGRAM on ETCHASKETCH draw a blue PARALLELOGRAM on GRAFFITI_WALL draw a yellow POLYGON on ETCHASKETCH draw a yellow POLYGON on GRAFFITI_WALL draw a purple RECTANGLE on ETCHASKETCH draw a purple RECTANGLE on GRAFFITI_WALL

Setup

Before looking at SHAPE or SURFACE, we need to examine the high level decoupled use of our double-dispatch.

Visitor pattern

The visitor pattern works by way of a visitor object visiting the elements of a data structure (e.g. list, tree and so on) polymorphically, applying some action (call or agent) against the polymorphic element objects in the visited target structure.

In our example below, we make a list of polymorphic SHAPE objects, visiting each of them with a polymorphic SURFACE, asking the SHAPE to be drawn on the SURFACE.

make-- Print shapes on surfaces.locall_shapes:ARRAYED_LIST[SHAPE]l_surfaces:ARRAYED_LIST[SURFACE]docreatel_shapes.make(6)l_shapes.extend(create{POLYGON}.make_with_color("red"))l_shapes.extend(create{RECTANGLE}.make_with_color("grey"))l_shapes.extend(create{QUADRILATERAL}.make_with_color("green"))l_shapes.extend(create{PARALLELOGRAM}.make_with_color("blue"))l_shapes.extend(create{POLYGON}.make_with_color("yellow"))l_shapes.extend(create{RECTANGLE}.make_with_color("purple"))createl_surfaces.make(2)l_surfaces.extend(create{ETCHASKETCH}.make)l_surfaces.extend(create{GRAFFITI_WALL}.make)acrossl_shapesasic_shapesloopacrossl_surfacesasic_surfacesloopic_surfaces.item.drawing_agent(ic_shapes.item.drawing_data_agent)endendend

We start by creating a collection of SHAPE and SURFACE objects. We then iterate over one of the lists (SHAPE), allowing elements of the other (SURFACE) to visit each of them in turn. In the example code above, SURFACE objects are visiting SHAPE objects.

The code makes a polymorphic call on {SURFACE}.draw indirectly by way of the `drawing_agent', which is the first call (dispatch) of the double-dispatch pattern. It passes an indirect and polymorphic agent (`drawing_data_agent'), allowing our visitor code to only know about two things:

  • What is the drawing agent of the surface (e.g. al_surface.drawing_agent on line #21)?
  • What is the drawing data agent of the shape (e.g. al_shape.drawing_data_agent on line #21)?

Because both SURFACE and SHAPE define their own agents, our visitor code is freed from having to know what is the appropriate call to make, polymorphically or otherwise. This level of indirection and decoupling is simply not achievable in other common languages like C, C++ and Java except through either some form of reflection or feature overloading with signature matching.

SURFACE

Within the polymorphic call to {SURFACE}.draw is the call to an agent, which becomes the second polymorphic call or dispatch in the double-dispatch pattern.

deferredclassSURFACEfeature{NONE}-- Initializationmake-- Initialize Current.dodrawing_agent:=agentdrawendfeature-- Accessdrawing_agent:PROCEDURE[ANY,TUPLE[STRING,STRING]]-- Drawing agent of Current.feature{NONE}-- Implementationdraw(a_data_agent:FUNCTION[ANY,TUPLE,TUPLE[name,color:STRING]])-- Draw `a_shape' on Current.locall_result:TUPLE[name,color:STRING]dol_result:=a_data_agent(Void)print("draw a "+l_result.color+" "+l_result.name+" on "+type+"%N")endtype:STRING-- Type name of Current.deferredendend

The agent argument in line #19 and call in line #24 are both polymorphic and decoupled. The agent is decoupled because the {SURFACE}.draw feature has no idea what class `a_data_agent' is based on. There is no way to tell what class the operation agent was derived from, so it does not have to come from SHAPE or one of its descendants. This is a distinct advantage of Eiffel agents over the single inheritance, dynamic and polymorphic binding of other languages.

The agent is dynamically polymorphic at run-time because the object is created in the moment it is needed, dynamically, where the version of the objectified routine is determined at that time. The only strongly bound knowledge is of the Result type of the agent signature—that is—a named TUPLE with two elements. However, this specific requirement is based on a demand of the enclosing feature (e.g. line #25 uses the named elements of the TUPLE to fulfill `draw' feature of SURFACE), which is necessary and has not been avoided (and perhaps cannot be).

Finally, note how only the `drawing_agent' feature is exported to ANY client! This means that the visitor pattern code (who is the ONLY client of this class) only needs to know about the agent to get its job done (e.g. using the agent as the feature applied to the visited objects).

SHAPE

The SHAPE class has the basis (e.g. drawing data) for what is drawn, perhaps on a SURFACE, but it does not have to be. Again, the agents provide the indirection and class agnostics required to make the co-variant relationship with SHAPE as decoupled as possible.

Additionally, please take note of the fact that SHAPE only provides `drawing_data_agent' as a fully exported feature to any client. Therefore, the only way to interact with SHAPE, other than creation, is through the facilities of the `drawing_data_agent', which is used by ANY client to indirectly and polymorphically gather drawing data for the SHAPE!

deferredclassSHAPEfeature{NONE}-- Initializationmake_with_color(a_color:likecolor)-- Make with `a_color' as `color'.docolor:=a_colordrawing_data_agent:=agentdrawing_dataensurecolor_set:color.same_string(a_color)endfeature-- Accessdrawing_data_agent:FUNCTION[ANY,TUPLE,likedrawing_data]-- Data agent for drawing.feature{NONE}-- Implementationdrawing_data:TUPLE[name:likename;color:likecolor]-- Data needed for drawing of Current.doResult:=[name,color]endname:STRING-- Object name of Current.deferredendcolor:STRING-- Color of Current.end

Classic Spaceship example

A variation of the classic Spaceship example has one or more spaceship objects roaming about a universe filled with other items like rogue asteroids and space stations. What we want is a double-dispatch method for handling encounters (e.g. possible collisions) between two co-variant objects in our make-believe universe. In our example below, the output excursion of our USS Enterprise and USS Excelsior will be:

Starship Enterprise changes position from A-001 to A-002. Starship Enterprise takes evasive action, avoiding Asteroid `Rogue 1'! Starship Enterprise changes position from A-002 to A-003. Starship Enterprise takes evasive action, avoiding Asteroid `Rogue 2'! Starship Enterprise beams a science team to Starship Excelsior as they pass! Starship Enterprise changes position from A-003 to A-004. Starship Excelsior changes position from A-003 to A-005. Starship Enterprise takes evasive action, avoiding Asteroid `Rogue 3'! Starship Excelsior is near Space Station Deep Space 9 and is dockable. Starship Enterprise changes position from A-004 to A-005. Starship Enterprise beams a science team to Starship Excelsior as they pass! Starship Enterprise is near Space Station Deep Space 9 and is dockable. 

Visitor

The visitor for the classic Spaceship example also has a double-dispatch mechanism.

make-- Allow SPACESHIP objects to visit and move about in a universe.locall_universe:ARRAYED_LIST[SPACE_OBJECT]l_enterprise,l_excelsior:SPACESHIPdocreatel_enterprise.make_with_name("Enterprise","A-001")createl_excelsior.make_with_name("Excelsior","A-003")createl_universe.make(0)l_universe.force(l_enterprise)l_universe.force(create{ASTEROID}.make_with_name("Rogue 1","A-002"))l_universe.force(create{ASTEROID}.make_with_name("Rogue 2","A-003"))l_universe.force(l_excelsior)l_universe.force(create{ASTEROID}.make_with_name("Rogue 3","A-004"))l_universe.force(create{SPACESTATION}.make_with_name("Deep Space 9","A-005"))visit(l_enterprise,l_universe)l_enterprise.set_position("A-002")visit(l_enterprise,l_universe)l_enterprise.set_position("A-003")visit(l_enterprise,l_universe)l_enterprise.set_position("A-004")l_excelsior.set_position("A-005")visit(l_enterprise,l_universe)visit(l_excelsior,l_universe)l_enterprise.set_position("A-005")visit(l_enterprise,l_universe)endfeature{NONE}-- Implementationvisit(a_object:SPACE_OBJECT;a_universe:ARRAYED_LIST[SPACE_OBJECT])-- `a_object' visits `a_universe'.doacrossa_universeasic_universeloopcheckattached{SPACE_OBJECT}ic_universe.itemasal_universe_objectthena_object.encounter_agent.call([al_universe_object.sensor_data_agent])endendend

The double-dispatch can be seen in line #35, where two indirect agents are working together to provide two co-variant calls working in perfect polymorphic concert with each other. The `a_object' of the `visit' feature has an `encounter_agent' which is called with the sensor data of the `sensor_data_agent' coming from the `al_universe_object'. The other interesting part of this particular example is the SPACE_OBJECT class and its `encounter' feature:

Visitor action

The only exported features of a SPACE_OBJECT are the agents for encounter and sensor data, as well as the capacity to set a new position. As one object (the spaceship) visits each object in the universe, the sensor data is collected and passed to the visiting object in its encounter agent. There, the sensor data from the sensor_data_agent (that is—the data element items of the sensor_data TUPLE as returned by the sensor_data_agent query) are evaluated against the current object and a course of action is taken based on that evaluation (see `encounter' in SPACE_OBJECT below). All other data is exported to {NONE}. This is similar to C, C++ and Java scopes of Private. As non-exported features, the data and routines are used only internally by each SPACE_OBJECT. Finally, note that encounter calls to `print' do not include specific information about possible descendant classes of SPACE_OBJECT! The only thing found at this level in the inheritance are general relational aspects based completely on what can be known from the attributes and routines of a general SPACE_OBJECT. The fact that the output of the `print' makes sense to us, as human beings, based on what we know or imagine about Star ships, space stations and asteroids is merely logical planning or coincidence. The SPACE_OBJECT is not programmed with any specific knowledge of its descendants.

deferredclassSPACE_OBJECTfeature{NONE}-- Initializationmake_with_name(a_name:likename;a_position:likeposition)-- Initialize Current with `a_name' and `a_position'.doname:=a_nameposition:=a_positionsensor_data_agent:=agentsensor_dataencounter_agent:=agentencounterensurename_set:name.same_string(a_name)position_set:position.same_string(a_position)endfeature-- Accessencounter_agent:PROCEDURE[ANY,TUPLE]-- Agent for managing encounters with Current.sensor_data_agent:FUNCTION[ANY,TUPLE,attachedlikesensor_data_anchor]-- Agent for returning sensor data of Current.feature-- Settingsset_position(a_position:likeposition)-- Set `position' with `a_position'.doprint(type+" "+name+" changes position from "+position+" to "+a_position+".%N")position:=a_positionensureposition_set:position.same_string(a_position)endfeature{NONE}-- Implementationencounter(a_sensor_agent:FUNCTION[ANY,TUPLE,attachedlikesensor_data_anchor])-- Detect and report on collision status of Current with `a_radar_agent'.doa_sensor_agent.call([Void])checkattached{likesensor_data_anchor}a_sensor_agent.last_resultasal_sensor_datathenifnotname.same_string(al_sensor_data.name)thenif(position.same_string(al_sensor_data.position))thenif((al_sensor_data.is_dockableandis_dockable)and(is_mannedandal_sensor_data.is_manned)and(is_manueverableandal_sensor_data.is_not_manueverable))thenprint(type+" "+name+" is near "+al_sensor_data.type+" "+al_sensor_data.name+" and is dockable.%N")elseif((is_dockableandal_sensor_data.is_dockable)and(is_mannedandal_sensor_data.is_manned)and(is_manueverableandal_sensor_data.is_manueverable))thenprint(type+" "+name+" beams a science team to "+al_sensor_data.type+" "+al_sensor_data.name+" as they pass!%N")elseif(is_mannedandal_sensor_data.is_not_manned)thenprint(type+" "+name+" takes evasive action, avoiding "+al_sensor_data.type+" `"+al_sensor_data.name+"'!%N")endendendendendname:STRING-- Name of Current.type:STRING-- Type of Current.deferredendposition:STRING-- Position of Current.is_dockable:BOOLEAN-- Is Current dockable with another manned object?deferredendis_manned:BOOLEAN-- Is Current a manned object?deferredendis_manueverable:BOOLEAN-- Is Current capable of being moved?deferredendsensor_data:attachedlikesensor_data_anchor-- Sensor data of Current.doResult:=[name,type,position,is_dockable,notis_dockable,is_manned,notis_manned,is_manueverable,notis_manueverable]endsensor_data_anchor:detachableTUPLE[name,type,position:STRING;is_dockable,is_not_dockable,is_manned,is_not_manned,is_manueverable,is_not_manueverable:BOOLEAN]-- Sensor data type anchor of Current.end

There are three descendant classes of SPACE_OBJECT:

SPACE_OBJECTASTEROIDSPACESHIPSPACESTATION

In our example, the ASTEROID class is used for the `Rogue' items, SPACESHIP for the two star ships and SPACESTATION for Deep Space Nine. In each class, the only specialization is the setting of the `type' feature and of certain properties of the object. The `name' is supplied in the creation routine as well as the `position'. For example: Below is the SPACESHIP example.

classSPACESHIPinheritSPACE_OBJECTcreatemake_with_namefeature{NONE}-- Implementationtype:STRING="Starship"-- <Precursor>is_dockable:BOOLEAN=True-- <Precursor>is_manned:BOOLEAN=True-- <Precursor>is_manueverable:BOOLEAN=True-- <Precursor>end

So, any SPACESHIP in our universe is dock-able, manned and maneuverable. Other objects, like Asteroids are none of these things. A SPACESTATION, on the other hand, is both dock-able and manned, but is not maneuverable. Thus, when one object has an encounter with another, it first checks to see if the positions put them in the vicinity of each other and if they are, then the objects interact based upon their basic properties. Note that objects with the same type and name are considered to the same object, so an interaction is logically disallowed.

Eiffel example conclusion

With regards to double-dispatch, Eiffel allows the designer and programmer to further remove a level of direct object-to-object knowledge by decoupling class routines from their classes by way of making them agents and then passing those agents instead of making direct object feature calls. The agents also have specific signatures and possible results (in the case of queries), making them ideal static type checking vehicles without giving up specific object details. The agents are fully polymorphic so that the resulting code has only the specific knowledge required to get its local job done. Otherwise, there is no maintenance burden added by having specific internal class feature knowledge spread around many co-variant objects. The use and mechanics of agents ensure this. One possible downside of the use of agents is that an agent is computationally more expensive than its direct call counterpart. With this in mind, one ought never to presume the use of agents in the double-dispatch and their application in visitor patterns. If one can clearly see a design limit as to the domain of class types that will be involved in the co-variant interactions, then a direct call is the more efficient solution in terms of computational expense. However, if the class domain of participating types is expected to grow or differ substantially, then agents present an excellent solution to lessening the maintenance burden in the double-dispatch pattern.

See also

Related Research Articles

Asteroid Astronomical object

An asteroid is a minor planet of the inner Solar System. Sizes and shapes of asteroids vary significantly, ranging from 1-meter rocks to dwarf planets almost 1000 km in diameter; they are metallic or rocky bodies with no atmosphere.

<i>Deep Space 1</i> NASA spacecraft launched in 1998

Deep Space 1 (DS1) was a NASA technology demonstration spacecraft which flew by an asteroid and a comet. It was part of the New Millennium Program, dedicated to testing advanced technologies.

Starship <i>Enterprise</i> Series of fictional spacecraft

Enterprise or USS Enterprise is the name of several fictional spacecraft, some of which are the main craft and setting for various television series and films in the Star Trek science fiction franchise. The most notable were Captain James T. Kirk's USS Enterprise (NCC-1701) from the original 1960s television series, and Captain Jean-Luc Picard's USS Enterprise (NCC-1701-D) from Star Trek: The Next Generation.

<i>NEAR Shoemaker</i> American robotic space probe launched in 1996 to study the near-Earth asteroid 433 Eros

Near Earth Asteroid Rendezvous – Shoemaker, renamed after its 1996 launch in honor of planetary scientist Eugene Shoemaker, was a robotic space probe designed by the Johns Hopkins University Applied Physics Laboratory for NASA to study the near-Earth asteroid Eros from close orbit over a period of a year. It was the first spacecraft to successfully orbit an asteroid and also land on an asteroid. In February 2000, the mission succeeded in closing in with the asteroid and afterwards orbited it several times. On February 12, 2001, the mission succeeded in touching down on the asteroid. It was terminated just over two weeks later.

Spacecraft Vehicle or machine designed to fly in space

A spacecraft is a vehicle or machine designed to fly in outer space. A type of artificial satellite, spacecraft are used for a variety of purposes, including communications, Earth observation, meteorology, navigation, space colonization, planetary exploration, and transportation of humans and cargo. All spacecraft except single-stage-to-orbit vehicles cannot get into space on their own, and require a launch vehicle.

Spaceflight Flight into or through outer space

Spaceflight is an application of astronautics to fly spacecraft into or through outer space, either with or without humans on board. Most spaceflight is uncrewed and conducted mainly with spacecraft such as satellites in orbit around Earth, but also includes space probes for flights beyond Earth orbit. Such spaceflight operates either by telerobotic or autonomous control. The more complex human spaceflight has been pursued soon after the first orbital satellites and has reached the Moon and permanent human presence in space around Earth, particularly with the use of space stations. Human spaceflight programs include the Soyuz, Shenzhou, the past Apollo Moon landing and the Space Shuttle programs, with currently the International Space Station as the main destination of human spaceflight missions while China's Tiangong Space Station is under construction.

<i>Clementine</i> (spacecraft) American space project

Clementine was a joint space project between the Ballistic Missile Defense Organization and NASA, launched on January 25, 1994. Its objective was to test sensors and spacecraft components in long-term exposure to space and to make scientific observations of both the Moon and the near-Earth asteroid 1620 Geographos.

Surveyor 6

Surveyor 6 was the sixth lunar lander of the American uncrewed Surveyor program that reached the surface of the Moon. Surveyor 6 landed on the Sinus Medii. A total of 30,027 images were transmitted to Earth.

Multiple dispatch or multimethods is a feature of some programming languages in which a function or method can be dynamically dispatched based on the run-time (dynamic) type or, in the more general case, some other attribute of more than one of its arguments. This is a generalization of single-dispatch polymorphism where a function or method call is dynamically dispatched based on the derived type of the object on which the method has been called. Multiple dispatch routes the dynamic dispatch to the implementing function or method using the combined characteristics of one or more arguments.

In programming language theory and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types. The concept is borrowed from a principle in biology where an organism or species can have many different forms or stages.

B612 Foundation Planetary defense nonprofit organization

The B612 Foundation is a private nonprofit foundation headquartered in Mill Valley, California, United States, dedicated to planetary science and planetary defense against asteroids and other near-Earth object (NEO) impacts. It is led mainly by scientists, former astronauts and engineers from the Institute for Advanced Study, Southwest Research Institute, Stanford University, NASA and the space industry.

Celestia Astronomy computer program

Celestia is a 3D astronomy software program created by Chris Laurel. The program allows users to virtually travel through a simulated version of our universe. Celestia can display objects of various scales using OpenGL.

USS <i>Enterprise</i> (NCC-1701) Fictional starship in Star Trek with registry number NCC-1701

USS Enterprise (NCC-1701) is a fictional starship in the Star Trek media franchise. It is the main setting of the original Star Trek television series (1966–69), and it is depicted in films, other television series, spin-off fiction, products, and fan-created media. Under the command of Captain James T. Kirk, the Enterprise carries its crew on a mission "to explore strange, new worlds; to seek out new life and new civilizations; to boldly go where no man has gone before." The 2022 series Star Trek: Strange New Worlds depicts the Enterprise under the command of Kirk's predecessor, Captain Christopher Pike.

<i>Hayabusa2</i> Japanese space mission to asteroid Ryugu

Hayabusa2 is an asteroid sample-return mission operated by the Japanese state space agency JAXA. It is a successor to the Hayabusa mission, which returned asteroid samples for the first time in June 2010. Hayabusa2 was launched on 3 December 2014 and rendezvoused in space with near-Earth asteroid 162173 Ryugu on 27 June 2018. It surveyed the asteroid for a year and a half and took samples. It left the asteroid in November 2019 and returned the samples to Earth on 5 December 2020 UTC. Its mission has now been extended through at least 2031, when it will rendezvous with the small, rapidly-rotating asteroid 1998 KY26.

Spacecraft magnetometer

Spacecraft magnetometers are magnetometers used aboard spacecraft and satellites, mostly for scientific investigations, plus attitude sensing. Magnetometers are among the most widely used scientific instruments in exploratory and observation satellites. These instruments were instrumental in mapping the Van Allen radiation belts around Earth after its discovery by Explorer 1, and have detailed the magnetic fields of the Earth, Moon, Sun, Mars, Venus and other planets and moons. There are ongoing missions using magnetometers, including attempts to define the shape and activity of Saturn's core.

Space architecture Architecture of off-planet habitable structures

Space architecture is the theory and practice of designing and building inhabited environments in outer space. This mission statement for space architecture was developed at the World Space Congress in Houston in 2002 by members of the Technical Aerospace Architecture Subcommittee of the American Institute of Aeronautics and Astronautics (AIAA). The architectural approach to spacecraft design addresses the total built environment. It is mainly based on the field of engineering, but also involves diverse disciplines such as physiology, psychology, and sociology.

162173 Ryugu Apollo asteroid

162173 Ryugu, provisional designation 1999 JU3, is a near-Earth object and a potentially hazardous asteroid of the Apollo group. It measures approximately 1 kilometre (0.62 mi) in diameter and is a dark object of the rare spectral type Cb, with qualities of both a C-type asteroid and a B-type asteroid. In June 2018, the Japanese spacecraft Hayabusa2 arrived at the asteroid. After making measurements and taking samples, Hayabusa2 left Ryugu for Earth in November 2019 and returned the sample capsule to Earth on 5 December 2020.

The space-opera blockbuster Star Wars franchise has borrowed many real-life scientific and technological concepts in its settings. In turn, Star Wars has depicted, inspired, and influenced several futuristic technologies, some of which are in existence and others under development. In the introduction of the Return of the Jedi novelization, George Lucas wrote: "Star Wars is also very much concerned with the tension between humanity and technology, an issue which, for me, dates back even to my first films. In Jedi, the theme remains the same, as the simplest of natural forces brought down the seemingly invincible weapons of the evil Empire."

<i>Hera</i> (space mission)

Hera is a space mission in development at the European Space Agency in its Space Safety program, which objective is to contribute to validate the kinetic impact method to possibly deviate a near-Earth asteroid in a colliding trajectory with Earth. It will measure the size and the morphology of the crater and momentum transmitted by an artificial projectile during an impact on an asteroid, which will allow measuring the efficiency of the deflection produced by the impact. This being a test, the asteroid and the deflection test have been chosen in order not to pose any risk, whatever the result. Furthermore, the mission will fully characterise the composition and physical properties of a binary asteroid, including, for the first time, the sub-surface and internal structures. It will also perform technological demonstrations linked to operations in the vicinity of a small body and the deployment and the communication with CubeSats in interplanetary space.

References

  1. A Simple Technique for Handling Multiple Polymorphism. In Proceedings of OOPSLA '86, Object–Oriented Programming Systems, Languages and Applications, pages 347–349, November 1986. Printed as SIGPLAN Notices, 21(11). ISBN   0-89791-204-7
  2. More Effective C++ by Scott Meyers(Addison-Wesley, 1996)
  3. "Using Type dynamic (C# Programming Guide)". Microsoft Developer Network. Microsoft. 30 Sep 2009. Retrieved 25 May 2016. ... Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic ...