為什麼教小學生x=x+1是錯誤的?淺議少兒編程教育的誤區。

来源:https://www.cnblogs.com/bluedoctor/archive/2020/05/17/12895220.html
-Advertisement-
Play Games

如果因為過早學一樣東西而有損後來的學習成長,那這種學習無異於“揠苗助長”。正是基於這個原因,教會小學生理解x=x+1是有害無益的。 ...


    對程式員而言,類似x=x+1的代碼是再常見不過的了,幾乎所有常見的編程語言教程在開始初級教程的時候,都會拿這個問題的計算來做示例,比如對於C#,會像下麵這樣的代碼:

int x=0;
x=x+1;

    也可以這樣寫:

x+=1;

    也可以像C語言那樣,這樣寫更簡單:

int x=0;
x++;
++x;

    其它編程語言都大同小異了,程式員朋友們都知道上面的代碼無非就是將變數x的值增加了1,或者說為變數x賦了一個比它原來大1的新數值。但是,如果你打算把這行代碼告訴一個小學生,甚至一個初中生,以此想說明coding是多麼簡單就錯了,如果教他學編程,那就是大錯,為什麼要這樣說呢?

     為了這個問題,我將x=x+1這個式子寫給幾個小學生看,他們的第一反應是“這個等式怎麼這樣寫啊?”,“這個式子寫的不對,兩邊不相等!”。我說這不是等式,這表示將變數x的值變大一個數,也就是將變數x的值加1後再賦值給變數x...後面的話沒法繼續進行下去了,小學生的神情是這樣的:

一臉懵逼

     幸好我是在跟中國小朋友交談,如果我給幾個美國小朋友說x=x+1,說不定會有家長控告我“損害了小孩正常的思維邏輯”。(PS:1968年,美國一位母親投訴老師教會了她孩子字母“O”,狀告幼兒園破壞了孩子的想象力,結果幼兒園敗訴。)於是我順著小學生的思路,將這個式子修改成下麵這樣:

y = x + 1

    我問這樣寫你們可以明白嗎?然後他們說這看起來好像是一個方程,但怎麼有2個未知數?我說這的確可以看作是一個方程,到了初中階段,老師會教你們這是“2元1次方程”,上面的等式等同於:

x + 1 -y =0

    這時候有小朋友說我知道了,這叫做“等式變換”。

    我說沒錯,但是寫成y= x + 1 這樣能更好的表示未知數 x 和 y的關係,在這裡這個方程的意思表示未知數y總是比x要大一個數....每當x有一個確定的值,就能得到一個確定的y值,這樣x和y就建立了一種關係,我們稱這種關係為“函數關係”,假設這個函數為f,那麼這個函數關係可以記為:

y=f(x)

    上面的式子表示 y是x的函數,x是自變數,也可以說x是函數f的參數。這個函數的概念將是你們在初中學的內容,比如以後要學的計算三角形問題的三角函數。

    講到這裡,小學生們表示不是很理解了,本來是一個方程,為什麼要提出函數的概念呢?

    於是,我繼續講,請看下麵兩個“方程”有什麼區別?

y = x +1
b = a +1

    有同學說這兩個式子看起來差不多啊,只不過表示未知數的英文字母不同。

    我說是的,在上面的方程中,等式右邊未知數不管用字母x表示,還是用a表示,它們都只是一個符號而已,同樣等式左邊的字母y或者b也都僅僅是一個符號而已,所以上面兩個方程對應的函數可以像下麵這樣表示:

y= x + 1     =>   y=f1(x)=x+1
b= a + 1     =>   b=f2(a)=a+1

    所以不管自變數用哪個英文字母表示,自變數x或者自變數a 都是函數的形式參數,函數計算的結果都是將這個參數值加1後的結果,那麼上面的函數f1或者函數f2本質上都是相同的,也就是函數的名字不是最重要的,重要的是函數的內容,也就是函數如何處理參數,計算結果的過程。當我們不曉得函數應該取什麼名字的時候,我們就叫這個函數為“匿名函數”吧。

    這個時候有同學又問了:既然函數名都不重要了,那對於y=f(x)這個函數關係式,一定需要y嗎?

    這個問題真是棘手,我想了想,說可以不需要y,因為y只是一個符號,用它來綁定這個函數的計算結果而已,比如對比下麵這兩個函數關係式:

y=f(x)
z=f(x)

    此時我很想對小學生們說:“同學,這裡我們可以把上面兩個式子中的y,z都看作一個變數...”,但一想到他們很可能會馬上問什麼是變數、變數跟自變數有啥區別等等新問題就打住了,更不能說可以用變數y來存儲函數f的計算結果,因為在整個中學數學中,就沒有“變數是用來存儲計算結果”這個說法,而是把變數當作是顯式數字一樣,對其進行代數計算的,代數式中有自變數和因變數,現在教小學生程式變數的概念,很可能會誤導他們的數學邏輯思維。如果因為過早學一樣東西而有損後來的學習成長,那這種學習無異於“揠苗助長”,這也是我為何一直不願輕易教授少兒編程的原因。正是基於這個原因,教會小學生理解x=x+1是有害無益的。

 

    上面說不能輕易的教授少兒編程,但不是說一定不能進行少兒編程教學,而是要註意少兒編程語言的選擇,以及教授的方式方法,學習少兒編程的目的是更加有利於學生在學校學校的知識的理解應用,而不是為了編程而學編程,本末倒置。基於這個特點,選擇函數式編程語言而不是命令式語言,就是少兒編程的不二選擇了。Lisp是最古老的編程語言,也是第一個函數式語言,善於處理符號計算問題,Scheme語言是Lisp家族最簡單的方言,特別適合在校學生學校學習編程,理解電腦編程的原理,是MIT的SCIP(Structure and Interpretation of Computer Programs)課程使用的語言。

    下麵,使用Scheme編程語言來幫助學生理解 y=x+1 的問題。

