Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

or as procedure in scheme

I want to apply or to every element of list, example: (apply or '(#t #t #f)) expected result #t, but I'm getting error:

'#' to 'apply' has wrong type (kawa.lang.Macro) (expected: procedure, sequence, or other operator)

As I understand or is not a procedure. Is there any procedure that can be used instead of or?

like image 514
Misho Tek Avatar asked Dec 18 '17 22:12

Misho Tek


3 Answers

The easiest way to do this is with exists*. Whenever you would use (apply or some-list), you can use (exists values some-list). Or if you like, you can define a function that uses exists to do that:

#!r6rs
(import (rnrs base)
        (rnrs lists))

(define (or* . lst)
  (exists values lst))

values is the identity function, so (values x) is just x.

exists is a higher-order function defined so that (exists f (list x ...)) is equivalent to (or (f x) ...).

For example (exists values (list #t #t #f)) is equivalent to (or (values #t) (values #t) (values #f)), which is the same as (or #t #t #f).

Trying it out:

> (apply or* '(#t #t #f))
#t
> (apply or* '(#f #f #f))
#f
> (or* #t #t #f)
#t
> (or*)
#f

*exists is sometimes known as ormap or any

like image 199
Alex Knauth Avatar answered Sep 30 '22 20:09

Alex Knauth


In SRFI-1 List Library you have every and any which basically is and and or for a procedure over a list.

#!r6rs

(import (rnrs base)
        (only (srfi :1) every any)

(define num1-10 '(1 2 3 4 5 6 7 8 9 10))
(define odd1-9 '(1 3 5 7 9))

(every odd? num1-10) ; ==> #f
(any odd? num1-10)   ; ==> #t
(every odd? odd1-9)  ; ==> #t

For a list of booleans the procedure only need to return the argument. values returns it's argument and serve as identity:

(define booleans '(#f #t))
(every values booleans) ; ==> #f
(any values booleans)   ; ==> #t

SRFI-1 is a safe choice as it is the list library of the upcoming R7RS Red edition. In many R5RS and R6RS implementations SRFI-1 is included and you can easily add it from the SRFI reference implementation if it isn't. In DrRacket's default language DrRacket, that has ormap and andmap, you can opt to use SRFI-1 instead by importing them with (require srfi/1).

like image 22
Sylwester Avatar answered Sep 30 '22 20:09

Sylwester


You could define your own procedure that uses or

(define (orp . ls) 
     (if (null? ls) #f
           (if (< (length ls) 2) (car ls) (or (car ls) (orp (cdr ls))))))

And use it:

(apply orp '(#t #f #t))
like image 31
Misho Tek Avatar answered Sep 30 '22 20:09

Misho Tek