Re: Cmap Cgrep and lazyness
Alexey Trofimenko writes: what I want to ask - would map and grep return an iterators too?.. if it's true, then previous construct becames very memory efficient, like if I write loop ( ... ; ... ; ... ) {...; next if ...; ...; say} Yep, they will. hm.. It could be a little too functional, though, for perl, which is filled up by side effects. for example, $filehandle is iterator too, but it has side effect of changin' position in file. now sub process (@a is Lazy) { map {...} @a } becomes somewhat dangerous if called as @b = process $file Well, perhaps not. Theoretically, at this point, $file has been read completely. It's just that it's lying and it hasn't really. But if you try to read again, it should resync and things should work properly. But indeed there are cases where it is a problem: my $x = 2; sub mklist () { return map { 2 * $_ } 0..10; } my @list = mklist; say @list[0..4]; # 0 2 4 6 8 $x = 1; say @list; # 0 2 4 6 8 5 6 7 8 9 10 Which is assuredly different from what would happen if it were evaluated non-lazily. Fortunately, if you fear such effects, you can use the eager flattener: my @list = **mklist; Which will exhaust the iterator and turn it into a real list immediately. Of course, if you do: my @list = ** 0...; You'll be testing your computer's temper. Luke (assuming we have lazy arrays too. maybe it should be := insted of = ?) I don't actually know whether it should be := . I expect not; the laziness may be built into the array value implementation. However, it would feel cleaner to make it behave as a tied array. But then you'd have to declare it tied, which would be a pain. Luke
Re: push with lazy lists
Joseph Ryan wrote: The way I understand the magicness of lazy lists, I'd expect: @x = 3..Inf; say pop @x; # prints Inf @x = 3..Inf; push @x, 6; # an array with the first part being # lazy, and then the element 6 say pop @x; # prints 6 say pop @x; # prints Inf say pop @x; # prints Inf say pop @x; # prints Inf # etc The way I think of a lazy infinite list is kind of like a special object. It needs to keep track of what the start is and what the end is. Every other element doesn't actually exist, but is calculated based on the index of the FETCH/STORE/SPLICE/whatever call. I guess that's true with X..Y lazy lists. I thought there were other ways to make lazy lists, like giving it a closure that gets called lazily to populate the list with the result's being cached. I can't remember the syntax though. I think gather was one way. Maybe I'm just remembering wrong. Anyhow, I was thiking that was how X..Inf was implemented. That would be foolish in this case. how 'bout @x = gather{ loop{ take time } } # can this be @x = gather { take time loop } push @x, later; say pop @x;# later say pop @x;# heat death? say @x[rand]; # how about now? Also, any list that contains and infinite list becomes tied. The container list's FETCH would change so that any accessed index that falls within the indexes owned by the infinite list would be dispatched to the infinite list. So, with a list like: @array = ('a','b','c',2..Inf,woops); Elements 0, 1, and 2 would be accessable as normal, but then elements 3 through Inf would be dispatched to the infinite list. However, since woops's index is also Inf, and that index is owned by the infinite list, it would be impossible to access it except through a pop call (which doesn't look at indexes at all). I was wondering about lazy list where we don't know how many element it might generate. Admittedly, I picked a poor example. I would right to assume woops would also be accessable with @array[-1], right? Dan
Re: The .bytes/.codepoints/.graphemes methods
Aaron Sherman wrote: On Tue, 2004-06-29 at 11:34, Austin Hastings wrote: (2) Perl6 should equitably support all its target locales; (3) we should set out to make sure the performance is damn fast no matter what locale we're using. Well, that's a nice theory, but you can prove that low-level encodings (e.g. ASCII, EBCDIC) will be more efficient than high-level encodings (e.g. UTF-8), so the only way to accomplish what you suggest in (2) is to break (3) by slowing down the faster handling (not what you wanted, I'm sure). At the Parrot level, codepoint operations will generally be the most efficient, even on strings with exotic charsets. Parrot uses an internal encoding that allows O(1) access to codepoints; essentially, it uses an array of 8-, 16-, or 32-bit integers, depending on the highest codepoint value. This is the default even for character sets with shift characters, like Shift-JIS. On strings where all codepoints have values under 256, bytewise and codepointwise lookup are equivalent; otherwise, though, bytewise lookup will actually be *slower* than codepointwise, as Parrot will maintain the illusion that each codepoint is stored in an integer that's the perfect size for it. If you force Parrot to use the UTF-8 encoding internally then bytewise lookup becomes fastest, and codepointwise slows down a lot. But you really shouldn't do that--UTF-8 is ill-suited for actually *manipulating* text, unlike the Parrot internal encodings. (UTF-16 and UTF-32 will presumably be available too, although I've seen no specific mention of them.) You can also force it to use a raw or bytes encoding, where bytes and codepoints are identical. But you can't store Unicode characters in such a string and have them behave in a reasonable way. (Note: this is all based on my own, possibly false, memory.) -- Brent Dax Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker Oceania has always been at war with Eastasia.
Re: Cmap Cgrep and lazyness
Alexey Trofimenko wrote: apply to it perl6 GC, which wouldn't always free memory immediately, so it could eat 3_000_000 or more. Parrot runs a DOD (Dead Object Detection) sweep whenever its memory pools fill up, so this is probably a far smaller problem than you suggest. (If there still isn't any space in the existing pools after a DOD, it malloc()s a new one.) ok, I know, that 1..n will return an iterator in perl6, which is called only when new item needed. great. what I want to ask - would map and grep return an iterators too?.. if it's true, then previous construct becames very memory efficient, like if I write loop ( ... ; ... ; ... ) {...; next if ...; ...; say} As you mentioned below, this causes problems if the code in question has side effects. But there are other cases where it messes up: sub even($_ = $CALLER::_) { ! $_ % 2 } my @e=grep { even() } 1..1024; #Okay, we don't need even anymore... undef even; say @e; Put that Cundef in an Ceval, and all of a sudden you can't tell if the laziness is safe even at compile time. I suggest that this laziness be confined only to places where it's specifically asked for: my @e=grep { even() } :lazy 1..1024; -- Brent Dax Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker Oceania has always been at war with Eastasia.
Re: undo()?
Juerd [EMAIL PROTECTED] writes: I thought temp replaced local. temp is dynamic scoping, the same thing as Perl5's local. Hypotheticals are the ones that turn permanent if everything succeeds according to plan but revert to the old value if stuff fails -- a rollback mechanism, basically. I was just about to mention hypothetical scoping wrt undo but for some reason did not. In fairness to the undo suggestion, there is a significant difference: to use hypotheticals to revert you have to plan the reverting when (or before) you make the change. I think continuations work this way also (except that they don't just revert one thing). This sounds like a no-brainer (i.e., you're writing the code that uses undo so obviously you planned at coding time to do the reversion) until you think about putting references into the mix; with undo you could revert an arbitrary item. One thing worth noting about .undo is that retrofitting it later would not break backward-compatibility at the language level. It would be one heck of a messy change under the hood, but any user who wasn't using it wouldn't have to even know about the change. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: undo()?
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes: Actually, I think you're underestimating the little guys. After all, if they rolled back *all* of your changes, all they could do was repeatedly execute the same code! Except that you can pass the continuation some arguments, possibly including functions, closures, or even other continuations, which would rather complicate matters. But Luke's explanation makes sense of some things I previously couldn't make sense of. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: if not C, then what?
Jonathan Lang [EMAIL PROTECTED] writes: Strictly from a grammatical perspective, I'd be much more comfortable with C, then instead of Cthen as the perl equivelent of the C-style comma: have the then keyword change the preceeding comma from a list constructor to an expression combiner. From a parsing perspective, though, this would be a nightmare. Parsing Perl was nightmarish already before work started on Perl6. If we wanted a language that's easy to parse, we'd be using lisp, or maybe assembly language. Still, I'm not sure what the comma adds, other than extra[1] punctuation. This is different from its use in conditional sentences, since in that case the protasis (if clause), being an introductory subordinate clause, is usually set off from the rest of the sentence via a comma, whether or not then is used to introduce the apodosis (then clause). It is common to see a comma before then for this reason, but that is entirely a different use (and meaning) of then. Come to think of it, the frequent use of then in conditionals might make it a bad choice for use in another way. Actually, the whole purpose of the C-style comma is to allow you to place multiple expressions in a place that's only designed to take one, such as the various divisions within a loop control set (loop ($i = 0, $j = 1; $i 10; $i++, $j*=2) {...}). For something like this, you might be better off doing something like last($a, $b, $c) (where last is a sub that takes a list of arguments, evaluates them one at a time, and returns the value of the last one). Unfortunately, last is already in use by perl; so you'd have to think up another name for the sub, such as final. Oh, like lisp's progn (except that final is a better name for it). Perl5 programmers have been known to use xor for this, though of course that is not the intended use of xor. where C[-] is read as followed by. You could even set up a right-to-left version, C[-], but why bother? Oh, for aesthetic symetry, of course ;-) [1] Do one thing then do another is valid SWE I think. then is not a coordinating conjunction like and; it's a special adverb of sorts, in a similar category with because (except that because is a subordinator; whereas, then does coordinate; but it is not a conjunction) or so (although so often is treated like a conjunction and takes the comma, which is an odd little wrinkle -- but it does not always do this). then can function as a coordinating adverb (like consequently and nonetheless and so on); in the case wherein it joins whole independent clauses it is preceded by a semicolon (as in She went to the store; then she came home. -- if there were a comma in this case it would be after then, not before), but it can also be used to coordinate the parts of a compound part of speech, e.g., a compound verb with the subject expressed only once (if at all; in the imperative mood the subject need not be expressed); in that case no punctuation is needed, as in She went to the store then came home. This last usage most closely fits the proposed way of using it in Perl, as in (you) Go to the store then come straight home. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: if not C, then what?
David Storrs [EMAIL PROTECTED] writes: e.g., is this legal? sub infix:before ( $before, $after ){ ... } I should HOPE it would be legal to define infix:before. Some of us don't want to use untypeable characters every time we want to define an operator that doesn't conflict with the core language. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: if not C, then what?
Jonathan Lang [EMAIL PROTECTED] writes: For the record, I was mentally parsing this example as: pray_to $_; sacrifice $virgin for @evil_gods; So was I, FWIW. The precedence of Cthen isn't very intuitive to me. Is that an argument for changing its precedence, or for leaving it out of the core language? -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: if not C, then what?
Jonadab the Unsightly One skribis 2004-07-03 13:33 (-0400): e.g., is this legal? sub infix:before ( $before, $after ){ ... } I should HOPE it would be legal to define infix:before. There already are infix:x and infix:xx. If Perl 6 will let us define our own operators just like built in ones, infix:before should also be possible. And infix:¥ (for those like me who have a simple terminal that doesn't know how to display this, or are suffering from my lack of config-fu to get headers and encodings synched: this is Yen, created using ^KYe in vim. I see a dashed rectangle.) will in my programs probably only be used through infix:Y or infix:z, which I will define myself if necessary. (zip() is not infix and thus not an *equivalent* alternative.) Juerd
Re: push with lazy lists
- Original Message - From: Dan Hursh [EMAIL PROTECTED] Date: Friday, July 2, 2004 10:32 pm Subject: Re: push with lazy lists Joseph Ryan wrote: I guess that's true with X..Y lazy lists. I thought there were other ways to make lazy lists, like giving it a closure that gets called lazily to populate the list with the result's being cached. I can't remember the syntax though. I think gather was one way. Maybe I'm just remembering wrong. Anyhow, I was thiking that was how X..Inf was implemented. That would be foolish in this case. how 'bout @x = gather{ loop{ take time } } # can this be @x = gather { take time loop } push @x, later; say pop @x;# later say pop @x;# heat death? say @x[rand]; # how about now? I'm a bit confused by your syntax, but I think I understand what you mean. I was under the impression that loops were not lazily evaluated, but essentially run until they were broken out of. The advantage of using an infinite list is just that you have an iterator that never runs out. Also, any list that contains and infinite list becomes tied. The container list's FETCH would change so that any accessed index that falls within the indexes owned by the infinite list would be dispatched to the infinite list. So, with a list like: @array = ('a','b','c',2..Inf,woops); Elements 0, 1, and 2 would be accessable as normal, but then elements 3 through Inf would be dispatched to the infinite list. However, since woops's index is also Inf, and that index is owned by the infinite list, it would be impossible to access it except through a pop call (which doesn't look at indexes at all). I was wondering about lazy list where we don't know how many element it might generate. Admittedly, I picked a poor example. I would right to assume woops would also be accessable with @array[-1], right? Oh yeah, that would work too. :) - Joe
Re: undo()?
Luke Palmer [EMAIL PROTECTED] writes: Oh no! Someone doesn't understand continuations! How could this happen?! :-) Yes, well, I've only just started reading up on them recently... A continuation doesn't save data. It's just a closure that closes over the execution stack Ah. That helps a lot. For some reason, I hadn't realize that yet from reading about them in Dybvig. You could make the programmer specify which variables he wants delta data for, and then any *others* wouldn't keep it and wouldn't be undoable. A much more useful way to do this would be: use undo $foo $bar $baz ; my $foo = 41; my $state = undo.save; $foo++; $foo.undo($state); # or perhaps $state.remember; That seems reasonable to me. I don't want to think about what happens when you write: use undo $state ; Something terribly inefficient, I suppose. There could be a warning in the documentation about that. Or something could try to be clever and detect this sort of thing; I'm not entirely certain whether that's equivalent to the halting problem, but either way it sounds like all kinds of excitement, or something. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}} split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/
Re: Cmap Cgrep and lazyness
Brent 'Dax' Royal-Gordon writes: As you mentioned below, this causes problems if the code in question has side effects. But there are other cases where it messes up: sub even($_ = $CALLER::_) { ! $_ % 2 } my @e=grep { even() } 1..1024; #Okay, we don't need even anymore... undef even; say @e; Put that Cundef in an Ceval, and all of a sudden you can't tell if the laziness is safe even at compile time. Perhaps this isn't a problem. Think of your code this way: my $even = sub ($_ = $CALLER::_) { ! $_ % 2 }; my @e = grep { $even() } 1..1024; undef $even; say @e; Is it a problem now? Nope. @e holds a reference to the grep generator, which holds a reference to the code, which holds a reference to $even. So the Cundef $even didn't change a thing. So it is only a problem if sub calls are made by name lookup as they are in Perl 5. If the sub is predeclared, the call to even() my have been made into a reference. I suggest that this laziness be confined only to places where it's specifically asked for: my @e=grep { even() } :lazy 1..1024; There's a way to go the other way, to specifically mark it as non-lazy: my @e = **grep { even() } 1..1024; I don't mind lazy by default, as long as the error messages are smart enough to know that they were inside a lazy generator. That is, in your case: Subroutine call to even() not defined at test.pl line 2 Called from lazy generator on test.pl line 2. Luke