C#, Dart, TypeScript , Python: side-by-side
Tags: csharp, dart, typescript, python
Published: 2024-01-14 20:42:17

## String formating

| Language   | Syntax Type                              | Example                                | Description                                                                           |
| ---------- | ---------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- |
| C#         | Composite Formatting                     | `string.Format("Hello {0}!", "World")` | Uses indexed placeholders within a format string.                                     |
|            | Interpolation                            | `$"Hello {name}!"`                     | Allows embedding expressions inside string literals.                                  |
| Dart       | String Interpolation                     | `'Hello $name!'`                       | Uses the dollar sign ($) to interpolate the value of Dart expressions within strings. |
|            | Concatenation                            | `'Hello ' + name + '!'`                | Combines strings together using the + operator.                                       |
| TypeScript | Template Literals                        | `` `Hello ${name}!` ``                 | Uses backticks and `${}` to interpolate expressions within strings.                   |
| Python     | Percent Formatting                       | `'Hello %s!' % name`                   | Uses % as a placeholder for variables and provides a tuple of values.                 |
|            | str.format()                             | `'Hello {}!'.format(name)`             | Uses curly braces {} as placeholders and provides values via the format method.       |
|            | f-Strings (Literal String Interpolation) | `f'Hello {name}!'`                     | Embeds expressions inside string literals using f-prefix and curly braces.            |

Each of these methods has its own advantages and use cases. For example, C#'s interpolated strings and Python's f-strings provide a very readable way to embed expressions in strings, while C#'s composite formatting is useful for more complex scenarios where you might want to reuse the same variable multiple times in a formatted string or apply specific formatting to values (like date or number formats).

It's important to note that these are not the only ways to format strings in these languages, but they are the most common and idiomatic methods

## Ternary Conditional Operator

| Language   | Syntax Example            | Equivalent If-Else Statement             |
| ---------- | ------------------------- | ---------------------------------------- |
| C#         | `var x = y == 2 ? 0 : 1;` | `if (y == 2) { x = 0; } else { x = 1; }` |
| Dart       | `var x = y == 2 ? 0 : 1;` | `if (y == 2) { x = 0; } else { x = 1; }` |
| TypeScript | `let x = y == 2 ? 0 : 1;` | `if (y == 2) { x = 0; } else { x = 1; }` |
| Python     | `x = 0 if y == 2 else 1`  | `if y == 2: x = 0 else: x = 1`   |

In Python, the ternary conditional operator is slightly different in syntax. It uses the `if ... else` keywords in a single line, rather than the `?` and `:` symbols. The general form is `x = true_value if condition else false_value`.

In all these languages, the ternary conditional operator is used to make the code more concise and to reduce the need for a multi-line if-else statement when only a single value assignment is needed based on a condition.

## Code Blocks

| Language   | Code Block Definition | Notes                                                                                                                                                                                                                  |
| ---------- | --------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| C#         | Curly braces `{}`     | Curly braces are required to define the scope of code blocks for classes, methods, loops, and conditional statements. Indentation is a best practice for readability but is not enforced by the compiler.              |
| Dart       | Curly braces `{}`    | Similar to C#, Dart uses curly braces to define the scope of code blocks. Indentation is recommended for readability but is not enforced by the language.                                                              |
| TypeScript | Curly braces `{}`     | TypeScript, like JavaScript, uses curly braces to define the scope of functions, classes, loops, and conditional statements. Indentation is a matter of style and best practices, not a language requirement.          |
| Python     | Indentation           | Python uses indentation to define code blocks. A consistent level of indentation is required to denote the scope of loops, conditional statements, functions, and classes. Curly braces are not used for this purpose. |

**C#, Dart, TypeScript:** In these languages, a code block begins with an opening curly brace `{` and ends with a closing curly brace `}`. Everything within the braces is considered part of the same block. For example:

```csharp
// C# example
if (condition)
{
    // This is a code block
    Console.WriteLine("Condition is true.");
}
```

```dart
// Dart example
if (condition) {
  // This is a code block
  print('Condition is true.');
}
```

