Operator resolution

I don’t doubt that I have a few more type checking errors in store for me
in the current version of list_min below (which ideally I would implement
in a more polymorphic manner). Right now I’m not sure about this error
about operator overloading (code highlighted in yellow).

This more simple case works fine, so I haven’t captured the essence of the
problem:
var a: double = 1.00
var b: double = 2.79

val x = if a < b then 1 else 0

error(3): the symbol [<] cannot be resolved: there are too many matches:
lt_string_string, lt_ssize1_int1, …
exit(ATS): uncaught exception:
_2fhome_2ffac2_2fhwxi_2fresearch_2fATS_2fIMPLEMENT_2fGeizella_2fAnairiats_2fsvn_2fats_2dlang_2fsrc_2fats_error_2esats__FatalErrorException(1233)

fn find (
SDmap: &map (string, double), k: string, res: &double?
) : void = () where {
val b = linmap_search (SDmap, k, lam(x,y) => compare_string_string(x,y),
res)
val () = if b then let
prval () = opt_unsome {double} (res)
in
print “Some(”; print res; print ")“
end else let
prval () = opt_unnone {double} (res) in ($raise InvalidCase; print
"None()”)
end // end of [val]
val () = print_newline ()
} // end of [find]

fun list_min (inlist: List string, emap: &map(string,double)): Option_vt
string = let
fun loop(cmin: string, rlist: List string, emap: &map(string,double)):
string = case+ rlist of
| list_cons (x, xs) => let
var xval: double
val _ = find(emap, x, xval)
var cminval: double
val _ = find(emap, cmin, cminval)
in
if cminval < xval then loop(cmin,xs,emap) else loop(x,xs,emap)
end
| list_nil () => cmin
in case+ inlist of
| list_cons (x, xs) => Some_vt(loop(x,xs))
| list_nil () => None_vt ()
end // end of [list_min]

I admit I’m not sure why it isn’t what you suggest, but when I change it
to that I get a new error:

It needs to be changed as Hongwei suggests otherwise ‘cminval’ and ‘xval’
are of type ‘double?’ which is an uninitialized double. There would be no
comparison operator defined for that. Making the changes results in the
other type error you paste. This is because the ‘find’ function now expects
the ‘res’ parameter to be an initialized ‘double’ on completion. But the
case where the ‘linmap_search’ fails results in an unintialized double (a
‘double?’).

You either need to propogate the ‘linmap_search’ failure through the result
of ‘find’ and handle it by the caller, or handle it in ‘find’ by setting it
to some sentinel value in the case where linmap_search fails. This will
probably also necessitate adding a type hint to the ‘if’. Something like:

if :(res: double) => b then let
prval () = opt_unsome {double} (res)
in
print “Some(”; print res; print “)”
end else let
prval () = opt_unnone {double} (res)
val () = res := -1.0
in ($raise InvalidCase; print “None()”)
end

‘-’ -> ‘~’

In ATS, ‘~’ stands for the negative sign.

fn find (
SDmap: &map (string, double), k: string, res: &double?
) : void

Should it be ‘res: &double? >> double’ ?

prval () = linset_free (…)
^^^^^

‘prval’ should be replaced with ‘val’; otherwise, there will be memory leak.

Would it be better for this sort of mistake to emit an error? While in my
case it was originally done out of ignorance, I can see it being a
plausible typo.

Thanks for all the feedback; I’ve mostly gone through with abstract
interfaces for set and map (working on finishing map now).

I’m still having a bit of trouble with find, changing it around a bit:
extern
fun gDMap_find(mp: &gDMap, k: string): double

implement
gDMap_find (mp, k): double = let
var res: double?
val b = $LM.linmap_search (mp, k, lam(x,y)
=> compare_string_string(x,y), res)
in
if: (res:double) => b then let
prval () = opt_unsome {double} (res)
val _ = $showtype res
in res end
else let
prval () = opt_unnone {double} (res)
in ($raise InvalidCase; -1.0) end
end // end of [gDMap_find]

Now i’m getting:

error(1): fixity cannot be resolved.

(highlighted above)

Also if you know of any good examples for ref-counted absvtypes, I’ll try
and have a look (thanks for the abstract type examples).

One other thing, not sure I understand “(res:double) => b” completely, but
I assume this means something like “assert res is a double”.

I basically copied the function “find” from
./ats-lang-anairiats-0.2.9/doc/EXAMPLE/TEST/libats_linmap_avltree.dats.

I admit I’m not sure why it isn’t what you suggest, but when I change it to
that I get a new error:
/media/RAID5/share/ATS_learning/toCNF4.dats: 14846(line=554, offs=14) –
15195(line=564, offs=2): error(3): mismatch of static terms (tyleq):
The needed term is: S2Eapp(S2Ecst(at_viewt0ype_addr_view); S2Ecst(double),
S2Evar(res(11138)))
The actual term is: S2Eapp(S2Ecst(at_viewt0ype_addr_view); S2Etop(0;
S2Ecst(double_t0ype)), S2Evar(res(11138)))
/media/RAID5/share/ATS_learning/toCNF4.dats: 14846(line=554, offs=14) –
15195(line=564, offs=2): error(3): mismatch of static terms (tyleq):
The needed term is: S2Ecst(double_t0ype)
The actual term is: S2Etop(0; S2Ecst(double_t0ype))

If I call $showtype on xval before and after using find, it reports
S2Etop(0; S2Ecst(double_t0ype))

So the book-keeping seems to be in order as far as that goes.

local

assume myset = linset (…)
val cmp = lam (x, y) = …

in

end

Is there a similar idiom to this that works with ‘cloptr’ to avoid use of
the garbage collector, assuming a ‘linset’ that takes a cloptr instead of a
cloref?

Please add no space between ‘:’ and ‘<’.

I was referring to:

prval () = linset_free (…)
^^^^^

‘prval’ should be replaced with ‘val’; otherwise, there will be memory leak.

Full code attached, if it helps.

cnf4.zip (7.5 KB)

I remember seeing something like:

prval () = linset_free (…)

in your code. This will lead to memory leak. Please use ‘val’ for 'prval’
instead.

I took a look at your code.

It is great to see that you have made so much progress.

There is one issue that I would like to point out now, which I think is
vital for you to
continue making progress.

First, this is the time to introduce some abstract types. You use linmap
and linset directly,
which is a style that I suggest you to avoid as much as possible.

Please introduce abstract types like myset and mymap, and then implement
them based on
linset and linap. Please take a look how this is done in the following code:


If you use ATS properly, the language can really do wonders for you.

Hongwei

PS: I also have the feeling that GRexp should not be defined as a
dataviewtype; it should be
abstract and its values should be ref-counted.

I see now. When using , why would something like the following:

fun loopCOV {n:nat} (COV: matrix(double,n,n), rlist: List(string), imap:
&gIdxMap n, ccov: double): double = let…

result in:

error(1): fixity cannot be resolved.

I thought the “1” in cloref1 would allow any effect, or does fixity mean
something else here?

Right now, this typo causes the compiler to put the token PMVerr in the
emitted code (if it is not stopped earlier).
By looking at the location info associated with PMVerr, you can readily
identify the source of the problem.

Yes, we can probably do better later.

Declaration:

absviewtype myset
fun myset_union (xs: myset, ys: myset): myset
overload + with myset_union

Implementation:

local

assume myset = linset (…)
val cmp = lam (x, y) = …

in (* in of [local] *)

implement
myset_union (xs, ys) = linset_union (xs, ys, cmp)

end // …