느긋한 계산법
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
느긋한 계산법은 수식의 계산을 필요한 시점까지 늦추는 계산 방식이다. 이는 람다 계산법과 함수형 프로그래밍 언어에서 주로 사용되며, 수식이 변수에 할당될 때가 아닌, 그 값이 실제로 사용될 때 계산을 수행한다. 이 방식을 통해 무한 자료 구조를 다룰 수 있고, 불필요한 계산을 피하여 성능을 최적화할 수 있다. 느긋한 계산법은 하스켈과 같은 언어에서 기본적으로 지원되며, 다른 언어에서는 특수한 구문이나 기법을 통해 구현할 수 있다.
더 읽어볼만한 페이지
- 프로그래밍 계산법 - 조급한 계산법
조급한 계산법은 변수 값 결정 시 수식을 즉시 계산하여 메모리 사용량과 속도를 향상시키는 방식으로, BASIC 코드에서 변수 값을 미리 계산하여 재사용하는 방식으로 활용된다. - 평가 전략 - 식 (프로그래밍)
식(프로그래밍)은 프로그래밍 언어에서 값을 계산하는 데 사용되는 구문 요소이며, 연산자, 피연산자, 함수 호출 등으로 구성되고, 대입은 변수에 값을 할당하는 동작이다. - 평가 전략 - 조급한 계산법
조급한 계산법은 변수 값 결정 시 수식을 즉시 계산하여 메모리 사용량과 속도를 향상시키는 방식으로, BASIC 코드에서 변수 값을 미리 계산하여 재사용하는 방식으로 활용된다. - 컴파일러 최적화 - 데이터 흐름 분석
데이터 흐름 분석은 프로그램의 제어 흐름 그래프를 바탕으로 변수의 정의, 사용, 생존 여부를 분석하며, 전이 함수와 결합 연산을 통해 데이터 흐름 정보를 계산하고 반복적으로 갱신하여 해를 구한다. - 컴파일러 최적화 - 인라인 확장
인라인 확장은 컴파일러가 함수 호출 지점에 함수의 코드를 직접 넣어 실행 속도를 빠르게 하지만 코드 크기가 커지는 단점이 있어 자주 호출되는 작은 함수에 적합한 최적화 기법이다.
느긋한 계산법 |
---|
2. 역사
크리스토퍼 워즈워스가 람다 계산법에 지연 계산법을 도입하였다.[5] 프로그래밍 언어의 경우, 피터 헨더슨과 제임스 H. 모리스[6], 다니엘 P. 프리드먼과 데이비드 S. 와이즈가 독립적으로 도입하였다.[7][8]
지연 평가는 특히 함수형 프로그래밍 언어에서 많이 활용된다. 표현식이 변수에 바인딩될 때 바로 평가되지 않고, 평가자가 표현식의 값을 생성하도록 강요될 때 평가된다. 즉, `x = expression;`과 같이 표현식의 결과를 변수에 할당하는 구문이 있을 때, `x`에 실제로 무엇이 들어 있는지는 나중에 `x`를 참조하여 그 값을 필요로 할 때까지는 중요하지 않다.[9]
3. 응용
어떤 함수를 호출할 때, 그 함수가 인수의 전부를 이용한다고는 할 수 없다. 조건에 따라 버려지는 값을 사전에 준비하는 것은 비효율적이다. 이 경우 지연 평가를 수행하면 필요한 때만 값이 계산되므로 계산량을 줄일 수 있다.
지연 평가는 구현이 어렵고, 계산이 일어나는 시점을 예측하기 어렵다는 약점이 있다.
컴퓨터 윈도잉 시스템에서 화면에 정보를 표시하는 것은 마지막 순간에 디스플레이 코드를 실행하는 '노출 이벤트'에 의해 구동된다. 이를 통해 윈도잉 시스템은 불필요한 디스플레이 콘텐츠 업데이트 계산을 피한다.[14]
현대 컴퓨터 시스템에서 지연 계산의 또 다른 예는 쓰기 시 복사(copy-on-write) 페이지 할당 또는 요청 페이징이며, 메모리에 저장된 값이 변경될 때만 메모리가 할당된다.[14]
3. 1. 제어 구조
느긋한 계산법을 사용하면 if-then-else 및 단락 평가 연산자와 같은 제어 구조를 일반적인 방식으로 정의할 수 있다.[10][11]
하스켈에서는 다음과 같이 정의할 수 있다.
`ifThenElse a b c`는 `a`를 평가한 다음, `a`가 참이면 `b`를, 그렇지 않으면 `c`를 평가한다. 즉, `b` 또는 `c` 중 하나만 평가된다. `EasilyComputed || LotsOfWork`에서 쉬운 부분이 `True`를 반환하면 많은 작업을 하는 식을 피할 수 있다. `SafeToTry && Expression`을 평가할 때 `SafeToTry`가 `false`이면 `Expression`을 평가하지 않는다.
반대로, 적극적인 언어에서는 `ifThenElse a b c`에 대한 위의 정의가 `a`의 값에 관계없이 `a`, `b`, `c`를 모두 평가한다. 이는 `b` 또는 `c`가 부작용을 가지거나, 계산에 시간이 오래 걸리거나, 오류를 발생시킬 수 있기 때문에 바람직하지 않다.
3. 2. 무한 자료 구조
지연 계산법은 계산 가능한 무한 리스트를 생성할 수 있게 한다. 실제 값은 필요할 때만 계산된다. 예를 들어, 피보나치 수의 무한 리스트(종종 스트림이라고 함)를 생성하는 함수를 만들 수 있다. ''n''번째 피보나치 수의 계산은 단순히 무한 리스트에서 해당 요소를 추출하는 것이며, 리스트의 처음 n개 요소만 평가하게 한다.[12][13]
예를 들어, 하스켈에서는 모든 피보나치 수의 목록을 다음과 같이 쓸 수 있다.[13]
```haskell
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
```
하스켈 구문에서 ":
"는 목록에 원소를 첨가하는 것이고, `tail`은 첫 번째 원소를 빼고 리스트를 돌려주며, `zipWith`는 특정한 (여기서는 (+)) 함수를 사용하여 두 목록의 각 원소를 결합하여 세 번째 항목을 생성하도록 한다.[12]
프로그래머가 주의한다면, 특정한 결과값을 생성할 때 필요한 값만 계산한다. 그러나 특정 계산에서 목록의 길이를 구하거나 목록 원소들의 전체 합을 구하는 것과 같이 프로그램에서 무한히 많은 원소를 계산하는 경우라면 계산을 끝내지 못하거나 메모리를 다 쓰게 될 것이다.
3. 3. 기타 활용
컴퓨터 윈도잉 시스템에서 화면에 정보를 표시하는 것은 마지막 순간에 디스플레이 코드를 실행하는 ''노출 이벤트''에 의해 구동된다. 이를 통해 윈도잉 시스템은 불필요한 디스플레이 콘텐츠 업데이트 계산을 피한다.[14]
현대 컴퓨터 시스템에서 지연 계산의 또 다른 예는 쓰기 시 복사(copy-on-write) 페이지 할당 또는 요청 페이징이며, 메모리에 저장된 값이 변경될 때만 메모리가 할당된다.[14]
4. 성능
람다 항을 축소하는 데 필요한 베타 감소 횟수는 값에 의한 호출 또는 이름에 의한 호출 감소에 필요한 횟수보다 크지 않다.[16][17] 특정 프로그램의 경우 단계 수가 훨씬 적을 수 있다. 예를 들어 처치 수를 사용하는 특정 계열의 람다 항은 값에 의한 호출에서는 무한한 횟수의 단계(즉, 완료되지 않음), 이름에 의한 호출에서는 지수적인 횟수의 단계가 걸리지만, 필요에 의한 호출에서는 다항식 횟수의 단계만 걸린다. 필요에 의한 호출은 작업을 반복하지 않고(값에 의한 호출과 유사), 불필요한 작업을 수행하지 않아(이름에 의한 호출과 유사) 최적화되어 있다.[18]
느긋한 계산법은 필요할 때 값을 생성하므로 메모리 사용량을 줄일 수 있다.[19] 하지만, 실제로 느긋한 계산법은 적극적인 계산법에 비해 상당한 성능 문제를 일으킬 수 있다. 예를 들어, 최신 컴퓨터 아키텍처에서는 계산을 지연하고 나중에 수행하는 것이 즉시 수행하는 것보다 느리다. 이는 엄격성 분석을 통해 완화될 수 있다.[18] 느긋한 계산법은 또한 평가되지 않은 표현식으로 인해 메모리 누수를 발생시킬 수 있다.[20]
5. 구현
일부 프로그래밍 언어는 기본적으로 표현식 평가를 지연시키고, 다른 언어는 함수 또는 특수 구문을 통해 평가를 지연시킨다.[9] 미란다와 하스켈에서는 함수 인수 평가가 기본적으로 지연된다.[9] 스킴의 `delay` 및 `force`, OCaml의 `lazy` 및 `Lazy.force`와 같은 특수 구문을 사용하여 계산을 명시적으로 중단하거나,[9] 썽크로 표현식을 감싸서 지연시킬 수 있다.[9]
6. 적극적 계산법과의 관계
하스켈과 같은 느긋한 프로그래밍 언어에서는 표현식이 필요할 때만 평가되지만, 경우에 따라 코드를 더 적극적으로 만들거나 반대로 더 느긋하게 만들 수도 있다. 이는 평가를 강제하는 코드를 작성하거나 피함으로써 가능하다. 엄격성 분석은 컴파일러 최적화의 일종으로, 컴파일러가 값이 항상 사용될 것임을 추론할 수 있게 해준다. 이 경우, 프로그래머가 값을 강제로 평가할지 여부는 엄격성 분석이 엄격한 평가를 강제하기 때문에 무의미해질 수 있다.
하스켈에서 생성자 필드를 엄격하게 표시하면 해당 값은 즉시 요구된다. `seq` 함수를 사용하여 값을 즉시 요구하고 전달할 수도 있는데, 이는 생성자 필드가 느긋해야 하는 경우에 유용하다. 재귀적 엄격성을 위해서는 `deepSeq` 함수를 사용한다. 하스켈 98에서 패턴 매칭은 기본적으로 엄격하며, 느긋하게 만들려면 `~` 한정자를 사용해야 한다.[21]
6. 1. 적극적 언어에서 지연 계산 시뮬레이션
자바에서는 값이 필요할 때 값을 계산하는 메서드를 가진 객체를 사용하여 느긋한 계산을 수행할 수 있다. 람다 표현식이 Java SE8에 도입된 이후로 자바는 이에 대한 간결한 표기법을 지원해 왔다. 다음은 제네릭 인터페이스로 느긋한 계산법을 위한 프레임워크를 제공하는 예시이다.[1]```java
interface Lazy
T eval();
}
```
`eval()` 메서드가 있는 `Lazy` 인터페이스는 `java.util.function` 라이브러리의 `get()` 메서드가 있는 `Supplier` 인터페이스와 동일하다.[1]
`Lazy` 인터페이스를 구현하는 각 클래스는 `eval` 메서드를 제공해야 하며, 클래스의 인스턴스는 느긋한 계산법을 수행하는 데 필요한 모든 값을 가질 수 있다.
자바스크립트에서 느긋한 계산법은 제너레이터를 사용하여 흉내낼 수 있다. 예를 들어, 모든 피보나치 수의 스트림은 메모이제이션을 사용하여 작성할 수 있다.
파이썬 2.x에서 `range()` 함수[26]는 정수 목록을 계산한다. 처음 할당 문이 평가될 때 전체 목록이 메모리에 저장되므로 이는 즉시 또는 조급한 평가의 예이다. 파이썬 3.x에서 `range()` 함수[27]는 필요에 따라 목록의 요소를 계산하는 생성자를 반환한다. 요소는 필요할 때만 생성되므로 이는 느긋하거나 지연된 평가의 예이다.
.NET 프레임워크에서는 `System.Lazy
6. 1. 1. 자바
자바에서는 값이 필요할 때 값을 계산하는 메서드를 가진 객체를 사용하여 느긋한 계산을 수행할 수 있다. 이 메서드의 본문에는 이 계산을 수행하는 데 필요한 코드가 포함되어야 한다. 람다 표현식이 Java SE8에 도입된 이후로 자바는 이에 대한 간결한 표기법을 지원해 왔다. 다음 예시는 제네릭 인터페이스로 느긋한 계산법을 위한 프레임워크를 제공한다.[1]```java
interface Lazy
T eval();
}
```
`eval()` 메서드가 있는 `Lazy` 인터페이스는 `java.util.function` 라이브러리의 `get()` 메서드가 있는 `Supplier` 인터페이스와 동일하다.[1]
`Lazy` 인터페이스를 구현하는 각 클래스는 `eval` 메서드를 제공해야 하며, 클래스의 인스턴스는 느긋한 계산법을 수행하는 데 필요한 모든 값을 가질 수 있다. 예를 들어, 210을 느긋하게 계산하고 출력하는 다음 코드를 고려해 보자.[1]
```java
Lazy
for (int i = 0; i < 10; i++) {
Lazy
a = () -> b.eval() + b.eval();
}
System.out.println("a = " + a.eval());
```
위에서 변수 `a`는 처음에 람다 표현식 `() -> 1`에 의해 생성된 느긋한 정수 객체를 참조한다. 이 람다 표현식을 평가하는 것은 `eval` 메서드가 `1`을 반환하는 `Lazy
루프의 각 반복은 `a`를 루프 내부의 람다 표현식을 평가하여 생성된 새 객체에 연결한다. 이러한 각 객체는 다른 느긋한 객체 `b`에 대한 참조를 유지하고 `b.eval()`을 두 번 호출하고 합계를 반환하는 `eval` 메서드를 갖는다. 변수 `b`는 람다 표현식 내에서 참조되는 변수가 효과적으로 final이 되도록 하는 자바의 요구 사항을 충족하기 위해 여기에 필요하다.[1]
이것은 느긋한 정수의 이 구현이 `eval`에 대한 이전 호출의 결과를 메모이제이션하지 않기 때문에 비효율적인 프로그램이다. 또한 상당한 오토박싱과 언박싱이 포함된다. 명확하지 않을 수 있는 점은 루프가 끝날 때 프로그램이 11개의 객체의 연결 리스트를 구성했으며 결과 계산에 관련된 모든 실제 덧셈이 코드의 마지막 줄에서
a.eval()
을 호출하는 데 대한 응답으로 수행된다는 것이다. 이 호출은 필요한 덧셈을 수행하기 위해 리스트를 재귀적으로 탐색한다.[1]다음과 같이 느긋한 객체를 메모이제이션하는 자바 클래스를 빌드할 수 있다.[1]
```java
class Memo
private Lazy
private T memo; // the memorandum of the previous value
public Memo(Lazy
this.lazy = lazy;
}
public T eval() {
if (lazy != null) {
memo = lazy.eval();
lazy = null;
}
return memo;
}
}
```
이를 통해 이전 예제를 훨씬 더 효율적으로 다시 작성할 수 있다. 원래 반복 횟수에 대해 지수 시간으로 실행되던 것은 메모이제이션된 버전은 선형 시간으로 실행된다.[1]
```java
Lazy
for (int i = 0; i < 10; i++) {
Lazy
a = new Memo
}
System.out.println("a = " + a.eval());
```
자바의 람다 표현식은 단지 구문적 설탕이다. 람다 표현식으로 작성할 수 있는 모든 것은 인터페이스를 구현하는 익명 내부 클래스의 인스턴스를 생성하는 호출로 다시 작성할 수 있으며, 익명 내부 클래스의 모든 사용은 명명된 내부 클래스를 사용하여 다시 작성할 수 있으며, 명명된 내부 클래스는 최외각 중첩 레벨로 이동할 수 있다.[1]
6. 1. 2. 자바스크립트
자바스크립트에서 느긋한 계산법은 제너레이터를 사용하여 흉내낼 수 있다. 예를 들어, 모든 피보나치 수의 스트림은 메모이제이션을 사용하여 다음과 같이 작성할 수 있다.```javascript
/**
- 제너레이터 함수는 느긋한 계산법을 구체화하는 제너레이터 객체를 반환합니다.
- @return {!Generator
} 정수의 널이 아닌 제너레이터입니다. - /
function* fibonacciNumbers() {
let memo = [1n, -1n]; // 초기 상태를 생성합니다(예: "네가피보나치" 수의 벡터).
while (true) { // 무한 반복
memo = [memo[0] + memo[1], memo[0]]; // 각 평가 시 상태를 업데이트합니다.
yield memo[0]; // 다음 값을 생성하고 재개될 때까지 실행을 일시 중지합니다.
}
}
let stream = fibonacciNumbers(); // 숫자의 느긋하게 평가된 스트림을 생성합니다.
let first10 = Array.from(new Array(10), () => stream.next().value); // 처음 10개의 숫자만 평가합니다.
console.log(first10); // 출력은 [0n, 1n, 1n, 2n, 3n, 5n, 8n, 13n, 21n, 34n]입니다.
6. 1. 3. 파이썬
파이썬 2.x에서 `range()` 함수[26]는 정수 목록을 계산합니다. 처음 할당 문이 평가될 때 전체 목록이 메모리에 저장되므로 이는 즉시 또는 조급한 평가의 예입니다.파이썬 3.x에서 `range()` 함수[27]는 필요에 따라 목록의 요소를 계산하는 생성자를 반환합니다. 요소는 필요할 때만 생성되므로 이는 느긋하거나 지연된 평가의 예입니다. 이처럼 느긋한 평가로 변경하면 전체 참조가 되지 않을 수 있는 큰 범위의 실행 시간을 절약하고, 언제든지 하나 또는 소수의 요소만 필요한 큰 범위의 메모리 사용량을 절약할 수 있습니다.
파이썬 2.x에서는 `xrange()`라는 함수를 사용하여 필요에 따라 범위의 숫자를 생성하는 객체를 반환할 수 있습니다. `xrange`의 장점은 생성된 객체가 항상 동일한 양의 메모리를 사용한다는 것입니다.
버전 2.2부터 파이썬은 이터레이터 (느긋한 시퀀스)를 구현하여 느긋한 평가를 나타냅니다.
6. 1. 4. .NET
.NET 프레임워크에서는 `System.LazyF# 코드 예시:
```fsharp
let fibonacci = Seq.unfold (fun (x, y) -> Some(x, (y, x + y))) (0I,1I)
fibonacci |> Seq.nth 1000
```
C# 및 VB.NET에서는 `System.Lazy
C# 코드 예시:
```csharp
public int Sum()
{
int a = 0;
int b = 0;
Lazy
a = 3;
b = 5;
return x.Value; // returns 8
}
```
C#을 이용한 더 실용적인 예제:
```csharp
// n번째 피보나치 수의 재귀적 계산
public int Fib(int n)
{
return (n == 1)? 1 : (n == 2)? 1 : Fib(n-1) + Fib(n-2);
}
public void Main()
{
Console.WriteLine("어떤 피보나치 수를 계산하시겠습니까?");
int n = Int32.Parse(Console.ReadLine());
Lazy
bool execute;
if (n > 100)
{
Console.WriteLine("이것은 시간이 좀 걸릴 수 있습니다. 정말 이 큰 숫자를 계산하시겠습니까? [y/n]");
execute = (Console.ReadLine() == "y");
}
else execute = true;
if (execute) Console.WriteLine(fib.Value); // 숫자는 필요할 때만 계산됩니다.
}
```
`yield` 키워드를 사용하는 C# 예시:
```csharp
// 즉시 계산
public IEnumerable
{
IList
int prev = -1;
int next = 1;
for (int i = 0; i < x; i++)
{
int sum = prev + next;
prev = next;
next = sum;
fibs.Add(sum);
}
return fibs;
}
// 느긋한 계산
public IEnumerable
{
int prev = -1;
int next = 1;
for (int i = 0; i < x; i++)
{
int sum = prev + next;
prev = next;
next = sum;
yield return sum;
}
}
7. 복합 수식
논리식 계산에서 `(a and b)`에서 `a`가 거짓이면 `b`를 계산하지 않아도 전체 식의 결과를 알 수 있다. `(a or b)`에서 `a`가 참인 경우에도 마찬가지이다. 항이 복잡한 식일수록 이점이 크며, 식에서 결과가 참이나 거짓일 가능성과 계산 비용에 따라 어떤 항을 먼저 계산해야 하는지 결정할 수 있다. 예를 들어 `(a or b or c)`와 같은 식에서 `a`가 참일 가능성이 높다면, 전체 식을 쉽게 계산할 수 있다.
산술식 계산에서도 비슷한 접근 방식을 취할 수 있다. 어떤 수에 0을 더하거나, 0이나 1을 곱하는 경우는 특별한 효과가 있다. 그러나 논리값은 참, 거짓 두 가지 값을 가지는 반면, 수는 여러 가지 값을 가질 수 있기 때문에 이러한 특별한 값들을 검사하는 것이 큰 이득이 되지 못할 수 있다.
8. 오류 회피
특정 상황에서 계산 시 오류를 발생시키는 수식은 `(안전한 식 and 수식)` 형태로 보호할 수 있다. 예를 들어 `(N <> 0 and (x mod N = 0))`과 같은 형태는 0으로 나누는 오류를 방지한다. 이러한 방식은 `if N <> 0 then if x mod N = 0 then ...`과 같이 쓸 수도 있지만, 더 간결하게 표현할 수 있다.
좀 더 구체적인 예시로, 뒤쪽에 공백이 있는 텍스트 문자열에서 공백이 아닌 마지막 문자의 위치를 찾는 경우를 생각해 보자.
```
l:=Length(t);
while l > 0 and t(l) = " " do decrement l;
```
위와 같이 작성하면 문자열 전체가 공백일 때 `l`이 0이 되지만, 문자열의 0번째 문자를 읽는 시도는 하지 않으므로 오류를 피할 수 있다.
9. 지연 계산을 지원하는 언어
지연 계산법은 주로 함수형 프로그래밍 언어에서 사용된다. 지연 계산을 사용하면 수식이 변수에 접근하는 순간 계산되는 것이 아니라, 계산값을 출력하라고 강제로 요청할 때까지 계산을 늦춘다. 예를 들어, 'x:=수식;'과 같은 구문에서 x에 들어있는 값은 나중에 참조될 때까지는 계산되지 않는다.
어떤 프로그래밍 언어는 수식 계산을 기본적으로 늦추는 반면, 어떤 언어들은 함수나 특별한 구문을 사용하여 계산을 지연시킨다. 미란다와 하스켈은 기본적으로 계산을 늦춘다. 다른 언어들은 특수한 구문을 사용하거나 성크에 수식을 감싸서 계산을 늦춘다. 예를 들어, 스킴에서는 "delay"와 "force"를 사용하여 이를 명시한다.
지연 계산법을 사용하면 무한 반복이나 크기 문제 없이 계산 가능한 끝없는 목록을 만들 수 있다. 예를 들어, 피보나치 수로 끝없는 목록(보통 스트림이라고 부름)을 만드는 함수를 작성할 수 있다. n번째 피보나치 수는 끝없는 목록에서 해당 원소를 추출하여 간단하게 계산할 수 있으며, 이때 목록의 처음 n개의 수만 계산된다.
하스켈에서의 피보나치 수열 예시는 다음과 같다.
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
하스켈 구문에서 ":
"는 목록에 원소를 추가하는 것이고, tail
은 첫 번째 원소를 제외한 리스트를 반환하며, zipWith
는 특정 함수(여기서는 (+))를 사용하여 두 목록의 각 원소를 결합하여 세 번째 항목을 생성한다.
프로그래머가 주의한다면, 특정 결과값을 생성하는 데 필요한 값만 계산될 것이다. 그러나 목록의 길이를 구하거나 원소들의 합을 구하는 것과 같이 무한히 많은 원소를 계산하는 작업은 프로그램이 계산을 끝내지 못하거나 메모리를 모두 소진할 수 있다.
9. 1. 지연 평가를 원칙으로 하는 언어
컨커런트 클린, 하스켈, 레이지 K는 지연 평가를 원칙으로 하는 프로그래밍 언어이다.[1][2][3]9. 2. 지연 평가를 사양에 정의하는 언어
D 언어, ML, 스칼라, Scheme, 매스매티카참조
[1]
간행물
[2]
서적
Programming language design concepts
https://books.google[...]
John Wiley and Sons
2010-12-30
[3]
간행물
[4]
서적
Writing Efficient Programs
Prentice-Hall
[5]
간행물
[6]
간행물
[7]
간행물
[8]
간행물
[9]
학술회의
A Syntactic Approach to Combining Functional Notation, Lazy Evaluation, and Higher-Order in LP Systems
https://books.google[...]
Springer
2011-01-14
[10]
웹사이트
utility-ht: Data.Bool.HT.Private
https://hackage.hask[...]
2022-01-08
[11]
웹사이트
The Haskell 98 Report: Standard Prelude
https://www.haskell.[...]
2022-01-08
[12]
학술회의
Branching Types
Springer
[13]
학술회의
Eager Haskell: resource-bounded execution yields efficient iteration
Association for Computing Machinery
2002
[14]
기타
Lazy and Speculative Execution
http://research.micr[...]
Microsoft Research
2006-12-12
[15]
웹사이트
Out of memory when assigning values to existing arrays?
http://www.mathworks[...]
MATLAB Central
[16]
서적
Proceedings of the 23rd ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL '96
https://hal.inria.fr[...]
1996
[17]
학술지
Uniform confluence in concurrent computation
https://hal.inria.fr[...]
2000-09
[18]
PhD
Shared-Environment Call-by-Need
https://digitalrepos[...]
University of New Mexico
2019-07
[19]
서적
Programming F#
https://books.google[...]
O'Reilly Media, Inc.
2010-12-31
[20]
기타
Space leak zoo
http://blog.ezyang.c[...]
[21]
웹사이트
Lazy pattern match - HaskellWiki
http://www.haskell.o[...]
[22]
기타
Leveraging Lambda Expressions for Lazy Evaluation in Java
https://4comprehensi[...]
4Comprehension
2018-07-25
[23]
기타
CS:2820 Notes, Fall 2020, Lecture 25
https://homepage.div[...]
2021-01
[24]
기타
Interface Suppier
[25]
서적
"Effective Java: Programming Language Guide"
Addison-Wesley
[26]
웹사이트
2. Built-in Functions — Python 2.7.11 documentation
https://docs.python.[...]
[27]
웹사이트
2. Built-in Functions — Python 3.5.1 documentation
https://docs.python.[...]
[28]
웹사이트
Lazy(T) Class (System)
http://msdn.microsof[...]
Microsoft
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com