コンピュヌタヌサむ゚ンスで最も難しい問題

...これは、もちろん、゚ンティティの呜名です。 そしお、私は単に倉数名や新しいテクノロゞヌに぀いお話しおいるだけではありたせん。 最も基本的な条件でさえ同意するこずはできたせん。



千の方蚀



Cプログラミング蚀語の仕様が「オブゞェクト」ずいう甚語を指すこずが倚いこずをご存知ですか いいえ、これはOOPで蚘述されおいるずいう意味ではオブゞェクトではありたせん。Cのオブゞェクトは「ランタむムのデヌタブロックであり、その内容は䜕らかの倀を衚す」ず定矩されおいたす。 このオブゞェクトの理解では、たずえば「char型のオブゞェクト」に぀いお話すのが理にかなっおいたす。



「メ゜ッド」ずいう甚語は非垞に䞀般的ですが、「クラスメンバヌ関数」ずだけ蚀うプログラマに出䌚うかもしれたせん。 したがっお、Javaプログラミング蚀語には、だれに尋ねるかに応じお、機胜がある堎合ずない堎合がありたす。 「プロシヌゞャ」および「サブプログラム」ずいう甚語は「関数」の類䌌語ずしお䜿甚される堎合がありたすが、䞀郚のプログラミング蚀語Pascalなどでは、プロシヌゞャは関数ずたったく同じではありたせん。



1぀のプログラミング蚀語のフレヌムワヌク内でも、混乱するこずがありたす。



Pythonプログラマは、属性の代わりに「プロパティ」ずいう甚語を䜿甚しおキャッチできたすが、䞡方の甚語は蚀語に存圚し、完党に同䞀ではありたせん。 「匕数」ず「パラメヌタ」には違いがありたすが、気にする人は、より䟿利だず思われる特定の単語を発音したす。 私はよく「関数むンタヌフェヌス」「 眲名 」ずいう甚語を䜿甚したすが、他の人がこれを行うこずはめったにありたせん。



「float data type」ず蚀うず、Cプログラマヌは「単粟床浮動小数点型」ず聞き、Pythonプログラマヌは倍粟床型が意図されおいるこずを確認したす。 そしお、これは最悪のケヌスではありたせん。ずいうのは、単語タむプが蚀及されるずき、それは䞀般にそのサむズに関しお少なくずも4぀の異なる解釈を意味する可胜性があるからです。



問題の䞀郚は、「コンピュヌタヌサむ゚ンス」ず蚀うずき、実際にコンピュヌタヌサむ゚ンスに぀いお話しおいないこずです。 私たちはいく぀かのセット数癟から で実甚的なプログラミングに取り組んでいたす 。非理想的なプログラミング蚀語は、それぞれ独自の特性ず癖がありたす。 同時に、特定の限られた数の甚語がありたすが、これは異なる蚀語の異なる機胜に適甚される堎合があり、堎合によっおはそうではありたせん。 Javascriptでプログラミングを孊び始める人は、「クラス」が䜕であるかに぀いおある皋床の考えを持ち、それは最初の蚀語がRubyである人の考えずは非垞に異なるでしょう。 人々は、ある蚀語の背景を別の蚀語に持っお来お、䟋えば、通垞の閉鎖はないずいう非難を始めたす。なぜなら、圌らの蚀語では「閉鎖」ずいう甚語は完党に異なる䜕かを意味するからです。



時々、どういうわけか、これらすべおに耐えるこずができたす。 そしお、時には恥ずかしさが生じるこずがありたす。 このような状況の私の最も少ないお気に入りの䟋を次に瀺したす。



配列、ベクトル、およびリスト



Cでは、配列は、同じタむプの倉数の明確に定矩された量の倀を配眮できる順次デヌタブロックです。 int [5]は、int型の5぀の倉数を次々に盎接栌玍するように蚭蚈された配列を蚘述したす。



C ++は、ベクトルの抂念を、珟圚のニヌズに合わせお自動的にサむズ倉曎できる配列の類䌌物ずしお導入したす。 リストの暙準タむプもありたす。この堎合、二重リンクリストを参照したす実際、暙準は特定の実装に芁件を提瀺しおいたせんが、機胜芁件により、配列に基づくベクトル、および二重にリンクされたリストに基づくリストを論理的に実装したす。 しかし、ちょっず埅っおください C ++ 11では、「initializer_list」ずいう甚語が導入されおおり、その名前には「list」リストずいう単語が含たれおいたすが、実際は配列です。



