Closed tjpalmer closed 1 month ago
This is likely fixed since I pulled out the overloads and now use targeted type handling, but I hit a different problem while testing:
$ let something(a: Mapped<String, Int>, b: Mapped<String, Int>): Int { a.length + b.length }
interactive#0: void
$ something(new Map([new Pair("a", 1)]), new MapBuilder<String, Int>())
interactive#1: 1
$ translate(1, "csharp")
[interactive#1]: interactive#0 does not export symbol something
An operation is not implemented: External reference: nym`-repl/i0000//chunk.temper`.something at CSharpTranslator.kt:1655
$ translate(1, "py")
[interactive#1]: interactive#0 does not export symbol something
Translated py for interactive#1
interactive-0001/
interactive_0001/
__init__.py: text/python
import interactive_0001.chunk as _0
from temper_core import await_safe_to_exit
await_safe_to_exit()
chunk.py: text/python
from builtins import int
from temper_core import Pair, map_constructor
pair = Pair
return_: 'int' = something(map_constructor((pair('a', 1),)), {})
export = return_
__init__.py.map: application/json
{ "version": 3, "file": "py/interactive-⋯": [], "names": [], "mappings": "A;A;A" }
chunk.py.map: application/json
{ "version": 3, "file": "py/interactive-⋯C,EAAC,CAAC,CAAE,GAA6B,CAAC;AAAA,SAAAC" }
interactive#3: void
Fixed the tangent bug in the previous comment, so now I can easily test this translation:
$ let something(a: Mapped<String, Int>, b: Mapped<String, Int>): Int { a.length + b.length }
interactive#0: void
$ something(new Map([new Pair("a", 1)]), new MapBuilder<String, Int>())
interactive#1: 1
$ translate(1, "csharp")
[interactive#1]: interactive#0 does not export symbol something
Translated csharp for interactive#1
interactive-0001/
src/
Chunk/
ChunkGlobal.cs: text/x-csharp
using C0 = Interactive0001.Chunk;
using C1 = TemperLang.Core;
using G = System.Collections.Generic;
namespace Interactive0001.Chunk
{
public static class ChunkGlobal
{
internal static int return__7;
static ChunkGlobal()
{
return__7 = C0::ChunkGlobal.Something(C1::Mapped.ConstructMap(C1::Listed.CreateReadOnlyList<G::KeyValuePair<string, int>>(new G::KeyValuePair<string, int>("a", 1))), C1::Mapped.AsReadOnly(new C1::OrderedDictionary<string, int>()));
}
}
}
ChunkGlobal.cs.map: application/json
{ "version": 3, "file": "csharp/interact⋯AAA7B,IAA6B,KAAC,AAArE;AAAA;AAAqE;AAAA" }
interactive#2: void
Note the Mapped.AsReadOnly
call, which shows the new behavior and ought to work correctly.
The C# backend translates
Listed
toIReadOnlyList
andMapped
toIReadOnlyDictionary
, but in .NET,IList
isn't a subtype ofIReadOnlyList
, even thoughList
is a subtype of both, and same issue for Dictionary types. We provide convenience and work around this today by making overloads forListed
to all 3 list types mentioned above, but we don't do exponential overloads. So for example, Temper like this:Will fail at the C# compiler because we'll make
IDictionary
andIReadOnlyDictionary
overloads for ALL parameters at a time, but we don't do all the combinations, because exponential can get big.To handle the general case, we need the expected type of expressions in TmpL. For example, I know when a value is a MapBuilder, but I need to know if it's going into a Mapped. If so, I need to wrap/cast it in generated C# code to an IReadOnlyList.