NAV
C# Python Rust

Introduction

Comparing General Programming Language

About

This page provides a comparison between many general purpose programming languages. General purpose here meaning any coding languages that can be used in a variety of use cases (although they need not necessarily be the best for all use cases). These languages should at minimum be Turing Complete. These languages can range from dynamic to static type checking, be compiled or interpreted, and have many different syntactic sugar. The goal is to show how each language approaches common semantic programming constructs such as bindings, conditionals, and loops. This will only focus on the language by itself and not any libraries (including any standard libraries) that it may use.

Languages

This page will have 3 languages you may switch between and compare.

Introduction to each of the supported languages. Also includes a numbered list of sources referenced.

// Sources and information about the C# language
// [1]: https://learn.microsoft.com/en-us/dotnet/csharp/
// 
# Sources and information about the Python language
# [1]: https://docs.python.org/3/reference/index.html
# [2]: https://peps.python.org
# 
// Sources and information about the Rust language
// [1]: https://doc.rust-lang.org/reference/index.html
// [2]: https://doc.rust-lang.org/rustdoc
// 

The current version for each of the languages are defined in the table.

Language Name Earliest Working Version Latest Working Version
C# ??? 8.0
Python ??? 3.7
Rust ??? 1.64.0

Unless otherwise noted as a comment in the code, all code snippets should work with any version between the earliest and latest working versions for the associated language.

Comments

These are pieces of code that are generally ignored by the compiler or interpreter. Comments help programmers with providing extra information about the code without executing it.

Line Comments

Line Comments between language

// This is a single line comment
// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/comments
# This is a single line comment
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#comments
// This is a single line comment
// Source [1]: https://doc.rust-lang.org/reference/comments.html#non-doc-comments

All line comments produce no output

Line comments are comments that run from the start of some symbol to the end of the line. Anything placed between will be ignored or removed when running the program. Once the line terminates, the comment also terminates, allowing the program to resume processing code after.

Start Symbol Languages
// C#, Rust
# Python

Block Comments

Block Comments (or equivalent) between language

/*
    This
    is
    a
    block
    comment

    Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/comments
*/
"""
    This
    is
    a
    multi-line
    string
    (Not a true block comment but equivalent)
    Can use either triple single quote (') or triple double quote (")

    Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
        -> see "longstring" definition
"""
/*
    This
    is
    a
    block
    comment

    Source [1]: https://doc.rust-lang.org/reference/comments.html#non-doc-comments
*/

All block comments produce no output

Block comments are comments that run from a certain start symbol to an end symbol. This means that comments can cover a small span of text (such as a single word within the same line) or a large span of text (such as a comment that spans multiple lines). Block comments can also be nested within themselves.

Has Block Comments? Languages
Yes, Directly C#, Rust
Sort of, Indirectly Python
No
Start Block Comment Symbol Start Block Comment Symbol Languages
/* */ C#, Rust

For languages don't directly have block comments, these are conventional alternative:

Block Comment Alternative Languages
Multi-Line Strings Python

Documentation Comments

Documentation comment examples

/// <summary> This is a single line documentation comment. </summary>
/** <summary>
    This is a multiple
    line documentation comment.
    This can apply to any class and its members.
    Uses XML markup for formatting.

    Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/
</summary>
*/
""" This is a documentation comment applied to class, function or module when it is the first expression inside. 
    Source [1]: https://docs.python.org/3/glossary.html#term-docstring 
    Source [2]: https://peps.python.org/pep-0257/

    Uses ReStructureText markup for formatting 
    Source [2]: https://peps.python.org/pep-0287/
"""
//! This is a outer line documentation comment
/*! This is an outer block documentation comment.
    Applies to the parent item of this comment.
*/ 

/// This is an inner line documentation comment
/** This is an inner block documentation comment.
    Applies to the item after this comment.
    Uses Markdown for formatting.
*/

// Source [1]: https://doc.rust-lang.org/reference/comments.html#doc-comments
// Source [2]: https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html

Comments that document your code outside of the source code and are generally used to generate documentation. Not all languages have this facility built into their compiler or interpreter.

Has Documentation Comments Languages
Yes C#, Python, Rust
No
Documentation Markup Language Languages
CommonMark Markdown Rust
ReStructureText Python
XML C#

Token

These are the smallest meaningful value known by the program. They often take the form of literal values, identifiers, and reserved keywords and operators. There are many different kinds of tokens unique to each programming language, so this section will focus on the general categories often found between languages.

