-
Notifications
You must be signed in to change notification settings - Fork 6
Section on named parameters #13
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
Open
ppolesiuk
wants to merge
5
commits into
master
Choose a base branch
from
named-params
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,11 +1,332 @@ | ||||||||||
| # Named Parameters | ||||||||||
|
|
||||||||||
| ## Type Parameters | ||||||||||
| The mechanism of named parameters is one of the central features of the Fram | ||||||||||
| programming language. With the support of other language constructs, named | ||||||||||
| parameters are used to express a variety of advanced programming features, | ||||||||||
| such as parametric polymorphism, existential types, record types, and ML-like | ||||||||||
| module system. Here we give a brief overview of named parameters in Fram. | ||||||||||
|
|
||||||||||
| ## Parametric Polymorphism and Type Schemes | ||||||||||
|
|
||||||||||
| Fram supports ML-style parametric polymorphism and type reconstruction. | ||||||||||
| Briefly, the type of a function is automatically inferred by the compiler | ||||||||||
| and generalized to be as polymorphic as possible. For instance, consider | ||||||||||
| the following definition of the identity function. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let id x = x | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The compiler infers the type of `id` to be `T -> T` for each type `T`. | ||||||||||
| To represent such polymorphism over type `T`, the type system assigns | ||||||||||
| *type schemes* to variables. The type scheme of `id` function is | ||||||||||
| `{type T} -> T -> T`, where the first arrow `{type T} -> ...` binds | ||||||||||
| the type parameter `T` in the rest of the type `T -> T`. When a variable | ||||||||||
| with a type scheme is used, all parameters within curly braces of the | ||||||||||
| type scheme are instantiated. In case of type parameters, the compiler | ||||||||||
| guesses the actual types to be used for instantiation based on the | ||||||||||
| context of the usage. For example, the `id` function can be used with | ||||||||||
| different types as follows. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let a = id 42 # instantiates T to Int | ||||||||||
| let b = id "abc" # instantiates T to String | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The programmer can also explicitly specify type parameters when defining | ||||||||||
| the function. For example, the equivalent definition of `id` with an explicit | ||||||||||
| type parameter is as follows. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let id {type T} (x : T) = x | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| It is also possible to define functions with multiple type parameters. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let const {type A, type B} (x : A) (_ : B) = x | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The type scheme of `const` is `{type A, type B} -> A -> B -> A`. | ||||||||||
|
|
||||||||||
| ## Named Type Parameters | ||||||||||
|
|
||||||||||
| Type parameters presented in previous section are *anonymous*, i.e., their | ||||||||||
| names are not visible outside the definition. Indeed, the programmer has no | ||||||||||
| means to specify the names of type parameters implicitly introduced by ML-style | ||||||||||
| type inference. However, Fram also supports *named type parameters*, which | ||||||||||
| can be explicitly specified by the programmer. To specify a named type | ||||||||||
| parameter, the `type` keyword is omitted and only the name of the parameter is | ||||||||||
| written within curly braces. For example, the definition of `id` function with | ||||||||||
| a named type parameter is as follows. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| # identity function with a type scheme {T} -> T -> T | ||||||||||
| let id {T} (x : T) = x | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| When a polymorphic function has a named type parameter, it can be explicitly | ||||||||||
| instantiated by specifying the name of the type parameter and the actual | ||||||||||
| type to be used for instantiation. When the explicit instantiation is omitted, | ||||||||||
| the compiler infers the actual type as usual. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let intId = id {T=Int} | ||||||||||
| let strId = id : String -> String # infers T to be String | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| When multiple named type parameters are present, the programmer can specify | ||||||||||
| the actual types for some of the parameters, and let the compiler infer | ||||||||||
| the rest. Moreover, the order of the specified parameters can be arbitrary. | ||||||||||
|
|
||||||||||
| ```fram | ||||||||||
| let pair {A, B} (x : A) (y : B) = (x, y) | ||||||||||
| let p1 = pair {A=Int, B=String} 42 "abc" | ||||||||||
| let p2 = pair {B=String} 42 "abc" # infers A to be Int | ||||||||||
| let p3 = pair {B=String, A=Int} 42 "abc" | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| In rare cases, the programmer may want to give a name to a type parameter | ||||||||||
| that is the same as an existing type in the current scope. In order to avoid | ||||||||||
| name clashes, the name visible in the scheme might be different from the name | ||||||||||
| of the type parameter used within the function body. For example, assume that | ||||||||||
|
Comment on lines
+90
to
+92
|
||||||||||
| that is the same as an existing type in the current scope. In order to avoid | |
| name clashes, the name visible in the scheme might be different from the name | |
| of the type parameter used within the function body. For example, assume that | |
| that is the same as an existing type in the current scope. To avoid name clashes, the name visible in the scheme can be different from the name of the type parameter used within the function body. For example, assume that |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed 'implicitly' to 'explicitly' - type parameters introduced by ML-style inference are implicit, not specified explicitly.