Advertisement

Macrofication: Refactoring by Reverse Macro Expansion

  • Christopher SchusterEmail author
  • Tim Disney
  • Cormac Flanagan
Part of the Lecture Notes in Computer Science book series (LNCS, volume 9632)

Abstract

Refactoring is a code transformation performed at development time that improves the quality of code while preserving its observable behavior. Macro expansion is also a code transformation, but performed at compile time, that replaces instances of macro invocation patterns with the corresponding macro body or template. The key insight of this paper is that for each pattern-template macro, we can automatically generate a corresponding refactoring tool that finds complex code fragments matching the macro template and replaces them with the equivalent but simpler macro invocation pattern; we call this novel refactoring process macrofication.

Conceptually, macrofication involves running macro expansion in reverse; however, it does require a more sophisticated pattern matching algorithm and additional checks to ensure that the refactoring always preserves program behavior.

We have implemented a macrofication tool for a hygienic macro system in JavaScript, integrated it into a development environment and evaluated it by refactoring a popular open source JavaScript library. Results indicate that it is sufficiently flexible for complex refactoring and thereby enhances the development workflow while scaling well even for larger code bases.

Keywords

Pattern Repetition Repeated Variable Pattern Match Algorithm Pattern Environment Code Smell 
These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

Notes

Acknowledgements

This research was supported by the National Science Foundation under grants CCF-1337278 and CCF-1421016.

References

  1. 1.
    The Rust Language. http://www.rust-lang.org/
  2. 2.
    Adams, M.D.: Towards the essence of hygiene. In: POPL 2015 (2015)Google Scholar
  3. 3.
    Alexandrescu, A.: Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley, Reading (2001)Google Scholar
  4. 4.
    Allen, E., Culpepper, R., Nielsen, J.: Growing a syntax. In: FOOL 2009 (2009)Google Scholar
  5. 5.
    Bachrach, J., Playford, K., Street, C.: D-Expressions: Lisp Power, Dylan Style. Style DeKalb IL (1999)Google Scholar
  6. 6.
    Clinger, W.: Macros that work. In: POPL 1991 (1991)Google Scholar
  7. 7.
    Culpepper, R.: Refining syntactic sugar: tools for supporting macro development. Ph.D. thesis, Northeastern University Boston (2010)Google Scholar
  8. 8.
    De Roover, C., Inoue, K.: The Ekeko/X program transformation tool. In: SCAM 2014, pp. 53–58, September 2014Google Scholar
  9. 9.
    Debray, S.K., Evans, W., Muth, R., De Sutter, B.: Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22(2), 378–415 (2000)CrossRefGoogle Scholar
  10. 10.
    Disney, T., Faubion, N., Herman, D., Flanagan, C.: Sweeten your javascript: hygienic macros for ES5. In: Proceedings of the 10th ACM Symposium on Dynamic Languages, DLS 2014, pp. 35–44. ACM, New York (2014)Google Scholar
  11. 11.
    Erdweg, S., Rendel, T., Kästner, C., Ostermann, K.: SugarJ: library-based syntactic language extensibility. In: OOPSLA 2011 (2011)Google Scholar
  12. 12.
    Flatt, M., Culpepper, R., Darais, D., Findler, R.B.: Macros that work together. J. Funct. Prog. 22, 181–216 (2012). doi: 10.1017/S0956796812000093 MathSciNetCrossRefzbMATHGoogle Scholar
  13. 13.
    Flatt, M.: Composable and compilable macros: you want it when? In: ICFP 2002, pp. 72–83 (2002)Google Scholar
  14. 14.
    Foderaro, J.K., Sklower, K.L., Layer, K.: The FRANZ LISP Manual. University of California, Berkeley (1983)Google Scholar
  15. 15.
    Fowler, M.: Refactoring: Improving the Design of Existing Code. Pearson Education, India (1999)zbMATHGoogle Scholar
  16. 16.
    Ganz, S., Sabry, A., Taha, W.: Macros as multi-stage computations: type-safe, generative, binding macros in MacroML. In: ICFP 2001 (2001)Google Scholar
  17. 17.
    Garrido, A., Johnson, R.: Challenges of refactoring C programs. In: IWPSE 2002, pp. 6–14 (2002)Google Scholar
  18. 18.
    Ge, X., DuBose, Q.L., Murphy-Hill, E.: Reconciling manual and automatic refactoring. In: ICSE 2012, pp. 211–221 (2012)Google Scholar
  19. 19.
    Ghuloum, A., Dybvig, R.K.: Implicit phasing for R6RS libraries. In: ICFP 2007 (2007)Google Scholar
  20. 20.
    Griswold, W.G.: Program restructuring as an aid to software maintenance. Ph.D. thesis, University of California, San Diego (1992)Google Scholar
  21. 21.
    Herman, D., Wand, M.: A theory of hygienic macros. In: Drossopoulou, S. (ed.) ESOP 2008. LNCS, vol. 4960, pp. 48–62. Springer, Heidelberg (2008)CrossRefGoogle Scholar
  22. 22.
    Hieb, R., Dybvig, R., Bruggeman, C.: Syntactic abstraction in scheme. Lisp Symb. Comput. 5(4), 295–326 (1992)Google Scholar
  23. 23.
    ECMA International: ECMA-262 ECMAScript Language Specification. ECMAScript, 6th edn. (2015)Google Scholar
  24. 24.
    Kernighan, B.W., Ritchie, D.M.: The C Programming Language, vol. 2. Prentice Hall, Upper Saddle River (1988)zbMATHGoogle Scholar
  25. 25.
    Klop, J.W., Klop, J.: Term rewriting systems. Centrum voor Wiskunde en Informatica (1990)Google Scholar
  26. 26.
    Kohlbecker, E.E., Wand, M.: Macro-by-example: deriving syntactic transformations from their specifications. In: POPL 1987 (1987)Google Scholar
  27. 27.
    Lahoda, J., Bečička, J., Ruijs, R.B.: Custom declarative refactoring in NetBeans: tool demonstration. In: WRT 2012, pp. 63–64. ACM, New York (2012)Google Scholar
  28. 28.
    Lee, B., Grimm, R., Hirzel, M., McKinley, K.: Marco: safe, expressive macros for any language. In: Noble, J. (ed.) ECOOP 2012. LNCS, pp. 589–613. Springer, Heidelberg (2012)CrossRefGoogle Scholar
  29. 29.
    Li, H., Thompson, S.: Clone detection and removal for Erlang/OTP within a refactoring environment. In: PEPM 2009. ACM (2009)Google Scholar
  30. 30.
    Li, H., Thompson, S.: Let’s make refactoring tools user-extensible! In: WRT 2012, pp. 32–39. ACM, New York (2012)Google Scholar
  31. 31.
    Long, J.: The ES6-macros project. https://github.com/jlongster/es6-macros
  32. 32.
    Martelli, A., Montanari, U.: An efficient unification algorithm. In: TOPLAS 1982 (1982)Google Scholar
  33. 33.
    Mens, T., Tourwé, T.: A survey of software refactoring. IEEE Trans. Softw. Eng. 30, 126–139 (2004)CrossRefGoogle Scholar
  34. 34.
    Opdyke, W.F.: Refactoring object-oriented frameworks. Ph.D. thesis (1992)Google Scholar
  35. 35.
    Overbey, J.L., Behrang, F., Hafiz, M.: A foundation for refactoring C with macros. In: FSE 2014 (2014)Google Scholar
  36. 36.
    Overbey, J.L., Johnson, R.E.: Differential precondition checking: a lightweight, reusable analysis for refactoring tools. In: ASE (2011)Google Scholar
  37. 37.
    Pitman, K.M.: Special forms in Lisp. In: LFP 1980 (1980)Google Scholar
  38. 38.
    Pombrio, J., Krishnamurthi, S.: Resugaring: lifting evaluation sequences through syntactic sugar. In: PLDI 2014, pp. 361–371. ACM, New York (2014)Google Scholar
  39. 39.
    Pombrio, J., Krishnamurthi, S.: Hygienic resugaring of compositional desugaring. In: ICFP 2015, pp. 75–87. ACM, New York (2015)Google Scholar
  40. 40.
    Rafkind, J.: Syntactic extension for languages with implicitly delimited and infix syntax. Ph.D. thesis, The University of Utah (2013)Google Scholar
  41. 41.
    Rafkind, J., Flatt, M.: Honu: syntactic extension for algebraic notation through enforestation. In: GPCE 2012 (2012)Google Scholar
  42. 42.
    Riehl, J.: Language embedding and optimization in mython. In: DLS 2009 (2009)Google Scholar
  43. 43.
    Roberts, D., Brant, J., Johnson, R.E.: A refactoring tool for smalltalk. TAPOS 3(4), 253–263 (1997)Google Scholar
  44. 44.
    Schäfer, M., De Moor, O.: Specifying and implementing refactorings. In: OOPSLA 2010 (2010)Google Scholar
  45. 45.
    Schäfer, M., Dolby, J., Sridharan, M., Torlak, E., Tip, F.: Correct refactoring of concurrent Java code. In: D’Hondt, T. (ed.) ECOOP 2010. LNCS, vol. 6183, pp. 225–249. Springer, Heidelberg (2010)CrossRefGoogle Scholar
  46. 46.
    Schäfer, M., Verbaere, M., Ekman, T., de Moor, O.: Stepping stones over the refactoring rubicon. In: Drossopoulou, S. (ed.) ECOOP 2009. LNCS, vol. 5653, pp. 369–393. Springer, Heidelberg (2009)CrossRefGoogle Scholar
  47. 47.
    Sheard, T., Jones, S.: Template meta-programming for Haskell. In: Workshop on Haskell (2002)Google Scholar
  48. 48.
    Skalski, K., Moskal, M., Olszta, P.: Meta-programming in Nemerle. In: GPCE 2004 (2004)Google Scholar
  49. 49.
    Sperber, M., Dybvig, R.K., Flatt, M., Van straaten, A., Findler, R., Matthews, J.: Revised6 report on the algorithmic language scheme. J. Funct. Prog. 19, 1–301 (2009). doi: 10.1017/S0956796809990074
  50. 50.
    Steele Jr., G.L.: Common LISP: The Language. Digital Press, Burlington (1990)zbMATHGoogle Scholar
  51. 51.
    Stroustrup, B., Kumar, A., Sutton, A.: Rejuvenating C++ programs through demacrofication. In: ICSM 2012 (2012)Google Scholar
  52. 52.
    Taha, W., Sheard, T.: Multi-stage programming with explicit annotations. In: PEPM 1997 (1997)Google Scholar
  53. 53.
    Tobin-Hochstadt, S., St-Amour, V.: Languages as libraries. In: PLDI 2011 (2011)Google Scholar
  54. 54.
    Visser, E.: Program transformation with stratego/XT. In: Lengauer, C., Batory, D., Blum, A., Odersky, M. (eds.) Domain-Specific Program Generation. LNCS, vol. 3016, pp. 216–238. Springer, Heidelberg (2004)CrossRefGoogle Scholar
  55. 55.
    Wakita, K., Homizu, K., Sasaki, A.: Hygienic macro system for JavaScript and Its light-weight implementation framework. In: ILC 2014 (2014)Google Scholar
  56. 56.
    Warth, A., Piumarta, I.: OMeta: an object-oriented language for pattern matching. In: DLS 2007 (2007)Google Scholar

Copyright information

© Springer-Verlag Berlin Heidelberg 2016

Authors and Affiliations

  • Christopher Schuster
    • 1
    Email author
  • Tim Disney
    • 1
  • Cormac Flanagan
    • 1
  1. 1.University of CaliforniaSanta CruzUSA

Personalised recommendations