编程起步:(二)告诉机器一个函数

编程起步:(二)告诉机器一个函数

可以教初中生编程,但不能是那种Hello World编程;编程的概念也可以被初中生理清,但不能一股脑地把莫名其妙的概念塞到他们的脑海。

函数这个概念就是一例。如果你对上篇编程起点:(一)告诉机器一个功能有印象,那么应该还记得函数从“功能”(function)派生而来,也学习了单参数输入的函数与调用,函数、参数的命名与赋值,还有控制台的使用方法。

如果对这些印象有些模糊,请再回去读一遍。如果记得,请活动一下脑子:

  • 打开控制台
  • 输入任意一个函数
  • 用任意输入调用这个函数
  • 每次调用都要重新输入这个函数,用什么方法可以缓解这个问题?

如果有任何一个有点模糊,请阅读编程起点:(一)告诉机器一个功能

本篇结构与练习方式

本篇主要通过一系列练习,打磨函数中输入与输出的概念。这是学习中痛苦而必要的一环。希望你能在解题中收获一点正反馈。

接下来每一节都会遇到新的一种函数,文中会给出一个例子,请你都想一想如何调用,写出具体调用的例子,然后逐步求值,最后用控制台验证。然后才看答案。就像之前讲x => x * x一样。

例题后面会附上几个练习,请你练习这个 “调用-逐步求值-验证” 过程。你可以多写几个类似的函数,重复这一过程。

练习是很私人的。为了达到最佳效果,最好自己尽力做了练习,再去寻求帮助或解答。

对不同程度的练习,“尽力”的标准不一样。有例题参考的条件下,本篇每道题都不建议花超过五分钟。如果超过了,可以考虑思考的方向对不对。

多个输入

之前的函数,输入数量没有大于一个的。

例题:“调用-逐步求值-验证” 函数(x, y) => x - y

如果想自行做出例题,请及时停止下拉或挡住下方,后续例题也是一样。

先观察函数本身,对比已经熟悉的x => x * x

  • 同样是用箭头=>分隔输入输出;
  • 输入有xy两个,为避免歧义用英文括号包起来,同时用英文逗号,分隔;
  • 输出是x - y

再研究调用,与(x => x * x)(2)的主要区别还是在输入上,((x, y) => x - y)(2, 3)

接着是逐步求值

  1. ((x, y) => x - y)(2, 3)
  2. (x=2, y=3) => x - y
  3. 2 - 3
  4. -1

跟之前一样,也是通过替换输出中的输入求值。

最后通过控制台求值,与上述结果一致
-1

为文章简洁,后续例题仅列出逐步求值过程。

练习:“调用-逐步求值-验证” 如下函数

  1. (y, x) => x - y
  2. (x, y, z) => x / y + y / z - z / x

输出为函数

之前的函数,输出都是数值

例题:“调用-逐步求值-验证” 函数x => (y => x - y)

如果想自行做出例题,请及时停止下拉或挡住下方,后续例题也是一样。

一些初学者一看到两个箭头就慌了,但你只要抓住=>分隔输入输出的定义就行。也就是说,这个函数的输入是x,输出是(y => x - y)。尝试用x调用一次:

  • (x => (y => x - y))(2)
  • (x=2) => (y => x - y)
  • y => 2 - y

输出是个函数,而且如果你在控制台做了这个练习,会得到略微不一样的结果。请以上述逐步求值结果为准。

练习: 逐步求出(x => (y => x - y))(2)(3)的值,并验证结果。

用什么方法可以缓解看起来复杂的问题?一种方法就是命名,给输出的函数命名。比如let f = y => x - y,你可以用这样的思路,再做一次上述练习。

练习:“调用-逐步求值-验证” 如下函数

  • a => b => a + b
  • (x, y) => z => x * z - y

输入为函数

之前的函数,输入都是数值

例题:“调用-逐步求值-验证” 函数let call = (func, x) => func(x),其中func代表函数。

如果想自行做出例题,请及时停止下拉或挡住下方,后续例题也是一样。

  • call(x => x * x, 2)
  • (x => x * x)(2)
  • (x=2) => x * x
  • 2 * 2
  • 4

思考题:

  1. call对应之前讲的哪个概念?
  2. call((x, y) => x + y, (4, 5))符合语法么?如果符合,请逐步求值并验证;如果不符合,要怎样修改call或调用方式?

练习:“逐步求值-验证” 如下调用:

  • call(y => x => x + y, 1)
  • call(x => x * x, call(x => x + 1, 2))

你可以考虑休息一下,后面会更难一些。

输入与输出都是函数

例题:“调用-逐步求值-验证” 函数let compose = (outer, inner) => x => outer(inner(x))

如果喜欢中文:let 组合函数 = (外函数, 内函数) => x => 外函数(内函数(x))

如果想自行做出例题,请及时停止下拉或挡住下方。

  • compose(x => x * x, x => x - 1)(2)
  • (x => x * x) ((x => x - 1)(2))
  • (x => x * x) ((x=2) => x - 1)
  • (x => x * x) ((x=2) => x - 1)
  • (x => x * x) (2 - 1)
  • (x => x * x) (1)
  • (x=1) => x * x
  • 1 * 1
  • 1

思考题:

  • 如何消去 compose并简化 compose(x => x * x, y => y - 1)

练习:“调用-逐步求值-验证” 如下函数

  • compose(y => y * y, z => z - 1)(3)
  • compose(x => x * x, x => x * x)(2)

小结

本文通过一些练习,配上模板化的解法,逐步打磨对函数的理解,尤其是函数作为输入或输出。可以通过目录回顾:

至此,你应当掌握了学习函数的基本概念。

思考题:

  • 你在这两篇文章里见过输入数量为零的函数吗?你觉得还有别的输入或输出类型的函数么?
  • 你更喜欢把这两节讨论的概念叫做“函数”,还是“功能”,为什么?
  • 如果一个人说了一句“玫瑰不叫玫瑰,依然芳香”,然后说叫“函数”还是“功能”都不重要,你认同他的观点么?

下一节是《编程起步:(三) 功能还是函数,这是一个问题》 ,它的末尾附有本节部分思考题答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值