develooper Front page | perl.perl6.users | Postings from August 2022

Re: BEGIN {} question

Thread Previous | Thread Next
From:
Richard Hainsworth
Date:
August 30, 2022 20:34
Subject:
Re: BEGIN {} question
Message ID:
369440cb-3a66-7686-c34d-014760bf20b9@gmail.com
Hi Todd,

Long time no see.

Re your 'keeper'. There is a reason why things are called the way they 
are in Raku (aka Perl6). BEGIN is NOT a special subroutine.

BEGIN is a phaser. And it introduces a block. Blocks are not subroutines 
(subs). Even though blocks and subs (and methods and callables) are code 
related things, a sub can take a signature, but a block cannot. You can 
pass arguments to a block using pointy syntax, eg -> $x, %y {  ... }, 
which is why it is possible to do things like 'for %some-hash.kv -> 
$key, $value { .... }'. The 'for' takes a block, which can be pointy. 
'for' does not take a special subroutine.

But a sub can have a parameter list, eg., 'sub (Int $b where *>= 10) { 
say %b }; ' The 'where' bit means that the compiler will put in checks 
that $b is always greater-equal to 10. So subs are far far more than blocks.

Also you cannot return from a block, but you can return from a sub.

So, by putting in your keeper that BEGIN is a special subroutine, you 
are ignoring a whole world of Raku goodness, as well as making it 
difficult for yourself to understand other phasers.

And talking of phasers, there are some really useful ones, like FIRST 
and LAST, that are in loops. So if you want something to happen first 
time in a loop, put it in FIRST { }.

Also I see you are on the compile time whine again. When perl6 first 
became available as 'pugs', it did take FOREVER. Then as more of perl6 
became implemented as rakudo, startup times became slower.

Things changed when modules were precompiled. I really do not understand 
what you are talking about when you say you don't think precompile is 
useful everywhere.

For example, when I write something that is called from the command line 
(for example in my raku-collection-raku-documentation distribution), I 
have a one-liner raku program 'RakuDoc' that just says 'use 
Collection::RakuDoc'.

EVERYTHING else is in the module Collection::RakuDoc, all the MAIN 
subroutines, and stuff. That then only gets compiled once. So, the first 
time RakuDoc is called from the command line, there is a startup delay 
because the whole module is compiled. Every other time RakuDoc is 
called, its really so fast I don't notice a problem. Only the *one* line 
is compiled each time the program is called. All the rest is in 
precompiled form.

Same with my Extractor program, which is in the raku-extraction module. 
This is a GUI program that takes the rakudoc (aka POD6) files and 
converts them into markdown. For example, I write the README's for my 
github repos as README.rakudoc, then use Extractor to turn it into a 
README.md. The result is far better because the rakudoc renderer I use 
(from my pod-render distribution) automatically collects all the headers 
and puts them into a Table of Contents. If you've tried to do a TOC in 
markdown, you know what a hassle it is.

But Extractor is a GTK::Simple program. And GTK::Simple takes forever to 
precompile. But once done, I don't notice any startup time.

And I change my software quite a lot, so every time I change something, 
yes, startup is slow the first time, but not the next time. Surely, you 
use a piece of software more than once.

Compared to the OLD days, rakudo programs react like lightning. Design 
your software properly, and you wont - as a human - notice much of a delay.

I think the startup complaint (not the compile time for something) has 
been effectively relegated to the days when rakudo was young. So whilst 
in the past I truly sympathised with your rants about compile times, I 
am now quite confused and I find sympathy hard to come by.

Since you continue for ever to complain about 'compile' time issues, 
rather than startup times, I wonder whether the programs you write are 
massive monolithic lines of code with thousands of lines, much like most 
standard software when FORTRAN or COBOL were the high level languages, 
or whether you design things to make each section more manageable.

If the programs you write to be run from the command line are thousands 
of lines long, then yes!! you will suffer!!! from long!!!! startup times 
because the program is re-compiled EVERY time. However, if you redesign 
the code, putting things into classes, roles, subroutines, and Raku-y 
goody things, you can push stuff into modules, and reduce your calling 
program to a single line.

When you change your software, do you change every part of it every 
time? Or do you change some client related interface part? Put the 
interface part into one module, and the other more stable functionality 
into other modules. Then when you change the interface part, you dont 
change the other modules. They have already been compiled. So the first 
time you start up your program, only the section you have changed gets 
recompiled, not the entire monolith.

By the way, I assume that you understand the Raku meaning of 'module', 
as opposed to a 'distribution'. When I write a large piece of software, 
I may have three or four different modules under the lib/ directory. The 
top level program (I try to make it one line only), uses one module, 
which then may use other modules, all of them in the same directory, 
under the lib/ subdirectory. The distribution can then also contain 
simple tests under t/ and development tests under xt/

Regards,

Richard

On 30/08/2022 2:38 am, ToddAndMargo via perl6-users wrote:
> On 8/28/22 15:58, ToddAndMargo via perl6-users wrote:
>> Hi All,
>>
>> I am thinking of using
>>
>>     BEGIN {}
>>
>> to fire up a splash screen (libnotify).
>>
>> Question: is what happens between the brackets
>> isolated from the rest of the code?   If I set
>> variable values or declare variables, are they
>> wiped out, etc.?
>>
>> Many thanks,
>> -T
>>
>>
>
>
>
> My keeper on BEGIN.  That you for all the help
> and tips!
>
>
>
> Perl6: BEGIN {}
>
>
> BEGIN is a special subroutine that runs at compile time.
> It will see any code above it, such as variables and
> imported modules, but not below it.
>
> The idea is to run something at the start of compile before
> the rest of compile completes.  A splash screen for example.
>
> Perl 6's compile can take a very long time and users may not
> realize it started and restart it several times.
>
> Note that a space is required between `BEGIN and the `{}`
>
>
> BEGIN {
>    # Splash Screen
>
>  ( my $ProgramName   = $?FILE ) ~~ s|.*"/"||;
>    my Str $NotifyStr = "\nStarting $ProgramName\n";
>    my Str $Icon      = "/home/linuxutil/Images/Info.png";
>    my Str $Title     = "$ProgramName Splash Screen";
>    my Str $Timeout   = "8";       # zenity = seconds
>
>    # Note: zenity seems to not detach when run without a shell
>    shell "zenity --info --title \"$Title\" --text \"$NotifyStr\" 
> --width=220 --timeout=$Timeout &";
> }
>

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About