もちろん、Lispリストはリンクリストであるため、頭ず尟ぞのアクセスの芳点からリストを簡単に凊理できたす。 Haskellも動䜜したす。さらに、むンデックスによっおアむテムにすばやくアクセスするためのData.Arrayがありたす。



Perlでは、シヌケンス型は配列ですが、ここで䜿甚するのに「型」ずいう蚀葉はあたり適切ではありたせんが、むしろ倉数の圢匏です。 Perlには「リスト」ずいう抂念もありたすが、これは匏の評䟡の䞀郚ずしお存圚する䞀時的なオブゞェクトにすぎず、埓来のコンテナヌデヌタ型ではありたせん。 これはかなり奇劙なこずであり、その説明には耇数の段萜が必芁なので、ここからは始めたせん。



Pythonでは、リストはC ++のベクトルに䌌たプロパティを持぀基本デヌタ型であり、CPythonではC配列に基づいお実装されたす。 暙準ラむブラリは、ほずんど䜿甚されないデヌタ型配列も提䟛したす。これは、C配列に数倀をパックしおスペヌスを節玄し、Cを介しおPythonにアクセスするプログラマヌを混乱させたす。 ああ、組み蟌みのバむト配列型がただありたすが、これはバむトを栌玍する配列ずは異なりたす。



Javascriptには配列型がありたすが、文字列キヌを持぀ハッシュテヌブルの䞊に構築されたす。 C配列に数倀を栌玍するためのArrayBufferもありたすPythonの配列タむプに非垞に䌌おいたす。



PHPでは、配列ず呌ばれるデヌタ型は、実際には文字列キヌを持぀順序付きハッシュテヌブルです。 PHPにもリストがありたすが、これはデヌタ型ではなく、単なる構文䞊の砂糖です。 PHPから他の蚀語に切り替えた人は、叀兞的なハッシュテヌブルが敎然ずしおいないように芋えるこずに時々驚かされたす。



Lua蚀語は、配列、ベクトル、たたはリストの甚語をたったく䜿甚せずに、あらゆる皮類の䌝統を拒吊したす。 そこにある唯䞀のデヌタ型はテヌブルず呌ばれたす。



2回起きないように、連想コンテナのデヌタ型の名前を芋おみたしょう。



C ++ マップただし、これは実際にはバむナリツリヌです。C++ 11はハッシュテヌブルであるunordered_mapを远加したす

JavaScript オブゞェクトこれは実際には叀兞的な連想配列ではありたせんが、文字列キヌでアクセス可胜な倀を栌玍できたす。たた、Mapデヌタ型もありたす。

ルア テヌブル

PHP 配列文字列キヌのみ

Perl ハッシュたた、タむプではなく「フォヌム」に加えお、ハッシュは完党に異なるものずも呌ばれるずいう事実による曖昧さ、さらに文字列キヌのみ

Python dict

Rust マップ2぀の別個のタむプ-BTreeMapずHashMapずしお存圚したすが



ポむンタヌ、リンク、゚むリアス



Cには、䞀郚のデヌタをメモリに保存するためのアドレスであるポむンタヌがありたす。 Cの堎合、これは自然なこずです。Cのすべおがメモリ内のデヌタを管理し、1぀の倧きなデヌタブロック内のアドレスずしおすべおのデヌタを衚珟するこずに関するものであるためです。 ポむンタは、この倧きなデヌタブロックの単なるむンデックスです。



C ++は、Cからポむンタヌを継承し、それらの乱甚に察しお盎ちに譊告したす。 別の方法ずしお、ポむンタずたったく同じように芋えるが、「*」挔算子を䜿甚する必芁のない倀にアクセスするためのリンクが提案されたす。 これにより、Cにはなかった新しい非垞に奇劙な機䌚がすぐに䜜成されたす。2぀のロヌカル倉数がメモリ内の同じデヌタブロックを指すこずができるため、行a = 5; 倉数bの倀を完党に倉曎できたす。



Rustにはリンクがあり、C ++構文も䜿甚したすが、実際には「借甚ポむンタヌ」です぀たり、ポむンタヌですが、透過的です。 Cポむンタヌの構文を䜿甚する蚀語には、あたり䞀般的ではない「玔粋なポむンタヌ」もありたす。



Perlにはリンクがありたす。 2぀の別個のタむプのリンクです。 ハヌドリンクアドレスが利甚できず、アドレスを盎接䜿甚しないこずを意味する唯䞀の䟋倖を陀き、Cのポむンタヌの類䌌物および゜フトリンク。倉数の内容を別の倉数の名前ずしお䜿甚したす。 たた、Perlには、C ++の参照ず同様に機胜する゚むリアスがありたすが、ロヌカル倉数では機胜せず、実際にはデヌタ型ではなく、単なるシンボルテヌブルの操䜜です。



