title: Simulate null parameters in Freemarker macros
body: <p>I'm building a site using Freemarker and have started heavily using macros.  I know in Freemarker 2.3 that passing a null value into a macro as a parameter is equivalent to not passing a parameter at all so I've created a global variable called &quot;null&quot; to simulate null checking in my macros:</p>
  <pre><code>&lt;#assign null=&quot;NUL&quot; /&gt;
  </code></pre>
  <p>Now in my macros I can do this:</p>
  <pre><code>&lt;#macro doSomething param1=null&gt;
    &lt;#if param1 != null&gt;
      &lt;div&gt;WIN!&lt;/div&gt;
    &lt;/#if&gt;
  &lt;/#macro&gt;
  </code></pre>
  <p>The problem comes if I want to pass a parameter that isn't a scalar. For instance, passing a List (which in Freemarker is a SimpleSequence) to a macro and checking against my null keyword yields the error:</p>
  <blockquote>
  <p>freemarker.template.TemplateException:
  The only legal comparisons are between
  two numbers, two strings, or two
  dates. Left  hand operand is a
  freemarker.template.SimpleSequence
  Right hand operand is a
  freemarker.template.SimpleScalar</p>
  </blockquote>
  <p>I took a look at the freemarker code and I can see the issue (ComparisonExpression.isTrue()):</p>
  <pre><code>if(ltm instanceof TemplateNumberModel &amp;&amp; rtm instanceof TemplateNumberModel) { 
    ...
  }
  else if(ltm instanceof TemplateDateModel &amp;&amp; rtm instanceof TemplateDateModel) {
    ...
  }
  else if(ltm instanceof TemplateScalarModel &amp;&amp; rtm instanceof TemplateScalarModel) {
    ...
  }
  else if(ltm instanceof TemplateBooleanModel &amp;&amp; rtm instanceof TemplateBooleanModel) {
    ...
  }
  // Here we handle compatibility issues
  else if(env.isClassicCompatible()) {
    ...
  }
  else {
    throw new TemplateException(&quot;The only legal comparisons...&quot;, env);
  }
  </code></pre>
  <p>So the only solution I can think of is to set isClassicCompatible to true, which I think will call toString() on both objects and compare the result.  However, the documentation specifically says anything relying on old features should be rewritten.</p>
  <p>My quesion is, is there a solution to this that doesn't rely on deprecated features?</p>