Is there a way for a function to stop another running function?

Okay so I was trying to develop a script so that a once occupied vehicle gets deleted within 30 seconds once left by the driver. But there are cases in which the driver gets back on the car so that the car stops getting deleted in 30 seconds because it’s now occupied again.

The problem is with how this countdown must get aborted because the player has entered the car once again. Instead of the countdown stopping, another countdown starts again interfering with the original countdown and the solution for this must that the onOccupy function must stop the countdown that was started by the onDerelict function, in other words, a function stopping another function.

local car = script.Parent
local seat = car.DriveSeat
local occ = car:GetAttribute("Occupied")
local ac = car:GetAttribute("Active")
wait(1)
car:SetAttribute("Active", false)
car:SetAttribute("Occupied", false)
local gui = car.Body.topPart.DeletingGui

local function countdown()
	local r = 30
	local i = 1
	for count = r,0,-i do
		gui.TextLabel.Text = "This car will be deleted in "..count.." seconds"
		wait(i)
	end
end
	
local function onDerelict()
	car:SetAttribute("Active", false)
	if car:GetAttribute("Occupied") and not car:GetAttribute("Active") then -- occ^~ac->
		gui.Enabled = true
		countdown()
	end
end
local function onOccupy()
	if not car:GetAttribute("Occupied") and not car:GetAttribute("Active") then --	~occ^~ac->
		car:SetAttribute("Occupied", true)
		car:SetAttribute("Active", true)
	elseif car:GetAttribute("Occupied") and not car:GetAttribute("Active") then --	occ^~ac->
		car:SetAttribute("Active", true)
		--gui.Enabled = false
	end
end
seat.ChildAdded:Connect(onOccupy)
seat.ChildRemoved:Connect(onDerelict)

Coroutines were tried but when applied, the countdown, when called, would be called dead, thus bricking the entire script.

“Return” is also tried but when applied, the return would happen after the countdown has passed and the car was deleted (remember, we’re trying to prevent the car from being deleted) and getting to do the return before the countdown is not possible.

So is really there a way to do this?

Did you try to create a boolean variable and keep track of it while the for loop (countdown) is running to determine whether or not to break it?

No.
In the entire script there are only two boolean values (occ and ac) and is only used together in two and one combinations, all unrelated to the loop:

occ^~ac enables the countdown
~occ^~ac sets both to true,
otherwise occ^~ac sets ac to true

Is there a way for a function to stop another running function?

No, but you can create functions that cause other functions to continue running, so kind of the opposite.

Although if I were you I’d use some kind of timer that can be started and stopped, for example

local cleanupTimer

function newTimer(time, stepCallback, exhaustCallback)
	local timeRemaining = time
	local stop
	local c
	
	function stop()
		c:Disconnect()
		c = nil
		stop = function() end
	end

	function step(dt)
		timeRemaining -= dt
		if stepCallback then stepCallback(timeRemaining) end
		if timeRemaining <= 0 then
			stop()
			if exhaustCallback then exhaustCallback() end
		end
	end

	c = RunService.PreSimulation:Connect(step)
	return stop
end

local function stopCleanupTimer()
	if cleanupTimer then 
		cleanupTimer() 
		cleanupTimer = nil
	end
end

local function resetCleanupTimer()
	stopCleanupTimer()
	cleanupTimer = newTimer(
		30, 
		updateTimerLabel,
		cleanupCar
	)
end
	

Just posted an answer that sets a framework for something similar to this (“A bit more advanced” section):

Most of it can be ignored, take note of how the self.connectionFunction is changed after the time runs out. In your case, this can be forcibly changed outside of the script if connected to an event.