Domain-Specific Languages in Racket compared to Model-Driven frameworks such as Xtext - racket

Racket and Xtext are both considered as language workbenches, but they are based on different concepts and workflows.
As an experienced Xtext user, I find it difficult to adapt my thought process to Racket.
In Xtext, the grammar of a language is converted into, or mapped to, a set of classes (also called a metamodel).
Xtext also generates a parser that converts a source file into a set of instances of those classes. A scoping API allows to resolve named references, so that the result is an object graph (also called a model) rather than an abstract syntax tree (AST).
Such a model can be queried, transformed, or fed into a template engine to generate code.
In Racket, the reader produces an AST in the form of a syntax object. However, most examples that I have found seem to make an ad-hoc use of this syntax object. Either they are toy languages that do not need a complete object graph, or they are too complex and it is difficult to infer a general methodology.
For my current language project, after struggling with syntax objects, I have created the equivalent of a metamodel using Racket structs. Then it was fairly easy to convert a syntax object into an object graph that I could manipulate as if it were a model in EMF. However, I feel like I am not using syntax objects the way they are intended to be.
Here are my questions:
What tools or APIs are available to work on syntax objects and achieve a similar ease-of-use as a model-driven framework?
Are there documents that describe a general language development methodology in Racket, that could be applied to non-trivial languages?
Are there documents that explain the Racket way, compared to Xtext or any other model-driven language framework?
EDIT:
Based on the documentation for Metaprogramming helpers, syntax classes can be used to specify and compose syntax patterns, and attach attributes to their elements. They can achieve a similar purpose as the classes of a metamodel.
However, as far as I can see, syntax classes are not classes, and syntax objects are not linked to syntax classes in a class-instance relationship.
This has the following consequences:
Syntax classes do not support inheritance directly, but we can achieve a similar effect with ~or* and attribute declarations for subclasses.
Syntax classes do not come with accessors for their attributes: you have to call syntax-parse every time you want to read an attribute.
At this point, there are still two missing features that are not addressed in the documentation that I have found:
Traversing a syntax tree from child to parent: how can I get a reference to the syntax object enclosing a given syntax object?
Scoping: how can I define specific scoping rules for my language?

Related

Declaring, but not defining F# classes

Is there a way in F# to declare a class, but not define it like in C# or C++ or Java, or pretty much any other language, so that we can avoid the use of the and keyword? I have two fairly big classes that reference eachother, and I don't want to put them both in the same file like this:
type Type1 =
// definitions
and Type2 =
//definitions
F# doesn't make it any easier to have circular references than that. I am bit confused by your statement that C# and Java allow you to "declare but not define" a class; these languages have no concept of forward declaration like C++ does, and the only reason C++ has that is to support its header/translation unit-based compilation model, which C# and Java thankfully don't have.
Anyway. To go further I suggest you read Cyclic dependencies are evil and perhaps factor out a common top-level type for your 2 classes so they don't need to reference each other. F# allows circular references, but try not to work against the language.

Architecture-independent "pure logic" code generation

I don't really know if any common terms exist for what I'm asking about, so I apologize for possible stupid misuse of the terms.
I'm interested, if there are any solutions or at least experiments for creating "pure logic" code, abstract of any architectural patterns, and later generation of architecture-specific code based on it.
For example:
"pure logic" is addition of two integers — a and b
it can be dumped as inline "= a + b"
or as a function "function sum(a,b){return a+b}; =sum(a,b)"
or as a class "class Sum(a, b){...}; s = new Sum(a,b); =s.result();
or maybe this class has no constructor arguments but requires applying them after construction
or it accepts a dictionary with dozen possible keys including 2 we need
or maybe we have DI/IoC container and we call lazy-loaded singleton serevice with 2 injected arguments
and so on
So, basically, it's like we have a mix of global functions and variables, and then we apply generation rules and templates to get a specific coder-friendly result.
Basically, you cannot escape having to define some syntax, and giving it semantics. And that gives you a language. In this language you have types (integers) and an operation (you can add them).
So now this business of generating code is basically your compiler for the language, which uses various high level languages as the back end.
Since some of the languages are perhaps not as "pure" as your high level language, or are semantically distant in various ways, the generated code in some of the back-end dialects might end up looking like dog's breakfast in order to precisely implement the semantics.

How to use CoffeeScript together with Google Closure

