乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 328|回复: 12

function和quote的区别

[复制链接]

122

主题

647

帖子

223

银币

版主

Rank: 10Rank: 10

铜币
1174
发表于 2020-2-18 14:28:00 | 显示全部楼层 |阅读模式
先看例子
(setq  TT (EVAL (quote(LAMBDA (K ) (ALERT K ) ) ) ))
(TT "dd" )
编译以后是这样的:
Offset         0    1   2  3   4  5   6   7   8    9  A    B  C   D  E  F
00000000   0D 0A 20 46 41 53 34 2D  46 49 4C 45 20 3B 20 44      FAS4-FILE ; D
00000010   6F 20 6E 6F 74 20 63 68  61 6E 67 65 20 69 74 21   o not change it!
00000020   0D 0A 31 0D 0A 31 20 24  20 24 0D 0A 31 32 33 20     1  1 $ $  123
00000030   36 20 24 14 01 01 01 00  32 00 32 22 2A 39 01 00   6 $     2 2"*9  
00000040   55 01 00 02 00 64 64 5B  54 54 00 45 56 41 4C 00   U    dd[TT EVAL
00000050   00 5B 4C 41 4D 42 44 41  00 00 5B 4B 00 00 39 01    [LAMBDA  [K  9
00000060   00 5B 41 4C 45 52 54 00  00 5B 4B 00 00 39 02 00    [ALERT  [K  9  
00000070   39 03 00 01 01 43 00 00  06 00 0A 01 5C 00 00 43   9    C      \  C
00000080   00 00 01 00 0A 01 43 06  00 00 00 1C 14 01 00 00         C         
00000090   00 09 05 00 0A 09 04 00  34 00 07 35 01 03 00 03           4  5   
000000A0   0B 06 02 00 0A 09 01 00  35 01 02 00 03 16 15 00           5      
000000B0   B6 81 1A 52 B3 0A 3B 66  61 73 34 20 63 72 75 6E   ? R?;fas4 crun
000000C0   63 68 0A 3B 24 3B 41 32  2F 31 38 2F 32 30         ch ;$;A2/18/20
(setq tt (eval(function(lambda (k)    (alert k)   ))))
(tt "dd")
这两句编译后是这样:
Offset      0   1   2    3   4   5   6     7   8   9   A   B   C   D   E   F
00000000   0D 0A 20 46 41 53 34 2D  46 49 4C 45 20 3B 20 44      FAS4-FILE ; D
00000010   6F 20 6E 6F 74 20 63 68  61 6E 67 65 20 69 74 21   o not change it!
00000020   0D 0A 32 36 0D 0A 33 20  24 14 01 01 01 00 09 02     26  3 $      
00000030   00 5C 00 00 18 03 00 03  02 00 35 01 01 00 03 19    \        5     
00000040   01 00 16 24 0D 0A 31 33  39 20 37 20 24 14 01 01      $  139 7 $   
00000050   01 00 32 00 32 2A 2A 39  01 00 55 01 00 02 00 64     2 2**9  U    d
00000060   64 5B 54 54 00 45 56 41  4C 00 00 56 6B 77 6F 74   d[TT EVAL  Vkwot
00000070   65 00 00 01 01 43 00 00  06 00 0A 32 00 32 1A 2A   e    C     2 2 *
00000080   39 01 00 5B 41 4C 45 52  54 00 4B 00 00 5C 00 00   9  [ALERT K  \  
00000090   43 00 00 03 00 0A 5C 00  00 32 00 5B 2D 6C 61 6D   C     \  2 [-lam
000000A0   62 64 61 2D 00 00 3A 01  43 06 00 01 00 1C 14 01   bda-  : C      
000000B0   00 00 00 09 05 00 0A 57  00 00 00 00 09 06 00 51          W       Q
000000C0   01 04 00 01 00 35 01 03  00 03 0B 06 02 00 0A 09        5         
000000D0   01 00 35 01 02 00 03 16  18 00 A9 8A FC F9 EA 3D     5       ?
000000E0   9D EE 0A 3B 66 61 73 34  20 63 72 75 6E 63 68 0A    ?;fas4 crunch
000000F0   3B 24 3B 41 32 2F 31 38  2F 32 30                  ;$;A2/18/20
可以看出以下几点:
1.用quote时没有定义函数,蓝色字符为1,1,意思是函数部分只有一个字节长,含有一个符号。
   用function是定义了一个函数,-lambda-,函数内容紫红色部分,蓝色字符 26 3说明函数部分的长度是26个字节,含有3个符号。
2.用quote时 , (alert k) 是作为一个表来解释运行的。绿色的39 02 00说明这个表有两个元素。
3.用function时, alert和 k是两个独立的字符串。
结论:用quote时lambda没有编译成函数,是解释运行,速度慢。用function时,lambda被编译成了一个函数,可以进行优化,速度快。
所谓优化,就是可以快速、直接访问函数入口地址,不需要查找函数名对应的地址后再调用。
有的反编译,没有正确处理function,导致用了这个函数的程序不能被反编译。
回复

使用道具 举报

56

主题

346

帖子

68

银币

中流砥柱

Rank: 25

铜币
512
发表于 2022-7-14 11:39:00 | 显示全部楼层
确实如楼主所说,《乐筑天下》翻译的autolisp函数对这个函数说明如下:
function
通知 Visual LISP 编译器将参数作为内置函数进行链接和优化
(function symbol | lambda-expr)
function 函数与 quote 函数相同,但它将通知 Visual LISP 编译器将参数视为内部函数或用 defun 定义的函数,对其进行链接和优化。
由 function 引用的经过编译的 lambda 表达式加载到 Visual LISP IDE 时,将包含调试信息。
参数
symbol
命名函数的符号。
lambda-expr
如下格式的表达式:
(LAMBDA arguments {S-expression}* )
返回值
表达式的求值结果。
示例
下列代码中,Visual LISP 编译器不能优化被引用的 lambda 表达式:
(mapcar
  '(lambda (x) (* x x))
       '(1 2 3))
向表达式中添加 function 函数后,编译器可对 lambda 表达式进行优化。例如:
(mapcar
   (function (lambda (x) (* x x)))
      '(1 2 3))
回复

使用道具 举报

18

主题

158

帖子

12

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
225
发表于 2022-7-14 11:51:00 | 显示全部楼层

我上面那个语句,编译后看码似乎和楼主用function后是差不多的,肯定不是第一种结果
如果用list是不优化的,那么下面这个tt1命令怎么写才对呢?tt2是可以正常运行的
  1. (defun ttfunc (func / )
  2.    (eval func)
  3. )
  4. (defun c:tt1()
  5.   (ttfunc (function (lambda() (princ "\test"))))
  6. )
  7. (defun c:tt2()
  8.   (ttfunc (list (lambda() (princ "\test"))))
  9. )

回复

使用道具 举报

18

主题

158

帖子

12

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
225
发表于 2022-7-13 21:30:00 | 显示全部楼层
这么写,编译优化了吗?function定义的函数,似乎没法作为参数传递到其它函数中
  1. (setq  TT (list (LAMBDA ( ) (ALERT K ) ) ) )
  2. (setq k "dd")
  3. (eval TT)
回复

使用道具 举报

2

主题

18

帖子

6

银币

初来乍到

Rank: 1

铜币
25
发表于 2020-2-18 16:03:00 | 显示全部楼层
硬核技术贴
回复

使用道具 举报

7

主题

450

帖子

22

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
473
发表于 2020-2-19 11:14:00 | 显示全部楼层
确实啊,出错在这个地方很多。
回复

使用道具 举报

1

主题

13

帖子

3

银币

初来乍到

Rank: 1

铜币
48
发表于 2020-2-19 11:16:00 | 显示全部楼层

硬核技术贴
回复

使用道具 举报

0

主题

54

帖子

72

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
151
发表于 2020-2-19 17:52:00 | 显示全部楼层
意思是用function效率更高?我每次都是用的'(lambda(x) )   这个'是不是相当于quote
回复

使用道具 举报

122

主题

647

帖子

223

银币

版主

Rank: 10Rank: 10

铜币
1174
发表于 2020-2-19 22:28:00 | 显示全部楼层

确实如此,function是为优化而生的
回复

使用道具 举报

122

主题

647

帖子

223

银币

版主

Rank: 10Rank: 10

铜币
1174
发表于 2020-2-19 22:29:00 | 显示全部楼层

可以把出错的文件发给我,帮你研究解决方法
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-1-31 16:02 , Processed in 0.170659 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表