changeset 23428:5807e3958e38 v8.2.2257

patch 8.2.2257: Vim9: using -> for lambda is ambiguous Commit: https://github.com/vim/vim/commit/2949cfdbe4335b9abcfeda1be4dfc52090ee1df6 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 31 21:28:47 2020 +0100 patch 8.2.2257: Vim9: using -> for lambda is ambiguous Problem: Vim9: using -> for lambda is ambiguous. Solution: Stop supporting ->, must use =>.
author Bram Moolenaar <Bram@vim.org>
date Thu, 31 Dec 2020 21:30:03 +0100
parents 8f2dcc0cfcf6
children de278e062eb6
files src/eval.c src/testdir/test_vim9_assign.vim src/testdir/test_vim9_builtin.vim src/testdir/test_vim9_cmd.vim src/testdir/test_vim9_disassemble.vim src/testdir/test_vim9_expr.vim src/testdir/test_vim9_func.vim src/testdir/test_vim9_script.vim src/version.c src/vim9compile.c
diffstat 10 files changed, 142 insertions(+), 178 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -3316,7 +3316,10 @@ eval7(
      * Lambda: {arg, arg -> expr}
      * Dictionary: {'key': val, 'key': val}
      */
-    case '{':	ret = get_lambda_tv(arg, rettv, in_vim9script(), evalarg);
+    case '{':	if (in_vim9script())
+		    ret = NOTDONE;
+		else
+		    ret = get_lambda_tv(arg, rettv, in_vim9script(), evalarg);
 		if (ret == NOTDONE)
 		    ret = eval_dict(arg, rettv, evalarg, FALSE);
 		break;
@@ -3617,7 +3620,24 @@ eval_lambda(
     *arg += 2;
     rettv->v_type = VAR_UNKNOWN;
 
-    ret = get_lambda_tv(arg, rettv, FALSE, evalarg);
+    if (**arg == '{')
+    {
+	// ->{lambda}()
+	ret = get_lambda_tv(arg, rettv, FALSE, evalarg);
+    }
+    else
+    {
+	// ->(lambda)()
+	++*arg;
+	ret = eval1(arg, rettv, evalarg);
+	*arg = skipwhite_and_linebreak(*arg, evalarg);
+	if (**arg != ')')
+	{
+	    emsg(_(e_missing_close));
+	    ret = FAIL;
+	}
+	++*arg;
+    }
     if (ret != OK)
 	return FAIL;
     else if (**arg != '(')
@@ -5645,8 +5665,8 @@ handle_subscript(
 	    *arg = p;
 	    if (ret == OK)
 	    {
-		if ((*arg)[2] == '{')
-		    // expr->{lambda}()
+		if (((*arg)[2] == '{' && !in_vim9script()) || (*arg)[2] == '(')
+		    // expr->{lambda}() or expr->(lambda)()
 		    ret = eval_lambda(arg, rettv, evalarg, verbose);
 		else
 		    // expr->name()
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -66,7 +66,7 @@ def Test_assignment()
   CheckDefFailure(['var x:string'], 'E1069:')
   CheckDefFailure(['var x:string = "x"'], 'E1069:')
   CheckDefFailure(['var a:string = "x"'], 'E1069:')
-  CheckDefFailure(['var lambda = {-> "lambda"}'], 'E704:')
+  CheckDefFailure(['var lambda = () => "lambda"'], 'E704:')
   CheckScriptFailure(['var x = "x"'], 'E1124:')
 
   var nr: number = 1234
@@ -1032,11 +1032,11 @@ def Test_assign_lambda()
   # check if assign a lambda to a variable which type is func or any.
   var lines =<< trim END
       vim9script
-      var FuncRef = {-> 123}
+      var FuncRef = () => 123
       assert_equal(123, FuncRef())
-      var FuncRef_Func: func = {-> 123}
+      var FuncRef_Func: func = () => 123
       assert_equal(123, FuncRef_Func())
-      var FuncRef_Any: any = {-> 123}
+      var FuncRef_Any: any = () => 123
       assert_equal(123, FuncRef_Any())
   END
   CheckScriptSuccess(lines)
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -231,7 +231,7 @@ def Test_extend_arg_types()
   assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, s:string_keep))
 
   var res: list<dict<any>>
-  extend(res, map([1, 2], {_, v -> {}}))
+  extend(res, map([1, 2], (_, v) => ({})))
   assert_equal([{}, {}], res)
 
   CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number')
@@ -254,7 +254,7 @@ enddef
 
 
 def Wrong_dict_key_type(items: list<number>): list<number>
-  return filter(items, {_, val -> get({[val]: 1}, 'x')})
+  return filter(items, (_, val) => get({[val]: 1}, 'x'))
 enddef
 
 def Test_map_function_arg()
@@ -313,7 +313,7 @@ def Test_filter_wrong_dict_key_type()
 enddef
 
 def Test_filter_return_type()
-  var l = filter([1, 2, 3], {-> 1})
+  var l = filter([1, 2, 3], () => 1)
   var res = 0
   for n in l
     res += n
@@ -323,7 +323,7 @@ enddef
 
 def Test_filter_missing_argument()
   var dict = {aa: [1], ab: [2], ac: [3], de: [4]}
-  var res = dict->filter({k -> k =~ 'a' && k !~ 'b'})
+  var res = dict->filter((k) => k =~ 'a' && k !~ 'b')
   res->assert_equal({aa: [1], ac: [3]})
 enddef
 
@@ -539,8 +539,8 @@ def Test_nr2char()
 enddef
 
 def Test_readdir()
-   eval expand('sautest')->readdir({e -> e[0] !=# '.'})
-   eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
+   eval expand('sautest')->readdir((e) => e[0] !=# '.')
+   eval expand('sautest')->readdirex((e) => e.name[0] !=# '.')
 enddef
 
 def Test_remove_return_type()
@@ -566,16 +566,16 @@ def Test_search()
   setline(1, ['foo', 'bar'])
   var val = 0
   # skip expr returns boolean
-  search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
+  search('bar', 'W', 0, 0, () => val == 1)->assert_equal(2)
   :1
-  search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
+  search('bar', 'W', 0, 0, () => val == 0)->assert_equal(0)
   # skip expr returns number, only 0 and 1 are accepted
   :1
-  search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
+  search('bar', 'W', 0, 0, () => 0)->assert_equal(2)
   :1
-  search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
-  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
-  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
+  search('bar', 'W', 0, 0, () => 1)->assert_equal(0)
+  assert_fails("search('bar', '', 0, 0, () => -1)", 'E1023:')
+  assert_fails("search('bar', '', 0, 0, () => -1)", 'E1023:')
 enddef
 
 def Test_searchcount()
@@ -667,7 +667,7 @@ enddef
 
 def Test_submatch()
   var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
-  var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
+  var Rep = () => range(10)->map((_, v) => submatch(v, true))->string()
   var actual = substitute('A123456789', pat, Rep, '')
   var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
   actual->assert_equal(expected)
@@ -703,7 +703,7 @@ def Test_term_start()
 enddef
 
 def Test_timer_paused()
-  var id = timer_start(50, {-> 0})
+  var id = timer_start(50, () => 0)
   timer_pause(id, true)
   var info = timer_info(id)
   info[0]['paused']->assert_equal(1)
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -305,7 +305,7 @@ enddef
 def Test_skipped_expr_linebreak()
   if 0
     var x = []
-               ->map({ -> 0})
+               ->map(() => 0)
   endif
 enddef
 
@@ -368,7 +368,7 @@ enddef
 
 def Test_filter_is_not_modifier()
   var tags = [{a: 1, b: 2}, {x: 3, y: 4}]
-  filter(tags, { _, v -> has_key(v, 'x') ? 1 : 0 })
+  filter(tags, ( _, v) => has_key(v, 'x') ? 1 : 0 )
   assert_equal([{x: 3, y: 4}], tags)
 enddef
 
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -896,7 +896,7 @@ def Test_disassemble_channel()
 enddef
 
 def WithLambda(): string
-  var F = {a -> "X" .. a .. "X"}
+  var F = (a) => "X" .. a .. "X"
   return F("x")
 enddef
 
@@ -904,7 +904,7 @@ def Test_disassemble_lambda()
   assert_equal("XxX", WithLambda())
   var instr = execute('disassemble WithLambda')
   assert_match('WithLambda\_s*' ..
-        'var F = {a -> "X" .. a .. "X"}\_s*' ..
+        'var F = (a) => "X" .. a .. "X"\_s*' ..
         '\d FUNCREF <lambda>\d\+\_s*' ..
         '\d STORE $0\_s*' ..
         'return F("x")\_s*' ..
@@ -929,7 +929,7 @@ def Test_disassemble_lambda()
 enddef
 
 def LambdaWithType(): number
-  var Ref = {a: number -> a + 10}
+  var Ref = (a: number) => a + 10
   return Ref(g:value)
 enddef
 
@@ -938,7 +938,7 @@ def Test_disassemble_lambda_with_type()
   assert_equal(15, LambdaWithType())
   var instr = execute('disassemble LambdaWithType')
   assert_match('LambdaWithType\_s*' ..
-        'var Ref = {a: number -> a + 10}\_s*' ..
+        'var Ref = (a: number) => a + 10\_s*' ..
         '\d FUNCREF <lambda>\d\+\_s*' ..
         '\d STORE $0\_s*' ..
         'return Ref(g:value)\_s*' ..
@@ -1541,10 +1541,10 @@ def Test_disassemble_compare()
         ['{a: 1} is aDict', 'COMPAREDICT is'],
         ['{a: 1} isnot aDict', 'COMPAREDICT isnot'],
 
-        ['{-> 33} == {-> 44}', 'COMPAREFUNC =='],
-        ['{-> 33} != {-> 44}', 'COMPAREFUNC !='],
-        ['{-> 33} is {-> 44}', 'COMPAREFUNC is'],
-        ['{-> 33} isnot {-> 44}', 'COMPAREFUNC isnot'],
+        ['(() => 33) == (() => 44)', 'COMPAREFUNC =='],
+        ['(() => 33) != (() => 44)', 'COMPAREFUNC !='],
+        ['(() => 33) is (() => 44)', 'COMPAREFUNC is'],
+        ['(() => 33) isnot (() => 44)', 'COMPAREFUNC isnot'],
 
         ['77 == g:xx', 'COMPAREANY =='],
         ['77 != g:xx', 'COMPAREANY !='],
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -1806,58 +1806,56 @@ def Test_expr7_list_vim9script()
 enddef
 
 def LambdaWithComments(): func
-  return {x ->
+  return (x) =>
             # some comment
             x == 1
             # some comment
             ||
             x == 2
-        }
 enddef
 
 def LambdaUsingArg(x: number): func
-  return {->
+  return () =>
             # some comment
             x == 1
             # some comment
             ||
             x == 2
-        }
 enddef
 
 def Test_expr7_lambda()
   var lines =<< trim END
-      var La = { -> 'result'}
+      var La = () => 'result'
       assert_equal('result', La())
-      assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val}))
+      assert_equal([1, 3, 5], [1, 2, 3]->map((key, val) => key + val))
 
       # line continuation inside lambda with "cond ? expr : expr" works
       var ll = range(3)
-      map(ll, {k, v -> v % 2 ? {
+      map(ll, (k, v) => v % 2 ? {
                 ['111']: 111 } : {}
-            })
+            )
       assert_equal([{}, {111: 111}, {}], ll)
 
       ll = range(3)
-      map(ll, {k, v -> v == 8 || v
+      map(ll, (k, v) => v == 8 || v
                     == 9
                     || v % 2 ? 111 : 222
-            })
+            )
       assert_equal([222, 111, 222], ll)
 
       ll = range(3)
-      map(ll, {k, v -> v != 8 && v
+      map(ll, (k, v) => v != 8 && v
                     != 9
                     && v % 2 == 0 ? 111 : 222
-            })
+            )
       assert_equal([111, 222, 111], ll)
 
-      var dl = [{key: 0}, {key: 22}]->filter({ _, v -> v['key'] })
+      var dl = [{key: 0}, {key: 22}]->filter(( _, v) => v['key'] )
       assert_equal([{key: 22}], dl)
 
       dl = [{key: 12}, {['foo']: 34}]
       assert_equal([{key: 12}], filter(dl,
-            {_, v -> has_key(v, 'key') ? v['key'] == 12 : 0}))
+            (_, v) => has_key(v, 'key') ? v['key'] == 12 : 0))
 
       assert_equal(false, LambdaWithComments()(0))
       assert_equal(true, LambdaWithComments()(1))
@@ -1867,33 +1865,31 @@ def Test_expr7_lambda()
       assert_equal(false, LambdaUsingArg(0)())
       assert_equal(true, LambdaUsingArg(1)())
 
-      var res = map([1, 2, 3], {i: number, v: number -> i + v})
+      var res = map([1, 2, 3], (i: number, v: number) => i + v)
       assert_equal([1, 3, 5], res)
   END
   CheckDefAndScriptSuccess(lines)
 
-  CheckDefFailure(["var Ref = {a->a + 1}"], 'E1004:')
-  CheckDefFailure(["var Ref = {a-> a + 1}"], 'E1004:')
-  CheckDefFailure(["var Ref = {a ->a + 1}"], 'E1004:')
-
-  CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
+  CheckDefFailure(["var Ref = (a)=>a + 1"], 'E1004:')
+  CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1004:')
+  CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1004:')
+
+  CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
   # error is in first line of the lambda
-  CheckDefFailure(["var L = {a -> a + b}"], 'E1001:', 0)
-
-  assert_equal('xxxyyy', 'xxx'->{a, b -> a .. b}('yyy'))
-
-  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
-        'E1106: One argument too many')
-  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x', 'y')"],
-        'E1106: 2 arguments too many')
-  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
-
-  CheckDefSuccess(['var Fx = {a -> {k1: 0,', ' k2: 1}}'])
-  CheckDefFailure(['var Fx = {a -> {k1: 0', ' k2: 1}}'], 'E722:', 2)
-  CheckDefFailure(['var Fx = {a -> {k1: 0,', ' k2 1}}'], 'E720:', 2)
-
-  CheckDefSuccess(['var Fx = {a -> [0,', ' 1]}'])
-  CheckDefFailure(['var Fx = {a -> [0', ' 1]}'], 'E696:', 2)
+  CheckDefFailure(["var L = (a) => a + b"], 'E1001:', 0)
+
+  assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))
+
+  CheckDefExecFailure(["var s = 'asdf'->((a) => a)('x')"], 'E118:')
+  CheckDefExecFailure(["var s = 'asdf'->((a) => a)('x', 'y')"], 'E118:')
+  CheckDefFailure(["echo 'asdf'->((a) => a)(x)"], 'E1001:', 1)
+
+  CheckDefSuccess(['var Fx = (a) => ({k1: 0,', ' k2: 1})'])
+  CheckDefFailure(['var Fx = (a) => ({k1: 0', ' k2: 1})'], 'E722:', 2)
+  CheckDefFailure(['var Fx = (a) => ({k1: 0,', ' k2 1})'], 'E720:', 2)
+
+  CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
+  CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
 enddef
 
 def NewLambdaWithComments(): func
