Nim for Pythonistas

PyCon ๐Ÿ‡ฎ๐Ÿ‡น, May 24th 2024

github.com/pietroppeter/nim-for-pythonistas
let ๐Ÿ’ฌ = "Ciao PyCon"
for i in -5 .. 5:
  echo ๐Ÿ’ฌ.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
    C    i    a    o         P    y    C    o    n
   C   i   a   o       P   y   C   o   n
  C  i  a  o     P  y  C  o  n
 C i a o   P y C o n
Ciao PyCon
 C i a o   P y C o n
  C  i  a  o     P  y  C  o  n
   C   i   a   o       P   y   C   o   n
    C    i    a    o         P    y    C    o    n
     C     i     a     o           P     y     C     o     n

Nim is a programming language

let ๐Ÿ’ฌ = "Ciao PyCon"
for i in -5 .. 5:
  echo ๐Ÿ’ฌ.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
    C    i    a    o         P    y    C    o    n
   C   i   a   o       P   y   C   o   n
  C  i  a  o     P  y  C  o  n
 C i a o   P y C o n
Ciao PyCon
 C i a o   P y C o n
  C  i  a  o     P  y  C  o  n
   C   i   a   o       P   y   C   o   n
    C    i    a    o         P    y    C    o    n
     C     i     a     o           P     y     C     o     n

Nim is a systems programming language

let ๐Ÿ’ฌ = "Ciao PyCon"
for i in -5 .. 5:
  echo ๐Ÿ’ฌ.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
    C    i    a    o         P    y    C    o    n
   C   i   a   o       P   y   C   o   n
  C  i  a  o     P  y  C  o  n
 C i a o   P y C o n
Ciao PyCon
 C i a o   P y C o n
  C  i  a  o     P  y  C  o  n
   C   i   a   o       P   y   C   o   n
    C    i    a    o         P    y    C    o    n
     C     i     a     o           P     y     C     o     n

Nim is a statically typed and compiled
systems programming language

let ๐Ÿ’ฌ = "Ciao PyCon"
for i in -5 .. 5:
  echo ๐Ÿ’ฌ.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
    C    i    a    o         P    y    C    o    n
   C   i   a   o       P   y   C   o   n
  C  i  a  o     P  y  C  o  n
 C i a o   P y C o n
Ciao PyCon
 C i a o   P y C o n
  C  i  a  o     P  y  C  o  n
   C   i   a   o       P   y   C   o   n
    C    i    a    o         P    y    C    o    n
     C     i     a     o           P     y     C     o     n

Nim is a statically typed and compiled
systems programming language
good for everything

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿ Pythonista

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿ Pythonista

๐Ÿงฎ (applied) Mathematician

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿ Pythonista

๐Ÿงฎ (applied) Mathematician

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

๐Ÿธ Python Milano and PyData Milan: milano.python.it

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿ Pythonista

๐Ÿงฎ (applied) Mathematician

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

๐Ÿ‘‘ HN: Programming Language Underdog (2018)

๐Ÿธ Python Milano and PyData Milan: milano.python.it

Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง

๐Ÿ Pythonista

๐Ÿงฎ (applied) Mathematician

๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist

๐Ÿ‘‘ HN: Programming Language Underdog (2018)

๐Ÿธ Python Milano and PyData Milan: milano.python.it

๐Ÿ™ Recurse Center: recurse.com

sometimes people ask me "what can I do to improve my Python skills?" Much to their surprise, I often suggest doing a project in a completely different language or outside of their area of expertise. I think the main benefit of doing this is that you'll often see a completely different way of thinking about a problem that you can bring home to your own projects.

David Beazley, March 2023

3 things I like about Python ๐Ÿ

- A

- P

- E

3 things I like about Python ๐Ÿ

- Accessibility

- P

- E

3 things I like about Python ๐Ÿ

- Accessibility

- Playfulness

- E

3 things I like about Python ๐Ÿ

- Accessibility

- Playfulness

- Everything

3 things I struggle with Python ๐Ÿ™Š

- A

- P

- E

3 things I struggle with Python ๐Ÿ™Š

- A

- P

- Errors

3 things I struggle with Python ๐Ÿ™Š

- A

- Portability

- Errors

3 things I struggle with Python ๐Ÿ™Š

- Abstraction

- Portability

- Errors

Agenda

  1. Easy and fast (+ superpowers ๐Ÿฆธ)
  2. Compiler (and types)
  3. Multiple backends (Javascript ๐Ÿคฏ)
  4. A Niche tech (and me)

Easy and fast (+ superpowers ๐Ÿฆธ)

nim is an easy to learn and fast complement to Python (with metaprogramming ๐Ÿฆธ)

๐ŸŽ๏ธ Performant: compiles natively

const N = 3
type Matrix = array[N, array[N, int]]

let
  A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]]

func `*`(a, b: Matrix): Matrix =
  for i in 0 ..< N:
    for j in 0 ..< N:
      for k in 0 ..< N:
        result[i][j] += a[i][k]*b[k][j]

echo A*B
[[1, 3, 6], [4, 9, 15], [7, 15, 24]]

HPC from Python to Nim (Fosdem 2022)

Pythonic Syntax with ๐Ÿฆธ Superpowers

type
  Grid = array[3, array[3, Cell]]
  Cell = enum X, O

func initGrid: Grid =
  [[X,O,X],[O,X,O],[X,O,X]]

proc show(g: Grid) =
  for row in g:
    echo row

