V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
muchan92
V2EX  ›  程序员

为什么非得按顺序写代码?顺序重要吗?

  •  
  •   muchan92 · 15 天前 · 7834 次点击

    是否有人想过,“顺序”是代码非本质复杂性的根源。

    “顺序”是双刃剑,代码量少时方便,一旦程序变大,就会变为“枷锁”,改动一点儿都可能崩塌,而需求变化却是常态。

    真相是,不按照顺序,我们依然可以把逻辑正确描述出来。因为逻辑关系自带方向性,可以自动推导。真正适合顺序的地方是计算过程,而非逻辑。

    打破“顺序枷锁”,才能从根本上提升代码的稳定性和可维护性,不再需要重构。因为“稳定性”,本就不该依赖于天生脆弱的顺序。

    https://github.com/rainforesters/imsure

    github.com/rainforesters/imsure
    // [编译期间]
    // 定义规则,描述依赖关系,与顺序无关
    A = X + Y  ✅
    Y = D - E  ✅
    X = B * C  ✅
    // [运行期间]
    // 可以在任何位置、任何时间进行赋值
    E = 1 // wait 1s
    C = 2 // wait 1s
    B = 3 // wait 1s
    D = 4 // wait 1s
    (A: 9, Y: 3, X: 6)
    
    101 条回复    2025-11-12 09:01:41 +08:00
    1  2  
    w568w
        1
    w568w  
       15 天前   ❤️ 71
    前排提示:OP 是之前那个计算机民间科学家

    历史战绩:

    一种省时省力的编程方式 https://www.sunp.eu.org/t/1121454
    人心中的成见是一座大山 https://www.sunp.eu.org/t/1122487
    我认为促进手机电池 CPU GPU 等硬件发展的好方法是,开发更耗资源的游戏或软件比如微信 https://www.sunp.eu.org/t/1157448
    Leviathann
        2
    Leviathann  
       15 天前
    何意味
    muchan92
        3
    muchan92  
    OP
       15 天前
    @w568w 呵呵
    chendy
        4
    chendy  
       15 天前
    字文的序顺不影响阅读是吧

    道理我都懂,但是乱序执行不是编译器和运行时的事么
    普通人类乱序写代码是想训练 AI 么
    laminux29
        5
    laminux29  
       15 天前
    adoal
        6
    adoal  
       15 天前
    并没有什么非得按顺序写代码。从上层来说,有纯函数式程序设计等范式。从底层来说,有 CPU 乱序执行。只是你不关注罢了。
    Rickkkkkkk
        7
    Rickkkkkkk  
       15 天前
    这就好像你在 21 世纪,去重新研究 18 世纪前人就搞完的数学一样。

    要不先上个大学?
    vfs
        8
    vfs  
       15 天前
    所以你的项目解决了什么问题? 我要如何使用你的项目?
    dog82
        9
    dog82  
       15 天前
    可以,但是会影响编译速度
    muchan92
        10
    muchan92  
    OP
       15 天前
    这是解决数学或乱序执行问题吗?请先搞清楚再说好吧。
    Alias4ck
        11
    Alias4ck  
       15 天前
    goto
    muchan92
        12
    muchan92  
    OP
       15 天前
    @vfs 使用声明式写法,用规则来描述业务逻辑。就像写方程式一样,业务逻辑直接映射为规则,不需要推导,它会自动按正确顺序执行。即使需求变更,也只是调整下规则的依赖关系而已,简单可靠,不会涉及到推翻脆弱的代码顺序。
    villivateur
        13
    villivateur  
       15 天前   ❤️ 1
    您是否在找:HDL
    moudy
        14
    moudy  
       15 天前
    @muchan92 建议去读一下 prolog 语言,然后再读一下 xslt
    NewYear
        15
    NewYear  
       15 天前
    我同意楼主的想法,且感同身受。

    我会写程序,当我成为领导后,再也不关心所谓的顺序写代码。。。
    我乱序的把指令丢给下属。。他会自动的把我的想法用代码描述。。。并自动放在指定的位置。

    乱序编程法,并没有任何问题。
    你只是需要一个中间件,哪怕这个中间件是“人”。
    muchan92
        16
    muchan92  
    OP
       15 天前
    @moudy 我学过,但它们解决的问题并不一样。
    OneLiteCore
        17
    OneLiteCore  
       15 天前
    代码是给机器执行的没错问题是代码也要让人读让人来维护,搞乱顺序或者额外定义一套依赖关系并不会对生产力有任何提升,但是带来的维护问题却是无法忽视的。

    本来大公司的代码就已经是一座屎山了各个年代的代码各种设计模式和写法都有,加上这套玩意不如直接在招聘简章里面要求必须剃光头了。
    CodeCodeStudy
        18
    CodeCodeStudy  
       15 天前
    编译器会重排序的
    muchan92
        19
    muchan92  
    OP
       15 天前
    @villivateur 是 Hardware Description Language 吗?挺好玩,有意思。
    deplives
        20
    deplives  
       15 天前
    请让我尊称您为计算机民间科学家
    BestPix
        21
    BestPix  
       15 天前
    你可以设计一个乱序输入的编辑器,不要顺序打字。
    Gilfoyle26
        22
    Gilfoyle26  
       15 天前
    闭关三年,一日练成,横空出世,整体木瓶,独步天下,拿到江湖一看,是个垃圾。
    muchan92
        23
    muchan92  
    OP
       15 天前
    @OneLiteCore 为什么会错误的以为这会更难维护?实际上这更容易维护。你以为你需要弄懂所有的规则才能写代码、改代码?并非如此,你甚至不需要感知它之前是否有规则,你只需要描述你的规则就好了。就像类型约束一样,假设一个类型为 int64 的变量,它的取值范围从无规则时 64 位,到规则 1 约束 32 位,再到规则 2 约束 16 位。
    Ketteiron
        24
    Ketteiron  
       15 天前
    好奇看了下 demo 给我看晕了。
    这要是真有人用在生产上,怕是一半时间都在 debug 。
    声明式/响应式编程我承认有一定合理性和可行性,本质上是希望将 n²的组合复杂度缩小为 2n ,虽然其实并没有消除任何复杂度。
    muchan92
        25
    muchan92  
    OP
       15 天前
    @Ketteiron 思维惯性的阻力,你若看 prolog 的话会更晕。和上条回复一样,错觉以为这会导致更难 debug ,实际上你几乎不需要 debug 。因为,若定义一条规则把取值范围从 64 位收窄为 16 位,那么它一定会收窄为 16 位,这是确定的肯定不会出错。同理,假设有多条业务规则作用于一个变量上,那么它也是取值收窄的过程,并且每次都是确定的不会出错,由此推及整个程序也是确定的。所以,实际上很少需要 debug 。
    liuchenx
        26
    liuchenx  
       15 天前
    1. 你这解决了什么问题?
    2. 有什么优势?
    就目前发的那个 demo 看不出来什么,连个业务相关的 demo 都没有, 一上来就各种付费,你觉得这里的人谁会上当?
    YUX
        27
    YUX  
    PRO
       15 天前
    zig
    lqs
        28
    lqs  
       15 天前   ❤️ 1
    您是否在找:Microsoft Excel
    maigebaoer
        29
    maigebaoer  
       15 天前 via Android
    Excel 满足你
    muchan92
        30
    muchan92  
    OP
       15 天前
    @liuchenx 有示例 https://github.com/rainforesters/imsure-demo ,按照惯性思维,你可能会觉得难看懂,但要实现相同功能,按传统方式来写代码肯定会复杂得多。你最好先忘掉规则,只把数据结构当做一个普通对象,读写任何属性都是正确的。然后再去看,规则是如何保证属性始终保持正确性的。
    shyling
        31
    shyling  
       15 天前
    因为高级编程语言讲究的就是按人脑思维。

    机器确实不那么 care 顺序,所以这是编译时运行时的优化点。
    muchan92
        32
    muchan92  
    OP
       15 天前
    @lqs
    @maigebaoer
    对啦,终于有人看懂了。它很像 Excel ,但可以用作通用编程,简单、可靠、稳定。
    afirefish
        33
    afirefish  
       15 天前
    上层:依赖倒置,切片编程等都是系统性解决代码可维护性的东西,或许就是你说的非顺序执行?
    下层:微处理器乱序执行(虽然我讲不出原理,但是我知道有这么个东西)
    muchan92
        34
    muchan92  
    OP
       15 天前
    @shyling 有没有可能我们是被“命令式的机器执行思维”限制了原本更人性化的“方程式思维“。
    forisra
        35
    forisra  
       15 天前
    这是特德·姜《你一生的故事》(也就是电影《降临》)里面的七肢桶来地球了?要用非线性语言来给我们使用线性语言的人类大脑升级一下。
    pweng286
        36
    pweng286  
       15 天前
    我怎么记得好像刷到过
    muchan92
        37
    muchan92  
    OP
       15 天前
    @forisra 请问你解决数学问题时是用“算术方法”还是“方程方法”?难道命令式编程不是把业务需求改写为算术过程吗?
    henix
        38
    henix  
       14 天前
    我很喜欢 Makefile ,以前也思考过能否将 Makefile 式的依赖计算引入到编程语言内部
    一个看起来很接近的东西是 Vue 的 Computed Properties ,个人认为在某些场景下还是有用的,比如能自动缓存
    但大多数情况下直接用变量赋值确实是最简单的
    kome
        39
    kome  
       14 天前 via iPhone
    处理器: 我不造啊,我要计算 a-b ,但是 ab 的数据还没送过来呀,c+d 的数据已经送过来了,反正闲着也是闲着,我就先计算 c+d 了。
    340244120w
        40
    340244120w  
       14 天前
    预告后续楼主总篇: 《如何让同事懵逼,让领导抓心:构建代码护城河完全指南》
    muchan92
        41
    muchan92  
    OP
       14 天前
    @340244120w 你认为这会抬高编程门槛?相反这其实会降低编程门槛。我们十几个项目都工作良好,稳定可靠。

    传统思维会认为,在没有完全弄懂程序的所有细节之前是不可能正确修改代码的,因为每一行代码都堆叠在前面的代码之上,移动一点儿都可能崩塌。

    但这种方式不会。你完全不必了解全部规则,也能放心大胆地修改代码,不会出错。为什么呢?举例说明,假设需求变了,要把程序改为 A = X + Z 。你有两个选择:
    一、你开心时,可以找到 A = X + Y 的地方把 Y 换为 Z 就好了;
    二、你不开心时,忘掉之前的 A = X + Y ,管那么多干啥,直接新写一个规则 A = X + Z 把之前所有关于 A 的覆盖掉就好了。

    现在你不必了解全局也可以放心大胆地写代码了。
    因为每一个规则,只关注依赖的变量,但不必关心被依赖的变量在哪儿、何时准备好,仅仅把自己计算正确就行了。当然,被依赖的变量也是如此计算的。

    所以,从方法二可以看出,即使程序迭代了上百次,你也可以完全忽略已有规则,就当它们都不存在,所有变量都是新的,大不了就把新需求从头写一下而已。
    Tink
        42
    Tink  
    PRO
       14 天前
    我看不懂你说的,有实际应用?发个大型一点的 demo 出来看看
    msg7086
        43
    msg7086  
       14 天前
    我怎么感觉类似的东西我大学里写 haskell 的时候就写过了。
    canteon
        44
    canteon  
       14 天前
    你快乐就行
    xtreme1
        45
    xtreme1  
       14 天前
    来碰瓷 pl 领域了, 开始发明 theorem prover 了?
    Coq / Agda 了解一下先
    cocong
        46
    cocong  
       14 天前
    思路听新奇,不过思想上只是一个框架,为何不直接开发一门新的编程语言,那样用起来应该会更简单
    cocong
        47
    cocong  
       14 天前
    思路很新奇,不过实现上只是一个框架,为何不直接开发一门新的编程语言,那样用起来应该会更简单
    cmos
        48
    cmos  
       14 天前
    1. 乱序早几十年就有了。
    2. 至于“语言”的顺序,是为了让人更好的写、读、理解。
    3. 楼主本科哪个学校的?可曾读过什么书?
    4. 一眼就是民科。尤其是这种代码,居然用 js 演示,明显的不是科班出身,至少不懂组成原理和结构。
    phcbest
        49
    phcbest  
       14 天前
    程序员里面的常熟阿诺
    roykingH
        50
    roykingH  
       14 天前
    代码是给人看 不是给机器看的 编译器会优化 你写的顺序未必是机器执行的顺序
    有时间可以看看编译以后的代码长啥样
    rb6221
        51
    rb6221  
       14 天前   ❤️ 1
    额,我就说一个点,如果你觉得你写的东西真的很复杂,能不能像研究生那样写一个详实的几万字论文出来,而不是在帖子里对着回复者说“你不懂,但是我懒得跟你解释,懂的人自然会懂”
    你这样真的是在推广你的理论吗?
    muchan92
        52
    muchan92  
    OP
       14 天前
    @Tink 有示例在 #30
    muchan92
        53
    muchan92  
    OP
       14 天前
    @msg7086 @xtreme1 感觉相似是在声明式和依赖关系,区别在于 Haskell/Coq/Agda 是静态一次性计算,不会动态持续更新。据我目前所知,最接近的是 Excel 。
    @xtreme1 另外,我没碰想瓷任何东西,我承认会有认知局限,感谢你让我了解了 Coq/Agda ,但你若说“碰瓷”Excel/VisiCalc 可能更接近。
    visper
        54
    visper  
       14 天前
    haskell 之类的极端纯函数式编程?全部都是函数定义,最后由一个函数出结果。
    muchan92
        55
    muchan92  
    OP
       14 天前
    @cocong 首先作为库,并且在实际应用中证明这种方案的可行性,远比直接搞一套语言更实际。
    @cmos @roykingH 前面解释过,这并非解决乱序执行问题。关于可读、可写、可维护性见 #41
    chairuosen
        56
    chairuosen  
       14 天前
    “有一部分变量关系声明不需要顺序” 等于 “编程不需要顺序” ?

    先关闭冰箱门,再塞进大象,再打开冰箱门?
    OneLiteCore
        57
    OneLiteCore  
       14 天前
    @muchan92

    这不是 “错误的以为” 而是行业目前的现状,是经受了数十年全球大规模应用部署和验证过的,你应该也知道目前你描述的这种方法并不是被普遍接受的主流对吧。

    项目内业务是会互相耦合的,可能就是你说的逻辑关系或者依赖关系,是这个关系其存在本身错综复杂导致的稳定性和可维护性问题,与是否顺序无关。
    muchan92
        58
    muchan92  
    OP
       14 天前
    @rb6221 我一直在耐心理性解释的吧,从未怼人,哪里有讲过“你不懂,但是我懒得跟你解释,懂的人自然会懂”之类的言论。
    OneLiteCore
        59
    OneLiteCore  
       14 天前
    另外程序执行必定会先有一个起点然后再有一个终点,这注定在时间上是存在线性的顺序关系的,电脑高低要先开机才能关机而无法反过来对吧。
    cocong
        60
    cocong  
       14 天前
    @muchan92 程序员也要用户体验啊,你这几行代码搞定的是写起来那么复杂,谁用啊。
    muchan92
        61
    muchan92  
    OP
       14 天前
    @visper 解释过了在 #53
    xtreme1
        62
    xtreme1  
       14 天前
    @muchan92 #53
    我们要解决的问题是维护程序的正确性.

    大部分现代程序采用的方式是上 unit test, regression test, 上静态分析
    另一条路是写出符合某 specification 的代码, 即 formal verification, 也是你实际上在做的路子.
    这是 cs 中 pl 领域的很大一块, low hanging fruit 基本不存在了. 想入门这块可以从 Software Founditions 和 PLFA 看起.

    所以 #1 说你是计算机民科是毫不夸张的.
    fregie
        63
    fregie  
       14 天前
    我觉得你这玩意的终点是 FLUX 架构:单项数据流,声明式编程
    cenbiq
        64
    cenbiq  
       14 天前
    看了一下你这个项目,似乎是受到 vue 观察机制或者 rxjs 的启发,相当于一个完全使用响应式数据流驱动的概念,但问题是我直接写 vue 全用计算属性,或者直接使用 angular 不好吗?而且你得思考一个问题,所有业务都适合响应式数据流吗?我以前用 angular 时思考过这个问题,个人认为大多数业务不需要使用数据流来处理。
    fregie
        65
    fregie  
       14 天前
    @fregie 这东西在大型项目中确实很好,稳定性好便于维护,代价是提高理解成本和编码量
    sir283
        66
    sir283  
       14 天前   ❤️ 1
    我怎么就想不到这种水贴的方式啊,难怪我的币还是这么少。
    cenbiq
        67
    cenbiq  
       14 天前
    而且你这个所谓“乱序”也就是声明式数据流,复杂度一旦高起来调试会非常困难,我写过数据处理流程相当复杂的 android 项目,完全使用 kotlin Coroutines/Flow ,并且存在一些过度使用 flow 的情况,你知道对复杂的数据流进行调试和不小心搞出来的数据流循环的调试有多麻烦吗?
    muchan92
        68
    muchan92  
    OP
       14 天前
    @OneLiteCore 首先抱歉,我不应该用“错误”而改用“错觉”更合适,后面一条回复就使用了“错觉”。
    其次,你所讲的是业务需求的本质复杂性,它不会被消除,但使用命令式写法会引入更多的非本质复杂性。正如 #41 举例,若按照命令式写法,你首先得在计算 A 之前,先计算出新的 Z ,而 Z 有可能是异步的,所以不得不重新打乱之前已有的同步计算 A 的过程,重构代码。而这种方式则不会,修改局部即只作用于局部。程序维护一次和维护一百次时维护难度是相同的。
    Mark24
        69
    Mark24  
       14 天前
    类似 Mobx
    把 React/Vue 的 响应式 带到 写逻辑中。

    一种发布订阅模型的应用
    unused
        70
    unused  
       14 天前
    第一步:1+1=2
    第二步:付费

    内容没看懂,来个斐波那契数列看看?
    muchan92
        71
    muchan92  
    OP
       14 天前
    @cenbiq 你的几个举例,并非完全“声明式”,它们调试难度就是为了抵消“非完全声明式“所引入的额外难度。递归和循环问题我都遇到过,程序会第一时间指出该问题,不会隐瞒。
    Ketteiron
        72
    Ketteiron  
       14 天前
    @muchan92 #68 缺点是几乎无法正常测试,所有规则都是黑盒,就如#62 说的,可维护性是非常重要的,能保证大型项目能正常迭代。
    你这种做法相当于是放弃了各种测试和静态分析,在组合数量爆炸时虽然不用梳理大量组合逻辑,但是一个规则对其他规则以及集合总体的影响是几乎无法预知的,有好处,也有坏处,在我看来坏处大于好处。
    docx
        73
    docx  
       14 天前 via iPhone
    顺序对机器不太重要,但如果人工要介入 debug 什么的就有得受了
    gaobing
        74
    gaobing  
       14 天前   ❤️ 2
    狭隘了
    老弟
    要我说
    你还得多学学
    你说的顺序
    只是上下行间的顺序
    那你有没有想过
    为什么按照要从左到右的拼写顺序写代码?
    为什么要横着写代码?
    难道代码天生就该依赖
    脆弱的左右拼写顺序和横行顺序?
    我给你演示下什么是好代码。
    打破从左到右的顺序:
    // int a;
    a tni;
    // if (condition) {
    noitidnoc fi {
    // doSomething();
    gnihtemoS od;
    // }
    }

    打破横行的顺序,竖着写代码:
    i i
    n f
    t (
    c
    a o
    = n
    1 d
    ; i
    t
    i
    o
    n
    {

    }

    打破所有顺序,天生强壮的代码:
    ifit}a ={1oc
    ond
    ition doS
    ohi
    ngmet
    muchan92
        75
    muchan92  
    OP
       14 天前
    @docx 实际上 debug 没有想象中那么难,因为若一个值是错误的话,那么它不会传播很远,可能下一个就定位到了。所以,错误不会如想象中那般,传播得非常遥远。
    muchan92
        76
    muchan92  
    OP
       14 天前
    @gaobing 没人逼你非得乱序写代码 A Y X ,你依然可以顺序写 X Y A ,它只是说可以这么写而已。另外,你这样占楼...
    muchan92
        77
    muchan92  
    OP
       14 天前
    @Ketteiron 要写测试很容易,因为它就是一个数据结构,你赋值了某个属性,然后去测试数据是否正确即可,仅此而已。
    nickyadance23
        78
    nickyadance23  
       14 天前
    太好了,我们发现了计算机的终极
    geminikingfall
        79
    geminikingfall  
       14 天前
    @w568w 填补了知乎上说计算机没有民科的空白。
    shouh
        80
    shouh  
       14 天前
    顺序是让自己看得懂而已
    kome
        81
    kome  
       14 天前 via iPhone
    [编译期间]
    def add(x:int,y:int):
    return x+y
    [执行期间]
    x=1
    y=2
    println(add(x,y))

    顺序重不重要?当然重要,不给能源,处理器就无法工作,至于你给处理器什么电路,什么功能,这些在有没有能源面前,屁都不算。
    expy
        82
    expy  
       14 天前
    SQL 了解一下,只管声明想要的结果。
    yxc246800
        83
    yxc246800  
       14 天前
    你认为的顺序只是你的逻辑方式是顺序的,所以写出来的代码是顺序的。
    至于编译器,链接器,执行器如何理解你的代码那就不一定是顺序的了,你理解还只在表面。

    高级语言就是服务于生产者的,如果顺序逻辑是有利于生产者生产的那就是顺序逻辑最合适。
    所以并非是写代码的人选择了顺序写代码,而是代码本身在最表层选择了顺序逻辑
    IndexOutOfBounds
        84
    IndexOutOfBounds  
       14 天前


    不知道有没有描述准确,看起来是有特定场景限制的吧
    dlyxy
        85
    dlyxy  
       14 天前
    "wait 1s"是什么意思,不要性能了?
    lscho
        86
    lscho  
       14 天前
    代码顺序只是解决人类读写问题而已,运行期间又不是按照代码顺序来的

    如果你想反驳没必要顺序,那你为什么在这里回答别人是按顺序来的呢?
    cnhongwei
        87
    cnhongwei  
       14 天前
    这样的代码,不说好不好看懂,就说,如果变量一多,规则一多,出现循环依赖如何调试?如果有一些数据是与时间等外部相关的数据,怎么稳定?
    zacard
        88
    zacard  
       14 天前
    damn !我怎么就想不出这种忽悠付费的方式
    felixcode
        89
    felixcode  
       14 天前
    你先出个编译器或解释器吧,别在这大套的理论,说的越多越民科
    muchan92
        90
    muchan92  
    OP
       14 天前
    @kome @yxc246800 我从未全盘否认顺序,正文说了顺序适合于计算过程,我当然承认它的地位。但它并非没有缺点,如 #41 #68 所述,按命令式方法,除了重构代码,是否还会有更好解决办法。
    muchan92
        91
    muchan92  
    OP
       14 天前
    @IndexOutOfBounds 解释的可以。它是通用编程,没有场景限制,非要说的话,就是写小一点的项目或脚本用命令式方法更简单,中大一些的项目我就会用这种声明式写法。
    v2er119
        92
    v2er119  
       14 天前
    支持一下 OP ,JS 水平比我高,还有开源精神。
    unclejimao
        93
    unclejimao  
       14 天前   ❤️ 1
    @w568w 啊,有一种被剧透的感觉,你坏坏
    shaozelin030405
        94
    shaozelin030405  
       14 天前
    那整体逻辑支持交换律吗
    intmax2147483647
        95
    intmax2147483647  
       14 天前
    哈哈哈哈 这玩意儿能要付费也太离谱了,至少把 README 写完整一点让人知道你的卖点是啥吧
    kome
        96
    kome  
       14 天前 via iPhone
    @muchan92 你说的这东西不就是函数定义么,定义好了扔那就是了,数据啥时候需要处理,啥时候去找函数就是了。不需要了扔,随你删不删;需要修改了,可以修改函数本身,也可以去重新定义一个新的。
    jy02534655
        97
    jy02534655  
       14 天前
    Terry05
        98
    Terry05  
       13 天前
    代码是写给人看的,很多时候代码的重构就是为了增加可读性
    qgmzmy
        99
    qgmzmy  
       13 天前 via iPhone
    何意味
    levelworm
        100
    levelworm  
       13 天前
    你可以不断地 goto 啊?以前写 BASIC 代码就是这样,跳来跳去的,一会自己都晕了。C 也是可以的。
    1  2  
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   3305 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:30 · PVG 19:30 · LAX 03:30 · JFK 06:30
    ♥ Do have faith in what you're doing.