Live data from Hacker News

Nim Apocrypha, Vol. I

blog.johnnovak.net

11–20 of 59 posts

Re: Nim Apocrypha, Vol. I

#11
post #7
post #3

Excellent! Lots of good tips. The `with` syntax is new to me, but it looks useful for dealing with lots of subfields. Its also a good point that while Nim looks like Python, it very much isn't. Nim is overall much better designed from a computer science perspective with saner scoping rules, etc, IMHO. That means that while Nim as a language is relatively complex, overall its easier to work with than C++ or even Pytho…

https://dlang.org/spec/statement.html#WithStatement D also has withs. Definitely in the "not necessary but nice to have" category of features, particularly when implementing state machines (i.e. statment soup)

I seem to be in the minority but I really dislike this type of sugar. I find that it always makes code harder to read because you can't disambiguate what the code is doing without some heavy context, and changes to the class can profoundly change the way the code is behaving without triggering as much as a warning.

For this same reason I really dislike that in C++ you can just implicitly drop the "this->" to target class members. You can never tell at a glance what "foo = blah" does if you don't know whether "foo" is a member of "this" or not.

I think your page demonstrates what I mean in the "nested WithStatement" example:

    Foo foo;
    Bar bar;
    Baz baz;

    f();               // prints "f"

    with(foo)
    {
        f();           // prints "Foo.f"

        with(bar)
        {
            f();       // prints "Bar.f"

            with(baz)
            {
                f();   // prints "Bar.f".  `Baz` does not implement `f()` so
                       // resolution is forwarded to `with(bar)`'s scope
            }
        }
        with(baz)
        {
            f();       // prints "Foo.f".  `Baz` does not implement `f()` so
                       // resolution is forwarded to `with(foo)`'s scope
        }
    }
    with(baz)
    {
        f();           // prints "f".  `Baz` does not implement `f()` so
                       // resolution is forwarded to `main`'s scope. `f()` is
                       // not implemented in `main`'s scope, so resolution is
                       // subsequently forward to module scope.
    }
Wi

I get that sometimes it can cut on a lot of repetition, but I think I would be fine if the syntax was more explicit while still avoiding repetition, for instance:

    with (some_object) {
        .some_member = 1;
        .some_other = 4;
        not_a_member = .some_method();
    }
And beyond that make it non nestable (i.e. only the first level of "with" is taken into account) to avoid the situation above with complicated overloading.

In my experience that would account for 99% of uses of `with` while making the code a lot more readable without requiring a lot of context to make sense of it.

Although frankly even that might arguably overkill, for dynamic languages or ones with type inference you might as well just do something like:

    {
        let v = &mut some_annoyingly.long.thing();

        v.foo = bar;
        v.baz();
    }
It's almost the same amount of typing and you don't need any magic.

Re: Nim Apocrypha, Vol. I

#12
post #4
post #3

Excellent! Lots of good tips. The `with` syntax is new to me, but it looks useful for dealing with lots of subfields. Its also a good point that while Nim looks like Python, it very much isn't. Nim is overall much better designed from a computer science perspective with saner scoping rules, etc, IMHO. That means that while Nim as a language is relatively complex, overall its easier to work with than C++ or even Pytho…

Nim is heavily inspired by Wirth languages, where you have the same capabilities to do low level programming, without the traps of C derived languages.

Citation required. How can Wirth languages (e.g. Pascal, Modula) have "the same capabilities for low level programming", but without the traps, of C derived languages (e.g. C, C++)? The idea suggests itself that you can have one or the other, but not both.

Personally from trying it out, I like the speed resulting from the stricter module system. And there might be a little additional protection against bad builds resulting from it. But I assume it comes at a price in flexibility as well - I can't really tell since I quit after working 6 months in it.

Re: Nim Apocrypha, Vol. I

#13
post #9
post #8

Earlier quoted context omitted.

We have like 5 different `with` macros including one in stdlib.

I assume "We"=Nim? It's an interesting pattern to test language designs with. On the one hand expressive macros can be disastrous in big codebases, on the other hand a more "monadic" (implemented via passing some kind of object through a chain rather than algebraically) way is very template-intensive.

At least one (very bottom of [1]) of the 5+ variants makes you list which fields the code gets access to (in a tiny 6 line Nim macro). That is an alternate, perhaps more keystroke-heavy solution to the problem bothering @simias.

[1] https://github.com/c-blake/cligen/blob/master/cligen/macUt.n...

Re: Nim Apocrypha, Vol. I

#14
post #4

Earlier quoted context omitted.

Nim is heavily inspired by Wirth languages, where you have the same capabilities to do low level programming, without the traps of C derived languages.

Citation required. How can Wirth languages (e.g. Pascal, Modula) have "the same capabilities for low level programming", but without the traps, of C derived languages (e.g. C, C++)? The idea suggests itself that you can have one or the other, but not both. Personally from trying it out, I like the speed resulting from the stricter module system. And there might be a little additional protection against bad builds res…

[deleted]

Re: Nim Apocrypha, Vol. I

#15
> Unless if you’re one of those NodeJS wielding kids who thinks Electron is a good idea and the web is the ultimate application development platform… Ignorance is bliss!

MIC DROP!!

Wonderful article. Nim is a great programming language. I am using nim and c these days as my primary languages.

Re: Nim Apocrypha, Vol. I

