android 函數式編程_Android開發人員的函數式編程-第1部分

android 函數式編程

by Anup Cowkur

通過安納普·考庫(Anup Cowkur)

Android開發人員的函數式編程-第1部分 (Functional Programming for Android Developers — Part 1)

Lately, I’ve been spending a lot of time learning Elixir, an awesome functional programming language that is friendly to beginners.

最近,我花了很多時間學習Elixir ,這是一種很棒的函數式編程語言,對初學者很友好。

This got me thinking: why not use some of the concepts and techniques from the functional world in Android programming?

這讓我開始思考:為什么不在Android編程中使用功能界的一些概念和技術?

When most people hear the term Functional Programming, they think of Hacker News posts yammering on about Monads, Higher Order Functions and Abstract Data Types. It seems to be a mystical universe far removed from the toils of the daily programmer, reserved only for mightiest hackers descended from the the realm of Númenor.

當大多數人聽到“ 函數式編程 ”一詞時他們會想到Hacker News上有關Monad,高階函數和抽象數據類型的文章。 這似乎是一個神秘的世界,它遠離日常程序員的工作,只保留給Númenor領域的最強大的黑客。

Well, screw that! I’m here to tell you that you too can learn it. You too can use it. You too can create beautiful apps with it. Apps that have elegant, readable codebases and have fewer errors.

好吧, 擰緊 ! 我在這里告訴您您也可以學習它。 您也可以使用它。 您也可以使用它創建漂亮的應用程序。 具有精美易讀的代碼庫且錯誤更少的應用。

Welcome to Functional Programming (FP) for Android developers. In this series, we’re gonna learn the fundamentals of FP and how we can use them in good old Java and new awesome Kotlin. The idea is to keep the concepts grounded in practicality and avoid as much academic jargon as possible.

歡迎使用面向Android開發人員的函數式編程(FP)。 在本系列中,我們將學習FP的基礎知識,以及如何在老式Java和新的Kotlin中使用它們。 這樣做的目的是使概念扎根于實用性,并盡可能避免使用學術術語。

FP is a huge subject. We’re gonna learn only the concepts and techniques that are useful to writing Android code. We might visit a few concepts that we can’t directly use for the sake of completeness but I’ll try to keep the material as relevant as possible.

FP是一個巨大的主題。 我們將僅學習對編寫Android代碼有用的概念和技術。 為了完整起見,我們可能會訪問一些無法直接使用的概念,但我將嘗試使材料盡可能相關。

Ready? Let’s go.

準備? 我們走吧。

什么是函數式編程,為什么要使用它? (What is Functional Programming and why should I use it?)

Good question. The term Functional programming is an umbrella for a range of programming concepts which the moniker doesn’t quite do justice to. At it’s core, It’s a style of programming that treats programs as evaluation of mathematical functions and avoids mutable state and side effects (we’ll talk about these soon enough).

好問題。 “ 函數式編程 ”一詞是一系列編程概念的統稱,綽號并非如此。 從本質上講,這是一種編程風格,將程序視為對數學函數的評估,并避免了可變的狀態副作用 (我們將盡快討論這些問題)。

At it’s core, FP emphasizes :

FP的核心是:

  • Declarative code — Programmers should worry about the what and let the compiler and runtime worry about the how.

    聲明性代碼 -程序員應該擔心什么,而讓編譯器和運行時擔心如何

  • Explicitness — Code should be as obvious as possible. In particular, Side effects are to be isolated to avoid surprises. Data flow and error handling are explicitly defined and constructs like GOTO statements and Exceptions are avoided since they can put your application in unexpected states.

    顯式 -代碼應盡可能明顯。 特別是副作用 應當隔離以避免意外。 明確定義了數據流和錯誤處理,并避免了GOTO語句和異常之類的構造,因為它們會使您的應用程序處于意外狀態。

  • Concurrency — Most functional code is concurrent by default because of a concept known as functional purity. The general agreement seems to be that this trait in particular is causing functional programming to rise in popularity since CPU cores aren’t getting faster every year like they used to (see Moore’s law) and we have to make our programs more concurrent to take advantage of multi-core architectures.

    并發性 -由于稱為功能純度的概念,大多數功能代碼默認情況下是并發的。 普遍的共識似乎是,特別是這種特性正在導致函數式編程的普及,因為CPU內核并沒有像以前那樣每年都在變得更快(請參閱摩爾定律 ),并且我們必須使程序更并發才能利用多核體系結構。

  • Higher Order Functions — Functions are first class members just like all the other language primitives. You can pass functions around just like you would a string or an int.

    高階函數 -就像所有其他語言原語一樣,函數是一等成員。 您可以像傳遞字符串或整數一樣傳遞函數。

  • Immutability — Variables are not to be modified once they’re initialized. Once a thing is created, it is that thing forever. If you want it to change, you create a new thing. This is another aspect of explicitness and avoiding side effects. If you know that a thing cannot change, you have much more confidence about its state when you use it.

    不變性 -變量一旦初始化就不能修改。 一旦創建了事物,它便永遠存在。 如果您要更改它,那么可以創建一個新東西。 這是明確性和避免副作用的另一方面。 如果您知道某事物無法更改,那么使用它時,您對它的狀態就會更有信心。

