This is a better explanation than most. I very much appreciate that it doesn't dim procedural programming to make OOP look better like most videos I've seen. Though "simple" isn't always a good word for procedural programming given that things like Linux are written that way.
Most programs I have worked on uses a combination of all 3
1:06 the moment you're using the new keyword, you are dealing with object oriented programming - not strictly procedural.
clear and straightforward ❤
Underrated af
Your visuals are nice, good explanations!
Awesome video dude! ❤
Love these vids, idk how I stumped upon your account but it’s very helpful
i agree with you, normally i try to avoid recursion unless it is the only solution i see, i prefer loops over recursions, i can definitely say my code is a mix of all three styles ( when the style is needed ).
Amazing video.
fyi the function PrintNumbers(int i, int max) is not strictly a pure function (it does not give the same output for the same set of inputs) because you have a side-effect - Console.WriteLine() is IO bound and could cause an exception, in C# you probably would have to roll your own IO monad (essentially a container) and return the IO(result) or IO(error) to make it a pure function. The benefit is that you can remove stateful exception handling which is outside of the function and have "railway-oriented" exception handling.
Procedural FTW
man 12:00 is the best :)
Your fp example was oddly made in a way that seems harder to read than the default example everyone gives, where calculatetotal would take two parameters, list of numbers and total. You'd slice the first element off the list, add it to total, and do it like that. There's also really no point in using recursion imo, the reason it's popular is because Haskell etc have first-class support for it. Language you used here doesn't have that(was it C#? I didn't recognize it). However, that language likely has built-in reduce-method. Universality of these operations is a big selling point of FP, and by specifically avoiding showcasing it, you're seemingly purposefully trying to make FP seem worse than it is, by doing the example code in bad style, insisting on recursion when it's not really needed, and insisting on not using the universal patterns when universality of those patterns is a big selling point of the language. Also, the whole createoutput would've also been able to use the exact same reduce-operator, further showcasing this "simple universal tools serve you often quite well"
--------- My Procedural style: 4 LOC, with mutation and straightforward logic const main = () => { const nums = std.getInput("enter array of numbers") // or however it is done let sum = 0 for (const num of nums) { sum += num } console.log(`Total: ${sum}\nAverage: ${sum / nums.length}`) } --------- My Functional style: 4 LOC, with no mutations and concise logic const average = nums => nums.reduce((acc, el) => {sum: acc.sum + el, avg: (acc.sum + el)/nums.length}, {sum: 0, avg: 0}) const display = ({sum, avg}) => console.log(`Total: ${total}\nAverage: ${average}`) const main = () => { const nums = std.getInput("enter array of numbers") // or however it is done display(average(nums)) } --------- My OOP style (I never use it so it may have syntax issues):16 LOC, with mutations and convoluted logic class displayNumber { let sum, average = 0 constructor(nums) { let newSum = 0 for (const num of nums) { newSum += num } this.sum = newSum this.average = newSum / nums.length } display = () => console.log(`Total: ${this.sum}\nAverage: ${this.average}`) } const main = () => { const nums = std.getInput("enter array of numbers") // or however it is done?? let displayNumber = new displayNumber(nums) displayNumber.display() } ---------- FP > Procedural > OOP
I’m a freshman going into uni and I’ve studied for the Java oracle certification a couple years ago, so I am familiar with the concepts theoretically however never implemented them into an actual project. What project should I do with Java to be familiar and gain my memory back of Java as I am a bit rusty but remember concepts and am familiar with OOPS programming.
The object-oriented example is not very good. I can't believe that you coupled the notion of summing numbers to the number data itself. I would have created a NumberSumCalculator class which takes in a NumberArray along with an implementation of a NumberAdder interface. What if you wanted different strategies for adding numbers together? After all, there are many different ways to combine two numbers, and you want your code to be flexible, maintainable, and readable. You'd probably also want a NumberAverageCalculator interface, since there are multiple ways to find the average of a list of numbers. Not to mention that you coupled creating the output with the number data as well. I think the best solution would be a NumberDataOutputWriter class which takes in some sort of Writer interface (you might not want to print it to standard out, you could print to a file, write to a string, et cetera), as well as an object that implements both the NumberSumCalculator and NumberAverageCalculator interfaces so that you can get at that data. Overall, your solution is not scalable, readable, maintainable, flexible, or robust. 0/10. (edit) I’m sorry if this sounded too serious, I’m just kidding. I really enjoyed the video.
hmm... 6:35 there's something wrong here, because functional programming don't require immutable vars. Almost all functional lang-s are statically typed, but that doesn't mean they have immutable vars. The key feature is pure functions , higher order functions and possibly, monads. Pure function—is a function without side effects, in other words, same input—same output. Purity gives a more readable code, where user clearly see all possible outputs of a function. In the first example 6:58 we have a mutable variable, but it exist in separate name scope, so the function is pure! it doesnt change anything from outer scope.
Why the hell would you use Stringbuilder for that?
@madlep