Tokens are created during the lexing stage of the parser.

Literal Tokens

These tokens are parsed as the exact fixed value they represent and hold no other meaning beyond themselves. They often represent a value of basic types defined in the program. See Types Section for more details on this.

Boolean Literal

Example boolean literal values across languages

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/bool#literals
// True and False Literals
true
false
# Source [1]: 
#   - https://docs.python.org/3/library/constants.html#False
#   - https://docs.python.org/3/library/constants.html#True
# True and False Literal - Constants in Python
True
False

// Source [1]: https://doc.rust-lang.org/reference/expressions/literal-expr.html#boolean-literal-expressions

// True and False Literal
true
false

These are literal values which might eventually become boolean value inside a program. Generally, one represents the concept of "true" and the other the concept of "false".

True Keyword False Keyword Languages
true false C#, Rust
True False Python

Numeric Literal

Example numeric literal values across languages

// Integral Literal
// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types#integer-literals 
0
42
-1
100_000
// Floating Point Literal
// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types
3.14
-2.71
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals
# Python has 3 kinds of numeric literals: Integer, Floating Point, and Imaginary
# Integer Literal
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#integer-literals
0
42
-1
100_000
# Floating Point Literal
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#floating-point-literals
3.14
-2.71
# Imaginary Literal
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#imaginary-literals
1j
8.32j
// Source [1]: 
//      - https://doc.rust-lang.org/reference/tokens.html#numbers
//      - https://doc.rust-lang.org/reference/tokens.html#number-literals

// Integer Literal
// Source [1]: https://doc.rust-lang.org/reference/tokens.html#integer-literals
0
42
-1
100_000
// Floating Point Literal
// Source [1]: https://doc.rust-lang.org/reference/tokens.html#floating-point-literals
3.14
-2.71

These are any literal tokens which may eventually become a numeric value inside the program. These are used to represent any kind of number including integral numbers and real numbers, and can also be in represented in different bases from decimal, such as binary and hexadecimal.

One kind of distinction a language can make is whether floating point numbers and integers are treated as separate kinds of literal values.

Float-Integer Distinction Languages
Yes C#, Python, Rust
No

Literal Text

Example textual literal values across languages

// Character Literal
// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#6455-character-literals
'a'
// String Literal
// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#6456-string-literals
"Hello"
# String Literal
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
# Python does not distinguish between characters and strings
# Characters are just strings of length 1
'a'
"Hello"

// Character Literal
// Source [1]: https://doc.rust-lang.org/reference/tokens.html#character-literals
'a'
// String Literal
// Source [1]: https://doc.rust-lang.org/reference/tokens.html#string-literals
"Hello"

These are literal values which might eventually become text value inside a program.

Char-String Distinction Languages
Yes C#, Rust
No Python
Char Start Symbol Char End Symbol Languages
' ' C#, Rust
" or ' " or ' Python
String Start Symbol String End Symbol Languages
" " C#, Rust
" or ' " or ' Python

Keyword Token

Keywords are tokens that have specific meaning in the language. The table show the total number of keywords found in the language (though not all are strictly used).

Language Number of Keywords
C# 120
Python 38
Rust 54

Strict Keyword

Example of strict keywords

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
// Each keyword is separated by comma (,)
abstract , as , base , bool , break , byte , case , catch , char , checked , class , 
const , continue , decimal , default , delegate , do , double , else , enum , event , 
explicit , extern , false , finally , fixed , float , for , foreach , goto , if , 
implicit , in , int , interface , internal , is , lock , long , namespace , new , null , 
object , operator , out , override , params , private , protected , public , readonly , 
ref , return , sbyte , sealed , short , sizeof , stackalloc , static , string , struct , 
switch , this , throw , true , try , typeof , uint , ulong , unchecked , unsafe , ushort , 
using , virtual , void , volatile , while
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#keywords
# Each keyword is separated by comma (,)
and , as , assert , async , await , break , class , continue , def , del , 
elif , else , except , False , finally , for , from , global , import , 
if , in , is , lambda , not , None , nonlocal , or , pass , raise , 
return , True , try , while , with , yield
// Source [1] https://doc.rust-lang.org/reference/keywords.html#strict-keywords
// Each keyword is separated by comma (,)
as , async , await , break , const , continue , crate , dyn , else , enum , 
extern , false , fn , for , if , impl , in , let , loop , match , mod , 
move , mut , pub , ref , return , self , Self , static , struct , 
super , trait , true , type , unsafe , use , where , while