Declarative, Explicit and Concurrent code that is easier to reason about and is designed to avoid surprises? I hope I’ve piqued your interest.

聲明性,顯式和并發代碼更易于推理并旨在避免意外? 希望我引起了您的興趣。

In this first part of the series, let’s start with some of the most fundamental concepts in FP : Purity, Side effects and Ordering.

在本系列的第一部分中,讓我們從FP中最基本的概念開始: 純度副作用有序性

純功能 (Pure functions)

A function is pure if its output depends only on its input and has no side effects (we’ll talk about the side effects bit right after this). Let’s see an example, shall we?

如果函數的輸出僅取決于其輸入并且沒有副作用 (在此之后再討論副作用),則該函數為純函數。 讓我們看一個例子,好嗎?

Consider this simple function that adds two numbers. It reads one number from a file and the other number is passed in as a parameter.

考慮這個簡單的函數,將兩個數字相加。 它從文件中讀取一個數字,另一個數字作為參數傳遞。

Java

Java

int add(int x) {    int y = readNumFromFile();    return x + y;}

Kotlin

Kotlin

fun add(x: Int): Int {    val y: Int = readNumFromFile()    return x + y}

This function’s output is not dependent solely on its input. Depending on what readNumFromFile() returns, it can have different outputs for the same value of x. This function is said to be impure.

該函數的輸出不僅僅取決于其輸入。 根據readNumFromFile()返回的內容,對于x的相同值,它可以具有不同的輸出。 據說此功能不純凈

Let’s convert it into a pure function.

讓我們將其轉換為純函數。

Java

Java

int add(int x, int y) {    return x + y;}

Kotlin

Kotlin

fun add(x: Int, y: Int): Int {    return x + y}

Now the function’s output is only dependent on its inputs. For a given x and y, The function will always return the same output. This function is now said to be pure. Mathematical functions also operate in the same way. A mathematical functions output only depends on its inputs — This is why functional programming is much closer to math than the usual programming style we are used to.

現在,函數的輸出僅取決于其輸入。 對于給定的xy,該函數將始終返回相同的輸出。 現在據說該功能是函數。 數學函數也以相同的方式運行。 數學函數的輸出僅取決于其輸入-這就是為什么函數編程比我們習慣的常規編程風格更接近數學的原因。

P.S. An empty input is still an input. If a function takes no inputs and returns the same constant every time, it’s still pure.

PS空輸入仍然是輸入。 如果一個函數不接受任何輸入并且每次都返回相同的常量,那么它仍然是純凈的。

P.P.S. The property of always returning the same output for a given input is also known as referential transparency and you might see it used when talking about pure functions.

PPS對于給定輸入始終返回相同輸出的屬性也稱為引用透明性 ,在談論純函數時,您可能會看到它。

副作用 (Side effects)

Let’s explore this concept with the same addition function example. We’ll modify the addition function to also write the result to a file.

讓我們通過相同的加法函數示例來探索這個概念。 我們將修改加法功能以將結果也寫入文件。

Java

Java

int add(int x, int y) {    int result = x + y;    writeResultToFile(result);    return result;}

Kotlin

Kotlin

fun add(x: Int, y: Int): Int {    val result = x + y    writeResultToFile(result)    return result}

This function is now writing the result of the computation to a file. i.e. it is now modifying the state of the outside world. This function is now said to have a side effect and is no longer a pure function.

