Q: Help with a Shen freeze / thaw problem

73 views
Skip to first unread message

Antti Ylikoski

unread,
Jan 16, 2017, 12:22:36 PM1/16/17
to Shen

I have a problem with the OS Shen, for which problem I would like to
ask for some help from the group.

I have the below file in Shen, copied from two textbooks:

------------------------------------------------------------

\\ Lazy lists and more, in Shen
\\
\\ Dr Antti Ylikoski 2017-01-15
\\
\\ First load the maths-lib.shen


(defmacro @c-macro
  [@c X Y] -> [cons [freeze X] [freeze Y]])


(defmacro @l-macro
  [@l ] -> (freeze [])
  [@l X | Y] -> [@c X [@l | Y]])


(define @hd
  X -> (thaw (hd X)))


(define @tl
  X -> (thaw (tl X)))


\\ ------------------------------------------------------------

\\ Abelson-Sussman-Sussman p. 50

(define smallest-divisor
  N -> (find-divisor N 2))

(define find-divisor
  N Test-Divisor ->
    (cases (> (square Test-Divisor) N) N
           (divides? Test-Divisor N) Test-Divisor
  true (find-divisor N (+ Test-Divisor 1))))

(define divides?
  A B -> (divisible-by? B A))

(define prime?
  N -> (= N (smallest-divisor N)) where (> N 0)
  N -> (error "Neg arg to prime?"))

(define next-prime
  X -> X where (prime? X)
  X -> (next-prime (+ 1 X)))

(define primes-from
  N -> (@c N (primes-from (next-prime (+ N 1)))))

(define primes \\ Returns a lazy stream
  -> (primes-from 2))


------------------------------------------------------------

When attempting to create a lazy stream of all primes by calling

(set p (primes))

the system will remain in an infinite loop.

I have (track ...)ed and (step +)ed the program.  The following will
happen.

When the Shen expression (primes) is called, the expression
(primes-from 2) will be Shen evaluated.

This, in turn, will cause the expression
(@c 2 (primes-from (next-prime 3))) to be evaluated.

This call of the (@c ...) macro should return a cons cell of two
(freeze ...)ed Shen expressions, namely (freeze 2) and
(freeze (primes-from (next-prime 3))).

This will not happen.  The Shen expression
(primes-from (next-prime 3)) will get called, which will run an
infinite loop.  This will happen instead of the said Shen form being
(freeze...)d and the freeze'd form returned.

Any smart help would be very much appreciated.

yours, AJY
Helsinki, Finland, the EU


Mark Tarver

unread,
Jan 17, 2017, 6:36:00 AM1/17/17
to Shen
This looks a bit like https://groups.google.com/forum/?hl=en#!topic/qilang/xSgmtGUkGWI to which I replied.  Other responses welcome.

Mark

Mark Tarver

unread,
Jan 21, 2017, 4:11:20 AM1/21/17
to Shen
Well this is what I get.  There is no hang.

Mark

Shen, copyright (C) 2010-2015 Mark Tarver
www.shenlanguage.org, Shen Professional Edition 14
running under Common Lisp, implementation: SBCL
port 2.1 ported by Mark Tarver
commercially licensed to Mark Tarver



(0-) (defmacro @c-macro
  [@c X Y] -> [cons [freeze X] [freeze Y]])
@c-macro

(1-) (defmacro @l-macro
  [@l ] -> (freeze [])
  [@l X | Y] -> [@c X [@l | Y]])
@l-macro

(2-) (define @hd
  X -> (thaw (hd X)))
@hd

(3-) (define @tl
  X -> (thaw (tl X)))
@tl

(4-) (define smallest-divisor
  N -> (find-divisor N 2))
smallest-divisor

(5-) (define find-divisor
  N Test-Divisor ->
    (cases (> (square Test-Divisor) N) N
           (divides? Test-Divisor N) Test-Divisor
           true (find-divisor N (+ Test-Divisor 1))))
find-divisor

(6-) (define divides?
  A B -> (divisible-by? B A))
divides?

(7-) (define prime?
  N -> (= N (smallest-divisor N)) where (> N 0)
  N -> (error "Neg arg to prime?"))
prime?

(8-) (define next-prime
  X -> X where (prime? X)
  X -> (next-prime (+ 1 X)))
next-prime

(9-) (define primes-from
  N -> (@c N (primes-from (next-prime (+ N 1)))))
primes-from

(10-) (define primes \\ Returns a lazy stream
  -> (primes-from 2))
primes

(11-) (set p (primes))
[#<CLOSURE (LAMBDA () :IN primes-from) {1005906A7B}> | #<CLOSURE (LAMBDA () :IN
primes-from) {1005906A9B}>]

Antti Ylikoski

