DEV Community

lit
lit

Posted on

Pure Science/Math Notation in Nim: Multiplication

Flexible is Nim's syntax, which allows you to write something you may never image that you can write freely in any programming language! And sometimes it even makes just wanna say "WoW".

And this time I'd show you something you can easily do to simplify the notation of multiplication in Nim, making your writing mathematics expression simpler and more comfortable.


The Multiplication Sign

Just think back: in the period of learning Elementary Mathematics, you were once told that "The multiplication sign can be omitted", e.g. a×b is written as ab.

From then on, × almost disappears between two numbers (you may come up with its usage of vector cross product, but that's another story, and I'm going to introduce relative feature also supported by Nim in following post), it became very normal for you to omit the multiplication sign between numbers.

However, later you met programming languages like C/C++, Java, Go, Rust, etc. or smalltalk, Haskell, ... And you were told multiplication is done via *, and you had to write a*b over a b, which is, not just with an additional character, and, for typing this character, *,
I guess it's sometimes a strain on one's pinky finger due to keeping pressing the "Shift" key.

Can We Write Code just like Mathematics Expressions

So can you image there are such a language in which * can just be omitted like in Mathematics?

Yes, you can make it done in Nim, via {.experimental: "callOperator".}, mentioned above.

To clarify, Nim itself isn't a special language peculiar to the field of mathematics (also called DSL), and its original multiplication is also written as a*b, like most Universal Programming Language. However, with great power provided by Nim, it's easy to make it.

Let's see how easy:

{.experimental: "callOperator".}  # required for func `()`

func `()`[T](x, y: T): T = x*y
Enter fullscreen mode Exit fullscreen mode

Then here you are:

let
  a = 2
  b = 3
  c = 9
assert (a b c) == 54
Enter fullscreen mode Exit fullscreen mode

And you may replace your code like (assuming a,b,c is all integer)

#include <math.h>  // pow

// ...
static
int f(int a, int b, int c)
// in fact for parameter types,
// you shall write `const int` over `int` to express
// what Nim expresses below.
{
    return a*(a+b)*(int)pow(a, c);
}
// ...
Enter fullscreen mode Exit fullscreen mode

with

from std/math import `^`

# ...
func f(a, b, c: int): int = a (a+b) a^c
# ...
Enter fullscreen mode Exit fullscreen mode

And with little speed loss (Nim's speed is almost the same as C)

Don't you like this?


In case you wonder what happened to code above,
I'd like to give some explain.

Explain

Thanks to Nim's command-invocation-syntax,

Routines can be invoked without the () if the call is syntactically a statement.

Therefore, in code above, (a b c) is just the same as (a(b(c))).

What Else We Can Do with These Features of Nim

Command Invocation Syntax

Also thanks to the feature of command-invocation-syntax, life is simpler with Nim:

Code like:

echo 1
Enter fullscreen mode Exit fullscreen mode
stdout.write 1
Enter fullscreen mode Exit fullscreen mode

can be written.

And quite a few parentheses can be omitted, saving your pinky finger from pain of keeping pressing shift key, again.

Call Operator

For {.experimental: "callOperator".},

not sure if you recall, but it's Nim's equivalent as of Python's __call__, though more powerful.

It allows you to make a object callable.

But in Nim, not only for object (instance of one class), but for any type! Such a feature that allows programmers bind routines to any type beyond such a type's original definition is often called "extension methods", which is supported in various forms by C#, Kotlin, Swift, Ruby, etc. (though in Nim this feature is subtly different from other languages, but introduce it is beyond topic, and I may mention this in later post)

Therefore, you can just make primitive types like int callable, not only custom defined types.

EOF

Thanks for reading till EOF.

I'm going to write about Nim's powerful syntax and macros as a serials, but may lack time.

The following are some relative resources for you to preview if interested:

  • A few great magic macro libraries written in Nim: nim-meta.
  • "Write Python in Nim! " A pure Nim library providing Python-like functions, macros... NimPyLib
  • Bridge of Python and Nim, simplifiying your writing Python C-extension and calling Python in Nim: NimPy

Top comments (0)