├── .gitignore ├── IcanDo.IO ├── LICENSE ├── README.md ├── agenda.nim ├── conclusions.nim ├── crown.webp ├── fibonacci.nim ├── fosdem ├── IcanDo.IO ├── agenda.nim ├── bunny.html ├── hello.nim ├── hi.py ├── index.html ├── index.nim ├── intro.nim ├── nbex.nim ├── okazzu.html ├── one.html ├── one.nim ├── pyconit.png ├── three.nim ├── title.nim └── two.nim ├── four.nim ├── hello.html ├── hello.nim ├── hi.py ├── index.html ├── index.nim ├── intro.nim ├── languages-color.png ├── lightning.html ├── lightning.nim ├── main.py ├── matrix.nim ├── my.html ├── nbex.html ├── nbex.nim ├── nim.cfg ├── notes.md ├── notes_lightning.md ├── one.nim ├── plant_app.html ├── pyconit.png ├── quotes.html ├── quotes.nim ├── therapy_spongebob.gif ├── three.nim ├── title.nim └── two.nim /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.html # add explicitly -------------------------------------------------------------------------------- /IcanDo.IO: -------------------------------------------------------------------------------- 1 | 624 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Pietro Peterlongo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nim-for-pythonistas 2 | 3 | me introducing [Nim](https://nim-lang.org/) to pythonistas. a talk on the Nim programming language, being a Pythonista and improving your programming skills learning a (niche) language. 4 | 5 | A lot of thoughts and work for this presentation prepared during a batch at [Recurse Center](https://www.recurse.com/) 🐙 6 | 7 | Delivered: 8 | - Nov 10th, 2023 as a lightning (5') talk at PyCon Sweden, Stockholm 9 | [slides](https://pietroppeter.github.io/nim-for-pythonistas/lightning.html) 10 | - May 24th, 2024 as a 30' talk at PyCon Italy, Florence. 11 | [slides](https://pietroppeter.github.io/nim-for-pythonistas/), [video](https://www.youtube.com/watch?v=yPMudqyKtLQ) 12 | - Feb 2nd, 2025 as a 25' talk at FOSDEM, Brussels 13 | [slides](https://pietroppeter.github.io/nim-for-pythonistas/fosdem/) 14 | 15 | ## FOSDEM 2025 16 | 17 | https://fosdem.org/2025/schedule/event/fosdem-2025-6414-nim-for-pythonistas-and-open-source-lovers-/ 18 | 19 | **Description**: 20 | 21 | You might have heard of Nim as a fast and statically typed language with a Python-like syntax that compiles to compact executables and you are curious to hear more about it. Or you might have never heard of Nim and you might be curious what a talk about another programming language (that is not Rust) has anything to do with a Python devroom. Or maybe you are someone who loves Open Source (possibly even contributed to some open source projects) but does not feel like you will ever be able to contribute a project of your own that might interest others. If you connect with one of these three descriptions, I have prepared this talk for you. Even if you do not see yourself in any of those, please keep reading to see if you should consider joining the Python devroom for this talk. 22 | 23 | This talk is divided in three parts: 24 | 25 | 1. What is Nim? 26 | 2. Why Nim made me a better Pythonista 27 | 3. How Nim can help you getting more involved in Open Source 28 | 29 | In the first part I will give a quick introduction to Nim emphasizing similarity and differences with Python. I will explain that Nim can be used as a fast and easy to learn complement to Python with a great interoperability and metaprogramming superpowers. Nim has also a powerful type system, functional features and can compile to Javascript. 30 | 31 | In the second part I will tell you a bit about my story on how I got attracted to Nim coming from Python, the benefits of a niche community, and how I came out with a deeper appreciation for the Python project and community. 32 | 33 | In the third part, I will show you how easy it is to create your own open source project with Nim and share it with the world (maybe even a Python version of it), and I will tell you a little bit about my own open source project, called Nimib, a literate programming tool for interactive explanations. 34 | 35 | The talk is kept approachable for beginners while trying to be interesting also for experts. It does not have any specific pre-requisites on Nim, Python or Open Source but a familiarity and interest with at least one of those will help you take the most out of it. 36 | 37 | ## PyCon Italy 2024 38 | 39 | Click thumbnail to see the video: 40 | [![pycon 2024 nim for pythonista video thumbnail](pyconit.png)](https://www.youtube.com/watch?v=yPMudqyKtLQ) 41 | 42 | https://2024.pycon.it/it/event/nim-for-pythonistas 43 | 44 | **Elevator Pitch**: What if I could tell you that there is a language that looks like Python but achieves the performance of C? And that also has the power of metaprogramming of Lisp? Nim is a statically typed compiled language that does all the above and more. And it is easy to learn for Pythonistas. 45 | 46 | **Description**: 47 | 48 | Experienced Pythonistas are used to reach out to an alternative language when in need for higher performance. In the past this meant to reach out for C, C++ or Cython, more recently the trend is towards Rust. Nim is a relatively unexplored option as a language to learn as a second (or third or …) language on top of Python, but it does provide some interesting benefits. 49 | As Rust, Nim is a statically typed and compiled programming language that can be use to boost Python’s performance. But Nim has different tradeoffs, in particular less emphasis on memory safety and a much easier learning curve, thanks to a indentation based syntax very much familiar to Python developers. 50 | 51 | In this talk we will give a brief presentation of Nim language particularly tailored to Pythonistas. We will cover the language from the ground up, making frequent remarks to the differences with Python. We will briefly cover metaprogramming, one of the most powerful parts of Nim. We will try to cover the philosophy of the language (the Zen of Nim) and we will also cover the part of the ecosystem that are relevant for interoperability with Python (nimpy, nimporter, …). 52 | We will also cover one of the most interesting aspects of Nim that represents a rather distinctive selling point: Nim can compile to Javascript and allows us to be able to work with frontend technologies directly. 53 | 54 | At the end we will briefly cover Nimib, my open source project recently ported also to Python. This will showcase a way to use metaprogramming in a real project and how to create a Python package using Nim. 55 | 56 | The goal of this talk is to make you curious to go and try out Nim (come for the performance, stay for the ergonomics!), but even if you just come out with a better appreciation and understanding of Python we would still be happy. 57 | 58 | ## Lightning at PyCon Sweden 2023 59 | 60 | Lightning talk 5' at PyCon Sweden 2023, November 10th. That lightning session was lots of fun, watch it in full here: https://www.youtube.com/watch?v=FLCTCyTjqFc 61 | 62 | https://pietroppeter.github.io/nim-for-pythonistas/lightning.html 63 | 64 | ## code for slides 65 | 66 | slides are done with [nimislides] (a [nimib] theme). slide code is structure in modules (using named templated for slide), it is a helpful way to structure nimislides code while working on it. 67 | 68 | [nimislides]: https://github.com/HugoGranstrom/nimiSlides 69 | [nimib]: https://github.com/pietroppeter/nimib 70 | -------------------------------------------------------------------------------- /agenda.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | const 4 | oneShort* = "Easy and fast (+ superpowers 🦸)" 5 | oneLong* = "nim is an *easy* to learn and *fast* complement to Python (with metaprogramming 🦸)" 6 | twoShort* = "Compiler (and types)" # add more about safety 7 | twoLong* = "A smart compiler and a powerful type system can give you safety without compromising expressivity" 8 | threeShort* = "Multiple backends (Javascript 🤯)" 9 | threeLong* = "Having multiple backends is cool and
the Javascript one is a game changer" 10 | fourShort* = "A Niche tech (and me)" 11 | fourLong* = "Why should I invest in a niche tech?" 12 | 13 | mySlide(all): 14 | nbText "## Agenda"& 15 | "\n1. " & oneShort & 16 | "\n2. " & twoShort & 17 | "\n3. " & threeShort & 18 | "\n4. " & fourShort 19 | speakerNote "- " & oneLong & "\n- " & twoLong & "\n- " & threeLong & "\n- " & fourLong 20 | 21 | template section(number: untyped) = 22 | mySlide(number): 23 | nbText "### " & `number short` 24 | nbText `number Long` 25 | 26 | section(one) 27 | section(two) 28 | section(three) 29 | section(four) 30 | 31 | when isMainModule: 32 | myInit("agenda") 33 | all 34 | one 35 | two 36 | three 37 | four 38 | nbSave -------------------------------------------------------------------------------- /conclusions.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | import quotes 3 | 4 | minSlide(notAConclusion): 5 | nbText """## Conclusions 6 | 7 | To improve as a programmer: 8 | """ 9 | unorderedList: 10 | listItem: 11 | nbText "✨ new language!" 12 | listItem: 13 | nbText "🗻 new domain!" 14 | listItem: 15 | nbText "👑 Nim?" 16 | listItem: 17 | nbText "🐣 Niche?" 18 | 19 | template all* = 20 | notAConclusion 21 | GuidoPythonMainIdea 22 | 23 | when isMainModule: 24 | myInit("conclusions") 25 | all 26 | nbSave 27 | -------------------------------------------------------------------------------- /crown.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/nim-for-pythonistas/ce311b6dec92c602f096dd1eb713abcbc8b4be59/crown.webp -------------------------------------------------------------------------------- /fibonacci.nim: -------------------------------------------------------------------------------- 1 | import nimpy 2 | 3 | func fib*(n: int): int {. exportpy .} = 4 | if n < 2: 1 else: fib(n - 1) + fib(n - 2) 5 | -------------------------------------------------------------------------------- /fosdem/IcanDo.IO: -------------------------------------------------------------------------------- 1 | 624 -------------------------------------------------------------------------------- /fosdem/agenda.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | const 4 | oneShort = "What is Nim?" 5 | oneLong = """ 6 | Nim can be used as a fast and easy to learn complement to Python with a great interoperability and metaprogramming superpowers. 7 | 8 | Nim has also a powerful type system, functional features and can compile to Javascript.""" 9 | twoShort = "Why Nim made me a better Pythonista" 10 | twoLong = """ 11 | how I got attracted to Nim coming from Python, the benefits of a niche community, 12 | and how I came out with a deeper appreciation for the Python project and community.""" 13 | threeShort = "How Nim helped me get into Open Source" 14 | threeLong = """ 15 | how easy it is to create your own open source project with Nim 16 | 17 | my open source project, Nimib 🐳 18 | """ 19 | 20 | mySlide(all): 21 | nbText "## Agenda"& 22 | "\n1. " & oneShort & 23 | "\n2. " & twoShort & 24 | "\n3. " & threeShort 25 | 26 | template section(number: untyped) = 27 | mySlide(number): 28 | nbText "### " & `number Short` 29 | nbText `number Long` 30 | 31 | section(one) 32 | section(two) 33 | section(three) 34 | 35 | 36 | when isMainModule: 37 | myInit("agenda") 38 | all 39 | one 40 | two 41 | three 42 | nbSave 43 | -------------------------------------------------------------------------------- /fosdem/bunny.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bunny_meets_whaley.py 6 | 7 | 8 | 9 | 10 | 11 | 12 | 35 | 36 | 40 | 44 | 45 | 46 |
47 |
48 | 🏡 49 | bunny_meets_whaley.py 50 | 51 |
52 |
53 |
54 |

Bunny 🐰 meets Whaley 🐳!

55 |

Hello world example for pyscript with nimib.py.

56 |
57 |
58 |

This code adds functionality to the button (try block is a workaround):

59 |
try:
 60 |     from js import document
 61 | 
 62 |     def handler(e):
 63 |         output = document.createElement("span")
 64 |         output.innerHTML = "🐳"
 65 |         container = document.querySelector("div#emoji-container")
 66 |         container.appendChild(output)
 67 | 
 68 |     button = document.querySelector("button#click-me")
 69 |     button.addEventListener("click", handler)
 70 | except ImportError:
 71 |     print("running pyscript block not in js")
 72 | 
