wryun / es-shell

es: a shell with higher-order functions
http://wryun.github.io/es-shell/
Other
307 stars 25 forks source link

Is there a design limitation preventing support for rc-style switch statements? #31

Closed hyphenrf closed 2 years ago

hyphenrf commented 3 years ago

Or is it just waiting to be implemented? I'm thinking about giving that a try honestly.

hyphenrf commented 3 years ago

so far I reached this:

fn switch match cases {
   let ((case body rest) = $cases)
    if { eval '~' $match $case } {
       $body
    }{ switch $match $rest }
}

which can be used like so:

switch expr (
   'pattern1' { body 1 }
   'pattern2' { body 2 }
   '*' { default body }
)

I don't think it's in any way better than a builtin syntax though

wryun commented 2 years ago

FYI, you can also implement without the recursion something like (avoiding the eval, which admittedly you need for complex things):

fn switch input cases { 
  for ((condition fragment) = $cases) { 
    if {~ $input $condition} { 
       $fragment 
    } 
  } 
}
hyphenrf commented 2 years ago

I don't really remember why I needed eval, but I remember needing it. perhaps it was to avoid some form of pattern expansion or delay evaluation..? I'm not so sure.. it must've propagated from an earlier private implementation.

EDIT: now I remember; it was to expand the patterns because they had to be quoted. I also remember why I made it recursive.. to bail early on a match. But this could be done with break I suppose. It just felt more elegant as a recursive function.

it'll look something like this probably:

fn switch match cases {
   catch @{} {
     for ((case body) = $cases) if { eval '~' $match $case }{
        $body
        break
     }
   }
}
wryun commented 2 years ago

https://github.com/wryun/es-shell/pull/36