Skip to content

Add docs and syntax lookup for scoped polymorphic types #693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

fhammerschmidt
Copy link
Member

Copy link
Collaborator

@zth zth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff!

@ryyppy
Copy link
Member

ryyppy commented May 28, 2023

Looking good! One question I had if it would be better to call it "locally scoped polymorphic types" vs "globally scoped polymorphic types" (instead of "normal polymorphic "?)

Would make more sense to me, but if everyone thinks this is fine, we can go with this ofc.

@cristianoc
Copy link
Contributor

More precise, though longer.
How about "local polymorphic types"?
There are several little variations one can try.

@ryyppy
Copy link
Member

ryyppy commented May 29, 2023

i had some more thoughts about it and will post another suggestion later today when i am at a computer.

@ryyppy
Copy link
Member

ryyppy commented May 30, 2023

According to the types docs, we currently call 'a a "type parameter" aka parametrized types, aka generics. (see https://rescript-lang.org/docs/manual/latest/type#type-parameter-aka-generic)

For symmetry, I'd propose to call 'a . a polymorphic type parameter, due to less ambiguity vs "scoped".

Instead of "normal type parameter", I'd probably call it "common type parameter".

@cristianoc
Copy link
Contributor

According to the types docs, we currently call 'a a "type parameter" aka parametrized types, aka generics. (see https://rescript-lang.org/docs/manual/latest/type#type-parameter-aka-generic)

For symmetry, I'd propose to call 'a . a polymorphic type parameter, due to less ambiguity vs "scoped".

Instead of "normal type parameter", I'd probably call it "common type parameter".

That terminology might be inferred to describe the difference between list<'a> the poly type parameter, vs list<int> the "normal" type parameter

@fhammerschmidt
Copy link
Member Author

So what name is it now? Or should we do a survey on the forum?

@cristianoc
Copy link
Contributor

I have validated "scoped polymorphic types".
It might or might not be optimal.

Considering another choice needs validation.
E.g. "local polymorphic types" I can try to see if it passes validation.

Not sure there are other suggestions so far that can be bought forward.

@cristianoc
Copy link
Contributor

Give me an example of local polymorhic types in restrict, and explain their use case compared to ordinary polymorphic types with an example.

In the context of programming languages, local polymorphic types with restrictions refer to type parameters that are scoped within a specific block or context, and can only be used within that scope. This is in contrast to ordinary polymorphic types, where the type parameters are globally defined and can be used across different parts of the codebase.

Let's consider a hypothetical programming language that supports both local and ordinary polymorphic types for a clearer understanding.

Example of Local Polymorphic Types with Restrictions:

function foo<T>(x: T): T {
  // Perform some operations on x
  return x;
}

function bar(): void {
  let result = foo(42);  // Type argument inferred as number
  // Perform further operations using result
  console.log(result);
}

function baz(): void {
  let result = foo("Hello");  // Type argument inferred as string
  // Perform further operations using result
  console.log(result);
}

In the above example, the function foo is defined with a type parameter T, but the type argument for T is not explicitly specified. When foo is called within the bar function, the type argument is automatically inferred as number, and when called within the baz function, the type argument is inferred as string. The type parameter T is local to each call of foo, and the type argument is resolved within the scope of that particular call.

Use Case for Local Polymorphic Types:
Local polymorphic types are useful in situations where you want the flexibility to work with different types within a specific scope without affecting other parts of the codebase. This allows for more localized type inference and can improve code readability and maintainability.

In the example above, the foo function can be called multiple times with different types, and the type argument is resolved independently for each call. This enables the developer to leverage polymorphism within specific contexts without impacting the type inference in other parts of the program. This can be particularly useful when dealing with type-sensitive operations or algorithms where the behavior might vary based on the specific type used.

Comparison to Ordinary Polymorphic Types:
In contrast, ordinary polymorphic types, also known as global polymorphic types, are defined at a higher level and can be used throughout the entire codebase. Any code that references the polymorphic type will utilize the same type argument.

For example:

function foo<T>(x: T): T {
  // Perform some operations on x
  return x;
}

function bar(): void {
  let result = foo<number>(42);  // Type argument explicitly set as number
  // Perform further operations using result
  console.log(result);
}

function baz(): void {
  let result = foo<string>("Hello");  // Type argument explicitly set as string
  // Perform further operations using result
  console.log(result);
}

In this case, the type argument for foo is explicitly set to number in the bar function, and string in the baz function. The type parameter T is globally defined and affects all instances of foo across the codebase.

Ordinary polymorphic types are more suitable when you want consistency in type resolution across different parts of the codebase or when you want to enforce a specific type argument throughout the program.

In summary, local polymorphic types with restrictions allow for localized type inference and flexibility within specific scopes, whereas ordinary polymorphic types provide global consistency for type resolution across the entire codebase. The choice between them depends on the specific requirements and design of the program.

@cristianoc
Copy link
Contributor

I have misspelled "restrict," so the answer is for TS, but the concept seems to come across no problem.
So I'd say "local polymorphic types" are also a valid alternative.

@cristianoc
Copy link
Contributor

I personally don't have strong preferences on local vs scoped.

@fhammerschmidt
Copy link
Member Author

@ryyppy are you fine with "local polymorphic types"?

@ryyppy ryyppy merged commit e8cb31d into rescript-lang:master Jun 1, 2023
@fhammerschmidt fhammerschmidt deleted the scoped-polymorphic-types branch June 1, 2023 15:30
@ryyppy
Copy link
Member

ryyppy commented Jun 1, 2023

After back and forth let's settle for "scoped polymorphic types" since this seems to be the most liked version so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document universally qualified types
4 participants