Strict keywords are always treated as keywords. When parsing/lexing, these words can never be treated as an identifier directly.

Contextual Keyword

Example of contextual keywords across languages

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/#contextual-keywords
// Each keyword is separated by comma (,)
add , and , alias , ascending , args , async , await , by , descending , dynamic , equals , file , from , 
get , global , group , init , into , join , let , managed , nameof , nint , not , notnull , nuint , on , 
or , orderby , partial , record , remove , required , scoped , select , set , unmanaged , value , var , 
when , where , with , yield
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#soft-keywords
# This is since version 3.10
# Each keyword is separated by comma (,)
_ , case , match
// Source [1]: https://doc.rust-lang.org/reference/keywords.html#weak-keywords
// Each keyword is separated by comma (,)
dyn , union , 'static

These are any keywords that are sometimes keywords when in a specific context.

Identifier Token

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#643-identifiers
example
ident_1
_ident2
// Keyword as identifier
@if
# Source [1]: https://docs.python.org/3/reference/lexical_analysis.html#identifiers
example
ident_1
_ident2
// Source [1]: https://doc.rust-lang.org/reference/identifiers.html
example
ident_1
_ident2
// Keyword as identifier
r#if

These are the name that can bind to values or other names. Generally, only names not already keywords are considered identifier. Some languages can treat keywords as identifiers through a special prefix.

Type

A data type represents a set of all valid values that are possible and operations/functions one can apply to them. Data types act as an abstraction over and provide meaning to the underlying byte representation.

We can classify types into two categories: atomic and composite.

Has Types Languages
Yes
Unityped
No
Type Checking Languages
Compile Time (Static) C#, Rust
Runtime (Dynamic) Python
Type Declaration Languages
Explicit C#
Inferred Rust?
Implicit Python

In the next sections, we will only go over types that are directly available (that is, types that do not depend on other files nor user definition).

Atomic Types

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
// List of data types separated by comma ( , )
bool, byte, sbyte, char, decimal, double, float, 
int, uint, nint, nuint, long, ulong, short, ushort,
// void - act as a type for function that returns nothing
# Source [1]: https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy
# List of data types separated by comma ( , )
None, NotImplemented, Ellipsis, 
# Sub-classes of Number supertype
int, bool, float, complex 
// Source [1]: https://doc.rust-lang.org/reference/types.html
// List of data types separated by comma ( , )
bool,
// Numeric
i8, u8, i16, u16, f32, i32, u32,  f64, i64, u64
// Textual
char

These are all types that have values which do not hold other values. At a low level, all types are just some way of representing a pattern of byte(s). The idea of these types is that they provide the fundamental units for the type system.

Composite Type

// Source [1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types
// List of data types separated by comma ( , )
object, string, dynamic
# Source [1]: https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy
# List of data types separated by comma ( , )
# Sequence types
str, bytes, bytearray, list, tuple,
# Set types
set, frozenset,
# Mapping Types
dict,
# Class and object
class, object
# Slice
slice,
# Functions, Generators, Coroutines, and Async functions 
// Source [1]: https://doc.rust-lang.org/reference/types.html
// List of data types separated by comma ( , )
struct, enum, union, 
// Tuple, Array, Slice, 
// References, Raw Pointer, Function Pointer,
// Trait, Impl

These are types representing values that hold other values. This means that other types are needed.

Expression

Expressions are a combination of tokens that evaluate to some value. Expressions may or may not necessarily change the state of the program after being evaluated.

Statement

Statements are a combination of tokens that change the state of the program when executed. Statements may or may not produce results after execution.

Binding

A binding takes identifiers and relate that to an expression or value.

Variable

bool a = true;
a = True
// Immutable variable
let a: bool = true;
let b = false;

// Mutable variable
let mut c: bool = true;
let mut d = false;

Variable bindings take a value or the result of an expression and associate an identifier with it. Once bound, the variable may be allowed to change values later on. In dynamic languages, they may also be allowed to change types.

Binding Operator Languages
= C#, Python, Rust
Variable Type Languages
Always required C#
Optional, type inferred Rust
Optional, type hinting Python
Type Location Languages
Before identifier C#
After identifier : Rust, Python
Variable default mutability Languages
Mutable (changable) C#, Python
Immutable (not changable) Rust
Binding can change types Languages
Yes Python
No C#, Rust

