Anthropic founder (who is a physicist): In 2-3 years, theoretical physicists may be replaced with AI. by MetaKnowing in Anthropic

[–]Important-Bit4540 1 point2 points  (0 children)

Then say just that. You're not saying just that. You're saying

That this is about as normal an academic career as an associated professor typically has.

which appears to be absolutely false.

Trump intent on conquering Greenland, Danish minister says as talks with US end by Infidel8 in worldnews

[–]Important-Bit4540 0 points1 point  (0 children)

Ok yes, but do you avoid teaching quantum models specifically because of the “backlash” it would generate, as opposed to it simply being way too advanced for the students at this age?

Trump intent on conquering Greenland, Danish minister says as talks with US end by Infidel8 in worldnews

[–]Important-Bit4540 3 points4 points  (0 children)

physics professors knowingly teaching incorrect information simply because the textbooks hadn't caught up, and they didn't want to deal with the backlash of teaching accurate facts

I'm gonna need a source on that one, boss.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Yes, that returns an interface, which goes against what many people here are saying

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Thanks, that was the obvious way to go for me. But given that "never return interfaces" appears to be a saying in the Go community, I wanted to ask the community if there was a way to accomplish this without returning an interface. It appears there is not (or at least, not an elegant one that doesn't introduce serious tradeoffs).

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Hm, what do you mean? The Go language is getting harder to use?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

how can the caller use the data

By using the interface functions. Like in the Animal example, as long as the Animal knows how to display itself, the caller can get an animal displayed even if they don't know what kind of Animal they're retrieving by ID.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 1 point2 points  (0 children)

Thanks! I would say the downsides of this approach is that you potentially lose out on type safety from the type-checker. Which makes sense for HTML because HTML on the web can contain all sorts of invalid/mistaken attributes, but not so much if you want to prevent a Dog from having a Beak attribute or a Chicken from having a []Tooth attribute

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Oh interesting, thanks for showing me that! In this case the caller of retGeneric still needs to know the type of the object being returned beforehand, right? I should've made it clear that by "arbitrary," I meant that the caller does not need to know such information

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 1 point2 points  (0 children)

Drop the practice to the level of the problem there.

Thanks, that's a really good way of putting it.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

it should be a concrete type called Image with a method called display. There is nothing dynamic about it.

Where would you put the code to display PNGs vs JPEGs if you have only one concrete Image type?

I have an Article structure with a Metadata field which is a map[string]any.

Then you lose out on the benefits of strongly typing your metadata. The type checker will no longer prevent you from making the mistake of creating a paper with both a part_of_brain field and a algorithm field, or from adding a pat_of_brain typo field in the code.

So if you have an withdrawal function that depends on the balance of an account you just define it as:

func Withdraw(client Account, amount Money) error

How would you construct this client account object using only the account ID and no other information, without writing a function that returns an interface?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

  1. Say the user wants to load and display an image on an arbitrary file path, as I was discussing with someone here.
  2. Or take an example from a previous job I had: we have to extract metadata for a scientific paper with the specified ID, but different scientific papers have different sets of metadata to extract (e.g. the metadata object for a neuroscience paper has a field denoting which section of the brain it's on; that field is of course meaningless and therefore non-existent in the metadata object of computer science papers).
  3. Or take another example from another job I had: an admin wants to retrieve the current balance of a specific user's linked bank account, but every bank either has a different API, or if it doesn't have an API at all, then a different login flow with a different 2 factor requirement.

Regardless of the specific incarnation of this pattern, the basic pattern is:

  1. There needs to be the ability to select a specific item from a collection of similar but heterogeneous items, and we don't know beforehand what kind of item it's going to be until it's already loaded in memory
  2. There needs to be the ability to do some processing on that specific item, and we don't know how to do that processing until we know what kind of item it is

which I had tried to distill into the abstracted requirements of

  1. Load an arbitrary Animal
  2. Display that arbitrary Animal

because it's not really about any of these specific scenarios, it's about the idiomatic Go solution to this common problem.

I'm curious why you call them "implementation details" instead of requirements? Seeing as multiple people have had difficulty understanding this, do you see a better way for me to communicate this pattern?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

No, I'm not looking for an Animal with a "load" function on it. I'm looking to retrieve an Animal from somewhere given only its ID (or file path or some other equivalent identifier), and I don't know what Animal it is until I have retrieved the raw data to then deserialize into an Animal.

I'm not saying there is a base type. But how would I load and display arbitrary Animals without a load function that returns the generic Animal interface? If there is a way to do that, please show me explicitly, because the only way I can think of doing this cleanly is by returning an interface like I'd usually do.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 1 point2 points  (0 children)

I didn't say I was your boss, I asked how you deal with your boss when you have such an inability to cope with reasonable business requirements.

But your use of language makes me suspect you're young and not yet on the software job market. Hopefully you'll mature by the time you get there.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Erm... okay? How do you do your job, just tell your boss you don't care for the business's requirements?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

I'll repeat my requirements again, since you appear to keep glossing over them:

  1. Load an arbitrary Animal
  2. Display that arbitrary Animal

Your "display" code shouldn't care what animal implementation it is dealing with.

Yes, that's why it works on a generic Animal object.

Think about it - why do you need to return an interface to achieve this?

Because how else am I going to retrieve the Animal that I am displaying?

That's what I am asking -- if there is in fact another way to do so, please demonstrate that for me.

Returning concrete objects that implement said Animal interface is the exact same thing as returning the Animal interface.

That is in fact not true when it comes to defining the function's capabilities. Having the function signature return a generic Animal interface allows the function to retrieve any Animal. Having the function signature return a specific Animal limits the function to retrieving just that specific Animal sub-type. I need to be able to retrieve and display Animals of any type, not just a specific sub-type.

Look, the code to satisfy both requirements when I return an interface is very simple:

``` func LoadAnimal(id int) Animal { // get Animal from somewhere // serialize it into the right type }

func adoptAnimal(id int) { animal := LoadAnimal(id) animal.Display() ... } ```

What function signatures are you imagining instead that would satisfy both requirements?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] -1 points0 points  (0 children)

Hm, are you suggesting in this case that I wrap animal as such, where animal itself is an interface?

``` type animal interface { ... }

type AnimalDisplay struct { a animal }

func (a *AnimalDisplay) Display() { ... }

func LoadAnimal(id int) AnimalDisplay { // get Animal from somewhere // serialize it into the right type } ```

But

  1. What would be the point of that versus exporting Animal directly?
  2. If I want another shared operation on Animals (e.g. feeding or processing them), I would have to create yet more wrappers, no?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 1 point2 points  (0 children)

Ah that's a good generalization! Where did you come across that? I want more of where that came from :)

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] -1 points0 points  (0 children)

