backquote substitution not working as intended
A Logo programming environment for Microsoft Windows
Brought to you by:
david_costanzo
I'm reading the UCBLogo user manual (I think the english version of the FMSLogo manual has similar wording):
Backquotes can be nested. Substitution is done only for commas at the same depth as the backquote in which they are found:
SHOW `[a `[b ,[1+2] ,[foo ,[1+3] d] e] f]
[a ` [b , [1+2] , [foo 4 d] e] f]
It seems to me that only the inner most comma was resolved, which was not at the same depth as the backquotes.
I think this not supposed to happen:
show `[,pos]
[[0 0]]
show `[[,pos]]
[[[0 0]]]
show `[[[,pos]]]
[[[[0 0]]]]
show `[[[[,pos]]]]
[[[[[0 0]]]]]
I think I reported this already as a bug, but can't find it here.
I asked the same question to the GitHub had hosts the newest version of UCBLogo here:
https://github.com/jrincayc/ucblogo-code/discussions/111
I had asked this same question in 2014 to Brian Harvey who seemed to believe it was a bug but it seems he didn't have time to fix it.
Readying the rest of the discussion in github makes me think this might not be a bug. Still the documentation is confusing, specially regarding nesting of backquotes.
Hah. So I guess that obtuse example came from the scheme manual.
I agree that the documentation is unclear and the examples are not self-evident. I don't remember any discussion about nesting levels of commas, but I do remember discussing that the examples don't really enlighten.
Is the Scheme documentation any better?
My (copyrighted) ANSI CLISP manual's Appendix D offers a different way to understand it: if the expression is well-formed, only the innermost commas are substituted.
The CLISP manual (copyleft) suggests that backtick is most important when defining macros in LISP, which are very different from macros in UCBLogo. Maybe that's why the backtick is only used one in all of logolib.
I can't think of a clear example which shows the value of the nesting behavior. I think it would need to be some partial evaluation where the output is later RUN so that the inner backticks are evaluated at a later time.
I'll see what I can do about making the documentation clearer, but it might be that the only thing I can do is dissect the examples.
This all came about for me when I was trying to solve this puzzle
In A802 x A = 5B61B. What is the value of B? Given that A and B are digits from 0-9
So, for A=2 and B=9 I constructed this
And then, after some trial and error I got this:
which does have a nested backquotes
Interesting. My immediate thought was to use algebra to solve for B and then write a function for it:
Then try all values of :A from 0-9 until I found an integer, perhaps with
MAPandISEQ. This has the drawback of obscuring the question asked by the puzzle to the point where it's not recognizable in FINDB. I would never have thought to use backtick to build a Logo predicate.For backtick, I tried to write something that makes
SETPC [:red :green :blue]work, but I wasn't able to figure it out. The only thing I figured out is that I want the example to use.MACROso that the output from backtick is automatically RUN.Here is another version of the macro without reduce
Nice. I think you're on the right path. Maybe all useful nested backtick instructions use
,@. I didn't think to use that when I failed with my SETPENCOLOR toy.I'm with you: the definition of how nested backticks works seems awkward if you're always going to proceed them with
,@. Why wouldn't it just replace at all levels? There's got to a good reason for the way it's defined, but it's beyond me.As I went to update the documentation, I realized that your latest refinement could be written without nested backticks:
While this looks simpler to me, it took several iterations to arrive at it, so the nested backticks were still useful.
It never occurred to me that that leaving :a and :b not prepended with the comma could work. But now that I see it, it makes sense.
Something like this?
No, I was trying for a replacement of SETPC that used nested backticks without the caller ever seeing a backtick. I was thinking that, with the right backtick usage, I could get the word
:rout of[:r :g :b], evaluate it, then pass the clean list to SETPENCOLOR. In retrospect, I think my approach was wrong. Instead of forcing the use of backticks to do something, I should really at existing code for situations for where using backticks makes things simpler. That's what I really want out of backtick documentation...something that shows where backtick is desirable, not just functionally correct.For the example you listed above, you've previously written that you prefer:
to:
I was hoping to enable
I have tried to clarify the behavior of backquote and improve the examples. This was done with [r5771].
When doing research on how to update the documentation, I realized that I neither understood your original post nor Brian Harvey's response.
The key to understanding nested backquotes is that there are three types of nesting: nested lists, nested backquotes, and nested substitution. The first one, which is what you thought mattered has nothing to do with backquote nesting (a backquote always replaces at all levels in its list input). What matters is the nesting of backquotes and the nesting of substitution expressions (see the new documentation for a walkthrough).
I wasn't able to find and good documentation on nested backquotes for scheme or LISP on the Web. I did find one comment in the CLISP cookbook about it being defined in a useless way and a refusal to expound more on it. It might be that no one understands it well. I still can't think of any useful application in FMSLogo, even in the context of partial evaluation which seems like it should be a natural fit. I suspect that LISP has some extra language features that FMSLogo doesn't have which make nesting backquotes usable in limited circumstances in LISP. However, I also wasn't able to find any examples that showed an effective use of nested backquotes in LISP.
In the end, I documented the behavior of nested backquotes and recommended to avoid them.
After having done all of this, I now have one more update to make to your puzzle:
Note that the space between
,:band the last)is very important.Related
Commit: [r5771]
Diff:
I have attached a private build of FMSLogo which includes the documentation update.