Skip to main content

Defeating the Purpose of a DSL

First, I neglected to mention in my previous post that I found Paul Cowan's blog to be a tremendous help in figuring out how build a DSL with Boo and Rhino DSL.

Second, I wanted to point out that, because this is an internal DSL written in Boo, it's still possible to use familiar programming constructs in the DSL scripts. For example, I could dynamically generate the team definitions from some other datasource, like so:

stats = GetData()

for row as DataRow in stats.Rows:
define row["name"]:
defense Determine.DefenseFromRanking(cast(int,row["defenseRanking"]))
pass_offense Determine.PassOffenseFromRanking(cast(int,row["passOffenseRanking"])), with_qb_type(Determine.QbTypeFromRatingAndExperience(cast(double,row["qbRating"]), cast(int,row["qbExperience"])))
run_offense Determine.RunOffenseFromRanking(cast(int,row["runOffenseRanking"]))

where GetData() returns a DataTable with multiple team statistics, and Determine is a static class that gets the name of different team components based on relevant stats.

The meta methods that define the keywords won't work as is for this. Remember, they're operating on the AST. In this case, the parameter types simply need to be relaxed from StringLiteralExpression to Expression. Here's the new run_offense meta method as an example:


[Meta]
public static def run_offense(expression as Expression):
return [|
_currentTeam.RunOffense = $expression
|]

So, string literals and method calls both work here. One thing that slightly limits the extensibility of the language in this matter is the use of the implicit base class as a container for the script. The body of the script (minus any import statements) goes directly into the implementation of an abstract method declared on the base class, so extending the language by adding methods directly to the script is out. Other than that, everything should work like normal. All the constructs of the language are available. Of course, doing something like what's listed above sort of defeats the purpose of creating a language for easy data scripting in the first place, as it isn't very readable or maintainable...

Comments

Popular posts from this blog

Enabling Globalization Invariant Mode for .NET Core App on Raspberry Pi Running LibreElec

I had an app I wanted to run on my Raspberry Pi 3 running LibreElec . In LibreElec you can install the dotnet core 2.2 runtime as an addon, and in Visual Studio you can compile for ARM processors with ‘Target Runtime’ set to ‘linux-arm’ in the publish profile. So, I published to a folder from VS using that profile, and I copied the output over to my RPi which had the dotnet runtime installed. I did a simple dotnet Whatever.dll to run the app (actually in this case, it was /storage/.kodi/addons/tools.dotnet-runtime/bin/dotnet Whatever.dll because of the way the addon is installed) and was met with this error: FailFast: Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support. at System.Environment.FailFast(System.String) at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode() at System.Globalization.GlobalizationMode..cctor() at Syste

Migrating Hg Repos with hg-fast-export and Windows Subsystem for Linux

Introduction I prefer Mercurial (hg) to git . I don’t really have any reason for this preference - they both do the same thing, and the user experience for 90% of the use cases is the same. It probably comes from the conditions of the DVCS landscape when I started using these systems. Some of this may have been perception only, but it looked like this: GitHub didn’t have free private repos BitBucket did have free private repos BitBucket was very hg-friendly Joel Spolsky had an amazing tutorial that served as both a how-to for hg as well as a general intro to DVCS hg was much more Windows-friendly than git Since hg was written in python, I felt like extending it would be easier than doing so for git if I ever needed to (admittedly, this is a pretty ridiculous reason) hg felt like a more unified, “coherent” system than the very linux-y feeling git and its extensions (also pretty ridiculous) Where they differed, I liked the verbs hg used better than git’s counterparts

Serializing Anonymous Methods

I’m taking some time off from not blogging to do a little blogging. I hope this doesn’t inconvenience absolutely nobody. I was doing some [binary] serialization work recently when I came across a problem – I wanted to serialize objects with delegate fields that were populated with anonymous methods at runtime. To wit, I had types like this: public delegate void MakeMove(); public class AdrianPeterson { public int GameOneYards { get; set; } public Football Ball { get; set; } public MakeMove Move { get; set; } } Populated like this: var explicitDirections = new List<string> { "left", "right", "left" }; var ap = new AdrianPeterson(); var apName = ap.GetType().Name; ap.GameOneYards = 87; ap.Move = () => Moves.Weave(apName, explicitDirections); So, I pop a [ Serializable ] on AdrianPeterson (and Football ), and I’m set, right? Wrong. Wrong like getting away from running AP in the second half when the only receiving threat you have is bei