News for hackers. Stuff that matters.
Re:The visitor pattern is essentially the same thing as Chur... by DougBTX on Thursday February 04, 2021 @05:56AM (#26024365)
It works without the cast if Shape is a generic function itself:

    type Shape = <T>(
        circle: (x: number, y: number, r: number) => T,
        rectangle: (x: number, y: number, w: number, h: number) => T
    ) => T;

    function Circle(x: number, y: number, r: number): Shape {
        return (_Circle, _Rectangle) => _Circle(x, y, r);
    }

    function Rectangle(x: number, y: number, w: number, h: number): Shape {
        return (_Circle, _Rectangle) => _Rectangle(x, y, w, h);
    }

    const exampleCircle = Circle(2, 1.4, 4.5);
    const exampleRectangle = Rectangle(1.3, 3.1, 10.3, 7.7);

    function area(shape: Shape): number {
        return shape(
            (x, y, r) => Math.PI * r * r,
            (x, y, w, h) => w * h
        );
    }

    console.log(area(exampleCircle));
    console.log(area(exampleRectangle));
Re:The visitor pattern is essentially the same thing as Chur... by throw_m239339 on Thursday February 04, 2021 @06:19AM (#26024450)
I'm embarrassed to admit it took me a while to make sense of that code snippet.

Now, in order for it to work, a language has to support closures, not just functions.

Re:The visitor pattern is essentially the same thing as Chur... by Twisol on Thursday February 04, 2021 @06:34AM (#26024507)
> Now, in order for it to work, a language has to support closures, not just functions.

Objects are a reasonable stand-in for closures. Pass in the first batch of arguments to the constructor, and store them as fields. Access them from the method (which plays the role of the "returned" closure) when it's called later.

(This is effectively the same as "closure conversion" in the literature, but we're taking advantage of the implicit-receiver convention to hide the parameter by which we're passing the prepared fields.)