Common Lisp dotimes result mystery












3














I got this



(dotimes (temp-one 10 temp-one))


from the Hyperspec examples on dotimes. Running this produces the answer 10. So the temp-one in the third parameter position is acting as a returned "result," but how did it get to 10 when dotimes starts at 0 and would only go to 9?



>(dotimes (temp-one 10 temp-one) (format t "~3d " temp-one))
0 1 2 3 4 5 6 7 8 9
10


What am I missing here about the third parameter?










share|improve this question


















  • 3




    As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
    – jkiiski
    Nov 21 '18 at 5:50
















3














I got this



(dotimes (temp-one 10 temp-one))


from the Hyperspec examples on dotimes. Running this produces the answer 10. So the temp-one in the third parameter position is acting as a returned "result," but how did it get to 10 when dotimes starts at 0 and would only go to 9?



>(dotimes (temp-one 10 temp-one) (format t "~3d " temp-one))
0 1 2 3 4 5 6 7 8 9
10


What am I missing here about the third parameter?










share|improve this question


















  • 3




    As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
    – jkiiski
    Nov 21 '18 at 5:50














3












3








3







I got this



(dotimes (temp-one 10 temp-one))


from the Hyperspec examples on dotimes. Running this produces the answer 10. So the temp-one in the third parameter position is acting as a returned "result," but how did it get to 10 when dotimes starts at 0 and would only go to 9?



>(dotimes (temp-one 10 temp-one) (format t "~3d " temp-one))
0 1 2 3 4 5 6 7 8 9
10


What am I missing here about the third parameter?










share|improve this question













I got this



(dotimes (temp-one 10 temp-one))


from the Hyperspec examples on dotimes. Running this produces the answer 10. So the temp-one in the third parameter position is acting as a returned "result," but how did it get to 10 when dotimes starts at 0 and would only go to 9?



>(dotimes (temp-one 10 temp-one) (format t "~3d " temp-one))
0 1 2 3 4 5 6 7 8 9
10


What am I missing here about the third parameter?







loops common-lisp






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 5:28









147pm147pm

582416




582416








  • 3




    As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
    – jkiiski
    Nov 21 '18 at 5:50














  • 3




    As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
    – jkiiski
    Nov 21 '18 at 5:50








3




3




As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
– jkiiski
Nov 21 '18 at 5:50




As the hyperspec says: "At the time result-form is processed, var is bound to the number of times the body was executed"
– jkiiski
Nov 21 '18 at 5:50












2 Answers
2






active

oldest

votes


















5














If you look at the dotimes Hyperspec entry it states it's a macro meaning you get to see "under the hood" by calling macroexpand:



