Typically in Erlang you write ..
(fun(X) -> X * 2 end)(6)
to get 12 as the result. With string lambda, you write ..
(utils:lambda("X * 2"))(6)
to get the same result. Ok, counting the characters of the module and the function, you grin at the fact that it is really more verbose than the original one. But we have less boilerplates, with the explicit function declaration being engineered within the lambda.
A couple of more examples of using the string lambda :
(utils:lambda("X+2*Y+5*X"))(2,5) => 22
(utils:lambda("Y+2*X+5*Y"))(5,2) => 34
Less noisy ? Let's proceed ..
You can have higher order functions using the string lambdas, and with lesser noise .. The following are based on original Javascript examples in Oliver Steele's page ..
lists:map(fun(X) -> X * X end, [1,2,3]).
-> [1,4,9]
lists:filter(fun(X) -> X > 2 end, [1,2,3,4]).
-> [3,4]
lists:any(fun(X) -> length(X) < 3 end, string:tokens("are there any short words?", " ")).
-> false
and with string lambdas, you have the same result with ..
utils:map("X*X", [1,2,3]).
utils:filter("X>2", [1,2,3,4]).
utils:any("length(_) < 3", string:tokens("are there any short words?", " ")).
In the last example,
_ is the parameter to a unary function and provides a very handy notation in the lambda. Here are some more examples with unary parameter ..%% multiply by 5
(utils:lambda("_*5"))(8).
-> 40
%% length of the input list > 2 and every element of the list > 3
(utils:all_and(["length(_) > 2", "utils:all(\">3\", _)"]))([1,2,3,4]).
-> false
Explicit Parameters
As per original convention,
-> separates the body of the lambda from the parameters, when stated explicitly and the parameters are matched based on their first occurence in the string lambda ..(utils:lambda("X Y->X+2*Y"))(1,4).
-> 9
(utils:lambda("Y X->X+2*Y"))(1,4).
-> 6
Implicit Parameters
If not specified explicitly, parameters can be implicit and can be effectively deduced ..
%% left section implicit match
(utils:lambda("/2"))(6)
-> 3
%% right section implicit match
(utils:lambda("10/"))(2)
-> 5
%% both sections implicit match
(utils:lambda("/"))(12,6)
-> 2
Chaining for Curry
The operator
-> can be chained to implement curried functions.((utils:lambda("X->Y->X+2*Y"))(1))(4).
-> 9
or deferred invocation ..
Fun=(utils:lambda("X->Y->X+2*Y"))(1).
-> #Fun<erl_eval.6.72228031>
Fun(4).
-> 9
Higher Order Functions
String lambdas allow creating higher order functions with much less noise and much more impact than native boilerplates in the language.
%% compose allows composition of sequences of functions backwards
(utils:compose("+1", "*2"))(1).
-> 3
%% higher order functions
utils:map("+1", utils:map("*2", [1,2,3])).
-> [3,5,7]
lists:map(utils:compose(["+1", "*2"]), [1,2,3]).
-> [3,5,7]
And here are some catamorphisms ..
lists:reverse() is typically defined by Erlang in the usual recursive style :reverse([] = L) ->
L;
reverse([_] = L) ->
L;
reverse([A, B]) ->
[B, A];
reverse([A, B | L]) ->
lists:reverse(L, [B, A]).
Here is
reverse() using catamorphism and delayed invocation through string lambdas ..Reverse = utils:lambda("utils:foldl(\"[E] ++ S\", [], _)").
-> #Fun<erl_eval.6.72228031>
and later ..
Reverse([1,2,3,4]).
-> [4,3,2,1]
Or the classic factorial ..
Factorial = utils:lambda("utils:foldr(\"E*S\", 1, lists:seq(1,_))").
-> #Fun<erl_eval.6.72228031>
and later ..
Factorial(5).
-> 120
Motivation to learn another programming language
I am no expert in functional programming. I do not use functional programming in my day job. But that is why I am trying to learn functional programming. Also it is not that I will be using functional programming to write production code in the near future. We all know how the enterprise machinery works and how a typical application developer has to struggle through the drudgery of boilerplates in his bread-earner job. Learning newer paradigms of programming will teach me how to think differently and how to move gradually towards writing side-effect free programs. The principal take-away from such learning is to be able to write a piece of code that encapsulates my intention completely within the specific block, without having to look around for those unintentional impacts in other areas of the codebase.
I am a newbie in Erlang and the attempt to port string lambdas to Erlang is entirely driven by my desire to learn the programming language. The source code is still a bit rusty, may not use many of the idioms and best practices of the language, and may not cover some of the corner cases. Go ahead, download the source code, and do whatever you feel like. But drop in a few comments in case you have any suggestions for improvement.
- lib_lambda.erl (the string lambda implementation)
- lib_misc.erl (miscellaneous utilities)
- lib_lambda_utilities.erl (utility wrappers)


