Open xialvjun opened 1 year ago
@daanx Hope you fix this before it's too late.
Surely a better way to fix this is just to have the code explicitly set the scope of public/private? For example in Cargo you can do pub(crate)
to restrict access to that crate.
Don't forget the enormous benefits that come from using path based imports:
You can see the kind of disaster that you end up with if the import system gets too "magical" in Python.
I don't know why "no path based imports" may be a disaster.
Things should be simple. We can access:
sibling
sibling's public children
sibling's public children's public children...
ancestor
ancestor's public children
ancestor's public children's public children...
ancestor's sibling
ancestor's sibling's public children
ancestor's sibling's public children's public children
or short version
sibling
ancestor
ancestor's sibling
and use dot operator to access the public children of everything you can access
So, an example:
pac: package
pri: private - default
pub: public
use: we can access these things here
pac A
pri B
pri C
use C, B, B.D, A, A.E, A.E.G, D (ie C,B,A,D and their recursive pubic children)
pub D
use D, B, B.D, A, A.E, A.E.G, C (ie D,B,A,C and their recursive pubic children)
use C, D, B, B.D, A, A.E, A.E.G (ie C,D,B,A and their recursive pubic children)
pub E
pri F
use F, E, E.G, A, A.E, A.E.G, G (ie F,E,A,G and their recursive pubic children)
pub G
use G, E, E.G, A, A.E, A.E.G, F (ie G,E,A,F and their recursive pubic children)
use F, G, E, E.G, A, A.E, A.E.G (ie F,G,E,A and their recursive pubic children)
use B, B.D, E, E.G, A, A.E, A.E.G (ie B,E,A and their recursive pubic children)
It seems use
and mod
is just sugar of const
, and dependency list is just top module
// Cargo.toml
[dependency]
tokio=0.1.0
hyper=0.2.0
// In src/main.rs
// dependency list is just top module, it's just like put the content of the crate in src/main.rs
mod tokio {
// tokio's content
}
mod hyper {xxx}
pub fn main() {}
use hyper::http;
// is the same as
const {http} = hyper;
// if you want to define a module with the same name of one of your dependency list, just shadow the name
const real_tokio = tokio;
mod tokio { xxx };
// module can shadow the name, so it's just like const. mod is just a sugar
mod abc { pub fn a() {} }
const abc = { fn a() {}; { a } }
// even we define some compile time items like type in module, because const is also compile time
mod abc { pub type a {} }
const abc = { type a {}; { a } }
I guess the request is for something like protected? If you give a Koka file a module declaration by default all of its functions are private unless explicitly marked pub
. This goes for both files relative to the module (inside the library) as well as external users. Are you arguing that without something like protected (package private) we might end up making too many things public?
I don't see what that issue has to do with referring to files by path based imports. If it is private or protected (package private) then it shouldn't matter if you know the path to it, you cannot access the definition. If JavaScript messed that up it doesn't have to be the same for Koka regardless whether Koka uses paths or not.
My question in short: how to declare something public in its library but private out of its library.
Yeah, there is no current mechanism for that in Koka, other than to include the private definitions in the library you want to use them in - though this makes it hard to share across internal files, or use a naming convention that will make it clear to external users not to use it internal-
etc. I'm not sure if Daan has plans for some sort of mechanism like this. If you want users to be able to see a type, but not be able to construct / match on the type you can use the keyword abstract
, which forces them to interact with it via functions you define (since they cannot inspect it at all).
Personally I would go with the naming convention. I'm not a huge fan of protected/private in general. If a user wants to use pieces of your library to create their own library that fits their use case better they have to fork it and try to keep the fork synced and up to date. A naming convention would make it clear to most users which functions are intended for internal use only, and only expert users who understand the internal mechanisms should use. Additionally I would create a top level import mypackage
which includes only the necessary interfaces / functions or pub export
s some other files that contain only the necessary interfaces, and put all the implementation under an internal
or impl
directory. This makes it clear when a user is using internal or implementation details, while encouraging them to use just the single import.
I understand that many people will not feel the same way as me, just putting out my opinion.
Some use case: I have a library like ffmpeg for av processing, and I need some tool functions in it, those tool functions are only used by myself in this library, I won't ensure their api stability, so they shouldn't be exposed to library users.
Well, explicit name internal-
did solve problem, but explicit effect name in function function a_function_use_io() {}
also solve effect type, then why we need algebraic effect.
Mean no offend, I just want to say: we should not trust human consciousness.
EDIT: Sorry, I found explicit name internal-
and explicit effect name in function function a_function_use_io() {}
, they do have differences. We do set explicit item name internal_
, but we didn't set explicit effect name _use_io
. That's the difference. I just imagined a problem which doesn't exist.
@TimWhiting I noticed there at https://github.com/koka-community/html/blob/b59d465bb8813a97e36f7310885a5e8f8ff1b893/html/html.kk#L9-L10
pub import html-builder
pub import core-components
Non-pub artifacts within html/html-builder
and html/core-components
seem to have been publicly re-exported from html/html
, I'd imagine only pub
artifacts get re-exported in this way, is current result a bug or right by design?
Only the pub functions should be re-exported and available. If that is not the case we should create a new issue for this.
not use path based imports is very important.
Node, Deno are running on the wrong way, on the other hand, Carogo/rust do it right.
Why do I emphasize this ? Let's see:
What if we change JS to:
So, JUST MAKE THIS SYNTAX ERROR:
import * as utils from 'ffmpeg/utils';
Well, we can't change JS, but we should do Koka the right way.
Well, it's just like Java's
public protected private
, the last problem is "should it default private or protected". I preferprotected
in Koka.If it's default protected, then
Originally posted by @xialvjun in https://github.com/koka-lang/koka/issues/31#issuecomment-1482200826
reference: https://api-extractor.com/pages/setup/configure_rollup/#:~:text=(The%20API%20Extractor,with%20that%20effort.)