6 ms·
I noticed you sealed the C# classes. What if you want to keep it extensible, which makes sense? How will that extensible pattern matching look then? Also would
by CmonDev 12y ago
I noticed you sealed the C# classes. What if you want to keep it extensible, which makes sense? How will that extensible pattern matching look then?
Also would be interesting to see how long would C#6 code be (twice as short?).
Apart from the sample, I also don't understand why F#'s naming patterns are not consistent with the rest of .NET (in terms of starting letter case). Feels alien.
Also how come this was considered a sane syntax for arrays?
[|1; 2; 3|]
instead of
[1, 2, 3]
Even Haskell's syntax is less alien.
- noblethrasher 12y agoNot to mention indexers. Well, programming languages do have a prescriptive aspect. Arrays in C# 1.0 were more fundamental than List whereas the situation in F# 1.0 was the reverse, and F# doesn't really want you to use arrays as much as it wants you to use list. ... Personally, I always mark my classes as either sealed or abstract. In OO terms, I only care about extending the Shape class, not the individual subclasses because those themselves are are already extensions... of the Shape class. If I did want to extend, say, the Circle class, I would probably make a new abstract class called Ellipse that derived from Shape and then derive Circle from Ellipse. But, I don't really think in strict OO terms any more. C# has a decent type system (despite what my fellow ML programmers might say), but one of the mistakes of the language (i.e. the spec) is that it conflates types with classes. Those are different things. You may see three classes, but I see one type. In this case it's a sum type called Shape that ranges over Circle and Square. A sum type , as you may know, is just the type-theoretic version of logical OR. Indeed, it wasn't until I learned about sum types that I finally understood why you would use an abstract class as opposed to an interface: abstract classes are for when you want to say that a Foo is a Bar OR a Baz OR a Biz whereas interfaces are for when you want to say that Foo is a Bar AND a Baz, AND a Biz.
- CmonDev 12y ago> "In this case it's a sum type called Shape that ranges over Circle and Square" How do I extend Shape to include Triangle without modifying the current code (e.g. in a separate file)?
- noblethrasher 12y agoYou would have to modify the code, and as I mentioned, it can be pretty painful in F# and other ML languages if you already have a bunch of functions that apply to Shape. Subclassing is a good and useful tool that simply works better in C# than F#. But, just as importantly, class hierarchies are often a poor way to model a problem.
- CmonDev 12y agoFair enough, thanks for answers.
- noblethrasher 12y agoYou're welcome. It just occurred to me that you may have been asking about extending Shape in the C# example. In that case, you'd just subclass Shape as normal[1]. Some people argue that sum types shouldn't be extended, but I never really understood that. Basically, C# lets you define unbounded sum types (in the form of subclassing) whereas idiomatic F# more or less demands that you know up front how many variants you're going to need. [1] Although, sometimes I do define my classes to prevent this by marking the constructor(s) of the abstract base class as private, and then writing the derived class definitions within the body of the base class.
- CmonDev 12y agoI have seen opinions that C# is good for architecture and F# is good for implementation of components. I might opt for such an approach. Really wish I had a default non-null immutability in C# though.
- Xophmeister 12y agoIIRC, F# is derived from (or, at least, heavily influenced by) OCaml and that's the OCaml syntax for arrays. OCaml lists (I don't know F#, but presumably it's the same) have the [x; y; z] format. Note that lists and arrays are different: They're both homogeneous, but arrays have a fixed length while lists can shrink/grow; indexing arrays is O(1), whereas you have to traverse lists at O(n). In functional programming, it's a very common pattern to work with lists, hence the nicer syntax.
- deleted 12y ago[deleted]
- enricosada 12y agoF# is ML family (like ocaml) With F# you use tuple a lot so is nicer have ',' as separator for tuple parts. let tuple1 = (1, 3) //tuple (int, int) let tuple2 = 1, 3 //same as before, parens are optional let list = [ 1; 2; 3 ] //list of int let array = [| 1; 2; 3; |] //array of int let listOfTuple1 = [ (0,0); (1,2); (4,5) ] //list of tuple (int, int) let listOfTuple2 = [ 0,0; 1,2; 4,5 ] //same as before see https://dotnetfiddle.net/vzeZvJ https://dotnetfiddle.net/vzeZvJ nice and fast syntax guide http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/ http://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/
- frowaway001 12y agoI think the question is "why has ML such a nice syntax, and OCaml managed to make it worse all across the board"?
- iconjack 12y agoThere are only so many ASCII symbols to use for separators and brackets when creating syntax for literals. Think of [| and |] as〚 and 〛 (double square brackets), then it doesn't look so bad, I think.