유창한 API에서 자연어 문법 사용


14

WebSQL / Phonegap Database API에 대한 쿼리 추상화를 고민하고 있으며 자연 영어 문법의 사용을 모방하는 유창한 API를 정의하고 의문을 가지고 있습니다.

예제를 통해이를 설명하는 것이 가장 쉬울 수 있습니다. 다음은 내 문법에 유효한 모든 쿼리이며 주석은 의도 된 의미를 설명합니다.

//find user where name equals "foo" or email starts with "foo@"
find("user").where("name").equals("foo").and("email").startsWith("foo@")

//find user where name equals "foo" or "bar"
find("user").where("name").equals("foo").or("bar");

//find user where name equals "foo" or ends with "bar"
find("user").where("name").equals("foo").or().endsWith("bar");

//find user where name equals or ends with "foo"
find("user").where("name").equals().or().endsWith("foo");

//find user where name equals "foo" and email is not like "%contoso.com"
find("user").where("name").equals("foo").and("email").is().not().like("%contoso.com");

//where name is not null
find("user").where("name").is().not().null();

//find post where author is "foo" and id is in (1,2,3)
find("post").where("author").is("foo").and("id").is().in(1, 2, 3);

//find post where id is between 1 and 100
find("post").where("id").is().between(1).and(100);

Quentin Pradet의 피드백을 기반으로 편집 : 또한 API는 복수형과 단수형을 모두 지원해야합니다.

//a equals b
find("post").where("foo").equals(1);

//a and b (both) equal c
find("post").where("foo").and("bar").equal(2);

의문을 제기하기 위해 여기서 가능한 모든 구성을 다 쓰지 않았다고 가정 해 봅시다. 또한 가장 정확한 영어 문장을 다룰 수 있다고 가정 해 봅시다 . 결국 문법 자체는 SQL에 의해 정의 된 동사와 구성으로 제한됩니다.


그룹화 관련 편집 : 하나의 "문장"은 하나의 그룹이며 우선 순위는 SQL에서 정의 된대로 왼쪽에서 오른쪽입니다. 여러 그룹을 여러 where문 으로 표현할 수 있습니다 .

//the conjunctive "and()" between where statements is optional
find("post")
  .where("foo").and("bar").equal(2).and()
  .where("baz").isLessThan(5);

볼 수 있듯이, 각 방식의 정의는 인수 "결합 수단 '을 예를 들어.이 인 문법 문맥에 의존 or()하고 and()어느 탈락 될 수 또는 필드 이름 참조 또는 기대치.

나에게 이것은 매우 직관적으로 느껴지지만 귀하의 의견을 듣고 싶습니다. 이것이 유용하고 유용한 API입니까, 아니면 좀 더 단호한 구현에 역행해야합니까?

레코드의 경우 :이 라이브러리는 구성 객체를 기반으로하는보다 일반적인 비 유량 API도 제공합니다.


1
체인은 또한 jQuery가 매우 유명한 이유이기도합니다. 매우 간단하고 순차적이며 이해할 수 있습니다.
Joseph

3
이것은 흥미 롭다! 프로그래머에게 물어보십시오.
Benjamin Gruenbaum 2016 년

2
그룹화를 어떻게 처리 하시겠습니까? 동등 물 : ... where foo = 1 or (bar = 2 and qux = 3)?

7
유창한 API의 IMO는 끔찍합니다. 예를 들어, 연산자 우선 순위의 부족은 성가신 일입니다. 로 해석 where("name").equals("foo").or("bar")합니다 (name=="foo")or bar. 그러면 문자열이 리터럴을 나타내는 경우와 열 이름을 제공 할 때 명확하지 않습니다.
CodesInChaos

4
btw. 데이터베이스 쿼리에 DSL을 사용하려는 경우 SQL이라는 기존 DSL을 사용할 수 있습니다.
코드 InChaos

답변:


23

나는 그것이 틀렸다고 생각한다. 나는 자연어를 공부하고 상황과 많은 인간 지식으로 만 해결할 수있는 모호성으로 가득합니다. 프로그래밍 언어가 모호하지 않다는 사실은 매우 좋습니다! 문맥에 따라 메소드의 의미를 변경하고 싶지 않다고 생각합니다.

  • 모호함을 가져 오므로 더 많은 놀라움이 추가됩니다.
  • 예를 들어 사용자는 다루지 않은 구성을 사용하려고합니다. find("user").where("name").and("email").equals("foo");
  • 오류를 신고하기가 어렵습니다. 무엇을 할 수 find("user").where("name").not().is().null();있습니까?

