In this article, Cédric Beust explains how to port a RPN calculator from Haskell to Fantom. It could have made me want to code more in Haskell or go discover Fantom. Not at all. Reading the article, I felt the urge to code the same algorithm with Ioke. You know, this language I discovered through a MasterMind Kata a while ago.

Here is the Fantom code:

```
foldingFunction := | Int[] n, Str p -> Int[] | {
echo("n:" + n)
switch(p) {
case "*" : return n.push(n.pop * n.pop)
case "+" : return n.push(n.pop + n.pop)
case "-" : return n.push(n.pop - n.pop)
case "/" : return n.push(n.pop / n.pop)
default: return n.push(p.toInt)
}
};
"8 1 2 + 5 * +".split.reduce([,], foldingFunction)
```

Here is my first try with Ioke:

```
rpn=method(sum, x,
case(x,
"+", [sum pop! + sum pop!],
"*", [sum pop! * sum pop!],
"-", [sum pop! - sum pop!],
"/", [sum pop! / sum pop!],
[x toRational]
) + sum
)
"8 1 2 + 5 * +" split fold([], sum, x, rpn(sum, x)) println
```

Quite neat. The code looks a lot like the Fantom code or even the Haskell code/

Now let’s use the power of Ioke and remove duplication by defining *rpn* method on *List* itself :

```
List rpn = method(x,
append!(case(x,
"+", pop! + pop!,
"*", pop! * pop!,
"-", pop! - pop!,
"/", pop! / pop!,
x toRational
)
)
)
"8 1 2 + 5 * +" split prepend!([]) fold(rpn) println
```

I like that one better. We could remove some more duplication at the expense of readability, because, you know, there must be another way to convert “+” to , “*” to * and “-” to -:

```
List rpn = method(x,
append!(case(x,
or("+","*","-","/"), Message fromText(x) appendArgument(pop!) sendTo(pop!),
x toRational
))
)
```

Here we used reflection, but we could use eval method and regexp:

```
List rpn = method(x,
append!(if(x !~(#/[-+*/]/),x toRational,Origin eval("#{s pop!}#{x}#{s pop!}))
)
"8 1 2 + 5 * +" split prepend!([]) fold(rpn) println
```

Ok, now let’s try to recall those days I was an expert in Perl, and compress this to the max:

```
r=fn(e,e split fold([],s,x,s append!(if(x !~(#/[-+*/]/), x toRational,
Origin eval("#{s pop!}#{x}#{s pop!}")))))
r("8 1 2 + 5 * +") println
```

This one, I’m not really proud of. Should I?

Note that you seem to be using an imperative style. The point of the exercise in Fantom and Haskell was to compare their fold/reduce capacities. I’m not sure if Ioke supports fold(?).

—

Cédric

Hi Cédric. Not sure I understand your question. I use Ioke’s fold method on List in every code sample. Also the code doesn’t seem imperative style to me. Can you elaborate?

David.

My bad, David, I was looking for the fold in the wrong place.