Related
What are the differences between Module and Class in OCaml.
From my searching, I found this:
Both provide mechanisms for abstraction and encapsulation, for
subtyping (by omitting methods in objects, and omitting fields in
modules), and for inheritance (objects use inherit; modules use
include). However, the two systems are not comparable.
On the one hand, objects have an advantage: objects are first-class
values, and modules are not—in other words, modules do not support
dynamic lookup. On the other hand, modules have an advantage: modules
can contain type definitions, and objects cannot.
First, I don't understand what does "Modules do not support dynamic lookup" mean. From my part, abstraction and polymorphism do mean parent pointer can refer to a child instance. Is that the "dynamic lookup"? If not, what actually dynamic lookup means?
In practical, when do we choose to use Module and when Class?
The main difference between Module and Class is that you don't instantiate a module.
A module is basically just a "drawer" where you can put types, functions, other modules, etc... It is just here to order your code. This drawer is however really powerful thanks to functors.
A class, on the other hand, exists to be instantiated. They contains variables and methods. You can create an object from a class, and each object contains its own variable and methods (as defined in the class).
In practice, using a module will be a good solution most of the time. A class can be useful when you need inheritance (widgets for example).
From a practical perspective dynamic lookup lets you have different objects with the same method without specifying to which class/module it belongs. It helps you when using inheritance.
For example, let's use two data structures: SingleList and DoubleLinkedList, which, both, inherit from List and have the method pop. Each class has its own implementation of the method (because of the 'override').
So, when you want to call it, the lookup of the method is done at runtime (a.k.a. dynamically) when you do a list#pop.
If you were using modules you would have to use SingleList.pop list or DoubleLinkedList.pop list.
EDIT: As #Majestic12 said, most of the time, OCaml users tend to use modules over classes. Using the second when they need inheritance or instances (check his answer).
I wanted to make the description practical as you seem new to OCaml.
Hope it can help you.
OK, here's what I want :
I have written several REALLY demanding functions (mostly operating on bitmaps, etc) which have to be as fast as possible
Now, let's also mention that these functions may also be grouped by type, or even by the type of variable on which they operate.
And the thing is, apart from the very implementation of the algorithms, what I should do - from a technical point of view - in order not to mess up the speed.
And now, I'm considering the following scenarios :
Create them as simple functions and just pass the necessary parameters as arguments
Create a class (for 'grouping'/organisation purposes) and just declare them as static
Create class by type, e.g. Create a class for working on bitmaps, create a new instance of that Class for every bitmap (e.g. Bitmap* myBitmap = newBitmap(1010);, and operate on it with its inner methods (e.g. myBitmap->getFirstBitSet())
Now, which of these approaches is the fastest? Is there really any difference between straight simple functions and Class-encapsulated static functions, performance-wise? Any other scenario that would be preferable, which I haven't mentioned?
Sidenote : I'm using the clang++ compiler, for Mac OS X 10.6.8. (if that makes any difference)
At CPU level, there is only one kind of function, and it very much ressemble the C kind. You could craft your own, but...
As it turns out, C++ being built with efficiency in mind maps most functions directly to call instructions:
a namespace level function is like a regular C function
a static method is like a namespace level function (from a call point of view)
a non-static method is very similar to a static method, except an implicit this parameter is passed on top of the other parameters (one pointer)
All those 3 have the exact same kind of performance.
On the other hand, virtual methods have a slight overhead. There was a C++ technical report on performance which estimated the overhead compared to a non-virtual method between 10% and 15% (from memory) for empty functions. Meaning that for any function with meat inside (ie, doing real work), the overhead itself is close to getting lost in the noise. The real cost comes from the inhibition of inlining unless the virtual call can be deduced at compile-time.
There is absolutely no difference between classic old C functions and static methods of classes. The difference is only aesthetic. If you have multiple C functions that have certain relation between them, you can:
group them into a class;
place them into a namespace;
The difference will again be aesthetic. Most likely this will improve readability.
In case if these C functions share some static data, it would make sense (if possible) to define this data as private static data members of a class. In this case variant with the class would be preferable over the variant with namespace.
I would discourage you from creating a dummy instance. This will be misleading to the reader of the source code.
Creating an instance for every bitmap is possible and can even be favorable. Especially if you call methods on this instance several times in a typical scenario.
I was reading "Design Patterns: Elements of Reusable Object-Oriented Software", (specifically the chapter about the prototype design pattern) and it stated that...
"Prototype is particularly useful with static languages like C++ where classes are not objects, and little or no type information is available at run-time." (pg 121)
(emphasis mine)
I had always thought that classes were synonymous to objects, and I'm confused as to what this statement means. How are classes not objects, and why does it matter if a language is static?
A class in C++ is not an object: a class is a description of how to build an object, and a reference to a type of an object.
Compare with a language like Python: in python, like in C++, you instantiate an object from a class. Unlike C++, the class you used is also an object: it usually has type type, and you can create new ones at runtime, manipulate them like any other object, or even create objects which are classes which themselves have different types.
You may be wondering why you'd want this, and usually you don't need it -- it's like C++ template meta-programming, you only need it when you need it because you can't achieve your goal in any other way. It's probably also the case that problems you'd solve in Python with meta-classes you'd solve in C++ using template meta-programming.
In C++, this declares a class:
class A {
public:
int a;
};
whereas this declares an object:
A a;
One cannot interrogate a class a run-time, as one can interrogate an object. It makes sense to say, "object 'a', what is your address? Please invoke operator+. etc." In C++, with its static typing, it makes no sense to say, "Class A, what is your list of members? Please add a new member, "b"."
In other languages (Python comes to mind), one can manipulate classes in this way, because each class is also an object. In addition to serving as a template for objects, the class itself is an object -- it can be printed, modified, etc.
For example, a class could describe what a book is: Name, Author, Date of Publishing, Description.
An object of the "Book" class would be a specific book: C++ Primer Plus, Stephen Prata, 2005, A book that teaches C++.
So, classes are not the same as objects.
To expand on what Andrew Aylett said.
A class in C++ is not an object: a class is a description of how to build an object, and a reference to a type of an object.
Furthermore, in languages like Python or smalltalk. Everything is an object. A function is a object, a class is a object. As such these languages are Dynamically Typed, meaning that types are checked during runtime and variables can take on any type.
C++ is statically typed. Variables can only take on one type, and type checking is performed at compile time.
So in python for instance, you can modify a class on the fly. Add functions and fields, because it is an object, and can be modified.
What that sentence refers is to is the fact that classes are not first-order entities in a language like C++. In other languages, you can pass a class as a parameter to a function, e.g., the same way as you can pass an object or a function as a parameter.
There are many more implications of being classes first-order entities or not, e.g., the possibility of modifying a class at runtime, or inspecting the full internals of a class, etc.
Usually classes are found to be first-order entities in dynamic languages like ruby, or in the meta object protocol for lisp, etc.
Hope this clarifies it a bit.
Classes are not the same as Objects. A class is (more or less) the type, and an Object is the instance, simmiliar to the following:
int i;
YourClass object;
Here you wouldn't say i and int are the same -- neither are YourClass and object.
What the statement wants to say: Many object orientated languages are very object orientated, so that they start making everything (or nearly everything) an object (of one or another class). So in many languages a class would be an instance (hence an object) of some class class (which can be confusing).
This sometimes has advantages, as you can treat classes (that's types) in such languages like you could treat any other object. You can than do very dynamic stuff with them, like store them in variables or even manipulate the classes during runtime (e.g. to create new classes your program finds the need to have).
Take a look at this c++-similiar pseudo code:
YourClass myObject = new YourClass(); // creates an object (an instance)
Class baseClass = myObject.get_class(); // store the class of myObject in baseClass. That's storing a type in a variable (more or less)
Class subClass = myObject.inherit(); // dynamically create a new class, that only exists in variable subClass (a Class-object), inheriting from baseClass
subClass.add_method(some_function); // extend the new class by adding a new method
subClass.get_class() subClass.create_instance(); // declare a new variable (object) of your newly created type
BaseClass another_onne = subClass.create_instance(); // also valid, since you inherited
This obviously doesn't translate well to c++, because of c++'s strict typing. Other languages are more dynamic in typing, and there this flexibility can come in handy (and make thinks more complicated; sometimes both at the same time). Still I think it explains the principle, if you understand c++.
I had always thought that classes were synonymous to objects
The language in OOP literature is sometimes not specific. It doesn't help either that programming languages have somewhat different notions of what an object is.
A class is a template or definition from where objects (instances of that class) are created. That is, a class provides the structure, type signatures and behaviors that objects of that class (or type... more on that later.)
An object is just a location in memory of an instance of that class.
Wikipedia provides good documentation on this. I suggest you read it:
http://en.wikipedia.org/wiki/Class_(computer_programming)
http://en.wikipedia.org/wiki/Object_(object-oriented_programming)
Also, there is the concept of a type. A type (or interface as sometimes called in some literature or programming languages) is typically the collection of type/method signatures (and possibly behavior). Things like Java interfaces and C++ pure virtual classes tend to represent types (but aren't exactly the same).
Then a class that conforms to that type (be it interface or pure virtual class) is an implementation of that type.
That class, that type implementation is just a recipe of how to construct objects of that class/type in memory.
When you instantiate a class/type, you reify, construct an instance (object) of that class in memory.
In C++, a class is not an object since a class itself is not instantiated. A C++ class is not an instance of some other class (see the definitions I put above.)
OTH, in languages like Java, a class itself is represented by instances of a primordial class (java.lang.Class). So a class X has an object in memory (an java.lang.Class instance) associated with it. And with it, with that "class" object, you can (in theory) instantiate or manufacture another instance (or object) of class/type X.
It can get confusing. I strongly suggest you search and read the literature on classes, types, prototypes and objects/instances.
and I'm confused as to what this statement means. How are classes not
objects,
As explained above. A class is not an object. An object is an instance, a piece of memory constructed and initialized by the "recipe" of a class or type.
and why does it matter if a language is static?
That part of the book is a bit misleading because Java, for example, is statically typed and yet, classes can be object themselves. Perhaps the text is refering to dynamically typed languages (like JavaScript) where classes can also be objects or instances.
My suggestion is to never use the word object, and to simply limit the vocabulary to "classes" and "instances". But that's my personal predilection. Other people might disagree, and so be it.
The simpler I can put it for you to understand it:
An object is a "physical" instance of a class. It consumes memory while the program is running.
A class describes an object: Hierarchy, properties, methods. A class it's like a "template" for creating objects.
When a class is said to be an object, it means that there's an object that represents that class at runtime. In C++, classes are dissolved at compile time. Their instances (i.e. objects) are merely sequences of bytes holding the object's fields, without any reference to the class itself. Now, C++ does provide some type information at runtime via RTTI, but that's only for polymorphic types, and is not considered a class object.
The lack of having objects that represent classes at runtime is the reason there's no reflection in C++ - there's just no way to get information about a certain class, as there's no object that represent it.
BTW, C++ is considered a 2-level language: objects are instances of classes, but classes are not instances of anything, because they only exist at compile type. On 3-level languages such as C# and Java, classes are also objects at runtime, and as such, are themselves instances of yet another class (Class in Java, Type in C#). The last class is an instance of itself, hence the language only has 3 levels. There are languages with more levels, but that's beyond the scope of this question...
For the purposes of interoperability with Java, I need a class that has a nullary constructor that performs initialization.
Objects of this class need to have something resembling mutable java fields (namely, the object represents the backend of a game, and needs to keep game state).
deftype does everything I want to do except provide a nullary constructor (since I'm creating a class with fields).
I don't need the fields to be publicly readable, so I can think of 4 solutions:
Use gen-class; I don't want to do this if I can avoid it.
Somehow encoding private member variables outside of the knowledge of deftype; I've been told this can't be done.
Writing a modified deftype that also creates a nullary constructor; frankly I don't know clojure well enough for this.
Taking the class created by deftype and somehow adding a new constructor to it.
At the end of this, I need to have a Java class, since I will be handing it off to Java code that will be making a new object from the class.
Are any of the solutions I suggested (or any that I haven't thought of) other than using gen-class viable?
There's absolutely no shame in, where appropriate, writing a dash of Java if your Java interop requirements are simultaneously specific and unshakable. You could write a Java class with a single static factory method that returns an instance of the deftype class and that does whatever initialization/setup you need.
Alternatively, you can write a nullary factory function in Clojure, and call that directly from Java all day long.
In any case, neither deftype nor defrecord are intended to be (or will they ever be) fully-featured interop facilities. gen-class certainly comes the closest, which is why it's been recommended.
I'd suggest just writing the object in Java - for Java-like objects with mutable fields it will probably be more elegant, understandable and practical.
I've generally had pretty good results mixing Java and Clojure code in projects. This seems like one of those cases where this might be appropriate. The interoperability is so good that you barely have any extra complexity.
BTW - I'm assuming that you need a nullary constructor to meet the requirements of some persistence library or something similar? It seems like an odd requirement otherwise. If this is the case then you may find it makes sense to rethink your persistence strategy..... arbitrary restrictions like this always seem like a bit of a code smell to me.
I was reading the GoF book and in the beginning of the prototype section I read this:
This benefit applies primarily to
languages like C++ that don't treat
classes as first class objects.
I've never used C++ but I do have a pretty good understanding of OO programming, yet, this doesn't really make any sense to me. Can anyone out there elaborate on this (I have used\use: C, Python, Java, SQL if that helps.)
For a class to be a first class object, the language needs to support doing things like allowing functions to take classes (not instances) as parameters, be able to hold classes in containers, and be able to return classes from functions.
For an example of a language with first class classes, consider Java. Any object is an instance of its class. That class is itself an instance of java.lang.Class.
For everybody else, heres the full quote:
"Reduced subclassing. Factory Method
(107) often produces a hierarchy of
Creator classes that parallels the
product class hierarchy. The Prototype
pattern lets you clone a prototype
instead of asking a factory method to
make a new object. Hence you don't
need a Creator class hierarchy at all.
This benefit applies primarily to
languages like C++ that don't treat
classes as first-class objects.
Languages that do, like Smalltalk and
Objective C, derive less benefit,
since you can always use a class
object as a creator. Class objects
already act like prototypes in these
languages." - GoF, page 120.
As Steve puts it,
I found it subtle in so much as one
might have understood it as implying
that /instances/ of classes are not
treated a first class objects in C++.
If the same words used by GoF appeared
in a less formal setting, they may
well have intended /instances/ rather
than classes. The distinction may not
seem subtle to /you/. /I/, however,
did have to give it some thought.
I do believe the distinction is
important. If I'm not mistaken, there
is no requirement than a compiled C++
program preserve any artifact by which
the class from which an object is
created could be reconstructed. IOW,
to use Java terminology, there is no
/Class/ object.
In Java, every class is an object in and of itself, derived from java.lang.Class, that lets you access information about that class, its methods etc. from within the program. C++ isn't like that; classes (as opposed to objects thereof) aren't really accessible at runtime. There's a facility called RTTI (Run-time Type Information) that lets you do some things along those lines, but it's pretty limited and I believe has performance costs.
You've used python, which is a language with first-class classes. You can pass a class to a function, store it in a list, etc. In the example below, the function new_instance() returns a new instance of the class it is passed.
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
C# and Java programs can be aware of their own classes because both .NET and Java runtimes provide reflection, which, in general, lets a program have information about its own structure (in both .NET and Java, this structure happens to be in terms of classes).
There's no way you can afford reflection without relying upon a runtime environment, because a program cannot be self-aware by itself*. But if the execution of your program is managed by a runtime, then the program can have information about itself from the runtime. Since C++ is compiled to native, unmanaged code, there's no way you can afford reflection in C++**.
...
* Well, there's no reason why a program couldn't read its own machine code and "try to make conclusions" about itself. But I think that's something nobody would like to do.
** Not strictly accurate. Using horrible macro-based hacks, you can achieve something similar to reflection as long as your class hierarchy has a single root. MFC is an example of this.
Template metaprogramming has offered C++ more ways to play with classes, but to be honest I don't think the current system allows the full range of operations people may want to do (mainly, there is no standard way to discover all the methods available to a class or object). That's not an oversight, it is by design.