Yeah I was worried about what he's gonna say. Turns out he said something really funny and true. Even the stereotype of europeans being more nuance oriented doesn't work here.
@@xhivo97 Basically, he'd expect a European to be more nuanced in this case. The implication being "If a European thinks that, imagine what a hyper-tribalistic American will think" or something like that probably
the only two ways to implement runtime polymorphism (afaik) is either some kind of pointer dereferencing mechanism (like vtable lookups) or tagged union dispatching. The guy is right, you cant do an open API (by that i guess he means dependency injection and whatnot) with tagged union dispatching, because all types have to be available at compile time , your only approach is virtual methods or directly passing function pointers or something else (any pointer deref mechanism suffer equally much from performance problems so it doesn't really matter).
and i say this as someone who uses tagged union dispatching extensively in my own code (i agree they're much faster). The only place i dont use it however is in public APIs where i desire some kind of dependency injection interface, precisely for this reason.
methods turn everything into a single open API, and a very bad one. prob better to use callbacks or manually managed vtables to make an open API, if you need performance.
LSP can also communicate over STDIN/STDOUT, not sockets even if that is also supported. Doesn't help the fact that a lot of unnecessary JSON encoding/decoding, as LSP it is under active constant development a looser protocol format is probably good but at some point they should maybe look at creating a tighter binary protocol.
@@ristekostadinov2820 Yes but they are much more hard typed, the LSP protocol is still expanding while still being backwards compatible with older clients/editors without having to recompile protocol buffer files. While protocol buffers are great for this specific use case maybe something that can be defined at runtime is better.
@@torphedo6286 stdin/stdout is not that slow. A contemporary system should be able to to at least 4-5 gigabytes per second which is way way more than what is needed for some diagnostic data about code in a file. If your terminal had to print all that data visually it would be slow but thats not whats happening when stdin/stdout is used between two programs.
If performance is any concern, like in simulating molecules. What is wrong with header files to define the boundary between two pieces of code developed separately? Just let the compiler and linker take care of the abstraction, so the execution is unhindered.
The dynamic case. You could do static dispatch with templates or generics, or traits. But there are other methods over than virtual method calls. But the question is just turned to how you'd do it. With fat pointers, jump tables... or dispatch by a kind of object for multiple objects, like in ECS.
" What is wrong with header files to define the boundary between two pieces of code developed separately" You have to know that and use proper programming languages that is not "Javascript".
He pointed out that the guy basically thinks there was no algorithm substitution at runtime before OO, which is a glaring lack of knowledge about programming. You can do this in C by using function pointers, for example.
I am confused about blow's comment, aren't virtual methods just syntactic sugar over function pointers in some sense? where's the performance advantage lays at?
I have used MD simulation software and even written some myself, and anything below 200 time steps per second per core for a one million atoms system on a modern CPU is an utter failure and a waste of time and resources. I wonder how his pet project simulator in javascript went.
i wonder why is LSP bad? i mean, jonathan said the idea of client-server LSP is bad. i have no say about client-server nature of it, but i think overall idea of LSP is good. it "compartmentalizes" the stuff - which is what he himself considers a good thing. so, i am searching for clips where he goes into _proper_ detaail about his thoughts on LSP
LSP is bad because its an external process doing IPC. The overall idea of having a "language provider" is a good idea. The idea of having a "language SERVER provider" is the problem. The problem is "Server" entails having an external process. Cost of a function call: 50ns Cost of an IPC Anything from 1ms to 100ms What an IPC involves is your process saving/serializing data, then context switching to another process, then reading data/deserializing, that's a lot of spent cycles and latency. Everything for something that would be a single function call, the reason LSPs are separated is because they crash, that's the problem, programmers can't make stable programs, even thou the LSP typescript is made in a "dynamic language" running in a sandbox. "compartmentalizing" isn't good, its just necessary because of bad quality of software.
1:57 WTF , you can't have virtual methods in C++ and export them because its a landmine of compatibility problems with ABI and name mangling and lots of shit. By his definition no extensible software was ever made in C++, no, they don't exist. (typing this on Windows, with thousands of DLLs made with C++ that don't use Virtual methods to be extensible, yes, I know about COM, IUnknown, not all of them are COM, indeed, com itself isn't virtual)
He seems very arrogant. Rather than having a constructive talk and telling his conversation partner why it's a bad idea to only have virtual functions and explaining alternatives, he seemingly immediately assumes a position of superiority and assumes some sort of "religious belief" about programming styles in his talking partner.
"immediately assumes a position of superiority" no, he doesn't , any good programmer know about this, he just assumes he's talking to professionals The difference between ``` int func() {} void * fun_ptr = func; (*fun_ptr)(); // this is not a virtual method, it doesn't involve an extra indirection. ``` vs ``` struct _obj { void * fun_ptr; } object; object o = { fun_ptr = func }; o->*fun_ptr(); // this is a virtual call, that does a pointer dereferencing. ```
Lsp is the best thing to ever happen. Now we van use Vim or, good forbid, emacs and still get a proper ide experience. Just without the crap that comes with something like Visual Studio or intellij
vim is crap. it's 50 years old and you need to spend 5 hours adding plugins to it so it can kinda work 20% of the time and badly. it's probably a bad thing that we keep giving it life support. have you even tried visual studio, intellij, or visual studio code nowadays? all 3 of those are pretty good and they just work out of the box. visual studio is pretty much the only program in existence right now that you can literally just hit a button and it will compile and run your c++ project just like that. and vs code is the best editor i've ever used. and yes i've used all of them. yeah, all of them.
@@monad_tcp Stem is a relatively new term and distinction, and I'm not sure if this is true. I bet there were plenty of mathematicians, engineers, and scientists were involved in student demonstrations in the 60s, which were the insufferable activists of their time. Academia and activism have been integral since the beginning of academia. It's kinda the natural result of young people with energy who feel empowered receiving an education on things.
The problem isn't virtual methods but agree that the guy didn't know how to make virtual methods fast when it comes to rendering. Lazy ness is good here
Obviously, people writing in C++, or whatever else is implied, wouldn't use function pointers because they have the appropriate mechanism in the language. So I'm not sure what he's talking about. I guess sometimes he just likes rant about obvious things like that.
why wouldn't one use function pointers? people constantly do it in other languages, why not do it in C++? in compiled languages, functions have constant lifetime (except for dynamic libraries) and are immutable, so using function pointers is even simpler than data pointers, as there is no chance of dangling or race condition.
@@Daniel_Zhu_a6f are you for real? My comment contains the reason. Though I understood what you tried to say, your reply is absolute nonsense when taken at face value. Why are you even asking stupid questions like that? Obviously people will choose the path of least resistance, or they have to because they use lots existing code, stuff like that. Virtual function are easier to write and call, case closed.
@@the_original_dude maybe i don't understand what you mean. i assumed that you propose to prefer using vtables instead of function pointers. i think, function pointers are much more useful than vtables. vtables are seldom necessary and don't give fine control over execution, you can do same stuff better with pointers (e.g. first finding the correct method, then applying it to multiple objects without dispatching)
@@Daniel_Zhu_a6f the reasons for using virtual functions have absolutely nothing to do with versatility and performance. You reason about it like you're in a vacuum. There are people using libraries, supporting existing code, working within a group of people with certain skills. It doesn't even make any sense to ask such a question without a very specific context.
@@the_original_dude mmm, no. unless you teach kids to do scratch or office workers to use excel formulas, you'll have to deal with function pointers. they exist in every PL, starting from assemblies and up to JS-Python world. you can't do higher order functions, callbacks or injections without function pointers.
I'm new to programming can someone explain this? Isn't a virtual method just you stating in the base class that all subclasses must have an implementation of this method? Is the idea that inheritance in general is bad and that composition should be used instead?
Jonathan's point has always been that OOP is bad in general. It's a very controversial subject and I would only recommend to look at both sides of the argument with critical eyes. The overall argument tends to be between performance vs readability or as I like to think about it : user experience vs developer experience. That said, yes a virtual method is pretty much what you mentioned. The problem is, it is one of those features that has a slight overhead when you use it. It doesn't matter in small programs but it could potentially accumulate at scale and I can see how it is important in games. If you're curious, you can look up benchmarks for virtual method calls vs direct method calls. Depending on the source, the difference can be insignificant or worth keeping in mind. You can also look into branch prediction, cache misses, etc... if you want to understand the lower level stuff as it all comes down to how you interact with the hardware.
beyond specifying the need for a method to be implemented (which any form of inheritance technically requires without any need for a classifer) a virtual call mandates additional semantics that requires dispatch to the method to dynamically go through the object at runtime. This turns a pre-calculated jump within the executable (or in the case of inlining which virtual methods can't benefit from,literally no work) into at the very least an additional memory access and a call that you suddenly can't see the other end of (and thus cannot be machine processed for optimisation at all) this is generally just kind of a real loss even before getting into anything about paradigms and program design.
@@johnbernier1143 It's not even simply the case that "OOP is readable, but non-OOP is faster". There are arguments to be made here that OOP is actually bad for program structure also *on top of* the performance implications. This is what Casey just argued with Uncle Bob himself about a little while ago. Jon would no doubt say the same thing.
Yes, virtual method is exactly what you said. But Jon's idea goes deeper and the error is even more glaring. The purpose of virtual mehtods is to not need to know which code exactly will be executed at runtime and make it dependent on the program state. You can achieve this in multitude of ways, for example in C, with simple (well, everything in C is simple) function pointers and/or unions.
"i was giving a speech about how to go fast but couldn't finish because i didn't have enough time" is the most programmer sentence I've ever heard
“I have only made this letter longer because I have not had the time to make it shorter.”
-Blaise Pascal
I would say conflating levels of abstraction on purpose is the most programmer THING I've ever seen. ;-)
@@bradb9635 This quote lives rent free in my head.
Ironic... He could save others from having insufficient processing time, but not himself...
So this is the "Methodist Church" I keep hearing about.
"this guy was from Europe, so that makes it extra bad". lmao!
Yeah I was worried about what he's gonna say. Turns out he said something really funny and true. Even the stereotype of europeans being more nuance oriented doesn't work here.
In the age of internet, desinformation, and short attentionspans, everyone everywhere gets dumbed down.
I don't get it, maybe it's because I'm European.
@@xhivo97 Basically, he'd expect a European to be more nuanced in this case. The implication being "If a European thinks that, imagine what a hyper-tribalistic American will think" or something like that probably
I'm from Europe and found this hilarious LOL LOL. I totally agree with his point in this video.
What is this heresy?? In the name of encapsulation, the smart pointer and the garbage collector, may Bill taketh away thy performance boost.
ohLord.forgiveUsOurSins()
the only two ways to implement runtime polymorphism (afaik) is either some kind of pointer dereferencing mechanism (like vtable lookups) or tagged union dispatching. The guy is right, you cant do an open API (by that i guess he means dependency injection and whatnot) with tagged union dispatching, because all types have to be available at compile time , your only approach is virtual methods or directly passing function pointers or something else (any pointer deref mechanism suffer equally much from performance problems so it doesn't really matter).
and i say this as someone who uses tagged union dispatching extensively in my own code (i agree they're much faster). The only place i dont use it however is in public APIs where i desire some kind of dependency injection interface, precisely for this reason.
methods turn everything into a single open API, and a very bad one. prob better to use callbacks or manually managed vtables to make an open API, if you need performance.
LSP can also communicate over STDIN/STDOUT, not sockets even if that is also supported. Doesn't help the fact that a lot of unnecessary JSON encoding/decoding, as LSP it is under active constant development a looser protocol format is probably good but at some point they should maybe look at creating a tighter binary protocol.
protocol buffers also exist and they're much more efficient than json
@@ristekostadinov2820 Yes but they are much more hard typed, the LSP protocol is still expanding while still being backwards compatible with older clients/editors without having to recompile protocol buffer files. While protocol buffers are great for this specific use case maybe something that can be defined at runtime is better.
Why would they talk via stdin/stdout?? printing is so slow
@@torphedo6286 stdin/stdout is not that slow. A contemporary system should be able to to at least 4-5 gigabytes per second which is way way more than what is needed for some diagnostic data about code in a file.
If your terminal had to print all that data visually it would be slow but thats not whats happening when stdin/stdout is used between two programs.
There are also some _bad_ decisions. If you modify a file then it will send the whole file content inside the json request, every single time.
If performance is any concern, like in simulating molecules. What is wrong with header files to define the boundary between two pieces of code developed separately?
Just let the compiler and linker take care of the abstraction, so the execution is unhindered.
You can't sell textbooks if the solution is so simple like that.
The dynamic case. You could do static dispatch with templates or generics, or traits. But there are other methods over than virtual method calls. But the question is just turned to how you'd do it. With fat pointers, jump tables... or dispatch by a kind of object for multiple objects, like in ECS.
" What is wrong with header files to define the boundary between two pieces of code developed separately"
You have to know that and use proper programming languages that is not "Javascript".
What does Jonathan mean by virtual methods in this context? Abstractions in general or something more specific?
Just c++ virtual class methods (I think)
essentially anywhere you use a jump table in place of regular function calls that can be reasoned about by the compiler
He pointed out that the guy basically thinks there was no algorithm substitution at runtime before OO, which is a glaring lack of knowledge about programming. You can do this in C by using function pointers, for example.
Casey showcasing virtual function performance penalties ua-cam.com/video/tD5NrevFtbU/v-deo.html
I am confused about blow's comment, aren't virtual methods just syntactic sugar over function pointers in some sense? where's the performance advantage lays at?
I have used MD simulation software and even written some myself, and anything below 200 time steps per second per core for a one million atoms system on a modern CPU is an utter failure and a waste of time and resources.
I wonder how his pet project simulator in javascript went.
i wonder why is LSP bad?
i mean, jonathan said the idea of client-server LSP is bad.
i have no say about client-server nature of it, but i think overall idea of LSP is good. it "compartmentalizes" the stuff - which is what he himself considers a good thing.
so, i am searching for clips where he goes into _proper_ detaail about his thoughts on LSP
Found any?
@@mkwheremw nah, i stopped watching such wastes.
> _" Found any? "_
LSP is bad because its an external process doing IPC.
The overall idea of having a "language provider" is a good idea. The idea of having a "language SERVER provider" is the problem. The problem is "Server" entails having an external process.
Cost of a function call: 50ns
Cost of an IPC Anything from 1ms to 100ms
What an IPC involves is your process saving/serializing data, then context switching to another process, then reading data/deserializing, that's a lot of spent cycles and latency.
Everything for something that would be a single function call, the reason LSPs are separated is because they crash, that's the problem, programmers can't make stable programs, even thou the LSP typescript is made in a "dynamic language" running in a sandbox.
"compartmentalizing" isn't good, its just necessary because of bad quality of software.
Web "Developers"™
1:57 WTF , you can't have virtual methods in C++ and export them because its a landmine of compatibility problems with ABI and name mangling and lots of shit.
By his definition no extensible software was ever made in C++, no, they don't exist. (typing this on Windows, with thousands of DLLs made with C++ that don't use Virtual methods to be extensible, yes, I know about COM, IUnknown, not all of them are COM, indeed, com itself isn't virtual)
Nice preview, lol.
He seems very arrogant. Rather than having a constructive talk and telling his conversation partner why it's a bad idea to only have virtual functions and explaining alternatives, he seemingly immediately assumes a position of superiority and assumes some sort of "religious belief" about programming styles in his talking partner.
"immediately assumes a position of superiority" no, he doesn't , any good programmer know about this, he just assumes he's talking to professionals
The difference between
```
int func() {}
void * fun_ptr = func;
(*fun_ptr)(); // this is not a virtual method, it doesn't involve an extra indirection.
```
vs
```
struct _obj { void * fun_ptr; } object;
object o = { fun_ptr = func };
o->*fun_ptr(); // this is a virtual call, that does a pointer dereferencing.
```
Hold up are vtables really that bad? Seems a bit exaggerated..
Yes they are bad. But in the context of worse alternatives (e.g. hash tables with function pointers), they seem good.
@@krux02 at this point just make a linked list of function pointers. the worst possible performance, finally!!!
@@krux02 the problem is vtables are only useful in the context of OOP, hash tables with function pointers have real use-cases
Vtables are not the main problem, it's more about indirection leading to cache misses.
Lsp is the best thing to ever happen. Now we van use Vim or, good forbid, emacs and still get a proper ide experience. Just without the crap that comes with something like Visual Studio or intellij
vim is crap. it's 50 years old and you need to spend 5 hours adding plugins to it so it can kinda work 20% of the time and badly. it's probably a bad thing that we keep giving it life support. have you even tried visual studio, intellij, or visual studio code nowadays? all 3 of those are pretty good and they just work out of the box. visual studio is pretty much the only program in existence right now that you can literally just hit a button and it will compile and run your c++ project just like that. and vs code is the best editor i've ever used. and yes i've used all of them. yeah, all of them.
The idea is great, the implementation could use some improvements.
Academia produces terrible software and even worse programmers.
don't forget the insufferable activists. Academia is amazing at producing those as well.
Academia has always produced insufferable activist, it's a part of the deal. Bad workers shouldn't be though @@Tsunkuotaku
@@KoopstaKlicca it used to be that STEM was relatively safe, but that also changed
@@monad_tcp Stem is a relatively new term and distinction, and I'm not sure if this is true. I bet there were plenty of mathematicians, engineers, and scientists were involved in student demonstrations in the 60s, which were the insufferable activists of their time. Academia and activism have been integral since the beginning of academia. It's kinda the natural result of young people with energy who feel empowered receiving an education on things.
I lol'd
The problem isn't virtual methods but agree that the guy didn't know how to make virtual methods fast when it comes to rendering. Lazy ness is good here
Obviously, people writing in C++, or whatever else is implied, wouldn't use function pointers because they have the appropriate mechanism in the language.
So I'm not sure what he's talking about.
I guess sometimes he just likes rant about obvious things like that.
why wouldn't one use function pointers? people constantly do it in other languages, why not do it in C++? in compiled languages, functions have constant lifetime (except for dynamic libraries) and are immutable, so using function pointers is even simpler than data pointers, as there is no chance of dangling or race condition.
@@Daniel_Zhu_a6f are you for real? My comment contains the reason. Though I understood what you tried to say, your reply is absolute nonsense when taken at face value.
Why are you even asking stupid questions like that? Obviously people will choose the path of least resistance, or they have to because they use lots existing code, stuff like that.
Virtual function are easier to write and call, case closed.
@@the_original_dude maybe i don't understand what you mean. i assumed that you propose to prefer using vtables instead of function pointers.
i think, function pointers are much more useful than vtables. vtables are seldom necessary and don't give fine control over execution, you can do same stuff better with pointers (e.g. first finding the correct method, then applying it to multiple objects without dispatching)
@@Daniel_Zhu_a6f the reasons for using virtual functions have absolutely nothing to do with versatility and performance.
You reason about it like you're in a vacuum.
There are people using libraries, supporting existing code, working within a group of people with certain skills.
It doesn't even make any sense to ask such a question without a very specific context.
@@the_original_dude mmm, no. unless you teach kids to do scratch or office workers to use excel formulas, you'll have to deal with function pointers.
they exist in every PL, starting from assemblies and up to JS-Python world. you can't do higher order functions, callbacks or injections without function pointers.
I'm new to programming can someone explain this? Isn't a virtual method just you stating in the base class that all subclasses must have an implementation of this method? Is the idea that inheritance in general is bad and that composition should be used instead?
Jonathan's point has always been that OOP is bad in general. It's a very controversial subject and I would only recommend to look at both sides of the argument with critical eyes.
The overall argument tends to be between performance vs readability or as I like to think about it : user experience vs developer experience.
That said, yes a virtual method is pretty much what you mentioned.
The problem is, it is one of those features that has a slight overhead when you use it. It doesn't matter in small programs but it could potentially accumulate at scale and I can see how it is important in games.
If you're curious, you can look up benchmarks for virtual method calls vs direct method calls. Depending on the source, the difference can be insignificant or worth keeping in mind.
You can also look into branch prediction, cache misses, etc... if you want to understand the lower level stuff as it all comes down to how you interact with the hardware.
beyond specifying the need for a method to be implemented (which any form of inheritance technically requires without any need for a classifer) a virtual call mandates additional semantics that requires dispatch to the method to dynamically go through the object at runtime.
This turns a pre-calculated jump within the executable (or in the case of inlining which virtual methods can't benefit from,literally no work) into at the very least an additional memory access and a call that you suddenly can't see the other end of (and thus cannot be machine processed for optimisation at all) this is generally just kind of a real loss even before getting into anything about paradigms and program design.
yes. read up on vtables
@@johnbernier1143 It's not even simply the case that "OOP is readable, but non-OOP is faster". There are arguments to be made here that OOP is actually bad for program structure also *on top of* the performance implications. This is what Casey just argued with Uncle Bob himself about a little while ago. Jon would no doubt say the same thing.
Yes, virtual method is exactly what you said. But Jon's idea goes deeper and the error is even more glaring. The purpose of virtual mehtods is to not need to know which code exactly will be executed at runtime and make it dependent on the program state. You can achieve this in multitude of ways, for example in C, with simple (well, everything in C is simple) function pointers and/or unions.