現在,此功能將計算結果寫入文件。 即它現在正在修改外部世界的狀態。 現在據說該功能具有副作用 ,不再是純功能。

Any code that modifies the state of the outside world — changes a variable, writes to a file, writes to a DB, deletes something etc — is said to have a side effect.

可以修改外部環境狀態的任何代碼(更改變量,寫入文件,寫入DB,刪除某些內容等)都具有副作用。

Functions that have side effects are avoided in FP because they are no longer pure and depend on historical context. The context of the code is not self contained. This makes them much harder to reason about.

FP中避免了具有副作用的功能,因為它們不再是純粹的,而是取決于歷史背景 。 代碼的上下文不是自包含的。 這使得他們很難推理。

Let’s say you are writing a piece of code that depends on a cache. Now the output of your code depends on whether someone wrote to the cache, what was written in it, when it was written, if the data is valid etc. You can’t understand what your program is doing unless you understand all the possible states of the cache it depends on. If you extend this to include all the other things your app depends on — network, database, files, user input and so on, it becomes very hard to know what exactly is going on and to fit it all into your head at once.

假設您正在編寫一段取決于緩存的代碼。 現在,代碼的輸出取決于是否有人向緩存中寫入了內容,寫入了內容,寫入的時間,數據是否有效等。除非您了解所有可能的狀態,否則您將無法理解程序在做什么取決于它的緩存。 如果將其擴展到包括應用程序所依賴的所有其他內容(網絡,數據庫,文件,用戶輸入等),將很難知道到底發生了什么并立即將其全部放入您的腦海。

Does this means we don’t use network, databases and caches then? Of course not. At the end of the execution, you want the app to do something. In the case of Android apps, it usually means updating the UI so that the user can actually get something useful from our app.

這是否意味著我們那時不使用網絡,數據庫和緩存? 當然不是。 在執行結束時,您希望應用程序執行某些操作。 對于Android應用,通常意味著更新UI,以便用戶實際上可以從我們的應用中獲得有用的信息。

FP’s greatest idea is not to completely forego side effects but to contain and isolate them. Instead of having our app littered with functions that have side effects, we push side effects to the edges of our system so they have as little impact as possible, making our app easier to reason about. We’ll talk about this in detail when we explore a functional architecture for our apps later in the series.

FP的最大想法不是完全放棄副作用,而是要遏制和隔離它們。 我們不會在應用程序中散布有副作用的功能,而是將副作用推到系統的邊緣,以使它們的影響盡可能小,從而使我們的應用程序更易于推理。 在本系列后面的內容中,我們將為我們的應用程序探索功能架構時,將對此進行詳細討論。

訂購方式 (Ordering)

If we have a bunch of pure functions that have no side effects, then the order in which they are executed becomes irrelevant.

如果我們有一堆沒有副作用的純函數,那么執行它們的順序就無關緊要了。

Let’s say we have a function that calls 3 pure functions internally:

假設我們有一個內部調用3個純函數的函數:

Java

Java

void doThings() {    doThing1();    doThing2();    doThing3();}

Kotlin

Kotlin

fun doThings() {    doThing1()    doThing2()    doThing3()}

We know for sure that these functions don’t depend on each other (since the output of one is not the input of another) and we also know that they won’t change anything in the system (since they are pure). This makes the order in which they are executed completely interchangeable.

我們確定這些函數不會相互依賴(因為一個函數的輸出不是另一個函數的輸入),并且我們也知道它們不會改變系統中的任何內容(因為它們是純函數)。 這使得它們執行的順序完全可以互換。

The order of execution can be re-shuffled and optimized for independent pure functions. Note that if the input of doThing2() were the result of doThing1() then these would have to be executed in order, but doThing3() could still be re-ordered to execute before doThing1().

可以重新調整執行順序,并針對獨立的純函數進行優化。 需要注意的是,如果doThing2()的輸入是doThing1的結果(),則這些必須以執行,但doThing3()仍然可以重新排序doThing1之前執行()。

What does this ordering property get us though? Concurrency, that’s what! We can run these functions on 3 separate CPU cores without worrying about screwing anything up!

這個訂購屬性讓我們得到什么? 并發,就是這樣! 我們可以在3個獨立的CPU內核上運行這些功能,而不必擔心搞砸了!

