Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

" // use .Not(), for me, is more elegant than use the '!' operator "

That's like doing "#define BEGIN {" in C.

I'd also make a note that if you're considering .NET, F# is a better language than C# in nearly every aspect. C#'s development is practically stagnated, at least from an outsider's point of view.

As a comparison, the F# code of his example is just:

  type Student = { Age: int; Name: string }
  let student = { Age = 17; Name = "Paulo Ortins" }
  let PrintAdultStudent student = if student.Age > 18 then printfn "%s" student.Name
That's 176 significant chars versus 267, and as normally formatted, 3 lines versus ~9. Once you start using F#, going back to C# is just painful due to the incredible verbosity and lack of critical things like pattern matching (active patterns are amazing) and good type inference.


I don't know how you can say the C#'s development is practically stagnated. Evidence? Async/await was just added in C# 5.0.


Because in 5 years of development now, C# has only shipped two major features: dynamic and async. Both of which F# has had since 2007 (maybe dynamic was 2008). Both of which F# implemented better (as libraries, so you don't need intrinsic compiler support). Async's design comes from F#'s design.

But without comparing it to F#, Microsoft has not polished the C# 3.0 design. Expression trees are still half implemented (no way to call one exptree from another). MS created anonymous types, but neglected to add simple types like tuples (let alone anything more advanced). Type inference is still ridiculously limited in scope:

  - Neither parameters nor members can be type inferred.
  - Local function vars can't be type inferred (because they chose identical syntax for expression trees).
  - Generic constraints can't be type inferred.
  - Generic parameters have limited inference. If one parameter can't be inferred, you _must_ specify all of them.
On one of the developer blogs, they noted that the reason fields couldn't be inferred was really due to internal compiler codebase complexity. Yet 5 years later, that's still not taken care of. Basically, they aimed for the LINQ outcome, and implemented the required feature set only within the context of LINQ, not for the language as a whole. Which is fine for V3. But then they just left it at that.


I love F#, and greatly prefer it to C# for most tasks, but I think you're overreaching a bit. C#'s dynamic feature is also extensible (via IDynamicMetaObjectProvider) and much more complete than F#'s (e.g. F# probably ought to have (?[]) and (?[]<-) operators for dynamic indexed properties). Likewise, there are several real benefits to having built-in support for async/await, such as the improved performance of a state-machine-based approach and a far better debugging story (e.g. call stacks that are async-aware).

C# is truly a great language; it was just created by people who have different priorities than you (or I) do.


You're right, you can implement interfaces for C# dynamic extension, but that won't help against existing objects. But I'm out of my league here, because every time I see an API that shows off dynamic, it boils down to saving a handful of quotes. I get the feeling F# added it just to say "yeah, what's your point?"

The benefits of built-in features you mention can be accomplished by special-casing as an optimization. Zero downside language wise, only requires some level of more resources for the compiler writers. For debugging, seems like the same amount of work; either way it has to reconstruct the "async stack". Best of both worlds, no downside.

C# is a great language, probably the best of the mainstream ones I'd say. But I still find it severely lacking in some areas, with no justification other than lack of desire/resources (type inference being the #1 case).


C# has tuples[1], but I'll agree they are not built into the language. Being able to have multiple return values from a function would be really nice rather than having to go

    return Tuple.Create(valueA, valueB);
Likewise being able to declare functions as returning multiple values in a natural fashion would be really cool.

But both of those changes are very much sugar, neither of them would make the language more powerful.

[1]http://msdn.microsoft.com/en-us/library/system.tuple.aspx


By that definition, any language that has user-defined types has tuples. Proper tuples are represented as a kind of type, not just a Tuple class.

As far as sugar - if the language is Turing complete, then every feature is syntactic sugar. You need a perverse definition of power to suggest that being able to properly handle tuples via deconstruction doesn't increase the power of the language.


> As far as sugar - if the language is Turing complete, then every feature is syntactic sugar. You need a perverse definition of power to suggest that being able to properly handle tuples via deconstruction doesn't increase the power of the language.

The difference in this case is just a couple of lines of code.

Compare that to C, where it would be a great deal more work!

(Of course a good deal of this difference is in C# using and abusing the heap so much.)

> As far as sugar - if the language is Turing complete, then every feature is syntactic sugar. You need a perverse definition of power to suggest that being able to properly handle tuples via deconstruction doesn't increase the power of the language.

Well yes, but there is the matter of how much mental effort the transformation from idealized software engineering concept to actual implementation takes the programmer.

Tuples in C# don't require that much mental effort, sure it'd be great if they were a native part of the language, but they aren't unreasonably unwieldy.

That said there are certainly times I wish multivalued returns were a natural part of C#!

Of course the problem with returning multiple unnamed values is that you can easily lose semantic information. (obviously I am ignoring comments above a function) It is not too hard to indicate the meaning of a single return value from a function, but beyond that it can get a bit harder.

(Yeah I know the scripting language people don't care, but with every passing day I am more firmly in the static typing side of things, I like my fields with both names and types!)

All that said, I can only imagine how much more productive the 80s 90s would have been if C had supported multiple return values from a function. In the very least Windows programming and HRESULTs would have been a fair bit saner!

(I do find it funny that seemingly no compiler vendor ever extended C to add multiple return values into it!)


+1


Is possible to use F# for web applications ?


Yes, but you have to make an effort. Quick google: http://tomasp.net/blog/fsharp-mvc-web.aspx/


Since then, F# has a full LINQ-to-SQL generator (via the Type Providers mechanism), so you don't need that part of the interop.

Also, this is more of a Visual Studio/web framework issue. The VS people chose to ignore F# with their project type specifications. And the MVC people are very C# oriented, depending on C#-compiler implementation details for many of their methods.

Frameworks like WebSharper, for example, allow you to use full F# across the stack.

On the other hand, using MVC with F# controllers is very smooth, and you can use C# on the rendering engine, as there's rarely much code at all going into the actual view part.


That article is 3.5 years old -- much has changed since then.

The F# Foundation site has up-to-date information: http://fsharp.org/webstacks/

About the only thing I know of that you can't do with F# right now (in terms of web development) is write inline code in ASP.NET MVC Razor views. That's not too big a deal though, since you can still write the guts of the application (e.g., your controllers) in F#.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: