Why shouldn't sleep(0.5) DWIM?
Is there any really good reason why sleep() doesn't work for microseconds? I mean, if I can do this: sub sleep { my($time) = shift; if( /^[+-]?\d+$/ ) { sleep($time); } else { select(undef, undef, undef, $time); } } Why can't Perl? Smells like a C holdover to me. -- Michael G. Schwern [EMAIL PROTECTED]http://www.pobox.com/~schwern/ If you have to shoot, shoot! Don't talk. -- Tuco, "The Good, The Bad And The Ugly"
Re: JWZ on s/Java/Perl/
"Branden" [EMAIL PROTECTED] wrote: Well, mandatory locking is something we should definetly NOT have in Perl6. Most of perl's code today is not threaded, and I believe much of it will continue to be this way. The pseudo-fork thread behaviour that is being proposed also makes this ok. Even if you have threads, you have to say explicitly if you want anythinig to be shared. And if you explicitly share something, then you should care the locks by yourself. Call me lazy, but in my ideal world, if I had some code with multiple iterpreter threads that happened to share some perl variables, then I'd like Perl to take care of any locking needed ensure those variables are assessed in a thread-safe way. IE I let the Perl developers do all the hard locking code behind the scenes, and I don't have to worry my pretty little head about it. Now, there may be practical reasons why it isnt possible for perl to do this for me automatically (reasons, anyone?), but it's a nice ideal. Just MHO ;-) Dave M.
Re: Why shouldn't sleep(0.5) DWIM?
On Tue, Jan 30, 2001 at 04:13:39AM -0500, Michael G Schwern wrote: Is there any really good reason why sleep() doesn't work for microseconds? I mean, if I can do this: sub sleep { my($time) = shift; if( /^[+-]?\d+$/ ) { sleep($time); } else { select(undef, undef, undef, $time); } } Why can't Perl? Smells like a C holdover to me. I guess it's part of the can of sub-second worms: if we do sleep(), people will ask why don't we do time() and alarm(), too. sleep() and alarm() we could get away with more easily, but changing time() to do subsecond granularity would be A Bad Thing for backward compatibility. Think of generated filenames, or various logs with timestamps. We can (hopefully) do a magical p52p6 translator, but fixing the existing data is a tad harder. -- $jhi++; # http://www.iki.fi/jhi/ # There is this special biologist word we use for 'stable'. # It is 'dead'. -- Jack Cohen
Re: JWZ on s/Java/Perl/
David Mitchell wrote: I let the Perl developers do all the hard locking code behind the scenes, and I don't have to worry my pretty little head about it. Now, there may be practical reasons why it isnt possible for perl to do this for me automatically (reasons, anyone?), but it's a nice ideal. Dave M. The thing with mandatory locks per variable, is that as long as you only want to access _that_ variable, it's ok, but if you want to make several uses of several variables and want to do it all at once, you've got a problem. Suppose we have: $a++; $x = $a; $y = $a; die if ($x != $y);## will die on a MT environment well, if every access to the variable is mandatory, then this code would execute the following operations: lock $a load $a inc store $a unlock $a lock $a lock $x load $a store $x unlock $a unlock $x lock $a lock $y load $a store $y unlock $a unlock $y ... See the problem with this code? A statement using $x or $a cannot run while $x = $a is running, because both variables are locked. That assures $x = $a is executed without problems, but any statement modifying $a (for example, $a++) could get to run between $x = $a and $y = $a, and so $x and $y will hold different values. So, instead of locking the variables for each statement, you should better lock them for the whole block of statements. lock $a; $a++; $x = $a; $y = $a; die if ($x != $y);## won't ever die unlock $a; AFAIK, Java locks the non-local variables for every statement. I think I read this somewhere but I can't remember where. I guess this kind of locking makes the statement $x = $a + $a; run with the same value of $a for both operands. (I could be wrong, and I think even if there was no locking, the VM could read $a only once and use the two operands from the same reading, by copying from a local register to other, or duplicating it on the stack...). Please correct me if I'm wrong, but I think that is the kind of thing Java does. If anyone can find it written somewhere, please post. Well, IMO, this kind of locking is very weak. If instead of writing $x = $a + $a; you wrote $x = $a; $x += $a; You would loose all the locking behaviour that would guarantee that the two $a's are the same. This goes even worse in Perl, because you know Perl has too much special cases, and there are many more ways to do it, and you would always have to think "Is this a statement?" or "Is the lock working?", etc. That's why I think, in perl, $x = $a + $a; should behave as $x = $a; $x += $a; i.e., with no locking, and no guarantee that the two reads of the non-local variable $a will return the same thing. (I'm not saying they _always_ will return different things, neither that they _eventually_ will return different things, only that it's not guaranteed that they will return the same thing!) How can one force the sane behaviour, of returning the same thing for both reads? In all the cases, by setting an explicit lock on $a. The bottom line is: If you are gonna write a threaded program, you can be lazy or careful. If you're lazy, just let it run with no locks in it and pray so that no race conditions occur. If you're careful, you will promptly identify which variables are shared, and just put locks around any section of the code that either reads or writes to that variable (or variables). I've read so many wrong implemented thread programs written in Java that I almost think they shouldn't include threads in it. People read "Java is thread-safe" and go on using it as they wouldn't ever go into this kind of situation. But race conditions are probably the hardest type to spot, hardest to reproduce kind of things that lead to bugs. I think the less magic we put into locks, the more we enforce programmers to be conscient about race conditions in multi-threading. - Branden
Re: Why shouldn't sleep(0.5) DWIM?
At 09:43 AM 1/30/2001 -0600, Jarkko Hietaniemi wrote: On Tue, Jan 30, 2001 at 04:13:39AM -0500, Michael G Schwern wrote: Is there any really good reason why sleep() doesn't work for microseconds? I mean, if I can do this: sub sleep { my($time) = shift; if( /^[+-]?\d+$/ ) { sleep($time); } else { select(undef, undef, undef, $time); } } Why can't Perl? Smells like a C holdover to me. I guess it's part of the can of sub-second worms: if we do sleep(), people will ask why don't we do time() and alarm(), too. sleep() and alarm() we could get away with more easily, but changing time() to do subsecond granularity would be A Bad Thing for backward compatibility. Think of generated filenames, or various logs with timestamps. We can (hopefully) do a magical p52p6 translator, but fixing the existing data is a tad harder. Also there isn't a portable way to do subsecond sleeps. Not that it's stopped perl before, but on some of the platforms that perl 5 runs on there isn't *any* way to do it. I'm up for raising the bar for base OS/C compiler features that this sort of thing is available. Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: JWZ on s/Java/Perl/
"Branden" [EMAIL PROTECTED] wrote: The thing with mandatory locks per variable, is that as long as you only want to access _that_ variable, it's ok, but if you want to make several uses of several variables and want to do it all at once, you've got a problem. [ big snip ] Sorry, I misunderstood you. I think in fact we agree! What I was advocating was that Perl should automatically make accesses to individual shared variables safe, so 2 threads executing 1: $shared = 10; 2: $shared = 20; wont guarantee whether $shared ends up as 10 or 20, but will guarantee that the internal representation of $shared wont get corrupted. Anything that guarantees consistency between multiple variable accesses should be up to the programmer to decide where to lock, IMHO.
Re: Why shouldn't sleep(0.5) DWIM?
Jarkko Hietaniemi wrote: I guess it's part of the can of sub-second worms: if we do sleep(), people will ask why don't we do time() and alarm(), too. sleep() and alarm() we could get away with more easily, but changing time() to do subsecond granularity would be A Bad Thing for backward compatibility. Think of generated filenames, or various logs with timestamps. We can (hopefully) do a magical p52p6 translator, but fixing the existing data is a tad harder. I see no trouble in time returning a float value. p52p6 could translate time() to int(time()) and everything should work ok. Anyway, time is probably gonna change in perl6, since it's UNIX-based now and i think we no longer have to know how many seconds have passed since mid-night january 1st 1970, do we? Also, we could translate the stringified result of the float value of time to be the string of only the integers, what would probably solve the log timestamps problem, but as it would also be solved with int(time()), I won't consider it here, since it can lead to not DWIM, IMO. For reference, see RFC 99 on standardizing time to (oops!) UNIX-time (even so, my point continues, int(time()) solves p52p6 problem!), RFC 73, on making all built-ins return objects, which would do the stringifying thing or even allow with and without fractions in one object, and RFC 48, on changing localtime() and gmtime(), 'cause maybe time() will go with them too! - Branden
Re: Why shouldn't sleep(0.5) DWIM?
On Tue, Jan 30, 2001 at 10:49:56AM -0500, Dan Sugalski wrote: At 09:43 AM 1/30/2001 -0600, Jarkko Hietaniemi wrote: On Tue, Jan 30, 2001 at 04:13:39AM -0500, Michael G Schwern wrote: Is there any really good reason why sleep() doesn't work for microseconds? I mean, if I can do this: sub sleep { my($time) = shift; if( /^[+-]?\d+$/ ) { sleep($time); } else { select(undef, undef, undef, $time); } } [return value not perfect for sleep when you call select] Also there isn't a portable way to do subsecond sleeps. Not that it's stopped perl before, but on some of the platforms that perl 5 runs on there isn't *any* way to do it. You don't need to do it, do you? man 3 sleep RETURN VALUE Zero if the requested time has elapsed, or the number of seconds left to sleep. man perlfunc sleep EXPR sleep Causes the script to sleep for EXPR seconds, or forever if no EXPR. May be interrupted if the process receives a signal such as "SIGALRM". Returns the number of seconds actually slept. You probably cannot mix "alarm" and "sleep" calls, because "sleep" is often implemented using "alarm". So on a system that can't do a subsecond sleep, you do the integer sleep and return (aargh, C and perl differ) how long you slept for. How does the program discover if sleep can do subseconds? use Config; ? Nicholas Clark
UNIX epoch issues (Re: Why shouldn't sleep(0.5) DWIM?)
Jarkko Hietaniemi wrote: As I said the problem isn't the p52p6 doing that kind of transformation. The problem is someone familiar with perl5 writing code in perl6: if (my $fh = open("/tmp/$$".time())) { and later something crashing and burning because some other place expects to find a filename of the form /^\d+\d+$/, or someone printing into log files like this print LOG time() . ": gorkulator borked. Please investigate." and someone splitting on /\./, etc. Good point, this is a problem with changing time() from UNIX epoch (or anything else which provides sub-second granularity or otherwise introduces a "."). probably gonna change in perl6, since it's UNIX-based now and i think we no longer have to know how many seconds have passed since mid-night january 1st 1970, do we? Some sort of less C/UNIX-centric way would be nice, yes. We had a whole ton of discussions on this regarding "what epoch is the right one", and the general consensus was that we should keep time() as-is. The basic argument went like this: 1. All epochs are arbitrary 2. The UNIX epoch is well-known and understood 3. Therefore let's not mess with it In fact RFC 99 proposed the reverse - that all platforms should use the UNIX epoch. There was about a 50/50 split, some said "Why mess with MacOS?" and others said "This would help Perl cross-platform." See RFC 99 at http://dev.perl.org/rfc/99.pod The full discussions, which included ponderings of Modified Julian, the ISO format, etc, can be found starting at the following places: Original proposal to use MJD and introduce mjdate(), which resulted in much heated slashing and burning: http://www.mail-archive.com/perl6-language@perl.org/msg02171.html Reintroduction as standardizing on UNIX epoch: http://www.mail-archive.com/perl6-language@perl.org/msg02308.html General slashing and burning of the UNIX epoch idea: http://www.mail-archive.com/perl6-language-datetime%40perl.org/msg00029.html Since there were many replies your best bet is to read the "Follow-ups" at the bottom rather than hitting the "Next Thread" button. -Nate
Re: Why shouldn't sleep(0.5) DWIM?
Jarkko Hietaniemi wrote: As I said the problem isn't the p52p6 doing that kind of transformation. The problem is someone familiar with perl5 writing code in perl6: if (my $fh = open("/tmp/$$".time())) { and later something crashing and burning because some other place expects to find a filename of the form /^\d+\d+$/, or someone printing into log files like this print LOG time() . ": gorkulator borked. Please investigate." and someone splitting on /\./, etc. Well, then I propose the same of RFC 48: deprecate time() and create another name to refer to the number of seconds since (an epoch) with decimals for fractions of seconds. Maybe it could be called now() or timestamp(). Then time needn't be on CORE, and can be put together with localtime() and gmtime() on Time::Local or anything like it. It could be implemented as: sub Time::Local::time { return int(CORE::now()); } Since there will probably a change of mind from programming perl5 to programming perl6 (as it will be probably more object-oriented, less unix-centric, etc.), I see no problem in telling perl programmers to change their implementations: change: : if (my $fh = open("/tmp/$$".time())) { for: : if (my $fh = open("/tmp/$$".int(now( { or: : my $fh = open(" /tmp/.$progname-$$-" . date(now(), '%Y%m%d%H%M%S')); : # creates the file /tmp/.myperlscript-56473-20010130173742 : # just by looking at it, I can tell it was generated by "myperlscript" : # running by process whose pid is 56473, and was generated : # at 17:37:42, on january 30th, 2001. : # much easier to figure it out than than seconds from 1970... change: : print LOG time() . ": gorkulator borked. Please investigate."; for: : print LOG int(now()) . ": gorkulator borked. Please investigate."; or: : print LOG date(now(), '%Y-%m-%d %H:%M:%S')# much better! : . ": gorkulator borked. Please investigate."; : # in a logfile, the clarity argument is even more valuable... Well, at least that's what I think about time. This change wouldn't break compatibility, and changing the way we think about this function is a healthy thing for our programmer minds. Just because UNIX decided that its sleep function would return an int value, doesn't mean we have to follow it on our design! - Branden P.S.: Nathan, on re-reading RFC 48 I spotted out that comparison of dates isn't mentioned. Of course there's a section on ``Date arithmetic'', that talks about -, I think mentioning and is worth it.
Re: UNIX epoch issues (Re: Why shouldn't sleep(0.5) DWIM?)
On Tue, 30 Jan 2001, Nathan Wiger wrote: Jarkko Hietaniemi wrote: As I said the problem isn't the p52p6 doing that kind of transformation. The problem is someone familiar with perl5 writing code in perl6: if (my $fh = open("/tmp/$$".time())) { and later something crashing and burning because some other place expects to find a filename of the form /^\d+\d+$/, or someone printing into log files like this Well, FWIW, here are two suggestions on how to handle this, the grouchy way and the helpful way: 1) (grouchy) If you're writing Perl6, you should be writing Perl6, and you should know how time() behaves and handle it properly. 2) (helpful) time() returns an int-based time value (as now), but time(something) returns a subsecond-value...if we wanted to get really fancy, then the value of something as an int could be the number of places of accuracy that would be returned. Dave
Re: Why shouldn't sleep(0.5) DWIM?
Lightning flashed, thunder crashed and Jarkko Hietaniemi [EMAIL PROTECTED] whispered : | I guess it's part of the can of sub-second worms: if we do sleep(), | people will ask why don't we do time() and alarm(), too. sleep() and | alarm() we could get away with more easily, but changing time() to do | subsecond granularity would be A Bad Thing for backward compatibility. Why do we have to worry about changing time()? There's a real parallel between sleep() and alarm(), so we would want to do both if we did either, but time() really has no relation to them. Or, should we just implement usleep() and (for lack of a better name) ualarm()? -spp
Re: Why shouldn't sleep(0.5) DWIM?
On Tue, Jan 30, 2001 at 05:49:43PM -0200, Branden wrote: Well, then I propose the same of RFC 48: deprecate time() and create another name to refer to the number of seconds since (an epoch) with decimals for fractions of seconds. Maybe it could be called now() or timestamp(). Then time needn't be on CORE, and can be put together with localtime() and gmtime() on Time::Local or anything like it. It could be implemented as: sub Time::Local::time { return int(CORE::now()); } Why the urge to move it out of the core? Should perl6 be like Python, where you first need to do a gazillion imports before you can do anything useful? Say goodbye to quick one-liners then. Since there will probably a change of mind from programming perl5 to programming perl6 (as it will be probably more object-oriented, less unix-centric, etc.), I see no problem in telling perl programmers to change their implementations: change: : if (my $fh = open("/tmp/$$".time())) { for: : if (my $fh = open("/tmp/$$".int(now( { or: : my $fh = open(" /tmp/.$progname-$$-" . date(now(), '%Y%m%d%H%M%S')); : # creates the file /tmp/.myperlscript-56473-20010130173742 : # just by looking at it, I can tell it was generated by "myperlscript" : # running by process whose pid is 56473, and was generated : # at 17:37:42, on january 30th, 2001. : # much easier to figure it out than than seconds from 1970... If time() is there to stay, why bother changing the code? If you insist on getting file names with year/month/date in them, you can do so now using localtime(), and if you don't mind to have files with seconds- since-epoch in the name, why would you mind when perl6 rolls along? change: : print LOG time() . ": gorkulator borked. Please investigate."; for: : print LOG int(now()) . ": gorkulator borked. Please investigate."; or: : print LOG date(now(), '%Y-%m-%d %H:%M:%S')# much better! : . ": gorkulator borked. Please investigate."; : # in a logfile, the clarity argument is even more valuable... Write them as: printf LOG "%d: %s\n" = time (), "gorkulator borked. Please investigate."; or: printf LOG "%s: %s\n" = scalar (localtime ()), "gorkulator borked. Please investigate."; or: use POSIX; printf LOG "%s: %s\n" = strftime ("%Y-%m-%d %H:%M:%S", localtime ()), "gorkulator borked. Please investigate."; and gain two things: 1) You get "much better!" without waiting for perl6 to roll along, 2) It doesn't matter whether time() returns an integer or a float. Well, at least that's what I think about time. This change wouldn't break compatibility, and changing the way we think about this function is a healthy thing for our programmer minds. Just because UNIX decided that its sleep function would return an int value, doesn't mean we have to follow it on our design! Moving time() out of the core doesn't break compatibility? Changing the return value of sleep() doesn't change compatibility? What *does* change it then? Let's not forget that Perl is a glue language. It heavily interacts with its environment, other programs and is eager to network with the outside world. Seconds since 1970 might be as arbitrary as any other measurement, but that's irrelevant. What's relevant is 30 years of code that produces and expects timestamps in seconds since 1970. Deprecating time() in favour of some other arbitrary measurement is absurd. It might makes sense to have some other functions giving units since some point in the past next to time() though. Abigail
Re: Why shouldn't sleep(0.5) DWIM?
"Stephen P. Potter" wrote: Why do we have to worry about changing time()? There's a real parallel between sleep() and alarm(), so we would want to do both if we did either, but time() really has no relation to them. Or, should we just implement usleep() and (for lack of a better name) ualarm()? One thing that was discussed on the archives that I sent out was introducing a parallel mjdate() (or isodate() or whatever) which gave access to the internal means of maintaining time in Perl. Then Perl's internal clock could be sub-second ticks since 4152 BC, Modified Julian, etc, etc. So time() could remain unchanged (from a language/user perspective, at least), but sleep() and alarm() could use the internal sub-second methods of timekeeping to DWIM. The user gets sleep(0.5) and time() is still epoch seconds. But the big problem is that there's a lot of stuff that's based off of time() right now, like stat(), lstat(), etc, etc. When you think of the cascading effects of changing Perl's timekeeping it gets really, really sticky. If the internal timekeeping were changed, one thing that's apparent from the discussions is that there would *have* to be a core way of providing exactly what time() does currently or lots of stuff would break really badly. Someone can certainly chime in if they see an easy way around this, but as I recall there was little disagreement on this point. -Nate
Re: Why shouldn't sleep(0.5) DWIM?
On Tue, Jan 30, 2001 at 01:07:18PM -0800, Nathan Wiger wrote: But the big problem is that there's a lot of stuff that's based off of time() right now, like stat(), lstat(), etc, etc. When you think of the cascading effects of changing Perl's timekeeping it gets really, really sticky. I don't see this problem, unless you plan to write a filesystem in Perl. Surely Perl asks the OS for l?stat() instead of keeping track of it itself? Abigail
Re: Why shouldn't sleep(0.5) DWIM?
On Tue, Jan 30, 2001 at 01:07:18PM -0800, Nathan Wiger wrote: If the internal timekeeping were changed, one thing that's apparent from the discussions is that there would *have* to be a core way of providing exactly what time() does currently or lots of stuff would break really badly. Someone can certainly chime in if they see an easy way around this, but as I recall there was little disagreement on this point. I really and truly don't see why we can't have things dealing with a number of seconds do the Right Thing with fractional seconds, including returning them. It isn't an issue that we don't have the resolution available; the functions were, and will continue to be, best-effort. There isn't a real problem with formatting; if you're programming in p6, you should be saying int(time) if you don't want a period. Remember, 75% of p5 code works straight, 90% can be translated. time - int(time) is easy to translate. And having it in the 25% that needs to change isn't that bad. You shouldn't be using time() to generate unique filenames becuase the time isn't unique. Splitting on a period is probably valid in many cirucumstances, but you can deal. You can't make an omlet without breaking a few eggs, and this is a little one to break. (And please, don't get into epoch discussions here. The units, accuracy, resolution, and zeropoint of a measurement are all different questions. I personaly would prefer to see units of seconds, a basepoint of 1/1/1970, and resolution and accuracy best-reasonably-available.) If you really want time() to do what it did before, you can always say: sub time {int (CORE::time()) + epoch difference}; Indeed, a perl5::time module that does exactly that might be a Good Thing. -=- James Mastros -- "My country 'tis of thee, of y'all i'm rappin'! Lan where my brothers fought, land where our King was shot -- from every building top, let freedom happen!" -=- Monique, Sinfest[.net] AIM: theorbtwo homepage: http://www.rtweb.net/theorb/
Re: Why shouldn't sleep(0.5) DWIM?
Lightning flashed, thunder crashed and Nathan Wiger [EMAIL PROTECTED] whisper ed: | But the big problem is that there's a lot of stuff that's based off of | time() right now, like stat(), lstat(), etc, etc. When you think of the | cascading effects of changing Perl's timekeeping it gets really, really | sticky. Most of those don't deal with subsecond time anyway, from the perspective that (l?stat) uses what is recorded in the filesystem inode. | If the internal timekeeping were changed, one thing that's apparent from | the discussions is that there would *have* to be a core way of providing | exactly what time() does currently or lots of stuff would break really | badly. Someone can certainly chime in if they see an easy way around | this, but as I recall there was little disagreement on this point. Changing sleep/alarm doesn't have to involve changing perl's internal timekeeping. sleep/alarm are just wrappers around the C library sleep/alarm. It should be trivial to make the wrapper recognize when a float is passed as the argument and switch to usleep (or setitimer or whatever) when that is found. -spp