Re: The dark corners of rep
- From: Christopher Roy Bratusek <zanghar freenet de>
- To: General discussion about sawfish wm <sawfish-list gnome org>
- Subject: Re: The dark corners of rep
- Date: Wed, 13 May 2009 06:24:23 +0200
Am Dienstag, den 12.05.2009, 20:56 -0400 schrieb Eli Barzilay:
> On May 12, Christopher Roy Bratusek wrote:
> > Am Dienstag, den 12.05.2009, 13:58 +0900 schrieb Teika Kazura:
> > > One more bad point is there: not for dev, but that users of
> > > Sawfish have to learn Rep.
> >
> > ... if we switch they'll have to learn <xyz> instead of rep, that
> > not a valid point against rep in favour of lisp/scheme.
>
I meant the learning thing in general, and we were talking about users,
not developers.
... of course there's not much to read about rep. But well librep is
open for development, current version in trunk is 0.90, theoretically
librep can be completely rewritten to be the best solution, if that is
desired. But that seems not to be the case.
(some) THINGS THAT THE REPLACEMENT FOR REP NEEDS TO HAVE:
- who rewrites the whole(!) lisp part? (I don't have the time, currently
fully rewriting a project of mine and don't want to do that again ^_^;)
- replacement needs real gtk support (replacements with
gtk-widget-abstraction like oo.o or ff will be rejected!)
- replacement needs gtkbuilder support (we want the sawfish-themer back)
- replacement needs gtk/gnome 3 support not too long after they have
been released
PRO REP:
- ours and if we need to make changes inside we don't rely on other devs
CONTRA REP:
- see below
> It is a valid point against rep (are there any books about rep? anyone
> uses it outside of sawfish?). Even more: it is a *major* point
> against it. Scheme and Lisp systems can be very flexible, and it's
> easy to come up with a language that is scheme- or lisp-like (just
> using sexpr syntax for that is enough). If the semantics of the
> language is far enough from scheme or lisp, then you still have a
> different language, despite the superficial resemblance.
>
> The thing with rep is that it's somewhere between Scheme, Lisp, and
> ELisp. This is a very bad thing -- more than just the lack of books
> to learn it (I'm sure that most people just read about scheme or lisp
> or elisp, but they're all different languages from rep).
>
> Here's a list of some obvious problems I ran into. I don't know if
> there are many people here who use Scheme or Lisp, but those who do
> will probably be horrified by these (and if they tried to program
> sawfish, they probably know about some of them).
>
> * No `set!'; uses `setq' and it can be used with new variables
>
> user> (set! x 1)
> *** Unbound variable: set!
> user> (setq x 1)
> 1
>
> This is like Lisp and ELisp. There's even `set', which comes from
> the dark past of Lisp:
>
> user> (setq x 'y)
> y
> user> (set x 123)
> 123
> user> y
> 123
>
> There is no `setf', so it looks like it'll be close to ELisp.
>
> * However, these variables are lexically scoped -- not dynamically
> scoped as in Lisp/ELisp:
>
> user> (setq x 123)
> 123
> user> (define (ret-x) x)
> user> (let ((x 999)) (ret-x))
> 123
>
> This is actually a very important point -- rep is lexically scoped
> (which is good), which means that it has closures, and `lambda' is
> not just a self-evaluating form:
>
> user> (funcall '(lambda () 1))
> *** Invalid function: (lambda () 1)
> ;; this *does* work in elisp, and in some popular lisps too
>
> * Actually this is another confusing point: rep has `funcall', but it
> is not necessary since it has a single namespace. In fact, the
> implementation could just as well be in rep instead of in C:
>
> (define (funcall f . xs) (apply f xs))
>
> which is what the C code is doing.
>
> * Also, rep has `defun' and `defvar', but the distinction between them
> in lisps is setting the "function value" or the "symbol value" --
> this is not something that rep has, so `defun' is mostly syntactic
> sugar for `define' with function.
>
> * `defvar', however, still makes the defined name special (dynamically
> scoped):
>
> user> (defvar x 1)
> x
> user> (define (ret-x) x)
> user> (let ((x 123)) (ret-x))
> 123
>
> This has the usual possible catastrophe:
>
> user> (define (foo x) (ret-x))
> user> (foo 5)
> 5
>
> which Common Lisp users solve by always naming special variables
> with *stars* (and some compilers will warn you if not).
>
> * Even worse, `defvar' does its magic in a way that shadows possible
> later definitions:
>
> user> (defvar x 123)
> x
> user> (define x 1234)
> user> x
> 123
> user> (defun x () 12345)
> user> (x)
> *** Invalid function: 123
>
> (This behavior is unique to rep, AFAICT.)
>
> * It has Common Lisp's idiom of using `defun' inside a `let' to get a
> local binding:
>
> user> (let ((count 0)) (defun count! () (setq count (1+ count))))
> user> (list (count!) (count!) (count!))
> (1 2 3)
>
> but -- it also does the same with `define':
>
> user> (let ((count 0)) (define (count!) (setq count (1+ count))))
> user> (list (count!) (count!) (count!))
> (1 2 3)
>
> which is of course not needed, because you can do the usual thing in
> scheme:
>
> (define count! (let ((count 0)) (lambda () (setq count (1+ count)))))
>
> * But -- yes, there's another "but" -- it also does what Common Lisp
> is doing with multiple `defun's, and it will happily do so with
> `define':
>
> user> (let ((count 0))
> (define (count!) (setq count (1+ count)))
> (define (reset!) (setq count 0)))
> user> (list (count!) (count!) (reset!) (count!))
> (1 2 0 1)
>
> which happens because `define' is actually more like Lisp's `defvar'
> and `defun' in that it has a global effect (which is a surprising
> contradiction for a lexically scoped, single-namespace language):
>
> user> (let ((x 1)) (define xx (1+ x)) xx)
> 2
> user> xx
> 2
>
> *BUT* -- `define' *is* defining something local if it's in a
> function's scope:
>
> user> (define (foo x) (define xx (1+ x)) xx)
> user> (foo 5)
> 6
> user> xx
> *** Unbound variable: xx
>
> which makes rep more like JavaScript. Still `defvar' does have a
> global effect:
>
> user> (define (foo x) (defvar xx (1+ x)) xx)
> user> (foo 1)
> 2
> user> xx
> 2
>
> which is just like `setq':
>
> user> (define (foo x) (setq xx (1+ x)) xx)
> user> (foo 1)
> 2
> user> xx
> 2
>
> and let's not forget `set' -- unlike in modern Lisps (which are
> lexically scoped except for `defvar'ed bindings), `set' behaves as
> it does in a dynamically scoped language:
>
> user> (define (foo x) (define xx 'x) (set xx 33) x)
> user> (foo 1)
> 33
>
> but `eval' behaves as a lexically scoped language:
>
> user> (define x 3)
> user> (let ((x 999)) (eval 'x))
> 3
>
> * There's also a bunch of elisp-isms that make the language appear
> more like elisp:
>
> - `concat', not `string-append'
> - `mapcar', not `map'
> - `?x' syntax for characters, not `#\x'
> - `defmacro' macros, no hygiene; `defmacro' syntax as in lisp
> (separate argument list)
> - "first class" macros (yet another can of worms) that can be passed
> around like values (which even elisp can't use directly).
> - `print' and `princ', not `write' and `display' (and `write' is
> bound to something different)
> - `integerp', `stringp', `string=' , etc -- not `integer?',
> `string?', `string=?', etc
> - doc strings
> - elisp-like vectors (bracket syntax, `length', `aref'), unlike
> scheme or common lisp
> - lisp/elisp-like backquotes (try ``,a and also `backquote' vs
> `quasiquote')
>
> and some scheme-isms:
>
> - `number->string', not `number-to-string'
> - `call/cc'
> - exact rationals
>
> and some of its own features (regexps, threads, IO, modules, and
> more).
>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]