@@ -2002,10 +1998,10 @@ enddef
 def Test_expr7_lambda_vim9script()
   var lines =<< trim END
       vim9script
-      var v = 10->{a ->
+      var v = 10->((a) =>
 	    a
 	      + 2
-	  }()
+            )()
       assert_equal(12, v)
   END
   CheckScriptSuccess(lines)
@@ -2013,9 +2009,9 @@ def Test_expr7_lambda_vim9script()
   # nested lambda with line breaks
   lines =<< trim END
       vim9script
-      search('"', 'cW', 0, 0, {->
+      search('"', 'cW', 0, 0, () =>
 	synstack('.', col('.'))
-	->map({_, v -> synIDattr(v, 'name')})->len()})
+          ->map((_, v) => synIDattr(v, 'name'))->len())
   END
   CheckScriptSuccess(lines)
 enddef
@@ -2089,8 +2085,8 @@ def Test_expr7_dict()
   CheckDefFailure(["var x = 'a' .. #{a: 1}"], 'E1097:', 3)
 
   CheckDefFailure(["var x = {a:8}"], 'E1069:', 1)
-  CheckDefFailure(["var x = {a : 8}"], 'E1059:', 1)
-  CheckDefFailure(["var x = {a :8}"], 'E1059:', 1)
+  CheckDefFailure(["var x = {a : 8}"], 'E1068:', 1)
+  CheckDefFailure(["var x = {a :8}"], 'E1068:', 1)
   CheckDefFailure(["var x = {a: 8 , b: 9}"], 'E1068:', 1)
   CheckDefFailure(["var x = {a: 1,b: 2}"], 'E1069:', 1)
 
