"포인트 프리"스타일이란 무엇입니까 (함수 프로그래밍에서)?


103

내가 최근에 눈치 챘던 문구는 "포인트 프리"스타일의 개념입니다 ...

첫째, 거기 질문하고, 이 중 하나 .

다음, 나는 발견 여기 가 언급 "가치가 논의 포인트 무료 스타일의 저자 '싫어하는입니다 될 수있는 또 다른 주제를."

"포인트 프리"스타일이란 무엇입니까? 누군가 간결하게 설명 할 수 있습니까? "자동"카레와 관련이 있습니까?

제 레벨에 대한 아이디어를 얻기 위해-저는 Scheme을 스스로 가르치고 있으며 간단한 Scheme 인터프리터를 작성했습니다. "암시 적"커링이 무엇인지 이해하지만 Haskell이나 ML을 모릅니다.


3
참고 : 왜 포인트 프리 라고 불리는 지 확인 하려면 포인트 프리를 방문 하세요 ./하지만 포인트 프리에는 더 많은 포인트가 있습니다! HaskellWiki에서.
Petr Pudlák 2012 년

답변:


66

그냥 보면 위키 백과 문서 당신의 정의를 얻을 수 :

암묵적 프로그래밍 (점없는 프로그래밍)은 변수 대신 결합 자와 함수 구성 [...]을 사용하여 함수 정의에 인수 관련 정보가 포함되지 않는 프로그래밍 패러다임입니다.

Haskell 예 :

관례 (인수를 명시 적으로 지정) :

sum (x:xs) = x + (sum xs)
sum [] = 0

포인트 프리 ( sum명시적인 인수가 없음 +-0 으로 시작 하는 접힘 ) :

 sum = foldr (+) 0

심지어 간단한 : 대신 g(x) = f(x), 당신은 쓸 수 있습니다 g = f.

예 : 커링 (또는 기능 구성과 같은 작업)과 밀접한 관련이 있습니다.


8
아 알 겠어! 따라서 인수를 선언하는 대신 다른 함수를 결합하여 항상 새 함수를 빌드합니다. 매우 우아합니다!
Paul Hollingsworth

22
프로그래밍 할 때 변수 / 인수에 대한 새 이름을 만들어야하는 것을 정말 싫어합니다. 그것이 내가 포인트 프리 스타일을 좋아하는 큰 이유 중 하나입니다!
Martijn

2
커링과 어떤 관련이 있습니까?
kaleidic

1
@kaleidic : 변수 이름이 없기 때문에 부분적으로 적용된 함수를 구성해야합니다. 이것이 바로 우리가 카레라고 부르는 것입니다 (또는 더 정확하게는 카레를 통해 가능해진 것입니다)
Dario

1
sum (x:xs) ...대신에 의미 하지 sum sum (x:xs) ...않습니까?
Ehtesh Choudhury 2011

33

Point-free 스타일은 정의되는 함수의 인수가 명시 적으로 언급되지 않고 함수가 함수 합성을 통해 정의됨을 의미합니다.

두 가지 기능이있는 경우

square :: a -> a
square x = x*x

inc :: a -> a
inc x = x+1

이 두 함수를를 계산하는 함수에 결합하려면 다음 x*x+1과 같이 "포인트 전체"를 정의 할 수 있습니다.

f :: a -> a
f x = inc (square x)

요점없는 대안은 논쟁에 대해 이야기하지 않는 것입니다 x.

f :: a -> a
f = inc . square

22
어리석게도 Haskell에서 '포인트 프리'방식은 일반적으로 더 뾰족 해 보이는 방식입니다 (더 많은 기간). 이 성가심은 훌륭한 니모닉을 만듭니다. (이 책은 실제 세계 하스켈이에 코멘트.)

3
@Dan 의 의견과 관련하여 Pointfree HaskellWiki 페이지는 왜 pointfree 라고 불리는 지에 대한 설명을 제공합니다 .
Vincent Savard

2
@Dan : Haskell 포인트가 "그 원 연산자"를 의미하기 때문에 어리 석다고 생각하지 않습니다 (그래도 °처럼 보일 것입니다). 그러나 혼란 스럽습니다. 특히 함수형 프로그래밍 언어를 처음 접할 때 그렇습니다. 하스켈에 대한 모든 소개 책은 포인트없는 스타일을 설명해야합니다.
Sebastian Mach

13

JavaScript 샘플 :

//not pointfree cause we receive args
var initials = function(name) {
  return name.split(' ').map(compose(toUpperCase, head)).join('. ');
};

const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0];
const join = m => m.join();

//pointfree
var initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));

initials("hunter stockton thompson");
// 'H. S. T'

참고


5

점없는 스타일은 코드가 인수가 존재하고 사용되고 있더라도 명시 적으로 언급하지 않음을 의미합니다.

이것은 함수가 작동하는 방식 때문에 Haskell에서 작동합니다.

예를 들면 :

myTake = take

하나의 인수를 사용하는 함수를 반환하므로 원하는 경우가 아니면 인수를 명시 적으로 입력 할 이유가 없습니다.


1
때로는 Haskell 98에서 myShow = show. Haskell wiki
Ehtesh Choudhury 2011

-1

다음은 다른 라이브러리가없는 TypeScript의 한 예입니다.

interface Transaction {
  amount: number;
}

class Test {
  public getPositiveNumbers(transactions: Transaction[]) {
    return transactions.filter(this.isPositive);

    //return transactions.filter((transaction: {amount: number} => transaction.amount > 0));
  }

  public getBigNumbers(transactions: Transaction[]) {
    // point-free
    return transactions.filter(this.moreThan(10));

    // not point-free
    // return transactions.filter((transaction: any) => transaction.amount > 10);
  }

  private isPositive(transaction: Transaction) {
    return transactions.amount > 0;
  }

  private moreThan(amount: number) {
    return (transaction: Transaction) => {
      return transactions.amount > amount;
    }
  }
}

포인트없는 스타일이 더 "유창"하고 읽기 쉽다는 것을 알 수 있습니다.


이것은 점없는 스타일이 아니라 람다와 명명 된 함수의 차이 일뿐입니다.
kralyk

@kralyk 나는 당신이 요점을 놓쳤다 고 생각합니다 this.moreThan(10). 명명 된 함수가 아닙니다. 그것은 카레 함수일뿐만 아니라 암시 적으로 (즉, 점이없는) transaction입력으로 취하는 함수입니다 .
AZ.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.