10 comments:
Nice, congratulations!
I can't seem to open the attached files. Can you host them elsewhere?
It would be really neat to use Erlang parse substitutions to do this. You'd eliminate the run-time overhead of performing the string hackery and function instantiation.
@Anonymous:
I do not have any alternative site for hosting. If u send me your email address, I can mail the code to you. My email address is [dghosh at acm dot org].
@mike:
As I mentioned, I have only started learning Erlang. Will u please pass on a few pointers on parse transformation in Erlang ?
Amazing!
You could host it on google code :)
Here is a google code URI :
http://code.google.com/p/erl-string-lambda/
Parse transformations are (very roughly) something like Erlang's version of Lisp macros. It would allow, for example, the Erlang code F = lambda('+1') to be translated at compile time into the corresponding "fun" definition. I too am a novice at Erlang, but from what I've seen on a few blogs (Planet Erlang, Yariv's Blog, etc) it doesn't seem very hard at all.
what a truly horrible idea. this reminds me of the bad old days when people did things in C like:
#define EVER ;;
for( EVER )
do_something();
erlang has a perfectly fine mechanism for creating anonymous functions. why kludge it up with string hacks?
情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,按摩棒,震動按摩棒,微調按摩棒,情趣按摩棒,逼真按摩棒,G點,跳蛋,跳蛋,跳蛋,性感內衣,飛機杯,充氣娃娃,情趣娃娃,角色扮演,性感睡衣,SM,潤滑液,威而柔,香水,精油,芳香精油,自慰套,自慰,性感吊帶襪,吊帶襪,情趣用品加盟AIO交友愛情館,情人歡愉用品,美女視訊,情色交友,視訊交友,辣妹視訊,美女交友,嘟嘟成人網,成人網站,A片,A片下載,免費A片,免費A片下載愛情公寓,情色,舊情人,情色貼圖,情色文學,情色交友,色情聊天室,色情小說,一葉情貼圖片區,情色小說,色情,色情遊戲,情色視訊,情色電影,aio交友愛情館,色情a片,一夜情,辣妹視訊,視訊聊天室,免費視訊聊天,免費視訊,視訊,視訊美女,美女視訊,視訊交友,視訊聊天,免費視訊聊天室,情人視訊網,影音視訊聊天室,視訊交友90739,成人影片,成人交友,美女交友,微風成人,嘟嘟成人網,成人貼圖,成人電影,A片,豆豆聊天室,聊天室,UT聊天室,尋夢園聊天室,男同志聊天室,UT男同志聊天室,聊天室尋夢園,080聊天室,080苗栗人聊天室,6K聊天室,女同志聊天室,小高聊天室,上班族聊天室,080中部人聊天室,同志聊天室,聊天室交友,中部人聊天室,成人聊天室,一夜情聊天室,情色聊天室,寄情築園小遊戲情境坊歡愉用品,情境坊歡愉用品,情趣用品,成人網站,情人節禮物,情人節,AIO交友愛情館,情色,情色貼圖,情色文學,情色交友,色情聊天室,色情小說,七夕情人節,色情,情色電影,色情網站,辣妹視訊,視訊聊天室,情色視訊,免費視訊聊天,美女視訊,視訊美女,美女交友,美女,情色交友,成人交友,自拍,本土自拍,情人視訊網,視訊交友90739,生日禮物,情色論壇,正妹牆,免費A片下載,AV女優,成人影片,色情A片,成人論壇,情趣,免費成人影片,成人電影,成人影城,愛情公寓,成人影片,保險套,舊情人,微風成人,成人,成人遊戲,成人光碟,色情遊戲,跳蛋,按摩棒,一夜情,男同志聊天室,肛交,口交,性交,援交,免費視訊交友,視訊交友,一葉情貼圖片區,性愛,視訊,視訊聊天,A片,A片下載,免費A片,嘟嘟成人網,寄情築園小遊戲,女同志聊天室,免費視訊聊天室,一夜情聊天室,聊天室
Post a Comment