What’s the difference between Row Polymorphism and Structural Typing?

The definitions I’ve stumbled across seem to indicate they express the same idea. That’s that the relationship between record types is determined by their fields (or properties) rather than their names. Their Wikipedia pages also seem to indicate the same idea:

A structural type system (or property-based type system) is a major class of type system in which type compatibility and equivalence are determined by the type’s actual structure or definition and not by other characteristics such as its name or place of declaration.

In programming language type theory, row polymorphism is a kind of polymorphism that allows one to write programs that are polymorphic on record field types (also known as rows, hence row polymorphism).

Are there any differences between them?

How do type classes make ad-hoc polymorphism less ad-hoc?

The title of the paper that introduced type classes is "How to make ad-hoc polymorphism less ad-hoc".

It seems the type classes approach is being compared to how OOP does ad-hoc polymorphism.

As far as I can tell, the paper never explains how type classes are less ad-hoc than OOP techniques like V-tables or prototype chains, or even has any comparison at all of the trade-offs between the two approaches.

What is non-ad-hoc about ad-hoc polymorphism via type classes?

Note: this is a somewhat objective question, as "ad-hoc" is here a technical term. From the paper, "Ad-hoc polymorphism occurs when a function is defined over several different types, acting in a different way for each type."

Uncurrying and Polymorphism

How do we uncurry functions when they are polymorphic? For example, is it possible to uncurry the following types? If so what is the uncurried type?

  1. $ \forall X. X \rightarrow int \rightarrow X$ ?
  2. $ int \rightarrow \forall X. X \rightarrow X$ ?
  3. $ int \rightarrow \forall X. X \rightarrow int \rightarrow X$ ?

What is meant by the Polymorphism definition?

Based on many tutorials that I have read, the following is the definition of Polymorphism:

Polymorphism is the ability of an object to take on many forms.

Now let’s assume that we have an Animal parent class, and a Dog and a Cat child classes.

Is the above Polymorphism definition means that an Animal variable can have many forms in the sense that an Animal variable can be an Animal or it can be a Dog or it can be a Cat, or does it mean something else?

Why F-bounded polymorphism and F-bounded quantification are called, well, F-bounded

It’s claimed in Wikipedia that:

F-bounded quantification or recursively bounded quantification, introduced in 1989, allows for more precise typing of functions that are applied on recursive types. A recursive type is one that includes a function that uses it as a type for some argument or its return value

Here’s the article which Wikipedia refers to, and F-bounded quantification is introduced in that article in following fashion:

F-bounded quantification is a natural extension of bounded quantification that seems particularly useful in connection with recursive types.

My question is – why though it’s F-bounded, what does “F” stands for in this particular context?

What are the relations between these two descriptions of let polymorphism?

In Types and Programming Languages by Pierce, there are two descriptions of let-polymorphism.

Sec23.8 Fragments of SystemF on p359 says

This has led to various proposals for restricted fragments of System F with more tractable reconstruction problems.

The most popular of these is the let-polymorphism of ML (§22.7), which is sometimes called prenex polymorphism because it can be viewed as a fragment of System F in which type variables range only over quantifier-free types (monotypes) and in which quantified types (polytypes, or type schemes) are not allowed to appear on the left-hand sides of arrows. The special role of let in ML makes the correspondence slightly tricky to state precisely; see Jim (1995) for details.

Sec 22.7 Let Polymorphism says

The first step is to change the ordinary typing rule for let so that, instead of calculating a type for the right-hand side t1 and then using this as the type of the bound variable x while calculating a type for the body t2, …, it instead substitutes t1 for x in the body, and then typechecks this expanded expression … We write a constraint-typing rule for let in a similar way:

enter image description here

In essence, what we’ve done is to change the typing rules for let so that they perform a step of evaluation

enter image description here

The second step is to rewrite the definition of double using the implicitly annotated lambda-abstractions from §22.6.

let double = λf. λa. f(f(a)) in let a = double (λx:Nat. succ (succ x)) 1 in let b = double (λx:Bool. x) false in ... 

The combination of the constraint typing rules for let (CT-LetPoly) and the implicitly annotated lambda-abstraction (CT-AbsInf) gives us exactly what we need: CT-LetPoly makes two copies of the definition of double, and Ct-AbsInf assigns each of the abstractions a different type variable. The or- dinary process of constraint solving does the rest.

What are the relations between the two descriptions?

Does each of the two descriptions imply (or lead to) the other? How? More specifically, do the first description’s

  • type variables range only over quantifier-free types (monotypes)

  • quantified types (polytypes, or type schemes) are not allowed to appear on the left-hand sides of arrows

and the second description’s

  • the constraint typing rules for let (CT-LetPoly)
  • the implicitly annotated lambda-abstraction (CT-AbsInf)

imply each other, and how?


Related to my previous question What is "Hindley-Milner (i.e., unification-based) polymorphism"?

