[sql] 데이터베이스와 함수형 프로그래밍이 맞지 않는가?

나는 한동안 웹 개발자였으며 ​​최근에 함수형 프로그래밍을 배우기 시작했습니다. 다른 사람들과 마찬가지로 저는 이러한 개념 중 많은 부분을 전문 작업에 적용하는 데 상당한 어려움을 겪었습니다. 저에게있어 주된 이유는 무국적 상태를 유지하려는 FP의 목표 사이의 충돌이 제가 수행 한 대부분의 웹 개발 작업이 매우 데이터 중심적인 데이터베이스에 크게 묶여 있다는 사실과 상당히 상충되는 것 같습니다.

OOP 측면에서 저를 훨씬 더 생산적인 개발자로 만든 것은 MyGeneration d00dads for .Net, Class :: DBI for perl, ActiveRecord for ruby ​​등과 같은 객체 관계형 매퍼의 발견이었습니다. 하루 종일 insert 및 select 문을 작성하고 데이터를 개체로 쉽게 작업하는 데 집중합니다. 물론 파워가 필요할 때도 SQL 쿼리를 작성할 수 있었지만 그렇지 않으면이면에서 멋지게 추상화되었습니다.

이제 기능 프로그래밍으로 전환하면 링크와 같은 많은 FP 웹 프레임 워크 에서이 예제 와 같이 많은 상용구 SQL 코드를 작성해야하는 것처럼 보입니다 . Weblocks는 조금 더 좋아 보이지만 데이터 작업을 위해 일종의 OOP 모델을 사용하는 것 같으며이 예제 에서와 같이 데이터베이스의 각 테이블에 대해 수동으로 코드를 작성해야합니다 . 이러한 매핑 함수를 작성하기 위해 일부 코드 생성을 사용한다고 가정하지만 이는 확실히 리스프와 같지 않은 것 같습니다.

(참고로 Weblocks 또는 링크를 자세히 살펴 보지 않았습니다. 사용 방법을 오해하고있을 수 있습니다.)

따라서 질문은 웹 응용 프로그램의 데이터베이스 액세스 부분 (매우 큰 것으로 생각됨) 또는 SQL 데이터베이스와의 인터페이스가 필요한 기타 개발의 경우 다음 경로 중 하나를 강제로 내리는 것 같습니다.

  1. 함수형 프로그래밍을 사용하지 마십시오
  2. 많은 수의 SQL 또는 SQL과 유사한 코드를 수동으로 작성해야하는 성가신 비 추상적 인 방식으로 데이터에 액세스합니다.
  3. 함수형 언어를 의사 OOP 패러다임으로 강제하여 진정한 함수형 프로그래밍의 우아함과 안정성을 일부 제거합니다.

분명히 이러한 옵션 중 어느 것도 이상적이지 않습니다. 이러한 문제를 피할 수있는 방법을 찾았습니까? 여기에 정말 문제가 있습니까?

참고 : 저는 개인적으로 FP 전면에서 LISP에 가장 익숙하므로 예제를 제공하고 여러 FP 언어를 알고 싶다면 lisp가 선호되는 언어 일 것입니다.

추신 : 웹 개발의 다른 측면과 관련된 문제는 이 질문을 참조하십시오 .



답변

우선 CLOS (Common Lisp Object System)가 “의사 -OO”라고 말하지 않겠습니다. 일등 OO입니다.

둘째, 필요에 맞는 패러다임을 사용해야한다고 생각합니다.

함수는 데이터의 흐름이며 실제로 상태가 필요하지 않은 동안 상태 비 저장 데이터를 저장할 수 없습니다.

여러 가지 요구 사항이 혼합 된 경우 패러다임을 혼합하십시오. 도구 상자의 오른쪽 아래 모서리 만 사용하도록 제한하지 마십시오.


답변

데이터베이스 전문가의 관점에서 보면 프론트 엔드 개발자는 객체 지향적이거나 기능적이지 않지만 관계형이며 사용하는 데이터베이스를 사용하는 가장 효과적인 방법을 고려하기보다 데이터베이스를 자신의 모델에 맞게 만드는 방법을 찾기 위해 너무 열심히 노력한다는 것을 알았습니다. 세트 이론. 이로 인해 일반적으로 코드 성능이 저하되는 것을 보았습니다. 또한 성능 조정이 어려운 코드를 생성합니다.