88 | 89 |
90 | 98 |
99 |
import nimib as nb
100 | 
101 | nb.init(pyscript=True)
102 | 
103 | nb.text("## Bunny 🐰 meets Whaley 🐳!")
104 | nb.text("Hello world example for pyscript with nimib.py.")
105 | 
106 | nb.html("<button id=\"click-me\">Click me! 🐰🐳</button><br/>")
107 | nb.html("<div id=\"emoji-container\"></div>")
108 | 
109 | nb.text("This code adds functionality to the button (try block is a workaround):")
110 | with nb.code(pyscript=True):
111 |     try:
112 |         from js import document
113 | 
114 |         def handler(e):
115 |             output = document.createElement("span")
116 |             output.innerHTML = "🐳"
117 |             container = document.querySelector("div#emoji-container")
118 |             container.appendChild(output)
119 | 
120 |         button = document.querySelector("button#click-me")
121 |         button.addEventListener("click", handler)
122 |     except ImportError:
123 |         print("running pyscript block not in js")
124 | 
125 | nb.save()
126 | 
127 |
140 | -------------------------------------------------------------------------------- /fosdem/hello.nim: -------------------------------------------------------------------------------- 1 | import nimib 2 | 3 | nbInit 4 | 5 | nbText "A sample program with _Nimib_" 6 | 7 | nbCode: 8 | echo "hello RC!" 9 | 10 | nbSave 11 | -------------------------------------------------------------------------------- /fosdem/hi.py: -------------------------------------------------------------------------------- 1 | import nimib as nb 2 | 3 | nb.init() 4 | 5 | nb.text("Welcome to `nimib.py`!") 6 | 7 | message = "hello" 8 | 9 | with nb.code(): 10 | print(message) 11 | 12 | nb.save() 13 | -------------------------------------------------------------------------------- /fosdem/index.nim: -------------------------------------------------------------------------------- 1 | import nimib except toJson 2 | import nimislides, nbex 3 | import title, intro, agenda, one, two, three 4 | 5 | template thanks* = 6 | slide: 7 | nbText """# 🙏""" 8 | reference "🐘 [@pietroppeter@fosstodon.org](https://fosstodon.org/@pietroppeter)" 9 | reference "🦋 [@pietroppeter.bsky.social](https://bsky.app/profile/pietroppeter.bsky.social)" 10 | reference "👨‍💼 [LinkedIn - Pietro Peterlongo](https://www.linkedin.com/in/pietro-peterlongo-b7605627/)" 11 | reference "🔵⚪️ [agilelab.it](https://www.agilelab.it/)" 12 | nbText "🧑‍💻 [github.com/pietroppeter](https://github.com/pietroppeter)" 13 | 14 | when isMainModule: 15 | myInit("index.nim") 16 | titleSlide 17 | slide: 18 | intro.all 19 | agenda.all 20 | slide: 21 | agenda.one 22 | one.all 23 | slide: 24 | agenda.two 25 | two.all 26 | slide: 27 | agenda.three 28 | three.all 29 | thanks 30 | nbSave -------------------------------------------------------------------------------- /fosdem/intro.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | template helloFosdemAnimated* = 4 | import sequtils, strutils 5 | autoAnimateSlides(4): 6 | nbCode: 7 | let 💬 = "Hi Fosdem" 8 | for i in -5 .. 5: 9 | echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join() 10 | showText(@[ 11 | ({1.int255, 2, 3, 4}, "Nim is a"), 12 | ({3.int255, 4}, " statically typed and compiled
"), 13 | ({2.int255, 3, 4}, " systems"), 14 | ({1.int255, 2, 3, 4}, " programming language"), 15 | ({4.int255}, "
good for everything"), 16 | ]) 17 | 18 | template meNotAnimated* = 19 | slide: 20 | nbText "## Me 👨‍👩‍👧" 21 | nbText "🧑‍🔬 Data Scientist @ [AgileLab](https://www.agilelab.it/)" # mention handbook an holacracy 22 | nbText "🍸 Python Milano and PyData Milan: [milano.python.it](milano.python.it)" 23 | nbText "👑 [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/)" 24 | nbText "🐙 Recurse Center: [recurse.com](recurse.com)" 25 | 26 | template pyconitVideo* = 27 | slide: 28 | nbImage "../pyconit.png" 29 | 30 | template pyconitPromo* = 31 | slide(slideOptions(imageBackground="pyconit.png")): 32 | nbText """

🍝Come to PyCon Italy!🤌""" 33 | nbText """

May 28-31, Bologna | pycon.it""" 34 | nbText "⠀" 35 | nbText "⠀" 36 | nbText "⠀" 37 | nbText "⠀" 38 | nbText "⠀" 39 | nbText "⠀" 40 | nbText "⠀" 41 | 42 | template all* = 43 | helloFosdemAnimated 44 | meNotAnimated 45 | pyconitVideo 46 | pyconitPromo 47 | 48 | when isMainModule: 49 | myInit("intro") 50 | all 51 | nbSave 52 | -------------------------------------------------------------------------------- /fosdem/nbex.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides 2 | import std / strformat 3 | export strformat 4 | 5 | type 6 | int255* = range[0 .. 255] 7 | 8 | const adaptiveColumnsHtml* = """

""" 9 | 10 | const 11 | pythonBlue* = "#3572A5" # from github/linguist 12 | pyconRedBrick* = "#F17A5D" 13 | pyconYellow* = "#F8B03D" 14 | pyconRed* = "#DB0000" 15 | pyconViolet* = "#9473B0" 16 | pyconPurple* = "#FA00FF" 17 | pyconGreen* = "#219653" 18 | pyconKeppel* = "#34B4A1" 19 | pyconWhite* = "#FCE8DE" 20 | nimYellow* = "#ffe953" 21 | fosdemPurple* = "#A12D94" #rgb(161, 45, 148) 22 | blueForFosdem* = "#00B9E8" 23 | 24 | const 25 | tripleBackticks* = "```" # hack to avoid issues when showing source 26 | bOpen* = "{" 27 | bClose* = "}" 28 | 29 | template reference*(text: string) = 30 | nbTextSmall: text 31 | 32 | # small text 33 | template addNbTextSmall* = 34 | nb.partials["nbTextSmall"] = "" & nb.partials["nbText"] & "" 35 | nb.renderPlans["nbTextSmall"] = nb.renderPlans["nbText"] 36 | 37 | template nbTextSmall*(text: string) = 38 | nbText: text 39 | nb.blk.command = "nbTextSmall" 40 | 41 | template mySlide*(ident: untyped, body: untyped) = 42 | template ident* = 43 | slide: 44 | body 45 | 46 | template minSlide*(ident: untyped, body: untyped) = 47 | # I can customize with custom background if I do not get to make it complete 48 | template ident* = 49 | slide: 50 | body 51 | 52 | template slideIframe*(url: string) = 53 | nbRawHtml: "
" 54 | 55 | template slideIframeFromNblog*(filename: string) = 56 | slideIframe("https://nimib-land.github.io/nblog/drafts/" & filename & ".html") 57 | 58 | template slideIframe*(ident: untyped, frameAsStr: untyped) = 59 | template ident* = 60 | slide(slideOptions(iframeBackground=frameAsStr)): 61 | discard 62 | 63 | template slideIframe*(ident: untyped, frameAsStr: untyped, body: untyped) = 64 | template ident* = 65 | slide(slideOptions(iframeBackground=frameAsStr)): 66 | body 67 | 68 | template spanColor*(col: string, text: string) = 69 | nbRawHtml("" & text & "") 70 | 71 | template hColor*(level: int, col: string, text: string) = 72 | nbRawHtml("" & text & "") 73 | 74 | template h1Color*(col: string, text: string) = hColor(1, col, text) 75 | template h2Color*(col: string, text: string) = hColor(2, col, text) 76 | template h3Color*(col: string, text: string) = hColor(3, col, text) 77 | template h4Color*(col: string, text: string) = hColor(4, col, text) 78 | 79 | template myInit*(sourceFileRel = "my.nim") = 80 | nbInit(thisFileRel=sourceFileRel, theme=revealTheme) 81 | setSlidesTheme(Solarized) 82 | addNbTextSmall 83 | 84 | template divStyled*(style: string, body: untyped) = 85 | nbRawHtml "
" 86 | body 87 | nbRawHtml "
" 88 | 89 | when isMainModule: 90 | myInit 91 | slide: 92 | divStyled("background-color:pink;"): 93 | h1Color("orange"): "H1 Title" 94 | spanColor("blue"): "hi" 95 | nbSave 96 | -------------------------------------------------------------------------------- /fosdem/okazzu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | okazzu.nim 5 | 6 | 7 | 8 | 9 | 10 | 11 | 34 | 35 | 36 | 37 |
38 |
39 | 🏡 40 | okazzu.nim 41 | 42 |
43 |
44 |
45 | 46 | 47 | 455 |
456 | 464 |
465 |
import nimib, p5
466 | nbInit
467 | nbUseP5
468 | nbJsFromCode:
469 |   var colors = @["#f70640", "#f78e2c", "#fdd903", "#cae509", "#63be93", "#81cfe5", "#299dbf", "#38187d", "#a4459f", "#f654a9", "#2F0A30"];
470 | 
471 |   type
472 |     Form = ref object
473 |       x, y, x0, y0, r0, r, d0, d: float
474 |       a, t, r1, r2, r3: float 
475 |       n: int
476 |       col: string
477 | 
478 |   var forms: seq[Form]
479 | 
480 |   proc newForm(x, y: float): Form =
481 |     result = new Form
482 |     result.x = x
483 |     result.y = y
484 |     result.x0 = x
485 |     result.y0 = y
486 |     result.r0 = random(10, 25)
487 |     result.r = result.r0
488 |     result.d0 = random(15) * random() + 5
489 |     result.d = result.d0
490 |     result.n = int(random(3, 13))
491 |     result.a = random(100)
492 |     result.t = random(10000)
493 |     result.r1 = random(0.01)
494 |     result.r2 = random(0.01)
495 |     result.r3 = random(0.01)
496 |     result.col = random(colors)
497 | 
498 |   proc show(form: Form) =
499 |     noStroke()
500 |     fill(form.col)
501 |     push()
502 |     translate(form.x, form.y)
503 |     rotate(form.a)
504 |     for i in 0 ..< form.n:
505 |       let theta = map(i, 0, form.n, 0, TAU)
506 |       ellipse(form.r * cos(theta), form.r * sin(theta), form.d, form.d)
507 |     pop()
508 | 
509 |   proc move(form: Form) =
510 |     form.t += 1
511 |     form.a = TAU * sin(form.t * form.r1);
512 |     form.r = form.r0 * sin(form.t * form.r2);
513 |     form.d = form.d0 * sin(form.t * form.r3);
514 |     form.x += 0.5;
515 |     form.y -= 0.5;
516 |     if form.x > width:
517 |       form.x = 0
518 |     if form.y < 0:
519 |       form.y = height
520 | 
521 |   setup:
522 |     createCanvas(900, 900)
523 | 
524 |     var c = 18
525 |     var w = width / c
526 |     for i in 0 ..< c:
527 |       for j in 0 ..< c:
528 |         let x = i * w + w / 2;
529 |         let y = j * w + w / 2;
530 |         if ((i + j) mod 2 == 0):
531 |           for k in 0 ..< 5:
532 |             forms.add(newForm(x, y))
533 |     background(0)
534 | 
535 |   draw:
536 | 
537 |     translate(width / 2, height / 2)
538 |     scale(1.1)
539 |     translate(-width / 2, -height / 2)
540 |     background(255)
541 |     for f in forms:
542 |       f.show()
543 |       f.move()
544 | nbSave
545 |
558 | -------------------------------------------------------------------------------- /fosdem/one.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |

Metaprogramming 🦸

15 |
16 |
17 |

Metaprogramming 🦸

18 |
let
19 |   home = "Milan"
20 |   h = (10*60+15).float / 60
21 | 
22 | echo fmt"from Brussels to {home} the train takes {h:.1f} hours"
from Brussels to Milan the train takes 10.2 hours
23 |
24 |
25 |

Metaprogramming 🦸

26 |
let
27 |   home = "Milan"
28 |   h = (10*60+15).float / 60
29 | 
30 | echo fmt"from Brussels to {home} the train takes {h:.1f} hours"
from Brussels to Milan the train takes 10.2 hours
31 |

the echo fmt"..." statement is transformed at compile time into something like

32 |
var temp = ""
33 | temp.add "from Brussels to "
34 | temp.formatValue(home, "")
35 | temp.add " the train takes "
36 | temp.formatValue(h, ".2f")
37 | temp.add " hours"
38 |
39 |
40 |
41 | 42 | 43 | 44 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /fosdem/one.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | template slidePerformant* = 4 | slide: 5 | nbText: "### 🏎️ Performant: compiles natively" 6 | #nbText: "_todo: matrix multiplications_" 7 | nbCode: 8 | const N = 3 9 | type Matrix = array[N, array[N, int]] 10 | 11 | let 12 | A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 13 | B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]] 14 | 15 | func `*`(a, b: Matrix): Matrix = 16 | for i in 0 ..< N: 17 | for j in 0 ..< N: 18 | for k in 0 ..< N: 19 | result[i][j] += a[i][k]*b[k][j] 20 | 21 | echo A*B 22 | 23 | reference "[HPC from Python to Nim (Fosdem 2022)](https://archive.fosdem.org/2022/schedule/event/nim_hpcfrompythontonim/)" 24 | 25 | template slideSyntaxFlexible* = 26 | slide: 27 | nbText: "### Pythonic Syntax with 🤸‍♂️ Extra Flexibility" 28 | nbCode: 29 | type Counter = object 30 | val: int 31 | 32 | var counter = Counter(val: 0) 33 | echo(counter) 34 | 35 | nbCode: 36 | proc inc(c: var Counter) = inc c.val 37 | 38 | # all the following are equivalent 🤸‍♂️ 39 | inc counter # command syntax 40 | inc(counter) # function syntax 41 | counter.inc # method syntax 42 | 43 | echo counter 44 | 45 | nbTextSmall "\"Concise code is not in conflict with readability, it enables readability\", [Zen of Nim](https://nim-lang.org/blog/2021/11/15/zen-of-nim.html)" 46 | 47 | mySlide(procedureOverloading): 48 | nbText "### Procedure Overloading" 49 | nbCode: 50 | type 51 | Cat = object 52 | Dog = object 53 | 54 | proc speak(c: Cat) = echo "meow" 55 | proc speak(d: Dog) = echo "woof" 56 | 57 | let 58 | fuffi = Cat() 59 | fido = Dog() 60 | 61 | fuffi.speak 62 | fido.speak 63 | nbText "💎 the advantages of OOP without full blown OOP 💎" 64 | 65 | template slideInterop* = 66 | 67 | slide: 68 | nbText: "### 🤝 Interop with Python 🐍" 69 | nbText: fmt""" 70 | 71 | `fibonacci.nim` 72 | {tripleBackticks}nim 73 | import nimpy 74 | 75 | func fib*(n: int): int {bOpen}. exportpy .{bClose} = 76 | if n < 2: 1 else: fib(n - 1) + fib(n - 2) 77 | {tripleBackticks} 78 | 79 | `main.py` 80 | {tripleBackticks}python 81 | import nimporter 82 | from fibonacci import fib 83 | 84 | print(fib(10)) 85 | {tripleBackticks} 86 | 87 | {tripleBackticks} 88 | python3 main.py 89 | {tripleBackticks} 90 | 91 | {tripleBackticks} 92 | 89 93 | {tripleBackticks} 94 | 95 | """ 96 | 97 | reference "[yglukhov/nimpy](https://github.com/yglukhov/nimpy)" 98 | reference "[Pebaz/nimporter](https://github.com/Pebaz/nimporter)" 99 | 100 | 101 | mySlide(effectsTracking): 102 | nbText "### Functional Powers 🧠 Effects tracking" 103 | nbRawHtml adaptiveColumnsHtml 104 | nbRawHtml "
" 105 | nbCode: 106 | let aGlobal = 42 107 | 108 | proc withSideEffects(x: int): int = 109 | echo "writing ", x, " in a file" 110 | "IcanDo.IO".writeFile($x) 111 | x + aGlobal 112 | 113 | echo withSideEffects(624) 114 | echo "IcanDo.IO".readFile 115 | nbRawHtml "
" 116 | 117 | nbRawHtml "
" 118 | nbText "⠀" 119 | nbRawHtml "
" 120 | 121 | nbRawHtml "
" 122 | nbCode: 123 | func noSideEffects(x: int): int = 124 | # in a func compiler will error 125 | # if you try to do I/O or access global ... 126 | x + 42 127 | 128 | echo noSideEffects(-42) 129 | nbRawHtml "
" 130 | nbRawHtml "
" 131 | 132 | template effectsTrackingBug* {.dirty.} = 133 | nbText "### Functional Powers 🧠 Effects tracking" 134 | columns: 135 | column: 136 | nbCode: 137 | let aGlobal = 42 138 | 139 | proc withSideEffects(x: int): int = 140 | echo "writing ", x, " in a file" 141 | "IcanDo.IO".writeFile($x) 142 | x + aGlobal 143 | 144 | echo withSideEffects(624) 145 | echo "IcanDo.IO".readFile 146 | 147 | column: 148 | nbText "⠀" 149 | 150 | column: 151 | nbCode: 152 | func noSideEffects(x: int): int = 153 | # in a func compiler will error 154 | # if you try to do I/O or access global ... 155 | x + 42 156 | 157 | echo noSideEffects(-42) 158 | 159 | 160 | template okazzu* = 161 | slide(slideOptions(iframeBackground="okazzu.html")): 162 | discard 163 | 164 | mySlide(backends): 165 | nbText """## compiler backends ⚙️ 166 | - C 167 | - C++ 168 | - Objective-C 169 | - Javascript 🤯 170 | 171 | FFI: Foreign Function Interface 172 | """ 173 | speakerNote """ 174 | - very pragmatic choice 175 | - C is the primary (default) backend 176 | - C++ allows for best-in-class interoperability with C++ libraries (e.g. Unreal engine) 177 | - backends are treated like assembler 178 | - you will use a single backend at the time (but you can use when clauses) 179 | """ 180 | 181 | mySlide(metaFormat): 182 | nbCode: 183 | import std / strformat 184 | let here = "Brussels" 185 | let there = "Milan" 186 | let minutes = 10*60+15 187 | echo fmt"from {here} to {there} the train takes {time.float / 60:.2f} hours" 188 | 189 | template metaprogrammingBug* {. dirty .} = # dirty fixes it! 190 | import std / strformat # move outside of nbCode 191 | nbCode: 192 | let 193 | home = "Milan" 194 | h = (10*60+15).float / 60 195 | 196 | echo fmt"from Brussels to {home} the train takes {h:.1f} hours" 197 | 198 | template metaprogramming* {. dirty .} = 199 | slide: 200 | nbText "## Metaprogramming 🦸" 201 | # add quote from Zen of Nim (Leverage meta programming to keep the language small.) 202 | import std / strformat # move outside of nbCode 203 | nbCodeInBlock: # to counter dirty 204 | let 205 | home = "Milan" 206 | h = (10*60+15).float / 60 207 | 208 | echo fmt"from Brussels to {home} the train takes {h:.1f} hours" 209 | nbText "the `echo fmt\"...\"` statement is transformed at **compile time** into something like" 210 | nbCodeSkip: 211 | var temp = "" 212 | temp.add "from Brussels to " 213 | temp.formatValue(home, "") 214 | temp.add " the train takes " 215 | temp.formatValue(h, ".2f") 216 | temp.add " hours" 217 | 218 | 219 | template metaprogrammingAnimated* {. dirty .} = 220 | import std / strformat # move outside of nbCode 221 | autoAnimateSlides(3): 222 | showFrom(1): 223 | nbText "## Metaprogramming 🦸" 224 | # add quote from Zen of Nim (Leverage meta programming to keep the language small.) 225 | 226 | showFrom(2): 227 | nbCodeInBlock: # to counter dirty 228 | let 229 | home = "Milan" 230 | h = (10*60+15).float / 60 231 | 232 | echo fmt"from Brussels to {home} the train takes {h:.1f} hours" 233 | 234 | showFrom(3): 235 | nbText "the `echo fmt\"...\"` statement is transformed at **compile time** into something like" 236 | nbCodeSkip: 237 | var temp = "" 238 | temp.add "from Brussels to " 239 | temp.formatValue(home, "") 240 | temp.add " the train takes " 241 | temp.formatValue(h, ".2f") 242 | temp.add " hours" 243 | 244 | template interactivity* = 245 | slide: 246 | nbRawHtml """ 247 | 257 | """ 258 | nbText """ 259 | ## Interactivity 🪄 260 | 261 | ```nim 262 | button: 263 | text "Say hi!" 264 | proc onclick(ev: Event; n: VNode) = 265 | waves.add "👋" 266 | tdiv: 267 | text waves 268 | ``` 269 | """ 270 | nbKaraxCode: 271 | from jsony import toJson 272 | var waves = "".kstring 273 | karaxHtml: 274 | button: 275 | text "Say hi!" 276 | proc onclick(ev: Event; n: VNode) = 277 | waves.add "👋" 278 | tdiv: 279 | text waves 280 | 281 | template all* = 282 | slidePerformant # change compiles to C to native compilation! 283 | slideSyntaxFlexible 284 | procedureOverloading 285 | effectsTracking 286 | metaprogrammingAnimated 287 | slideInterop 288 | interactivity 289 | backends 290 | okazzu 291 | 292 | when isMainModule: 293 | myInit("one.nim") 294 | all 295 | nbSave 296 | -------------------------------------------------------------------------------- /fosdem/pyconit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/nim-for-pythonistas/ce311b6dec92c602f096dd1eb713abcbc8b4be59/fosdem/pyconit.png -------------------------------------------------------------------------------- /fosdem/three.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | mySlide(easierOpenSource): 4 | nbText "### Easier Open Source 🎋" 5 | nbText "1. Idea" 6 | nbCode: 7 | import nimoji 8 | echo "I :heart: :pizza: and :beer:".emojize 9 | nbText """2. Code 10 | 11 | ```nim 12 | nimble init # ... 13 | ``` 14 | 15 | 3. Publish 16 | 17 | ```nim 18 | nimble publish # opens a PR to a packages.json 19 | ``` 20 | 21 | """ 22 | 23 | template easierOpenSourceAnimated* = 24 | import nimoji 25 | autoAnimateSlides(5): 26 | showFrom(1): 27 | nbText "### Easier Open Source 🎋" 28 | showFrom(2): 29 | nbText "1. Idea" 30 | showFrom(3): 31 | nbCodeSkip: 32 | import nimoji 33 | echo "I :heart: :pizza: and :beer:".emojize 34 | nbText "```\nI ❤️ 🍕 and 🍺\n```" 35 | showFrom(4): 36 | nbText """ 37 | 2. Code 38 | 39 | ```nim 40 | nimble init # ... 41 | ``` 42 | """ 43 | showFrom(5): 44 | nbText """ 45 | 3. Publish 46 | 47 | ```nim 48 | nimble publish # opens a PR to a packages.json 49 | ``` 50 | 51 | """ 52 | 53 | 54 | 55 | mySlide(nimibLiterate): 56 | nbText: "### Nimib as 'Literate Programming'" 57 | nbFile("hello.nim"): """ 58 | import nimib 59 | 60 | nbInit 61 | 62 | nbText "A sample program with _Nimib_" 63 | 64 | nbCode: 65 | echo "hello RC!" 66 | 67 | nbSave 68 | """ 69 | nbText: "`nim r hello`" 70 | 71 | #slideIframe(nimibShow, "hello.html") 72 | template nimibShow* = 73 | slide(slideOptions(iframeBackground="../hello.html")): 74 | discard 75 | 76 | mySlide(nimibPy): 77 | nbText: """### [Nimib.py]() 78 | """ 79 | nbFile("hi.py"): """ 80 | import nimib as nb 81 | 82 | nb.init() 83 | 84 | nb.text("Welcome to `nimib.py`!") 85 | 86 | message = "hello" 87 | 88 | with nb.code(): 89 | print(message) 90 | 91 | nb.save() 92 | """ 93 | nbText: "`python hi.py`" 94 | speakerNote: """ 95 | Thanks to advent of code 96 | """ 97 | 98 | #slideIframe(nimibPyShow, "https://nimib.land/nimib.py/hi.html") 99 | template nimibPyShow* = 100 | slide(slideOptions(iframeBackground="https://nimib.land/nimib.py/hi.html")): 101 | discard 102 | 103 | #slideIframe(adventOfCode, "https://pietroppeter.github.io/adventofcode2023/day25/solution.html"): 104 | # nbText "# 🎄👨‍💻" 105 | template adventOfCode* = 106 | slide(slideOptions(iframeBackground="https://pietroppeter.github.io/adventofcode2023/day25/solution.html")): 107 | nbText "# 🎄👨‍💻" 108 | 109 | template nimislides* = 110 | slide: 111 | nbText """## 🛝 Slides with Nim(ib)""" 112 | nbCodeSkip: 113 | mySlide(all): 114 | nbText "## Agenda"& 115 | "\n1. " & oneShort & 116 | "\n2. " & twoShort & 117 | "\n3. " & threeShort 118 | 119 | template section(number: untyped) = 120 | mySlide(number): 121 | nbText "### " & `number Short` 122 | nbText `number Long` 123 | 124 | section(one) 125 | section(two) 126 | section(three) 127 | 128 | reference "[nimislides](), thanks Hugo!💘" 129 | 130 | template plantApp* = 131 | slide(slideOptions(iframeBackground="../plant_app.html")): 132 | discard 133 | 134 | template nimibLand* = 135 | slide: 136 | nbText "## Nimib(Land) 🐳" 137 | 138 | template nimibPyscript* = 139 | slide(slideOptions(iframeBackground="bunny.html")): 140 | discard 141 | 142 | 143 | 144 | template all* = 145 | easierOpenSourceAnimated 146 | nimibLand 147 | plantApp 148 | nimibLiterate 149 | nimibShow 150 | nimiSlides 151 | nimibPy 152 | nimibPyShow 153 | nimibPyscript 154 | 155 | when isMainModule: 156 | myInit("three") 157 | all 158 | nbSave 159 | -------------------------------------------------------------------------------- /fosdem/title.nim: -------------------------------------------------------------------------------- 1 | import nimib except toJson 2 | import nimislides, nbex 3 | 4 | template titleSlide* = 5 | slide(slideOptions(imageBackground="../crown.webp")): 6 | # hacky value for bottom since I do not understand boxes 7 | divStyled("font-size:1.5rem;"): 8 | discard 9 | 10 | slide(slideOptions(imageBackground="../crown.webp")): 11 | divStyled("background-color:rgb(161, 45, 148);"): 12 | h1Color(nimYellow): "Nim for Pythonistas" 13 | h2Color(nimYellow): "(and Open Source Lovers)" 14 | h2Color(nimYellow): "FOSDEM, Brussels, Feb 2nd 2025" 15 | spanColor(blueForFosdem): "github.com/pietroppeter/nim-for-pythonistas" 16 | 17 | when isMainModule: 18 | myInit("title") 19 | titleSlide 20 | nbSave -------------------------------------------------------------------------------- /fosdem/two.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | template threethingsAnimated*(titolo, uno, due, tre: string, reverse=false) = 4 | autoAnimateSlides(4): 5 | nbText: titolo 6 | showText(@[ 7 | ({1.int255, 2, 3, 4}, "- " & uno[0]), 8 | ((if reverse: {4.int255} else: {2.int255, 3, 4}), uno[1 .. ^1]), 9 | ]) 10 | showText(@[ 11 | ({1.int255, 2, 3, 4}, "- " & due[0]), 12 | ({3.int255, 4}, due[1 .. ^1]), 13 | ]) 14 | showText(@[ 15 | ({1.int255, 2, 3, 4}, "- " & tre[0]), 16 | ((if reverse: {2.int255, 3, 4} else: {4.int255}), tre[1 .. ^1]), 17 | ]) 18 | 19 | template likePythonAnimated* = 20 | threethingsAnimated( 21 | "## 3 things I like about Python 🐝", 22 | "Accessibility", 23 | "Playfulness", 24 | "Everything", 25 | ) 26 | 27 | template strugglePythonAnimated* = 28 | threethingsAnimated( 29 | "## 3 things I struggle with Python 🙊", 30 | "Abstraction", 31 | "Portability", 32 | "Errors", 33 | reverse = true 34 | ) 35 | 36 | template quoteSlide(who: string, what: string, ident: untyped) = 37 | mySlide(ident): 38 | nbText: "> " & what & "\n\n" & who 39 | 40 | quoteSlide("David Beazley, March 2023", """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.""", 41 | beazley) 42 | 43 | quoteSlide("Guido Van Rossum, King's Day Speech, 2016", """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.""", 44 | guidoPythonMainIdea) 45 | 46 | mySlide(nicheCommunity): 47 | nbText "### Niche community 💌" 48 | 49 | mySlide(colorLanguage): 50 | nbText "### Color of a Language 🎨" 51 | columns: 52 | column: 53 | nbImage "../languages-color.png" 54 | nbText "[forum.nim-lang.org](https://forum.nim-lang.org/t/6350#39982)" 55 | column: 56 | nbImage "https://github.com/PMunch/colourfinder/raw/master/goodcolours.png" 57 | 58 | template all* = 59 | beazley 60 | 61 | likePythonAnimated # low floor, no ceiling 62 | strugglePythonAnimated 63 | 64 | nicheCommunity 65 | colorLanguage 66 | 67 | guidoPythonMainIdea 68 | 69 | when isMainModule: 70 | myInit("two") 71 | all 72 | nbSave 73 | -------------------------------------------------------------------------------- /four.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | 4 | mySlide(zenOfNim): 5 | nbText: "### Zen of Nim" 6 | nbText: """ 7 | ```md 8 | 1. Copying bad design is not good design. 9 | 2. If the compiler cannot reason about the code, 10 | neither can the programmer. 11 | 3. Don’t get in the programmer’s way. 12 | 4. Move work to compile-time: 13 | Programs are run more often than they are compiled. 14 | 5. Customizable memory management. 15 | 6. Concise code is not in conflict with readability, 16 | it enables readability. 17 | 7. (Leverage meta programming to keep the language small.) 18 | 8. Optimization is specialization: 19 | When you need more speed, write custom code. 20 | 9. There should be one and only one programming language 21 | for everything. 22 | That language is Nim. 23 | ``` 24 | """ 25 | 26 | template ruleTheMole* = 27 | slide(slideOptions(iframeBackground="https://forum.nim-lang.org/t/8780")): 28 | discard 29 | 30 | # slideIframe(ruleTheMole, "https://forum.nim-lang.org/t/8780") 31 | 32 | mySlide(easierOwnership): 33 | nbText "### Easier ownership 💌" 34 | 35 | mySlide(growingCulture): 36 | nbText "### Growing Culture 🎏" 37 | 38 | mySlide(easierOpenSource): 39 | nbText "### Easier Open Source 🎋" 40 | 41 | mySlide(colorLanguage): 42 | nbText "### Color of a Language 🎨" 43 | columns: 44 | column: 45 | nbImage "languages-color.png" 46 | nbText "[forum.nim-lang.org](https://forum.nim-lang.org/t/6350#39982)" 47 | column: 48 | nbImage "https://github.com/PMunch/colourfinder/raw/master/goodcolours.png" 49 | 50 | mySlide(nimibLiterate): 51 | nbText: "### Nimib as 'Literate Programming'" 52 | nbFile("hello.nim"): """ 53 | import nimib 54 | 55 | nbInit 56 | 57 | nbText "A sample program with _Nimib_" 58 | 59 | nbCode: 60 | echo "hello RC!" 61 | 62 | nbSave 63 | """ 64 | nbText: "`nim r hello`" 65 | 66 | #slideIframe(nimibShow, "hello.html") 67 | template nimibShow* = 68 | slide(slideOptions(iframeBackground="hello.html")): 69 | discard 70 | 71 | mySlide(nimibPy): 72 | nbText: """### [Nimib.py]() 73 | """ 74 | nbFile("hi.py"): """ 75 | import nimib as nb 76 | 77 | nb.init() 78 | 79 | nb.text("Welcome to `nimib.py`!") 80 | 81 | message = "hello" 82 | 83 | with nb.code(): 84 | print(message) 85 | 86 | nb.save() 87 | """ 88 | nbText: "`python hi.py`" 89 | speakerNote: """ 90 | Thanks to advent of code 91 | """ 92 | 93 | #slideIframe(nimibPyShow, "https://nimib.land/nimib.py/hi.html") 94 | template nimibPyShow* = 95 | slide(slideOptions(iframeBackground="https://nimib.land/nimib.py/hi.html")): 96 | discard 97 | 98 | #slideIframe(adventOfCode, "https://pietroppeter.github.io/adventofcode2023/day25/solution.html"): 99 | # nbText "# 🎄👨‍💻" 100 | template adventOfCode* = 101 | slide(slideOptions(iframeBackground="https://pietroppeter.github.io/adventofcode2023/day25/solution.html")): 102 | nbText "# 🎄👨‍💻" 103 | 104 | template nimislides* = 105 | slide: 106 | nbText """## 🛝 Slides with Nim(ib)""" 107 | nbCodeSkip: 108 | autoAnimateSlides(7): 109 | nbText "## Me 👨‍👩‍👧" 110 | showFrom(3): 111 | nbText "🐍 Pythonista" 112 | showFrom(4): 113 | nbText "🧮 (applied) Mathematician" 114 | showFrom(2): 115 | nbText "🧑‍🔬 Data Scientist" 116 | showFrom(6): 117 | nbText "👑 [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/)" 118 | showFrom(5): 119 | nbText "🍸 Python Milano and PyData Milan: [milano.python.it](milano.python.it)" 120 | showFrom(7): 121 | nbText "🐙 Recurse Center: [recurse.com](recurse.com)" 122 | 123 | reference "[nimislides](), thanks Hugo!💘" 124 | template all* = 125 | easierOwnership 126 | colorLanguage 127 | 128 | growingCulture 129 | zenOfNim 130 | ruleTheMole 131 | 132 | easierOpenSource 133 | nimibLiterate 134 | nimibShow 135 | nimiSlides 136 | nimibPy 137 | nimibPyShow 138 | adventOfCode 139 | 140 | when isMainModule: 141 | myInit("four") 142 | all 143 | nbSave 144 | -------------------------------------------------------------------------------- /hello.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | hello.nim 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 | 47 | 48 | 49 |
50 |
51 | 🏡 52 | hello.nim 53 | 54 |
55 |
56 |
57 |

A sample program with Nimib

58 |
echo "hello RC!"
hello RC!
59 |
60 | 67 |
68 |
import nimib
69 | 
70 | nbInit
71 | 
72 | nbText "A sample program with _Nimib_"
73 | 
74 | nbCode:
75 |     echo "hello RC!"
76 | 
77 | nbSave
78 | 
79 |
92 | -------------------------------------------------------------------------------- /hello.nim: -------------------------------------------------------------------------------- 1 | import nimib 2 | 3 | nbInit 4 | 5 | nbText "A sample program with _Nimib_" 6 | 7 | nbCode: 8 | echo "hello RC!" 9 | 10 | nbSave 11 | -------------------------------------------------------------------------------- /hi.py: -------------------------------------------------------------------------------- 1 | import nimib as nb 2 | 3 | nb.init() 4 | 5 | nb.text("Welcome to `nimib.py`!") 6 | 7 | message = "hello" 8 | 9 | with nb.code(): 10 | print(message) 11 | 12 | nb.save() 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |

Nim for Pythonistas

20 |

PyCon 🇮🇹, May 24th 2024

21 | github.com/pietroppeter/nim-for-pythonistas 22 |
23 |
24 |
25 |
26 |
let 💬 = "Ciao PyCon"
 27 | for i in -5 .. 5:
 28 |   echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
 29 |     C    i    a    o         P    y    C    o    n
 30 |    C   i   a   o       P   y   C   o   n
 31 |   C  i  a  o     P  y  C  o  n
 32 |  C i a o   P y C o n
 33 | Ciao PyCon
 34 |  C i a o   P y C o n
 35 |   C  i  a  o     P  y  C  o  n
 36 |    C   i   a   o       P   y   C   o   n
 37 |     C    i    a    o         P    y    C    o    n
 38 |      C     i     a     o           P     y     C     o     n
39 |

Nim is a programming language

40 |
41 |
42 |
let 💬 = "Ciao PyCon"
 43 | for i in -5 .. 5:
 44 |   echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
 45 |     C    i    a    o         P    y    C    o    n
 46 |    C   i   a   o       P   y   C   o   n
 47 |   C  i  a  o     P  y  C  o  n
 48 |  C i a o   P y C o n
 49 | Ciao PyCon
 50 |  C i a o   P y C o n
 51 |   C  i  a  o     P  y  C  o  n
 52 |    C   i   a   o       P   y   C   o   n
 53 |     C    i    a    o         P    y    C    o    n
 54 |      C     i     a     o           P     y     C     o     n
55 |

Nim is a systems programming language

56 |
57 |
58 |
let 💬 = "Ciao PyCon"
 59 | for i in -5 .. 5:
 60 |   echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
 61 |     C    i    a    o         P    y    C    o    n
 62 |    C   i   a   o       P   y   C   o   n
 63 |   C  i  a  o     P  y  C  o  n
 64 |  C i a o   P y C o n
 65 | Ciao PyCon
 66 |  C i a o   P y C o n
 67 |   C  i  a  o     P  y  C  o  n
 68 |    C   i   a   o       P   y   C   o   n
 69 |     C    i    a    o         P    y    C    o    n
 70 |      C     i     a     o           P     y     C     o     n
71 |

Nim is a statically typed and compiled
systems programming language

72 |
73 |
74 |
let 💬 = "Ciao PyCon"
 75 | for i in -5 .. 5:
 76 |   echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join()
     C     i     a     o           P     y     C     o     n
 77 |     C    i    a    o         P    y    C    o    n
 78 |    C   i   a   o       P   y   C   o   n
 79 |   C  i  a  o     P  y  C  o  n
 80 |  C i a o   P y C o n
 81 | Ciao PyCon
 82 |  C i a o   P y C o n
 83 |   C  i  a  o     P  y  C  o  n
 84 |    C   i   a   o       P   y   C   o   n
 85 |     C    i    a    o         P    y    C    o    n
 86 |      C     i     a     o           P     y     C     o     n
87 |

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

88 |
89 |
90 |

Me 👨‍👩‍👧

91 |
92 |
93 |

Me 👨‍👩‍👧

94 |

🧑‍🔬 Data Scientist

95 |
96 |
97 |

Me 👨‍👩‍👧

98 |

🐍 Pythonista

99 |

🧑‍🔬 Data Scientist

100 |
101 |
102 |

Me 👨‍👩‍👧

103 |

🐍 Pythonista

104 |

🧮 (applied) Mathematician

105 |

🧑‍🔬 Data Scientist

106 |
107 |
108 |

Me 👨‍👩‍👧

109 |

🐍 Pythonista

110 |

🧮 (applied) Mathematician

111 |

🧑‍🔬 Data Scientist

112 |

🍸 Python Milano and PyData Milan: milano.python.it

113 |
114 |
115 |

Me 👨‍👩‍👧

116 |

🐍 Pythonista

117 |

🧮 (applied) Mathematician

118 |

🧑‍🔬 Data Scientist

119 |

👑 HN: Programming Language Underdog (2018)

120 |

🍸 Python Milano and PyData Milan: milano.python.it

121 |
122 |
123 |

Me 👨‍👩‍👧

124 |

🐍 Pythonista

125 |

🧮 (applied) Mathematician

126 |

🧑‍🔬 Data Scientist

127 |

👑 HN: Programming Language Underdog (2018)

128 |

🍸 Python Milano and PyData Milan: milano.python.it

129 |

🐙 Recurse Center: recurse.com

130 |
131 |
132 |
133 |

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.

134 |
135 |

David Beazley, March 2023

136 |
137 |
138 |
139 | 140 |
141 |
142 |
143 |
144 |

3 things I like about Python 🐝

145 |

- A

146 |

- P

147 |

- E

148 |
149 |
150 |

3 things I like about Python 🐝

151 |

- Accessibility

152 |

- P

153 |

- E

154 |
155 |
156 |

3 things I like about Python 🐝

157 |

- Accessibility

158 |

- Playfulness

159 |

- E

160 |
161 |
162 |

3 things I like about Python 🐝

163 |

- Accessibility

164 |

- Playfulness

165 |

- Everything

166 |
167 |
168 |

3 things I struggle with Python 🙊

169 |

- A

170 |

- P

171 |

- E

172 |
173 |
174 |

3 things I struggle with Python 🙊

175 |

- A

176 |

- P

177 |

- Errors

178 |
179 |
180 |

3 things I struggle with Python 🙊

181 |

- A

182 |

- Portability

183 |

- Errors

184 |
185 |
186 |

3 things I struggle with Python 🙊

187 |

- Abstraction

188 |

- Portability

189 |

- Errors

190 |
191 |
192 |
193 |

Agenda

194 |
    195 |
  1. Easy and fast (+ superpowers 🦸)
  2. 196 |
  3. Compiler (and types)
  4. 197 |
  5. Multiple backends (Javascript 🤯)
  6. 198 |
  7. A Niche tech (and me)
  8. 199 |
200 | 209 |
210 |
211 |
212 |

Easy and fast (+ superpowers 🦸)

213 |

nim is an easy to learn and fast complement to Python (with metaprogramming 🦸)

214 |
215 |
216 |

🏎️ Performant: compiles natively

217 |
const N = 3
218 | type Matrix = array[N, array[N, int]]
219 | 
220 | let
221 |   A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
222 |   B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]]
223 | 
224 | func `*`(a, b: Matrix): Matrix =
225 |   for i in 0 ..< N:
226 |     for j in 0 ..< N:
227 |       for k in 0 ..< N:
228 |         result[i][j] += a[i][k]*b[k][j]
229 | 
230 | echo A*B
[[1, 3, 6], [4, 9, 15], [7, 15, 24]]
231 |

HPC from Python to Nim (Fosdem 2022)

232 |
233 |
234 |

Pythonic Syntax with 🦸 Superpowers

235 |
236 |
237 |
type
238 |   Grid = array[3, array[3, Cell]]
239 |   Cell = enum X, O
240 | 
241 | func initGrid: Grid =
242 |   [[X,O,X],[O,X,O],[X,O,X]]
243 | 
244 | proc show(g: Grid) =
245 |   for row in g:
246 |     echo row
247 | 
248 | proc update(g: var Grid) =
249 |   for i in g.low .. g.high:
250 |     for j in g[i].low .. g[i].high:
251 |       g[i][j] = if g[i][j] == X: O else: X
252 |
    253 |
  • 🦸 syntax fits well with metaprogramming
  • 254 |
  • 💡 UFCS (Uniform Function Call Syntax)
  • 255 |
256 |
257 |
258 |

259 |
260 |
261 |
var g = initGrid()
262 | show g # command
[X, O, X]
263 | [O, X, O]
264 | [X, O, X]
265 |
g.update # method
266 | g.show
[O, X, O]
267 | [X, O, X]
268 | [O, X, O]
269 |
update(g) # function
270 | show(g)
[X, O, X]
271 | [O, X, O]
272 | [X, O, X]
273 |
274 |
275 |
276 |
277 |

🦸 Metaprogramming

278 |
    279 |
  1. Generics
  2. 280 |
  3. Templates
  4. 281 |
  5. Macros (AST)
  6. 282 |
283 |

AST: Abstract Syntax Tree

284 |

DSL: Domain Specific Language

285 |
286 |

with power comes responsibility

287 |
288 |
289 |
290 |

🤝 Interop with Python

291 |

fibonacci.nim

292 |
import nimpy
293 | 
294 | func fib*(n: int): int {. exportpy .} =
295 |   if n < 2: 1 else: fib(n - 1) + fib(n - 2)
296 | 
297 |

main.py

298 |
import nimporter
299 | from fibonacci import fib
300 | 
301 | print(fib(10))
302 | 
303 |
python3 main.py
304 | 
305 |
89
306 | 
307 |

nimporter

308 |

nimpy

309 |
310 |
311 |
312 |
313 |

Compiler (and types)

314 |

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

315 |
316 |
317 |

const for compile time evaluation

318 |
import std / [sequtils, strutils]
319 | 
320 | func fizzBuzz(n: int): string = 
321 |   case n mod 15
322 |   of 0: "FizzBuzz"
323 |   of 3, 6, 9, 12: "Fizz"
324 |   of 5, 10: "Buzz"
325 |   else: $n
326 | 
327 | const result = (1 .. 15).toSeq.mapIt(it.fizzBuzz).join()
328 | 
329 | echo result
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz
330 |
331 |
332 |

let and var for safe mutability

333 |
334 |
335 |

let is a (runtime defined) immutable value

336 |
let x = 1
337 | x = x + 1
338 | # Error: 'x' cannot be assigned to
339 | 
340 |
341 |
342 |

use var for a mutable variable

343 |
var x = 1
344 | inc x
345 | echo x
2
346 |
347 |
348 |
349 |
350 |

var parameters

351 |

use var for a mutable parameter

352 |
proc divmod(a, b: int; q, r: var int) =
353 |   q = a div b
354 |   r = a mod b
355 | 
356 | var q, r: int
357 | 
358 | echo (q, r)
359 | divmod(8, 5, q, r) # modifies q and r
360 | echo (q, r)
(0, 0)
361 | (1, 3)
362 |
363 |
364 |

Effects tracking

365 |
366 |
367 |
let aGlobal = 42
368 | 
369 | proc withSideEffects(x: int): int =
370 |   echo "writing ", x, " in a file"
371 |   "IcanDo.IO".writeFile($x)
372 |   x + aGlobal
373 | 
374 | echo withSideEffects(624)
375 | echo "IcanDo.IO".readFile
writing 624 in a file
376 | 666
377 | 624
378 |
379 |
380 |

381 |
382 |
383 |
func noSideEffects(x: int): int =
384 |   # in a func compiler will error
385 |   # if you try to do I/O or access global ...
386 |   x + 42
387 | 
388 | echo noSideEffects(-42)
0
389 |
390 |
391 |
392 |
393 |

Procedure Overloading

394 |
type
395 |   Cat = object
396 |   Dog = object
397 | 
398 | proc speak(c: Cat) = echo "meow"
399 | proc speak(d: Dog) = echo "woof"
400 | 
401 | let
402 |   fuffi = Cat()
403 |   fido = Dog()
404 | 
405 | fuffi.speak
406 | fido.speak
meow
407 | woof
408 |

(the advantages of OOP without full blown OOP)

409 |
410 |
411 |
412 |
413 |

Multiple backends (Javascript 🤯)

414 |

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

415 |
416 |
417 |

compiler backends

418 |
    419 |
  • C
  • 420 |
  • C++
  • 421 |
  • Objective-C
  • 422 |
  • Javascript
  • 423 |
424 |

FFI: Foreign Function Interface

425 | 435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |

A Niche tech (and me)

444 |

Why should I invest in a niche tech?

445 |
446 |
447 |

Easier ownership 💌

448 |
449 |
450 |

Color of a Language 🎨

451 |
452 |
453 |
454 | 455 |
456 |
457 |

forum.nim-lang.org

458 |
459 |
460 |
461 | 462 |
463 |
464 |
465 |
466 |
467 |
468 |

Growing Culture 🎏

469 |
470 |
471 |

Zen of Nim

472 |
1. Copying bad design is not good design.
473 | 2. If the compiler cannot reason about the code,
474 |    neither can the programmer.
475 | 3. Don’t get in the programmer’s way.
476 | 4. Move work to compile-time:
477 |    Programs are run more often than they are compiled.
478 | 5. Customizable memory management.
479 | 6. Concise code is not in conflict with readability,
480 |    it enables readability.
481 | 7. (Leverage meta programming to keep the language small.)
482 | 8. Optimization is specialization:
483 |    When you need more speed, write custom code.
484 | 9. There should be one and only one programming language
485 |    for everything.
486 |    That language is Nim.
487 | 
488 |
489 |
490 |
491 |
492 |

Easier Open Source 🎋

493 |
494 |
495 |

Nimib as 'Literate Programming'

496 |
hello.nim
497 |
import nimib
498 | 
499 | nbInit
500 | 
501 | nbText "A sample program with _Nimib_"
502 | 
503 | nbCode:
504 |     echo "hello RC!"
505 | 
506 | nbSave
507 | 
508 | 509 |

nim r hello

510 |
511 |
512 |
513 |
514 |

🛝 Slides with Nim(ib)

515 |
autoAnimateSlides(7):
516 |   nbText "## Me 👨‍👩‍👧"
517 |   showFrom(3):
518 |     nbText "🐍 Pythonista"
519 |   showFrom(4):
520 |     nbText "🧮 (applied) Mathematician"
521 |   showFrom(2):
522 |     nbText "🧑‍🔬 Data Scientist"
523 |   showFrom(6):
524 |     nbText "👑 [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/)"
525 |   showFrom(5):
526 |     nbText "🍸 Python Milano and PyData Milan: [milano.python.it](milano.python.it)"
527 |   showFrom(7):
528 |     nbText "🐙 Recurse Center: [recurse.com](recurse.com)"
529 |

nimislides, thanks Hugo!💘

530 |
531 |
532 |

Nimib.py

533 |
hi.py
534 |
import nimib as nb
535 | 
536 | nb.init()
537 | 
538 | nb.text("Welcome to `nimib.py`!")
539 | 
540 | message = "hello"
541 | 
542 | with nb.code():
543 |     print(message)
544 | 
545 | nb.save()
546 | 
547 | 548 |

python hi.py

549 | 553 |
554 |
555 |
556 |
557 |

🎄👨‍💻

558 |
559 |
560 |
561 |
562 |

Conclusions

563 |

To improve as a programmer:

564 |
    565 |
    566 | 567 |
  • 568 |

    ✨ new language!

    569 |
  • 570 |
    571 | 572 |
    573 | 574 |
  • 575 |

    🗻 new domain!

    576 |
  • 577 |
    578 | 579 |
    580 | 581 |
  • 582 |

    👑 Nim?

    583 |
  • 584 |
    585 | 586 |
    587 | 588 |
  • 589 |

    🐣 Niche?

    590 |
  • 591 |
    592 | 593 |
594 |
595 |
596 |
597 |

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.

598 |
599 |

Guido Van Rossum, King's Day Speech, 2016

600 |
601 |
602 |
603 |
604 | 605 | 606 | 607 | 615 | 616 | 617 | -------------------------------------------------------------------------------- /index.nim: -------------------------------------------------------------------------------- 1 | import nimib except toJson 2 | import nimislides, nbex 3 | import title, intro, agenda, one, two, three, four, conclusions 4 | 5 | when isMainModule: 6 | myInit("index") 7 | titleSlide 8 | slide: 9 | intro.all 10 | agenda.all 11 | slide: 12 | agenda.one 13 | one.all 14 | slide: 15 | agenda.two 16 | two.all 17 | slide: 18 | agenda.three 19 | three.all 20 | slide: 21 | agenda.four 22 | four.all 23 | slide: 24 | conclusions.all 25 | nbSave -------------------------------------------------------------------------------- /intro.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | import quotes 3 | 4 | mySlide(helloPyCon): 5 | nbCode: 6 | import sequtils, strutils 7 | let 💬 = "Ciao PyCon" 8 | for i in -5 .. 5: 9 | echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join() 10 | nbText "Nim is a statically typed and compiled \nsystems programming language for everything" 11 | 12 | 13 | template helloPyConAnimated* = 14 | import sequtils, strutils 15 | autoAnimateSlides(4): 16 | nbCode: 17 | let 💬 = "Ciao PyCon" 18 | for i in -5 .. 5: 19 | echo 💬.toSeq.mapIt(' '.repeat(abs(i)) & it).join() 20 | showText(@[ 21 | ({1.int255, 2, 3, 4}, "Nim is a"), 22 | ({3.int255, 4}, " statically typed and compiled
"), 23 | ({2.int255, 3, 4}, " systems"), 24 | ({1.int255, 2, 3, 4}, " programming language"), 25 | ({4.int255}, "
good for everything"), 26 | ]) 27 | 28 | template meAnimated* = 29 | autoAnimateSlides(7): 30 | nbText "## Me 👨‍👩‍👧" 31 | showFrom(3): 32 | nbText "🐍 Pythonista" 33 | showFrom(4): 34 | nbText "🧮 (applied) Mathematician" 35 | showFrom(2): 36 | nbText "🧑‍🔬 Data Scientist" 37 | showFrom(6): 38 | nbText "👑 [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/)" 39 | showFrom(5): 40 | nbText "🍸 Python Milano and PyData Milan: [milano.python.it](milano.python.it)" 41 | showFrom(7): 42 | nbText "🐙 Recurse Center: [recurse.com](recurse.com)" 43 | 44 | minSlide(me): 45 | nbText """## Me 👨‍👩‍👧 46 | - Pythonista 47 | - (applied) mathematician 48 | - Data Scientist 49 | - [HN: Programming Language Underdog (2018)](https://totallywearingpants.com/posts/nim-underdog/) 50 | - Python Milano and PyData Milan: [milano.python.it](milano.python.it) 51 | - Recurse Center: [recurse.com](recurse.com) 52 | """ 53 | speakerNote """ 54 | When I mean for Pythonistas, in my idea audience for this talk 55 | I include myself. 56 | - I have worked the last few years as a Data Scientist 57 | - and I have a Pythonista since the late nineties 58 | - (took a break from Python while studying Math at the university) 59 | - I have started to be recently be much more involved in 60 | Python community as a Python Milano and PyData Milan co-organizer 61 | - but before that, a few years ago I ran into an article on Hacker News 62 | that talked about a programming language underdog. 63 | - somehow that encounter and the journey I am going to share 64 | is responsible for why I have been more active in Python community 65 | - as a final note, I will mention that some of the work for this presentation 66 | has been prepared while doing a batch at Recurse Center, 67 | which is a delightful place to improve your skills as a programmer 68 | surrounded by kind and generous people doing the same 69 | """ 70 | 71 | minSlide(therapy): 72 | nbText "## Therapy" 73 | speakerNote """ 74 | This could also serve as a therapy session for our relation 75 | with Python and its future, in case you happen to need one 76 | (add quotes from twitter) 77 | """ 78 | 79 | template therapySpongebob* = 80 | slide: 81 | nbImage("therapy_spongebob.gif") 82 | 83 | minSlide(likePython): 84 | nbText """## 3 things I like about Python 🐝 85 | - Accessibility 86 | - Playfulness 87 | - Everything 88 | """ 89 | 90 | template threethingsAnimated*(titolo, uno, due, tre: string, reverse=false) = 91 | autoAnimateSlides(4): 92 | nbText: titolo 93 | showText(@[ 94 | ({1.int255, 2, 3, 4}, "- " & uno[0]), 95 | ((if reverse: {4.int255} else: {2.int255, 3, 4}), uno[1 .. ^1]), 96 | ]) 97 | showText(@[ 98 | ({1.int255, 2, 3, 4}, "- " & due[0]), 99 | ({3.int255, 4}, due[1 .. ^1]), 100 | ]) 101 | showText(@[ 102 | ({1.int255, 2, 3, 4}, "- " & tre[0]), 103 | ((if reverse: {2.int255, 3, 4} else: {4.int255}), tre[1 .. ^1]), 104 | ]) 105 | 106 | template likePythonAnimated* = 107 | threethingsAnimated( 108 | "## 3 things I like about Python 🐝", 109 | "Accessibility", 110 | "Playfulness", 111 | "Everything", 112 | ) 113 | 114 | 115 | template likePythonAnimatedOld* = 116 | autoAnimateSlides(4): 117 | nbText: "## 3 things I like about Python 🐝" 118 | showText(@[ 119 | ({1.int255, 2, 3, 4}, "- A"), 120 | ({2.int255, 3, 4}, "ccessibility"), 121 | ]) 122 | showText(@[ 123 | ({1.int255, 2, 3, 4}, "- P"), 124 | ({3.int255, 4}, "layfulness"), 125 | ]) 126 | showText(@[ 127 | ({1.int255, 2, 3, 4}, "- E"), 128 | ({4.int255}, "verything"), 129 | ]) 130 | 131 | minSlide(strugglePython): 132 | nbText """## 3 things I struggle with Python 🙊 133 | - Abstraction 134 | - Portability 135 | - Errors 136 | """ 137 | 138 | template strugglePythonAnimated* = 139 | threethingsAnimated( 140 | "## 3 things I struggle with Python 🙊", 141 | "Abstraction", 142 | "Portability", 143 | "Errors", 144 | reverse = true 145 | ) 146 | 147 | template all* = 148 | helloPyConAnimated 149 | meAnimated 150 | Beazley 151 | therapySpongebob 152 | likePythonAnimated 153 | strugglePythonAnimated 154 | 155 | when isMainModule: 156 | myInit("intro") 157 | all 158 | nbSave -------------------------------------------------------------------------------- /languages-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/nim-for-pythonistas/ce311b6dec92c602f096dd1eb713abcbc8b4be59/languages-color.png -------------------------------------------------------------------------------- /lightning.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |

Nim 👑 for Pythonistas 🐍

14 |

github.com/pietroppeter/nim-for-pythonistas

15 |

⚡ @ PyCon🇸🇪 2023, Nov 10th

16 |

Pietro Peterlongo from Python Milano 🇮🇹

17 | 25 |
26 |
27 |

What is Nim 👑

28 |
29 |
30 |
let message = "Hi_PyConSE23!"
 31 | for i in 0 ..< message.len:
 32 |   echo message[0 .. i]
H
 33 | Hi
 34 | Hi_
 35 | Hi_P
 36 | Hi_Py
 37 | Hi_PyC
 38 | Hi_PyCo
 39 | Hi_PyCon
 40 | Hi_PyConS
 41 | Hi_PyConSE
 42 | Hi_PyConSE2
 43 | Hi_PyConSE23
 44 | Hi_PyConSE23!
45 |
46 |
47 |

Nim is a
programming language

48 |
49 |
50 |

A Programming Language Underdog (2018)

51 | 60 |
61 |
62 |

What is Nim 👑

63 |
64 |
65 |
let message = "Hi_PyConSE23!"
 66 | for i in 0 ..< message.len:
 67 |   echo message[0 .. i]
H
 68 | Hi
 69 | Hi_
 70 | Hi_P
 71 | Hi_Py
 72 | Hi_PyC
 73 | Hi_PyCo
 74 | Hi_PyCon
 75 | Hi_PyConS
 76 | Hi_PyConSE
 77 | Hi_PyConSE2
 78 | Hi_PyConSE23
 79 | Hi_PyConSE23!
80 |
81 |
82 |

Nim is a
compiled

programming language

83 |
84 |
85 |

A Programming Language Underdog (2018)

86 |
87 |
88 |

What is Nim 👑

89 |
90 |
91 |
let message = "Hi_PyConSE23!"
 92 | for i in 0 ..< message.len:
 93 |   echo message[0 .. i]
H
 94 | Hi
 95 | Hi_
 96 | Hi_P
 97 | Hi_Py
 98 | Hi_PyC
 99 | Hi_PyCo
100 | Hi_PyCon
101 | Hi_PyConS
102 | Hi_PyConSE
103 | Hi_PyConSE2
104 | Hi_PyConSE23
105 | Hi_PyConSE23!
106 |
107 |
108 |

Nim is a
statically typed

compiled

programming language

109 |
110 |
111 |

A Programming Language Underdog (2018)

112 |
113 |
114 |

What is Nim 👑

115 |
116 |
117 |
let message = "Hi_PyConSE23!"
118 | for i in 0 ..< message.len:
119 |   echo message[0 .. i]
H
120 | Hi
121 | Hi_
122 | Hi_P
123 | Hi_Py
124 | Hi_PyC
125 | Hi_PyCo
126 | Hi_PyCon
127 | Hi_PyConS
128 | Hi_PyConSE
129 | Hi_PyConSE2
130 | Hi_PyConSE23
131 | Hi_PyConSE23!
132 |
133 |
134 |

Nim is a
statically typed

compiled

programming language

for everything

135 |
136 |
137 |

A Programming Language Underdog (2018)

138 |
139 |
140 |

Pythonic Syntax with 🦸 Superpowers

141 |
142 |
143 |
type
144 |   Grid = array[3, array[3, Cell]]
145 |   Cell = enum X, O
146 | 
147 | func initGrid: Grid =
148 |   [[X,O,X],[O,X,O],[X,O,X]]
149 | 
150 | proc show(g: Grid) =
151 |   for row in g:
152 |     echo row
153 | 
154 | proc update(g: var Grid) =
155 |   for i in g.low .. g.high:
156 |     for j in g[i].low .. g[i].high:
157 |       g[i][j] = if g[i][j] == X: O else: X
158 |
    159 |
  • 🦸 syntax fits well with metaprogramming
  • 160 |
  • 💡 UFCS (Uniform Function Call Syntax)
  • 161 |
162 |

Zen of Nim (2021)

163 |
164 |
165 |

166 |
167 |
168 |
var g = initGrid()
169 | show g # command
[X, O, X]
170 | [O, X, O]
171 | [X, O, X]
172 |
g.update # method
173 | g.show
[O, X, O]
174 | [X, O, X]
175 | [O, X, O]
176 |
update(g) # function
177 | show(g)
[X, O, X]
178 | [O, X, O]
179 | [X, O, X]
180 |
181 |
182 |
183 |
184 |

🏎️ Performant: compiles to C

185 |
const N = 3
186 | type Matrix = array[N, array[N, int]]
187 | 
188 | let
189 |   A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
190 |   B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]]
191 | 
192 | func `*`(a, b: Matrix): Matrix =
193 |   for i in 0 ..< N:
194 |     for j in 0 ..< N:
195 |       for k in 0 ..< N:
196 |         result[i][j] += a[i][k]*b[k][j]
197 | 
198 | echo A*B
[[1, 3, 6], [4, 9, 15], [7, 15, 24]]
199 |

HPC from Python to Nim (Fosdem 2022)

200 |
201 |
202 |

🤝 Interop with Python

203 |

fibonacci.nim

204 |
import nimpy
205 | 
206 | func fib*(n: int): int {. exportpy .} =
207 |   if n < 2: 1 else: fib(n - 1) + fib(n - 2)
208 | 
209 |

main.py

210 |
import nimporter
211 | from fibonacci import fib
212 | 
213 | print(fib(10))
214 | 
215 |
python3 main.py
216 | 
217 |
89
218 | 
219 |

nimporter

220 |

nimpy

221 |
222 |
223 |
224 |

🤯 Compiles to Javascript!

225 |
226 | 227 |

🌱✨ plant app 👇

228 |
229 | 230 |
231 |
232 |
233 |
234 |

🛷 Slides source

235 |
import nimib, nimislides
236 | import std / strformat
237 | 
238 | template slideIframe*(url: string) =
239 |   nbRawHtml: "<section data-background-iframe=\"" & url & "\" data-background-interactive></section>"
240 | 
241 | template slideIframeFromNblog*(filename: string) =
242 |   slideIframe("https://nimib-land.github.io/nblog/drafts/" & filename & ".html")
243 | 
244 | # small text
245 | template addNbTextSmall* =
246 |   nb.partials["nbTextSmall"] = "<small>" & nb.partials["nbText"] & "</small>"
247 |   nb.renderPlans["nbTextSmall"] = nb.renderPlans["nbText"]
248 | 
249 | template nbTextSmall*(text: string) =
250 |   nbText: text
251 |   nb.blk.command = "nbTextSmall"
252 | 
253 | template slideTitle =
254 |   slide:
255 |     bigText: "Nim 👑 for Pythonistas 🐍"
256 |     nbText: "[github.com/pietroppeter/nim-for-pythonistas](https://github.com/pietroppeter/nim-for-pythonistas)"
257 |     nbText: "_⚡ @ PyCon🇸🇪 2023, Nov 10th_"
258 |     reference: "Pietro Peterlongo from [Python Milano](https://milano.python.it) 🇮🇹"
259 |     speakerNote: """
260 | - slides are on github
261 | - I organize event in Milan come to speak!
262 | - Nim is one of the reason I am here today
263 | """
264 | 
265 | template reference(text: string) =
266 |   nbTextSmall: text
267 | 
268 | template slideWhatIsNim =
269 |   slide(slideOptions(autoAnimate=true)):
270 |     nbText: "## What is Nim 👑"
271 |     columns:
272 |       column:
273 |         nbCodeInBlock:
274 |           let message = "Hi_PyConSE23!"
275 |           for i in 0 ..< message.len:
276 |             echo message[0 .. i]
277 |       column:
278 |         nbText: "<span data-id=\"nimis\">Nim is a</span>" &
279 |         "<span data-id=\"proglang\"><br>programming language</span>" #&
280 |     reference "[A Programming Language Underdog (2018)](url.info)" # small
281 |     speakerNote: """
282 | - an interesting second (or 3rd or nth) proglang to learn after python
283 | - programming languages are fun!
284 | - nim is my way of procrastinating learning Rust
285 | - it is much more niche, I learn it for fun not for money
286 | """
287 | 
288 |   slide(slideOptions(autoAnimate=true)):
289 |     nbText: "## What is Nim 👑"
290 |     columns:
291 |       column:
292 |         nbCodeInBlock:
293 |           let message = "Hi_PyConSE23!"
294 |           for i in 0 ..< message.len:
295 |             echo message[0 .. i]
296 |       column:
297 |         nbText: "<span data-id=\"nimis\">Nim is a</span>" &
298 |         "<span data-id=\"compiled\"><br>compiled</span>" &
299 |         "<span data-id=\"proglang\"><br>programming language</span>"
300 |     reference "[A Programming Language Underdog (2018)](url.info)" # small
301 | 
302 |   slide(slideOptions(autoAnimate=true)):
303 |     nbText: "## What is Nim 👑"
304 |     columns:
305 |       column:
306 |         nbCodeInBlock:
307 |           let message = "Hi_PyConSE23!"
308 |           for i in 0 ..< message.len:
309 |             echo message[0 .. i]
310 |       column:
311 |         nbText: "<span data-id=\"nimis\">Nim is a</span>" &
312 |         "<span data-id=\"static\"><br>statically typed</span>" &
313 |         "<span data-id=\"compiled\"><br>compiled</span>" &
314 |         "<span data-id=\"proglang\"><br>programming language</span>"
315 |         #"<span data-id=\"everything\"><br>for everything</span>"
316 |     reference "[A Programming Language Underdog (2018)](url.info)" # small
317 | 
318 |   slide(slideOptions(autoAnimate=true)):
319 |     nbText: "## What is Nim 👑"
320 |     columns:
321 |       column:
322 |         nbCodeInBlock:
323 |           let message = "Hi_PyConSE23!"
324 |           for i in 0 ..< message.len:
325 |             echo message[0 .. i]
326 |       column:
327 |         nbText: "<span data-id=\"nimis\">Nim is a</span>" &
328 |         "<span data-id=\"static\"><br>statically typed</span>" &
329 |         "<span data-id=\"compiled\"><br>compiled</span>" &
330 |         "<span data-id=\"proglang\"><br>programming language</span>" &
331 |         "<span data-id=\"everything\"><br>for everything</span>"
332 |     reference "[A Programming Language Underdog (2018)](url.info)" # small
333 | 
334 | template slideAlternativeToRust =
335 |   slide:
336 |     nbText: "_(an alternative to Rust)_" # have it appear later and small
337 |     # with different tradeoffs
338 | 
339 | template slideSyntax =
340 |   slide:
341 |     nbText: "### Pythonic Syntax with 🦸 Superpowers"
342 |     columns:
343 |       column:
344 |         nbCode:
345 |           type
346 |             Grid = array[3, array[3, Cell]]
347 |             Cell = enum X, O
348 | 
349 |           func initGrid: Grid =
350 |             [[X,O,X],[O,X,O],[X,O,X]]
351 | 
352 |           proc show(g: Grid) =
353 |             for row in g:
354 |               echo row
355 |           
356 |           proc update(g: var Grid) =
357 |             for i in g.low .. g.high:
358 |               for j in g[i].low .. g[i].high:
359 |                 g[i][j] = if g[i][j] == X: O else: X
360 |         nbTextSmall: "- 🦸 syntax fits well with **metaprogramming**\n" &
361 |         "- 💡 UFCS (Uniform Function Call Syntax)"
362 |         nbTextSmall: "[Zen of Nim (2021)](https://nim-lang.org/blog/2021/11/15/zen-of-nim.html)"
363 | 
364 |       column:
365 |         nbText: "⠀" # https://www.compart.com/en/unicode/U+2800
366 |       column:
367 |         #nbText: "Indentation based syntax that fits Nim's macro system"
368 |         nbCode:
369 |           var g = initGrid()
370 |           show g # command
371 |         nbCode:          
372 |           g.update # method
373 |           g.show
374 |         nbCode:
375 |           update(g) # function
376 |           show(g)
377 |     
378 | 
379 | template slidePerformant =
380 |   slide:
381 |     nbText: "### 🏎️ Performant: compiles to C"
382 |     #nbText: "_todo: matrix multiplications_"
383 |     nbCode:
384 |       const N = 3
385 |       type Matrix = array[N, array[N, int]]
386 | 
387 |       let
388 |         A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
389 |         B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]]
390 | 
391 |       func `*`(a, b: Matrix): Matrix =
392 |         for i in 0 ..< N:
393 |           for j in 0 ..< N:
394 |             for k in 0 ..< N:
395 |               result[i][j] += a[i][k]*b[k][j]
396 | 
397 |       echo A*B
398 | 
399 |     reference "[HPC from Python to Nim (Fosdem 2022)](https://archive.fosdem.org/2022/schedule/event/nim_hpcfrompythontonim/)"
400 | 
401 | const
402 |   tripleBackticks = "```" # hack to avoid issues when showing source
403 |   bOpen = "{"
404 |   bClose = "}"
405 | 
406 | template slidePragmatic =
407 | 
408 |   slide:
409 |     nbText: "### 🤝 Interop with Python"
410 |     nbText: fmt"""
411 | 
412 | `fibonacci.nim`
413 | {tripleBackticks}nim
414 | import nimpy
415 | 
416 | func fib*(n: int): int {bOpen}. exportpy .{bClose} =
417 |   if n < 2: 1 else: fib(n - 1) + fib(n - 2)
418 | {tripleBackticks}
419 | 
420 | `main.py`
421 | {tripleBackticks}python
422 | import nimporter
423 | from fibonacci import fib
424 | 
425 | print(fib(10))
426 | {tripleBackticks}
427 | 
428 | {tripleBackticks}
429 | python3 main.py
430 | {tripleBackticks}
431 | 
432 | {tripleBackticks}
433 | 89
434 | {tripleBackticks}
435 | 
436 | """
437 | 
438 |     reference "[nimporter](https://github.com/Pebaz/nimporter)"
439 |     reference "[nimpy](https://github.com/yglukhov/nimpy)"
440 | 
441 | template slidePortable =
442 |   slide:
443 |     slide:
444 |       nbText: "### 🤯 Compiles to Javascript!"
445 |       fragment:
446 |         nbText: "### [🌱✨ plant app](https://pietroppeter.github.io/nblog/drafts/plant_app.html?utm_source=github-pietroppeter) 👇"    
447 |   
448 |     slideIframeFromNblog("plant_app")
449 | 
450 | # WIP
451 | template slideEverything =
452 |   slide:
453 |     nbText: "### For everything"
454 |     unorderedList:
455 |       listItem: nbText"gamedev: nico, godot bindings (Turing Complete)"
456 |       listItem: nbText"langdev: arturo, min"
457 | 
458 | template slideSource =
459 |   slide:
460 |     nbText: "### 🛷 Slides source"
461 |     nbText: "```nim\n" & nb.source & "\n```\n"
462 |     reference "[nimislides by Hugo Granström](https://github.com/HugoGranstrom/nimiSlides)"
463 | 
464 | when isMainModule:
465 |   nbInit(theme = revealTheme)
466 |   setSlidesTheme(Solarized)
467 |   addNbTextSmall
468 | 
469 |   when false:
470 |     discard
471 |   slideTitle
472 |   slideWhatIsNim 
473 |   #slideAlternativeToRust
474 |   slideSyntax
475 |   slidePerformant # compiles to C
476 |   slidePragmatic # FFI: e.g. nimporter and nimpy
477 |   slidePortable # Compiles to Javascript!
478 |   #slideEverything
479 |   #slideProductive
480 |   slideSource
481 |   nbSave
482 | 
483 | 
484 |

