There has been an on going discussion of what languages
are effective for creating self-modifying code in the comp.ai
newsgroup. I will summarize some of the langauges I have
identified thus far. I am distributing this note to several
different language groups because I am interested in hearing
of other languages that are also effective for creating self-
modifying code.
When discussing languages for creating self-modifying
code we must first identify why we want such languages. If
you have such tools then you can write a program that itself
will write a program. This can be considered a form of
learning where a program learns a procedure or function that
can be used to do a task.
Thus the main focus is to be able to create a function or
procedure and then run it. We also want to be able to create a
function or procedure and then be able to modify it easily.
For the first function created might not do the task we want it
to do, thus we would want our program to automatically
modify the created function or procedure until it is modified
into a form that will execute the task effectively.
What is the most effective representation of a function
that can be modified? If we represent a function as a string it
is not as easily modified and manipulated as when it is
represented as a structure of symbols. Thus to have an
effective language for the creation of self-modifying code it is
best to have a language that manipulates symbols and
structures effectively. Examples of languages that fit into this
category are: Lisp, Prolog, Pop, Smalltalk, Icon, and many
others. C, Pascal, Ada and like languages do not have as
effective built-in tools for the creation and manipulation of
structures and symbols.
We would also need tools that can then execute the
symbol-structure representations of functions that we have
created. Preferrably we would want a tool that could execute
the structure on different sets of input values. This tool would
resemble the apply tool that exists in some implementations of
Lisp. Apply takes two arguments. The first argument is a
structure that represents a function. The second argument is
a list or structure of arguments to be passed to the function.
There are a number of programming languages that allow the
creation of such 'apply' tools fairly easily. The languages that I
have identified so far are: Lisp; Prolog; Pop-11; and Smalltalk.
In Common Lisp apply is a built function that operates not on a
structure but rather on a function type. Thus we need to
name our 'apply' tool differently. We name it 'apply_to' and
define it as follows. (Scheme and other Lisp dialects probably
have similar tools.)
> (defun apply_to (funlist arglist)
(apply (eval (list 'function funlist)) arglist))
We execute apply_to as follows:
> (apply_to '(lambda (a b) (+ a b)) '(4 5))
9
In Pop-11 the name apply is also already taken, thus again we
use 'apply_to' and define it as follows: (Developed in
discussions with A. Sloman.):
: define apply_to(funlist, arglist);
popval(funlist) (explode (arglist));
enddefine;
We call it as follows:
apply_to([procedure(A, B); A+B =>; endprocedure], [4 5]);
** 9
Prolog's syntax is significantly different from Lisp and Pop-11.
Predicates (functions) are broken into several parts called
clauses. Thus we need a structure that can represent several
clauses. In order to represent a predicate in a structureal
form we will use a structure that has the name 'lambda' and
has one argument which itself is a list of nameless clauses. We
will also use a lambda structure of two arguments to represent
a single clause. The first argument being a list of parameters
for this nameless clause and the second argument being the
body. Apply is then defined as follows:
apply(lambda([Clause1|_]), Args) :-
Function =.. [lambda|Clause1], apply(Function, Args).
apply(lambda([_|Rest], Args) :- apply(lambda(Rest), Args).
apply(lambda(Args, Body), Args) :- Body.
Apply can then be used as follows: (Note that a third argument
'C-Result' is needed for a return value.)
?- apply(lambda([[[A,B,C], (C is A + B)]]), [4, 5, Result]).
C=Result=9
For a more detailed discussion of apply in Prolog see my article
in "Computer Languages" 1993, Volume 18, # 1.
Defining apply in Smalltalk is slightly more complex.
There are no tools for 'apply' on structures. There are only
tools for the evaluation of strings. Likewise unnamed
functions are in the form of blocks which differ from the
structures that exist in smalltalk. Thus there are a number of
conversions that must be made to apply a method (function)
in the form of a structure. The below defined apply is limited
because of all of the ambiguities of translations of structures
to strings and then to blocks. The below apply only takes numbers as
arguments to the unnamed function being passed to apply and
only allows three parameters at most.
apply: lambda arguments:args
^Compiler evaluate:
(((lambda printString) replaceFrom: 1 to: 1
with: '[' startingAt:1)
replaceFrom: ((lambda printString) size) to:
((lambda printString) size)
with: ']' startingAt:1)
, ((args collect: [:each | ' value:',
(each printString)])
inject: '' into: [:string :next | string , next])
We would use the above method as follows:
^Compiler apply: #(:a :b | a+b) arguments: #(4 5)
9
To the best of my knowledge other languages such as
Icon, and Forth don't have tools such as 'apply' although they
do have tools to create and manipulate symbols and
structures. Many people have commented that we could
create a program that wrote a string that represented a
program to a file and then exectued that file. Icon reportedly
has the power to do this. While this of course is possible it
adds a number of complicating steps in the process of creating
self-modifying code, and thus makes these languages less
suited for this purpose. With Icon some of the compilcations
include: translating a structure of symbols into a string;
writing a file; managing files for there may be an apply within
an apply; executing a file; and accessing the value outputed
from the execution of the file. With other languages such as C
the same compilcations exist, however we have a couple of
additional difficulties: the development of a set of tools for
structures; and a set of tools for representing symbols that can
act as key words or variable names in the functions that are
created by the self-modifying code.
I am very interested in receiving any email or news
responses. In particular demonstrations of 'apply' in other
langauges.
H. Justin Coven, Ph.D.
Computer Science Dept.
Bellarmine College
Louisville, KY 40206
hjcove01@ulkyvx.louisville.edu
|