row type polymorphism vs TypeScript

I’m trying to understand what are capabilities of row type polymorphism. Most articles/posts I saw were written before even TypeScript came out. All things I saw so far, can be done with TypeScript, even as old as 2.2 (current is 3.5) and TypeScript correctly derives types even without annotations (hover a variable to see its derived type):

  • Change property
  • Add property

The only problem I see is that after a few such applications type declarations displayed to user become cumbersome.

Actual question: are there any more advanced examples of row polymorphism which TypeScript isn’t capable of?

PS: Please, use code-like notation, I’m having hard time reading this “fraction-like” notation.

How is polymorphism used in the real world? [closed]

I am trying to understand how Polymorphism is used in a real life project, but I can only find the classical example (or something similar to it) of having an Animal parent class with a methodspeak(), and many child classes that override this method, and now you can call the method speak() on any of the child objects, for example:

Animal animal;  animal = dog; animal.speak();  animal = cat; animal.speak(); 

Step from procedural to OO, redesigning classes with polymorphism and other good practice standards

I made a small software, for image processing, that does some small and basics edits. I wrote this code in C++, by not checking any good practice of C++ Designs. At the beginning, my point was just made some code work. Those are the classes with methods and attributes:


class MasterPH { public:     cv::Mat img;     cv::Mat tmp;     cv::Mat original;      cv::Mat hist_Mat_r;     cv::Mat hist_Mat_g;     cv::Mat hist_Mat_b;      int exposure_val = 0;     int red_val = 0;     int green_val = 0;     int blue_val = 0;     double contrast_val = 0;      int hue = 0;     int luminance = 0;     int saturation = 0; }; 


class ImgProcessing { public:     ImgProcessing();      void processMaster(cv::Mat& img, cv::Mat& tmp, int brightness, int red, int green, int blue, double contrast);     void processHLS(cv::Mat& img, cv::Mat& tmp, int hue, int luminance, int saturation);     void black_n_white(cv::Mat& img, cv::Mat& tmp);     void sepia(cv::Mat& img, cv::Mat& tmp); }; 


class ImgHandling { public:     ImgHandling();      void imgLoad(cv::Mat& img, cv::Mat& tmp, cv::Mat& original, QString& path);     void imgSave(QString& path, cv::Mat& img);      void calculateHist(cv::Mat& img, cv::Mat& hist_Mat, int color); }; 


class ImgDistortions { public:     ImgDistortions();       void rotate(cv::Mat& img, cv::Mat& tmp, int angle);     void flipH(cv::Mat& img, cv::Mat& tmp);     void flipV(cv::Mat& img, cv::Mat& tmp); }; 


class ImgConvolution { public:     ImgConvolution();      void applyKernel(); // To implement still }; 

Plus a class containing all the buttons & sliders, that just call these functions.

So now I need some advice on how I can step from this kind of Procedural-Code, to a more Object Oriented one, via using all the possible Good Practice design of C ++.

I’m new to C++, so I’m still learning on how I can apply polymorphism etc…

using super-constructor vs methods polymorphism

I’m using Java but this applies to any OOP language. What is preferred between these two approaches?

First approach:

public abstract class Planet {   public abstract Colors[] getColors();   public abstract long getWeight();   public abstract int getIdFromEarth();   public abstract boolean isHabitable(); }  public class Earth extends Planet() {   public Color[] getColors() {     return Arrays.of(Color.BLUE, Color.GREEN);   }   public long getWeight() {     return 33338838383;   }   public int getIdFromEarth() {     return 3;   }   public boolean isHabitable() {     return true;   } } 

Second approach:

public abstract class Planet {   private final Colors[] colors;   private final long weight;   private final int idFromEarth;   private final boolean isHabitable;   public Planet(Colors[] colors, long weight, int idFromEarth, boolean isHabitable) {     this.colors = colors;     this.weight = weight;     this.idFromEarth = idFromEarth;     this.isHabitable = isHabitable;   }   public final Colors[] getColors() {     return colors;   }   public final long getWeight() {     return weight;   }   public final int getIdFromEarth() {     return idFromEarth;   }   public final boolean isHabitable() {     return isHabitable;   } }  public class Earth extends Planet() {     public Earth() {         super(Arrays.of(Color.BLUE, Color.GREEN),         33338838383,         3,         true)     } } 

I like second approach because:

  • subclasses are small (good if we have a lot of subclasses
  • no polymorphism involved (faster? more efficient?)

Cons of second approach in constructor call itself. It’s hard to say without IDE support which parameters are assinged and so easy to make I mistake:

        super(Arrays.of(Color.BLUE, Color.GREEN),         33338838383,         3,         true) 

Should I definitely prefer one of these approaches or may be you can suggest something else? Imaging we have more parameters – not 4, but 6 or 10. I don’t want to use enum cause in real app things a little more complicated and I have to have class hierarchy to operate with certain “group of planets”.