Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Lisp case analysis

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

Today, I would like to share with you the relevant knowledge points of Lisp case analysis. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

Lisp has a wealth of built-in data types in which integers and strings are no different from other languages. Values like 71 or "hello" also have roughly the same meaning as languages such as C++ or Java. The three really interesting types are symbols (symbol), tables, and functions. I'll use the rest of this chapter to introduce these types, as well as how the Lisp environment compiles and runs the source code. This process is often called evaluation in Lisp terms. Reading through this section is extremely important for a thorough understanding of the true potential of metaprogramming, as well as the identity of code and data, and the concept of domain-oriented languages. Don't take it lightly. I will try my best to make it lively and interesting, and I hope you can get some inspiration. All right, let's start with symbols.

In general, symbols are equivalent to markers in C++ or Java languages, and their names can be used to access variable values (such as currentTime, arrayCount, n, and so on), except that the symbols in Lisp are more basic. In C++ or Java, variable names can only be a combination of letters and underscores, while Lisp symbols are very inclusive. For example, the plus sign (+) is a legal symbol, and other symbols like -, =, hello-world, *, and so on can all be symbol names. The naming rules of symbolic names can be found on the Internet. You can assign any value to these symbols, and we will use pseudo codes to illustrate this point here. Assuming that the function set assigns a value to a variable (like the equal sign = in C++ and Java), here is our example:

The value of set (test, 5) / / symbol test is 5

The value of set (=, 5) / / symbol = is 5

The value of the set (test, "hello") / / symbol test is the string "hello"

Set (test, =) / / the value of the symbol = at this time is 5, so the value of test is also 5

The value of set (*, "hello") / / symbol * is "hello"

Is there something wrong with it? Suppose we assign an integer or a string value to *, what about multiplication? Anyway * always multiply? The answer is very simple. The role of a function in Lisp is very special, and a function is a data type, just like integers and strings, so you can assign it to symbols. The built-in function of the multiplication function Lisp is assigned to * by default. You can assign other functions to * so that * does not represent multiplication. You can also store the value of this function in another variable. Let's use pseudo code to explain again:

3) / / 3 times 4, the result is 12

Set (temp, *) / / assign the value of *, that is, the multiplication function, to temp

Set (*, 3) / / assign 3 to *

* (3B4) / / incorrect expression, * is no longer multiplication, but the number 3

Temp (3p4) / / temp is a multiplication function, so the value of this expression is 3 times 4 equals 12.

Set (*, temp) / / assign the multiplication function to * again

* (3D4) / / 3 times 4 equals 12

A little weirder, assign the minus sign to the plus sign:

Set (+, -) / / minus sign (-) is a built-in subtraction function

The + (5,4) / plus sign (+) now represents the subtraction function, and the result is that 5 minus 4 equals 1.

This is just an example, and I haven't talked about functions in detail yet. Functions in Lisp are data types, like integers, strings, symbols, and so on. A function does not necessarily have a name, which is very different from the case in C++ or Java. Here the function represents itself. In fact, it is a pointer to a code block with some other information (such as a set of parameter variables). A function has a name only when it is assigned to another symbol, just like assigning a numeric value or string to a variable. You can create a function with a built-in function specifically for creating a function, and then assign it to the symbol fn, which is represented by pseudo code:

Fn [a]

{

Return * (a, 2)

}

This code returns a function with one parameter, which is used to calculate the result of multiplying the parameter by 2. This function does not have a name, you can assign this function to another symbol:

Set (times-two, fn [a] {return * (a, 2)})

We can now call this function like this:

Time-two (5) / / returns 10

Let's skip symbols and functions and talk about tables. What is a watch? You may have heard a lot about it. A table, in a nutshell, is to express blocks like XML in s expressions. The table is enclosed in a pair of parentheses, the elements in the table are separated by spaces, and the table can be nested. For example (this time we use real Lisp syntax, note that we use semicolons to indicate comments):

Empty table

(1); a table containing one element

(1 "test"); two-element table, one element is an integer 1 and the other is a string

(test "hello"); two-element table, one element is a symbol, the other is a string

(test (1 2) "hello"); three element table, one symbol test, one containing two elements 1 and 2

; table, the last element is a string

When the Lisp system encounters such tables, what it does is very similar to what Ant does with XML data, which is to try to execute them. In fact, the Lisp source code is a specific kind of table, just as the Ant source code is a specific XML. The order in which Lisp executes the table is that the first element of the table is treated as a function and the other elements as arguments to the function. If one of the parameters is also a table, the table is evaluated according to the same principle, and the result is passed to the original function as an argument. This is the basic principle. Let's look at the real code:

(* 3 4); equivalent to the pseudo code listed above * (3p4), that is, the calculation of 3 times 4

(times-two 5); return 10, times-two according to the previous definition is twice the parameter

(3 4); error, 3 is not a function

(time-two); error, times-two requires a parameter

(times-two 3 4); error, times-two requires only one parameter

(set + -); assign the subtraction function to the symbol +

(+ 54); based on the result of the previous sentence, + means subtraction at this time, so return 1

(* 3 (+ 22)); the result of 2 / 2 is 4, then multiplied by 3, the result is 12

In the above example, all tables are treated as code. How to treat a table as data? Again, imagine that Ant takes XML data as its own parameter. In Lisp, we prefix the table with'to represent the data.

