Knowing when what you're looking at must be a macroHow to know whether a symbol represents function or macro?Strange Lisp Quoting scenario - Graham's On Lisp, page 37How do you compile macros in a Lisp compiler?Where to learn how to practically use Common LispLisp: Macros vs FunctionsCommon Lisp: unable to get the uncompress function in Paul Graham's book workingChoosing/evaluating macro argument forms“,@” in lisp macro functionsUsing a macro to define functions computing the 10 Easter related based datesLexical Bindings in Common Lisp MacrosGraham's Ansi Common Lisp: p.170 having trouble understanding example

How do you give a date interval with diffuse dates?

Why were these characters absent in Spider-Man: Far From Home?

How slow can a car engine run?

Which GPUs to get for Mathematical Optimization (if any)?

What happens if a company buys back all of its shares?

Arithmetics in LuaLaTeX

Why aren't there any women super GMs?

What could make large expeditions ineffective for exploring territory full of dangers and valuable resources?

Who or what determines if a curse is valid or not?

How to not confuse readers with simultaneous events?

Everyone but three

How do you send money when you're not sure it's not a scam?

What is this green alien supposed to be on the American covers of the "Hitchhiker's Guide to the Galaxy"?

Are there any Saints that have miraculously overcome death (should have died, but did not)?

What causes a rotating object to rotate forever without external force—inertia, or something else?

What are the basics of commands in Minecraft Java Edition?

What makes MOVEQ quicker than a normal MOVE in 68000 assembly?

Why is Google approaching my VPS machine?

Pauli exclusion principle - black holes

How can electric field be defined as force per charge, if the charge makes its own, singular electric field?

Locked-up DOS computer beeped on keypress. What mechanism caused that?

How to draw a winding on a toroid of a circular cross section?

Demographic consequences of closed loop reincarnation

Difference between c++14 and c++17 using: `*p++ = *p`



Knowing when what you're looking at must be a macro


How to know whether a symbol represents function or macro?Strange Lisp Quoting scenario - Graham's On Lisp, page 37How do you compile macros in a Lisp compiler?Where to learn how to practically use Common LispLisp: Macros vs FunctionsCommon Lisp: unable to get the uncompress function in Paul Graham's book workingChoosing/evaluating macro argument forms“,@” in lisp macro functionsUsing a macro to define functions computing the 10 Easter related based datesLexical Bindings in Common Lisp MacrosGraham's Ansi Common Lisp: p.170 having trouble understanding example






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















I know there is macro-function, explained here, which allows you to check, but is it also possible in simply reading lisp source to sometimes infer of what you're looking at "that must be a macro"? (assuming of course you have never seen the function/macro before).



I'm fairly sure the answer is yes, but as this seems so fundamental, I thought worth asking, especially because any nuances on this may be valuable & interesting to know about.



In Paul Graham's ANSI Common Lisp, p70, he is describing how to use defstruct.



When I see (defstruct point x y), were I to know absolutely nothing about what defstruct was, this could just as well be a function.



But when I see



(defstruct polemic
(subject "foo")
(effect "bar"))


I know that must be a macro because (let's assume), I also know that subject and effect are undefined functions. (I know that because they error with undefined function when called 'at the top level'(?)) (if that's the right term).



If the two list arguments to defstruct above were quoted, it would not be so simple. Because they're not quoted, it must be a macro.



Is it as simple as that?



I've changed the field names slightly from those used on the book to make this question clearer.



Finally, Graham writes:




"We can specify default values for structure fields by enclosing the field name and a default expression in a list in the original definition"




