20 ms·
More functional C#
I added this code as a comment to a thread that was almost all the way off the front page by the time I got to it. It was a response to some 'functional folks' criticizing the verbosity of c#. While you can certainly do c# the java way, you can also do it in a near functional way.
I decided to post the code as a full submission because I think c# often gets dismissed as Java copy-cat, which hasn't been true in a decade.
The code (non-destructive, no side effects) calculates square roots :
public static void Main()
{
const int n = 21;
Observable.Generate<double,double>(1, x=>true, x=> 0.5 * (x + (n/x)), x=>x )
.Scan(new {prv = 0d, cur = 0d}, (prev, curr) => new {prv = prev.cur, cur = curr})
.FirstAsync(_ => Math.Abs(_.cur - _.prv) < 1E-10)
.Select(_ => _.cur)
.Subscribe(Console.WriteLine);
// this is just to compare values, so is not part of the solution
Console.WriteLine(Math.Sqrt(n));
Console.ReadLine();
}
Read the more OO c# implementation that inspired me here:
https://news.ycombinator.com/item?id=7044497
Read the Haskell code that inspired both here:
https://news.ycombinator.com/item?id=7043943
- _random_ 13y agoMaybe it's strange for them to see something that is both functional and highly practical? PS: once Roslyn get's finally released, Java will never catch up again.
- altreal 13y agoNo one is using Java because it has great features compared to C#. Java is essentially what C# 2.0 used to be and C# has already moved on to V5. People use Java because it's cross platform. When you write server code you want it to be able to run on whatever box instead of paying for hefty Windows hosting. With now Oracle at helm, Java is likely the worst choice for any new project.
- kevingadd 13y agoI'm guessing Observable, Scan, FirstAsync and Subscribe are all from the Rx reactive/observable framework? I haven't seen them before.
- sequence7 13y agoScan and Observable are part of System.Reactive the other two are I think part of System or System.Data.Entity
- ppog 13y agoObservable, Scan and FirstAsync are from Rx. (FirstAsync is roughly equivalent to LINQ First(), except that it doesn't block.) This particular Subscribe method is also part of Rx, but it's basically a helper method around the BCL System.IObservable<T>.Subscribe(IObserver<T>) that saves you having to implement IObserver.
- profquail 13y agoYou can write Java code which works similarly to your C# code by using RxJava: https://github.com/Netflix/RxJava https://github.com/Netflix/RxJava Or Python, via RxPy: https://github.com/Reactive-Extensions/RxPy https://github.com/Reactive-Extensions/RxPy Or JavaScript, via RxJs: https://github.com/Reactive-Extensions/RxJS https://github.com/Reactive-Extensions/RxJS Or Ruby, via Rx.rb: https://github.com/Reactive-Extensions/Rx.rb https://github.com/Reactive-Extensions/Rx.rb Or Objective-C, via Rx.ObjC: https://github.com/Reactive-Extensions/Rx.ObjC https://github.com/Reactive-Extensions/Rx.ObjC Your code is a good demonstration of how Rx works though, and it's nice to know it's becoming more popular.
- _random_ 13y agoRx was invented by Microsoft, so C# is a rightful first choice for Rx examples :). That code doesn't demonstrate Rx per se, it demonstrates how lambda expressions, extension methods, anonymous types, type inference enable a succinct backwards-compatible (to some extent) functional syntax in C#.
- platz 13y agoLook at the type signatures of many LINQ and Rx methods. I would hardly say they are succint. While just using expressions can be compact, maintaining a functional library or creating functional methods in your application will be a chore in c# due to the verbosity of the type syntax (Type inference won't help you on method signatures)
- Touche 13y agoBut why do things "near functional" when you have F# which is fully functional?
- knocte 13y ago+1
- DanielBMarkham 13y agoYes. Exactly. This is like saying visual basic does classes. Sure, it does, but why would you use it like that?
- deleted 13y ago[deleted]
- ryeguy 13y agoBecause you're already using C# and it can?
- azth 13y agoCan't you mix C# and F# in the same project though?
- kenjackson 13y agoOften mixing them in the same project will result is much less natural code. The above is pretty straightforward.
- ryeguy 13y agoYes, but that's a bit pointless since you can do the same thing in both languages, it's just F#'s syntax is cleaner.
- sklivvz1971 13y agoNo you can't, you can use two different projects, but it's a bad solution in most cases.
- Ycros 13y agoC#'s functional side is why I actually really enjoy working with it. I get to use a nice blend of OO and functional, where each makes sense. OO more on a macro scale, organising code.
- pjmlp 13y agoThe future is to have multi-paradigm languages. Each paradigm gets used depending on the type of problem being solved.
- sklivvz1971 13y agoHopefully, the future is having multiparadigm developers. At the moment, most developers seem to struggle with their first... most of the time without realizing it.
- eldavido 13y agoScala has a lot of this, too. I've started using it because despite loving C#, the JVM is more widely supported on the PaaS providers (e.g. Heroku) than the CLR. You should check it out if you're ever in a position where JVM interop is a hard requirement.
- Dewie 13y agoI have read a lot of lang. wars and complaints about programming languages... but C# is one of the only languages that I can't remember reading any complaints about. None. I must conclude, by the usual Stroustrup quote, that no one uses C#. (yes this is tongue in cheek)
- egeozcan 13y agoWell, I use it =) C# is a language with a somewhat limited market ("Enterprise" applications running on Windows Servers, and yes, I know about Mono). And in this market, a very strict subset of C# (see: Java) is happily used. I know a lot of people who refrain from using even lambdas and implicit typing, let alone the other "fringe functional stuff", because "they make things complicated".
- jagawhowho 13y agoYou're not giving mono the credit it's due.
- egeozcan 13y agoI think Mono is great. It's just not a big market but of course it has great potential.
- V-2 13y agoC# is a language with a somewhat limited market ("Enterprise" applications running on Windows Servers, and yes, I know about Mono) One would think that Windows Phone - fastest growing smartphone OS - would go before Mono... geez, I make a living out of desktop C# apps (WPF). Not solely, but on a daily basis.
- smilliken 13y agoFastest growing is easier to achieve when you have low market share. Mono is significantly more important for the future of C# than Windows Phone.
- kungfooguru 13y agoThis is a joke, right?
- Chromozon 13y agoThis is hobbyist code. It should never actually be used out in the real world. Once you make the distinction, you can better appreciate code snippets like these.
- kungfooguru 13y agoAh, I'm all for that. The comments confused me to thinking it wasn't simply, look how you can do it in C# (but never actually dot his).
- geezsaini 13y agoIf you are going to criticize this approach to C# you are going to need to be more specific - the classic argument for this kind of thing is correctness, and against is optimization, is it the latter you are implicitly pointing out? And if so, what insight as to implementation details that you think make the solution slower?
- Pxtl 13y agoAbsolutely - C# 3.5 introduced a beautiful suite of FP-ish features that made the language fun to write functional code with, and later versions of C# parallelized and asynced those FP-ish features.
- lumpysnake 13y agoWhat's the point of writing code in a functional way to end up with something that is completely unreadable? I'd rather have code written in simple, well factored functions and classes and easy to reason about, than having to deal with such a mess of functional code. Don't get me wrong, functional code can be very elegant and clear, but the example provided here is a huge turn off to me.
- V-2 13y agoI don't like the underscore notation (I think it's foreign to C#), but other than that it's very readable to me, so I guess it's a matter of practice and (acquired) taste
- platz 13y agoWhile sprinkling a few expressions like this around is nice, it's quite a chore to embrace a true dataflow or similiar functionally typed design through your whole application, because the types in c# are so verbose i.e. public Generate(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IScheduler scheduler)
- EpicEng 13y agoYet, when calling that method, type inference will do its job and I will just pass in a few lamdas. What's the problem?
- platz 13y agoright, just using the method is not a problem. I'm saying it sucks if you have to write a whole bunch of methods like that because you are creating your own generators, etc...
- CmonDev 13y agoMethods with that many arguments are probably not a very good idea anyway.
- platz 13y agoUnfortunately there's probably not a great alternative in many cases such as this