스택큐힙리스트

RoundRobin 기능적 접근 - 왜 내 함수에 부작용이 있는 걸까요? 본문

카테고리 없음

RoundRobin 기능적 접근 - 왜 내 함수에 부작용이 있는 걸까요?

스택큐힙리스트 2024. 1. 5. 11:37
반응형

목표


나는 순수 함수적인 방식으로 라운드 로빈 알고리즘( https://en.wikipedia.org/wiki/Round-robin_scheduling )을 만들려고 하고있다.


이 함수는 다음과 같은 배열을 받아들이도록 되어있다:


[
[ 1, 2 ],
[ 3, 4 ]
]

그리고 다음 출력을 생성해야 한다:


[ 1, 3, 2, 4 ]


코드


이를 위해 나는 다음과 같이 재귀적으로 라운드 로빈을 구현하기로 결정했다:


const roundRobin = (arr, results) => {
if (arr.length === 0) return results;
const newResults = arr.reduce((acc, current) => {
if (current.length > 0) {
acc.results.push(current.shift());
acc.arr.push(current);
}
return acc;
}, { arr: [], results });
return roundRobin(newResults.arr, newResults.results);
};

여기서 나는 결과의 배열을 채우고 더 이상 추가할 것이 없을 때까지 종료하는 배열을 작성합니다. 다음과 같이이 코드를 사용합니다:


const array =     [
[ 1, 2 ],
[ 3, 4 ]
];
const result = roundRobin( array, [] );

문제


나는 코드에서 나의 arr 매개 변수에서 reduce를 사용하여 원본을 수정하지 않음을 보장하고 있습니다. 그러나 roundRobin을 사용하기 전과 후에 배열을 인쇄하면 변수가 변경됩니다! 어떻게 해서 그것을 변형하게 되는 것인가요?


질문:



  1. pure한 reduce를 사용하고 있는데, 어떻게 매개 변수를 변형하고 있는 걸까요?

  2. roundRobin을 구현하는 다른 pure/functional한 방법은 있을까요?

답변 1



  1. 만약 나는 순수한 reduce를 사용한다면, 어떻게 매개변수를 변형하고 있나요?



함수 매개변수는 실제로는 변형될 수 없습니다; 이상한 생각이지만, 아마도 당신은 함수에 전달된 인자들이 변형되고 있다는 뜻일 것입니다. 그리고 맞아요, 다른 사람들이 가리킨대로 .shift로 인해 그렇게 됩니다.


그리고 무슨 가치가 있을지 몰라도, 사용자가 제공한 람다가 순수하지 않은 한, .reduce는 순수하지 않습니다.




  1. roundRobin을 구현하는 다른 순수/함수적인 방법이 있나요?





비어 있는지 여부를 확인하는 함수 isEmpty 입니다.

xs.length === 0

첫 번째 요소를 반환하는 함수 head 입니다.
( [ x , ...xs ] ) =>
x

첫 번째 요소를 제외한 나머지 요소들을 반환하는 함수 tail 입니다.
( [ x , ...xs ] ) =>
xs

새로운 요소를 마지막에 추가하는 함수 append 입니다.
( xs , x ) =>
xs.concat ( [ x ] )

roundRobin 함수는 반복적으로 요소를 순환합니다. 함수에 첫 번째 요소를 전달하고 acc 에 결과값을 누적합니다.
( [ x , ...xs ] , acc = [] ) =>
x === undefined
? acc
: isEmpty ( x )
? roundRobin ( xs , acc )
: roundRobin ( append ( xs , tail ( x ) )
, append ( acc , head ( x ) )
)

data 변수에는 다음과 같은 배열이 저장되어 있습니다.
[ [ 1 , 4 , 7 , 9 ]
, [ 2 , 5 ]
, [ 3 , 6 , 8 , 10 , 11 , 12 ]
]

console.log ( roundRobin ( data ) )
// => [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ]

console.log ( roundRobin ( [ [ 1 , 2 , 3 ] ] ) )
// => [ 1 , 2 , 3 ]

console.log ( roundRobin ( [] ) )
// => []


답변 2

라운드로빈(RoundRobin) 기능적 접근법 - 왜 내 함수에 부작용(side effects)이 있는가?
프로그래밍에서 부작용은 함수나 프로시저가 외부에 영향을 주거나 상태를 변경하는 것을 의미합니다. 이는 일부 개발자들에게는 문제가 될 수 있고, 계산의 예측 가능성과 디버깅 가능성을 감소시킬 수 있습니다. 이 글에서는 라운드로빈 기능적 접근법이 왜 부작용을 가지고 있는지 살펴보고자 합니다.
라운드로빈은 CPU 스케줄링 알고리즘 중 하나로, 여러 작업이 동시에 실행되는 시분할 시스템에서 공평하게 CPU 자원을 할당합니다. 이 알고리즘은 각 작업에 정해진 시간 슬라이스를 부여하고, 슬라이스 초과 시 다음 작업으로 이동합니다. 하지만, 라운드로빈 알고리즘을 기능적 접근법으로 구현할 때 부작용이 발생할 수 있습니다.
부작용은 함수의 의도와 다른 결과를 초래하거나, 외부 상태를 변경하는 것입니다. 라운드로빈 구현에서 부작용은 CPU 자원 할당 및 작업 상태 변경과 관련이 있습니다. 라운드로빈 함수는 실행 중인 작업을 결정하고, 작업을 수행하는 동안 시간 슬라이스의 초과 여부를 확인합니다. 이로 인해 CPU 자원의 할당과 작업 상태 변경에 부작용이 발생할 수 있습니다.
예를 들어, 라운드로빈 알고리즘을 통해 CPU 자원이 작업 A에 할당되었다고 가정해 봅시다. 작업 A는 슬라이스만큼의 시간 동안 실행됩니다. 그러나 작업 A가 슬라이스의 초과 여부를 확인하는 과정에서, 작업 B가 불러와야 할 데이터를 수정하는 경우, 작업 B는 부작용에 영향을 받을 수 있습니다. 이로 인해 예상치 못한 결과가 발생하고, 알고리즘의 신뢰성과 예측 가능성을 감소시킬 수 있습니다.
이러한 부작용들은 기능적 접근법으로 해결할 수 있습니다. 함수형 프로그래밍은 외부 상태 변경을 최소화하고, 부작용을 허용하지 않는 것을 목표로 합니다. 라운드로빈 알고리즘을 구현하는데 있어서도 순수 함수(pure function)를 사용하고, 상태 수정을 피함으로써 부작용을 최소화할 수 있습니다.
결론적으로, 라운드로빈 기능적 접근법은 함수의 부작용을 최소화하도록 설계되었습니다. 하지만 CPU 자원 할당 및 작업 상태 변경과 관련된 일부 부작용이 여전히 발생할 수 있습니다. 따라서 기능적 접근법을 사용하여 부작용을 최소화함으로써 알고리즘의 신뢰성을 높이고 예측 가능성을 높일 수 있습니다. 이는 라운드로빈 알고리즘을 구현하는 데 있어서 중요한 고려사항이 될 것입니다.

반응형
Comments