Skip to content

Givens without as #10538

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
merged 10 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/docs/internals/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,11 @@ Expr1 ::= [‘inline’] ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[
| [SimpleExpr ‘.’] id ‘=’ Expr Assign(expr, expr)
| SimpleExpr1 ArgumentExprs ‘=’ Expr Assign(expr, expr)
| PostfixExpr [Ascription]
| StructuralInstance
| ‘inline’ InfixExpr MatchClause
Ascription ::= ‘:’ InfixType Typed(expr, tp)
| ‘:’ Annotation {Annotation} Typed(expr, Annotated(EmptyTree, annot)*)
StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ TemplateBody] New templ
Catches ::= ‘catch’ (Expr | ExprCaseClause)
PostfixExpr ::= InfixExpr [id] PostfixOp(expr, op)
InfixExpr ::= PrefixExpr
Expand Down Expand Up @@ -396,9 +398,8 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses
ConstrMods ::= {Annotation} [AccessModifier]
ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor
EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template)
GivenDef ::= [GivenSig] Type ‘=’ Expr
| [GivenSig] ConstrApps [TemplateBody]
GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘as’ -- one of `id`, `DefParamClause`, `UsingParamClause` must appear
GivenDef ::= [GivenSig] (Type [‘=’ Expr] | StructuralInstance)
GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefParamClause`, `UsingParamClause` must be present
Extension ::= ‘extension’ [DefTypeParamClause] ‘(’ DefParam ‘)’
{UsingParamClause}] ExtMethods
ExtMethods ::= ExtMethod | [nl] ‘{’ ExtMethod {semi ExtMethod ‘}’
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/reference/changed-features/implicit-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ no longer applies.
**3.** Package prefixes no longer contribute to the implicit search scope of a type. Example:
```scala
package p
given a as A
given a: A = A()

object o {
given b as B
given b: B = B()
type C
}
```
Expand Down
22 changes: 8 additions & 14 deletions docs/docs/reference/changed-features/numeric-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,38 +133,32 @@ should produce the `BigFloat` number `BigFloat(-123, 997)`:
The companion object of `BigFloat` defines an `apply` constructor method to construct a `BigFloat`
from a `digits` string. Here is a possible implementation:
```scala
object BigFloat {
object BigFloat:
import scala.util.FromDigits

def apply(digits: String): BigFloat = {
val (mantissaDigits, givenExponent) = digits.toUpperCase.split('E') match {
def apply(digits: String): BigFloat =
val (mantissaDigits, givenExponent) = digits.toUpperCase.split('E') match
case Array(mantissaDigits, edigits) =>
val expo =
try FromDigits.intFromDigits(edigits)
catch {
case ex: FromDigits.NumberTooLarge =>
throw FromDigits.NumberTooLarge(s"exponent too large: $edigits")
}
catch case ex: FromDigits.NumberTooLarge =>
throw FromDigits.NumberTooLarge(s"exponent too large: $edigits")
(mantissaDigits, expo)
case Array(mantissaDigits) =>
(mantissaDigits, 0)
}
val (intPart, exponent) = mantissaDigits.split('.') match {
val (intPart, exponent) = mantissaDigits.split('.') match
case Array(intPart, decimalPart) =>
(intPart ++ decimalPart, givenExponent - decimalPart.length)
case Array(intPart) =>
(intPart, givenExponent)
}
BigFloat(BigInt(intPart), exponent)
}
```
To accept `BigFloat` literals, all that's needed in addition is a `given` instance of type
`FromDigits.Floating[BigFloat]`:
```scala
given FromDigits as FromDigits.Floating[BigFloat] {
given FromDigits: FromDigits.Floating[BigFloat] with
def fromDigits(digits: String) = apply(digits)
}
} // end BigFloat
end BigFloat
```
Note that the `apply` method does not check the format of the `digits` argument. It is
assumed that only valid arguments are passed. For calls coming from the compiler
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/changed-features/structural-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ than other classes. Here is an example:
trait Vehicle extends reflect.Selectable {
val wheels: Int
}
val i3 = new Vehicle { // i3: Vehicle { val range: Int }
val i3 = Vehicle with { // i3: Vehicle { val range: Int }
Copy link
Contributor

Choose a reason for hiding this comment

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

This change needs to be reverted.

val wheels = 4
val range = 240
}
Expand Down
12 changes: 5 additions & 7 deletions docs/docs/reference/contextual/by-name-context-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ trait Codec[T] {
def write(x: T): Unit
}

given intCodec as Codec[Int] = ???
given intCodec: Codec[Int] = ???

given optionCodec[T](using ev: => Codec[T]) as Codec[Option[T]] {
def write(xo: Option[T]) = xo match {
given optionCodec[T](using ev: => Codec[T]): Codec[Option[T]] with
def write(xo: Option[T]) = xo match
case Some(x) => ev.write(x)
case None =>
}
}

val s = summon[Codec[Option[Int]]]

Expand All @@ -36,7 +34,7 @@ The precise steps for synthesizing an argument for a by-name context parameter o
1. Create a new given of type `T`:

```scala
given lv as T = ???
given lv: T = ???
```
where `lv` is an arbitrary fresh name.

Expand All @@ -46,7 +44,7 @@ The precise steps for synthesizing an argument for a by-name context parameter o


```scala
{ given lv as T = E; lv }
{ given lv: T = E; lv }
```

Otherwise, return `E` unchanged.
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/reference/contextual/context-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Context functions are written using `?=>` as the "arrow" sign.
They are applied to synthesized arguments, in
the same way methods with context parameters are applied. For instance:
```scala
given ec as ExecutionContext = ...
given ec: ExecutionContext = ...