또한 가장 정확한 영어 문장을 다룰 수 있다고 가정 해 봅시다. 결국 문법 자체는 SQL에 의해 정의 된 동사와 구성으로 제한됩니다.

아니요, 가장 정확한 영어 문장을 다룰 수는 없습니다. 다른 사람들은 이전에 시도했지만 매우 빨리 복잡해집니다. 자연어 이해 라고 부르지 만 아무도 실제로 시도하지 않습니다. 작은 문제를 먼저 해결하려고합니다. 라이브러리에는 기본적으로 두 가지 옵션이 있습니다.

  • 영어의 하위 집합으로 자신을 제한하거나 SQL을 제공합니다.
  • 또는 "영어"를 다룰 때 언어의 모호성, 복잡성 및 다양성으로 인해 불가능하다는 것을 알게됩니다.

입력 해 주셔서 감사합니다. 첫 번째 사례를 다루기 위해 내 질문을 수정하고 몇 가지 경고를 추가했습니다. 나는 모호함에 대한 당신의 입장에 동의합니다-그것은 내 질문의 요점입니다. 잘 정의 된 상황에서 프로그래밍 언어가 모호 할 수 있습니까?
fencliff

모호한 경우 잘 정의되지 않은 것입니다. 모호한 경우 둘 이상의 잠재적 결과가 있으며 무언가가 그중 하나를 선택해야합니다. 선택이 잘 정의되어 있거나 언어 파서가 임의로 선택합니다. 따라서 결정 론적 (1 + 1은 항상 2)과 달리 확률 론적 언어 (1 + 1은 2, 때로는 1 또는 3)를 원한다면 프로그래밍 언어의 모호성은 괜찮습니다.
Michael Paulukonis 2016 년

그의 제안이나 영어에 대해 이야기하고 있습니까? 대부분의 경우, 애매 모호함은 컴퓨터에서 사용할 수없는 문맥 및 / 또는 지식 (일부는 상식)을 사용하여 해결할 수 있습니다.
Quentin Pradet

+1 유창한 API의 특정 구현에 대한 문맥 민감도를 잘 파악합니다. 나는 유창한 API에 대한 아이디어를 처음에는 좋아했지만 이것을 자세히 보지 않았습니다. 확실히 큰 문제.
Jimmy Hoffa

그가 문법을 모호하지 않고 문맥을 자유롭게한다면 문제는 무엇입니까? 그들은 복수형 구절의 단수형 동사와 그와 같은 것들을 제거하고 싶을 지 모르지만 그들이하려는 행동의 핵심을 바꾸지는 않습니다. 당신은하지 않았을 is()또는 equal()단지 equals(). 이후 오류보고와 관련된 문제가 표시되지 않습니다. null()또한 구문 함수가 아닌 비교할 리터럴이됩니다. find("user").where("name").is().not().null();가된다find("user").where("name").not().equals(null);
WHN

3

나는 이것이 훌륭한 디자인이 아니라는 다른 사람들의 게시물에 다소 동의하는 경향이 있습니다. 그러나 나는 다른 이유가 있다고 생각합니다.

SQL 쿼리에 대한 구체적인 구문으로 보는 것을 제시합니다. 구체적인 구문 은 언어를 도울 수 없으며 언어가 나쁜 경우에만 상처를 줄 수 있다고 생각합니다 .

그러나 추상 구문 은 다른 이야기입니다. 추상 구문은 언어 구조와 구문을 결합하여 더 큰 구문을 만드는 방법을 정의합니다. 언어의 성공은 추상 구문 정의의 품질에 크게 좌우된다고 생각합니다.

유창한 API에 대한 나의 문제는 모호하거나 불분명하거나 표현 적이 지 않다는 것이 아닙니다. 실제 언어와 구조를 숨기고, 그렇게함으로써 실제보다 훨씬 복잡하게 만드는 것입니다. 모호성, 명백하지 않은 구문 오류 등을 도입함으로써).