#16
post #11
post #7

Earlier quoted context omitted.

https://dlang.org/spec/statement.html#WithStatement D also has withs. Definitely in the "not necessary but nice to have" category of features, particularly when implementing state machines (i.e. statment soup)

I seem to be in the minority but I really dislike this type of sugar. I find that it always makes code harder to read because you can't disambiguate what the code is doing without some heavy context, and changes to the class can profoundly change the way the code is behaving without triggering as much as a warning. For this same reason I really dislike that in C++ you can just implicitly drop the "this->" to target c…

This is true however with is fairly uncommon, so as with any feature of languages that add syntax like this it's up to your judgement as to when to use it.

Re: Nim Apocrypha, Vol. I

#17
post #11
post #7

Earlier quoted context omitted.

https://dlang.org/spec/statement.html#WithStatement D also has withs. Definitely in the "not necessary but nice to have" category of features, particularly when implementing state machines (i.e. statment soup)

I seem to be in the minority but I really dislike this type of sugar. I find that it always makes code harder to read because you can't disambiguate what the code is doing without some heavy context, and changes to the class can profoundly change the way the code is behaving without triggering as much as a warning. For this same reason I really dislike that in C++ you can just implicitly drop the "this->" to target c…

Use syntax highlighting that differentiates between members and non members, problem solved.

Re: Nim Apocrypha, Vol. I

#18
post #4

Earlier quoted context omitted.

Nim is heavily inspired by Wirth languages, where you have the same capabilities to do low level programming, without the traps of C derived languages.

Citation required. How can Wirth languages (e.g. Pascal, Modula) have "the same capabilities for low level programming", but without the traps, of C derived languages (e.g. C, C++)? The idea suggests itself that you can have one or the other, but not both. Personally from trying it out, I like the speed resulting from the stricter module system. And there might be a little additional protection against bad builds res…

Undefined behavior and null terminated strings with the attendant buffer overflows are not fundamental constants of low level programming; they’re implementation details of C. Rusty (and Nim, Modula, Pascal, Ada, etc.) show that it’s perfectly possible to write low-level code with zero-cost abstractions without “unsafe by default” programming languages like C.

Re: Nim Apocrypha, Vol. I

#19
post #7
post #3

Excellent! Lots of good tips. The `with` syntax is new to me, but it looks useful for dealing with lots of subfields. Its also a good point that while Nim looks like Python, it very much isn't. Nim is overall much better designed from a computer science perspective with saner scoping rules, etc, IMHO. That means that while Nim as a language is relatively complex, overall its easier to work with than C++ or even Pytho…

https://dlang.org/spec/statement.html#WithStatement D also has withs. Definitely in the "not necessary but nice to have" category of features, particularly when implementing state machines (i.e. statment soup)

State machines can be metaprogrammed: https://github.com/mratsim/Synthesis

You describe the events, transitions and even interrupts and this compiles to optimized goto statements with no allocation, no indirect function calls, no switch statement.

There are compile-time checks to make sure you don't have state with no transition from and it also produce a visual graph of your state and transitions.

It's been tuned to be used as the core of my high performance multithreading runtime so zero overhead compared to handwritten.

It is suitable for any state machine with zero alloc constraint and state machines can be composed (they are just a function).

I hope in the future to be able to add model checking using Nim Z3 integration so that we can reach Ada/Sparks formal verification prowess: https://github.com/nim-lang/RFCs/issues/222

Re: Nim Apocrypha, Vol. I

#20
post #4

Earlier quoted context omitted.

Nim is heavily inspired by Wirth languages, where you have the same capabilities to do low level programming, without the traps of C derived languages.

Citation required. How can Wirth languages (e.g. Pascal, Modula) have "the same capabilities for low level programming", but without the traps, of C derived languages (e.g. C, C++)? The idea suggests itself that you can have one or the other, but not both. Personally from trying it out, I like the speed resulting from the stricter module system. And there might be a little additional protection against bad builds res…

Has answered multiple times, including to your previous comments.

- bounds checking enabled by default for arrays and strings

- real enumerations that aren't implicit converted into numeric types (fixed in C++11, if one bothers to use enum classes)

- enumerations can be used as indexes (C++ can work around this with enum classes and some boilerplate templates)

- most data conversions must be done explicitly

- ability to actually define subtypes that are enforced by the type system (C++ offers this, provided one does the required boilerplate class/template code)

- memory allocation by default doesn't require doing math with data sizes (C++ as well, yet there is too much malloc()/free() pollution in C++ code bases)

- no need to deal with pointers for out parameters, thanks reference parameters, which even in C++ there isn't any guarantee they aren't null, even though that would actually trigger UB)

- in some of the dialects, namely Modula-2 and Oberon and the languages derived from them, unsafe code requires explicit import of SYSTEM package

- if one wants to do crazy C like code, all the necessary gear is available, pragmas to turn off bounds checking, pointer arithmetic, unchecked casts, unions, mapping variables to explicit memory addresses, pointers to callbacks, it is everything there in the package. The original bare bones ISO Pascal wasn't no longer relevant in the mid-80's, unless the teacher didn't knew any better.

In fact, IBM i, z/OS and Unisys ClearPath have done pretty well with PL/S, PL.8 and NEWP, only adding support for C and C++ after the market started to care about POSIX support on mainframes.

Post reply on HN