Today we are very excited and proud to announce that we finished testing and moved to the packaging procedure for our next brainchild called “Orbifold S#“. The purpose of this article is to give a brief overview of what S# actually is, key features and possible use cases.
S# is a weakly-typed dynamic language and runtime infrastructure to make your applications extendable, customizable and highly flexible. It allows introducing expressions and large code blocks evaluation within your applications in the similar way Microsoft Office deals with VBScript, gives you possibilities providing rich formula evaluation capabilities like it can be seen in MS Excel, etc.
“Orbifold S# Runtime” will be distributed absolutely free for academic and non-commercial usage!. You can download runtime right now from here.
The key principles of S# are:
- Be simple
- Be efficient
- Be intuitive
S# runtime has been designed to be easily hosted by applications. Minimum script execution scenario requires two lines of code! The important part of S# is its well-defined extendable runtime engine together with the application programming interface that allows full bi-directional communication between script and application code. In particular it is easy to extend S# by embedding external functions and functional objects, shared static or dynamic variables, operator handlings and type filters from the host application. Moreover the execution semantics of some language constructs has extensibility mechanisms available externally. This enables developers to create user-friendly executable business/domain specific languages on S# basis.
S# can work in single-expression mode in order to execute string expressions to values. This is especially helpful when application should allow users executing only light-weight portions of the functionality. S# is a pure .NET interpreted language completely written in C#.
For the moment it is ported to the following platforms:
- Microsoft .NET 3.5 (SP1)
- Microsoft Silverlight 3.0
- Microsoft .NET Compact Framework
- Microsoft XNA Framework
This means that S# runtime can be hosted by applications based on .NET like Console, Windows Forms, ASP.NET, Silverlight 2 and 3, Windows Presentation Foundation (WPF), XNA (both PC and XBox scenarios) and MONO (Linux).
Key features that will be dwelled on in the upcoming articles are:
- Designed to be easily embedded into applications
- Highly extensible grammar and language
- Rich and controlled communication between runtime and host application in both directions
- Sits on the top of .NET, has support for interaction with .NET code
- Works in a single-expression evaluation mode to execute string expressions to values and return results to application
- No code emitting, no CodeDom or background compilation, 100% interpreted language (own Virtual Machine and Debugging facilities are in progress)
- Completely in-memory execution, does not require temp files, local system access, etc
- C# and Java-like language syntax designed to be familiar to .NET and Java developers; easy to study for non-developer users
- Various platforms are supported
- Fully remotable; expressions and scripts can be sent across the wire and executed on a remote machine
- Weakly-typed as IronPython and IronRuby for .NET
You will need a couple of clicks in order to install S# runtime on your machine. For the moment runtime requires less than 1 MB on you hard drive.
For the moment you will have runtimes only for .NET 3.5 and Silverlight 3.0 installed by default. Both components are automatically registered within the “Add Reference” dialog in Visual Studio 2008 (note this requires installation to be started by a user with administrator account).
When creating a new Silverlight application you will be able adding S# reference without any additional implications related to finding the assembly installed on the local drive:
From Installation right to Execution
I am going to show you how easily you can start hosting S# runtime right after installation process is finished. You need to create an empty “Silverlight 3” application project and add reference to “Orbifold S# for Silverlight” assembly using “Add Reference” dialog in Visual Studio 2008.
Next open “MainPage.xam” file and add a Canvas control. We are going to execute scripts that perform some operations against the Canvas element.
After that you will need opening the code-behind file “MainPage.xaml.cs”. S# runtime hosting will require at least 2 namespaces involved: “Orbifold.SSharp” and “Orbifold.SSharp.Runtime”
Note that S# runtime should be initialized before executing scripts. This procedure should be done once and I would recommend placing “RuntimeHost.Initialize()” method call somewhere in “App.xaml.cs” in the future.
Now it’s time to do some scripting on the “MainPage.Loaded” event:
S# runtime supports a large amount of Scoping facilities (local scopes, global scopes, dynamic or application-controlled scopes). The same goes to execution contexts. Execution Contexts is a highly valuable and extensible area that deserves a separate article. All this will be described in future articles and in API guides.
As I want promoting my “canvas” element to the runtime I need creating a simple execution context for my future script and provide possibility accessing “canvas” during runtime. This is achieved by adding a “canvas” variable to the scope that references our “canvas” element inside application. Note that you can provide any “alias” you want and it may not carry the same name as host-side variable/element.
Next step is defining the body of the script. I’m going to assign a new background brush for the Canvas and add a Rectangle element. Note that I don’t have to use full namespace paths for .NET classes as they are resolved automatically by S# runtime. You may forget about endless “using” clauses here.
After that I create a Rectanlge, configure it’s properties (including attached ones) and add it to the Children collection of the Canvas control by referencing “canvas” variable.
Finally I call “Script.RunCode” providing the body of the script and root execution context. When launching this Silverlight application you will see the following result:
Yes, everything works perfect. Script got access to application structures and even managed to create and add new objects using core .NET Silverlight functionality. I would like to highlight “namespace resolving” feature once more as it really simplifies coding efforts. Let’s extend the script above to apply rotation for the Rectangle shape. “RotateTransform” class resides in “System.Windows.Media” namespace in Silverlight 3.0.
As S# is a weakly-typed language you don’t have a need worrying about value types as they will be resolved automatically during runtime.
When running modified script you should see the following results:
Extending Language with Custom Functions
Though S# supports a huge part of C# syntax constructions it may be required adding some domain-specific constructions or functions that simplify script building for end-users.
I am going to create two new functions: “CreateRectangle” that creates a Rectangle shape in a simplified manner and “Rotate” that will rotate FrameworkElement.
Both functions are fairly simple and don’t require comments. Please note that each S# function element should expose “IInvokable” interface. This is the only requirement for external functions integration.
In order to promote these functions you will need to include them into the scope the same fashion “Canvas” element was done – ScriptContext.SetItem() method. However to reduce development time there are also generics-based methods:
Note that you can provide any name for the function. In this case I used “CreateRectangle” and “Rotate”. Now let’s modify the code from the samples above in order to consume new functions:
This time the code becomes less complex but more efficient. I can create a Rectangle shape providing position and size and can call “Rotate” in order to apply Rotate Transformation.
Just for demonstration purposes I’ve added a function usage sample. I’ve introduced a function (event handler) called “OnCanvasClick” that is wired with “MouseLeftButtonDown” event of Canvas. Function requests access to global variable scope via the “global” keyword (similar to PHP)
Now if you execute a script Rectangle will rotate 10 degrees each time you click design surface with a left button of the mouse. Another important point is that weakly-typed and dynamic nature of S# allows me accessing Angle value of RenderTransform property as of RotateTransform actually. By default RenderTransform property is of Transform type. S# didn’t require me doing type casting or conversion in order to set property value and this is really helpful in many scenarios.
The S# language has a great number of features and runtime is extremely extensible. We will unveil more details, links and samples for S# very soon.
UPDATE: Meanwhile we are finishing all the packaging work you can download the raw runtime (without documentation, samples and some other stuff) right now here.