Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the language pure again #14

Open
mauriciotogneri opened this issue Aug 5, 2024 · 0 comments
Open

Make the language pure again #14

mauriciotogneri opened this issue Aug 5, 2024 · 0 comments
Assignees
Labels
feature New feature or request language Language related issues

Comments

@mauriciotogneri
Copy link
Collaborator

mauriciotogneri commented Aug 5, 2024

The language should be pure but still allow to do:

  • I/O
  • State mutation
  • Throw errors

There are 3 alternatives:

Monads

This approach is very complicated to understand and implement. Example:

-- Define the DateMonad type
type DateMonad = () -> Date

-- Pure function: Takes a value and returns a DateMonad that wraps the value.
function unit(value: Date): DateMonad {
    return () -> value
}

-- Pure function: Takes a DateMonad and a function, returns a new DateMonad.
function bind(monad: DateMonad, f: (Date) -> DateMonad): DateMonad {
    return () -> f(monad())()
}

-- Impure function: Returns the current date. Output varies with each call.
function getCurrentDate(): Date {
    return new Date()  -- Assume this returns the current date
}

-- Impure function: Takes a date, prints it (side effect), returns a DateMonad.
function printDate(date: Date): DateMonad {
    print("The current date is: " + date.toString())  -- Side effect: printing
    return unit(date)
}

-- Impure function: Entry point of the program.
function main() {
    -- Wrapping the current date in a DateMonad. This involves an impure function.
    let currentDateMonad = unit(getCurrentDate())
    
    -- Using bind to chain the date fetching and printing.
    let resultMonad = bind(currentDateMonad, printDate)
    
    -- Executing the monad. This involves impure functions due to I/O and current date fetching.
    resultMonad()
}

Annotations

This approach annotates each function as pure or impure. Example

@pure
function formatDate(date: Date): String {
    return date.toString()
}

@impure
function printDate(formattedDate: String): void {
    print("The current date is: " + formattedDate)  // Side effect: printing
}

@impure
function getCurrentDate(): Date {
    return new Date()
}

@impure
function main() {
    // Fetch the current date (impure)
    let currentDate = getCurrentDate()
    
    // Format the date (pure)
    let formattedDate = formatDate(currentDate)
    
    // Print the formatted date (impure)
    printDate(formattedDate)
}

With this approach, the compiler needs to check that all pure functions only call other pure functions.

Uniqueness type

Pass a unique reference to impure functions that should always return a new instance of that reference. Example:

// Define a function to get the current date
// This function is impure and interacts with the external world
getCurrentDate :: *World -> (Date, *World)
getCurrentDate world = 
    let
        -- Here we interact with the system to get the current date
        (date, newWorld) = System.getCurrentDate world
    in
        (date, newWorld)

// Define a pure function to format the date
-- This function is pure as it does not have side effects
formatDate :: Date -> String
formatDate date = 
    -- Format the date as a string (pure operation)
    dateToString date

-- Define a function to print the formatted date
-- This function is impure and performs I/O
printDate :: String -> *World -> *World
printDate formattedDate world =
    let
        -- Here we perform an I/O operation to print the date
        newWorld = System.print formattedDate world
    in
        newWorld

-- Define the main function that coordinates the operations
-- This function is impure as it performs I/O and uses impure functions
main :: *World -> *World
main world =
    let
        -- Get the current date (impure operation)
        (currentDate, world1) = getCurrentDate world
        
        -- Format the date (pure operation)
        formattedDate = formatDate currentDate
        
        -- Print the formatted date (impure operation)
        finalWorld = printDate formattedDate world1
    in
        finalWorld
@mauriciotogneri mauriciotogneri added the feature New feature or request label Aug 5, 2024
@mauriciotogneri mauriciotogneri added this to the v9 milestone Aug 5, 2024
@mauriciotogneri mauriciotogneri self-assigned this Aug 5, 2024
@mauriciotogneri mauriciotogneri moved this to Todo in sdk Aug 7, 2024
@mauriciotogneri mauriciotogneri modified the milestones: 0.9.0, 1.0.0 Aug 7, 2024
@mauriciotogneri mauriciotogneri added the language Language related issues label Aug 9, 2024
@mauriciotogneri mauriciotogneri changed the title Make language pure Make the language pure Aug 10, 2024
@mauriciotogneri mauriciotogneri changed the title Make the language pure Make the language pure again Aug 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request language Language related issues
Projects
Status: Todo
Development

No branches or pull requests

1 participant