Re: Why pass by reference?
On Fri, 19 Jun 2009, Martin D Kealey wrote: > To that end I would propose that: > - parameters should be read-only AND invariant by default, and > - that invariance should be enforced passing a deep immutable clone >(*5) in place of any object that isn't already immutable. Sorry, typo: that last word should have been "invariant", meaning that it *won't* change, rather than "immutable", meaning that it *can't*. Compilers can rely on invariance to perform a range of very powerful optimizations; immutability is one way to guarantee invariance, but not the only way. -Martin
Re: Why pass by reference?
> Matthew Walton wrote: > > If a user of your API contrives to make it change while you're > > running, that's their own foot they've just shot, because they can > > look at the signature and know the semantics of the parameter > > passing being used and know that if they change the value externally > > before you return Bad Things Could Happen. > On Tue, 16 Jun 2009, TSa wrote: > I agree that the caller is responsible for the constness of the value > he gives to a function. With this we get the best performance. At the language level this is wrong. Programmers are BAD at this sort of thing, unless the compiler *always* has enough to throw a compile-time error, and even then it's dicey because we may defer compilation. It seems to me this is pushing something onto the author of the caller that they shouldn't have to deal with, especially when you consider that the parameter they're passing into the function may come from somewhere else, which hasn't been made -- and indeed CAN'T be made -- to promise not to meddle with the value (note *1). If the compiler can't spot it, how do you expect a fallible human being to do so? If a function requires an invariant parameter then the compiler should ensure that that guarantee is met, and not rely on the programmer to do something that is impossibly hard in the general case. A simple way would be to call $parameter := $parameter.INVARIANT() (*2) on the caller's behalf before calling the function. Conversely, when calling a function where the parameter is declared :rw, the compiler can call $parameter := $parameter.LVALUE() (*3) on the caller's behalf first if it needs to convert an immutable object to a mutable one. (Or throw up its hands and assert that it's not allowed.) If we really expect the optimizer to make Perl6 run well on a CPU with 1024 cores (*4), we have to make it easy to write programs that will allow the optimizer to do its job, and (at least a little bit) harder to write programs that defeat the optimizer. To that end I would propose that: - parameters should be read-only AND invariant by default, and - that invariance should be enforced passing a deep immutable clone (*5) in place of any object that isn't already immutable. -Martin Footnotes: *1: There are many possible reasons, but for example the caller didn't declare it :readonly in turn to its callers because it *did* plan to meddle with it -- but just not by calling this function with its :readonly parameter. *2: Yes I made up "INVARIANT". The trick is that the compiler only needs to insert the call if can't prove the invariance of $parameter, which it *can* prove when: - it arrived in a :readonly parameter; or - it's locally scoped, and hasn't "escaped". In addition the implementation of INVARIANT() could: - return $self for any "value" class; and - return the encapsulated immutable object for the case outlined in the following footnote. Otherwise the default implementation of INVARIANT() would be like deepclone(). (Declaring a "value class" would ideally be shorter than declaring a "container class", but I'm a bit stuck as to how to achieve that. Ideas are welcome...) *3: The LVALUE method produces the sort of proxy object that others have described, but with the reverse function: it acts as a scalar container that can only hold immutable objects, and proxies all method calls to it, but allows assignment to replace the contained object. Calling INVARIANT on such a container object simply returns the encapsulated immutable object. *4: As a generalization, the assumptions floating round that "the compiler will optimize things" just aren't facing reality: programmers are about the worst people when it comes to learning from the past mistakes of others, and future generations of Perl6 programmers will inevitably create evil container classes with no corresponding value classes, and thus most parallelizing optimizations will be defeated. *5: At the language level at least, copying is NOT the enemy of optimization. On the contrary, if you always copy and *never* mutate, that ensures that the compiler can always determine the provenance and visibility of any given datum, and thus has *more* opportunities to avoid *actually* copying anything. And it can parallelize to the full extent of available hardware because it can guarantee that updates won't overlap.
Re: Why pass by reference?
TSa Thomas.Sandlass-at-vts-systems.de |Perl 6| wrote: HaloO, Matthew Walton wrote: If a user of your API contrives to make it change while you're running, that's their own foot they've just shot, because they can look at the signature and know the semantics of the parameter passing being used and know that if they change the value externally before you return Bad Things Could Happen. I agree that the caller is responsible for the constness of the value he gives to a function. With this we get the best performance. I don't understand why John thinks that an intermediate proxy is needed. A very shallow wrapper that ensures the readonlyness suffices. Most of the time not even that when the constness is known statically. Regards TSa. "shallow wrapper" is what I'm talking about. That is indeed a proxy: if a full-blown run-time check is needed (when it gets passed beyond its ability to track at compile time) it forwards methods, intercepts others, and modifies accessors.
Re: Why pass by reference?
HaloO, Matthew Walton wrote: If a user of your API contrives to make it change while you're running, that's their own foot they've just shot, because they can look at the signature and know the semantics of the parameter passing being used and know that if they change the value externally before you return Bad Things Could Happen. I agree that the caller is responsible for the constness of the value he gives to a function. With this we get the best performance. I don't understand why John thinks that an intermediate proxy is needed. A very shallow wrapper that ensures the readonlyness suffices. Most of the time not even that when the constness is known statically. Regards TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: Why pass by reference?
> Complex or not in that sense, it complicates things in allowing the value to > be changed by another path. I think that is something we want to avoid > doing, not present as a feature. Much of my original post concerns the > actual meaning, not whether it is considered simple. > > Since then, I see that it is useful for plural containers. We don't want to > copy them! But for items, why do we not even _have_ pass by value? The > compiler must assume the worst and can't optimize as well. 'is copy' is pass-by-value... remember everything in Perl 6 is a reference, of sorts. Pass-by-value of the reference is covered by 'is ref'. A more useful variant of that being 'is rw', which gives you an extra assurance with its lvalue checking that the user's not giving you something that's going to explode when you try to modify it. Pass-by-value of the thing the reference points to is covered by 'is copy', which is the semantics people would generally expect when they hear 'pass-by-value'. Pass-by-reference-but-don't-accidentally-change-what-it-points-to is covered by the default case or 'is readonly'. This seems to me to be the ideal - we don't copy huge values around when the user doesn't need them, but we also don't have hugely dangerous mutable parameters by default (they should be extremely explicit for the user of an API). Most of the time, there won't be another path where the value could change. Under a threaded model allowing shared variables, sure it could be changed by another thread, but hopefully you're under lock there. If a user of your API contrives to make it change while you're running, that's their own foot they've just shot, because they can look at the signature and know the semantics of the parameter passing being used and know that if they change the value externally before you return Bad Things Could Happen. Matthew
Re: Why pass by reference?
> Complex or not in that sense, it complicates things in allowing the value to > be changed by another path. I think that is something we want to avoid > doing, not present as a feature. Much of my original post concerns the > actual meaning, not whether it is considered simple. > > Since then, I see that it is useful for plural containers. We don't want to > copy them! But for items, why do we not even _have_ pass by value? The > compiler must assume the worst and can't optimize as well. 'is copy' is pass-by-value... remember everything in Perl 6 is a reference, of sorts. Pass-by-value of the reference is covered by 'is ref'. A more useful variant of that being 'is rw', which gives you an extra assurance with its lvalue checking that the user's not giving you something that's going to explode when you try to modify it. Pass-by-value of the thing the reference points to is covered by 'is copy', which is the semantics people would generally expect when they hear 'pass-by-value'. Pass-by-reference-but-don't-accidentally-change-what-it-points-to is covered by the default case or 'is readonly'. This seems to me to be the ideal - we don't copy huge values around when the user doesn't need them, but we also don't have hugely dangerous mutable parameters by default (they should be extremely explicit for the user of an API). Most of the time, there won't be another path where the value could change. Under a threaded model allowing shared variables, sure it could be changed by another thread, but hopefully you're under lock there. If a user of your API contrives to make it change while you're running, that's their own foot they've just shot, because they can look at the signature and know the semantics of the parameter passing being used and know that if they change the value externally before you return Bad Things Could Happen. Matthew
Re: Why pass by reference?
Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote: Actually, it only looks complicated while you think only on the callee side. No, in general it requires introducing a read-only proxy in front of the container. This may be optimized away when it can be tracked at compile-time, but that's certainly not "simple" as compared to not having it nor the aliased item container at all. Because when you take the caller side, you'll note that it builds a capture to send to the call, and the capture is always a reference, so the signature just makes sure that references becomes read-only. To illustrate: my $a = 1; foo($a); In this case, the capture sent must contain a direct reference to the scalar held in '$a', so both signatures with "is ref" or signatures with "is copy" can work. So, if foo has the signature sub foo($a is ref) {...} it will be able to change the scalar outside &foo. If it is sub foo($a) {...} It will be a read-only access to that scalar sub foo($a is rw) {...} Works almost like "is ref", but encloses immutables into a container in order to always provide rw semantics. No, "is rw" does not like immutables. It will cause autovivification to take place, but will not accept something that is not an lvalue such as 1 or "Hello" literals. This was just doubled-checked with S06, S09, and discussion with Larry in #perl6. If Ra rakudo: sub foo($a is rw) { $a += 1; say $a }; foo(1); rakudo 77f9d7: OUTPUT«2» that directly contradicts S06, which states "Otherwise the signature fails to bind, and this candidate routine cannot be considered for servicing this particular call." Doing otherwise affects the semantics of MMD for allowing overloading based on whether the parameter is an lvalue or not. Somebody who works with rakudo could submit a bug, if it's not in there already? sub foo($a is copy) {...} Is the completely opposite to "is ref", copying the actual value to a new container. Agreed. So, it is not at all complicated, it's just oriented to the Capture, and the capture provides semantics to the call that are not present in any other language I'm aware of. Complex or not in that sense, it complicates things in allowing the value to be changed by another path. I think that is something we want to avoid doing, not present as a feature. Much of my original post concerns the actual meaning, not whether it is considered simple. Since then, I see that it is useful for plural containers. We don't want to copy them! But for items, why do we not even _have_ pass by value? The compiler must assume the worst and can't optimize as well. --John
Re: Why pass by reference?
Em Dom, 2009-06-14 às 15:53 -0500, John M. Dlugosz escreveu: > In Perl 6, the default parameter passing is to make a read-only alias > for the caller's lvalue. This means that the function may not change > the caller's variable, but must track changes to it made by other means. > What is the point? > It is a contrivance to illustrate how the variable can be changed by > other means, and requires a global variable, the same variable passed as > two different parameters, or the variable and a closure that affects the > variable be passed. Actually, it only looks complicated while you think only on the callee side. Because when you take the caller side, you'll note that it builds a capture to send to the call, and the capture is always a reference, so the signature just makes sure that references becomes read-only. To illustrate: my $a = 1; foo($a); In this case, the capture sent must contain a direct reference to the scalar held in '$a', so both signatures with "is ref" or signatures with "is copy" can work. So, if foo has the signature sub foo($a is ref) {...} it will be able to change the scalar outside &foo. If it is sub foo($a) {...} It will be a read-only access to that scalar sub foo($a is rw) {...} Works almost like "is ref", but encloses immutables into a container in order to always provide rw semantics. sub foo($a is copy) {...} Is the completely opposite to "is ref", copying the actual value to a new container. So, it is not at all complicated, it's just oriented to the Capture, and the capture provides semantics to the call that are not present in any other language I'm aware of. daniel
Re: why infix::(Int, Int --> Rat)
HaloO, David Green wrote: On 2008-Dec-4, at 3:08 pm, Mark J. Reed wrote: Using "div" instead of "/" should make it pretty clear that you're disposing of the remainder. I strongly agree to that. Actually you are disposing of the fractional part. I misremembered div vs. idiv, but how standard is it? IIRC, that was in the discussion about the euclidean modulo operation. The final outcome at the time was to have floor semantics by default. I know "div" commonly means int division, but not always. On the one hand, some things you just have to learn; on the other, lots of P6 operators have word-names as well as symbols, and "div" is the obvious way to spell "/" (what else would you call it?). It's not only the name that is at stake but the rest of the specification of the div and mod pair. It is specced to be type specific. E.g. if one implements the Gaussian integers---that is complex numbers with integer coordinates---I would expect div to be *closed* on that type and not lead out of the type as it is prescribed in the Int case. In general I would expect that a type Foo that supports a notion of division implements div and mod with signature :(Foo, Foo --> Foo). Note that the wording of the spec enforces infix::(Num,Complex-->Num) instead of infix::(Num,Complex-->Complex) and I wonder how a Complex is numified. This should be changed, too. The mixed signature cases of div and mod should return the larger of the two types. E.g. :(Rat, Int --> Rat) and :(Num, Int --> Num) as long as Num can hold the result. Does Num in general failover to Rat? A way to get both [quotient and reminder] in one fell swoop would be nice Agreed; though having two different operators seems a bit unperlish. We have the pair of infix (!) operators min, max and the operator minmax that delivers both values in one go. Copying that prior art would simply mean to define divmod. I'm fine with that. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: why infix::(Int, Int --> Rat)
HaloO, Mark J. Reed wrote: Well, respelling it is OK, just not sure how. Python 3 uses // for integer division, but we don't want to open up that can of worms again.. We still haven't used '÷' which is Latin1. But if we use that it should be as infix:<÷>:(Int, Int --> Rat) because this doesn't need to be accompanied with a mod. That allows div on two Ints to return an Int which complies to the general prescription for overloading div and mod homogenously. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: why infix::(Int, Int --> Rat)
On Fri, Dec 5, 2008 at 9:10 AM, David Green <[EMAIL PROTECTED]> wrote: > I misremembered div vs. idiv, but how standard is it? I know "div" commonly > means int division, but not always. True enough. In ANSI C, / already does integer division, but there's also a div() function - the difference there is that div() is guaranteed to round toward zero, whereas the rounding semantics of / is implementation-dependent. > On the one hand, some things you just have to learn; on the other, lots of P6 > operators have > word-names as well as symbols, and "div" is the obvious way to spell "/" > (what else would you > call it?). Well, respelling it is OK, just not sure how. Python 3 uses // for integer division, but we don't want to open up that can of worms again.. >> A way to get both [quotient and reminder] in one fell swoop would be nice > > Would it make sense to include the remainder as a trait on the quotient? Maybe, but it smacks of the old and smelly "0 but true" type hacks to me. > Or return some other special compound type that numifies to the quotient. There could be a special-purpose Quotient type with the desired behavior, but maybe Perl6 would benefit from a generic "stealth list" type, like Lisp's multiple values. Such an object behaves like a simple scalar, even in list context, but if you use the right methods you can access additional values beyond the obvious one. -- Mark J. Reed <[EMAIL PROTECTED]>
Re: why infix::(Int, Int --> Rat)
On 2008-Dec-4, at 3:08 pm, Mark J. Reed wrote: Using "div" instead of "/" should make it pretty clear that you're disposing of the remainder. I misremembered div vs. idiv, but how standard is it? I know "div" commonly means int division, but not always. On the one hand, some things you just have to learn; on the other, lots of P6 operators have word-names as well as symbols, and "div" is the obvious way to spell "/" (what else would you call it?). A way to get both [quotient and reminder] in one fell swoop would be nice Agreed; though having two different operators seems a bit unperlish. Int-div could return two values, but that seems prone to accidentally interpolating unwanted remainders into lists or things like that. Would it make sense to include the remainder as a trait on the quotient? Or return some other special compound type that numifies to the quotient. -David
Re: why infix::(Int, Int --> Rat)
On Thu, Dec 4, 2008 at 3:26 PM, David Green <[EMAIL PROTECTED]> wrote: > Something more explicit like "idiv" was suggested for integral division. > Personally, I'm happy not to have anything special provided for it, on the > grounds that having to say, e.g. "floor($i/$j)", forces you to be blatantly > clear that you're disposing of the remainder and how. Using "div" instead of "/" should make it pretty clear that you're disposing of the remainder. The sorts of calculations that involve heavy use of integer quotients typically also involve heavy use of the remainders, and it's only reasonable that both halves be treated with equal respect in terms of language support. A way to get both in one fell swoop would be nice (e.g. Ruby's Integer#divmod), but at the very least, if we have mod (%), we should have div, too. -- Mark J. Reed <[EMAIL PROTECTED]>
Re: why infix::(Int, Int --> Rat)
On 2008-Dec-4, at 9:42 am, TSa wrote: I remember the state of affairs being that [div] returns an Int Something more explicit like "idiv" was suggested for integral division. Personally, I'm happy not to have anything special provided for it, on the grounds that having to say, e.g. "floor($i/$j)", forces you to be blatantly clear that you're disposing of the remainder and how. -David
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
David Green wrote: > I bet we actually don't disagree much; I'm not really against "ro" -- > I'm just not against "readonly" because of its length. If I were > writing casually, I'd use "rw" and "ro"; formally, I'd use "read only" > and "read/write" (or even "readable and writable"). At an in-between > level, which is where I believe we should be aiming, I think I'd put > "rw" and "read-only". I'm not entirely sure why. Maybe > psychologically, "ro" looks like it could be a word, whereas the > unpronounceable "rw" has to be an abbreviation? Or maybe it's just > because I see "rw" every day in ls output, but "ro" not so much. At any > rate, if I wanted to argue in favour of "ro", I think symmetry (which > you already mentioned) is the strongest argument. Yes indeed, symmetry. It's powerful. Once you see "rw" you're going to assume the other is "ro". Same with "readonly" and "readwrite". And vice-versa and con-versa and any other versas you can think of. rw/readonly is the worst choice. It has that double wammy of bad interfaces: rote learning and counter-intuitiveness. Not only do you have to memorize that "read-only" is "readonly" and "read/write" is "ro" but you have to actively fight your intuition that they should be symmetrical. This generates mistakes. Constant mistakes. rw/ro makes similar things similar. So does readwrite/readonly. Pick one of them. Asymmetry will cause far more problems than too little or too much verbosity. -- ROCKS FALL! EVERYONE DIES! http://www.somethingpositive.net/sp05032002.shtml
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
On 2008 Sep 24, at 17:45, David Green wrote: On 2008-Sep-23, at 5:27 pm, Michael G Schwern wrote: David Green wrote: Happily, brevity often aids clarity. The rest of the time, it should be up to one's editor; any editor worth its salt ought to easily auto-complete "ro" into "readonly". Eeep! The "your IDE should write your verbose code for you" argument! For that one, I brine and roast an adorable hamster. Fair enough. As long as you remember to share with the rest of us!! I would argue that if you need your editor to expand verbose language constructs to make the language usable or to express common idioms, then the language has a design deficiency. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
On 2008-Sep-23, at 5:27 pm, Michael G Schwern wrote: David Green wrote: Happily, brevity often aids clarity. The rest of the time, it should be up to one's editor; any editor worth its salt ought to easily auto-complete "ro" into "readonly". Eeep! The "your IDE should write your verbose code for you" argument! For that one, I brine and roast an adorable hamster. Fair enough. As long as you remember to share with the rest of us!! That's just another way of saying that your language is too verbose for a human to write it without hanging themselves. See also Java. But the problem with Java isn't just that it's too verbose to write; it's that it's too verbose to read, too. Why shouldn't your editor help with verbosity? The amount of typing shouldn't be a main concern in language design, because your editor can mostly compensate for that; there are other, better reasons to decide how verbose something should be. Anyhow, I see where you're going, and I understand the desire for no abbvs. But man, "ro" is pretty damn easy to remember. [1] This is even sillier when you hold it up against all the magic symbols we're supposed to remember. [EMAIL PROTECTED], :name, |$arg, $arg!, $arg?, : $arg. As a bear of limited recall, I sometimes feel a bit overwhelmed by all the stuff there is to remember. I'm certainly not against all abbreviations. I have a deeply ingrained instinct to name my variables x, y, and z, and to name files... x, y, and z. My shell profile is full of one-letter aliases (I don't have time to waste typing 2-char command names!). However experience has taught me the value of more robust names for anything but one-liners. I bet we actually don't disagree much; I'm not really against "ro" -- I'm just not against "readonly" because of its length. If I were writing casually, I'd use "rw" and "ro"; formally, I'd use "read only" and "read/write" (or even "readable and writable"). At an in-between level, which is where I believe we should be aiming, I think I'd put "rw" and "read-only". I'm not entirely sure why. Maybe psychologically, "ro" looks like it could be a word, whereas the unpronounceable "rw" has to be an abbreviation? Or maybe it's just because I see "rw" every day in ls output, but "ro" not so much. At any rate, if I wanted to argue in favour of "ro", I think symmetry (which you already mentioned) is the strongest argument. You're only a beginner once, and if everything is done right for a short time. The rest of your career, you're experienced. Ooh, now that I completely agree with! Software that thinks "user- friendly" means "dumbed-down" drives me nuts. -David
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
Michael G Schwern schwern-at-pobox.com |Perl 6| wrote: John M. Dlugosz wrote: I'm not opposed to having it be "ro", but wonder why he didn't call it that in the first place, so there must be a reason. Nobody's perfect? My other thought is that since parameters are read-only by default it's not thought you'd have to write it much so clarity wins out over brevity, the flip side of Huffamn encoding. But that doesn't work out so good for normal variable declarations. The verbosity (which a hyphen would only make worse) discourages "const-ing", as they say in C. Perhaps he was thinking that 'constant' would be used there. But I agree, it's not the same thing. In C++ I often use const for things that are in 'auto' scope and initialized in the normal flow sequence. Anyway, was 'ro' rejected for some good reason, $Larry, or was it simply considerate as not to waste a short word on a rare use since that's the default (for parameters)? I agree that knowing 'rw', and that being common, if I wanted the other one and didn't use it every day, I would =guess= that it should be called 'ro' to match. --John
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
Michael G Schwern schwern-at-pobox.com |Perl 6| wrote: It should be possible to alias it in your own scope easily. Every time someone replies to a Perl 6 language design nit with "but you can change the grammar" *I* kill a kitten. *meowmmmf* That would not be a change in the grammar. Merely deciding for yourself which names should be short based on your own usage. Since readonly is a class name, the equivalent of a typedef would be used. I think that should be my ::ro ::= readonly; but I have some technical points that still need to be addressed/worked out. --John
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
David Green wrote: > On 2008-Sep-23, at 2:32 pm, Michael G Schwern wrote: >> My other thought is that since parameters are read-only by default >> it's not >> thought you'd have to write it much so clarity wins out over brevity, >> the flip >> side of Huffamn encoding. But that doesn't work out so good for normal >> variable declarations. > > I'd call it straight Huffman encoding, because clarity is what we should > be optimising for. (You read code more than you write it... unless you > never make any mistakes!) Happily, brevity often aids clarity. The > rest of the time, it should be up to one's editor; any editor worth its > salt ought to easily auto-complete "ro" into "readonly". Eeep! The "your IDE should write your verbose code for you" argument! For that one, I brine and roast an adorable hamster. That's just another way of saying that your language is too verbose for a human to write it without hanging themselves. See also Java. Anyhow, I see where you're going, and I understand the desire for no abbvs. But man, "ro" is pretty damn easy to remember. [1] This is even sillier when you hold it up against all the magic symbols we're supposed to remember. [EMAIL PROTECTED], :name, |$arg, $arg!, $arg?, :$arg. If we expect the user to remember what all that means, I think they can figure out "$thing is ro". It would be incoherent to take a corner of the language design and suddenly pretend otherwise. The mark of a great interface is not that you know what everything is the first time you encounter it, but when you remember what it is the second time. The first time what's important is the user knows where to find instructions and how to play with the device. It should have a strong analogy and mesh clearly with the surrounding devices "ro" and "rw" have a strong analogy with the common read-only and read-write terms and they mesh with each other. Once this is known to the user, the second time it will be "obvious". You're only a beginner once, and if everything is done right for a short time. The rest of your career, you're experienced. Instead of dumbing the language down for beginners, the trick is to turn beginners into experienced programmers as quickly and painlessly as possible. Now I've totally digressed. -- s7ank: i want to be one of those guys that types "s/j&jd//.^$ueu*///djsls/sm." and it's a perl script that turns dog crap into gold.
Re: Why no "is ro"? (Re: Subroutine parameter with trait and default.)
On 2008-Sep-23, at 2:32 pm, Michael G Schwern wrote: My other thought is that since parameters are read-only by default it's not thought you'd have to write it much so clarity wins out over brevity, the flip side of Huffamn encoding. But that doesn't work out so good for normal variable declarations. I'd call it straight Huffman encoding, because clarity is what we should be optimising for. (You read code more than you write it... unless you never make any mistakes!) Happily, brevity often aids clarity. The rest of the time, it should be up to one's editor; any editor worth its salt ought to easily auto-complete "ro" into "readonly". -David
Re: Why does p6 always quote non-terminals?
On Tue, Jun 27, 2006 at 09:04:27PM -0700, Dave Whipp wrote: > I was reading the slides from PM's YAPC::NA, and a thought drifted into > my mind (more of a gentle alarm, actually). One of the examples struck me: > > rule parameter_list { [ , ]* } > > Its seems common in the higher layers of a grammar that there are more > non-terminal than terminals in each rule, so maybe the current "rule" > isn't properly huffmanized (also, the comma seemed some-how out of place > -- most symbols will need to be quoted if used in similar context). A > more traditional YACC/YAPP coding of the > rule would be: > > rule parameter_list { parameter [ "," parameter ]* } > > Is there a strong reason (ambiguity) why every nonterminal needs to be > quoted (or could we at least have a form ( C< rule:y {...} > ) where > they are not)? I see this as increasingly important when rules are used > to process non-textual streams. In these cases every token will need to > be quoted using angle brackets, which at that point might become little > more than line noise. If we flipped the idea of "meta" such that only literals needed quoting for rules, I'd expect that for consistency sake we'd need to do the same for the other regexy things. For non-grammatical regexes, that would start to grate real quick I think. But maybe that's a good dividing line--for m//, s///, and rx// you don't quote your literals, and to match a rule, you use the regular assertion syntax. But *within* a regex, token, or rule you need to quote your literals because all non-quoted, wordish text is assumed to be an assertion. Nah, that's as far as I'll entertain the thought because there is a major show stopper--rules may be parameterized. In the universe of undelimited assertions, how are you to pass parameters to the assertion? Use parens as in a subroutine call? (rules are special subs after all) Sounds like it invites confusion. Or would you mandate that to get the effect of parameterized rules, you should really be using a closure anyway? So, I guess that answers your question ... If not, I'm sure someone else will come along and give something more definitive :-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: why no negative (auto reversed) ranges?
On Mon, Mar 20, 2006 at 01:26:03PM +0100, TSa wrote: : HaloO, : : S03 does explicitly disallow auto-reversed ranges. : And I'm not sure if the upto operator has a downto : cousin where ^-4 == (-1, -2, -3, -4) returns a list : that is suitable for indexing an array from the back. : Why is that so? I suppose because nobody else wanted it yet. If we were to add such an operator opposite to ^4, I suspect it'd be v-4 or some such, but maybe negative version numbers are more useful. :-) But Huffman coding says that symmetry *should* be broken when a thing is used much more frequently than its opposite. : With negative ranges, negative array and list length : becomes a logical extension and .reverse just flips : the sign of the array. But I know that code snippets : like 'if @array < 10 {...}' then need to be "upgraded" : to explicitly take the abs: 'if abs @array < 10 {...}' : which is good documentation but somewhat inconvenient. People would certainly rebel. : OTOH, using contentless arrays as kind of integer becomes : even more attractive ;) Though you can always use $array as an arrayless content... : Is there a .reversed property for arrays, lists and : ranges that allows to query the direction of growth? Not with a standard array. : And is .reverse working lazily with respect to the : list or array and just flips this property? .reverse isn't a mutator. It merely presents a reversed view of whatever, and is hopefully as lazy as the underlying object allows in reverse. (To reverse an array in place we'd use .=reverse.) Larry
Re: Why submethods
HaloO, Luke Palmer wrote: On 10/29/05, Damian Conway <[EMAIL PROTECTED]> wrote: So we need a mechanism that is externally (i.e. from a class interface point-of-view) a subroutine, but internally has the features of a method (i.e. has an invocant). Since it's externally sub-like but internally method-like, we call this useful construct a submethod. Wouldn't the semantics fall out naturally from 1) beeing a scoped 'our sub' 2) the topic type ^_ of the topic item $_ beeing contra-variantly defined to the concrete class type? Number 1) assumes that a sub definition in a class without my or our gets a sig of :(Any $_ = CALLER<$_>, [EMAIL PROTECTED]). The property 2) ensures the non-inheritance indirectly because an overriding sub in a derived class would permit the Foo::bar application. That is Luke's example could read class Foo { has $.data; # creates rw accessor our sub bar # sig is :( void: Foo $_, [EMAIL PROTECTED] ) { $.data = 23; # Not allowed outside of class scope? # .data = 23; # Or force through accessor? } } my $foo = Foo.new; $foo.bar; # binds $_ := $foo and all member refs through $foo, # then calls Foo::bar with empty @_ say $foo.data; # prints 23 For most of that, doesn't a private method suffice? When it doesn't, I feel uneasy about: class Foo { submethod bar() { ... } } my $foo = Foo.new; $foo.bar; If that's externally sub-like, why does it look so much like a method? Isn't looking like a method more a feature of the dot syntax than anything else? Does bar($foo) cause the same perception? If my signature assumptions above are correct then an argumentless bar call without "invocant" is a "too few arguments" error. If I understand the term 'package dispatch' of Sam Vilain correctly the package that contains class Foo would maintain a dispatch into class scoped subs depending on the immediate class---is that the eigenclass?---of the "invocant". That is we could define class Bar { has $.data; # creates rw accessor our sub bar # sig is :( void: Bar $_, [EMAIL PROTECTED] ) { $.data = 42; } } in addition to the Foo from above and then sub package_dispatched ($x) { $x.bar } my $bar = Bar.new; package_dispatched( $foo ); say $foo.data; # 23 package_dispatched( $bar ); say $bar.data; # 42 But I can understand that Damian thinks that spelling 'our sub' as 'submethod' is good documentation and not a subtlety. OTOH, a 'my sub' is not considered too subtle. Actually a 'has sub foo ...' form might be an alternate spelling for 'has &.foo = sub ...' and we can drop the strange word 'submethod' and nicely unify all code types. That is sub = package dispatch on void method = unary dispatch on single invocant item type multi = symmetric multi dispatch on invocant tuple type or left biased successive single dispatch on invocant list or a mix of both --
Re: Why submethods
On Sat, 2005-10-29 at 17:30 -0400, Stevan Little wrote: > However, it could also be that the creator of Foo did not intend for > subclasses to be able to "Just Work", and that the whole idea of Foo > is to do a "Template Method" style pattern in which subclasses must > implement the &help_process_data submethod in order for things to > work. This is an entirely valid usage for a submethod, and in fact, I > think it is an excellent way for implementing the "Template Method" > pattern. Hmm. I think I much prefer; method you_must_implement { ... } or a trait, perhaps method you_must_implement is required; I think that methods disappearing out of scope in subclasses is just Nasty And Wrong™, for the exact reason Luke outlined. Side-effects like that are just asking for trouble IMHO. > It is also possible that we could bring over the role idea of > "required methods" and have the same basic principle relate to > classes and submethods. If marked as such, a submethod is required to > be implemented by a subclass, or class composition fails. > I think that could be a useful feature which would allow very safe > re-use along those lines. Good point, which is why the "is required" as above would be better. It seems to me that there's an awful lot of specification going into these varied types of methods. Method Type Purpose DispatchVisibility ---|--|---| $.method()| external API| MMD | all $.submethod() | refactoring | package | single $:private() | internal API| package | single I must admit I also fail to see the difference between submethods and private methods. And what do I use for methods that I don't want to make visible to "the world"? Perhaps a more useful definition might be that submethods are only available on $?SELF (and are still subject to normal dispatch). Sam.
Re: Why submethods
> "DC" == Damian Conway <[EMAIL PROTECTED]> writes: DC> But factoring method implementations out into a subroutines is DC> also extremely annoying, because a subroutine doesn't provide the DC> internal conveniences that a method does. In particular, it DC> doesn't have an invocant and so you can't call $.attrs or DC> &.methods. Instead you would have to pass the invocant to the DC> subroutine call as an argument and then call accessors and methods DC> explicitly through that argument. DC> So we need a mechanism that is externally (i.e. from a class DC> interface point-of-view) a subroutine, but internally has the DC> features of a method (i.e. has an invocant). Since it's externally DC> sub-like but internally method-like, we call this useful construct DC> a submethod. so it sounds like to me these are methods private to this class. they can't found by any other class (via inheritance). so what is the external sub interface for? we can see the need for private worker methods and even p5 has a convention of marking such subs with a leading _. uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org
Re: Why submethods
Luke, On Oct 29, 2005, at 3:42 PM, Luke Palmer wrote: Another thing that scares me with the "utility sub" point of view follows: class Foo { method process_data($data) { $.help_process_data($data); } submethod help_process_data($data) { $data+1; } } Foo.new.process_data(0); # 1 class Bar is Foo { } Bar.new.process_data(0); # dies[1] What??? I didn't change anything yet! Why does it die? (This is the first principle in the journal entry you quoted) This is true, but I think that it is easily rectified. A submethod is said to have an implicit next METHOD unless $?SELF.class =:= $?CLASS I think we could add onto that and say that in addition to checking the invocant's class, we could also check the calling context, and do like we do with private methods, and allow things like this to Just Work. However, it could also be that the creator of Foo did not intend for subclasses to be able to "Just Work", and that the whole idea of Foo is to do a "Template Method" style pattern in which subclasses must implement the &help_process_data submethod in order for things to work. This is an entirely valid usage for a submethod, and in fact, I think it is an excellent way for implementing the "Template Method" pattern. It is also possible that we could bring over the role idea of "required methods" and have the same basic principle relate to classes and submethods. If marked as such, a submethod is required to be implemented by a subclass, or class composition fails. I think that could be a useful feature which would allow very safe re-use along those lines. Anyway, just my 2 cents. Stevan
Re: Why submethods
On 10/29/05, Damian Conway <[EMAIL PROTECTED]> wrote: > So we need a mechanism that is externally (i.e. from a class interface > point-of-view) a subroutine, but internally has the features of a method (i.e. > has an invocant). Since it's externally sub-like but internally method-like, > we call this useful construct a submethod. Hmm, thanks. For most of that, doesn't a private method suffice? When it doesn't, I feel uneasy about: class Foo { submethod bar() { ... } } my $foo = Foo.new; $foo.bar; If that's externally sub-like, why does it look so much like a method? Another thing that scares me with the "utility sub" point of view follows: class Foo { method process_data($data) { $.help_process_data($data); } submethod help_process_data($data) { $data+1; } } Foo.new.process_data(0); # 1 class Bar is Foo { } Bar.new.process_data(0); # dies[1] What??? I didn't change anything yet! Why does it die? (This is the first principle in the journal entry you quoted) Let's presume that I want to extend Foo by adding a method completely unrelated to process_data, and I would like its behavior to stay the same for process_data. How would I do that? Luke [1] Well, it wouldn't, since for Liskov sanity we require that a method of the same name already exists. Let's say that Foo's parent class implemented "submethod help_process_data($data) { die }".
Re: Why $.?
On Mon, 2005-05-16 at 04:02 -0600, Luke Palmer wrote: > I am currently failing to see the need for a distinction between $. > and $: . The only difference is in whether accessors are *generated*; Not at all! There are numerous differences as described in A12: * The attribute gets a "private" trait * "we basically force people to document the private/public distinction every place they reference $:x" -A12 * Prevents access to class variables (e.g. using "our") from outside the class. * %$obj notation includes private attributes when inside, but not when outside the class * Private variables use a different dispatcher.
Re: Why lexical pads
On Sep 25, 2004, at 10:27 PM, Larry Wall wrote: On Sat, Sep 25, 2004 at 10:01:42PM -0700, Larry Wall wrote: : We've also said that MY is a pseudopackage referring to the current : lexical scope so that you can hand off your lexical scope to someone : else to read (but not modify, unless you are currently compiling : yourself). However, random subroutines are not allowed access : to your lexical scope unless you specifically give it to them, : with the exception of $_ (as in 1 above). Otherwise, what's the : point of lexical scoping? Note that this definition of MY as a *view* of the current lexical scope from a particular spot is exactly what we already supply to an C, so we're not really asking for anything that isn't already needed implicitly. MY is just the general way to invoke the pessimization you would have to do for an C anyway. A mildly interesting thought would be for C to take additional parameters to make explicit what's visible to the eval'd code--essentially making the running of the code like a subroutine call. So the traditional C would turn into something like "eval $str, MY", but you could also have "eval $str, $x, $y", or just "eval $str", which would execute in an "empty" lexical scope. That would allow additional optimizations at compile-time (and make MY the sole transporter of lexical scope), since not every C would need what MY provides, but even more importantly, it would allow the programmer to protect himself against accidentally referencing a lexical he didn't intend, just because the code in his string coincidentally used the same variable name. More optimization opportunities, and more explicit semantics. But that's now a language issues, so I'm cc-ing this over to there. JEff
Re: Why do users need FileHandles?
On Fri, Aug 13, 2004 at 10:53:02AM +0100, Nicholas Clark wrote: > On Wed, Aug 11, 2004 at 03:25:20PM -0700, David Storrs wrote: > > On Sat, Aug 07, 2004 at 03:55:21PM +0100, Nicholas Clark wrote: > > > > However, Acme::Intraweb hasn't been updated for a while, whereas CPANPLUS > > > has, so I'm not sure if it still works. Both are by Jos Boumans. > > > > Urrmmm...ok, I'm sure I'm just being dense here, but I do not see your > > point. Can you unpack it for me? > > IIRC you said "it would be good if perl6 could do this" > > My point was that Jos wrote a module for perl5 that could do this last year. > However, I suspect if you attempt to install it from CPAN today it will > break, because it's not been updated to cope with changes to CPANPLUS, > upon which it depends. Ah. Thanks, that makes it more more clear. I'll look into Acme::Intraweb. --Dks
Re: Why do users need FileHandles?
On Wed, Aug 11, 2004 at 03:25:20PM -0700, David Storrs wrote: > On Sat, Aug 07, 2004 at 03:55:21PM +0100, Nicholas Clark wrote: > > However, Acme::Intraweb hasn't been updated for a while, whereas CPANPLUS > > has, so I'm not sure if it still works. Both are by Jos Boumans. > > Urrmmm...ok, I'm sure I'm just being dense here, but I do not see your > point. Can you unpack it for me? IIRC you said "it would be good if perl6 could do this" My point was that Jos wrote a module for perl5 that could do this last year. However, I suspect if you attempt to install it from CPAN today it will break, because it's not been updated to cope with changes to CPANPLUS, upon which it depends. Nicholas Clark
Re: Why do users need FileHandles?
On Sat, Aug 07, 2004 at 03:55:21PM +0100, Nicholas Clark wrote: > On Sat, Jul 24, 2004 at 02:50:18PM -0700, David Storrs wrote: > > #!/usr/bin/perl6 > > #!/usr/bin/perl I stated perl6 explicitly to be, well, explicit. > > #use warnings; # Note that I am NOT explicitly using these > > #use strict; > > > > { no 'warnings'; no 'strict'; # These must be explicitly turned off... > > no installation_security; # or this would throw warning & error > > use Acme::Intraweb; > > > use SomeModule; # > > use OtherModule;# > > use Foo;# If these are not installed, > > use Bar;# they will be auto-installed. > > use Baz;# > > use Jaz;# > > } > > > However, Acme::Intraweb hasn't been updated for a while, whereas CPANPLUS > has, so I'm not sure if it still works. Both are by Jos Boumans. Urrmmm...ok, I'm sure I'm just being dense here, but I do not see your point. Can you unpack it for me? --Dks
Re: Why do users need FileHandles?
On Sat, Jul 24, 2004 at 02:50:18PM -0700, David Storrs wrote: > Definitely. On the other hand...I find myself wondering if we could > offer a pragma so that people can have the option if they want it. > For example: > > > #!/usr/bin/perl6 #!/usr/bin/perl > #use warnings; # Note that I am NOT explicitly using these > #use strict; > > { no 'warnings'; no 'strict'; # These must be explicitly turned off... > no installation_security; # or this would throw warning & error use Acme::Intraweb; > use SomeModule; # > use OtherModule;# > use Foo;# If these are not installed, > use Bar;# they will be auto-installed. > use Baz;# > use Jaz;# > } However, Acme::Intraweb hasn't been updated for a while, whereas CPANPLUS has, so I'm not sure if it still works. Both are by Jos Boumans. Nicholas Clark
Re: Why do users need FileHandles?
On Sun, Jul 18, 2004 at 08:20:25PM -0700, David Storrs wrote: > Race condition: what if something deletes the file between the moment > that perl closes the file and the moment that it re-opens it? Is > there a cross-platform way to do an atomic reopen? No. To the best of my knowledge there isn't a way on Unix to reopen the same file descriptor read-write using an existing read-only file descriptor. Therefore there can't be a cross-platform way to do it, as it's not even possible everywhere. You can't store the filename of the file you originally opened, as someone is free to move it and replace it with a symlink to a critical system file, to try 0wn your system. Opening needs to be done once at open time. Nicholas Clark
Re: Why do users need FileHandles?
Luke Palmer wrote: It's likely that CPAN will have a Bundle::EYEWTIBWATA. [1] [1] Everything You Ever Wanted To Install But Were Afraid To Ask EYEWTIBWATL eye-witty-bwattle .. But Were Always Too Lazy
Re: Why do users need FileHandles?
On Sat, 24 Jul 2004, Brent 'Dax' Royal-Gordon wrote: > Hmm...maybe this could be done for Perl 5... I guess it could be relatively easily done by means of the [EMAIL PROTECTED] feature present in recent perls... Michele -- > A mathematically-inclined glove-fetishist [...] What a wonderful introduction to a puzzle! - Richard Heathfield in sci.math, "Re: Gloves in the dark"
Re: Why do users need FileHandles?
Brent 'Dax' Royal-Gordon <[EMAIL PROTECTED]> writes: >> hopefully without dependencies on external non-Perl things like gcc). > > Don't think it'll be possible for modules that have C components, I'm really hoping Perl6 will be sufficiently powerful that C components won't be needed or wanted. >> Oh, and here's me resisting the urge to suggest that use ought to >> automatically install from the CPAN anything that isn't present, as >> a core behavior right out of the box. > > Security nightmare. *shrug* Running untrusted code (Perl or otherwise) on your system that you haven't examined first is inherently a security nightmare. If it wants to download things from wherever and install them it can (assuming that you're running under an account that has privileges to install or at least has its own install location just for that account), and that's not all it can do, not by a longshot. Or did you mean that someone might compromise the CPAN in order to compromise all the systems downloading stuff from it? Again, that's already true now, in theory. (More likely, a single mirror would be compromised. One would hope it would be discovered quickly.) However, I wasn't serious about making use automatically install. Well, not altogether serious. CPAN.pm or something like it is really almost good enough, and what it lacks can be added in without any change to the behavior of use. Installing once before you use is really not a very large burden in the scheme of things. I was, however, very pleased to hear that we won't have to reinstall half the contents of the CPAN every time we upgrade Perl or Parrot. Definitely looking forward to that improvement. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,"[EMAIL PROTECTED]/ --";$\=$ ;-> ();print$/
Re: Why do users need FileHandles?
Larry Wall wrote: Sounds like you're confusing #3 with #4. Larry Could be. Does 3 mean at install time, you down load the latest of the 'supported' packages from the CPAN alike or is it more like versioned snapshots? (Possibly yet to be decided?) It's the idea of a standard library being open to daily change that scaring me most at the moment. If that's not likely, then me other concerns, well, aren't. Dan
Re: Why do users need FileHandles?^H^H^H^H^HCore modules?
On 7/23/04, Luke Palmer wrote: Not necessarily. Glop, on which I'm doing a presentation at OSCON (have to plug it sometime ;-), "Game Language on Perl, you say? Goodness, what's that??" Sorry. Got tired of English. =) There's a lot of stuff like that. Way too much to include in a distribution. That's why we're going to distribute close to nothing with Perl 6 in order to force vendors to install a decent module suite. It's likely that CPAN will have a Bundle::EYEWTIBWATA. [1] Well, it certainly makes sense to me to have perl itself as minimal as possible, as long as there's an "official" bundle so that you can make reasonable assumptions about what "everyone" has. I think with a sensible auto-inclusion system (really, they're quite nice--if it can be done at compile time), we'll be able to keep things out of core and still make them feel like they're in core. There's something to be said for modules like that. Yup, something very good. And there's our second system syndrome. Fortunately, Perl is embracing its second system syndrome. Works for me. Anyway, Perl already got a complete rewrite for P5, right? So this would actually be Third System Syndrome, and thus we've nothing to worry about. (I'm not worried, anyway.) -David "impatient, maybe, but not worried" Green
Re: Why do users need FileHandles?
On Sun, Jul 25, 2004 at 11:41:14PM -0500, Dan Hursh wrote: : Larry Wall wrote: : : >On Sun, Jul 25, 2004 at 01:32:29AM -0500, Dan Hursh wrote: : >: >2. Really core. This is the sort of "standard library". Just the most : >: >essential bits that are required for general Perl usability. You'd : >: >probably include most of these, even in a "trimmed down" release, such : >: >as an OS installer : >: : >: What most venders will ship. : > : >Which is basically why we are planning not to produce one of these. : >I think we should concentrate on 1 and 3. : : I know. In that case, I think venders are liable to be lazy or peeved : and ship option 1 or worse, nothing. Is the answer really supposed to : be CPAN or no library? Is there a plan to at least have stable : snapshots of CPAN? Sorry to be a pest on this, but the implications : actually scare me about things I didn't worry about before because I had : confidence that they would be addressed in 'the library'. Maybe I just : need to sit and meditate some more. Sounds like you're confusing #3 with #4. Larry
Re: Why do users need FileHandles?
Larry Wall wrote: On Sun, Jul 25, 2004 at 01:32:29AM -0500, Dan Hursh wrote: : >2. Really core. This is the sort of "standard library". Just the most : >essential bits that are required for general Perl usability. You'd : >probably include most of these, even in a "trimmed down" release, such : >as an OS installer : : What most venders will ship. Which is basically why we are planning not to produce one of these. I think we should concentrate on 1 and 3. I know. In that case, I think venders are liable to be lazy or peeved and ship option 1 or worse, nothing. Is the answer really supposed to be CPAN or no library? Is there a plan to at least have stable snapshots of CPAN? Sorry to be a pest on this, but the implications actually scare me about things I didn't worry about before because I had confidence that they would be addressed in 'the library'. Maybe I just need to sit and meditate some more. Dan
Re: Why do users need FileHandles?
On Sun, Jul 25, 2004 at 01:32:29AM -0500, Dan Hursh wrote: : >2. Really core. This is the sort of "standard library". Just the most : >essential bits that are required for general Perl usability. You'd : >probably include most of these, even in a "trimmed down" release, such : >as an OS installer : : What most venders will ship. Which is basically why we are planning not to produce one of these. I think we should concentrate on 1 and 3. Larry
Re: Why do users need FileHandles?
Aaron Sherman wrote: Do any C++ programmers consider the STL to be anything other than "in core" even though it's not part of the compiler, and with at least GCC, it's distributed as a separate component? Do any C programmers consider strlen or sprintf to be outside of the core? It's part of the ANSI C *STANDARD LIBRARY*, not the ANSI C spec. Does anyone really ship compilers w/o a standard library. I don't care if they are in separate tar/rpm/etc files. As long as they go together. Does anyone other than a spec writer document the language minus the library? Define "outside of the core", please. I'm sticking to my definition involving the camel book and packing them together. If I was going to make a recommendation (which I guess I am), I would suggest having 4 layers of library: 1. Really-really core (the stuff you can't write the other stuff without), and is probably all built-ins in Parrot. The toy for the researcher. Not much of a tool yet, but fun. 2. Really core. This is the sort of "standard library". Just the most essential bits that are required for general Perl usability. You'd probably include most of these, even in a "trimmed down" release, such as an OS installer What most venders will ship. 3. The "extended core". The modules from some CPAN-alike that are considered to be "supported Perl extensions" In Perl 5, I think of libwww-perl and libnet this way, but making an official distinction lets users decide what modules to rely on in code that will have to be "updatable" for 5 years. What my site IT people might get around to installing in the site image for perl 6 during the perl 8.2 time frame. 4. The CPAN-like grab-bag of goodies. The pre-pre-alpha modules that work on two-ish platforms. Many of which were in the same state a year ago. OK, maybe I'm over stating that. But I do think that if perl 6.X.Y is not accompanied by a packaged perl library version I.J.K that is as documented, tested and portable as the language, then most people won't see any modules outside of those shipped in the perl6 source archive. I hate that. To put it another, if a library version is not done in concert with a given language version, then either users can't rely on the availability or exact behavior of any function beyond the core package. Each vendor with have to make their own library, and test it. Overlooking the duplication of effort for each vender, given that vendors seem to have enough trouble packaging remotely recent versions of perl 5, and given that different venders might not choose the same selection of modules or that they might not pick compatible versions of the same modules, this just looks like a black eye waiting to happen. This all assumes that venders put the effort into it at all. If not the venders, do you expect each perl programmer to have root -like access? I could have missed the chapter, but I didn't see a good way for a perl programmer to install from CPAN to his home directory and use it seemlessly with an OS shipped perl install. So far my experience do it with CPAN haven't gone well anyone. Maybe each user could compile his own interpreter from source. That's how I had my best luck. I still get lots of errors on CPAN installs. It's kind of a pain. Besides, things should be run out of a user's home directory in a production environment. I know this isn't a new problem, but it is why I didn't use Net::FTP at work until about a year ago. They just didn't install the bugger and I didn't have control of the site image. The same goes for perl5.6 for that matter, so I might not see perl6 at work before I retire in some 20 years from now and this will all be moot. I just think there ought to be a decent library. It worked well for python and java (even inspite of how java's library is designed!) and it would put perl ahead of the likes of C and C++ (which I believe have far too skinny standard libraries to be useful). I also think that library needs to be tested as well as perl6. It needs to be equally portable as well. (Yes I know there are limits there. If TK won't run on my watch, I'll understand. I'm sure the watch probably won't support all the core features either.) And a given version of the library needs to 'go together' with a given version of the language. The gcc folks may not tar the C++ standard lib up with the compiler, but there tends to be a given version of one to use with a given version of the other. Of course, maybe there are other solutions. Maybe I'm wrong for thinking it ought to be a requirement. Maybe I just need to work at a shop with more perl biggots on staff. Dan
Re: Why do users need FileHandles?
On Sat, Jul 24, 2004 at 04:51:52PM -0700, Brent 'Dax' Royal-Gordon wrote: : This would require 'cpan' to parse the script with a modified grammar : that noted all the 'use's (and 'require's, I guess), then install each : module. Or something like that. : : Hmm...maybe this could be done for Perl 5... If the main impediment is security, you have to know what the checksums of the modules you're looking for are, and that means you have to know exactly what version you're looking for (or have info on all versions). Which implies that you might need something like Perl 6's ability to (attempt to) use two different versions of the same module simultaneously. But don't let me discourage you from playing with it in Perl 5... :-) Larry
Re: Why do users need FileHandles?
David Storrs wrote: #!/usr/bin/perl6 #use warnings; # Note that I am NOT explicitly using these #use strict; { no 'warnings'; no 'strict'; # These must be explicitly turned off... no installation_security; # or this would throw warning & error use SomeModule; # use OtherModule;# use Foo;# If these are not installed, use Bar;# they will be auto-installed. use Baz;# use Jaz;# } use FrobNitz; # If this is not installed, the script fails.
Re: Why do users need FileHandles?
On Sat, Jul 24, 2004 at 02:23:10PM -0700, Brent 'Dax' Royal-Gordon wrote: > Jonadab the Unsightly One wrote: > > >Oh, and here's me resisting the urge to suggest that use ought to > >automatically install from the CPAN anything that isn't present, as a > >core behavior right out of the box. > > Security nightmare. Definitely. On the other hand...I find myself wondering if we could offer a pragma so that people can have the option if they want it. For example: #!/usr/bin/perl6 #use warnings; # Note that I am NOT explicitly using these #use strict; { no 'warnings'; no 'strict'; # These must be explicitly turned off... no installation_security; # or this would throw warning & error use SomeModule; # use OtherModule;# use Foo;# If these are not installed, use Bar;# they will be auto-installed. use Baz;# use Jaz;# } use FrobNitz; # If this is not installed, the script fails.
Re: Why do users need FileHandles?
Jonadab the Unsightly One wrote: Surely, at bare minimum, there must be something included in core to allow things that are not in core to be easily installed, the equivalent of what CPAN.pm is for Perl5 (hopefully even better, and I believe that's the current plan--the core will include CPAN, LWP, and not much else. hopefully without dependencies on external non-Perl things like gcc). Don't think it'll be possible for modules that have C components, although Parrot's Native Call Interface ought to make a lot of XS uses obsolete. (With NCI, Parrot provides opcodes to load a shared library, then retrieve functions from it and treat them like normal Parrot subs--all without writing any C. That includes converting arguments and return values from Parrot types to C types.) Oh, and here's me resisting the urge to suggest that use ought to automatically install from the CPAN anything that isn't present, as a core behavior right out of the box. Security nightmare. -- Brent "Dax" Royal-Gordon <[EMAIL PROTECTED]> Perl and Parrot hacker Oceania has always been at war with Eastasia.
Re: Why do users need FileHandles?
JOSEPH RYAN <[EMAIL PROTECTED]> writes: > Well, that's what all of the ruckus is about. There is a strong > leaning towards including *no* builtin modules with the core. Surely, at bare minimum, there must be something included in core to allow things that are not in core to be easily installed, the equivalent of what CPAN.pm is for Perl5 (hopefully even better, and hopefully without dependencies on external non-Perl things like gcc). I could live with very little else in core, but the means to install whatever is not in core is essential; that's the thing that allows everything else to be made optional -- because it can be installed easily enough. Oh, and here's me resisting the urge to suggest that use ought to automatically install from the CPAN anything that isn't present, as a core behavior right out of the box. -- $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,"[EMAIL PROTECTED]/ --";$\=$ ;-> ();print$/
Re: Why do users need FileHandles?
I define "outside the core" as "anything that isn't packaged with Perl itself". Things you'd define as "part of the language." I/O stuff, threading stuff, standard types, builtin functions, etc. And yeah, most of that stuff will be written natively in C, PIR, or be part of parrot itself. I think there will also be a much larger "standard library" that will be bundled separately, which would contain your libwww, libnet, and other widely/commonly used modules. The way I think of it is kinda like installing something with the windows installer: you can check to install the "minimal" or standard version, the "full" version (which would be perl + the "standard library"), or you could even check "custom" and choose what you'd like to install. And, of course, everything else would just be on the CPAN. - Joe
Re: Why do users need FileHandles?
On Thu, 2004-07-22 at 19:21, JOSEPH RYAN wrote: > Well, that's what all of the ruckus is about. > There is a strong leaning towards including *no* > builtin modules with the core. So, that leaves only > the builtin functions and classes as "the core", and > so what is "in core" becomes a pretty big deal. I don't think so. Do any C++ programmers consider the STL to be anything other than "in core" even though it's not part of the compiler, and with at least GCC, it's distributed as a separate component? Do any C programmers consider strlen or sprintf to be outside of the core? It's part of the ANSI C *STANDARD LIBRARY*, not the ANSI C spec. Define "outside of the core", please. If I was going to make a recommendation (which I guess I am), I would suggest having 4 layers of library: 1. Really-really core (the stuff you can't write the other stuff without), and is probably all built-ins in Parrot. 2. Really core. This is the sort of "standard library". Just the most essential bits that are required for general Perl usability. You'd probably include most of these, even in a "trimmed down" release, such as an OS installer 3. The "extended core". The modules from some CPAN-alike that are considered to be "supported Perl extensions" In Perl 5, I think of libwww-perl and libnet this way, but making an official distinction lets users decide what modules to rely on in code that will have to be "updatable" for 5 years. 4. The CPAN-like grab-bag of goodies. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Perl Toolsmith http://www.ajs.com/~ajs/resume.html
Re: Why do users need FileHandles?
David Green writes: > >So making it "go in the core" may just mean that it's > >on the list of recommended modules to install. > > Does that mean having to "use Some::Module" to use it? Not necessarily. Glop, on which I'm doing a presentation at OSCON (have to plug it sometime ;-), makes use of an idiom where you don't have to 'use' everything you want. That's because the small module quanta used in the design would make the first 50 lines of your program 'use' statements. I should expect a similar thing in Perl 6 if traits are going to be packaged up in their own modules. > If so, that partially defeats the point of having a magical DWIMy > shorthand in the first place. (And if not -- then I guess it's > irrelevant to most end users whether it's "really" a module or not.) Here's one defining feature of core: if $feature.has_shorthand { $feature.in_core = !$feature.requires_use; } Sorry. Got tired of English. > I think stringified filehandles should be "core" -- i.e. always > available without having to install ... There's a lot of stuff like that. Way too much to include in a distribution. That's why we're going to distribute close to nothing with Perl 6 in order to force vendors to install a decent module suite. It's likely that CPAN will have a Bundle::EYEWTIBWATA. [1] > In fact, my general attitude towards random feature $foo is: useful > to lots of people who want to use it + not harmful to people who > don't = put it all in the core. And there's our second system syndrome. Fortunately, Perl is embracing its second system syndrome. I think with a sensible auto-inclusion system (really, they're quite nice--if it can be done at compile time), we'll be able to keep things out of core and still make them feel like they're in core. There's something to be said for modules like that. Luke [1] Everything You Ever Wanted To Install But Were Afraid To Ask
Re: Why do users need FileHandles?
Luke Palmer <[EMAIL PROTECTED]> wrote on July 22, 2004: Even more philosophical is "what is core?" I believe the standard definition is "Anything I want to use goes in the core; anything everyone else wants goes wherever there's room left over." ... So making it "go in the core" may just mean that it's on the list of recommended modules to install. Does that mean having to "use Some::Module" to use it? If so, that partially defeats the point of having a magical DWIMy shorthand in the first place. (And if not -- then I guess it's irrelevant to most end users whether it's "really" a module or not.) I think stringified filehandles should be "core" -- i.e. always available without having to install or include anything -- because they're exactly the sort of easy thing that Perl is supposed to make trivial. And of course, since there are plenty of cases where pretending a file is just a string won't work, Perl should also make the harder cases easy by including plain old 'open' in The Core as well. [Not] using one doesn't in any way get in the way of using the other, and they'd both be commonly used, so I think they both need to be readily available. In fact, my general attitude towards random feature $foo is: useful to lots of people who want to use it + not harmful to people who don't = put it all in the core. -David "at least until starting perl begins to take longer than your coffee break" Green
Re: Why do users need FileHandles?
- Original Message - From: Dan Hursh <[EMAIL PROTECTED]> Date: Thursday, July 22, 2004 3:07 pm Subject: Re: Why do users need FileHandles? > Luke Palmer wrote: > > > JOSEPH RYAN writes: > > > >>- Original Message - > >>From: David Storrs <[EMAIL PROTECTED]> > >>Date: Monday, July 19, 2004 5:04 pm > >>Subject: Re: Why do users need FileHandles? > >> > >> > >>>Second, I would suggest that it NOT go in a library...this is > >>>reasonably serious under-the-hood magic and should be > integrated into > >>>the core for efficiency. > >> > >>How would integrating this in the core make it more efficient? Core > >>or not, I'd see something like this being implemented with a custom > >>pmc. I tend to think of inclusion in the core being more of a > >>philosophical decision... > > > > > > Yes, it is. Whether or not a PMC is in the core, it should be > equally> fast. That is, unless Parrot is allowed intimate > knowledge of the PMC's > > internals. And there are very few (any?) PMCs that possess this > > property even now. > > > > Even more philosophical is "what is core?" I get the impression > that> Larry is trying to blur the distinction between core and non- > core as > > much as possible. So making it "go in the core" may just mean > that it's > > on the list of recommended modules to install. > > > > Luke > > How about we say "in core" means it packaged with the perl6 source > and > covered in the coresponding camel & lama books. :) Well, that's what all of the ruckus is about. There is a strong leaning towards including *no* builtin modules with the core. So, that leaves only the builtin functions and classes as "the core", and so what is "in core" becomes a pretty big deal. - Joe
Re: Why do users need FileHandles?
Luke Palmer wrote: JOSEPH RYAN writes: - Original Message - From: David Storrs <[EMAIL PROTECTED]> Date: Monday, July 19, 2004 5:04 pm Subject: Re: Why do users need FileHandles? Second, I would suggest that it NOT go in a library...this is reasonably serious under-the-hood magic and should be integrated into the core for efficiency. How would integrating this in the core make it more efficient? Core or not, I'd see something like this being implemented with a custom pmc. I tend to think of inclusion in the core being more of a philosophical decision... Yes, it is. Whether or not a PMC is in the core, it should be equally fast. That is, unless Parrot is allowed intimate knowledge of the PMC's internals. And there are very few (any?) PMCs that possess this property even now. Even more philosophical is "what is core?" I get the impression that Larry is trying to blur the distinction between core and non-core as much as possible. So making it "go in the core" may just mean that it's on the list of recommended modules to install. Luke How about we say "in core" means it packaged with the perl6 source and covered in the coresponding camel & lama books. :) Dan
Re: Why do users need FileHandles?
- Original Message - From: Luke Palmer <[EMAIL PROTECTED]> Date: Thursday, July 22, 2004 2:48 pm Subject: Re: Why do users need FileHandles? >> JOSEPH RYAN writes: > > > > How would integrating this in the core make it more efficient? Core > > or not, I'd see something like this being implemented with a custom > > pmc. I tend to think of inclusion in the core being more of a > > philosophical decision... > > Yes, it is. Whether or not a PMC is in the core, it should be equally > fast. That is, unless Parrot is allowed intimate knowledge of the > PMC'sinternals. And there are very few (any?) PMCs that possess this > property even now. But why would Parrot need to see the PMC's internals? I was thinking more along the lines of a class just looked just like PerlString, except with different, uh, stuff in the pmc class methods. > Even more philosophical is "what is core?" I get the impression that > Larry is trying to blur the distinction between core and non-core as > much as possible. So making it "go in the core" may just mean > that it's > on the list of recommended modules to install. You're probably right. Every time I think about the idea of "there will be no core modules", a conservative part of me becomes scared out of its mind, and that conservative side wants to riot. But, once I think about it a little more, that riot quickly gets beaten down with thought batons like: "Sure, there won't be any core modules, but most of what Perl5's core will be seamlessly built into the language anyways, and not having other core modules will free everyone from having to continue to use crusty old interfaces like Exporter and File::Find". But, going back to the original topic, something like this kind of I/O abstraction should still be some sort of *module* (core or not), not a core *behaivor*.
Re: Why do users need FileHandles?
JOSEPH RYAN writes: > - Original Message - > From: David Storrs <[EMAIL PROTECTED]> > Date: Monday, July 19, 2004 5:04 pm > Subject: Re: Why do users need FileHandles? > > > Second, I would suggest that it NOT go in a library...this is > > reasonably serious under-the-hood magic and should be integrated into > > the core for efficiency. > > How would integrating this in the core make it more efficient? Core > or not, I'd see something like this being implemented with a custom > pmc. I tend to think of inclusion in the core being more of a > philosophical decision... Yes, it is. Whether or not a PMC is in the core, it should be equally fast. That is, unless Parrot is allowed intimate knowledge of the PMC's internals. And there are very few (any?) PMCs that possess this property even now. Even more philosophical is "what is core?" I get the impression that Larry is trying to blur the distinction between core and non-core as much as possible. So making it "go in the core" may just mean that it's on the list of recommended modules to install. Luke
Re: Why do users need FileHandles?
- Original Message - From: David Storrs <[EMAIL PROTECTED]> Date: Monday, July 19, 2004 5:04 pm Subject: Re: Why do users need FileHandles? > Second, I would suggest that it NOT go in a library...this is > reasonably serious under-the-hood magic and should be integrated into > the core for efficiency. How would integrating this in the core make it more efficient? Core or not, I'd see something like this being implemented with a custom pmc. I tend to think of inclusion in the core being more of a philosophical decision... - Joe
Re: Why do users need FileHandles?
--- chromatic <[EMAIL PROTECTED]> wrote: > On Mon, 2004-07-19 at 14:04, David Storrs wrote: > > > Second, I would suggest that it NOT go in a library...this is > > reasonably serious under-the-hood magic and should be integrated > into > > the core for efficiency. > > You must have amazingly fast hard drives. I mount /tmp on swap. My "hard drive" is bitchin fast. =Austin
Re: Why do users need FileHandles?
On Mon, 2004-07-19 at 14:04, David Storrs wrote: > Second, I would suggest that it NOT go in a library...this is > reasonably serious under-the-hood magic and should be integrated into > the core for efficiency. You must have amazingly fast hard drives. -- c
Re: Why do users need FileHandles?
"David Storrs" <[EMAIL PROTECTED]> wrote ># Print file, inefficiently > print $default.readline for 1..$default.lines; print it efficiently: print $default; > # Append a line > $rw .= "an additional line\n"; $rw ~= "\n" unless $rw.chars[-1] eq "\n"; $rw ~= "an additional line\n"; > # New line is visible through $rw > print $rw.lines[-1]; # (*) > > # last line not yet visible through $default because it was > # added by external handle--just like in a tail -f, we > # need to move file pointer manually > $default.seek(File.current_pos); I don't think the manual sync is really needed: name the method something a bit more neutral: $default.refresh; > (*) The .lines[-1] semantic is feasible if we are willing to tolerate > very slow performance (at least the first time; it could cache the > locations of $/ after scanning and dump the cache if $/ changes), the > fact that it wouldn't work on all files (/dev/null, /dev/zero, etc), > and a few other issues. The performance here could depend on the encoding. If the file is ASCII, then we don't need to worry about multi-byte characters, so the under-the-hood implementation could follow a heuristic such as "seek to 1000 bytes from end of file: scan forward for "\n". If none found, then go back further. Otherwise continue to scan to find last "\n" in the file". Dave.
Re: Why do users need FileHandles?
"David Storrs" <[EMAIL PROTECTED]> wrote (apparently may days ago): > Race condition: what if something deletes the file between the moment > that perl closes the file and the moment that it re-opens it? Is > there a cross-platform way to do an atomic reopen? I'm not sure if you need to close it before you reopen it. You can usually open the file a second time before closing it. (the only issue would be if you were using mandatory locks, in which case you're probably a power-user using the FileHandle module, anyway). I don't know about the cross-platform aspect, but a similar scenario is that the file changes on disk while we've using it. In most modern editors, the user is asked: "file changed on disk: reload file? (Y/N)" when this happens. I'd like to think that we could arrange for an exception to be thrown (resumable, of course) if this happens when we've mapped a file into an object. Dave.
Re: Why do users need FileHandles?
On Tue, 20 Jul 2004 07.25, Austin Hastings wrote: > --- Rod Adams <[EMAIL PROTECTED]> wrote: > > If I cannot open a file for writing (permissions, out of space, > > write locked, etc), I want to know the instant I attempt to open it > > as such, _not_ when I later attempt to write to it. Having all > > these features available to open as arguements seems a much better > > idea to me. It's "Open a file with these specifications", not "Open > > a file, and then apply these specifications to it". > > But why? Do you really open files and then perform an hour of work > before attempting to use them? I'll argue that's not the normal case; > rather, the normal case is something like > > open or die ... > other_stuff() > while (...) { > print ... > } > close > > and the intervening delay (other_stuff) is negligible in wall-clock > terms: when a failure occurs, the user hears about it immediately. The issue isn't about how long it takes other_stuff() to run. The issue is whether other_stuff does something irrevocable that shouldn't have been done if the file couldn't be opened. Imagine a double-entry bookkeeping system that needs to atomically update two files at once. You don't want to discover that one file is inaccessible after you've already written the transaction to the other file. You'd end up circumventing the DWIMmery by writing empty strings to the files just to make sure they exist: $handle1 = open "file1"; $handle2 = open "file2"; print $handle1: ""; # Did it really open? print $handle2: "transaction 2" or die; print $handle1: "transaction 1" or die; I contend that however many examples you could come up with that make "open-on-write" look neat, it's possible to contrive just as many examples that make "open-on-write" look awkward. Which, IMHO, is a perfect argument for putting this functionality into a library where those who want to use it, will. It's probably time to leave all of this up to @Larry to concoct something that everyone's happy with. -- Debbie Pickett http://www.csse.monash.edu.au/~debbiep [EMAIL PROTECTED]
Re: Why do users need FileHandles?
On Mon, Jul 19, 2004 at 03:37:12PM -0500, Rod Adams wrote: > I think part of the "mental jam" (at least with me), is that the > read/write, exclusive, etc, are very critical to the act of opening the > file, not only an after the fact restriction on what I can do later. If > I cannot open a file for writing (permissions, out of space, write > locked, etc), I want to know the instant I attempt to open it as such, > _not_ when I later attempt to write to it. Having all these features > available to open as arguements seems a much better idea to me. It's > "Open a file with these specifications", not "Open a file, and then > apply these specifications to it". > > I do admit there is merit to your abstraction system, but IMO, it > belongs in a library. > > -- Rod Adams First, why are they incompatible? Offer both, let TIMTOWTDI sort it out. Second, I would suggest that it NOT go in a library...this is reasonably serious under-the-hood magic and should be integrated into the core for efficiency. --Dks
Re: Why do users need FileHandles?
On Sun, Jul 18, 2004 at 08:39:09PM -0500, Rod Adams wrote: > Case 1: > So I wanted to do a read/write scan, so I create my TextFile, start > reading in data, so the file is opened for reading. Then, I come to the > part where I want to update something, so I do a write command. Suddenly > the file has to be closed, and then re-opened for read and write. And > all my buffers, file pointers and the like are reset, (though curable > with very careful planning), leaving me in a bad spot. Better if I could > just declare the file open for read and write at open time. > > Case 2: > I meant to use some critical data file in read-only mode, and accidently > use a write command somewhere I didn't mean to, and silently just > clobbered /etc/passwd. Better if I could have just opened the file read > only, and trigger an error on the write command. > > What design philosophy would you envision TextFile taking to handle both > these cases in a coherent fashion? my $default is TextFile("/tmp/foo"); my $rw is TextFile("/tmp/foo")is rw; my $ro is TextFile("/etc/passwd") is const; $default will have the semantics that Dave has been describing--initially opened read-only, then re-opened as r/w if you write to it. $rw is explicitly r/w. Attempts to write to it succeed, and do not require an implicit re-open. $ro is explicitly ro. Attempts to write to it fail, and do not perform an implicit re-open. Given the above code, here is some usage: print $ro.readline(); # Prints first line $ro = "boom!";# THROWS AN ERROR (assume error was trapped somehow) # Print file, inefficiently print $default.readline for 1..$default.lines; # Append a line $rw .= "an additional line\n"; # New line is visible through $rw print $rw.lines[-1]; # (*) # last line not yet visible through $default because it was # added by external handle--just like in a tail -f, we # need to move file pointer manually $default.seek(File.current_pos); # Can't re-open for write mode, since another handle # already has the write-lock. Throw error to that effect. $default = "oops, this doesn't work"; (*) The .lines[-1] semantic is feasible if we are willing to tolerate very slow performance (at least the first time; it could cache the locations of $/ after scanning and dump the cache if $/ changes), the fact that it wouldn't work on all files (/dev/null, /dev/zero, etc), and a few other issues. > I don't think anyone (read: Larry) has declared exactly what the > capabilities of the default file handle object are yet. It seems me that > you could very well get what you want. True on both counts. --Dks
Re: Why do users need FileHandles?
On Sun, Jul 18, 2004 at 05:36:58PM -0700, Dave Whipp wrote: > truncate Vs append would be infered from usage (assign => truncate). One > might be able to infer read Vs write in a similar way -- open the file based > on the first access; re-open it (behind the scenes) if we write it after > reading it. You might run into issues if the user starts doing seeks before writing...although maybe not, since that just means that we need to (behind the scenes) remember the current location of the seek pointer when re-opening. Exclusivity issue: when it re-opens, should it lock before opening? Race condition: what if something deletes the file between the moment that perl closes the file and the moment that it re-opens it? Is there a cross-platform way to do an atomic reopen? FWIW, although I'm not sure it will work in practice, I really like this idea of eliminating FileHandles as a user-level object. > my Str $text is file("foo.txt") does no_follow_symlink does no_create; > > Do we have an antonym for C? How about 'no'? my Str $text is file("foo.txt") no follow_symlink no create; Other options (not all good): without not dont doesnt --Dks
Re: Why do users need FileHandles?
On Sun, 18 Jul 2004, Andrew Shitov wrote: > DW> my $text is TextFile("/tmp/bar"); > DW> $text = "hello"; # writes, truncates > DW> $text ~= ", world\n"; # appends > > DW> $text.print "again\n"; # for old-times sake > > Anyhow we still need $text.flush() or $text.close() methods. ^^ Not necessarily if lexically scoped, just as in (recent enough) perl5... Michele -- >A question out of curiousity: who is this Green of Green's functions? >Is he the same person of Green's theorem? :) Yes. He was also an early environmentalist; hence the current phrases "green" this and "green" that... - David C. Ullrich on sci.math, thread "Who is Green?"
Re: Why do users need FileHandles?
On Mon, Jul 19, 2004 at 07:40:01PM -0500, Rod Adams wrote: : TMTOWTDI can apply here, I believe. You give me my way, I'll give you : yours. Leave me open with all my parameters, and you can have your list : of file abstraction classes. I could see having those classes part of : core, if there's enough support for them, and then something simple like : "use Files;" to turn them on. The reality will be somewhere in the middle--or maybe it's off to one side or the other. I don't think anyone in this discussion (including me) has a complete grasp of how roles will change the way OO is done in Perl 6. When you open a filehandle, or create a string, or something in between, you're just making an object with various capabilities. With roles, you don't even necessarily have to specify a particular class to construct. You can view an "open" statement as a request for an object that fulfills certain roles, and let Perl search for and/or compose an appropriate class. You don't have to care about some artificial, predefined OO hierarchy because roles do an end run around the use of subclassing for a task that subclassing isn't good for. File handles are a classic case of "the god object" syndrome. With roles, I think we can have our OO cake, and maybe even bear to eat it too. Larry
Re: Why do users need FileHandles?
Austin Hastings wrote: --- Rod Adams <[EMAIL PROTECTED]> wrote: I think part of the "mental jam" (at least with me), is that the read/write, exclusive, etc, are very critical to the act of opening the file, not only an after the fact restriction on what I can do later. But why? I'd argue that this ties in to the verbose/exception discussion of a few weeks back: if the operation fails, let it pass an exception up the chain that can be caught and resolved (once) at a high level. Guess I'm still in the open "foo" or die; mentality. Given that file processing is so common in Perl, it deserves a high huffman scoring. The best way to do that is to abstract the operations away and replace them with a single declaration of intent. That declaration, of course, becomes a front-end for C or heavily optimized parrot. In a heavily OO paradigm, there would be a swarm of subclasses of type stream -- istream, ostream, iostream, exclusive_iostream, whatever. Is my $file = append_text_stream "foo.txt"; really so much better than my $file = open ">>foo.txt"; I'd strongly prefer having a few, extremely flexible, orthoganal, and complete tools, that DWIM the common case for me, than to have to sort through a long list of classes to get what I'm looking for. Now, there's nothing stopping open from returning an object of class FileHandle::OStream::Text::Exclusive or whatever. And that object can have lots of useful methods to play with. But let me describe to open what type of file I want, and let it sort it out. Another part of me that resists this is that I don't necessarily agree with a heavy OO paradigm. I've written several large projects in both a OO environment, and non-OO. I have almost always found the OO paradigms force me to convert what I wanted to do into something much more painful than the non-OO methods. It typically breaks down into the moment you want to do something to an object that the class designer did not take into account, you basically have to either rebuild parts of the object heirarchy from scratch, or get into really ugly things like declaring everything a friend of each other, or having to many accessor method calls you can't help but slow the whole program down. Also, my experience is that when following a heavy OO paradigm, you often fall into the trap of "There is only one way to do it. Why would you ever want another?" Is all OO bad? of course not. I use for several things, on a frequent basis. Is something that's OO necessarily better than something that's not? Despite the rumors from the Java crowd, no. So while I embrace Perl6 having extremely strong OO capabilities, I will argue strongly against it taking over the language. If I cannot open a file for writing (permissions, out of space, write locked, etc), I want to know the instant I attempt to open it as such, _not_ when I later attempt to write to it. Having all these features available to open as arguements seems a much better idea to me. It's "Open a file with these specifications", not "Open a file, and then apply these specifications to it". But why? Do you really open files and then perform an hour of work before attempting to use them? I'll argue that's not the normal case; rather, the normal case is something like open or die ... other_stuff() while (...) { print ... } close and the intervening delay (other_stuff) is negligible in wall-clock terms: when a failure occurs, the user hears about it immediately. It's often that I'll open a file to make sure I can save my results, then begin some process that is better measured in hours than seconds, and then begin outputting. It's not infrequent for me to have a list of five or six open statements at the start of a long process, and then close them all at the end. I do admit there is merit to your abstraction system, but IMO, it belongs in a library. I think rather that the abstraction should be the default, and the individual "I don't trust Perl" functions should be available as separate entry points if the user explicitly requires them. TMTOWTDI can apply here, I believe. You give me my way, I'll give you yours. Leave me open with all my parameters, and you can have your list of file abstraction classes. I could see having those classes part of core, if there's enough support for them, and then something simple like "use Files;" to turn them on. Just my 2¢. -- Rod
Re: Why do users need FileHandles?
--- Rod Adams <[EMAIL PROTECTED]> wrote: > Dave Whipp wrote: > > > > > Your case 2 is easy: "my Str $passwds is File("/etc/passwd") is > > const". With that, we might even catch your error at compile > > time. > > > >>/file/open/ and we're back where we started. > > > > Except that we've lost a layer of abstraction: the programmer > > manipulates a file's contents, not its accessor. Text files > > would be just an implementation of strings. No need to learn/use > > a different set of operators. Want to read bytes: use $str.bytes. > > Graphemes: $str.graphs. Also, we use the existing access control > > mechanisms ("is rw", "is const", instead of inventing new ones to > > pass to the C function as named-args). > > I think part of the "mental jam" (at least with me), is that the > read/write, exclusive, etc, are very critical to the act of opening > the file, not only an after the fact restriction on what I can do > later. But why? I'd argue that this ties in to the verbose/exception discussion of a few weeks back: if the operation fails, let it pass an exception up the chain that can be caught and resolved (once) at a high level. Given that file processing is so common in Perl, it deserves a high huffman scoring. The best way to do that is to abstract the operations away and replace them with a single declaration of intent. That declaration, of course, becomes a front-end for C or heavily optimized parrot. In a heavily OO paradigm, there would be a swarm of subclasses of type stream -- istream, ostream, iostream, exclusive_iostream, whatever. The suggestion is that we can derive an equally expressive vocabulary using barewords and the occasional adverbial modifier. > If I cannot open a file for writing (permissions, out of space, > write locked, etc), I want to know the instant I attempt to open it > as such, _not_ when I later attempt to write to it. Having all > these features available to open as arguements seems a much better > idea to me. It's "Open a file with these specifications", not "Open > a file, and then apply these specifications to it". But why? Do you really open files and then perform an hour of work before attempting to use them? I'll argue that's not the normal case; rather, the normal case is something like open or die ... other_stuff() while (...) { print ... } close and the intervening delay (other_stuff) is negligible in wall-clock terms: when a failure occurs, the user hears about it immediately. > I do admit there is merit to your abstraction system, but IMO, it > belongs in a library. I think rather that the abstraction should be the default, and the individual "I don't trust Perl" functions should be available as separate entry points if the user explicitly requires them. =Austin
Re: Why do users need FileHandles?
Dave Whipp wrote: Under the hood, I don't really care, as long as it works (and is sufficiently efficient). There are obvious implementations that might be a bit inefficient on the first iteration (e.g. close and reopen). Quite frankly, the number of times I open unstructured files in rd/wr mode in a typical program can be measured on the fingers of one foot! If I want to do a R-M-W operation then I do like -i, and use a tmp file. Maybe the hypothetical TextFile object would do the same (by default). If I want to micromanage the actual access to the file object, then I'd be happy to c a module that lets me manipulate file handles directly. I just don't see that as the common case. Your case 2 is easy: "my Str $passwds is File("/etc/passwd") is const". With that, we might even catch your error at compile time. /file/open/ and we're back where we started. Except that we've lost a layer of abstraction: the programmer manipulates a file's contents, not its accessor. Text files would be just an implementation of strings. No need to learn/use a different set of operators. Want to read bytes: use $str.bytes. Graphemes: $str.graphs. Also, we use the existing access control mechanisms ("is rw", "is const", instead of inventing new ones to pass to the C function as named-args). I think part of the "mental jam" (at least with me), is that the read/write, exclusive, etc, are very critical to the act of opening the file, not only an after the fact restriction on what I can do later. If I cannot open a file for writing (permissions, out of space, write locked, etc), I want to know the instant I attempt to open it as such, _not_ when I later attempt to write to it. Having all these features available to open as arguements seems a much better idea to me. It's "Open a file with these specifications", not "Open a file, and then apply these specifications to it". I do admit there is merit to your abstraction system, but IMO, it belongs in a library. -- Rod Adams
Re: Why do users need FileHandles?
"Rod Adams" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Case 1: > So I wanted to do a read/write scan, so I create my TextFile, start > reading in data, so the file is opened for reading. Then, I come to the > part where I want to update something, so I do a write command. Suddenly > the file has to be closed, and then re-opened for read and write. And > all my buffers, file pointers and the like are reset, (though curable > with very careful planning), leaving me in a bad spot. Better if I could > just declare the file open for read and write at open time. > > Case 2: > I meant to use some critical data file in read-only mode, and accidently > use a write command somewhere I didn't mean to, and silently just > clobbered /etc/passwd. Better if I could have just opened the file read > only, and trigger an error on the write command. > > What design philosophy would you envision TextFile taking to handle both > these cases in a coherent fashion? Firstly, I must say that if you phase a problems in terms of a solution, then its not surprising that the solution looks a bit your problem statement (E.g. "start reading in data" -- the important thing is to process it, not to read it) From a users point of view, you're just doing string manipulations: for $text.lines { /:w ^myfield (\d+)/ and $1 = "X" x $1.chars } Under the hood, I don't really care, as long as it works (and is sufficiently efficient). There are obvious implementations that might be a bit inefficient on the first iteration (e.g. close and reopen). Quite frankly, the number of times I open unstructured files in rd/wr mode in a typical program can be measured on the fingers of one foot! If I want to do a R-M-W operation then I do like -i, and use a tmp file. Maybe the hypothetical TextFile object would do the same (by default). If I want to micromanage the actual access to the file object, then I'd be happy to c a module that lets me manipulate file handles directly. I just don't see that as the common case. Your case 2 is easy: "my Str $passwds is File("/etc/passwd") is const". With that, we might even catch your error at compile time. > s/file/open/ and we're back where we started. Except that we've lost a layer of abstraction: the programmer manipulates a file's contents, not its accessor. Text files would be just an implementation of strings. No need to learn/use a different set of operators. Want to read bytes: use $str.bytes. Graphemes: $str.graphs. Also, we use the existing access control mechanisms ("is rw", "is const", instead of inventing new ones to pass to the C function as named-args). Alan Cooper, in his book on human-computer interface design, makes the case that files are an obsolete abstraction for users. I guess I'm making the same argument for programmers. Dave.
Re: Why do users need FileHandles?
Dave Whipp wrote: "Rod Adams" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] Uhm, my impression was that most of the "huffmanization" discussion was centered around declaring a file handle to be read only, write only, read-write, exclusive, etc. Masking the file handle with what basically amounts to a file handle subclass like you describe will still need to allow the user to specify all those attributes. So you would still need to allow: my $text is TextFile("/tmp/foo.txt" :rw ); my $text is TextFile("/tmp/foo.txt" :excl ); my $text is TextFile("/tmp/foo") is rw; my $text is TextFile("/tmp/foo") is const; truncate Vs append would be infered from usage (assign => truncate). One might be able to infer read Vs write in a similar way -- open the file based on the first access; re-open it (behind the scenes) if we write it after reading it. Case 1: So I wanted to do a read/write scan, so I create my TextFile, start reading in data, so the file is opened for reading. Then, I come to the part where I want to update something, so I do a write command. Suddenly the file has to be closed, and then re-opened for read and write. And all my buffers, file pointers and the like are reset, (though curable with very careful planning), leaving me in a bad spot. Better if I could just declare the file open for read and write at open time. Case 2: I meant to use some critical data file in read-only mode, and accidently use a write command somewhere I didn't mean to, and silently just clobbered /etc/passwd. Better if I could have just opened the file read only, and trigger an error on the write command. What design philosophy would you envision TextFile taking to handle both these cases in a coherent fashion? :excl would probably need to be an option, but is not sufficiently common to be agressively huffmanised: my $text is TextFile("foo.txt", :no_overwrite); my $text is TextFile("foo.txt") does no_overwrite; ot that having wrapper classes for file handles is a bad idea, it just doesn't relate to what I saw being discussed. Oh, and "TextFile" should be spelled "IO::File::Text", IMHO. Possibly, but would need a hufmanized alias for common use. Possible just "file": s/file/open/ and we're back where we started. my Str $text is file("foo.txt") does no_follow_symlink does no_create; my $text = open("foo.txt" :no_follow_symlink :no_create); I don't think anyone (read: Larry) has declared exactly what the capabilities of the default file handle object are yet. It seems me that you could very well get what you want. -- Rod Adams
Re: Why do users need FileHandles?
"Rod Adams" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Uhm, my impression was that most of the "huffmanization" discussion was > centered around declaring a file handle to be read only, write only, > read-write, exclusive, etc. Masking the file handle with what basically > amounts to a file handle subclass like you describe will still need to > allow the user to specify all those attributes. > > So you would still need to allow: > my $text is TextFile("/tmp/foo.txt" :rw ); > my $text is TextFile("/tmp/foo.txt" :excl ); my $text is TextFile("/tmp/foo") is rw; my $text is TextFile("/tmp/foo") is const; truncate Vs append would be infered from usage (assign => truncate). One might be able to infer read Vs write in a similar way -- open the file based on the first access; re-open it (behind the scenes) if we write it after reading it. :excl would probably need to be an option, but is not sufficiently common to be agressively huffmanised: my $text is TextFile("foo.txt", :no_overwrite); my $text is TextFile("foo.txt") does no_overwrite; > Not that having wrapper classes for file handles is a bad idea, it just > doesn't relate to what I saw being discussed. > Oh, and "TextFile" should be spelled "IO::File::Text", IMHO. Possibly, but would need a hufmanized alias for common use. Possible just "file": my Str $text is file("foo.txt") does no_follow_symlink does no_create; Do we have an antonym for C? Dave.
Re: Why do users need FileHandles?
Dave Whipp wrote: I was thinking about the discussions about the "open" function, and of the capabilities of "string"s. Given that we'll have things like $str.bytes, etc. It doesn't seem a stretch to suggest that we could also have $str.lines. Once we have that, and also a level of pervasive laziness (lazy evaluation), it seems to me that we don't really need user-visible file handles for most of the common operations on files. Imagine: my $text is TextFile("/tmp/foo.txt"); for $text.lines { ... } I guess what I'm saying is that if we can make tying the standard idiom, then we can relax you huffmanization worries for things like the "open" function. Uhm, my impression was that most of the "huffmanization" discussion was centered around declaring a file handle to be read only, write only, read-write, exclusive, etc. Masking the file handle with what basically amounts to a file handle subclass like you describe will still need to allow the user to specify all those attributes. So you would still need to allow: my $text is TextFile("/tmp/foo.txt" :rw ); my $text is TextFile("/tmp/foo.txt" :excl ); Not that having wrapper classes for file handles is a bad idea, it just doesn't relate to what I saw being discussed. Oh, and "TextFile" should be spelled "IO::File::Text", IMHO. -- Rod Adams
Re: Why do users need FileHandles?
"Andrew Shitov" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > DW> my $text is TextFile("/tmp/bar"); > DW> $text = "hello"; # writes, truncates > DW> $text ~= ", world\n"; # appends > > DW> $text.print "again\n"; # for old-times sake > > Anyhow we still need $text.flush() or $text.close() methods. I'd argue that these are only rarely needed. Even with Perl5 filehandles, I rarely find myself needing to close a file. Garbage collection does the job adequately. The case of "flush" is more interesting. It is really used for two purposes: forcing the ram-contents to be stored on disk, so it can be recovered even id the process dies violently, is one use; ensuring a message is sent so it can be received by a consumer is the other. Even if both these roles have the same underlying implementation, we might want to abstract them differently. C is as good a name as any for the sync-to-disc usage; but the second might be better named C -- and probably wouldn't be on a "text" object, anyway. I'm not sure that the details of inter-thread messaging have been decided yet, but I'd think that a common messaging paradigm would apply. Dave.
Re: Why do users need FileHandles?
DW> my $text is TextFile("/tmp/bar"); DW> $text = "hello"; # writes, truncates DW> $text ~= ", world\n"; # appends DW> $text.print "again\n"; # for old-times sake Anyhow we still need $text.flush() or $text.close() methods. -- Андрей, [EMAIL PROTECTED]
Re: Why C needs work
At 11:02 AM -0800 1/23/03, Michael Lazzaro wrote: Yes, no doubt so, and good point. I think I should make it clear that my speculation on somehow unifying C and C is _not_ an attempt to gut A4, because I like A4 quite a lot. I'm just thinking out loud about how we could _extend_ A4 in one particular way. This, I think, is where I beg and plead--given how much effort it takes for Larry to get new apocalypses out, I'd really rather not make it so we want him to revisit old decisions while an apocalypse is in progress. (Yeah, for the week or two after one comes out, sure, just not when he's working on a new one) Either he'll be ignoring perl6-language (if I have to ask Robert to unsubscribe him :) or he'll be thrashing between the new stuff and revisiting the old stuff. Yeah, it's selfish, but I can't get perl 6 implemented if you guys keep distracting Larry so he never gets the darned thing designed. :) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Why C needs work
Michael Lazzaro writes: > > Think, think. What do these things have in common? > > # known from A4 > > for @a, sub ($x) {...} # primitive spelling > for @a -> $x {...} # pointy sub, looks great > > map {...} @a # old-style map syntax > map sub ($x) {...}, @a # primitive spelling > map -> $x {...} @a # pointy sub? Oof, kinda opaque, here. suppose that -> ( ... ) { ... } #(1) is prefix way of saying { ... } is sig( ... )#(2) so "->" is a more like prefix form of "is signature" then alias for "sub" . so suppose that . I can even assume that another way to say (2) can be { ... } ( ... ) <- #(3) so -> and <- are just another ways to say "is signature" before or after the block . so now we have ( no piping operators !) #nonempty signature for @a -> $x { ... } ; map { ... } $x <- @a #empty signature for @a -> { ... } ; map { ... } <- @a I am not sure but it seems that parser can handle both (1) and (3) . the problem with (3) is that parser will have to wait till it see <- to realize what is going on this is meaningfull ( but probably not very usefull ) now sub ->( $x ) { ... } ; sub { ... } ( $x ) <-; > > # purely speculative alternatives > > for @a : sub ($x) {...}# indirect object syntax > for @a : -> ($x) {...} # not as good as before > > map @a : {...} # indirect object syntax > @a -> map {...}# L2R now , if we make totally crazy assumtion that signature ->( ... ) is allowed to be separated by something from its block then this works @a ->($x) map {...} #==> @a .map { ... } is sig($x) @a -> map {...} #==> @a .map { ... } is sig( ) and if several signature specifications for the same block will just concatenate to form a single concatenated signature then this will work : for @a -> ( $x ), @b -> ( $y ) { ... } is equivalent to for zip(@a,@b) -> ($x,$y) { ... } Here "for" will have to dispatch the signature pieces to the block . and it also be able to notice the "stream separator" in the signature because it gets signature in 2 pieces explicitely. so ->( $x ) ->( $y ) { ... } or { ... } is sig( $x ) is sig( $y ) is same as { ... } is sig( $x ,$y ) so > map {...} <- @a# R2L (these look great) this is postfix (empty) signature specification > > # But the combination of both meanings doesn't work at all. > # (pointy sub doesn't work as well with indirect-object or > # pipe-like syntax, and vice versa) > > map @a : -> $x {...} # indirect + pointy sub > map @a : sub ($x) {...}# arguably better looking? > > @a -> map sub ($x) {...} # objpipe + primitive spelling (OK) > @a -> map -> ($x) {...}# objpipe + pointy sub (very NOT OK) > @a -> map ($x) {...} # 'implied' sub? (Nope, NOT OK) > > I mean, it _looks_ like there should be way to put those together by > making '->' mean something more encompassing than pointy sub. There's > some beautifully expressive syntax in there. > > Think, think... > > MikeL > > >
Re: Why C needs work
On Wednesday, January 22, 2003, at 07:40 PM, Thomas A. Boyer wrote: I have a strong suspicion that this possibility was carefully considered by {LW, DC, ...} (that's set notation, not a code block :) before the Apocalypse 4 "pointy sub" syntax (and the for-loop syntax using it) was promulgated. And that it was Yes, no doubt so, and good point. I think I should make it clear that my speculation on somehow unifying C and C is _not_ an attempt to gut A4, because I like A4 quite a lot. I'm just thinking out loud about how we could _extend_ A4 in one particular way. I keep thinking there has to be a way to extend the pointy sub syntax to just *do* the kind of piping we keep talking about. I like the <~ and ~> proposal, but it's true that they imply a symmetry that isn't really there. I like pointy sub, but it's true it's a win only in limited circumstances. Think, think. What do these things have in common? # known from A4 for @a, sub ($x) {...} # primitive spelling for @a -> $x {...} # pointy sub, looks great map {...} @a # old-style map syntax map sub ($x) {...}, @a # primitive spelling map -> $x {...} @a # pointy sub? Oof, kinda opaque, here. # purely speculative alternatives for @a : sub ($x) {...}# indirect object syntax for @a : -> ($x) {...} # not as good as before map @a : {...} # indirect object syntax @a -> map {...}# L2R map {...} <- @a# R2L (these look great) # But the combination of both meanings doesn't work at all. # (pointy sub doesn't work as well with indirect-object or # pipe-like syntax, and vice versa) map @a : -> $x {...} # indirect + pointy sub map @a : sub ($x) {...}# arguably better looking? @a -> map sub ($x) {...} # objpipe + primitive spelling (OK) @a -> map -> ($x) {...}# objpipe + pointy sub (very NOT OK) @a -> map ($x) {...} # 'implied' sub? (Nope, NOT OK) I mean, it _looks_ like there should be way to put those together by making '->' mean something more encompassing than pointy sub. There's some beautifully expressive syntax in there. Think, think... MikeL
Re: Why C needs work (was Re: L2R/R2L syntax)
On Wednesday, January 22, 2003, at 11:42 AM, Kwindla Hultman Kramer wrote: Michael Lazzaro writes: And it provides a very visual way to define any pipe-like algorithm, in either direction: $in -> lex -> parse -> codify -> optimize -> $out; # L2R $out <- optimize <- codify <- parse <- lex <- $in; # R2L It's clear, from looking at either of those, that they represent data pipes. Both are even clearer than the equiv: $out = $in.lex.parse.codify.optimize; One question: How does this approach to building a pipe-lining syntax square with the "alternative spelling of the assignment operator" feature that's been discussed elsewhere in this thread? It's not immediately obvious to me how the post-/pre-invocant operation "becomes" an assignment at the end of the chain. In other words, are the first two code fragments above really equivalent to the third? They're equiv only if make a rule saying they're equiv, like what Damian was proposing for <~ and ~>. (Except this isn't quite the same thing as Damian was proposing, which is why I'm not using <~ and ~> to describe it.) You could for example use: $x <- 5; ...to do assignment (if you're into that sort of thing) if the '<-' was overloaded to do the right thing when it was piping 'to' a simple variable. Even $x <- $y <- 5; could work, since the R2L chain would do the same as $x = $y = 5; So short answer, it squares pretty well with an alternative spelling for assignment, for persons that would like to do that. They'd be equiv iff we defined the operators such that they were. MikeL
Re: Why C needs work (was Re: L2R/R2L syntax)
Thomas A. Boyer writes: > Michael Lazzaro wrote: > > *Now*, what to do about the fantastic magic that pointy-sub provides? > > The _spectacular_ win would be if we could just recognize an optional > > parameter list as part of a block. > > > > map @a : ($a,$b) {...} # params + closure = closure with params? > > for @a : ($a,$b) {...} > > > > So that anywhere you had a closure, you could put a paramlist in front > > of it. Not likely we could get that to work, since best-case scenario > > it would probably barf on $a and $b being undefined before it ever got > > to the closure. But it might be possible, at the expense of some > > parser complexity. > I sertainly can do it like taht : map @a : {...} is sig($a,$b) for @a : {...} is sig($a,$b) or map @a : sub($a,$b) {...} for @a : sub($a,$b) {...} or @a ~> map sub($a,$b) {...} It also seems that the difference between map and for may be twisted as follows : map apply particular closure to several ( possibly one ) array , while for takes particular array ( which may have possibly passed some pre -zipping/-weaving) and apply pour it to several ( possibly one ) closures. if we assume that for can accept as its last arguments sequence one or more closures than with the existing pointy sub meaning of -> we can have for @a -> ( $x ){ ... } -> ( $y ){ ... } -> ( $z ){ ... } ; and "," is unnecessary after the curly for the same reason it is unnecessary after @a. since grep/map/and_friends are just subroutines this naturally gives piping behaviour : for @a -> ( $x ){ ... } #this is map ,grep -> ( $y ){ ... } #this is grep ,sort -> ( $a,$b ){ ... } ; #this is sort this is similar to the old "then" suggestion of Damian Conway @a then map -> ( $x ){ ... } #this is map then grep -> ( $y ){ ... } #this is grep then sort -> ( $a,$b ){ ... } ; #this is sort arcadi
Re: Why C needs work (was Re: L2R/R2L syntax)
Michael Lazzaro wrote: > *Now*, what to do about the fantastic magic that pointy-sub provides? > The _spectacular_ win would be if we could just recognize an optional > parameter list as part of a block. > > map @a : ($a,$b) {...} # params + closure = closure with params? > for @a : ($a,$b) {...} > > So that anywhere you had a closure, you could put a paramlist in front > of it. Not likely we could get that to work, since best-case scenario > it would probably barf on $a and $b being undefined before it ever got > to the closure. But it might be possible, at the expense of some > parser complexity. I agree that it might be difficult to recognize the ($a,$b) as a parameter list rather than a list expression. Smalltalk marks block parameters this way: b := [:a :b | a < b]. "Assign a two-paremeter block to b" ^b value: 1 value: 2. "Return the value of invoking b on 1 and 2" The "[" makes it clear that a block is next; the ":" marks parameters and the "|" ends the list. A literal translation to Perlish syntax would be map @a { :$a :$b | $a + $b } but then we get into discussions about Larry's 2nd law of colons. Besides, we perl mongers already use "|" for a sufficient multitude of other things. But my point is: just because C-ish programmers think "(...){ ... }" feels parameterish doesn't mean that the parameter declaration has to come *before* the opening curly brace. And no, despite two Smalltalk-related posts in the last three days, I don't want to turn Perl into Smalltalk; I just think that Smalltalk has a nice syntactic solution to the problem we're talking about here. The problem is, I can't think of any syntaxes better than map @a { $a $b: $a + $b } # hey, buddy, can you lend me a colon? map @a { args $a, $b; $a + $b } map @a { -> ($a, $b); $a + $b } map @a { $a, $b ->$a + $b } # can't coexist with A4-style pointy subs map @a { my^ $a, $b; $a + $b } # the ^ is reminiscent of "map @a { $^a + $^b } map @a {{$a, $b} $a + $b } # all other uses of consecutive curlies require space: "{ {" map @a { EXPLICIT_ARGUMENTS_TO_FOLLOW $a $b ARGUMENTS_STOP_HERE $a + $b } and they all look uglier than... well, um, uh... I want. I have a strong suspicion that this possibility was carefully considered by {LW, DC, ...} (that's set notation, not a code block :) before the Apocalypse 4 "pointy sub" syntax (and the for-loop syntax using it) was promulgated. And that it was rejected because it's hard to come up with something that "looks right." Even the Smalltalk syntax is a tad awkward-looking to me, and the warpage that is necessary to make it Perlish just compounds the problem. Hmmm. I guess I didn't really say anything here, did I? Do I post these ruminations, or should I just hit that cancel button before I "open my mouth and remove all doubt?" Nah. I'm goin' for it: maybe somebody else will think of a syntax that looks right! =thom "Must be a yearning deep in human heart to stop other people from doing as they please. Rules, laws--always for the other fellow. A murky part of us, something we had before we came down out of the trees, and failed to shuck when we stood up. Because not one of those people said: 'Please pass this so I won't be able to do something I know I should stop.' Nyet, tovarishchee, was always something they hated to see their neighbors doing. Stop them 'for their own good'--not because the speaker claimed to be harmed by it." Manuel Davis O'Kelley The Moon is a Harsh Mistress
Re: Why C needs work
David Storrs <[EMAIL PROTECTED]> writes: > On Tue, Jan 21, 2003 at 03:52:30PM -0800, Dave Whipp wrote: > >> $a = sub ($a, $b) { ... } >> $x = -> ($y, $z) { ... } >> >> The pointy-arrow doesn't buy anything here. > > IMHO, it's actually a loss. I have yet to come up with any mnemonic > for "pointy arrow means sub" that will actually stick in my brain. > Every time I see this construct, I have to stop in my tracks and > mentally flip through the reference manual. Personally, I think it looks a bit like a lambda on its side (and if we're going to have unicode operators then I'd not be unhappy to see 'real lambda' being an equivalent to '->'. -- Piers
Re: Why C needs work (was Re: L2R/R2L syntax)
--- Luke Palmer <[EMAIL PROTECTED]> wrote: [[... Massive elision ...]] > I'm thinking it would be a very good idea to unify C and C > in their argument style. I still think the distinction between > C's void and C's list context is a good one; i.e. don't > make them I synonyms. > > But it seems natural to have C a method of C, however > unnatural that seems. I don't know, my thoughts are quite unclear at > this point; perhaps I'll write back when I've thought about this a > bit more. On a somewhat disjunctive note, if you're going to play games with unifying C and C, let's undef the operation-order of map. That is, for (1,2,3) { print } # 1 2 3 map { print } (1, 2, 3) # or however you rewrite the syntax # ? ? ? @a = map { print } (1, 2, 3) for @a { print } # 1 2 3 Note that the order of the results of map would still be guaranteed, but not the order of operation. This is for threading, obviously, and we should probably do the same thing everywhere we can, so that if you want serial operation, you use "for" or some construction that honors ordering attributes internal to the data. The point is to warn people that preserving state in map blocks won't work, although stateless data or statistics will: map { count++; ... } @array # works fine -- count == array.length map { %hist{$_}++ } @array # works fine -- hist{} counts occurrences map { ...$last ...; # I do not think that code last=$_; ... } @array # means what you think it means... =Austin
Re: Why C needs work (was Re: L2R/R2L syntax)
Michael Lazzaro writes: > And it provides a very visual way to define any pipe-like algorithm, in > either direction: > > $in -> lex -> parse -> codify -> optimize -> $out; # L2R > > $out <- optimize <- codify <- parse <- lex <- $in; # R2L > > It's clear, from looking at either of those, that they represent data > pipes. Both are even clearer than the equiv: > > $out = $in.lex.parse.codify.optimize; > > Whether you would code a pipeline as L2R or R2L depends on the specific > algorithm you're representing, and is purely a matter of taste... > you'd probably use R2L in the same places as you use C-like > chaining in Perl5. I can't begin to justify why one should be superior > to the other, and would certainly use them both. > This explanation of (and rationale for) a "post-invocant" underpinning for l2r/r2l pipe-lining was wonderfully clear. I've also found that newish perl programmers frequently find C and friends to be confusing, particularly when they are traveling in a pack (not to speak of an C). One question: How does this approach to building a pipe-lining syntax square with the "alternative spelling of the assignment operator" feature that's been discussed elsewhere in this thread? It's not immediately obvious to me how the post-/pre-invocant operation "becomes" an assignment at the end of the chain. In other words, are the first two code fragments above really equivalent to the third? Kwin
Re: Why C needs work (was Re: L2R/R2L syntax)
> Date: Wed, 22 Jan 2003 10:38:23 -0800 > From: Michael Lazzaro <[EMAIL PROTECTED]> > > On Tuesday, January 21, 2003, at 03:52 PM, Dave Whipp wrote: > > But in a for loop: > > > > for 1,2,3,4 { ... } > > for 1,2,3,4 -> ($a,$b) {...} > > > > its cuteness works because the brain sees it as a piping operator (even > > though its not). > > *** SPECULATION AHEAD *** > > Note that C allows you to name the arguments, using the pointy sub > rule: > > for @a -> ($a,$b) {...} > > but note ALSO that it'd be great if C and friends had that > capability, so you could C two-at-a-time, etc. (C and > C don't really need it, but I *suppose* you could use it for > grepping/sorting tuples.) I'm not sure whether you know that this already is the plan. The following three are equivalent: my @a = map { uc } @b; my @a = map { uc $^a } @b; my @a = map -> $x { uc $x } @b; And I believe two-at-a-time would also work. > So we want the pointy-sub rule for C and friends too: > > my @a = map -> ($a,$b) {...}; # pass to {...} 2-at-a-time, as $a > and $b > > Pretty neat. > > But ignoring pointy-sub for the moment, and assuming that we in fact > used -> and <- to mean pre/post-invocant (e.g. "pipes"): if we defined > C as just another word for C, what we really want is rules > such that *all* of the following work. Question is, is it possible to > come up with something consistent. Maybe. > > # void context > > @a.map {...} > @a.for {...} # identical > @a -> map {...} # identical > @a -> for {...} # identical > > @a -> {...} # identical (a cool shorthand when given > a closure?) > > for @a {...} # Doh! This wouldn't work > for @a : {...}# Hey, but this would (indirect object > syntax) > map @a : {...}# identical > > for @a,@b,@c : {...} # is this OK? > for (@a,@b,@c) : {...}# OK, and better looking > > # list context > > my @a = @b -> for {...} > my @a = @b -> map {...} # identical > my @a = map {...} <- @b # identical > my @a = for {...} <- @b # identical > > my @a <- map {...} <- @b# identical > my @a <- for {...} <- @b# identical > > That works. Pretty darn well, too. (Note the critical bit, the > introduction of indirect object syntax to C.) Yeah, good point. Why is it that C and C, so similar in nature, accept such different forms for their arguments? But, I'll have to admit, for @a,@b :-> $a, $b { ... } Doesn't look quite as nice as the older version :-> I'm thinking it would be a very good idea to unify C and C in their argument style. I still think the distinction between C's void and C's list context is a good one; i.e. don't make them I synonyms. But it seems natural to have C a method of C, however unnatural that seems. I don't know, my thoughts are quite unclear at this point; perhaps I'll write back when I've thought about this a bit more. Luke
Re: Why C needs work (was Re: L2R/R2L syntax)
On Tuesday, January 21, 2003, at 03:52 PM, Dave Whipp wrote: But in a for loop: for 1,2,3,4 { ... } for 1,2,3,4 -> ($a,$b) {...} its cuteness works because the brain sees it as a piping operator (even though its not). That's an excellent observation. I like the 'for' syntax quite a bit, but never quite could put my finger on why it worked so well. You're right, that's exactly it. And this begs the question: what exactly does the C contribute to the semantics of the pipeline? What would C (in void context) do differently? Hmm. Perhaps there doesn't _need_ to be a difference. You currently use C when you don't care about capturing the results. You use C when you do. But since we can identify context, perhaps they could be synonyms, if we tweak things a little. *** SPECULATION AHEAD *** Note that C allows you to name the arguments, using the pointy sub rule: for @a -> ($a,$b) {...} but note ALSO that it'd be great if C and friends had that capability, so you could C two-at-a-time, etc. (C and C don't really need it, but I *suppose* you could use it for grepping/sorting tuples.) So we want the pointy-sub rule for C and friends too: my @a = map -> ($a,$b) {...}; # pass to {...} 2-at-a-time, as $a and $b Pretty neat. But ignoring pointy-sub for the moment, and assuming that we in fact used -> and <- to mean pre/post-invocant (e.g. "pipes"): if we defined C as just another word for C, what we really want is rules such that *all* of the following work. Question is, is it possible to come up with something consistent. Maybe. # void context @a.map {...} @a.for {...} # identical @a -> map {...} # identical @a -> for {...} # identical @a -> {...} # identical (a cool shorthand when given a closure?) for @a {...} # Doh! This wouldn't work for @a : {...}# Hey, but this would (indirect object syntax) map @a : {...}# identical for @a,@b,@c : {...} # is this OK? for (@a,@b,@c) : {...}# OK, and better looking # list context my @a = @b -> for {...} my @a = @b -> map {...} # identical my @a = map {...} <- @b # identical my @a = for {...} <- @b # identical my @a <- map {...} <- @b# identical my @a <- for {...} <- @b# identical That works. Pretty darn well, too. (Note the critical bit, the introduction of indirect object syntax to C.) *Now*, what to do about the fantastic magic that pointy-sub provides? The _spectacular_ win would be if we could just recognize an optional parameter list as part of a block. map @a : ($a,$b) {...} # params + closure = closure with params? for @a : ($a,$b) {...} So that anywhere you had a closure, you could put a paramlist in front of it. Not likely we could get that to work, since best-case scenario it would probably barf on $a and $b being undefined before it ever got to the closure. But it might be possible, at the expense of some parser complexity. If we couldn't do that, you would have to say: for @a : sub ($a,$b) {...} # OK or @a -> for sub ($a,$b) {...} # a bit icky The first of those looks better than the second. I loathed the second after I first wrote it, but now it's beginning to grow on me a bit better. The intent is certainly clear, for example. The pointy-sub syntax doesn't really work in these cases, though. I can't think of anything you could use in place of 'sub' that would make either of those look better. So, the benefits of trying to pursue this: It makes C and C synonyms, and gives each the magical powers of the other. The fact even C is now an object method means you could say: for @obj : {...} and even overload the C behavior for a Collection-based @obj. It also gets rid of the perl5 bugaboo: for (@a) {...} map {...} @a;# params are reversed. Newbie trap! So the biggest single trick is, C would have the colon after the list: for @a : {...} If we did that, the rest might just work. Anyway, just speculation. MikeL
Re: Why C needs work (was Re: L2R/R2L syntax)
"David Storrs" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... > > And then we can replace the ~> with ->: > > > > for 1,2,3,4 > > -> sub ($a, $b) { $a+$b } > > -> sub ($a) { $a**2 } > > -> { $^foo - 1 } > > -> print; > > > > And this begs the question: what exactly does the C contribute to > > the semantics of the pipeline? What would C (in void context) > > do differently? > > One potential answer: make 'map' be lazy by default and 'for' be > nonlazy (energetic? active? ADHD?). My logic in suggesting it this > way around is that, to me, 'for' seems to operate more on a whole > list, while 'map' is intended to operate on elements one after > another. Like so: > > for (1,2,3) { print } # "I want to call print for this whole list" > map { print } (1,2,3) # "Map the 'print' function over the elements ># of this list" I have a feeling its the other way round: (1,2,3,4) ~> map { print } Vs for 1,2,3,4 -> print The "obj ~> method args" form calls the method on the object. C is then a method (called on the entire list) that calls its codeblock for each member The "for list -> sub" would call the sub for each member of the list. Hence an equivalence: for list -> { per-elem code } eq list ~> map { per-elem code } But remember, this is all getting very hypothetical: -> doesn't (currently) mean "L2R pipe into sub" Dave.
Re: Why C needs work (was Re: L2R/R2L syntax)
On Tue, Jan 21, 2003 at 03:52:30PM -0800, Dave Whipp wrote: > $a = sub ($a, $b) { ... } > $x = -> ($y, $z) { ... } > > The pointy-arrow doesn't buy anything here. IMHO, it's actually a loss. I have yet to come up with any mnemonic for "pointy arrow means sub" that will actually stick in my brain. Every time I see this construct, I have to stop in my tracks and mentally flip through the reference manual. > But in a for loop: > > for 1,2,3,4 { ... } > for 1,2,3,4 -> ($a,$b) {...} > > its cuteness works because the brain sees it as a piping operator (even > though its not). Agreed. [snip] > And then we can replace the ~> with ->: > > for 1,2,3,4 > -> sub ($a, $b) { $a+$b } > -> sub ($a) { $a**2 } > -> { $^foo - 1 } > -> print; > > And this begs the question: what exactly does the C contribute to > the semantics of the pipeline? What would C (in void context) > do differently? One potential answer: make 'map' be lazy by default and 'for' be nonlazy (energetic? active? ADHD?). My logic in suggesting it this way around is that, to me, 'for' seems to operate more on a whole list, while 'map' is intended to operate on elements one after another. Like so: for (1,2,3) { print } # "I want to call print for this whole list" map { print } (1,2,3) # "Map the 'print' function over the elements # of this list" --Dks
Re: Why C needs work (was Re: L2R/R2L syntax)
"Michael Lazzaro" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... > Of course, _I'd_ even prefer using <- and -> as the 'piping' operators, > and having ~> or |> for pointy sub, because then $a->foo and $a.foo > really _could_ be the same thing, 'cept for precedence. But that's not > gonna happen, and _I'm_ not gonna press it. :-) I wouldn't (and don't) give up so easily! The "->" syntax for anonymous subs is cute: but it seems to be cute only in limited contexts -- those where it is also being used as a (conceptual) piping operator. Compare: $a = sub ($a, $b) { ... } $x = -> ($y, $z) { ... } The pointy-arrow doesn't buy anything here. But in a for loop: for 1,2,3,4 { ... } for 1,2,3,4 -> ($a,$b) {...} its cuteness works because the brain sees it as a piping operator (even though its not). Perl6 is still Perl. We're allowed to do a bit of DWIMery in the parser, if needed, to make the simple (common) cases work. So perhaps we should define the C in terms of pipelines. With some minor syntax changes, we can free up the -> operator: for 1,2,3,4 ~> sub ($a,$b) { ... } Sure, its not quite so cute. You could rename the C if desired (for example, perhaps it could be spelt C in this context, though you'd need to work on the lexical scoping rules). The only remaining magic would be to retrofit the basic C to work. And then we can replace the ~> with ->: for 1,2,3,4 -> sub ($a, $b) { $a+$b } -> sub ($a) { $a**2 } -> { $^foo - 1 } -> print; And this begs the question: what exactly does the C contribute to the semantics of the pipeline? What would C (in void context) do differently? Dave.
Re: Why C needs work (was Re: L2R/R2L syntax)
On Tuesday, January 21, 2003, at 02:38 PM, Buddha Buck wrote: Michael Lazzaro wrote: And it provides a very visual way to define any pipe-like algorithm, in either direction: $in -> lex -> parse -> codify -> optimize -> $out; # L2R $out <- optimize <- codify <- parse <- lex <- $in; # R2L It's clear, from looking at either of those, that they represent data pipes. The problem with this example is that the two lines deal with two different calling conventions, going by Damian's proposal... So the apparant symmetry between <~ and ~> isn't really there. I like <~ and ~>, but I think that it will be a common mistake to think that $a ~> b~>c~>d can be reversed to give d<~c~, at least as currently formulated. Agreed, it could be quite misleading. Personally, I'd be happier if <~ and ~> worked _only_ on objects and methods, instead of arbitrary subs... but I understand the utility of the other way. Of course, _I'd_ even prefer using <- and -> as the 'piping' operators, and having ~> or |> for pointy sub, because then $a->foo and $a.foo really _could_ be the same thing, 'cept for precedence. But that's not gonna happen, and _I'm_ not gonna press it. :-) MikeL
Re: Why C needs work (was Re: L2R/R2L syntax)
Smylers wrote: Michael Lazzaro wrote: And it provides a very visual way to define any pipe-like algorithm, in either direction: $in -> lex -> parse -> codify -> optimize -> $out; # L2R $out <- optimize <- codify <- parse <- lex <- $in; # R2L It's clear, from looking at either of those, that they represent data pipes. Yes; that is nice. I'm just not convinced that it's sufficiently nice to require adding yet another way of passing data around to the language. I'm happy enough with the asymmetry that occurs just having the arrows to indicate 'reverse flow' data. The problem with this example is that the two lines deal with two different calling conventions, going by Damian's proposal... Perl 5 has two different code calling conventions: object oriented method calls, and procedural subroutine calls. OO method calls are L2R already: $object.method1().method2().method3().method4(); Procedural subroutine calls are R2L already: sub4 sub3 sub2 sub1 $variable; But there is no way to do OO method calls R2L, and there is no way to do procedural subroutine calls L2R. Damian's ~> and <~ proposal fills in this gap: method4 <~ method3 <~ method2 <~ method1 <~ $Xbject; $variable ~> sub1 ~> sub2 ~> sub3 ~> sub4; To the best of my knowledge, the following two WILL NOT WORK: sub4 <~ sub3 <~ sub2 <~ sub1 <~ $variable; $Xbject ~> method1 ~> method2 ~> method3 ~> method4 The first one tries to invoke the sub1 method of $variable, while the second tries to call the method1 function with $object as an argument. If either of these works, it's either coincidence or careful planning. So the apparant symmetry between <~ and ~> isn't really there. I like <~ and ~>, but I think that it will be a common mistake to think that $a ~> b~>c~>d can be reversed to give d<~c~, at least as currently formulated.
Re: Why C needs work (was Re: L2R/R2L syntax)
On Tuesday, January 21, 2003, at 01:31 PM, Smylers wrote: Michael Lazzaro wrote: it's that I _dislike_ the perl5 rule, ... Oh. That's "dislike" rather than "disliked"? My question was predicated on your declaration "I emphatically withdraw my objection", which I took to mean that your knowledge of the infrared comma rule -- or whatever it's called -- meant you no longer disliked the Perl 5 syntax? I still dislike it, but if a variation upon it means we can make things like C, C, etc. semi-normal functions, instead of cases within the grammar, then I think everyone agrees that would be a Good Thing. Keeping one grammar special case in return for not having a dozen others -- yeah, I'll sign up for that. I don't loath the old C syntax to the point where I'd just die if it were there. And I don't expect we'd really get rid of it, it's too intrinsic to Perl5. At very minimum, we'd have to keep the global functions around as a module you could load for Perl5-friendliness. I do think OO & pipelines are the better, more generic way to do the same thing. So I'd really like to see pipelines, even if they're just in addition to the old C style. After that, it's just a question of whether the old style is worth the redundant declarations, which is purely a matter-of-taste thing. the most frequent mistake is to reverse the order of the arguments, saying map @a, {...} That happens if you conceptualize C as taking two arguments. I think you're right about that. And we have both: for (@a) {...} and map {...} @a; Which stings some newbies repeatedly, poor lads. Was that an understandable explanation? :-) Yes. Thanks, again. Please don't take personally my disagreeing with so much you've written! On the contrary. I'm just so happy someone understood what I was trying to say, I think I'm going to burst into tears... Wait, no... OK, I'm better now. MikeL
Re: Why C needs work (was Re: L2R/R2L syntax)
Michael Lazzaro wrote: > On Monday, January 20, 2003, at 12:30 PM, Smylers wrote: > > > It was only on reading that (and discovering that you hadn't > > previously known about the 'optional comma with closure argument' > > rule) that I understood why you had previously been so in favour of > > proposed new syntaxes: through a desire to banish the Perl 5 syntax. > > Yes. Again, it's not that I never knew about the perl5 rule, Sorry, I wasn't meaning to suggest that you didn't know Perl 5; I was specifically referring to your saying that you'd presumed that conditions and loops were special cases in the grammar, but that actually they'll be dealt with by the general Perl _6_ rule about commas and closure arguments. > it's that I _dislike_ the perl5 rule, ... Oh. That's "dislike" rather than "disliked"? My question was predicated on your declaration "I emphatically withdraw my objection", which I took to mean that your knowledge of the infrared comma rule -- or whatever it's called -- meant you no longer disliked the Perl 5 syntax? > as I dislike most special-case grammar rules. So do I! I was particularly impressed by the ultraviolet comma rule, and how it avoids special cases, when Damian paraded it at a talk last summer. I also don't reckon it's _that_ special. So long as the rule is that such commas are optional, as distinct from their absence being mandatory, then the rule is a very general one: commas may be omitted where they aren't needed to delimit list items. Obviously with string and numeric values commas are always required: $a -1 They are the only way of determining op/term for the minus sign: a single argument of one less than the value in C<$a>, or two arguments with the second being minus one? But closures can be unambiguously determined without commas. Since whitespace is no longer allowed in hash look-ups, space followed by an open brace must be the start of a closure, and hence another argument. Similarly once the closing brace has been reached the closure is ... ahem, closed, so anything following must be a separate argument. > If we dropped C, etc., we could drop the inferred-comma rule as > well (unless we're really successful in making C a simple > function, in which case we need the rule anyway, so who cares?) I guess that's the crucial issue. Since it was Damian saying that it is possible to have C and friends as functions -- and since this was something that'd already been dealt with before I joined this list, and so presumably would've had any impossibility pointed out -- I believed it to be true. There's another sub-thread casting doubt on -- and trying to resolve -- the issue. I completely agree that whether the infrared comma rule is needed over there makes a big difference to its use here. But I think I disagree about the "who cares" part ... > But the inferred-comma rule is tangential to my dislike of the current > C syntax. I'd dislike C, and like pipelines, even if the > inferred-comma rule wasn't there. As you've not doubt noticed, I'm the opposite: I like C and don't (yet?) see the point of right-left pipelines. (That means not that I claim you're in some way 'wrong' to have those preferences, merely that we think differently to each other.) There's one Perl slogan that'd suggest having both ways in the language, so both of us get to code in the way we like. Countering that is the risk of adding too many ways of doing things and just causing confusion for everybody with all the different ways of invoking functions/methods on data. Hence my quibble with "who cares": I could probably be persuaded that it's 'better' for the language not to have the Perl 5 syntax, my preference, than to have so many alternative syntaxes. (I'm not sure.) > > Mike ... do you still find right-left pipelines as compelling as > > you've previously argued? > > Yes, very much so. ... I've seen quite a few newbies struggle with > the C syntax; Me too. The most-strugglable bit for many has been the right-left data flow, that you start by typing where you want the data to end up, then the process it goes through last, then the process it goes through first, and lastly the data that's being processed. Left-right pipelines should be great at fixing this. > the most frequent mistake is to reverse the order of the arguments, > saying > > map @a, {...} That happens if you conceptualize C as taking two arguments. In my mind C operates on items in a list (and it just so happens that in Perl an array provides a list): map { ... } $a, $b, $c; So C takes _many_ arguments, and one of these arguments is not like the others. And it makes sense to put the 'special' argument first. (That's also how I remember which way round things like C are.) Thinking of it as operating on a list of things also helps to emphasize that C processes just a single item at a time, that it isn't an agregate operation on the items as a group. > (Another common one is to not understa
Re: Why C needs work (was Re: L2R/R2L syntax)
On Monday, January 20, 2003, at 04:33 PM, Michael Lazzaro wrote: But both the OO and pipeline syntaxes do more to point out the noun, verb, and adjective of the operation. Adverb. The {...} part is an adverb, not an adjective. Sorry there. MikeL
Re: Why not {,n} in quantifiers?
Miko O'Sullivan writes: : From: "Larry Wall" <[EMAIL PROTECTED]> : > It's unlikely that {n,m} will still have that meaning in Perl 6. Maybe : we'll : > have something like this: : > : > Perl 5 Perl 6 : > {1,3} <1..3> : > {3} <3> : > {3,} <3+> : > {0,3} <3-> : : What are your feelings on multiple ranges for matches? E.g. the following : expression means "1 to 3, 5, or 10 or more": : : <1..3|5|10+> My feelings are that nobody has ever asked me for it before, so it's not something worth making special syntax for. On the other hand, if instead of inventing new syntax we stick to a more Perlish syntax, we could generalize it to an ordinary slice kind of list: <1..3,5,10..Inf> But you'd still have the complexity of making it work, and it still seems like something almost nobody would ever use. And you could get the same effect with an appropriate assertion: (...)* { @$+.length =~ (1..3,5,10..Inf) or fail } That's assuming that quantified captures produce arrays rather than the final match as Perl 5 does. Larry
Re: Why not {,n} in quantifiers?
From: "Larry Wall" <[EMAIL PROTECTED]> > It's unlikely that {n,m} will still have that meaning in Perl 6. Maybe we'll > have something like this: > > Perl 5 Perl 6 > {1,3} <1..3> > {3} <3> > {3,} <3+> > {0,3} <3-> What are your feelings on multiple ranges for matches? E.g. the following expression means "1 to 3, 5, or 10 or more": <1..3|5|10+> -Miko
Re: Why not {,n} in quantifiers?
Aaron Sherman writes: : Hopefully there will be some replacement. I can't count the number of : times I've relied on things like: : : $b = qr/\d{1,3}/; : if (@ip = ($addr =~ /($b)\.($b)\.($b)\.($b)/)) { : die "$0: \"$addr\": bad IP\n" if grep {$_>255} @ip; : print("0x",(map {sprintf "%02x", $_} @ip),"\n"); : } else { : die "$0: \"$addr\" is not an IP address\n"; : } : : It would be a shame to loose that. Bear in mind we have to translate Perl 5 to Perl 6, so it's quite unlikely that we would drop the general case. The only question here is what it ought to look like in the general re-huffmanization of regexen. Larry
Re: Why not {,n} in quantifiers?
On Tue, 2002-05-14 at 20:13, Larry Wall wrote: > It's unlikely that {n,m} will still have that meaning in Perl 6. Maybe we'll > have something like this: > > Perl 5Perl 6 > {1,3} <1..3> > {3} <3> > {3,} <3+> > {0,3} <3-> > > Then again, maybe not... Hopefully there will be some replacement. I can't count the number of times I've relied on things like: $b = qr/\d{1,3}/; if (@ip = ($addr =~ /($b)\.($b)\.($b)\.($b)/)) { die "$0: \"$addr\": bad IP\n" if grep {$_>255} @ip; print("0x",(map {sprintf "%02x", $_} @ip),"\n"); } else { die "$0: \"$addr\" is not an IP address\n"; } It would be a shame to loose that.