@@ -2139,6 +2135,9 @@ def Test_expr7_dict_vim9script()
 		['two']: 2,
 		   }
       assert_equal({one: 1, two: 2}, d)
+
+      var dd = {k: 123->len()}
+      assert_equal(3, dd.k)
   END
   CheckScriptSuccess(lines)
 
@@ -2174,7 +2173,7 @@ def Test_expr7_dict_vim9script()
       vim9script
       var d = {one : 1}
   END
-  CheckScriptFailure(lines, 'E1059:', 2)
+  CheckScriptFailure(lines, 'E1068:', 2)
 
   lines =<< trim END
       vim9script
@@ -2629,7 +2628,7 @@ def Test_expr7_not()
       unlet g:false
 
       assert_equal(true, !test_null_partial())
-      assert_equal(false, !{-> 'yes'})
+      assert_equal(false, !() => 'yes')
 
       assert_equal(true, !test_null_dict())
       assert_equal(true, !{})
@@ -2668,8 +2667,8 @@ func Test_expr7_fails()
   call CheckDefFailure(["var x = [1, 2"], "E697:", 2)
   call CheckDefFailure(["var x = [notfound]"], "E1001:", 1)
 
-  call CheckDefFailure(["var x = { -> 123) }"], "E451:", 1)
-  call CheckDefFailure(["var x = 123->{x -> x + 5) }"], "E451:", 1)
+  call CheckDefFailure(["var X = () => 123)"], "E488:", 1)
+  call CheckDefFailure(["var x = 123->((x) => x + 5)"], "E107:", 1)
 
   call CheckDefFailure(["var x = &notexist"], 'E113:', 1)
   call CheckDefFailure(["&grepprg = [343]"], 'E1012:', 1)