(set test'(1 2)); the value of test is a two-element table

(set test (1 2)); error, 1 is not a function

(set test'(* 34)); the value of test is a three-element table, and the three elements are *, 3, 4, respectively

We can use a built-in function head to return the first element of the table, and the tail function to return the table made up of the remaining elements.

(head'(* 3 4)); return symbol *

(tail'(* 3 4)); return table (3 4)

(head (tal'(* 3 4); returns 3

(head test); return *

You can think of Lisp's built-in functions as Ant's task. The difference is that instead of extending Lisp in another language (although we can do it), we can extend ourselves with Lisp itself, as in the example of the times-two function above. Lisp's built-in set of functions is very compact and contains only the necessary parts. The rest of the functions are implemented as standard libraries.

Lisp macro

We have seen the application of metaprogramming in a template engine similar to jsp. We generate code through simple string handling. But we can do better. Let's start with the question of how to write a tool that automatically generates Ant scripts by looking for source files in the directory structure.

It is an easy way to generate Ant scripts using string processing. Of course, a more abstract, expressive, and scalable way is to use the XML library to generate XML nodes directly in memory, so that the nodes in memory can be automatically serialized into strings. Not only that, our tool can also analyze these nodes and transform existing XML files. By directly dealing with the XML node. We can go beyond string processing and use higher-level concepts, so our work will be faster and better.

Of course, we can directly use Ant itself to handle XML transformations and make code generation tools. Or we can use Lisp to do the job. As we know before, tables are built-in data structures in Lisp, and Lisp contains a number of tools to quickly and efficiently manipulate tables (head and tail are the easiest two). Moreover, Lisp has no semantic constraints, you can construct any data structure, as long as you want.

Lisp does metaprogramming through macro. We write a set of macros to convert the task list (to-do list) into a dedicated domain language.

Recall that in the example of to-do list above, the data format of XML is as follows:

Clean the hose

Wash the dishes

Buy more soap

The corresponding s expression is as follows:

(todo "housework"

(item (priority high) "Clean the house")

(item (priority medium) "Wash the dishes")

(item (priority medium) "Buy more soap"))

Suppose we want to write a task table manager, store the task table data in a set of files, and when the program starts, read the data from the file and display it to the user. How do you do this task in other languages (such as Java)? We parse the XML file, get the task table data from it, write code to traverse the XML tree, convert it to the data structure of Java (to be honest, parsing XML in Java is not easy), and finally show the data to the user. What should I do if I use Lisp now?

Assuming that we want to do the same thing, we will probably use the Lisp library to parse XML. XML is a Lisp table (s expression) to us, and we can traverse this table and submit the relevant data to the user. However, since we use Lisp, it is no longer necessary to save the data in XML format, just use the s expression, so there is no need to do the conversion. We don't need a special parsing library either. Lisp can process s expressions directly in memory. Note that the Lisp compiler, like the. net compiler, is always available at run time for Lisp programs.

But there's a better way. We don't even have to write expressions to store data, we can write macros and treat the data as code. So what should I do? It's really simple. Recall that Lisp's function call format:

(function-name arg1 arg2 arg3)

Each of these parameters is an s expression, which, after evaluation, is passed to the function. If we replace arg1 with (+ 4 5), the program will first find the result, which is 9, and then pass 9 to the function. Macros work like functions. The main difference is that the parameters of the macro are not evaluated when substituted.

(macro-name (+ 4 5))

Here, (+ 4 5) is passed to the macro as a table, and then the macro can process the table at will, and of course it can be evaluated. The return value of the macro is a table, and then the program is executed as code. The position occupied by the macro is replaced with the result code. We can define a macro to replace the data with arbitrary code, for example, with code that displays the data to the user.

What does this have to do with metaprogramming and the task list program we need to do? In fact, the compiler will work for us and call the corresponding macros. All we have to do is create a macro that converts the data into the appropriate code.

For example, the macro of C to the third power used above to be written in Lisp looks like this:

(defmacro triple (x)

`(+ ~ x ~ x ~ x))

Note: in Common Lisp, the single quotation marks here should be anti-single quotation marks, meaning that the table is not evaluated, but you can evaluate an element in the table, the token ~ indicates the evaluation of element x, which should be a comma in Common Lisp. The difference between anti-single quotation marks and single quotation marks is that the elements of the table identified by single quotation marks are not evaluated. The symbol used by the author here is a self-invented Lisp dialect, Blaise, which is slightly different from common lisp. In fact, inventing dialects is a unique pleasure of lisp masters, and many fanatics are keen to do so. For example, Paul Graham invented ARC, and many tokens are much simpler and more modern than traditional Lisp.

The use of single quotation marks is to prohibit the evaluation of the table. Every time triple appears in the program,

(triple 4)

Will be replaced with:

(+ 4 4 4)

We can write a macro for the task list program, convert the task data into executable code, and then execute it. Suppose our output is on the console:

(defmacro item (priority note)

`(block

(print stdout tab "Prority:" head (tail priority)) endl)

(print stdout tab "Note:" ~ note endl endl)

We created a very small and limited language to manage task tables embedded in Lisp. This language is only used to solve domain-specific problems, often referred to as DSLs (domain-specific language, or domain-specific language).

These are all the contents of the article "Lisp case Analysis". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report