def f(x: Int): ExecutionContext ?=> Int = ...

Expand Down Expand Up @@ -86,13 +86,13 @@ with context function types as parameters to avoid the plumbing boilerplate
that would otherwise be necessary.
```scala
def table(init: Table ?=> Unit) = {
given t as Table // note the use of a creator application; same as: given t as Table = new Table
given t: Table = Table()
init
t
}

def row(init: Row ?=> Unit)(using t: Table) = {
given r as Row
given r: Row = Row()
init
t.add(r)
}
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/reference/contextual/conversions.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ If such an instance `C` is found, the expression `e` is replaced by `C.apply(e)`
primitive number types to subclasses of `java.lang.Number`. For instance, the
conversion from `Int` to `java.lang.Integer` can be defined as follows:
```scala
given int2Integer as Conversion[Int, java.lang.Integer] =
given int2Integer: Conversion[Int, java.lang.Integer] =
java.lang.Integer.valueOf(_)
```

Expand All @@ -59,9 +59,9 @@ object Completions {
//
// CompletionArg.fromStatusCode(statusCode)

given fromString as Conversion[String, CompletionArg] = Error(_)
given fromFuture as Conversion[Future[HttpResponse], CompletionArg] = Response(_)
given fromStatusCode as Conversion[Future[StatusCode], CompletionArg] = Status(_)
given fromString : Conversion[String, CompletionArg] = Error(_)
given fromFuture : Conversion[Future[HttpResponse], CompletionArg] = Response(_)
given fromStatusCode : Conversion[Future[StatusCode], CompletionArg] = Status(_)
}
import CompletionArg._

Expand Down
8 changes: 4 additions & 4 deletions docs/docs/reference/contextual/derivation-macro.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ we need to implement a method `Eq.derived` on the companion object of `Eq` that
produces a quoted instance for `Eq[T]`. Here is a possible signature,

```scala
given derived[T: Type](using Quotes) as Expr[Eq[T]]
given derived[T: Type](using Quotes): Expr[Eq[T]]
```

and for comparison reasons we give the same signature we had with `inline`:

```scala
inline given derived[T] as (m: Mirror.Of[T]) => Eq[T] = ???
inline given derived[T]: (m: Mirror.Of[T]) => Eq[T] = ???
```

Note, that since a type is used in a subsequent stage it will need to be lifted
Expand All @@ -41,7 +41,7 @@ from the signature. The body of the `derived` method is shown below:


```scala
given derived[T: Type](using Quotes) as Expr[Eq[T]] = {
given derived[T: Type](using Quotes): Expr[Eq[T]] = {
import quotes.reflect._

val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get
Expand Down Expand Up @@ -176,7 +176,7 @@ object Eq {
case '[EmptyTuple] => Nil
}

given derived[T: Type](using q: Quotes) as Expr[Eq[T]] = {
given derived[T: Type](using q: Quotes): Expr[Eq[T]] = {
import quotes.reflect._

val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get
Expand Down
18 changes: 9 additions & 9 deletions docs/docs/reference/contextual/derivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ The `derives` clause generates the following given instances for the `Eq`, `Orde
companion object of `Tree`,

```scala
given [T: Eq] as Eq[Tree[T]] = Eq.derived
given [T: Ordering] as Ordering[Tree] = Ordering.derived
given [T: Show] as Show[Tree] = Show.derived
given [T: Eq] : Eq[Tree[T]] = Eq.derived
given [T: Ordering] : Ordering[Tree] = Ordering.derived
given [T: Show] : Show[Tree] = Show.derived
```

We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_.
Expand Down Expand Up @@ -179,7 +179,7 @@ we need to implement a method `Eq.derived` on the companion object of `Eq` that
a `Mirror[T]`. Here is a possible implementation,

```scala
inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = {
inline given derived[T](using m: Mirror.Of[T]): Eq[T] = {
val elemInstances = summonAll[m.MirroredElemTypes] // (1)
inline m match { // (2)
case s: Mirror.SumOf[T] => eqSum(s, elemInstances)
Expand Down Expand Up @@ -278,7 +278,7 @@ object Eq {
}
}

inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = {
inline given derived[T](using m: Mirror.Of[T]): Eq[T] = {
lazy val elemInstances = summonAll[m.MirroredElemTypes]
inline m match {
case s: Mirror.SumOf[T] => eqSum(s, elemInstances)
Expand Down Expand Up @@ -309,7 +309,7 @@ In this case the code that is generated by the inline expansion for the derived
following, after a little polishing,

```scala
given derived$Eq[T](using eqT: Eq[T]) as Eq[Opt[T]] =
given derived$Eq[T](using eqT: Eq[T]): Eq[Opt[T]] =
eqSum(summon[Mirror[Opt[T]]],
List(
eqProduct(summon[Mirror[Sm[T]]], List(summon[Eq[T]]))
Expand All @@ -326,13 +326,13 @@ As a third example, using a higher level library such as shapeless the type clas
`derived` method as,

```scala
given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]) as Eq[A] {
given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]): Eq[A] {
def eqv(x: A, y: A): Boolean = inst.fold2(x, y)(false)(
[t] => (eqt: Eq[t], t0: t, t1: t) => eqt.eqv(t0, t1)
)
}

given eqProduct[A](using inst: K0.ProductInstances[Eq, A]) as Eq[A] {
given eqProduct[A](using inst: K0.ProductInstances[Eq, A]): Eq[A] {
def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)(
[t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => Complete(!eqt.eqv(t0, t1))(false)(true)
)
Expand All @@ -354,7 +354,7 @@ change the code of the ADT itself. To do this, simply define an instance using
as right-hand side. E.g, to implement `Ordering` for `Option` define,

```scala
given [T: Ordering] as Ordering[Option[T]] = Ordering.derived
given [T: Ordering]: Ordering[Option[T]] = Ordering.derived
```

Assuming the `Ordering.derived` method has a context parameter of type `Mirror[T]` it will be satisfied by the
Expand Down
6 changes: 3 additions & 3 deletions docs/docs/reference/contextual/extension-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The three definitions above translate to
```scala
<extension> def < (x: String)(y: String): Boolean = ...
<extension> def +: (xs: Seq[Elem])(x: Elem): Seq[Elem] = ...
infix <extension> def min(x: Number)(y: Number): Number = ...
<extension> infix def min(x: Number)(y: Number): Number = ...
```

Note the swap of the two parameters `x` and `xs` when translating
Expand Down Expand Up @@ -195,7 +195,7 @@ trait SafeDiv:
By the second rule, an extension method can be made available by defining a given instance containing it, like this:

```scala
given ops1 as IntOps // brings safeMod into scope
given ops1: IntOps with {} // brings safeMod into scope

1.safeMod(2)
```
Expand All @@ -210,7 +210,7 @@ object List:
extension [T](xs: List[List[T]])
def flatten: List[T] = xs.foldLeft(Nil: List[T])(_ ++ _)

given [T: Ordering] as Ordering[List[T]]:
given [T: Ordering]: Ordering[List[T]] with
extension (xs: List[T])
def < (ys: List[T]): Boolean = ...
end List
Expand Down
10 changes: 5 additions & 5 deletions docs/docs/reference/contextual/given-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A special form of import wildcard selector is used to import given instances. Ex
```scala
object A {
class TC
given tc as TC
given tc: TC = ???
def f(using TC) = ???
}

Expand Down Expand Up @@ -60,10 +60,10 @@ For instance, assuming the object

```scala
object Instances {
given intOrd as Ordering[Int]
given listOrd[T: Ordering] as Ordering[List[T]]
given ec as ExecutionContext = ...
given im as Monoid[Int]
given intOrd: Ordering[Int] = ...
given listOrd[T: Ordering]: Ordering[List[T]] = ...
given ec: ExecutionContext = ...
given im: Monoid[Int] = ...
}
```

Expand Down
Loading