I am a Racket beginner trying to create my own DSL.
As a long-time user of Xtext and other similar tools in the Eclipse 
ecosystem, I have come to Racket expecting that it would address similar 
concerns.
At the moment, I have mixed feelings: I find the metaprogramming facilities 
in Racket very effective, but at the same time I am struggling to achieve 
tasks that were supported natively by Xtext.

For those who don't know Xtext, here is a summary of how it works:

   - A language project is based on a grammar with attribute annotations.
   - The grammar is converted into a "metamodel", i.e. a set of classes 
   where each grammar rule corresponds to a class.
   - A parser is automatically generated. It can convert some source text 
   into a "model", i.e. a set of instances of the classes from the metamodel.
   - A model can be manipulated using Java APIs. Specialized languages are 
   available to constrain a model, query it, transform it, or generate code 
   using templates.


In Racket, I have started my language project by reproducing what I would 
have done in Xtext:

   - I have created a grammar with bragg
   - I have written a set of syntax classes that play the role of the 
   metamodel
   - Syntax objects play the role of the model, and I can get their 
   attributes with syntax-parse
   - I have written several macros that can generate Racket code in the 
   simplest cases.


However, I miss some facilities that Xtext provides out-of-the-box:

   - Racket syntax classes do not directly support inheritance.
   - Syntax objects are not tied to syntax classes in a class-instance 
   relationship, and I have to use syntax-parse every time I want to read an 
   attribute.
   - Xtext automatically creates child->parent references in the generated 
   AST. In Racket, it seems that I cannot get the parent of a syntax object.
   - Xtext provides a default mechanism for resolving named references, and 
   a scoping API for languages that need specific scoping rules. The AST 
   generated by Xtext is actually an object graph rather than a tree.
   

My main concern is about managing the scopes/lexical contexts in my 
language. I am still browsing the documentation but I have found no library 
or guide that addresses this issue.
The language examples that I have found are either too simple (their 
scoping rules can be easily mapped to those of Racket through macros), or 
use ad-hoc techniques, so that it is difficult to infer a general 
methodology.

So far, I have made two attempts to work around these issues: (1) by 
creating a metamodel-like data structure using Racket structs, and 
transforming syntax objects into struct instances; or (2) using syntax 
objects only and attaching context data to each of them as a syntax 
property.
Both have strengths and weaknesses, and I am still feeling that I am not 
using Racket with the right mindset.

I hope I have made my concerns clear. Maybe I can create a small example to 
further illustrate what I want to do and where I am stuck.
Have you experienced similar concerns in one of your projects?
What design patterns would you recommend ?
Do you know any well-commented real-life example that I could use for 
inspiration?

Thanks in advance for your answers.

Guillaume Savaton

N.B: I have also published a similar question at stackoverflow two weeks 
ago, but it still has no answer:
https://stackoverflow.com/questions/61622912/domain-specific-languages-in-racket-compared-to-model-driven-frameworks-such-as

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/3ee19998-88bf-48f7-8129-c1be9419d4c9%40googlegroups.com.

Reply via email to