重温“卡马克谈functional programming in c++”

这里写图片描述
正在准备些关于overwatch的gameplay architecture的blog,里面的观点也让我想起12年时候看的carmack谈的functional programming in c++这个文章。
就回去重温了下,过去了5年,很多地方也有了不同的感触。
原先的blog这里:http://blog.csdn.net/toughbro/article/details/7725450
carmack的原文链接现在不太好访问了,可以看gamasutra上面的转载:http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php

对于state变化的控制和实际情况中的妥协的火候的把握,可以说5年后重读文章最有共鸣的地方。

状态变化,functional programming & OO programming
可以说程序的复杂度和state的变化是非常相关的。
对于state变化的控制力,可以说是程序员对于整个系统控制力最重要的方面之一,而对于state变化模糊不清也是我们程序员会出现大量系统缺陷的重要原因。
而这里,object oriented programming就倾向于把state变化封装起来,而functional programming倾向于将state变化显示呈现,进而增强我们对于state变化的控制力。
这个就是functional programming的力量所在。

所以carmack建议:在可以的情况下,我们应该尽量的使用functional programming去简化程序的复杂度,显示呈现state的变化。
当然这里并不绝对,object oriented programming有它好的地方,我们围绕为什么去鼓励functional programming(显示呈现state变化)来判定应该怎么做就好。

pure function
pure function可以看下专门的wiki:https://en.wikipedia.org/wiki/Pure_function
pure function在c++中并不是一个语法定义,在D语言里倒是有关键字定义。
在carmack这里的定义包括:

  • 只读参数,然后返回结果,不会修改参数
  • 没有自己的内部状态,不修改global变量,不做IO

wiki上面提到一些例子就是像sin(x)这样的函数。
它有这样一些好处:

  • 线程安全,如果参数是value parameter,这就是一个写线程安全代码的非常强大的方式
  • 易读,易测,易懂,易于维护

c++中class的const函数就是非常好的一个关键字,我们应该尽可能多的使用这个,来提升函数的pure性质。

实践中的妥协与不完美
这个部分可以说是5年之后再读的时候发现共鸣最多的部分,道理虽然很棒,但是实际用的时候还是讲求一个火候,纯粹的情况实在太少太少。

绝对pure与比较pure

实际中就是难以做到纯粹,把所有函数那弄成pure function更是不可能。
carmack的看法是把一团乱麻的情况,弄到比较pure这个过程是意义极大的,把比较pure弄到绝对pure意义就有限了,实际项目中,根据具体情况,我们自己把握火候就好。
就像class中的const关键字一样,不一定非得pure functional programming才行,class中使用const的function就让state的变化控制好很多,就已经大大提升了。

性能因素
性能因素也是妥协的一个重要原因,比较典型的functional programming都是返回一个结果的copy,这个在结果是大数据量的时候显然是需要权衡的了。
在性能紧张的情况下,必须要牺牲复杂度来引进性能的因素了。
我个人对此的信条是“以不hack来hack”,就是要尽可能的降低系统的复杂度,尽可能不要hack,然后在一些非常需要hack来获得性能的地方,提供hack的budget。
比如在天刀中,后期做的一个优化就是把entity中的graphic component单独从其他component中提取出来,从:

class Entity
{
component* GetComponent<T>(){}//一个for循环取component
vector<component*> mComponents;
};

到这种专门把graphic component单独处理,因为它明显是读取频率最高的component,做成inline读取,省去了一个带for的function call,性能优势异常的明显

class Entity
{
component* GetComponent<T>(){}//一个for循环取component
component* GetComponent<GraphicComponent> { return mGraphicComponent; }
vector<component*> mComponents;
GraphicComponent* mGraphicComponent;
};

但是这个做法的关键是一定要保证entity实现的复杂度要控制的足够好,否则这样的hack会极大地破坏entity的设计,在关键数据结构上复杂度失控可不是好玩的。
可以说通过良好的实现,积累出一些复杂度余量,然后用在这种能够大量提升性能的地方,但不能多用。

编程多年之后的看点
之前也有和刚工作的同学一起聊编程很多年之后,有什么不一样,看什么的东西。
总体说来很多了,包括不限于:会越来越多的透过具体的技术,做法和语法,更多的关注这种复杂度的控制,state变化的控制,火候的妥协了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Learning C++ Functional Programming by Wisnu Anggoro English | 10 Aug. 2017 | ISBN: 1787281973 | ASIN: B06WVD7CVT | 304 Pages | AZW3 | 2.4 MB Key Features Modularize your applications and make them highly reusable and testable Get familiar with complex concepts such as metaprogramming, concurrency, and immutability A highly practical guide to building functional code in C++ filled with lots of examples and real-world use cases Book Description Functional programming allows developers to divide programs into smaller, reusable components that ease the creation, testing, and maintenance of software as a whole. Combined with the power of C++, you can develop robust and scalable applications that fulfill modern day software requirements. This book will help you discover all the C++ 17 features that can be applied to build software in a functional way. The book is divided into three modules—the first introduces the fundamentals of functional programming and how it is supported by modern C++. The second module explains how to efficiently implement C++ features such as pure functions and immutable states to build robust applications. The last module describes how to achieve concurrency and apply design patterns to enhance your application's performance. Here, you will also learn to optimize code using metaprogramming in a functional way. By the end of the book, you will be familiar with the functional approach of programming and will be able to use these techniques on a daily basis. What you will learn Get to know the difference between imperative and functional approaches See the use of first-class functions and pure functions in a functional style Discover various techniques to apply immutable state to avoid side effects Design a recursive algorithm effectively Create faster programs using lazy evaluation Structure code using design patterns to make the design process easier Use concurrency techniques to develop responsive software Learn how to use the C++ Standard Template Library and metaprogramming in a functional way to improve code optimization About the Author Wisnu Anggoro is a Microsoft Certified Professional in C# programming and an experienced C/C++ developer. He has also authored the books Boost.Asio C++ Network Programming - Second Edition and Functional C# by Packt. He has been programming since he was in junior high school, which was about 20 years ago, and started developing computer applications using the BASIC programming language in the MS-DOS environment. He has solid experience in smart card programming, as well as desktop and web application programming, including designing, developing, and supporting the use of applications for SIM Card Operating System Porting, personalization, PC/SC communication, and other smart card applications that require the use of C# and C/C++. He is currently a senior smart card software engineer at CIPTA, an Indonesian company that specializes in innovation and technology for smart cards. He can be reached through his email at wisnu@anggoro.net. Table of Contents Diving into Modern C++ Manipulating functions in functional programming Applying immutable state to the function Recurring method invocation using recursive algorithm Procrastinating the execution process using Lazy Evaluation Optimizing code with Metaprogramming Running parallel execution using Concurrency Creating and debugging application in functional approach
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值