DragonLang/Document

From Esolang
Jump to navigation Jump to search

Back to DragonLang

Basics

Data types

Basic data type

  • Numbers, all valid real numbers, with no upper and lower limit and supports 2 to 36 base.
  • Complexs, formed by a ± bi.
  • Documents, simply a string in Python/CangjieLang, except it must be quoted in "", if it is in then it is a Rune.
  • Booleans, which works like in Python but it is strict.

Composite data type

  • Dynamic array which we call it vector, literally a list in Python.
  • Static array which we call it simply array, literally an array in C++.
  • Dictionary, just like what's in Python.
  • Hashed set, like in CangjieLang.

User-defined data type

Struct

struct YourStructName: # Literally a struct in C++, but in Python-style.
    attributes
    
    methods

"ADT"

enum Result[T, E]:  # The core of security in CangjieLang.
    Ok(T)
    Error(E)

Tuple

Literally tuple in Python, except we often call a tuple with length of 2 "pair".

Memory-related type

  • Safe reference: &x(static borrow) and &mut x(dynamic borrow)
  • Intellij-pointer: Like unique_ptr in C++.
  • Unsafe reference(raw pointer): Literally a pointer in C++.

Special type

  • Any-type: Like Python.
  • "Never gonna give you up": Indicates a function that never returns.
  • Void type: Like C++.
  • Option[T]: Explicitly optional values.
  • 1st Level Civil Functions, like in LUA.

Variable definition

let x: int;
let x <- 15;
let y <- x;
let y <- ; # Delete the variable y.

Control Flow

Conditional jump

Just like what in Python.

Except "match", which is imported from CangjieLang.

Looping

There are 3 types of looping:

for i in range(start, stop, step):
    code
for item in collection:
    code
while condition:
    code

Jumping

There will be some labels for noting that a code block, thus you can simply jump to that label, but it is not safe, and we can simply use the break and continue to loop.

outer: while cond1:
    while cond2:
        if should_exit:
            break outer;  # Jump out the outer loop

Error handling

try:
    risky_operation();
catch Exception as e:
    fallback();
else:
    print("Yay!!!!");
finally:
    cleanup();

# From CangjieLang:
let file = File.open("data.txt")?;  // If error, return directly.

But we define that x÷0 is infinity and 0÷0 is NaN, and anything modulo to 0 will return itself, so THERE IS NOZeroDivisionError.

Concurrency control

There are 3 types of concurrency control:

Normal concurrency:

async def task():
    data = await fetch_async()
    print(data)

# Structured Concurrency
async with TaskGroup() as tg:
    tg.spawn(task1())
    tg.spawn(task2())

Deed check:

def transfer(amount: int) -> void:
    require amount > 0      // Entrance
    ensure balance >= 0     // Exit
    ...

Tail recursively optimizes markers:

@tailrec
def factorial(n: int, acc=1) -> int:
    if n <= 1: return acc;
    return factorial(n-1, acc*n);

Do something in other languages!!

cpp_block """
    std::vector<int> vec{1,2,3}; 
    for(auto& x : vec) { ... }
"""

The cpp_block and python_block will change to other languages.

Object-Oriented Programming

Module:

# Access Control + Inheritance Declaration
[pub | priv | prot] class YourClassName[Args] : [parent] [implements_interface] {
    # Fields area
    [pub | priv | prot] field name: type [= default]
    
    # Constructor area
    [static] new(parameter list) [-> contract] {
        # Construction logic
    }

    # Methods area
    [pub | priv | prot] [mutating] fn methodname(argument) [-> return_type] [contract] {
        # Method body
    }

    # Destructor (optional)
    drop() {
        # Resource Cleanup
    }
}

Note that a brace can be omitted.

This is just a basic object, a completed is shown below:

# 泛型+继承+接口+契约
pub generic[T] 
class SafeArray : Collection implements Serialize {
    priv data: [T]
    len: int
    
    new(size: int) -> require size > 0 {
        data = alloc_array[T](size)
        len = size
    }
    
    pub fn get(index: int) -> T & require index in 0..<len {
        return data[index]
    }
    
    mutating pub fn set(index: int, value: T) -> require index in 0..<len {
        data[index] = value
    }
    
    drop() {
        free_array(data)  # Manually free the memory
    }
    
    # Implementing Interface
    override pub fn serialize(self) -> JSON:
        return json_array(self.data)
}

Functions

Now we already talked about the functions in above(methods in class and concurrency control), but fn is only used for... Uh... Class.

What? You say you don't know the function outside the class?!

Uh... I'd love to throw eggs at you (like HowToBasic), but I don't think I should be angry. After thinking about it for 114514 seconds, I decided to write the full function model.

[pub/priv/prot] [mutating] def your_function_name(arg1: type, arg2: type, ..., kwarg1 = value1, kwarg2 = value2, ...) [-> ret_type] {
    function_body;
    return [return_value];
}

Abbreviation:

[pub/priv/prot] [mutating] def your_function_name(*args, **kwargs) [-> ret_type] {
    function_body;
    return [return_value];
}