From: Jan Moringen <jan.moringen@uni-bielefeld.de>
To: rms@gnu.org
Cc: emacs-devel@gnu.org
Subject: Re: Potential copyright problem in EIEIO improvement
Date: Sun, 03 Jan 2010 19:52:07 +0100 [thread overview]
Message-ID: <3504_1262544732_ZZg0O73~B6ki9.00_1262544727.3761.1636.camel@localhost.localdomain> (raw)
In-Reply-To: <E1NR6A4-00027O-SB@fencepost.gnu.org>
On Sat, 2010-01-02 at 10:45 -0500, Richard Stallman wrote:
> Please show the whole of the Dylan code you want to adapt.
> To judge this issue
> we need to see the facts.
Sure.
The following piece of code is from the paper "A Monotonic Superclass
Linearization for Dylan". It is labeled "Appendix A: Implementation of
the Dylan Linearization" there. This code implements the Dylan
linearization *without* the improvement presented in the paper.
=== Begin Appendix A ===
define constant compute-class-linearization =
method (c :: <class>) => (cpl :: <list>)
local method merge-lists (reversed-partial-result :: <list>,
remaining-inputs :: <sequence>)
if (every?(empty?, remaining-inputs))
reverse!(reversed-partial-result)
else
// start of selection rule
local method candidate (c :: <class>)
// returns c if it can go in the result now, otherwise false
local method head? (l :: <list>)
c == head(l)
end method head?,
method tail? (l :: <list>)
member?(c, tail(l))
end method tail?;
any?(head?, remaining-inputs)
& ~any?(tail?, remaining-inputs)
& c
end method candidate,
method candidate-direct-superclass (c :: <class>)
any?(candidate, direct-superclasses(c))
end method candidate-direct-superclass;
let next = any?(candidate-direct-superclass,
reversed-partial-result);
// end of selection rule
if (next)
local method remove-next (l :: <list>)
if (head(l) == next) tail(l) else l end
end method remove-next;
merge-lists(pair(next, reversed-partial-result),
map(remove-next, remaining-inputs))
else
error("Inconsistent precedence graph");
end if
end if
end method merge-lists;
let c-direct-superclasses = direct-superclasses(c);
local method cpl-list (c)
as(<list>, all-superclasses(c))
end method cpl-list;
merge-lists(list(c),
concatenate(map(cpl-list, c-direct-superclasses),
list(as(<list>, c-direct-superclasses))));
end method; // compute-class-linearization
=== End Appendix A ===
The code from Appendix A above is available (in a very similar form)
under GPL for example in Open Dylan:
=== Begin sources/dylan/class-dynamic.dylan ===
define function compute-implementation-class-precedence-list
(c :: <implementation-class>, u :: <subjunctive-class-universe>)
=> cpl :: <list>;
let convert = scu-converter(u);
local method merge-lists (partial-cpl :: <list>, remaining-lists :: <list>)
// The partial-cpl is in reverse order at this point.
if (every?(empty?, remaining-lists))
reverse!(partial-cpl)
else
local
method unconstrained-class (s)
let s :: <implementation-class> = scu-entry(s, u);
local
method s-in-and-unconstrained-in? (l :: <list>)
head(l) == s
end method,
method s-unconstrained-in? (l :: <list>)
head(l) == s | ~member?(s, tail(l))
end method;
any?(s-in-and-unconstrained-in?, remaining-lists)
& every?(s-unconstrained-in?, remaining-lists)
& s
end method,
method unconstrained-class-in-superclasses (c :: <implementation-class>)
any?(unconstrained-class, direct-superclasses(c))
end method;
let next = any?(unconstrained-class-in-superclasses, partial-cpl);
if (next)
local method remove-next (l :: <list>)
if (head(l) == next) tail(l) else l end
end method;
merge-lists(pair (next, partial-cpl),
map-into(remaining-lists, remove-next, remaining-lists))
else
error(make(<inconsistent-precedence-class-error>,
format-string: "Inconsistent precedence graph"))
end
end
end;
let c-direct-superclasses = map-as(<list>, convert, direct-superclasses(c));
merge-lists(list(c),
add(map(rcurry(all-iclass-superclasses, u), c-direct-superclasses),
c-direct-superclasses))
end function compute-implementation-class-precedence-list;
=== End sources/dylan/class-dynamic.dylan ===
The contribution of the paper is an improved version of the "candidate"
method. This code is called "Appendix B: Implementation of the C3
Linearization" in the paper:
=== Begin Appendix B ===
local method candidate (c :: <class>)
// returns c if it can go in the result now, otherwise false
local method tail? (l :: <list>)
member?(c, tail(l))
end method tail?;
~any?(tail?, remaining-inputs)
& c
end method candidate,
method candidate-at-head (l :: <list>)
~empty?(l) & candidate(head(l))
end candidate-at-head;
let next = any?(candidate-at-head, remaining-inputs);
=== End Appendix B ===
Finally, the code I derived from Appendix A and Appendix B:
=== Begin Jan's EIEIO improvement ===
(defun eieio-c3-candidate (class remaining-inputs)
"Returns CLASS if it can go in the result now, otherwise nil"
;; Ensure CLASS is not in any position but the first in any of the
;; element lists of REMAINING-INPUTS.
(and (not (some (lambda (l) (member class (rest l)))
remaining-inputs))
class))
(defun eieio-c3-merge-lists (reversed-partial-result remaining-inputs)
"Merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order, if possible.
If a consistent order does not exist, signal an error."
(if (every #'null remaining-inputs)
;; If all remaining inputs are empty lists, we are done.
(nreverse reversed-partial-result)
;; Otherwise, we try to find the next element of the result. This
;; is achieved by considering the first element of each
;; (non-empty) input list and accepting a candidate if it is
;; consistent with the rests of the input lists.
(let ((next (some (lambda (c) (eieio-c3-candidate c remaining-inputs))
(mapcar #'first
(remove-if #'null remaining-inputs)))))
(if next
;; The graph is consistent so far, add NEXT to result and
;; merge input lists, dropping NEXT from their heads where
;; applicable.
(eieio-c3-merge-lists
(cons next reversed-partial-result)
(mapcar (lambda (l) (if (eq (first l) next) (rest l) l))
remaining-inputs))
;; The graph is inconsistent, give up
(error "Inconsistent precedence graph"))))
)
(defun eieio-class-precedence-c3 (class)
"Return all parents of CLASS with direct ones in c3 order."
(let ((parents (or (class-parents-fast class)
'(eieio-default-superclass))))
(eieio-c3-merge-lists
(list class)
(append
(mapcar
(lambda (x)
(cons x (class-precedence-list x)))
parents)
(list parents))))
)
=== End Jan's EIEIO improvement ===
I hope, this clarifies the situation. Thanks for your patience.
Kind regards,
Jan
next prev parent reply other threads:[~2010-01-03 18:52 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-30 2:49 Potential copyright problem in EIEIO improvement Jan Moringen
2009-12-30 5:42 ` Eli Zaretskii
2009-12-31 3:16 ` Jan Moringen
2009-12-31 1:45 ` Richard Stallman
2009-12-31 3:25 ` Jan Moringen
2010-01-01 2:55 ` Richard Stallman
2010-01-01 18:52 ` Jan Moringen
2010-01-02 15:45 ` Richard Stallman
2010-01-03 18:52 ` Jan Moringen [this message]
2010-01-04 4:09 ` Richard Stallman
2010-01-04 5:37 ` Jan Moringen
2010-01-04 16:23 ` Richard Stallman
2010-01-05 4:23 ` Jan Moringen
2010-01-05 20:45 ` Richard Stallman
2010-01-06 8:11 ` David Kastrup
2010-01-30 21:32 ` Richard Stallman
2010-02-01 3:02 ` Jan Moringen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='3504_1262544732_ZZg0O73~B6ki9.00_1262544727.3761.1636.camel@localhost.localdomain' \
--to=jan.moringen@uni-bielefeld.de \
--cc=emacs-devel@gnu.org \
--cc=rms@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).