Skip to content

Conversation

@odersky
Copy link
Contributor

@odersky odersky commented Dec 18, 2021

  1. For every (possibly erased and/or context) function class
    XFunctionN, generate an alias ImpureXFunctionN in the Scala package defined as

    type ImpureXFunctionN[...] = {*} XFunctionN[...] 
  2. Introduce -> and ?-> function operators, treated by default like => and ?=>.

  3. Under -Ycc treat -> and ?-> as immutable function types, whereas A => B
    is an alias of {*} A -> B and A ?=> B is an alias of {*} A ?-> B. For instance,
    A -> B maps to Function1[A, B] whereas A => B now maps to ImpureFunction1[A, B].

Closures are unaffected, we still use => for all closures whether they are pure or not.

Also: improve printing of capturing types, so that we use native capturing syntax instead of
explicit @retains under -Ycc even before phase cc.

@odersky odersky added the cc-experiment Intended to be merged with cc-experiment branch on origin label Dec 18, 2021
@odersky odersky changed the title Generate "Impure" function aliases Distinguish between pure and impure function types Dec 19, 2021
@s5bug
Copy link

s5bug commented Dec 20, 2021

How do pure vs impure defs change with this? I.e. how should one mark a def as supposed-to-be-pure, so that it becomes a -> and not an =>?

@odersky
Copy link
Contributor Author

odersky commented Dec 20, 2021

This whole thing has to be understood in terms of capture calculus, a type system that can track which capabilities can get captured in a value. The idea is that we don't want to track effects, but instead track the capability to have an effect. A first version of this was presented
at this year's Scala symposium [EDITED to switch to a link that's openly accessible]

https://infoscience.epfl.ch/record/290885?ln=en

That paper is ostensibly about checked exceptions, but it contains a "capture calculus" that is much more general than that. We have fleshed out the meta theory of that type system since the paper appeared.

Because we track capabilities instead of effects we don't need two versions of def. Methods don't capture anything, only objects do. Functions are objects, so they can capture capabilities. With this PR, => will mean a function that can retain arbitrary effect capabilities in its closure and -> will mean a function that cannot. So -> by itself denotes pure functions. You can also express functions that only retain a specific capability, e.g. {c} A -> B for the function from A to B that retains capability c and is otherwise pure.

@s5bug
Copy link

s5bug commented Dec 20, 2021

So, for example, the output of println might be {Print} Unit? Which means println as a function reference would be {Print} String -> Unit? Or would println have an output of just Unit and the function reference is {println} String -> Unit?

@odersky
Copy link
Contributor Author

odersky commented Dec 20, 2021

So, for example, the output of println might be {Print} Unit? Which means println as a function reference would be {Print} String -> Unit? Or would println have an output of just Unit and the function reference is {println} String -> Unit?

The second is correct (or rather {Print} String -> Unit). Captures represent the possibility of future effects. Unit is already evaluated, it does not capture anything.

 1. Allow `->` and `?->` and function operators, treated like `=>` and `?=>`. 2. under -Ycc treat `->` and `?->` as immutable function types, whereas `A => B` is an alias of `{*} A -> B` and `A ?=> B` is an alias of `{*} A ?-> B`. Closures are unaffected, we still use `=>` for all closures where they are pure or not. Improve printing of capturing types Avoid explicit retains annotations also outside phase cc Generate "Impure" function aliases For every (possibly erased and/or context) function class XFunctionN, generate an alias ImpureXFunctionN in the Scala package defined as type ImpureXFunctionN[...] = {*} XFunctionN[...] Also: - Fix a bug in TypeComparer: glb has to test subCapture in a frozen state - Harden EventuallyCapturingType extractor to not crash on illegal capture sets - Cleanup transformation of inferred types
@odersky odersky merged commit d5e74f7 into scala:cc-experiment Dec 25, 2021
@odersky odersky deleted the pure-funs branch December 25, 2021 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cc-experiment Intended to be merged with cc-experiment branch on origin

2 participants