Bio Don Syme has had a major contribution to the design of F#. He has also participated in the design of C# generics and .NET CLR. He joined Microsoft Research in 1998 and has a Ph.D. from the University of Cambridge Computer Laboratory in 1999.
QCon is a conference that is organized by the community, for the community.The result is a high quality conference experience where a tremendous amount of attention and investment has gone into having the best content on the most important topics presented by the leaders in our community. QCon is designed with the technical depth and enterprise focus of interest to technical team leads, architects, and project managers.
I think we had just started down the road towards Visual Studio 2010 and we have almost completed that road, now that technical work is done and it's just a matter of last polishing touch and then it's coming out. In Visual Studio 2010 you get F# and of course you can also use Visual Studio 2008, you can also use it on Mono and Linux and Mac. We like to always remind people of that because it's not just about Visual Studio 2010.
We had some interesting points during the design process, so for instance there is a question about the .NET 4.0 dependency or not and we think it's a really strong point of F# that it is quite cross-platform, not just in the .NET 2.0, 3.5, 4.0 sense but also in the Mono and the SilverLight sense and MoonLight as well. Basically, what we think about cross-platform these days is we have a tendency to think (when we use the words cross-platform, you immediately think) Linux, Mac, Window. But the platforms are changing in the world now and we also have to think about the Cloud, we have to think about the client side, in SilverLight for example, we have to think about phones more.
Although in F# as it is today you wouldn't think about it as a big mobile phone programming language, it's relevant and at some point we have to start running on all of these platforms and make it viable to do development with the language and it's definitely on my mind a lot. Yes, today you can get F# forVisual Studio 2008, you can use it in Windows without Visual Studio and you can use it with the Visual Studio 2008 shell, you can use it with the Visual Studio 2010, you can use it with Mono and Linux. Particularly on Linux and Mac we focus on testing against Linux and Mac, Mono 2.4 - 2.6.
It's been a funny time the last 2 years. Of course we did a huge amount of design refinement and bug fixing and working a lot with users and adopters of F#, but a big part of it has been taking what was a research project and effectively splitting it into 2. One is the core maintained set what we would think of as in the language and in the F#.core library and there was quite a lot of tool things which were part of the initial project which obviously had value but we wanted to maintain. We wanted to make sure that they're available.
We spent quite a long time thinking how we were going to keep them available to the community. In the end, we put out the Power Pack on the CodePlex as an open source library on the Microsoft the permissive license MSPL or the Microsoft Public License (it's called OSS License). That includes first of all a compatibility library, then it is a math library, there is a Lex and Yacc library, there is some asynchronous programming helpers and there will be more of those over time. This scenario we are going to look at, definitely.
Yes, there is the query integration. That was something we would definitely like to have had in the core library implementation. It was one of those things that just went into the power pack and we'll be looking at moving that across over time into the official core supported set. It's a very nice feature, which allows you to do basically C# style LINQ programming embedded queries in F# that have the queries execute on the database. It's been pretty widely used and we're happy where we've landed with that feature of the power pack. We might give it a go. I've got a good blog entry which will take you to the basics of using the LINQ query support for F#.
That's in the core F# library. The core F# library is definitely everything which is absolutely essential for building additional functionality rich. Quotation is one part of that. That allows you to take expression trees of F# code. This leads onto the question of what is the next step with F# as well and one of the big things we're focusing on is effectively living through the ramifications of the feature set that we have in F#, what we're calling version 2, which is the version of the version of the language that you get today. We call the research F# the F# version 1 and now F# version 2.
All the typing and you can opt into various parts of which you do the HTML in F# as well, if you wish, as a DSL effectively. You can actually do asynchronous programming as well. On the client side, of course you need to do lots of asynchronous requests back to the server. One of the things that amaze me about web programming is just how many languages you need to know.
You have to know HTML, you have to know CSS, you have to know SQL, you have to know a programming language like C# and probably there is one or 2 more languages that are typical, ASP.NET markup for example. These together are just too much to know. Since I've been able to use the F# quotation facility and the F# facilities in general to really simplify that problem down in a very nice way.
I think there is a lot of people investigating what they can do with the feature set to simplify some of the really challenging parts of modern programming, where we take web programming that is desperately in need of simplification and strong typing.
Yes, in that case we're representing data in the HTML sense and we're also representing Java Script because parts of the F# code have been translated through the Java Script. It's like you are writing F# that runs at Java Script and that's a very exciting development framework.
In that setting they are definitely using F# as a richer information representation and that would be common. Often, the data is flowing into F# from the outside log file and you wouldn't think of doing that. In F# programming, you use F# expressions as your data representation instead of inventing some new language or something. You wouldn't go and invent a new file format, just for one or 2 data terms or one or 2 specific tables they are easy to code up in F# and you get the strong typing and you get immediate access to them.
Yes. F# is set up as a scripting language which we think of as programmatic scripting. You are still doing programming at some level. We wouldn't encourage it for doing all your batch file kind of work. Probably already most people are going to write batch files or already have their favorite batch file language, PowerShell for example on the Windows. Or you may be using the Apache or any other on Unix.
But there is this sort of borderline where you may be doing log file analysis and programming whereas you are doing text file munging and your regular expression matching or maybe examples like searching across files and doing analysis on the contents of the files. That's a borderline to do serious programming. Some of that you can fake up using a whole lot of other tools, but at some point it can be quite enjoyable to sit down with an FSX file into Visual Studio or something, just open up your Control-N end and get a new FSX file or in emacs or something.
You could end transition to make that till more efficient to be parallel for example. Then, you might definitely do that. There is kind of a typical transition of cracking some data source, a log file for example and then starting to build up an analysis and then actually running that over the full data set, might be gigabytes and then thinking "OK, this program is written, it's efficient, it's F# and it will still take 2 weeks to run over these different data sets. Let's stop petitioning that up." You would you just manual petitioning or you can start doing parallel processing on that as well.
That's actually what I was talking about at QCon today. They asked me not to just talk about F# programming and parallel programming, but also more generally thematically about functional programming and parallel programming. It's an interesting overlap between the 2, because I'm not the one to say that functional programming is the only lens you should look at parallel programming through nor is parallel programming the only rationale for functional programming.
Functional programming is just a fantastic paradigm for rich data oriented work and engine or purpose programming as well, regardless of whether you're doing parallel programming or not. But there is overlap and I try to characterize the overlap in various ways. One was the fact that all the functional languages encourage you to minimize and reduce the amount of state in your application down to some essential kind of level that's mainly for the use of immutable data structures all the way through the code.
There is lots of immutability patterns all the way through the code. An area where F# is particularly strong is in task parallelism. You can go through the .NET 4.0 task parallel library. There is also an F# specific library called the async library. That's interesting because it lets you mix IO parallelism like when you are fetching this set of web pages in parallel or you are serving a set of TCP server side requests in parallel, you can mix those with some CPU computations.
You have a lot of requests coming in, you effectively got a separate little task, which is like a reactive task. It's not a thread, because it's got to go to sleep in a lightweight sleep mode, whenever it needs to say fetch data from back-end databases. When you have requests coming in, I mean many requests 50,000 simultaneous requests or the like and coming on through TCP channels and they need to react to the requests and then work with back-end databases and they will return asynchronous requests. This sort of program is very sweet in F# because it gives you effectively a lightweight task model, which is well oriented to doing a bit of IO work and a bit of CPU work.
Yes, you can have 50,000 on a single process. There are some cases where you don't need to do that. There are cases where you know you're going to be serving 10 requests at the time and you can afford to set up a thread for each of those requests. One of the interesting things though is that, as you design a server side system the requirements can shift around and move. What you think of as being a very computation expensive video decoding on something on the server, after a while you start to shift parts of that work off to other back-end services and the front-end server actually suddenly becomes more like a telephone exchange.
It's busy taking calls and passing on calls and sharing information back and through and the requirements can change enough quickly. What you think of serving 10 requests suddenly has to serve thousands of requests because the balance changes. That kind of heavy server side asynchronous programming is something which drops out very sweetly in F# and it's been a particular interest of mine recently. Again it's this business of saying "We've got this great feature set.
It's clear this mechanism in F# for having lightweight reactive agents or tasks is a good mechanism for building many different things, both on the client side on the server side and we're working through all the ramifications of what are the things you can build, the exact kind of performance trade-offs about when it's right to use this kind of mechanism. We're very consistently really pleased with where we've landed with the features set and the kind of different programming that it enables solving quite complex tasks.
There is one philosophy for building lightweight agents, which is you start with actors, you start with things with message cues and everything is a process with a message cue. That's fine, that's a good model with Erlang, but I'm actually interested just starting with a little more primitive, which is this whole lightweight asynchronous mechanism.
Actors are one thing you can build with that, but you can also build the TCP request handlers which aren't actually actors. You don't want to hold message cues for each of those because that's too expensive. I'm very happy that the async mechanism seems to be useful for a really surprising number of things and actors are one of those.
On the server side that's the sort of thing we are looking to putting in the Power Pack as well instead of helper classes to help you build a TCP server nice and easily. In F# you can also just take a standard TCP code that you use with C# and trick the code across F#, look at the samples which come in F# these days, as well. A lot of my job, as an architect is to work on what's the transition point from let's say you build a server side system which handles 5,000 or 10,000 simultaneous requests.
At some point, if you are successful in your Web 2.0 company, you can have 20,000 people and you are going to need another server. At some point you are going to be wanting to transition across the Cloud Computing. I'm interested in that transition point on how to take a working F# asynchronous application that serves all these requests and I suddenly have that running inside as Azure from Microsoft or EC2 from Amazon or looking at the various Cloud to compute platforms.
Just checking that transition point we often just work through what is that code in experience like and build those critical samples that help you transition across into the next step of your application's lifetime I really enjoy doing that, because you learn a lot about computing along the way, about Cloud computing. In that case I've been working with Windows Azure and I got to say I was really very pleased with how smooth that transition was.
You have your server side app and it comes along into a particular TCP channel and you just deploy it to Azure and you may have to make one small adjustment for the automatic load balancing that the Cloud computing servers will do and your same F# code within. It was just one evening of working for the first time with Windows Azure and we had a scalable application. We should scale indefinitely, as long as you buy the Cloud computing resources you could scale at 100 millions of simultaneous requests.
I was really pleased with how that transition worked. I think there is a sweet spot on using the web as a data source and you are an analyst effectively using F# as a programming tool to access that as a data source. For instance, you might be connected to financial data sources to give you financial data streams over the way of new programmatically accessing those working with those and that's great. On the server side the sweet spot is as an implementation language for these data streams, providers of these data streams, perhaps matched up from other data streams effectively. You are taking some data streams and you are building some analysis engine and you are providing that in turn, over the web. I think that's really interesting, exciting for a language like F# because it plays to F# strength in data analysis and it's also got a nice encapsulation boundary.
We know what web servers or web REST API should look like on the outside and of course when you are using any language, you don't want to force your clients to be talking that same language necessarily. For some libraries of course that's a good thing, but for some settings like providing data services you obviously have to deploy behind that through a more general purpose API that can be accessed from any other language as well.
I think it is a wonderful application area for F# and what you can do with F# today and I sometimes think of F# as a perfect language for doing for the Web 2.0 not the UI sort of things for the data analysis side of things. We've seen some of that in the machine learning applications of F# that F# being used for advertising engine, the add predict engine that's used in parts of the big Microsoft add setter pipe line. I think it's a fantastic application area. It's a little bit of a tendency in the functional programming world to focus a little bit too much on slightly old fashioned programming. You might think the sort of Fibonacci kind of examples and everything that leads on from those.
Yes. That's a big part of the work that I'm describing. We go through and we show how to use F# asynchronous programming for that kind of work.
17. The people now are starting to discover F# - they are mostly like C#, Java or whatever programmers and they see this ml based programming language. It's very new to them, so they start asking questions, like "When should I use a function, when should I use a method, when should use a class, an object or when should I use a Union Type?" What do you think of that?
Big part of our work in the last years is that we make sure that those points are as smooth as possible. In some sense it doesn't matter that dramatically whether you use a static method or a function in a module. From the programming perspective, there is very little difference between the 2. In that particular example, the static members do allow you to start doing overloading. That can require more design, then there is something just plain and simple about modules and functions or with different names or with nicely inferred types. But in a certain usage level it doesn't matter so much which you use.
There is a point for implementation code where these decisions don't matter that much and in fact, we do hear people who come from the object oriented background who just start doing object oriented programming in F#. What you notice is that quite a lot of your classes start to disappear because you suddenly find yourself some using functions where you would have had to create other classes before or you start using F# object expressions to avoid creating leaf classes that are just filling in the abstract methods.
You get this convergence away from some of the object oriented design pattern down to a sort of simpler version of OO programming just using OO for what is very nice and then you get a convergence down the side the people using functional programming who maybe would have had the tendency not to have any structure. Maybe if they are coming from the same ML background, they maybe not even using any sort of object oriented programming even to encapsulate mutable state and then they suddenly discover how nice it is to encapsulate mutable state if they are using it in F#.
Then, you get this transition through this convergence to a point where basically you are using object oriented programming for what it's actually really most suited - to encapsulating concrete types, some good encapsulation of interface types and then hidden implementation of those. Effectively we are seeing these 2 streams of programming and merging to a fairly nice balance in the middle.
We're very interested in collecting more of those questions from the F# community and from people doing library design in F#. We would tend to make a distinction in library design (everything that would encourage people to really make this decision fairly upfront) between what we call Vanilla .NET library design, which is where you are absolutely making a library for use from any other .NET language.
Then there are F# to F# library design, which might be for instance the internal architecture of your application or you've got a set of libraries or you're building an F# specific framework. Of course, in the latter one, you'd be much freer to use F# specific constructs. For instance, if you are doing total vanilla .NET library design, you would follow in general the .NET library design guidelines and those are really fantastic guidelines. For instance, let's take a guideline about when to use structures, for example - you just go to read the .NET design guidelines.
It'll give you good advice when to use exceptions and it'll give you good guidelines. In an F# to F# library, if you are really putting the library like the F# call library on a long term maintainable setting, the F# language specific features are actually about implementation and less about library design. F# in a sense influences library design just a little bit less than maybe some functional programming advocates would think, there are some places it does affect in F# to F# library design. Let's take an example.
If you've got a function which is effectively an asynchronous method, it's something you can call and it will give you in return a result but it gives it to you asynchronously. Then, that pattern in F# to F# code would of course have been something with an asynchronous return type or asynchronous String for example, for the contents of a wide page. You would use that idiom in F# to F# code. Let's take another example - expression trees. You have some kind of discriminated union at your API boundary.
There are a lot of good reasons, good software engineering reasons to hide the representation of your discriminated union behind some basically an API for creating elements of the discriminated union and not necessarily for analyzing them. Let's say the Java view API is the discriminated union. represents propositional object or something underneath. You probably don't need to reveal that representation on the outside and it's not a good idea to from the software engineering perspective. Just because F# has these features, it doesn't mean that at the API boundary you will hide them and suppress them because you want to put your library on a very long term maintainable setting. For example, the actual data flowing into your library might come from XML, it may come from JSON format.
It doesn't necessarily have to come from the F# programmer programming against that library. We're working on a set of guidelines for those 2 cases - Vanilla .NET library design, and F# to F# library design. We'll be running those by the F# community, working with F# community and other users of F# to understand if the guidelines are in the right place, so we look forward to people's feedback.
We were chatting about this before. I think what you are referring to is that often you have a language element, le'ts take asynchronous programming or numeric literals. You know that you are putting that in the language for one or 2 specific reasons. People have big integers, they want to be able to write 300 million I and then get a big integer, but there are 10 or 5% use cases where people do actually need to reconfigure the meaning of those literals.
For example, there are many different big integer packages and there are good reasons to suddenly decide to want to switch to a different one. In the language, you don't tie the mechanism just to one underlying type, you try and let it represent different types, we map to different types as well if we use it in various ways. We've done the same thing with F# asynchronous programming. You can define your own Computation Expression builder which would do a different variation on asynchronous programming.
It's a generic thing and it is actually a very interesting side to this in F# which is that the people sometimes look at F# Computation Expression and they say "It's Haskell monads, so it's some a mechanism for monads." It's not actually just a mechanism for monads. It's also a mechanism for monoids as well, which is basically comprehensions where you might think Haskell list expressions or Python comprehensions and the like.
It's very interesting things you can do with this which some people know about, like sequence expressions in F# for example, but there is also things like asynchronous sequences. You want a stream of results coming from, say, Twitter feed. Let's say you want to subscribe to all the tweets coming under a particular person's name and Twitter gives you these APIs to do that and a natural way to view this stream is in various ways.
One way to view this is as an asynchronous sequence of things coming in. Basically, each time you want to react to the next tweet, you do a lightweight sleep and you then you are woken when the next twit arrives. This lets you have many simultaneous reactors reacting to these strings of events coming in. the F# computation expressions syntax lets you define this asynchronous sequences very sweetly as a very general purpose mechanism that lets you do both monads and these monoids as well. It's very sweet.
21. F# is a functional programming language but also is an object oriented programming language. How could you do the design so that object orientation doesn't crush into functional programming or the other way around, the keep the goodness of functional programming not harming object orientation?
In some sense this comes from the history of F# as well. People are familiar with F# and know that it started as an implementation of core ML as first the core of OCaml language which in itself is very similar to the first version of ML which I used, which is Edinburgh ML. It's always trying to capture the fundamental goodness of that kind of programming. That's always had that vision at its core and we never let things get in the way of maintaining that core experience.
It doesn't mean we haven't had to make some compromises or some design changes in that area, like we support overloading on addition, for example. We can add two 64 bit integers, two 32 bit integers using the F# addition premitives and that's actually different to the design of the OCaml language, for example. But, it does mean that, as we added the object oriented constructs we worked very hard to make sure that they were sweet to use in the context of functional programming.
This is going back quite a few years now, like till 4 years ago when we made the decision about object oriented programming, but one of the key design decisions is about using nominal types, giving in to accepting the role of nominal types in software engineering and in encoding. The tradition in the functional programming world has always been the same structural types. If you are going to do functional object oriented programming, it's all going to be about structural types and structural type compatibility and there is lots of great theories and several good implementations which show that this can work out very nicely in practice, including with type inference.
The OCaml object system is a great one, for example. When we came to the .NET libraries, we as language researchers with our particular views about functional programming and then we had the experience of encountering .NET in its early years, when they came up with these library design principles. You can look at C# as being a library oriented language. It's a great programming language, but they called it in its first version a component oriented language, the language for writing .NET libraries and .NET components in. That's why it had properties, that's why it had events in the first version of the language.
We say "OK" and then being driven by the library design, they got their problem specification is we want to build this great set of libraries, we need a language to do it. They didn't head towards structural typing and the like. Structural typing wasn't an essential element in writing fantastic libraries. It's useful, it can have its uses, but it's not essential and that was really a learning experience for us - that actually nominal types and names are important in library design and therefore, in an F# object oriented world you can focus much more on nominal types than you think.
The funny thing is that has many advantages, as well. It makes your type inference problem much simpler, it helps you a lot with IntelliSense, for example the fact you are pinning down many more types all the way through your program to be particular nominal types. I think that was a key design decision in a sense giving up on some things in the functional pro theory ideal and accepting the more software engineering reality. My boss, Luca Cardelli was very clear in his view of object orientation is about software engineering, functional programming is much more about implementation code and compositionality in programming in the small. That really helped guide us through some of the design decisions.
22. You just mentioned IntelliSense. I guess Visual Studio today supports IntelliSense and debugging of F#. Was it more difficult to implement IntelliSense for F# being it a functional programming language?
Because it's a type inferred language, there are definite trade-offs in the type inferred language. The C# IntelliSense implementation is absolutely superb, we are pretty happy with where we landed in F#, it's got a couple of rough edges, you might need to put a little bit more type annotation in your code. The more concrete type information there is, the better IntelliSense experience becomes. We're very happy with the automatic background type checking that you get with F# code, that reads quickly I think that's absolutely critical in the tool set.
The information you get about inferred types is also very good. You can check a lot of your code by you write your code and hover over and you see the inferred type of your code. The debugging experience - we're happy with where we landed with that, as well. It helps, of course in F# to have a strict evaluation order and the main things we are focusing on is a good break pointing experience and a good stepping experience.
We focus primarily on debugging of debug grade code and less about debugging optimized code. It's trade-offs in debugging optimized code, you could still do it, but there is some interesting trade-offs we made. Tail calls are off by default in debug grade code because they do affect the debugging experience. Of course, for immediate loops, for directly tailored course of things, tail calls is still taken, but if tail calls are mutually recursive and for indirect tail calls if you do write code that critically depends on tail calls (which is more rare in F# than you might expect that you absolutely critically depend on tail calls) and you want that to run in debug mode, then you might have to turn on tail calls explicitly. That's easy to do. However, we're happy about where we've landed with debugging.
Signature files. Yes, this is interesting, because I'm very familiar with people coming from O Camel, for example. In Java, each class is a separate file. That's not how you do things in F#. You typically have substantially larger implementation files. It can even be that a single file actually represents a whole layer in your architecture implementation or your whole component, like the type checker in F# is one large file, or the name resolution engine, which would probably in Java correspond to 10 or 15 actual classes, if possible even more.
Name resolution is a single file. Because that encapsulates a substantial chunk of implementation logic. Within a larger assembly, you are actually encapsulating at the file level, because your additional encapsulation boundary where you can hide a lot of detail at the signature file level. That's one use of signature files. Basically you see that your file is a list of what's in the file, perhaps your documentation and some attributes, and with the types and everything that's not mentioned in the signature file is hidden.
The other use of signature files is when you are writing a framework or a library and they can be very nice to do the exterior design of the library by this writing in the signature files and have the implementation of the library as implementation files. The comments, for example, would be different. On the signature files you have the XML help comments, which are the official Help for the constructs in the library and in the implementation files, your comments will all be about the implementation.
Although there is a little bit of duplication between the 2, like the names of the public methods get duplicated, which is a fundamental trade-off in the mechanism, they still comply a really good methodology of giving a design view of the library and giving an implementation view of the library. Signature files are one of those features which people often think "Why would I ever want to use that? I don't want to duplicate anything into another file!" Then, suddenly, they use it and realize how, in certain application areas, it really gives a simplified view of the library.
You should probably use signature files more in those cases where the ratio between interface signature and implementation is probably about 1-3 or 1-5 or something. There are some cases where there is almost no implementation at all. It's just like type definitions or something and in those cases you wouldn't so much use a signature file.
It was about the final design decisions. That's all done. For me, it's absolutely wonderful. I feel wonderful with the way we've landed and we still have plenty of work to do, we got all the specification document, we always need to do more work on that. We're finalizing that in the next few months as we come through the productization.
There is a Power Pack which we talked about, but for me, the great thing is this business that the language is now done and I can use the language for all these interesting things, like the server side programming work I was telling you about. The great thing is, of course, that what you wrote (this has been true for the 6 months) that F# code you write just remains source code compatible.
There is no more business about getting the latest version of F# and having to adjust the code or anything. What you write today will run forever - we're in that zone for the language. Of course, we started to think about F# version next, we've got some great features mind, we've got a lot of great suggestions which we need to enact, like better error messages and ways to improve the general experience and also the improvements we can make.
We've also got some great features we're working on. I can't tell you all of them today. The key thing with the strongly typed language is once you get the data under the type discipline, then the program you experience is fantastic. But, it's getting things under that type discipline and there are some fantastic techniques today for doing this in F#. If you look at expert F#, which is coming out, the second edition will actually change the name. It will actually be called The Art of F# Programming in the second edition. Our publisher were very keen to have that title for the second edition.
We have this thing called the schema reader design pattern. That's actually a very sweet way for getting external data under the type discipline of a language and into a schema. That's used by some people. If you're an F# architect, or you aspire to be a good user of the language, we encourage you to get that book and take a look at those events and topics. We think there are some interesting ways to really open up that process of getting data under the static type discipline of a language like F# and we're looking at easing that boundary - getting the world statically typed.
No, we haven't done that. The F#.core is for F# to F# use, they are not designed for use out of the .NET languages. There is nothing particular stopping you, but their design is not arbitrary. That library exists for the purpose of supporting F# coding. There are some third party products you could buy implemented in F#, which you can use with other .NET languages, but that's more specific than just general .NET components.
Yes. We see a lot of people having an application where one component is written in F# and maybe the whole user interface is written in Visual Basic or C#. That's a very common setup. We expect that to be really common use so that the actual delivered product is one component F# and several other languages. We do that in the F# implementation itself, which does have quite a lot of F# code. Most of the logic is in F#, but the properties page in Visual Studio is done in Visual Basic and we have a C# component called the Managed Package Framework, which is also part of the overall code base we work with. We use F# in that mode.
Effectively, the Web Sharper Framework takes that to a really polished level and I've been very surprised at how simple and elegant that is. The other uses of F# - I have to think about those. I really like the use of F# in the context of a data rich tool, like AutoCad. Effectively F# is bringing functional programming right next to those interesting sources of data of design which is obviously a lot of analysis you can do or a lot of programmatic construction of elements in engineering setting.
The other big one I think will be very interesting is putting F# a part of a GIS system (Geographical Information System) or perhaps accessing that data via web APIs like the Google Maps API or the Big Maps API or the like. Or accessing it directly in the arch GIS kind of system. That's exactly what I wanted F# to be for in a sense of practical language which would be right next to the interesting data sources for the people doing that interesting kind of work.