@@ -2691,7 +2690,7 @@ func Test_expr7_fails()
   call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
 
   call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
-  call CheckDefExecFailure(["{a: 1->len()"], 'E1004:', 1)
+  call CheckDefExecFailure(["{a: 1->len()"], 'E723:', 2)
   call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
 endfunc
 
@@ -2725,12 +2724,12 @@ def Test_expr7_trailing()
 
   # method call
   l = [2, 5, 6]
-  l->map({k, v -> k + v})
+  l->map((k, v) => k + v)
   assert_equal([2, 6, 8], l)
 
   # lambda method call
   l = [2, 5]
-  l->{l -> add(l, 8)}()
+  l->((l) => add(l, 8))()
   assert_equal([2, 5, 8], l)
 
   # dict member
@@ -2895,8 +2894,8 @@ def Test_expr7_subscript_linebreak()
 enddef
 
 func Test_expr7_trailing_fails()
-  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
-  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
+  call CheckDefFailure(['var l = [2]', 'l->((l) => add(l, 8))'], 'E107:', 2)
+  call CheckDefFailure(['var l = [2]', 'l->((l) => add(l, 8)) ()'], 'E274:', 2)
 endfunc
 
 func Test_expr_fails()
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -54,7 +54,7 @@ def CallRecursive(n: number): number
 enddef
 
 def CallMapRecursive(l: list<number>): number