PHPにはリンクがありたすが、Perlの圱響にもかかわらず、リンク構文はC ++から取られたした。 C ++は、それが参照する倉数のタむプによっおリンクを定矩したす。 しかし、PHPには倉数の宣蚀がないため、倉数は、挔算子を含む特定の操䜜セットに参加した瞬間からリンクず芋なされ始めたす。 この魔法のシ​​ンボルは、倉数に「参照性」を「感染」させたす。



Python、Ruby、JavaScript、Lua、Java、および他の倚くの蚀語には、ポむンタヌ、リンク、たたぱむリアスがありたせん。 これは、特定の高レベルのこずを説明する過皋で、「これが瀺す...」、「これは...を参照する」などのフレヌズをしばしば蚀わなければならないため、CおよびC ++の䞖界から来た人々にずっおこれらの蚀語を理解するこずを困難にしたすこれは人々を誀解させ、メモリ内の特定の領域ぞのポむンタたたはリンクが実際にあり、その内容に盎接アクセスできるずいう印象を䞎えたす。 この理由から、私はC ++゚むリアシングのリンクの動䜜を呌び出したす。これは、䜕が起こっおいるかずいう本質をより明確に反映し、「リンク」ずいう単語をより䞀般的に䜿甚するためです。



参照枡しおよび倀枡し



ずころで、リンクに぀いお。 Python に぀いおはすでにこれを説明したしたが、ここで短いバヌゞョンをもう䞀床曞きたす。 ここで重芁な質問は蚀語Cが意味ず芋なすものであり、この質問はCに関連する蚀語ファミリヌ以倖では意味をなさないため、この二分法はほずんどの蚀語で意味をなさない。



ここでの基本的な問題は、Cが構造を蚘述するための構文を持っおいるこずですが、構造の蚀語のセマンティクスはコヌドでは芋られたせん-単なるバむトのセットです。 構造はコンテナのように芋えたす。このような信頌性の高いコンテナです。内容は䞭括匧で囲たれおいるため、挔算子「。」を䜿甚する必芁がありたす。 内郚メンバヌにアクセスしたす。 しかし、Cの堎合、構造はバむナリデヌタの単なるブロックであり、intずそれほど倉わらず、たあ、少し倧きいかもしれたせん。 ああ、はい、あなたはただいく぀かの別々のデヌタを芋るこずができたす。 ある構造を別の構造内に配眮するず、C蚀語は倖郚構造内の内郚ブロックのデヌタブロックを愚かに分離したす。 ある構造を別の構造に割り圓おるず、たずえばdouble型の倉数を割り圓おる堎合ず同様に、通垞のバむトコピヌが発生したす。 線は幻想的です。 その結果、Cで唯䞀の「本圓の」コンテナはポむンタです



関数に構造䜓を枡すず、Cは他の型の倉数のように、構造䜓を完党にコピヌしたす。 関数で構造を倉曎する堎合は、関数で関数にポむンタヌを枡す必芁がありたす。 非垞に倧きな構造䜓を関数に枡したい堎合は、パフォヌマンスを向䞊させるために再びポむンタヌを䜿甚する必芁がありたす。



C ++がリンクの抂念を導入したした。これは、Cのすべおのポむンタが簡単すぎおわかりにくいのに突然気づいた堎合に備えおです。 これで、以前ず同様に、構造を「倀で」枡すこずができたすが、呌び出された関数がリンクを受け入れる堎合は、構造を「参照で」枡し、関数はそれを倉曎できたす。 関数の匕数は、枡される倉数の゚むリアスになるため、intのような単玔な型でも曞き換えるこずができたす。 この「参照による転送」は、「゚むリアスによる転送」ず呌ばれたす。



Java、Python、Ruby、Lua、JavaScript、および他の倚くの蚀語は、個別の゚ンティティずしおコンテナ䞊で動䜜したす。 内郚に構造がある倉数があり、この倉数を別の倉数に割り圓おるず、実際にはコピヌは行われたせん。 䞡方の倉数が参照するようになりたした...いいえ、参照しない、瀺す...いいえ、瀺さない...



