[erlang-questions] Matthew Sackman's "cut" proposal
Richard O'Keefe
ok@REDACTED
Mon Jul 11 07:34:11 CEST 2011
On 11/07/2011, at 3:00 PM, Richard O'Keefe wrote:
>
> I began a survey of 'fun's in the kernel/ directory.
> Out of the first 22, one could use "_".
Here are the counts. funs may be ruled out for multiple
reasons; in each such case only the most severe reason was
counted.
46 the fun should be replaced by a comprehension
30 the fun has multiple clauses
72 the fun has a complex body, a 'case' or 'if' or a comma
or an operator.
22 the fun does pattern matching on one or more arguments
4 the fun wants its arguments in a different order from the
underlying function call
7 one or more arguments is in a "deep" position
26 the fun has no arguments (this is usually in a spawn of
some kind, or possibly a transaction)
27 funs are candidates for the "cut" "_" treatment.
However, I didn't bother distinguishing, until it was too
late, between funs that could have been fun foo/N and the
rest; about half of these candidates should be of that form.
So about 1 'fun' out of 14 or more could use the Matthew Sackman
treatment. This seems to depend on style; for a long time I thought
there weren't going to be _any_ candidates but they were clumped in
a small number of files.
Look for example at
f_send = fun(S,D) -> inet_tcp:send(S,D) end,
f_recv = fun(S,N,T) -> inet_tcp:recv(S,N,T)
end,
f_setopts_pre_nodeup =
fun(S) ->
inet:setopts(S,
[{active, false},
{packet, 4},
nodelay()])
end,
f_setopts_post_nodeup =
fun(S) ->
inet:setopts(S,
[{active, true},
{deliver, port},
{packet, 4},
nodelay()])
end,
f_getll = fun(S) ->
inet:getll(S)
end,
which could have been
f_send = fun inet_tcp:send/2,
f_recv = fun inet_tcp:recv/3,
f_setops_pre_nodeup =
cut(inet:setopts(_, [{active,false},{packet,4},nodelay()]),
f_setopts_post_nodeup =
cut(inet:setopts(_, [{active,true},{deliver,port},{packet,4},nodelay()]),
f_getll = fun inet:getll/1
We could just add
setopts(Opts) ->
fun (Socket) -> prim_inet:setopts(Socket, Opts) end.
or better still,
nodeup_opts(Opts) ->
fun (Socket) ->
prim_inet:setopts(Socket, [{packet,4},nodelay()]++Opts)
end.
and then we'd have
f_send = fun inet_tcp:send/2,
f_recv = fun inet_tcp:recv/3,
f_setops_pre_nodeup = nodeup_opts([{active,false}]),
f_setopts_post_nodeup = nodeop_opts([{active,true},{deliver,port}]),
f_getll = fun inet:getll/1
and there'd be no need for the "cut" "_" treatment at all.
Why did Pop-2 need partial application?
Because it used dynamic scope for variables, so that returning a lambda
would not have worked.
Why does Eiffel have agents?
Because it didn't have lambdas.
Erlang _does_ have working funs so we can do manual Currying on the rare
occasions when it's needed.
More information about the erlang-questions
mailing list