Recently I have started to use Google Closure Tools for my javascript development. Until now, I have used to write my code in CoffeeScript, however, the javascript generated by CoffeeScript seems to be incompatible with Google Closure Compiler's advanced mode.
Is there any extension to the CoffeeScript compiler adding Google Closure support?
There are various tools that aiming to make CoffeeScript usable with Google Closure Tools. I will describe three of them:
Bolinfest's CoffeeScript fork
Features:
Fixed function binding, loops, comprehensions, in operator and various other incompatibilities
Fixed classes syntax for Google Closure
Automatic generation of #constructor and #extends annotations
Automatically inserts goog.provide statement for each class declared
Python's like include namespace as alias support translated to goog.require and goog.scope
Drawbacks:
Constructor has to be the very first statement in the class
Cannot use short aliases for classes inside the class (i.e. class My.Long.Named.Car cannot be refered as Car in class definition as pure CoffeeScript allows)
User written JsDoc comments don't get merged with compiler generated ones
Missing provide equivalent for include
No support for type casting, this can be done only by inserting pure javascript code inside backticks "`"
Based on outdated CoffeeScript 1.0
Read more at http://bolinfest.com/coffee/
My CoffeeScript fork
Disclaimer: I am the author of this solution
This solution is inspired by the Bolinfest's work and extends it in these ways:
Constructor can be placed anywhere inside the class
Short aliases for classes work using goog.scope
User written JsDoc comments get merged with compiler generated, user written #constructor and #extends annotations are replaced by generated
Each namespace is provided or included mostly once, namespace, that is provided is never included. You can provide namespace by keyword provide
Support for typecasting using cast<typeToCastTo>(valueToBeCast) syntax
Based on CoffeeScript 1.6
Read more at https://github.com/hleumas/coffee-script/wiki
Steida's Coffee2Closure
Unlike the two solutions above, Steida's Coffee2Closure is postprocessor of javascript code generated by upstream nontweaked CoffeeScript. This approach has a one major advantage, that it will need no or only slight updates with continued development of CoffeeScript and still be actual. However, by the very nature of this approach, some of the features cannot be delivered. Currently it fixes only classes and bindings, loops, in operator and few other incompatibilities. It has no support for automatic annotation generation, type casting or custom keywords.
https://github.com/Steida/coffee2closure

How create dialects with XText

The project I'm working on has a custom file format, with a pre-defined structure. The structure is really simple and generic (and I cannot change it): it is composed by (nested) commands and typed properties.
Using this structure, several dialects have been created. The dialects are an "instantiation" of the generic grammar, and specify the name and the meaning of commands and the expected properties.
I created a model with EMF for one of these dialects, and I would like to reuse XText to easily create a professional text editor and be able to read and write my model into the correct format.
Now I have a choice. On one side, I can directly target the dialect, and mix in the same grammar the concepts from the custom file structure and those from the dialect. On the other side, I can create a grammar describing the file structure, and on top of this I can describe my dialect.
Which way I should follow? I think that the latter is the best one, but how can I create a grammar describing those two layers?
Xtext allows extending existing languages: in the head of the grammar you could specify a parent grammar, that gets inherited.
For an example, see the Domain model example from Xtext 2.0, that extends the XBase language:
grammar org.eclipse.xtext.example.domainmodel.Domainmodel with org.eclipse.xtext.xbase.Xbase
Every grammar element can be replaced by new syntax; new validation can be added, etc. See the following blog posts for further ideas: http://koehnlein.blogspot.com/2011/07/extending-xbase.html
You can use the same approach: create a base language, then extend them for your various dialects.

Why do web development frameworks tend to work around the static features of languages?

I was a little surprised when I started using Lift how heavily it uses reflection (or appears to), it was a little unexpected in a statically-typed functional language. My experience with JSP was similar.
I'm pretty new to web development, so I don't really know how these tools work, but I'm wondering,
What aspects of web development encourage using reflection?
Are there any tools (in statically typed languages) that handle (1) referring to code from a template page (2) object-relational mapping, in a way that does not use reflection?
Please see lift source. It doesn't use reflection for most of the code that I have studied. Almost everything is statically typed. If you are referring to lift views they are processed as Xml nodes, that too is not reflection.
Specifically referring to the <lift:Foo.bar/> issue:
When <lift:Foo.bar/> is encountered in the code, Lift makes a few guesses, how the original name should have been (different naming conventions) and then calls java.lang.Class.forName to get the class. (Relevant code in LiftSession.scala and ClassHelpers.scala.) It will only find classes registered with addToPackages during boot.
Note that it is also possible (and common) to register classes and methods manually. Convention is still that all transformations must be of the form NodeSeq => NodeSeq because that is the only thing which makes sense for an untyped HTML/XHTML output.
So, what you have is Lift‘s internal registry of node transformations on one side, and on the other side the implicit registry of the module. Both types use a simple string lookup to execute a method. I guess it is arguable if one is more reflection based than the other.