-  return map(l, {_, v -> CallMapRecursive([v])})[0]
+  return map(l, (_, v) => CallMapRecursive([v]))[0]
 enddef
 
 def Test_funcdepth_error()
@@ -310,7 +310,7 @@ def Test_nested_global_function()
       vim9script
       def Outer()
         def g:Inner()
-          echo map([1, 2, 3], {_, v -> v + 1})
+          echo map([1, 2, 3], (_, v) => v + 1)
         enddef
         g:Inner()
       enddef
@@ -509,11 +509,11 @@ def Test_call_funcref_wrong_args()
 enddef
 
 def Test_call_lambda_args()
-  CheckDefFailure(['echo {i -> 0}()'],
-                  'E119: Not enough arguments for function: {i -> 0}()')
+  CheckDefFailure(['echo ((i) => 0)()'],
+                  'E119: Not enough arguments for function: ((i) => 0)()')
 
   var lines =<< trim END
-      var Ref = {x: number, y: number -> x + y}
+      var Ref = (x: number, y: number) => x + y
       echo Ref(1, 'x')
   END
   CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
@@ -522,7 +522,7 @@ enddef
 def Test_lambda_uses_assigned_var()
   CheckDefSuccess([
         'var x: any = "aaa"'
-        'x = filter(["bbb"], {_, v -> v =~ x})'])
+        'x = filter(["bbb"], (_, v) => v =~ x)'])
 enddef
 
 " Default arg and varargs
