BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Quentin
Super User

Hi @novinosrin .  I'm struggling to understand your question.  (I'm not at all opposed to asking such questions out of curiosity).

 

Is it whether a null statement is useful?  Do the docs really claim that it's useful, or simply that it is allowed?  I like that it's allowed, but I don't often find it useful

 

Is the question "what happens in the machine code when I compile a step with a null statement?" Here I don't know, and unless it would be shown that there were tremendous efficiency impacts, wouldn't care too much.  Which doesn't mean it's not a fair question.

 

 

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
novinosrin
Tourmaline | Level 20

Thank you Sir @Quentin  for chiming in. 

 

Yes, that's a better way to describe it. The docs says

1. "Although the Null statement performs no action, it is an executable statement. Therefore, a label can precede the Null statement, or you can use it in conditional processing."[ examples to understand this statement in a meaningful is wanted ]

 

2. "The Null statement is useful while you are developing a program"[ The one example in the docs seems very inadequate to me]

 

Now going beyond the docs to comprehend better, I was thinking if I could understand in what sense the tokenization of the null statement is done by the compiler before the compiled code gets executed would help me figure out something. Also, in an open code, the meaning seems very hazy regardless of any intuition the null statement in a datastep would provide. 

Quentin
Super User

Hi,

 

Taking it in parts:

 


@novinosrin wrote:

Yes, that's a better way to describe it. The docs says

1. "Although the Null statement performs no action, it is an executable statement. Therefore, a label can precede the Null statement, or you can use it in conditional processing."[ examples to understand this statement in a meaningful is wanted ]

 

 

I think you already had an example of null statement being useful in conditional processing.  For example, I might code:

 

  if unit='inches' then height=height*2.54 ;
  else if unit='cm' then ; *do nothing cuz already in cm ;
  else put "ER" "ROR: (USER) " "unexpected unit!" unit= ;

 

 

That second statement works because SAS doesn't mind a null statement.  I suppose if SAS didn't accept a null statement I could do something like:

 

  if unit='inches' then height=height*2.54 ;
  else if unit='cm' then do ; end ; *do nothing cuz already in cm ;
  else put "ER" "ROR: (USER) " "bad unit!" unit= ;

 

So that has any empty do block with no statements in it, but is not actually a null statement (as per documentation; they may very well compile to the same byte code).

 

As for labels, if you look in the documentation on label: statement, it has more examples. I don't use the label statement much (ever?) in DATA step, but consider:

 

 

*list the female students ;
data want ;
  set sashelp.class ;
  if sex='M' then goto end;
  
  put (name sex)(=) ;

  end: ; *null statement;
run ;

The docs say END: is a label pointing to a null statement.  The docs say that the label: statement needs to point to a statement and end with a semicolon (like any other statement), so allowing a null statement before the semicolon is useful.  Allowing a null statement avoids the need to do something silly like:

 

 

*list the female students ;
data want ;
  set sashelp.class ;
  if sex='M' then goto end;
  
  put (name sex)(=) ;

  end: foo=1; *non-null statement;
run ;

That said, below code works (perhaps the label points to the RUN statement?):

 

 

data want ;
  set sashelp.class ;
  if sex='M' then goto end;
  
  put (name sex)(=) ;

  end: 
run ;

 

 

And so does the below, which doesn't have a statement after the label (other than an implied run):

 

data want ;
  set sashelp.class ;
  if sex='M' then goto end;
  
  put (name sex)(=) ;

  end: 

data foo ;
run ;

 

 

2. "The Null statement is useful while you are developing a program"[ The one example in the docs seems very inadequate to me]

 

I can imagine it might feel more useful if GOTO was more popular.  As in the example, you could have some rare condition you don't want to handle yet, and say:

 

data want ;
set have ; if condition then goto handler ; return ; handler: ; run ;

 

 

And you could write the handler section later.  I've never wanted to do that, but I think that's the case they're making.

 

Or I suppose with the conditional example, could code:

 

 

  if x=1 then y=1 ;
  else if x=2 then y=22 ;
  else if x=3 then /*do not know what to do yet, fill me in later*/ ;
else put "ERROR: bad value";

 

 

I don't know if there is too much to worry about in the tokenization of a null statement.  But I agree, the concept of a compiled/executable null statement in a data step would have a different "meaning" then a null statement in open code or proc step where it is interpreted rather than compiled.

 

Within the BASE SAS language, I've never seen a null statement cause a problem or anything interesting of note.  Well, here's one.   I suppose a null statement can "break" a code block, but that seems fair:

 

54   data _null_ ;
55     if sex='M' then foo=1;
56     ;
57     else if sex='F' then foo=2;
       ----
       160
ERROR 160-185: No matching IF-THEN clause.

58   run ;

NOTE: The SAS System stopped processing this step because of errors.

I suppose that is evidence that the data step compiler does not simply skip null statements, it sees them enough to break compilation.

 

 

In the macro language, a null SAS language statement can cause problems, as discussed.

 

Kind Regards,

--Q.

 

 

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
novinosrin
Tourmaline | Level 20

