Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-11-14 Thread Leandro Facchinetti
Hi WarGrey Gyoudmon Ju,

I’m happy to know that other people are working on the same space. It
seems like we’re taking different approaches and I’d like to see your
project when you release it.

Best.
-- 
Leandro Facchinetti 
https://www.leafac.com
GPG: 0x5925D0683DF3D583

-- 
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.


Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-11-13 Thread WarGrey Gyoudmon Ju
I have been writing my CSS engine.

[sorry this reply might be a little off-topic here]

Long period before, someone in this mailing list asked if their are user
editable configuration file formats that can be used in real world
applications. `info.rkt` might be a choice but it is not designed for the
purpose. Finally I choose the syntax of CSS to achieve the goal because it
is elegant and expressive enough, although I cannot say I like it, it is
the only choice for web front-end guys.

As I have mentioned before, Scribble has already acted as a great and
powerful preprocessor, I think therefore there is no much necessary to
write a CSS front-end with s-exp looking in practice.

At the beginning of the task, I have struggled to work with the syntax
object (yes, it is one of the core essentials that make Racket different),
however it is hard to trace the datatypes of CSS itself (and
case-sensitivity), this is even more painful in Typed Racket. Thus, I think
write my own parser along with datatypes and exn trees is a better choice.

Meanwhile I have finished the engine of CSS syntaxes, grammars and
computation modeling(which is the supplement of what CSS preprocessors do),
and trying to make CSS interact with Racket efficiently. BTW, CSS is not
good architected as a programming language, I am not sure if I would keep
following their specs(I mean the language parts, I don't care the applied
parts), it is becoming too complicated but does not make much sense.

One of the major reasons I started this project is I need an expressive way
to describe (desktop) applications in Racket, maybe in the future I will
release a CSS-based GUI frameworks. Finally I still need to find a more
efficient computation model because this engine is running in the runtime,
after upgrading to Racket 6.7, it's surprisingly slower than before...

On Fri, Oct 28, 2016 at 3:17 AM,  wrote:

