masak / alma

ALgoloid with MAcros -- a language with Algol-family syntax where macros take center stage
Artistic License 2.0
137 stars 14 forks source link

Implement the 'once' block macro #327

Open masak opened 6 years ago

masak commented 6 years ago

From https://github.com/masak/007/issues/313#issuecomment-401594975:

Guess we need to write once as a macro. I'm not currently clever enough to realize whether we have the primitives available to express once as a macro in 007, or whether once itself needs to be such a primitive.

I think it can be done in pure 007. Funnily enough, we'll need another hidden COMPILING:: variable to express it:

@parsed(/ "once" >> <G.block> /)
macro term:<once>(block) {
    my initialized = new Symbol("initialized");
    return quasi {
        my COMPILING::{{{initialized}}};
        if !COMPILING::{{{initialized}}} {
            {{{Q::Block @ block}}}
            COMPILING::{{{initialized}}} = True;
        }
    };
}
masak commented 5 months ago

Rust has a "once cell" crate. Food for inspiration.

All of a sudden I'm also reminded of Josh Bloch's insistance that the singleton pattern should be implemented using enums. This has something to do with the built-in guarantees provided by the Java Virtual Machine itself during initialization.