Great talk. This is exactly how I'm writing code today after doing c# my whole career since dotnet 1.0
@blo0m19853 ай бұрын
Can you please recommend your favorite books on this topic? Thx )
@sakesun3 ай бұрын
If this talk was available decade ago, FP might be a lot more mainstream these days.
@Michael.SMarsh6 күн бұрын
The interesting thing about "hard FP" is that the "complicated" things (monads, applicatives, etc.) are actually just taking the idea of "expressions + immutability" to its logical conclusion: after you get a taste with "plain" data, you start thinking "what if I could represent this computation that could return null, fail, read/write a file, etc. as an immutable data type as well?"
@AndersBaumannКүн бұрын
Abstract record Contact; record Email(string Value) : Contact; record Post(string Value) : Contact; record Telephone(string Value): Contact; Use pattern matching. This is as close to DU as you can get in C# today. The only difference is that an actual DU ensures that all possible cases of the Contact type are handled in pattern matching.
@joancomasfdz3 ай бұрын
This is what ive been doing for some time: cherry picking FP concepts and applying them tl my C# projects. The results have been simpler code and easier testability. In particular i focus on: immutability, impureheim sandwich, unions + pattern matching (with Dunet). I encourage everyone to try it.
@Swampdragon1023 ай бұрын
Oversight: Assignments in C# are also expressions, which can be useful in some cases. "If it has an assignment, it is probably a statement" is therefore completely false. More correct would be: if it has a *declaration*, it is probably a statement. I say probably, because variables can be declared in expressions with the `out` and `is` and `switch` keywords.
@Swampdragon1023 ай бұрын
Lambdas are not fundamental to FP, but *closures* are. It's the idea of extending the lifetime of a value by capturing it within a function. You can fully emulate OOP with closures over mutable variables, and you can emulate closures with OOP. In fact, the C# compiler compiles lambdas that capture data into classes with the captured values as fields and the code as a method. But yeah, the syntax details do not matter.
@ShawnShaddock3 ай бұрын
We can already do curried functions in C# var add = (int n1) => (int n2) => n1 + n2; var add10 = add(10); var x = add10(10); // 20
@deyanvp3 ай бұрын
getting an error on the first line: error CS0815: Cannot assign lambda expression to an implicitly-typed variable
@7th_CAV_Trooper2 ай бұрын
@@deyanvp check your language version. Works fine with dotnet 8, C# 12.
@thomasschroter38022 ай бұрын
Curried function is a function that returns another (or same) function. This can easily be done in C#. But it is a kind of brain twist. Best is to use delegate declarations in a recursive manner: int value = 0; adding (1)(1)(10)(20); AddFn adding (int x) { value += x; WriteLine (value); return adding; } delegate AddFn AddFn (int a);
@davidmartensson2733 ай бұрын
I do not try to do pure functional in C# but I often build parts using functional principles where makes for better code. We also use many of the new features like pattern matching in switch statements and are beginning to use switch expressions. Having worked with typescript and written some experiments in F# and some in Elixir I have some functional experience. Also, the If statement in F# is more or less equal to the C# ternary: let x = if y == 2 then 4 else 5 var x = y == 2 ? 4 : 5;
@1980NightFire2 ай бұрын
Fun fact, unions have been possible to implement since .NET 1.1 to my knowledge, using explicit struct layout
@adambickford87203 ай бұрын
Isn't the 'obvious' solution to have every `ContactMethod` have a method that knows how to consume its data and print to the console?
@fsharpfan3 ай бұрын
No, because then the type is tightly coupled with console. Imagine that you have the function and next you have to support storing to file. Add a new function to each type to handle that? No. Add a new function to some module which pattern matches the cases.
@adambickford87203 ай бұрын
@@fsharpfan No more tightly coupled than the current solutions switch. You're either writing a new subclass or a new case statement. I'm a huge fp fan, this did not sell it well imo.
@7th_CAV_Trooper2 ай бұрын
In Pascal there is a difference between functions and procedures. I wish the speaker had used those terms instead of expression and statement. For the sake of this talk, I'm willing to accept the definitions given by the speaker but, from the point of view of language design, statements are expressions too. Anything that can be defined with BNN is probably an expression. I'm debating whether to share this with one of my teammates who is trying to understand expressions in the context of language design right now. I don't want to confuse him, but this was a great presentation that I want him to see.
@wabisabimindset3 ай бұрын
Great talk but what a noisy place. I saw a few other NDC Oslo 2024 talks, and they were nearly the same and noisy. They do not appear to have been very organized this year, Oslo.
@mar_sze3 ай бұрын
It always bothers me that OOP and FP are treated like opposite concepts that are mutually exclusive. The data are objects, the services that perform operations on them are objects, and they might all be immutable and stateless, and makes it not any less functional/object-oriented.
@naturebc3 ай бұрын
The issue here is not FP vs OO. The issue is C# is getting so complicated that when looking at someone else's code, you often can't see what's written, even though it's obvious. They are destroying C# by complexity. The beauty of C is that, the language doesn't change and that's the main feature of it. C# is in danger of being destroyed by these shysters who think following every useless trend is cool.
@okmarshall3 ай бұрын
Hard disagree. It gives loads of tools and you can choose what you do in your organisation. Nothing is forced upon you but C# provides a crazy amount of functionality.
@Crumbledore3 ай бұрын
I don't think there has ever been a point in C#'s life where it was what you describe. It has always been a language that makes big changes to even core aspects of how the language is used. It's nothing like golang for which that is actually one of their fundamental principles. I'd also argue that many modern changes have made the language easier to understand and read. I don't know what aspects you're referring thar you consider more difficult to read. LINQ, top level statements, null coalescing and many more have made the language much simpler to parse for me
@z0nx2 ай бұрын
@@Crumbledore Have you ever tried simple FP in c#? Yes, it is an abomination compared to F#. Writing mutable classes and DI? Yeah, then C# is ok.
@vinr3 ай бұрын
no DI, and functional arguments are good just for these kind of presentations, imagine not having DI and you passing every single service, repository to each and individual function in production application, it's a joke, functional programming is really good, but not the way it is explained here
@Qrzychu923 ай бұрын
you know that's how many other languages work? Go, Rust, Elixir etc - DI containers are even consider as antipattern. It's not a joke, just different approach. And in practice, if you do it right, it's way less of a hassle than you think. Have you heard about Vertical Slice Architecture? That's basically what do in functional world - no repositories, no services, so nothing to pass.
@jackpioneer35663 ай бұрын
@@Qrzychu92 Vertical Slice Architecture isn't tied to either FP or OOP-it works with both approaches. You can have repositories, services, and even Dependency Injection if they fit your design. The core idea of vertical slices is about grouping everything necessary to execute a use case as cohesively as possible. It's less about rejecting specific patterns like repositories or DI and more about ensuring each feature is self-contained, avoiding unnecessary layers. So, whether you use DI/Repositories/Services or not, the focus remains on organizing code by feature, not enforcing a strict patter
@Qrzychu923 ай бұрын
@@jackpioneer3566 the main idea of VSA (at least according to Jimmy Bogard), is to have a slice where all the code you need is there. No services, no nothing,full code duplication, just procedural, make it work. Then refactor the code smells away. If you do that enough times, you will end up with clean architecture and DDD inside of your slice. You are right, it doesn't matter if it's FP or OOP. It's just with FP that the natural way to start, in OOP you are trained into thinking "I need a repository and a service", even though it's a single line when using EF Core directly
@salameez2 ай бұрын
Tell me you've never done a project with FP without telling me you've never done a project with FP
@z0nx2 ай бұрын
So what is the way to go in FP? Isn't it just currying, manually wiring up all the dependencies?