การใช้ไวยากรณ์ภาษาธรรมชาติใน API ได้อย่างคล่องแคล่ว


14

ฉันกำลังหาข้อสรุปเกี่ยวกับ API ของฐานข้อมูล WebSQL / Phonegap และฉันพบว่าตัวเองทั้งที่ถูกดึงดูดและสงสัยว่าจะกำหนด 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

2
คุณจะจัดการกลุ่มอย่างไร เทียบเท่ากับ: ... where foo = 1 or (bar = 2 and qux = 3)?

7
IMO API ที่คล่องแคล่วชนิดนี้น่ากลัว ตัวอย่างเช่นการขาดความสำคัญของผู้ประกอบการเป็นที่น่ารำคาญ ฉันต้องการแยกเป็นwhere("name").equals("foo").or("bar") (name=="foo")or barจากนั้นจะไม่ชัดเจนเมื่อสตริงแสดงถึงตัวอักษรและเมื่อมันแสดงชื่อคอลัมน์ ...
CodesInChaos

4
BTW หากคุณต้องการใช้ DSL เพื่อสอบถามฐานข้อมูลคุณสามารถใช้ DSL ที่มีอยู่แล้วที่เรียกว่า SQL
CodesInChaos

คำตอบ:


23

ฉันคิดว่ามันผิดมาก ฉันศึกษาความเป็นธรรมชาติและเต็มไปด้วยความคลุมเครือที่สามารถแก้ไขได้ด้วยบริบทและความรู้ของมนุษย์จำนวนมาก ความจริงที่ว่าภาษาการเขียนโปรแกรมไม่ชัดเจนเป็นสิ่งที่ดีมาก! ฉันไม่คิดว่าคุณต้องการความหมายของวิธีการที่จะเปลี่ยนแปลงตามบริบท:

  • นี่คือการเพิ่มความประหลาดใจมากขึ้นตั้งแต่คุณนำความกำกวม
  • ผู้ใช้ของคุณจะต้องการใช้สิ่งปลูกสร้างที่คุณจะไม่ครอบคลุมเช่น find("user").where("name").and("email").equals("foo");
  • เป็นการยากที่จะรายงานข้อผิดพลาด: คุณสามารถทำfind("user").where("name").not().is().null();อะไรได้บ้าง

สมมติว่าฉันสามารถครอบคลุมประโยคภาษาอังกฤษที่ถูกต้องส่วนใหญ่ไวยากรณ์เองนั้น จำกัด อยู่ที่คำกริยาและการผันคำกริยาที่กำหนดโดย SQL

ไม่คุณไม่สามารถครอบคลุมประโยคภาษาอังกฤษที่ถูกต้องที่สุด คนอื่นเคยลองมาก่อนและมันก็ซับซ้อนมากอย่างรวดเร็ว มันเรียกว่าการทำความเข้าใจภาษาธรรมชาติแต่ไม่มีใครลองทำเช่นนั้นจริง: เรากำลังพยายามแก้ไขปัญหาที่เล็กกว่าก่อน สำหรับไลบรารีของคุณโดยทั่วไปคุณมีสองตัวเลือก:

  • ไม่ว่าคุณจะ จำกัด ตัวเองเป็นภาษาอังกฤษบางส่วน: นั่นให้ SQL แก่คุณ
  • หรือคุณพยายามปิดบัง "ภาษาอังกฤษ" และคุณพบว่ามันเป็นไปไม่ได้เนื่องจากความกำกวมความซับซ้อนและความหลากหลายของภาษา

ขอบคุณสำหรับข้อมูลของคุณ แก้ไขคำถามของฉันเพื่อครอบคลุมกรณีแรกที่คุณอยู่ในรายการและเพิ่มคำเตือนบางอย่าง ฉันเห็นด้วยกับตำแหน่งของคุณเกี่ยวกับความกำกวม - นั่นคือปมคำถามของฉัน เป็นที่ยอมรับได้หรือไม่สำหรับภาษาการเขียนโปรแกรมที่ต้องใช้บริบทในบริบทที่กำหนดไว้อย่างดี?
fencliff

หากไม่ชัดเจนก็ไม่ชัดเจน หากไม่ชัดเจนมีมากกว่าหนึ่งผลลัพธ์ที่เป็นไปได้และสิ่งที่ต้องเลือกอย่างใดอย่างหนึ่ง ตัวเลือกจะถูกกำหนดอย่างดีหรือตัวแยกวิเคราะห์ภาษาจะเลือกแบบสุ่ม ดังนั้นความกำกวมในภาษาการเขียนโปรแกรมก็ไม่เป็นไรถ้าคุณต้องการภาษาสุ่ม (1 + 1 อาจเท่ากับ 2 และบางครั้งอาจเท่ากับ 1 หรือ 3) เมื่อเทียบกับที่กำหนด (1 + 1 เท่ากับ 2 เสมอ)
Michael Paulukonis

