[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Dec 4 11:18:51 1993 
Subject:Languages for self-modifying code 
From:hjcove01 
Volume-ID:931205.01 

	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