morloc-project / morloc

A typed, polyglot, functional language
GNU General Public License v3.0
195 stars 4 forks source link

Cannot guess serialization type #15

Closed Zach1031 closed 2 years ago

Zach1031 commented 2 years ago

When attempting to compile morloc code from a C++ or Python source file in which a function requires/returns a list of generic type 'a' results in the error message: Cannot guess serialization type: PV CppLang (Just "a_q0") "a_q0"

This error is misleading, as the true error is not a serialization issue. The error results from the user not defining the list type and living the type generic. (i.e. defining as "std::vector<$1>" "a" instead of "std::vector<$1>" "int").

arendsee commented 2 years ago

Thanks for the report! Could you post the morloc code that generated the error?

Zach1031 commented 2 years ago

Sure

The morloc code that I used to test the issue:

source cpp from "serial_test.cpp" ("test")

test :: Int -> List Int
test cpp :: "int" -> "std::vector<$1>" a

export test

And the C++ function that morloc is sourcing from:

vector<int> test(int x){
  return {1, 2, 3};
}
arendsee commented 2 years ago

The immediate solution to the problem is to change the type signatures to:

test :: Int -> List Int
test cpp :: "int" -> "std::vector<$1>" "int"

The error is being triggered by the generic a in the C++ signature. This should not be generic since the return vector written in the C++ function is vector<int>. The signature "int" -> "std::vector<$1>" a would be appropriate for the C++ function:

template <class A>
vector<A> test(int x){
   ???
}

The ??? is where the problem is. There isn't a fully generic implementation of the signature Int -> List a. The only sensible thing to do would be to return an empty list where the integer input is ignored and the list type parameter is inferred by context. If something else where known about a, for example, if it were required to be a type that had a default value (such as any monoid) or if it were a type from which ordered or random values could be selected, then the function could be implemented.

The morloc code passes the typechecker. This is in itself a bit dubious. But until morloc has some why to express typeclasses or other constraints on generic variables, I can't be too strict. The error is raised when the compiler attempts to generate code for the test function. When you run morloc make on the code above, the compiler will try to make an executable program that can run the test function given an integer from the user. It fails because it does not know what type is returned from test so it can't generate correctly typed C++ code or figure out serialization.

You are definitely right that the error message is misleading. The root cause of the error is not that it can't serialize this particular type. The problem is that is doesn't know what type it needs to serialize. The error should be something like:

Error: cannot infer concrete type for generic `a`

file "xxx.loc" line 4:
    test cpp :: "int" -> "std::vector<$1>" a

morloc needs a major over-haul of its error handling. It has the infrastructure to get source code line and column numbers, but I haven't wired it up yet.

Anyway, thanks for the report! I will plan on addressing this in the next dev cycle. I've certainly been putting off writing proper error handling for far too long.