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

Case as replacement for cond #37

Open
DaddyWesker opened this issue Feb 19, 2024 · 7 comments
Open

Case as replacement for cond #37

DaddyWesker opened this issue Feb 19, 2024 · 7 comments
Labels
answered Tutorial question is answered but not added to docs tutorial Tutorial question

Comments

@DaddyWesker
Copy link
Contributor

I've got some question regarding possibility to replace scheme's cond with metta's case. Is it possible? I've tried to write simple check function to see if my idea works:

(= (check $x $y)
    (case $x
        ((0 1)
        ((> $x $y) $x)
        ($_ $y))))

But apparently it doesn't work since, as i understand case, it will check not if $x larger than $y but instead if (== $x (> $x $y)) (expression equality). Is there some way to write this code using case in current metta state? Or only consequent if's are usable in that case? @vsbogd @Necr0x0Der

@vsbogd
Copy link
Contributor

vsbogd commented Feb 20, 2024

Yes, case doesn't reduce conditions, but with current implementation you can calculate the result of the condition in advance and then compare it with expected result. For instance following will work:

(= (check $x $y)
  (case ($x (> $x $y)) (
    ((0 $_) 1)
    (($_ True) $x)
    ($_ $y)
  )))

@DaddyWesker
Copy link
Contributor Author

Well, question was for general case and example was just to demonstrate my question. In general It could be needed to check several different conditions. Anyway, thanks for the answer.

@vsbogd
Copy link
Contributor

vsbogd commented Feb 20, 2024

In general It could be needed to check several different conditions.

I agree this approach is too verbose for many different conditions. You can also right your own case implementation:

(: my-case (-> %Undefined% Expression %Undefined%))
(= (my-case $x $conds)
  (if (== $conds ())
    (empty)
    (let ($cond $templ) (car-atom $conds)
      (let $tail (cdr-atom $conds)
        (if $cond $templ (my-case $x $tail)) ))))

(= (check $x $y)
  (my-case $x (
    ((== $x 0)  1)
    ((> $x $y) $x)
    (True $y)
  )))

But pay attention that check also should be modified. In implementation from description unification pattern and boolean conditions are mixed in a list of conditions. To simplify implementation one need to choose either using unification (then use library case) or conditioning (then use my-case).

@Necr0x0Der
Copy link
Contributor

Yes, case doesn't reduce conditions and works more like case in functional languages, otherwise something like this would work

(= (check $x $y)
    (case True
        (((== 0 $x) 1)
         ((> $x $y) $x)
         ($_ $y))))

but it doesn't. This difference should be explained in a tutorial.

@Necr0x0Der Necr0x0Der added the tutorial Tutorial question label Feb 21, 2024
@Necr0x0Der
Copy link
Contributor

Another funny was would be to write:

(= (check $x $y)
   (let $conds
        (((== 0 $x) 1)
         ((> $x $y) $x)
         ($_ $y))
       (case True $conds))
)

It seemingly works, but the difference with normal case is that all the branches will be evaluated. It's not a tragedy for simple cases, but ruins the idea sequential mutually-exclusive evaluation in case .

@Necr0x0Der
Copy link
Contributor

BTW, my guess is that in @vsbogd implementation (let $tail (cdr-atom $conds) will also evaluate the whole tail. It may need a more careful consideration, but my first guess is that this

(= (my-case $x $conds)
  (if (== $conds ())
    (empty)
    (let ($cond $templ) (car-atom $conds)
      (if $cond
          $templ
          (let $tail (cdr-atom $conds) (my-case $x $tail)) ))))

will at least screen out evaluation of the tail if $cond is true. Unfortunately, $templ will be evaluated even if $cond is false.

@Necr0x0Der Necr0x0Der added the answered Tutorial question is answered but not added to docs label Feb 21, 2024
@vsbogd
Copy link
Contributor

vsbogd commented Feb 22, 2024

(let $tail (cdr-atom $conds) will also evaluate the whole tail.

Yes, unfortunately it is inevitable with current let semantics. It can be eliminated in minimal MeTTa using chain and eval wisely though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answered Tutorial question is answered but not added to docs tutorial Tutorial question
Projects
None yet
Development

No branches or pull requests

3 participants