2015-10-19 86 views
1

是否有本機語言支持的懶惰評估語法?類似於斯卡拉的lazy val如何在Dart中進行懶惰評估?

我已經通過the docs,找不到任何東西。關於「懶惰地加載一個圖書館」只有一章,但這不是我所要求的。

基於這項研究,我傾向於相信(請糾正我,如果我錯了),目前沒有這樣的事情。但是,也許你知道任何計劃或功能要求將提供功能?或者也許它被Dart團隊考慮並拒絕了?

如果確實沒有本地支持,那麼實現懶惰評估的最佳實踐(最好的語法)是什麼?一個例子,將不勝感激。

編輯:

,我尋找的功能的好處大多是一樣的,在其他語言的實現:Scala's lazy valC#'s Lazy<T>Hack's __Memorize attribute

  1. 簡潔的語法
  2. 延遲計算,直到需要該值
  3. 緩存結果(需要個懶惰)
  4. 不破純功能範式(下面說明)

一個簡單的例子:

class Fibonacci { 

    final int n; 
    int _res = null; 

    int get result { 
    if (null == _res) { 
     _res = _compute(this.n); 
    } 
    return _res; 
    } 

    Fibonacci(this.n); 

    int _compute(n) { 
    // ... 
    } 
} 

main(List<String> args) async { 
    print(new Fibonacci(5).result); 
    print(new Fibonacci(9).result); 
} 

該吸氣劑是非常冗長,並具有重複的代碼。 此外,我不能使構造函數const,因爲緩存變量_res必須按需計算。我想如果我有一個類似於Scala的lazy特性,那麼我也會有一個持久構造函數的語言支持。這是由於事實,懶惰評估_resreferentially transparentwould not be in the way

class Fibonacci { 

    final int n; 
    int lazy result => _compute(this.n); 

    const Fibonacci(this.n); // notice the `const` 

    int _compute(n) { 
    // ... 
    } 
} 

main(List<String> args) async { 
    // now these makes more sense: 
    print(const Fibonacci(5).result); 
    print(const Fibonacci(9).result); 
} 
+0

可以喲請提供一個具體的例子,說明你想用惰性評估來完成什麼。就我所知,沒有特別的語言支持,也沒有關於它的討論。列表,地圖...上的很多方法都是懶惰評估的。例如'map()','fold()','reduce()',...參見http://stackoverflow.com/questions/20491777/dart-fold-vs-reduce。也許只是關閉做你想做的事。 –

回答

1

UPDATE2

從@lrn的評論 - 用在Expando緩存使得它與常量工作:

class Lazy<T> { 
    static final _cache = new Expando(); 
    final Function _func; 
    const Lazy(this._func); 
    T call() { 
    var result = _cache[this]; 
    if (identical(this, result)) return null; 
    if (result != null) return result; 
    result = _func(); 
    _cache[this] = (result == null) ? this : result; 
    return result; 
    } 
} 


defaultFunc() { 
    print("Default Function Called"); 
    return 42; 
} 
main([args, function = const Lazy(defaultFunc)]) { 
    print(function()); 
    print(function()); 
} 

嘗試在DartPad

更新

可重複使用的Lazy<T>在Dart中可能如下所示,但它也不適用於const,如果計算需要引用實例成員(this.xxx),則不能在字段初始值設定項中使用。

void main() { 
    var sc = new SomeClass(); 
    print('new'); 
    print(sc.v); 
} 

class SomeClass { 
    var _v = new Lazy<int>(() { 
    print('x'); 
    return 10; 
    }); 
    int get v => _v(); 
} 

class Lazy<T> { 
    final Function _func; 
    bool _isEvaluated = false; 
    Lazy(this._func); 
    T _value; 
    T call() { 
    if(!_isEvaluated) { 
     if(_func != null) { 
     _value = _func(); 
     } 
     _isEvaluated = true; 
    } 
    return _value; 
    } 
} 

嘗試在DartPad

使用封閉懶惰的 http://matt.might.net/articles/implementing-laziness/

飛鏢版本評價:

void main() { 
    var x =() { 
    print ("foo"); 
    return 10; 
    }(); 
    print("bar"); 
    print(x); 
    // will print foo, then bar then 10. 
    print('==='); 
    // But, the following Scala program: 
    x =() { 
    print("foo"); 
    return 10; 
    }; 
    print ("bar"); 
    print (x()); 
    // will print bar, then foo, then 10, since it delays the computation of x until it’s actually needed. 
} 

嘗試在DartPad

+0

謝謝你的回答。我熟悉你鏈接的這篇文章。這實際上是我在Dart尋找一個好的*懶惰評估*實現的原因之一。你提供的兩個例子都有我嘗試實現的缺陷。無論結果是否被使用,首先計算一次。其次,不能與Dart中的類成員和常量構造函數一起使用。你能看看編輯我的問題嗎? –

+0

我看起來更多一點。有關代碼,請參閱[DartPad](https://dartpad.dartlang.org/a4489204eb37f57ed067)。我不認爲有一種方法可以在Dart中將常量與惰性評估結合使用。 –

+0

Dart中的靜態成員是初始化的,但我想這也僅限於您的需求。 –