wpietri 4 years ago

For those that want to know more about Nim, it is "a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula." : https://nim-lang.org/

And HTMX "allows you to access AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext": https://htmx.org/

treeform 4 years ago

I love Nim. I been using it professionally for more than 3 years now. At first I started with it just as a faster python with types, but it so much more! You can run Nim everywhere regular places such as backend, frontend, mobile, but also in crazier places like GPU shaders and imbedded.

I also like the community. It's not so big that it feels like you only see people once but not so small that there are no useful libraries written. Just the right size for me. You can always get people to help you out on stuff, reminds me of old IRC days.

fouric 4 years ago

> In Nim, converters are automatically ran to convert between types if needed.

Huh, this is an interesting take. Instead of taking either of the extremes of "coerce types aggressively" (Perl, PHP, C (kinda)) or "no type coercion ever" (CL (kinda), Rust?), Nim has programmable type coercion, so you can enable it just when you need it.

oneplane 4 years ago

At this point I'm more worried about the whole supply chain of libraries and dependencies in the background than how nice the abstractions are.

It used to be that a powerful demo of a framework or language would be a pretty sweet starting point, but I'm not so sure about that anymore.

  • recursivedoubts 4 years ago

    i can't speak for nim, but htmx is a dependency-free, 10k javascript library that doesn't require a build step

    • tata71 4 years ago

      Why aren't more people using this?

  • ajusa 4 years ago

    As far as Nim's dependencies go in this case, it's literally just Karax (no dependencies), Jester (depends on httpbeast which has no dependencies) and treeform's ws library (no dependencies). So the only thing in this chain that isn't transparently being used is httpbeast. Thankfully I've read through that code and contributed a bit to that project, so I can reasonably trust it.

    Nim has a smaller community, so the supply chain tends not to be more than one or two levels deep in my experience. This is also because the standard library is fairly large.

    • recursivedoubts 4 years ago

      would be interesting to know the total size of the program including deps

      sounds extremely tight given the functionality

      • ajusa 4 years ago

        If I understood your point correctly you are talking about the binary size? Me naively compiling with `nim c -d:release` and running `strip` on it gives the server binary to be around 700kb, and it's dynamically linked to glibc. There are tricks and stuff to make this smaller [1], but it's already small enough and easy enough to deploy.

        Plus Nim is fast! I can load the index page of this application at 90k requests per second single-threaded on a laptop from a few years ago.

        [1]: https://hookrace.net/blog/nim-binary-size/

        • oneplane 4 years ago

          That is a pretty neat result, it looks like with that custom linking magic you can make binaries even smaller. Makes sense if you consider the vast majority of standard libraries isn't actually used regardless of how you link.

nyanpasu64 4 years ago

There's some odd syntax in this post, which passes colon-delimited indented code blocks to function calls, than control flow primitives. It reminds me of Ruby/Kotlin blocks or Swift's blocks (criticized in https://blog.metaobject.com/2020/06/the-curious-case-of-swif...), but it's quite unusual from my Python/C++/Rust background and I think it's worth explaining in the blog post, since I don't know if it's passing a key-value map/struct or a lambda.

  • ajusa 4 years ago

    +1 to what planetis mentioned. I didn't include a full explanation of the macro because I was more or less showing off a project - not doing a full tutorial of all of the internal bits and implementation details of what libraries I was using.

    So in this case, the `template` bits are doing plain code substitution at compile time, and the buildHtml `macro` is doing more advanced code generation, also at compile time. This means that it should avoid the overhead you mentioned with a key-value struct/lambda.

    For what it's worth, this could also have been implemented as a `proc` which would then take in a lambda/anonymous function to generate the HTML, but that incurs additional overhead and requires a bit of extra syntax, which felt like a hassle.

gunapologist99 4 years ago

Very, very cool demo! If someone decides to use this for production, don't forget about sanitizing inputs to mitigate XSS, CSRF, etc (and, of course, message storage, authentication, and all those other things.)

  • ajusa 4 years ago

    (Author here) Thanks! The inputs aren't sanitized in this example, but the output (the generated HTML) actually is in this case. Specifically this part:

      text ": " & sentMessage.getStr()
    

    The `text` function in the Karax DSL is actually escaped once it is converted to a string, see https://github.com/karaxnim/karax/blob/c71bc927494418c3f52f9... for the implementation if you are curious. There is a way to render raw HTML using `verbatim` instead of `text` in Karax.

    So in this case, I believe it would be protected against XSS to some extent, but I obviously haven't done an in depth security check for a demo/simple project. There are plenty of other potential issues as well (username collisions, websocket errors, user lists) but I judged those to be out of the scope of a simple project like this.

lelandbatey 4 years ago

This Nim example is very short. For comparison, I'd created a similar chat service from vanilla Flask and Vanilla HTML (with a tiny amount of jQuery) about 8 years ago and even though it was very basic it took ~500 lines of Python2, HTML, CSS and JS (even though it's only 3 files).

https://github.com/lelandbatey/flask_example/tree/master/fla...

kitd 4 years ago

This is a really good sales pitch for both Nim and Htmx IMHO. I've used htmx a bit but never Nim. Even so, the code is easy to read and follow.

e67f70028a46fba 4 years ago

Not bad for 70 loc!

  • cb321 4 years ago

    Much Nim code is similarly concise.