[TW5] rpn – Basic Math in Reverse Polish Notation (Prerelease)

193 views
Skip to first unread message

Thomas Elmiger

unread,
Jun 30, 2017, 6:55:59 PM6/30/17
to TiddlyWiki
Hi all

For some stuff I am working on, I needed simple calculations. Math.js seemed like overkill, so I built something really neat and small. Now I am thinking about making it a plugin if there are others that would like to use it. Please give it a try and let me know what you think:

https://tid.li/tw5/plugins.html#rpn%20%E2%80%93%20Basic%20Math%20in%20Reverse%20Polish%20Notation

rpn is a simple and lightweight solution for basic math operations. It is inspired by formerly popular calculators using Reverse Polish Notation. See Wikipedia for more info.


<<rpn 2 50 *>>

will output: 100


Features:

  • basic operations: +, -, /, *
  • limit digits after comma (dacs)
  • use pi to get Math.PI (π)
  • string concatenation (&)

Have fun and good night!

Thomas

Mat

unread,
Jun 30, 2017, 7:46:09 PM6/30/17
to TiddlyWiki
Great stuff Thomas!!! I very much need this NOW for an ambitious TW project soon to be released.

In my project, I'm currently I'm using Tobias' calc macro, and I note this is missing from your "Alternatives" list. Any reflections on how yours compares to this?

He has an interesting cleveness in merging the operator with one of the operands, which saves a definition for the user. I.e his syntax is

<<calc 5 +2>>
 or
 <$macrocall $name=calc value=5 operation="+2" />


I really like that yours allow concatenation! This should come in handy. 

("dacs"? ...I'll never remember that and I believe the standard term is decimals ;-) 


Yours looks promising in the sense of not making multi-step calculations overly cluttered - but is it possible to make the following work without the wikify widget? 

\define foo() <<rpn 2 2 *>>

<$wikify name=f text=<<foo>>>
<$macrocall $name="rpn" a=<<rpn 2 2 *>> b=<<f>> operation="*"/>
</$wikify>


Anyway, really cool Thomas!!!


<:-)

Thomas Elmiger

unread,
Jul 1, 2017, 7:18:13 AM7/1/17
to TiddlyWiki
Hi Mat

Thanks for the great feedback!!! I guess I overlooked calc on Tobias’ pages either because I ran into math.js first and was repelled by it’s complexity … or I did not evaluate it further because it is specialised on working with field values which I do not need. (But I found out that rpn covers this also in a way I would prefer.) I have added it to my alternatives of course.

First of all: I like your hint to the term decimals! For me it suggests, that a fixed number of digits after the comma would be returned. rpn can’t do that (it would be nice to show the exactness of a result). But maybe it is just me?

Here are some differences and similarities I found:

* calc has more functionality (until, beyond, by) – as all solutions by Tobias it is very sophisticated, mine is primitive ;–)
* calc unites operator and operand – rpn separates them (this makes my macro usage easier)
* calc does not round all numbers the same way – some are rounded up, others are floored (see example below)
* calc and rpn both do not return trailing zeros (as one could hope specifying parameters like decimals or dacs)
* both can handle values from fields: calc accepts field (and tiddler) names, in rpn you can use transclusions

You can copy this in a new tiddler in the calc wiki to try yourself:

<
<calc 1 /3 decimals:4>>

<
<calc 0 +1.5500 decimals:4>>

<
<calc 0 +1.5 decimals:0>> – the 5 in 1.5 is rounded (up)

<
<calc 1 +1.555>> – the last 5 is floored

---

calc has 2444 characters, rpn.js has 1305

<
<calc 2444 /1305 >>

that is a plus of 87 percent

I am not sure about your last question. For the first I use wikify a lot myself – are there any disadvantages I am not aware of?

Second: I guess you are not after this:
<$macrocall $name="rpn" a=<<rpn 2 2 *>> b=<<rpn 2 2 *>> operation="*"/>

rpn expects text as input and interpretes it as a number, wikify is a safe way to get text as output from other macros …

Thanks again and have a nice weekend!

Mat

unread,
Jul 1, 2017, 11:11:53 AM7/1/17
to TiddlyWiki
Thanks for reply! I'll look closer at your answer, but for now just to clarify my point about if it is possible to avoid having to use wikify (e.g by having it "built in" instead?). 

Compare this...

\define tot_words()
<$wikfiy name=wpt text=<<words_per_tid>> >
<$wikfiy name=not text=<<nr_of_tids>> >
<$macrocall $name="rpn" a=<<wpt>> b=<<not>> operation="*" />
</$wikify>
</
$wikify>
\end

