LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (May 2006, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Fri, 26 May 2006 17:21:58 +0000
Reply-To:     toby dunn <tobydunn@HOTMAIL.COM>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         toby dunn <tobydunn@HOTMAIL.COM>
Subject:      Re: enterprise guide peculiarities - %str()
Comments: To: iw1junk@comcast.net
In-Reply-To:  <052620061644.18051.4477305F0008F2D700004683220073483005029A06CE9907@comcast.net>
Content-Type: text/plain; format=flowed

Ian ,

Okay I can live with the explaination so far. We havent had a spirited round of posts in quit some time. Kind of refreshing even if you do end up kick me all over the SAS-L school yard. But then I wouldnt expect my 7 years of programming experience to hold up to your 20 or 30 years. So I get to learn something and I hope others do too.

I will make one comment here you stated:

NO! That is the mistake. You told the macro facility to hide the meaning of the slash as divide in arithmetic expressions. You did not tell it to change the symbol and you can find nothing in the documentation that would even hint that is what you did.

Well actually the online docs do talk about this under the section "How Macro Quoting Works".

/*Snippet*/ When the macro processor masks a text string, it masks special characters and mnemonics within the coding scheme, and prefixes and suffixes the string with a hexadecimal character, called a delta character. The prefix character marks the beginning of the string and also indicates what type of macro quoting is to be applied to the string. The suffix character marks the end of the string. The prefix and suffix characters preserve any leading and trailing blanks contained by the string. The hexadecimal characters used to mask special characters and mnemonics and those used for the prefix and suffix characters may vary and are not portable.

There are more hexadecimal combinations possible in each byte than are needed to represent the symbols on a keyboard. Therefore, when a macro quoting function recognizes an item to be masked, the macro processor uses a previously unused hexadecimal combination for the prefix and suffix characters.

Macro functions, such as %EVAL and %SUBSTR, ignore the prefix and suffix characters. Therefore, the prefix and suffix characters do not affect comparisons.

When the macro processor is finished with a macro quoted text string, it removes the macro quoting-coded substitute characters and replaces them with the original characters. The unmasked characters are passed on to the rest of the system. /*Snippet End*/

As a secondary thind to note a lady from SI (I dont have the paper in front of me wrote about macro quoting) which covers the physical act of quoting.

So did I tell it to change the character? One could say that it is implict when I choose to use the quoting function. But to say that is to say that I know how SAS is physically masking the meaning of the characters when quoting is used and ignoring what the intent of masking. Now whether or not you agree with that statement is another story.

Toby Dunn

From: iw1junk@comcast.net To: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> CC: toby dunn <tobydunn@HOTMAIL.COM> Subject: Re: enterprise guide peculiarities - %str() Date: Fri, 26 May 2006 16:44:16 +0000

Toby, I will embed comments your message below. Ian Whitlock

Date: Fri, 26 May 2006 04:01:20 +0000 Reply-To: toby dunn <tobydunn@HOTMAIL.COM> Sender: "SAS(r) Discussion" From: toby dunn <tobydunn@HOTMAIL.COM> Subject: Re: enterprise guide peculiarities - %str() Comments: To: iw1junk@COMCAST.NET In-Reply-To: <052620060122.20439.4476584F000C067000004FD7220730003305029A06CE9 907@comcast.net> Content-Type: text/plain; format=flowed Ian , I think you read a little more into some of what I wrote than I intended. Guess that is what i get for not writing a book as I normally do. The first problem you noted was truelly an error on my part for thinking one thing and writing another, then not double checking what I wrote close enough. I actually forced the error you mentioned before I wrote the post, just as a sanity check for myself. The use of %bquote was just something I threw in for giggles. *****Ian I consider the use of %BQUOTE in open code to act like a compile time quoting function a serious offense because when adopted by someone not fully understanding the consequences they can get mysterious macro compile time errors. Now you say that you do it for giggles! Did you get a degree in psychology by any chance? ***** I could have just as easily put %str(), but then again you already know that. *****Ian The point not that you could have easily used %STR(), but that it should have been very hard for you to use %BQUOTE() in this example. ***** Nice explaination of the %eval and the use of quotes. However, I think my true quable here is getting lost.

You once said (forgive me if I mangle this) that in the data step language words have meaning and as such we as programmers have to distinguish between what we want SAS to interprete as having meaning and what we dont. So we put quotes around those words that we dont want SAS to interprete as haveing meaning. The macro language is somewhat different, in that everything is text and we as SAS programmers give meaning to words by prefixing them with &'s and %'s. *****Ian Except for typos and perhaps understanding, it looks reasonably close to something I have said. The intent was to consider two distinct languages, SAS and macro. In SAS the data is usually external to the language, hence quoting is only needed for the odd bits of character data that may appear inside SAS code. The system is common to many languages that make the same assumption that data is generally external to the code. In contrast, macro is a language in which the data (SAS code) is integrally part of the macro program. Hence it is the programming instructions that are distinguished rather than the data. Percent signs and ampersands are used to distinguish some macro instructions but there are other forms of text that also have meaning. For example, in %do i = 1 %to &fini + 1 ; the "+ 1" has meaning. On the other hand, in %let x = &fini + 1 ; the "+ 1" has no meaning. Consequently it is important to know the context and the time (i.e. macro compile, macro execute, SAS compile, SAS execute) in order to make precise statements of what symbols have meaning to whom when. ***** ( there is more meaning in those statements than one at first thinks and I still ponder those words today). However, this & and % business raises a problem in that sometimes we want the &'s and %'s to be interpreted by the macro facility as just text. *****Ian True and that means when we write an & we mean it to be the symbol &. If the macro facility chooses to store that symbol some other way, it still should treat that symbol as an &. That is the point I was trying to make in the message below and that is the point that you seem to have overlooked. The fact that macro uses "010F02" to store the instruction %NRSTR(&) gives you no right to expect that the symbol to be manipulated is not an ampersand! In fact, if your wish were true macro quoting would be completely useless. I note that nowhere in the documentation will you find a statement of how %NRSTR(&) is stored since it is not the programmer's business. Moreover, I assume that SI feels free to change this internal method of accomplishing this task at any time. Hence you would be very unwise to try and make use of it in any macro code that you wish to work with. In short, you seem to have interpreted the words "just text" (I suspect that I use "just data") in some absolute manner without regard to the fact that I was talking about programming and that as a programmer, when I write %put %nrstr(&) ; I expect to see an ampersand and not some dump from memory. ***** Thus, arise the need for macro quoting. Now if I quote some macro value I as the programmer have specifically told SAS not to interpret those as having significant meaning to the macro facility. In otherwords forget any possible meaning for these characters other than as just text. Programmatically this can be some what tricky to implement, so SI decided when quoting is used it would change the underlying value of the characters to be quoted to a non- printable character.

So when we get to the %eval I was thinking it did a literal character by character comparison of the underlying value in each expression. *****Ian Yes, it does compare character by character, the "underlying value" rather than the internal means of referencing that "underlying value". Now take a moment to ponder on wisdom of not choosing to insist that you know every intenal detail of how your code is executed before allowing you to use SAS. ***** But if it did that then the example of %put %eval( "/" = "&Y" ) ; would evaluate to a false statement. Because the underlying value of a '/' would be different than the value on the right hand side of the equals sign which is a nonprintable character. However, if it translated the nonprntable characters of 'Y' back to a '/' (in some fashion) in this case then it would it would evaluate to a true statement. This in some way irks me as I explicitly told SAS to change the value of '/' to a non printable character when I told it to quote the string *****Ian NO! That is the mistake. You told the macro facility to hide the meaning of the slash as divide in arithmetic expressions. You did not tell it to change the symbol and you can find nothing in the documentation that would even hint that is what you did. Well, you are not the first "programmer" to not understand what he did with some piece of code. Incidentally, the use of '"programmer"' in the previous sentence is completely different from and not to be confused with quoting the word "programmer", which I didn't quote in the last part of this sentence. ***** and I havent yet at the time of the %eval told it to unquote the string and translate it back to the '/'. ***** That is also wrong. To be precise, you haven't told it to give the character back it's meaning in an arithmetic expression. But you did by reference explicitly ask that it be compared with a slash. ***** But this would lead to printing problems if it followed this philosophy making macro quoting more unwieldy, also it make for a higher user error rate. So %eval is attempting to use the quoted string in context, choosing to see the values as they would translate too rather than as they really are nonprintable characters. *****Ian I see nothing in what you have written to lead me to think that I have misinterpreted what you meant. As an exercise, write a simple macro that essentially uses macro quoting to accomplish something useful. Then analyse how many times in that code you should have been thankful that the language didn't work the way you thought it should. Here is a portion of a log to show that you can have what you want in SAS, while the rest of us can be thankful that it doesn't take less work. 80 %let x = %str(/) ; 81 data _null_ ; 82 set sashelp.vmacro ; 83 where name = "X" ; 84 if value ^= "/" then put "Toby is satisfied" ; 85 else put "Toby is irked" ; 86 test = symget ( "x" ) ; 87 if test = "/" then put "Programmers are satisfied" ; 88 else put "Programmers have a big problem" ; 89 put value= " %nrstr(&)x=&x " test= ; 90 run ; Toby is satisfied Programmers are satisfied value= &x=/ test=/ *****

Toby Dunn

From: Ian Whitlock <iw1junk@COMCAST.NET> Reply-To: iw1junk@COMCAST.NET To: SAS-L Subject: Re: enterprise guide peculiarities - %str() Date: Fri, 26 May 2006 01:22:24 +0000 Subject: Re: enterprise guide peculiarities - %str() Summary: Another subtlety of macro quoting is discussed Respondent: Ian Whitlock In part in answer to Paa K <sas.paa@GMAIL.COM> Toby Dunn <tobydunn@HOTMAIL.COM> a lot of errouneous information by writing in part the following: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Now what I was refering to is that when you put the quoted value inside of double quotes it acts atleast like the quoting is removed. 17 %let Y = %str(/) ; 18 19 %put %eval( %bquote(/) = &Y ) ; 1 20 %put %eval( "/" = &Y ) ; 0 21 %put %eval( "/" = "&Y" ) ; 1 The first %eval evaluates to a true value which makes perfect sense given I have the same value quoted on either side of the equals sign. But notice I did not suround the &Y with double quote marks. If the %str() macro quoting were removed then %eval would return a false statement. Now in the second %eval I get a false value. So even though the first slash is in double quote marks it isnt equal to the macro quoted value of &Y. In the last %eval I enclosed both sides in Double quotes. When I do that I get a true value. Which using inductive reasining shouldnt happen given the first two examples. Unless the macro quoting is removed when &Y is enclosed in the double quotes. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< We consider each of the three basic claims to explain the results produced by lines 19-21. In reference to line 19 Toby suggested that if the action of %STR were removed from the value of Y the result of the %EVAL would be false. It is wrong for two reasons. First consider: 9 %let Y = / ; 10 11 %put %eval( %bquote(/) = &Y ) ; ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: / = / We did not get false; we got a message saying that the request could not be handled. The problem is that when %EVAL sees an arithmetic operator it expects to do arithemtic and it couldn't. The second reason is more philosophical, since it involves what would happen if %EVAL didn't work the way it does, but it still is very important to understanding the way macro works. The expression %BQUOTE(/) and the expression / are the same because quoting removes the meaning, it does not change the symbol. The point is confused becasue the method of implementation does actually change the stored value, but the method of implementation does not change the logical circumstance that a symbol macro quoted or not it is logically the same symbol. SAS/macro treats it that way, and it is not a bug for SAS/macro to treat it that way. It is also worth remarking that had line 19 been in a macro the %BQUOTE functuion would not have hidden the /-mark at the time the %PUT statement was compiled. In this case it doesn't matter, but the habit of using %BQUOTE to hide typed symbols does matter because sometimes the distinction is important. In reference to line 20, Toby hints that there is some difference in symbols between a macro quoted /-mark and a macro unquoted /-mark that is causing the evaluation to false. This is not true. One must remember that double quote marks are part of the expression as well as indicators of quoting. Thus the reason line 20 produces a 0 is becasue the set of symbols to the left of the equal sing begin wht a double quote and the the set of sybols to the right does not. It has nothing to do with the nature of the /-mark. Another way to put it, is that the expression on the left is three characters and the expression on the right is one character which happens to match one of the lefthand characters, but that does not make the expressions equal. Now line 20 produces 1, i.e. true, becasue the expression on the left has three symbols (two double quotes and a /-mark) and the expression on the right also has the same three symbols. Here the confusion is compounded by the fact that meaning of the /-mark is hidden from %EVAL by two different techniques, but that is irrelevant to the conclusion that the marks on the left are the same as those on the right. In other words, lines 19 and 20 both produce a 1 for the same reason, a /-mark is a /-mark whether its meaning is hidden or not. Now to really confuse things, consider "/" = '/' In SAS code the logical expression is true because the quote marks are not part of the expressions (they are indicators of how to treat the objects contained between them) and the symbol inside is the same on both sides of the equaality. In macro the logical expression is false becasue single quotes and double quotes are different symbols. They hide, but they are also part of the expression. I hope that somebody is interested and helped by this explanation. Ian


Back to: Top of message | Previous page | Main SAS-L page