> Hi, all.
>
> I am working on an embedded DSL for CSS in Racket. I want to get feedback
> from
> the community regarding the project’s goals and my choice of tools for
> implementing it.
>
>
> LANGUAGE
>
> I want to use Racket to generate CSS for me. I am not interested in a
> “#lang”
> language, but in a DSL that lives embedded in the code. In particular, I
> want
> “quote” and “unquote”. The best I can think of is something like:
>
>   (define main-background-color #'red)
>   (define the-css
> #`([body #:background-color #,main-background-color]))
>   (css-expr->string the-css) ;; => "body{background-color:red;}"
>
> Note the explicit use of syntax objects. They allow for arbitrary “quote”
> and
> “unquote” and preserve source location information, which improves the
> quality
> of error messages. This is the best solution I could find, but I recognize
> it is
> unusual—I cannot name a single other example of embedded DSL in Racket that
> operates with syntax objects directly. Can you think of something better?
>
>
> COMPILER FRONT END
>
> I want good error messages, so I am using “syntax-parse”. I defined the
> concrete
> syntax tree in terms of syntax classes—each production rule on the
> context-free
> grammar for the concrete syntax tree is a “syntax-parse” syntax class. For
> example, the following defines a “stylesheet” as a list of “rules”:
>
>   (define-syntax-class stylesheet
> (pattern (rule:rule ...)))
>
> The abstract syntax tree are typed structs, because I want to benefit from
> the
> correctness guarantees of Typed Racket. For example, the following is a
> struct
> for “stylesheets”:
>
>   (struct stylesheet ([rules : (Listof rule)]) #:transparent)
>
> Then, the parser uses “syntax-parse” with the syntax classes to generate
> the
> typed structs. For example, the following is a parser rule for
> “stylesheets”:
>
>   (define (parse/stylesheet expression)
> (syntax-parse expression
>   [stylesheet:stylesheet
>(extended:stylesheet (map parse/rule
>  (syntax->list #'(stylesheet.rule
> ...]))
>
> With this approach, I get a combination of good parsing error messages and
> typed
> structures to work on the compiler back end. But there is no
> “syntax-parse” in
> Typed Racket, so the parser module must be untyped. The interaction between
> untyped (compiler front end) and typed (compiler back end) modules leads to
> performance penalties. Overall, the whole architecture feels awkward, I
> feel
> like I am fighting the tools. Can you think of a better solution?
>
>
> COMPILER BACK END
>
> I use the typed structures in a module that concatenates strings to form
> CSS. This is the part I am happiest about, but I accept suggestions of more
> principled approaches than carefully constructed calls to “string-append”
> and
> “string-join”.
>
>
> OPINION
>
> My inspiration were the DSLs from http://www.cliki.net/CSS. I could not
> find a
> Racket equivalent. The following is an example of what the language looks
> like,
> recreating the CSS from 

Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-10-29 Thread lfacchi2
> I'd be interested in trying a working prototype. It's hard to evaluate the 
> wisdom of the technical choices without enjoying the benefits of the new 
> interface.

Thank you for your interest. The implementation needs some fixes that I expect 
to finish by the end of the week that starts tomorrow. As soon as I do that, 
I’ll publish a preliminary version and let you know.

-- 
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.


Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-10-29 Thread Matthew Butterick

On Oct 28, 2016, at 8:58 AM, lfacc...@jhu.edu wrote:

> Regarding the syntax of the DSL, I was intentionally vague about it in the
> original post because I wanted to focus on the technical choices I made.

I'd be interested in trying a working prototype. It's hard to evaluate the 
wisdom of the technical choices without enjoying the benefits of the new 
interface.

-- 
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.


Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-10-28 Thread lfacchi2
> I just meant: it's an approach that has worked before. "Better"? That's for
> you to decide.

Alright :)

Regarding the syntax of the DSL, I was intentionally vague about it in the
original post because I wanted to focus on the technical choices I made. But let
me expand on it a bit the means of an example. The following is the source code:

  (define two-column-layout
#`(#:max-width 910px
   [@media (and screen (#:min-width 960px))
   #:max-width 1000px
   [a #:color |#ff0011|]]))

  (css-expr->string
   #`([body
   #:margin-left 10px
   #:padding-left (px 10)
   #:font-family "Equity" "Concourse" Arial
   #:border {#:left (1px solid yellow)
 #:right (2px solid black)}
   #,@two-column-layout]))

The following is the compiled CSS:

  body {
margin-left: 10px;
padding-left: 10px;
font-family: "Equity", "Concourse", Arial;
border-left: 1px solid yellow;
border-right: 2px solid black;
max-width: 910px;
  }

  @media screen and (min-width: 960px) {
body {
  max-width: 1000px;
}

body a {
  color: #ff0011;
}
  }

Note that:

- [Selector “body”, declarations “margin-left” and “padding-left”] The value
  “10px” is expressible in two ways “10px” and “(px 10)”. The former
  representation is better for writing out explicitly (yes, it is a pun on
  “10px” being a symbol in Racket). The latter representation is better when the
  magnitude is a variable, for example, “(px #,gutter)”.

  Similar representation options are available elsewhere in the DSL, for
  example, CSS at rules.

- [Selector “body”, declaration “font-family”] The CSS value delimited by quotes
  is a Racket string, the CSS value not delimited by quotes is a Racket
  symbol. In fact, in the DSL both the values “10px” and “Arial” go through the
  same translation mechanism.

- [Selector “body”, declaration “font-family”] Lists of CSS values do not
  require extra parenthesis in the DSL.

- [Selector “body”, declaration “border”] It is possible to nest
  declarations, a featured borrowed from SASS.

- [Selector “body”, declaration “border”, sub-declarations “left” and “right”] A
  composite CSS value require extra parenthesis in the DSL.

- [Selector “body”, splicing “two-column-layout”] A mixin is the result of an
  “unquote-splicing”. Mixins can have parameters, in the form of a function that
  returns a piece of DSL syntax. This is a feature from SASS that the DSL gets
  for free, because of the Racket embedding. The same is true of SASS variables.

- [Mixin “two-column-layout”, at-rule “@media” and selector “a”] It is possible
  to nest rules. Another feature borrowed from SASS.

- [Mixin “two-column-layout”, selector “a”, declaration “color”] It is possible
  to represent colors with Racket symbols, for example, “|#ff0011|” and
  “\#ff0011”. Unsurprisingly, they go through the same translation mechanism as
  “10px” and “Arial”. This is one of the very few places where I anticipate
  users having to escape characters in symbols.

There are many more tricks in this DSL. This example serves only to give you a
flavor of what I am trying to accomplish while trying to avoid overwhelm you
with the details. These details are still changing, which is the main reason why
I have not published the library yet. Of course, if it interests you, I can give
an overview of the whole language. But that goes beyond my main point for the
moment, which is to figure out if I am using the right tools for the job.

If you have more suggestions, please comment. I am happy to read your feedback.

-- 
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.


Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-10-28 Thread Matthew Butterick
>> 1) Perhaps have a look at the approach used by the `xml` and `html` and 
>> `json`
>> libraries, which is 1) parse data from string, 2) store data in nested
>> structs, 3) generate new string from nested-struct thingy.
> 
> I understand this approach, but I do not understand how it is better than 
> what I
> proposed. Can you please elaborate on that?

I just meant: it's an approach that has worked before. "Better"? That's for you 
to decide.


>> Notationally, how is this an improvement over regular CSS? And if it's not,
>> why not use regular CSS notation, and parse it?
> 
> I believe it is easier to build syntactically correct S-expressions than it is
> to concatenate strings to form syntactically correct CSS. 

Perhaps, but looking at your example again, it seems you intend to represent 
CSS values (on the right-hand side) as symbols, using vertical bars to escape 
things like |#444|?

([body
   {#:margin (40px auto)
#:max-width 650px
#:line-height 1.6
#:font-size 18px
#:color |#444|
#:padding (0 10px)}]
  [h1 h2 h3
  {#:line-height 1.2}])

If so, while 650px can be made into a symbol, 1.6 and 0 cannot (would have to 
be |1.6| and |0|). Also, certain CSS values have double quotes (for instance 
`font-family`) so the "font-family-name" would have to be notated as 
|"font-family-name"|. 

If I misunderstand your notation proposal, I apologize. But I think that users 
should be spared notational inconvenience wherever possible. 


-- 
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.


Re: [racket-users] Request for comments: An embedded DSL for CSS in Racket

2016-10-27 Thread Matthew Butterick
None of the below is meant to deter your voyage of discovery! 
Have fun and hack around!

On Oct 27, 2016, at 12:17 PM, lfacc...@jhu.edu wrote:
> I cannot name a single other example of embedded DSL in Racket that
> operates with syntax objects directly. Can you think of something better?


1) Perhaps have a look at the approach used by the `xml` and `html` and `json` 
libraries, which is 1) parse data from string, 2) store data in nested structs, 
3) generate new string from nested-struct thingy.

2) Maybe a metalanguage that embeds at the reader level, and expands certain 
source strings into S-expressions? See http://docs.racket-lang.org/debug/ for 
an example, where the `#R` prefix in source takes on special meaning.

>  ([body
>{#:margin (40px auto)
> #:max-width 650px
> #:line-height 1.6
> #:font-size 18px
> #:color |#444|
> #:padding (0 10px)}]
>   [h1 h2 h3
>   {#:line-height 1.2}])


Notationally, how is this an improvement over regular CSS? And if it's not, why 
not use regular CSS notation, and parse it?


> Furthermore, I implemented some ideas that I borrowed from other CSS
> preprocessors such as SASS/Less. For example, the language supports nested
> declarations and attributes, appropriately unnesting them when generating the
> CSS output.

IMHO, automating piles of repetitive CSS is the best reason to make a library. 
But I have not upgraded my terrible, horrible, no good, very bad `css-tools` 
library into something suitable for public consumption for two reasons:

1) To write a library that actually parses and generates good CSS, I'd have to 
keep up with the CSS spec, and all the browsers, and that gives me the shivers.

2) Most of what I need is basic computational work — variable substitution, 
math operations, string expansions — and I couldn't figure out what a separate 
library would add that I couldn't already do with simple Racket functions 
embedded in a Pollen source file.



-- 
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.