Re: Symbol clashes: how to avoid them. Part 2



How often does this problem really arise?
I faced the problem when tried to add iterate to symbolicweb. Real-
world task, not a library, not a DSL experiment. I like iterate as it
is more lispy then loop. It is _much_ better than loop. First of all,
loop is not extensible (do you remember we are coding in an extensible
language!). But it is convinient that loop uses symbols as keywords,
so it does not matter which "for" to use with loop. It is not the case
with iterate - it is truly lispy sublanguage and it obeys all lisp
rules. Lisp says DSL should rely upon its own symbols and don't mess
everything around.

So, (to simplify things) iterate requires "for" to be from the same
package as the iteration variable. But... some other library exports
"for" too. So: you have no internal "for" in the current package. And
you need write something like

(iter
(for that-lib:i in '(1 2 3))
(collect that-lib:i))

that is super ugly!
There is a synonym mechanism in iterate. But there is other problem:
that-lib exports "collect" too, and collect is a macro. Synonyms
mechanism has lower priority than a macro mechanism. So... I define
synonyms for "for" and "collect" and write (moderately ugly)

(iter
(ifor i in '(1 2 3))
(icollect i))

Ok. We solved it, hurray!

But... All this code is not a final package. It is a library too.

How do I'll use this in my final code?

I'll use

(defpackage :mylib-user (:use :hunchentoot :cl-who :mylib :that-
lib :iterate)
shadow all clashing symbols that we shadowed in my-lib...
)
redefine all synonyms...

final defpackage looks very funny... In fact I need not only to copy
defpackage symbolicweb, I need to do it again at again as symbolicweb
itself changes. Cool...

Yes, there IS an alternative. Don't use anything, prefix everything.

(iter:iter
(ifor i in mylist)
(cl-who:with-html-output-to-string (:esc (that-lib:that-fun i))
(ps:ps-inline (alert "ouch"))))

etc. Well. Where did we started? We simply wanted to generate html+js
in a convinient way. What we get in fact?

A. Difficult to start. Defpackage is hard to write
B. Difficult to use. We should remember from which package which
symbol comes from. Should final use care that our project consists of
several packages? It is a special sublanguage for generating html+js
and rendering it from http server, so we need all frequently used
symbols in one package. We want to use completion for entering
symbols, not an apropos for finding them and then entering. Even
worse, If I'll enter unexported symbol w/o prefix by an omission, it
gets interned to my package, but remains unbound. So I'll be very
surprised at compile time. And then I will need to investigate with
apropos which symbol is wrong, then unintern it. All this is very hard
for serios DSLs with hundreds of symbols.

C. When we want to improve something we have to learn this.
D. When library changes, we get unexpected symbol clashes.

Ok, friendly lispers explained me already that I am dumb and that lisp
is perfect... Hmm... After using lisp for nine years, I started to
think about learning PHP...

All this disappointment stems from experience with real system called
Symbolicweb. I took a small part in its development (testing, etc).
Someday I decided that it would be fine to have examples running not
in a :symbolicweb package. In fact, final user will not work
in :symbolicweb package. He would use it. Moreover, in context of web
development, Symbolicweb can itself be considered as a library. So, if
we give an example we would give a defpackage example too. I get much
trouble with it.

For me it looks like that lisp is not scalable enough in the sence of
using many different libraries in one project. Simplest and very
evident solution of importing just all non-clashing symbols is
rejected by any and every right lisper.

Of course, it seems that iterate is not designed will... It tried to
be lispy so hard, so it fell into all lispy traps... It would better
use symbols as keywords, or just allow keywords to be used, like this:
(iter
(:for i :from 1 :to 10)
(:collect i))
.



Relevant Pages

  • Re: is it ok to (setf (get :const :prop) :val)?
    ... I first faced to this problem while playing to Symbolicweb. ... package was previously like this: ... ain't using iterate still. ... substitute for loop. ...
    (comp.lang.lisp)
  • Re: is it ok to (setf (get :const :prop) :val)?
    ... I first faced to this problem while playing to Symbolicweb. ... package was previously like this: ... ain't using iterate still. ... substitute for loop. ...
    (comp.lang.lisp)
  • Re: is it ok to (setf (get :const :prop) :val)?
    ... I first faced to this problem while playing to Symbolicweb. ... package was previously like this: ... ain't using iterate still. ... substitute for loop. ...
    (comp.lang.lisp)
  • Re: is it ok to (setf (get :const :prop) :val)?
    ... I first faced to this problem while playing to Symbolicweb. ... package was previously like this: ... ain't using iterate still. ... substitute for loop. ...
    (comp.lang.lisp)
  • Re: Multivalue tail recursion?
    ... Well, iterate just plain looks nicer/lispier than loop, and ... functions operating on series/vectors/streams of data elements are much ... expressions, because they are typically implemented very inefficiently. ...
    (comp.lang.lisp)