Write Code That Writes Code

Mohammad Amin Khakzadan - Jun 13 '19 - - Dev Community

We always write codes with our fingers, we always type on our keyboards, and we work hours and hours to create computer programs.

But things we write can be written by a computer. and currently, programming languages like C, C++, Python, Java, ... in the final compilation step will be translated to the machine byte codes, and that means programs that write codes.

But this should not be the end. We must write programs that can write codes in other programming languages like C, C++, Python, java, ruby or whatever else.

maybe that be a new programming language or some frameworks that change code structure or a text stream processor that translate text to something else.

I will show you a simple example for every subject I've mentioned, but that is not the only way you can do it.

a new programming language

During the time, we always hear about new programming languages that provide a set of features and obey a design philosophy, but most of them always copying other programming language principles, and they can't be used for the everyday use cases. But if we forget them, and try to create a new programming language from the zero ground with our creativity, that will bring us a whole of new ideas to accomplish our goals.

for example, think you want to make a simple text editor, a programming language for that purpose can be something like this:

OpenWindow
{
    text_area: TextArea[editable, fullsize]
    KeyPress('CTRL+s') =>
    {
        path = AskPath('Save As', 'Save', 'Cancel)
        open(path, 'wt').write(text_area.text)
    }
    KeyPress('CTRL+o') =>
    {
        path = AskPath('Open', 'Open', 'Cancel)
        text_area.text = open(path).read()
    }
}

or maybe you be an artist and want to draw some pixel arts:

use random, new_image

image = new_image([500, 500])
image.fill('Navy Blue')

repeat (40)
{
    image.draw_dot(
        random.position_range([0, 0], [image.width, 300]),
        random.color_range('bw:200', 'bw:256')
    )
}

image.draw_rectangle([0, 300], image.size, 'Dark Blue')

repeat(10)
{
    start = random.position_range([40, 200], [image.width - 40, 300])
    end = [start.x + random.choice(1, -1) * random.range(20, 35), 300]
    image.draw_rectangle(start, end, 'Dark Blue')
}

Can you guess what the program will draw?

or some programming languages like this one:

set total_words to zero.
open "article.txt" then,
    for each line,
        add number of words in line to total_words.
    end.
end.
print total_words.

Metaprogramming

If you understand how compilers work, what's really going on is not so much that Lisp has a strange syntax as that Lisp has no syntax. You write programs in the parse trees that get generated within the compiler when other languages are parsed. But these parse trees are fully accessible to your programs. You can write programs that manipulate them. In Lisp, these programs are called macros. They are programs that write programs.

Programs that write programs? When would you ever want to do that? Not very often, if you think in Cobol. All the time, if you think in Lisp. It would be convenient here if I could give an example of a powerful macro, and say there! how about that? But if I did, it would just look like gibberish to someone who didn't know Lisp; there isn't room here to explain everything you'd need to know to understand what it meant. In Ansi Common Lisp I tried to move things along as fast as I could, and even so I didn't get to macros until page 160.

source link: https://stackoverflow.com/questions/514644/what-exactly-is-metaprogramming

or a framework that can edit program structure, an example in python:

from auto_code_gene import python as py
import sys

writer = py.PyWriter(sys.stdout)
node = \
py.Function('parse_argv', 'argv', [
    py.For('arg', 'argv', [
        py.If("len(argv) == 0", [
            py.Raise('ValueError', py.Str('empty argument')),
        ]),
        py.If("arg == '-'", [
            py.Pass()
        ])
    ])
])

node.write(writer)

result:

def parse_argv(argv):
    for arg in argv:
        if len(argv) == 0:
            raise ValueError('empty argument')
        if arg == '-':
            pass

text stream processor

some programs that can translate this text:

INC stdlib.h
ST buffer:
    char *pntr, size_t start, size_t len, size_t size
    FN ${buffer}, allocate_buffer,
        pntr = malloc($size), start = 0, len = 0, size = $(size)

to this C file:

#include <stdlib.h>

struct buffer
{
    char *pntr;
    size_t start;
    size_t len;
    size_t size;
};

struct buffer *
allocate_buffer(size_t size)
{
    struct buffer *result;

    result = malloc(sizeof(struct buffer));
    if (result == NULL)
    {
        return NULL;
    }

    result->pntr = malloc(size);
    if (result->pntr == NULL)
    {
        free(result);
        return NULL;
    }

    result->start = 0;
    result->len = 0;
    result->size = size;

    return result;
}

Conclusion

Never write programs with your fingers, always write programs that make codes. and do it for each time you want to write something. because computers can automate the job.

. . . . . .
Terabox Video Player