そしお、圌女はここにいたす-甚語の問題です 蚀語Xがパラメヌタヌを倀で枡すのか参照で枡すのかを尋ねるず、おそらくこの人はC蚀語モデルの芳点で考え、他のすべおの蚀語をこの基本モデルに䜕らかの圢で圓おはたるものずしお提瀺したす。 「䞡方の倉数が参照されおいる」ず蚀えば、C ++リンク゚むリアスに぀いお話しおいるず思うかもしれたせん。 「䞡方の倉数が瀺す」ず蚀えば、Cスタむルのポむンタヌに぀いお話しおいるず刀断できたす倚くの堎合、蚀語には最初も2番目もありたせん。 しかし、英語では、私たちが蚀いたいこずを衚珟する他の蚀葉はありたせん。



意味的には、蚀語は、倉数の内容その意味が抜象的な䞖界で独自に存圚しおいるかのように動䜜し、倉数は単なる名前です。 割り圓おは、名前ず倀を関連付けたす。 これを初心者に「今はbを指しおいる」たたは「今では同じオブゞェクトを参照しおいる」ず説明するのは魅力的ですが、これらの説明は実際には蚀語に存圚しない間接性を远加したす。 aずbは䞡方ずも同じオブゞェクトを参照したす。



この堎合の関数呌び出しは、関数内の匕数が呌び出しコヌドが関数に枡したのず同じ倀を指定するため、割り圓おフォヌムです。 それらを倉曎するこずができたす-たた、呌び出しコヌドはこれらの倉曎の結果を芋るこずができたす。 呌び出された関数内で倉数を再割り圓おするこずはできたせん。この堎合の倉数ぱむリアスではありたせん。倀を割り圓おるず、名前関数内が新しい倀にバむンドされたすが、呌び出し元のコヌドの倉数には圱響したせん。 これはすべお、叀兞的な「参照枡し」や「倀枡し」をやや超えおいたす。 確立された甚語はたったくありたせん。オブゞェクトの転送、名前による転送、転送の共有ず呌ばれるものを聞きたした。



原則ずしお、C ++スタむルの参照枡しは、他の蚀語でも実装できたす前述したように、PHPはC ++リンク構文を䜿甚しお゚むリアスで転送できたす。 ただし、゚むリアスによる送信は、倀による送信の代替ずしおのみ存圚し、倀による送信は存圚したす。半䞖玀前の䜎レベルCでは、他のものを実装するこずは䞍可胜だったからです。



倀で枡すこずでできるこずはすべお、名前で枡すこずで明瀺的なコピヌを行うこずでもできたす。 さらに倚くの堎合、そのようなこずは、関数からいく぀かの倀を返すこずができるようにするために行われたす。これは、高レベル蚀語では他の倚くの方法で行うこずができたす。



無料タむピング



もちろんこれは解釈の問題ですが、個人的には「フリヌタむピング」などは存圚しないず確信しおいたす。 少なくずも、この甚語の特定の定矩を聞いたこずはありたせん。

私は思い出させたす





「匷い」タむピングず「匱い」タむピングの抂念は、䞖界の調和のずれた図を䜜成したす。 「静的」および「動的」な類型化も理解可胜であり、補完的です。 蚀語には静的および動的だけでなく、匷い型ず匱い型の䞡方の芁玠を含めるこずができたすが、䞀郚の䜍眮はただ䞀般的です。 たずえば、Goは静的に型付けされおいるず芋なされたすが、Goのむンタヌフェむス{}には動的な型付けの兆候がありたす。 逆に、Pythonは正匏に静的に型指定されおおり、各倉数はオブゞェクト型ですが、幞運を祈りたす。



「匷い」/「匱い」タむピングの関係は倉数の倀を指し、「静的」/「動的」はそれらの名前を指すため、4぀の組み合わせすべおが存圚したす。 Haskellは匷力で静的です。匱いず静的では、Pythonは匷力で動的です。Shellは脆匱で動的です。



それでは、「無料入力」ずは䜕ですか これは「匱い」の類䌌物であるず誰かが蚀いたすが、倚くの人は「自由に型付けされた」Pythonず呌んでいたすが、Pythonは匷い型付けの蚀語を指したす。 少なくずもCより匷い。



たた、「自由に型付けされた」ずいう甚語はほずんど軜rog的な意味で出くわすので、人々は「C ++のように型付けされおいない」こずを意味するず掚枬できたす。 ここでは、だれの牛が動き、C ++が沈黙するこずに泚意する必芁がありたす。 C ++型システムには欠陥はありたせん。 たずえば、タむプTぞのポむンタヌのタむプはどうなりたすか いいえ、これはT *ではありたせん。ヌルポむンタヌおよびこれはT型の倉数ぞのポむンタヌではないたたはランダムガベヌゞT型の倉数ぞのポむンタヌではない可胜性が高いを割り圓おるこずができるためです。 特定の型の倉数に実際にこの型の倀が含たれおいない可胜性がある堎合、静的型付けを誇りに思うポむントは䜕ですか



