Function Template not working : segfaults.

47 views
Skip to first unread message

Chotu S

unread,
Apr 1, 2015, 11:39:20 PM4/1/15
to ats-lan...@googlegroups.com
I have not programmed in ATS for a while , so I was trying to review ATS and tried to implement Maybe monad from this  discussion thread : 




#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"

datatype Maybe (a : t@ype) =
  | Nothing (a) of ()
  | Just    (a) of (a)
  
datatype Expr = 
  | Val of Int 
  | Div of (Expr , Expr)

(* from UPENN haskell example *)
(* ok  = Div (Div (Val 1972) (Val 2)) (Val 23) *)
val ok  = Div (Div ( Val (1972) , Val (2) ) ,    Val (23))

(* val err = Div (Val 2) (Div (Val 1) (Div (Val 2) (Val 3))) *)
val err =   Div (Val (2) , Div (Val (1) , Div (Val (2) ,  Val (3))))

abst@ype M (t@ype) = ptr 
 
extern
fun {a : t@ype}
ret (v : a ) : M(a)
 
extern
fun{a,b : t@ype}
bind : M(a)  -> M(b)
 
extern
fun{a,b:t@ype}
bind$cont (x : a) : M(b)

assume M (a : t@ype) = Maybe (a)

extern
fun div (m : int , n : int) : Maybe(int) 

implement{a}
ret (x) = Just (x)

implement{a,b}
bind (ma) = 
  case ma of
    | Nothing _ => Nothing ()
    | Just (x) => bind$cont<a,b> (x)


fun eval (e : Expr) : Maybe(int) =
  case e of
    | Val n => ret (n)
    | Div (e1 , e2) => 
        bind<int,int>(eval (e1)) where {
          implement bind$cont<int,int> (m) = 
            bind<int,int>(eval (e2)) where {
              implement bind$cont<int,int> (n) = div (m,n) }}
              
implement              
div (m , n) =
  if n = 0 
     then Nothing ()
     else ret (m / n)


fun print_maybe (m : Maybe (int)) : void = 
  case m of
    | Nothing _ => println! ("Nothing")
    | Just (x)  => println! (x)


implement main0 () = () where {
  val res1 = eval (ok)
  val res2 = eval (err)
  val _ = print_maybe (res1)
  val _ = print_maybe (res2)
}
  




When run this segfaults , and I think it is because it does not see second implementation of bind$cont and keep calling the first one which leads to stack overflow .
Does not second implementation override the first one ?


gmhwxi

unread,
Apr 2, 2015, 7:48:34 AM4/2/15
to ats-lan...@googlegroups.com
Your assessment of the situation sounds correct to me. However, I don't see an easy way to get out of the
situation.

See:
https://groups.google.com/forum/#!searchin/ats-lang-users/monad/ats-lang-users/gGOqTJwiegE/K8ieRTSodDEJ

Why not just implement 'bind' as a higher order function (as in Haskell)?

Shea Levy

unread,
Apr 2, 2015, 9:25:06 AM4/2/15
to ats-lan...@googlegroups.com
By the way, for a better error message in a case like this you may want to try something like https://github.com/NixOS/nix/blob/master/src/libmain/stack.cc#L17-L38
-- 
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/15972562-7ae1-44f4-8cd1-94b7288f326a%40googlegroups.com.

gmhwxi

unread,
Apr 2, 2015, 10:11:41 PM4/2/15
to ats-lan...@googlegroups.com
Here is some explanation:

When the first bind<int,int> is being compiled, 'bind<int,int>' is stored on some
kind of stack. When the second bind<int,int> is countered, the one on the stack is still
there; so the second bind<int,int> and the first bind<int,int> are actually compiled into
two calls to the same function (instead of each call to a different function)


On Wednesday, April 1, 2015 at 11:39:20 PM UTC-4, Chotu S wrote:
Reply all
Reply to author
Forward
0 new messages