Hacker News new | past | comments | ask | show | jobs | submit login

    if(and(or(cond1, cond2), cond3), effect1(), effect2())
In most languages, if `cond1` evaluates to true, you would not evaluate `cond2`. If `cond1` and `cond2` evaluate to false, you would not evaluate `cond3`. If all conds evaluate to false, you would not evaluate `effect1()`, and if `cond3` and either `cond1` or `cond2` are true, you would not evaluate `effect2()`

They're not functions because they don't evaluate their arguments before evaluating their body. Their operands are passed verbatim and evaluated explicitly by the body on demand.

In Kernel, for example, we can define these as operatives, which don't evaluate their operands. Assuming we have some primitive operatives `$cond`, `$define!` and `$vau` (the constructor of operatives), and an applicative `eval`:

    ($define! and
        ($vau (lhs rhs) env
            ($cond ((eval lhs env) (eval rhs env)
                   (#t #f)))))
                   
    ($define! or
        ($vau (lhs rhs) env
            ($cond ((eval lhs env) #t)
                   (#t (eval rhs env)))))
                   
    ($define! if
        ($vau (condition consequent antecedent) env
            ($cond ((eval condition env) (eval consequent env))
                   (#t (eval antecedent env)))))
These aren't the definitions Kernel uses in its standard environment. It uses recursive definitions of `$and?` and `$or?` which take arbitrary number of operands, and `$cond` is defined in terms of `$if`, which is primitive:

    ($define! $cond
        ($vau clauses env
            ($if (null? clauses) #inert
                 ($let ((((test . body) . rest) clauses))
                    ($if (eval test env)
                         (apply (wrap $sequence) body env)
                         (apply (wrap $cond) rest env))))))

    ($define! $and?
        ($vau x env
            ($cond ((null? x) #t)
                   ((null? (cdr x)) (eval (car x) env))
                   ((eval (car x) env) (apply (wrap $and?) (cdr x) env))
                   (#t #f))))
                   
    ($define! $or?
        ($vau x env
            ($cond ((null? x) #f)
                   ((null? (cdr x)) (eval (car x) env))
                   ((eval (car x) env) #t)
                   (#t (apply (wrap $or?) (cdr x) env)))))



I don't think that's what Rye is doing.

It's doing if(cond, effect1, effect2) where effect1 and effect2 are functions, and only evaluating the matching effect function. But everything is functions.


technically effect1 and effect2 are so called "blocks of code" in rebol/rye/red/...

Everything being a function is trying to say that every "active word" (a word that does something ... print, first, if, fn, context, extends, ...) is just a function.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: