His book on DDD with F# is terrific - I've been coding since the days of punch cards and it's one of the very best I've read. One of those rare books that changes the way you think.
Excellent. I'm a C# developer and I use Python for fun. I was thinking to learn Ruby because I never seen "what to do" with F#. Now I know I'm going to learn and use F# (I already write functional programming in C#).
@@hamoudrodriguez2702 I found an old book at work and I almost finished to read it: "Functional Programming in C#" by Oliver Sturm (Wrox). I found that I was already writing code in a "functional way" but the book goes much deeper... sometimes I think "too much", using a proper functional language makes it more easy and less weird (like implementing/mimiking currying in C#). After 1 year, I can say that I'm a F# developer. I have all my personal projects in F# and I usually mix C# and F# in the same VS solution. At work I started to use it for Test projects (so I don't force all the team to learn a new language, but just basic stuff easy to amend if needed) and I think this is the right step to start to use it. You will not be able to connect to a database, create services, consume 3rd party APIs or create MVC services with F# on the first attempt. Start with Unit/Integration tests and small ancillary projects (maybe just Models/Entities) is a easy step and you will not block any project, but you wil learn the language. You will not be able to manage parallel programming and Json manipulation from the beginning... just start with tests (Moq/Foq and FSUnit are nice libraries to use). To return to your question: I use a lot of functions, extension methods, fluent/chainable code, but it came out "naturally", mimic examples found along the way, I don't have a precise source.
About brackets vs indentation. As a user of a Swedish keyboard, I must say that typing some characters is a hassle (it's easier on the layout of the English keyboard). And RSI (repetitive strain injury) really is an issue among programmers. So I'm all for skipping all unnecessary characters like semicolons etc. This video really made me wanna learn F#. Looks like a neat language.
Technically you could approximate Sum types in C#, for example an abstract class with multiple subclasses. The subclasses are the options, the base class is the Sum type. For example, Shape -> Circle, Shape -> Square, Shape is a Sum type of either Circle OR Square.
8:00 if you believe that you are crazy. Everyone I know who complains about white space is BECAUSE of learning and using python for an extended period. There is nothing worse than going back to your code later and writing a few more lines in a later function and the IDE has decided to switch up tabs vs spaces, and suddenly your code crashes in 1 branch after an hour of running because of "inconsistent use of tabs and spaces" There is nothing redeemable about white space formatting, and since there is also nothing wrong with using {} to define blocks (it doesnt even decrease readability), so there is no reason not to use {} to define a block in your language. Yes, you SHOULD use whitespace to help deliminate that for the reader. But that is SHOULD, it is not SHOULD HAVE TO use indentation the COMPILER can read. Whitespace is for the user, not the compiler.
Hi Carlos, I got a couple of responses from other places indicating that it is not a straightforward process. I don't think Microsoft is really interested in making it anything beyond a niche language.
So having code be self documenting is an ideal to strive for, but letting the compiler deduce types all over the place (including return type from the last line) is also the best thing since sliced bread? Dont get me wrong, I like type inference in c# - I use var all the time - but only because I can usually look a few lines above to see the type in the method signature or a constructor call In general Im lnterested in fp, and looks f# has some cool features, but it felt like the talker was a bit selective in choosing pros/cons
I feel the same apprehension about the type inference. In C#, I only like to use var in combination with new or literals, so I can always tell the class from that same line. Even using it for a function return value is a bit of a code smell actually. I can't imagine reasoning about F# code without having to mouse-over for type info all the time.
@@Geert2682 Surprisingly, the powerful custom types system, combined with no implicit conversion ever, and the strong incentives to good functional programming (especially chainable functions, i.e. monoids) means that in a block you rarely deal with confusingly similar types. To be fair, I'm not an engineer but a mathematician, so my standards may be a bit skewed, but I found that in F# I worry much less about types compared to C, for example: the fact that the IDE immediately tells me that something's wrong allows me to code confidently. In C I only ever find out that I accidentally turned a double into a float when my numerical simulation fails horribly.
With F# it seems that you really ought to be working with it in an IDE that can inlay the type hints for you. That way you don’t need to specify the types yourself, but you can visibly see what is inferred.
With the exception of the Equals() / GetHashCode() and reference vs. value comparisons (which I grant you, is a huge PITA), all of this is in C# already. Uninitialized variables throw a compile-time error, and type inference has been around for a long time. The composition of Lambdas at 39:51 for instance: Why would I need to write a Compose() method? I'd just do "square(double(add1(5)))". We can argue all day about whether forward or backward composition is better, but it's a religious issue: everything in C# is composed backward, and everything in F# is composed forward, so there's no confusion either way. All in all, though, a very informative video - I wanted to see whether functional programming was something worth adding to my arsenal (in the form of F#) and this video gave me the info I needed. I see there are times when it might be worth incorporating.
True but they are well hidden behind the "unsafe" keyword and a flag to allow it in your project. I think it as the same approach as the "null" in F#. You can use it to interface with the eco system (Like pinvoke where you realy need it), but is hidden behind a steep hurdle so no one uses it as long as you don't realy need it. I like pointers!
@@riccardoorlando2262 eh, i like pointers... besides, there's really nothing else besides integers, floats and pointers, as far as the cpu is concerned 😁
You can initialize it with a value you would call "uninitialized" and define in your code a way to handle it. So even the exceptions are not exceptions anymore but another situation you just handle in your code. A good example is a Maybe monad, a thing that can be either Nothing, or Just "a value of any type". Your code then can be written to handle all the situations explicitly. In your example you could have a type ValueInitializedInTheFuture = NotYetReady | Ready Int
@@MiningForPies the real answer is that you move the code that doesn’t have all the necessary data “downward” in the control flow diagram, and put it in a place where all the data is available in the enclosing scope. If that’s not possible, you can create intermediate types that have the partial data, and transform it to the final type once you have all the data. Or, in many cases, you can use the built-in functions that operate on optional types, like “map”, which maps a function over the optional value if it exists, and does nothing if it doesn’t exist. At the end of the day, if your values are implicitly uninitialized, then you have a potential bug on your hands, and worse, if you’re passing that value between layers, then you’re kicking the can down the road and making it someone else’s problem. Hence all the defensive “if-null-then-throw” code we find throughout C# codebases. Setting unavailable data to null makes it easier at the initial implementation, but the cost of nullability doesn’t magically disappear. You pass that cost down the road (up the call stack), and it has to be dealt with somewhere. The real cost is not some slew of runtime crashes (although that’s possible), it’s the fact that you can’t ever trust the data to be there. Nobody can trust it without reading the code leading up to the point you care about. If everything must be initialized, then you don’t have to think about all that other code. You know it works, and you can trust it.
53:40 This might look succinct, but it's also not extensible. What if there's a new cart type or payment method? The user of our library can't implement it. I mean, that's the core feature of interfaces. Discriminated unions are useful when we know in advance how many options there are; or in other words, when there is no one else but us implementing an interface, like in an option type.
C# certainly has limitations when working with FP so you have to be wary and not double down on FP but when you can slide it in it makes things a lot quicker(I use an implementation of Option and Result from Rust built in C# for my web backend). I know some people get upset over "evangelism" but the reality is that most new languages are including FP and OOP because having both as an option really makes things easier in certain scenarios. Rust is a great example of this but the learning curve is very hard. IMO once you go use something like Rust for a bit you have a hard time going back to pure OOP because you see some cases where FP would be far easier. I really don't care much about syntax, I prefer the verbose and often large C-based approach but languages seem to be moving further and further from this.
This and how every parameter is pass by value by default are the two things people get incorrect most often. Even if you are passing a reference type it is passed in by value by default. It just so happens the value is the reference.
it's called "Primary Constructors" and was an unfortunately short-lived feature that only existed in VS2014. Scott may have not heard that it was removed from the spec prior to 2015.
"friendly community, no 'silly questions'", *someone criticizes the language syntax "that's a silly thing to say". Honestly, not sure if there is research on the matter, but having written in languages with and without braces, personally I prefer to have them.
The statement is not silly, the argument is. You can't say anything about it. It's like if I said "I like apples" in a watermelon community. You aren't even giving a reason, so there's nothing anyone there can tell you.
C# primary constructors existed in a preview version of C#, they were removed before the final release (that would have been C# 6.0). The team moved to record types instead, they were not ready for C# 7.0, nor 8.0, wait at see if they add record types in C# 9.0. Record types should look and act pretty much like F#: public class Person(string Name, Datetime Birthdate);
People need to stop trying to sell F# with "less lines of code' because that is a silly metric. You can write minimized Javascript that takes 1 line of code but that is not good. Also problem with union types tends to be serialization not that simple as it looks. F# is a really cool language but the evangelism is terrible.
@@riccardoorlando2262 If he said that it's more readable that is subjective but OK, but it is not more readable because it has less lines of code in fact it's usually the other way around because information density is higher and it's hard to see blocks and branches.
Not the same thing. In the example Snack type, it can be either Apple, Banana or Cherry. Up to there Enum will do. However, if Snack is Apple, it will have a value of type AppleVariety, if it is a Banana it will have a value of type BananaVariety, and if it is a Cherry it will have a value of type CherryVariety. That you cannot do with enums. While you can define a type for the value of the enums, all the values of the enum are of that same type, not a different type for each one... plus, in the enum those values are constant! Not with discriminated types, in F# you could initialize a Snack to be an Apple and you must specify the AppleVariety when you initialize it. The closest to this in C# is to have a base class Snack, and three derived classes Apple, Banana, and Cherry, each with a property AppleVariety, BananaVariety and CherryVariety respectively. Execpt, now Snack is open to extension. That without saying that it is a lot more code to make it in C#.
I don't agree. Till indentation it was fine. But removing curly braces and all blows it to another level. The code might look clean but there is such a thing called as readability
Everyone should indent their code regardless of whether the compiler requires curly braces. If you don't, your code isn't particularly readable. So since everyone indents their code anyway (for readability), the only good reason to add curly braces is to satisfy the compiler (in curly brace-requiring languages). So you have braces for the compiler and indentation for humans, with both attempting to serve the same ultimate purpose, violating the DRY principle. Plus it allows for the possibility of having subtle bugs where the curly brace scope is different from the indentation-indicated scope.
Fully agree with you. I was really tempted to learn F#, but he completely put me off. Had the same experience about 5 years ago at a .net user group meeting with another F# evangelist who had the same condescending type of explaining it.
@@romanmueller4496 you were tempted to learn a language and the behaviour of one guy that use it, it's what put you off? So you wont try a Ferrari just because one guy says that other cars sucks? The guy in the video is not even the creator of the language so what's ur point? Moreover you say he is an evangelist but you consider his talking as "insulting" of C# just because he said it's a verbose language.
@@ghevisartor6005 If you had read my message properly, you would have noticed it was the second experience of this kind of behavior. It doesn't matter if he is the creator of the language or not. He speaks like he does at a public conference. I am not even going to comment further re your Ferrari/other car point, as it doesn't make any sense. No need to discuss this any further.
@@romanmueller4496 Again you are saying because of how two person talk about something you changed your mind about trying that thing. You are right it doesn't make any sense.
Watched it because I thought about learning F#. Not going to anymore. "It's a fun language, feels like a script language" ... No thanks. It's not the language that needs to be fun. Scripting languages are a pain in the ass. If you want to get C# programmers to be interested in F# don't constantly insult C# just because you apparently either don't like it or don't master it.
His book on DDD with F# is terrific - I've been coding since the days of punch cards and it's one of the very best I've read. One of those rare books that changes the way you think.
L😊😊
😊😊
Excellent. I'm a C# developer and I use Python for fun. I was thinking to learn Ruby because I never seen "what to do" with F#. Now I know I'm going to learn and use F# (I already write functional programming in C#).
What were your resources to learn functional c#?
@@hamoudrodriguez2702 I found an old book at work and I almost finished to read it: "Functional Programming in C#" by Oliver Sturm (Wrox).
I found that I was already writing code in a "functional way" but the book goes much deeper... sometimes I think "too much", using a proper functional language makes it more easy and less weird (like implementing/mimiking currying in C#).
After 1 year, I can say that I'm a F# developer. I have all my personal projects in F# and I usually mix C# and F# in the same VS solution. At work I started to use it for Test projects (so I don't force all the team to learn a new language, but just basic stuff easy to amend if needed) and I think this is the right step to start to use it. You will not be able to connect to a database, create services, consume 3rd party APIs or create MVC services with F# on the first attempt. Start with Unit/Integration tests and small ancillary projects (maybe just Models/Entities) is a easy step and you will not block any project, but you wil learn the language.
You will not be able to manage parallel programming and Json manipulation from the beginning... just start with tests (Moq/Foq and FSUnit are nice libraries to use).
To return to your question: I use a lot of functions, extension methods, fluent/chainable code, but it came out "naturally", mimic examples found along the way, I don't have a precise source.
@@AlessandroPiccione thank you! I will have a look into that book and see what I can learn from it!
40:44 As an option:
Func composed = x => add1(doubl(square(x)));
Thats very interesting. Functional languages show how many bad habits we repeat again and again in C-like languages.
Thanks so much for the talk! I learned a lot, and got motivated to learn F#!
Informative video that I like a lot!
He made me very passionate about F#, and I bought his "Domain Modeling Made Functional" book.
Have you read it yet? Recommend?
About brackets vs indentation. As a user of a Swedish keyboard, I must say that typing some characters is a hassle (it's easier on the layout of the English keyboard). And RSI (repetitive strain injury) really is an issue among programmers. So I'm all for skipping all unnecessary characters like semicolons etc. This video really made me wanna learn F#. Looks like a neat language.
I have a shortcut to switch from Italian to English configuration, and I memorized the English configuration xD
Technically you could approximate Sum types in C#, for example an abstract class with multiple subclasses. The subclasses are the options, the base class is the Sum type. For example, Shape -> Circle, Shape -> Square, Shape is a Sum type of either Circle OR Square.
8:00 if you believe that you are crazy. Everyone I know who complains about white space is BECAUSE of learning and using python for an extended period.
There is nothing worse than going back to your code later and writing a few more lines in a later function and the IDE has decided to switch up tabs vs spaces, and suddenly your code crashes in 1 branch after an hour of running because of "inconsistent use of tabs and spaces" There is nothing redeemable about white space formatting, and since there is also nothing wrong with using {} to define blocks (it doesnt even decrease readability), so there is no reason not to use {} to define a block in your language. Yes, you SHOULD use whitespace to help deliminate that for the reader. But that is SHOULD, it is not SHOULD HAVE TO use indentation the COMPILER can read.
Whitespace is for the user, not the compiler.
That sounds more like an IDE issue than a language issue.
Also, F# doesn’t allow the use of tabs, so that issue is nonexistent here.
Can you write a Windows GUI application entirely in F#, or do you need to use C# and just write pieces in F#?
Hi mountainhobo, did you ever receive a response?, please tell me if you did. Thanks.
Hi Carlos, I got a couple of responses from other places indicating that it is not a straightforward process. I don't think Microsoft is really interested in making it anything beyond a niche language.
XAML based - no you can't, you need C# help there.
So having code be self documenting is an ideal to strive for, but letting the compiler deduce types all over the place (including return type from the last line) is also the best thing since sliced bread?
Dont get me wrong, I like type inference in c# - I use var all the time - but only because I can usually look a few lines above to see the type in the method signature or a constructor call
In general Im lnterested in fp, and looks f# has some cool features, but it felt like the talker was a bit selective in choosing pros/cons
I feel the same apprehension about the type inference. In C#, I only like to use var in combination with new or literals, so I can always tell the class from that same line. Even using it for a function return value is a bit of a code smell actually. I can't imagine reasoning about F# code without having to mouse-over for type info all the time.
@@Geert2682 Surprisingly, the powerful custom types system, combined with no implicit conversion ever, and the strong incentives to good functional programming (especially chainable functions, i.e. monoids) means that in a block you rarely deal with confusingly similar types.
To be fair, I'm not an engineer but a mathematician, so my standards may be a bit skewed, but I found that in F# I worry much less about types compared to C, for example: the fact that the IDE immediately tells me that something's wrong allows me to code confidently. In C I only ever find out that I accidentally turned a double into a float when my numerical simulation fails horribly.
With F# it seems that you really ought to be working with it in an IDE that can inlay the type hints for you. That way you don’t need to specify the types yourself, but you can visibly see what is inferred.
With the exception of the Equals() / GetHashCode() and reference vs. value comparisons (which I grant you, is a huge PITA), all of this is in C# already. Uninitialized variables throw a compile-time error, and type inference has been around for a long time. The composition of Lambdas at 39:51 for instance: Why would I need to write a Compose() method? I'd just do "square(double(add1(5)))". We can argue all day about whether forward or backward composition is better, but it's a religious issue: everything in C# is composed backward, and everything in F# is composed forward, so there's no confusion either way.
All in all, though, a very informative video - I wanted to see whether functional programming was something worth adding to my arsenal (in the form of F#) and this video gave me the info I needed. I see there are times when it might be worth incorporating.
excellent talk
26:25 it does have pointers
True but they are well hidden behind the "unsafe" keyword and a flag to allow it in your project. I think it as the same approach as the "null" in F#. You can use it to interface with the eco system (Like pinvoke where you realy need it), but is hidden behind a steep hurdle so no one uses it as long as you don't realy need it.
I like pointers!
@@killergoldfisch1 like them or hate them, there are things that you can do only through pointers.
@@GeorgeTsiros Yes, and those are the _only_ things you should do with pointers.
@@riccardoorlando2262 eh, i like pointers... besides, there's really nothing else besides integers, floats and pointers, as far as the cpu is concerned 😁
How do you handle passing data between layers if every item must be initialised. Sometimes you don’t have the information at that point
You can initialize it with a value you would call "uninitialized" and define in your code a way to handle it. So even the exceptions are not exceptions anymore but another situation you just handle in your code. A good example is a Maybe monad, a thing that can be either Nothing, or Just "a value of any type". Your code then can be written to handle all the situations explicitly. In your example you could have a type ValueInitializedInTheFuture = NotYetReady | Ready Int
how do you pass data if you don't have the information? sounds like a horrible architecture
Tvde1 that’s frankly the answer of someone who has never worked in the real world.
@@MiningForPies the real answer is that you move the code that doesn’t have all the necessary data “downward” in the control flow diagram, and put it in a place where all the data is available in the enclosing scope. If that’s not possible, you can create intermediate types that have the partial data, and transform it to the final type once you have all the data.
Or, in many cases, you can use the built-in functions that operate on optional types, like “map”, which maps a function over the optional value if it exists, and does nothing if it doesn’t exist.
At the end of the day, if your values are implicitly uninitialized, then you have a potential bug on your hands, and worse, if you’re passing that value between layers, then you’re kicking the can down the road and making it someone else’s problem. Hence all the defensive “if-null-then-throw” code we find throughout C# codebases.
Setting unavailable data to null makes it easier at the initial implementation, but the cost of nullability doesn’t magically disappear. You pass that cost down the road (up the call stack), and it has to be dealt with somewhere.
The real cost is not some slew of runtime crashes (although that’s possible), it’s the fact that you can’t ever trust the data to be there. Nobody can trust it without reading the code leading up to the point you care about. If everything must be initialized, then you don’t have to think about all that other code. You know it works, and you can trust it.
@@softwareminimalist That's what you use null for in C#
Presentation was well done.
53:40 This might look succinct, but it's also not extensible. What if there's a new cart type or payment method? The user of our library can't implement it. I mean, that's the core feature of interfaces. Discriminated unions are useful when we know in advance how many options there are; or in other words, when there is no one else but us implementing an interface, like in an option type.
C# certainly has limitations when working with FP so you have to be wary and not double down on FP but when you can slide it in it makes things a lot quicker(I use an implementation of Option and Result from Rust built in C# for my web backend). I know some people get upset over "evangelism" but the reality is that most new languages are including FP and OOP because having both as an option really makes things easier in certain scenarios. Rust is a great example of this but the learning curve is very hard. IMO once you go use something like Rust for a bit you have a hard time going back to pure OOP because you see some cases where FP would be far easier. I really don't care much about syntax, I prefer the verbose and often large C-based approach but languages seem to be moving further and further from this.
#######################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################o#####o##################################################################################################################################################################################k###########i###############################################
11:57 In C# the default access modifier is not private, it's internal.
This and how every parameter is pass by value by default are the two things people get incorrect most often. Even if you are passing a reference type it is passed in by value by default. It just so happens the value is the reference.
The default access modifier for class members is private. Internal is only the default for namespace level.
Why I *hate* javascript: 27:50
This is truly motivational, thank you beared good looking man!
Thank you for this video. It is very helpful.
I really like F# but I don't know why I feel it's not readable at all! maybe because I spend a too much time in oop world
@14:20 what feature is this "default constructor" in C# where you put the parameters directly in the head of the class definition?
it's called "Primary Constructors" and was an unfortunately short-lived feature that only existed in VS2014. Scott may have not heard that it was removed from the spec prior to 2015.
But it will be coming back with C# 9.0 wich will ship november 2020 with .NET 5
19:20...Whisky Tango Foxtrot?!
great teacher!
40:38 What about using operator overloading?
In C# you can only overload operators as pert of a struct or class definition... you do not get that chance with delegates.
12:12 it's not like anyone would want to read the code anyway.
"friendly community, no 'silly questions'", *someone criticizes the language syntax "that's a silly thing to say". Honestly, not sure if there is research on the matter, but having written in languages with and without braces, personally I prefer to have them.
I don't think you watched the presentation.
@rrobertt13 I don't think you watched the presentation
@@jks612 you're avenged, my dear friend.
@@MrDVolk Thanks bro.
The statement is not silly, the argument is. You can't say anything about it. It's like if I said "I like apples" in a watermelon community. You aren't even giving a reason, so there's nothing anyone there can tell you.
14:15 -- Wait a second, what the hell is that?
C# primary constructors existed in a preview version of C#, they were removed before the final release (that would have been C# 6.0). The team moved to record types instead, they were not ready for C# 7.0, nor 8.0, wait at see if they add record types in C# 9.0.
Record types should look and act pretty much like F#: public class Person(string Name, Datetime Birthdate);
People need to stop trying to sell F# with "less lines of code' because that is a silly metric. You can write minimized Javascript that takes 1 line of code but that is not good. Also problem with union types tends to be serialization not that simple as it looks. F# is a really cool language but the evangelism is terrible.
To be fair, it's not just "less lines", it's "less lines, and more readable". Less noise with all of the signal.
@@riccardoorlando2262 If he said that it's more readable that is subjective but OK, but it is not more readable because it has less lines of code in fact it's usually the other way around because information density is higher and it's hard to see blocks and branches.
I hate the elitist behavior of F# evangelists.
49:24 -> Not available in C# ? We call it "enum" ...
Not the same thing. In the example Snack type, it can be either Apple, Banana or Cherry. Up to there Enum will do. However, if Snack is Apple, it will have a value of type AppleVariety, if it is a Banana it will have a value of type BananaVariety, and if it is a Cherry it will have a value of type CherryVariety. That you cannot do with enums.
While you can define a type for the value of the enums, all the values of the enum are of that same type, not a different type for each one... plus, in the enum those values are constant! Not with discriminated types, in F# you could initialize a Snack to be an Apple and you must specify the AppleVariety when you initialize it.
The closest to this in C# is to have a base class Snack, and three derived classes Apple, Banana, and Cherry, each with a property AppleVariety, BananaVariety and CherryVariety respectively. Execpt, now Snack is open to extension. That without saying that it is a lot more code to make it in C#.
Not the same.
I don't agree. Till indentation it was fine. But removing curly braces and all blows it to another level. The code might look clean but there is such a thing called as readability
I agree! Curly braces make the code absolutely unreadable.
Everyone should indent their code regardless of whether the compiler requires curly braces. If you don't, your code isn't particularly readable. So since everyone indents their code anyway (for readability), the only good reason to add curly braces is to satisfy the compiler (in curly brace-requiring languages). So you have braces for the compiler and indentation for humans, with both attempting to serve the same ultimate purpose, violating the DRY principle. Plus it allows for the possibility of having subtle bugs where the curly brace scope is different from the indentation-indicated scope.
oop programmers never have to learn to indent, so it really does feel alien to indent
The point is that I never indent the code manually. I just type and don't worry about formatting at all because it happens automatically.
_moonPtr there is no “correct” way except in languages that force the syntax on you.
This guy is very condescending.
Fully agree with you. I was really tempted to learn F#, but he completely put me off. Had the same experience about 5 years ago at a .net user group meeting with another F# evangelist who had the same condescending type of explaining it.
@@romanmueller4496 you were tempted to learn a language and the behaviour of one guy that use it, it's what put you off?
So you wont try a Ferrari just because one guy says that other cars sucks? The guy in the video is not even the creator of the language so what's ur point?
Moreover you say he is an evangelist but you consider his talking as "insulting" of C# just because he said it's a verbose language.
@@ghevisartor6005 If you had read my message properly, you would have noticed it was the second experience of this kind of behavior. It doesn't matter if he is the creator of the language or not. He speaks like he does at a public conference.
I am not even going to comment further re your Ferrari/other car point, as it doesn't make any sense. No need to discuss this any further.
@@romanmueller4496 Again you are saying because of how two person talk about something you changed your mind about trying that thing.
You are right it doesn't make any sense.
Watched it because I thought about learning F#. Not going to anymore. "It's a fun language, feels like a script language" ... No thanks. It's not the language that needs to be fun. Scripting languages are a pain in the ass.
If you want to get C# programmers to be interested in F# don't constantly insult C# just because you apparently either don't like it or don't master it.
You will not learn a language because of one opinion? He also did not "insult" C#.