Total words in my wikis:
<$wikify name=tw text=<<tot_words>>>
<$macrocall $name="rpn" a=<<tw>> b="10" operation="*"/>
</$wikify>

...compared to...
 
\define tot_words() <$macrocall $name="rpn" a=<<words_per_tid>> b=<<nr_of_tids>> operation="*" />

Total words in my wikis:
<$macrocall $name="rpn" a=<<tot_words>> b="10" operation="*"/>


Forcing to use surrounding stuff quickly adds up when there are a few steps in the calculations.

I have no idea how you've made rpn but maybe it's possible to make a and b pass a wikify filter automatially?

<:-)

Thomas Elmiger

unread,
Jul 1, 2017, 5:16:55 PM7/1/17
to TiddlyWiki
Hi again!

I. DID. IT.

After the most serious grinding of my most powerful gray cells alongside the less powerful ones I can announce the public beta of the universal elegant lightweight calculation macro rpn which offers (nearly) everything a power user like legendary Mat with the hat <:-) could desire.

* decimals that can be forced to show trailing zeros
* integrated wikification of operands (!!!)

To accomplish the second, I studied the great, long and complicated lesson by Andreas Hahn here:
https://groups.google.com/forum/?hl=de#!searchin/tiddlywikidev/parse$20a$20value$20using$20javascript%7Csort:relevance/tiddlywikidev/S5WuvbEPvvQ/Q__AI90O1o8J

as well as the internals of the ingenious wikify widget on tiddlywiki.com.

The result can be tested on the address mentioned before: https://tid.li/tw5/plugins.html#rpn%20%E2%80%93%20Basic%20Math%20in%20Reverse%20Polish%20Notation

So get a fresh copy and enjoy calculating. As always: make a backup first, use at your own risk. Feedback highly appreciated.

Cheers, Thomas

Saq Imtiaz

unread,
Jul 2, 2017, 3:20:48 PM7/2/17
to TiddlyWiki
This is neat. The lack of any kind of ability to do basic arithmetic is the biggest hindrance I've had so far in TW5. I rolled my own solution but it is not without its own shortcomings.

You can probably add support for % (modulus) without too much trouble. Will give this a go next time I have the time to fiddle with my TW5 project. Bookmarked.

Saq

@TiddlyTweeter

unread,
Jul 3, 2017, 9:06:09 AM7/3/17
to TiddlyWiki
Caro Thomas

Sounds great.

Can it add up a column of money numbers (negative and positive) in a table?

Josiah

Thomas Elmiger

unread,
Jul 3, 2017, 10:57:41 AM7/3/17
to TiddlyWiki
Hi Josiah

The short answer is: no.

Maybe one of the prior existing alternatives is what you are looking for: http://mathcell.tiddlyspot.com/

Happy calculating!
Thomas

Thomas Elmiger

unread,
Jul 8, 2017, 4:37:54 PM7/8/17
to TiddlyWiki
Hi Saq

You were right, that was easy and will be useful. rpn can now do % calculation as well as round upwards (Math.ceil) and downwards (Math.floor)
https://tid.li/tw5/plugins.html#rpn%20%E2%80%93%20Basic%20Math%20in%20Reverse%20Polish%20Notation

Have fun!
Thomas

Saq Imtiaz

unread,
Jul 8, 2017, 4:42:08 PM7/8/17
to TiddlyWiki
Great thank you. Will report back once I get a chance to play with it.

Saq

@TiddlyTweeter

unread,
Jul 8, 2017, 4:46:43 PM7/8/17
to tiddl...@googlegroups.com
i looked at your gizmo. i'm wondering

(1) if you can take the result of one calculation and feed it into another?

(2) whether it allows more than one mathematical transformation at a time (like it divides then multiplies then adds)?

Just asking
Josiah

Thomas Elmiger

unread,
Jul 9, 2017, 8:08:24 AM7/9/17
to tiddl...@googlegroups.com
Hi Josiah

1) You can pull together three operations like this:

<$macrocall $name="rpn" a=<<rpn 20 20 +>> b=<<rpn 3 10 *>> operation="%"/>

or like this:

\define a() <<rpn 1 2 +>>
\define b() <<rpn 3 4 +>>

<$macrocall $name="rpn" a=<<a>> b=<<b>> operation="+"/>

If you need more you will have to wikify intermediate results.

2) Not really in the sense of true RPN where you could write "100 10 5 1 + * /" but I don’t find that very readable/understandable so I did not use stacks to store operands and operators in. But as demonstrated in 1 it is possible with some limits.

At the moment you can not use macros containing macros or lists as parameters. – Maybe I try to add this later or someone can give me a hint …

All the best,
Thomas
Reply all
Reply to author
Forward
0 new messages