[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