@@ -1413,12 +1413,12 @@ enddef
 
 def Test_closure_simple()
   var local = 'some '
-  RefFunc({s -> local .. s})->assert_equal('some more')
+  RefFunc((s) => local .. s)->assert_equal('some more')
 enddef
 
 def MakeRef()
   var local = 'some '
-  g:Ref = {s -> local .. s}
+  g:Ref = (s) => local .. s
 enddef
 
 def Test_closure_ref_after_return()
@@ -1429,8 +1429,8 @@ enddef
 
 def MakeTwoRefs()
   var local = ['some']
-  g:Extend = {s -> local->add(s)}
-  g:Read = {-> local}
+  g:Extend = (s) => local->add(s)
+  g:Read = () => local
 enddef
 
 def Test_closure_two_refs()
@@ -1467,12 +1467,12 @@ enddef
 
 def MakeArgRefs(theArg: string)
   var local = 'loc_val'
-  g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
+  g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
 enddef
 
 def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
   var local = 'the_loc'
-  g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
+  g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
 enddef
 
 def Test_closure_using_argument()
@@ -1526,7 +1526,7 @@ endfunc
 
 def Test_call_closure_not_compiled()
   var text = 'text'
-  g:Ref = {s ->  s .. text}
+  g:Ref = (s) =>  s .. text
   GetResult(g:Ref)->assert_equal('sometext')
 enddef
 
@@ -1536,7 +1536,7 @@ def Test_double_closure_fails()
     def Func()
       var name = 0
       for i in range(2)
-          timer_start(0, {-> name})
+          timer_start(0, () => name)
       endfor
     enddef
     Func()
@@ -1549,8 +1549,8 @@ def Test_nested_closure_used()
       vim9script
       def Func()
         var x = 'hello'
-        var Closure = {-> x}
-        g:Myclosure = {-> Closure()}
+        var Closure = () => x
+        g:Myclosure = () => Closure()
       enddef
       Func()
       assert_equal('hello', g:Myclosure())
