diff --git a/examples/02_Calc_Sum.mers b/examples/02_Calc_Sum.mers
index 7a97260..d30fce2 100755
--- a/examples/02_Calc_Sum.mers
+++ b/examples/02_Calc_Sum.mers
@@ -1,10 +1,10 @@
 total := 0.0
-{() -> {
+().loop(() -> {
   ("Total: ", total, ". Type a number to change.").concat.println
   ().read_line.trim.parse_float.try((
     n -> &total = (total, n).sum,
     // not a number, so return a 1-tuple to break from the loop
     () -> (())
   ))
-}}.loop
+})
 "Goodbye.".println
diff --git a/examples/03_Basic_Calculator.mers b/examples/03_Basic_Calculator.mers
index a2f60e2..3a864bd 100755
--- a/examples/03_Basic_Calculator.mers
+++ b/examples/03_Basic_Calculator.mers
@@ -5,7 +5,7 @@
 
 current := 0.0
 
-{() -> {
+().loop(() -> {
   ("[ ", current, " ]").concat.println
   input := ().read_line.trim
   num := (input, 1).substring.trim.parse_float.try((
@@ -24,4 +24,4 @@ current := 0.0
   } else if input.eq("exit") {
     (())
   }
-}}.loop
+})
diff --git a/examples/04_Greatest_Common_Divisor.mers b/examples/04_Greatest_Common_Divisor.mers
index 74293a3..2a5cccf 100755
--- a/examples/04_Greatest_Common_Divisor.mers
+++ b/examples/04_Greatest_Common_Divisor.mers
@@ -1,5 +1,5 @@
 gcd := vals -> {
-  () -> {
+  ().loop(() -> {
     (a, b) := vals
     if a.eq(b)
       (a)
@@ -7,8 +7,8 @@ gcd := vals -> {
       &vals = (a, b.subtract(a))
     else
       &vals = (a.subtract(b), b)
-  }
-}.loop
+  })
+}
 
 get_num := () -> {
   line := ().read_line.trim
diff --git a/examples/05_Matrix_Multiplicator.mers b/examples/05_Matrix_Multiplicator.mers
index 18366f4..6bf475c 100755
--- a/examples/05_Matrix_Multiplicator.mers
+++ b/examples/05_Matrix_Multiplicator.mers
@@ -17,7 +17,7 @@ split_once := (s, delim) -> {
 split_ := (s, delim, require_nonempty) -> {
   out := (s).as_list
   &out.pop
-  {
+  ().loop(
     () -> s.split_once(delim).try((
       (s1, s2) -> {
         &s = s2
@@ -30,7 +30,7 @@ split_ := (s, delim, require_nonempty) -> {
         (())
       }
     ))
-  }.loop
+  )
   out
 }
 
@@ -62,9 +62,11 @@ read_matrix_line := width -> {
       if w.eq(0) {
         width = line.len
       } else {
-        {() -> if line.len.subtract(w).signum.eq(-1) {
-          &line.push(0.0)
-        } else (())}.loop
+        ().loop(() ->
+          if line.len.subtract(w).signum.eq(-1) {
+            &line.push(0.0)
+          } else (())
+        )
       }
       (line)
     }
@@ -87,10 +89,12 @@ matrix_get := (matrix, (line, col)) -> {
 leftpad := (str, l) -> {
   str := (str).concat
   d := l.subtract(str.len)
-  {() -> if d.signum.eq(1) {
-    &str = (" ", str).concat
-    &d = d.subtract(1)
-  } else {(())}}.loop
+  ().loop(() ->
+    if d.signum.eq(1) {
+      &str = (" ", str).concat
+      &d = d.subtract(1)
+    } else (())
+  )
   str
 }
 
diff --git a/mers_lib/src/program/configs/with_base.rs b/mers_lib/src/program/configs/with_base.rs
index d663f13..2f086ad 100755
--- a/mers_lib/src/program/configs/with_base.rs
+++ b/mers_lib/src/program/configs/with_base.rs
@@ -13,7 +13,7 @@ use super::Config;
 impl Config {
     /// `deref: fn` clones the value from a reference
     /// `eq: fn` returns true if all the values are equal, otherwise false.
-    /// `loop: fn` runs a function until it returns (T) instead of (), then returns T.
+    /// `loop: fn` runs a function until it returns (T) instead of (), then returns T. Also works with ((), f) instead of f for ().loop(() -> { ... }) syntax, which may be more readable
     /// `try: fn` runs the first valid function with the argument. usage: (arg, (f1, f2, f3)).try
     /// NOTE: try's return type may miss some types that can actually happen when using it on tuples, so... don't do ((a, b), (f1, any -> ())).try unless f1 also returns ()
     /// `len: fn` gets the length of strings or tuples
@@ -180,7 +180,11 @@ impl Config {
                 info_check: Arc::new(Mutex::new(CheckInfo::neverused())),
                 out: Arc::new(|a, _i| {
                     let mut o = Type::empty();
-                    for t in &a.types {
+                    for t in a.types.iter().flat_map(|v| if let Some(t) = v.as_any().downcast_ref::<data::tuple::TupleT>() {
+                            if let Some(t) = t.0.get(1) {
+                                t.types.iter().collect::<Vec<_>>()
+                            } else { [v].into_iter().collect() }
+                        } else { [v].into_iter().collect() }) {
                         if let Some(t) = t.as_any().downcast_ref::<data::function::FunctionT>() {
                             for t in (t.0)(&Type::empty_tuple())?.types {
                                 if let Some(t) = t.as_any().downcast_ref::<data::tuple::TupleT>() {
@@ -200,15 +204,21 @@ impl Config {
                     Ok(o)
                 }),
                 run: Arc::new(|a, _i| {
-                    if let Some(r) = a.get().as_any().downcast_ref::<data::function::Function>() {
+                    let a = a.get();
+                    let delay_drop;
+                    let function = if let Some(function) = a.as_any().downcast_ref::<data::function::Function>() {
+                            function
+                    } else if let Some(r) = a.as_any().downcast_ref::<data::tuple::Tuple>() {
+                        delay_drop = r.0[1].get();
+                        delay_drop.as_any().downcast_ref::<data::function::Function>().unwrap()
+                    } else {
+                        unreachable!("called loop on non-function")
+                    };
                         loop {
-                            if let Some(r) = r.run(Data::empty_tuple()).one_tuple_content() {
+                            if let Some(r) = function.run(Data::empty_tuple()).one_tuple_content() {
                                 break r;
                             }
                         }
-                    } else {
-                        unreachable!("called loop on non-function")
-                    }
                 }),
             }),
         )