macros.tex 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. \section{JavaScript Compiler}
  2. \subsection{Compilation and Macros}
  3. Erlang JavaScript/OTP Parse Transform has two modes defined
  4. by {\bf \-jsmacro} and {\bf \-js} Erlang module attributes.
  5. The first mode precompiles Erlang module functions
  6. into JavaScript strings. The second one exports Erlang functions
  7. into a separate JavaScript file ready to run in the browser or Node.js.
  8. \paragraph{}
  9. Sample usage of {\bf \-jsmacro} and {\bf \-js}:
  10. \begin{lstlisting}
  11. -module(sample).
  12. -compile({parse_transform, shen}).
  13. -jsmacro([tabshow/0,doc_ready/1,event/3]).
  14. -js(doc_ready/1).
  15. \end{lstlisting}
  16. \subsection{Erlang Macro Functions}
  17. Macro functions are useful for using N2O as a server-side framework.
  18. Functions get rewritten during Erlang compilation into a JavaScript format
  19. string ready for embedding. Here is an example from N2O pages:
  20. \begin{lstlisting}
  21. tabshow() ->
  22. X = jq("a[data-toggle=tab]"),
  23. X:on("show",
  24. fun(E) -> T = jq(E:at("target")),
  25. tabshow(T:attr("href")) end).
  26. doc_ready(E) ->
  27. D = jq(document),
  28. D:ready(fun() ->
  29. T = jq("a[href=\"#" ++ E ++ "\"]"),
  30. T:tab("show") end).
  31. event(A,B,C) ->
  32. ws:send('Bert':encodebuf(
  33. [{source,'Bert':binary(A)}, {x,C},
  34. {pickle,'Bert':binary(B)}, {linked,C}])).
  35. main() ->
  36. Script1 = tabshow(),
  37. Script2 = event(1, 2, 3),
  38. Script3 = doc_ready(wf:js_list("tab")),
  39. io:format("tabshow/0:~n~s~nevent/3:~n~s~ndoc_ready/1:~n~s~n",
  40. [Script1,Script2,Script3]).
  41. \end{lstlisting}
  42. Perform compilation and run tests:
  43. \vspace{1\baselineskip}
  44. \begin{lstlisting}
  45. $ erlc sample.erl
  46. $ erl
  47. > sample:main().
  48. \end{lstlisting}
  49. \vspace{1\baselineskip}
  50. You'll get the following output:
  51. \vspace{1\baselineskip}
  52. \begin{lstlisting}
  53. tabshow/0:
  54. var x = $('a[data-toggle=tab]');
  55. x.on('show',function(e) {
  56. var t = $(e['target']);
  57. return tabshow(t.attr('href'));
  58. });
  59. event/3:
  60. ws.send(Bert.encodebuf({source:Bert.binary(1),
  61. x:3,
  62. pickle:Bert.binary(2),
  63. linked:3}));
  64. doc_ready/1:
  65. var d = $(document);
  66. d.ready(function() {
  67. var t = $('a[href="#' + 'tab' + '"]');
  68. return t.tab('show');
  69. });
  70. \end{lstlisting}
  71. \vspace{1\baselineskip}
  72. As you see, no source-map needed.
  73. \subsection{JavaScript File Compilation}
  74. Export Erlang function to JavaScript file with {\bf -js([sample/0,fun\_{args}/2])}.
  75. You could include functions for both {\bf macro} and {\bf js} definitions.
  76. \newpage
  77. \subsection{Mapping Erlang/OTP to JavaScript/OTP}
  78. Following OTP libraries are partially supported in Erlang JavaScript Parse Transform:
  79. {\bf lists}, {\bf proplists}, {\bf queue}, {\bf string}.
  80. \paragraph{\bf Example 1}\
  81. \vspace{1\baselineskip}
  82. \begin{lstlisting}
  83. S = lists:map(fun(X) -> X * X end,[1,2,3,4]),
  84. \end{lstlisting}
  85. transforms to:
  86. \begin{lstlisting}
  87. s = [1,2,3,4].map(function(x) {
  88. return x * x;
  89. });
  90. \end{lstlisting}
  91. \paragraph{\bf Example 2}\
  92. \vspace{1\baselineskip}
  93. \begin{lstlisting}
  94. M = lists:foldl(fun(X, Acc) -> Acc + X end,0,[1,2,3,4]),
  95. \end{lstlisting}
  96. transforms to:
  97. \begin{lstlisting}
  98. m = [1,2,3,4].reduce(function(x,acc) {
  99. return acc + x;
  100. },0);
  101. \end{lstlisting}