proc update(g: var Grid) =
  for i in g.low .. g.high:
    for j in g[i].low .. g[i].high:
      g[i][j] = if g[i][j] == X: O else: X
  • ๐Ÿฆธ syntax fits well with metaprogramming
  • ๐Ÿ’ก UFCS (Uniform Function Call Syntax)

โ €

var g = initGrid()
show g # command
[X, O, X]
[O, X, O]
[X, O, X]
g.update # method
g.show
[O, X, O]
[X, O, X]
[O, X, O]
update(g) # function
show(g)
[X, O, X]
[O, X, O]
[X, O, X]

๐Ÿฆธ Metaprogramming

  1. Generics
  2. Templates
  3. Macros (AST)

AST: Abstract Syntax Tree

DSL: Domain Specific Language

with power comes responsibility

๐Ÿค Interop with Python

fibonacci.nim

import nimpy

func fib*(n: int): int {. exportpy .} =
  if n < 2: 1 else: fib(n - 1) + fib(n - 2)

main.py

import nimporter
from fibonacci import fib

print(fib(10))
python3 main.py
89

nimporter

nimpy

Compiler (and types)

A smart compiler and a powerful type system can give you safety without compromising expressivity

const for compile time evaluation

import std / [sequtils, strutils]

func fizzBuzz(n: int): string = 
  case n mod 15
  of 0: "FizzBuzz"
  of 3, 6, 9, 12: "Fizz"
  of 5, 10: "Buzz"
  else: $n

const result = (1 .. 15).toSeq.mapIt(it.fizzBuzz).join()

echo result
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

let and var for safe mutability

let is a (runtime defined) immutable value

let x = 1
x = x + 1
# Error: 'x' cannot be assigned to

use var for a mutable variable

var x = 1
inc x
echo x
2

var parameters

use var for a mutable parameter

proc divmod(a, b: int; q, r: var int) =
  q = a div b
  r = a mod b

var q, r: int

echo (q, r)
divmod(8, 5, q, r) # modifies q and r
echo (q, r)
(0, 0)
(1, 3)

Effects tracking

let aGlobal = 42

proc withSideEffects(x: int): int =
  echo "writing ", x, " in a file"
  "IcanDo.IO".writeFile($x)
  x + aGlobal

echo withSideEffects(624)
echo "IcanDo.IO".readFile
writing 624 in a file
666
624

โ €

func noSideEffects(x: int): int =
  # in a func compiler will error
  # if you try to do I/O or access global ...
  x + 42

echo noSideEffects(-42)
0

Procedure Overloading

type
  Cat = object
  Dog = object

proc speak(c: Cat) = echo "meow"
proc speak(d: Dog) = echo "woof"

let
  fuffi = Cat()
  fido = Dog()

fuffi.speak
fido.speak
meow
woof

(the advantages of OOP without full blown OOP)

Multiple backends (Javascript ๐Ÿคฏ)

Having multiple backends is cool and
the Javascript one is a game changer

compiler backends

  • C
  • C++
  • Objective-C
  • Javascript

FFI: Foreign Function Interface

A Niche tech (and me)

Why should I invest in a niche tech?

Easier ownership ๐Ÿ’Œ

Color of a Language ๐ŸŽจ

Growing Culture ๐ŸŽ

Zen of Nim

1. Copying bad design is not good design.
2. If the compiler cannot reason about the code,
   neither can the programmer.
3. Donโ€™t get in the programmerโ€™s way.
4. Move work to compile-time:
   Programs are run more often than they are compiled.
5. Customizable memory management.
6. Concise code is not in conflict with readability,
   it enables readability.
7. (Leverage meta programming to keep the language small.)
8. Optimization is specialization:
   When you need more speed, write custom code.
9. There should be one and only one programming language
   for everything.
   That language is Nim.

Easier Open Source ๐ŸŽ‹

Nimib as 'Literate Programming'

hello.nim
import nimib

nbInit

nbText "A sample program with _Nimib_"

nbCode:
    echo "hello RC!"

nbSave

nim r hello

๐Ÿ› Slides with Nim(ib)

autoAnimateSlides(7):
  nbText "## Me ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง"
  showFrom(3):
    nbText "๐Ÿ Pythonista"
  showFrom(4):
    nbText "๐Ÿงฎ (applied) Mathematician"
  showFrom(2):
    nbText "๐Ÿง‘โ€๐Ÿ”ฌ Data Scientist"
  showFrom(6):
    nbText "๐Ÿ‘‘ [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/)"
  showFrom(5):
    nbText "๐Ÿธ Python Milano and PyData Milan: [milano.python.it](milano.python.it)"
  showFrom(7):
    nbText "๐Ÿ™ Recurse Center: [recurse.com](recurse.com)"

nimislides, thanks Hugo!๐Ÿ’˜

Nimib.py

hi.py
import nimib as nb

nb.init()

nb.text("Welcome to `nimib.py`!")

message = "hello"

with nb.code():
    print(message)

nb.save()

python hi.py

๐ŸŽ„๐Ÿ‘จโ€๐Ÿ’ป

Conclusions

To improve as a programmer:

  • โœจ new language!

  • ๐Ÿ—ป new domain!

  • ๐Ÿ‘‘ Nim?

  • ๐Ÿฃ Niche?

I believe the most important idea is that Python is developed on the Internet, entirely in the open, by a community of volunteers (but not amateurs!) who feel passion and ownership.

Guido Van Rossum, King's Day Speech, 2016