unread,
Jan 22, 2017, 1:01:28 AM1/22/17
to Shen
OK, thanks.

I shall get the SP Home, which is based on the SBCL, and see whether the problem remains.

As I said, I suspect the implementation of the CLisp, which has previously proved somewhat untrustworthy.

Whether or not the Linux is "buggy" for software development, is worth a long and nontrivial discussion.  This text has been written with a Win10 PC, which I got specifically for the Shen work.

yours, AJY

Mark Tarver

unread,
Jan 22, 2017, 3:25:00 AM1/22/17
to qil...@googlegroups.com
I haven't used Linux for software development other than to port SP to it.  It seems to work fine tho' the default colours for the GUI interface are different in Linux (a nuisance).  The OS seems to be of an inferior finish to Windows 7.  But I've found no gross deviation wrt Shen.

CLisp was AFAIK more reliable than SBCL for a long time but slower.  SBCL now is more stable so it is the platform of choice for SP.

Mark 

--
You received this message because you are subscribed to the Google Groups "Shen" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+unsubscribe@googlegroups.com.
To post to this group, send email to qil...@googlegroups.com.
Visit this group at https://groups.google.com/group/qilang.
For more options, visit https://groups.google.com/d/optout.

Bruno Deferrari

unread,
Jan 22, 2017, 8:06:25 AM1/22/17
to qil...@googlegroups.com
I just tried this in both shen-scheme and shen-sbcl and couldn't reproduce the problem either.

Shen, copyright (C) 2010-2015 Mark Tarver
running under Scheme, implementation: chibi-scheme
port 0.14 ported by Bruno Deferrari

(0-) (load "maths-lib.shen")
sign
abs
..snip...
min

run time: 1.56205105781555 secs
loaded

(1-) (load "lazy.shen") \\ @c, @hd, etc
@c-macro
@l-macro
@hd
@tl

run time: 0.0353000164031982 secs
loaded

(2-) (load "primes.shen")
smallest-divisor
...snip...
primes

run time: 0.0396239757537842 secs
loaded

(3-) (set p (primes))
[#<procedure f> | #<procedure f>]

(4-) (@hd (@tl (@tl (@tl (value p)))))
7

(5-)

--
You received this message because you are subscribed to the Google Groups "Shen" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+unsubscribe@googlegroups.com.
To post to this group, send email to qil...@googlegroups.com.
Visit this group at https://groups.google.com/group/qilang.
For more options, visit https://groups.google.com/d/optout.



--
BD

Antti Ylikoski

unread,
Jan 22, 2017, 9:30:11 AM1/22/17
to Shen

You have solved my problem, thanks!

The question was, as you have pointed out, that the delayed stream
macros need to be in a separate file, which file needs to be loaded
before loading the primes functions Shen file.

This question has occurred before, it is a consequence of the manner
that Shen processes and uses macro definitions.

See the files dstreams.shen and dprimes.shen, I renamed the files so.

yours, AJY
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+un...@googlegroups.com.

To post to this group, send email to qil...@googlegroups.com.
Visit this group at https://groups.google.com/group/qilang.
For more options, visit https://groups.google.com/d/optout.



--
BD
dstreams.shen
dprimes.shen

Bruno Deferrari

unread,
Jan 22, 2017, 3:51:22 PM1/22/17
to qil...@googlegroups.com
On Sun, Jan 22, 2017 at 11:27 AM, Antti Ylikoski <antti.y...@gmail.com> wrote:

You have solved my problem, thanks!

The question was, as you have pointed out, that the delayed stream
macros need to be in a separate file, which file needs to be loaded
before loading the primes functions Shen file.

This question has occurred before, it is a consequence of the manner
that Shen processes and uses macro definitions.

See the files dstreams.shen and dprimes.shen, I renamed the files so.

yours, AJY


Good, I'm glad it is solved now.

Always keep in mind that Shen's `load` function works in two steps:

#1 reading and parsing the file
#2 evaluating the code that was the result of #1

Macro expansions happens in #1, and the evaluation of the code that defines the macros (and the adding of such macros to the macros list) happens in #2. Because #2 doesn't happen until after #1 is complete, macros defined in a file will not be used while reading the file that defines them.

This is just how the default `load` function works, nothing prevents you from implementing your own `load` variant that reads expressions one by one and evaluates each one before reading the next, but that requires a bit of work.
 
To unsubscribe from this group and stop receiving emails from it, send an email to qilang+unsubscribe@googlegroups.com.

To post to this group, send email to qil...@googlegroups.com.
Visit this group at https://groups.google.com/group/qilang.
For more options, visit https://groups.google.com/d/optout.



--
BD
Reply all
Reply to author
Forward
0 new messages