Constant

const bool A_CONST = true;
# Python has no enforceable constant
# By conventions, identifiers in SCREAMING_SNAKE_CASE usually signify constants 
A_CONST = True
const A_CONST: bool = true;

Constant binding takes a value or the result of some constant expression and associates it with an identifier. Once bound, the identifier cannot change values for the life of its scope.

Prefix Keyword Languages
const C#, Rust
None Python
Binding Operator Languages
= C#, Python, Rust
Constant Type Languages
Always required C#, Rust
Optional, type hinted Python
Type Location Languages
Before identifier C#
After identifier : Rust, Python

Callable Unit

void NoParameterFunction(){}
void SingleParameterFunction(bool param){}
void MultipleParameterFunction(int param1, int param2){}
def no_parameter_function():
    pass

def single_parameter_function(param):
    pass

def multiple_parameter_function(param1, param2):
    pass
fn no_parameter_function() -> () {}
fn single_parameter_function(param1: i64) -> () {}
fn multiple_parameter_function(param1: i64, param2: i64) -> () {}

Also known functions, procedures, subroutines. These bind an identifier to some block of code. They can take values in as parameter as inputs to the function, in which identifiers of the same name may be referred inside the code block, and return values back out.

Function Definition Keyword Languages
def Python
fn Rust
No Keyword C#
Parameters Typing Languages
Always required C#,Rust
Optional, type hint Python
Parameter Types Required Languages
Always C#, Rust
Optional, type hint Python
Resulting Typing Languages
Always required C#
Almost always Rust (unless () (unit type))
Optional, type hint Python
Resulting Type Location Languages
Before identifier C#
After parameters -> Rust
After parameters : Python

Control Flow

Control flow code determines how code flows in the program. According to the structured program theorem, there are only three constructs needed to build any Turing-equivalent machine: sequence, selection, and repetition.

Sequence

// S1;S2
/* 
S0;
{ 
    S1;
    S2;S3;
    S4;
}
S5;
*/ 
# S1\nS2
# or
# S1;S2
"""
S0
# implied block
    S1;
    S2
    S3;S4
S5

"""
// S1;S2
/*
S0;
{ 
    S1;
    S2;S3;
    S4;
}
S5;
*/

A sequence defines how one can separate two statements from each other. The idea is for the program to execute the first statement and then execute the next statement.

Sequence Separator Languages with this as Primary Languages with this as Secondary
; C#, Rust Python
newline Python

Multiple sequences can be pulled together into a block.

Sequence Open Block Sequence Close Block Languages
{ } C#, Rust
Indent Dedent Python

Selection

Also known as conditional. For this control flow, it can branch out into different code sequences depending on certain conditions.

Single Branch

Example of single branch conditional

bool condition = true; // or false
if(condition){
    // Code here run when condition is true
}
condition: bool = True # or False
if condition:
    # Code here run when condition is true
    pass
let condition: bool = true; // or false
if condition {
    // Code here run when condition is true
}

This conditional branches to a block of code if some condition is true, and is skipped if the condition is false. The true branch meets back to the main path of execution. This kind of conditional can be used to implement an optional path of execution when some condition is met.

Branching Keyword Languages
if C#, Python, Rust
Structure Languages
if (<condition_expression>) {<true_block>} C#, Rust
if <condition_expression> {<true_block>} Rust
if <condition_expression>: INDENT <true_block> DEDENT Python

Branch With Default (if-else)

Example of branch with default conditional

bool condition = true; // or false
if(condition){
    // Code runs here when conditional is true
}
else {
    // Code runs here when conditional is false
}
condition = True # or False
if condition:
    # Code runs here when conditional is True
    pass
else: 
    # Code runs here when conditional is False
    pass
let condition = true; // or false
if condition {
    // Code runs here when conditional is true
}
else {
    // Code runs here when conditional is false
}

This modifies a conditional by creating a branch for code after any conditions prior to it is false. Think of this as the default case. Note that unlike having code outside the conditional, the code only runs inside this default case only when it has not taking any path previously.

Default Keyword Languages
else C#, Python, Rust
Structure After If-Condition Languages
else {<false_block>} C#, Rust
else: INDENT <false_block>} DEDENT Python

Multiple Branches

Example of multiple branch:

