Yes, the same representation is used. That is why I used ‘$UNSAFE.cast’
in my original code.
Passing a closure by value is impossible in general because the type ‘clo’
is not of a fixed size (as we cannot tell anything about the environment in
a closure).On Tuesday, December 29, 2015 at 3:45:52 PM UTC-5, Mike Jones wrote:
So (…) - means closure on heap which is ptr, and &(…) -
means ptr to closure that is not already ptr, on stack or static. Wouldn’t
the representation be the same, such that a function taking a closure as
argument could take either, assuming something like ptr to tuple with an
anonymous function and captured data?
And can you pass a closure by value? That assumes a tuple copy. Not
efficient, but curious.
I assume that if there is no alloc/malloc library to link, there cannot be links, because I kind of remember that for ATS the GC operates via this API. I would like to confirm that.
The danger for me is my application layers on ThreadX, wrappers by Cypress, but I think it exposes the alloc/malloc. Would a simple search of the generated C be enough to determine no leaks? Or are there other calls I need to check?> On Dec 28, 2015, at 5:30 PM, gmhwxi gmh...@gmail.com wrote:
To recognize whether the C code generated from ATS source
does something bad (e.g., leaks memory), one needs to analyze the
C code. Tools need to be developed for doing such analysis.
On Monday, December 28, 2015 at 7:28:14 PM UTC-5, gmhwxi wrote:
In general, malloc needs to be called to construct a closure.
However, ‘free’ is not called automatically. If you use a linear
closure (cloptr) but do not call ‘free’, you will get a type-error somewhere.
If you use a persistent closure (cloref), you can not free the closure explicitly
(in a type-safe manner). Instead, GC is needed to reclaim the closure.
In other words, if you create a cloref but do not run GC, you have a potential
memory leak.
On Monday, December 28, 2015 at 5:13:53 PM UTC-5, Mike Jones wrote:
Ref 3.13 of Introduction, ifold2…
Do closures of in general:
Gen code with a malloc call?
Gen code with free after exiting scope?
Meaning, if I am not linking a library with malloc and free I can’t accidentally use it, and if I do have a library, I can’t accidentally produce a leak?
For example, the function example sqrmodsum in the text: does it produce an error when malloc is not available, and if available, does this example leak? Or does it make one heap object that is reused on each call?
I guess I want to know under what circumstances a nieve maintainer can get into trouble. My hope is the behavior is either fail to compile, or no leak. If I am correct, then in which ways can I create a closure that leaks so I can r cognizant them?
//
// HX-2015-12-31:
// this one need a cast:
//
fun{}
sqrmodsum
(n: int, d: int): int = let
//
var
fopr =
lam@(res: int, x: int): int =
if x mod d = 0 then res + x * x else res
//
in
ifold2(10, $UNSAFE.cast(addr@fopr), 0)
end // end of [sqrmodsum]
//On Thursday, December 31, 2015 at 11:06:01 PM UTC-5, Mike Jones wrote:
Can you add the cast version in the code or write it here? I think it is
important because one might need to pass stack allocated lams to prexisting
higher ordered functions. As much as I don’t like casting, for embedded
code, this seems the only way, unless there is something not said here.
I should have said ‘stack-allocated’ (instead of ‘statically allocated’).
However, the stack
allocation in the original call-frame of the function; it is not done via
alloca.On Tue, Dec 29, 2015 at 12:34 PM, Mike Jones proc...@gmail.com wrote:
This shows how to put it on heap/GC, and stack, how do you put it in
static memory? I assume you create a standard function or instantiated
template. Then do you have to cast it?
If the type of the target of cast is not given, then the typerchecker
does not check anything. So this kind of cast is the most unsafe kind.On Thursday, December 31, 2015 at 11:50:57 PM UTC-5, Mike Jones wrote:
BTW, how does the compiler know what type to cast to?
There is another closure example in the introduction book I want to understand. Section 6.5 has code below.
The fun definitions have , and do not follow the typical syntax of a value bound to a lam. So does this mean a closure is returned? Does it mean the fun is a closure? Is any thing on the heap? And what is the purpose of it in this example?
fun{
a:t@ype
} insertion_sort
(
A: arrszref (a)
, cmp: (a, a) -> int
) : void = let
val n = g0uint2int_size_int(A.size())
fun ins (x: a, i: int): void =
if i >= 0 then
(
if cmp (x, A[i]) < 0
then (A[i+1] := A[i]; ins (x, i-1)) else A[i+1] := x
// end of [if]
) else A[0] := x // end of [if]
// end of [ins]
fun loop (i: int): void =
if i < n then (ins (A[i], i-1); loop (i+1)) else ()