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 racket-users+unsubscr...@googlegroups.com.
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