데이터베이스 액세스를 고려할 때 데이터 무결성 (모든 비즈니스 규칙이 사용자 인터페이스를 통하지 않고 데이터베이스 수준에서 적용되어야하는 이유), 성능 및 보안이라는 세 가지 주요 고려 사항이 있습니다. SQL은 프런트 엔드 언어보다 처음 두 가지 고려 사항을 더 효과적으로 관리하도록 작성되었습니다. 이를 위해 특별히 설계 되었기 때문입니다. 데이터베이스의 작업은 사용자 인터페이스의 작업과 훨씬 다릅니다. 작업을 관리하는 데 가장 효과적인 코드 유형이 개념적으로 다르다는 것이 놀라운 일입니까?

그리고 데이터베이스는 기업의 생존에 중요한 정보를 보유하고 있습니다. 기업이 생존이 위태로울 때 새로운 방법을 실험하지 않는 것은 놀라운 일입니다. 도대체 많은 기업이 기존 데이터베이스의 새 버전으로 업그레이드하는 것을 꺼려합니다. 따라서 데이터베이스 설계에는 본질적인 보수주의가 있습니다. 그리고 그것은 의도적으로 그런 식입니다.

T-SQL을 작성하거나 데이터베이스 디자인 개념을 사용하여 사용자 인터페이스를 만들려고하지 않습니다. 왜 인터페이스 언어와 디자인 개념을 사용하여 제 데이터베이스에 액세스하려고합니까? SQL이 충분히 화려하지 않다고 생각하기 때문입니까? 아니면 편하지 않습니까? 당신이 가장 편하게 느끼는 모델에 맞지 않는다고해서 그것이 나쁘거나 잘못되었다는 의미는 아닙니다. 그것은 합법적 인 이유로 다르며 아마도 다를 수 있음을 의미합니다. 다른 작업에 다른 도구를 사용합니다.


답변

Ben Moseley와 Peter Marks의 “Out of the Tar Pit”논문을 참조하십시오. “Out of the Tar Pit”(2006 년 2 월 6 일)

Functional-Relational Programming이라는 프로그래밍 패러다임 / 시스템을 자세히 설명하는 현대 고전입니다. 데이터베이스와 직접적으로 관련되지는 않지만 시스템의 기능적 코어에서 외부 세계 (예 : 데이터베이스)와의 상호 작용을 분리하는 방법에 대해 설명합니다.

이 논문은 또한 관계형 데이터베이스와 관련된 관계형 대수를 사용하여 애플리케이션의 내부 상태가 정의되고 수정되는 시스템을 구현하는 방법에 대해서도 설명합니다.

이 백서에서는 데이터베이스와 함수형 프로그래밍을 통합하는 방법에 대한 정확한 답을 제공하지는 않지만 문제를 최소화하는 시스템을 설계하는 데 도움이 될 것입니다.


답변

  1. 기능적 언어는 무국적 상태를 유지하려는 목표가 없으며 상태 관리를 명시 적으로 만드는 목표가 있습니다. 예를 들어, Haskell에서는 State 모나드를 “정상”상태의 핵심으로 간주하고 IO 모나드는 프로그램 외부에 존재해야하는 상태 표현으로 간주 할 수 있습니다. 이 두 모나드는 (a) 상태 저장 작업을 명시 적으로 표현하고 (b) 참조 적으로 투명한 도구를 사용하여 구성함으로써 상태 저장 작업을 구축 할 수 있습니다.

  2. 이름에 따라 데이터베이스를 개체 집합으로 추상화하는 여러 ORM을 참조합니다. 사실 이것은 관계형 데이터베이스의 정보가 나타내는 것이 아닙니다! 이름에 따라 관계형 데이터를 나타냅니다. SQL은 관계형 데이터 세트에 대한 관계를 처리하기위한 대수 (언어)이며 실제로는 그 자체로 상당히 “기능적”입니다. (a) ORM이 데이터베이스 정보를 매핑하는 유일한 방법이 아니라는 점, (b) SQL이 실제로 일부 데이터베이스 디자인에 매우 좋은 언어라는 점, (c) 기능적 언어가 관계형 대수학을 갖는 경우 관용적 (그리고 Haskell의 경우 typechecked) 방식으로 SQL의 힘을 노출하는 매핑.

