Just as a demonstration how you can do the task in LuaTeX (expandably!)
Of course it still involves passing the thing to TeX to execute.
%! TEX program = lualatex
\documentclass{article}
\begin{document}
% define some macros here.
% NOTE \a and \b should not be redefined in normal code
\def\a{123}
\def\b{456}
% the old value of \a is 123
\directlua{print("========", token.get_macro("a"))}
\edef\c{
\directlua{
--[[ the old value is 123 (use this comment style because new lines are stripped, this is directlua not luacode environment ]]
print(token.get_macro("a"))
--[[ create a table of tokens with content \let\a\b. Can use token.create as well ]]
local tokens=token.scan_toks(false, false)
--[[ run it ]]
tex.runtoks(function()
tex.sprint(tokens)
end)
--[[ look, the macro content really changed ]]
print(token.get_macro("a"))
}{\let\a\b}
}
% and outside too
\directlua{print(token.get_macro("a"))}
\end{document}
Some notes regarding this code from LuaTeX documentation:
Alternatively copy the definition of \beginlocalcontrol macro from https://tex.stackexchange.com/a/628874/250119 we can do the following:
%! TEX program = lualatex
\documentclass{article}
\newluafunction\beginlocalcontrol
\directlua{lua.get_functions_table()[\the\allocationnumber] = function() return tex.runtoks(token.get_next) end} % define its meaning
\luadef\beginlocalcontrol\allocationnumber
\begin{document}
% define some macros here.
% NOTE \a and \b should not be redefined in normal code
\def\a{123}
\def\b{456}
% the old value of \a is 123
\directlua{print("========", token.get_macro("a"))}
\edef\c{
\beginlocalcontrol\let\a\b\endlocalcontrol
}
% the macro content changed
\directlua{print("======== changed", token.get_macro("a"))}
\end{document}
As an alternative to using \newluafunction/\allocationnumber, it's possible to
use #lft+1 such as seen in
1
2
3
but there's a risk of undefined behavior in Lua 5.2 when allocations are non-sequential (unlikely in practice however)