"보다 일반적인 API"도 제공한다고 언급 했으므로이 모든 것을 이미 알고있는 것처럼 들립니다. 그것에 나는 "좋은!" 그렇다고해서 유창한 API를 동시에 개발할 수는 없습니다! 단일 추상 구문 정의는 여러 가지 구체적인 구문을 지원할 수 있습니다. 추상 구문이 실제로 중요하다는 점을 명심해야하지만 구체적인 구문도 매우 유용 할 수 있습니다.


2

Quentin Pradet의 장점 외에도이 언어의 이점이 의심됩니다.

아마도 자연어에 가까운 문법의 요점은 그것을 접근 가능하게 만드는 것입니다. 그러나 SQL은 이미 자연 언어에 매우 가깝습니다. 이 중 하나가 다른 것보다 영어에 더 가깝습니까?

find("user").where("name").equals("foo")

select user from table where name = 'foo'

직감이나 가독성의 관점에서 문법의 이점을 실제로 보지 못합니다. 실제로 SQL 버전은 공백으로 인해 더 읽기 쉽고 입력하기 쉽습니다.


2

가 있습니다 불량 이 API를 고려하여 이루어진 것으로 보인다 이상적인 디자인 결정 미만.

첫 번째는 유틸리티의 문제입니다. 어떤 용도로 사용됩니까? 이것은 SQL의 방언으로 컴파일 할 데이터 구조를 만드는 것으로 보입니다. 또한 문법은 제한된 SQL 집합으로 보입니다. "이것은 SQL을 사용하는 것보다 어떤 이점이 있습니까?" 키가됩니다. 적절한 보간으로 문자열을 작성하는 것보다 유창한 인터페이스를 사용하여 작성하는 것이 더 번거로운 경우이 API를 사용하여 작성하지 않습니다.

영어는 모호합니다. 영어로 유창한 인터페이스를 모델링하는 것은 좋지 않은 선택입니다 ( 라틴어를 사용하는 것이 좋습니다 ). 동일한 일련의 호출 체인에 대해 유효한 구문 분석이 여러 개있을 경우 혼란과 놀라움이 발생 합니다. 이것들 중 어느 것도 API에 좋은 것은 아닙니다.

이 API가 노출하는 것보다 SQL에 더 많은 부분이 있습니다. 조인 (그들의 무수한 형태 중 하나)은 예제 세트에서 두드러지게 나타나지 않습니다. 하위 쿼리 ( foo in (select id from bar)), 공용체 및 그룹 별은 자주 사용되는 몇 가지 사항입니다. 복잡한 논리 그룹은 직관적 인 방식으로 나타나지 않습니다.

이 API를 사용하여 작성한 후 API가 원하는 쿼리를 표현할 수없는 것을 발견하면 상당한 시간이 손실됩니다. 응용 프로그램에서 쿼리 (이 API의 간단한 쿼리, 원시 SQL의 복잡한 쿼리)를 수행하기 위해 혼합 스타일을 사용하는 것은 좋지 않은 선택이며 궁극적으로 더 표현적인 스타일이 사용됩니다.

프로그래밍은 널리 퍼져 있지만 영어 실력은 그렇지 않습니다. 언어가 "SQL like"로 제한되어 있어도, 원어민이 영어를 제 2 또는 제 3 언어로 사용하는 사람과 무언가를 읽는 방법에 대한 뉘앙스가 있습니다.

영어를 위해 API에는 불필요한 중복성이 있습니다. 특히 같은 일을하는 equal()equals(). 나는 그것을 확신하지 못하지만, 그것이 is()영어와 더 가까운 것을 위해 추가되지 않은 것이라고 생각합니다 . 나는 채팅에서 루비에서 중복되는 메소드에 대한 내 의견을 듣는 것을 환영합니다-같은 실수를하지 마십시오.

앉아서 사용할 수있는 쿼리의 포괄적 인 예제 세트를 작성하십시오. 쿼리 자체보다 덜 번거롭지 않은 방식으로 이러한 모든 예제를 처리 할 사람을 결정하십시오. 당신이 할 수 없다면, API 작성 경로를 따라가는 것이 가치가 있는지 고려하십시오. SQL은 수십 년 동안의 세련미가 오늘날의 곳입니다 (완벽하지는 않지만 더 좋은 것을 찾지 못했습니다).

RFC 1925-12 가지 네트워킹 진실

(12) 프로토콜 설계에서, 추가 할 항목이 없을 때가 아니라 제거 할 항목이 없을 때 완벽에 도달했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.