In many cases, compilers in advanced pure functional languages like Haskell can tell by formally analyzing your code whether it’s concurrent or not, and can stop you from shooting yourself in the foot with deadlocks, race conditions and the like. These compilers can theoretically also auto-parallelize your code (this doesn’t actually exist in any compiler I know of at the moment but research is ongoing).

在許多情況下,使用Haskell這樣的高級純函數語言的編譯器可以通過形式化分析代碼來判斷代碼是否是并發的,并且可以阻止您死于死鎖,競爭條件等。 從理論上講,這些編譯器還可以自動并行化您的代碼(目前我所知道的任何編譯器中實際上都不存在此代碼,但研究仍在進行中)。

Even if your compiler is not looking at this stuff, as a programmer, it’s great to be able to tell whether your code is concurrent just by looking at the function signatures and avoid nasty threading bugs trying to parallelize imperative code which might be full of hidden side effects.

即使您的編譯器沒有考慮這些問題,作為程序員,也能夠僅通過查看函數簽名來判斷代碼是否是并發的,并且避免討厭的線程錯誤試圖并行化命令性代碼(可能充滿了隱藏的內容),這是很好的。副作用。

摘要 (Summary)

I hope this first part has intrigued you about FP. Pure, Side effect free functions make it much easier to reason about code and are the first step to achieving concurrency.

我希望第一部分對FP感興趣。 純的,無副作用的功能使代碼推理變得更加容易,并且是實現并發的第一步。

Before we get to concurrency though, we have to learn about immutability. We’ll do just that in Part 2 of this series and see how pure functions and immutability can help us write simple and easy to understand concurrent code without resorting to locks and mutexes.

在開始并發之前,我們必須了解不變性 。 我們將在本系列的第2部分中做到這一點,看看純函數和不變性如何能夠幫助我們編寫簡單易懂的并發代碼,而無需借助鎖和互斥體。

Functional Programming for Android developers — Part 2If you haven’t read part 1, please read it here:medium.com

適用于Android開發人員的函數式編程—第2部分 如果您尚未閱讀第1部分,請在此處閱讀: medium.com

If you liked this, click the ? below. I notice each one and I’m grateful for every one of them.

如果喜歡此,請單擊“?”。 下面。 我注意到每個人,我感謝每個人。

For more musings about programming, follow me so you’ll get notified when I write new posts.

有關編程的更多信息,請關注我,以便在我撰寫新文章時得到通知。

翻譯自: https://www.freecodecamp.org/news/functional-programming-for-android-developers-part-1-a58d40d6e742/

android 函數式編程

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395787.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395787.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395787.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java編程 內存_Java編程技術之淺析JVM內存

JVMJVM->Java Virtual Machine:Java虛擬機,是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。基本認知:1.JVM是用于運行Java代碼的假象計算機,主要有一套字節碼指令…

bzoj1116: [POI2008]CLO

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id1116 題目大意:Byteotia城市有n個 towns m條雙向roads. 每條 road 連接 兩個不同的 towns ,沒有重復的road. 你要把其中一些road變成單向邊使得:每個town都有且只有一個入度 題解&am…

java排序算法大全_各種排序算法的分析及java實現

排序一直以來都是讓我很頭疼的事,以前上《數據結構》打醬油去了,整個學期下來才勉強能寫出個冒泡排序。由于要找工作了,也知道排序算法的重要性(據說是面試必問的知識點),所以又花了點時間重新研究了一下。排序大的分類可以分為兩…

Cocos2d-x 3.0 簡捷的物理引擎

Cocos2d-x 3.0 開發(九)使用Physicals取代Box2D和chipmunk http://www.cocos2d-x.org/docs/manual/framework/native/physics/physics-integration/zh -- 官網Demo 水墨魚的專欄 http://www.cocos2d-x.org/docs/catalog/zh --- 官方 搭“server” 須要哪…

google i/o_Google I / O 2017最有希望的突破

google i/oby Aravind Putrevu通過Aravind Putrevu Google I / O 2017最有希望的突破 (The most promising breakthroughs from Google I/O 2017) Google I/O is one of the biggest developer conferences. This year was particularly exciting. There were two keynotes: o…

java clex 中的 IloLPMatrix

最近看 cplex 在 java 的 callback,發現它給的 callback 例子中,都是用 IloLPMatrix 這個類放約束條件,在 IloLPMatrix 中, 每個約束條件存儲在 IloRange 中。 使用 IloLPMatrix 的好處是,這個類可以方便查看模型中的求…

