Closed jonathanstiansen closed 5 years ago
I'd love @DrBoolean's perspective here. I feel pretty good in calling them isomorphic.
(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.
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
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 :-)
😊
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.
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.
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.
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.
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?