Re: Time::Local -- and lexical scope

2005-07-05 Thread Dave Whipp

Dave Whipp wrote:

You can use {time - $epoch} or {time.as%d} or {int time}. (That 
last one is not {+time}, because that would be a floating-point value, 
not an integer).


I was thinking: an epoch is just a time, and int time is a duration -- 
the number of seconds since the current epoch. So, the following should 
work:


for 1 .. 2 - {
   use epoch time();
   sleep 6;
   say int time;
}

This should print something close to 6, twice.

But something niggled me: does the value of the RHS of a use get 
evaluated at run time, or compile time? In perl5, that could definitely 
would only execute the Cuse once.


I could see 3 possible behaviors:

1. Cuse sets the epoch for each iteration of the loop, thus calling 
time() one per iteration


2. Cuse executes just once, at compile time. Thus seconds iteration 
prints approximately 12


3. Cuse does a compile-time binding of the epoch to the time() 
function. So each iteration prints 0.



Which actually happens?


Re: Time::Local -- and lexical scope

2005-07-05 Thread Larry Wall
On Tue, Jul 05, 2005 at 03:48:47PM -0700, Dave Whipp wrote:
: Dave Whipp wrote:
: 
: You can use {time - $epoch} or {time.as%d} or {int time}. (That 
: last one is not {+time}, because that would be a floating-point value, 
: not an integer).

Or {time.int}, presumably.

: I was thinking: an epoch is just a time, and int time is a duration -- 
: the number of seconds since the current epoch. So, the following should 
: work:
: 
: for 1 .. 2 - {
:use epoch time();
:sleep 6;
:say int time;
: }
: 
: This should print something close to 6, twice.
: 
: But something niggled me: does the value of the RHS of a use get 
: evaluated at run time, or compile time? In perl5, that could definitely 
: would only execute the Cuse once.

I would not necessarily assume that use is the best interface for
setting what is essentially a lexically scoped variable.

: I could see 3 possible behaviors:
: 
: 1. Cuse sets the epoch for each iteration of the loop, thus calling 
: time() one per iteration

The pragma could arrange to install something in the runtime code
at that point, but it would take extraordinary measures and be
completely unexpected.

: 2. Cuse executes just once, at compile time. Thus seconds iteration 
: prints approximately 12

Or much more than that, given separate compilation.

: 3. Cuse does a compile-time binding of the epoch to the time() 
: function. So each iteration prints 0.

: Which actually happens?

Am I allowed to vote for none of the above?  :-)

Actually what should happen is most like 2, I suspect.

Coming at it from a different angle, I'm thinking we should try to
get rid of built-in none-ary functions like time anyway, and parse them
to expect an argument, on the assumption that this will simplify
MMD.  (In fact, that's a good reason to get rid of the entire
named unary precedence level and treat them all as list operators
for parsing purposes.)  So if we're allowing an optional argument
to time(), then it makes sense to allow time($epoch), where time
can default to a particular epoch, or even to the epoch defined in
the caller's lexical scope.  I'd like time(2000) to be the standard
default, but time(1958) shouldn't be too hard to arrange.

We could set that default pragmatically, but pragmatically speaking,
we should just set the epoch as a lexical variable that is visible
to the default value for the parameter.  Then the caller can
even do something like:

temp $_epoch_ = 1970;

$x = time();# sub time (?$epoch = $CALLER::_epoch_)

I'm not suggesting that's the proper name for the lexical variable.
In fact, we haven't got any convention for forced-lexicals in Perl
6 yet, other than, $_ and $/ are two examples of them, and $?FOO is
a compile-time lexical, and $=FOO is file-scoped in some fashion.
At one point I was thinking $*FOO would let the variable itself
decide if it was lexical or global, on the assumption that $_ is just
short for $*_.  But maybe that's a Bad Idea.  How do we decide which
variables are forced lexicals?  More specifically, how to we request
the compiler to force other variables to be lexical, and poke them
into our lexical pads automatically for us?  I think the epoch is
one of those, however we spell it.  Then different modules can run
with different epochs, as long as all absolute times are passed
as objects.

Larry