chicken scheme ; error while using let inside a function - scheme

what is wrong with this code ?
(define (make-node key data )
(list key data 'null 'null ) )
(define (right)(2) )
(define (left) (3) )
;;inserts a key to the tree
;; string x string -> list
(define (insert lst key data )
(if (null? lst )
(make-node key data )
(cond ( [(string>? key (car lst)) (list-set lst 2 (insert lst key data)) ]
[(string<? key (car lst)) (list-set lst 3 (insert lst key data)) ]
[(string=? key (car lst)) (list-set lst 1 data ) ]
))))
(define (list-set lst ix data )
(if (eqv? ix 0 ) ( cons data (cdr lst ) ) ( cons (car lst) (list-set ( cdr lst) ( - ix 1 ) data ))))
( define (newdiction) [
let ( ( [ tree '() ]) [ (msg key data )[ cond ( (eqv? msg 'insert ) [ set! tree (insert tree key data ) ] ) ] ] )
] )
the chicken scheme interpreter spits:
CHICKEN
(c) 2008-2014, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.9.0.1 (stability/4.9.0) (rev 8b3189b)
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
bootstrapped 2014-06-07
; loading dict.scm ...
Error: during expansion of (let ...) - in `let' - symbol expected: (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set! tree (insert tree key data)))))))
Call history:
<syntax> (define (list-set lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst...
<syntax> (##core#set! list-set (##core#lambda (lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst...
<syntax> (##core#lambda (lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst...
<syntax> [list-set] (##core#begin (##core#if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst) (- ix...
<syntax> [list-set] (##core#if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst) (- ix 1) data)))
<syntax> [list-set] (eqv? ix 0)
<syntax> [list-set] (cons data (cdr lst))
<syntax> [list-set] (cdr lst)
<syntax> [list-set] (cons (car lst) (list-set (cdr lst) (- ix 1) data))
<syntax> [list-set] (car lst)
<syntax> [list-set] (list-set (cdr lst) (- ix 1) data)
<syntax> [list-set] (cdr lst)
<syntax> [list-set] (- ix 1)
<syntax> (define (newdiction) (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set......
<syntax> (##core#set! newdiction (##core#lambda () (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg...
<syntax> (##core#lambda () (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set! t...... <--

This code is suffering from too many parentheses. So Scheme is very flexible and thus you can have code like this:
((som-func som-arg) some-other-arg)
What is happening there? Well. Since (some-func som-arg) is not a special form or macro it has to be an expression that leads to a function so it gets evaluated. Since some-func is not a special form or macro it has to be an expression that leads to a function and thus it evalautes it and some-arg and applies it. The result will be the function to call with the evaluation of some-other-arg as the argument.
I see you use [ ... ] as well as ( ... ). Know that the difference between these are just how they look and the interpretation of them is the same. Thus if you change (+ 1 2) to [+ 1 2] you get 3 both times. No difference. You may use them to indicate some sort of grouping in macros like let, but it makes no difference for the implementation.
If you look at your let:
(let ([(tree '())] ...)
body ...)
So the first variable is (tree '()) with no value.. But (tree '()) isn't a symbol but a list.
(let ([tree '()] ...)
body ...)
Here tree is bound to '(). see?
Now looking at you first cond you have one term. Usually cond has more than two or else a simple if would suffice. The predicate in the one term is:
[(string>? key (car lst)) (list-set lst 2 (insert lst key data))]
Now without the extra ( ... ) around the whole thing the whole code above would become a term instead of just playing a predicate.
But hang on.. Why do you have cond and if. A cond is a if-elseif-else. Isn't there a way to make the whole thing one cond? Yes! This is the same with one cond:
(define (insert lst key data)
(cond
[(null? lst) (make-node key data)]
[(string>? key (car lst)) (list-set lst 2 (insert lst key data))]
[(string<? key (car lst)) (list-set lst 3 (insert lst key data))]
[else (list-set lst 1 data)]))
I noticed also that you check if it's less than, greater than and equal to, but no else (alternative) so I assumed if it weren't less or greater than that it must be equal and thus everything goes in the last term since you now have a complete venn diagram.

You're doing (let (((tree '()) ...) but let expects a list of variable/value pairs. So you'd have to remove one set of parentheses: (let ((tree '())) ...)
In Lisp and Scheme, parentheses have a very specific meaning, you can't just add an extra set of parentheses around an expression without changing its meaning, like you can in many languages.

Related

Drracket: Create a function that will return a sorted list given a comparer using bubble sort

This is what I have to sort strings:
;create a function that checks if a list of strings is sorted
(define (stringCmpr l)
(if (<= (length l) 1)
true
(and (string<=? (car l) (cadr l))(stringCmpr (cdr l))
)
)
)
;Create a funciton that checks if a list of numbers is sorted
(define (numCmpr l)
(if (<= (length l) 1)
true
(and (<= (car l) (cadr l)) (numCmpr (cdr l))
)
)
)
;create function that checks whether a list containes numbers of
strings checks if the list is sorted
(define (is-sorted? l)
(if (number? (car l))
(numCmpr l)
(stringCmpr l)
)
)
(define (bubble-pass lst)
(cond
((empty? lst) lst)
((= (length lst) 1) lst)
((and (= (length lst) 2) (string>? (first lst) (second lst)))
(list
(second lst) (first lst)))
((and (= (length lst) 2) (string<? (first lst) (second lst)))
lst)
((string>? (first lst) (second lst))
(append
(list (second lst))
(bubble-pass (append (list (first lst)) (rest (rest lst))))
)
)
(else
(append (list (first lst) (second lst)) (bubble-pass (rest
(rest lst))))
)
)
)
(define (string-bubble-sort lst)
(if (is-sorted? lst)
lst
(string-bubble-sort (bubble-pass last))
)
)
This works for sorting strings in order from A-Z
This is what I have so far for the general sort (func represents the comparer: <, > =, string<?, etc):
;create a function that checks if a list of strings is sorted
(define (gen-stringCmpr l func)
(if (<= (length l) 1)
true
(and (func (car l) (cadr l))(gen-stringCmpr (cdr l) func)
)
)
)
;Create a funciton that checks if a list of numbers is sorted
(define (gen-numCmpr l func)
(if (<= (length l) 1)
true
(and (func (car l) (cadr l)) (gen-numCmpr (cdr l) func)
)
)
)
;create funciton that checks whether a list contains numbers or
strings checks if the list is sorted
(define (general-sorted? l func)
(if (number? (car l))
(gen-numCmpr l func)
(gen-stringCmpr l func)
)
)
; Purpose: Create a function that bubble sorts a list given a
; comparison function
;Signature:
; list function-> list
;Examples:
(check-expect (general-bubble-sort (list "B" "A" "C") string<?) (list
"A" "B" "C"))
(check-expect (general-bubble-sort (list "B" "A" "C") string>?) (list
"C" "B" "A"))
(check-expect (general-bubble-sort (list 6 4 5) <) (list 4 5 6))
(check-expect (general-bubble-sort (list 2 3 1) >) (list 3 2 1))
Stub:
(define (general-bubble-sort lst func) '( "spinach")
Template:
Code:
(define (general-bubble-pass lst func)
(cond
((empty? lst) last)
((= (length lst) 1) last)
((and (= (length lst) 2) (equal? (func (first lst) (second lst))
false)) (list (second lst) (first lst)))
((and (= (length lst) 2) (func (first lst) (second lst))) last)
((equal? (func (first lst) (second lst)) false)
(append
(list (second last))
(general-bubble-pass (append (list (first lst)) (rest (rest
lst))) func)
)
)
(else
(append (list (first lst) (second lst)) (general-bubble-pass
(rest (rest lst)) func))
)
)
)
(define (general-bubble-sort lst func)
(if (general-sorted? lst func)
lst
(general-bubble-sort (general-bubble-pass lst func) func)
)
)
You aren't properly using your abstractions here because of overly permissive signatures. Technically you want your final bubble sort to work like this:
; general-bubble-sort: (X) [List-of X] [X X -> Boolean] -> [List-of X]
By constraining the types of what we take in and telling users how they should use it, we eliminate the checking we need to do in general-sorted?. We just know that we have to pass the correct function to it, otherwise it is the users fault for not passing the correct function. You can also abstract more of your code between your two functions. Like this:
(define (general-sorted? l func)
(or (<= (length l) 1) (and (func (car l) (cadr l)) (general-sorted? (cdr l)))))
Your second function has a lot going on in it, lets combine some of the cases and also not use (equal? x boolean). That is bad practice. Instead we should use a boolean expression to get us true when appropriate. We should also make use of accumulators here as it clearly says what piece of data we are keeping track of as we are recurring down:
(define (general-bubble-pass lst func)
(local [(define (general-bubble-pass-acc lst bubble)
(cond
[(empty? lst) (list bubble)]
[(not (func (first lst) bubble)) (cons bubble (general-bubble-pass-acc (rest lst) (first lst)))]
[else (cons (first lst) (general-bubble-pass-acc (rest lst) bubble))]))]
(if (<= (length lst) 1) lst (general-bubble-pass-acc (rest lst) (first lst)))))
Your final bubble sort function doesn't change.

Scheme Lexical Analyzer

Currently working on a lexical analyzer in Scheme. I'm new to scheme but have a general understanding of what to do. I am following a online tutorial, however I keep getting this error because I'm not using UMASS scheme. What can I do to replace this class (Error: record-parse unbound identifier). Below is my code
#lang racket
(define record_parse
(lambda(noun adjective adverb conjunction prep terminator)
((noun) '(dog cat rat house tree))
((adjective) '(furry fast lazy sneaky))
((adverb) '(quickly silently))
((conjunction) '(and or))
((prep) '(with around up))
((terminator) '(!))))
(define noun '(dog cat rat house tree))
(define adjective '(furry fast lazy sneaky))
(define adverb '(quickly silently))
(define conjunction '(and or))
(define prep '(with around up))
(define terminator '(!))
(define class_parse (record-parse 'parse '(full full)))
(define cons_parse (car class_parse))
(define sel_parse (caddr class_parse))
(define tree_parse (car sel_parse))
(define rest_parse (cadr sel_parse))
(define parse_article
(lambda (list_of_tokens)
(cond
((null? list_of_tokens) #f)
((member? (car list_of_tokens) '(a the))
(cons_parse
(car list_of_tokens)
(cdr list_of_tokens)))
(else #f )
)
)
)
(define (member? x list)
(if (null? list) #f
(if (equal? x (car list)) #t
(member? x (cdr list)))))
(define parse_noun
(lambda (list_of_tokens)
(cond
((null? list_of_tokens) #f)
((member? (car list_of_tokens) noun)
(cons_parse
(car list_of_tokens)
(cdr list_of_tokens)))
(else #f )
)
)
)
(define parse_noun_phrase
(lambda (list_of_tokens)
(let ((p_det (parse_article list_of_tokens)))
(if p_det
(let ( (p_n (parse_noun (rest_parse p_det))))
(if p_n
(cons_parse
(list 'noun_phrase
(tree_parse p_det)
(tree_parse p_n))
(rest_parse p_n)
)
#f)
)
#f)
)
))
(define verb '(loves hates eats chases stalks))
(define parse_verb
(lambda (list_of_tokens)
(cond
((null? list_of_tokens) #f)
((member? (car list_of_tokens) verb)
(cons_parse
(car list_of_tokens)
(cdr list_of_tokens)))
(else #f )
)
)
)
(define parse_verb_phrase
(lambda (list_of_tokens)
(let ((p1 (parse_verb list_of_tokens)))
(if p1
(let ((p2 (parse_noun_phrase (rest_parse p1))))
(if p2
(cons_parse
(list 'verb_phrase
(tree_parse p1)
(tree_parse p2))
(rest_parse p2)
)
#f)
)
#f)
)
))
(define parse_sentence
(lambda (list_of_tokens)
(let ((p1 (parse_noun_phrase list_of_tokens)))
(if p1
(let ((p2 (parse_verb_phrase (rest_parse p1))))
(if p2
(cons_parse
(list 'sentence
(tree_parse p1)
(tree_parse p2))
(rest_parse p2)
)
#f)
)
#f)
)
))
;example of parsing a sentence
;(example
; '(parse_sentence '(the dog chases the cat))
; (cons_parse
; '(sentence (noun_phrase the dog)
; (verb_phrase chases
; (noun_phrase the cat)
; (terminator)))
; '()
; )
; )
(begin
(display "Enter a Sentance in (): ")
(let ((input (read)))
(parse_article (parse_sentence input))))
I am getting the error with the (define class_parse (record-parse 'parse '(full full)))
The procedure you defined is called record_parse, but you're trying to invoke it as record-parse. After that typo is fixed, you'll get a different error: record_parse is defined to receive 6 parameters, but you're passing only two: 'parse and '(full full). And the body of record_parse doesn't make sense, it seems that you tried to implement a case expression, but that's not how it's written in Scheme - at all.
That's only for starters, it looks like there are more errors. You should test each procedure individually until you get the hang of the syntax and before writing more complex behavior that involves using all of the procedures.

Scheme function that returns a function

I need to write a scheme function that returns as a function which then takes another argument, eg a list and in turn return the desired result. In this example (c?r "arg") would return -- (car(cdr -- which then subsequently takes the list argument to return 2
> ((c?r "ar") '(1 2 3 4))
2
> ((c?r "ara") '((1 2) 3 4))
2
The problem I have is how can I return a function that accepts another arg in petite?
Here's how you might write such a function:
(define (c?r cmds)
(lambda (lst)
(let recur ((cmds (string->list cmds)))
(if (null? cmds)
lst
(case (car cmds)
((#\a) (car (recur (cdr cmds))))
((#\d) (cdr (recur (cdr cmds))))
(else (recur (cdr cmds))))))))
Note that I'm using d to signify cdr, not r (which makes no sense, to me). You can also write this more succinctly using string-fold-right (requires SRFI 13):
(define (c?r cmds)
(lambda (lst)
(string-fold-right (lambda (cmd x)
(case cmd
((#\a) (car x))
((#\d) (cdr x))
(else x)))
lst cmds)))
Just wanted to add my playing with this. Uses SRFI-1.
(import (rnrs)
(only (srfi :1) fold)) ;; require fold from SRFI-1
(define (c?r str)
(define ops (reverse (string->list str)))
(lambda (lst)
(fold (lambda (x acc)
((if (eq? x #\a) car cdr) ; choose car or cdr for application
acc))
lst
ops)))
Its very similar to Chris' version (more the previous fold-right) but I do the reverseso i can use fold in the returned procedure. I choose which of car or cdr to call by looking at the character.
EDIT
Here is an alternative version with much more preprocessing. It uses tail-ref and list-tail as shortcuts when there are runs of #\d's.
(define (c?r str)
(let loop ((druns 0) (ops (string->list str)) (funs '()))
(cond ((null? ops)
(let ((funs (reverse
(if (zero? druns)
funs
(cons (lambda (x)
(list-tail x druns))
funs)))))
(lambda (lst)
(fold (lambda (fun lst)
(fun lst))
lst
funs))))
((eq? (car ops) #\d) (loop (+ druns 1) (cdr ops) funs))
((= druns 0) (loop 0 (cdr ops) (cons car funs)))
(else (loop 0 (cdr ops) (cons (lambda (x)
(list-ref x druns))
funs))))))
This can be made even simpler in #!racket. we skip the reverse and just do (apply compose1 funs).
(define (c?r str)
(let loop ((druns 0) (ops (string->list str)) (funs '()))
(cond ((null? ops)
(let ((funs (if (zero? druns)
funs
(cons (lambda (x)
(list-tail x druns))
funs))))
(apply compose1 funs)))
((eq? (car ops) #\d) (loop (+ druns 1) (cdr ops) funs))
((= druns 0) (loop 0 (cdr ops) (cons car funs)))
(else (loop 0 (cdr ops) (cons (lambda (x)
(list-ref x druns))
funs))))))
Assuming a compose procedure:
(define (compose funs . args)
(if (null? funs)
(apply values args)
(compose (cdr funs) (apply (car funs) args))))
(compose (list cdr car) '(1 2 3 4))
=> 2
c?r can be defined in terms of compose like so:
(define (c?r funs)
(lambda (e)
(compose
(map
(lambda (f) (if (char=? f #\a) car cdr))
(reverse (string->list funs)))
e)))
then
((c?r "ar") '(1 2 3 4))
=> 2
((c?r "ara") '((1 2) 3 4))
=> 2

Partitioning a list in Racket

In an application I'm working on in Racket I need to take a list of numbers and partition the list into sub-lists of consecutive numbers:
(In the actual application, I'll actually be partitioning pairs consisting of a number and some data, but the principle is the same.)
i.e. if my procedure is called chunkify then:
(chunkify '(1 2 3 5 6 7 9 10 11)) -> '((1 2 3) (5 6 7) (9 10 11))
(chunkify '(1 2 3)) -> '((1 2 3))
(chunkify '(1 3 4 5 7 9 10 11 13)) -> '((1) (3 4 5) (7) (9 10 11) (13))
(chunkify '(1)) -> '((1))
(chunkify '()) -> '(())
etc.
I've come up with the following in Racket:
#lang racket
(define (chunkify lst)
(call-with-values
(lambda ()
(for/fold ([chunk '()] [tail '()]) ([cell (reverse lst)])
(cond
[(empty? chunk) (values (cons cell chunk) tail)]
[(equal? (add1 cell) (first chunk)) (values (cons cell chunk) tail)]
[else (values (list cell) (cons chunk tail))])))
cons))
This works just fine, but I'm wondering given the expressiveness of Racket if there isn't a more straightforward simpler way of doing this, some way to get rid of the "call-with-values" and the need to reverse the list in the procedure etc., perhaps some way comepletely different.
My first attempt was based very loosely on a pattern with a collector in "The Little Schemer" and that was even less straightforward than the above:
(define (chunkify-list lst)
(define (lambda-to-chunkify-list chunk) (list chunk))
(let chunkify1 ([list-of-chunks '()]
[lst lst]
[collector lambda-to-chunkify-list])
(cond
[(empty? (rest lst)) (append list-of-chunks (collector (list (first lst))))]
[(equal? (add1 (first lst)) (second lst))
(chunkify1 list-of-chunks (rest lst)
(lambda (chunk) (collector (cons (first lst) chunk))))]
[else
(chunkify1 (append list-of-chunks
(collector (list (first lst)))) (rest lst) list)])))
What I'm looking for is something simple, concise and straightforward.
Here's how I'd do it:
;; chunkify : (listof number) -> (listof (non-empty-listof number))
;; Split list into maximal contiguous segments.
(define (chunkify lst)
(cond [(null? lst) null]
[else (chunkify/chunk (cdr lst) (list (car lst)))]))
;; chunkify/chunk : (listof number) (non-empty-listof number)
;; -> (listof (non-empty-listof number)
;; Continues chunkifying a list, given a partial chunk.
;; rchunk is the prefix of the current chunk seen so far, reversed
(define (chunkify/chunk lst rchunk)
(cond [(and (pair? lst)
(= (car lst) (add1 (car rchunk))))
(chunkify/chunk (cdr lst)
(cons (car lst) rchunk))]
[else (cons (reverse rchunk) (chunkify lst))]))
It disagrees with your final test case, though:
(chunkify '()) -> '() ;; not '(()), as you have
I consider my answer more natural; if you really want the answer to be '(()), then I'd rename chunkify and write a wrapper that handles the empty case specially.
If you prefer to avoid the mutual recursion, you could make the auxiliary function return the leftover list as a second value instead of calling chunkify on it, like so:
;; chunkify : (listof number) -> (listof (non-empty-listof number))
;; Split list into maximal contiguous segments.
(define (chunkify lst)
(cond [(null? lst) null]
[else
(let-values ([(chunk tail) (get-chunk (cdr lst) (list (car lst)))])
(cons chunk (chunkify tail)))]))
;; get-chunk : (listof number) (non-empty-listof number)
;; -> (values (non-empty-listof number) (listof number))
;; Consumes a single chunk, returns chunk and unused tail.
;; rchunk is the prefix of the current chunk seen so far, reversed
(define (get-chunk lst rchunk)
(cond [(and (pair? lst)
(= (car lst) (add1 (car rchunk))))
(get-chunk (cdr lst)
(cons (car lst) rchunk))]
[else (values (reverse rchunk) lst)]))
I can think of a simple, straightforward solution using a single procedure with only primitive list operations and tail recursion (no values, let-values, call-with-values) - and it's pretty efficient. It works with all of your test cases, at the cost of adding a couple of if expressions during initialization for handling the empty list case. It's up to you to decide if this is concise:
(define (chunkify lst)
(let ((lst (reverse lst))) ; it's easier if we reverse the input list first
(let loop ((lst (if (null? lst) '() (cdr lst))) ; list to chunkify
(cur (if (null? lst) '() (list (car lst)))) ; current sub-list
(acc '())) ; accumulated answer
(cond ((null? lst) ; is the input list empty?
(cons cur acc))
((= (add1 (car lst)) (car cur)) ; is this a consecutive number?
(loop (cdr lst) (cons (car lst) cur) acc))
(else ; time to create a new sub-list
(loop (cdr lst) (list (car lst)) (cons cur acc)))))))
Yet another way to do it.
#lang racket
(define (split-between pred xs)
(let loop ([xs xs]
[ys '()]
[xss '()])
(match xs
[(list) (reverse (cons (reverse ys) xss))]
[(list x) (reverse (cons (reverse (cons x ys)) xss))]
[(list x1 x2 more ...) (if (pred x1 x2)
(loop more (list x2) (cons (reverse (cons x1 ys)) xss))
(loop (cons x2 more) (cons x1 ys) xss))])))
(define (consecutive? x y)
(= (+ x 1) y))
(define (group-consecutives xs)
(split-between (λ (x y) (not (consecutive? x y)))
xs))
(group-consecutives '(1 2 3 5 6 7 9 10 11))
(group-consecutives '(1 2 3))
(group-consecutives '(1 3 4 5 7 9 10 11 13))
(group-consecutives '(1))
(group-consecutives '())
I want to play.
At the core this isn't really anything that's much different from what's
been offered but it does put it in terms of the for/fold loop. I've
grown to like the for loops as I think they make for much
more "viewable" (not necessarily readable) code. However, (IMO --
oops) during the early stages of getting comfortable with
racket/scheme I think it's best to stick to recursive expressions.
(define (chunkify lst)
(define-syntax-rule (consecutive? n chunk)
(= (add1 (car chunk)) n))
(if (null? lst)
'special-case:no-chunks
(reverse
(map reverse
(for/fold ([store `((,(car lst)))])
([n (cdr lst)])
(let*([chunk (car store)])
(cond
[(consecutive? n chunk)
(cons (cons n chunk) (cdr store))]
[else
(cons (list n) (cons chunk (cdr store)))])))))))
(for-each
(ƛ (lst)
(printf "input : ~s~n" lst)
(printf "output : ~s~n~n" (chunkify lst)))
'((1 2 3 5 6 7 9 10 11)
(1 2 3)
(1 3 4 5 7 9 10 11 13)
(1)
()))
Here's my version:
(define (chunkify lst)
(let loop ([lst lst] [last #f] [resint '()] [resall '()])
(if (empty? lst)
(append resall (list (reverse resint)))
(begin
(let ([ca (car lst)] [cd (cdr lst)])
(if (or (not last) (= last (sub1 ca)))
(loop cd ca (cons ca resint) resall)
(loop cd ca (list ca) (append resall (list (reverse resint))))))))))
It also works for the last test case.

Removing null elements from the scheme list

(define filter-in
(lambda (predicate list)
(let((f
(lambda (l)
(filter-in-sexpr predicate l))))
(map f list))))
(define filter-in-aux
(lambda (pred lst)
(if (null? lst) '()
(cons (filter-in-sexpr pred (car lst))
(filter-in-aux pred (cdr lst))))))
(define filter-in-sexpr
(lambda (pred sexpr)
(if (equal? (pred sexpr) #t)
sexpr
'())))
Calling (filter-in number? ’(a 2 (1 3) b 7)) produces ( () 2 () () 7).
How I can skip null elements from the generated list to get final outcome of (2 7) ?
The problem is that you're mapping filter-in-sxpr over the list. You can either run another filter pass to remove the nulls, or use a modified filter-in-aux like this:
(define filter-in-aux
(lambda (pred lst)
(if (null? lst) '()
(let ((h (filter-in-sexpr pred (car lst)))
(t (filter-in-aux pred (cdr lst))))
(if (null? h) t
(cons h t))))))

Resources