Full podcast episode: th-cam.com/video/pdJQ8iVTwj8/w-d-xo.html Lex Fridman podcast channel: th-cam.com/users/lexfridman Guest bio: Chris Lattner is a legendary software and hardware engineer, leading projects at Apple, Tesla, Google, SiFive, and Modular AI, including the development of Swift, LLVM, Clang, MLIR, CIRCT, TPUs, and Mojo.
This doesn't really do zero-cost exceptions justice. As per usual, all that is compared is what happens when things go wrong. Yes, exceptions are much slower in that case. So, how often should things go wrong in a well written, normal piece of software? 80% error rate? 50%? 10%? 1%? Even less? If you are doing some operation and it is reasonably likely to fail, like say communicating over a network, it makes sense to not use exceptions. If it is extremely rare, exceptions start to make more sense. Also there is the question of how much one cares about the performance cost of the error path. No one cares that it takes an extra millisecond to put up an error message just because you used exceptions. If the algoritm needs to be as fast as possible even when an error happens, sure something else is needed but in many cases the overhead of the error parh doesnt matter at all. But here's the thing. What is the cost to turning every single operation into a branch? With exceptions, you write every operation as if it will succeed, no branching needed, then strategically use catch where it makes sense. Often you don't need to catch at all, or only at very high level places, as an exception means the whole operation failed. You let the app crash, or catch and report that whatever the user was trying to do failed. In the right situation, the branchless nature of zero cost exceptions is much faster than the alternatives. In terms of complexity, I dont find exceptions harder to reason about than a return statement. You have no idea where a return is going to go, but it can only go somewhere up the callstack. It can't just jump anywhere. So too with exceptions. They don't magically jump just anywhere, but to an exception handler on the stack. Whether or not using exceptions is the best choice is going to depend on the nature of the code and project, but they are a very useful tool in the right situation. At minimum, i find that they work well as a better assertion for things that ought never happen, but in theory could.
As the clip itself starts cold in the middle of an interview, it would be nice if at least the video description said something about what the clip is about. Who is talking? What is the subject?
...and yes nesting of functions should also never exist. It destroys opportunity for code reuse and prevents refactoring. A lot of language features have been developed "just because we can", but the large majority of language features should be not only ignored but actively avoided.
Writing your code expecting that errors happen commonly is just silly If something happens often its not an "Exception" - you would never use exceptions for flow control.
People hate goto, but they are fine with hidden goto that you can’t clearly see by reading the code. Writing code that is 100% exception safe is hard. It’s very easy to make subtle bugs that are difficult to find. Rust returns errors. C returns errors. C++ exceptions are a messy exception. Nowadays it’s extremely easy to implement your own C++ error/value wrapper (similar to Rust).
Exceptions are a disaster, they actively make a programming language worse. It is very rarely documented which exact APIs are going to throw which excpetions, and the error handling for code that needs to be reliable becomes basically impossibly complex to write. Just return an error when an error occurs, exceptions solve exactly zero problems and create a vast number of them.
Python closures are disgusting. They're the only objects in the entire language that catch the local variables themselves by reference. Why the creators of Python decided to do it this way boggles my mind. You can't even run [lambda: print(i) for i in range(70)] without all these closures getting bount to this i variable and as a result all of them print 69
A little too in the weeds and did not quite address the more global question of Hey let's just get rid of errors altogether. What of the not having NULL debate? You mention Rust, I assume to consider that. A lot of missing points here.
I assume you meant "lets get rid of error HANDLING altogether." The only way to actually get rid of errors is not to write any code at all. And before you say let ChatGPT do it... I spent hours trying to work with ChatGPT to write a method with no errors, and every time ChatGPT assured me that THIS version was right...
Every language is going to have to adress errors in some way. Either it is by using the type system to catch errors before/during compilation, code that handles errors that happen during execution, or even restricting the language do much that errors are not a thing. Most languages have a mix of the first two, and this discussion is about the second one. And every language that is not very restricted, is going to have to think deeply about the second method.
@@TapetBart This raises the fascinating question of can you entirely error-proof a language that would still do functional things? By restricting it? Or would that make it so circumscribed as to be useless?
@@spiritualpolitics8205 yep. Loop up the language Dhall. It is used for writing configurations. It is a very restricted language that works perfectly for its use. There are other languages that allow you to do more, but they require a ton more of you yourself writing proofs to the compiler. So there is a trade off between usability and guarantees. Of course, this only works as long as the compiler is correct also.
"Think about a function that doesn't return anything..." Uh.. functions are defined as code that ONLY returns things with no side effects. If you have a function that doesn't return anything, then it doesn't do anything whatsoever. Chris actually meant "method", not function. Of course, Python also labels methods as functions, so.... consistency is the hobgoblin of little minds?
@@imagudspellr1644 From Microsoft's co-pilot: Functional programming has its roots in academia, evolving from the lambda calculus, a formal system of computation based only on functions1. The early functional programming languages include: Lisp LISP: Defined by McCarthy in the late 1950s, LISP uses Church’s λ notation for functions2. Iswim: Developed by Peter Landin in the 1960s, Iswim significantly pushed the functional programming paradigm2. APL APL: Developed by Iverson in the 1960s, APL also contributed to the advancement of functional programming2. These languages laid the foundation for modern functional languages like Common Lisp, Scheme, Clojure, Wolfram Language, Racket, Erlang, Elixir, OCaml, Haskell, and F#1. Learn more 1 en.wikipedia.org 2 cse.psu.edu 3 en.wikipedia.org 4 codedocs.org which functional languages were pure, i.e., did not allow for side-effects? Searching for: pure functional programming languages Generating answers for you… Pure functional programming languages are those that do not allow for side-effects. In these languages, functions depend only on their arguments, regardless of any global or local state1. Here are some examples of pure functional languages: Haskell: Haskell is a statically typed, purely functional programming language with type inference and lazy evaluation2. Mercury: Mercury is a logic/functional programming language which combines the clarity and expressiveness of declarative programming with advanced static analysis and error detection features2. Clean: Clean is a general purpose, state-of-the-art, pure and lazy functional programming language designed for making real-world applications2. These languages ensure that when a pure function is called with some given arguments, it will always return the same result, and cannot be affected by any mutable state or other side effects3. This is in contrast with impure procedures, common in imperative programming, which can have side effects3.
If you pass a function F as an argument to a function G which invokes F, but doesn't return anything, would you really say that G doesn't do anything? In JavaScript, if a function performs an I/O operation, is that considered a "side effect"?
@@_____case Yes, if G is a function and never returns anything, the only thing it does is noncomputational - i.e., it wastes time. But if it returns something or not depending on its inputs, then it is doing work and making a binary decision at least. And yes, if the Javascript I/O function changes the state of the system and if that state can then be queried - it's not a real function and has side-effects. That's a method, not a function.
Full podcast episode: th-cam.com/video/pdJQ8iVTwj8/w-d-xo.html
Lex Fridman podcast channel: th-cam.com/users/lexfridman
Guest bio: Chris Lattner is a legendary software and hardware engineer, leading projects at Apple, Tesla, Google, SiFive, and Modular AI, including the development of Swift, LLVM, Clang, MLIR, CIRCT, TPUs, and Mojo.
Nesting should be illegal? Wait until Lex hears about decorators.
😂😂
He’ll convulse 😂
Or classes defined locally in a function!
@@blenderpanzinever seen that done but just reading it pissed me off 😂
Isn't he a lisp guy?
My favorite quote: *"The art of API design is actually really profound."*
What an empty statement lol. Glad you enjoyed it.
@@bobwilkinsonguitar6142 emptier than space 😂😂
This doesn't really do zero-cost exceptions justice.
As per usual, all that is compared is what happens when things go wrong. Yes, exceptions are much slower in that case. So, how often should things go wrong in a well written, normal piece of software? 80% error rate? 50%? 10%? 1%? Even less? If you are doing some operation and it is reasonably likely to fail, like say communicating over a network, it makes sense to not use exceptions. If it is extremely rare, exceptions start to make more sense.
Also there is the question of how much one cares about the performance cost of the error path. No one cares that it takes an extra millisecond to put up an error message just because you used exceptions. If the algoritm needs to be as fast as possible even when an error happens, sure something else is needed but in many cases the overhead of the error parh doesnt matter at all.
But here's the thing. What is the cost to turning every single operation into a branch? With exceptions, you write every operation as if it will succeed, no branching needed, then strategically use catch where it makes sense. Often you don't need to catch at all, or only at very high level places, as an exception means the whole operation failed. You let the app crash, or catch and report that whatever the user was trying to do failed. In the right situation, the branchless nature of zero cost exceptions is much faster than the alternatives.
In terms of complexity, I dont find exceptions harder to reason about than a return statement. You have no idea where a return is going to go, but it can only go somewhere up the callstack. It can't just jump anywhere. So too with exceptions. They don't magically jump just anywhere, but to an exception handler on the stack.
Whether or not using exceptions is the best choice is going to depend on the nature of the code and project, but they are a very useful tool in the right situation. At minimum, i find that they work well as a better assertion for things that ought never happen, but in theory could.
As the clip itself starts cold in the middle of an interview, it would be nice if at least the video description said something about what the clip is about. Who is talking? What is the subject?
The description includes a short bio
Nesting is beautiful, powerful and profound. Programming without nesting is not programming and should be illegal.
nah
people don't realise they are still nested if they have dependant variables
Nesting is just a way of achieving an output. That's it.
@@martiananomaly Programming is just a way of achieving an output. That's it.
Fortran subroutines FTW!!!
Wait, so it’s all nested functions?
Always has been.
Well, this clip did what it was meant to do, which was to interest me in the full interview
...and yes nesting of functions should also never exist. It destroys opportunity for code reuse and prevents refactoring. A lot of language features have been developed "just because we can", but the large majority of language features should be not only ignored but actively avoided.
Lex sounds like he don't know about programming. Nesting functions is basically the premise of FN
Writing your code expecting that errors happen commonly is just silly
If something happens often its not an "Exception" - you would never use exceptions for flow control.
People hate goto, but they are fine with hidden goto that you can’t clearly see by reading the code.
Writing code that is 100% exception safe is hard. It’s very easy to make subtle bugs that are difficult to find.
Rust returns errors. C returns errors. C++ exceptions are a messy exception. Nowadays it’s extremely easy to implement your own C++ error/value wrapper (similar to Rust).
people love to hate goto, but few people actually do hate it
C++ got std::expected
Returning an error is a goto
Exceptions are a disaster, they actively make a programming language worse. It is very rarely documented which exact APIs are going to throw which excpetions,
and the error handling for code that needs to be reliable becomes basically impossibly complex to write.
Just return an error when an error occurs, exceptions solve exactly zero problems and create a vast number of them.
Python closures are disgusting. They're the only objects in the entire language that catch the local variables themselves by reference. Why the creators of Python decided to do it this way boggles my mind.
You can't even run [lambda: print(i) for i in range(70)] without all these closures getting bount to this i variable and as a result all of them print 69
from functools import partial
[partial(print,i) for i in range(70)]
Here you go
@@MurtagBY But then I need to write my lambdas with all the mutables explicitly as inputs. In which case it can just be a global function.
you don’t use callables that return None in a comprehension….
@1apostoli True but he's not calling voids in a comprehension. He's constructing a list of void functions.
Honestly though python doesn't need closures. They make a lot of sense in cpp but I find them superfluous in python.
Nesting should be illegal? Yeesh, don't ever try looking into Uncle Bob's clean code manifesto.
Tbh nobody should look into Uncle Bob’s clean code manifesto if they value their own sanity…
my moment is when say: "my opinions is..."
why didn't you talk about condition-restart system in common lisp?
A little too in the weeds and did not quite address the more global question of Hey let's just get rid of errors altogether. What of the not having NULL debate? You mention Rust, I assume to consider that. A lot of missing points here.
I assume you meant "lets get rid of error HANDLING altogether." The only way to actually get rid of errors is not to write any code at all. And before you say let ChatGPT do it... I spent hours trying to work with ChatGPT to write a method with no errors, and every time ChatGPT assured me that THIS version was right...
Every language is going to have to adress errors in some way. Either it is by using the type system to catch errors before/during compilation, code that handles errors that happen during execution, or even restricting the language do much that errors are not a thing.
Most languages have a mix of the first two, and this discussion is about the second one. And every language that is not very restricted, is going to have to think deeply about the second method.
@@TapetBart
This raises the fascinating question of can you entirely error-proof a language that would still do functional things? By restricting it? Or would that make it so circumscribed as to be useless?
@@spiritualpolitics8205 yep. Loop up the language Dhall. It is used for writing configurations. It is a very restricted language that works perfectly for its use.
There are other languages that allow you to do more, but they require a ton more of you yourself writing proofs to the compiler. So there is a trade off between usability and guarantees.
Of course, this only works as long as the compiler is correct also.
It is impossible to get rid of errors in software (and hardware).
This is immutable.
return 0
this is unintelligible tbh.
FIZIRST!
"Think about a function that doesn't return anything..." Uh.. functions are defined as code that ONLY returns things with no side effects. If you have a function that doesn't return anything, then it doesn't do anything whatsoever. Chris actually meant "method", not function. Of course, Python also labels methods as functions, so.... consistency is the hobgoblin of little minds?
@@imagudspellr1644That's like saying, "you can be a virgin if you only have sex once a month."
@@imagudspellr1644 From Microsoft's co-pilot: Functional programming has its roots in academia, evolving from the lambda calculus, a formal system of computation based only on functions1. The early functional programming languages include:
Lisp
LISP: Defined by McCarthy in the late 1950s, LISP uses Church’s λ notation for functions2.
Iswim: Developed by Peter Landin in the 1960s, Iswim significantly pushed the functional programming paradigm2.
APL
APL: Developed by Iverson in the 1960s, APL also contributed to the advancement of functional programming2.
These languages laid the foundation for modern functional languages like Common Lisp, Scheme, Clojure, Wolfram Language, Racket, Erlang, Elixir, OCaml, Haskell, and F#1.
Learn more
1
en.wikipedia.org
2
cse.psu.edu
3
en.wikipedia.org
4
codedocs.org
which functional languages were pure, i.e., did not allow for side-effects?
Searching for: pure functional programming languages
Generating answers for you…
Pure functional programming languages are those that do not allow for side-effects. In these languages, functions depend only on their arguments, regardless of any global or local state1. Here are some examples of pure functional languages:
Haskell: Haskell is a statically typed, purely functional programming language with type inference and lazy evaluation2.
Mercury: Mercury is a logic/functional programming language which combines the clarity and expressiveness of declarative programming with advanced static analysis and error detection features2.
Clean: Clean is a general purpose, state-of-the-art, pure and lazy functional programming language designed for making real-world applications2.
These languages ensure that when a pure function is called with some given arguments, it will always return the same result, and cannot be affected by any mutable state or other side effects3. This is in contrast with impure procedures, common in imperative programming, which can have side effects3.
If you pass a function F as an argument to a function G which invokes F, but doesn't return anything, would you really say that G doesn't do anything?
In JavaScript, if a function performs an I/O operation, is that considered a "side effect"?
@@_____case Yes, if G is a function and never returns anything, the only thing it does is noncomputational - i.e., it wastes time. But if it returns something or not depending on its inputs, then it is doing work and making a binary decision at least. And yes, if the Javascript I/O function changes the state of the system and if that state can then be queried - it's not a real function and has side-effects. That's a method, not a function.
@@KenOtwell If a function in JS performs an HTTP request and then doesn't return anything, that's still a method?