Earlier quoted context omitted.
In that setup, how do you write a test which acts against a mock version of your API client (a static function in your proposal?)
Run a fake version of the API server, and then connect the real client to it. It is usually a mistake to make the "unit" of your unit test too small.
Don't Be Afraid of Types
151–160 of 233 posts
Re: Don't Be Afraid of Types
#152As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…
The article's perspective would be that structs are useful, so use them liberally. And nearly all good, large C programs do, as far as I can tell.
Of course there are tradeoffs and you can take it too far. The article mentions that as well.
Re: Don't Be Afraid of Types
#153Earlier quoted context omitted.
I believe OO was never meant to be reasoned about, it was just a way to avoid coupling just enough to avoid death. Also, even as a FP head, I think something is missing in FP for some domains.. where I go from object state soup, to function composition soup. At which point I'm in need for a kind of protocol algebra (sitting between pure FP and object graphs). Maybe haskellers do that in their own way, sadly I don't h…
OO (as a data container or not) fits into some domains very well. Gonna get stuff from a database? Objects are great. Want to move something without being accidentally written/corrupted? Objects are great. Want to model a 3D object with per node/face/$ANYTHING properties, objects are great. Does object handle everything? Of course not, but having it as a capability at hand allows some neat tricks and tidy code. I bel…
Re: Don't Be Afraid of Types
#154Earlier quoted context omitted.
But once you get down to the unit data values inside any of those aggregates, you're still dealing with either characters, ints, floats, strings, arrays, and they each have their own individual access patterns and, more importantly, modification functions. You can't add a number to a string, only to another number. If you are dealing with a float, you better be careful how you check it for equality. If it's pure bina…
> You can't add a number to a string Haven't written JavaScript?
Re: Don't Be Afraid of Types
#155> I found that there’s a slight aversion to creating new types in the codebases I work in. I've encountered the same phenomenon, and I too cannot explain why it happens. Some of the highest-value types are the small special-purpose types like the article's "CreateSubscriptionRequest". They make it much easier to test and maintain these kinds of code paths, like API handlers and DAO/ORM methods. One of the things that…
This can't be the explanation for everything, but I do know that once upon a time just the sheer source-code size of the types was annoying. You have to create a constructor, maybe a destructor, and there's all this syntax, and you have to label all the fields as private or public or protected and worry about how it fits into the inheritance hierarchy... and that all still applies in some languages. Even the dynamic…
You don't even need a modern language for that kind of thing, plenty of languages from a half century or so ago also let you do that. From Ada (40+ years old):
type PrimaryColor is (Red, Green, Blue);
Or if you're content with a mere alias, C (50+ years old) for your first example: typedef char* MyNewType;Re: Don't Be Afraid of Types
#156As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…
But once you get down to the unit data values inside any of those aggregates, you're still dealing with either characters, ints, floats, strings, arrays, and they each have their own individual access patterns and, more importantly, modification functions. You can't add a number to a string, only to another number. If you are dealing with a float, you better be careful how you check it for equality. If it's pure bina…
Works in C, as long as the integer keeps the resulting pointer within the bounds of the allocation. See a trivial example[1].
Re: Don't Be Afraid of Types
#157Earlier quoted context omitted.
OO (as a data container or not) fits into some domains very well. Gonna get stuff from a database? Objects are great. Want to move something without being accidentally written/corrupted? Objects are great. Want to model a 3D object with per node/face/$ANYTHING properties, objects are great. Does object handle everything? Of course not, but having it as a capability at hand allows some neat tricks and tidy code. I bel…
Objects are famously bad at (relational) databases, hence a near universal loathing of ORMs.
I also write my templated queries myself and talk with the server directly. No need to go "FizzBuzz Enterprise Edition" for a simple task.
Re: Don't Be Afraid of Types
#158People might be afraid of types because in OOP land there's the idea that types aren't mere containers for data. You have to use encapsulation, inheritance and polymorphism. Fields and properties shouldn't have public setters. You assign a value only through a method, otherwise you make the gods angry. You have gazillions of constructors, static, public, protected, private and internal. And you have gazillions of met…
Mostly agree, but there are methods that truly are best co-located with their (immutable) data. A good example is Point.Offset(deltaX, deltaY) which returns a new point relative to the callee. Why force that into a static class? There are plenty of examples where you want to use an abstraction over various immutable record types. Services vs. records is a false dichotomy and there is power in mixing the two. Yes, the…
There's probably a deeper question, how to make objects 'transposable' in general case (like going from row-based to column-based representation) without duplicating code or exposing internals?
Re: Don't Be Afraid of Types
#159Earlier quoted context omitted.
OOP eventually degrades into "lasagna" (a play on "spaghetti code".) Layers and layers of complexity like you describe. Once you have enough "layers" it becomes almost impossible to follow what is actually happening.
I don't think this is what lasagna means. Lasagna is when you have your software organized in layers. In other words instead of having a big ball of mud where A calls B calls C calls A calls C calls B you have layers (like in lasagna) so that A calls B calls C and you keep your code base so that classes/modules/types that are in the lower layer do not depend on or know of the anything above them and the dependencies…
https://stackoverflow.com/questions/2052017/ravioli-code-why... https://en.wikipedia.org/wiki/Spaghetti_code#Ravioli_code
A related principle that I don't think is talked about enough is "locality": I'd rather have all the code about one feature in one file or close together, rather than it strewn across files where it's harder to read and understand as a whole. Traditional Java was notorious for being the opposite of this. Traditional HTML+CSS+JavaScript is also very bad for this problem.
Re: Don't Be Afraid of Types
#160Earlier quoted context omitted.
OOP eventually degrades into "lasagna" (a play on "spaghetti code".) Layers and layers of complexity like you describe. Once you have enough "layers" it becomes almost impossible to follow what is actually happening.
I don't think this is what lasagna means. Lasagna is when you have your software organized in layers. In other words instead of having a big ball of mud where A calls B calls C calls A calls C calls B you have layers (like in lasagna) so that A calls B calls C and you keep your code base so that classes/modules/types that are in the lower layer do not depend on or know of the anything above them and the dependencies…