6/12 Sprint2 看板和燃盡圖

轉載于:https://www.cnblogs.com/queenjuan/p/5578551.html

mailto 附帶附件_我和我的朋友如何將附帶項目發展為每月$ 17,000的業務

mailto 附帶附件In 2014, my friends and I set out to build the best possible web design tools. We built UI kits, Admin Dashboards, Templates, and Plugins. We’ve always tried to create products that are helpful in the development process, and that we oursel…

轉:PHP應用性能優化指南

程序員都喜歡最新的PHP 7,因為它使PHP成為執行最快的腳本語言之一(參考PHP 7 vs HHVM 比較)。但是保持最佳性能不僅需要快速執行代碼,更需要我們知道影響性能的問題點,以及這些問題的解決方案。本文涵蓋了保障PHP應用平…

java 運行異常處理_Java編程異常處理和I/O流

重點:  1.在編寫程序時,要正確地使用捕獲例外和聲明拋出異常的兩種例外處理的方法。2.遇到實際問題時,要根據需要正確使用各種輸入/輸出流,特別是對中文使用適當的字符輸入流。3.正…

反射練習

1.反射 一種計算機處理方式。是程序可以訪問、檢測和修改它本身狀態或行為的一種能力。 新建一個Person類: public class Person { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age age; } pu…

開源 物聯網接入_我們剛剛推出了開源產品。 那么接下來會發生什么呢?

開源 物聯網接入by Victor F. Santos由Victor F.Santos 我們剛剛推出了開源產品。 那么接下來會發生什么呢? (We just launched an open source product. So what happens next?) Last month me and the ninja god Pedro launched GitShowcase, a plug-and-play p…

Class? getClass()

getClass()方法屬于Object的一部分,它將產生對象的類,并且在打印該類時,可以看到該類類型的編碼字符串,前導"["表示這是一個后滿緊隨的類型的數組,而緊隨的"I"表示基本類型int, //: initialization/OptionalTrailingArgrments.java package object;import …

log4j使用說明

1.log4j代碼中修改輸出級別:如: protected final Logger logger LoggerFactory.getLogger(Test.class); 將其轉成實現類,修改輸出級別即可System.out.println(logger.isDebugEnabled()?"debug is true":"debug is false&quo…

java list集合增刪改_Java中集合類list的增刪改查

今天給大家帶來的是Java中list類的使用,java.util 包提供了list類來對線性數據操作List接口是Collection接口的子接口,List有一個重要的實現類--ArrayList類,List中的元素是有序排列的而且可重復,所以被稱為是序列List可以精確的控…

IIS6、IIS7和IIS8各版本的差別

一、寫在前面 目前市面上所用的IIS版本估計都是>6.0的.所以我們主要以下面三個版本進行講解 服務器版本IIS默認版本server20036.0server20087.0server20128.0二、IIS6的請求過程 由圖可知,所有的請求會被服務器中的http.sys組件監聽到,它會根據IIS中的 Metabase 查看基于該 …

Android Studio 插件的使用

1、GsonFormat https://github.com/zzz40500/GsonFormat 2、Android SelectorChapek http://blog.csdn.net/weifei554287925/article/details/41727541

函數式編程基礎_在收件箱中免費學習函數式編程的基礎

函數式編程基礎by Preethi Kasireddy通過Preethi Kasireddy 在收件箱中免費學習函數式編程的基礎 (Learn the fundamentals of functional programming — for free, in your inbox) If you’re a software developer, you’ve probably noticed a growing trend: software ap…

安卓Java虛擬機大小_虛擬機為安卓流暢度背鍋,是因為關系數十萬程序員飯碗?...

導讀:虛擬機相當于應用程序在不同運行環境中的翻譯。說起谷歌安卓系統的“虛擬機”,很多人愛拿它和蘋果iOS做比較,結果,安卓的很多短腿兒都讓虛擬機背了鍋,比如安卓手機運存容量是iPhone的兩到三倍,流暢度卻…

Redis PHP連接操作

安裝 要在PHP程序中使用Redis,首先需要確保 Redis 的PHP驅動程序和 PHP 安裝設置在機器上。可以查看 PHP教程 教你如何在機器上安裝PHP。現在,讓我們來看看一下如何設置 Redis 的PHP驅動程序。 需要從 github 上資料庫: https://github.com/n…