不是引站,我自己也经常用来着,有次看到回调函数突然想起这个,当然和回调函数是不一样的,却不知道为什么能用,看说明上说函数参数可以为任何类型,但没找到说可以放个函数进去,这些基础知识不知道在哪里学,比如
echo md5(10>1 ? 10 : 1);
竟然也可以,总之,学习到很多,谢谢大家。
1
est 2018-09-12 11:57:46 +08:00 2
咖喱化(科里化)?
|
2
javaWeber 2018-09-12 12:00:06 +08:00 4
从内向外,函数返回的结果,作为参数使用呗。。
|
3
deston 2018-09-12 12:02:59 +08:00 3
2 楼上说的很清楚了,我来看看楼下怎么说
|
4
zn 2018-09-12 12:06:46 +08:00 via iPhone 1
函数调用得到的就是一个值,跟一个普通的 1 在本质上没什么区别,都是堆栈上的一个条目而已。
|
5
Fairy1128 2018-09-12 12:06:55 +08:00 2
函数的结果作为参数传递给另一个函数 很正常啊 又不是 callback 更谈不上柯里化
|
6
lnim 2018-09-12 12:08:24 +08:00 via iPhone
二楼说的很明白了 只要函数有返回值 就都可以这样写啊 而且在函数范式的语言中 函数也能直接当参数使用~
|
7
marcong95 2018-09-12 12:09:14 +08:00 1
数学课本?函数这样用不是理所当然的么?复合函数了解一下?
|
8
kerr92 2018-09-12 12:10:43 +08:00 via iPhone 1
这种一点也不奇怪吧…… JS 里的 c().b().a()都很正常
|
9
mengzhuo 2018-09-12 12:13:12 +08:00 8
基础知识啊~
Go 的话,这是栈(call stack)的作用,不考虑 inline,SSA 这些东西,大概过程是这样的(中文翻译可能不准确) 语法检查器发现语法 a(b(c())), 校验合格之后,告诉 tokenizer,处理一下。 tokenizer 把这个拆成( parse )语法树( AST ) a() -- |- b() |- c() 然后告诉编译器,处理一下。 编译器找到语法树叶子节点,反向查找得到执行树 c->b->a,然后依次写机器码 伪内存地址 0x00001:func c() ... 跳转到 b() 伪内存地址 0xff002: func b() ... 跳转到 a() 伪内存地址 0xf1113: func a() 保存可执行文件退出。 |
10
cuzfinal 2018-09-12 12:15:11 +08:00 4
想了解程序的运行?
❌:查阅编译原理等相关书籍 ⭕️:上论坛发帖询问 |
11
puga2006 2018-09-12 12:15:18 +08:00 2
这个不是最基础的函数编程思想么,我感觉楼主的疑惑倒是怪怪的🤔
|
12
littleylv 2018-09-12 12:16:33 +08:00 11
不觉得楼主像是“写了多年程序”的样子
|
13
arthasgxy 2018-09-12 12:17:46 +08:00 1
y=x+1
z=y+1 w=z+1 w=((x+1)+1)+1 如果这样看起来不感觉奇怪的话。 你把它写成函数也不会觉得奇怪吧。。。 |
14
imn1 2018-09-12 12:17:57 +08:00
区块链……
|
15
tumi9527 2018-09-12 12:18:40 +08:00 1
php 匿名函数了解一下
|
16
marsgt 2018-09-12 12:20:54 +08:00 1
其实就是数学上把一组复杂函数抽象成单个量的思想,可以去看看《代码之髓》这类的书
|
17
watzds 2018-09-12 12:21:31 +08:00 via Android 1
函数式编程只能这样写
|
18
irainsoft 2018-09-12 12:22:11 +08:00 2
f(g(x))也奇怪吗
|
19
HXM 2018-09-12 12:22:14 +08:00 via Android 1
复合函数
|
20
kx5d62Jn1J9MjoXP 2018-09-12 12:22:39 +08:00 via Android 1
斯坦福公开课 CS110 了解一下
|
21
shenjo 2018-09-12 12:27:39 +08:00 1
一等公民了解下?
|
22
shisang 2018-09-12 12:39:18 +08:00
fp 了解一下
|
23
wizardoz 2018-09-12 12:41:37 +08:00 1
求值顺序了解一下
|
24
shisang 2018-09-12 12:41:56 +08:00 1
你看到 clojure 不得疯掉,全是括号
|
25
hhsuan 2018-09-12 12:42:36 +08:00 via Android 1
有什么语言是不能这样写的吗?
|
26
reus 2018-09-12 12:43:02 +08:00 1
小学生都知道 1 * (2 + 3) 吧。为什么 (2 + 3) 可以做被乘数?一样道理,改成前缀表达式就是 *(1, +(2, 3)),和函数调用就一样了
|
27
janus77 2018-09-12 12:45:01 +08:00 1
我的年龄是 10+10 岁。
|
28
jmc891205 2018-09-12 12:46:07 +08:00 1
数学上的 f(g(h(x)))楼主有疑问吗?
|
29
zsdroid 2018-09-12 12:52:18 +08:00 2
多年写错了吧,可能是多日
|
30
K0 2018-09-12 12:58:10 +08:00 via iPhone 1
mov eax, dword
ret |
31
lzhCoooder 2018-09-12 13:04:16 +08:00 1
c 先压栈执行完弹出,b 再压栈再弹出,a 再压栈再弹出...你再连着用一个线程只有一个调用栈,不影响的
|
32
PythonAnswer 2018-09-12 13:05:04 +08:00 via iPhone 1
各种汇编佬都出来了
|
33
lty494685444 2018-09-12 13:07:20 +08:00 1
编程水平不知道,不过我感觉楼主你数学应该不太好
|
34
lihongjie0209 2018-09-12 13:07:44 +08:00 2
用过 linux 的管道吗, 一样的
a(b(c())) c() | b | a |
35
zhzer 2018-09-12 13:09:14 +08:00 1
那你这基础有够逊的
代码解析成 AST 然后根据后序遍历的顺序,从最底层求值,每一层 function 拿到的都是结果并非过程 |
36
RqPS6rhmP3Nyn3Tm 2018-09-12 13:10:12 +08:00 via iPhone 1
汇编,stack pointer
|
37
ksco 2018-09-12 13:13:05 +08:00 1
写了多年程序?莫非楼主写的是 PHP ?(狗头保命
|
38
xlui 2018-09-12 13:17:31 +08:00 via Android
编译原理了解一下
|
39
forblackking 2018-09-12 13:24:39 +08:00 via Android
用 FP 来看函数是一等公民可以作为输入输出,内层函数的结果作为参数依次传给外层函数
|
40
misaka19000 2018-09-12 13:26:38 +08:00 via Android
这和柯里化毛关系没有
一个字:栈 话说楼主真不是开黑 PHP 的? |
41
gesse 2018-09-12 13:26:57 +08:00
楼主真的是“写了多年程序”的样子吗?
|
42
jeffersonpig 2018-09-12 13:43:12 +08:00
写了多年程序?
|
43
somebody 2018-09-12 13:44:07 +08:00 via Android
看帖子的回复,还是有不少人不懂的
|
44
jeffersonpig 2018-09-12 13:45:01 +08:00
@lihongjie0209 linux 管道对于写了多年程序的人来说可能比函数嵌套调用更难理解吧
|
45
SeanChense 2018-09-12 13:46:11 +08:00
跟函数式啥关系?
`exit(main(argc, argv));` 也是函数式编程么? |
46
maichael 2018-09-12 13:59:15 +08:00
这跟函数式、柯里化有什么关系……又不是传函数进去。
上面的人是没看清楚还是咋地。 |
47
orange1818 2018-09-12 14:03:29 +08:00
估计是 java 写多了没见过函数式编程
|
48
nervdy 2018-09-12 14:07:16 +08:00
上面的楼全被点了个感谢
|
49
tourist2018 2018-09-12 14:07:55 +08:00
num := getNum()
fmt.Println(num) --------------------- fmt.Println(getNum()) 楼主真的。。。 |
50
shapimai 2018-09-12 14:10:26 +08:00
写了多年程序?
|
52
XXneet 2018-09-12 14:12:40 +08:00
抽象数据类型
|
53
bumz 2018-09-12 14:25:22 +08:00 3
c() = 2
b(x) = 3 * x a(x) = 4 * x a(b(c())) = a(b(2)) = a(6) = 24 这和数学不是一样的嘛?学名叫 applicative order 和柯里化、函数式、链式调用有个毛关系 至于为什么可以这样做?因为等式两边的东西是同一个东西,用哪一个都是一样的。 |
54
merin96 2018-09-12 14:27:48 +08:00
|
55
xuanbg 2018-09-12 14:31:22 +08:00
这个就是简单的等价替换而已
|
56
jianleer 2018-09-12 14:33:21 +08:00
因为栈
|
57
falcon05 2018-09-12 14:36:44 +08:00 via iPhone
人的悟性可以差别很大…
|
58
neptuno 2018-09-12 14:41:31 +08:00
指针的指针。。。。
|
59
leeho 2018-09-12 14:41:59 +08:00
多年=2 年?
|
60
DOLLOR 2018-09-12 14:45:24 +08:00
btoa(encodeURIComponent(JSON.stringify({result:'牛逼牛逼'})))
>"JTdCJTIycmVzdWx0JTIyJTNBJTIyJUU3JTg5JTlCJUU5JTgwJUJDJUU3JTg5JTlCJUU5JTgwJUJDJTIyJTdE" JSON.parse(decodeURIComponent(atob("JTdCJTIycmVzdWx0JTIyJTNBJTIyJUU3JTg5JTlCJUU5JTgwJUJDJUU3JTg5JTlCJUU5JTgwJUJDJTIyJTdE"))) >{result: "牛逼牛逼"} 不过这样写很蛋疼,如果有管道操作符就好了 {result:'牛逼牛逼'} |> JSON.stringify |> encodeURIComponent |> btoa >"JTdCJTIycmVzdWx0JTIyJTNBJTIyJUU3JTg5JTlCJUU5JTgwJUJDJUU3JTg5JTlCJUU5JTgwJUJDJTIyJTdE" |
61
ch940621 2018-09-12 14:48:00 +08:00
写了多年程序厉害了...
|
62
circleee 2018-09-12 14:52:38 +08:00
我毕业的时候写过 a = fun()[0]
哈哈哈哈 |
64
Justin13 2018-09-12 15:20:04 +08:00 via Android
简单的线性流水式调用
|
65
chenxytw 2018-09-12 15:32:35 +08:00 1
a()()()() 这才是 curry.....
上面说 柯里化的在想啥 |
66
stevenhawking 2018-09-12 15:37:09 +08:00
哦,这有啥,你忘了链式方法?
->a()->b()->c() |
67
persimmon 2018-09-12 15:46:28 +08:00
调用栈不断在加深而已 ......
|
68
SoulGem 2018-09-12 15:48:16 +08:00
多年程序都写了啥啊……
|
69
Mrlgm 2018-09-12 16:13:25 +08:00
就像 jquery 的链式调用一样,返回了个对象呗
|
70
lihongjie0209 2018-09-12 16:26:33 +08:00 1
楼上们就知道瞎说, 和函数式有什么关系, 只是在调用的时候参数运算了一下而已, 现在这么多装逼的?
先反驳一下函数一等公民的. 函数一等公民是函数可以作为参数和返回值. 有函数 a, b, c, d 那么函数 a 可以把 b, c 作为参数, 并返回另一个函数 d: d = a(b, c) 这才是函数是一等公民 以楼主的例子, 我完全可以用 JAVA 7 之前的任何版本写出以下代码 a(b(c())) obj.a(obj.b(obj.c())) 那么是不是说 JAVA 在 7 之前就支持函数式了?? |
71
lihongjie0209 2018-09-12 16:27:15 +08:00
@forblackking 请问在 a(b(c())) 中, 哪里有函数了?
|
72
Malthael 2018-09-12 17:04:25 +08:00
上下文??
|
73
colinlet 2018-09-12 17:09:43 +08:00 1
《数据结构》
《计算机组成原理》 《计算机操作系统》 《计算机网络》 |
74
rockyou12 2018-09-12 17:13:43 +08:00
lz 一击脱离加发在 php 节点下,莫不是在钓鱼......
|
75
kakalulin 2018-09-12 17:15:03 +08:00
编译原理了解一下
|
76
GoForce5500 2018-09-12 18:03:57 +08:00
推荐 Coursera 上的 Programming Language,第二门课程有一周作业就是拿 Racket 写一个小型解释器。
|
77
CODEWEA 2018-09-12 18:05:43 +08:00 via iPhone
求求你 别再黑 php 了 去官网了解下匿名函数
|
78
sampeng 2018-09-12 18:08:25 +08:00
楼上的都介绍计算机系的书籍是什么鬼。。。高中数学里的函数你们吃掉了?
f(x)和 f(f(x))没见过? |
79
HowToMakeLove 2018-09-12 18:17:25 +08:00 1
能分的清,多层嵌套的 for/foreach 这种吗?
|
80
SpiderXiantang 2018-09-12 18:22:27 +08:00
放入栈 从外到里一个个入栈 然后栈的时候肯定先返回里面的函数吧 瞎说的
|
81
arthas2234 2018-09-12 18:27:35 +08:00
基础知识不过关啊。。。会去好好学吧
|
82
laqow 2018-09-12 18:33:16 +08:00 via Android
看一下 LISP 语言就会觉得不这么写都不正常
|
83
RingoTC 2018-09-12 18:36:13 +08:00
函数的函数鸭
|
84
bucky 2018-09-12 18:38:05 +08:00
这和函数式有什么关系?函数返回值不用变量直接直接传入另一个函数和需要函数式支持?
|
85
RainyH2O 2018-09-12 18:50:02 +08:00
第一次看到过程 VS 对象 VS 函数打的这么激烈的
你们是要给这种调用形式争夺唯一代表权么 |
86
xlui 2018-09-12 19:20:43 +08:00 via Android
t.c:
int a() {return 1;} int b(int i) {return i+1;} int c(int i) {return i+1;} int main() { c(b(a())); } gcc -S t.c -o a.s cat a.s: ... main: ... movl $0, %eax call a movl %eax, %edi call b movl %eax, %edi call c |
88
MineDog 2018-09-12 19:30:58 +08:00
47 楼,别黑我 java,这算什么函数式编程,只是方法的返回值作为参数而已,算一个语法糖吧
|
89
lichao 2018-09-12 19:43:38 +08:00
c() |> b() |> a()
|
90
luopengfei14 2018-09-12 19:44:59 +08:00 via iPhone
@xlui 大佬
|
91
mmdsun 2018-09-12 19:50:09 +08:00 via Android
楼主问的是函数调用栈帧原理吧
|
92
reus 2018-09-12 21:06:49 +08:00 1
就一个表达式求值,关函数式、柯里化、调用栈什么事?这里根本就没有出现高阶函数
f(xxx, ...) 这是函数调用表达式,传入的参数可以是其他表达式,也就是可以传入另一个函数调用表达式,同理可以嵌套多层。a(b(c())) 就是嵌套了多层的函数调用表达式。 水平真低。 |
93
yichinzhu 2018-09-12 22:12:18 +08:00 via Android
在 v2 学到了很多黑 PHP 的姿势😑
|
94
zagreb 2018-09-12 22:38:43 +08:00 via iPhone 1
看了附言 1:
“不知道基础知识哪里学”,表达式,函数表达式和函数返回值了解一下。函数参数没说一定要变量,表达式就行。 “ md5(...)”,你想表达的是不是 md5(max(a,b))? |
95
qiayue 2018-09-12 22:40:26 +08:00
a(b(c())) 等价于下面三行
$cResult = c( ); $bResult = b( $cResult ); $aResult = c( $bResult ); 举一个真实例子,get 获取到的数据,先 url decode 之后,再 base64 解码,再 json decode 成数组 $userUrlEncode = $_GET['user']; $userBase64 = urldecode( $userUrlEncode );//传入字符串,返回字符串 $userJson = base64_decode( $userBase64 );//传入字符串,返回字符串 $user = json_decode( $userJson );////传入字符串,返回数组 以上串起来写就是 $user = json_decode(base64_decode(urldecode( $_GET['user'] ))); 记住,传进去的并不是函数,而是函数返回的结果 |
96
qiayue 2018-09-12 22:41:14 +08:00
$aResult = c( $bResult );
勘误,正确为: $aResult = a( $bResult ); |
97
qiayue 2018-09-12 22:42:46 +08:00
$user = json_decode( $userJson );////传入字符串,返回数组
勘误,正确为: $userArr = json_decode( $userJson, TRUE );////传入字符串,返回数组 或者 $userObj = json_decode( $userJson );////传入字符串,返回对象 |
98
zmj1316 2018-09-12 22:48:03 +08:00
我刚看到以为是问 C++ 左值右值呢......
|
99
deljuven 2018-09-12 22:56:36 +08:00
1L 的说法是正确的,基本就是计算机语言理论那一套东西,参看 Wikipedia: https://en.wikipedia.org/wiki/Currying
|