Nesting functions to build an imperial to metric conversion framework

Hello everyone :slight_smile:

This all started with the impossibility to use macros inside macros. I’ve been looking at functions as a possible solution for what I want to do, which is:

Create a set of global functions that can fall each other.

The idea is for example to have a global function .round(decimals), and another function .yardstometers(yards), and being able to chain [.yardstometers(value)].round[2], so that I can keep the fields I have in tiddlers are expressed in yards (the source unit), and simply use something like [.yardstometers({!!yards-field}].round[2]] in my tiddlers manipulating those distances in yards.

Unfortunately, I’m way over my head and can’t seem to manage making it work (I’m probably still very fuzzy on the syntax and the fit of my use case to functions).

Can anybody show me an example of what I’m trying to do with the yards to meters and rounding to 2 decimals?

A yard (3 feet) is 0.9144 meters.

Using TWCore math filter operators (see https://tiddlywiki.com/#Mathematics%20Operators, you can write:

{{{ [{!!yards}multiply[0.9144]fixed[2]] }}}

where:

  • yards is a field in the current tiddler
  • 0.9144 is the number of meters in a yard
  • fixed[2] rounds the result to 2 decimal places

enjoy,
-e

1 Like

Hey, thanks @EricShulman :slight_smile: I know I can do that, but my point was to be able to have a number of functions producing what your expression does, so that I can use the functions whenever appropriate, rather than typing an expression every time, and with the possibility of rounding or not rounding depending on the situation.

Again, I could write a macro:

/define y2m(value)
<$text text={{{[[$value$]multiply[0.9144]]}}}/>
/end

… to convert any value including a {!!field}, and another macro

\define round(value decimals)
<$text text={{{[[$value$]fixed[decimals]]}}}/>
\end

… but I can’t call use the round macro inside the y2m one. In other words, if I want to be able to use these “recursively”, I would have to use functions, I think, but I can’t figure out how to apply the example below (factorial calculation with the function “.step” called inside the main function “.f”) to my use case:

\function .step(n) [<n>subtract[1]] :map[.f<currentTiddler>multiply<n>]
\function .f(n) [<n>match[0]then[0]] [<n>match[1]then[1]] :else[.step<n>]

(which renders the result of 40320 for <<.f 8>>)

In anycase, what I ended up doing is define the macro with value and decimals parameters anyway for that yards case, and when used without specifying the decimals input, it just gives the result without the decimals.

\function .yardstometers() [multiply[0.9144]]
\function .round() [fixed[2]]

{{{ [[3].yardstometers[].round[]] }}}

… or

\function .yardstometers(yards) [<yards>multiply[0.9144]]
\function .round(fixed) [fixed<fixed>]

{{{ [.yardstometers[3].round[2]] }}}

demo

1 Like