Subscribe to The Madman Scribblings        RSS Feed
-----

[Nemerle] Creating an IF statement with an optional Else.

Icon 1 Comments
When I set out to create this macro, after having a couple of issues with the current if.
If( condition ){ truth statement }else{ falsehood statement }



  • In Nemerle an If statement always require an else.
    Which you don't always want to have to include.
  • Is that when returns a the void literal on false.
    Which can mean the Truth part have a different return type to the False. (Not Allowed)
    Also mean it can't be used mid expression like the If


nf Macro

nf( expression that evaluate to a bool){ what to return on true. }

using Nemerle;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;
using Nemerle.Compiler;
using Nemerle.Compiler.Typedtree;
using Nemerle.Macros;



namespace MacroLibrary1
{
  public macro nf(nf_pred,nf_truth) 
  syntax ("nf","(",nf_pred,")",nf_truth)
  {
       <[ 
    if($nf_pred==true){$nf_truth}
    else{ $(Typedtree.TExpr.DefaultValue() : typed)}
   ]>
  }

}




Ok so now I have a if statement that return the default value, on the condition be false.

The xf Macro
So can the else part of an if-statement be made conditional?

    public macro xf(xf_pred,xf_truth,nf_false) 
    syntax ("xf","(",xf_pred,")",xf_truth,Optional("else",nf_false))
  {
    def fx=if(nf_false==null){<[$(Typedtree.TExpr.DefaultValue() : typed)]>}
           else{nf_false};
      <[ 
    if($xf_pred==true){$xf_truth}
    else{$fx}
  ]>

  }




The mf Macro

Now I have an If-Statement with and optional Else, let rewrite it using a different "core" conditional - match
public macro mf(mf_pred,mf_truth,mf_false) 
  syntax ("mf","(",mf_pred,")",mf_truth,Optional("else",mf_false))
  {
  def fx=match(mf_false){
          | null  => <[$(Typedtree.TExpr.DefaultValue() : typed)]>
          | _     => <[$mf_false]>
  };
   <[
   match ($mf_pred){
     | true       => $mf_truth
     | _          => $fx                 
    }
 ]>  

  }




Usage Example
99 Bottles of Beer

using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;

using Conditional_Marco;

module Program
{
  Main() : void
   {
  
def songVerse = x=>{
def BottlesOfBeer= x=> $"$(mf(x==0)\"No more\" else{x.ToString()}) Bottle$(mf(x!=1)\"s\") of beer";
WriteLine(
$<#$(BottlesOfBeer(x)) on the wall, $(BottlesOfBeer(x)).
$(mf(x>0)"Take one down, Pass it around."else"Goto the shop and buy some more.")
$(BottlesOfBeer(mf(x==0) 99 else x-1)) on the wall.
    
#>)};
  $[0..99].Rev().Iter(x=>songVerse(x));
 _ReadLine()
}
}



Pluralising bottles Bottle$(mf(x!=1)\"s\").

1 Comments On This Entry

Page 1 of 1

skorned Icon

16 February 2011 - 10:42 AM
The English in the part below isn't quite clear.

Quote

Is that when returns a the void literal on false.
Which can mean the Truth part have a different return type to the False. (Not Allowed)
Also mean it can't be used mid expression like the If
0
Page 1 of 1

Search My Blog

Recent Entries

Recent Comments