Repository: gleam-lang/gleam

Issue #1267: Raise a compile error if a module would have the same name as an existing Erlang module
Created: 2021-09-14T18:27:53Z
Heyo,
So I was playing around with some of the erlang file functions, and I noticed some interesting behaviour when it came to naming my file file.gleam.
When importing a module that  has the same name as the erlang module that is being referenced in external function declarations, the resulting erlang call ends up failing with exception error: undefined function file:open_file/2.
Here is an example, I have file.gleam as follows:
import gleam/erlang/charlist.{Charlist}

pub external type Reason

pub external type IODevice

pub external fn read_file(String) -> Result(String, Reason) =
  "file" "read_file"

pub type FileMode {
  Write
}

pub external fn open_file(String, FileMode) -> Result(IODevice, Reason) =
  "file" "open"

pub type WriteResult {
  Ok
  Error(Reason)
}

pub external fn write_file(IODevice, Charlist) -> WriteResult =
  "file" "write"
which compiles to the following erlang:
-module(file).
-compile(no_auto_import).

-export([read_file/1, open_file/2, write_file/2]).
-export_type([reason/0, io_device/0, file_mode/0, write_result/0]).

-type reason() :: any().

-type io_device() :: any().

-type file_mode() :: write.

-type write_result() :: ok | {error, reason()}.

-spec read_file(binary()) -> {ok, binary()} | {error, reason()}.
read_file(A) ->
    file:read_file(A).

-spec open_file(binary(), file_mode()) -> {ok, io_device()} | {error, reason()}.
open_file(A, B) ->
    file:open(A, B).

-spec write_file(io_device(), gleam@erlang@charlist:charlist()) -> write_result().
write_file(A, B) ->
    file:write(A, B).

and within an escript example.gleam I have:
import file

pub external type CharList

pub fn main(_args: List(CharList)) {
  file.open_file("test.txt", file.Write)
}
The result being:
escript: exception error: undefined function file:open_file/2
  in function  escript:run/2 (escript.erl, line 750)
  in call from escript:start/1 (escript.erl, line 277)
  in call from init:start_em/1 
  in call from init:do_boot/3 

Now the interesting bit is when i modify the escript example.gleam to be:
import file.{Write, open_file}

pub external type CharList

pub fn main(_args: List(CharList)) {
  open_file("test.txt", Write)
}
this works perfectly fine because the compiler circumvents the use of the custom open_file by inlining the call to open_file to be:
file:open(<<"test.txt"/utf8>>, write).

Duplicate issue #1896: Prohibit compilation if there is a .gleam file and a .erl file with the same file/module name
Created: 2022-12-15T00:10:02Z
in src/gleamish_extlib.gleam, I had:
import gleam/io

pub fn main() {
  io.println("Welcome to a Gleamish ExtLib!")
  io.println(
    "Notice: This package is meant to be used only as library and not a stand-alone application.",
  )
}
as well as a gleamish_extlib.erl with -module(gleamish_extlib). and gleam test --target javascript worked but gleam test --target erlang failed and I didn't know why until I transferred one by one files from the current to an empty new project.

Closing comment (2024-07-22T19:10:06Z): Closing as duplicate of #1267