I have heard of several situations of people using say, JavaScript or Python (or something), inside a program written in C#. When would using a language like JavaScript to do something in a C# program be better then just doing it in C#?
-
1Why would someone downvote this question? IMHO its a good question.– KK.Feb 22, 2013 at 3:54
-
28It's very useful for making absurdly complex pieces of software that require expensive consultants to maintain it, especially when the scripting language is terrible.– whatsisnameFeb 22, 2013 at 4:07
-
2I don't have an "answer", per say, but the Pragmatic Programmer has a chapter on this (#12 - Domain Languages). Might provide some insight for you.– CraigeFeb 22, 2013 at 4:33
-
1There are some good answers on a similar question on Game Development: gamedev.stackexchange.com/questions/2913/…– celionFeb 22, 2013 at 5:31
-
6Sometimes it's even better to have a large system within a scripting lanugage - it's called "Unix way". You can glue numerous distinct subsystems together using a tiny scripting layer. This architecture is known to be very robust and scalable.– SK-logicFeb 22, 2013 at 9:30
10 Answers
When you have behavior that you don't want to have to recompile the program in order to change. This is exactly why so many games use Lua as a scripting/modding language.
-
42And also it's so that users can add functionality themselves. You kind of implied it, but I think it's important enough to deserve to be emphasized more.– user39685Feb 22, 2013 at 1:30
-
2
-
@meawoppl ...or to add functionality to a program. Look at IDA's integration of Python (dubbed IDAPython) Feb 22, 2013 at 17:49
-
Why not make it so that you only need to recompile one library (e.g. with specific game logic components)?– DenFeb 25, 2013 at 9:15
-
If you look at other tools, such as AutoCAD, Sparx Enterprise Architect, MS Word, you don't have recompile them to script them in C#. Feb 27, 2013 at 16:36
This technique can be used to implement core logic that is easily portable between different language environments. For example, I have a calculator simulator where all the internal calculator logic is implemented in 100% JavaScript. The user interface code is of course different for each platform:
- Web browser (JavaScript)
- iOS (Objective-C)
- Windows (C++ with Qt)
- Mac OS X (C++ with Qt)
- Java Swing (Java)
With this arrangement, making versions of my program for different operating environments, and especially keeping them up to date, is much simpler.
Very broadly there are two situations where you would apply this pattern:
- This is used internally to leverage some quality of the embedded language.
- This is used to provide external programmability.
Internally
- Typically the embedded language is interpreted which allows changes to be made and tested quickly without a re-compile.
- The embedded language may be more expressive than the language your core application is written in, again allowing for faster development.
- The language may be a better fit for some particular domain compared to a general purpose language.
- The language is used by internal users who need a "simpler" programming language/environment. Short programs are written by people who are not software developers using a relatively simple syntax/API.
An example here would be Lua used in Adobe Lightroom.
So what we do with Lua is essentially all of the application logic from running the UI to managing what we actually do in the database. Pretty much every piece of code in the app that could be described as making decisions or implementing features is in Lua until you get down to the raw processing, which is in C++. (Mark Hamburg Interview: Adobe Photoshop Lightroom)
Externally
- Allow users to extend the behavior of your application without requiring special tooling and/or libraries and/or access to your source code.
- Provide those users with a well defined API and a sandboxed enviornment. This could also be done in the application's language but embedding an interpreter can make this easier.
IBM used scripting languages very successfully in their mainframe operating system VM-CMS. EXEC, EXEC/2 and later Rexx were used throughout the system both internally and externally. Different applications (e.g. XEDIT) were scriptable using those same languages and internal applications/utilities (e.g. E-mail) were written in the scripting language and leveraged the tight integration with the OS and other tools. Customers created and shared many scripted tools and applications. DEC also provided DCL. Later on Microsoft supported VBscript as a scripting language in most of their applications and more recently PowerShell (also MS/DOS batch files). Unix shells have scripting as well.
The trend today appears to be exposing APIs in some way and leave the choice of scripting language up to users who can utilize different bindings or other means of accessing the API.
Real world examples would include:-
Most web browsers which will support embedded JavaScript.
Microsoft Office Suite -- Excel Word etc. all support embedded VBA scripts.
Many network routers include script APIs, in a variety of languages TCL, Perl , Lua.
Many embedded devices are implemented using a very small set of core C functions which are glued together using a scripting language such as Lua. So you have a set of small, fast C functions which interact with the hardware, and, most of the control logic in a flexible, easy to amend scripting langauge.
-
@antony.trupe. The name commonly used to refer to ECMAscript - en.wikipedia.org/wiki/ECMAScript Feb 23, 2013 at 23:16
Sometimes scripting is embedded in an application because it's a means to extend the host application by other developers. In order to capture as wide a range of programming language skills as possible, multiple scripting languages could be supported by the host. For example, on the JVM, you can embed a whole slew of JSR-223 compliant languages, including Python, Ruby, JavaScript, etc.
Another reason not already mentioned is that the embedded language has one or more standout features which the host language could not easily duplicate. An example of this would be the Parse functionality or effortless DSL (domain specific language/dialect) creation which can be found in a language like Rebol.
There is one interesting way of using a scripting language inside an application which have not been mentioned by the others yet.
If your host language has a rich, reflective runtime, it is often useful to embed a simple language with REPL in your applications, hook it on a socket and give it an access to the whole system.
It can be used for an interactive debugging (and it's naturally much more powerful than your usual debugger), hot code patching, various monitoring purposes, even backdoors (if you're up to no good).
-
Naturally much more powerful than your usual debugger? In what way? How can a "simple external scripting language" with no intrinsic knowledge of your host language's idioms, memory model, object model, basic data types, etc possibly provide any useful facilities that a debugger designed to work with the language could not? Feb 23, 2013 at 4:17
-
@MasonWheeler, can you hotswap the code with a usual debugger? Can you perform arbitrary complex programmable queries about the state of your runtime? Can you perform complicated controlled experiments? And you're wrong in assuming that a scripting language has no "intrinsic knowledge of host language's idioms, ...". If both host and scripting language are running in a same VM (.NET, JVM, V8, whatever), there is a full access to all the guts from your scripting language.– SK-logicFeb 23, 2013 at 12:23
My specific situation, when I use an interpreted scripting language in a major application:
There is an external device that performs several functions. Measurements, control, readouts. It's pretty "dumb" itself and requires precise control, step-by-step, including lots of wait states and ad-hoc decision making on the control mechanism side.
Various functionalities of the device are required at various points of the main application, at different times, often on-demand. The main app does not allow for wait states as such, everything must be done with finite state machines.
Now whoever wrote a finite state machine knows implementing a wait state is effectively at least two, often three or four internal states of the machine. Implementing twenty wait-states for various functions (and waiting for their responses and reacting accordingly) of the external device would be a very, very frustrating experience.
So, instead there are states of "execute a no-wait function", "execute a blocking function", "execute a branching/conditional/jump" function in the finite state machine, maybe six states total. And there are control scripts that get scheduled for execution, then executed by the interpreter controlling the external device, and their results placed where they are required.
Summing up, the application: in a RTOS, using an internal interpreted scripting language may enormously reduce complexity of performing tasks abundant in wait-states (blocking functions).
From my experience, we once developed a big application that does rewrite sourcecode of an "ancient" langue to be unicode compatible. The was done in C#. I ended up writing only the engine (that creates a data model and provides means to do the steps necessary for the rewrite process) in C# - the "glue code" for actually executing things is done in IronPython.
The biggest point for the integrated IronPython: Let's assume you loaded a big data model (about one hour load time). Then you want to -manually- collect information and look up things. Doing this with a Python script from an interactive console is far far better than clicking through the data model with the debugger (plus, it's replayable).
There are couple reasons.
- Learning curve. Virtually everyone can learn and write in javascript.
- Security. It's hard to control security context of script code in C# or Java. Javascript is perfect for that. Script author never able access to disk or anywhere if do not allow them. Core javascript engine is just a advanced calculator.
- Quality. You put a very thick limit to scripting code. "Spaghetti code" levels are very different for Javascript or C#/Java. (Which is prevents you from opening the gates of hell)
- Type safety. C#/Java are type-safe environment, you mostly don't prefer it in a scripting environment. Expression like "12" + 3 gives "123" in javascript but C#/Java will not even compile. Script writers mostly does not even what is "type"
- Dynamic. Any object can contain any property/method and may change it's type in time. For example I could provide a proxy C# object to scripting environment that exposes XML nodes as properties.
- Productivity. Usually writing script is much more easy than C#/Java. No compilation or "plugin registration" required. You could directly edit the script content within application with immediate results.
- Managing. Using C#/Java requires a SDK to be link on plugins that exposes internal classes to world. This plugin architecture requires the "backward-compatibility" for old SDK versions. This architecture forces you to create "virtual" domain objects that provides internal mechanism of application in domain context. It's more manageable/flexible than exposing an API.
-
3This misses the point of the question of embedding scripting within a larger program. For example, why would one a developer chose to add script-fu to the gimp? Or have modding of Civ V with lua - why would a developer chose to add scripting to an application?– user40980Feb 23, 2013 at 3:53
When? Between 1948 and 2008 - initially compiled languages took significant time to compile and link, so it was commonplace to create a scripting language to allow user customisation and configuration. If you look at the history of AutoLisp, then the answer is initially AutoCAD shipped with a scripting language within it, but this was phased out in favour of exposing an scriptable interface to VBA then .net.
With CLR, enabling a C# program or a Lua program call into an existing system are not significantly different in development cost, and the .net runtime ships with the tools to generate and compile on the fly.
You no longer need to have a scripting language within the larger program, but instead expose the larger program to the scripting facilities of the runtime.
In environments which don't offer on the fly code generation and compilation, and it is seen as desirable to offer a general-purpose automation language rather than a domain specific one, you will still get Lua or Python scripting. For tools offering a COM interface, then that scripting language will be C# or VB.net ( MS Office, Sparx Enterprise Architect ). So having a scripting language for a program written in a language which is itself simple enough to be a scripting language is a unnecessary.
-
A google search for Lua-scriptable XNA games doesn't turn up zero results. Feb 24, 2013 at 17:24
-
@user16764 and a google search for bicycles made of meringue turns up six million. Feb 24, 2013 at 17:34