From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id cNGxB5BzBWbZLQAAe85BDQ:P1 (envelope-from ) for ; Thu, 28 Mar 2024 14:41:36 +0100 Received: from aspmx1.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id cNGxB5BzBWbZLQAAe85BDQ (envelope-from ) for ; Thu, 28 Mar 2024 14:41:36 +0100 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; none Received: from mail-a.sr.ht (mail-a.sr.ht [46.23.81.152]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 14CE423511 for ; Thu, 28 Mar 2024 14:41:36 +0100 (CET) DKIM-Signature: a=rsa-sha256; bh=7EF5X3dKn/f8LdcYEdFDKtu9qpqyPF1L845+8I221DE=; c=simple/simple; d=lists.sr.ht; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Unsubscribe:List-Subscribe:List-Archive:List-Post:List-ID; q=dns/txt; s=20240113; t=1711633295; v=1; b=OkPiNWqbcGwq6sYPzOxHKTXCcOo3yvgcn7aQtTjGty9Bfg/qnh/9JZyUAOqbZUSA88LUZ/uI Q+3j0OKqjWQF6VkAT9OyRgcYic1Z/ysDINiLQihRPjLDUdK4HWKQ+fgSZqUoEjfGoh5mWWc1Ul4 kAKmEASgGlpBe2PqFDqcVron/2VqIpZIxvr/EYzvWGeSSMVleYWNxjYVrqSMqHeTtYppY1bR+oL t/cia8qHLSyInQUjrwHTEKlh8P50SVTTGBp2W9UtMc6euVhw5aEEg1VBmmwmi0erd5LbcQkTFgO QilH2jqvB8hDwUb2Ftt5SpdyRQa7dRMoQquVHOB60FRNQ== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id B4142202A9 for ; Thu, 28 Mar 2024 13:41:35 +0000 (UTC) Received: from quail.birch.relay.mailchannels.net (quail.birch.relay.mailchannels.net [23.83.209.151]) by mail-a.sr.ht (Postfix) with ESMTPS id 930CE2029C for <~johnnyrichard/olang-devel@lists.sr.ht>; Thu, 28 Mar 2024 13:41:34 +0000 (UTC) X-Sender-Id: hostingeremail|x-authuser|carlos@maniero.me Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 9648380366E for <~johnnyrichard/olang-devel@lists.sr.ht>; Thu, 28 Mar 2024 13:41:31 +0000 (UTC) Received: from fr-int-smtpout1.hostinger.io (unknown [127.0.0.6]) (Authenticated sender: hostingeremail) by relay.mailchannels.net (Postfix) with ESMTPA id 8CC9D80361E for <~johnnyrichard/olang-devel@lists.sr.ht>; Thu, 28 Mar 2024 13:41:30 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1711633291; a=rsa-sha256; cv=none; b=pjDZXH6qChbUiZLJblj0nU4/jEl/2iJYK6YtJJ6HA5KY0GYV2c/TLKiiaxaLkdutwww2Dn yUaZ0evZWmjSPy112ENAF8seJvTPY3ghcut9O/wLQoRfzAta+KPnaFBKY09qDOzTIN3cM5 L+A1+qrzLe+rSJYS7qVX8Yh/tqiSdORKb8V8SXZNjYY1JyeuMXbU53xTi7JWv8xLQG1PAi YushsAbY/bY7l4VBm47sthVfjYIGRz6ADuKpu91nGsPIpMTUHTw0XAzllKR0JT0L7UAr9m shwxfYNg/m5D3mPMc127KV2g53uJFhJkBXDA41nUh3lmXoest4sN/xURmOuYGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1711633291; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=APEX1dGTTKn6XjhBnimM+knbR9Ok22Nps/iUfggDTq0=; b=gezpEhUCCo04nBbtkmY913c4Mn7rLSWOL4Pf3uMwndwIiCcNzgSgWmMzBeJuOy1Cd5SkvJ ieJNdWKafUXBRNHr7dJtbUjACLqHAaEuwRg4XwdfKovSM/sTlvboUII0RbcocThjgZ5i59 q8FqncgNDIOUh0sZUS/Rv+yqegTdrPS8mw0r2MgofhwUlRFVhDu0qUOFrXBN8PwE8WUIp8 +Vdmip96RTMUalAOoEPSh1lafGd+2Qbdl46xOOOenvAAxjsoU+67XHsZAlAsU2NcaWFCx9 dgSFttF2AXgS39yedcxz9Dc+Zgb08atLYoCCVdjFIe3aw84RfXHaYTQKArWyvg== ARC-Authentication-Results: i=1; rspamd-699949c56f-5hn5v; auth=pass smtp.auth=hostingeremail smtp.mailfrom=carlos@maniero.me X-Sender-Id: hostingeremail|x-authuser|carlos@maniero.me X-MC-Relay: Neutral X-MailChannels-SenderId: hostingeremail|x-authuser|carlos@maniero.me X-MailChannels-Auth-Id: hostingeremail X-Bubble-Inform: 1a311ca00597af2f_1711633291280_1366955776 X-MC-Loop-Signature: 1711633291280:2543323069 X-MC-Ingress-Time: 1711633291280 Received: from fr-int-smtpout1.hostinger.io (fr-int-smtpout1.hostinger.io [89.116.146.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.118.191.224 (trex/6.9.2); Thu, 28 Mar 2024 13:41:31 +0000 Mime-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maniero.me; s=hostingermail1; t=1711633286; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=APEX1dGTTKn6XjhBnimM+knbR9Ok22Nps/iUfggDTq0=; b=oQOwXDxcgAR6tKXIF7jCk1LjxeKJthV0hcQIvDkwDqj1YISxLlMu1ysAOlqARLoFqBU0b2 D69L/9kj4lmmAfE9Xt5WTUvTVJDKOoMfbf4CM08+OG8r3nqrqnngyH5IuJmttR24M7db6Z iiUiqMctmIvp6eIoMow1zaDWTWhziV6Jh0sYOk1p4ib84fHcR6B0UTUSwzoYdRvc52gJZK 17r5R7aXp/0/uSH5n5GQJdqxyjzZ4diKVXB4sijLQiNF7KgmqLWMnZgmiiu4IDGa47kYeQ YqheeG5ZH8SKDJbF+6+i2gJsmkazzVrZA2t8gN/hbe4RXtQhzFBPP/bmuuwVIA== Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Thu, 28 Mar 2024 10:41:20 -0300 Message-Id: From: "Carlos Maniero" To: "Johnny Richard" Cc: <~johnnyrichard/olang-devel@lists.sr.ht> Subject: Re: [RFC] Namespaces in OLANG X-Mailer: aerc 0.15.2-211-g37d5fc691aff References: In-Reply-To: X-CM-Analysis: v=2.4 cv=OPEh3zaB c=1 sm=1 tr=0 ts=66057385 a=WwxFCuf3mf1fs3oSi6/dng==:117 a=WwxFCuf3mf1fs3oSi6/dng==:17 a=IkcTkHD0fZMA:10 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=NEAV23lmAAAA:8 a=Mj5dn38bQ9FH6FwPlTMA:9 a=QEXdDO2ut3YA:10 a=BXDaF_L80NY05PYiAFlV:22 X-CM-Envelope: MS4xfEOAGz2JLwYogOmEkB0BhWH1MPC4vga4ZIHnLi77vni3c098rumltm+g7qm558+PBV/hHV0WKEZMpl0Ol5ZisFqVLBNoy/ST/Sb3UYkjch5osSFwbQQe JfMHogb78/soCTGgmSj+TvQmPIklNj3mD0qF8d8fVWhF8ZjCEKQFd2jJQCRpCY1ghoyn028UvZy5D75jkGWOHsFHuu3m4iXNolfBQzNlLVZkCdGtH03qg5Ta VUiqlV1fm8b2115PnD9PWg== X-AuthUser: carlos@maniero.me List-Unsubscribe: List-Subscribe: List-Archive: Archived-At: List-Post: List-ID: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel.lists.sr.ht> Sender: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel@lists.sr.ht> X-Migadu-Country: NL X-Migadu-Flow: FLOW_IN X-Migadu-Queue-Id: 14CE423511 X-Spam-Score: -4.00 X-Migadu-Spam-Score: -4.00 X-Migadu-Scanner: mx10.migadu.com X-TUID: IzLPIyc7uJbV > Thank you very much for providing this insightful reading material. > > However, if you're confident in the direction proposed, I > won't obstruct progress. I believe it's crucial that we take the necessary time to thoroughly define the right approach. No need to rush this process. I just wanna make sure we can clearly outline the direction we want for olang in a user experience perspective. By discussing these subject I believe we can clearly write the goal of the language that yet is still subjective. > > 2. Full Compatibility with C: > >=20 > > It is completely compatible with C! > >=20 > > int olang_core_math__add(int, int); > >=20 > > If you think it is ugly to call a function that way directly, you ca= n create > > macros in C to improve the readability, but completely optional. > >=20 > > #define NSMATH(name) olang_core_math__##name > > I think this is too ugly and very hack. I would prefer to call > olang_core_math_add instead. You quoted the entire text (which I truncated), do you mean the macro is hacky? Or everything? The macro is just a suggestion. You mentioned that you would prefer to use *olang_core_math_add*. Did you mean *olang_core_math__add*, or are you opposed to the use of double underscores to separate the namespace from the identifier? > > 3. Manual namespacing is inconvenient:=20 > >=20 > > You don't need to manually namespace every function with the cost of= start > > every single file with a *ns* statement. > > If we keep managing names manually, we already have the *1* and *2* for > free. So, the only benefit of namespacing would be to avoid the > inconvenience of adding it manually. That's partially correct. I mentioned points 1 and 2 because most modern system languages, such as C++ and Rust, mangle names to avoid conflicts. However, I made a mistake by not including this solution in the Alternatives section. > > An important observation of the *ns* usage is that it must match the di= rectory > > structure. The path of a file that declares the namespace *olang.core.m= ath* > > must ends with *olang/core/math.ol*. This requirement is need for futur= e > > import resolution. > >=20 > > Alternatives: > > ------------- > >=20 > > 1. Automatically create namespaces based on the filename: > > I know we don't have written down nicely the goal of the language, but I > prefer being explicit and avoid convention over configuration. Agree! That's why namespaced files are great \o/ > > 2. Manual namespaces: ... > >=20 > > Conclusion > > ---------- > >=20 > > In my opinion, the introduction of a namespace statement offers numerou= s > > benefits: > >=20 > > - It aids in resolving function name conflicts. > > - It facilitates deterministic code generation while maintaining compat= ibility > > with C. > > The current suggestion doesn't solve the all compatibility with C. We > have to provide a way of calling a C function from olang code without > namespacing (in case of namespace being mandatory). Good catch! In my opinion, we should follow C's approach on this matter. extern fn pow(base: u32, power: u32) In this case, the extern identifier matches exactly with the assembly symbol. Please note that the extern statement is merely a semantic tool; it does not generate any code. Do you think that namespaces translation in between C and olang are necessary? In our arena implementation, all functions have the *arena_* prefix. By using *extern* the way I'm proposing we will call these functions in olang with their exactly name, ie, *arena_alloc* will be called using *arena_alloc* not just *alloc*. IMO, it is ok since it is an external. Do you think that translating namespaces between C and olang is necessary? In our arena implementation, all functions have the *arena_* prefix. By using *extern* in the way I'm proposing, we will call these functions in olang by their exact names. For instance, *arena_alloc* will be invoked as *arena_alloc*, not just *alloc*. In my opinion, this is acceptable since it is an external function. > > - It simplifies the resolution of imports. > > I would suggest to not go much further with import resolution (unless > you already want to define modules). Perhaps we could have namespace > doing nothing else than namespacing... > If by "modules" you are referring to the file level, and not to something like packages or libraries, then that is exactly what I want to define! Influenced by Clojure, I recommended calling it a "namespace". However, I believe that naming it =E2=80=98mod' or =E2=80=98mo= dule' is more suitable for its purpose. mod olang.core.math fn add(a: u32, b: u32) { return a + b } > > These advantages come with the minor stipulation of initiating all file= s with a > > namespace statement, which, in my view, is a small price to pay for the > > benefits gained. > > I'm not keen on the idea of enforcing strict adherence to the folder > structure. > > How about we introduce a namespace block instead? Within this > block, everything would automatically have the namespace added as a > prefix. This could offer more flexibility while still maintaining > organization. Don't you think that in practice almost every single file will namespace? C++ follows this pattern, and look at this Qt mirror [1], 6k files, all namespaced, they even created a macro to facilitate the work. [1] https://github.com/search?q=3Drepo%3Aradekp%2Fqt+%2FQT_BEGIN_NAMESPACE%= 5Cn%2F&type=3Dcode&p=3D1 > I think module has a different meaning. If you want to have modules, > for sure we have to discuss import resolution. IMHO namespace shouldn't > do anything else than namespacing. I believe you're right. It's almost impossible to discuss modules without bringing up imports. To me, the way C handles this is one of the most painful things in my life (hehe). The main issue is that I never know where something is coming from, which is especially painful when I'm trying to replicate something I've already done. This also, often leads to unused includes over time because it's hard to determine if an include is actually being used. If we abandon modules and just go with C++-like namespaces, I believe we we may want to endure C's painful include system. This is because the language won't have control over function names. The way the include system is designed sends a message to developers that including a file is akin to concatenating all the definitions into a single file. But yet I think it would be ok to have names imports even if we don't control the language names but it would be just a semantic tool. Named Imports ------------- mod myprog import olang.core.math fn main(): u32 { return olang.core.math::sum(1, 2) } And even associate identifiers to it. mod myprog import olang.core.math as ocm fn main(): u32 { return ocm::sum(1, 2) } Note that there is no actually difference in between mangling and my module purpose, except the fact modules generates deterministic and friendly names that can be easily used in C and also easy to gen code, once to generate the assembly symbol of *olang.core.math::sum* we can just replace dots by underscores and double column to double underscores. External Linkage ---------------- We probably don't wanna to make all function global for external linkage. So we may need a visibility keyword. And to me, everything that can be imported should also be available for external linkage, even if we decide to do not generate an object file per module. I would recommend the usage of *export* or *pub*. I like *export* better. Note that this is required no meter how we decide to handle imports. No mangling ----------- But what if I really need something to have the exact name? Lets say you wanna integrate with a bootloader that is integrated on the link process an= d expects a symbol called *kmain* to jump into? Ok, I admit, in that case namespaces it is gonna be a pain in the ass. But the good news is that these are exceptional, you don't need this for your entire application but only for a few functions. I was wondering that we could have a *global* keyword where everything that is global assumes its own name and is always have public visibility. mod myprog import olang.core.math as ocm global fn main(): u32 { return ocm::sum(1, 2) } If we decided that we wanna both for the language *mod* and *ns* we could even have a global ns. mod myprog import olang.core.math as ocm ns global { fn main(): u32 { return ocm::sum(1, 2) } } Summarizing ----------- We have a few options in the table. 1. Use the names the way they are. (C approach) Pros: - Simple, no magic, it is what it is. - Easy to produce debug info since the assembly symbol will be the function name. Cons: - More challenge to keep the code out of name conflicts in large codebases. - Requires developers to manually namespace functions. 2. Use mangled names (C++, Rust approach) Pros: - Keep the code out of naming conflicts Cons: - Non deterministic names - Since the function name is usually non deterministic, you are required to use a no-mangle statement to integrate with C. - More debug info is required. 3. Use modules (Zig approach (I think)) Pros: - Keep the code out of naming conflicts - Deterministic assembly symbols permit integrate with C without any magic, you just need to follow the convention ns__fn. Cons: - If you really need to have a specific name for your function you gonna need a no-mangle approach. - More debug info is required. - It is not entirely free of name conflicts, you can force a conflict by create function that starts with double underscores which is not recommended by C, since these names are reserved. I haven't talked too much about zig, but here goes a fun fact, zig uses dot in their names which solves the conflict name I described above once you cannot create an identifier that contains a dot, but it also makes non viable the C integration without an ABI.