diff --git a/effekt/jvm/src/test/scala/effekt/ParserTests.scala b/effekt/jvm/src/test/scala/effekt/ParserTests.scala index d79cf558f..b22a7aac4 100644 --- a/effekt/jvm/src/test/scala/effekt/ParserTests.scala +++ b/effekt/jvm/src/test/scala/effekt/ParserTests.scala @@ -318,7 +318,7 @@ class ParserTests extends munit.FunSuite { parseExpr("resume(42)") parseExpr("in(42)") - parseExpr("fun() { foo(()) }") + parseExpr("box { foo(()) }") parseExpr("10.seconds") @@ -338,10 +338,9 @@ class ParserTests extends munit.FunSuite { test("Boxing") { parseExpr("box f") - parseExpr("unbox f") assertEqualModuloSpans( - parseExpr("unbox box f"), - parseExpr("unbox (box f)") + parseExpr("box f"), + parseExpr("(box f)") ) assertNotEqualModuloSpans( parseExpr("box { 42 }"), @@ -532,7 +531,7 @@ class ParserTests extends munit.FunSuite { """return x; |""".stripMargin) - parseStmts("fun() { x = x + 1; x }") + parseStmts("box { x = x + 1; x }") } test("Definition statements") { @@ -544,7 +543,7 @@ class ParserTests extends munit.FunSuite { parseStmts("val (left, right) = list; return left") - parseStmts("val g: () => Unit / Exc at {exc} = fun() { closure() }; ()") + parseStmts("val g: () => Unit / Exc at {exc} = box { closure() }; ()") } test("Pattern-matching val parses with correct span") { diff --git a/effekt/shared/src/main/scala/effekt/Compiler.scala b/effekt/shared/src/main/scala/effekt/Compiler.scala index 278ff60f0..ca6964757 100644 --- a/effekt/shared/src/main/scala/effekt/Compiler.scala +++ b/effekt/shared/src/main/scala/effekt/Compiler.scala @@ -6,7 +6,7 @@ import effekt.core.Transformer import effekt.namer.Namer import effekt.source.{AnnotateCaptures, ExplicitCapabilities, ModuleDecl, ResolveExternDefs} import effekt.symbols.Module -import effekt.typer.{BoxUnboxInference, Typer, Wellformedness} +import effekt.typer.{UnboxInference, Typer, Wellformedness} import effekt.util.messages.{CompilerPanic, FatalPhaseError} import effekt.util.{SourceTask, Task, VirtualSource, paths} import kiama.output.PrettyPrinterTypes.Document @@ -207,7 +207,7 @@ trait Compiler[Executable] { * Explicit box transformation * [[NameResolved]] --> [[NameResolved]] */ - BoxUnboxInference andThen + UnboxInference andThen /** * Wellformedness checks (exhaustivity, non-escape) * [[Typechecked]] --> [[Typechecked]] diff --git a/effekt/shared/src/main/scala/effekt/Lexer.scala b/effekt/shared/src/main/scala/effekt/Lexer.scala index cc0eeddf0..55b272e15 100644 --- a/effekt/shared/src/main/scala/effekt/Lexer.scala +++ b/effekt/shared/src/main/scala/effekt/Lexer.scala @@ -127,13 +127,11 @@ enum TokenKind { case `with` case `case` case `do` - case `fun` case `match` case `def` case `extern` case `record` case `box` - case `unbox` case `return` case `region` case `resource` @@ -178,8 +176,8 @@ object TokenKind { val keywords = Vector( `let`, `true`, `false`, `val`, `var`, `if`, `else`, `while`, `type`, `effect`, `interface`, - `try`, `with`, `case`, `do`, `fun`, `match`, `def`, `module`, `import`, `export`, `extern`, - `include`, `record`, `box`, `unbox`, `return`, `region`, `resource`, `new`, `and`, `is`, + `try`, `with`, `case`, `do`, `match`, `def`, `module`, `import`, `export`, `extern`, + `include`, `record`, `box`, `return`, `region`, `resource`, `new`, `and`, `is`, `namespace`, `pure`, `private` ) diff --git a/effekt/shared/src/main/scala/effekt/Namer.scala b/effekt/shared/src/main/scala/effekt/Namer.scala index 844f88370..99cc803de 100644 --- a/effekt/shared/src/main/scala/effekt/Namer.scala +++ b/effekt/shared/src/main/scala/effekt/Namer.scala @@ -431,7 +431,7 @@ object Namer extends Phase[Parsed, NameResolved] { args.foreach(resolve) } - case source.Unbox(term, _) => resolve(term) + case source.Unbox(term, _) => resolve(term) // shouldn't occur since unbox is not part of the source case source.New(impl, _) => resolve(impl) @@ -513,10 +513,6 @@ object Namer extends Phase[Parsed, NameResolved] { if !Context.resolveOverloadedOperation(target) then Context.abort(pp"Cannot resolve operation ${target}, called on a receiver that is a computation.") } - // (unbox term).bar(args) = Invoke(Unbox(term), bar, args) - case source.Unbox(term, _) => - if !Context.resolveOverloadedOperation(target) - then Context.abort(pp"Cannot resolve operation ${target}, called on an unboxed computation.") // expr.bar(args) = Call(bar, expr :: args) case term => diff --git a/effekt/shared/src/main/scala/effekt/Parser.scala b/effekt/shared/src/main/scala/effekt/Parser.scala index 0c625bbe4..86b497ac5 100644 --- a/effekt/shared/src/main/scala/effekt/Parser.scala +++ b/effekt/shared/src/main/scala/effekt/Parser.scala @@ -408,7 +408,7 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) { some(ident, `/`).mkString("/") labelled "module name" def isToplevel: Boolean = peek.kind match { - case `val` | `fun` | `def` | `type` | `effect` | `namespace` | `interface` | `type` | `record` | `var` | `include` | `extern` => true + case `val` | `def` | `type` | `effect` | `namespace` | `interface` | `type` | `record` | `var` | `include` | `extern` => true case _ => false } @@ -861,16 +861,6 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) { Box(captures, expr, span()) } - // TODO deprecate - def funExpr(): Term = - nonterminal: - val blockLiteral = `fun` ~> BlockLiteral(Nil, valueParams().unspan, Nil, braces { stmts(inBraces = true) }, span()) - Box(Maybe.None(Span(source, pos(), pos(), Synthesized)), blockLiteral, blockLiteral.span.synthesized) - - def unboxExpr(): Term = - nonterminal: - Unbox(`unbox` ~> expr(), span()) - def newExpr(): Term = nonterminal: New(`new` ~> implementation(), span()) @@ -1183,8 +1173,6 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) { case `try` => tryExpr() case `region` => regionExpr() case `box` => boxExpr() - case `unbox` => unboxExpr() - case `fun` => funExpr() case `new` => newExpr() case `do` => doExpr() case _ if isString => templateString() diff --git a/effekt/shared/src/main/scala/effekt/core/Parser.scala b/effekt/shared/src/main/scala/effekt/core/Parser.scala index 32fd8b5d9..0f5f9dad7 100644 --- a/effekt/shared/src/main/scala/effekt/core/Parser.scala +++ b/effekt/shared/src/main/scala/effekt/core/Parser.scala @@ -80,7 +80,6 @@ class EffektLexers(positions: Positions) extends Parsers(positions) { lazy val `with` = keyword("with") lazy val `case` = keyword("case") lazy val `do` = keyword("do") - lazy val `fun` = keyword("fun") lazy val `resume` = keyword("resume") lazy val `match` = keyword("match") lazy val `def` = keyword("def") @@ -93,7 +92,6 @@ class EffektLexers(positions: Positions) extends Parsers(positions) { lazy val `at` = keyword("at") lazy val `in` = keyword("in") lazy val `box` = keyword("box") - lazy val `unbox` = keyword("unbox") lazy val `return` = keyword("return") lazy val `region` = keyword("region") lazy val `resource` = keyword("resource") @@ -106,7 +104,7 @@ class EffektLexers(positions: Positions) extends Parsers(positions) { "def", "let", "val", "var", "true", "false", "else", "type", "effect", "interface", "try", "with", "case", "do", "if", "while", "match", "module", "import", "extern", "fun", - "at", "box", "unbox", "return", "region", "new", "resource", "and", "is", "namespace" + "at", "box", "return", "region", "new", "resource", "and", "is", "namespace" ) def keyword(kw: String): Parser[String] = @@ -419,7 +417,6 @@ class CoreParsers(positions: Positions, names: Names) extends EffektLexers(posit // ------ lazy val block: P[Block] = ( blockVar - | `unbox` ~> pure ^^ Block.Unbox.apply | `new` ~> implementation ^^ Block.New.apply | blockLit // TODO check left associative nesting (also for select) diff --git a/effekt/shared/src/main/scala/effekt/source/Tree.scala b/effekt/shared/src/main/scala/effekt/source/Tree.scala index 92d6e0fee..4864f2cd5 100644 --- a/effekt/shared/src/main/scala/effekt/source/Tree.scala +++ b/effekt/shared/src/main/scala/effekt/source/Tree.scala @@ -533,7 +533,7 @@ enum Term extends Tree { case Do(effect: Option[TypeRef], id: IdRef, targs: List[ValueType], vargs: List[ValueArg], bargs: List[Term], span: Span) extends Term, Reference /** - * A call to either an expression, i.e., `(fun() { ...})()`; or a named function, i.e., `foo()` + * A call to either an expression, i.e., `(box { () => ... })()`; or a named function, i.e., `foo()` */ case Call(target: CallTarget, targs: List[ValueType], vargs: List[ValueArg], bargs: List[Term], span: Span) diff --git a/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala b/effekt/shared/src/main/scala/effekt/typer/UnboxInference.scala similarity index 92% rename from effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala rename to effekt/shared/src/main/scala/effekt/typer/UnboxInference.scala index 7d6e4c0bd..b17aa1a67 100644 --- a/effekt/shared/src/main/scala/effekt/typer/BoxUnboxInference.scala +++ b/effekt/shared/src/main/scala/effekt/typer/UnboxInference.scala @@ -4,11 +4,11 @@ package typer import effekt.context.{ Annotations, Context, ContextOps } import effekt.symbols.* -object BoxUnboxInference extends Phase[NameResolved, NameResolved] { +object UnboxInference extends Phase[NameResolved, NameResolved] { import source._ - val phaseName = "box-unbox" + val phaseName = "unbox" def run(input: NameResolved)(using Context) = { val transformedTree = Context.timed(phaseName, input.source.name) { rewrite(input.tree) } @@ -52,12 +52,18 @@ object BoxUnboxInference extends Phase[NameResolved, NameResolved] { case v: Var => v.definition match { // TODO maybe we should synthesize a call to get here already? case sym: (ValueSymbol | symbols.RefBinder) => v - case sym: BlockSymbol => Box(Maybe.None(v.span.emptyAfter), v, v.span.synthesized).inheritPosition(v) + case sym: BlockSymbol => + C.error(pp"Computation ${sym} is used in an expression position, which requires boxing (e.g. `box ${sym}`") + v } - case n: New => Box(Maybe.None(n.span.emptyAfter), rewriteAsBlock(n), n.span.synthesized).inheritPosition(n) + case n: New => + C.error(pp"Creating an instance in an expression requires boxing (e.g. `box new ${n.impl.id}[...] { ... }`") + rewriteAsBlock(n) - case b: BlockLiteral => Box(Maybe.None(b.span.emptyAfter), rewriteAsBlock(b), b.span.synthesized).inheritPosition(b) + case b: BlockLiteral => + C.error(pp"Function literals in expression position require boxing (e.g. `box { (${b.vparams.map(_.id).mkString(", ")}) => ... `") + rewriteAsBlock(b) case l: Literal => l diff --git a/effekt/shared/src/main/scala/effekt/util/AnsiHighlight.scala b/effekt/shared/src/main/scala/effekt/util/AnsiHighlight.scala index 7df6c28ff..66f2af4f7 100644 --- a/effekt/shared/src/main/scala/effekt/util/AnsiHighlight.scala +++ b/effekt/shared/src/main/scala/effekt/util/AnsiHighlight.scala @@ -59,10 +59,10 @@ object AnsiHighlight { // keywords case `let` | `val` | `var` | `if` | `else` | `while` | - `type` | `effect` | `interface` | `fun` | `do` | `case` | `with` | `try` | + `type` | `effect` | `interface` | `do` | `case` | `with` | `try` | `true` | `false` | `match` | `def` | `module`| `import`| `export`| `extern`| `include`| - `record`| `box`| `unbox`| `return`| `region`| + `record`| `box`| `return`| `region`| `resource`| `new`| `and`| `is`| `namespace`| `pure` => keyword(text) case _ => text diff --git a/examples/benchmarks/are_we_fast_yet/bounce.effekt b/examples/benchmarks/are_we_fast_yet/bounce.effekt index d24417034..44332f7e0 100644 --- a/examples/benchmarks/are_we_fast_yet/bounce.effekt +++ b/examples/benchmarks/are_we_fast_yet/bounce.effekt @@ -16,7 +16,7 @@ def randomBall { rand: Random }: Ball at {global} = { val y = ref(toDouble(rand.next().mod(500))); val xVel = ref(toDouble(rand.next().mod(300) - 150)); val yVel = ref(toDouble(rand.next().mod(300) - 150)); - new Ball { + box new Ball { def bounce() = { val xLimit = 500.0; val yLimit = 500.0; diff --git a/examples/benchmarks/other/generator.effekt b/examples/benchmarks/other/generator.effekt index ac91d54ca..7b76c5cea 100644 --- a/examples/benchmarks/other/generator.effekt +++ b/examples/benchmarks/other/generator.effekt @@ -30,7 +30,7 @@ def generator { prog: => Unit / Yield } {r: Region}: Generator at {prog, r} = { cont = box { resume(()) } } } - new Generator { + box new Generator { def value() = v def next() = cont() } diff --git a/examples/benchmarks/other/nbe.effekt b/examples/benchmarks/other/nbe.effekt index e0791105b..4a0f0c837 100644 --- a/examples/benchmarks/other/nbe.effekt +++ b/examples/benchmarks/other/nbe.effekt @@ -62,7 +62,7 @@ def reify(v: Value): Term / fresh = v match { /// strong normalization of the term def normalize(t: Term): Term = { var i = 0 - try reify(eval(empty[Name, Value](compareInt), t)) + try reify(eval(empty[Name, Value](box compareInt), t)) with fresh { i = i + 1; resume(i) } } diff --git a/examples/benchmarks/other/variadic_combinators.effekt b/examples/benchmarks/other/variadic_combinators.effekt index a75962e49..acc8fbe75 100644 --- a/examples/benchmarks/other/variadic_combinators.effekt +++ b/examples/benchmarks/other/variadic_combinators.effekt @@ -41,7 +41,7 @@ def f3(fs: List[=> (Int => Int at {}) at {}]) = else first(fs)()(n - 1) } -def mod3(x: Int): Int = first(vfix([f1, f2, f3]))()(x) +def mod3(x: Int): Int = first(vfix([box f1, box f2, box f3]))()(x) def run(n: Int) = { mod3(n) + mod3(n + 1) + mod3(n + 2) diff --git a/examples/llvm/issue1012.effekt b/examples/llvm/issue1012.effekt index d35c1f54e..d540b89be 100644 --- a/examples/llvm/issue1012.effekt +++ b/examples/llvm/issue1012.effekt @@ -7,7 +7,7 @@ def use { g: (Int) => Int } : Int = { } def main() : Unit = { - val t = [f] + val t = [box f] list::map(t) { y => use {y} } println("hi") -} \ No newline at end of file +} diff --git a/examples/llvm/nosuchelement.effekt b/examples/llvm/nosuchelement.effekt index 160f665d8..be888e6f6 100644 --- a/examples/llvm/nosuchelement.effekt +++ b/examples/llvm/nosuchelement.effekt @@ -9,7 +9,7 @@ def id[A](f: ((A) => Unit at {io, global}) => Unit at {io, global}): ((A) => Uni // [error] java.util.NoSuchElementException: key not found: h def main() = { val f = box { (n: Int) => println(n) } - def h = id(g); + def h = id(box g); val x = h(f); println(x) } diff --git a/examples/llvm/prompt-duplication.effekt b/examples/llvm/prompt-duplication.effekt index 2811ce89e..78f379e75 100644 --- a/examples/llvm/prompt-duplication.effekt +++ b/examples/llvm/prompt-duplication.effekt @@ -9,8 +9,8 @@ def main() : Unit = { } with E { () => def f() = { () } def g() = { - resume(f) + resume(box f) } - resume(g) + resume(box g) } } diff --git a/examples/neg/blocks_in_value_pos.check b/examples/neg/blocks_in_value_pos.check index 48df119ca..7b7cf24d8 100644 --- a/examples/neg/blocks_in_value_pos.check +++ b/examples/neg/blocks_in_value_pos.check @@ -2,5 +2,5 @@ Unit but got type () => Unit / { MyPrint } at ?C - resume(prog); - ^^^^ + resume(box prog); + ^^^^^^^^ diff --git a/examples/neg/blocks_in_value_pos.effekt b/examples/neg/blocks_in_value_pos.effekt index d0dcb8600..85e3455f8 100644 --- a/examples/neg/blocks_in_value_pos.effekt +++ b/examples/neg/blocks_in_value_pos.effekt @@ -4,6 +4,6 @@ effect MyPrint(n: Int): Unit def main { prog: => Unit / MyPrint } = try { prog(); prog() } with MyPrint { (n: Int) => - resume(prog); + resume(box prog); println(n) } diff --git a/examples/neg/issue362.effekt b/examples/neg/issue362.effekt index fdcf535df..23ab294d0 100644 --- a/examples/neg/issue362.effekt +++ b/examples/neg/issue362.effekt @@ -7,5 +7,5 @@ def main() = { val cap = try { foo {arr} } with arr: Exc { def op() = resume(println("hey")) } - (unbox cap)() + cap() } diff --git a/examples/neg/issue365.check b/examples/neg/issue365.check index 1acc9ba3e..d3d2e8af2 100644 --- a/examples/neg/issue365.check +++ b/examples/neg/issue365.check @@ -1,3 +1,3 @@ [error] examples/neg/issue365.effekt:8:28: Not allowed {io} - val unboxed: Cap at {} = myCap; - ^^^^^ \ No newline at end of file + val unboxed: Cap at {} = box myCap; + ^^^^^^^^^ diff --git a/examples/neg/issue365.effekt b/examples/neg/issue365.effekt index 09a7fafbd..0aae4f189 100644 --- a/examples/neg/issue365.effekt +++ b/examples/neg/issue365.effekt @@ -5,6 +5,6 @@ extern io def cap(): Cap at {} = default { <> } def main() = { def myCap = cap() - val unboxed: Cap at {} = myCap; + val unboxed: Cap at {} = box myCap; () -} \ No newline at end of file +} diff --git a/examples/neg/issue50.check b/examples/neg/issue50.check index 422d91e7f..c0ee9b56c 100644 --- a/examples/neg/issue50.check +++ b/examples/neg/issue50.check @@ -1,3 +1,3 @@ [error] examples/neg/issue50.effekt:16:11: Not allowed {Effect2} - k = fun (x: Unit) { resume(x) }; - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + k = box { x => resume(x) }; + ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/neg/issue50.effekt b/examples/neg/issue50.effekt index 05b1acc45..93f301d22 100644 --- a/examples/neg/issue50.effekt +++ b/examples/neg/issue50.effekt @@ -8,19 +8,19 @@ def handle2 { prog: () => Unit / { Effect2 } }: Unit = { } def escape { prog: () => Unit / { Effect1, Effect2 } }: Unit = region this { - var k: (Unit) => Unit at { this, prog } in this = fun (x: Unit) { () } + var k: (Unit) => Unit at { this, prog } in this = box { x => () } handle2 { try { prog() } with Effect1 { () => - k = fun (x: Unit) { resume(x) }; + k = box { x => resume(x) }; resume(()) } } - (unbox k)(()) + k(()) } def main() = { escape { do Effect1(); do Effect2() } -} \ No newline at end of file +} diff --git a/examples/neg/issue512.effekt b/examples/neg/issue512.effekt index a67b3814c..996ab7f6f 100644 --- a/examples/neg/issue512.effekt +++ b/examples/neg/issue512.effekt @@ -6,9 +6,9 @@ def main() = { def myref = region r1 { // ERROR r1 var x in r1 = "hoho"; - new Ref[String] { + box new Ref[String] { def get() = x } } println(myref.get()) -} \ No newline at end of file +} diff --git a/examples/neg/issue548a.effekt b/examples/neg/issue548a.effekt index 4f52680f3..815a6eb04 100644 --- a/examples/neg/issue548a.effekt +++ b/examples/neg/issue548a.effekt @@ -12,7 +12,7 @@ def withTime[A] { prog: { Time } => A }: A = def main() = { def b { t: Time }: Time at {t} = box t; // this is fine val cap = withTime {b} // ERROR escape - def t2: Time = unbox cap + def t2: Time = cap t2.now(); () } diff --git a/examples/neg/lambdas/capability_closure.effekt b/examples/neg/lambdas/capability_closure.effekt index 27ef6587b..5fd15d014 100644 --- a/examples/neg/lambdas/capability_closure.effekt +++ b/examples/neg/lambdas/capability_closure.effekt @@ -4,7 +4,7 @@ interface Get { def outer() = { def inner(): Int / {} = do get() - fun() { inner() } + box { inner() } } def main() = { @@ -13,5 +13,5 @@ def main() = { } with Get { def get() = resume(42) } - (unbox f)() -} \ No newline at end of file + f() +} diff --git a/examples/neg/lambdas/closure.effekt b/examples/neg/lambdas/closure.effekt index b7525e4ed..bfdf94cbf 100644 --- a/examples/neg/lambdas/closure.effekt +++ b/examples/neg/lambdas/closure.effekt @@ -1,14 +1,14 @@ def twice { someBlock: () => Unit / {} } = { - fun() { someBlock(); someBlock() } + box { someBlock(); someBlock() } } effect Yield(): Unit def main() = { val f = try { // @Yield => - val g = fun(){ do Yield() } + val g = box { do Yield() } twice { - def unboxed() = { (unbox g)() }; + def unboxed() = { g() }; unboxed()// (@Yield) } } with Yield { println("yielded!"); resume(()) } f() -} \ No newline at end of file +} diff --git a/examples/neg/lambdas/continuations.check b/examples/neg/lambdas/continuations.check index e7cc7c70c..5bb2d9d71 100644 --- a/examples/neg/lambdas/continuations.check +++ b/examples/neg/lambdas/continuations.check @@ -1,3 +1,3 @@ [error] examples/neg/lambdas/continuations.effekt:17:14: Not allowed {Raise} - cont = fun() { resume(()) }; - ^^^^^^^^^^^^^^^^^^^^ + cont = box { resume(()) }; + ^^^^^^^^^^^^^^^^^^ diff --git a/examples/neg/lambdas/continuations.effekt b/examples/neg/lambdas/continuations.effekt index a507b1fc9..87c293989 100644 --- a/examples/neg/lambdas/continuations.effekt +++ b/examples/neg/lambdas/continuations.effekt @@ -4,7 +4,7 @@ effect Yield(): Unit def main() = region this { // here we use the region of the main function - var cont: () => Unit at {this} in this = fun() { () } + var cont: () => Unit at {this} in this = box { () } try { try { @@ -14,7 +14,7 @@ def main() = region this { } with Yield { // the assignment is not valid since the continuation must not leave // the current scope, which is the one of Raise. - cont = fun() { resume(()) }; + cont = box { resume(()) }; () } } with Raise { msg => @@ -22,4 +22,4 @@ def main() = region this { } cont() -} \ No newline at end of file +} diff --git a/examples/neg/lambdas/inference.check b/examples/neg/lambdas/inference.check index ea7eebe7e..5346308d3 100644 --- a/examples/neg/lambdas/inference.check +++ b/examples/neg/lambdas/inference.check @@ -1,28 +1,28 @@ [error] examples/neg/lambdas/inference.effekt:13:8: Expected type - (Int => Bool at {}) => String + (Int => Bool at {}) => String at {} but got type - (Int => Unit at {}) => String + (Int => Unit at {}) => String at ?C Type mismatch between Bool and Unit. comparing the argument types of (Int => Unit at {}) => String (given) (Int => Bool at {}) => String (expected) when comparing the return type of the function. - hof2(fun(f: (Int) => Unit at {}) { "" }) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -[error] examples/neg/lambdas/inference.effekt:13:8: Expected type - (Int => Bool at {}) => String at {} + hof2(box { (f: (Int) => Unit at {}) => "" }) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +[error] examples/neg/lambdas/inference.effekt:13:12: Expected type + (Int => Bool at {}) => String but got type - (Int => Unit at {}) => String at ?C + (Int => Unit at {}) => String Type mismatch between Bool and Unit. comparing the argument types of (Int => Unit at {}) => String (given) (Int => Bool at {}) => String (expected) when comparing the return type of the function. - hof2(fun(f: (Int) => Unit at {}) { "" }) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -[error] examples/neg/lambdas/inference.effekt:13:12: Type Int => Unit at {} does not match the declared type Int => Bool at {}. + hof2(box { (f: (Int) => Unit at {}) => "" }) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +[error] examples/neg/lambdas/inference.effekt:13:15: Type Int => Unit at {} does not match the declared type Int => Bool at {}. when comparing the return type of the function. - hof2(fun(f: (Int) => Unit at {}) { "" }) - ^^^^^^^^^^^^^^^^^^^^^^ + hof2(box { (f: (Int) => Unit at {}) => "" }) + ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/neg/lambdas/inference.effekt b/examples/neg/lambdas/inference.effekt index 9e0e24ffb..d64c4eaea 100644 --- a/examples/neg/lambdas/inference.effekt +++ b/examples/neg/lambdas/inference.effekt @@ -5,11 +5,11 @@ def main() = { def hof1(f: (Int) => String at {}): Unit = () def hof2(f: ((Int) => Bool at {}) => String at {}): Unit = () - hof2(fun (f: (Int) => Bool at {}) { + hof2(box { (f: (Int) => Bool at {}) => f(3); "" }) - hof2(fun(f: (Int) => Unit at {}) { "" }) - hof1(fun(b: Bool) { () }) -} \ No newline at end of file + hof2(box { (f: (Int) => Unit at {}) => "" }) + hof1(box { (b: Bool) => () }) +} diff --git a/examples/neg/lambdas/localstate.effekt b/examples/neg/lambdas/localstate.effekt index dcfa3de3a..5e950e7f1 100644 --- a/examples/neg/lambdas/localstate.effekt +++ b/examples/neg/lambdas/localstate.effekt @@ -7,7 +7,7 @@ def main() = { def count1(n: Int): Int = if (n == 0) n else count1(n - 1) - def hof { g2 : => Unit } = fun () { + def hof { g2 : => Unit } = box { x = x + 1 println(x + y); g2() } @@ -21,4 +21,4 @@ def main() = { incrementer } local() -} \ No newline at end of file +} diff --git a/examples/neg/lambdas/polymorphicescape.check b/examples/neg/lambdas/polymorphicescape.check index 584ff49bd..5677648b8 100644 --- a/examples/neg/lambdas/polymorphicescape.check +++ b/examples/neg/lambdas/polymorphicescape.check @@ -1,3 +1,3 @@ [error] examples/neg/lambdas/polymorphicescape.effekt:37:14: Not allowed {leak} - leak = fun() { resume(h) } // ERROR - ^^^^^^^^^^^^^^^^^^^ + leak = box { resume(h) } // ERROR + ^^^^^^^^^^^^^^^^^ diff --git a/examples/neg/lambdas/polymorphicescape.effekt b/examples/neg/lambdas/polymorphicescape.effekt index 314cc8ef2..8597f95ff 100644 --- a/examples/neg/lambdas/polymorphicescape.effekt +++ b/examples/neg/lambdas/polymorphicescape.effekt @@ -16,7 +16,7 @@ def two[A, B]() = (do get[A](), do get[B]()) def main() = { - var leak: () => String at {io} = fun() { "" }; + var leak: () => String at {io} = box { "" }; try { val (n1, n2) = two[Int, Int](); println(n1); @@ -34,8 +34,8 @@ def main() = { def get() = resume("") def put[S](n, x) = { val h = x; - leak = fun() { resume(h) } // ERROR + leak = box { resume(h) } // ERROR resume(h) } } -} \ No newline at end of file +} diff --git a/examples/neg/lambdas/simpleescape.effekt b/examples/neg/lambdas/simpleescape.effekt index 961b7f49c..2d0ab6d9f 100644 --- a/examples/neg/lambdas/simpleescape.effekt +++ b/examples/neg/lambdas/simpleescape.effekt @@ -6,9 +6,9 @@ def main() = { try { def block(msg: String): Unit / {} = { do Raise(msg) } val f = if (do Flip()) { - fun() { block("first") } + box { block("first") } } else { - fun() { block("second") } + box { block("second") } } f } with Raise { msg => diff --git a/examples/pos/bidirectional/scheduler.effekt b/examples/pos/bidirectional/scheduler.effekt index 8349f310a..c4997861d 100644 --- a/examples/pos/bidirectional/scheduler.effekt +++ b/examples/pos/bidirectional/scheduler.effekt @@ -18,12 +18,12 @@ def scheduler { prog: => Unit / Process } = region this { } try { prog() } with Process { def yield() = { - queue = queue.pushFront(fun() { resume(()) }) + queue = queue.pushFront(box { resume(()) }) } def fork() /* {{() => Unit} => Unit} => Unit */ = { queue = queue - .pushFront(fun() { resume { {prog: () => Unit} => prog() /* FIX do abort() */ } }) - .pushFront(fun() { resume { {prog: () => Unit} => () } }) + .pushFront(box { resume { {prog: () => Unit} => prog() /* FIX do abort() */ } }) + .pushFront(box { resume { {prog: () => Unit} => () } }) } def exit() /* Nothing => Unit */ = () } @@ -51,4 +51,4 @@ def main() = { do yield() println(6) } -} \ No newline at end of file +} diff --git a/examples/pos/capture/borrows.effekt b/examples/pos/capture/borrows.effekt index 9bedb2214..4c1447140 100644 --- a/examples/pos/capture/borrows.effekt +++ b/examples/pos/capture/borrows.effekt @@ -6,9 +6,9 @@ interface Borrowed[T] { def main() = { var counter = 22; - val p : Borrowed[Int] at {counter} = new Borrowed[Int] { + val p : Borrowed[Int] at {counter} = box new Borrowed[Int] { def dereference() = counter }; counter = counter + 1; println(p.dereference) -} \ No newline at end of file +} diff --git a/examples/pos/capture/defdef.effekt b/examples/pos/capture/defdef.effekt index 2be88e1ba..b9a54b1d1 100644 --- a/examples/pos/capture/defdef.effekt +++ b/examples/pos/capture/defdef.effekt @@ -3,21 +3,21 @@ def myModule { eff : Eff } = region this { def outer = this; - val e1 = fun() { eff.use(); () }; - def x = unbox e1; + val e1 = box { eff.use(); () }; + def x = e1; def test1() = x(); def test1b = x; - val f: () => Unit at {eff} = test1b; + val f: () => Unit at {eff} = box test1b; def test2() = { test1(); var x in outer = 42; x }; - val g = test2; + val g = box test2; () } -def main() = () \ No newline at end of file +def main() = () diff --git a/examples/pos/capture/forcing.effekt b/examples/pos/capture/forcing.effekt index 1fd5a84c9..4b74cff32 100644 --- a/examples/pos/capture/forcing.effekt +++ b/examples/pos/capture/forcing.effekt @@ -1,9 +1,9 @@ type NumberThunk = () => Int at {} def force(t: NumberThunk): Int = t() -def init(n: Int): NumberThunk = fun() { n } -def test(): NumberThunk = fun() { +def init(n: Int): NumberThunk = box { n } +def test(): NumberThunk = box { val num: Int = (init(42))() num } -def main() = println(test()()) \ No newline at end of file +def main() = println(test()()) diff --git a/examples/pos/capture/mbed.effekt b/examples/pos/capture/mbed.effekt index 7111febbf..d281bf626 100644 --- a/examples/pos/capture/mbed.effekt +++ b/examples/pos/capture/mbed.effekt @@ -67,7 +67,7 @@ def loop[T] { f: => Unit / Loop[T] }: T = { } -def DigitalOut(name: String) = new Output { +def DigitalOut(name: String) = box new Output { def set(n: Bool) = useOut() def get() = { useOut(); true } } @@ -99,7 +99,7 @@ def main() = { if (x <= 0) do break("STOP"); // also ok! - precise.timeout(100.millis, flip) + precise.timeout(100.millis, box flip) } // not allowed! diff --git a/examples/pos/capture/optimizing_unbox.effekt b/examples/pos/capture/optimizing_unbox.effekt index 8982fa714..7eb0bee27 100644 --- a/examples/pos/capture/optimizing_unbox.effekt +++ b/examples/pos/capture/optimizing_unbox.effekt @@ -3,11 +3,11 @@ effect Yield(): Unit def main() = try { val make = { - val f = fun() { y.Yield() } + val f = box { y.Yield() } f } // here we had the problem that we perform the direct-style "run-optimization", even though make obviously has capture set {y} val res = make(); println(res) -} with y: Yield { () } \ No newline at end of file +} with y: Yield { () } diff --git a/examples/pos/capture/regions.effekt b/examples/pos/capture/regions.effekt index 39534ae05..945633e4a 100644 --- a/examples/pos/capture/regions.effekt +++ b/examples/pos/capture/regions.effekt @@ -16,7 +16,7 @@ def makeCounter {r: Region} = { def get() = state def inc() = state = state + 1 } - c1 + box c1 } def twoCounters() = { @@ -43,7 +43,7 @@ def twoCounters() = { val _ = { def c1 = makeCounter {inner} def c2 = makeCounter {outer} - val l = Cons(c1, Cons(c2, Nil())); + val l = Cons(box c1, Cons(box c2, Nil())); () }; () @@ -73,7 +73,7 @@ def testLifted2() = try { def get() = do Get() def inc() = () }; - obj + box obj } // should print 42 println(o.get()) @@ -95,7 +95,7 @@ def main() = region this { c1.inc() println(c1.get()) - val boxed = c1; + val boxed = box c1; boxed }; @@ -107,4 +107,4 @@ def main() = region this { // testLifted2(); () -} \ No newline at end of file +} diff --git a/examples/pos/capture/resources.effekt b/examples/pos/capture/resources.effekt index fe8dfc058..6977761f7 100644 --- a/examples/pos/capture/resources.effekt +++ b/examples/pos/capture/resources.effekt @@ -19,7 +19,7 @@ def parameter[T] {a: Array[T]} = { } def main() = { - val f: () => Int at {foo} = user; + val f: () => Int at {foo} = box user; val arr = makeArray[Int](10); inspect(arr); () diff --git a/examples/pos/capture/selfregion.effekt b/examples/pos/capture/selfregion.effekt index b2e14bfb3..8c546594d 100644 --- a/examples/pos/capture/selfregion.effekt +++ b/examples/pos/capture/selfregion.effekt @@ -1,6 +1,6 @@ def bar {r: Region} = { var x in r = 42 - fun() { x = x + 1; x } + box { x = x + 1; x } } def ex1() = region this { @@ -57,4 +57,4 @@ def main() = { ex4(); ex5(); ex6() -} \ No newline at end of file +} diff --git a/examples/pos/capture/state_eff.effekt b/examples/pos/capture/state_eff.effekt index 92d0af88a..572a83eac 100644 --- a/examples/pos/capture/state_eff.effekt +++ b/examples/pos/capture/state_eff.effekt @@ -9,14 +9,14 @@ def handleState[S, R](init: S) { prog: {State[S]} => R }: R = { val res = prog {state} box { (s: S) => res } at {prog} } with state: State[S] { - def get() = box { (s: S) => (unbox resume(s))(s) } - def set(x) = box { (s: S) => (unbox resume(()))(x) } + def get() = box { (s: S) => (resume(s))(s) } + def set(x) = box { (s: S) => (resume(()))(x) } } - (unbox stateFun)(init) + stateFun(init) } def main() = - handleState(0) { {s: State[Int]} => + handleState(0) { {s: State[Int]} => println(s.get[Int]()) s.set(2) println(s.get[Int]()) diff --git a/examples/pos/global_capabilities.effekt b/examples/pos/global_capabilities.effekt index 2e342a5a1..e306dcfd0 100644 --- a/examples/pos/global_capabilities.effekt +++ b/examples/pos/global_capabilities.effekt @@ -29,11 +29,11 @@ def globalCapabilities { console: MyConsole } { time: Time }: Unit = { val repeatTime = repeater { sayTime }; // some more variants illustrating closure and capability sets - val b = sayTime; + val b = box sayTime; val n = repeater { () => sayTime() }; val n1 = repeater { sayTime }; - val b2 : () => Unit at {console, time} = box { () => (unbox n)(3) }; + val b2 : () => Unit at {console, time} = box { () => n(3) }; val b3 = n(3); val b4 = box { () => n(3) }; val r = repeater { b }; @@ -50,7 +50,7 @@ def localCapabilities { console: MyConsole } { time: Time }: Unit = } def effectHandlers { console: MyConsole } { time: Time }: Unit = { - def report(t: Int) = console.myprintln(show(t) ++ "ms") + def report(t: Int) = console.myprintln(show(t) ++ "ms") val before = time.now(); try { @@ -73,7 +73,7 @@ def run[T] { prog : {MyConsole} {Time} => T }: T = { } with console: MyConsole { def myprintln(msg) = { println(msg); resume(()) } } with time: Time { - def now() = { + def now() = { i = i + 1 resume(i) } diff --git a/examples/pos/infer/infer_boxed.effekt b/examples/pos/infer/infer_boxed.effekt index da8860bbc..74615cfda 100644 --- a/examples/pos/infer/infer_boxed.effekt +++ b/examples/pos/infer/infer_boxed.effekt @@ -1,5 +1,5 @@ def definition() = { - val f = fun() { 1 }; + val f = box { 1 }; f } @@ -10,4 +10,4 @@ def callsite() = // a() def main() = - println(callsite()) \ No newline at end of file + println(callsite()) diff --git a/examples/pos/infer/infer_effect_polymorphic.effekt b/examples/pos/infer/infer_effect_polymorphic.effekt index 251a05e14..a47e9bd36 100644 --- a/examples/pos/infer/infer_effect_polymorphic.effekt +++ b/examples/pos/infer/infer_effect_polymorphic.effekt @@ -4,7 +4,7 @@ effect Yield(): Unit def effectPolymorphic() = { //: () => Unit at {effectPolymorphic} / Yield = { def local(): Unit = do Yield() - fun() { local() } + box { local() } } def main() = diff --git a/examples/pos/issue108.effekt b/examples/pos/issue108.effekt index 23f56c862..4086a3ea0 100644 --- a/examples/pos/issue108.effekt +++ b/examples/pos/issue108.effekt @@ -31,14 +31,14 @@ def mapping[A, B] {f: A => B} : Unit / {Reduce[A], Iterate[B]} = } def reduce[A, B] {iterator: () => Unit / Iterate[A]} {reducer: () => B / Reduce[A]} = { - var coroutine = fun() {Absent()} - coroutine = fun() { + var coroutine = box { Absent() } + coroutine = box { try { iterator() Absent() } with Iterate[A] { def emit(e) = { - coroutine = fun() {resume(())} + coroutine = box { resume(()) } Present(e) } } diff --git a/examples/pos/lambdas/annotated.effekt b/examples/pos/lambdas/annotated.effekt index a5d161035..7cd1a6550 100644 --- a/examples/pos/lambdas/annotated.effekt +++ b/examples/pos/lambdas/annotated.effekt @@ -3,9 +3,9 @@ effect Exc(): Unit def main() = try { def closure(): Unit = do Exc() - val g: () => Unit / Exc at {exc} = fun() { closure() } + val g: () => Unit / Exc at {exc} = box { closure() } g() } with exc: Exc { println("exception!"); resume(()) - } \ No newline at end of file + } diff --git a/examples/pos/lambdas/effects.effekt b/examples/pos/lambdas/effects.effekt index 1d921119b..7f5a382f6 100644 --- a/examples/pos/lambdas/effects.effekt +++ b/examples/pos/lambdas/effects.effekt @@ -3,11 +3,11 @@ interface Get { def get(): Unit } interface Yield { def yield(): Unit } def main() = { - val f1: () => Unit / { Exc, Get } at {} = fun() { () }; - val f2: () => Unit / { Exc, Get } at {} = fun() { do raise() }; - val f3: () => Unit / { Exc, Get } at {} = fun() { do raise(); do get() }; - // val f4: () => Unit / { Exc, Get } at {} = fun() { do raise(); do yield() }; + val f1: () => Unit / { Exc, Get } at {} = box { () }; + val f2: () => Unit / { Exc, Get } at {} = box { do raise() }; + val f3: () => Unit / { Exc, Get } at {} = box { do raise(); do get() }; + // val f4: () => Unit / { Exc, Get } at {} = box { do raise(); do yield() }; // val f5: () => Unit / { Exc } at {} = f3; () -} \ No newline at end of file +} diff --git a/examples/pos/lambdas/generators.effekt b/examples/pos/lambdas/generators.effekt index 32f1dd758..9d28de35f 100644 --- a/examples/pos/lambdas/generators.effekt +++ b/examples/pos/lambdas/generators.effekt @@ -13,18 +13,18 @@ def numbers() = { def main() = region this { - var generator: () => Result at {this} in this = fun() { Done() } + var generator: () => Result at {this} in this = box { Done() } try { numbers() - generator = fun() { Done() } + generator = box { Done() } } with Yield { n => - generator = fun() { resume(()); Next(n) } + generator = box { resume(()); Next(n) } } // right now we do not infer unbox for a mutable variable since it // already is of block type. - def gen() = (unbox generator)() + def gen() = generator() println(gen()) println(gen()) println(gen()) diff --git a/examples/pos/lambdas/higherorder.effekt b/examples/pos/lambdas/higherorder.effekt index 937bf068b..632b29452 100644 --- a/examples/pos/lambdas/higherorder.effekt +++ b/examples/pos/lambdas/higherorder.effekt @@ -4,16 +4,16 @@ effect Yield(): Unit def repeater { f: => Unit }: Int => Int at {f} = { def rec(n: Int): Int = if (n == 0) { f(); n } else rec(n - 1) - fun(n: Int) { rec(n) } + box { n => rec(n) } } def main() = try { val repeat = repeater { do Yield(); println("hello") }; - def closure(): Int = (unbox repeat)(3); - val g = fun(n: Int) { closure(); n + 1 } - def unboxed() = (unbox g)(1); + def closure(): Int = repeat(3); + val g = box { (n: Int) => closure(); n + 1 } + def unboxed() = g(1); unboxed(); () } with Yield { println("yielded"); resume(()) } diff --git a/examples/pos/lambdas/localstate.effekt b/examples/pos/lambdas/localstate.effekt index 5043873d1..69bb07fb1 100644 --- a/examples/pos/lambdas/localstate.effekt +++ b/examples/pos/lambdas/localstate.effekt @@ -7,7 +7,7 @@ def main() = { def count1(n: Int): Int = if (n == 0) n else count1(n - 1) - def hof { g2 : => Unit } = fun () { + def hof { g2 : => Unit } = box { x = x + 1 println(x + y); g2() } @@ -22,4 +22,4 @@ def main() = { () } local() -} \ No newline at end of file +} diff --git a/examples/pos/lambdas/scheduler.effekt b/examples/pos/lambdas/scheduler.effekt index 64305c9e5..f0a0198f3 100644 --- a/examples/pos/lambdas/scheduler.effekt +++ b/examples/pos/lambdas/scheduler.effekt @@ -20,12 +20,12 @@ def scheduler { prog: => Unit / Proc } = region this { } try { prog() } with Proc { def yield() = { - queue = queue.pushFront(fun() { resume(()) }) + queue = queue.pushFront(box { resume(()) }) } def fork() = { queue = queue - .pushFront(fun() { resume(true) }) - .pushFront(fun() { resume(false) }) + .pushFront(box { resume(true) }) + .pushFront(box { resume(false) }) } def exit() = () } @@ -57,4 +57,4 @@ def main() = { println(6) } } -} \ No newline at end of file +} diff --git a/examples/pos/lambdas/simpleclosure.effekt b/examples/pos/lambdas/simpleclosure.effekt index 7d2879af4..742b31c08 100644 --- a/examples/pos/lambdas/simpleclosure.effekt +++ b/examples/pos/lambdas/simpleclosure.effekt @@ -14,14 +14,14 @@ def main() = { // since `block` closes over `Raise` we have to make sure that // it cannot leave the outer `try`. if (do Flip()) { - fun() { block("first") } + box { block("first") } } else { - fun() { block("second") } + box { block("second") } } } with Flip { // the continuation itself transitively closes over `block` and `Raise`. // it also must not leave the scope of Raise. - val h: () => Unit at {raise} = fun() { (resume(true))(); (resume(false))() } + val h: () => Unit at {raise} = box { (resume(true))(); (resume(false))() } h } diff --git a/examples/stdlib/map/cache.effekt b/examples/stdlib/map/cache.effekt index 10f3f8455..210f6d6d0 100644 --- a/examples/stdlib/map/cache.effekt +++ b/examples/stdlib/map/cache.effekt @@ -8,7 +8,7 @@ effect time(): Int def main() = { var currentTime = 0 try { - var cache: Map[String, CacheEntry[String]] = map::empty(compareStringBytes) + var cache: Map[String, CacheEntry[String]] = map::empty(box compareStringBytes) val maxAge = 8 def cachePut(key: String, value: String): Unit = diff --git a/examples/stdlib/map/counter.effekt b/examples/stdlib/map/counter.effekt index b6e7d6cd4..ef452916a 100644 --- a/examples/stdlib/map/counter.effekt +++ b/examples/stdlib/map/counter.effekt @@ -3,7 +3,7 @@ import map import bytearray def counter(words: List[String]): Map[String, Int] = { - var m: Map[String, Int] = map::empty(compareStringBytes); + var m: Map[String, Int] = map::empty(box compareStringBytes); list::foreach(words) { word => m = m.putWithKey(word, 1) { (_, n1, n2) => n1 + n2 } diff --git a/examples/stdlib/map/map.effekt b/examples/stdlib/map/map.effekt index 7033b8519..5a47eead1 100644 --- a/examples/stdlib/map/map.effekt +++ b/examples/stdlib/map/map.effekt @@ -3,7 +3,7 @@ import map def main() = { val l = [(0, "Hello"), (1, "World"), (2, "Woo!")] - val m = map::fromList(l, compareInt) + val m = map::fromList(l, box compareInt) println(map::internal::prettyPairs(m.toList) { n => show(n) } { s => show(s) }) val m2 = m.put(-1, "Hullo") @@ -17,12 +17,12 @@ def main() = { val m4 = m.delete(1).put(42, "Whole new world!").put(100, "Big").put(1000, "Bigger").put(10000, "Biggest!") println(map::internal::prettyPairs(m4.toList) { n => show(n) } { s => show(s) }) - val m5 = map::fromList(Cons((1, "Foo"), Cons((-1, "Huh?!"), m4.toList.reverse)), compareInt) + val m5 = map::fromList(Cons((1, "Foo"), Cons((-1, "Huh?!"), m4.toList.reverse)), box compareInt) println(map::internal::prettyPairs(m5.toList) { n => show(n) } { s => show(s) }) - val m6: Map[Int, String] = m5.toList.fromList(compareInt) + val m6: Map[Int, String] = m5.toList.fromList(box compareInt) println(map::internal::prettyPairs(m6.toList) { n => show(n) } { s => show(s) }) - val nuMap = map::fromList(l.reverse, compareInt) + val nuMap = map::fromList(l.reverse, box compareInt) println(map::internal::prettyPairs(nuMap.toList) { n => show(n) } { s => show(s) }) } diff --git a/examples/stdlib/map/minmax.effekt b/examples/stdlib/map/minmax.effekt index 627c5ace9..ae5399f65 100644 --- a/examples/stdlib/map/minmax.effekt +++ b/examples/stdlib/map/minmax.effekt @@ -6,7 +6,7 @@ def show(opt: Option[(Int, String)]): String = opt match { } def main() = { - val m = map::fromList([(10, "Ten"), (20, "Twenty"), (5, "Five"), (30, "Thirty")], compareInt) + val m = map::fromList([(10, "Ten"), (20, "Twenty"), (5, "Five"), (30, "Thirty")], box compareInt) val min: Option[(Int, String)] = m.getMin val max: Option[(Int, String)] = m.getMax diff --git a/examples/stdlib/map/setops.effekt b/examples/stdlib/map/setops.effekt index c8ebc6295..c052cae03 100644 --- a/examples/stdlib/map/setops.effekt +++ b/examples/stdlib/map/setops.effekt @@ -2,19 +2,19 @@ import map def main() = { // Create multiple maps - val map1 = map::fromList([(1, "apple"), (2, "banana"), (3, "cherry")], compareInt) - val map2 = map::fromList([(2, "berry"), (3, "date"), (4, "elderberry")], compareInt) + val map1 = map::fromList([(1, "apple"), (2, "banana"), (3, "cherry")], box compareInt) + val map2 = map::fromList([(2, "berry"), (3, "date"), (4, "elderberry")], box compareInt) // Test union with different combine strategies println("Union (keeping first value):") println(map::internal::prettyPairs(map1.union(map2).toList) { n => show(n) } { s => show(s) }) println("\nUnion (combining values):") - val combinedMap = map1.union(map2, compareInt) { (k, v1, v2) => v1 ++ "/" ++ v2 } + val combinedMap = map1.union(map2, box compareInt) { (k, v1, v2) => v1 ++ "/" ++ v2 } println(map::internal::prettyPairs(combinedMap.toList) { n => show(n) } { s => show(s) }) // Test intersection println("\nIntersection (combining keys):") - val intersectedMap = map1.intersection(map2, compareInt) { (k, v1, v2) => v1 ++ "-" ++ v2 } + val intersectedMap = map1.intersection(map2, box compareInt) { (k, v1, v2) => v1 ++ "-" ++ v2 } println(map::internal::prettyPairs(intersectedMap.toList) { n => show(n) } { s => show(s) }) } diff --git a/examples/stdlib/set/unique.effekt b/examples/stdlib/set/unique.effekt index ed5ef68aa..57d981bf6 100644 --- a/examples/stdlib/set/unique.effekt +++ b/examples/stdlib/set/unique.effekt @@ -3,7 +3,7 @@ import set import bytearray def unique(words: List[String]): Set[String] = { - var s: Set[String] = set::empty(compareStringBytes); + var s: Set[String] = set::empty(box compareStringBytes); list::foreach(words) { word => s = s.insert(word) @@ -58,8 +58,8 @@ def main() = { println(uniqueSpeech.toList) testSorted(uniqueSpeech) - println(set::fromList(speech, compareStringBytes).toList) - testSorted(set::fromList(speech, compareStringBytes)) + println(set::fromList(speech, box compareStringBytes).toList) + testSorted(set::fromList(speech, box compareStringBytes)) // --- println("") diff --git a/examples/stdlib/stream/map.effekt b/examples/stdlib/stream/map.effekt index 4f1a7efb5..669f661d4 100644 --- a/examples/stdlib/stream/map.effekt +++ b/examples/stdlib/stream/map.effekt @@ -2,13 +2,13 @@ import stream import map def main() = { - val m = map::fromList([(1, 'H'), (2, 'e'), (3, 'l'), (4, 'l'), (5, 'o')], compareInt) + val m = map::fromList([(1, 'H'), (2, 'e'), (3, 'l'), (4, 'l'), (5, 'o')], box compareInt) for[(Int, Char)] { each(m) } { case (k, v) => println(show(k) ++ ": " ++ show(v) ++ " (" ++ show(v.toInt) ++ ")") } - val newMap = collectMap[Int, Char](compareInt) { each(m) } + val newMap = collectMap[Int, Char](box compareInt) { each(m) } println(map::internal::prettyPairs(newMap.toList) { n => show(n) } { c => show(c) }) val hello: String = collectString { eachValue(m) } diff --git a/examples/tour/captures.effekt.md b/examples/tour/captures.effekt.md index 3ce9b5a73..292355ca7 100644 --- a/examples/tour/captures.effekt.md +++ b/examples/tour/captures.effekt.md @@ -38,7 +38,7 @@ For the same reason, we must not return a function that closes over such a capab To prevent capabilities from escaping their scope, Effekt tracks captures. In the case of the previous example, the return type of the handler is `Exception at {exc}`. -This is called a boxed computation. A boxed computation may only be used after unboxing it, which is only permitted when all its captures are in scope. In fact, the example above does not typecheck, since the type `Exception at {exc}` would not be well-formed outside of the handler that introduces (and binds!) the capability `exc`. +This is called a boxed computation. A boxed computation may only be used after unboxing it, which happens automatically and is only permitted when all its captures are in scope. In fact, the example above does not typecheck, since the type `Exception at {exc}` would not be well-formed outside of the handler that introduces (and binds!) the capability `exc`. ## Boxing @@ -83,7 +83,7 @@ Thus, we need to enforce that both `f` and `g` are pure, that is, do not capture ``` def parallel (f: () => Unit at {}, g: () => Unit at {}): Unit = <> ``` -The type-checker will reject calls, where we try to pass functions that to close over capabilities (or builtin resources): +The type-checker will reject calls, where we try to pass functions that close over capabilities (or builtin resources): ```effekt:repl parallel( box { () => println("Hello, ") }, diff --git a/libraries/common/buffer.effekt b/libraries/common/buffer.effekt index 6002bc2c0..8d0d8e5d1 100644 --- a/libraries/common/buffer.effekt +++ b/libraries/common/buffer.effekt @@ -62,11 +62,11 @@ def arrayBuffer[T](initialCapacity: Int): Buffer[T] at {global} = { tail.set(mod(tail.get + 1, initialCapacity)) } } - buffer + box buffer } def refBuffer[T](): Buffer[T] at {global} = { val content = ref(None()) - new Buffer[T] { + box new Buffer[T] { def capacity() = if (content.get.isEmpty) 1 else 0 def full?() = content.get.isDefined def empty?() = isEmpty(content.get) diff --git a/libraries/common/queue.effekt b/libraries/common/queue.effekt index 8fe07ee9a..69a0430e8 100644 --- a/libraries/common/queue.effekt +++ b/libraries/common/queue.effekt @@ -103,7 +103,7 @@ def emptyQueue[T](initialCapacity: Int): Queue[T] at {global} = { tail.set(mod(tail.get + 1, capacity.get)) } } - queue + box queue } namespace examples { diff --git a/libraries/common/seq.effekt b/libraries/common/seq.effekt index 76af81ac8..b0eba9e54 100644 --- a/libraries/common/seq.effekt +++ b/libraries/common/seq.effekt @@ -875,7 +875,7 @@ def map[A, B](seq: Seq[A]) { f: (A) {Control} => B }: Seq[B] = { // def iterate[A, R](seq: Seq[A]) { prog: {Iterator[A]} => R }: R = { -// var k: Unit => Unit at {} = fun(unit: Unit) { () } +// var k: Unit => Unit at {} = box { () => () } // var v: Option[A] = None() // try { seq.each { el => do yield(el) } } with Generator[A] {