cheddar-lang / Cheddar

🧀 Cheddar, the language that works for you
cheddar.vihan.org
Apache License 2.0
28 stars 9 forks source link

Proposal: Switch lambdas #4

Open vihanb opened 8 years ago

vihanb commented 8 years ago

This proposal details the workings of the planned switch (optionally *) statement.

Overview

The switch lambda is a block statement which functions both as a literal and a conditional block. In it's literal form it owns its own class rather than a TC link.

switch foo {
    case 1, 2: print "Foo is one or two"
    case 3, 4: print "Foo is three or four"
    else: print "Foo is something else"
}

Definition

The syntax is either switch or switch * where switch * specifies a switch literal. There may be any amount of whitespace between switch and *, if * exists. Following is the expression to be evaluated if the switch matches. This is followed by a block surrounded with braces {} of newline-seperated statements, which are the conditionals. Conditionals either begin with case or else, if case, then the beginning description is optional. Following is an expression which returns the value to be matched against, commands in these expressions serve as a logical OR during matching. These are followed by a : representing a single statement may follow. Or curly braces {} which allows for a multi-line code block

Formal Grammar

EBNF

@         = "switch" , [ "*" ] , expression , "{" , @case

@case     = [ ["case"] | "default" ] , @caselist , @block , @case
          | "}"

@caselist = expression , { "," , expression }

@block    = "{" code block "}"
          | ":" statement
ConorOBrien-Foxx commented 8 years ago

"Following is the expression returning the value to be evaluated if the switch matches" -- does that mean one can assign a value to the switch? I hope not. If not, here is a better wording: "Following is the expression to be evaluated if the switch matches."

somebody1234 commented 8 years ago

I'd also like a Ruby-style match syntax for non-primitives (i.e. using functions/regeces): (maybe it can be in normal switch if comparing functions/regeces/objects isn't needed)

match foo {
    case /1$/: print "Foo ends with a one"
    case =>(foo) foo % 4: print "Foo is not divisible by 4"
    //maybe this as well when lazy ranges (a bit like generators) are implemented
    case 'foo'...'bar.': print "Foo is greater than 'foo' but less than 'bar.'"
}
vihanb commented 8 years ago

@somebody1234 hm okay. I can understand lambdas but with regexes, how will it know if the two items are equal?

ConorOBrien-Foxx commented 8 years ago

@vihanb what do you mean by "equal"?

RikerW commented 8 years ago

regeces

Regexes....

rjhunjhunwala commented 8 years ago

If you implement it using regexes for non primitives you lose the speed up offered by switch statements on close ranges of integers.

somebody1234 commented 8 years ago

@vihanb Ruby makes it match when it's a string and the regex matches IIRC

vihanb commented 8 years ago

@somebody1234 right, but what I meant was. what function will it check to see if it matches a case. Should it use the == operator? Should it have a special .matches?

somebody1234 commented 8 years ago

case should use the default ===, or a function that is specified, I guess? (In case you want to compare objects by certain properties or something)

ConorOBrien-Foxx commented 8 years ago

Idea: when <x> for literal matching, case <x> for === matching.

somebody1234 commented 8 years ago

@ConorOBrien-Foxx Literal matching? like regex/lambda matching?

schas002 commented 8 years ago

Yay, tag action galore 😑

ConorOBrien-Foxx commented 7 years ago

The syntax is kind of vague as of now. When does the switch end? When the next condition begins? Simple example:

let truth_machine = n -> {
    switch n {
        case 0: print n;
        case 1: print n; truth_machine(1);
        else: print "...?";
    }
};