To clarify and answer some of your questions: 3:50 - Nim's Intermediate Representation "NIR" is WIP since last year or so. 6:48 - You also could've installed Nim with apt. It's in the Ubuntu repos (stable 1.6 version). 8:36 - Nim code only depends on libc, and when provided a static libc (e.g. musl) - it can compile to a static binary. 10:03 - Default iterator is always inlined by the compiler leading to zero overhead for the abstraction. 14:02 - Basically, Nim v2 uses ARC memory management by default instead of GC - that's probably the biggest change from v1 26:04 - You can run code faster with 'nim r foo.nim' (subsequent calls don't recompile, unless the source code was changed) 27:31 - Parentheses are optional for single arguments. Space before parentheses is not allowed. Output of `echo` was weird because you called echo with a single argument - a tuple. Tuple syntax is `(foo, bar, ...)` . 28:32 - Nim's debug mode affects optimizations, asserts, some runtime bound-checking and stacktraces on crash. For gdb you need a couple more flags (there is an article about debugging nim that's easy to find with google). 29:54 - I'm not sure why your HelloWorld has so many linked libs. Same code on my PC is only linked to libc, ld and vdso. 46:15 - For compile-time code/`echo` you need to use `static:` blocks. `when` is just Nim's version of C's `#ifdef`. 47:50 - Nim's style guide 'NEP1' recommends using return only when it's control-flow properties are required. 51:41 - Tiny error here, correct syntax is {.foo.} with two dots. Nim surprisingly ignores it. 56:32 - Little confusion caused by previous error, correct syntax for multiple pragmas is {.foo, bar.} with only two dots. 57:02 - That code should've worked. But I, believe, Tutorial wasn't updated properly because in Nim v2 pragma is spelled {.noSideEffect.} , singular not plural. Anyway it's idiomatic to use `func` keyword instead of this pragma. 1:01:54 - `int` type is system-native integer (int32 on 32-bit machines, int64 on 64-bit hardware) 1:04:45 - `openarray` is a parameter type that accepts: arrays of any size, seq, string, slices. Kinda like a generic view type over collections. I believe, there were no more confusions past here. But you missed one of the best features of Nim, that you will probably appreciate. Nim is one of 2 languages that support proper UFCS (other one is D). For example: `foo(a) == a.foo == a.foo()`; `foo(a, b) == a.foo(b) == a.foo b`
I used Nim for a while, and i found its fast to write in, but...... like Python its not so easy to read the code (and thus edit it) afterwards, the main reason for that of course is the use of indentation rather than brackets or parenthesis between statements
Interesting how the human brain works. This is why we have so many human and computer languages. For me, Python and Nim are pleasant and easy to read. I can tolerate C but not many other curly bracket languages.
It would be very cool, one of these days, to compare the memory management features of Nim using Hooks vs Rust's ownership and borrowing constructs. Here's a little Nim program that we can dissect (one of these days) type CustomString = object data: ptr char length: int proc initCustomString(s: string): CustomString = result.data = cast[ptr char](alloc(s.len + 1)) result.length = s.len copyMem(result.data, s.cstring, s.len + 1) # Copy includes null terminator proc `=destroy`(x: CustomString) = if x.data != nil: dealloc(x.data) proc `=sink`(dest: var CustomString; src: CustomString) = `=destroy`(dest) dest.data = src.data dest.length = src.length proc `=copy`(dest: var CustomString; src: CustomString) = `=destroy`(dest) dest.data = cast[ptr char](alloc(src.length + 1)) dest.length = src.length copyMem(dest.data, src.data, src.length + 1) # Simple conversion function, safely converting ptr char to cstring, without explicit null-check proc toCString(p: ptr char): cstring = return cast[cstring](p) # Ensure proper casting proc main = var a = initCustomString("Hello") var b = a # Triggers `=copy` var c: CustomString c = move(a) # Triggers `=sink` echo toCString(b.data) # Use b to demonstrate that the deep copy was successful echo toCString(c.data) # Safely convert and print, assuming operation includes inherent guarantees main()
Nim is a nice language but I found there are some draw backs in Nim. There is no concept of package. If you are a library developer you need to redesign your project and eventually lose some nice features. But there are workarounds in Nim though. I would like to try something in Nim without GC. All my nim projects are using GC.
@@MikeShah Paro is basically modern Smalltalk or OOP done right. And of course Smaltalk environments are still space age technology compared to modern programming environments like neovim and emacs.
@@MikeShah Pharo is a fork of Squeak. It's one of the best SmallTalk-80 implementations out there. There's even a very nice MOOC course by Inria, the French national research institute for digital science and technology.
@@encapsulatio I've never used Pharo or Smalltalk, but a very broad observation it's biggest advantage isn't the syntax and semantics of the language, but the VM that you can constantly hack on without restarting it. Very similar to how you can hack and modify emacs while it is running, or the old symbolics lisp machines.
To clarify and answer some of your questions:
3:50 - Nim's Intermediate Representation "NIR" is WIP since last year or so.
6:48 - You also could've installed Nim with apt. It's in the Ubuntu repos (stable 1.6 version).
8:36 - Nim code only depends on libc, and when provided a static libc (e.g. musl) - it can compile to a static binary.
10:03 - Default iterator is always inlined by the compiler leading to zero overhead for the abstraction.
14:02 - Basically, Nim v2 uses ARC memory management by default instead of GC - that's probably the biggest change from v1
26:04 - You can run code faster with 'nim r foo.nim' (subsequent calls don't recompile, unless the source code was changed)
27:31 - Parentheses are optional for single arguments. Space before parentheses is not allowed. Output of `echo` was weird because you called echo with a single argument - a tuple. Tuple syntax is `(foo, bar, ...)` .
28:32 - Nim's debug mode affects optimizations, asserts, some runtime bound-checking and stacktraces on crash. For gdb you need a couple more flags (there is an article about debugging nim that's easy to find with google).
29:54 - I'm not sure why your HelloWorld has so many linked libs. Same code on my PC is only linked to libc, ld and vdso.
46:15 - For compile-time code/`echo` you need to use `static:` blocks. `when` is just Nim's version of C's `#ifdef`.
47:50 - Nim's style guide 'NEP1' recommends using return only when it's control-flow properties are required.
51:41 - Tiny error here, correct syntax is {.foo.} with two dots. Nim surprisingly ignores it.
56:32 - Little confusion caused by previous error, correct syntax for multiple pragmas is {.foo, bar.} with only two dots.
57:02 - That code should've worked. But I, believe, Tutorial wasn't updated properly because in Nim v2 pragma is spelled {.noSideEffect.} , singular not plural. Anyway it's idiomatic to use `func` keyword instead of this pragma.
1:01:54 - `int` type is system-native integer (int32 on 32-bit machines, int64 on 64-bit hardware)
1:04:45 - `openarray` is a parameter type that accepts: arrays of any size, seq, string, slices. Kinda like a generic view type over collections.
I believe, there were no more confusions past here. But you missed one of the best features of Nim, that you will probably appreciate.
Nim is one of 2 languages that support proper UFCS (other one is D). For example: `foo(a) == a.foo == a.foo()`; `foo(a, b) == a.foo(b) == a.foo b`
This is excellent, I will pin this up as I think folks exploring Nim will be helped out by your insights and further explanations!
Finally! My favorite programming language besides D! Thank you for the excellent explanation!
Cheers! Yes, this had been in the pipeline for quite a bit for ya 😁
I like the way you present this exploration.
Cheers!
Love the style of your videos. Down to earth, entertaining and insightful. Thank you for covering Nim
Cheers, thank you for the kind words!
Nim language has good bindings to gui toolkits.
I.e. nfltk , nimgl , nimqml , owlkettle .
Cheers, good to know!
👍Thanks Mike, Nim is so awesome!
As for editor i use vscode with the nim / nimsaem plugin.
[Nim language support for Visual Studio Code written in Nim]
Cheers -- thanks for sharing!
Haha, in 2024, someone actually make a nim lang discuss.
I used Nim for a while, and i found its fast to write in, but...... like Python its not so easy to read the code (and thus edit it) afterwards, the main reason for that of course is the use of indentation rather than brackets or parenthesis between statements
Interesting -- that's one thing that is hard to predict for myself in this series, how the language performs at scale in different domains.
Interesting how the human brain works. This is why we have so many human and computer languages. For me, Python and Nim are pleasant and easy to read. I can tolerate C but not many other curly bracket languages.
It would be very cool, one of these days, to compare the memory management features of Nim using Hooks vs Rust's ownership and borrowing constructs. Here's a little Nim program that we can dissect (one of these days)
type
CustomString = object
data: ptr char
length: int
proc initCustomString(s: string): CustomString =
result.data = cast[ptr char](alloc(s.len + 1))
result.length = s.len
copyMem(result.data, s.cstring, s.len + 1) # Copy includes null terminator
proc `=destroy`(x: CustomString) =
if x.data != nil:
dealloc(x.data)
proc `=sink`(dest: var CustomString; src: CustomString) =
`=destroy`(dest)
dest.data = src.data
dest.length = src.length
proc `=copy`(dest: var CustomString; src: CustomString) =
`=destroy`(dest)
dest.data = cast[ptr char](alloc(src.length + 1))
dest.length = src.length
copyMem(dest.data, src.data, src.length + 1)
# Simple conversion function, safely converting ptr char to cstring, without explicit null-check
proc toCString(p: ptr char): cstring =
return cast[cstring](p) # Ensure proper casting
proc main =
var a = initCustomString("Hello")
var b = a # Triggers `=copy`
var c: CustomString
c = move(a) # Triggers `=sink`
echo toCString(b.data) # Use b to demonstrate that the deep copy was successful
echo toCString(c.data) # Safely convert and print, assuming operation includes inherent guarantees
main()
Nim is a nice language but I found there are some draw backs in Nim. There is no concept of package. If you are a library developer you need to redesign your project and eventually lose some nice features. But there are workarounds in Nim though. I would like to try something in Nim without GC. All my nim projects are using GC.
Interesting -- thanks for sharing!
Would you not be creating a Nimble package?
@@vncstudio Basically, I am against the notion of package manager. I will only use it if there is no other ways.
C is basically an IR language.
C is the lingua franca as they say for machines -- so interop with C seems essential for new langauges to take off.
Nim has raylib bindings I think if you're interested
Noted, cheers!
Hey, Mike! Would you look at Herb Sutter's CPP2?
Under consideration if I will highlight any C++ successor/experiments
Hello
I'want to learn opencv but l have i5 cpu 8gb ram and intel hd 520 gpu is it Enough
Probably plenty to get started and learn!
Do one on pharo
Neat, had not heard of this language
@@MikeShah Paro is basically modern Smalltalk or OOP done right. And of course Smaltalk environments are still space age technology compared to modern programming environments like neovim and emacs.
Interesting -- will have to look into it@@encapsulatio
@@MikeShah Pharo is a fork of Squeak. It's one of the best SmallTalk-80 implementations out there. There's even a very nice MOOC course by Inria, the French national research institute for digital science and technology.
@@encapsulatio I've never used Pharo or Smalltalk, but a very broad observation it's biggest advantage isn't the syntax and semantics of the language, but the VM that you can constantly hack on without restarting it. Very similar to how you can hack and modify emacs while it is running, or the old symbolics lisp machines.