
A love letter to s7 Scheme - alekq
http://carloscarrasco.com/a-love-letter-to-s7-scheme.html
======
jpt4
(symbol-access) reminds me of the property list feature [0] of Chez Scheme and
other implementations (presumably R7RS as well), which allow arbitrary data to
be associated with any symbol "in the background" (as I visualize it). I've
pondered using tags stored in the prop-list as a kind of poor man's run-time
type system for polymorphic functions to check before performing the
appropriate operation, but chose to use custom record types, which generate
custom (is-type-x?) predicates, instead.

For the more knowledgeable, is (symbol-access) a complete general purpose
primitive for reactive programming, like (delay) and (force) are for laziness?

[0]
[http://www.scheme.com/csug8/objects.html](http://www.scheme.com/csug8/objects.html)

~~~
junke
Symbol property lists (like in CL:
[http://www.lispworks.com/documentation/lw70/CLHS/Body/t_symb...](http://www.lispworks.com/documentation/lw70/CLHS/Body/t_symbol.htm))
are useful, but you have to take care about the difference between symbols and
variables. The same symbol in a different environment can represent a variable
of a different type. Apparently symbol-access manipulates the current lexical
environment, ie. a specific binding of particular symbol.

> For the more knowledgeable, is (symbol-access) a complete general purpose
> primitive for reactive programming, like (delay) and (force) are for
> laziness?

As far as I know, yes, but careful about mutual references: if updating x when
y changes triggers another update of y from x, you might never terminate.

------
dleslie
Many of the nice features mentioned are R6RS things, or extensions of that
line. However, some R5RS schemes have extensions to support this behaviour.
I'll use my favourite, Chicken, as an example:

* Applicative Syntax for Data Structures[0]

* First-class Environments[1]

0: [http://wiki.call-cc.org/eggref/4/callable-data-
structures](http://wiki.call-cc.org/eggref/4/callable-data-structures)

1: [http://wiki.call-cc.org/eggref/4/environments](http://wiki.call-
cc.org/eggref/4/environments)

~~~
kazinator
I included some first-class environment manipulation in TXR Lisp. It's an
obvious feature. They are already first-class in the internals; you just have
to expose the API:

The API is very small, though:

[http://www.nongnu.org/txr/txr-
manpage.html#N-01144687](http://www.nongnu.org/txr/txr-
manpage.html#N-01144687)

Just make-env, env-vbind and env-fbind.

The intent is to be able to prepare an object which can be passed as the
optional environment parameter to eval and its ilk.

First class environments of this type are not incredibly useful; they
encourage the developer to create a more sophisticated eval hairball.

(First class environments in macro-expansion are incredibly useful, on the
other hand; but that is at code walking time, not run-time!)

Note that no provision is made to allow a form access the _current_
environment as a first class object. That is deliberate; by doing that, you
turn the language into NewLisp or Tcl, slamming the door on future efficient
compilation. Code should be written based on the assumption that _there is no
current environment, as an object_. The compiler decides how the abstract
environment maps to the machine code, and it's usually not via some object
that neatly associates symbols with value places.

It would literally be a five minute hack to provide a special operator form
like `(my-env)` that just yields the environment object when evaluated, but
the damage these five minutes would inflict on the language would be
inestimable.

~~~
qwertyuiop924
Agreed, but some of those features are quite useful. Allowing for tcl/lua-
style "upvars" means that a whole class of macros no longer have to be
written. I often wish it were more possible to extend the environment of an
existing closure, as this would allow for real dynamic variables (as opposed
to the hack that Scheme has now, which is actually terrible).

------
_delirium
It's interesting to see people not doing computer music using s7. It was
written at CCRMA [1] as their extension language of choice for various tools
like Common Music [2], much like Guile was written to be the GNU project's
extension language of choice. There's nothing really music-specific about it,
I just haven't seen uptake outside that community before.

[1] [https://ccrma.stanford.edu/](https://ccrma.stanford.edu/)

[2] [http://commonmusic.sourceforge.net/](http://commonmusic.sourceforge.net/)

~~~
pmoriarty
I've used Common Music to make some algorithmic compositions. It was a lot of
fun.

Unfortunately, I can't get the latest version of CM to compile, and CM has
been moving towards a GUI version, and away from teh command line, which I
found kind of sad.

Still, CM is my preferred algorithmic composition environment, by far. It's a
shame it's not better known.

------
shakna
First class environments is one of my favourite features of Scheme, and I
still don't understand why I've never seen it elsewhere.

However, it does make Scheme uniquely suitable for an embedded language, or
turning Scheme into a host language.

This [0] sort of demonstrates the magic that first class environments add, and
how they make re-writing a language, whilst its running, a breeze.

It gives you safety in eval, and means that the kind of methods that other
languages need to use to create, say a Flask-like API, are just plain
overkill.

[0]
[http://www.cs.rpi.edu/academics/courses/fall00/ai/scheme/ref...](http://www.cs.rpi.edu/academics/courses/fall00/ai/scheme/reference/schintro-v14/schintro_123.html)

~~~
kazinator
> _and I still don 't understand why I've never seen it elsewhere._

Because reflecting upon environments at run-time is a silly eval hack that
defies compilation.

An environment that is exposed to the code at run-time cannot be efficiently
treated by the compiler.

Lisp compilers throw away lexical environments when the dust settles.

An environment isn't something that is there, but you are blocked from
accessing it by the evil Lisp implementation that doesn't provide an API. It
in fact _isn 't_ there, except when the code is being inefficiently
interpreted.

~~~
shakna
It _can_ be ineffecient to generate and pass environments around, but it
doesn't _have_ to be, nor does it have to be a hack.

Compiling with continuations [0] gives you a very efficient output, and a
lexical environment that is easily modified, and intuitive to exist. Combine
that with Cheney on the MTA, and first class environments are no more costly
than a lambda.

It is also possible to compile the initial environment [1], which makes it
simpler to JIT any functions later linked to the structure.

I'm not sure why you think a compiler has to throw away the environment, its
certainly not what MIT Scheme does, as environments are special forms that
persist as you go down and up the stack. [2]

[0] [http://matt.might.net/articles/cps-
conversion/](http://matt.might.net/articles/cps-conversion/)

[1]
[https://github.com/gambit/gambit/commit/09284455ae7c7e8dff4a...](https://github.com/gambit/gambit/commit/09284455ae7c7e8dff4a71b8a60e5315e04fbe61)

[2] [https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-
html/...](https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-
html/scheme_14.html)

------
qwertyuiop924
Symbol-functions, as much as I sometimes wish for them, aren't a great idea:
They give macro-writers even less guarantees. However, wrapping datastructures
in functions definitely is.

Also, first-class environments are amazing, and I wish my scheme-of-choice
(CHICKEN) had them: It used to, but the code doesn't work with the new
compiler, and the long-promised replacement hasn't been written yet.

Maybe I should just dive in and write it myself...

------
mvidal01
What other games use Scheme as an extension language? I know of Little Wing
Pinball. I dont know if end user code can be used in it though.

~~~
marktangotango
Naughty Dog famously used a lisp in their games[1]. Those guys post here
sometimes, I don't recall they're usernames though.

[1]
[https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp](https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp)

~~~
p_l
Naughty Dog still does so, just usually for game logic, tooling etc. with core
engine in C++ (reasons are afaik language-unrelated). Some presentations about
uncharted and other games they did recently describe how they use it

