Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7440745
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T10:53:59+00:00 2026-05-29T10:53:59+00:00

This is a related question , some sort of a follow up. Let’s say

  • 0

This is a related question, some sort of a follow up.

Let’s say I’m trying to build a loop expression by using macros, in which the resulting loop expression is dependant on whether the parameter is a list:

(defmacro testing-loop (var)
   `(eval (append '(loop for x from 0 to 5)
            (when (consp ,var) '(and y in ,var))            
            '(collect)            
            (if (consp ,var) '(y) '(x))))

This seems to work:

CL-USER> (testing-loop 2)
(0 1 2 3 4 5)
CL-USER> (testing-loop (list 5 6 7))
(5 6 7)

But when applying this macro in a lexical closure, it breaks down:

CL-USER> (let ((bar (list 1 2 3)))
           (testing-loop bar))

which throws undefined variable: BAR

I expected testing-loop to macroexpand into the lexical scope where bar is bound?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T10:54:00+00:00Added an answer on May 29, 2026 at 10:54 am

    @mck, I see why you want to use eval now. But it’s a very messy solution, and slow, as I mentioned in my answer to the previous question. The classic On Lisp says this about eval:

    “Generally it is not a good idea to call eval at runtime, for two reasons:

    1. It’s inefficient: eval is handed a raw list, and either has to compile it on the
      spot, or evaluate it in an interpreter. Either way is slower than compiling
      the code beforehand, and just calling it.

    2. It’s less powerful, because the expression is evaluated with no lexical context.
      Among other things, this means that you can’t refer to ordinary
      variables visible outside the expression being evaluated.

    Usually, calling eval explicitly is like buying something in an airport gift-shop.
    Having waited till the last moment, you have to pay high prices for a limited
    selection of second-rate goods.”

    In this case the simplest thing is just to:

    (defmacro testing-loop (var)
      (let ((g (gensym)))
       `(let ((,g ,var))
          (if (consp ,g)
            (loop for x from 0 to 5 collect x)
            (loop for x from 0 to 5 and y in ,g collect y)))))
    

    I know you want to factor out the common loop for x from 0 to 5 (which isn’t actually needed in the second branch anyways). But loop is itself a macro which is converted at compile time to efficient, low level code. So the call to loop has to be built at compile time, using values which are available at compile time. You can’t just insert an (if) in there which is intended to be evaluated at run time.

    If you really don’t want to repeat loop for x from 0 to 5, you could do something like:

    (let ((a '(loop for x from 0 to 5)))
      `(if (consp ,var)
           (,@a collect x)
           (,@a and y in ,var collect y)))
    

    That’s just to give you the idea; if you really do this, make sure to gensym!

    A good lesson to learn from this is: when you are writing macros, you need to keep clearly in mind what is happening at compile time and what is happening at run time. The macro you wrote with eval compiles the loop macro dynamically, every time it is run, based on the return value of consp. You really want to compile the 2 different loop macros once, and just select the correct one at run-time.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This question is related to another question of mine. Thanks to some help I
This is a related question to one I posted earlier... I'm trying to sum
Some of this question is related to JPA, but it's more about approaches than
I believe this question is related to this one also, since I'm trying to
This question is closely related to Jquery - Send only some value from a
I've look for this, and there's some related questions, but no one gives me
All my questions in this topic related to asp.net 2.0 While working on some
This question is an extension of this Related question . Taking Derick's advice, I
I found this related question: How do I use composition with inheritance? I would
I have searched here, GooBingHooVista'd the world and read this related question for VS

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.