Automatic inheritance of bindings in Racket subclasses - oop

I'm having a class with several subclasses that all uses methods and fields from the parent-class. Is there a "correct" way of handling this?
So far I've been using (inherit method1 method2 ...) in each subclass.
I've searched in vain for a way that the parent-class can force the subclasses to inherit the bindings, and I understand that that might be bad style.
Not very experienced with Racket or OOP.

The methods are inherited even if you don't use inherit.
To call a method from a super class, one can use (send this method arg1 ...).
The form (inherit method) inside a class form will make the method available in form (method arg1 ...) inside the body. This is not just a convenient shorthand, but is also more efficient than (send this method).
I am unaware of forms that package names to inherit, but you can roll your own with a little macro. Here is an example:
(define-syntax (inherit-from-car stx)
(datum->syntax stx '(inherit wash buy sell)))
(define car% (class object%
(define/public (wash) (display "Washing\n"))
(define/public (buy) (display "Buying\n"))
(define/public (sell) (display "Selling\n"))
(super-new)))
(define audi% (class car% (super-new)
(inherit-from-car)
(define/public (wash-and-sell)
(wash)
(sell))))
(define a-car (new audi%))
(send a-car wash-and-sell)

Related

How can I access a class field by its name in racket?

I can access a class field by defining a method so (send joe get-name) will return me Joe. But can I get the same behavior without adding a method and just by calling a field, like this: (send joe name)?
#lang racket
(define person%
(class object%
(init-field name)
(super-new)
(define/public (get-name) name) ))
(define joe (new person% [name 'Joe]))
I think you're looking for get-field.
Example of usage: (get-field name joe)
Let me know if I've misunderstood your question.

What is the difference between polymorphism and duck typing?

I'm a little confused with the two terms, here's what I know:
Polymorphism is the ability of object of different types to be handled by a common interface. While duck typing, is a kind of dynamic typing that allows objects of different types to respond to the same methods.
From what I understand, polymorphism is more about creating an interface that can be shared across different classes. And duck typing is about loose typing that will allow methods to be called as long as it is found on the receiver of the message.
Is this correct? I'm pretty confused on the two, they seem related but I do not know what their relationship is. Thanks a lot in advance!
Polymorphism (in the context of object-oriented programming) means a subclass can override a method of the base class. This means a method of a class can do different things in subclasses. For example: a class Animal can have a method talk() and the subclasses Dog and Cat of Animal can let the method talk() make different sounds.
Duck typing means code will simply accept any object that has a particular method. Let's say we have the following code: animal.quack(). If the given object animal has the method we want to call then we're good (no additional type requirements needed). It does not matter whether animal is actually a Duck or a different animal which also happens to quack. That's why it is called duck typing: if it looks like a duck (e.g., it has a method called quack() then we can act as if that object is a duck).
So are these related? They are simply separate features that a programming language may have. There are programming languages which have polymorphism but that do not have duck typing (such as Java). There are also languages that have polymorphism and duck typing (such as Python).
This is an example for Polymorphism in Python.
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal)
print(animal.name + ': ' + animal.talk())
This is an example for duck Typing in Python.
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
def name(self):
print("ITS A DUCK NO NAME")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")
def in_the_forest(duck):
duck.quack()
duck.feathers()
duck.name()
def game():
for element in [Duck(), Person()]:
in_the_forest(element)
game()
In polymorphism we see subclass (Cat and Dog) inheriting from the parent class (Animal) and overriding the method Talk.
In case of duck typing we don’t create a subclass instead new class is created with method having same name but different function.
Short Answer:
Duck typing is one way of achieving Polymorphism.
Another way is by using static typing.
Long Answer:
There are two different concepts involved here, typing and programming technique.
Duck typing is a type of typing. And typing means when to throw error when an object passed around isn't what is expected. Duck typing is a kind of typing where it throws error when the program is running and the method being called isn't available. Static typing comes with compile time checking, so if the type info doesn't match, it will throw error when you compile the code. And that is typing.
Polymorphism is a programming technique where you allow multiple types of object to fulfill certain responsibilities. You can do that by using a base type to represent all the child class types. You can use duck typing to represent all the different types that have the needed methods. You can use an interface to represent all the types that implement the interface.
There are answers saying polymorphism is inheritance, and that is not correct. Although you can use inheritance to create polymorphic behavior and usually that's what you do, but that's not what polymorphism is about.
For one, you don't need inheritance to have polymorphism as described above.
Secondly, the term "Polymorphism" is more meaningful in the context of the client code that depends on abstraction, and not the implementation code. Just because you have a super class and a few other classes that inherit from it and overriding some methods does not mean it's polymorphism, to create polymorphism you have to write client code in a polymorphic way to consume these classes.
Two type Polymorphism
Method overloading(Compile time Polymorphism ).
Method overriding(Run Time Polymorphism ).
Method overloading :- same function name and different data type is known as Method overloading
Example :
int addTwovalues(int a, int b)
{ return (a+b)}
float addTwovalues(float a, float b)
{ return (a+b)}
Method overriding :- same function name and same data type but different Class
is known as Method overriding.
class a
{
virtual int addtwovalues()
{ // to do }
}
class b:a
{
override int addtwovalues()
{ // to do }
}
a obj=new a();
obj.addtwovalues();
b objb=new a();
objb.addtwovalues(); //run time Polymorphism

cannot define a constructor as a bound function

class A
constructor: ->
method: ->
In the above example, method is not bound to the class and neither is constructor.
class B
constructor: ->
method: =>
In this case, method is bound to the class. It behaves as you expect a normal object method to behave and has access to all of class B's fields. But the constructor is not bound? That seems strange. So i tried the following.
class C
constructor: =>
method: =>
This doesn't compile. I would expect the syntax to be the same on all methods that are bound to a class.
I would like to regard the -> operator as a static operator and the => operator as a dynamic operator. But it doesn't seem like you can. If you could, a method with the -> operator could not be called with super. But, in actuality, you can. Why does this make sense for the syntax of an object oriented language? This seems to not agree with most object oriented languages inheritance rules.
Try looking at how the code compiles. When you use =>, the methods are bound inside the constructor. Thus, it doesn't make any sense to use => for a constructor - when would it be bound?
I'm not sure about your issue with static vs. dynamic operators, but you can definitely call methods defined with the -> operator with super. The only thing -> vs => affects is that the => ensures that this is the object in question regardless of how it is called.
Summary of comments:
Calling the difference between -> and => analogous to static vs. dynamic (or virtual) does not quite convey what those operators do. They are used to get different behavior from javascript's this variable. For example, look at the following code:
class C
constructor: ->
method1: ->
console.log this
method2: =>
console.log this
c = new C()
c.method1() //prints c
f = c.method1;f() //prints window
c.method2() //prints c
f = c.method2;f() //prints c
The difference is in the second way we call each method: if the method is not "bound" to the object, its this is set by looking at what precedes the method call (separated by a .). In the first case, this is c, but in the second f isn't being called on an object, so this is set to window. method2 doesn't have this problem because it is bound to the object.
Normally, you can think of the the constructor function automatically being bound to the object that it is constructing (thus, you can't bind it with =>). However, its worth noting that this isn't quite what's happening, because if a constructor returns an object, that will be the return value of the construction, rather than the this during the constructor.
I think you're massively confused as to the meaning of the '=>', or fat arrow.
First off though, your examples aren't actually valid coffeescript, are they? There is no -> after the class declaration. Adding one is a compiler error.
Back to the fat arrow, there's no mapping to the terms static and dynamic that I can think of, that would apply here. Instead the fat arrow is a convenient syntactic sugar for wrapping a function with a closure that contains the reference to the object you're calling the function on.
The C++ analog is to possibly to say that the fat arrow is a method for automatically creating a functor: it lets you give the function as a callback to a third party who can call it without knowing your object, but where the code invoked inside will have access to your object as the this pointer. It serves no other purpose, and has no bearing on whether a function can be overloaded, or whether it can have access to super.

how to downcast a list of objects without using a function

I got a list of Objects of class-type B (B inherits from A).
How can I downcast all the B-objects to A-objects without using a function to pull the needed information and create a new instance?
(defclass A () ( (varI :initarg :varI :accessor varI) ) )
(defclass B (A) ( (varII :initarg :varII :accessor varII) ) )
(defun generate-list-of-type-B-objects () (....does...some..stuff....))
(defvar *listoftypeA* (generate-list-of-type-B-objects) )
(I know this example is easy to rewrite, as I could make the method generate a list of type A objects, but the function is used somewhere else where type-B objects are needed, and I do not want to duplicate code)
If you absolutely must convert your instances of class B into instances of class A, you can do a one-way conversion of them with the use of CHANGE-CLASS. This is a non-reversible change of each instance.
Since I am not 100% sure what you actually want, the best suggestion I can give is "have you tried leaving them as class B and see if it works?"
Chances are that it will just work, unless you have methods of a generic function somewhere that treat instances of class B differently than instances of class A. If it's only about dropping the space that the extra slot would take, have you measured that it's actually worth it (it probably isn't, unless you have several thousands of instances of class B, where you could get by with instances of class A).

Is every method returning `this` a monad?

Is every method on a class which returns this a monad?
I'm going to say a very cautious "possibly". A lot of this is contingent on your definitions.
It's worth noting that I'm taking the definition of monad from the category theory construct, not the functional programming construct.
If you think of a method A of class C that maps a C instance to another C instance (i.e. it returns this), then this would appear that C.A() is a functor from the category consisting of C instantiations to itself. Therefore it's an endofunctor, at least. It would appear that this construction obeys the basic identity and associativity properties that we expect, but further inspection would be required to say for sure.
Anyway, I wouldn't stake my life on it, and I'm not certain this is a very helpful way about thinking of such constructions, but it does seem a reasonable assumption on first inspection, at least.
I have limited understanding of monads. I can't tell if that meets the formal definition of a monad (I don't think so, but I don't know for sure), but return this; alone doesn't allow any of the cool things monads allow (fluid interfaces are nice, but not monads imho and nowhere as useful as even simple monads like the option type monad).
This snippet from wikipedia seems to say "no":
Formally, a monad is constructed by defining two operations (bind and return) and a type constructor M [... further restrictions we don't need here]
Edit: Moreover, a monad is a type and not an operation (e.g. method) - the question should rather read "Is a class a monad if all of its methods return this?"</nitpick >
Probably not, at least not in any of the usual ways.
Monads in programming are typically defined over a category of types with functions as arrows. In that case, a method returning this is an arrow from the class to itself--this is an endomorphism with the usual monoid of function composition, but is not a functor.
Note that functors involving function types are certainly possible, but a functor F(A) => (A -> A) doesn't really work because the type appears in both covariant and contravariant position, that is, given a function A -> B you can send A -> A to A -> B, or you can send B -> B to A -> B, but you can't get a B -> B from A -> A or vice versa.
However, there is one way to view instances as having monadic structure. Consider that instance methods effectively have this as an implicit argument. So for some class C, its methods are functions from C to whatever other type. This corresponds roughly to the covariant function functor above. Note that I'm not describing any particular class here, but the entire concept of classes and instances! So, for this mapping from C to instance methods of C:
If we have an instance method returning some type A and a function with type A -> B, we can trivially define a method returning something of type B: that's the rest of the functor definition, a.k.a. 'fmap` in Haskell.
If we have some value of type A, we can add a trivial instance method that just returns that value: that's the monad's "unit" operation, a.k.a. return in Haskell.
If we have an instance method returning a value of type A, and another instance method taking an argument of type A and returning a value of type B, we can define a method that simply returns a value of type B by combining them. That's the monadic bind, a.k.a. (>>=) in Haskell.
Haskell calls the monad of "functions that all take a first argument of some fixed type" the Reader Monad, and the do notation for it lets you write code where that first argument is implicitly available--rather like the way that this is implicitly available inside instance methods.
The difference here is that with class instances, the monadic structure is... sort of at the level of the syntax, not something you can use directly in a program, at least not in most languages.
In my opinion, No.
There are at least two issues I see with it.
A monad is often a glue between two functions. In this case methodA returns a type on which the next methodB is invoked, (and of course methodA and methodB both belonging to the same type).
A monad is supposed to allow type transformations. So if functionA returns TypeX and functionB expects TypeY, the monad needs to provide a bind operation which can convert a Monad(TypeX) into a Monad(TypeY). The monad then goes on to take the return value of the first function, wrap it as a Monad(TypeX), transform it to Monad(TypeY) from which TypeY would get extracted and fed into functionB.
A method which returns this is actually an implementation of Fluent Interface. And while many have argued it to be a monadic as well, I would only say that while it helps resolve problems similar to what monads could otherwise solve, and while the solution would seem similar to how a monadic solution might work (instead of the "." operator, the bind method of the monad has to be invoked without any explicit do block), it is not a monad. In other words it may walk like a monad and talk like a monad, but it is not a monad.
Slight Correction to point 2: The monad needs to provide mechanisms to a) convert TypeX into Monad(TypeX), transform from Monad(TypeX) to Monad(TypeY) and a coercion from Monad(TypeY) to TypeY