@Quentin  Ah finally a reason to have a pint tonight on the way home. It appears the examples are more aligned with programming styles from the days of yore i.e if i comprehend that style is akin to block-> break-> link,->jump or return if goto. Sighs 

 

I owe you a pint if i ever visit my headquarters in johnston, ri. Thank you for your time 🙂  Much appreciate it!

Quentin
Super User

@novinosrin wrote:

I owe you a pint if i ever visit my headquarters in johnston, ri. Thank you for your time 🙂  Much appreciate it!


 

Hmm, SAS jobs in Rhode Island are few and far between.  I may send you a side message....

 

Well if you never make it to little Rhody, hoping to maybe see you and many other online SAS friends at SGF in DC in 2020!

 

-Q.

 

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
Shmuel
Garnet | Level 18

I'm not sure this is the answer you are looking for.

 

As for your first question I think that next code illustrates a null statement:

if <condition> then ;  /* null statement */
else do;
   ...
end;

sometimes it fits way of thinking or emphasizes that the situation was not skipped.

 

As for your 2nd question:

In the early 1980 I remember I was using CARDS only.

Maybe DATALINES and LINES were added later.

novinosrin
Tourmaline | Level 20

Thank you Sir. Can you really illustrate the IF THEN ;;;; with a practical example plz. How, why , when and what scenarios plz

Shmuel
Garnet | Level 18

@novinosrin wrote:

Thank you Sir. Can you really illustrate the IF THEN ;;;; with a practical example plz. How, why , when and what scenarios plz


When you have a many conditions it is easy to build a decisions table, like:

C stands for condition in next table:

C1    C2     C3  ....  Cn    exec
 0       0       0                   nothing (not available)
 0       0       1                    ex1
 0       1       0                    ex2
 ....
 1       1       1                   nothing 

In such case I want to cover and code all combinations of the conditions, while some of then need no action

or I believe they are not available or I have no such data and cannot decide what to do - in such case a NULL statement

may be used. 

Quentin
Super User

My favorite null statement to avoid (and perhaps the most common observed) is:

%macrocall(foo);

That semicolon is NOT part of the macro language.  The final parenthesis ends the macro invocation and the macro executes.  The semicolon is an extra null statement in the SAS language. 

 

When you've got function-style macros that are designed to return part of a SAS statement, accidental generation of null SAS statements can cause all kinds of headaches.

 

That said,  a lot of macro programmers like to end their macro calls with semicolons, even though they know they're introducing null statements.

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
hashman
Ammonite | Level 13

@Quentin:

Quentin, like you, I've learned from Ian that coding something that serves no function should be avoided for two reasons: (1) it may lead to an error and (2) to a confusion. The semicolon after a macro is one of those, and it falls in both categories. A period after a macro reference "just in case" is another, though it falls just into category #2.

 

Kind regards

Paul D.

SASKiwi
PROC Star

@novinosrin  - My recollection is that the CARDS statement came first to SAS and it was originally restricted to 80 byte / char records, analogous to punched card input. DATALINES / LINES was added later to allow greater than 80 byte records. Now the CARDS and DATALINES statements behave exactly the same and whether greater than 80 byte records is allowed is controlled by the CARDIMAGE SAS option:

https://documentation.sas.com/?docsetId=lestmtsref&docsetTarget=p0114gachtut3nn1and4ap8ke9nf.htm&doc...

Tom
Super User Tom
Super User

 SAS statements end with a semi-colon. A "null statement" is just a free floating semi-colon. They are GLOBAL because they can appear outside of a PROC or DATA step (or inside either a PROC or a data STEP).

ChrisNZ
Tourmaline | Level 20

> Is the use of alias just to remove the yellow color patch on the datalines?

 

The color parser is not always right and makes mistakes.

These statement are the same (read @SASKiwi 's comment). Don't rely on the color parser to tell you what syntax is right, even if most times it helps.

Kurt_Bremser
Super User

Why is a null statement considered executable? Think of  this:

select (gender);
  when ('M') put "this is a male";
  when ('F') put "this is a female";
  otherwise; /* null statement */
end;

The select() block needs a branch for every situation resulting of what's in the select() statement (or it will throw an ERROR), so it executes the null statement following the otherwise keyword.

novinosrin
Tourmaline | Level 20

Sir Good morning, While it's nice to note your creative thinking, I am just seeking absolute clarity on the null statement(; or ;;;;  ) as executable stand alone in its own right as claimed by the docs. An executable global statement valid anywhere be it in open code or a datastep/proc construct doesn't seem convincing yet.

 

@ Everyone, To go further, what token would a null statement be? Would it be a special token, text(name token), or just a place holder text. How does the compiler see and do what is been instructed? Then of course at execution time we can deal with it accordingly if we know what does it execute Smiley Sad

 

 


@Kurt_Bremser wrote:

Why is a null statement considered executable? Think of  this:

select (gender);
  when ('M') put "this is a male";
  when ('F') put "this is a female";
  otherwise; /* null statement */
end;

The select() block needs a branch for every situation resulting of what's in the select() statement (or it will throw an ERROR), so it executes the null statement following the otherwise keyword.


 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 31 replies
  • 2011 views
  • 15 likes
  • 10 in conversation