Skip to content
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

Syntax for polymorphic values. #54

Closed
wants to merge 3 commits into from

Conversation

TomasMikula
Copy link
Collaborator

@TomasMikula TomasMikula commented Jun 28, 2017

This is another attempt at convenient syntax for polymorphic values. This PR addresses #37 and supersedes #44.

The syntax

ν[T].m[A, B[_], ...](e)

is rewritten to

new T { def m[A, B[_], ...] = e }

(The symbol "ν" is the Greek lowercase letter "Nu" (/njuː/) and stands for new.)

In case m has just one *-kinded type parameter which is not referenced from e, it can be omitted:

ν[T].m(e)

is rewritten to

new T { def m[A] = e }

where A is a fresh name.

If the method name is apply, it can be omitted:

ν[T][A, B[_], ...](e)

is rewritten to

new T { def apply[A, B[_], ...] = e }

The previous two shortcuts can be combined:

ν[T](e)

is rewritten to

new T { def apply[A] = e }

where A is a fresh name.

There is also an alternative syntax using Λ (Greek uppercase letter Lambda)

Λ[A, B[_], ...](e): T

which is equivalent to

ν[T][A, B[_], ...](e)

i.e.

new T { def apply[A, B[_], ...] = e }

When using Λ-syntax, type parameters cannot be omitted, and method name is (currently) assumed to be apply. Note also that the type T of the whole Λ-expression has to be specified (cannot be inferred, since kind-projector runs before typer).

See the test cases in polyval.scala for some examples.

@TomasMikula
Copy link
Collaborator Author

I fixed the 2.10 build failure and made the new functionality opt-in via scalac option

-P:kind-projector:forall=true

    ν[T].m[A, B[_], ...](e)

is rewritten to

    new T { def m[A, B[_], ...] = e }

(`ν` is the lowercase Greek letter "Nu" (/njuː/) and stands for `new`.)

In case `m` has just one *-kinded type parameter that is
is not referenced from `e`, it can be omitted:

    ν[T].m(e)

is rewritten to

    new T { def m[A] = e }

where `A` is a fresh name.

If the method name is `apply`, it can be omitted:

    ν[T][A, B[_], ...](e)

is rewritten to

    new T { def apply[A, B[_], ...] = e }

The previous two shortcuts can be combined:

    ν[T](e)

is rewritten to

    new T { def apply[A] = e }

where `A` is a fresh name.
    Λ[A, B[_], ...](e) : T

is rewritten to

    new T { def apply[A, B[_], ...] = e

Note that explicit type `T` of the Λ-expression is required.
@TomasMikula
Copy link
Collaborator Author

I changed the name from to ν (Greek lowercase letter Nu, pronounced "new"), since it better fits the order of arguments.

I also added alternative Λ-syntax which resembles System-F syntax for universal quantification.

I updated the description above to reflect these changes.

TomasMikula added a commit to TomasMikula/pascal that referenced this pull request Aug 1, 2017
@TomasMikula
Copy link
Collaborator Author

I published this functionality as a separate plugin: P∀scal.

I consider polymorphic values (including existing polymorphic lambdas) a separate concern from kind-projector's type lambdas through type projections. Nevertheless, I'm leaving this open for a while in case people want to see this in kind-projector anyway.

@fommil
Copy link
Contributor

fommil commented Sep 8, 2017

can you support the plain English spellings too? In Emacs I have a prettify-greek mode which will render these things as UTF-8 but save as ASCII to disk. It also makes it a lot easier for me to type...

@TomasMikula
Copy link
Collaborator Author

I could do Nu, but Lambda in term position is already reserved by kind-projector for polymorphic lambdas.

For typing, I have just installed Greek keyboard layout.

@fommil
Copy link
Contributor

fommil commented Sep 8, 2017

I think it would need to be the lowercase versions for prettify-greek to work (it'll use capitals)

@TomasMikula
Copy link
Collaborator Author

For kind-projector, Lambda and λ are already synonyms. It would be confusing to make lambda and Λ synonyms.

@TomasMikula
Copy link
Collaborator Author

I'm going to close this for the following reasons:

  1. With the addition of self-referencing polymorphic values, P∀ascal has by now diverged from this PR.
  2. New features add maintenance cost, which I don't mean to incur on kind-projector.
  3. kind-projector already claims the identifier λ from the name space. P∀scal claims another two, ν and Λ. Rather than having configuration options for what features of the plugin to turn on (and thus what identifiers will be reserved), the user may just add separate plugins à la carte.

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.

2 participants