Namespaces are well defined in the .Net universe, and they don't include the things that make up a module, except inside something very much like a module.
Given that they were designing a language to run on the CLR, making it incompatible with other languages would not have made sense.
On a slightly different tangent, namespaces and modules do NOT overlap -- in particular, you can't define another namespace inside a module, and defining another namespace is the sole purpose of namespaces. They may bear a superficial simularity, but they are distinct concepts.
I'm addressing the overlap between Haskell and
F#'s type systems. The part they share is a simplified subset of a system known sometimes as System F. F# by necessity provides bits and pieces of C#'s type system, but this isn't what the speaker was talking about.
Both C# and Haskell/F# are statically typed, but they're two different flavors.
Subtyping
Specifically, C# is a statically typed language with subtyping. This means that if you look at the typing rules for C# there's one like
Env |- x : T, T' <: T
---------------------
Env |- x : T'
Which means that any well typed term has more than one potential type. This in not the case in (vanilla) Haskell or F#. Every type has a single most general type, a principal type. This has a few benefits like total type inference.
Expressions Everywhere
Besides this, Haskell and F# have a greater emphasis on expressions, expressions have types, but statements don't. This means that in C#, the compiler is checking less of your code, because less of your code has types. In Haskell, everything has a real, checkable type.
In substantive terms, every single node on a Haskell AST has a type or kind (or sort). The same cannot be said of a C# one.
Sum Types
Beyond this, Haskell and F# have what are known as sum
types.
data Bool = True | False
This is how a boolean is defined in Haskell. This provides a few different guarantees than in C#. For example, when there are a discrete number of things in C#, like say, an AST. We can model this with an inheritance hierarchy, but these are open. Anyone can come along and add something to it. We can use an Enum
, but then there's no sane way to attach data to each tag uniformly. This is what's called a tagged union, and it's up to you to implement/use it correctly, the compiler ain't gonna help.
This makes it very hard to ensure that we've covered all possible nodes of an AST. For example, say you have a function
doStuff :: AST -> AST
doStuff (SomeExpr ..) = ...
doStuff (SomeStatement ..) = ...
--// doStuff (SomeIf ...) = Oh noes, we forgot a node
The compiler can warn you because it can prove exactly how many nodes there are, ever. In C#, the equivalent would have to be done with downcasting, and then, since the set of nodes in our hierarchy is open, there's no way to issue compile time warnings.
A company, Jane Street, raves about how useful this feature is in their large OCaml code base. Watch a few of their talks, they talk quite a bit about how using OCaml impacts them in the Real World.
Soapbox
Now I've outlined quite a few differences over System F over many mainstream type systems, but they're all still static type systems. It does bother me when people call Java/C#/C++ "not statically typed" they are. And they certainly give you more compile time guarantees than say, Python. So it's a bit unfair to dismiss them out right.
Best Answer
Yes.
F# is a descendant of the ML programming language, which in turn was heavily influenced by languages like Lisp and Scheme. Those languages were designed from day one to have three nice properties.
First, those languages do not really have statements the way you think of them in C#. Rather, almost everything is an expression that has a value, so an evaluate-and-then-print-the-value mechanism makes sense in almost every situation.
Second, those languages discourage programming with side effects, so you can make evaluations without worrying that you’re going to be messing up global state.
Third, most of the work you do in those languages is “at the top level”; there is typically no enclosing “class” or “namespace” or other context.
By contrast, C# emphasizes programming control flow with statements that produce side effects, and those statements are always in multiple nested containers -- a namespace, a class, a method, and so on.
So these are all things that make it harder for C# to have a REPL, but certainly not impossible. We’d just need to figure out what the semantics are for statements and expressions that appear outside of the usual context, and what the semantics are of mutations that change name bindings, and so on.
Because the F# team decided that having a REPL loop was a priority-one scenario for them. The C# team historically has not. Features do not get implemented unless they are the highest priority features that fit into the budget; until now, a C# REPL has not been at the top of our list.
The Roslyn project has a C# REPL (and will eventually have a VB REPL as well, but it is not ready yet.) You can download a preview release of it to see how you like it at
http://www.microsoft.com/en-us/download/details.aspx?id=27746