I think this matches the Haskell semantics pretty closely, so now, I was wondering what would be a more idiomatic way of implementing this in Fantom...
Suggestions?
mslMon 2 Aug 2010
Given you're looking at a stack, I'd prefer push and pop over insert, removeAt and addAll.
My take (not much different to yours):
calc := ["8", "1", "2", "+", "5", "*", "+"]
sum := calc.reduce([,]) |Int[] n, Str p -> Int[]| {
// if (p.isNum) { // I wish
if (p.isAlphaNum && !p.isAlpha) {
return n.push(Int(p))
}
else {
// return n.push(n.pop.trap(p, [n.pop])) // I Wish
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)
}
return n
}
}
echo(sum)
Raises a couple of interesting questions:
Why no is there no Str#isNumeric?
Would be super nice for the default implementation of sys::Obj.trap to handle the language provided shortcuts (sugar), so you could get the stuff in docLang::Expressions.shortcuts and remove the switch altogether.
mslMon 2 Aug 2010
Raises a couple of interesting questions
I'm the first to admit that they're probably not really that interesting at all ;)
brianMon 2 Aug 2010
I think this matches the Haskell semantics pretty closely, so now, I was wondering what would be a more idiomatic way of implementing this in Fantom...
Looks good to me. I concur with msl, I'd use push/pop.
cbeustMon 2 Aug 2010
I was using push() and pop() initially until I noticed that they both work at the end of the list, not at the beginning, which was a bit counterintuitive to me.
I agree the code is a bit cleaner, though:
echo(["8", "1", "2", "+", "5", "*", "+"].reduce([,], | 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())
default: return n.push(p.toInt)
}
}))
brianMon 2 Aug 2010
I was using push() and pop() initially until I noticed that they both work at the end of the list, not at the beginning, which was a bit counterintuitive to me.
List is actually backed by an array in the JVM, so definitely more efficient to push/pop at the end (versus a more functional linked list backing store).
Also by convention, we typically leave off the () of method calls which don't take any parameters. See Conventions.
ivanMon 2 Aug 2010
my 50 cents, single expression version (works in fansh :):
cbeust Mon 2 Aug 2010
Hi everyone,
I'm porting a few short Haskell programs to Fantom for fun and I'm currently looking at the RPN calculator (look for solveRPN on the page).
The function is:
Here is what I came up with:
The output:
I think this matches the Haskell semantics pretty closely, so now, I was wondering what would be a more idiomatic way of implementing this in Fantom...
Suggestions?
msl Mon 2 Aug 2010
Given you're looking at a stack, I'd prefer
push
andpop
overinsert
,removeAt
andaddAll
.My take (not much different to yours):
Raises a couple of interesting questions:
Str#isNumeric
?sys::Obj.trap
to handle the language provided shortcuts (sugar), so you could get the stuff in docLang::Expressions.shortcuts and remove the switch altogether.msl Mon 2 Aug 2010
I'm the first to admit that they're probably not really that interesting at all ;)
brian Mon 2 Aug 2010
Looks good to me. I concur with msl, I'd use push/pop.
cbeust Mon 2 Aug 2010
I was using push() and pop() initially until I noticed that they both work at the end of the list, not at the beginning, which was a bit counterintuitive to me.
I agree the code is a bit cleaner, though:
brian Mon 2 Aug 2010
List is actually backed by an array in the JVM, so definitely more efficient to push/pop at the end (versus a more functional linked list backing store).
Also by convention, we typically leave off the
()
of method calls which don't take any parameters. See Conventions.ivan Mon 2 Aug 2010
my 50 cents, single expression version (works in fansh :):
cbeust Wed 4 Aug 2010
I just posted a blog entry about this.