In application script hosting. How does tryfsharp.org work? - f#

I am interested in the ability to have F# scripting within my app.
Having something like tryfsharp.org would be great, specifically the Intellisense capability. Is any of this available on Github somewhere? How does this work?

Short answer
The code used for the first cut of TryFSharp with F# 2, which includes Intellisense support, is available as a code drop. As an example Rob Pickering built an online editor for Undertone with it. I suspect the code used on the current TryFSharp site which uses F# 3 will appear in time.
TryFSharp uses Silverlight to host the F# compiler in the client's browser (F# is written in F#). It is also possible to call an instance of the F# compiler running on the server from the browser on demand, which is an approach taken by TryFs.Net and Pit.
Longer answer
There are two sides to scripting:
Editing
Execution
F# already supports editing and execution of (.fsx) script files via F# Interactive.
Editing F# Code
There's no shortage of external editors for F# code:
Visual Studio
SharpDevelop
Xamarin Studio
Emacs
Vim
TryFSharp
F# Notebook
The editor support for Xamarin Studio, Emacs and Vim is based on the open source F# Bindings project, which provides code completion.
SharpDevelop uses the open source AvalonEdit and includes syntax highlighting for F#. You can use AvalonEdit in your own projects, for example the open source Refunctor project uses it to provide F# editing inside Reflector.
There are also a couple of new editors for F# on the horizon:
Cloud Sharper - web based F# IDE
Tsumani IDE - embedded editor for Excel, Hadoop, etc.
AvalonEdit is a good place to start for a desktop based embedded editor. Once you've chosen an editor environment then you need to choose between simple syntax highlighting or more advanced integration using F# Bindings. If you suspect people will use an external editor then syntax highlighting may be sufficient.
Bring your own editor is probably the easiest place to start which just leaves execution.
Executing F# Code
Options for executing F# code:
F# CodeDOM from the F# PowerPack
F# Compiler via the F# compiler code drop or invoking fsi.exe
Compiling a snippet with the F# CodeDOM:
open Microsoft.FSharp.Compiler.CodeDom
open System.CodeDom.Compiler
let compile snippet =
use provider = new FSharpCodeProvider()
let options = CompilerParameters(GenerateInMemory=true)
provider.CompileAssemblyFromSource(options, [|snippet|])
let snippet = """
module Snippet
let x = 1
"""
let results = compile snippet

Related

lua script editor for w32 application

I need to add some script support for an old w32 MFC application. It should be possible for user to enter a custom formulas for further calculation. It should be very simple edit control with syntax highlights and error messaging. Do any solutions for lua(activx or dll) which may be embedded to my application exist?
Scintilla includes a Lua lexer and provides syntax highlighting and more. Error messages can be displayed as annotations.

Why has the statement "printfn" in F# different name in VS2010 object browser?

I had know the difference between F# library and .NET library when I called their functions.
But when I saw the statement "printfn" in VS 2010 object browser, I saw only the "public static T PrintFormatLine(... format)" instead of "printfn".
Why has the statement "printfn" in F# library different name in VS2010 object browser?
How can I call functions in F# library, if there aren’t documents for the F# library, because the names in VS 2010 object browser are totally different?
The printfn function in the F# core library is annotated with a special attribute CompiledName that specifies the name of the function in a compiled form:
[<CompiledName("PrintFormatLine")>]
let printfn fp = ...
What is this good for? I think the motivation is that the FSharp.Core.dll library should follow the usual .NET naming guidelines. However, F# naming guidelines are a bit different (lowercase names are allowed, etc.), so the attribute is used to make the library look more like ordinary .NET library.
I don't think this is something that users of F# would use themselves. If you're writing code that will be used from C#, write it in a C# friendly style and if you're writing code that will be used from F#, follow the F# naming guidelines.

Can I access types created in F# Interactive with System.CodeDom?