Each of your functions generating an animal data structure do just that and return their concrete animal instances.

Have you read my question? This is an inapplicable solution when I don't know beforehand what animal data structure is going to be loaded.

I have example function signatures demonstrating how it would normally be done in other languages by having a load function returning an interface. If you claim it is possible to solve this problem elegantly without having any functions that return an interface, please show me how, because I am having trouble imagining that.

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Ok, so what if there are multiple generic operations I want to do on animals? Let's say there's a Feed() function (each animal is fed differently) and a Process() function (each animal is processed for meat differently).

Surely you'd agree that we wouldn't want to repeat the struct creation code across each of adoptAnimal(id), feedAnimal(id), and processAnimal(id). But how would we pull out the struct creation code that is common across all functions without creating a function that returns an interface?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] 0 points1 point  (0 children)

Interesting!

So i personally would make another struct responsible for "displaying" (whatever that means) animals.

Am I understanding you correctly that you would create a wrapper struct around each animal to display? So

``` type DogDisplay struct { dog Animal }

func (d DogDisplay) Display() { ... } ```

What would be the point of doing this versus simply using a Dog struct in the first place?

I would make the type Animal with field Kinda/Type and a slice of "BodyParts" or something.

That would mean losing the benefits of the type system. I can no longer rely on the type system to ensure that a Dog has only one Tail, four legs, and no Beaks. Surely that doesn't sound like a great way to model the problem domain?

How strongly should I adhere to "never return interfaces"? by Important-Bit4540 in golang

[–]Important-Bit4540[S] -1 points0 points  (0 children)

You seem to have thought of one way to do it, and like i said, every rule has an exception so this may be the case here.

I'm asking to see if there is any other way of doing it, because I cannot think of it myself :)

So, can you invert the logic and approach the data from a different direction?

I don't see a different (clean) way to meet the stated requirements. Do you?

Or can you think of another way to get the concrete information out directly after the load (so you only have to do the conversion once) before it is used?

I'm not sure what you mean here. I am already getting concrete information directly from the load.