Derw
  • Derw
  • Roadmap
  • 📖Guides
    • Creating your first project
    • Installing packages
    • Compiling and running your code
    • Formatting
    • Repl and playground
    • Testing
  • ⚖️Fundamentals
    • Literals
    • Definitions
    • Types
    • Conditionals
    • Imports and exports
    • Comments
  • 🔧Building things
    • Web pages
    • REPLs
  • 🪛Contributing
    • Contribution flow
    • Working on the compiler
  • 💭Hypotheticals
    • Hypotheticals
    • Async / await
Powered by GitBook
On this page
  • If statements
  • Case statements
  • Kernel code
  1. Fundamentals

Conditionals

In Derw, there are two main types of conditions: if statements, for simple tests of whether something is true or not, and case statements, for pattern matching a value against the possible values it might have. Typically you'd want to use if statements for small checks, and case statements when you have a wide range of possible values.

Both if statements and case statements must have a final value: all branches must have a value have a value.

If statements

If statements typically look like the following:

if condition then 
    someValue
else
    someOtherValue

Which can be put to use like this:

sayHi: string -> string
sayHi name =
    if name == "noah" then
        "Hi Noah!"
    else
        `I don't know you, ${name}`

They can also be used inline, like

if condition then someValue else someOtherValue

which might look like:

viewHi: string -> string
viewHi name =
    div 
        [] 
        [] 
        [ if name == "Noah" then text "Hi Noah" else text "I don't know you" ]

Typical ways of getting condition are: a boolean value, returning boolean from a function call, or using comparisons (==, !=, <, <=, >, >=).

Case statements

Case statements typically look like the following:

case value of
    somePotentialValue -> someValueToReturn

You can also match against literal values of strings and numbers. When using literal values, you must provide a default case, for example:

sayHi: string -> string
sayHi name =
    case name of
        "noah" -> "Hi, Noah!"
        "jeremey" -> "Hello, Jeremy!"
        default -> "I don't know you"
        
binaryToString: number -> string
binaryToString binary =
    case binary of
        0 -> "0"
        1 -> "1"
        default -> "0"

Lists can be pattern matched with destuctures, again with a default case being required. In the example below, the pattern looks for one element in the front of a list and calls it x, while calling the tail xs.

sum: List number -> number
sum numbers =
    case numbers of
        x :: xs -> x + (sum xs)
        default -> 0

Multiple list destructures can be chained, for example:

type Summary = 
    ValidSummary { pageCount: number, currentPage: number} 
    | InvalidSummary { reason: string }

parseSummary: List number -> Summary
parseSummary xs =
    case xs of 
        x :: y :: [] -> ValidSummary { pageCount: x, currentPage: y }
        x :: [] -> ValidSummary { pageCount: x, currentPage: y }
        default -> InvalidSummary { reason: "Too many values" }

It is also possible to match against parts of list. This is non-greedy by default for example:

parseParens: List string -> string
parseParens xs =
    case xs of
        "(" :: middle :: ")" :: rest -> String.join "" middle
        default -> ""
        
somethingWithAMiddle: string
somethingWithAMiddel =
    parseParens [ "(", "hello", ")" ]
    
testSomethingWithAMiddle: void
testSomethingWithAMiddle =
    Test.equals "hello" somethingWithAMiddle 
    
somethingWithoutAMiddle: string
somethingWithoutAMiddel =
    parseParens [ "(", "hello" ]
    
testSomethingWithoutAMiddle: void
testSomethingWithoutAMiddle =
    Test.equals "" somethingWithoutAMiddle 

Kernel code

If statements are turned into typical Javascript if statements. If the if statement is used within a const definition, then the generated if is turned into a ternary.

function sayHi(name: string): string {
    if (name === "noah") {
        return "Hi, Noah!";
    } else {
        return "I don't know you";
    }
}

const isMe: boolean = name === "noah" ? true: false;

Case statements are turned into switch statements. The case conditional is put into a const which is called _res + the body turned into a number. This is to prevent collisions with nested cases. Cases used within a const are turned into functions

function sayHello(name: string): string {
    const _res3373707 = name;
    switch (_res3373707) {
        case "Noah": {
            return "Hi Noah";
        }
        case "James": {
            return "Greetings";
        }
        default: {
            return "I don't know you";
        }
    }
}

const isKnownPerson = (function(): any {
    const _res3373707 = name;
    switch (_res3373707) {
        case "Noah": {
            return true;
        }
        case "James": {
            return true;
        }
        default: {
            return false;
        }
    }
})();
PreviousTypesNextImports and exports

Last updated 2 years ago

The most common use case is with union types, as shown in the page.

⚖️
Types