I am creating my type in FSX and passing those types into the Razor templating engine with the open source RazorEngine project.
Hosting Razor outside of ASP.NET requires compiling the Razor templates. If I pass a model created in FSX into the template, will System.CodeDom be able to have access to that type created by FSI? The basic error that I get is "The type or namespace name 'FSI_0004' could not be found".
Code that's compiled using System.CodeDom cannot generally have access to the code loaded in F# Interactive - the CodeDom essentially writes the C#/F# source code to disk and then invokes the command line compiler on the code (and the command line compiler cannot reference code loaded in F# Interactive).
There may be a way to get it working though - You could use the F# CodeDom provider from PowerPack. You could modify it to generate the source code (as it currently does) and then send the generated code to F# Interactive (instead of invoking command line compiler). This way, the code compiled on-the-fly could see F# Interactive code.
There are some issues that need to be resolved
Is it possible to provide your own CodeDom provider to RazorEngine?
The F# CodeDom provider may not correctly handle code generated by Razor (so you may need to fix/workaround a few things in the F# CodeDom provider). You may also need to modify it to generate code that works nicely with F# interactive (e.g. remove top-level namespaces)
What instance of F# Interactive do you want to use? (And how to get standard input, so that you can send your code there)
Do you need to load the compiled assembly and pass it back to Razor? I'm not sure if this can be done with F# Interactive.
These all depend on your scenario - but I guess that it may be possible to get what you want (possibly with some workarounds).

F# interactive: Reference a project in currently open solution

I would like to use the F# interactive console with the projects in the currently open solution in Visual Studio 2010. Is there a quick and easy way to add a reference in the F# interactive console to reference projects in the currently open solution?
I've got lines like this at the top of my .fs file:
#if INTERACTIVE
#r #"C:\path\to\some.dll"
#I #"C:\Users\bford\path\to\a\project\in\this\solution\bin\Debug"
#r "Project.name"
#endif
Alt-Enter now drops me into fsi with all the required stuff loaded
If it's a project you reference often, you can add an 'always' reference to the FSI command line, under Tools->Options->F# Tools->F# interactive options.
Add a -r switch like:
-r "C:\Users\yaddayadda\MyDll.dll"
I don't think there is any direct way to reference a project in the solution. The best way I can think of is to add a FSX file somewhere to your project with the #r directive:
#r #"bin\Debug\YourProject.dll"
Then you can at least reference the compiled DLL file simply by hitting Alt+Enter in Visual Studio. As far as I know, you cannot reference the project - you can only reference an assembly.
Currently, F# Interactive is really disconnected from the project system in Visual Studio. I suppose that closer integration would be quite useful (but probably difficult to provide).
Now in Visual Studio 2013 you can add a reference to the F# interactive window by right clicking on the referenced dll and clicking "Send to F# interactive".
I would think it should be straightforward to reference the current project, obtain the list of references it contains, and then optionally generate a list of #r (and possibly #i) statements for the interactive session being created, referencing the dll of the project itself as well.
For example: "fsi /i:pathOfLib1 /r:lib1 /i:pathOfLib2 /r:lib2 ...."
PS: base on the MSDN article it doesn't appear that library names can include their path prefixes hence the separate into /i and /i : http://msdn.microsoft.com/en-us/library/dd233172%28v=vs.100%29.aspx
It would be good if the Visual Studio F# Interactive Options menu allowed for the stipulation of a startup script that the invocation could pass to FSI via the "--use:" directive. Such a script could then be passed solution metadata that allows for the environments to be more integrated such as loading latest project outputs.

Seq.generate_using is MIA

I'm trying to use the Seq.generate_using function but unfortunately, I don't seem to be able to find it. I thought it would be living here:
Microsoft.FSharp.Collections.Seq.generate_using
But it doesn't. I am getting the error listed below.
C:\Users\Owner\Documents\Visual Studio
2008\Projects\fsharp1\Program.fs(54,63):
error FS0039: The value, constructor,
namespace or type 'generate_using' is
not defined. A construct with this
name was found in
FSharp.PowerPack.dll, which contains
some modules and types that were
implicitly referenced in some previous
versions of F#. You may need to add an
explicit reference to this DLL in
order to compile this code.
According to the Sept 2008 CTP Release Notes:
The F# library is split into two
components. FSharp.Core.dll: Contains
the core F# libraries, which will be
stabilized and versioned infrequently.
FSharp.PowerPack.dll: Contains
additional useful F# libraries and
tools which will version more
frequently, and allow continued
innovation on top of the core F#
language and libraries.
Some methods in the Seq module were moved into the FSharp.PowerPack assembly, so you can only get those methods by doing the following:
If you're using Visual Studio, open your Solution Explorer, right-click on the project file, choose "Add Reference", and add "FSharp.PowerPack.dll".
If you're using a script file or fsi, then type #r "FSharp.PowerPack";; to load the assembly.
Now you should be able to call Seq.generate_using.
The #r "FSharp.PowerPack";; works for me but the addition of PowerPack to my solution does not. I am trying to use HashSet<>.

Resources