diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java
new file mode 100644
index 000000000..cd75848e1
--- /dev/null
+++ b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the public ComputerCraft API - http://www.computercraft.info
+ * Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
+ * For help using the API, and posting your mods, visit the forums at computercraft.info.
+ */
+package dan200.computercraft.api.lua;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A function, which can be called from Lua. If you need to return a table of functions, it is recommended to use
+ * an object with {@link LuaFunction} methods, or implement {@link IDynamicLuaObject}.
+ *
+ * @see MethodResult#of(Object)
+ */
+@FunctionalInterface
+public interface ILuaFunction
+{
+ /**
+ * Call this function with a series of arguments. Note, this will always be called on the computer thread,
+ * and so its implementation must be thread-safe.
+ *
+ * @param arguments The arguments for this function
+ * @return The result of calling this function.
+ * @throws LuaException Upon Lua errors.
+ */
+ @Nonnull
+ MethodResult call( @Nonnull IArguments arguments ) throws LuaException;
+}
diff --git a/src/main/java/dan200/computercraft/api/lua/MethodResult.java b/src/main/java/dan200/computercraft/api/lua/MethodResult.java
index 2a7f80155..fce9f970f 100644
--- a/src/main/java/dan200/computercraft/api/lua/MethodResult.java
+++ b/src/main/java/dan200/computercraft/api/lua/MethodResult.java
@@ -58,7 +58,7 @@ public static MethodResult of()
*
* Integers, doubles, floats, strings, booleans, {@link Map}, {@link Collection}s, arrays and {@code null} will be
* converted to their corresponding Lua type. {@code byte[]} and {@link ByteBuffer} will be treated as binary
- * strings.
+ * strings. {@link ILuaFunction} will be treated as a function.
*
* In order to provide a custom object with methods, one may return a {@link IDynamicLuaObject}, or an arbitrary
* class with {@link LuaFunction} annotations. Anything else will be converted to {@code nil}.
diff --git a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
index 40bf39c23..e678667e1 100644
--- a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
+++ b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
@@ -48,6 +48,8 @@ public class CobaltLuaMachine implements ILuaMachine
ThreadUtils.factory( "Coroutine" )
);
+ private static final LuaMethod FUNCTION_METHOD = ( target, context, args ) -> ((ILuaFunction) target).call( args );
+
private final Computer m_computer;
private final TimeoutState timeout;
private final TimeoutDebugHandler debug;
@@ -275,6 +277,11 @@ private LuaValue toValue( @Nullable Object object, @Nullable Map