```typescript
// TypeScript example
if (condition) {
    // This is a code block
    console.log("Condition is true.");
}
```

**Python:** Python uses indentation to define the beginning and end of a code block. The amount of indentation for each block is consistent, and typically four spaces are used per indentation level. For example:

```python
# Python example
if condition:
    # This is a code block
    print("Condition is true.")
```

**Enforced by Language:** The enforcement of curly braces or indentation is a syntactic requirement in these languages. In C#, Dart, and TypeScript, omitting curly braces for code blocks that require them will result in a compiler error. In Python, inconsistent indentation will lead to a syntax error.

**Readability:** While not enforced by the compiler or interpreter in C#, Dart, and TypeScript, indentation is still crucial for maintaining readable and maintainable code. It is considered a best practice to use consistent indentation, such as using spaces or tabs, to visually separate code blocks from the surrounding code.

## Loops

### For Loop

| Language   | Syntax Example                               |
| ---------- | -------------------------------------------- |
| C#         | `for (int i = 0; i < 10; i++) { /* ... */ }` |
| Dart       | `for (var i = 0; i < 10; i++) { /* ... */ }` |
| TypeScript | `for (let i = 0; i < 10; i++) { /* ... */ }` |
| Python     | `for i in range(10): # ...`                  |

### For-Each Loop

| Language   | Syntax Example                                   |
| ---------- | ------------------------------------------------ |
| C#         | `foreach (var item in collection) { /* ... */ }` |
| Dart       | `for (var item in collection) { /* ... */ }`     |
| TypeScript | `for (let item of collection) { /* ... */ }`     |
| Python     | `for item in collection: # ...`                  |

### While Loop

| Language   | Syntax Example                    |
| ---------- | --------------------------------- |
| C#         | `while (condition) { /* ... */ }` |
| Dart       | `while (condition) { /* ... */ }` |
| TypeScript | `while (condition) { /* ... */ }` |
| Python     | `while condition: # ...`          |

### Do-While Loop

| Language   | Syntax Example                                  |
| ---------- | ----------------------------------------------- |
| C#         | `do { /* ... */ } while (condition);`           |
| Dart       | `do { /* ... */ } while (condition);`           |
| TypeScript | `do { /* ... */ } while (condition);`           |
| Python     | _Python does not have a built-in do-while loop_ |

### Loop Control Statements

| Language   | Break Example | Continue Example |
| ---------- | ------------- | ---------------- |
| C#         | `break;`      | `continue;`      |
| Dart       | `break;`      | `continue;`      |
| TypeScript | `break;`      | `continue;`      |
| Python     | `break`       | `continue`       |

### Notes on Loop Usage
**C#, Dart, TypeScript:** These languages share a similar C-style syntax for loops, including the traditional for loop with initialization, condition, and increment expressions. They also support for-each loops for iterating over collections, with slight differences in keyword usage (foreach in C# and for in Dart and TypeScript).

**Python:** Python's for loop is more like a for-each loop in C-style languages, iterating over items in a collection or sequence. Python uses the range() function to iterate over a sequence of numbers. Python does not have a traditional C-style for loop or a do-while loop.

**Do-While Loop:** Python does not have a built-in do-while loop construct. However, you can achieve similar behavior using a while loop with a condition that is always true initially, followed by a conditional break at the end of the loop body.

**Loop Control Statements:** The break statement is used to exit a loop prematurely, while the continue statement is used to skip the current iteration and proceed to the next iteration of the loop. These control statements are used similarly across all four languages.

## Anonymous and Higher-Order Functions

### Anonymous Functions (Lambdas)

| Language   | Syntax Example                                 |
| ---------- | ---------------------------------------------- |
| C#         | `Func<int, int> square = x => x * x;`          |
| Dart       | `var square = (int x) => x * x;`               |
| TypeScript | `const square = (x: number): number => x * x;` |
| Python     | `square = lambda x: x * x`                     |

### Higher-Order Functions