nimislides by Hugo Granström

485 |
486 |
487 |
488 | 489 | 490 | 491 | 499 | 500 | 501 | -------------------------------------------------------------------------------- /lightning.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides 2 | import std / strformat 3 | 4 | template slideIframe*(url: string) = 5 | nbRawHtml: "
" 6 | 7 | template slideIframeFromNblog*(filename: string) = 8 | slideIframe("https://nimib-land.github.io/nblog/drafts/" & filename & ".html") 9 | 10 | # small text 11 | template addNbTextSmall* = 12 | nb.partials["nbTextSmall"] = "" & nb.partials["nbText"] & "" 13 | nb.renderPlans["nbTextSmall"] = nb.renderPlans["nbText"] 14 | 15 | template nbTextSmall*(text: string) = 16 | nbText: text 17 | nb.blk.command = "nbTextSmall" 18 | 19 | template slideTitle = 20 | slide: 21 | bigText: "Nim 👑 for Pythonistas 🐍" 22 | nbText: "[github.com/pietroppeter/nim-for-pythonistas](https://github.com/pietroppeter/nim-for-pythonistas)" 23 | nbText: "_⚡ @ PyCon🇸🇪 2023, Nov 10th_" 24 | reference: "Pietro Peterlongo from [Python Milano](https://milano.python.it) 🇮🇹" 25 | speakerNote: """ 26 | - slides are on github 27 | - I organize event in Milan come to speak! 28 | - Nim is one of the reason I am here today 29 | """ 30 | 31 | template reference*(text: string) = 32 | nbTextSmall: text 33 | 34 | template slideWhatIsNim = 35 | slide(slideOptions(autoAnimate=true)): 36 | nbText: "## What is Nim 👑" 37 | columns: 38 | column: 39 | nbCodeInBlock: 40 | let message = "Hi_PyConSE23!" 41 | for i in 0 ..< message.len: 42 | echo message[0 .. i] 43 | column: 44 | nbText: "Nim is a" & 45 | "
programming language
" #& 46 | reference "[A Programming Language Underdog (2018)](url.info)" # small 47 | speakerNote: """ 48 | - an interesting second (or 3rd or nth) proglang to learn after python 49 | - programming languages are fun! 50 | - nim is my way of procrastinating learning Rust 51 | - it is much more niche, I learn it for fun not for money 52 | """ 53 | 54 | slide(slideOptions(autoAnimate=true)): 55 | nbText: "## What is Nim 👑" 56 | columns: 57 | column: 58 | nbCodeInBlock: 59 | let message = "Hi_PyConSE23!" 60 | for i in 0 ..< message.len: 61 | echo message[0 .. i] 62 | column: 63 | nbText: "Nim is a" & 64 | "
compiled
" & 65 | "
programming language
" 66 | reference "[A Programming Language Underdog (2018)](url.info)" # small 67 | 68 | slide(slideOptions(autoAnimate=true)): 69 | nbText: "## What is Nim 👑" 70 | columns: 71 | column: 72 | nbCodeInBlock: 73 | let message = "Hi_PyConSE23!" 74 | for i in 0 ..< message.len: 75 | echo message[0 .. i] 76 | column: 77 | nbText: "Nim is a" & 78 | "
statically typed
" & 79 | "
compiled
" & 80 | "
programming language
" 81 | #"
for everything
" 82 | reference "[A Programming Language Underdog (2018)](url.info)" # small 83 | 84 | slide(slideOptions(autoAnimate=true)): 85 | nbText: "## What is Nim 👑" 86 | columns: 87 | column: 88 | nbCodeInBlock: 89 | let message = "Hi_PyConSE23!" 90 | for i in 0 ..< message.len: 91 | echo message[0 .. i] 92 | column: 93 | nbText: "Nim is a" & 94 | "
statically typed
" & 95 | "
compiled
" & 96 | "
programming language
" & 97 | "
for everything
" 98 | reference "[A Programming Language Underdog (2018)](url.info)" # small 99 | 100 | template slideAlternativeToRust = 101 | slide: 102 | nbText: "_(an alternative to Rust)_" # have it appear later and small 103 | # with different tradeoffs 104 | 105 | template slideSyntax* = 106 | slide: 107 | nbText: "### Pythonic Syntax with 🦸 Superpowers" 108 | columns: 109 | column: 110 | nbCode: 111 | type 112 | Grid = array[3, array[3, Cell]] 113 | Cell = enum X, O 114 | 115 | func initGrid: Grid = 116 | [[X,O,X],[O,X,O],[X,O,X]] 117 | 118 | proc show(g: Grid) = 119 | for row in g: 120 | echo row 121 | 122 | proc update(g: var Grid) = 123 | for i in g.low .. g.high: 124 | for j in g[i].low .. g[i].high: 125 | g[i][j] = if g[i][j] == X: O else: X 126 | nbTextSmall: "- 🦸 syntax fits well with **metaprogramming**\n" & 127 | "- 💡 UFCS (Uniform Function Call Syntax)" 128 | nbTextSmall: "[Zen of Nim (2021)](https://nim-lang.org/blog/2021/11/15/zen-of-nim.html)" 129 | 130 | column: 131 | nbText: "⠀" # https://www.compart.com/en/unicode/U+2800 132 | column: 133 | #nbText: "Indentation based syntax that fits Nim's macro system" 134 | nbCode: 135 | var g = initGrid() 136 | show g # command 137 | nbCode: 138 | g.update # method 139 | g.show 140 | nbCode: 141 | update(g) # function 142 | show(g) 143 | 144 | 145 | template slidePerformant* = 146 | slide: 147 | nbText: "### 🏎️ Performant: compiles to C" 148 | #nbText: "_todo: matrix multiplications_" 149 | nbCode: 150 | const N = 3 151 | type Matrix = array[N, array[N, int]] 152 | 153 | let 154 | A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 155 | B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]] 156 | 157 | func `*`(a, b: Matrix): Matrix = 158 | for i in 0 ..< N: 159 | for j in 0 ..< N: 160 | for k in 0 ..< N: 161 | result[i][j] += a[i][k]*b[k][j] 162 | 163 | echo A*B 164 | 165 | reference "[HPC from Python to Nim (Fosdem 2022)](https://archive.fosdem.org/2022/schedule/event/nim_hpcfrompythontonim/)" 166 | 167 | const 168 | tripleBackticks* = "```" # hack to avoid issues when showing source 169 | bOpen* = "{" 170 | bClose* = "}" 171 | 172 | template slidePragmatic* = 173 | 174 | slide: 175 | nbText: "### 🤝 Interop with Python" 176 | nbText: fmt""" 177 | 178 | `fibonacci.nim` 179 | {tripleBackticks}nim 180 | import nimpy 181 | 182 | func fib*(n: int): int {bOpen}. exportpy .{bClose} = 183 | if n < 2: 1 else: fib(n - 1) + fib(n - 2) 184 | {tripleBackticks} 185 | 186 | `main.py` 187 | {tripleBackticks}python 188 | import nimporter 189 | from fibonacci import fib 190 | 191 | print(fib(10)) 192 | {tripleBackticks} 193 | 194 | {tripleBackticks} 195 | python3 main.py 196 | {tripleBackticks} 197 | 198 | {tripleBackticks} 199 | 89 200 | {tripleBackticks} 201 | 202 | """ 203 | 204 | reference "[nimporter](https://github.com/Pebaz/nimporter)" 205 | reference "[nimpy](https://github.com/yglukhov/nimpy)" 206 | 207 | template slidePortable* = 208 | slide: 209 | slide: 210 | nbText: "### 🤯 Compiles to Javascript!" 211 | fragment: 212 | nbText: "### [🌱✨ plant app](https://pietroppeter.github.io/nblog/drafts/plant_app.html?utm_source=github-pietroppeter) 👇" 213 | 214 | slideIframeFromNblog("plant_app") 215 | 216 | # WIP 217 | template slideEverything = 218 | slide: 219 | nbText: "### For everything" 220 | unorderedList: 221 | listItem: nbText"gamedev: nico, godot bindings (Turing Complete)" 222 | listItem: nbText"langdev: arturo, min" 223 | 224 | template slideSource = 225 | slide: 226 | nbText: "### 🛷 Slides source" 227 | nbText: "```nim\n" & nb.source & "\n```\n" 228 | reference "[nimislides by Hugo Granström](https://github.com/HugoGranstrom/nimiSlides)" 229 | 230 | when isMainModule: 231 | nbInit(theme = revealTheme) 232 | setSlidesTheme(Solarized) 233 | addNbTextSmall 234 | 235 | when false: 236 | discard 237 | slideTitle 238 | slideWhatIsNim 239 | #slideAlternativeToRust 240 | slideSyntax 241 | slidePerformant # compiles to C 242 | slidePragmatic # FFI: e.g. nimporter and nimpy 243 | slidePortable # Compiles to Javascript! 244 | #slideEverything 245 | #slideProductive 246 | slideSource 247 | nbSave 248 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import nimporter 2 | from fibonacci import fib 3 | 4 | print(fib(10)) # 89 5 | -------------------------------------------------------------------------------- /matrix.nim: -------------------------------------------------------------------------------- 1 | when defined(static3): 2 | const N = 3 3 | type 4 | Matrix = array[N, array[N, int]] 5 | Vector = array[N, int] 6 | 7 | func `*`(a, b: Matrix): Matrix = 8 | for i in 0 ..< N: 9 | for j in 0 ..< N: 10 | for k in 0 ..< N: 11 | result[i][j] += a[i][k]*b[k][j] 12 | 13 | func `*`(a: Matrix, v: Vector): Vector = 14 | for i in 0 ..< N: 15 | for j in 0 ..< N: 16 | result[i] += a[i][j]*v[j] 17 | 18 | func `+`(v: Vector, n: int): Vector = 19 | for i in 0 ..< N: 20 | result[i] = v[i] + n 21 | 22 | else: 23 | type 24 | Matrix*[T] = object 25 | data*: seq[T] 26 | nrows*: int 27 | ncols*: int 28 | Vector*[T] = seq[T] 29 | 30 | func initMatrix*[T](nrows, ncols: int): Matrix[T] = 31 | result.data = newSeq[T](nrows*ncols) 32 | result.nrows = nrows 33 | result.ncols = ncols 34 | 35 | func initVector*[T](size: int): Vector[T] = 36 | result = newSeq[T](size) 37 | 38 | func `[]`*[T](m: Matrix[T], i, j: int): T = 39 | doAssert i >= 0 and i < m.nrows 40 | doAssert j >= 0 and j < m.ncols 41 | m.data[i*m.ncols + j] 42 | 43 | proc `[]=`*[T](m: var Matrix[T], i, j: int, val: T) = 44 | doAssert i >= 0 and i < m.nrows 45 | doAssert j >= 0 and j < m.ncols 46 | m.data[i*m.ncols + j] = val 47 | 48 | func `*`*[T](a, b: Matrix[T]): Matrix[T] = 49 | doAssert a.ncols == b.nrows 50 | result = initMatrix[T](a.nrows, b.ncols) 51 | for i in 0 ..< a.nrows: 52 | for j in 0 ..< a.ncols: 53 | for k in 0 ..< b.ncols: 54 | result[i, j] = result[i, j] + a[i, k]*b[k, j] 55 | 56 | func `*`*[T](a: Matrix[T], v: Vector[T]): Vector[T] = 57 | doAssert a.ncols == v.len 58 | result = initVector[T](a.nrows) 59 | for i in 0 ..< a.nrows: 60 | for j in 0 ..< a.ncols: 61 | result[i] += a[i, j]*v[j] 62 | 63 | func `+`*[T](v: Vector[T], n: int): Vector[T] = 64 | result = initVector[T](v.len) 65 | for i in 0 ..< v.len: 66 | result[i] = v[i] + n 67 | 68 | func `$`*[T](m: Matrix[T]): string = 69 | for i in 0 ..< m.nrows: 70 | result += "[" 71 | for j in 0 ..< m.ncols: 72 | result += " " & $m[i, j] 73 | result += " ]\n" 74 | 75 | when isMainModule: 76 | import print 77 | import std / math 78 | 79 | when defined(static3): 80 | let 81 | A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 82 | B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]] 83 | v = [-1, -1, 1] 84 | 85 | print A 86 | print B 87 | print v 88 | print A*B 89 | print (A*B)*v 90 | print ((A*B)*v + 1) 91 | print sum ((A*B)*v + 1) 92 | else: 93 | let N = 2 94 | var 95 | A = initMatrix[int](N, N) 96 | B = initMatrix[int](N, N) 97 | v = initVector[int](N) 98 | for n in 1 .. N*N: 99 | A.data[n - 1] = n 100 | for i in 0 ..< N: 101 | for j in 0 ..< N: 102 | B[i, j] = if i <= j: 1 else: 0 103 | v[^1] = 1 104 | 105 | print A 106 | print B 107 | print v 108 | print A*B 109 | print (A*B)*v 110 | print sum (A*B)*v 111 | 112 | 113 | # https://packaging.python.org/en/latest/tutorials/packaging-projects/ -------------------------------------------------------------------------------- /my.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |

H1 Title

15 | hi 16 |
17 |
18 |
19 |
20 | 21 | 22 | 23 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /nbex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |

const for compile time evaluation

14 |
import std / [sequtils, strutils]
 15 | 
 16 | func fizzBuzz(n: int): string = 
 17 |   case n mod 15
 18 |   of 0: "FizzBuzz"
 19 |   of 3, 6, 9, 12: "Fizz"
 20 |   of 5, 10: "Buzz"
 21 |   else: $n
 22 | 
 23 | const result = (1 .. 15).toSeq.mapIt(it.fizzBuzz).join()
 24 | 
 25 | echo result
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz
26 |
27 |
28 |

let and var for safe mutability

29 |
30 |
31 |

let is a (runtime defined) immutable value

32 |
let x = 1
 33 | x = x + 1
 34 | # Error: 'x' cannot be assigned to
 35 | 
36 |
37 |
38 |

use var for a mutable variable

39 |
var x = 1
 40 | inc x
 41 | echo x
2
42 |
43 |
44 |
45 |
46 |

var parameters

47 |

use for a mutable parameter

48 |
proc divmod(a, b: int; q, r: var int) =
 49 |   q = a div b
 50 |   r = a mod b
 51 | 
 52 | var q, r: int
 53 | 
 54 | echo (q, r)
 55 | divmod(8, 5, q, r) # modifies q and r
 56 | echo (q, r)
(0, 0)
 57 | (1, 3)
58 |
59 |
60 |

Unchained

61 |

A fully type safe, compile time only units library

62 |
type
 63 |   KiloGram = distinct float
 64 |   Meter = distinct float
 65 | ...
 66 | 
67 |
import unchained
 68 | 
 69 | let
 70 |   m = 80.kg
 71 |   g = 9.81.m•s⁻²
 72 |   f = m*g
 73 | doAssert typeof(f) is Newton
 74 | 
 75 | echo f
784.8 KiloGram•Meter•Second⁻²
76 |
77 |
78 |

jsony

79 |

A fast and direct json <-> type serializer/deserializer

80 |
proc dumpHook*(s: var string, v: char) =
 81 |   s.add '"' & v & '"'
 82 | 
 83 | proc dumpHook*[T](s: var string, v: seq[T]) =
 84 |   s.add '['
 85 |   for i, e in v:
 86 |     if i != 0: s.add ','
 87 |     s.dumpHook(e)
 88 |   s.add ']'
 89 | 
90 |
import jsony
 91 | 
 92 | doAssert @['a', 'b', 'c'].toJson() == """["a","b","c"]"""
 93 | doAssert """["a","b","c"]""".fromJson(seq[char]) == @['a', 'b', 'c']
94 |
95 |
96 |
97 | 98 | 99 | 100 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /nbex.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides 2 | import std / strformat 3 | export strformat 4 | 5 | type 6 | int255* = range[0 .. 255] 7 | 8 | const 9 | pythonBlue* = "#3572A5" # from github/linguist 10 | pyconRedBrick* = "#F17A5D" 11 | pyconYellow* = "#F8B03D" 12 | pyconRed* = "#DB0000" 13 | pyconViolet* = "#9473B0" 14 | pyconPurple* = "#FA00FF" 15 | pyconGreen* = "#219653" 16 | pyconKeppel* = "#34B4A1" 17 | pyconWhite* = "#FCE8DE" 18 | nimYellow* = "#ffe953" 19 | 20 | const 21 | tripleBackticks* = "```" # hack to avoid issues when showing source 22 | bOpen* = "{" 23 | bClose* = "}" 24 | 25 | template reference*(text: string) = 26 | nbTextSmall: text 27 | 28 | # small text 29 | template addNbTextSmall* = 30 | nb.partials["nbTextSmall"] = "" & nb.partials["nbText"] & "" 31 | nb.renderPlans["nbTextSmall"] = nb.renderPlans["nbText"] 32 | 33 | template nbTextSmall*(text: string) = 34 | nbText: text 35 | nb.blk.command = "nbTextSmall" 36 | 37 | template mySlide*(ident: untyped, body: untyped) = 38 | template ident* = 39 | slide: 40 | body 41 | 42 | template minSlide*(ident: untyped, body: untyped) = 43 | # I can customize with custom background if I do not get to make it complete 44 | template ident* = 45 | slide: 46 | body 47 | 48 | template slideIframe*(url: string) = 49 | nbRawHtml: "
" 50 | 51 | template slideIframeFromNblog*(filename: string) = 52 | slideIframe("https://nimib-land.github.io/nblog/drafts/" & filename & ".html") 53 | 54 | template slideIframe*(ident: untyped, frameAsStr: untyped) = 55 | template ident* = 56 | slide(slideOptions(iframeBackground=frameAsStr)): 57 | discard 58 | 59 | template slideIframe*(ident: untyped, frameAsStr: untyped, body: untyped) = 60 | template ident* = 61 | slide(slideOptions(iframeBackground=frameAsStr)): 62 | body 63 | 64 | template spanColor*(col: string, text: string) = 65 | nbRawHtml("" & text & "") 66 | 67 | template hColor*(level: int, col: string, text: string) = 68 | nbRawHtml("" & text & "") 69 | 70 | template h1Color*(col: string, text: string) = hColor(1, col, text) 71 | template h2Color*(col: string, text: string) = hColor(2, col, text) 72 | template h3Color*(col: string, text: string) = hColor(3, col, text) 73 | template h4Color*(col: string, text: string) = hColor(4, col, text) 74 | 75 | template myInit*(sourceFileRel = "my.nim") = 76 | nbInit(thisFileRel=sourceFileRel, theme=revealTheme) 77 | setSlidesTheme(Solarized) 78 | addNbTextSmall 79 | 80 | template divStyled*(style: string, body: untyped) = 81 | nbRawHtml "
" 82 | body 83 | nbRawHtml "
" 84 | 85 | when isMainModule: 86 | myInit 87 | slide: 88 | divStyled("background-color:pink;"): 89 | h1Color("orange"): "H1 Title" 90 | spanColor("blue"): "hi" 91 | nbSave 92 | -------------------------------------------------------------------------------- /nim.cfg: -------------------------------------------------------------------------------- 1 | --verbosity:0 -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | ## fosdem version 2 | 3 | - new fosdem folder [x] 4 | - title [x] 5 | - intro [x] 6 | - agenda [x] 7 | - one: what is nim [x] 8 | - two: better pythonista [x] 9 | - three: open source [x] 10 | - added pyscript slide [x] 11 | - thanks [x] 12 | - animate stuff 13 | - strformat [x] 14 | - nimoji 15 | 16 | - stories about Nim and Open Source? NO 17 | - Status (p2p, crypto) 18 | - Exercism 19 | - Reddit (pixie?) 20 | - Crashoverride 21 | - Nitter 22 | - Unreal? 23 | - fasterthanrequests 24 | 25 | ## towards fosdem version - old 26 | 27 | - update title [x] 28 | - update intro [x] 29 | - agenda (change) 30 | - one (same?) 31 | - combine two and three 32 | - four is new three 33 | 34 | 35 | ---- 36 | 37 | issue nimislides: 38 | - had to use import conversions instead of import ./[conversions] 39 | (assume this is due to the fact I am using Nim 1.6) 40 | - int255 weird issue (again a 1.6 issue?) 41 | 42 | ## fixing stuff after dry run at "assaggi di pycon"" 43 | 44 | - [x] title 45 | - [x] add note: art by basquiat 46 | - [x] remove note! 47 | 48 | improve intro slides (write script and time it faster (5min?)) 49 | - [x] me (add a few lines, improve speaker notes) 50 | - [x] animate it 51 | - [x] animate the 3 properties slide 52 | - [x] spongebob therapy 53 | - [ ] script and time it 54 | 55 | improve four: 56 | - [x] add slide on making slides with nimib? yes! and thank Hugo! 57 | 58 | improve conclusion: 59 | - [x] new conclusion slide (animated) 60 | 61 | ### from issue 62 | 63 | given yesterday's dry run: 64 | - overall structure and content is fine 65 | - need to practice more and refine first intro part to go quicker and say fewer things 66 | - me slide: python clicked for me right away, had to program other stuff, when I came back to it I was happy 67 | - add reference here to programming language underdog 68 | - nim clicked me with me right away, surprised in how I could love another language in a similar way on how I love pyton 69 | - working with nim improved me as pythonista, surprised on which ways I was improved 70 | - struggle APE: do E first, then P, then A last and explain more clearly 71 | - redo the conclusion making more clear what are the goals: 1) taking an offside trip (like I did) is fine and might improve you in expected ways; 2) nim is a very interesting place to take an offside trip, based on some conditions and decisions about yourself and what you want to do. 72 | - maybe add a slide about making slides with code? 73 | 74 | other practical improvements: 75 | - [x] title slide: contrast of colors 76 | - [x] autoanimation for the "therapy slides" (starting with initials) 77 | - [ ] a gif for therapy slide? 78 | - [x] autoanimation for the hello slide 79 | - [x] change magic to superpowers (metaprogramming is a superpower) 80 | - [x] also in that slide, compiles natively (not: to C) 81 | - what do I do with the references? 82 | - [x] on compiler section emphasis is on safety, not expressivity 83 | - [x] add emojis 🎄👨‍💻 to advent of code slide 84 | - [ ] improve the color slide (more references, maybe fragments?) 85 | 86 | ## outstanding issues 87 | 88 | - I have a CORS problem for plant app from pietroppeter to nimib-land! (reveal.js iframe issue) 89 | - fixed with a hack (copied and pasted html of plant_app in local) 90 | 91 | ## Thu/Fri May 2/3 92 | 93 | - goal: draft of all slides! 94 | 95 | all slides: 96 | 97 | - title (basquiat's crown) [x] 98 | - intro: motivation and plan 99 | - hello [x] 100 | - something about me? (credibilità) 101 | - minimal draft [x] 102 | - quote by Beazley (Rilevanza) [x] 103 | - therapy 104 | - min [x] 105 | - 3 things I like about Python: Accessible, Playful, Everything (Soluzione?) 106 | - min [x] 107 | - 3 things I (sometimes) suffer with Python: Abstraction, Portability, Errors (Problema?) 108 | - min [x] 109 | - temporarily remove 110 | - elephant in the room: Rust (Stopper?) 111 | - min 112 | - different tradeoffs 113 | - quote by Guido on Python and Freedom (reinforces the tradeoff message) 114 | - min 115 | - agenda (promessa?) 116 | - min [x] 117 | - min intro ok [x] 118 | - node 1: nim for pythonistas 119 | - performance [x] 120 | - syntax [x] 121 | - name overload? (link to New York RCer) 122 | - metaprogramming (3 layers) 123 | - min [x] 124 | - interop with Python [x] 125 | - min one ok 126 | - node 2: compiler and types 127 | - compile time vs runtime 128 | - mutability 129 | - example metaprogramming (generics): jsony 130 | - node 3: javascript backend 131 | - multiple backends and FFI 132 | - min [x] 133 | - mind blown (p5nim okazzu art) 134 | - compiles to javascript 135 | - wrapping js stuff (e.g. p5js) 136 | - plant app 137 | - example of metaprogramming (macro): karax 138 | - node 4: a niche tech 139 | - what is a niche tech 140 | - zen of python 141 | - zen of nim 142 | (- the color of a language) 143 | - my own open source project 144 | - nimib 145 | - nimib.py (advent of code example) 146 | - conclusions 147 | - (not for now) quote by thopper on programming languages are nice (or not?) 148 | - not a conclusion, questions [x] 149 | - finish with most important idea of Python [x] 150 | - community work is very important 151 | - min ok [x] 152 | 153 | slides nice to have: 154 | - improve how quotes are shown 155 | - custom background color in minSlides 156 | - better animation for the APE slides 157 | 158 | other slides: 159 | - quote by Guido (use in conclusion) 160 | - 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. 161 | - “Python is an experiment in how much freedom programmers need. Too much freedom and nobody can read another’s code; too little and expressiveness is endangered.” 162 | - where is Nim used? exercism, status, ... 163 | - lignaggio (Wirthiano?) 164 | 165 | ## Fri Apr 26 + weekend 166 | 167 | news of today: this talk is short-listed for EuroPython 2024 (not accepted but in waiting list) 168 | 169 | - add links in readme to pycon italy version [x] 170 | - also update notes (moved to lightning and started a new one) [x] 171 | - collect existing material 172 | - this repo 173 | - todo issue (private), dates back to August 2023: https://github.com/pietroppeter/todo/issues/106 174 | - related 175 | - nimibLand for RC 176 | - nim & nimibLand for Crafted Software 177 | - giocare con le carte 178 | -------------------------------------------------------------------------------- /notes_lightning.md: -------------------------------------------------------------------------------- 1 | ## rushing it 2 | 3 | - [x] title 4 | - [x] what is nim 5 | - [x] syntax 6 | - [ ] performant 7 | - [ ] pragmatic: interop with Python + FFI 8 | - [ ] portable: compiles to js 9 | - (productive) 10 | - [ ] what next? 11 | 12 | ## slides 13 | 14 | - [x] 0 slide title 15 | - [ ] 0.5 disclaimer slide 16 | (last, maybe I do not even need a slide, and maybe it should be a last slide) 17 | - not happy with the leadership, especially recent facts, lead me to explore other languages 18 | - struggled a lot whether or not to give this presentation and in general to promote Nim 19 | - in the end I decided coding in Nim does give me Joy and I can make my "Happy place for Nim" here at RC 20 | - _feedback_: on the fence how to approach this in PyCon SE next week 21 | - [x] 1 what is Nim 22 | - [x] proglang description 23 | - a multi paradigm (imperative, functional, object-oriented) 24 | statically typed compiled programming language 25 | for everything 26 | - pragmatic: super powerful FFI (some say best C++ FFI around, bindings to unreal) 27 | - [ ] efficient, expressive, elegant 28 | - link to Programming Language Underdog (2018) 29 | - mention that references will not be discussed 30 | - [ ] 1.5 alternative to Rust 31 | - an alternative to Rust (different tradeoffs) 32 | - talk about memory management 33 | - [ ] 2 syntax as in Python (+ UFCS!) 34 | - beloved syntax from Python 35 | - Nim innovates on that with UFCS 36 | - that feature works very well with rest of system 37 | - in general Nim innovates on syntax also because of metaprogramming (show dumpTree: build an interactive app? show how it is almost a superset of python?) 38 | - Ref to go deeper: Araq, Zen of Nim (contrast with zen of Python) 39 | - [ ] 3 statically typed and compiled 40 | - not interpreted, you will miss the REPL at the beginning (there are substitute), but not be confided 41 | - compilation is key to performance 42 | - You do not need to be scared by for loops! 43 | - Example: matrix multiplication 44 | - safety (through type system and controlled mutability) 45 | - compiler is a smart assistant (not as good with error messages as Rust’s which in turn gets it from Elm but it depends also on other trade offs) 46 | - compilation is fast 47 | - compilation makes small portable executables 48 | - multiple “backends” 49 | - JAVASCRIPT! 50 | - [ ] performant: don't be scared of for loops 51 | - on performance: mratsim (arraymancer, Constantine); treeform (jsony, pixie) 52 | - on performance and Python interop: the fosdem video by that guy 53 | - refs: treeform (jsony), mratsim (arraymancer) 54 | - "come for the performance, stay for the ergonomics(/happiness/...)" 55 | - come for the language and stay for the community 56 | - [ ] portable: executables + JS! 57 | - JS: plant app 58 | - [ ] pragmatic: FFI, does not get in the way 59 | - python interop! 60 | - nimpy and nimporter 61 | - ref deech at strange loop 62 | - [ ] metaprogramming (generics, templates, macros) 63 | - [ ] relevant projects 64 | - [ ] where to start? 65 | - [ ] talk about playground before or here? 66 | - [ ] slide with embedded nim playground! 67 | - [ ] also nice for a live demo! 68 | - interesting projects for recursers 69 | - langdev: arturo, min 70 | - gamedev: nico, godot, raylib, unreal, ... 71 | - creative coding: p5nim (me) 72 | - japanese 73 | - embedded: ratel, ... 74 | - web: karax, happyx, prologue, ... 75 | - me: literate programming (nimib) 76 | - hugo: slides (based on nimib) 77 | - notable usages 78 | - exercism 79 | - nitter 80 | - turing complete 81 | - iffy: budget with buckets 82 | - crash override (and in general in security) 83 | - notable recurser: 84 | - zach! 85 | - why it might matters to you? 86 | - start doing open source 87 | - gentler intro to systems programming (if you do not feel like learning Rust, which has different tradeoffs) 88 | - slides! 89 | - for recurser: 90 | - offer to pair program 91 | - e.g. tic tac toe 92 | - CSS and NLP stuff... 93 | 94 | nice to haves: 95 | - [ ] CSS exercise (or reveal.js is enough?): make words appear one by one? 96 | 97 | ## content 98 | 99 | - I have content notes both in obsidian and github 100 | - [x] dump existing content and notes here 101 | - [x] review content 102 | 103 | ## setup 104 | 105 | - [x] minimal setup 106 | - [x] change vs code theme 107 | - [x] pick a theme: solarized 108 | - I prefer a light theme for remote presentation 109 | - [ ] build a theme selector? 110 | - [ ] open a PR for nimislides? 111 | - not needed! pick the theme here: https://revealjs.com/themes/ 112 | 113 | ## workflow improvements todo 114 | 115 | - create a template for my slides 116 | - vs code specific: started using terminal in the tab (switching tab does not work from terminal tab though) 117 | - vs code specific: nimiboost not working , why? 118 | - vs code specific: let's change vs code theme, which was the one from Sarah Drasner? 119 | - night owl! https://marketplace.visualstudio.com/items?itemName=sdras.night-owl 120 | - [x] change my default vs code theme to this! -------------------------------------------------------------------------------- /one.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | template slidePerformant* = 4 | slide: 5 | nbText: "### 🏎️ Performant: compiles natively" 6 | #nbText: "_todo: matrix multiplications_" 7 | nbCode: 8 | const N = 3 9 | type Matrix = array[N, array[N, int]] 10 | 11 | let 12 | A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 13 | B = [[1, 1, 1], [0, 1, 1], [0, 0, 1]] 14 | 15 | func `*`(a, b: Matrix): Matrix = 16 | for i in 0 ..< N: 17 | for j in 0 ..< N: 18 | for k in 0 ..< N: 19 | result[i][j] += a[i][k]*b[k][j] 20 | 21 | echo A*B 22 | 23 | reference "[HPC from Python to Nim (Fosdem 2022)](https://archive.fosdem.org/2022/schedule/event/nim_hpcfrompythontonim/)" 24 | 25 | 26 | template slideSyntax* = 27 | slide: 28 | nbText: "### Pythonic Syntax with 🦸 Superpowers" 29 | adaptivecolumns: 30 | column: 31 | nbCode: 32 | type 33 | Grid = array[3, array[3, Cell]] 34 | Cell = enum X, O 35 | 36 | func initGrid: Grid = 37 | [[X,O,X],[O,X,O],[X,O,X]] 38 | 39 | proc show(g: Grid) = 40 | for row in g: 41 | echo row 42 | 43 | proc update(g: var Grid) = 44 | for i in g.low .. g.high: 45 | for j in g[i].low .. g[i].high: 46 | g[i][j] = if g[i][j] == X: O else: X 47 | nbTextSmall: "- 🦸 syntax fits well with **metaprogramming**\n" & 48 | "- 💡 UFCS (Uniform Function Call Syntax)" 49 | 50 | column: 51 | nbText: "⠀" # https://www.compart.com/en/unicode/U+2800 52 | column: 53 | #nbText: "Indentation based syntax that fits Nim's macro system" 54 | nbCode: 55 | var g = initGrid() 56 | show g # command 57 | nbCode: 58 | g.update # method 59 | g.show 60 | nbCode: 61 | update(g) # function 62 | show(g) 63 | 64 | 65 | minSlide(metaprogramming): 66 | nbText """## 🦸 Metaprogramming 67 | 68 | 1. Generics 69 | 2. Templates 70 | 3. Macros (AST) 71 | 72 | AST: Abstract Syntax Tree 73 | 74 | DSL: Domain Specific Language 75 | 76 | > with power comes responsibility 77 | """ 78 | # should I not mention it here? 79 | # we will have example of usage of this feature later 80 | 81 | 82 | template slidePragmatic* = 83 | 84 | slide: 85 | nbText: "### 🤝 Interop with Python" 86 | nbText: fmt""" 87 | 88 | `fibonacci.nim` 89 | {tripleBackticks}nim 90 | import nimpy 91 | 92 | func fib*(n: int): int {bOpen}. exportpy .{bClose} = 93 | if n < 2: 1 else: fib(n - 1) + fib(n - 2) 94 | {tripleBackticks} 95 | 96 | `main.py` 97 | {tripleBackticks}python 98 | import nimporter 99 | from fibonacci import fib 100 | 101 | print(fib(10)) 102 | {tripleBackticks} 103 | 104 | {tripleBackticks} 105 | python3 main.py 106 | {tripleBackticks} 107 | 108 | {tripleBackticks} 109 | 89 110 | {tripleBackticks} 111 | 112 | """ 113 | 114 | reference "[nimporter](https://github.com/Pebaz/nimporter)" 115 | reference "[nimpy](https://github.com/yglukhov/nimpy)" 116 | 117 | template all* = 118 | slidePerformant # change compiles to C to native compilation! 119 | slideSyntax 120 | # overload (or skip here?) 121 | metaprogramming 122 | slidePragmatic 123 | 124 | when isMainModule: 125 | myInit("one") 126 | all 127 | #slidePerformant 128 | nbSave -------------------------------------------------------------------------------- /pyconit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/nim-for-pythonistas/ce311b6dec92c602f096dd1eb713abcbc8b4be59/pyconit.png -------------------------------------------------------------------------------- /quotes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |

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.

