言語を学習している人なら、おそらく「構文」という言葉を聞いたことがあるでしょうし、いつもそれを扱っているでしょう。 (クソ構文エラー).
数日前の夜、私はプログラミングのパラダイムやテクニックに真剣に従ったことがなかった、と思っていました。そして今日は、いつも聞いている (たとえすでに覚えていても) 最も小さなトピックから学び始めました。このリポジトリを作成しました。私が行った学習パスは特徴的です (LEARNING_LIST.md ファイル内)。私たちが思考や感情を伝達するための自然言語とは対照的に、プログラミング言語は、当初はコンピューターと通信する目的で男性と女性によって定義された人工言語と見なすことができますが、同様に重要なのは、人々の間でアルゴリズムを通信することです。 .
たとえば、言語定義は 3 つのコンポーネントで構成されます:
構文: プログラミング言語の構文は、その言語で正しく構造化されたプログラムとみなされるシンボルの組み合わせを定義する一連の規則です。言語の構文はその表面形式を定義します。テキストベースのプログラミング言語は、一連の文字に基づいています。テキスト言語の語彙文法は、文字をトークンに分割する方法を指定します。構文は、言語で整形式の文 (またはプログラム) を作成するために記号を組み合わせる方法を指します。構文は、言語の構成要素間の正式な関係を定義し、それによって言語内の正当な文字列を構成するさまざまな式の構造的記述を提供します。構文は、言語における記号の形式と構造のみを扱い、その意味は考慮されません。構文は、文が言語の文法に対して有効であるかどうかのみに関係する概念です
意味論: 意味論とは、文が有効な意味を持つかどうかに関するものです。セマンティクスは、言語における構文的に有効な文字列の意味を明らかにします。自然言語の場合、これは文やフレーズを私たちの経験の対象、思考、感情と関連付けることを意味します。プログラミング言語の場合、セマンティクスは、その言語でプログラムを実行するときにコンピューターが従う動作を記述します。この動作は、プログラムの入力と出力の関係を説明することによって、またはプログラムが実際のマシンまたは抽象的なマシン上でどのように実行されるかを段階的に説明することによって明らかにすることができます。セマンティクスは意味の研究の総称です。コンピューターサイエンスでは、プログラミング言語セマンティクスの主題は、プログラムに正確な数学的意味を与えることを目指します。
自然言語では、文は文法的には正しいが、意味的には意味が不明な場合があります。たとえば、次の文:
「その男は店から無限を買いました。」
これは文法的には正しいですが、現実の世界では意味がありません。同様に、プログラミング言語でも、ステートメントは構文的には正しくても、言語のルールや意図された意味に違反するため、意味的には正しくない場合があります。
プログラミングの低レベルのセマンティクスでは、正しい構文を持つステートメントが言語の型システムまたはその他の規則に従っても意味をなすかどうかを考慮します。構文が有効であっても、操作の意味が無効になる可能性があります。 Java などの静的型付け言語の型システムは、実行前にこれらのルールを適用するのに役立ちますが、JavaScript のような動的型付け言語では、実行時までこれらのルールが常に適用されるわけではありません。
JavaScript では型付けが緩く、より厳密な型システムに伴う保護が受けられない可能性があり、言語では意味的に意味をなさない特定の操作が許可されます。次の JavaScript コードを考えてみましょう:
let name = "Alice"; name = 42; // No error, but semantically this doesn't make sense.
ここで、構文は完全に有効であり、JavaScript では割り当てが許可されていますが、意味的には奇妙です。おそらく文字列 (名前) を保持することを目的とした変数に数値 (42) を割り当てようとしています。 JavaScript にはこの間違いを防ぐための型チェックはありませんが、開発者の意図と矛盾するため、これは 低レベルのセマンティック エラーです。
それを実装すれば。実行されます。エラーなし!
TypeScript や Java のような厳密な言語では、コンパイル中にただちに型エラーが発生します。
JavaScript のスーパーセットである TypeScript では、次のような低レベルのセマンティクスの問題を防ぐために型チェックが導入されています。
let name: string = "Alice"; name = 42; // Error: Type 'number' is not assignable to type 'string'.
TypeScript では、42 は数値であり、文字列として宣言された変数に代入できないため、コンパイラはセマンティック エラーを検出します。この型の強制により、開発者は意図しない間違いから保護されます。
JavaScript では、これらの低レベルのセマンティクスの問題を回避するために、開発者は実行時チェックをよく使用します。
let name = "Alice"; if (typeof name !== "string") { throw new Error("Expected a string!"); }
JavaScript は型を強制しませんが、手動チェックを追加すると、間違った型がプログラム内で問題を引き起こすエラーを回避できます。
より高いレベルでは、セマンティクスはプログラムが何を達成すべきかに関係します。それは、プログラムに有効な構文があるかどうか、または型が正しく揃っているかどうかだけではなく、プログラムが開発者が意図したとおりに動作するかどうか、またはプログラムが対処するように設計された問題を解決するかどうかが重要です。
たとえば、単純な株式取引システムを構築しているとします。コードの高レベルのセマンティクスは、システムが正しいビジネス ロジックを使用して正しい方法で株を取引することを確認することです。コードで型エラーや構文エラーが発生しなくても、意図した機能を満たせない可能性があります。
単純化された株式取引シナリオを使用した高レベルのセマンティクスの JavaScript の例を見てみましょう:
let openTrade = { symbol: "EURUSD", direction: "buy", profit: 100 }; function closeTrade(trade) { if (trade.profit >= 50) { console.log(`Closing trade for ${trade.symbol} with profit of ${trade.profit}`); } else { console.log(`Trade for ${trade.symbol} is not ready to close.`); } } // Check if a trade is open for EURUSD and close it if the profit target is reached. closeTrade(openTrade);
構文は正しく、プログラムはエラーなしで実行されます。ただし、同じシンボルに対して誤って 2 つの取引を入力するなど、システムのビジネス ルールに違反する、より高いレベルでの間違いが発生したと想像してください。
let openTrades = [ { symbol: "EURUSD", direction: "buy", profit: 100 }, { symbol: "EURUSD", direction: "sell", profit: 20 } ]; // Check all trades and close any that hit their profit target. openTrades.forEach(trade => closeTrade(trade));
ここでは、両方の取引が独立して処理されますが、システムは最終的に同じシンボルで 2 つの取引 (1 つは買い方向、もう 1 つは売り方向) になります。これは、常にシンボルごとに 1 つのオープン取引のみを行う必要があるという高レベルのビジネス ルールを破ります。
コードは構文エラーや型エラーなしで実行されますが、高レベルでは意味的に正しくありません。システム ロジックでは、シンボルごとに一度に 1 つの取引のみがアクティブになるようにする必要がありました。このエラーは、現実世界の取引システムにおいて、金銭的損失などの予期せぬ結果を引き起こす可能性があります。
この高レベルのセマンティクスの問題を解決するには、特定のシンボルに対して 1 つの取引のみが開かれるようにロジックを調整する必要があります。
let openTrades = [ { symbol: "EURUSD", direction: "buy", profit: 100 } ]; function openNewTrade(newTrade) { // Ensure no other trades are open for the same symbol. const existingTrade = openTrades.find(trade => trade.symbol === newTrade.symbol); if (!existingTrade) { openTrades.push(newTrade); console.log(`Opened new trade for ${newTrade.symbol}`); } else { console.log(`Cannot open a new trade for ${newTrade.symbol}, trade already exists.`); } } openNewTrade({ symbol: "EURUSD", direction: "sell", profit: 0 });
ここでは、同じシンボルに対してアクティブな取引がすでに存在する場合、新しい取引を開始できないことをロジックによって保証します。これは、構文や型の問題ではなく、プログラムが従うべきコア ビジネス ロジックに対処するため、高レベルのセマンティック修正です。
これはそれぞれについての基本的な情報でした。詳細については、次の項目を参照してください:
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3