Codegen for Times[ZZ] does not output zQ_TimesD_ZZG_new function
Acton Version
0.24.1.20250108.8.28.39
Steps to Reproduce and Observed Behavior
I wanted to implement the Times[ZZ] protocol to allow multiplication of ZZ.
import testing
class ZZ(value):
re: float
im: float
def __init__(self, re, im):
self.re = re
self.im = im
def __str__(self):
if self.re == 0 and self.im == 0:
return "0"
elif self.re == 0:
return "%fj" % self.im
elif self.im == 0:
return str(self.re)
else:
return "%f + %fj" % (self.re, self.im)
def __repr__(self):
return "ZZ(%f, %f)" % (self.re, self.im)
extension ZZ(Eq):
def __eq__(self, other):
return self.re == other.re and self.im == other.im
extension ZZ(Plus):
def __add__(self, other):
return ZZ(self.re + other.re, self.im + other.im)
@staticmethod
def __zero__():
return ZZ(0, 0)
extension ZZ(Times[ZZ]):
def __mul__(self, other: ZZ) -> ZZ:
return ZZ(self.re * other.re - self.im * other.im,
self.re * other.im + self.im * other.re)
def _testZZ():
c0 = ZZ(0, 0)
c1 = c0 + ZZ(1, 0)
c11 = c0 + ZZ(1, 1)
testing.assertEqual(c0, ZZ(0, 0))
testing.assertEqual(c0 + c0, ZZ(0, 0))
testing.assertEqual(c1, ZZ(1, 0))
testing.assertEqual(c11, ZZ(1, 1))
testing.assertEqual(c1 * c1, ZZ(1, 0))
It looks like the generated C code is missing the zQ_TimesD_ZZG_new function?
❯ acton test
Building project tests...
Failed to build project tests
actonc exited with code 1 / 0
stderr: Building project in /home/mzagozen/aoc/2024
Compiling z.act for development
Finished compilation in 0.097 s
Compiling tf2.act for development
Already up to date, in 0.000 s
Compiling tf.act for development
Already up to date, in 0.000 s
Compiling d02.act for development
Already up to date, in 0.000 s
Compiling d01.act for development
Already up to date, in 0.000 s
Compiling aoc.act for development
Already up to date, in 0.000 s
Compiling d03.act for development
Already up to date, in 0.000 s
Compiling d04.act for development
Already up to date, in 0.000 s
Compiling d05.act for development
Already up to date, in 0.000 s
Compiling d06.act for development
Already up to date, in 0.000 s
Final compilation step
ERROR: internal compiler error: compilation of generated Zig code failed, returned error code1
NOTE: this is likely a bug in actonc, please report this at:
NOTE: https://github.com/actonlang/acton/issues/new?template=ice.yaml
NOTE: acton 0.24.1.20250108.8.28.39 compiled by ghc 9.6 on linux x86_64
NOTE: cc: 0.13.0
zig stdout:
zig stderr:
Acton Project Builder - building /home/mzagozen/aoc/2024
Acton Base Builder
Building in /usr/lib/acton/base
-- filename : uri.c
full_path: /usr/lib/acton/base/out/types/uri.c
dir : /usr/lib/acton/base/out/types
file_path: /uri.c
-- filename : base64.c
full_path: /usr/lib/acton/base/out/types/base64.c
dir : /usr/lib/acton/base/out/types
file_path: /base64.c
-- filename : re.c
full_path: /usr/lib/acton/base/out/types/re.c
dir : /usr/lib/acton/base/out/types
file_path: /re.c
-- filename : numpy.c
full_path: /usr/lib/acton/base/out/types/numpy.c
dir : /usr/lib/acton/base/out/types
file_path: /numpy.c
-- filename : md5.c
full_path: /usr/lib/acton/base/out/types/crypto/hash/md5.c
dir : /usr/lib/acton/base/out/types/crypto/hash
file_path: /crypto/hash/md5.c
-- filename : process.c
full_path: /usr/lib/acton/base/out/types/process.c
dir : /usr/lib/acton/base/out/types
file_path: /process.c
-- filename : snappy.c
full_path: /usr/lib/acton/base/out/types/snappy.c
dir : /usr/lib/acton/base/out/types
file_path: /snappy.c
-- filename : file.c
full_path: /usr/lib/acton/base/out/types/file.c
dir : /usr/lib/acton/base/out/types
file_path: /file.c
-- filename : xml.c
full_path: /usr/lib/acton/base/out/types/xml.c
dir : /usr/lib/acton/base/out/types
file_path: /xml.c
-- filename : rts.c
full_path: /usr/lib/acton/base/out/types/acton/rts.c
dir : /usr/lib/acton/base/out/types/acton
file_path: /acton/rts.c
-- filename : term.c
full_path: /usr/lib/acton/base/out/types/term.c
dir : /usr/lib/acton/base/out/types
file_path: /term.c
-- filename : json.c
full_path: /usr/lib/acton/base/out/types/json.c
dir : /usr/lib/acton/base/out/types
file_path: /json.c
-- filename : time.c
full_path: /usr/lib/acton/base/out/types/time.c
dir : /usr/lib/acton/base/out/types
file_path: /time.c
-- filename : random.c
full_path: /usr/lib/acton/base/out/types/random.c
dir : /usr/lib/acton/base/out/types
file_path: /random.c
-- filename : testing.c
full_path: /usr/lib/acton/base/out/types/testing.c
dir : /usr/lib/acton/base/out/types
file_path: /testing.c
-- filename : argparse.c
full_path: /usr/lib/acton/base/out/types/argparse.c
dir : /usr/lib/acton/base/out/types
file_path: /argparse.c
-- filename : buildy.c
full_path: /usr/lib/acton/base/out/types/buildy.c
dir : /usr/lib/acton/base/out/types
file_path: /buildy.c
-- filename : __builtin__.c
full_path: /usr/lib/acton/base/out/types/__builtin__.c
dir : /usr/lib/acton/base/out/types
file_path: /__builtin__.c
-- filename : logging.c
full_path: /usr/lib/acton/base/out/types/logging.c
dir : /usr/lib/acton/base/out/types
file_path: /logging.c
-- filename : net.c
full_path: /usr/lib/acton/base/out/types/net.c
dir : /usr/lib/acton/base/out/types
file_path: /net.c
-- filename : http.c
full_path: /usr/lib/acton/base/out/types/http.c
dir : /usr/lib/acton/base/out/types
file_path: /http.c
-- filename : math.c
full_path: /usr/lib/acton/base/out/types/math.c
dir : /usr/lib/acton/base/out/types
file_path: /math.c
Debug build
Threads enabled
Debug build
Threads enabled
Threads enabled
Building executable from: /home/mzagozen/aoc/2024/out/types/z.test_root.c -> .test_z
Building executable from: /home/mzagozen/aoc/2024/out/types/tf2.test_root.c -> .test_tf2
Building executable from: /home/mzagozen/aoc/2024/out/types/d05.test_root.c -> .test_d05
Building executable from: /home/mzagozen/aoc/2024/out/types/d06.test_root.c -> .test_d06
install
+- install .test_d05
+- zig build-exe .test_d05 Debug x86_64-linux-gnu.2.27
+- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 5 errors
/home/mzagozen/aoc/2024/out/types/z.c:12:31: error: equality comparison with extraneous parentheses
/home/mzagozen/aoc/2024/out/types/z.c:12:31: note: remove extraneous parentheses around the comparison to silence this warning
/home/mzagozen/aoc/2024/out/types/z.c:12:31: note: use '=' to turn this equality comparison into an assignment
/home/mzagozen/aoc/2024/out/types/z.c:16:31: error: equality comparison with extraneous parentheses
/home/mzagozen/aoc/2024/out/types/z.c:16:31: note: remove extraneous parentheses around the comparison to silence this warning
/home/mzagozen/aoc/2024/out/types/z.c:16:31: note: use '=' to turn this equality comparison into an assignment
/home/mzagozen/aoc/2024/out/types/z.c:137:31: error: call to undeclared function 'zQ_TimesD_ZZG_new'; ISO C99 and later do not support implicit function declarations
/home/mzagozen/aoc/2024/out/types/z.c:137:22: error: cast to 'B_Times' (aka 'struct B_Times *') from smaller integer type 'int'
/home/mzagozen/aoc/2024/out/types/z.c:257:36: error: comparison of distinct pointer types ('B_NoneType (*)(zQ___test_main)' (aka 'struct B_NoneType *(*)(struct zQ___test_main *)') and 'B_NoneType (*)($Actor)' (aka 'struct B_NoneType *(*)(struct $Actor *)'))
error: the following command failed with 5 compilation errors:
/usr/lib/acton/zig/zig build-lib -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d01.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d03.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d06.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/z.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/aoc.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d02.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d04.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/tf.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d05.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/tf2.c -ODebug -target x86_64-linux-gnu.2.27 -mcpu westmere -I /home/mzagozen/aoc/2024 -I /home/mzagozen/.cache/acton/zig-local-cache/o/5ba49e2ea7f7137e8db6df131fec41ff -Mroot -lc++ -lc --cache-dir /home/mzagozen/.cache/acton/zig-local-cache --global-cache-dir /home/mzagozen/.cache/acton/zig-global-cache --name ActonProject -static --listen=-
Build Summary: 36/47 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
+- install ActonProject transitive failure
| +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 5 errors
+- install .test_z transitive failure
| +- zig build-exe .test_z Debug x86_64-linux-gnu.2.27 transitive failure
| +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_tf2 transitive failure
| +- zig build-exe .test_tf2 Debug x86_64-linux-gnu.2.27 transitive failure
| +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_d05 transitive failure
| +- zig build-exe .test_d05 Debug x86_64-linux-gnu.2.27 transitive failure
| +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_d06 transitive failure
+- zig build-exe .test_d06 Debug x86_64-linux-gnu.2.27 transitive failure
+- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
error: the following build command failed with exit code 1:
/home/mzagozen/.cache/acton/zig-local-cache/o/caeea20549f1656dc477d219b371f57a/build /usr/lib/acton/zig/zig /home/mzagozen/aoc/2024 /home/mzagozen/.cache/acton/zig-local-cache /home/mzagozen/.cache/acton/zig-global-cache --seed 0x523d5669 -Z31dffbeade203dbe --prefix /home/mzagozen/aoc/2024/out --prefix-exe-dir bin -Dtarget=x86_64-linux-gnu.2.27 -Dcpu=westmere -Doptimize=Debug
Expected Behavior
The program compiles and ZZ multiplication works!
I looked at this. The problem is that the compiler considers that the implementation of Times[ZZ] misses the Plus methods (Times is a subprotocol of Plus). So if you reorder the Acton source to merge these two extensions everything works:
extension ZZ(Times[ZZ]):
def __add__(self, other):
return ZZ(self.re + other.re, self.im + other.im)
@staticmethod
def __zero__():
return ZZ(0, 0)
def __mul__(self, other: ZZ) -> ZZ:
return ZZ(self.re * other.re - self.im * other.im,
self.re * other.im + self.im * other.re)
Whether this is a temporary problem to be fixed (there are some remaining problems with extensions) or not, I will have to ask the live language definition @nordlander.
(More exactly, the problem is in CodeGen.hs, function declCon, where the compiler decides that the witness class has two abstract attributes add and zero and hence does not generate a new function.)
This example should indeed work as expected without modifying the sources. But the example is also a good illustration of the big remaining problem with extensions, which I'm telling myself I must return to shortly. (The small remaining problem is that we can't implicitly declare extensions by simply listing protocol ancestors when a class is defined, but I guess that's easier to live with.)
I don't understand what the big problem with extension is? You only explained the / a small problem
This is a dupe of #1126.
@nordlander what is the big remaining problem? :)
@plajjan See my comment in #2380