

RE: What's so cool about Scheme? (2003) - dorsatum
http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html

======
divs1210
This post had inspired me to write CljOS[1], an Object System in Clojure
mainly because I wanted to write a game engine and had freshly arrived from
the Java world.

It turned out to be extremely straightforward to map objects to closures. Took
<100 lines of documented code!

    
    
        obj.method(& args) => (obj :method & args)
    

I even have a basic 2d sprite-based game engine here[2] (on top of Swing!).

[1] [https://github.com/divs1210/cljos](https://github.com/divs1210/cljos) [2]
[https://github.com/divs1210/bakait](https://github.com/divs1210/bakait)

------
Ono-Sendai
I like the koan. I was working on a closure implementation this weekend. When
wondering how to clean up the captured variables in the closure, I realised
that the most natural way (to me at least) is effectively to store a
'destructor' pointer in the closure, which is very similar to the idea of a
destructors and virtual methods in c++. As such I was enlightened :)

~~~
prakashk
[http://www.c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent](http://www.c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent)

------
discreteevent
Mafribe had an interesting comment here:
[https://news.ycombinator.com/item?id=9506195](https://news.ycombinator.com/item?id=9506195)

Milner showed how to encode the lambda calculus as message passing but
"parallel computation has no 'good' encoding into functional computation". So
message passing is fundamental. Plus in the end there are parts of your system
that you are going to have to model in this way anyway. e.g. IPC. Personally
it helps me psychologically to have a common model for everything even if when
I am e.g. composing functions I'm not really thinking about messages.

~~~
Ono-Sendai
Can you expand on "parallel computation has no 'good' encoding into functional
computation"?

~~~
Tobani
To be fair I think the same is true of procedural languages. Parallel
computation often requires some sort of coordination mechanism, and there are
more failure modes. Functional languages often lend them selves to elegant
mathematic-looking functions and algorithms with many of the dirtier parts
figured out by the compiler.

In order to map algorithms to parallel computing for non-trivially parallel
problems you'll need things like futures, message passing, etc. that gets you
back into specifying the dirtier low-level parts of the algorithm again.

Its more idiomatic in a procedural language because your'e doing all of this
work all the time any way. It is still a hassle, it just doesn't mess with the
"Elegance."

~~~
pdpi
Have you ever looked at Strategies (or the Par monad) in Haskell? To me,
Strategies exemplify some of the stuff you can do with functional languages
that are _really_ hard to achieve elsewhere.

~~~
Tobani
I have seen it before and it is pretty amazing. My comment was mostly in
context of the 2003 message. People are finding more and more clever ways of
handling this all the time. Par(at least monad-par on hackage) seems to have
come around 2011.

Really multi-core machines have only been standard for about 10 years now?
Before then, multi-processor machines filled more niche roles (Servers, HPC,
etc). Now my phone has 4 cores. Parallel computing is becoming more common
because all of the code you write will run on a multi-core system.

I definitely see how writing multi-threaded code in a lisp in 2003 would have
been less savory. Things are definitely better now. Things like Par & Repa can
do some amazing things in Haskell. I'm sure there are more some great packages
out for scheme that are similar . I don't think we're 100% there yet. Who
knows where we'll be in another 10 years?

------
melling
Sometime in the next 5 to 10 years, you'll be able to extend Emacs with
Scheme:

[http://emacswiki.org/emacs/GuileEmacs](http://emacswiki.org/emacs/GuileEmacs)

Hopefully, people will build IDE's comparable to IntelliJ with it.

~~~
davexunit
Not only that, but you'll have an operating system distribution made with
Scheme on which to run it:
[http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/...](http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/emacs.scm#n153)

------
brudgers
Master, I have heard Scheme is a poor man's Javascript.

~~~
pmelendez
Actually it's the other way around. Javascript was created because the author
couldn't use Scheme.

The first comment of
[https://brendaneich.com/tag/history/](https://brendaneich.com/tag/history/)
have this perl:

"As I’ve often said, and as others at Netscape can confirm, I was recruited to
Netscape with the promise of “doing Scheme” in the browser. "

Edit: After a second read, I get now that you were being sarcastic about the
koan. Silly me, I don't get those over the net :)

~~~
martin1975
every time someone gets into how cool functional languages are, for some
reason I always think of this -
[http://databaseanswers.org/data_models/father_of_all_models/...](http://databaseanswers.org/data_models/father_of_all_models/index.htm)

~~~
pmelendez
EAVs are awesome :)

Once upon a time, I didn't know about their existence and didn't have anyone
to point me in that direction, and I converged in pretty much the same thing
when I was asked to implement an automatic forms generator from data. It feels
silly when you just discover something cool that is old news.

~~~
jdmichal
I felt the same way having rediscovered tries writing a word-search algorithm
to cheat at Scrabble. (Hey, don't judge me!) "I wonder what would happen if I
made a binary search tree, except it has a branch for each letter..."

------
copsarebastards
> A closure is an object that supports exactly one method: "apply".

What's more, this enforces _good_ object-orientation: this is a reimagining of
the _single-responsibility principle_ because closures are objects that
literally do one thing.

Closures also enforce the _open-close principle_. Once it's closed it's
closed.

The result is that you get a lot of good OO practices for free.

------
pmelendez
>"If all you want to do is e.g. (map somefun mylist), being able to concisely
define executable "objects" (closures), inline if necessary, is very useful."

It is interesting because this is exactly how C++11 implements lambdas. Still
Scheme's closures are more convenient although C++14 is closing the gap.

~~~
jjtheblunt
I think you have a mistake in what you wrote, but please correct me if I am
wrong.

C++11 lambdas which capture free variables by reference can not be returned
from a function in which the free variables occur, and be expected to work,
because the function's variable (a free variable to the lambda) may no longer
refer to memory allocated for use as the variable.

That's not true for Scheme. Scheme's underlying implementation of lambda and
function call means that true closures are created: if a lambda refers to a
variable which is not local to (or a parameter to) the lambda, then that free
variable belongs to an environment, whose lifetime isn't delimited by popping
a stack and returns, and is therefore still live as long as some closure (or
stack activation frame) refers to it. Return of a lambda with free variables
will work in Scheme, and can fail in C++11.

~~~
pmelendez
You are correct in the sense that Scheme and C++ handle non-local variables
and non-parameters differently (In C++ you can also capture variables by
value, but I don't think there is a proper free variable capture mechanism at
all).

However, that's not what I meant when I wrote that. I was referring this
quote:

"being able to concisely define executable "objects" (closures), inline if
necessary, is very useful"

The fact that you can define inline executable objects is indeed very useful,
and C++ does exactly that: an inline mangled class instantiated bounded to one
variable.

It would be cool to have free variable in C++ in the same way that Scheme
handles it, but I don't think the language would get there anytime soon (Gee,
it is still cumbersome to have recursive lambdas).

------
arca_vorago
For anyone interested in Scheme, may I suggest taking a look at Racket. It has
a very nice IDE, and is growing surprisingly quickly. I admit though there is
something about lisp that I just really like (perhaps I'm addicted to
parentheses).