คุณกำลังพูดถึงข้อเสนอของเขาหรือภาษาอังกฤษ? ส่วนใหญ่เวลาความคลุมเครือสามารถแก้ไขได้โดยใช้บริบทและ / หรือความรู้ (ส่วนหนึ่งซึ่งเป็นสามัญสำนึก) สิ่งที่ไม่สามารถใช้ได้กับคอมพิวเตอร์
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 นี้

ภาษาอังกฤษคลุมเครือ ความพยายามในการจำลองอินเทอร์เฟซภาษาอังกฤษอย่างคล่องแคล่วเป็นตัวเลือกที่ไม่ดี (คุณควรใช้ละติน ) เมื่อมีหลาย parsings อาจจะเป็นที่ถูกต้องของชุดเดียวกันของห่วงโซ่ของสายนี้นำไปสู่ความสับสนและความประหลาดใจ สิ่งเหล่านี้ไม่ใช่สิ่งที่ดีที่มีใน API

มีชิ้นส่วนให้กับ SQL มากกว่าที่ API นี้กำลังเปิดเผย Joins (ในรูปแบบใด ๆ ที่นับไม่ถ้วน) ของพวกเขาจะหายไปในรูปแบบตัวอย่างชุด แบบสอบถามย่อย ( foo in (select id from bar)), สหภาพและกลุ่มโดยเป็นบางสิ่งที่มักใช้ การจัดกลุ่มเชิงตรรกะที่ซับซ้อนไม่ปรากฏว่ามีอยู่จริง

หากมีใครเขียนโดยใช้ API นี้แล้วพบว่า API ไม่สามารถแสดงข้อความค้นหาที่ต้องการได้เวลาที่สำคัญจะหายไป มันเป็นตัวเลือกที่ไม่ดีที่จะใช้รูปแบบผสมสำหรับการทำแบบสอบถามในแอปพลิเคชัน (แบบสอบถามแบบง่าย ๆ ใน API นี้ซับซ้อนใน SQL ดิบ) - และในที่สุดก็จะใช้รูปแบบที่มีการแสดงออกมากขึ้น

ในขณะที่การเขียนโปรแกรมแพร่หลายภาษาอังกฤษไม่คล่อง แม้จะมีข้อ จำกัด ของภาษาในการ "SQL เช่น" มีความแตกต่างของวิธีการที่เจ้าของภาษาจะอ่านอะไรบางอย่างและคนที่มีภาษาอังกฤษเป็นภาษาที่สองหรือที่สาม

มีความซ้ำซ้อนที่ไม่จำเป็นใน API เพื่อประโยชน์ของภาษาอังกฤษ โดยเฉพาะอย่างยิ่งequal()กับequals()การทำสิ่งเดียวกัน แม้ว่าฉันจะไม่แน่ใจ แต่ฉันเชื่อว่าis()ไม่มีการเพิ่ม op สำหรับการจับคู่ภาษาอังกฤษอย่างใกล้ชิด ฉันยินดีรับฟังการพูดคุยเกี่ยวกับความซ้ำซ้อนของวิธีการในทับทิมในการแชท - อย่าทำผิดพลาดเหมือนกัน

นั่งลงและเขียนชุดตัวอย่างที่ครอบคลุมของข้อความค้นหาที่คุณต้องการใช้ กำหนดผู้ที่คุณจะจัดการกับตัวอย่างเหล่านั้นทั้งหมดด้วยวิธีที่ไม่คลุมเครือซึ่งยุ่งยากน้อยกว่าการสืบค้นด้วยตนเอง หากคุณทำไม่ได้ให้พิจารณาว่าการใช้ API นั้นคุ้มค่าหรือไม่ SQL คือที่ที่ทุกวันนี้ (มันไม่สมบูรณ์แบบ แต่ฉันไม่พบอะไรที่ดีไปกว่านี้) ในช่วงหลายทศวรรษของการปรับแต่ง

RFC 2468-เครือข่ายจริงสิบสอง

(12) ในการออกแบบโปรโตคอลความสมบูรณ์แบบไม่ได้มาถึงเมื่อไม่มีอะไรเหลือให้เพิ่ม แต่เมื่อไม่มีอะไรเหลือให้นำออกไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.