(macroexpand '(dotimes (i 10 i)))


SBCL:



(BLOCK NIL
(LET ((I 0))
(DECLARE (TYPE UNSIGNED-BYTE I))
(TAGBODY
(GO #:G386)
#:G385
(TAGBODY)
(PSETQ I (1+ I))
#:G386
(UNLESS (>= I 10) (GO #:G385))
(RETURN-FROM NIL (PROGN I)))))


Allegro CL:



(do ((i 0 (1+ i)))
((>= i 10) i))


In both cases the iteration variable i is increased by one, and then the end test (>= i 10) is done. As jkiiski wrote:




"At the time result-form is processed, var is bound to the number of times the body was executed."




and the (return-from ..) form (SBCL) and i form (Allegro CL) are evaluated after the variable increase and test.






share|improve this answer





















  • Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
    – 147pm
    Nov 21 '18 at 17:08










  • The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
    – zut
    Nov 22 '18 at 22:03



















4














Hyperspec says:




At the time result-form is processed, var is bound to the number of
times the body was executed.




So, in the third form, the result-form, the variable gets first bound to the number of times the body was executed first, and then the third form is evaluated.



That is why the value of the variable is 10 and not the current value 9.



This is also visible, if you do



(macroexpand-1 '(dotimes (temp-one 3 temp-one) (format t "~3d~%" temp-one)))

;; resulting in CLISP in:
;; (DO ((TEMP-ONE 0 (1+ TEMP-ONE))) ((>= TEMP-ONE 10) TEMP-ONE)
;; (FORMAT T "~3d~%" TEMP-ONE)) ;
;; T


So finally, (1+ TEMP-ONE) is returned by the DO loop, to which DOTIMES expands to - as pointed out by @zut.






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%2f53405744%2fcommon-lisp-dotimes-result-mystery%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









    5














    If you look at the dotimes Hyperspec entry it states it's a macro meaning you get to see "under the hood" by calling macroexpand:



    (macroexpand '(dotimes (i 10 i)))


    SBCL:



    (BLOCK NIL
    (LET ((I 0))
    (DECLARE (TYPE UNSIGNED-BYTE I))
    (TAGBODY
    (GO #:G386)
    #:G385
    (TAGBODY)
    (PSETQ I (1+ I))
    #:G386
    (UNLESS (>= I 10) (GO #:G385))
    (RETURN-FROM NIL (PROGN I)))))


    Allegro CL:



    (do ((i 0 (1+ i)))
    ((>= i 10) i))


    In both cases the iteration variable i is increased by one, and then the end test (>= i 10) is done. As jkiiski wrote:




    "At the time result-form is processed, var is bound to the number of times the body was executed."




    and the (return-from ..) form (SBCL) and i form (Allegro CL) are evaluated after the variable increase and test.






    share|improve this answer





















    • Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
      – 147pm
      Nov 21 '18 at 17:08










    • The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
      – zut
      Nov 22 '18 at 22:03
















    5














    If you look at the dotimes Hyperspec entry it states it's a macro meaning you get to see "under the hood" by calling macroexpand:



    (macroexpand '(dotimes (i 10 i)))


    SBCL:



    (BLOCK NIL
    (LET ((I 0))
    (DECLARE (TYPE UNSIGNED-BYTE I))
    (TAGBODY
    (GO #:G386)
    #:G385
    (TAGBODY)
    (PSETQ I (1+ I))
    #:G386
    (UNLESS (>= I 10) (GO #:G385))
    (RETURN-FROM NIL (PROGN I)))))


    Allegro CL:



    (do ((i 0 (1+ i)))
    ((>= i 10) i))


    In both cases the iteration variable i is increased by one, and then the end test (>= i 10) is done. As jkiiski wrote:




    "At the time result-form is processed, var is bound to the number of times the body was executed."




    and the (return-from ..) form (SBCL) and i form (Allegro CL) are evaluated after the variable increase and test.






    share|improve this answer





















    • Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
      – 147pm
      Nov 21 '18 at 17:08










    • The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
      – zut
      Nov 22 '18 at 22:03














    5












    5








    5






    If you look at the dotimes Hyperspec entry it states it's a macro meaning you get to see "under the hood" by calling macroexpand:



    (macroexpand '(dotimes (i 10 i)))


    SBCL:



    (BLOCK NIL
    (LET ((I 0))
    (DECLARE (TYPE UNSIGNED-BYTE I))
    (TAGBODY
    (GO #:G386)
    #:G385
    (TAGBODY)
    (PSETQ I (1+ I))
    #:G386
    (UNLESS (>= I 10) (GO #:G385))
    (RETURN-FROM NIL (PROGN I)))))


    Allegro CL:



    (do ((i 0 (1+ i)))
    ((>= i 10) i))


    In both cases the iteration variable i is increased by one, and then the end test (>= i 10) is done. As jkiiski wrote:




    "At the time result-form is processed, var is bound to the number of times the body was executed."




    and the (return-from ..) form (SBCL) and i form (Allegro CL) are evaluated after the variable increase and test.






    share|improve this answer












    If you look at the dotimes Hyperspec entry it states it's a macro meaning you get to see "under the hood" by calling macroexpand:



    (macroexpand '(dotimes (i 10 i)))


    SBCL:



    (BLOCK NIL
    (LET ((I 0))
    (DECLARE (TYPE UNSIGNED-BYTE I))
    (TAGBODY
    (GO #:G386)
    #:G385
    (TAGBODY)
    (PSETQ I (1+ I))
    #:G386
    (UNLESS (>= I 10) (GO #:G385))
    (RETURN-FROM NIL (PROGN I)))))


    Allegro CL:



    (do ((i 0 (1+ i)))
    ((>= i 10) i))


    In both cases the iteration variable i is increased by one, and then the end test (>= i 10) is done. As jkiiski wrote:




    "At the time result-form is processed, var is bound to the number of times the body was executed."




    and the (return-from ..) form (SBCL) and i form (Allegro CL) are evaluated after the variable increase and test.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 21 '18 at 8:44









    zutzut

    55624




    55624












    • Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
      – 147pm
      Nov 21 '18 at 17:08










    • The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
      – zut
      Nov 22 '18 at 22:03


















    • Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
      – 147pm
      Nov 21 '18 at 17:08










    • The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
      – zut
      Nov 22 '18 at 22:03
















    Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
    – 147pm
    Nov 21 '18 at 17:08




    Right after I posted this I realized it had to be something like the last iteration is sent to result-form even though it fails/terminates. BTW, what sort of Lisp is that in the SBCL expanded macro? I'm still just a beginner and haven't seen much yet.
    – 147pm
    Nov 21 '18 at 17:08












    The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
    – zut
    Nov 22 '18 at 22:03




    The macroexpansion given by SBCL, the (BLOCK NIL ..), is also Common Lisp. It's in upper case as that is the standard. (My Allegro example was done in its "Modern" mode that keeps case and uses lowercase for the standard functions; it also comes with "ANSI" mode that behaves like SBCL). Coding using tagbody with go and labels feels like low-level assembly code, usually you would use higher-level abstractions, but nevertheless it's all part of Common Lisp.
    – zut
    Nov 22 '18 at 22:03













    4














    Hyperspec says:




    At the time result-form is processed, var is bound to the number of
    times the body was executed.




    So, in the third form, the result-form, the variable gets first bound to the number of times the body was executed first, and then the third form is evaluated.



    That is why the value of the variable is 10 and not the current value 9.



    This is also visible, if you do



    (macroexpand-1 '(dotimes (temp-one 3 temp-one) (format t "~3d~%" temp-one)))

    ;; resulting in CLISP in:
    ;; (DO ((TEMP-ONE 0 (1+ TEMP-ONE))) ((>= TEMP-ONE 10) TEMP-ONE)
    ;; (FORMAT T "~3d~%" TEMP-ONE)) ;
    ;; T


    So finally, (1+ TEMP-ONE) is returned by the DO loop, to which DOTIMES expands to - as pointed out by @zut.






    share|improve this answer


























      4














      Hyperspec says:




      At the time result-form is processed, var is bound to the number of
      times the body was executed.




      So, in the third form, the result-form, the variable gets first bound to the number of times the body was executed first, and then the third form is evaluated.



      That is why the value of the variable is 10 and not the current value 9.



      This is also visible, if you do



      (macroexpand-1 '(dotimes (temp-one 3 temp-one) (format t "~3d~%" temp-one)))

      ;; resulting in CLISP in:
      ;; (DO ((TEMP-ONE 0 (1+ TEMP-ONE))) ((>= TEMP-ONE 10) TEMP-ONE)
      ;; (FORMAT T "~3d~%" TEMP-ONE)) ;
      ;; T


      So finally, (1+ TEMP-ONE) is returned by the DO loop, to which DOTIMES expands to - as pointed out by @zut.






      share|improve this answer
























        4












        4








        4






        Hyperspec says:




        At the time result-form is processed, var is bound to the number of
        times the body was executed.




        So, in the third form, the result-form, the variable gets first bound to the number of times the body was executed first, and then the third form is evaluated.



        That is why the value of the variable is 10 and not the current value 9.



        This is also visible, if you do



        (macroexpand-1 '(dotimes (temp-one 3 temp-one) (format t "~3d~%" temp-one)))

        ;; resulting in CLISP in:
        ;; (DO ((TEMP-ONE 0 (1+ TEMP-ONE))) ((>= TEMP-ONE 10) TEMP-ONE)
        ;; (FORMAT T "~3d~%" TEMP-ONE)) ;
        ;; T


        So finally, (1+ TEMP-ONE) is returned by the DO loop, to which DOTIMES expands to - as pointed out by @zut.






        share|improve this answer












        Hyperspec says:




        At the time result-form is processed, var is bound to the number of
        times the body was executed.




        So, in the third form, the result-form, the variable gets first bound to the number of times the body was executed first, and then the third form is evaluated.



        That is why the value of the variable is 10 and not the current value 9.



        This is also visible, if you do



        (macroexpand-1 '(dotimes (temp-one 3 temp-one) (format t "~3d~%" temp-one)))

        ;; resulting in CLISP in:
        ;; (DO ((TEMP-ONE 0 (1+ TEMP-ONE))) ((>= TEMP-ONE 10) TEMP-ONE)
        ;; (FORMAT T "~3d~%" TEMP-ONE)) ;
        ;; T


        So finally, (1+ TEMP-ONE) is returned by the DO loop, to which DOTIMES expands to - as pointed out by @zut.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 11:09









        Gwang-Jin KimGwang-Jin Kim

        2,396116




        2,396116






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53405744%2fcommon-lisp-dotimes-result-mystery%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

            Costa Masnaga

            Fotorealismo

            Sidney Franklin