Live data from Hacker News

The use of `class` for things that should be simple free functions

quuxplusone.github.io

331–340 of 406 posts

Re: The use of `class` for things that should be simple free functions

#331

In typescript I will for example make a class called 'Tools' with static 'free form' functions and no constructor. I do it just because it's easy to organize, import and call the functions. Is this bad?

Not saying this is "bad", but why not use a module for that?

Re: The use of `class` for things that should be simple free functions

#332
post #98
post #29

Earlier quoted context omitted.

C# is slowly moving away from "everything is a class". Static classes with static imports is basically a module or namespace. C# also allows stand-alone functions inside methods. But you still have to declare a static class to hold "top-level" functions, which is somewhat ugly. Given the current development of C# I expect we see stand-alone functions in the future.

C# 9 will allow stand-alone functions in the top level program. They do however count as local functions to the top level programs, and will not be accessible from anywhere outside of that context.

Yeah, though it basically amounts to syntactic sugar at this point.

Re: The use of `class` for things that should be simple free functions

#333

I'm fairly new to Unity programming in C# and I was surprised a few months ago that everything in C# must be in a class. As far as I can tell there is no such thing as just a function. Now I have I have a class with some static functions in it.

"everything in C# must be in a class" As an aside, C# also has structure types which have value semantics - one example being DateTime: https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

Not to mention tuples and (soon in C# 9!) record types.

Re: The use of `class` for things that should be simple free functions

#334

Earlier quoted context omitted.

If you do use a class for this, of course you can provide a wrapper function that constructs the object, calls the "run" method on it, and returns the result. This can be in addition to the processing class, or it can be the entirety of the public API while the processing class is defined privately in an implementation file. I've done this before for Munkres, also called The Hungarian Algorithm, which assigns jobs to…

I get how this works and the reason for it. It just doesn't feel DRY to me. Like we're adapting to satisfy a pattern vs the pattern serving us and our dev goals. Aesthetically unpleasing, imo.

There's nothing repeating here... you define a procedure to achieve a higher-level task, which is a combination of other tasks. Kind of like File.ReadAllBytes() vs. FileStream. Later you use it when you need to perform that high-level task.

Re: The use of `class` for things that should be simple free functions

#335

The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures." Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He careful…

I felt as though I should know the moral of the story, yet I did not.

https://stackoverflow.com/a/11421598 Moral of the story is that closures and objects are ideas that are expressible in terms of each other, and none is more fundamental than the other. That's all there is to the statement under consideration.

Re: The use of `class` for things that should be simple free functions

#336

The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures." Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He careful…

I felt as though I should know the moral of the story, yet I did not. https://stackoverflow.com/a/11421598 Moral of the story is that closures and objects are ideas that are expressible in terms of each other, and none is more fundamental than the other. That's all there is to the statement under consideration.

It's code and state. Nothing more. Nothing less.

Re: The use of `class` for things that should be simple free functions

#337

Earlier quoted context omitted.

> 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…

> 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.

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 functions

#338
post #320

Earlier quoted context omitted.

I think your Wallet.pay(amount) example argues for a different conclusion than you arrive at. I have a Wallet with $500 in it. I call Wallet.pay(100). In your approach, it returns a new Wallet with $400 in it. But I also still have the old, unmutated Wallet with $500 in it, which could be referred to by mistake (or by malice). That's probably not the best argument for immutable objects...

If you limit the scope of usage, the old wallet should be garbage collected as soon as you have the new one. If you don't want to rely on that, or the point in time when gc happens is important or you're dealing with sensitive data, then the environment should allow you to perform appropriate cleanup actions and for you to utilize a different means to control and protect the data.

As josephcsible said in a post parallel to yours, affine types can do this for you. If not, though... if you never mess up and keep a reference to the old one, you're good. I don't care when it's garbage collected; if there's no reference to it, it's not going to be used. But if anybody, ever, keeps a reference...

Re: The use of `class` for things that should be simple free functions

#339
post #189

Earlier quoted context omitted.

> 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 whe…

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 t…

> 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 functions

#340
post #3

Also known in python as "if your class has only two methods, one of which is init, it's a function" in the "stop writing classes" https://www.youtube.com/watch?v=o9pEzgHorH0 EDIT: typo, changed link

what if it has just values (like an enum)?
Post reply on HN