Maybe I'm missing something, but it seems that the distinction between an abstraction and implementation only becomes relevant when the language has a distinction between the two?
In some senses, Javascript developers work only in abstractions; if I have two different API services in Javascript, and they both implement a .get, how would we distinguish, in Javascript, between writing a function which relies on an implementation of a thing-which-needs-a-get-function, and an abstraction of a thing-which-needs-a-get-function? With an example:
constcallGet=apiService=>url=>apiService.get(url)constapiA={get:url=>console.log(`called get with url ${url} on apiA`)}constapiB={get:url=>console.log(`called get with url ${url} on apiB`)}
I can call callGet using either apiA or apiB. Unless I'm missing something here, I don't really see, in fact, how non-OO languages have any way at all of caring about the distinction between abstraction/implementation; I'd be very glad to be pointed in the correct direction though!
In traditional Javascript there is no guarantee that the service you show, can know ahead of time if both objects (shown above) have implemented the getter pattern. It would only become known at runtime.
This is my #1 reason for advocating class design with types, and why I prefer Typescript over Javascript.
If we use typed classes, then the question is answered before compile time via intellisense. If either of the objects passed in did not implement getters the red squiggly line would show via intellisense while coding.
Therfore questions like 'how do we know' are answered by Intellisense. It's perhaps the greatest tool for programmers ever; and it works best on Typed objects.
Maybe I'm missing something, but it seems that the distinction between an abstraction and implementation only becomes relevant when the language has a distinction between the two?
In some senses, Javascript developers work only in abstractions; if I have two different API services in Javascript, and they both implement a
.get
, how would we distinguish, in Javascript, between writing a function which relies on an implementation of a thing-which-needs-a-get-function, and an abstraction of a thing-which-needs-a-get-function? With an example:I can call
callGet
using eitherapiA
orapiB
. Unless I'm missing something here, I don't really see, in fact, how non-OO languages have any way at all of caring about the distinction between abstraction/implementation; I'd be very glad to be pointed in the correct direction though!In traditional Javascript there is no guarantee that the service you show, can know ahead of time if both objects (shown above) have implemented the getter pattern. It would only become known at runtime.
This is my #1 reason for advocating class design with types, and why I prefer Typescript over Javascript.
If we use typed classes, then the question is answered before compile time via intellisense. If either of the objects passed in did not implement getters the red squiggly line would show via intellisense while coding.
Therfore questions like 'how do we know' are answered by Intellisense. It's perhaps the greatest tool for programmers ever; and it works best on Typed objects.
Indeed, and I'm also a big fan of Typescript; I think the question of catching at runtime vs compile time is a separate question, though.
My main point was that it isn't really possible to assert that Javascript developers don't use abstract declarations. That's all they use.