Programming

데이터베이스와 함수형 프로그래밍이 우연입니까?

procodes 2020. 7. 23. 20:39
반응형

데이터베이스와 함수형 프로그래밍이 우연입니까?


나는 한동안 웹 개발자였으며 ​​최근에 함수형 프로그래밍을 배우기 시작했다. 다른 사람들처럼, 나는이 개념들 중 많은 것을 나의 전문적인 업무에 적용하는 데 큰 어려움을 겪었습니다. 저에게있어 주된 이유는 FP의 무국적 상태 유지라는 목표 사이의 충돌이 내가 수행 한 대부분의 웹 개발 작업이 데이터베이스와 매우 밀접한 관련이 있다는 사실과 매우 상충되는 것입니다. 이는 매우 데이터 중심입니다.

OOP 측면에서 훨씬 생산적인 개발자가 된 한 가지 방법은 MyGeneration d00dads for .Net, Class :: DBI for perl, ActiveRecord for ruby와 같은 객체 관계형 매퍼를 발견하는 것이 었습니다. 하루 종일 insert 및 select 문을 작성하고 객체로 쉽게 데이터 작업에 집중할 수 있습니다. 물론, 나는 그들의 힘이 필요할 때 여전히 SQL 쿼리를 작성할 수 있지만 그렇지 않은 경우에는 배후에서 훌륭하게 추상화되었습니다.

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

(참고로 Weblocks 또는 Links를 매우 자세히 살펴 보지 않았습니다. 사용 방법을 오해했을 수도 있습니다).

따라서 문제는 웹 응용 프로그램의 데이터베이스 액세스 부분 (SQL 라이브러리와의 인터페이스가 필요한 다른 개발) 또는 다른 개발의 경우 다음 경로 중 하나를 강제로 수행하는 것 같습니다.

  1. 함수형 프로그래밍을 사용하지 마십시오
  2. 많은 SQL 또는 SQL과 유사한 코드를 수동으로 작성하는 성가신 방식으로 데이터에 액세스하십시오.
  3. 함수형 언어를 의사 -OOP 패러다임으로 만들면 진정한 함수형 프로그래밍의 우아함과 안정성을 제거 할 수 있습니다.

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

참고 : 저는 개인적으로 FP에서 LISP에 대해 가장 잘 알고 있습니다. 예를 들어 여러 FP 언어를 알고 싶다면 lisp가 선호되는 언어 일 것입니다.

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


우선 CLOS (Common Lisp Object System)가 "pseudo-OO"라고 말하고 싶지는 않습니다. 일류 OO입니다.

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

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

여러 가지 요구 사항이 혼합되어 있다면 패러다임을 혼합하십시오. 도구 상자의 오른쪽 하단 만 사용하도록 제한하지 마십시오.


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

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

데이터베이스는 회사의 생존에 중요한 정보를 보유합니다. 기업이 생존에 문제가 생겼을 때 새로운 방법을 시험해보고 싶지 않다는 것은 놀라운 일입니다. 많은 기업들이 기존 데이터베이스의 새 버전으로 업그레이드하기를 원하지 않습니다. 따라서 데이터베이스 디자인에는 본질적인 보수주의가 있습니다. 그리고 그것은 의도적으로 그런 식입니다.

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


벤 ose 슬리 (Ben Moseley)와 피터 마크 (Peter Marks)의 "타르 구덩이에서 벗어난"(The Tartar Pit) 문서를 참조하십시오.

기능적 관계형 프로그래밍이라는 프로그래밍 패러다임 / 시스템을 자세히 설명하는 최신 고전입니다. 데이터베이스와 직접 관련이 없지만 시스템의 기능적 핵심에서 외부 세계 (예 : 데이터베이스)와의 상호 작용을 분리하는 방법에 대해 설명합니다.

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

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


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

  2. 이름별로 추상 데이터베이스를 오브젝트 세트로 사용하는 여러 ORM을 참조합니다. 사실 이것은 관계형 데이터베이스의 정보가 나타내는 것이 아닙니다! 이름별로 관계형 데이터를 나타냅니다. SQL은 관계형 데이터 세트에서 관계를 처리하기위한 대수 (언어)이며 실제로는 "기능적"입니다. (a) ORM이 데이터베이스 정보를 매핑 할 수있는 유일한 방법은 아니며, (b) SQL은 실제로 일부 데이터베이스 디자인에 매우 유용한 언어이며, (c) 함수형 언어에는 종종 관계형 대수학이 있다는 점을 고려하기 위해이를 제시합니다. 관용적 (및 Haskell의 경우 유형 검사 된) 방식으로 SQL의 힘을 노출하는 매핑

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


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

