1. 2

    The same applies for Java as well. Java’s reference types don’t get passed by reference. Instead, the variables are effectively pointers, and the pointers get passed by value. It’s a subtle distinction but an important one when you’re talking about programming language design.

    1. 2

      Barbara Liskov (for the CLU language) termed this call by sharing, where the callee gets references to the arguments but can’t change what they refer to. A nice thing is that you can understand primitives (that might be passed by value as an optimisation) in the same way, as long as you lack reference equality. Since they’re immutable you can’t change them and discover that they aren’t actually shared!

      Nowadays most people just understand it as ‘references passed by value’, which is less fun. ☺️

      1. 2

        The term call by sharing still reveals a fundamentally mechanistic conception of argument passing. A better way to think about it is to make a distinction must be made between values, which exist in the semantics of a programming language (which is a timeless mathematical object, thus the question of whether it’s mutable doesn’t even make sense), and representations, which exist in computer memory (which obviously exists in time and might mutate). Now things become clearer: there is always a single number 42 and a single string “Hello, world!”, but they may be represented arbitrarily many times in computer memory.

      2. [Comment removed by author]

        1. 6

          The litmus test is to write a swap function/method.

          T a = foo;
          T b = bar;
          assert (a == bar);
          assert (b == foo);

          You can do that in C++, but not in Java. We assume that == does a pointer comparison here.

          Sometimes that is very useful (swap(foo[11], foo[42])), but it is also nice if a function call can never change your local variables.

          1. [Comment removed by author]

            1. 6

              I don’t know that sugar is a great way to describe it. “Liability”, is probably better. What I’ve seen happen is that people are surprised by the fact that they expect to be passing a copy, but in fact are passing a pointer to the value without an explicit, call site, indicator.

            2. 2

              You can write swap in C (not generically, of course), though:

              int a = foo, b = bar;
              swap_ints(&a, &b);
              assert (a == bar);
              assert (b == foo);

              The problem in Java is it doesn’t simultaneously have types “T” and “reference to T”.

              1. 7

                Doesn’t that specifically fail the litmus test? Note that qznc’s code has swap(a, b) but your code has swap(&a, &b). qznc is demonstrating pass-by-reference while your code is demonstrating pass-pointer-by-value, no? (Generics seems like a distraction here.)

                1. 1

                  AFAICT, pass-by-reference is syntactic sugar for specific use cases of pass-pointer-by-value.

                  I agree that genericity is a distraction, but someone could have said “strictly speaking, it’s not the same because…” That’s why I mentioned it in parentheses.

                  1. 1

                    I would say pass-reference-by-value is a workaround for the lack of pass-by-reference.

                    There is one advantage with C++ call-by-reference: The parameters cannot be NULL. The compiler complains about stuff like std::swap(NULL,NULL). There is need to check for NULL in the function.

                    1. 1

                      Wouldn’t a much simpler solution be to eliminate null pointers from the language definition?

                2. 1

                  Slightly off-topic, but you can do this, and it’s pretty generic:

                  #define swap(a, b) do {    \
                      __auto_type _a = &(a); \
                      __auto_type _b = &(b); \
                      __auto_type _t = *_a;  \
                      *_a = *_b;             \
                      *_b = _t;              \
                  } while (0)

                  This of course has some downsides.

                  1. 1

                    That’s not genericity, it’s boilerplate generation. Litmus test: Can a C compiler perform semantic analysis (e.g., checking that variables are in scope) on pre-preprocessed code?

          1. 4

            I’ve been hacking together a small and mostly LDoc-compatible documentation generator for distribution with luakit, so that up-to-date docs can be installed with the main program. Shortcoming: type inference isn’t as nice. Benefit: it’s very easy to tweak the documentation generation and include project-specific information, e.g. auto-generate nice-looking keybinding descriptions.

            1. 6

              The idea of stealthy ad blocking is nice, but I think it will be limited in practice. It will always be possible to draw opaque rectangles over ads, but anything further, such as reclaiming the space used by ads, is fairly easy to detect with JS. Since stealthy ad blocking merely obscures the ad, it also does not save bandwidth, prevent user tracking, save CPU usage, or protect against malware; all commonly cited reasons for blocking ads.

              1. 8

                A thing to consider: most websites do not actually require Javascript, they only claim to. Most of the sites that do require Javascript do it with negative amount of benefit to user. Also, a large fraction looks much better if you kill all their CSS, but that’s another sad story.

                I guess what happens is that an empty-profile container-separated (and not root inside the container, of course) browser instance will get spun up for just enough to load the page, scroll through it and load all the scroll-loaded content, then pass the now-static content to a sanitizer which can remove everything that looks like an ad.

                Tracker handling is a complicated story if websites start checking the responses for more than presence and freshness, until that you can just load them with randomized parameters and random referrer.

                On the other hand, a single large enough click-spoofing false-flag-operation conflict can redraw the web landscape faster than throwaway containers come to browsing…

              1. 2

                This is great; I really liked Luakit when I used it previously before finding out about the massive security problems. I’m glad to see it updated to the Webkit 2 API.

                However, I think the documentation here glosses over the fact that there are still serious practical security problems with this library even after switching to the new API: https://blogs.gnome.org/mcatanzaro/2017/02/08/an-update-on-webkit-security-updates/

                1. 2

                  Thanks for the feedback! I’ve added a short summary of that link at the top of the download section.

                  1. 1

                    Glad to see it. I would love to try out LuaKit again once Debian fixes their Webkit packages.