News for hackers. Stuff that matters.
Re:The use of `class` for things that should be simple free ... by cataphract on Thursday May 28, 2020 @03:53AM (#23334642)
But if you're passing a state object around, you might as well use a class, no? Admittedly simplifying a bit, an instance method is a function that implicitly takes "this" as the first argument.
Re:The use of `class` for things that should be simple free ... by kqr on Thursday May 28, 2020 @04:34AM (#23334905)
There's one big difference in terms of convenience in many common implementations of classes and methods. There are essentially three different pieces involved:

In OO notation, we have A.B(C)

In almost all languages, you can store C in a variable and supply it "later":

    z = C
    A.B(z)
You can also store A in a variable and supply it "later":

    x = A
    x.B(C)
However, it is much more rare to be able to store B in a variable and supply it "later". Often, you must store A.B:

    xy = A.B
    xy(C)
This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

With functions, things get easier. If you have B(A, C), you can generally just store B in a variable on its own:

    y = B
    y(A, C)
Some OO languages allow you to store plain methods that aren't yet bound to a particular instance (JavaScript, modern Java) but far from all do, without resorting to inconveniences like

    y = lambda o: o.B
Please note that what this workaround accomplishes is effectively to turn the method into a function!

I suspect the main argument here is that it just doesn't make sense notationally to treat the first argument to a function specially. It only introduces wierd edge cases that have to be worked around. Plain old function notation has stood the test of time for good reason: it's flexible and handles most of the common cases we want.

Re:The use of `class` for things that should be simple free ... by Huperniketes on Thursday May 28, 2020 @08:37AM (#23336531)
>There's one big difference in terms of convenience in many common implementations of classes and methods.

Which ones?

>However, it is much more rare to be able to store B in a variable and supply it "later". Often, you must store A.B:

How is it rare? Smalltalk doesn't require you to specify the receiver when storing a symbol. Neither does Objective-C (selector). Neither does Ruby. Nor Java.

Which commonly used languages require one to have the receiver tied to the method when memoized? C++ is the only one I'm aware of. So it might be rare to do it in C++, but not in OOP generally.

Re:The use of `class` for things that should be simple free ... by frutiger on Thursday May 28, 2020 @08:55AM (#23336654)
Even C++ lets you store the address of the member function and lets you invoke it with an instance later.
Re:The use of `class` for things that should be simple free ... by Huperniketes on Thursday May 28, 2020 @08:59PM (#23345119)
> Even C++ lets you store the address of the member function and lets you invoke it with an instance later.

Not for virtual member functions (not that I've been able to find). C++ is geared towards generating optimal executables. Since the type of the object is known at compile-time, the particular function used for that type is known, and the compiler will generate code that applies for it.

This is why C++ uses mangled names: to discriminate between identically named functions of different types and signatures.

Re:The use of `class` for things that should be simple free ... by projektfu on Thursday May 28, 2020 @03:29PM (#23341416)
Java before invokedynamic, I guess.
Re:The use of `class` for things that should be simple free ... by vanderZwan on Thursday May 28, 2020 @06:52AM (#23335826)
I like the approach Wouter van Oortmerssen uses in Lobster:

    class Animal:
        alive = true

    class Cat : Animal
        def hello(): print "meow"

    class Dog : Animal
        barked = 0

    def hello(d::Dog):
        print "bark!"
        barked++

    let d = Dog {}
    d.hello()

    let a:Animal = d
    a.hello()
In other words, A.B(C) is just syntactic sugar for B(A, C), and class definitions are just syntactic on top of that. The relation between OO and regular functions and stateful objects is completely transparent (the only real gotcha I can see is that a.hello() still works here because it was assigned a subclass where this method is defined). This makes it easy to store B for later usage, like you wanted to do in your example, and reason about its behavior.

[0] http://strlen.com/lobster/

Re:The use of `class` for things that should be simple free ... by beagle3 on Thursday May 28, 2020 @07:25AM (#23336039)
This is also the approach taken by Nim and D, and it is known as the UFCS (Uniform Function Call Syntax)[0], and I agree - it's the best of all worlds.

[0] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re:The use of `class` for things that should be simple free ... by vanderZwan on Thursday May 28, 2020 @07:26AM (#23336047)
Ah, I wondered where it originated. Thank you for that bit of info!
Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @09:15AM (#23336843)
I think Swift does this too?
Re:The use of `class` for things that should be simple free ... by edflsafoiewq on Thursday May 28, 2020 @04:47AM (#23334977)
> This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

That is also its advantage, since the method to call can depend on the instance. Not just for dynamic dispatch either. A statically dispatched call will look up B on classof(A).

Re:The use of `class` for things that should be simple free ... by DarkWiiPlayer on Thursday May 28, 2020 @04:43AM (#23334950)
I'd just like to add that you can still have the `A.B(C)` syntax, if you just define it as syntactic sugar for `(class of A).B(A, C)`
Re:The use of `class` for things that should be simple free ... by Tomis02 on Friday May 29, 2020 @03:28AM (#23347178)
> This means that at the time you select which method to call, you must also have at your disposal the instance on which you want to call it!

The time you "select which method to call" is when you write the code, right? You select it once. Like, "printf(arg);". I selected printf (in my mind), I called it. I don't need to do "x = print; x(arg)".

> With functions, things get easier. If you have B(A, C), you can generally just store B in a variable on its own:

> y = B

> y(A, C)

>Some OO languages allow you to store plain methods that aren't yet bound to a particular instance (JavaScript, modern Java) but far from all do...

Sorry, I lost the plot here. If you have B(A, C) then you don't need "y = B". B is an invariant of sorts. Just like you don't usually store the address of a class method; you just call that method on an object. Nobody writes:

> x = &objectInstance::method;

> x(args);

People just write

> "objectInstance.method(args);"

Therefore in your case, if using functions, you just do B(A, C). No assignment needed, works in every language.

What am I missing?

Re:The use of `class` for things that should be simple free ... by logicchains on Thursday May 28, 2020 @07:55AM (#23336221)
>But if you're passing a state object around, you might as well use a class, no?

A lot of your functions aren't going to need access to the whole state, only to some of it. If we're not using a class, we can just make these functions take only the needed arguments, rather than the whole state. This makes them easier to reason about, as we can know from the function signature that it only looks at the params we pass in, not the whole state. It also makes them easier to reuse elsewhere in the code, where we might not have the full state but we do have the arguments to the function.

For any function that doesn't need to access every member variable of a class, making it a class member function essentially creates an unnecessary coupling between that function and the class members variables it doesn't use. This makes it unecessarily harder to reuse elsewhere, as anyone who wants to use it needs to create an instance of the whole class, including any variables that aren't needed by that function.

Re:The use of `class` for things that should be simple free ... by lmkg on Thursday May 28, 2020 @11:19AM (#23338359)
This sounds like exposing internal implementation details. You're pushing some complexity onto the caller, and breaking up the uniformity of the interface. Sometimes the caller will want to manage that complexity for the reasons that you describe, but it's not always good to force the caller to wrangle that complexity.

Design trade-offs, as always. I get why you would do it your way, and it makes sense in some applications. But for some applications the fact that you're hiding which specific bits of state each function depends on, is actually the point of using a class.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @05:05AM (#23335078)
Let's use C and C++ as an example. What does the code look like?

    myobj.cool_func(1,2,3); // C++

    cool_func(myobj, 1, 2, 3); // C

Is this better?

If you use a vanilla C++ style class then the class definition is in the header. All changes to the class require a recompilation and break the ABI of the class. This means you basically cannot release patch versions of your library because consumers cannot link against it if they have the old headers.

Contrast with C where you would forward declare a struct in the header and pass that around while the definition is hidden in a .c file. This means changes to the size of the structure don't matter because all calling code ever sees is a pointer. (True data hiding!) It's called an opaque pointer and many many libraries use this pattern. e.g. libcairo.

There is then a pattern to do this in C++ called pimpl:

https://en.cppreference.com/w/cpp/language/pimpl

This solves it for C++ but the alleged convenience is gone because now you're coding C++ with the supposed convenience but still your class implementation has to trampoline all the calls to the pimpl which is an extra function call (if you're writing C or C++ this might matter).

But RAII, though. Not having [standardized] RAII sucks.

Re:The use of `class` for things that should be simple free ... by jcelerier on Thursday May 28, 2020 @06:07AM (#23335532)
> If you use a vanilla C++ style class then the class definition is in the header. All changes to the class require a recompilation and break the ABI of the class.

definitely not all, only things that change the layout. adding a non-virtual method does not break ABI at all for instance.

> Contrast with C where you would forward declare a struct in the header and pass that around while the definition is hidden in a .c file. This means changes to the size of the structure don't matter because all calling code ever sees is a pointer. (True data hiding!) It's called an opaque pointer and many many libraries use this pattern. e.g. libcairo.

Does this have a point in 2020 ? Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries. Such hiding is only relevant for legacy things such as what Linux distros obstinates themselves in doing for their userspace - hopefully in a few years everyone will switch to snap / flatpack / appimage to finally reach a sane application distribution model on Linux.

I'd definitely say PIMPL is 100% an anti-pattern in every possible case. It forces more memory allocations, and makes it much harder to hack your way out of things when it's 3AM and everything is crashing and you have 5 minutes to fix things before heads start to roll.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @06:43AM (#23335768)
> only things that change the layout. adding a non-virtual method does not break ABI at all for instance.

Yes, you are correct. The point was that C code can keep the ABI intact through (some) data layout changes but vanilla C++ classes cannot I misstated it.

>Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

That is the state of play now because Rust does not have a stable ABI. I thought one might be coming but maybe no one's working on it. It's unfortunate because it would be really nice to have binary crates with signing.

>hopefully in a few years everyone will switch to snap / flatpack / appimage to finally reach a sane application distribution model on Linux.

Snap has a while to go before it can be adopted fully. Images are enormous, they take a long time to load, and they don't respect (or don't understand) hidpi settings. I tried to use it for spotify and telegram-desktop and other applications but they just don't work that well.

>it much harder to hack your way out of things when it's 3AM and everything is crashing and you have 5 minutes to fix things before heads start to roll.

Absolutely but it comes from enormous systems like Windows where changing a library and breaking ABI means recompiling Everything. And these compilation jobs are often 'overnights'.

Re:The use of `class` for things that should be simple free ... by MaulingMonkey on Thursday May 28, 2020 @06:40PM (#23343812)
> adding a non-virtual method does not break ABI at all for instance.

Ctors/dtors can break ABI as well: https://gcc.godbolt.org/z/XAx00v

Re:The use of `class` for things that should be simple free ... by asveikau on Thursday May 28, 2020 @10:28AM (#23337680)
> Does this have a point in 2020 ? Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

It sure sounds to me like modern practice as you've defined it is that when a component has a security vulnerability you're not going to patch it. It's going to be statically linked and running in a container image maybe created by somebody else and you'll have no idea it's there.

Re:The use of `class` for things that should be simple free ... by MaulingMonkey on Thursday May 28, 2020 @05:06PM (#23342622)
Dynamic linking is no panacea here.

Yes, it theoretically lets you ship a patch version bump containing security fixes for the few languages with a stable ABI. But even ignoring the deluge of unpatched IOT garbage running seriously out of date kernels - nevermind userspaces - how do you ship that version bump of your library to your Windows users? Your OS X users? iOS? FreeBSD? RedHat? Android? Mint? Debian? PS4? Redox? Xbox One? Solaris? Switch? I've dynamically linked into PuTTY before - a good 'ole C codebase - and I still had to rebuild and redeploy myself when a security patch landed.

Meanwhile, an updated package on crates.io can change deps.rs badges, or trigger dependabot - optionally auto-merging the pull request if CI passes, or altering you to the build failure and need for manual action if that "patch" version broke things. Rustsec and cargo audit/geiger/crev are all hideously platform independent ways to catch problems. My patches to an unsound Rust crate can automatically land on your WASM-enabled website if you have things so configured.

Re:The use of `class` for things that should be simple free ... by pas on Thursday May 28, 2020 @07:01AM (#23335882)
I'd like to see the NixOS approach merged with flatpak/snap/whatever. Basically secure/deterministic, fine grained dependencies. Yet easily shared (since they are just content-addressable), and easily updated (since you don't actually have to depend on the content-hash, and distro maintainers can still coalesce the versions of many-many packages' common dependencies).
Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @07:19AM (#23335998)
> Good modern practice (c.f. Rust, etc) is to ship LTO'ed mostly-static binaries.

What Go and Rust do (by default) is only useful for internal software that you have full control of (both in source and in updates), but it is definitely not "good practice" for general software distribution.

Going fully static (Go) or mostly static (Rust) means your users/clients cannot update dependencies easily. Users will suffer when the vendor is not replying as quickly as they would hope for (which is not a pleasant experience at all, specially if you run server software) or when they simply discontinue the software (cf thousands of games). Then there is the usual duplicated code pages with less effective cache utilization etc. (which is a minor issue nowadays but if everything is a 100 Mo Electron copy it starts being painful).

Re:The use of `class` for things that should be simple free ... by loopz on Thursday May 28, 2020 @07:51AM (#23336198)
Users/clients could expect to be able to upgrade minor OS/utility versions, but not direct dependencies. There's no reason to expect rogue upgrades of dependencies to work out of the box, unless explicitly guaranteed by subvendors ie. within minor versions. The modern approach is to encapsulate the complexity within a static binary, or even containers with more files. The deliverables are provided and guaranteed by the vendor. If there are security issues, 99% of that should rather be solved by safe language usage and security perimeter or encrypted channels, while refraining from unsafe library dependencies and direct connections to core business processes.

Linux packaging is interesting, since the delivery model of gratis distributions often have no such guarantees. Thus one may indeed experience difficulties at any moment after a recent upgrade due to that model. In that case, the complexity lies within upstream and distro, a shared responsibility that the distro should reconcile but may fail to do in minute detail.

Modern methods involve a pipeline, and no rogue upgrades that haven't passed multiple stages of tests and security checks.

Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @05:10PM (#23342686)
> There's no reason to expect rogue upgrades of dependencies to work out of the box

If they don’t work, they are broken. Of course it can happen, but the opposite approach means never being able to do it.

> If there are security issues, 99% of that should rather be solved by safe language usage and security perimeter or encrypted channels

There is no mainstream language or operating system out there that solves "99% of security issues" unless you are talking about formally proven systems etc.

> The deliverables are provided and guaranteed by the vendor.

As I explained in the GP, this only happens for systems with support contracts.

For most software out there, this isn’t the case. Mainstream software vendors don’t guarantee you anything at all, for good reasons.

> Modern methods involve a pipeline, and no rogue upgrades that haven't passed multiple stages of tests and security checks.

That is not "modern". That is how it has always been done since the 80’s. Again, for software properly supported.

I am not sure why you talk about "rogue" updates, since nobody has mentioned such.

Re:The use of `class` for things that should be simple free ... by jcelerier on Thursday May 28, 2020 @07:58AM (#23336237)
> Users will suffer when the vendor is not replying as quickly as they would hope for (which is not a pleasant experience at all, specially if you run server software) or when they simply discontinue the software (cf thousands of games).

My experience as a Linux user is that I suffer even more from some minor update in /usr/lib/libwhatever.so suddenly breaking some feature in software that I use to do my job / have fun, which wouldn't happen at all if that software was self-contained.

Re:The use of `class` for things that should be simple free ... by jfkebwjsbx on Thursday May 28, 2020 @05:17PM (#23342776)
Being self-contained does not imply statically linked, though.

The benefit of dynamically linking is that you (as a user) or upstream (most likely) can fix those issues you point out, including future ones.

Being self-contained simply means updates aren’t forced into it, which is a good thing and I agree with it.

I didn’t downvote you, by the way, since the point you make is valid.

Re:The use of `class` for things that should be simple free ... by nicoburns on Thursday May 28, 2020 @05:32AM (#23335248)
> This means you basically cannot release patch versions of your library because consumers cannot link against it if they have the old headers.

This is pretty much only a problem in C/C++ though. Everyone else is using static linking (which you can of course also do in C++), or a VM of some form. IMO relying on a library having stable ABI is a bit of anti-pattern. It's like relying on the implementation details of a function/class rather than it's API: sometimes it's necessary, but it should be avoided if possible.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @05:54AM (#23335450)
Java has the possibility of maintaining ABIs as well. And I imagine that's what .Net assembles are about too.

I think you're heavily over stating reliance on libraries having stable ABIs as an anti-pattern. If a mistake is made in the ABI promise, can it get hairy? Absolutely. If you work on an application and are somewhere in the middle of it and need to recompile it to test a fix, do you want to wait for the compilation of the entire application to test it? Obviously not.

Re:The use of `class` for things that should be simple free ... by im3w1l on Thursday May 28, 2020 @09:11AM (#23336818)
In C you would do

    my_lib_cool_func(myobj, 1, 2, 3);
so you don't pollute the global namespace excessively. Having it accessed through the object avoids that.
Re:The use of `class` for things that should be simple free ... by Const-me on Thursday May 28, 2020 @06:43AM (#23335775)
> Is this better?

Very few professional developers code in vim or notepad. Vast majority of us are using IDEs. IDE knows types of things, type `myobj.` and you'll get a suggestion list with methods of that class callable from the current context.

> There is then a pattern to do this in C++ called pimpl

There's another useful pattern in C++:

    struct iObj
    {
        virtual ~iObj() { }
        virtual void cool_func( int a, int b, int c ) = 0;
        static std::unique_ptr<iObj> factory();
    };
Re:The use of `class` for things that should be simple free ... by mrep on Thursday May 28, 2020 @07:24AM (#23336028)
> Very few professional developers code in vim or notepad

Notepad++ and vim are the 3rd and 5th most popular development environment according to stack overflows 2019 report [0] and I and many others I know use Vim at least.

> IDE knows types of things, type `myobj.` and you'll get a suggestion list with methods of that class callable from the current context.

I've never used notepad but Vim absolutely supports omni completion [1].

[0]: https://insights.stackoverflow.com/survey/2019

[1]: https://vim.fandom.com/wiki/Omni_completion

Re:The use of `class` for things that should be simple free ... by jcelerier on Thursday May 28, 2020 @08:33AM (#23336483)
> Notepad++ and vim are the 3rd and 5th most popular development environment according to stack overflows 2019 report [0] and I and many others I know use Vim at least.

in C++ the ratio of ppl I know using an IDE with semantic code completion ability (that is, not rtags but actually using e.g. libclang or something that does understand C++ to some extent for IDE completion) vs "glorified text editors" must be 95/100 using an IDE though.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @10:07AM (#23337365)
Vim and VS Code have access to semantic code completion through the language server protocol.

But your assertion is weird. Either you work on Windows where everyone is on Visual Studio, or you have 95/100 people around you using CLion, XCode, and Qt Creator, two of which don't even have an entry on GP's survey link. One of which is probably only used to sign apps for ios. Could you give more info?

Re:The use of `class` for things that should be simple free ... by gpderetta on Thursday May 28, 2020 @10:30AM (#23337708)
I use emacs with clangd on a fairly large (~2M lines of code), but between clangd getting stuck, crashing or being too slow, I don't really get much benefits from it. When it works is great though.

TBH, in my limited experience, I have never seen code completion working well on large C++ code bases. I remember years ago VS literally becoming unresponsive when intellisense was enabled.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @06:51AM (#23335820)
https://www.cairographics.org/manual/cairo-cairo-t.html

All operations on `cairo_t` have prefix `cairo_`

Re:The use of `class` for things that should be simple free ... by Const-me on Thursday May 28, 2020 @07:08AM (#23335918)
That's doesn't give context for IDE. You can type `cairo_` and get suggestions what may follow, but you can't type `x.` and get suggestions on what you can do with x.
Re:The use of `class` for things that should be simple free ... by eternauta3k on Thursday May 28, 2020 @12:14PM (#23339002)
While PIMPL has additional indirection for accessing member variables, this pattern has indirection for accesing methods (need to go through vtable).
Re:The use of `class` for things that should be simple free ... by fluffything on Thursday May 28, 2020 @06:43AM (#23335769)
Why? The main advantage of passing a state as an argument is letting the user control the state. If you need an array as state, the user might want to put the array on the stack, or the heap, or in static memory, or protected behind a mutex somewhere...

It doesn't really matter that much how things are actually implemented: most languages are flexible enough that you can do this with a class or a function or even implement the algorithm as a generic interface. But if you want the algorithm implementation to be reusable, you have to remove as many assumptions about the state as possible because otherwise some users won't be able to use your algorithm.

If you pick up a class, and the class owns the state, now you need to make the class generic to allow the user to customize the state, you need to allow the user to break the state invariants, to be able to unsafely read and write from it, because otherwise you are forcing the user to read into a separate buffer, and then make a copy to your class, etc.

Somebody that knows how to avoid all these issues when writing their algorithm as a class, probably also knows that by just using a function most of these issues just cannot happen anymore (or are much harder to introduce).

You can also write the algorithm as a function, that takes some generic state, and provide a "class wrapper" for convenience, so that those who don't want to customize anything don't have to. But then your class doesn't implement the algorithm anymore, it just wraps it.

Re:The use of `class` for things that should be simple free ... by jmull on Thursday May 28, 2020 @07:34AM (#23336090)
If we’re talking about an algorithm as a class, the state managed by the class is algorithm state, not the data the algorithm acts on. The data the algorithm acts on should probably be passed as a parameter regardless of whether the algorithm is implemented as a class or top-level function.
Re:The use of `class` for things that should be simple free ... by fluffything on Thursday May 28, 2020 @09:52AM (#23337224)
> If we’re talking about an algorithm as a class, the state managed by the class is algorithm state, not the data the algorithm acts on.

I was only talking about algorithm state here. Check, for example, how the C++ string searching algorithms work to get a feeling of how these APIs work in the wild. For an example of this gone wrong, look no further than C++ stable_search, which does not let the user reuse the merge sort buffer across searches.

Re:The use of `class` for things that should be simple free ... by jmull on Thursday May 28, 2020 @01:15PM (#23339838)
Hm, I guess this is moving in the direction of a debate on semantics and API design... which is independent of the original topic.

I don’t know what stable_search is, but it would be a design decision if/how it supports different memory management options for buffers, and isn’t really affected by the decision to use a class or top-level function for implementation. Either way, buffer allocation could be hidden in the implementation and out of the user’s control or exposed to some degree and under the user’s control.

Re:The use of `class` for things that should be simple free ... by amw-zero on Thursday May 28, 2020 @03:58AM (#23334675)
Why? You would never suggest this if OO wasn’t the predominant paradigm. What is the benefit of implicitly passing the parameter? I prefer to see it passed explicitly, so the implicit passing is a downside to me, not a benefit.
Re:The use of `class` for things that should be simple free ... by jabirali on Thursday May 28, 2020 @04:20AM (#23334835)
In many languages, it is an explicit parameter though.

For instance, in Python, one would define a function with `def fun(state)` or a class method with `def fun(self)`. In the function body, one would use respectively `state.var` or `self.var` to refer to a variable `var` in the state object. Running it is then done using `fun(state)` or `state.fun()`.

There are some minor syntactic differences between the two, but I find both these examples to be just as explicit...

Re:The use of `class` for things that should be simple free ... by mcv on Thursday May 28, 2020 @05:19AM (#23335153)
If it's already explicitly part of an object, do you need to be explicit about the same thing twice?
Re:The use of `class` for things that should be simple free ... by still_grokking on Thursday May 28, 2020 @04:43AM (#23334946)
So you would not use type-classes in Haskell as they rely on implicitly passed parameters to functions?
Re:The use of `class` for things that should be simple free ... by kqr on Thursday May 28, 2020 @04:50AM (#23334988)
I can't speak for the GP, but what makes typeclasses in Haskell work for me is that there's a very strong cultural force ensuring that they are truly about consistency boundaries and maintaining invariants/laws.

Haskell developers don't just create a typeclass to bunch related functionality together. Doing so is a common beginner's anti-pattern. Typeclasses exist to wrap up general operations that satisfy some laws.

When objects in OOP are used in the same way, I don't mind it as much. It's when they're not that I don't find the syntactic inconvenience worth it.

Re:The use of `class` for things that should be simple free ... by js8 on Thursday May 28, 2020 @05:57AM (#23335473)
In Haskell typeclasses, it's the type of the parameter that is implicitly passed, not the parameter itself.
Re:The use of `class` for things that should be simple free ... by uryga on Thursday May 28, 2020 @06:09AM (#23335546)
i don't think that's correct, afaik typeclasses roughly desugar to passing a record of functions (vtable/"dictionary") at the call site
Re:The use of `class` for things that should be simple free ... by taejo on Thursday May 28, 2020 @06:31AM (#23335684)
And that vtable depends on the type, not the value.
Re:The use of `class` for things that should be simple free ... by uryga on Thursday May 28, 2020 @12:36PM (#23339301)
i guess there's really two implicit arguments - the value's type, `a` (quantified via forall - the System F "Λ") and its vtable `Show a`... though i guess the vtable is uniquely determined by the type bc in Haskell instances are globally unique
Re:The use of `class` for things that should be simple free ... by fauigerzigerk on Thursday May 28, 2020 @04:14AM (#23334807)
The canonical answer is encapsulation. But in my view it's rarely a good idea to couple state related to an algorithm's invocation (e.g a cache) with the data structure itself.
Re:The use of `class` for things that should be simple free ... by noobermin on Thursday May 28, 2020 @04:47AM (#23334974)
It's almost as if a hard and fast rule doesn't work, ie., the point of the article.
Re:The use of `class` for things that should be simple free ... by hamandcheese on Thursday May 28, 2020 @04:14AM (#23334801)
The benefit is encapsulation.
Re:The use of `class` for things that should be simple free ... by _0ffh on Thursday May 28, 2020 @04:59AM (#23335039)
Don't need a dedicated OOP lang for that benefit.

It's an age-old discussion. As old school software engineering became sufficiently advanced, some people bundled their favorite "state of the art" concepts, and called it OOP. (Also: Multiple people, multiple different concepts of what "OOP" actually precisely means.) It became a horrible hype, and from then on out everyone was taught to see all these concepts as "OOP concepts" that elevate OOP over other programming paradigms.

But they're not and they don't.

The only real "advantage" is, OOP languages are opinionated and will try to force their interpretation of these concepts on the coder. Which is nice, if you happen to like it that way. Just not everybody does.

Re:The use of `class` for things that should be simple free ... by fnord123 on Thursday May 28, 2020 @05:18AM (#23335149)
Encapsulation's a weird one. It's a cornerstone of OO but most/all OO languages have rubbish support for ABIs so changing your object in one library means you need to recompile your code using the library. This is the opposite situation that encapsulation seems to promise (in my view).
Re:The use of `class` for things that should be simple free ... by thom on Thursday May 28, 2020 @07:06AM (#23335907)
Is encapsulation different in either case? Nobody should be operating directly on the state, any more than they should be reflecting on private fields in a class.