귀하의 질문에서 주된 문제는 데이터베이스에서 가져온 레코드 기반 데이터를 많은 SQL을 작성하지 않고 lisp-y (lisp-ish?)로 추상화하는 좋은 방법을 찾는 것 같습니다. 암호. 이것은 언어 패러다임의 문제보다는 툴링 / 라이브러리의 문제와 비슷해 보입니다. 순수한 FP를 원한다면 lisp가 올바른 언어가 아닐 수도 있습니다. 일반적인 lisp는 순수한 fp보다는 oo, fp 및 기타 패러다임의 좋은 아이디어를 통합하는 것에 대한 것 같습니다. 순수한 FP 경로를 사용하려면 Erlang 또는 Haskell을 사용해야합니다.

I do think the 'pseudo-oo' ideas in lisp have their merit too. You might want to try them out. If they don't fit the way you want to work with your data you could try creating a layer on top of Weblocks that allows you to work with your data the way you want. This might be easier than writing everything yourself.

Disclaimer: I'm not a Lisp expert. I'm mostly interested in programming languages and have been playing with Lisp/CLOS, Scheme, Erlang, Python and a bit of Ruby. In daily programming life I'm still forced to use C#.


If your database doesn't destroy information, then you can work with it in a functional manner consistent with "pure functional" programming values by working in functions of the entire database as a value.

If at time T the database states that "Bob likes Suzie", and you had a function likes which accepted a database and a liker, then so long as you can recover the database at time T you have a pure functional program that involves a database. e.g.

# 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"

To do this you can't ever throw away information you might use (which in all practicality means you cannot throw away information), so your storage needs will increase monotonically. But you can start to work with your database as a linear series of discrete values, where subsequent values are related to the prior ones through transactions.

This is the major idea behind Datomic, for example.


Not at all. There are a genre of databases known as 'Functional Databases', of which Mnesia is perhaps the most accessible example. The basic principle is that functional programming is declarative, so it can be optimised. You can implement a join using List Comprehensions on persistent collections and the query optimiser can automagically work out how to implement the disk access.

Mnesia is written in Erlang and there is at least one web framework (Erlyweb) available for that platform. Erlang is inherently parallel with a shared-nothing threading model, so in certain ways it lends itself to scalable architectures.


I'm most comfortable with Haskell. The most prominent Haskell web framework (comparable to Rails and Django) is called Yesod. It seems to have a pretty cool, type-safe, multi-backend ORM. Have a look at the Persistance chapter in their book.


A database is the perfect way to keep track of state in a stateless API. If you subscribe to REST, then your goal is to write stateless code that interacts with a datastore (or some other backend) that keeps track of state information in a transparent way so that your client doesn't have to.

The idea of an Object-Relational Mapper, where you import a database record as an object and then modify it, is just as applicable and useful to functional programming as it is to object oriented programming. The one caveat is that functional programming does not modify the object in place, but the database API can allow you to modify the record in place. The control flow of your client would look something like this:

  • Import the record as an object (the database API can lock the record at this point),
  • Read the object and branch based on its contents as you like,
  • Package a new object with your desired modifications,
  • Pass the new object to the appropriate API call which updates the record on the database.

The database will update the record with your changes. Pure functional programming might disallow reassigning variables within the scope of your program, but your database API can still allow in-place updates.


Databases and Functional Programming can be fused.

for example:

Clojure is a functional programming language based on relational database theory.

               Clojure -> DBMS, Super Foxpro
                   STM -> Transaction,MVCC
Persistent Collections -> db, table, col
              hash-map -> indexed data
                 Watch -> trigger, log
                  Spec -> constraint
              Core API -> SQL, Built-in function
              function -> Stored Procedure
             Meta Data -> System Table

Note: In the latest spec2, spec is more like RMDB. see: spec-alpha2 wiki: Schema-and-select

I advocate: Building a relational data model on top of hash-map to achieve a combination of NoSQL and RMDB advantages. This is actually a reverse implementation of posgtresql.

Duck Typing: If it looks like a duck and quacks like a duck, it must be a duck.

If clojure's data model like a RMDB, clojure's facilities like a RMDB and clojure's data manipulation like a RMDB, clojure must be a RMDB.

Clojure is a functional programming language based on relational database theory

Everything is RMDB

Implement relational data model and programming based on hash-map (NoSQL)

참고URL : https://stackoverflow.com/questions/330371/are-databases-and-functional-programming-at-odds

반응형