Akuli / jou

Yet another programming language
MIT License
11 stars 4 forks source link

new import syntax cannot import function correctly #325

Closed littlewhitecloud closed 1 year ago

littlewhitecloud commented 1 year ago

file1.jou

import "stdlib/io.jou"
def hello() -> void:
    puts("helloworld!")

file2.jou

import "stdlib/io.jou"
def hello() -> void:
    puts("Hello, World!")

test.jou

import "./file2.jou"
import "./file1.jou"

def main() -> int:
    hello() # Which hello function file1's or file2's?
    return 0

output image

jou test.jou
compiler warning for file "test.jou", line 2: "./file1.jou" imported but not used
c:/program files/jou/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./jou_compiled/test/file2.obj:file2.jou:(.text+0x0): multiple definition of `hello'; ./jou_compiled/test/file1.obj:file1.jou:(.text+0x0): first defined here
The process failed with status 1.

The new import syntax failed to load the same name function, but we can use python's import syntax: file.function(arg1, arg2, ...)

import "stdlib\math.jou" # example
import "stdlib\io.jou"
def main() -> int:
   io.printf("%d", math.pow(2, 2))
   return 0

And revert the old syntax (Maybe) from "{file}" import "{function}"

littlewhitecloud commented 1 year ago

Or let compiler use the last import same name function just like tkinter.ttk

from tkinter import Tk, Button
from tkinter.ttk import Button
xxx = Button(master, ...) # use tkinter.ttk's Button
Akuli commented 1 year ago

This has nothing to do with Jou's syntax, and it is a limitation of how Jou works (and it behaves just like in C). Jou has always worked this way, even before the syntax was changed.

You are getting a linker error. When you compile a Jou file, it turns into a .o file. So the compiler creates two .o files, file1.o and file2.o, both containing a function named hello. When the linker sees this, it complains because you can't have two functions with the same name, but the .exe file can only have one function with a given name.

The Jou compiler could automatically prefix the function names: a hello function in file1.o could be actually called file1_hello. This is what "better C" languages (Zig, Rust, C++, ...) do. But Jou isn't like those languages, instead Jou avoids doing anything significantly more magical than C.

You need to name the functions differently -- again, just like in C. This is why every class name in self_hosted/ast.jou starts with Ast, for example.

Static/private functions would help too, because you can have multiple static functions with the same name in different files: #84

Moosems commented 9 months ago

@Akuli And if I import a library with a random function substitute that I don't want nor did I know it existed and have another file I need to import that has a function of the same name? I do think there should be some way to differentiate the two.

Akuli commented 9 months ago

Private functions (#84) will solve this for the most part. You can still have two private functions with the same name.

Any reasonable C or Jou library does not have a public function named substitute. Public functions tend to be prefixed with the name of the library.

For example, the Jou compiler uses LLVM's C api, and its functions are named starting with LLVM, e.g. LLVMVerifyModule or LLVMGetSourceFileName. Similarly, Python's functions are prefixed with Py (Python is implemented in C).

Jou could automatically add a prefix, e.g. def foo() in file bar.jou would create a function named bar_foo. This is basically what languages like C++ do. But once again, I don't want to add more magic to Jou.