15 |
16 |

David Beazley, March 2023

17 |
18 |
19 |
20 | 21 | 22 | 23 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /quotes.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | template quoteSlide(who: string, what: string, ident: untyped) = 4 | mySlide(ident): 5 | nbText: "> " & what & "\n\n" & who 6 | 7 | quoteSlide("David Beazley, March 2023", """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.""", 8 | beazley) 9 | 10 | quoteSlide("Guido Van Rossum, King's Day Speech, 2016", """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.""", 11 | guidoPythonMainIdea) 12 | 13 | when isMainModule: 14 | myInit("quotes") 15 | beazley 16 | guidoPythonMainIdea 17 | nbSave 18 | -------------------------------------------------------------------------------- /therapy_spongebob.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/nim-for-pythonistas/ce311b6dec92c602f096dd1eb713abcbc8b4be59/therapy_spongebob.gif -------------------------------------------------------------------------------- /three.nim: -------------------------------------------------------------------------------- 1 | import nimib, nimislides, nbex 2 | 3 | mySlide(backends): 4 | nbText """## compiler backends 5 | - C 6 | - C++ 7 | - Objective-C 8 | - Javascript 9 | 10 | FFI: Foreign Function Interface 11 | """ 12 | speakerNote """ 13 | - very pragmatic choice 14 | - C is the primary (default) backend 15 | - C++ allows for best-in-class interoperability with C++ libraries (e.g. Unreal engine) 16 | - backends are treated like assembler 17 | - you will use a single backend at the time (but you can use when clauses) 18 | """ 19 | 20 | #slideIframe(plantApp, "https://nimib-land.github.io/nblog/drafts/plant_app.html") 21 | # workaround for CORS problem when serving over github pages: 22 | # slideIframe(plantApp, "plant_app.html") 23 | 24 | template plantApp* = 25 | slide(slideOptions(iframeBackground="plant_app.html")): 26 | discard 27 | 28 | # slideIframe(okazzu, "https://pietroppeter.github.io/nim-ib-lightning-tcp/okazzu.html") 29 | 30 | template okazzu* = 31 | slide(slideOptions(iframeBackground="https://pietroppeter.github.io/nim-ib-lightning-tcp/okazzu.html")): 32 | discard 33 | 34 | 35 | template all* = 36 | backends 37 | okazzu 38 | plantApp 39 | # example of macro-based DSL: karax? 40 | 41 | when isMainModule: 42 | myInit("three") 43 | all 44 | nbSave -------------------------------------------------------------------------------- /title.nim: -------------------------------------------------------------------------------- 1 | import nimib except toJson 2 | import nimislides, nbex 3 | 4 | template titleSlide* = 5 | slide(slideOptions(imageBackground="crown.webp")): 6 | # hacky value for bottom since I do not understand boxes 7 | divStyled("font-size:1.5rem;"): 8 | discard 9 | 10 | slide(slideOptions(imageBackground="crown.webp")): 11 | divStyled("background-color:rgba(255, 175, 243, 0.5);"): 12 | h1Color(nimYellow): "Nim for Pythonistas" 13 | h2Color(pyconGreen): "PyCon 🇮🇹, May 24th 2024" 14 | spanColor(pythonBlue): "github.com/pietroppeter/nim-for-pythonistas" 15 | 16 | when isMainModule: 17 | myInit("title") 18 | titleSlide 19 | nbSave -------------------------------------------------------------------------------- /two.nim: -------------------------------------------------------------------------------- 1 | import nimib except toJson 2 | import nimislides, nbex 3 | 4 | mySlide(constFizzBuzz): 5 | nbText "### `const` for compile time evaluation" 6 | nbCode: 7 | import std / [sequtils, strutils] 8 | 9 | func fizzBuzz(n: int): string = 10 | case n mod 15 11 | of 0: "FizzBuzz" 12 | of 3, 6, 9, 12: "Fizz" 13 | of 5, 10: "Buzz" 14 | else: $n 15 | 16 | const result = (1 .. 15).toSeq.mapIt(it.fizzBuzz).join() 17 | 18 | echo result 19 | 20 | mySlide(unchainedExample): 21 | nbText """### [Unchained](https://github.com/SciNim/Unchained) 22 | 23 | A fully type safe, compile time only units library 24 | 25 | ```nim 26 | type 27 | KiloGram = distinct float 28 | Meter = distinct float 29 | ... 30 | ``` 31 | 32 | """ 33 | nbCode: 34 | import unchained 35 | 36 | let 37 | m = 80.kg 38 | g = 9.81.m•s⁻² 39 | f = m*g 40 | doAssert typeof(f) is Newton 41 | 42 | echo f 43 | 44 | 45 | mySlide(jsonyExample): 46 | nbText """### [jsony](https://github.com/treeform/jsony) 47 | 48 | A fast and direct json <-> type serializer/deserializer 49 | 50 | ```nim 51 | proc dumpHook*(s: var string, v: char) = 52 | s.add '"' & v & '"' 53 | 54 | proc dumpHook*[T](s: var string, v: seq[T]) = 55 | s.add '[' 56 | for i, e in v: 57 | if i != 0: s.add ',' 58 | s.dumpHook(e) 59 | s.add ']' 60 | ``` 61 | 62 | """ 63 | nbCode: 64 | import jsony 65 | 66 | doAssert @['a', 'b', 'c'].toJson() == """["a","b","c"]""" 67 | doAssert """["a","b","c"]""".fromJson(seq[char]) == @['a', 'b', 'c'] 68 | 69 | mySlide(letAndVar): 70 | nbText "### `let` and `var` for safe mutability" 71 | columns: 72 | column: 73 | nbText """ 74 | `let` is a (runtime defined) immutable value 75 | 76 | ```nim 77 | let x = 1 78 | x = x + 1 79 | # Error: 'x' cannot be assigned to 80 | ``` 81 | """ 82 | column: 83 | nbText "use `var` for a mutable variable" 84 | nbCode: 85 | var x = 1 86 | inc x 87 | echo x 88 | 89 | mySlide(varParameters): 90 | nbText """### `var` parameters 91 | 92 | use `var` for a mutable parameter 93 | """ 94 | nbCode: 95 | proc divmod(a, b: int; q, r: var int) = 96 | q = a div b 97 | r = a mod b 98 | 99 | var q, r: int 100 | 101 | echo (q, r) 102 | divmod(8, 5, q, r) # modifies q and r 103 | echo (q, r) 104 | 105 | mySlide(procedureOverloading): 106 | nbText "### Procedure Overloading" 107 | nbCode: 108 | type 109 | Cat = object 110 | Dog = object 111 | 112 | proc speak(c: Cat) = echo "meow" 113 | proc speak(d: Dog) = echo "woof" 114 | 115 | let 116 | fuffi = Cat() 117 | fido = Dog() 118 | 119 | fuffi.speak 120 | fido.speak 121 | nbText "(the advantages of OOP without full blown OOP)" 122 | # add ref to Nim for Pyhton Programmers by ZDSmith at blog.zdsmith.com 123 | 124 | mySlide(effectsTracking): 125 | nbText "### Effects tracking" 126 | adaptiveColumns: 127 | column: 128 | nbCode: 129 | let aGlobal = 42 130 | 131 | proc withSideEffects(x: int): int = 132 | echo "writing ", x, " in a file" 133 | "IcanDo.IO".writeFile($x) 134 | x + aGlobal 135 | 136 | echo withSideEffects(624) 137 | echo "IcanDo.IO".readFile 138 | 139 | column: 140 | nbText "⠀" 141 | 142 | column: 143 | nbCode: 144 | func noSideEffects(x: int): int = 145 | # in a func compiler will error 146 | # if you try to do I/O or access global ... 147 | x + 42 148 | 149 | echo noSideEffects(-42) 150 | 151 | template all* = 152 | constFizzbuzz # (compile time evaluation) - when? 153 | letAndVar 154 | varParameters 155 | effectsTracking 156 | procedureOverloading 157 | 158 | # describe briefly type system (primitive vs structured) 159 | # unchainedExample # maybe I skip it? 160 | # jsonyExample 161 | 162 | 163 | when isMainModule: 164 | myInit("two") 165 | all 166 | nbSave --------------------------------------------------------------------------------