5 ms·
I really enjoy writing code in Nim. The move to the new memory management system turns it into a true systems-language (comparable to C++ + SharedPtr's or Rust
by elcritch 3y ago
I really enjoy writing code in Nim. The move to the new memory management system turns it into a true systems-language (comparable to C++ + SharedPtr's or Rust + ARC's everywhere). I've been working on a multi-threaded pure Nim GUI which runs 60fps like a charm and compiles down to a ~3MB binary with no deps outside the system UI libs!
The other part is that Nim's strongly typed and compiles to native code but allows you to do dependent typing like things that lets you be flexible on types:
type
X = object
Y = object
Z = object
NotXY = not (X | Y)
proc doSomething(_: NotXY) = echo "hi!"
edit: I forgot the mention, but NIR is cool and part of an overall initiative to improve the Nim compiler which will hopefully reduce bugs and improve performance. Plus hopefully enable native WASM support which would be handy for GUI stuff!
- mathisfun123 3y agoWhat is `object` here? Effectively a ⊤?
- elcritch 3y agoNope, it's just an empty object, aka an empty C struct. Generics would be like: type MyObject[T] = object val: int other: T
- mathisfun123 3y agoI don't get it - if empty object doesn't act as a top how does what you wrote demonstrate flexibility? Edit: oh X, Y, Z are singletons I guess? Still don't see the flexibility or dependent types?
- elcritch 3y ago> I don't get it - if empty object doesn't act as a top how does what you wrote demonstrate flexibility? To quote from Wikipedia: dependent types are used to encode logic's quantifiers like "for all" and "there exists". ... dependent types help reduce bugs by enabling the programmer to assign types that further restrain the set of possible implementations In my example the objects could be any object types, combination of types, or concepts. It allows you to encode logic at the type system level. If you use generics with the example above you can do things roughly like: type State = enum Open, Closed SomeObject[T: State] = object val: int SomeObjectOpen = not SomeObject[state.Close] proc close(obj: SomeObjectOpen) = ... You can do some simlar things in other languages, but it's hard and more limited and usually can't expressions.
- mathisfun123 3y ago> dependent types are used to encode logic's quantifiers like "for all" and "there exists" Ya I don't think this is a good definition of dependent type - the prototypical example of a dependent type is a k-length vector. Obviously there's a mapping from what you wrote to this (in the same way there's almost always a mapping from a sequence of decision problems to an optimization problem) but it's still not a good formulation. > In my example the objects could be any object types, combination of types, or concepts Um yes this is literally what I was asking with respect to top ⊤. > usually can't [contain] expressions ya the negation is interesting - I wonder how it's implemented.
- elcritch 3y ago> Ya I don't think this is a good definition of dependent type - the prototypical example of a dependent type is a k-length vector. Yah that's why I qualified my statement as dependent type like setup as I don't know a good definition of dependent types which I really grok and I've only briefly dabbled in it. It'd be awesome if you could point out a good resource showing a clear example / simple proof. Well I started working on statically typed vector concepts [1]. The compiler can't do `proc concat[N,M: static int](v1: Vector[N], v2: Vector[M}): Vector[N+M]` and it fails. It might be able to be implemented via a macro like `proc concat(v1: Vector[N], v2: Vector[M}): typeFromSumOf(N,M)`, but I haven't tried yet. Also just using static ints would require specific values at some point to work I think. Whereas you'd really want "induction" of some sort. Maybe a SAT solver would be required at that point? There's DrNim [2] which does tie Z3 but it's sorta dormant. > Um yes this is literally what I was asking with respect to top ⊤. Ah, I didn't know what you meant by top T. > ya the negation is interesting - I wonder how it's implemented. Nim's VM runs from Nim AST, so probably running it as a VM expression. 1: https://github.com/elcritch/platonic https://github.com/elcritch/platonic 2: https://nim-lang.org/docs/drnim.html https://nim-lang.org/docs/drnim.html
- mathisfun123 3y ago> Nim's VM runs from Nim AST What does this mean? There's a runtime VM or compile time VM?
- auxym 3y agoIt's effectively a struct with no members. (Nim compiles to C, so in fact it compiles to exactly that).
- foresto 3y ago> I've been working on a multi-threaded pure Nim GUI Any plans to develop this into something beyond a hobby project? I think a Qt rival in a language safer and more pleasant than C++ would be welcomed by more than a few people.
- elcritch 3y agoThat's good to hear! I've been considering it. Not sure if as a commercial product in it's own right - what to sell, maybe first class mobile app support? At least I personally would like to use it to ship commercial cross-platform apps w/o needing electron or something huge like QT. Nim is much more pleasant than C++! You can actually embed the Nim compiler (~8MB) and run Nim as scripts too, so in theory you could remotely update your app as a nimscript. P.S. drop me a line (emails on my github profile) if you're interested
- MaxBarraclough 3y ago> something huge like QT In defence of Qt, there's a lot of functionality in there, and they've made it modular. To my knowledge Qt's library binaries have roughly the same file sizes as, say, their Gtk equivalents. I wouldn't expect a new competitor to be that different.
- pjmlp 3y agoDelphi is still around as well, https://www.embarcadero.com/products/delphi https://www.embarcadero.com/products/delphi
- miki123211 3y agoAre you considering accessibility in your project at all? What do you use for controls, native OS objects or something custom drawn? If the latter, you're in for a word of pain with screen reader compatibility, internationalization, right-to-left languages, handling of Asian input methods etc.
- elcritch 3y agoNot currently but it's on my mind and I'm using utf8 for text with utf-32 for rendering. Good links for screen reader info are welcome! > If the latter, you're in for a word of pain with screen reader compatibility, internationalization, right-to-left languages, handling of Asian input methods etc. Custom drawn, and yep it's a pain! Actually emoji's seem the hardest (e.g. smiley face + skin tone). The windowing library I'm building upon uses the OS'es input method editors (IME). For example MacOS'es functions for composing letters like `é` already works. Hopefully Asian input methods will work via the OS'es IME. Luckily I know a bit of (modern) Hebrew, so I'll can add basic RTL languages soon.
- ddlsmurf 3y agoWhy not use something like pango, libschrift, etc ? Text rendering is a hard problem, moreso one cross-platform...
- elcritch 3y agoIs it hard! Font rendering is handled by Pixie and the guys who wrote it made a great NimConf video showing that https://www.youtube.com/watch?v=8acDfUIwLnk https://www.youtube.com/watch?v=8acDfUIwLnk Pixie can render svg and ttf fonts with unicode in addition to drawing the shapes used for boxes and lines (e.g. like pango+cairo). It's SIMD optimized, very fast, and pure Nim so cross platform. The challenge I mentioned with emojis is text selection and cursor movement when dealing with multi-grapheme characters. :) edit: see https://youtu.be/8acDfUIwLnk?si=1EAUwUNZqje88J86&t=382 https://youtu.be/8acDfUIwLnk?si=1EAUwUNZqje88J86&t=382 where they discuss how hard Text is
- codethief 3y ago> I've been working on a multi-threaded pure Nim GUI which runs 60fps like a charm and compiles down to a ~3MB binary with no deps outside the system UI libs! Like the sibling I'd be very much interested in this! Have you considered open-sourcing the GUI library part?