Chez Scheme for Windows. make by bluedoctor. 2019.11.18
Chez Scheme Version 9.5.3
Copyright 1984-2019 Cisco Systems, Inc.

> (define y (+ x 1))
Exception: variable x is not bound
Type (debug) to enter the debugger.
> 

在Scheme中,使用define操作,定義一個變數並且可以將它綁定到一個對象上。上面的代碼

(define y (+ x 1))

本意是想表示本文前面說的等式:

y= x+1

但Scheme的REPL(互動式環境)提示說變數x沒有綁定。註意這裡說變數x沒有綁定,而不是說它沒有定義,實際上變數x是沒有定義的,修改為下麵的程式:

> (define x)
> (define y 1)
> (define y (+ x 1))
Exception in +: #<void> is not a number
Type (debug) to enter the debugger.

上面定義了變數x,但沒有綁定它的初始值,所以認為它是一個沒有任何返回值的過程,而加法操作需要一個數字參數。重新定義變數x並給它綁定一個數值:

> (define x 2)
> (define y (+ x 1))
> y
3

然而上面的變數y並不是一個函數,它只是一個變數,它的值在定義的時候就立刻求值了,之和跟變數x不再有關係。所以上面這段程式仍然無法表達y=x+1的含義。

前面我們說了函數最重要的是函數的定義,而不是它的名字,所以下麵我們直接定義一個計算返回參數x的值加1的結果的匿名函數:

> ((lambda (x) (+ x 1))    
     2)
3
lambda是Scheme中定義函數的操作,它的第一個“參數”是函數的參數,第二個“參數”是函數體(函數操作內容)部分。定義好當前函數後立刻使用一個參數來調用即可計算出函數的值。
我們可以把這個匿名函數綁定給變數y,這樣後續的函數操作就方便了:
> (define y (lambda (x) (+ x 1)))
> y
#<procedure y>
> (y 2)
3
> (define (y x) (+ x 1))
> (y 3)
4
>  

    從上面的代碼可以看到我們有2種定義函數的方式,效果都是一樣的,本質上第二種方式只不過是第一種方式的語法糖。第二種方式:

(define (y x) (+ x 1))

    看起來就是最接近本文的數學方程的程式語言的函數定義了:

y= x + 1

    到這裡,我們不僅僅教會了小學生什麼是函數,也順便用數學中的函數概念,實現了Scheme編程語言的學習,之後就能使用Scheme語言來增強數學的學習了,例如B站有個小學生求解根號6無限開方的問題,傳送門

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要介紹線程的基本概念和意義、多線程程式開發需要註意的問題、創建線程的方式、線程同步、線程通信、線程的生命周期、原子類等java併發編程基礎內容 ...
  • python處理word和excel表格數據 學習過程中遇到批量將excel表格數據填入到word的問題,對於excel的函數使用不是很熟悉,python中有處理word和excel的庫,所以學習使用python實現對數據的批量處理。首先是需要瞭解處理word和excel的具體操作。 python對 ...
  • 手把手教你使用python開發植物大戰僵屍游戲 課程目標 1.掌握python面向對象編程思想 2.熟練python常用編程語法 3.掌握python游戲開發框架pygame ...
  • 20183215 2019 2020 2 《Python程式設計》實驗三報告 課程:《Python程式設計》 班級: 1832 姓名: 董振龍 學號: 20183215 實驗教師:王志強 實驗日期:2020年5月16日 必修/選修:公選課 1.實驗內容 1.創建服務端和客戶端,選擇一個通信埠,用P ...
  • 隨著 Python 在近些年的火爆,網上出現了很多這個方向的公眾號和博客,文章也層出不窮。 受到此風氣的影響,我也把自己“培養”成了一名技術博主,寫作近兩年來,陸陸續續寫過不少的系列文章( "https://shimo.im/docs/6ggy3rRhyOcEu84a" )。 近期看到短視頻火熱起來 ...
  • 學習python和人工智慧的相關課程時安裝了Anaconda3,想在Jupyter notebook中歸納整理筆記,為了方便日後查找想安裝目錄(Table of Contents, TOC)插件,查找了安裝方法,但在 jupyter_contrib_nbextensions插件安裝過程中遇到很多問題 ...
  • 一:流的基本概念: Java中I/O操作主要是指使用Java進行輸入,輸出操作. Java所有的I/O機制都是基於數據流進行輸入輸出,這些數據流表示了字元或者位元組數據的流動序列。Java的I/O流提供了讀寫數據的標準方法。任何Java中表示數據源的對象都會提供以數據流的方式讀寫它的數據的方法。 數據 ...
  • 如何使用Spring Boot發送郵件? Spring Boot為發送郵件提供了starter:spring-boot-starter-mail 。 接下來,我們看看如何用Spring Boot發送郵件。 一、配置郵箱 這裡我們使用163網易郵箱 1.開啟SMTP服務 2.設置/重置客戶端授權密碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...