キャッシング



キャッシングで最もおもしろいこずは、これはどの蚀語の機胜でもなく、よく知られた抂念です。 キャッシングにより、䞀郚の蚈算結果が保存され、埌でそれらを繰り返す必芁がなくなりたす。 叀兞的な最適化、たたは速床のためのメモリの亀換。 キャッシュの最も重芁な特性は、キャッシュをクリアするか、キャッシュを砎棄するか、他の理由でキャッシュ内のデヌタにアクセスできない堎合、すべおが以前ず同じように動䜜し続け、少し遅くなるこずです。



そしお、䞀般的に再利甚するためにキャッシュをデヌタストレヌゞず呌ぶプログラマヌずコヌドをどこでも芋たす。 これは非垞に玛らわしいです。 良い䟋は、Pythonプロゞェクトでよく目にするコヌドの䞀䟋です。 圌に最初に気付いたのは、この機胜がreifyず呌ばれるPyramidプロゞェクトです。 圌女は、次のようなオブゞェクト属性の遅延初期化を実行したした。



class Monster: def think(self): # do something smart @reify def inventory(self): return []
      
      





ここでは、monster.inventoryは、実際に読んでみるたで存圚したせん。 この時点で、reifyが呌び出され䞀床だけ、返されるリストが属性になりたす。 すべおが完党に透過的です。倀が䜜成されるずすぐに、間接アクセスのオヌバヌヘッドが発生しない共通の属性になりたす。 それに䜕かを远加でき、すべおのアクセスで同じ結果が衚瀺されたす。 この属性は、芋る詊みによっお呜を呌ぶたで存圚したせんでした。



このようなアプロヌチは、特定の゚ンティティのいく぀かの関連するがただ別個の偎面を蚘述するオブゞェクトに意味がありたす䜕らかの理由でこれをすべお別個のクラスに分割するこずはできたせん。 そのようなオブゞェクトの䞀郚の初期化に時間がかかり、残りのオブゞェクトが機胜するためにその存圚が必芁でない堎合、明らかに必芁な堎合にのみ遅延初期化を䜿甚しお必芁なコンポヌネントを䜜成するこずは非垞に合理的です。



reifyは、長い間別個のコンポヌネントずしおPyPIリポゞトリに掲茉されおいたせんでした。 おそらくそれは䜕十行もれロから実装できるからです。 私が倚くのプロゞェクトで具䜓化を芋たものに぀いお話したずき、私は「倚くのプロゞェクトが私の膝の䞊に具䜓化の実装をコピヌたたは曞いた」こずを意味したした。 そしお最埌に、このコンポヌネントは... cached-propertyずいう名前でリポゞトリに远加されたした。 ドキュメントには、「キャッシュを無効にする」方法、぀たりオブゞェクトの内郚状態ぞの損傷の方法さえ瀺されおいたした。



私がここで芋た倧きな問題は、文字通り、私が芋たこのデコレヌタヌのすべおの䜿甚が、叀兞的な意味でのキャッシュではなかったこずです。 䞊蚘の䟋はやや玠朎ですが、それでも、キャッシュを「無効化」するず䞍可逆的な結果に぀ながりたす。Monster.inventoryの状態は完党に倱われたす。 @reifyの実際のアプリケヌションは、倚くの堎合、ファむルたたはデヌタベヌス接続を開きたす。これらの堎合、「無効化」はデヌタ砎壊に盞圓したす。 これはキャッシュではありたせん。キャッシュの損倱はスロヌダりンするだけで、メモリたたはディスク䞊のデヌタを損なうこずはありたせん。



はい。@ reifyを䜿甚するず、キャッシュを䜜成できたす。 それでも、dictを䜿甚しお、他のさたざたな方法でも䜜成できたす。



リポゞトリ内のこのコンポヌネントの出珟の早い段階でキャッシュプロパティの名前を倉曎する提案を提出しようずしたしたこれは、特に暙準蚀語ラむブラリに远加したい著者の意向を考慮するず重芁でした-しかし、誰も名前の名前付けが奜きではなく、䌚話はすぐに議論ず批刀に倉わりたした他の代替名。 したがっお、゚ンティティの呜名は、実際にコンピュヌタヌサむ゚ンスで最も重芁な問題です。



All Articles