@@ -1565,7 +1565,7 @@ def Test_nested_closure_fails()
       FuncB(0)
     enddef
     def FuncB(n: number): list<string>
-      return map([0], {_, v -> n})
+      return map([0], (_, v) => n)
     enddef
     FuncA()
   END
@@ -1642,8 +1642,8 @@ def Test_nested_lambda()
     vim9script
     def Func()
       var x = 4
-      var Lambda1 = {-> 7}
-      var Lambda2 = {-> [Lambda1(), x]}
+      var Lambda1 = () => 7
+      var Lambda2 = () => [Lambda1(), x]
       var res = Lambda2()
       assert_equal([7, 4], res)
     enddef
@@ -1653,8 +1653,8 @@ def Test_nested_lambda()
 enddef
 
 def Shadowed(): list<number>
-  var FuncList: list<func: number> = [{ -> 42}]
-  return FuncList->map({_, Shadowed -> Shadowed()})
+  var FuncList: list<func: number> = [() => 42]
+  return FuncList->map((_, Shadowed) => Shadowed())
 enddef
 
 def Test_lambda_arg_shadows_func()
@@ -1676,15 +1676,15 @@ def Test_script_var_in_lambda()
   var lines =<< trim END
       vim9script
       var script = 'test'
-      assert_equal(['test'], map(['one'], {-> script}))
+      assert_equal(['test'], map(['one'], () => script))
   END
   CheckScriptSuccess(lines)
 enddef
 
 def Line_continuation_in_lambda(): list<string>
   var x = range(97, 100)
-      ->map({_, v -> nr2char(v)
-          ->toupper()})
+      ->map((_, v) => nr2char(v)
+          ->toupper())
       ->reverse()
   return x
 enddef
@@ -1772,11 +1772,11 @@ def Test_recursive_call()
 enddef
 
 def TreeWalk(dir: string): list<any>
-  return readdir(dir)->map({_, val ->
+  return readdir(dir)->map((_, val) =>
             fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
                ? {[val]: TreeWalk(dir .. '/' .. val)}
                : val
-             })
+             )
 enddef
 
 def Test_closure_in_map()
@@ -1890,7 +1890,7 @@ def Test_block_scoped_var()
         var x = ['a', 'b', 'c']
         if 1
           var y = 'x'
-          map(x, {-> y})
+          map(x, () => y)
         endif
         var z = x
         assert_equal(['x', 'x', 'x'], z)
@@ -1922,7 +1922,7 @@ def Test_did_emsg_reset()
       vim9script
       au BufWinLeave * #
       def Func()
-          popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
+          popup_menu('', {callback: () => popup_create('', {})->popup_close()})
           eval [][0]
       enddef
       nno <F3> <cmd>call <sid>Func()<cr>
@@ -2014,7 +2014,7 @@ def Test_dict_member_with_silent()
       var d: dict<any>
       def Func()
         try
-          g:result = map([], {_, v -> {}[v]})->join() .. d['']
+          g:result = map([], (_, v) => ({}[v]))->join() .. d['']
         catch
         endtry
       enddef
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1162,7 +1162,7 @@ def Run_Test_import_fails_on_command_lin
 
   var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
                 rows: 6, wait_for_ruler: 0})
-  WaitForAssert({-> assert_match('^E1094:', term_getline(buf, 5))})
+  WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
 
   delete('XexportCmd.vim')
   StopVimInTerminal(buf)
@@ -3064,7 +3064,7 @@ def Run_Test_define_func_at_command_line
   # define Afunc() on the command line
   term_sendkeys(buf, ":def Afunc()\<CR>Bfunc()\<CR>enddef\<CR>")
   term_sendkeys(buf, ":call CheckAndQuit()\<CR>")
