Re: [racket-users] Little language design/implementation guidance

2019-02-06 Thread Neil Van Dyke

Stephen De Gabrielle wrote on 2/6/19 11:25 AM:


Dave Herman recently tweeted


BTW, Dave Herman was a great contributor of Racket (PLT Scheme) 
packages, and has been missed, though I understand the attraction of 
Mozilla at the time.


More generally, can you recommend resources a developer (without a 
background in language design) should refer to if they are building a 
simple templating system, application configuration file, etc. - that 
may grow into a little language?


If I could offer a few quick general guidelines instead:

* Consider whether declarative or imperative is better.  Declarative can 
let you do more static reasoning (even though you might implement by 
syntactic transformation to imperative Racket), and is often the thing 
to do.  However, sometimes imperative is what you want even when 
initially it looks like declarative, especially when you get into the 
next guideline...


* If you ever find yourself writing bits of an imperative language, 
consider just exposing a real language, like Scheme.  Even if you don't 
go for Emacs-like extensibility, there is a long-long history of 
everyone almost always reinventing a half-butted language when they 
would've been in a much better position by taking a real language off 
the shelf.  Perhaps a real language with extensions (like, if you really 
want a prototype object system, go Scheme with a small layered prototype 
object system).


* Consider whether your DSL, in which the the two previous guidelines 
might have you do as a mix of declarative with scattered bits in an 
off-the-shelf real imperative language... is even better as the 
off-the-shelf imperative language at the top level, with a couple really 
well-chosen syntax extensions or procedures.


* Don't be overinfluenced by the above guidelines.  Often, the less we 
know, the easier it is to make blanket generalizations. :)


Sorry I have to run and can't give a more thoughtful brain dump right 
now, but quick anecdotes of my own (criticize oneself first) from 
Racket: two non-public DSLs I made, one for high-performance XML 
transformation, and one for processing some cool and big tabular data, 
both make me cringe -- partly because of how I implemented them 
(`syntax-rules` rather than `syntax-parse` or `syntax-case`), and 
partly, with the latter, a bit less contrived declarative would've been 
more flexible yet looked about the same.


Another DSL, I might be the only one who likes it, but I really wanted 
to make it as part of rethinking Web development a bit, and you can see 
that I used the DSL only where I got benefit (moving some trivial 
computation and checking to syntax expansion time), and I expressly (see 
"By design...") avoided doing things like inventing my own declarative 
iterators, or reinventing a half-butted Scheme. There are some static 
checking things that I can't do this way (e.g., full HTML5 validation), 
but it seemed a good tradeoff, and I could always *layer* that crazy 
static checking later, if I really wanted to do things like make 
declarative language for mapping database results.  One DSL decision I 
made was to sacrifice the S-expression representation as data accessible 
to the programmer, in favor of emphasizing writing the byte stream as 
you go (yes, I've seen this get massive, in practice), and also using 
normal Racket ports, so that it could be combined with other Racket 
ways, for flexibility (again, not reinventing or restricting the 
language when it didn't benefit me). 
https://www.neilvandyke.org/racket/html-template/


BTW, related, a few places in the list archives, I talk about an 
alternative to configuration files, like thinking of the application 
instead as a framework, and the configuration file is actually an 
instantiation of the framework.  And some simple practical startup 
mechanics for doing that (e.g., executable that falls back to the 
default instantiation if no config file available, and maybe writes a 
"config file").  You don't have to do all that way, but you see how this 
could be powerful.  If you do it right, in a lightweight (in the 
developer burden sense) way, and, together with other factors, you could 
also encourage an ecosystem and culture of very casual extension of your 
application (like was part of what made Emacs so loved and powerful).


--
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.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Little language design/implementation guidance

2019-02-06 Thread Stephen De Gabrielle

Hi,

Dave Herman recently tweeted[1] that consulting a PL specialist was a good idea 
for little languages to avoid common foundational mistakes, specifically 
mentioning templating systems and configuration files.

So when designing(or evolving) a little language:
what beginners mistakes should you avoid? (some in the subsequent tweets I’ve 
copied below)
When should you consult a PL specialist? (and how do you identify a PL 
specialist?)
More generally, can you recommend resources a developer (without a background 
in language design) should refer to if they are building a simple templating 
system, application configuration file, etc. - that may grow into a little 
language?

Kind regards,

Stephen 

PS please forgive me if this is the wrong list for this question.


[1] https://twitter.com/littlecalculist/status/1092160821944213504?s=21

> It's frustrating that PL is considered such a specialization that PL people 
> only get brought in for big languages. There are vastly more little languages 
> everywhere. People often don't realize their little language needs better 
> underpinnings until very late, if at all.



Common mistakes tweeted by Dave Herman in subsequent thread;

> Scenario-solving: language design at its heart is figuring out what your 
> composable primitives are. Too often, people think of use cases one scenario 
> at a time and just sort of glue them together w/o generalizing and 
> simplifying.


> Reinventing lexical scope: many systems start by using string concatenation 
> as their core model, instead of composing modules with a rationalized notion 
> of scope. Another common scoping mistake is exposing variables as mutating a 
> global scope.


> Lack of abstraction mechanisms: when you don't think of yourself as designing 
> a language, you put up with boilerplate and copy-pasta.


> Lack of strategy for general-purpose logic: ultimately most DSLs end up 
> needing general-purpose programming language—often it's in a minority of 
> cases but when you need it you really need it. The best ones IMO have clear 
> extension points and contracts with a general-purpose PL.
> 


-- 
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.
For more options, visit https://groups.google.com/d/optout.