나는 대부분의 입술이 가난한 사람의 기능적 언어라고 말할 수 있습니다. 현대의 기능 관행에 따라 완전히 사용할 수 있지만 필요하지 않기 때문에 커뮤니티에서 사용할 가능성이 적습니다. 이것은 매우 유용 할 수 있지만 순수한 기능적 인터페이스가 여전히 데이터베이스를 의미있게 사용할 수있는 방법을 확실히 모호하게하는 혼합 된 방법으로 이어집니다.


답변

fp 언어의 상태 비 저장 특성이 데이터베이스 연결 문제라고 생각하지 않습니다. Lisp는 순수하지 않은 함수형 프로그래밍 언어이므로 상태를 다루는 데 문제가 없어야합니다. 그리고 Haskell과 같은 순수 함수형 프로그래밍 언어는 데이터베이스 사용에 적용 할 수있는 입력 및 출력을 처리하는 방법을 가지고 있습니다.

귀하의 질문에 따르면 귀하의 주요 문제는 많은 SQL을 작성하지 않고도 데이터베이스에서 가져온 레코드 기반 데이터를 lisp-y (lisp-ish?)로 추상화하는 좋은 방법을 찾는 데 있습니다. 암호. 이것은 언어 패러다임의 문제 라기보다는 도구 / 라이브러리의 문제처럼 보입니다. 순수한 FP를하고 싶다면 lisp가 당신에게 맞는 언어가 아닐 수도 있습니다. Common lisp는 순수한 fp보다는 oo, fp 및 기타 패러다임의 좋은 아이디어를 통합하는 것에 더 가깝습니다. 순수한 FP 경로로 가고 싶다면 Erlang이나 Haskell을 사용해야 할 것입니다.

나는 lisp의 ‘pseudo-oo’아이디어에도 장점이 있다고 생각합니다. 시도해 볼 수 있습니다. 데이터로 작업하려는 방식에 맞지 않는 경우 Weblocks 위에 원하는 방식으로 데이터를 작업 할 수있는 레이어를 만들 수 있습니다. 이것은 모든 것을 직접 작성하는 것보다 쉬울 수 있습니다.

면책 조항 : 저는 Lisp 전문가가 아닙니다. 저는 주로 프로그래밍 언어에 관심이 있고 Lisp / CLOS, Scheme, Erlang, Python 및 약간의 Ruby를 가지고 놀았습니다. 일상적인 프로그래밍 생활에서 저는 여전히 C #을 사용해야합니다.


답변

데이터베이스가 정보를 파괴하지 않는 경우 전체 데이터베이스의 기능을 값으로 사용하여 “순수 기능”프로그래밍 값과 일치하는 기능적 방식으로 정보를 사용할 수 있습니다.

T 시간에 데이터베이스에 “Bob이 Suzie를 좋아한다”라고 표시되고 데이터베이스와 liker를 수락하는 기능이 있으면 T 시간에 데이터베이스를 복구 할 수있는 한 데이터베이스를 포함하는 순수한 기능 프로그램을 갖게됩니다. . 예 :

# Start: Time T
likes(db, "Bob")
=> "Suzie"
# Change who bob likes
...
likes(db "Bob")
=> "Alice"
# Recover the database from T
db = getDb(T)
likes(db, "Bob")
=> "Suzie"

이를 위해 사용할 수있는 정보를 버릴 수 없으므로 (실용적으로 정보를 버릴 수 없음) 스토리지 요구 사항이 단조롭게 증가합니다. 그러나 후속 값이 트랜잭션을 통해 이전 값과 관련되는 일련의 이산 값으로 데이터베이스 작업을 시작할 수 있습니다.

예를 들어 이것은 Datomic 이면의 주요 아이디어 입니다.


답변

전혀. ‘기능 데이터베이스’라는 장르의 데이터베이스가 있으며, 그중 Mnesia 가 아마도 가장 접근하기 쉬운 예일 것입니다. 기본 원칙은 함수형 프로그래밍이 선언적이므로 최적화 할 수 있다는 것입니다. 영구 컬렉션에서 List Comprehensions 를 사용하여 조인을 구현할 수 있으며 쿼리 최적화 프로그램은 디스크 액세스를 구현하는 방법을 자동으로 해결할 수 있습니다.

Mnesia는 Erlang 으로 작성되었으며 해당 플랫폼에 사용할 수있는 웹 프레임 워크 ( Erlyweb )가 하나 이상 있습니다. Erlang은 본질적으로 비공유 스레딩 모델과 병렬이므로 특정 방식으로 확장 가능한 아키텍처에 적합합니다.