osa1 github gitlab twitter cv rss

Weirdest bug

April 25, 2013 - Tagged as: haskell, shen, en.

Haskell implementation of Shen is stuck because of some weird bugs. I think most of them are related with lazy io.

Weird bug #1: Print functions print not when they’re called, but at some later time. This causes Shen repl to take some input, and then print prompt line:

(+ 1 2)
(0.0-) 3.0

Shen REPL is defined in KLambda source, so we can know it’s implemented correctly. Also, KLambda REPL I wrote in Haskell doesn’t have this kind of problem(it prints the prompt, then gets user input).

Weird bug #2: REMOVED. When read this post second time after several hours, I realized his same as Weird bug #3. Writing really helps :-)

Weird bug #3: For some reason, shen.read-file-as-bytelist-help still doesn’t end even after printing the bytes. That’s because even if read-bytes return value is -1, else part of the conditional is taken. I have no idea why. Here’s a demonstration:

The file empty.txt is empty:

➜  cat empty.txt
➜

And reading it with read-byte Shen function returns correct value:

➜ shenhs

Shen 2010, copyright (C) 2010 Mark Tarver
www.shenlanguage.org, version 9.2
running under Haskell, implementation: GHC
port 0.1 ported by Ömer Sinan Ağacan

(= -1 (let stream (open file "empty.txt" in) (read-byte stream)))
(1.0-) true

But reading file with read-file gets stuck in an infinite tail-call:

(read-file "empty.txt")
(2.0-) ^C

For debugging purposes, I changed shen.read-file-as-bytelist-help and put some prints:

(defun shen.read-file-as-bytelist-help (V2003 V2004 V2005)
  (cond ((= -1 V2004)
         (do
           (pr "-1<nop>" (value *stoutput*))
           V2005))
        (true
         (do
           (pr (str (= -1 V2004)) (value *stoutput*))
           (do
             (pr "<ok>" (value *stoutput*))
             (shen.read-file-as-bytelist-help V2003 (read-byte V2003) (cons V2004 V2005)))))))

It prints false<ok> forever. Now this is strange because as I showed above, read-byte returns -1 so (= -1 V2004) should have returned true. Here’s an even more interesting observation:

(shen.read-file-as-bytelist-help -1 -1 -1)
(0.0-) false<ok>TypeError {foundTy = TyNum, expectedTy = TyStream}

Passing -1 as V2004 still prints false. Now you can think that the problem is at conditionals, but it works fine hundreds of times until the program comes to this function call.


UPDATE: I solved the read-file bug. That was because the lexer was reading -1 as a symbol, not a number. You can see the commit here. (lexer may still have bugs though, it’s not well-tested, maybe I should take my time and read Shen specification in detail.