Function Returning a Function Syntax

Greetings,

I was going through the script for the classic linked sword, and noticed a particularly interesting function. I am confused about the syntax used for calling the function.

Why are you able to directly input data into the returned function with curly braces which directly runs the returned function? Does anyone know where I can read about this in the documentation?

function Create(ty)
	return function(data)
		local obj = Instance.new(ty)
		for k, v in pairs(data) do
			if type(k) == 'number' then
				v.Parent = obj
			else
				obj[k] = v
			end
		end
		return obj
	end
end

Create("Part"){
	Name = "CreatedPart",
	Transparency = 0.5 
    Parent = workspace
}
1 Like

func {...} is the same as func({...}), you can also do it for strings like func "abc" which is the same as func("abc"), i guess its just for readability or something.
btw if you use print "hello" without brackets you deserve to go to hell

2 Likes

Agree, but I also think you shouldn’t be so harsh—unless you want your post to get deleted.

Can you clarify what you mean by this?

I thought curly braces are only for data structures like arrays, not for function calls, do you know any sources relating to lua-u function syntax?

yes but its just kind of an exception, like i said, probably for readability (well more accurately - fanciness). i only know about them because i randomly found out about it

1 Like

I understand what you mean now, you can replace parenthesis with curly braces if the argument you’re providing is an array and the function is expecting an array.

So these two function calls are the same, it’s just syntax sugar and what type of arguments the function takes. I appreciate the fast response!

Create("Part"){
	Name = "CreatedPart",
	Transparency = 0.5,
	Parent = workspace
}

Create2("One")("Two")

This is generally discouraged due to its ambiguity and limited abilities

What are the limitations of this?

You can only provide one argument. This is all at the cost of additional and unnecessary code, which only produces a pattern that is largely inconsistent with every other function call in the codebase

1 Like

Lua allows calling a returned function immediately by passing a table with {}.

function make_greeting(greet)
	return function(data)
		print(greet .. ", " .. data[1] .. "!")
	end
end

make_greeting("Hello"){ "John" } -- Outputs: Hello, John!

It’s just shorthand for MakeGreeting("Hello")({"John"}).

1 Like

You can also do it with strings. But again, it is discouraged to use this pattern

the only “popular” library I know that fully embraces this quirk from lua, is a UI library called Fusion.

it allows for this unique way to write code

New "TextButton" {
        Name = "button",
        Position = UDim2.fromScale(.5,.5),
        AnchorPoint = Vector2.new(.5,.5),
        Size = UDim2.fromOffset(200,200),
        ZIndex = 1,
        ...
}

doesn’t really serve a real objective purpose in my opinion other than looking “cool”

--you could also write it as:
Create "Part" {
	Name = "CreatedPart",
	Transparency = 0.5,
	Parent = workspace
}

additional stuff you may find interesting
--[[
the type(k) == 'number' bit of the code allows the functionality
to also define children within the "body" of the table
]]

Create "Part" {
	Name = "CreatedPart",
	Transparency = 0.5,
	Parent = workspace,

	Create "Decal" {
		Face = Enum.NormalId.Top,
		Texture = "rbxassetid://00000000"
	},

	Create "Highlight" {
		FillColor = Color3.new(0,1,0)
	}
}

1 Like

I use print'1' print'2' etc to debug my code. It’s faster to type. The code looks very readable and runs fine.

With IntelliSense, the speed at which you type print("1") over print"1" is entirely negligible. I also disagree with the latter having consistent readability, especially that at the same level of the former. This opinion is backed by the Roblox style guide. It’s ultimately inconsistent with the codebase due to its limited use-cases, requires redundancy to be leveraged, and has no functional benefit

Bro it’s like you read but didn’t read my post.

  1. it’s for debugging, it’s not being used outside of figuring out where my code is messing up. It gets deleted
  2. you said print"1" which takes considerably longer to type than print'1'

Functionally none of these arguments so far are about “functionally benefitical”. There’s no functional difference between passing arguments with and without parenthesis.

Thanks for the clarification! I appreciate the additional information you added, definitely saved me some time.

“There’s no functional difference between passing arguments with and without parenthesis.”

There is. You can only pass a single argument, and only two types of arguments. The Roblox style guide also claims it requires additional work from the compiler to parse.

“you said print"1" which takes considerably longer to type than print'1'”

My apologies, I wrote that out of habit. However, my original point still stands. The average typing speed and auto-completion features makes it negligible