Hi Mark! On 7/21/19 4:56 AM, Mark H Weaver wrote: > Hi Zelphir, > > Zelphir Kaltstahl <zelphirkaltst...@posteo.de> writes: > >> At first I had the macro use `define`, but then I thought: "What if I >> want to conditionally define a route procedure?". My guess is, that then >> the define form would be inside some `cond` or `if` form and then it >> would not work > You're right, it would not work. Nonetheless, I would strongly > discourage you from doing this kind of thing unless there's a very > compelling reason for it.
To be honest there are not really any compelling reasons and I did think about such consequences that you mention below, only the thought of not being able to use the macro conditionally and wanting it to be usable everywhere and fear of possibly making a mistake later on in my code, trying to use it somewhere, where it cannot be used. However, now that I think about it, there might not be a real need inside that project after all, as the API route are predefined in the docker docs. > Note that we have 'cond-expand' from SRFI-0 for conditional inclusion of > definitions, if you need it. 'cond-expand' is roughly analogous to #if > in C. It's less general than plain 'if', but there's an important > reason for that, and it has to do with the distinction between compile > time and run time. Aha! I did not know that : ) I will read about the `cond-expand` in the SRFI 0. Thanks for mentioning SRFI 0. I guess I am still a little uneducated with regard to SRFIs and what they contain. Zero seems like an important number. > If you use 'cond-expand', the condition is checked at compile time, and > consequently it is known at compile time which branch was taken and > therefore which definitions were chosen. > > If you use 'cond', then the condition will be checked at run time, which > will normally rule out the possibility of optimization opportunities > such as inlining and partial evaluation. At present, Guile is not able > to perform these optimizations for toplevel level definitions in any > case, but it might be possible in the future, at least for modules that > are not explicitly mutated using low-level operations like this. > > Also, it's possible that a future version of Guile may be more > disciplined in its handling of phases, i.e. expand-time > (i.e. compile-time) vs run-time phases. See section 7.2 (Import and > export levels) of the R6RS for details on one approach, which would > bring many advantages. It's been a while since I looked at this > closely, and at this point I would need some time to refresh my memory > of the details, but it seems to me that the code you've written would > likely cause problems with such an approach. > > Both the R6RS and R7RS have more declarative module systems, which bring > many benefits. Added freedom in one area often implies a loss of > freedom somewhere else. In this case, the freedom to treat modules as > arbitrarily mutable objects implies a loss of freedom in the compiler to > make any assumptions about what's in the module or even its set of > bindings. That freedom carries a very significant cost. > > Mark Thank you for your explanations. That's great feedback! It seems asking on the Guile user list saved me again from doing something not so good in my code. I will improve my code accordingly then, either by making use of SRFI 0 or reverting to simple `define`, knowing that I can only use it at the top level of a module or top level of the scope where I want things to be available, as with normal `define` forms. … *goes and reads SRFI 0* … OK, so the limitations are, that `cond-expand` is restricted to the top level, unless Guile implements it differently. Not sure what kind of useful condition I can come up with inside the `cond-expand` and simply putting a `#t` seems silly. I guess it is really for checking things you can know at expand time. I do not have any such conditions in mind to check. Perhaps I will stick with normal `define` forms for now and just need to remember, that it will be expanded to a `define` form and thus needs to be used like one. Actually, that would still make it possible to return the created procedures and then I could still conditionally return another procedure instead, so it is still somewhat flexible. Regards, Zelphir