On Wed, 31 Jul 2024, at 19:20, Elizabeth Mattijsen wrote:
>> On 31 Jul 2024, at 06:10, Kevin Pye <kjpr...@pye.id.au> wrote:
>> 
>> I am trying to build a replacement for the existing Physics::Constants 
>> module, but running into problems when loading the pre-compiled version. I 
>> want to use code like:
>> 
>> unit module Physics::Constants;
>> 
>> use Physics::Unit;
>> use Physics::Measure;
>> 
>> constant \avogadro-constant is export(:DEFAULT, :fundamental, 
>> :avogadro-constant) = Measure.new(
>>   value => 6.02214076e+23, 
>>   error => 0, 
>>   units => 'mol⁻¹',
>> );
>> 
>> which compiles and runs quite well. However, when I try to run "mi6 test" 
>> which will precompile and then load the code, I get the following output:
>> 
>> $ mi6 test
>> ===SORRY!=== Error while compiling 
>> /home/kevin/git/Physics-Constants/t/01-basic.rakutest
>> ===SORRY!=== Error while compiling 
>> /home/kevin/git/Physics-Constants/lib/Physics/Constants.rakumod 
>> (Physics::Constants)
>> An exception X::Comp::AdHoc occurred while evaluating a constant:
>> Cannot unbox a P6opaque (NQPMu) type object
>> at /home/kevin/git/Physics-Constants/lib/Physics/Constants.rakumod 
>> (Physics::Constants):6
>> Exception details:
>>   ===SORRY!=== Error while compiling 
>>   Cannot unbox a P6opaque (NQPMu) type object
>>   at line 
>> 
>> at .../Physics-Constants/t/01-basic.rakutest:2
>> t/01-basic.rakutest .. Dubious, test returned 1
>> No subtests run
>> 
>> I am guessing that it can't deserialize the serialized Physics::Measure 
>> object, but I could be quite wrong.
>
> This appears to be an issue with resolving somewhere deep in the 
> bowels.  In RakuAST, the error is slightly more clear:
>
> ===SORRY!===
> Cannot look up attributes in a RakuAST::Resolver type object. Did you 
> forget a '.new'?
>
> I'm pretty sure we won't fix this in the legacy grammar.  I'll be 
> looking at fixing this in RakuAST.  Meanwhile, I would also suggest 
> making this an issue in the Physics::Measure repo 
> https://github.com/librasteve/raku-Physics-Measure so that the author 
> is alerted to this problem, and maybe can figure out what tickles it.

The Physics::Measure author is already aware of the issue.

>
>
>> Any ideas on how to make this work?
>
> Put this in lib/Physics/Constants.rakumod:
> =====================
> use Physics::Unit;
> use Physics::Measure;
>
> my $avogadro-constant := Measure.new(
>   value => 6.02214076e+23,
>   error => 0,
>   units => 'mol⁻¹',
> );
>
> sub EXPORT {
>     Map.new: (:$avogadro-constant)  # must have () to force positional Pair
> }
> =====================
>
> And then run:
>
> $ raku -Ilib -MConstants -e 'say avogadro-constant'
> 6.02214076e+23mol⁻¹ ±0
>
> In other words: drop the module statement.  The namespace *from* which 
> you export constants, is usually not important.  And use an EXPORT sub 
> (https://docs.raku.org/syntax/sub%20EXPORT) to export whatever values 
> that were created when the mainline of the module runs.
>
> Disadvantages to this approach:
> - you lose the standard capability to selective importing
> - the constants are created at module load time, and not serialized

Unfortunately that won't help much in this case. There are over 300 constants 
planned to be included. Using a separate EXPORT sub decouples the definitions 
and export declarations too much, selective importing will be very useful to 
avoid polluting the namespace of code using the module, and creating hundreds 
of Physics::Measure objects at load time will be simply much too slow. (You 
might get away with it with selective importing and only creating a relatively 
few objects, but without that...)

We'll keep looking at other ways of defining the objects, but thanks anyway. 
(And sorry for increasing the RakuAST work needed.)

Kevin.

Reply via email to