Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SYNTAX: missing as default value

    Dear All!

    How do I specify a missing value as the default value for an optional numeric option in the syntax declaration?

    For example, consider the following code:
    Code:
    clear all
    
    program define listsome
       version 16.0
       syntax varname, [maxval(real .)]
       
       list `varlist' if `varlist'<`maxval'   
    end
    
    program define listsome2
       version 16.0
       syntax varname, [maxval(real -999999)]
       if (`maxval'==-999999) local maxval=.
       
       list `varlist' if `varlist'<`maxval'   
    end
    
    sysuse auto
    listsome2 price   // works, but clumsy implementation
    listsome price    // doesn't work => Error 197: Invalid syntax
    
    // end of file
    I don't see a reason why a missing value may not be declared as a default value. I understand that the behavior corresponds to the documentation as outlined in the section "option descriptor optional real value" of the help to syntax. But I don't understand why this behavior was chosen, not permitting numeric defaults. (Same applies to .a, .b, ..., .z - all missing values).

    Either code works if the missing value is passed as the option's value:
    Code:
    listsome price, maxval(.)
    listsome2 price, maxval(.)
    So, is there a more comfortable implementation of listsome avoiding a special value like is shown in listsome2?

    Thank you, Sergiy

  • #2
    This is a one approach.
    Code:
       syntax varname, [maxval(string)]
       local maxval = real("`maxval'")

    Comment


    • #3
      Another way to do it


      Code:
      program whatever 
         syntax , [maxval(numlist max=1)]
         if "`maxval'" == "" local maxval = . 
         di "`maxval'"
      end

      Comment


      • #4
        Dear Nick, William,

        thank you very much for responding to the question.
        Both solutions are an improvement over mine as they avoid using a special value.

        I personally favor Nick Cox 's solution since it appropriately stops with errors on invalid option content, rather than assuming it is a missing value, such as demonstrated by the test code below. I have added just a tiny bit of option missingok to permit the missing value not only to be default, but also to be specified directly by the external caller.

        Still, it seems that any solution to this problem will involve at least one additional line of code after the syntax for every such parameter (which is not much when I have 4-10 such parameters, but may become tedious when you have more - forgetting one may result in a difficult to catch bug).

        If anyone can figure out a solution that solely fits the syntax statement, I would be interested to see/hear it.

        Thank you, Sergiy Radyakin

        Code:
        capture program drop whatever
        program whatever, rclass 
           // Nick's solution:
           syntax , [maxval(numlist max=1 missingok)]
           if "`maxval'" == "" local maxval = .
           
           // William's solution:
           //syntax , [maxval(string)]
           //local maxval = real("`maxval'")
           
           display "`maxval'"
           return scalar v=`maxval' // solely for testing purposes
        end
        
        // UNIT TESTS FOLLOW:
        
        // check the default value is a missing
        whatever
        assert r(v)==.
        
        // check a missing value is accepted:
        whatever , maxval(.)
        assert r(v)==.
        
        // check an extended missing value is accepted:
        whatever , maxval(.z)
        assert r(v)==.z
        
        // check an integer number is accepted:
        whatever , maxval(-33)
        assert r(v)==-33
        
        // check a floating point number is accepted:
        whatever , maxval(3.3)
        assert r(v)==3.3
        
        // check a string value is rejected:
        capture noisily whatever , maxval("abc") // error 121
        assert _rc==121
        
        // check a list of multiple elements is rejected:
        capture noisily whatever , maxval(1(1)2) // error 123
        assert _rc==123
        
        display as text "End of tests"

        Comment

        Working...
        X