hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

So long, and thanks for all the F#

  • Some notes about using F# in ProjectEuler

    (After a long hiatus of just lurking and posting to the forums, I am trying to start blogging again.)

    Like many people, I recently discovered http://projecteuler.net.  The site contains a set of mathematically oriented programming problems that get progressively harder.  I started solving them using F#.  While doing so, I've come up with some comments on how F# is really good for these kinds of problems and some improvements that would be nice and probably applicable to more general kinds of programs.

    1. BigInt rules!  Since a lot of the problems are calculations on large integers, it is nice to have them available.  It would be nice if there was a "bigint" equivalent to the "int" and "float" functions to simplify conversions.  It would be really nice if there was a way to override the default numeric behavior of assuming that every number is an int;  it would be nice to be able to switch to "float" or "bigint" mode and have the type checker make the appropriate assumptions.
    2. A minor nit, but it would be nice to have a predefined identity function.  I seem to have one in each program I write (even beyond ProjectEuler).
    3. For most of the problems, I'd create a sequence expression with individual calculations and then aggregate the desired result after filtering.  This demonstrated the convenience of sequence comprehensions, but we already knew that :-)
    4. I tried to avoid "normal" imperative for and while loops and created new helper functions to work on sequences:  seqUntil and seqWhile would process a sequence depending on a boolean function, seqAll would see if a function was true for all values in a sequence (the counterpart to Seq.exists), seqSkip would remove the first n entries in a sequence (really creative name, there :-),  etc.  I think that a lot of these functions, especially the ones that are in the Haskell Prelude for lists, would be good additions to the Seq module.
    5. It would be nice to have some of the aggregation operations be representable in the comprehension language.  This has been described Simon Peyton-Jones and Phil Wadler in Comprehensive Comprehensions for Haskell and should be applicable to F# as well.
    6. I've noticed that I mix the sequence comprehension syntax with the "old-style" pipeline syntax a lot, even when the function could be done in a sequence comprehension.  Looking back, it seems that if I am exploring (ok, guessing) a solution incrementally, it is easier to do that by adding new Seq.map, Seq.filter, or Seq.fold functions at the end with "|>" while running each step in fsi.  Would it help if there was a way to run and augment sequence comprehensions incrementally in fsi?  If I knew the path to the solution(or subsolution), I would choose to use the comprehension syntax first.
    7. While there seems to have been an interest in having F# be an alternative to Matlab for some kinds of engineering computing, I think that it could give Mathematica a run for its money in the computational and presentation space.  Adding full symbolic math support would be nice, but a harder challenge...

    It has been a fun diversion to work on these problems, and interesting to see how concise the F# solutions are compared to the other languages represented.  The solutions in J are always the smallest, but I haven't grokked the syntax to understand the solutions yet :-)  The assembly language solutions are always interesting to read, but it is nice to see F# solutions that are as concise as the Ruby and Python solutions but running much faster...

     

  • F# and SQL Server CLR integration (Part 1)

    (reposted from http://blogs.msdn.com/lbruck/archive/2006/05/25/607029.aspx)

    Please read my first post to understand the goals and security implications of the samples I am presenting. 

    I will assume that you are in the sysadmin role on your SQL2005 server, you are using a program that allows you to execute TSQL commands (like Management Studio), and that you are running it on the same machine as your F# installation.  Change any paths to be appropriate to your machine.

    First of all, you need to turn on CLR support in SQL2005:

    sp_configure 'clr enabled', 1
    go
    reconfigure
    go

    Next, you need to create a database and allow the execution of "unsafe" assemblies in it.  There is a more sophisticated (and complicated) method involving signing the unsafe assemblies with a key and then granting the appropriate permissions to that key, but for testing purposes I will go the simple route:

    create database fsharp
    go
    alter database fsharp set trustworthy on
    go
    use fsharp
    go

    Now you need to load the two utility libraries used by most F# programs into the database:

    create assembly fslib from 'c:\fsharp\fsharp-1.1.11.7\bin\fslib.dll' with permission_set = unsafe
    go
    create assembly mllib from 'c:\fsharp\fsharp-1.1.11.7\bin\mllib.dll' with permission_set = unsafe
    go

    Now you are ready to write your first F# stored procedure.  Create a file called sqlclr.fs (the name is important) with following code:



    open System
    open System.Data
    open System.Data.Sql
    open System.Data.SqlTypes
    open Microsoft.SqlServer.Server

    [<SqlProcedure>]
    let printToday() =
       SqlContext.Pipe.Send(DateTime.Now.ToString())

    Compile this into a DLL.  To load and test out the procedure, issue the following commands:



    create assembly sqlclr from 'c:\fsharp\sqlclr\sqlclr.dll' with permission_set = unsafe
    go
    create procedure PrintToday external name sqlclr.sqlclr.PrintToday
    go
    exec PrintToday
    go

    I won't go into all of the details of SQL CLR integration at this point, I want to point out some important facts.  CLR stored procedures have to be static functions; this works well with normal F# functions since they are defined this way.  By default, they get created in a class with the same name as the source file;  the name of that class must be used as the second part of the external name of the stored procedure.

    This has been a lot of setup work for very little immediate reward, but it lays the foundation for what I'll present in future posts.  Next, I will demonstrate less trivial (and more useful) user-defined functions in F#.

     

  • F# and SQL Server CLR integration (Part 0)

    (reposted from http://blogs.msdn.com/lbruck/archive/2006/05/24/606653.aspx)

    One of the many features in SQL2005 is the ability to create stored procedures, functions (UDFs), and user-defined data types (UDTs) in any .NET language.  As might be expected, most of the examples available are in C# and Visual Basic.  However, I think that F# should get equal representation, especially since I think that certain features of F# can make it a great language for this:

    • Object expressions to make it easier to re-use "boiler-plate" code for UDTs
    • Easy IEnumerable<> functions for table-valued functions
    • Compositional pickling for simpler binary serialization
    • Integration with LINQ for more sophisticated query processing in UDFs

    There are still some technical challenges that need to be addressed before F# can be used  as a general purpose language with SQL2005 CLR.  The biggest problem is that SQL2005 is very strict about the IL it allows to run since it runs "in-process" on the server and the classes and assemblies used can be shared between multiple users.  Currently, F# runs afoul of one of the checks:  all static fields must be marked as readonly.  This restriction is to make sure that one user can't change the contents of a shared class being used by other users.  Don Syme is aware of the problem and working on a solution (no release date, yet).

    However, with the release of 1.1.11.7, it is possible to start experimenting with F# and SQL2005 by disabling or bypassing the CLR security checks.  By disabling the checks, we can use F#-generated assemblies at the risk of compromising the server.  Therefore, I can't recommend this in a production environment unless you have a very clear understanding of the security and stability implications and consequences of the various methods of disabling the checks.  See the SQL2005 documentation for more details.

    With these caveats, I'm going to present some sample F# programs which implement SQL2005 CLR objects.  These can be run on any SQL2005 installion (including the free Express Edition).  They require the use of .NET 2.0 (aka Whidbey) (another free download).

    My plan is to have four more posts over the next week:

    1. Setup and a simple stored procedure
    2. User defined functions (both scalar- and table-valued)
    3. User defined data types
    4. User defined aggregate functions

    I hope that this alternative look at F#/.NET interoperability will be interesting.

This Blog

Post Calendar

<October 2008>
SuMoTuWeThFrSa
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

Syndication

Powered by Community Server, by Telligent Systems