bool condition_1 = false; // or true
bool condition_2 = true; // or false
if(condition_1){
    // Code runs here when conditional_1 is true (regardless of condition_2)
}
else if (condition_2){
    // Code runs here when condition_1 is false and condition_2 is true
}
else {
    // Code runs here when both condition_1 and condition_2 are false
}
condition_1 = False # or True
condition_2 = True # or False
if condition_1:
    # Code runs here when conditional_1 is True (regardless of condition_2)
    pass
elif condition_2:
    # Code runs here when condition_1 is false and condition_2 is true
    pass
else: 
    # Code runs here when both condition_1 and condition_2 are false
    pass
let condition_1 = false; // or true
let condition_2 = true; // or false
if condition_1 {
    // Code runs here when condition_1 is true (regardless of condition_2)
}
else if condition_2 {
    // Code runs here when condition_1 is false and condition_2 is true
}
else {
    // Code runs here when both condition_1 and condition_2 are false
}

In this conditional, one can add an alterative path that occurs after checking the first condition and is bound by some other condition. This can be chained indefinitely to allow multiple mutually exclusive paths.

Alternative Keyword Languages
else if C#, Rust
elif Python

Conditional Expressions

Also known as ternary operator.

Example of conditional expressions

bool cond = true;
var true_val = 1;
var false_val = 22;
var res = cond ? true_val : false_val;
cond = True
true_val = 1
false_val = 22
res = true_val if cond else false_val
let cond = true;
let true_val = 1; 
let false_val = 22;
let res = if cond {true_val} else {false_val};

Conditional expressions are similar to conditional statements, where the branch that is chosen is based on some truth value of a condition. The difference is that conditional expressions can return values from them. Some language have a special operator that does this called the ternary operator. One specific constraint condition expression have is that there must always be a default part, as there must always be a value returned by the expression.

Structure Languages
<condition_expression> ? <true_expression> : <false_expression> C#
<true_expression> if <condition> else <false_expression> Python
if <condition> {<true_expression>} else {<false_expression>} Rust

Repetition

Also known as iteration or looping.

Language Conditional Loop Infinite Loop Count Loop Collection Loop
C# Yes Possible Yes Yes
Python Yes Possible Possibe Yes
Rust Yes Yes Possible Yes

Condition Loop

These are loops that are controlled by conditions. There are generally to kinds of conditional loop based on when the check occurs, at the beginning of the loop and at the end.

While Loop

Example of While Loop

bool condition = true;
while(condition){
    // Run code inside when true
}
condition = True
while condition:
    # Run code inside when true
    pass
let condition: bool = true;
while condition {
    // Run code inside when true
}

In this condition controlled loop, the condition is checked before the loop code is run. If the condition is false, the code is skipped, even if it has never ran. If the condition is true, the code inside is executed. Usually, the condition has some part of its expression that is dynamic and changes when in the loop.

While Loop Syntax Languages
while(<condition>) {<loop-code>} C#, Rust
while <condition> {<loop-code>} Rust
while <condition>: INDENT <loop-code> DEDENT Python

Infinite Loop

Example of Infinite Loop (or closest alternative) csharp for(;;) { // Do this forever. }

while True:
    # Do this forever
    pass
loop {
    // Do this forever
}

An infinite loop is a loop that has no explicit stop condition, meaning that the loop will run without end. To stop an infinite loop, one will require using some mechanism to stop the loop.

Structure Languages
loop Rust
Possible Alternative Languages
while-true C#, Python, Rust
empty-for C#

Iteration

Count Controlled Loop

A count-up look going from 0 to 10 (not including 10)

for(int i = 0; i < 10; i++){
    Console.WriteLine(i);
}
for i in range(0,10):
    print(i)
for i in 0..10 {
    println!(i);
}

These kind of loops are controlled by a range of numbers.

Keyword Langage
for C#, Python, Rust
Structure Langauge
for(start, end, next) C#
for <variable> in <range_iterable> Python, Rust

Count Controlled Loop

A count-up look going from 0 to 10 (not including 10)

var numbers = [1,2,3,4,5];
foreach(var number in numbers){
    Console.WriteLine(number);
}
numbers = [1,2,3,4,5]
for number in numbers:
    print(number)
for i in 0..10 {
    println!(i);
}

These kind of loops are controlled by a collection of values.

Keyword Langage
foreach C#
for Python, Rust
Structure Langauge
for(<type> <variable> in <collection>) C#
for <variable> in <range_iterable> Python, Rust