Comments by "p11" (@porky1118) on "Modern Software Engineering"
channel.
-
12
-
9
-
6
-
5
-
4
-
4
-
3
-
3
-
3
-
3
-
2
-
2
-
I think, there is still potetntial for a general purpose programming language having more influences from natural language, but not how the old approaches worked.
The old programming language, which tried to make programming languages more like natural languages, did it, by translating function calls and macros to a limited set of common phrases, often making it less flexible and clear. I think, SQL is a good example, even if not a general purpose language.
I would rather try to add features of natural language into programming languages.
The most important feature of natural languages, which has not been implemented in any programming language, is a way to nest complex phrases without the need of explicit brackets (might be words, which act like brackets).
In natural language, every word has some implicit relation. An adjective (A) always relates to the next object, which might consist of multiple words. In some languages a verb (V) at the end of a sentence or subsentence ends it. And relative pronouns (R) start a new subsentence. And Nouns (N) represent simple objects.
So lets assume, we have a sentence of this structure:
N1 A1 N2 R1 A2 A3 N3 N4 V1 V2
By strictly applying the rules (the description would have to be more accurate, but you should get the point), the nesting (restructured, so the verbs are written like function calls) would be something like this:
V2(N1, A1(N2), V2(R1, A2(A3(N3)), N4)
Even if it's not english grammer, I can try to insert some english words:
English: I like the blue boat, which swims from the great island fast.
Structure: I blue boat which from great island fast swim like.
Nesting: Like(I, blue(boat), swim(which, from(great(island)), fast)
(I know, "fast" is not a noun, and "from" is not an adjective, but it's difficult to have complex sentences, which use a structure like this and make sense.)
So how would I use this in a programming languare?
I'd add about three kinds of words, one which opens a bracket (like R), one which closes a bracket (like V) and one, which does none of it or both (like N or A). Maybe more.
And everything you define will belong to one of these word kind.
2
-
9:15 I don't think, it's in general a good idea to remove file interactions from unit tests.
If it's just short strings or a few lines, sure. But if I really need to read in larger data formats, I don't want to add them into my code, but rather have them in separate files.
Else I might even mess up the format, I want to parse (for example when the parsed format and the language I use both support strings surrounded by quotes and escape characters, I can't just write the content of a file down).
I'd prefer to have them in real files. Maybe they could even inlined into the file at compile time and not really be read at runtime, but I don't think, this would make such a huge difference.
Besides I'm not sure if writing a file system abstaction, which can be used everywhere, where a normal file can be used, will not cause other problems and make some of the code far more complicated and maybe even less performant. Java is probably an exception, where this works well, and only, because the performance reducing features are activated by default (in this case virtual method inheritance).
2
-
2
-
Isn't it a good workflow to merge develop into your feature branch at least once a day? It's similar to CI, but other people won't be disrupted by having to relearn changes of an unfinished feature.
For example, I rename a method and add a few similar methods and then remove some, I don't want to be used, after I'm sure, which are the best methods.
If I do CI, everyone has to learn the new methods, if they need one of them, and maybe they use one, I want to remove later, but can't anymore because it alreaty has been used.
So I just merge the develop every few hours, so I see, nothing breaks, and when my feature is finished, I merge it to develop.
2
-
What I dislike about most OO languges:
# No way to define simple functions
There might be static methods, but they still have to belong to a specific class, which often does not make sense.
In such cases, I "misuse" classes as modules, but it's often a lot of boiler plate code in this case (`public static`).
# To which object does a method belong?
Or I know, it should be a method, but don't know, of which of the objects. There are many posibilities, but none of them seems preferable.
As long as I don't need dispatch, functions are often the way to go.
Else it's pretty clear unless I need multiple dispatch, which also doesn't exist in most OO langugaes.
# Being able to overwrite any method
I think, methods should never be able to be overwritten in general.
There's one exception: Default methods. Some method of an abstract class, which is explicitly meant to be overwritten. (any virtual method in an abstract class)
And there could be empty method definitions, which can be defined in a child class (empty virtual methods).
And they can only be overwritten once by an inheriting class. If you need to overwrite something twice, something is wrong with your code.
Instead of overwriting methods, I like the idea of methods, which extend the behavior of the parent but without changing it (see method combinations), but most of the time, this is too complicated.
In cases, you want to extend behavior multiple times, it's probably the best to add a new virtual methods in child objects. This way it's not allowed to accidently forget to call the parent method, which often seems like boilerplate anyway.
2
-
2
-
1
-
1
-
1
-
8:00 That's basically what I do with my projects.
If I see some functionality, that might be useful for other programs as well, or when I need it for another program and don't want to rewrite it, I create a new repo, add this submodule of the existing program into that repo and let the other program use it.
When I find a bug in my new repo or have ideas for improvement, or if I need to extend it to work with one of my programs depending on it, I have to upgrade the repo, but not all programs, which depend on it. Sometimes I do, sometimes I don't, most of the time I at least plan to upgrade to a newer version some day.
Especially when using Rust, it's easy to have different programs using different versions of the same library.
1
-
1
-
Before I watch the video: I also recognized, that too much branching is rather worse than beneficial.
It should only be done for complex features, which might effect everyones work in a negative way. Like some major rework of an important feature.
I like to let interns work on their own branches, so they don't fear messing up everything, but most of the time, I just merge everything as it is and fix problems later anyway.
Only if it's something very bad, I would not merge it. But the worst thing, that happened so far, were some commits of unintended data, which weren't that bad, so I didn't merge everything, but cherry-picked a few commits.
1
-
1
-
I will take about two hours, maybe faster, if I'm able to focus, but if I realize, I have to rewrite some component, which I wanted to rewrite anyway, it will last at least one day longer, but if my approach of the rewrite does not work at the first try, it might take even longer, maybe it relies on other components, which need some refactor as well.
And when I'm done, there might be a few bugs, which could take less than a hour to find, but also one or two days, depending on my mental condition and if I my guesses, where the bugs might come from, are right, or if I follow the wrong track for some hours...
1
-
1
-
1
-
1
-
1
-
How can this be applied to gamedev?
Most things can't be independently deployable. Especially things, you would put into a library, like a physics or render engine, or more important your math stuff.
But you could put the rendering and the physics of a specific game into different microservices for example. Not sure, if that counts. But both could be independantly deployable.
You could test the game rendering by sending the game state to it, where which object moves and how they change, which objects get destroyed or created, if a new scene is loaded, etc.
You could even use it for different games, which use different physics or no physics at all, as long as the rendered objects stay the same.
Or you could test the game physics by using a very minimalistic renderer, or just outputting the expected positions. You could run the game with many different renderers, maybe some minimalistic 2D one or some realistic 3D one, or some surreal style.
That's basically how I tried to make some game I made less coupled.
But I'm not really happy with it. They use the same base code, some shared structs which are used by both services. But both services include most of the same structs, only cleaned up. For example balls in the renderer don't contain the speed, and balls in the physics don't contain the color. So it's kind of code duplication.
I created a library for both "services", so I still have to add some code to really make it run. I basically just have to define how the communication works.
I can use both libraries and just move data around inside the application to create a standalone.
Or I use only one of these libraries to write to and read from a tcp stream and create a client and server this way.
I like the basic design, but I'm not happy with the specifics.
What I also can think of is packing menus and the real game or each different part of the game into a single application, and then add a meta application, which just selects the next application.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
@hannessteffenhagen61 Unity doesn't seem like it's aimed at professionals. The benefit is, you can also get something done yourself, if you don't know that much about the project.
And even in Engines, you still need a lot of programming for the actual game logic.
You just don't need to know how to do some basic things like math, physics, rendering, audio, asset loading.
But when not using engines, you also just need to use some libraries, which already exist. You just have to decide for some, and maybe they don't work together well because the physics lib uses different vector types than the rendering lib, but getting something almost as good as an engine shouldn't be too difficult.
1
-
1
-
1
-
I'm kind of the leader in my team, since I'm the only employed programmer, and everyone else is an intern. I normally let them do, what they want. When I see, they are doing something stupid, I'll tell them, how I would do it, or how they could improve the code. If they don't fix it, I'll probably fix it myself some time later, at least when I have to work with the code.
It doesn't make too much sense to force a programming style onto them, when they will just stay for a few months. It will just slow them down.
1
-
1
-
1
-
1
-
1
-
Isn't it a good workflow to merge develop into your feature branch at least once a day? It's similar to CI, but other people won't be disrupted by having to relearn changes of an unfinished feature.
For example, I rename a method and add a few similar methods and then remove some, I don't want to be used, after I'm sure, which are the best methods.
If I do CI, everyone has to learn the new methods, if they need one of them, and maybe they use one, I want to remove later, but can't anymore because it alreaty has been used.
So I just merge the develop every few hours, so I see, nothing breaks, and when my feature is finished, I merge it to develop.
1
-
1
-
1
-
1