[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: s-expressions, c, css and javascript
From: |
tantalum |
Subject: |
Re: s-expressions, c, css and javascript |
Date: |
Thu, 22 Dec 2016 17:57:54 +0000 |
User-agent: |
Posteo Webmail |
Do you think deeper integration/compliance with scheme land would be
best?
i think a source-to-source compiler like sc/sescript, that simplifies
the use of another language, and scheme to machine code compilation are
the two best ways for more run-time efficient code.
otherwise there is likely overhead from mapping scheme semantics to a
different language. i have seen programs that compile from scheme to
others, including javascript, that add significant amounts of extra
library code that has to be loaded to emulate basic scheme features in
the target environment.
for sc or sescript i could imagine an extension that implements more
advanced code generation, like syntax-case macros and a module system,
maybe as a separate project named "scx" or so. there would probably be
no performance loss compared to using the lower-level language.
Did you try biwascheme?
yes :) i tried biwascheme. it is a nice project.
so far i have not really used it because of the inherent overhead and
because i did not want to make code dependent on an implementation more
complex than a transpiler.
somebody could make a browser plugin that integrates a scheme compiler,
as an alternative. this could tendentially be as fast as browser-native
javascript engines. javascript code/libraries might not run on it and be
incompatible though. afaik guile can share the same environment between
different languages.
Do you have examples or documentation?
the homepage gives only a brief overview of plcss
(http://sph.mn/content/e93). i am going to try to describe a few ways of
using it (see the "eval" part in particular) and also attach some
example code that is in current use at the end. i hope that helps.
# to use plcss in scheme code files
(import (sph lang plcss)) or (use-modules (sph lang plcss)) loads
"plcss->css" and all other related bindings.
# from lists to ports with "plcss->css"
(plcss->css
(quote ((".content" width "3px")))
(current-output-port))
this writes the result css string to standard output. the first argument
is a list of rules, which are lists but can also be plain strings.
the above is of course pretty much the same as
(plcss->css
(list (list ".content" (quote width) "3px"))
(current-output-port))
# from lists to strings with "plcss->css-string"
for example used in a procedure:
(define (create-css)
(plcss->css-string (quote ((".content" width "3px")))))
(create-css)
# like quasiquote with "css"
note the (unquote a) in the second to last line.
(define a "4px")
(define css-result-string
(css
(".content"
(".mtime" position absolute right 0 top 0 color "hsl(0,0%,67%)"
text-align right)
(".signature" border "1px solid hsl(0,0%,70%)"
display "inline-block" border-radius (unquote a) padding
"0.75rem" color "hsl(0,0%,10%)"))
(".middle .content" padding 0)))
nested expressions always come after properties btw. so ("a" font-weight
"bold" ("img" ...)) would be valid, but ("a" ("img" ...) font-weight
"bold") would not. it makes things more consistent and easier to read.
# read from files
usually i write plcss in separate files and then read the files as
scheme datums with the standard "read" procedure. the file content
supports the full scheme syntax including scheme comments and all, which
i find really nice.
so for example a file named "source.plcss" could contain the following
(".content" width "3px")
(".mtime" position absolute right 0 top 0 color "hsl(0,0%,67%)"
text-align right)
an example for reading file content as scheme datums:
(call-with-input-file "source.plcss"
(lambda (port)
(let loop ((e (read port))) (if (eof-object? e) (list) (cons e (loop
(read port)))))))
should afaik nicely work with guile.
## simple command-line plcss compiler
these lines in a text file that is executable and run from a shell
command-line make a basic plcss file compiler
#!/usr/bin/guile
!#
(import (sph lang plcss))
(plcss->css
(let loop ((e (read (current-input-port))))
(if (eof-object? e) (list) (cons e (loop (read
(current-input-port))))))
(current-output-port))
example use:
cat source.plcss | ./file-with-content-shown-above
# eval
we can take all this further and build something like a template
processor with eval.
## with implicit quasiquotation
(import (rnrs eval))
(define plcss-data (eval (list (q quasiquote)
plcss-data-list-read-from-file) (current-module)))
(plcss->css plcss-data (current-output-port))
now the plcss code inside files can contain (unquote) and
(unquote-splicing) expressions and insert and access variables from the
current module when it is evaluated with eval, or any other custom
module that is passed as the second argument to eval.
(environment (my module a) (another module)) can create
environment/module objects, and guiles module reflection procedures are
also useful. i am not sure how great these kinds of environment objects
are from a programming language theory standpoint, but they can be
useful.
## even further - implicit lambda
(eval (quasiquote (lambda (content) (unquote (list (q quasiquote)
plcss-data-list-read-from-file)))) (current-module))
this is what (sph lang template) does: it gets s-expressions using
scheme read, then builds a list with the symbol quasiquote at the
beginning and puts that in a list that looks like a lambda expression,
then evaluates this and it returns and actual procedure that we can call
with arguments that can be used with (unquote) inside the file to create
css. and another nice thing: it works just the same with sc, sescript
and sxml.
to make this clearer, say we have a file with the following content
("body" background-color "#000"
(".container" width "3px"))
we can now write
("body" background-color (unquote content)
(".container" width "3px"))
in the file, and after having created the procedure with eval,
(our-procedure "green")
can be called wherever we like to give us a customised css (or xhtml, or
javascript) string.
# plcss example files
& is for concatenation of nested selectors instead of separating them
with a space. for example ("tr" (".a")) would create "tr .a {}" but
("tr" ("&.a")) creates "tr.a".
$ cat table.plcss
(".ascii" text-align left
display inline
("&:not(:first-of-type)" margin-left "2rem")
("td, th" padding-left "0.5rem" padding-right "0.5rem")
("th" font-weight bold) ("td" font-style italic)
("td:first-child" font-weight bold font-style normal)
("tr" border-width "1px"
border-color "gray" border-bottom-style solid ("&:first-child"
border-top-style solid)))
$ cat start.plcss
((".modification" ".alternatives") ("input" width "6rem"
("&[type=number]" width "3rem"))
(".preview .area" width "75px" height "75px"))
(".modification" ("> .control" display inline-block
("&:not(:first-child)" margin-left "1rem")))
(".preview .area" transition "background-color 0.25s ease")
((".conversion" ".modification > .preview") (".preview .area" width
"503px" height "75px"))
(".alternatives" ("> *" display inline-block ("&:not(:first-child)"
margin-left "1rem"))
#;((".complement" ".greyscale") display inline-block)
(".greyscale" margin-left "1rem") (".hbox > *" ("&:not(:first-child)"
margin-left "1rem")))
("#text_display_area" width "15rem" height "35rem")
(".conversion" ("label" display "inline-block" ("&:not(:first-child)"
margin-left "1rem"))
("input" width "9rem"))
("@media (min-width: 140rem)"
(".middle" column-count 2 -moz-columns 2 columns 2 -moz-column-count 2
-webkit-column-count 2))
---
On 2016-12-21 19:32, Amirouche Boubekki wrote:
On 2016-12-07 23:43, tantalum wrote:
hi
last time i mentioned it was a few years ago, and i just thought i let
you know that sph-sc got some interesting updates recently, and plcss
and sescript (as well as sph-lib) are still actively maintained.
I started playing with Guile because of your mail :)
"sescript" is very similar to sc, it is like sc but for javascript or
ecmascript. javascript on its own already feels more like scheme than
c because of its use of anonymous first-class functions. sescript adds
features like "let", implicit return and even an r6rs library form.
sometimes i was able to copy code between scheme and sescript without
change because it is so similar.
Do you think deeper integration/compliance with scheme land would be
best? Did you try biwascheme?
"plcss" creates css. it is written in less than 90 lines of scheme
(but imports a few bindings) and can offer most features of or more
than tools like sass and lesscss.
That look like something I could put to use. Do you have examples or
documentation?
for details and examples, here links to the project homepages:
sc: http://sph.mn/content/3d3
sescript: http://sph.mn/content/413
plcss: http://sph.mn/content/e93
while we are at it, i recently made a time and calendar calculation
library from scratch (which was pretty difficult, if anyone wants to
check out how this can be done, see the "time" libraries in sph-lib
(http://files.sph.mn/sourcecode/sph-lib/)) and this went into the
calendar on http://ytilitu.xyz/ , which runs on guile.
Looks cool and useful :)