-  WaitForAssert({-> assert_equal(['errors: []'], readfile('Xdidcmd'))})
+  WaitForAssert(() => assert_equal(['errors: []'], readfile('Xdidcmd')))
 
   call StopVimInTerminal(buf)
   delete('XcallFunc')
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2257,
+/**/
     2256,
 /**/
     2255,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2938,7 +2938,7 @@ compile_list(char_u **arg, cctx_T *cctx,
 }
 
 /*
- * parse a lambda: "{arg, arg -> expr}" or "(arg, arg) => expr"
+ * Parse a lambda: "(arg, arg) => expr"
  * "*arg" points to the '{'.
  * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
  */
@@ -2988,52 +2988,6 @@ compile_lambda(char_u **arg, cctx_T *cct
 }
 
 /*
- * Compile a lamda call: expr->{lambda}(args)
- * "arg" points to the "{".
- */
-    static int
-compile_lambda_call(char_u **arg, cctx_T *cctx)
-{
-    ufunc_T	*ufunc;
-    typval_T	rettv;
-    int		argcount = 1;
-    int		ret = FAIL;
-
-    // Get the funcref in "rettv".
-    if (get_lambda_tv(arg, &rettv, TRUE, &EVALARG_EVALUATE) == FAIL)
-	return FAIL;
-
-    if (**arg != '(')
-    {
-	if (*skipwhite(*arg) == '(')
-	    emsg(_(e_nowhitespace));
-	else
-	    semsg(_(e_missing_paren), "lambda");
-	clear_tv(&rettv);
-	return FAIL;
-    }
-
-    ufunc = rettv.vval.v_partial->pt_func;
-    ++ufunc->uf_refcount;
-    clear_tv(&rettv);
-    ga_init2(&ufunc->uf_type_list, sizeof(type_T *), 10);
-
-    // The function will have one line: "return {expr}".  Compile it into
-    // instructions so that we get any errors right now.
-    compile_def_function(ufunc, TRUE, cctx);
-
-    // compile the arguments
-    *arg = skipwhite(*arg + 1);
-    if (compile_arguments(arg, cctx, &argcount) == OK)
-	// call the compiled function
-	ret = generate_CALL(cctx, ufunc, argcount);
-
-    if (ret == FAIL)
-	func_ptr_unref(ufunc);
-    return ret;
-}
-
-/*
  * parse a dict: {key: val, [key]: val}
  * "*arg" points to the '{'.
  * ppconst->pp_is_const is set if all item values are a constant.
@@ -3602,14 +3556,7 @@ compile_subscript(
 	    p += 2;
 	    *arg = skipwhite(p);
 	    // No line break supported right after "->".
-	    if (**arg == '{')
-	    {
-		// lambda call:  list->{lambda}
-		// TODO: remove this
-		if (compile_lambda_call(arg, cctx) == FAIL)
-		    return FAIL;
-	    }
-	    else if (**arg == '(')
+	    if (**arg == '(')
 	    {
 		int	    argcount = 1;
 		char_u	    *expr;
@@ -3631,7 +3578,10 @@ compile_subscript(
 		++*arg;
 		if (**arg != '(')
 		{
-		    semsg(_(e_missing_paren), *arg);
+		    if (*skipwhite(*arg) == '(')
+			emsg(_(e_nowhitespace));
+		    else
+			semsg(_(e_missing_paren), *arg);
 		    return FAIL;
 		}
 
@@ -4005,16 +3955,9 @@ compile_expr7(
 		    break;
 
 	/*
-	 * Lambda: {arg, arg -> expr}
 	 * Dictionary: {'key': val, 'key': val}
 	 */
-	case '{':   // Try parsing as a lambda, if NOTDONE is returned it
-		    // must be a dict.
-		    // TODO: if we go with the "(arg) => expr" syntax remove
-		    // this
-		    ret = compile_lambda(arg, cctx);
-		    if (ret == NOTDONE)
-			ret = compile_dict(arg, cctx, ppconst);
+	case '{':   ret = compile_dict(arg, cctx, ppconst);
 		    break;
 
 	/*