• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強而不息

            【ZT】微軟架構(gòu)師談編程語言發(fā)展(2)


            Herb:我想,我們有必要在“函數(shù)型”編程領(lǐng)域做一個進(jìn)一步區(qū)分,將其劃分成兩個部分。我非常同意Anders和 Erik的意見。我不太同意的是這樣的措辭:我們之所以繼續(xù)使用“命令型”編程語言,是因為這是大家目前所能理解的;通用程序員目前的工作并未取得巨大的成功;市場對于“所有的東西都是表達(dá)式,所有的語言都應(yīng)該是表達(dá)式類型的語言”這樣的理念已經(jīng)非常接受了;“函數(shù)型”語言是“串行執(zhí)行”的好藥方。我們要想使“函數(shù)型”語言運轉(zhuǎn)良好,關(guān)鍵的并不是處理好基本的表達(dá)式問題,而是處理好lambda表達(dá)式和副作用的問題,關(guān)鍵是能夠?qū)⒈磉_(dá)式作為第一級的編程要素來使用——LINQ也是最近才在做,關(guān)鍵是能夠指出lambda表達(dá)式和Closure(譯者注:函數(shù)型編程語言中的一個概念,可以方便地組合函數(shù),返回函數(shù))的副作用。實際上,最后這點目前是缺失的(Anders也附和著:對,對)。這些東西在“命令型”語言中也是要處理的東西。我為什么提這些?因為我覺得說“函數(shù)型”語言是方向,目前的“命令型”語言不夠好,因此是垃圾,必須要拋在腦后,全面采用“函數(shù)型”語言這樣的說法不對(譯者注:呵呵,對 Anders的說法有點急了,畢竟是泡在C++上,對C++有感情的人)。我認(rèn)為,對于“函數(shù)型”語言能夠幫助程序員完成哪些工作,目前還不太明了。比如,能夠用它寫通用代碼嗎?能夠用它系統(tǒng)級代碼嗎?當(dāng)然,“函數(shù)型”語言有不少我們能夠應(yīng)用的好東西,比如lambda表達(dá)式,比如Closure,C# 借鑒了,C++也在借鑒,這些語言因此增色不少。關(guān)于“函數(shù)型”語言還有另一個問題,那就是有兩種類型的“函數(shù)型”語言,一種是沒有副作用的,因此就沒有共享的易變的狀態(tài)的問題;一種是人人都在使用的,對吧(譯者注:顯然Herb認(rèn)為“沒有副作用”的理想情況是不太可能的)?因為你不太可能說,“瞧,我是完全并發(fā)安全的,因為每次我從XX(譯者注:聽不清)向量中得到一個拷貝,或者我使用XX(譯者注:聽不清)元素的時候,我都是取得一個拷貝”。確實不錯,這里是沒有共享的易變的狀態(tài),但是是否能夠完全并發(fā)安全則不一定。
             
            Anders:是的。我的意思是,在類似C#或VB這樣的“命令型”編程語言中加入“函數(shù)型”結(jié)構(gòu),能給我們提供“以函數(shù)型風(fēng)格”寫庫的能力,從而我們就能夠非常明確地說,如果你能保證傳入的lambda表達(dá)式是純粹的函數(shù),我們就能保證正確地把它分散到若干個線程或者CPU上,最后把它綜合起來,給你一個正確的結(jié)果,我們能夠保證代碼運行得更快,同時你還不用作任何編碼上的修改。如果你在寫一個大大的For循環(huán),我們永遠(yuǎn)都不可能保證做到前面所說的,此時,“函數(shù)型” 編程能夠提供給你的是一系列表達(dá)式,再加上“把代碼當(dāng)作參數(shù)傳遞”,“類型推論和泛型編程可以正確地綁定所有的類型”這些特性,這樣你就能更方便地編寫 “可組合的算法塊”。
             
            Charles:這樣一來不就削弱了抽象嗎(譯者注:Charles可能想的是程序員不需要再關(guān)心“可組合性”,語言和運行庫應(yīng)該保證這件事,而現(xiàn)在聽起來并非如此)?
             
            Herb:呃,我很同意Anders的意見,我想指出的是,當(dāng)前所有的語言都有意不保證 “沒有副作用”。之所以如此的原因是,除非所有的語言都添加一些機制讓程序員可以清除副作用,我們這些做語言的人不敢打這個包票。但是,添加這樣的機制涉及到眾多參加者,大家一起思考、討論什么是最好的方法的過程會很漫長。我們所做的是相信程序員,因為我們自己不知道。然而,程序員在很多情況下也不知道,因為他寫的函數(shù)要調(diào)用其他的庫。這里“可組合性”又浮上水面了,程序員根本不知道他用的庫有怎樣的副作用。一般說來程序員會再增加一層間接性,但是問題依然存在,沒有人能夠清楚地知道副作用,除非他擁有涉及到的所有的代碼,這就是難題所在。上面這些討論對“鎖”也適用,因為“鎖”也是個全局問題,對于“可操作性”是個障礙。
             
            Brian:(譯者注:在Herb說話的時候已經(jīng)很著急地想說了幾次)在這點上Haskell做得很好,Haskell是“永遠(yuǎn)沒有副作用”的范例。
             
            Erik:是的,但做到這點的過程也是痛苦的,因為并非所有的情況都一目了然。一旦你的(庫)代碼有副作用,而且因此使程序員的代碼必須按照某種順序執(zhí)行(因為副作用的關(guān)系,該程序必須先干某事,再干某事),某種意義上你在用匯編語言編寫東西,因為程序員將不再能用“表達(dá)式+表達(dá)式”的方式來寫代碼,他必須決定先對某個表達(dá)式求值,再對另一表達(dá)式求值,再把值加起來。因此我認(rèn)為我們在這點上干得還是不夠漂亮。
             
            Brian:現(xiàn)在,我們在“流庫”上有例子。好消息是,我們已經(jīng)有Haskell向你展示如何以“可行性”方面的代價,換來用絕對純粹的方式來做事。當(dāng)然,除Haskell外我們有各種“雜牌”語言。呵呵!
             
            (眾人均樂)
             
            Charles:這是個供研究的語言嗎?
             
            Brian:是的,我們將它設(shè)計為供研究用。
             
            Anders:沒有純粹的好或壞,我認(rèn)為,雖然進(jìn)展緩慢,我們?nèi)匀豢斓揭粋€令人滿意的中間點了。我完全同意說,如果我們確實能夠保證函數(shù)的純粹性,生活將會非常美好。最終我們必須要做到。
             
            Brian:在研究領(lǐng)域,大概有20多項工作與此有關(guān)——契約語言,契約和限制,等等。
             
            Erik:但是,不少的副作用也并非壞事,如果我的函數(shù)使用了一個局部變量,這就是使用了一個狀態(tài),但是,函數(shù)本身還是純粹的。如果你想要完全避免副作用,我覺得會非常困難,一些東西可以是局部不純粹而整體純粹的。
             
            Herb:回過頭,讓我們從整體上看看“可組合性”。讓我吃驚的一件事是,很多時候,人們甚至都沒有意識到這是個問題。他們并沒有意識到自己實際上經(jīng)常碰到這個問題。整個軟件工業(yè),整個世界其實已經(jīng)基于可組合的軟件了。在硬件會議上,我經(jīng)常對硬件公司提到的是(呵呵,通常此時我都是在轟擊硬件工業(yè),但是軟件業(yè)也有同樣的問題):硬件的并發(fā)問題被仔細(xì)地探索過了,而且,當(dāng)前消除共享易變狀態(tài)的最好辦法就是“鎖”;但是,鎖是全局的,是一種全局資源,不能被組合;“被鎖”是經(jīng)常發(fā)生的事情,而擁有一個鎖時,我還能調(diào)用任何其他的未知的代碼,這就破壞了“可組合性”。說到這里,有的聽者往往一臉茫然:這有什么問題嗎?我于是指出,好的,你們是否上網(wǎng)下載別人剛剛發(fā)布的,自己喜歡的新軟件,比如,某個瀏覽器,3個插件,然后就用呢?大家回答:是啊。于是我再指出,你們是否意識到了,當(dāng)你們這樣做時,經(jīng)常地,這些軟件都是第一次在最終用戶的機器上被組合,被使用?既然如此,你們怎么可能對其進(jìn)行測試?這時,屋子里有百分之十的人會露出恍然的表情,因為此前他們沒有想過這個問題:這些軟件是第一次在最終用戶的機器上被組合,我們怎么進(jìn)行測試?正因如此,“可組合性”是更加重要的一個問題。更不用說我們現(xiàn)在有AJAX,應(yīng)用程序,以及眾多的其他插件經(jīng)常被下載,而且被要求在同一個用戶界面中協(xié)調(diào)工作。

            Charles:你這么一說,關(guān)于“函數(shù)型”編程,我馬上想到一個問題是:在現(xiàn)有基礎(chǔ)上再加一層必須考慮的抽象,實際上能不能增加程序員的生產(chǎn)率,是否真的有幫助?作為程序員,現(xiàn)在還要考慮“副作用”的問題。反正我現(xiàn)在用C#還是其他語言編程的時候,是不會像一個“函數(shù)型”程序員那樣考慮副作用的。
             
            Herb:往一個語言上增加更多的特性無法使其變簡單,這是個我們面臨的基本難題。
             
            Anders:作為一個語言設(shè)計師,對于編程語言,我們所能做的是——減緩新特性不斷累積的速度,從而避免最終的倒塌。我想說的是,你永遠(yuǎn)不能收回某個特性。理論上,你可以收回某個特性,實際中,你不能這樣做,因為后果是若干代碼的崩潰,這行不通。
             
            Brian:是的,在從VB6到VB.NET的過程中,很多人已經(jīng)感到飽受折磨了。是的,(微軟的)解決方案是說那(VB.NET)是個完全不同的語言。但是,我認(rèn)為,“函數(shù)型”編程的概念已經(jīng)出現(xiàn)了不短的時間,新畢業(yè)的程序員至少聽說過這個概念。他們在Python、JavaScript或者其他什么地方見過 lambda表達(dá)式,或者他們學(xué)過Scheme,總之這不是個沒聽說過的東西,因此,當(dāng)他們在C#或其他的更傳統(tǒng)的編程語言,如VB或C++中看到這些概念的時候,他們并不會感到畏懼,因為他們了解這些概念的優(yōu)點,他們知道這些東西如果用得正確,可以增加代碼的可組合性。你知道,傳統(tǒng)語言的可組合性靠的是程序員的自覺。在某些方面,Haskell編程比“命令型”編程要痛苦得多,然而反過來說,它也比“命令型”編程要簡單些,因為你不會把事情弄得一團(tuán)糟。呵呵呵。
             
            Anders:這里我想插一句。我認(rèn)為,在很大程度上,我希望我們在C#或VB上做的工作至少是——在很大程度上對“函數(shù)型”編程進(jìn)行“去神秘化”。學(xué)院式的人總是傾向于讓事情聽起來比實際的要復(fù)雜,因為這樣一來就顯得他們自己比較聰明。“呃,我并不是針對任何人,但是,這里有不少符號代數(shù)和其他東西呢!(譯者注:音頻提高了,似乎在學(xué)某些人的語氣)”。當(dāng)我向人們解釋lambda表示式時,大家是另一種感覺:“你的意思是他們就是函數(shù)?這有什么新鮮的?我們早就有函數(shù)了,lambda表達(dá)式只是些語法糖衣外殼吧?”是的,lambda表達(dá)式確實只是語法糖衣外殼,但這是種強有力的語法糖衣外殼,它使你能按照一種新的方式去思考問題,以前總是存在的一些語法噪音——必須聲明函數(shù),進(jìn)行委托,等等——就會逐漸減少,最終,一個全新層次的表達(dá)式列表會產(chǎn)生出來。這才是關(guān)鍵所在!圍繞著“函數(shù)型”編程還有非常多神秘,我希望我們能夠(在打破神秘上)有所突破……
             
            Herb:關(guān)于(Brian)說的教育問題,就是關(guān)于人們能夠在學(xué)校中學(xué)到的東西的說法,我不太同意。我真的希望情況確實如此,但是我認(rèn)為缺乏證據(jù),或者說除了 “Pascal熟悉者”之外,我們無法獲得更多。不管是在學(xué)校還是在今后的職業(yè)生涯中,人們都認(rèn)為自己接觸了多種語言,因為他們用過C、C#、C++、 VB以及Pascal。但是,這些語言本質(zhì)上是一樣的,是同一族的語言。人們并沒有接觸過APL——編程就象在解釋器外殼(譯者注:可以想象DOS的命令行)上敲東西;不熟悉Prolog——任何東西都是規(guī)則;不知道Lisp——所有的都是鏈表。只有當(dāng)你深入了2到3種這些東西后,你才知道,并不是所有的東西都是命令。也許在你今后的職業(yè)生涯中用的都是命令型語言,正如我們大多數(shù)人一樣,但是,你不會對其他看待世界的觀點一無所知。某人從小到大,如果沒有離開過成長的城市,如紐約,超過一英里的話,會錯過不少有趣的地方,不管你是否想在其他地方住下來,你應(yīng)該知道它們,體驗它們。
             
            Brian:呃,我覺得這是個漸變的過程,當(dāng)然,我確實觀察到年輕一代程序員對于“函數(shù)型”編程有更好的認(rèn)識了。你知道,10年,15年之前,如果你和人們談起 Scheme時,人們會感到不解地看著你,“什么?你在說什么?”。現(xiàn)在,人們聽說過了,他們見過“函數(shù)型”編程的關(guān)鍵字。而且,通過 JavaScript和Python,人們嘗試了“函數(shù)型”編程,也使得這些東西更加流行。我并不是說已經(jīng)出現(xiàn)了巨大的變化,我是說逐漸的變化和更多的認(rèn)知,人們不再象以前那樣看到這些東西就害怕了。
             
            Erik:也許JavaScript是這個世界上最……(譯者注:Brian一陣激動的插嘴,搞得Erik的話聽不清了)。我不確定當(dāng)人們使用JavaScript時,他們是否意識到了這是一種把“函數(shù)”當(dāng)作第一要素的語言。
             
            Brian:你可以在運行的時候創(chuàng)造它們(函數(shù))……
             
            Charles:所有的東西都是一種類型,所有的東西都是對象,是吧?這是個有趣的語言。隨著整個互聯(lián)網(wǎng)的發(fā)展,你認(rèn)為這種語言也應(yīng)該有所進(jìn)化……?
             
            Brian:這里的“所有的東西都是對象”,不是面向?qū)ο蟮囊饬x。這里是從“任何東西都是關(guān)聯(lián)鏈表”的角度來說。現(xiàn)在我聽起來像一個老Lisp編程者(譯者注: Lisp基于鏈表),是吧?一個JavaScript的對象不像一個C#對象那樣——所有的內(nèi)存排列都決定了,什么東西都靜態(tài)地決定了。這意味著所有的東西都可以添加、拿走,可以違反規(guī)則,它確實只意味著一個關(guān)聯(lián)鏈表。
             
            Anders:屬性包(我得意地笑)……
             
            Brian:是的,屬性包的說法更好!
             
            Erik:是的,值可以是函數(shù)、其他對象,或者是其他屬性包。
             
            Brian: JavaScript其實就是源自Lisp的Scheme。我又在說Scheme,因為我也許是這個屋子中唯一老到聽說過這個詞的人,呵呵!但是, Scheme有點類似于“上帝的Lisp”(譯者注:不知道是God’s Lisp, Guard’s Lisp還是什么別的,懂得有限,暫時按God’s Lisp處理,達(dá)人請指教),所有的噪音都被消除了,只剩下最基本的、最少的東西。JavaScript就是把這些東西帶到了前臺,披上件不那么可怕的外衣的結(jié)果。因為JavaScript看起來有點“C”的味道,你可以使用花括號!呵呵!
             
            (一陣亂哄哄)
             
            Charles:但是,JavaScript只是一種解釋性語言,而且,對開發(fā)者來說,用它編程也不是很有效率。JavaScript不像C#或VB,它沒有一種真正的面向?qū)ο笳Z言所應(yīng)該具備的IDE,以及你可以工作于其上的框架。
             
            Anders:呃,JavaScript是一種弱類型語言,或者說動態(tài)編程語言。人們經(jīng)常把“編譯時”與語言的“類型強弱”相提并論。但是,這兩個概念其實是相互獨立的,是吧?你可以有一種“強類型”,然而在運行期編譯的語言,如果你真想要這樣的東西的話。但是,對我來說,我以前也講過,我非常樂于向那些喜歡“動態(tài)語言”、“腳本語言”的人指出,正是他們所醉心的那些地方會有問題。經(jīng)常地,人們都理所當(dāng)然地認(rèn)為,如果沒有類型礙事,就不用聲明什么東西了,可以隨手就用,諸如此類。這樣干的時候你確實能夠更快地寫程序,然而,這里有一個陷阱:因為沒有類型,我們(編譯器)給你提供的幫助就少得多。當(dāng)你寫“X.”時,對不起,“.”之后是什么我們沒法告訴你,我們沒有足夠的智能顯示給你,因為我們沒有任何辦法知道將發(fā)生什么。有時我們可以猜,但我們有可能猜錯,有時我們根本就一無所知,對吧?X或者其他參數(shù),我們不知道將發(fā)生什么。我發(fā)現(xiàn),有趣的是,我們在C#中進(jìn)行的類型推論的工作,在許多方面都使得C#編程看起來更像動態(tài)語言,因為不會隨時看到類型,甚至壓根看不到。但是,類型在那里,靜態(tài)地在那里,這也意味著,我們?nèi)匀豢梢越o你提供“語句完成”這樣的智能幫助。
             
            Charles:你是在說“var”關(guān)鍵字啰?
             
            Anders:“var”關(guān)鍵字只是個例子。光看這個關(guān)鍵字,似乎這是動態(tài)類型,然而,這是靜態(tài)類型。當(dāng)你定義“var Blar”時,我們知道“Blar”是什么類型;當(dāng)你寫“Blar.”時,“.”之后我們可以為你顯示出東西。
             
            Herb:我們(C++)中也在做一樣的事情。我有一個“int”類型的vector,我從該vector的頭部取出一個元素,我有什么必要再用 vector<int> 來聲明一個遍歷器?編譯器知道它是這個類型,編譯器能夠?qū)㈩愋驼_加到變量上。這就是“var”類型干的事,你不必到處都寫出類型信息。這帶來了很大的好處,你可以書寫更好的“范型”代碼,以前那些東西是寫“范型”代碼的障礙。
             
            Anders:我想說的是,(如果有類型),我們就能在你寫代碼的時候給你許多的幫助,尤其在“智能感知”上我說是大實話。當(dāng)今世界,如果你想把“智能感知”去掉,人們絕對會大叫“不!不!”,呵呵,這工具太有用了。但是,這里還有性能的問題。我是說,當(dāng)編譯器知道類型時,它能夠為你生成更好的代碼。就是說,你會得到更好的執(zhí)行效率。
             
            Erik:這里有件趣事。幾個月前我們有次編譯器XX(譯者注:沒聽清),參加者都反映說,“喔,你知道,F(xiàn)#是最好的動態(tài)語言!”要我來說的話,F(xiàn)#是擁有最先進(jìn)的靜態(tài)類型系統(tǒng)的語言。當(dāng)然,你不用寫任何的類型,因為編譯器幫你推斷了所有的類型。很有趣的是,人們經(jīng)常混淆“不用寫類型”與“動態(tài)類型”。
             
            Brian:這些人可都是寫編譯器的職業(yè)程序員!這是在課程結(jié)束時,做調(diào)查時出的趣事:“你最喜歡的動態(tài)語言?”“F#!”
             
            Charles:但是(結(jié)巴了一陣,可能是震驚了),從開發(fā)人員的角度來看,動態(tài)類型是設(shè)計期的事吧?就我自己而言,如果我不必對任何東西進(jìn)行強類型處理,我就會假設(shè)是動態(tài)類型。這是不是錯了?我是說,編譯器是怎么弄的?
             
            Anders: “動態(tài)類型”和“隱式類型”是有區(qū)別的。一種情況是,靠編譯器推斷出類型,但編譯器在編譯期就推斷出來了。另一種情況是,編譯器在編譯時一無所知,它假設(shè)這東西可以是任何類型,然后在運行時的適當(dāng)時機,檢查到底是什么類型。后一種情況下,當(dāng)你分發(fā)一個虛函數(shù)調(diào)用時,也許會使用一個查找表,或是別的什么東西,因為你壓根還不知道那是什么東西。前一種情況,根據(jù)到底是C#或是C++,你可以預(yù)先構(gòu)造好虛表,準(zhǔn)確地知道使用這個虛表的哪個內(nèi)存地址來找到實際的東西,因為我已經(jīng)計算好了。這就是預(yù)先有效地計算好了所有的東西。但是,人們往往錯誤理解(靜態(tài)類型)為,“我,我這個人本身,必須在任何時候親自手動寫出類型”實際上這并不必要,因為類型可以被推斷出來,如果你在一個地方知道了類型,你可以跟蹤程序邏輯,根據(jù)這里發(fā)生了什么,類型是如何變化的,從而知道在另一個地方類型是什么。如果你是個足夠聰明的編譯器,你應(yīng)該可以做到這些,是吧?我們正開始把這種“聰明”加入到程序語言中。
             
            Brian: F#可能是這方面最好的例子。F#甚至欺騙了職業(yè)編譯器程序員!我認(rèn)為人們真正喜歡的是快速的反饋。人們喜歡快速看到結(jié)果。在他們的意識中,他們把這種喜好和“動態(tài)”相混淆了。下面我具體講講:你輸入了一個函數(shù),然后馬上敲入一行代碼來測試剛寫的函數(shù),如果能夠正常工作,你就可以放心地忘掉它們(譯者注:指可以投入下面的其他工作),這是人使自己的“大腦堆棧”保持滿負(fù)荷運作的方式,是人的力量。歷史上,“動態(tài)語言”在使人以這種方式工作上卓有成效。你打開一個Lisp,你實際上得到的是一個Lisp的監(jiān)聽器,你鍵入代碼,然后在相同的環(huán)境中立即測試代碼。但是,這實際上是個工具問題,與編譯器什么的完全沒有關(guān)系。你能夠使動態(tài)語言有一個好的IDE和交互的開發(fā)環(huán)境,你也能使靜態(tài)語言,如F#,擁有這樣的IDE和交互的開發(fā)環(huán)境。這就是Sam在F#演示上干的事情。他打開好長一段代碼,用鼠標(biāo)選擇它們,用“GO”按鈕來執(zhí)行;然后他打開另外一段代碼,再用鼠標(biāo)選擇,再按“GO”來執(zhí)行。所有的人都以為這是動態(tài)解釋執(zhí)行的。實際上,這是靜態(tài)的,完全編譯的。這就是欺騙行家的方法。呵呵(我得意地笑……)。但這確實是人們喜歡的東西。大家都喜歡能提供“不斷反饋”的好工具,或者是“交互式開發(fā)環(huán)境”,無論你管這叫什么。只要你能夠隨時寫代碼并且測試,你就不必寫一大堆代碼后再測試。你會這樣想,“嘿,我寫了個叫‘RandomDouble’的函數(shù),讓我把它敲進(jìn)去看看是否能工作”。如果能正常工作,你就可以在進(jìn)一步的Debugging前把它忘掉(去做別的工作)。


            posted on 2007-09-11 03:13 lovedday 閱讀(328) 評論(0)  編輯 收藏 引用 所屬分類: ▲ Software Program

            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            欧美一区二区久久精品| 久久无码人妻一区二区三区午夜| 东方aⅴ免费观看久久av| 久久99国产精品久久99小说 | 久久精品人人做人人爽电影蜜月 | 日本精品久久久久中文字幕8| 久久久久人妻精品一区| 国产高潮久久免费观看| 久久久久亚洲av成人网人人软件 | 久久中文字幕精品| yy6080久久| 久久国产成人亚洲精品影院| 丁香色欲久久久久久综合网| 狠狠色丁香婷婷综合久久来来去| 无码AV波多野结衣久久| 午夜精品久久久久久| 久久久久久久综合日本亚洲| 99精品国产99久久久久久97| 久久伊人五月天论坛| 国内精品久久久久久野外| 亚洲AV成人无码久久精品老人| 国产成人精品久久亚洲高清不卡| 日韩人妻无码一区二区三区久久| 日日狠狠久久偷偷色综合96蜜桃| 久久精品国产只有精品2020| 久久人人爽人人爽人人片AV不| 香蕉99久久国产综合精品宅男自 | 亚洲国产精品无码久久一区二区| 久久人妻少妇嫩草AV无码蜜桃| 青青青青久久精品国产| 精品九九久久国内精品| 久久精品国产亚洲AV麻豆网站 | 久久久久女教师免费一区| 久久久久综合网久久| 国产精品久久久久…| 国产亚洲婷婷香蕉久久精品| 国产午夜福利精品久久2021| 无码AV波多野结衣久久| 久久香综合精品久久伊人| 婷婷久久久亚洲欧洲日产国码AV | 国产精品日韩深夜福利久久|