|
Yeah, it's not really TDD unless you're doing the red green refactor dealio. Which doesn't mean writing with the intention to test afterwards is bad, it's just not really the definition of TDD.
|
# ? Aug 25, 2017 21:14 |
|
|
# ? Jun 8, 2024 11:58 |
|
Hey let's have this discussion again for the 10th loving time
|
# ? Aug 25, 2017 21:27 |
|
vOv posted:Hey let's have this discussion again for the 10th loving time I hope that by clarifying terms early we have preempted confusion and arguing past each other.
|
# ? Aug 25, 2017 21:34 |
|
Bongo Bill posted:I hope that by clarifying terms early we have preempted confusion and arguing past each other. Why would it help this time
|
# ? Aug 25, 2017 22:27 |
|
If there are no tests at all, writing tests is easy. Test that the program is deterministic by giving it golden input and output, if determinism is a feature of your program. The most difficult part of writing tests altogether is actually writing code that can be tested without turning it into a TestGeneratorFactory or whatever. Simple things like passing contextual values via a configuration could allow a test for your client to completely fake/instrument the server-side connection. And then at some point when you're satisfied with your internal regression tests, you probably want some integration tests with the expected users of your library/API/service. Again, what becomes difficult is defining an API surface/abstraction that is somehow amenable to tests which switch out every component not provided by the library. (Regression and Integration) Tests fall naturally out of well-written code IMO. On the other hand, refactoring poorly-written code and the poorly-written tests for it is a nightmare. Refactoring tests in general is difficult because many testing environments are non-hermetic. Tests are haphazardly modifying global state and the order in which the test framework decides to execute your tests could determine the output; i.e. data races exists across test cases. You might think you can extract a piece of test logic from one function only to realize the test setup itself is non-deterministic.
|
# ? Aug 25, 2017 22:36 |
|
I love doing tests, especially acceptance testing where you get to watch the screen blit around clicking like crazy. Back at my last office, I had a project ready to go so that when I needed to show someone from another department what we do, I'd hook up their iPhone to my work machine and have it run through all the tests on the device.Coffee Mugshot posted:Tests are haphazardly modifying global state and the order in which the test framework decides to execute your tests could determine the output; i.e. data races exists across test cases. Don't most runners do the tests in a random order by default for this specific reason? Mezzanine fucked around with this message at 23:08 on Aug 25, 2017 |
# ? Aug 25, 2017 23:06 |
|
Mezzanine posted:Don't most runners do the tests in a random order by default for this specific reason? This helps, but a test runner can only control so much of the test environment. If you have a program which tests a database or network connection by reading a particular socket on your machine from the environment, it is possible between two executions of the test runner that the global/test environment is "fixed" in such a way that give your tests the appearance of being correct. Perhaps a poorly-faked test relies on reliably reading and writing from a table somewhere. It could be possible that two different test runners are executing in different environments and their operations interfere with one another. This actually happens quite frequently when testing interop code: like a python library that calls a C binary. Anyways, the point is, not even a sufficiently clever test driver can save you from shooting yourself in the foot with poorly-written tests that demonstrate patterns found in poorly-specified code.
|
# ? Aug 25, 2017 23:54 |
|
vOv posted:Hey let's have this discussion again for the 10th loving time this thread is a giant xfail stain but nobody cares enough to fix it
|
# ? Aug 26, 2017 00:20 |
|
Don't write tests. Don't write code.
|
# ? Aug 26, 2017 01:35 |
|
Coding horrors: WONTFIX, build fail on test fail disabled, eat poo poo and blind refactor Today's exciting adventure: we're learning how to code Apex, which is salesforce's exciting paean to versions of java past combined with the blind fuckery of multitenant systems design. Perhaps you'd like to use generics? Tough poo poo, idiot! They're not implemented in Apex, so get ready for sObject casts and type errors. They also have a "CICD pipeline" that seems to be built around manual configuration in their ui, with a small portion of development supported by Maven.
|
# ? Aug 26, 2017 01:56 |
|
https://twitter.com/hmemcpy/status/897528863680602113
|
# ? Aug 26, 2017 06:54 |
|
Harik posted:A brave new world of unicode parsing vulnerabilities. I'm honestly glad that I used php instead of perl for late 90s CGI work. As poo poo as it is it didn't train you that clever > *.
|
# ? Aug 26, 2017 07:25 |
|
Ranzear posted:I'm concerned that you phrase it this way instead of 'I should put things in functions and call them from a main flow control.' Functions have the undesirable property of always returning to where they were called from! You can't return through nested function calls directly! You need to write down every single argument and return value! NihilCredo posted:Sounds like you want a finite state machine tbh. Maybe I want a real handy notation for them.
|
# ? Aug 26, 2017 12:36 |
|
Vanadium posted:Maybe I want a real handy notation for them. What's your stack? I can't imagine that writing an enumeration could be so annoying you'd rather fiddle with break statements. For reference, I've refactored messy loops into FSMs in Visual Basic and I can assure you the thought "man, this enum and these functions are a little clunky, maybe I should go back to loops" never even manifested within the same galaxy cluster as my mind.
|
# ? Aug 26, 2017 13:54 |
|
het posted:This post is from a couple weeks ago, but at my first real job, we maintained sendmail-based mail systems and one of the things I wrote was sendmail cf that effectively used the destination address as a stack passing it between rulesets doing map lookups. It was weirdly satisfying to do though obviously gross. checks out
|
# ? Aug 26, 2017 15:06 |
|
Vanadium posted:Functions have the undesirable property of always returning to where they were called from! You can't return through nested function calls directly! You need to write down every single argument and return value! Are you looking for something like F# computation expressions? Happy case programming, no need to nest function calls in error checking if statements.
|
# ? Aug 26, 2017 20:28 |
|
Vanadium posted:Functions have the undesirable property of always returning to where they were called from! You can't return through nested function calls directly! You need to write down every single argument and return value! I grew out of procedural programming a long time ago. Now I do something even worse. I have my own superbastardized idea of objects and classes that works in most languages and centers around serializability for netcode, particularly in javascript but it ends up being very cross-language. I almost exclusively work in class-static functions with structurally-typed objects as arguments (really, more invokes duck typing with class mutation). Each function returns at least the first object argument for functional chaining. A class works out to being the set of static functions that take the typed object as the first argument and the strictly-data definition of the necessary structure for that object. The most important rule is that there are no breakable references on the actual object, and more interestingly the set of static functions for a type can differ between client and server. Each object can maintain a list of its classes for checking, especially in non-typed languages, which are retained through serialization too. The class constructor for an object can also receive an object to mutate instead, appending to its types. The fun part comes when you can just queue up object references to pass into a function, like Entity.Damage(Entity, DamageSource), and execute them later. This means stuff like tanks and projectiles all get to act, then damage gets resolved so nothing gets removed before acting, the key being that a Tank has a Collider class that also adds DamageSource for ramming damage (sets the value on impact), just the same as a Projectile simply has DamageSource. This is my personal coding horror because of the things I leave wide open out of laziness, like how a mutating class might overwrite other properties and should probably instead have it's own namespace on the object. That and slapping all these objects into a singleton and serializing the lot to ram it through a network connection. Anyway, don't need to write down arguments and return values if it's always a typed object
|
# ? Aug 26, 2017 21:30 |
|
Ranzear posted:I grew out of procedural programming a long time ago. Now I do something even worse. I have my own superbastardized idea of objects and classes that works in most languages and centers around serializability for netcode, particularly in javascript but it ends up being very cross-language. i didn’t know star citizen devs posted here
|
# ? Aug 26, 2017 23:37 |
|
uncurable mlady posted:i didn’t know star citizen devs posted here Seriously, that's sort of "source your quote" territory
|
# ? Aug 27, 2017 00:17 |
|
sucks because not lazy Bash code:
Gazpacho fucked around with this message at 00:27 on Aug 27, 2017 |
# ? Aug 27, 2017 00:23 |
|
TheBlackVegetable posted:Are you looking for something like F# computation expressions? No that's just monads, I really want a respectable-looking syntax for goto.
|
# ? Aug 27, 2017 00:47 |
|
Ranzear posted:I grew out of procedural programming a long time ago. Now I do something even worse. I'm... not sure this is what I'm looking for but do you have some sample code?
|
# ? Aug 27, 2017 00:49 |
|
Vanadium posted:No that's just monads, I really want a respectable-looking syntax for goto.
|
# ? Aug 27, 2017 01:01 |
|
Gazpacho posted:It kinda sounds like you want a compiler that can guess what you ambiguously want in a given flow situation. Doesn't everyone?
|
# ? Aug 27, 2017 01:02 |
|
What no I'm happy to be explicit, I just don't want to be verbose.
|
# ? Aug 27, 2017 01:06 |
|
Vanadium posted:I'm... not sure this is what I'm looking for but do you have some sample code? Vanadium posted:You need to write down every single argument and return value! I was more responding to this part of your gripes, not the goto part. If you extract the methods of a classical object into static functions (and pass the appropriate object back into it) you can do procedural or even functional programming on fairly discrete data. There's no real need to return anything because you're just passing a big ol' chunk of state around. The way you could utilize this is to create an object that represents your state machine then call functions on it, always as the first argument. This is kinda how you shoehorn state into Haskell. But yeah, my special brand of heresy deserves to be in this thread.
|
# ? Aug 27, 2017 02:23 |
|
Gazpacho posted:sucks because not lazy Nobody ever defeated Sheng Long by being lazy.
|
# ? Aug 27, 2017 02:38 |
|
Vanadium posted:What no I'm happy to be explicit, I just don't want to be verbose. I'm curious now. What's it look like in pseudo code?
|
# ? Aug 27, 2017 05:36 |
|
TheBlackVegetable posted:I'm curious now. What's it look like in pseudo code? I'm imagining something like: C++ code:
|
# ? Aug 27, 2017 05:49 |
|
Ranzear posted:I was more responding to this part of your gripes, not the goto part. If you extract the methods of a classical object into static functions (and pass the appropriate object back into it) you can do procedural or even functional programming on fairly discrete data. There's no real need to return anything because you're just passing a big ol' chunk of state around.
|
# ? Aug 27, 2017 08:30 |
|
Zopotantor posted:It sounds as if you are emulating the way we used to emulate object-oriented programming in non-OO languages, in an OO language. Yep, but as stated above it's for serialization. I abuse enumerability to hide properties from it too.
|
# ? Aug 27, 2017 13:04 |
|
just do whatever you want as long as you're not working with one or more other people but if you are working in a team (or you might be in the future) and you're doing something completely unrecognisable to any ordinary person who knows the language you're working in, then you should probably be prepared to be told to go gently caress yourself
|
# ? Aug 27, 2017 15:23 |
|
TheBlackVegetable posted:I'm curious now. What's it look like in pseudo code? Closest I can actually visualize is llvm ir basic blocks w/ their terminating instructions.
|
# ? Aug 27, 2017 16:55 |
|
uhhh just so you know, serializing object state and sending it to the server is something literally nobody does in a multiplayer game, because then any client can cheat and send ridiculous states.
|
# ? Aug 27, 2017 19:19 |
|
Suspicious Dish posted:uhhh just so you know, serializing object state and sending it to the server is something literally nobody does in a multiplayer game, because then any client can cheat and send ridiculous states. Except that this is what happens almost everywhere. And yes, this is how people cheat. And yes, then programmers add watchers and cheating-detection systems and everything becomes a bit more secure and 1000x more complicated.
|
# ? Aug 27, 2017 20:06 |
|
ok i guess i mean when it's not amateur hour. basically, the fancy not-quite-oop serialization system you used for netcode literally doesnt help your game nonetheless avoiding oop in a video game is a good idea and i'm happy you are experimenting with it. entity-component-architecture has been standard in games for 10 years at this point though.
|
# ? Aug 27, 2017 20:48 |
|
Volguus posted:Except that this is what happens almost everywhere. And yes, this is how people cheat. And yes, then programmers add watchers and cheating-detection systems and everything becomes a bit more secure and 1000x more complicated. This kind of depends on the game, right? MMOs use a pattern similar to message queuing and eventual consistency to help prevent or at least identify cheaters if I remember right. ... Having talked with friends in the game dev works, I'd rather stick with fintech. The requirements are clearer and even for very real time distributed systems I think you've got better wiggle room with latencies and client interactions. Plus your customers don't tend to be antagonistic fuckbags who will turn on you at the drop of a hat.
|
# ? Aug 27, 2017 21:54 |
|
https://medium.com/netscape/async-iterators-these-promises-are-killing-my-performance-4767df03d85b If you ever find yourself happy that you've managed to make some code only twice as slow as the (much simpler) equivalent code in Python, something has gone very deeply wrong.
|
# ? Aug 27, 2017 22:47 |
|
Plorkyeran posted:https://medium.com/netscape/async-iterators-these-promises-are-killing-my-performance-4767df03d85b The author appears to think that synchronous code must necessarily read the entire file into memory so I don't know if I'd trust his opinions.
|
# ? Aug 27, 2017 23:19 |
|
|
# ? Jun 8, 2024 11:58 |
|
vOv posted:The author appears to think that synchronous code must necessarily read the entire file into memory so I don't know if I'd trust his opinions. That might very well be the case in Javascript. I'm not familiar enough with the language to say for sure, but in the absence of generator functions or similar, you need something that you can iterate over that comes from a single expression that is evaluated once.
|
# ? Aug 27, 2017 23:27 |