Nested stream cloptrs: unable to close over variables in scope

42 views
Skip to first unread message

aditya siram

unread,
Jan 6, 2019, 7:32:27 AM1/6/19
to ats-lang-users
Hi,
I'm trying to take the cross product of two finite streams using nested 'cloptr' and I can't get it to typecheck, here's what I have:

fun foo(s:int): stream_vt(stream_vt(@(int,int))) =
  stream_vt_map_cloptr<int><stream_vt(@(int,int))>(
    streamize_intrange_lr(1,10),
    lam(i) =<cloptr1>
      stream_vt_map_cloptr<int><(int,int)>(
        streamize_intrange_lr(1,10),
        lam(j) =<cloptr1> @(i,j)
      )
  )

I want to cross (1..10) with (1..10) and get a stream of (1,1),(1,2),(1,3) ... but I get an error on the 'lam(j) =<cloptr1> @(i,j)' line:

...: dereference cannot be performed: the proof search for view located at [S2Evar(i(14251))] failed to turn up a result.
...: the dynamic expression cannot be assigned the type [S2Etyrec(flt0; npf=-1; 0=S2Ecst(int), 1=S2Ecst(int))].


The same thing works if instead of nesting a 'stream_vt_map_cloptr' I construct an explicit 'fun loop' inside the body of the first 'lam' that takes 'i' as an argument.

Why is there a difference?

aditya siram

unread,
Jan 6, 2019, 8:04:09 AM1/6/19
to ats-lang-users
But this typechecks and I don't understand why:

fun foo(s:int): stream_vt(stream_vt(@(int,int))) =
  stream_vt_map_cloptr
<int><stream_vt(@(int,int))>(
    streamize_intrange_lr
(1,10),
    lam
(i) =<cloptr1>

      let
        val i
= i (* added this *)
     
in

        stream_vt_map_cloptr
<int><(int,int)>(
          streamize_intrange_lr
(1,10),
          lam
(j) =<cloptr1> @(i,j)
       
)

     
end
 
)

aditya siram

unread,
Jan 6, 2019, 8:11:17 AM1/6/19
to ats-lang-users
It also typechecks if I do '!i' instead of just 'i' so I guess it's passed in as a reference and needs to be dereferenced before passing it along:

fun foo(s:int): stream_vt(stream_vt(@(int,int))) =
  stream_vt_map_cloptr
<int><stream_vt(@(int,int))>(
    streamize_intrange_lr
(1,10),
    lam
(i) =<cloptr1>
      stream_vt_map_cloptr
<int><(int,int)>(
        streamize_intrange_lr
(1,10),

        lam
(j) =<cloptr1> @(!i,j)
     
)
 
)




But in this example I didn't need to deference 'i' before adding to it:

fun bar(s:int): stream_vt(int) =
  stream_vt_map_cloptr
<int><int>(
    streamize_intrange_lr
(1,10),
    lam
(i) =<cloptr1> i+1
 
)



So while I've solved my original problem I still don't know why it works.

aditya siram

unread,
Jan 6, 2019, 8:23:01 AM1/6/19
to ats-lang-users
Actually that last example where I used '!i' doesn't work but the previous one where I did 'let val i = i in ... end' does.

Sorry for the noise.

gmhwxi

unread,
Jan 6, 2019, 3:55:38 PM1/6/19
to ats-lang-users

In the following code, 'i' is passed as a reference, which cannot be
used under another 'lam':

lam(i) =<cloptr1>
      stream_vt_map_cloptr
<int><(int,int)>(
        streamize_intrange_lr
(1,10),

        lam
(j) =<cloptr1> @(!i,j)
     
)

You need to do 'let val i = i ...' to take out the value stored in the original 'i'
so that you can have access to it under another 'lam'.
Reply all
Reply to author
Forward
0 new messages