getify / Functional-Light-JS

Pragmatic, balanced FP in JavaScript. @FLJSBook on twitter.
http://FLJSBook.com
Other
16.6k stars 1.96k forks source link

Chapter 7: How are closures and objects isomorphic? #169

Closed jonathanstiansen closed 5 years ago

jonathanstiansen commented 5 years ago

Closures and objects differ in how they allow access. Is information access not a behaviour? If it is, by definition doesn't that mean they are not isomorphic?

getify commented 5 years ago

I'd love @DrBoolean's perspective here. I feel pretty good in calling them isomorphic.

jonathanstiansen commented 5 years ago

(First thanks for your book, it's awesome - please don't take this as negative)

I've checked it and my reading group is discussing it, but your clear definition that isomorphism includes the same behaviour seems to be quite counter to @DrBoolean definition (and we're arguing how you use isomorphism). He says that :

That's just a fancy word for "holds the same data".

But you state clearly that behaviour is part of your definition, but he certainly says that an advantage of isomorphism is you can convert, and use different behaviour when your data is in different 'shapes'.

And I feel you use it that way too.

DrBoolean commented 5 years ago

Plenty of isomorphisms allow different behavior - consider String to List[Char] or IO to Task

You can prove an isomorphism by providing the two functions converting back and forth.

Here's a simple one:

class MyObject {
  constructor(name) {
    this.name = name
  }
  greet() {
    return `hello, I'm ${this.name}`
  }
}

const toClosure = x => {
  const name = x.name

  return {name}
}

const fromClosure = x =>
  new MyObject(x.name)

const sam = new MyObject('sam')
fromClosure(toClosure(sam)) = sam

I don't know about a proof forall closures to objects, but i suspect with getOwnPropertyNames and __proto__ it is possible

jonathanstiansen commented 5 years ago

Hello @DrBoolean, and may I say thank you to both of you for your work!

But my beef, so to speak, is with @getify specifically calling out isomorphism as including the same behaviour in Chapter 7 and wondering if you could maybe just remove one line:

Put simply, closures and objects are isomorphic representations of state (and its associated functionality).

Because I think the key here the "it's associated functionality" is not precise or helpful, and for us was quite a stumbling block to seeing any value in isomorphism, or how in a behavioral sense it could actually be done :-)

DrBoolean commented 5 years ago

😊

Good call. I think the chapter does isos justice, but that line is misleading for sure.

On Sep 26, 2018, at 7:44 AM, Jonathan Stiansen notifications@github.com wrote:

Hello @DrBoolean, and may I say thank you to both of you for your work!

But my beef, so to speak, is with @getify specifically calling out isomorphism as including the same behaviour in Chapter 7 and wondering if you could maybe just remove one line:

Put simply, closures and objects are isomorphic representations of state (and its associated functionality).

Because I think the key here the "it's associated functionality" is not precise or helpful, and for us was quite a stumbling block to seeing any value in isomorphism, or how in a behavioral sense it could actually be done :-)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

getify commented 5 years ago

The intent of this line, and others associated, is to suggest outcomes and behavior and functionality in a general or abstract sense, rather than strictly/concretely about how exactly it does something.

Consider a function foo() and bar(). In the sense presented in this chapter, they would be isomorphic if, in an abstract sense, you passed in the same sort of stuff and got out the same sort of stuff, even if the representation of the input or output were different, and even (and especially) if both functions went about the computation in entirely different ways.

As far as I'm concerned, if two things do entirely different things (not just the same thing in a different way), then it's not isomorphic. But if two things accomplish the same goal or outcome, even in different ways, they're isomorphic. That's the intent of my explanation in this chapter.

I'm not claiming closures and objects are isomorphic in some strict mathematical sense, I'm suggesting they're isomorphic in the sense that you largely can accomplish the same (essentially) outcomes with either, though clearly there are differences in how you go about it.

edit: also, the chapter suggests that isomorphism implies the ability to convert/transform one to the other and back.

DrBoolean commented 5 years ago

Right, I'm coming from the strict mathematical sense in that as long as two things can be converted back/forth, it doesn't matter what they do or how they work. It's solely about data.

But in the spirit of the book, i suppose the mathematical sense is less important than practical.

However, I've found isomorphisms to be very useful in practice for type conversions specifically to get different behavior: truncated = compose(fromList, concat('...'), take(3), toList) or converting a Map to a List of pairs for ordering. Also for encoding/decoding (especially relevant now with ML predictions). Just knowing there's an isomorphism is really helpful or proving there is one in order to ensure we can predict/reify some data structure.

getify commented 5 years ago

Mathematically, I'm sure there is benefit to two completely different things being able to be transformed one to the other. But in programming, I have found such a distinction to be less practical.

Instead, what I've found useful is when one thing doing one task can be transformed to another thing performing substantially the same task, but with potentially different tradeoffs or benefits. If I wanted two separate things that did wildly different tasks, they would just be two different pieces of code. I wouldn't see much programming use for being able to transform between them.