Herding Code 167: Glenn Block on scriptcs

This week on Herding Code, the guys talk to Glenn Block about scriptcs.

Download / Listen:

Herding Code 167: Glenn Block on scriptcs [audio://herdingcode.com/wp-content/uploads/HerdingCode-0167-ScriptCS.mp3]

Show Notes:

  • Intro
    • (00:10) K Scott asks Glenn if he’s still working with Node at Microsoft. Glenn says he’s moved from command-line tools for node and is focused on Azure Mobile Services, but he still owns the Node SDK and the Node story for Azure.
    • (01:56) K Scott scriptcs is another way to write C# code outside of the IDE as script files. It’s inspired by Glenn’s work with Node.js. It leverages Roslyn, NuGet, and some conventions to simplify scripting, such as automatically pulling in NuGet packages.
    • (03:58) K Scott comments on the ability to reference assemblies using the #r directive. Glenn says it’s even easier than that – you can use #r to reference GAC’d assemblies, but assemblies in the local bin folder are automatically referenced. K Scott asks about the hooks to support that, and Glenn explains how Roslyn supports a lot of scenarios; since it ships it as NuGet packages it can be used outside of Visual Studios. Roslyn allows for code to exist outside of a class.
    • (06:33) Jon talks about his initial experiences, and how the REPL made it really easy to get started. Glenn explains how that works and explains how, using Chocolatey you can quickly install scriptcs and a NuGet package like MongoDb and then just start writing code in the REPL.
  • Dependence on Roslyn
    • (09:35) Kevin points out that Roslyn is still in CTP and asks how that impacts scriptcs. Glenn says that since it’s a CTP Roslyn you can’t ship the binaries, but that’s not a problem for scriptcs since it pulls in the public NuGet packages. Roslyn is still evolving, it doesn’t yet support async / await or dynamic, for instance.
    • (11:13) scriptcs no longer takes a dependency on Roslyn. It uses a pluggable script executor which can use Roslyn but can potentially also use other script engines.
  • Example uses of scriptcs
    • (12:33) K Scott asks for some common use cases. Glenn says that it’s possible to build apps because you can have one script that includes other scripts, then talks about the WPF calculator sample in the scriptcs-samples repo.
    • (14:18) Glenn says another use he’s seeing is automation – basically as a replacement for PowerShell. He talks about the Fluent Automation sample which uses script-cs to automate Selenium tests.
    • (15:18) Glenn talks about a real world example at a large trucking company who is using scriptcs to automate data processing jobs.
    • (16:05) Octopus Deploy has added support for scriptcs. He used a loader script that passes configuration to user-written scripts.
    • (17:42) Glenn says it’s useful to tinker and play with libraries or services and give an example of interacting with Azure Mobile Services in the REPL.
    • (18:38) One other example is extensibility – creating hooks and allowing end users to just drop in a scriptcs script to extend behavior.
    • (19:03) Kevin says that in the past people have used JavaScript engines to support extensibility. Glenn says that touches on a common question – why scriptcs as opposed to a lot of other options such as F#, Ruby, node, etc.? He gives two reasons: you get to stay in a language you’re familiar with, and there’s a "grow up" story to migrate from scriptcs to a Visual Studio project using the same libraries, same code, etc.
    • (20:03) Jon says that the PowerShell syntax is different enough that he can’t remember it. He talks about the idea of using scriptcs for installation and initialization scripts in NuGet rather than PowerShell. Glenn says there are kind of ways to use C# with PowerShell, but it’s not the same. He mentions a sample from @beefarino which lets you talk to scriptcs from PowerShell.
    • (23:01) Kevin asks what the migration process is to move from scriptcs to a C# project. Glenn says it depends on how much you take advantage of scriptcs features like Script Packs. Script Packs bring a node-like require module syntax into scriptcs. Glenn talks about the Web API script pack which adds in proper usings and gives you an API that’s very easy to use in script, without IntelliSense. They’ve talked about creating a project exporter which could set up a project and bring in your Script Packs, etc.
    • (26:25) Kevin asks if the Script Pack / Require experience could be brought into standard C#. Glenn says the general concept could work because it’s just a DLL, although there are some incompatible things like import statements. They’ve looked at writing Script Packs as script, which could make this more useful.
    • (28:40) Kevin talks about how the Node module system handles conflicting dependencies and asks if scriptcs handles that. Glenn says not yet, but .NET is now able to handle that so it could be added in. The general idea of script modules depending on other script modules makes sense, but conflicting dependencies might not be very useful. They’re thinking of NuGet packages with no assemblies, just does as content, and talks about some implications.
    • (31:32) Jon talks about how Glenn had told him that a lot of his bizarre feature requests wouldn’t fit in the core but could be useful as extensions, then asks about the extensibility points. Glenn runs through what you can do: change the engine, use Script Packs, bring in NuGet packages, possible later REPL extensions via global NuGet packages. He says they’re following the Node team’s principles of keeping a small tight core and pushing features towards extensions.
  • Questions from Twitter
    • (34:14) Jeff Schumacher (@codereflection) asks Glenn to compare scriptcs performance vs. compiled code. Glenn says that there can be a short startup impact and potentiall
    • (35:58) Akim Boyko (@AkimBoyko) asks if it’s possible to run scriptcs without Roslyn, async/await support and in sandbox mode. Glenn talks about the Mono impact of running without requiring Roslyn support. Roslyn will be getting async/await support at some point, but it could also be added via CodeDom if people implement that. However, CodeDom doesn’t support the classless system that Roslyn does.
    • (38:04) Simon Cropp (@SimonCropp)  asks if scriptcs support plugging into the build pipeline? Eg if I wanted to plug in Fody (https://github.com/Fody/Fody/).
    • (39:41) Several questions on how scriptcs compares to Snippet Compiler, LinqPad and csscript.
    • (41:12) Dan Vanderboom (@danvanderboom) asks if scriptcs let us run a .cs code file by itself anywhere in the file system? Glenn says no and explains why he’s not sure that would be useful.
    • (42:55) Tomasz Janczuk (@tjanczuk) asks When will integration of scriptcs and edgejs be done? 😉 Glenn talks about how the projects have both grown up together and how the two would be useful together.
  • Debugging and IntelliSense
    • (45:29) Jon talks about how he messed something up in the samples and debugged it and asks about debugging support. Glenn points out that you can directly debug an EXE in Visual Studio and explains how to debug scriptcs code in Visual Studio. He also talks about MDbg which Glenn (and apparently everyone else) didn’t know existed. He also mentions a Script Pack for debugging.
    • (48:15) Jon says the REPL is great, and yet he’d sometimes like IntelliSense. Glenn talks about a lightweight WPF editor that’s in progress, but says if you get to a point where things are getting complex it’s probably time to move to move from scriptcs to a project. Jon says that for the most part Script Packs seem to really simplify the code to the point where you don’t really need IntelliSense, and Glenn agrees.
  • Shoutouts
    • (50:45) Glenn calls out the two other coordinators on the project, Filip Wojcieszyn (@filip_woj) and Justin Rusbatch (@jrusbatch) as well as some other top contributors.
  • Shell capabilities, TSR scenarios
    • (52:03) Kevin asks if there are possible changes to make it more shell-like with things like piping. Glenn says they currently have a poor story for arguments, but it’s coming. You can currently pipe text, but he’s not sure about piping objects.
    • (54:30) Jon says he’s got some AutoHotKey scripts and asks if scriptcs could handle that kind of thing.
  • Future plans
    • (56:10) K Scott asks where things are going in the future. Glenn mentions scriptcs modules, aliases, a better Visual Studio experience, export project, and saving DLLs.
    • (1:04:25) Glenn talks about some interesting ideas on GitHub, like a command to break execution into the REPL. They’ve got 20 active contributors, so things are moving fast.
    • (59:54) Glenn says he’s got a personal interest in seeing some adoption in Microsoft – such as adding scriptcs scripting to other projects.
    • (1:00:25) Glenn talks about one question that comes up: should the Roslyn team have tackled the scriptcs scenario?
  • Wrap up
    • (1:01:10) K Scott asks about Glenn’s upcoming plans, speaking engagements, etc.
    • (1:02:27) Jon makes a last minute sales pitch to try it out – you can install in seconds from Chocolatey and just start playing at the REPL. Glenn points one gotcha – scripts which run servers need to be run as admin.

Show Links:

Herding Code 166: Tomasz Janczuk on Edge.js

This week on Herding Code, the guys talk to Tomasz Janczuk about running .NET code in Node.js using Edge.js.

Download / Listen:

Herding Code 166: Tomasz Janczuk on Edge.js [audio://herdingcode.com/wp-content/uploads/HerdingCode-0166-EdgeJS.mp3]

Show Notes:

  • Intro and background on Edge.js
    • (00:40) Tomasz has been focusing on Node.js at Microsoft for the past 3 years. He’s been working on making Node.js run well on Windows. He’s also worked on hosting Node.js on Windows Azure with IISNode.
    • (02:08) Jon asks about Edge.js’s original name, Owin. Tomasz explains how that made sense with the original scope – connect middleware and express handlers – but it’s grown since then so it needed a more generic name.
    • (02:45) Edge.js lets you run Node.js and .NET code in one process and provides interop mechanisms between the two.
    • (03:05) Jon asks why that’s useful. Tomasz says you can do pretty much anything in either Node.js or .NET, but some things work a lot better on one platform. He gives examples like using ADO.NET to connect to SQL Server and running CPU bound computations as multi-threaded .NET code from the single-threaded Node.js event loop. There are two classes of scenarios: things that work better on one platform, or writing native extensions to Node.js without having to drop all the way down to raw C and native OS mechanisms.
    • (06:11) Jon brings up two questions from Twitter about Mono support (Jason Denizac @_jden "when’s mono support coming?" and Kevin Swiber "Mono support? Can we do legit Node modules in C#? Are grilled hotdogs really better than boiled?" Tomasz says not yet, but it’s high on the list. There are some complications to implement that support since Edge.js uses C++ CLI, which isn’t available on Mono.
  • Getting started and samples
    • (07:57) Jon asks what’s involved in setting it up. He says he ran npm install edge, then npm install edge-cs. Tomasz explains why he didn’t need to install edge-cs – C# support is built in, other language support plugs in.
    • (08:43) Jon asks about the samples. Tomasz explains the different ways of integrating CLR code into Node.js and talks about how the samples show these approaches.
    • (10:36) Jon says he liked how the samples progressed from very basic to pretty complex. Tomasz says you can do just about anything in Edge.js, but there’s a specific interface you need to follow in order to work smoothly between the Node.js async model and many synchronous operations in .NET. Every function in Edge.js uses an async function delegate, so you end up using small wrapper functions in some cases.
  • Marshalling and interop
    • (13:08) Kevin says this reminds him of COM / .NET interop and issues with object lifetime, garbage collection, etc. Tomasz says that that the async function delegate solves the threading models. Object lifetimes are controlled because everything is marshalled by value.
    • (16:22) Kevin asks if the marshal by value prevents working directly with the CLR object. Tomasz says that you can handle this using function proxies to create closures over CLR states.
    • (17:45) Scott K. asks if structs eliminate the serialiazation issues. Tomasz clarifies that the marshalling process is reflecting over the objects in .NET and recreating a synonymous JavaScript. Scott says this sounds like thunking from days of old.
    • (19:27) Jon says that he saw one sample that allows for debugging inline .NET code in a JavaScript file. Tomasz explains that this is done using the codedom compiler to create an in-memory assembly with debugging information, which can be attached to from Visual Studio.
    • (21:25) Jon says he thinks this sounds useful for using a NuGet package in a Node.js application and asks if there’s support for pulling in a NuGet package. Tomasz says that at this point it’s up to you how you’d get the assembly downloaded and set up, but that there’s an open issue to get script-cs integration going and that would handle this.
  • Overhead and performance
    • (23:06) Jon asks about the overhead of running two virtual machines and marshalling. Tomasz says there is some overhead, but it’s better than running two different processes. Edge.js is built for solving some specific scenarios, and it’s fast in those
    • (24:55) Kevin asks if there’s a delay when Edge.js spins up. Tomasz says that happens when you require Edge, but it’s not really noticeable.
  • Misc questions
    • (25:55) Jon asks what was the hardest part of implementing Edge.js. Tomasz says the function proxies to handle lifetimes and reconciling threading models.
    • (27:45) Scott says this sounds useful for authentication or using a legacy .NET library. Tomasz lists several more.
    • (29:20) Kevin asks how exceptions are handled. Tomasz explains how the exceptions are marshalled and thrown across VM boundaries.
    • (30:15) Kevin asks if it’s tied to specific Node.js versions. Tomasz says it works on all current stable versions.
    • (31:30) Question from Twitter: @jeremydmiller "I’ve seen a lot of samples of hosting . Net in node, but how about running node in a .net process?" Tomasz talks about an open issue, Mission Double Edge which would handle that. He explains that the challenge is that Node.js doesn’t have a hosting model.
    • (33:20) Jon says he saw several of the samples had the C# script named with .CSX extension and asks about that. Tomasz says that this is partly done to follow Roslyn conventions, including specifying assemblies as references in code using #r.
  • Future plans and next steps for listeners
    • (34:25) Jon asks what’s planned going forward. Tomasz talks about Mono support and adding support for additional languages, including F# (note: this has been added http://tjanczuk.github.io/edge/#/3) . Jon asks what’s involved in adding language support.
    • (36:30) Jon asks about the relationship with OWIN. Tomasz says there’s a separate module which allows you to plug any OWIN compatible .NET application and plug it into an Express.js pipeline. Jon says this reminds him of the Edge name and Tomasz explains that the idea is that mathematically an edge connects two nodes, so Edge.js connects differe.
    • (38:25) Jon asks about next steps for people to get started.
    • (38:55) Jon asks if this is a Microsoft project. Tomasz says it’s his own separate open source project that’s inspired by his day job, and this allows him some more flexibility to work with the community. He lists some of the community contributions they’ve seen so far.

Show Links: