This is becoming a recurring pattern among new languages I’m noticing. For example, a use blah;
will first look for a child module of ‘this’ module with the name blah
, it’s the same as use self::blah;
if you want to force it without any other lookups, if that doesn’t exist then it looks for a linked in library named blah
and uses that. You also have super::blah
to refer to a sibling blah
module or a crate::blah
to refer to your library root with a main module named blah
(with of course being able to double-colon index in to them like use crate::blah::blorp::{a_func, AStruct, another_module::*};
or whatever. When looking for a given module like blorp
that can be defined in the same module’s file like mod blah { ... }
, or it can be a blah.rs
file adjacent to the current file, or it can be a blah/mod.rs
(the full form, needed when it can have other child modules), it’s consistent at least but definitely not the C/C++ way, lol.
The mixin thing sounds like the difference between open
and include
in OCaml/ReasonML as well.
How does Crystal handle logging? I’m not actually a fan of Elixir’s way. I like how Rust does it, which is to just supply a set of extremely efficient log calls with the usual ‘levels’ of either a log
or tracing
crates style (log
is simple text messages, tracing
can be data, but you can delegate it to a log
handler), and you can have a whole multitude of different libraries actually do the handling of the logging of whatever style that you want, like env_logger
is one of the most simple, configured by environment variables on startup. I like to use log4rs
, which is familiar to me of a java’ish style logger system, very configurable and pluggable. Regardless of the logger any program works with them all, not just a single hardcoded set like elixir has for example.