| Language   | Syntax Example (e.g., using `map`)                 |
| ---------- | -------------------------------------------------- |
| C#         | `var squaredNumbers = numbers.Select(x => x * x);` |
| Dart       | `var squaredNumbers = numbers.map((x) => x * x);`  |
| TypeScript | `const squaredNumbers = numbers.map(x => x * x);`  |
| Python     | `squared_numbers = map(lambda x: x * x, numbers)`  |

### Notes on Anonymous Functions and Higher-Order Functions

**C#** uses lambda expressions to create anonymous functions and has a variety of higher-order functions available through LINQ (Language Integrated Query), such as `Select`, `Where`, and `Aggregate`.

**Dart** supports arrow syntax for defining anonymous functions concisely. Higher-order functions like `map`, `where`, and `reduce` are commonly used on collections.

**TypeScript**, like Dart, uses arrow functions for concise anonymous function syntax. It also has higher-order functions on arrays similar to Dart and other JavaScript array methods.

**Python** uses the `lambda` keyword to define anonymous functions. It has built-in higher-order functions like `map`, `filter`, and `reduce` (the latter is found in the `functools` module).

## Object-Oriented Programming

| Feature              | C#                         | Dart                                | TypeScript                 | Python                                 |
| -------------------- | -------------------------- | ----------------------------------- | -------------------------- | -------------------------------------- |
| Class Definition     | class MyClass { }          | class MyClass { }                   | class MyClass { }          | class MyClass:                         |
| Inheritance          | class Derived : Base { }   | class Derived extends Base          | class Derived extends Base | class Derived(Base):                   |
| Interfaces           | interface IMyInterface { } | class MyInterface { }               | interface IMyInterface { } | class MyInterface:                     |
| Polymorphism         | Virtual/override methods   | Virtual methods with `@override`    | Methods can be overridden  | Defining methods in child classes      |
| Encapsulation        | public/private/protected/internal/protected internal/private protected  | Public by default, private with `_` | public/private/protected   | Public by default, private with `_`    |
| Abstraction          | Abstract classes/methods   | Abstract classes/methods            | Abstract classes/methods   | Not directly supported, use ABC module |
| Constructors         | MyClass() { }              | MyClass() { }                       | constructor() { }          | def **init**(self):                    |
| Static Members       | static keyword             | static keyword                      | static keyword             | @staticmethod decorator                |
| Properties           | get; set;                  | get and set keywords                | get and set keywords       | @property decorator                    |
| Method Overloading   | Supported                  | Not supported                       | Supported                  | Not natively supported                 |
| Operator Overloading | Supported                  | Supported                           | Not natively supported     | Supported                              |
| Multiple Inheritance | Not supported              | Not supported                       | Not supported              | Supported via Mixins                   |
| Access Modifiers     | Yes                        | No (privacy by convention)          | Yes                        | No (privacy by convention)             |

Here are some key points about OOP in each language:

**C#:** C# is a statically typed language with a rich set of OOP features. It supports most of the classical OOP concepts, including interfaces, abstract classes, encapsulation with access modifiers, and polymorphism through virtual and override methods. C# does not support multiple inheritance for classes, but it allows a class to implement multiple interfaces.

**Dart:** Dart is an object-oriented language that supports classes and interface-like behavior using abstract classes. Unlike C#, Dart does not have interfaces as a separate construct; instead, every class implicitly defines an interface. Dart does not support method overloading but does support operator overloading. It uses a single underscore to denote private members.

**TypeScript:** TypeScript is a superset of JavaScript that adds static typing and OOP features. It supports classes, interfaces, and inheritance. TypeScript's OOP features are similar to those of C#, but since it compiles down to JavaScript, which is a prototype-based language, some features like operator overloading are not natively supported.

**Python:** Python is a dynamically typed language that supports OOP. It allows for multiple inheritance and uses a special module called abc (Abstract Base Classes) to create abstract classes and methods. Python does not have built-in access modifiers, but it follows a naming convention using underscores to indicate the intended level of privacy. Method overloading is not natively supported, but operator overloading is.