What I'm noticing is that that's true but it is not a (quoted) list. Would any readers of this post have phrased the above sentence at all differently (given that macros haven't been introduced in the book yet (though I have a basic awareness of what they are)).



My feeling is it's not a "data list" those default expressions are enclosed in. (apologies for bad terminology) - seeking how rightly to conceptualise here.










share|improve this question




























    3















    I know there is macro-function, explained here, which allows you to check, but is it also possible in simply reading lisp source to sometimes infer of what you're looking at "that must be a macro"? (assuming of course you have never seen the function/macro before).



    I'm fairly sure the answer is yes, but as this seems so fundamental, I thought worth asking, especially because any nuances on this may be valuable & interesting to know about.



    In Paul Graham's ANSI Common Lisp, p70, he is describing how to use defstruct.



    When I see (defstruct point x y), were I to know absolutely nothing about what defstruct was, this could just as well be a function.



    But when I see



    (defstruct polemic
    (subject "foo")
    (effect "bar"))


    I know that must be a macro because (let's assume), I also know that subject and effect are undefined functions. (I know that because they error with undefined function when called 'at the top level'(?)) (if that's the right term).



    If the two list arguments to defstruct above were quoted, it would not be so simple. Because they're not quoted, it must be a macro.



    Is it as simple as that?



    I've changed the field names slightly from those used on the book to make this question clearer.



    Finally, Graham writes:




    "We can specify default values for structure fields by enclosing the field name and a default expression in a list in the original definition"




    What I'm noticing is that that's true but it is not a (quoted) list. Would any readers of this post have phrased the above sentence at all differently (given that macros haven't been introduced in the book yet (though I have a basic awareness of what they are)).



    My feeling is it's not a "data list" those default expressions are enclosed in. (apologies for bad terminology) - seeking how rightly to conceptualise here.










    share|improve this question
























      3












      3








      3








      I know there is macro-function, explained here, which allows you to check, but is it also possible in simply reading lisp source to sometimes infer of what you're looking at "that must be a macro"? (assuming of course you have never seen the function/macro before).



      I'm fairly sure the answer is yes, but as this seems so fundamental, I thought worth asking, especially because any nuances on this may be valuable & interesting to know about.



      In Paul Graham's ANSI Common Lisp, p70, he is describing how to use defstruct.



      When I see (defstruct point x y), were I to know absolutely nothing about what defstruct was, this could just as well be a function.



      But when I see



      (defstruct polemic
      (subject "foo")
      (effect "bar"))


      I know that must be a macro because (let's assume), I also know that subject and effect are undefined functions. (I know that because they error with undefined function when called 'at the top level'(?)) (if that's the right term).



      If the two list arguments to defstruct above were quoted, it would not be so simple. Because they're not quoted, it must be a macro.



      Is it as simple as that?



      I've changed the field names slightly from those used on the book to make this question clearer.



      Finally, Graham writes:




      "We can specify default values for structure fields by enclosing the field name and a default expression in a list in the original definition"




      What I'm noticing is that that's true but it is not a (quoted) list. Would any readers of this post have phrased the above sentence at all differently (given that macros haven't been introduced in the book yet (though I have a basic awareness of what they are)).



      My feeling is it's not a "data list" those default expressions are enclosed in. (apologies for bad terminology) - seeking how rightly to conceptualise here.










      share|improve this question














      I know there is macro-function, explained here, which allows you to check, but is it also possible in simply reading lisp source to sometimes infer of what you're looking at "that must be a macro"? (assuming of course you have never seen the function/macro before).



      I'm fairly sure the answer is yes, but as this seems so fundamental, I thought worth asking, especially because any nuances on this may be valuable & interesting to know about.



      In Paul Graham's ANSI Common Lisp, p70, he is describing how to use defstruct.



      When I see (defstruct point x y), were I to know absolutely nothing about what defstruct was, this could just as well be a function.



      But when I see



      (defstruct polemic
      (subject "foo")
      (effect "bar"))


      I know that must be a macro because (let's assume), I also know that subject and effect are undefined functions. (I know that because they error with undefined function when called 'at the top level'(?)) (if that's the right term).



      If the two list arguments to defstruct above were quoted, it would not be so simple. Because they're not quoted, it must be a macro.



      Is it as simple as that?



      I've changed the field names slightly from those used on the book to make this question clearer.



      Finally, Graham writes:




      "We can specify default values for structure fields by enclosing the field name and a default expression in a list in the original definition"




      What I'm noticing is that that's true but it is not a (quoted) list. Would any readers of this post have phrased the above sentence at all differently (given that macros haven't been introduced in the book yet (though I have a basic awareness of what they are)).



      My feeling is it's not a "data list" those default expressions are enclosed in. (apologies for bad terminology) - seeking how rightly to conceptualise here.







      common-lisp






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 26 at 9:58









      mwalmwal

      7285 silver badges17 bronze badges




      7285 silver badges17 bronze badges






















          2 Answers
          2






          active

          oldest

          votes


















          4














          In general, you're right: if there's some nesting inside the call and you are sure that the car's of the nested lists aren't functions - it's a macro.



          Also, almost always, def-something and with-something are macros.



          But there's no guarantee. The question is, what are you trying to accomplish? Some code walking/transformation or external processing (like in an editor). For the latter, you should keep in mind that full control is possible only if you perform code evaluation, although heuristics (like in Emacs) can take you pretty far. Or you just want to develop your intuition for faster code reading...






          share|improve this answer






























            3














            There is a set of conventions that identify quite cleary what forms are supposed to be macros, simply by mimicking the syntax of existing macros or special operators of CL.
            For example, the following is a mix of various imaginary macros, but even without knowing their definition, the code shouldn't be too hard to figure out:



            (defun/typed example ((id (integer 0 10)))
            (with-connection (connection (connect id))
            (do-events (event connection)
            (event-case event
            (:quit (&optional code) (return code))))))


            The usual advice about macros is to avoid them if possible, so if you spot something that doesn't make sense as a lisp expression, it probably is, or is enclosed in, a macro.



            (defstruct point x y)



            [...] were I to know absolutely nothing about what defstruct was, this could just as well be a function.




            There are various hints that this is not a function. First of all, the name starts with def. Then, if defstruct was a function, then point, x and y would all be evaluated before calling the function, and that means the code would be relying on global variables, even though they are not wearing earmuffs (e.g. *point*, *x*, *y*), and you probably won't find any definition for them in the preceding forms (or later in the same compilation unit). Also, if it was a function, the result would be discarded directly since it is not used (this is a toplevel form). That only indicates the probable presence of side-effects, but still, this would be unusual.
            A top-level function with side-effects would look like this instead, with quoted data:



            (register-struct 'point '(x y))


            Finally, there are cases where you cannot easily guess if you are using a macro or a function:



            (my-get object :slot)


            This could be a function call, or you could have a macro that turns the above to (aref object 0) (assuming :slot is the zeroth slot in object, because all your objects are assumed to be of a certain custom type backed by a vector). You could also have compiler macros. In case of doubt, try to macroexpand it and look at the documentation.






            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55354268%2fknowing-when-what-youre-looking-at-must-be-a-macro%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              In general, you're right: if there's some nesting inside the call and you are sure that the car's of the nested lists aren't functions - it's a macro.



              Also, almost always, def-something and with-something are macros.



              But there's no guarantee. The question is, what are you trying to accomplish? Some code walking/transformation or external processing (like in an editor). For the latter, you should keep in mind that full control is possible only if you perform code evaluation, although heuristics (like in Emacs) can take you pretty far. Or you just want to develop your intuition for faster code reading...






              share|improve this answer



























                4














                In general, you're right: if there's some nesting inside the call and you are sure that the car's of the nested lists aren't functions - it's a macro.



                Also, almost always, def-something and with-something are macros.



                But there's no guarantee. The question is, what are you trying to accomplish? Some code walking/transformation or external processing (like in an editor). For the latter, you should keep in mind that full control is possible only if you perform code evaluation, although heuristics (like in Emacs) can take you pretty far. Or you just want to develop your intuition for faster code reading...






                share|improve this answer

























                  4












                  4








                  4







                  In general, you're right: if there's some nesting inside the call and you are sure that the car's of the nested lists aren't functions - it's a macro.



                  Also, almost always, def-something and with-something are macros.



                  But there's no guarantee. The question is, what are you trying to accomplish? Some code walking/transformation or external processing (like in an editor). For the latter, you should keep in mind that full control is possible only if you perform code evaluation, although heuristics (like in Emacs) can take you pretty far. Or you just want to develop your intuition for faster code reading...






                  share|improve this answer













                  In general, you're right: if there's some nesting inside the call and you are sure that the car's of the nested lists aren't functions - it's a macro.



                  Also, almost always, def-something and with-something are macros.



                  But there's no guarantee. The question is, what are you trying to accomplish? Some code walking/transformation or external processing (like in an editor). For the latter, you should keep in mind that full control is possible only if you perform code evaluation, although heuristics (like in Emacs) can take you pretty far. Or you just want to develop your intuition for faster code reading...







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 26 at 10:11









                  Vsevolod DyomkinVsevolod Dyomkin

                  8,2592 gold badges21 silver badges29 bronze badges




                  8,2592 gold badges21 silver badges29 bronze badges























                      3














                      There is a set of conventions that identify quite cleary what forms are supposed to be macros, simply by mimicking the syntax of existing macros or special operators of CL.
                      For example, the following is a mix of various imaginary macros, but even without knowing their definition, the code shouldn't be too hard to figure out:



                      (defun/typed example ((id (integer 0 10)))
                      (with-connection (connection (connect id))
                      (do-events (event connection)
                      (event-case event
                      (:quit (&optional code) (return code))))))


                      The usual advice about macros is to avoid them if possible, so if you spot something that doesn't make sense as a lisp expression, it probably is, or is enclosed in, a macro.



                      (defstruct point x y)



                      [...] were I to know absolutely nothing about what defstruct was, this could just as well be a function.




                      There are various hints that this is not a function. First of all, the name starts with def. Then, if defstruct was a function, then point, x and y would all be evaluated before calling the function, and that means the code would be relying on global variables, even though they are not wearing earmuffs (e.g. *point*, *x*, *y*), and you probably won't find any definition for them in the preceding forms (or later in the same compilation unit). Also, if it was a function, the result would be discarded directly since it is not used (this is a toplevel form). That only indicates the probable presence of side-effects, but still, this would be unusual.
                      A top-level function with side-effects would look like this instead, with quoted data:



                      (register-struct 'point '(x y))


                      Finally, there are cases where you cannot easily guess if you are using a macro or a function:



                      (my-get object :slot)


                      This could be a function call, or you could have a macro that turns the above to (aref object 0) (assuming :slot is the zeroth slot in object, because all your objects are assumed to be of a certain custom type backed by a vector). You could also have compiler macros. In case of doubt, try to macroexpand it and look at the documentation.






                      share|improve this answer



























                        3














                        There is a set of conventions that identify quite cleary what forms are supposed to be macros, simply by mimicking the syntax of existing macros or special operators of CL.
                        For example, the following is a mix of various imaginary macros, but even without knowing their definition, the code shouldn't be too hard to figure out:



                        (defun/typed example ((id (integer 0 10)))
                        (with-connection (connection (connect id))
                        (do-events (event connection)
                        (event-case event
                        (:quit (&optional code) (return code))))))


                        The usual advice about macros is to avoid them if possible, so if you spot something that doesn't make sense as a lisp expression, it probably is, or is enclosed in, a macro.



                        (defstruct point x y)



                        [...] were I to know absolutely nothing about what defstruct was, this could just as well be a function.




                        There are various hints that this is not a function. First of all, the name starts with def. Then, if defstruct was a function, then point, x and y would all be evaluated before calling the function, and that means the code would be relying on global variables, even though they are not wearing earmuffs (e.g. *point*, *x*, *y*), and you probably won't find any definition for them in the preceding forms (or later in the same compilation unit). Also, if it was a function, the result would be discarded directly since it is not used (this is a toplevel form). That only indicates the probable presence of side-effects, but still, this would be unusual.
                        A top-level function with side-effects would look like this instead, with quoted data:



                        (register-struct 'point '(x y))


                        Finally, there are cases where you cannot easily guess if you are using a macro or a function:



                        (my-get object :slot)


                        This could be a function call, or you could have a macro that turns the above to (aref object 0) (assuming :slot is the zeroth slot in object, because all your objects are assumed to be of a certain custom type backed by a vector). You could also have compiler macros. In case of doubt, try to macroexpand it and look at the documentation.






                        share|improve this answer

























                          3












                          3








                          3







                          There is a set of conventions that identify quite cleary what forms are supposed to be macros, simply by mimicking the syntax of existing macros or special operators of CL.
                          For example, the following is a mix of various imaginary macros, but even without knowing their definition, the code shouldn't be too hard to figure out:



                          (defun/typed example ((id (integer 0 10)))
                          (with-connection (connection (connect id))
                          (do-events (event connection)
                          (event-case event
                          (:quit (&optional code) (return code))))))


                          The usual advice about macros is to avoid them if possible, so if you spot something that doesn't make sense as a lisp expression, it probably is, or is enclosed in, a macro.



                          (defstruct point x y)



                          [...] were I to know absolutely nothing about what defstruct was, this could just as well be a function.




                          There are various hints that this is not a function. First of all, the name starts with def. Then, if defstruct was a function, then point, x and y would all be evaluated before calling the function, and that means the code would be relying on global variables, even though they are not wearing earmuffs (e.g. *point*, *x*, *y*), and you probably won't find any definition for them in the preceding forms (or later in the same compilation unit). Also, if it was a function, the result would be discarded directly since it is not used (this is a toplevel form). That only indicates the probable presence of side-effects, but still, this would be unusual.
                          A top-level function with side-effects would look like this instead, with quoted data:



                          (register-struct 'point '(x y))


                          Finally, there are cases where you cannot easily guess if you are using a macro or a function:



                          (my-get object :slot)


                          This could be a function call, or you could have a macro that turns the above to (aref object 0) (assuming :slot is the zeroth slot in object, because all your objects are assumed to be of a certain custom type backed by a vector). You could also have compiler macros. In case of doubt, try to macroexpand it and look at the documentation.






                          share|improve this answer













                          There is a set of conventions that identify quite cleary what forms are supposed to be macros, simply by mimicking the syntax of existing macros or special operators of CL.
                          For example, the following is a mix of various imaginary macros, but even without knowing their definition, the code shouldn't be too hard to figure out:



                          (defun/typed example ((id (integer 0 10)))
                          (with-connection (connection (connect id))
                          (do-events (event connection)
                          (event-case event
                          (:quit (&optional code) (return code))))))


                          The usual advice about macros is to avoid them if possible, so if you spot something that doesn't make sense as a lisp expression, it probably is, or is enclosed in, a macro.



                          (defstruct point x y)



                          [...] were I to know absolutely nothing about what defstruct was, this could just as well be a function.




                          There are various hints that this is not a function. First of all, the name starts with def. Then, if defstruct was a function, then point, x and y would all be evaluated before calling the function, and that means the code would be relying on global variables, even though they are not wearing earmuffs (e.g. *point*, *x*, *y*), and you probably won't find any definition for them in the preceding forms (or later in the same compilation unit). Also, if it was a function, the result would be discarded directly since it is not used (this is a toplevel form). That only indicates the probable presence of side-effects, but still, this would be unusual.
                          A top-level function with side-effects would look like this instead, with quoted data:



                          (register-struct 'point '(x y))


                          Finally, there are cases where you cannot easily guess if you are using a macro or a function:



                          (my-get object :slot)


                          This could be a function call, or you could have a macro that turns the above to (aref object 0) (assuming :slot is the zeroth slot in object, because all your objects are assumed to be of a certain custom type backed by a vector). You could also have compiler macros. In case of doubt, try to macroexpand it and look at the documentation.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Mar 26 at 12:51









                          coredumpcoredump

                          24.4k4 gold badges33 silver badges51 bronze badges




                          24.4k4 gold badges33 silver badges51 bronze badges



























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55354268%2fknowing-when-what-youre-looking-at-must-be-a-macro%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                              Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                              Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript