I don't have a
great understanding of the beam opcodes, but something like this:
derp() ->
A1 = get(a1),
A2 = get(a2),
A3 = get(a3),
A4 = get(a4),
A1 + A2 + A3 + A4.
But go out to I dunno a million (you might want to raise your atom limit) and I think it'll block a scheduler for a while. Beam Assembly for that is:
{function, derp, 0, 2}.
{label,1}.
{line,[{location,"derp.erl",6}]}.
{func_info,{atom,derp},{atom,derp},0}.
{label,2}.
{bif,get,{f,0},[{atom,a1}],{x,0}}.
{bif,get,{f,0},[{atom,a2}],{x,1}}.
{bif,get,{f,0},[{atom,a3}],{x,2}}.
{bif,get,{f,0},[{atom,a4}],{x,3}}.
{line,[{location,"derp.erl",11}]}.
{gc_bif,'+',{f,0},4,[{x,0},{x,1}],{x,0}}.
{gc_bif,'+',{f,0},4,[{tr,{x,0},{t_number,any}},{x,2}],{x,0}}.
{gc_bif,'+',{f,0},4,[{tr,{x,0},{t_number,any}},{x,3}],{x,0}}.
return.
I'm not 100%, but i don't think think get(...) is charged any reductions, so it won't yield. gc_bif potentially does garbage collection which does get charged reductions and BEAM can yield during gc.
I'm just adding at the end to do something with the values, so the compiler doesn't ignore them. If you wanted to write BEAM assembly, you can probably make a terrible function there without nearly as much work. smallnum math doesn't usually charge reductions from what I was seeing, so you could probably do something almost useful with that.