四个程序员的一天

article/2025/9/27 15:46:27

你,一个DotNet程序员,刚刚加入一个新项目组。除了你之外,其他的成员包括:Ceer,一直从事C项目的程序员,他刚刚转入C#不到一个月; Jally,整天抱着本Design Pattern(没错,就是GoF的那本)在啃的前Java程序员;以及Semon,你对他完全不了解,只是听PM介绍说他是搞Scheme的(传说中的第二古老的语言LISP的方言之一)。不过你也没在意,毕竟计算机这玩意,老东西是不吃香的。

周一,刚打开电脑,老板就跑到你们组的办公座面前:“好吧,伙计们,现在有个function需要你们来搞定。具体是这样的:用户输入2个数,并输入一个操作符。你根据输入的情况来得出相应的运算结果。“

Example: Foo(+, 1, 2) = 3; Foo(*, 3, 6) = 18; Foo(/, 2, 4) = 0.5  

Ceer最先作出反应:简单嘛,判断一下输入的操作符就好了。说着,他很快在白板上写出如下代码: 

public class CStyle_Calculator  
{  static public double Foo(char op, double x, double y)  {  switch(op)  case ’+’: return x + y; break;  case ’-’: return x - y; break;  case ’*’: return x * y; break;  case ’/’: return x / y; break;  default: throw new Exception(”What the Hell you have input?");  }  
}  

Jally只看了一遍,就捂着鼻子连连摇头:好一股的代码臭味。还不如看我用OO的方法来解决:

public interface I操作符 //谁说代码不能写中文的?恩恩  
{  double 运算(double x, double y);  
}  
public class OO_Calculator  
{  private I操作符 m_op;  public OO_Calculator(I操作符 op)  {  this.m_op = op; //依赖注入【注2】  }  public double Foo(double x, double y)  {  return this.m_op.运算(x, y);  }  
}  public class 加法:I操作符  
{  public double 运算(double x, double y)  {  return x + y;  }  
}  public class 减法:I操作符  
{  public double 运算(double x, double y)  {  return x - y;  }  
}  public class 乘法:I操作符  
{  public double 运算(double x, double y)  {  return x * y;  }  
}  public class 除法:I操作符  
{  public double 运算(double x, double y)  {  return x / y;  }  
}  public class TheMainClass  
{  static public void Main()  {  I操作符 我的加法 = new 加法();  OO_Calculator 我的加法器 = new OO_Calculator(我的加法);  double sum = 我的加法器.Foo(3, 4);  System.Console.WriteLine(sum);  //sum = 7  //其他3个我就不废话了  }  
}

你看着Jally把白板写得密密麻麻之后,耸耸肩,暗叹,你们这些用java的废柴,就一个运算器还搞出Interface这些东西,烦不烦啊。 让你们见识见识DotNet的强大吧. 那个运算符我直接用delegate传进去不就好了么.
public delegate double TheOperator(double x, double y);  public class Operators  
{  static public double Add(double x, double y)  {  return x + y;  }  static public double Sub(double x, double y)  {  return x - y;  }  //乘,除法 我也懒得废话了  
}  public class DotNet_Calculator  
{  public double Foo(TheOperator op, double x, double y)  {  return op(x, y);  }  
}  public class TheMainClass  
{  static public void Main()  {  TheOperator myAdd = new TheOperator(Operators.Add);  TheOperator mySub = new TheOperator(Operators.Sub);  DotNet_Calculator dc = new DotNet_Calculator();  double sum = dc.Foo(myAdd, 2, 4); //sum = 6  System.Console.WriteLine(sum);  double sub = dc.Foo(mySub, 3, 7); //sub = -4  System.Console.WriteLine(sub);  }  
}  

//dot net 下面还可以用CodeDom动态构造C#代码,然后在内存编译运行。

//如果觉得专门写个Operators很烦的话,可以试试C#2.0的匿名方法 

很好,当你写完代码之后,挑衅的看着Jally,Ceer却开始抱怨起来:”这不就是C里面的函数指针么,我也会...“

“然则DotNet下面的Delegate是类型安全滴...”你继续洋洋得意./

而Semon,看了看你们3位华丽的代码,啥也没说,只是在键盘上敲下了2行代码

(define (Foo op x y)  
(op x y))

然后就下班了...

【注: scheme的代码稍微解释下:(+ 1 2) = 3, (* 3 4) = 12.】

至于Semon的解法:

(define (Foo op x y)  
(op x y))  

看明白了么,上面的代码只有一个作用:第一行是函数头,定义了一个叫Foo的函数。该函数接受3个参数op, x, y。

第二行定义了函数的行为:把第一个参数op当作运算符,计算后面2个参数。

所以:(Foo + 1 2) = 3. (Foo / 12 6) = 2.

好了好了,不编故事了。

我只是想简单的让大家在繁忙的工作之余,也瞅瞅Function Programming(函数编程)世界的美妙。函数编程,最大的特点是它是将函数作为语言里1st class的元素来对待的。一个函数可以接受另一个函数作为参数,也可以把一个函数作为结果来返回。这样的函数我们称为Higher-order function。

那么,Function Programming和我们传统的面向对象有啥区别捏? 恩,这个嘛,扯得远可以扯到图灵机和冯·诺以曼这2种体系的差异...@_@不过那个太学术性,俺就不说了,有时间在『代码之谜』系列文章里面科普吧。不过有句话可以较好的概括FP和OO的区别(好吧,这个也是抄“紫皮书”上面的):

“Pascal是为了建造金字塔...Lisp是为了建造有机体...”“作为Lisp的内在数据结构,表对于这种可用性起着重要的提升作用...”“采用100函数在一个数据结构上操作,远远优于采用10个操作在十个数据结构上工作”“金字塔矗立在那里千年不变,而有机体则必须演化,否则就会消亡”。

而另一个总结得比较好的话是:(同样是抄来的)

一个对象:一组相同的运算上面,外加不同的数据。(想想你的object,是不是这样的?)

一个Closure:一组相同的数据,外加不同的操作。(Delegate就是这样的思想,有兴趣的话也可以去看看Ruby)

基本上,恩,没啥说的了。 如果你感兴趣的话,可以去看MIT SICP的课程(有在线版的,MIT也作为Open Course开设了的) 

原文链接:http://www.cnblogs.com/linkcd/archive/2005/07/19/196087.html


http://chatgpt.dhexx.cn/article/ZswtmWhR.shtml

相关文章

2020年“1024”,程序员日

1024 程 序 员 日 向可爱的程序员致敬 随着时代的发展,大数据技术行业发展愈趋成熟,坚持自己对知识、技术和创新追求的程序员层出不穷。相信很多人都不知道,其实,程序员也有他们自己专属的节日: 程序员日。每个节日都有自己的来历…

【历史上的今天】8 月 20 日:传奇程序员诞生日

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2021 年 8 月 20 日,在科技历史上,有两位对着后世软件工程和电子游戏行业影响深远的人诞生,谷歌也在去年发布了 Pixel 4 系列的新成…

2022年程序员日记

01 月 01 日 做程序员好多年了呢, 想换行。 回车键却坏了。 ** 01 月 10 日 ** 又发了购书卡, 我觉得我需要买《颈椎病康复指南》了, 毕竟, 《沉默的愤怒》刚读完, 而那本《活着》还没到阅读时间。 01 月 11…

【历史上的今天】10 月 24 日:1024 程序员节;中文维基百科上线;苹果发布 iPad mini

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2021 年 10 月 24 日,大概在 2014 - 2015 年间,中国互联网兴起了一个全新的概念:10 月 24 日的程序员节。1024 程序员节是中国程序员…

10·24程序猿节,向用代码改变世界的人致敬!( 文末有彩蛋!)

今天是2021年的10月24日,是中国广大程序员们的共同节日。bug菌今日只字不提技术,就想跟大家一起享受下只属于程序员的节日,宅宅的摊一天,做点自己想做的事,什么临时加班,远程调优,迭代升级等都搁…

透传消息和非透传消息

目前的消息推送方式主要有两种:通知和透传。 什么是透传?透传即是透明传送,即传送网络无论传输业务如何,只负责将需要传送的业务传送到目的节点,同时保证传输的质量即可,而不对传输的业务进行处理。透传消息…

什么是透传模块?为什么要透传?

什么是透传模块 透传模块顾名思义就是透明传输模块,透明传输就是在传输过程中,对外界透明,就是说你看不见他是传送网络,不管传输的业务如何,我只负责将需要传送的业务传送到目的节点,相当于一条数据线或者串…

基于ESP32实现一个WIFI透传模块demo

esp32作为一个热门芯片,网上的文章很多,sdk里的例子和官网的教程也是比较详细。不过作为新玩家,还是要先做一些小改动才更容易入门。所以这里就综合几个example代码,写一个简单的透传demo。 作为一个练手的demo,很多参…

十、stm32-ESP8266(串口透传、MCU透传、控制LED亮灭)

目录 一、固件库模板二、准备资料三、简介1. 引脚2. 无线组网2.1 ESP8266 在 SoftAP 模式2.2 ESP8266 在 station 模式2.3 ESP8266 在 SoftAP station 共存模式 3、透传功能4. 基本配置(所有AT指令都必须换行)4. 模式配置4.1 STA 模式4.2 AP 模式 四、实…

如何用 ESP-AT 进行多种场景下的 UDP 透传

> 此博客将会记录三种不同的测试场景下的 UDP 透传 ESP 设备开启 Wi-Fi AP UDP Server 模式ESP 设备开启 Wi-Fi AP UDP Client 模式ESP 设备开启 Wi-Fi Station UDP Client 模式ESP 设备开启 Wi-Fi Station UDP Server 模式 1 ESP 设备开启 Wi-Fi AP UDP Server 模式 说…

WIFI-TTL透传模块

简介 WiFi-TTL透传模块基于我司DT-ESPC2-12模块研发,引出串口TTL、EN、STATE 等引脚。产品内置我司最新版本的串口透传固件可完成设备TTL 端口到WiFi/云的数据实时透传。本模块可直接取代原有的有线串口,实现嵌入式设备数据采集和控制。 TTL-WiFi 模块…

vue透传

太香了 背景介绍 透传是一个通讯层面的概念,指的是在通讯中不管传输的业务内容如何,只负责将传输的内容由源地址传输到目的地址,而不对业务数据内容做任何改变。 其实透传这个概念,我最早是从上面一个领导那里听到的&#xff0…

Ra-08透传固件应用

目录 1、功能介绍2、硬件接线3、固件烧录4、应用说明指令说明指令使用示例应用示例 5、联系我们 1、功能介绍 Ra-08透传固件主要功能有,设置发送或者接收模式,配置各个射频参数,设置本地地址与发送的目标地址,设置进入睡眠模式等…

EC800G透传模式

透传:指与传输网络的介质、调制解调方式、传输方式、传输协议无关的一种数据传送方式。1.准备 安信可透传云http://netlab.luatos.com/ QCOM_V1.6 LTE Standard TCP/IP 应用指导 2.AT指令格式介绍 2.1场景配置 该命令可用来配置、、以及其他TCP/IP 场景参数。Qo…

【无线通信】一文讲透串口透传

而随着万物互联的深入,想要实现智能设备的通信,串口透传就是一种非常高效的通信方式。 ** 什么是串口透传? ** 透传:透明传输(SerialNet)。即在传输过程中,对外界透明,不管所传输的…

ESP8266配置透传模式(AT指令)

ESP8266使用AT指令的前提是模块已烧录AT固件,固件可以在官网下载,固件烧录这里也直接略过,可以参考其他博文 AT指令恢复出厂设置 用AT指令将ESP8266恢复出厂设置(因为之前配置了什么也不确定,直接恢复出厂&#xff09…

透传,无线透传

透传: 透传,即透明传输,指的是在通讯中不管传输的业务内容如何,只负责将传输的内容由源地址传输到目的地址,而不对业务数据内容做任何改变。 无线透传模块: 透明传输模块,透明传输就是在传输过程中&#x…

关于ESP8266的透传模式测试(一)——TCP Client透传模式

一、前言 本次测试所使用的是正点原子的ATK-ESP8266 WIFI模块。直接使用官方提供的固件使用AT指令来配置模块并使用。 模块默认为AT指令状态,模拟波特率为115200(8bit数据位,1bit停止位)。 硬件连接 使用USB转TTL方式&#xf…

一文了解透传云基础知识

一文了解透传云基础知识 一:透传云定义, 首先了解下透传的定义 透传:透明传输。即在传输过程中,不管所传输的内容、数据协议形式,不对数据做任何处理,只是把需要传输的内容数据传输到目的。 透传云&#xf…