Re: proposal: use \ as none junction delimeter
Luke Palmer wrote: But I counter that arguability by saying that you really shouldn't be putting one() in type signatures. If you want something to be an A or a B, and you're not doing any checking later on in the code, then it's fine if it's both A and B. If you are doing checking later on, then it should either be in a multimethod or you should factor it out into an abstract type. Perl's not so keen on what you "should" do, though, but I offer this as solace for those who wish to break the guidelines: sub foo ( one(Dog, Cat, Horse) $x ) I think there is a practical application of this. If the classes are derived from the same base e.g. Mammal then &foo cannot be called with a Mammal instance but &foo could. The former also excludes junction types. In the latter case there are seven matching types when superclasses are neglected: Dog, Cat, Horse, Dog|Cat, Dog|Horse, Cat|Horse and Dog|Cat|Horse. I also have another idea where the exclusivity of one() is usefull, but I don't know how to write that in Perl6. I want a method Mammal::reproduce( Mammal[male^female]$self: Mammal[$self.type ^ (male|female)] $partner ) returns Mammal[male^female]; Am I making sense? -- TSa (Thomas SandlaÃ)
Re: Fun with junctions (was Sets vs Junctions)
On Sun, Feb 13, 2005 at 04:10:08PM -0600, Jonathan Scott Duff wrote: : On Sun, Feb 13, 2005 at 11:10:20AM -0600, Patrick R. Michaud wrote: : > Autothreading, even if enabled by default, doesn't happen until a : > junction is created and used somewhere. Thus the only time our hypothetical : > new programmer would be forced to become aware of junctions (without : > himself/herself having created a junction) is when he/she calls some : > routine that chooses to generate and return a junction on its own. : : Like when he uses a module from CPAN that uses junctions (as an : implementation detail of the module that just happens to be exposed). : Or when the module that he has created and released to CPAN starts : getting used with code that uses junctions and his users discover : bizarre behavior. : : > That isn't likely to happen often. : : Perhaps. We've already got an invariant on incoming parameters that lets the user ignore junctions until they're ready to handle them. (That's really what the autothreading "feature" is all about, after all. It's not really there in it's own right; it's an encapsulation feature--or in this case, an eXcapsulation feature.) Now, we might break that invariant by making it too easy to declare junctive parameter types, so I suspect we need to make sure that doesn't happen too easily. More on that below. But what y'all are talking about above is the other end--the return type. And maybe we need to enforce a newbie-friendly invariant on that end as well. I suppose we could default to not accepting junctional return values by default, and have a pragma to turn it on. Or perhaps the problem isn't returning junctions per se, but storing them into a variable that the user is thinking of as a simple scalar value. So we could allow a user to write junctions as arguments: if $a == 1 | 2 | 3 {...} while by default disallowing an assignment like: $a = 1 | 2 | 3; They could allow such assignments by use of a special pragma: use Quantum::Superpositions; (or some such... :-) Come to think of it, we could have the same default on modules that declare function parameters. Then to suppress autothreading excapsulation you'd have to both declare the parameter as a junctional type *and* use the pragma in the lexical scope. That might ameliorate the problem of having types that sneakily become junctional when the person declaring the function parameters wasn't expecting it. The pragma would only be aimed at the assignment type checker. Since junctional return values are allowed, you could still say things like: @foo = (1|2|3).values; The main thing is that this approach allows most of the newbie-friendly, rvalue uses of junctions without letting people get into trouble by storing junctions where they weren't expecting. Basically, we disallow storing qubits into lvalues. So maybe the actual pragma name is use qubits; Note: the pragma is not "use junctions", since they're already allowed to use junctions, as long as they don't try to observe them. :-) I'd be tempted to make it just use qm; but people might confuse that with some kind of quote operator. Plus, they're already using qm in the same sense that we all use QM every day of our lives without thinking about it. On the other hand, if we ever get real quantum computers we might want to reserve "qubits" for a real data type. So maybe it should be use jubits; or some such... On the other hand, we're multiplying entities here. Maybe we should stick with: use junctions; with the understanding that it merely turns on full support for junctions instead of the default partial support. Which implies you could go the other way and turn off all junction support in the current lexical scope with: use junctions :none; And now, of course, I'm trying to figure out what use junctions :one; use junctions :any; use junctions :all; would mean... :-) Larry
Containers vs Objects.
In my recent unsuccessful attempt to convert junctions into sets with their own container, perhaps the strongest argument against could be paraphrased as follows: Everything about junctions or sets can be represented fully as an object, and objects are nicely stored in scalars, because it's simply one instance of a given class, in this case C. My question comes down to: so what makes Arrays and Hashes so special? As many pure-OO languages demonstrate, both can be fully represented as an object, and objects belong in Scalars. The obvious statement I expect to here is "Perl's always had Arrays and Hashes". While I'm not sure if they were there for Perl 1.0 (I started w/ Perl 4.xx), I do know that they certainly predate P5's objects and references. Therefore, there was no other way to create an array or hash. That is no longer the case. In P6, we've even gone so far as to say that you can access an element in an array ref with C<$ref[1]>. I'm fairly sure you can call all the methods of the Array class on the $ref, letting you do C<$ref.pop> and all the other fun things we do with arrays. Similar things hold for hashes. So I'm interested in hearing what pushes Arrays and Hashes over the edge for needing their own container and sigil, whereas Junctions/Sets do not. -- Rod Adams
Re: Fun with junctions (was Sets vs Junctions)
On Feb 15, 2005, at 11:06 AM, Larry Wall wrote: So maybe the actual pragma name is use qubits; Note: the pragma is not "use junctions", since they're already allowed to use junctions, as long as they don't try to observe them. :-) To quote Noah, what's a qubit? http://www.jr.co.il/humor/noah4.txt :-) Regards, David
Re: Containers vs Objects.
On Tue, 2005-02-15 at 14:26 -0600, Rod Adams wrote: > The obvious statement I expect to here is "Perl's always had Arrays > and Hashes". While I'm not sure if they were there for Perl 1.0 (I > started w/ Perl 4.xx) They were. > So I'm interested in hearing what pushes Arrays and Hashes over the edge > for needing their own container and sigil, whereas Junctions/Sets do not. Perl isn't a "pure" object-oriented language. -- c
Re: Fun with junctions (was Sets vs Junctions)
Damian Conway wrote: >Rod Adams wrote: > >> However, what if what you're calling a non-Perl Parrot based function? >> Do we disable junctions from playing with non-PurePerl functions? Or do >> we autothread over them? How do we tell if a non-Perl function outputs >> to determine if we should be able to autothread into them or not? > >The non-outputting happens at the output operation, which is *always* in >Parrot (at some level) and presumably is dealt with there. Certainly all Perl code is Parrot code, at some level. However, I think this is more Patrick's problem than Dan's, and that Patrick is going to need some guideince from I see it this way: When perl sees a function call, and one of the arguments is a junction, there are three basic options: 1) If the junction is wrapped up in some larger container, like a slurpy list, pass it on as is. 2) If the function in question is an "outputing" one, throw an exception. 3) autothread over the function. Consider the following: $x = 3|4; $y = fun($x); sub fun ($x) { warn "enter: fun($x)\n" if $DEBUG; $x + 1; } Which option from above is in effect? I do not think I left any room for the junction to be enclosed in a larger container, so option #1 is out. That leaves #2 and #3. If we autothread, the C only gets a regular scalar, and is happy, so we could get the dreaded repeated outputs. If we throw and exception, then we have the case that when debugging is turned off (normal case), there is no output at all, and we now have a very confused library user, wondering why this simple math function is complaining about outputting a junction. So is there a runtime internal flag, saying "I'm in the middle of autothreading a junction, if I happen across anything wanting to generate output, throw an exception."? That would certainly solve the pure Perl problem. But it starts to break down at the Parrot level. Now consider the case that above fun() was written in Python, and imported into the perl-space. Constrast that to the CPAN author who refactors a perceived slow part of their module into PIR or even into C, and binding it into Parrot via neo-XS. (I don't follow p6i enough to remember what they call it. Certainly it's better than "neo-XS"). How does the "runtime flag" work in these cases? Does Parrot now have to mark all the subs that _might_ perform some type of output as such, regardless of where that sub came from? If so, has Dan signed off on this? If not, how does Patrick resolve whether to autothread or raise exception? -- Rod Adams
Re: Containers vs Objects.
At 01:04 PM 2/15/2005 -0800, chromatic wrote: On Tue, 2005-02-15 at 14:26 -0600, Rod Adams wrote: > So I'm interested in hearing what pushes Arrays and Hashes over the edge > for needing their own container and sigil, whereas Junctions/Sets do not. Perl isn't a "pure" object-oriented language. No argument there. Which is why I was interested effectively the argument that "Junctions/Sets are Objects, and don't need their own container/sigil" was considered so compelling. -- Rod Adams
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 03:07:53PM -0600, Rod Adams wrote: > I see it this way: > When perl sees a function call, and one of the arguments is a junction, > there are three basic options: > 1) If the junction is wrapped up in some larger container, like a slurpy > list, pass it on as is. > 2) If the function in question is an "outputing" one, throw an exception. > 3) autothread over the function. > > Consider the following: > > $x = 3|4; > $y = fun($x); > sub fun ($x) { > warn "enter: fun($x)\n" if $DEBUG; > $x + 1; > } > > Which option from above is in effect? I do not think I left any room for > the junction to be enclosed in a larger container, so option #1 is out. > That leaves #2 and #3. > If we autothread, the C only gets a regular scalar, and is happy, so > we could get the dreaded repeated outputs. As you've written things above, C is autothreaded (your option #3), and we'll see two C output lines if $DEBUG is set. Whether or not the repeated outputs are "dreaded" is a matter of perspective. Since the caller has chosen to pass a junction to C, the caller shouldn't be overtly surprised when C is autothreaded, or that it generates multiple output lines. In fact, I'd be concerned if it didn't. > If so, has Dan signed off on this? > If not, how does Patrick resolve whether to autothread or raise exception? Well, the ultimate answer is that both Dan and Patrick (and others) will negotiate the exact interface when we get to that point, and that we don't seem to be too concerned about it at the moment. (It could just be that we're both burying our heads in the sand hoping it'll be magically "solved" by the other. :-) However, in working out these examples I'm fairly comfortable that it can be made to work at the Perl 6 compiler level if need be, although it will probably be a lot more efficient if we can find a way to do it within Parrot. The how to "resolve whether to autothread or raise exception" question is moot for the example above, because S09 makes it fairly clear that C will always autothread when it is called, resulting in $y = any( fun(3), fun(4) ); The various permutations of C that I've tried in order to get things to break haven't broken yet. But perhaps I'm just not sufficiently creative in my attempts to destroy things. OTOH, what happens with...? sub nofun($x is rw) { $x += 2; } $y = 3 | 4; nofun($y); Pm
Re: Fun with junctions (was Sets vs Junctions)
Larry Wall wrote: Or perhaps the problem isn't returning junctions per se, but storing them into a variable that the user is thinking of as a simple scalar value. That was the largest, perhaps only, reason I made my "Sets vs Junctions" post. Although my solution to the issue was different from yours in almost every respect. You put limits on unsuspectedly storing a junction in a scalar. I made a new place to put them. -- Rod Adams
Re: Containers vs Objects.
chromatic wrote: So I'm interested in hearing what pushes Arrays and Hashes over the edge for needing their own container and sigil, whereas Junctions/Sets do not. Perl isn't a "pure" object-oriented language. Rephrasing my question: What characteristics would _any_ new structure or class have to have to merit becoming a first class container with it's own sigil, rather than being just another class? Or is Perl close enough to "pure" object-oriented these days, where only grandfathered classes make the cut? As a separate question, is there a relatively easy way to create a user-defined class with it's own sigil? (w/o having to modify half the parse rules). -- Rod Adams
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 11:06:51AM -0800, Larry Wall wrote: > > But what y'all are talking about above is the other end--the return > type. And maybe we need to enforce a newbie-friendly invariant on that > end as well. I suppose we could default to not accepting junctional > return values by default, and have a pragma to turn it on. Or perhaps > the problem isn't returning junctions per se, but storing them into > a variable that the user is thinking of as a simple scalar value. Pardon me while my brain autothreads: - But restrictions aimed at newbie-friendliness are a drag! People are only newbies for a little while, and they are intermediate-to-expert for a lifetime! Isn't the whole philosophy of Perl "we will trust that you know what you're doing and only enforce the B&D if you ask for it"? - Shut up, nitwit. Trust $Larry. Every time you have doubted his decisions in the past, he's been right and you've been wrong...or, at the very least, it has turned out to not be as bad as you first thought. --Dks -- [EMAIL PROTECTED]
Re: Containers vs Objects.
Rod Adams writes: > So I'm interested in hearing what pushes Arrays and Hashes over the > edge for needing their own container and sigil, whereas Junctions/Sets > do not. Nothing. In fact, arrays and hashes aren't atomic or fundamental in any respect, and the main thing that keeps them there is history. And in fact, one of the big questions that's always in the back of my mind (that I'm not searching for an answer to, but I'm always observing for one) is: what do @ and % mean these days? They have syntactical semantics: sub foo ([EMAIL PROTECTED]) { say @_.elems; } my @a = (1,2,3,4,5); my $a = @a; foo(@a); # 5 foo($a); # 1 Hashes do too, particularly in rules. But what are some nice, abstract concepts that these could represent. One that I've been thinking of is: * @something is necessarily ordered: there is a well-defined "first element" * %something is necessarily a set: adding something twice is always redundant Or something like that. I've noticed in my recent programming which has been heavily algorithmic that sets are ubiquitous. % would still mean hash by default, but hash would mean a "set of pairs". Correspondingly, @ would mean array by default, but you could certainly put a linked list in there. The biggest problem (perhaps) with these abstractions is that subscripting--their most common operation--is not well-defined. Presumably most of these containers would define reasonable subscripters, but if you ask for an array in your parameter list, you may not even be able to subscript it. So I don't think these are quite right. Also, rules refer to the "value" of a hash for a partcular key, and that's not well-defined for sets either. Maybe now is the time to figure out what they *do* mean. Luke
Re: Fun with junctions
> "DW" == David Wheeler <[EMAIL PROTECTED]> writes: DW> On Feb 15, 2005, at 11:06 AM, Larry Wall wrote: >> So maybe the actual pragma name is >> >> use qubits; >> >> Note: the pragma is not "use junctions", since they're already allowed >> to use junctions, as long as they don't try to observe them. :-) DW> To quote Noah, what's a qubit? RGGTTT :) 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: Fun with junctions (was Sets vs Junctions)
David Storrs writes: > On Tue, Feb 15, 2005 at 11:06:51AM -0800, Larry Wall wrote: > > > > But what y'all are talking about above is the other end--the return > > type. And maybe we need to enforce a newbie-friendly invariant on > > that end as well. I suppose we could default to not accepting > > junctional return values by default, and have a pragma to turn it > > on. Or perhaps the problem isn't returning junctions per se, but > > storing them into a variable that the user is thinking of as a > > simple scalar value. > > Pardon me while my brain autothreads: > >- But restrictions aimed at newbie-friendliness are a drag! >People are only newbies for a little while, and they are >intermediate-to-expert for a lifetime! Isn't the whole >philosophy of Perl "we will trust that you know what you're >doing and only enforce the B&D if you ask for it"? Yeah, but I wouldn't say that experienced programmers would see anything off about this at first glance: sub stuff($x) { $access++; # do stuff with $x } my $ret = Module::foo(); say $access; # 10 stuff($ret); say $access; # 15 And then they find that $access has been incremented five times in one call. This is a bad debugging situation. Indeed, marking junctions with a secondary sigil has been one of my wants as an implementor. In fact, we have to mark when things are tied in order to cope with implementation limitations. What if junction variables are just tied variables. We return tied stuff all the time; that's how lvalue methods work. The question is how do we mark them. Secondary sigil is one way: my $~ret = Module::foo(); But is "this variable is tied" something the programmer should think every time he uses it? We could do: my $ret is tied = Module::foo(); stuff($ret); Making junctions a pragma as Larry suggests seems something like the mistake of "use integer" (but to a much lesser degree). The question seems not to be whether you want junctions in general, but whether you're expecting a junction from a particular place. And sometimes you just want ultimate versatility, in which case: use tied ; Should work as "use junctions". This might even, er, tie in to the message I sent earlier today about what @ and % mean. Luke
Re: proposal: use \ as none junction delimeter
Thomas Sandlaà writes: > Luke Palmer wrote: > > >But I counter that arguability by saying that you really shouldn't be > >putting one() in type signatures. If you want something to be an A or a > >B, and you're not doing any checking later on in the code, then it's > >fine if it's both A and B. If you are doing checking later on, then it > >should either be in a multimethod or you should factor it out into an > >abstract type. Perl's not so keen on what you "should" do, though, but > >I offer this as solace for those who wish to break the guidelines: > > > >sub foo ( one(Dog, Cat, Horse) $x ) > > I think there is a practical application of this. If the classes are > derived from the same base e.g. Mammal then &foo cannot > be called with a Mammal instance but &foo could. Uhh, only if Perl could give a proof that there were no other mammals than those three. I wish Perl could do that. What you probably mean is that &foo could not be called with Pegasus, but &foo could. Multiple inheritance restriction. And now you've lost Liskov substitutability, among other things. And I claim that such would not be a good programming practice, or used very often in real life. But see above for a possible solution :-) > I also have another idea where the exclusivity of one() is usefull, but > I don't know how to write that in Perl6. I want a > > method > Mammal::reproduce( Mammal[male^female]$self: > Mammal[$self.type ^ (male|female)] $partner ) > returns Mammal[male^female]; I see where you're going with this. In this specfic case, I'd probably do: enum Gender { male, female } # Creates mutually-exclusive roles multi sub reproduce( Mammal & male, Mammal & female ) is symmetric returns Mammal { ... } But the symmetric bit wouldn't work in the general case. There's also this: enum Charge { positive, negative } multi sub force( Charge $x, Charge ^ ::($left.Charge) $y) { "attract" } multi sub force( Charge $left, ::($left.Charge) $y) { "repel" } Which would define semantics independent of the number of Charges there actually were. And here we actually did use ^. But that really doesn't change my argument at all. Luke
Re: Fun with junctions (was Sets vs Junctions)
Patrick R. Michaud wrote: On Tue, Feb 15, 2005 at 03:07:53PM -0600, Rod Adams wrote: I see it this way: When perl sees a function call, and one of the arguments is a junction, there are three basic options: 1) If the junction is wrapped up in some larger container, like a slurpy list, pass it on as is. 2) If the function in question is an "outputing" one, throw an exception. 3) autothread over the function. Consider the following: $x = 3|4; $y = fun($x); sub fun ($x) { warn "enter: fun($x)\n" if $DEBUG; $x + 1; } Which option from above is in effect? I do not think I left any room for the junction to be enclosed in a larger container, so option #1 is out. That leaves #2 and #3. If we autothread, the C only gets a regular scalar, and is happy, so we could get the dreaded repeated outputs. As you've written things above, C is autothreaded (your option #3), and we'll see two C output lines if $DEBUG is set. Whether or not the repeated outputs are "dreaded" is a matter of perspective. Since the caller has chosen to pass a junction to C, the caller shouldn't be overtly surprised when C is autothreaded, or that it generates multiple output lines. In fact, I'd be concerned if it didn't. The case of Damian's response in a prior message: Rod Adams wrote: I also find the following incredibly disturbing: >perl6 -e "$x = 'cat'|'dog'; say $x;" dog cat That would be disturbing if that's what happened. C is just a shorthand for C. So saying a junction is the same as printing it, which is a run-time error. Could easily be achieved with a single layer of encapsulation? perl6 -e "$x = 'cat'|'dog'; say1 $x; sub say1 ($x) {say $x}" Or is the consensus that that's somehow not disturbing, and direct calls are disturbing. If what you're saying is true, then feeding a junction into DBI for a "insert" statement, since the output proper is encapsulated, would create multiple new records in the database? I'm back to being very disturbed. If so, has Dan signed off on this? If not, how does Patrick resolve whether to autothread or raise exception? Well, the ultimate answer is that both Dan and Patrick (and others) will negotiate the exact interface when we get to that point, and that we don't seem to be too concerned about it at the moment. (It could just be that we're both burying our heads in the sand hoping it'll be magically "solved" by the other. :-) Actually, using the semantics you've outlined above, there is no implementation problem. However, I disagree that those semantics are desirable. OTOH, what happens with...? sub nofun($x is rw) { $x += 2; } $y = 3 | 4; nofun($y); Do we need to change the semantics of what happens with autothreading to: method autothread (&func, $junction) { my $result; my $value; for $junction.values -> $value { my $temp = $value; func($temp); $result |= $temp; } $result; } -- Rod Adams
Junction Values
Okay, so we've established that: $x = any(3,4,5); @l = $x.values.sort; Leaves us with @l == (3,4,5), and that makes a fair amount of sense. What do the following evaluate to: @l1 = all(3,4,5).values.sort; @l2 = one(3,4,5).values.sort; @l3 = none(3,4,5).values.sort; @l4 = any(all(1,2),all(3,4)).values.sort; If C<.values> doesn't it cut it for these cases, what other forms of introspection are we going to allow on junctions, to determine what they are? On a slightly different topic, do the following equivalences work: any($a, $a) == $a any($a,$a,$b) == any($a,$b) any(any($a,$b),any($c,$d)) == any($a,$b,$c,$d) all($a, $a) == $a all($a,$a,$b) == all($a,$b) all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d) none($a, $a) == undef none($a,$a,$b) == none($a,$b) none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) one($a, $a) == false one($a,$a,$b) == ($a == $b ?? undef :: $b) -- Rod Adams
Re: Junction Values
Rod Adams wrote: Okay, so we've established that: $x = any(3,4,5); @l = $x.values.sort; Leaves us with @l == (3,4,5), and that makes a fair amount of sense. What do the following evaluate to: @l1 = all(3,4,5).values.sort; Same. @l2 = one(3,4,5).values.sort; Same. @l3 = none(3,4,5).values.sort; Same. @l4 = any(all(1,2),all(3,4)).values.sort; = (all(1,2),all(3,4)).sort = (all(1,2),all(3,4)) If C<.values> doesn't it cut it for these cases, what other forms of introspection are we going to allow on junctions, to determine what they are? .values tells you what raw values are inside the junction. The other kind of introspection that's desirable is: "what raw values can *match* this junction". There would probably be a .states method for that. To see the difference between the two, consider: my $ideal_partner = all( any(«tall dark rich»), any(«rich old frail»), any(«Australian rich»), ); $ideal_partner.values would return the three distinct values in the junction: ( any(«tall dark rich»), any(«rich old frail»), any(«Australian rich»), ); But $ideal_partner.states would return only those non-junctive values that (smart-)match the junction. Namely, "rich". On a slightly different topic, do the following equivalences work: (I will assume in all my answers that $a, $b, $c, $d have different values, except where it doesn't matter either way). any($a, $a) == $a True. any($a,$a,$b) == any($a,$b) True. any(any($a,$b),any($c,$d)) == any($a,$b,$c,$d) True. all($a, $a) == $a True. all($a,$a,$b) == all($a,$b) False. The autothreading makes that: all( $a==$a, $a==$b, $b==$b, $b==$a) and they're not (in general) all true. all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d) False. Because all($a,$b) != all($a,$b,$c,$d) none($a, $a) == undef True. none($a,$a,$b) == none($a,$b) True. none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) True. one($a, $a) == false True. one($a,$a,$b) == ($a == $b ?? undef :: $b) True. Damian
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 05:49:44PM -0600, Rod Adams wrote: > Damian Conway wrote: > > > >That would be disturbing if that's what happened. > >C is just a shorthand for C. > >So saying a junction is the same as printing it, which is a run-time > >error. > > Could easily be achieved with a single layer of encapsulation? > > perl6 -e "$x = 'cat'|'dog'; say1 $x; sub say1 ($x) {say $x}" > > Or is the consensus that that's somehow not disturbing, and direct calls > are disturbing. Here are some options in the absence of other syntactic modulation: * No it's not disturbing nor is it surprising. You've written a routine that's not Junction-aware and you've given it a Junction thus triggering the autothreading behavior. * As per Larry's earlier email, perhaps the assignment generates an error because you haven't asked for your mind to be warped that way. * In my view of autothreading as a dangerous default, you get an error because C isn't autothreaded and C<$x> parameter to C is a Junction. Passing a Junction to C generates an error. You get the same behavior as that last one if the Any type is consistent with the Junction type (which no one has yet commented on but makes sense to me). That would mean autothreading only happens on routines with explicitly typed non-Junctionish parameters. > If what you're saying is true, then feeding a junction into DBI for a > "insert" statement, since the output proper is encapsulated, would > create multiple new records in the database? I'm back to being very > disturbed. You're also making some assumptions that may not be true. Using existing DBI with perl6 should cause DBI to run with perl5 semantics thus triggering an error if passed a Junction. A perl6 DBI would be written such that Junctions can't be put in places that don't want them (at least that's how *I* would do it). For the case where a junction is stringified, I would imagine that the Junction's C or C (ala python) method gets called and it does something appropriate. Those are my assumptions. > Patrick R. Michaud wrote: > >OTOH, what happens with...? > > > > sub nofun($x is rw) { > > $x += 2; > > } > > > > $y = 3 | 4; > > nofun($y); That's either an error ("Can't modify constant") or the same as 5|6. The former makes the most sense to me at the moment. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Junction Values
On Wed, Feb 16, 2005 at 12:17:35PM +1100, Damian Conway wrote: > >none($a, $a) == undef > > True. Isn't this one false in the case when $a is undef? -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Containers vs Objects.
On Tue, Feb 15, 2005 at 04:20:28PM -0600, Rod Adams wrote: : chromatic wrote: : : >>So I'm interested in hearing what pushes Arrays and Hashes over the edge : >>for needing their own container and sigil, whereas Junctions/Sets do not. : >> : >> : > : >Perl isn't a "pure" object-oriented language. : > : > : Rephrasing my question: : : What characteristics would _any_ new structure or class have to have to : merit becoming a first class container with it's own sigil, rather than : being just another class? It would have to be very much basic to the way we classify nouns in our heads. So I think that sort of thing should be added about as often as a natural language adds a new case or number marker, which is not very. To be sure, English is not a great example of clarity here. English junctions cause a great deal of confusion on the subject of singular and plural verbs: If any of you are coming to the store... If any of you is coming to the store... : Or is Perl close enough to "pure" object-oriented these days, where only : grandfathered classes make the cut? Well, the reason we grandfather the grandfathers is that we wouldn't be here without them. There's a precedence to things such that descendents don't happen without ancestors. The very fact that something is historical means that it has generally had more influence than anything derived from it. By that argument, Perl programmers have spent a great deal more time thinking about plural values as arrays than as junctions or sets or objects. That's not the only way to think--and I've certainly realized that in studying Japanese, wherein there is no grammatical singular/plural distinction--but it's how a lot of English speakers think, and a lot of existing Perl programmers too. But as far as English is concerned, sets are just objects that have a singular outside and a (potentially) plural inside, much like almost any other object. At least, that's how concrete sets work. The problem is that as soon as you start throwing junctionals around, you're now talking about abstract set definitions with all sorts of interesting entanglements inside. That's the basic problem with 0 < $x < 10 after all--the problem with rewriting that as 0 < $x and $x < 10 is that it should only work as long as the two values of $x remain entangled so that the always refer to the same abstract value. : As a separate question, is there a relatively easy way to create a : user-defined class with it's own sigil? (w/o having to modify half the : parse rules). Certainly, just say macro term:<¢> ($name) is parsed(m:p//) {...} or some such. (Making it interpolate would be a little more work.) Larry
Re: Containers vs Objects.
Larry wrote: That's the basic problem with 0 < $x < 10 after all--the problem with rewriting that as 0 < $x and $x < 10 is that it should only work as long as the two values of $x remain entangled so that the always refer to the same abstract value. That's certainly true. But I think the real problem there is in mistakenly treating Perl 6 comparators as binary ops (with n-ary sugar), rather than as genuine n-ary ops. That is, a junction must autothread early, and over the entire operation (or at least, over the entire equi-precedential part of the operation) in which it's used. So if: $x = -1 | 11; then: 10 < $x < 0 --> any(10 < -1 < 0, 10 < 11 < 0) --> any(10 < -1 && -1 < 0, 10 < 11 && 11 < 0) --> any(false, false) The mistake is in thinking that the n-ary comparison should be expanded before the junction autothreads. Damian
Re: Junction Values
Jonathan Scott Duff wrote: none($a, $a) == undef True. Isn't this one false in the case when $a is undef? Yes. Apologies for not being more precise. Damian
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 05:49:44PM -0600, Rod Adams wrote: > >As you've written things above, C is autothreaded (your option #3), > >and we'll see two C output lines if $DEBUG is set. > > The case of Damian's response in a prior message: > [...] > Could easily be achieved with a single layer of encapsulation? > > perl6 -e "$x = 'cat'|'dog'; say1 $x; sub say1 ($x) {say $x}" Nope. Even in this case you've created a function C with a scalar context that isn't expecting a junction of values, so the call to C is autothreaded over the values of the junction $x. > If what you're saying is true, then feeding a junction into DBI for a > "insert" statement, since the output proper is encapsulated, would > create multiple new records in the database? I'm back to being very > disturbed. Welcome to the world of dynamic languages. If junctions disturb you, then Perl 6's ability to override built-in routines and operators will really keep you up at night. (See C, and http://www.nntp.perl.org/group/perl.perl6.language/19195. :-) > Actually, using the semantics you've outlined above, there is no > implementation problem. > However, I disagree that those semantics are desirable. Fair enough. I'm not the one who expects to make that decision, nor am I really advocating a particular interpretation -- I'm trying to leave that to others. I'm just implementing (and explaining) how the "current state of things" appears to be based on the specs I've read. Pm
Re: Containers vs Objects.
On Wed, Feb 16, 2005 at 01:13:53PM +1100, Damian Conway wrote: : Larry wrote: : : >That's the basic problem with : > : >0 < $x < 10 : > : >after all--the problem with rewriting that as : > : >0 < $x and $x < 10 : > : >is that it should only work as long as the two values of $x remain : >entangled so that the always refer to the same abstract value. : : That's certainly true. But I think the real problem there is in mistakenly : treating Perl 6 comparators as binary ops (with n-ary sugar), rather than : as genuine n-ary ops. Yes, that's what I was trying to say, but my tongue got entangled with my thoughts... Larry
Re: Junction Values
On Wed, Feb 16, 2005 at 12:17:35PM +1100, Damian Conway wrote: > Rod Adams wrote: > >On a slightly different topic, do the following equivalences work: > >[...] > >none($a, $a) == undef > True. Scott already caught (and Damian acknowledged) this one, it's false if $a == undef. > >none($a,$a,$b) == none($a,$b) > True. Okay, I follow this one -- here's the derivation. -> none($a == none($a, $b), $b == none($a, $b)) -> none(none($a==$a, $a==$b), none($b==$a, $b==$b)) -> none(none(1, 0), none(0, 1)) -> none(0, 0) -> true > >none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) > True. H... -> none(none($a,$b) == none($a,$b,$c,$d), none($c,$d) == none($a,$b,$c,$d)) -> none(none($a == none($a,$b,$c,$d), $b == none($a,$b,$c,$d)), none($c == none($a,$b,$c,$d), $d == none($a,$b,$c,$d))) -> none(none(none($a==$a, $a==$b, $a==$c, $a==$d), none($b==$a, $b==$b, $b==$c, $b==$d)), none(none($c==$a, $c==$b, $c==$c, $c==$d), none($d==$a, $d==$b, $d==$c, $d==$d))) -> none(none(none(1, 0, 0, 0), none(0, 1, 0, 0)), none(none(0, 0, 1, 0), none(0, 0, 0, 1))) -> none(none(0, 0), none(0, 0)) -> none(1,1) -> false Ummm, what am I missing? To state it another way... we can show that none($a,$b) == none($a, $b, $c, $d) is true, so none( none($a,$b), none($c,$d) ) == none($a, $b, $c, $d) is equivalent to none( none($a,$b) == none($a, $b, $c, $d), none($c,$d) == none($a, $b, $c, $d)) which is none(1, 1), or false. Did I autothread wrongly here? And for completeness... > >one($a,$a,$b) == ($a == $b ?? undef :: $b) > True. ...except when $a == $b == undef. Pm
Re: Junction Values
Damian Conway wrote: .values tells you what raw values are inside the junction. The other kind of introspection that's desirable is: "what raw values can *match* this junction". There would probably be a .states method for that. To see the difference between the two, consider: my $ideal_partner = all( any(Âtall dark richÂ), any(Ârich old frailÂ), any(ÂAustralian richÂ), ); $ideal_partner.values would return the three distinct values in the junction: ( any(Âtall dark richÂ), any(Ârich old frailÂ), any(ÂAustralian richÂ), ); But $ideal_partner.states would return only those non-junctive values that (smart-)match the junction. Namely, "rich". One would need a method of determining whether the C<.values> are in an any/all/none/one relationship. Trivial, but necessary. That and C<.values> are likely enough introspection. Leave the C<.state> for CPAN to solve. On a slightly different topic, do the following equivalences work: (I will assume in all my answers that $a, $b, $c, $d have different values, except where it doesn't matter either way). all($a,$a,$b) == all($a,$b) False. The autothreading makes that: all( $a==$a, $a==$b, $b==$b, $b==$a) and they're not (in general) all true. I knew I was typing this all wrong. Whipping out math symbols, replace the == with â, or identical to. In other words, I was not asking how C< if all($a,$a,$b) == all($a,$b) {...} > evaluated, but instead if if all($a,$a,$b) {...} if all($a,$b) {...} would both evaluate the same. And I was making no assumptions about the values of $a .. $d. all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d) False. Because all($a,$b) != all($a,$b,$c,$d) Should have been all(all($a,$b), all($c,$d)) â all($a,$b,$c,$d) Sorry for any confusion. It's just a real pain to type chars that are not bound on your keyboard. As for the undef's, I didn't know what else to call the empty junctive. -- Rod Adams
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 07:20:53PM -0600, Jonathan Scott Duff wrote: > > Patrick R. Michaud wrote: > > >OTOH, what happens with...? > > > > > > sub nofun($x is rw) { > > > $x += 2; > > > } > > > > > > $y = 3 | 4; > > > nofun($y); > > That's either an error ("Can't modify constant") or the same as 5|6. > The former makes the most sense to me at the moment. Hmm. $y is definitely not constant -- that's how I was able to do the assignment in the first place. And "is rw" certainly doesn't sound like "constant" to me. :-) I guess it's going to be 5|6 -- what happens is that the autothreading of nofun() is really passing the references to $y's individual elements, just like any other subroutine call passes references, and those individual elements are modified in place, just like any other subroutine call with "is rw" parameters. So, things are still consistent. :-) Pm
Re: Junction Values
Patrick R. Michaud wrote: none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) True. H... -> none(none($a,$b) == none($a,$b,$c,$d), none($c,$d) == none($a,$b,$c,$d)) -> none(none($a == none($a,$b,$c,$d), $b == none($a,$b,$c,$d)), none($c == none($a,$b,$c,$d), $d == none($a,$b,$c,$d))) -> none(none(none($a==$a, $a==$b, $a==$c, $a==$d), none($b==$a, $b==$b, $b==$c, $b==$d)), none(none($c==$a, $c==$b, $c==$c, $c==$d), none($d==$a, $d==$b, $d==$c, $d==$d))) -> none(none(none(1, 0, 0, 0), none(0, 1, 0, 0)), none(none(0, 0, 1, 0), none(0, 0, 0, 1))) -> none(none(0, 0), none(0, 0)) -> none(1,1) -> false Ummm, what am I missing? To state it another way... we can show that none($a,$b) == none($a, $b, $c, $d) is true, so none( none($a,$b), none($c,$d) ) == none($a, $b, $c, $d) is equivalent to none( none($a,$b) == none($a, $b, $c, $d), none($c,$d) == none($a, $b, $c, $d)) which is none(1, 1), or false. Did I autothread wrongly here? No, upon closer looking, you're right that it should both evaluate false, and that they are not equivalent in what I meant to be asking. none(none($a,$b),none($c,$d)) ? all(any($a,$b),any($c,$d)) Should work, though. Not that it helps simplify matters at all. In essence, what I'm doing is attempting to create a set of rules whereby one can simplify a junction, by removing the nestedness of it, or removing terms outright. In the process, I'm making sure that I understand what they mean. -- Rod Adams
Re: Junction Values
Patrick R. Michaud wrote: none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) True. H... -> none(none($a,$b) == none($a,$b,$c,$d), none($c,$d) == none($a,$b,$c,$d)) RHS distributes first. So the expansion is this instead... -> none(none(none($a,$b),none($c,$d)) == $a, none(none($a,$b),none($c,$d)) == $b, none(none($a,$b),none($c,$d)) == $c, none(none($a,$b),none($c,$d)) == $d, ) -> none(none(none($a,$b)=$a, none($c,$d)=$a), none(none($a,$b)=$b, none($c,$d)=$b), none(none($a,$b)=$c, none($c,$d)=$c), none(none($a,$b)=$d, none($c,$d)=$d), ) -> none(none(0, 1), none(0, 1), none(1, 0), none(1, 0), ) -> none(0, 0, 0, 0, ) -> true Ummm, what am I missing? To state it another way... we can show that none($a,$b) == none($a, $b, $c, $d) is true, RHS distributes first again: none($a,$b) == none($a, $b, $c, $d) -> none( none($a,$b)==$a, none($a,$b)==$b, none($a,$b)==$c, none($a,$b)==$d, ) -> none( 0, 0, 1, 1, ) -> false Damian
Re: Containers vs Objects.
On Wed, Feb 16, 2005 at 01:13:53PM +1100, Damian Conway wrote: > Larry wrote: > >0 < $x < 10 > >after all--the problem with rewriting that as > >0 < $x and $x < 10 > >is that it should only work as long as the two values of $x remain > >entangled so that the always refer to the same abstract value. > > That's certainly true. But I think the real problem there is in mistakenly > treating Perl 6 comparators as binary ops (with n-ary sugar), rather than > as genuine n-ary ops. > > That is, a junction must autothread early, and over the entire operation > (or at least, over the entire equi-precedential part of the operation) in > which it's used. Uh oh, I hadn't caught that particular nuance. Is it indeed over the entire equi-precedential part of the operation, or just over the chained operators? For example, given $x = -1 | 10; $ref.meth1($x).meth2($x) are the meth1 and meth2 calls considered to be "equi-precedential", with a result of ... any( $ref.meth1(-1).meth2(-1), $ref.meth1(10).meth2(10) )? And what of ... $ref.meth1($x) + $x are the $x still "tied" to each other even though they're being used at different levels of precedence? I.e., do I get any( $ref.meth1(-1) + -1, $ref.meth1(10) + 10) or any( any( $ref.meth1(-1) + -1, $ref.meth1(-1) + 10 ), any( $ref.meth1(10) + -1, $ref.meth1(10) + 10 ) ) ? Pm
Re: Junction Values
On Wed, Feb 16, 2005 at 02:53:15PM +1100, Damian Conway wrote: > Patrick R. Michaud wrote: > > >>>none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d) > >> > >>True. > > > > > >H... > > > > -> none(none($a,$b) == none($a,$b,$c,$d), > > none($c,$d) == none($a,$b,$c,$d)) > > RHS distributes first. So the expansion is this instead... Ummm, okay, but that's not what I interpreted from S09, where it says that the "left-most" conjunction or injunction is autothreaded first. In this I've also assumed that $a == $b is equivalent to &infix:<==>($a, $b) so I'm missing the piece that says to distribute the RHS first. Pm
Re: Junction Values
Patrick R. Michaud wrote: RHS distributes first. So the expansion is this instead... Ummm, okay, but that's not what I interpreted from S09, where it says that the "left-most" conjunction or injunction is autothreaded first. In this I've also assumed that $a == $b is equivalent to &infix:<==>($a, $b) so I'm missing the piece that says to distribute the RHS first. Probably because that piece is still only in my head. Or because I got that bit of S09 wrong. Or because Larry or Luke overrode me on it and I haven't updated my Perl6::Junctions module accordingly. ;-) So forget what I said, and go with what Patrick said. Since it's easy to argue the outcome of these corner cases either way (depending on how you backtranslate them to English), it will be best to make the rules consistent (i.e. left-most first for both functions and operators). Apologies all...and thanks Patrick. Damian
Re: Containers vs Objects.
Patrick R. Michaud wrote: Uh oh, I hadn't caught that particular nuance. Is it indeed over the entire equi-precedential part of the operation, or just over the chained operators? For example, given $x = -1 | 10; $ref.meth1($x).meth2($x) are the meth1 and meth2 calls considered to be "equi-precedential", I'm not sure that's the right question. I think the question is: what are the relative precedences of "argument list to method call" and "method call on result". And I think it's pretty clear that arg list wins there. So: $ref.meth1($x).meth2($x) -> any($ref.meth1(-1).meth2($x), $ref.meth1(10).meth2($x) ) -> any( any( $ref.meth1(-1).meth2(-1), $ref.meth1(-1).meth2(10) ), any( $ref.meth1(10).meth2(-1), $ref.meth1(10).meth2(10) ), ) Or to put it another way: method call isn't n-ary. And what of ... $ref.meth1($x) + $x are the $x still "tied" to each other even though they're being used at different levels of precedence? I.e., do I get any( $ref.meth1(-1) + -1, $ref.meth1(10) + 10) or any( any( $ref.meth1(-1) + -1, $ref.meth1(-1) + 10 ), any( $ref.meth1(10) + -1, $ref.meth1(10) + 10 ) ) Definitely the latter. As Einstein avowed: "no spooky action at a distance!" ;-) Damian
Re: Containers vs Objects.
Larry Wall wrote: But as far as English is concerned, sets are just objects that have a singular outside and a (potentially) plural inside, much like almost any other object. At least, that's how concrete sets work. Hmm. I would argue that most of the time, when English Speakers use sets quite commonly in their speak, and often refer to them as lists (e.g. Shopping Lists). In fact, when expressing any list, we go out of our way to explicitly give them an order or ranking. Not to mention people do think in terms of sets. Back to the shopping list, you have the set of things on your list (#list), and the set of things in your cart (#cart), as well as the things in the store (#store). What can you cross off your list? #list x #cart What's left to buy? #list - #cart What's not available? #list - #store What did you buy that wasn't asked for? #cart - #list Add to this the not infrequent use of the phrase "You listed ___ twice." in response to hearing a list, thus implying something more set-ish about it than an array gets. Or the frequency with which one gives six or more responses to the question "What are your top 5 ?" I have little ability to translate hashes into English, beyond "How many cans of ___ are in the cupboard?" So in terms of frequency of use in the English Language, I'd rank things in the following order: 1) Scalars 2) Sets 3) Arrays 4) Hashes As for Perl Speakers, I would argue that a high percentage of the time someone says C< for @list {...} >, they really don't care for which order the elements are executed in, just that they are. Creating a hash where all the values are 1, just to get the set like features of the keys, is a fairly common Perl idiom. As Computer Science Speakers, Sets are a very fundamental data structure. Okay, not as fundamental as Arrays. But easily more so than Hashes. Programmers tend not to speak in terms of Sets very often, because their languages don't support them. Junctions, on the other hand, almost never come up in English, except as a Set. Where do you see sentences which have a word which means two other words _at_once_, and the listener is supposed to understand all of the meanings? Double entendres come close, but there are two main drawbacks: 1) only a limited set of words can be used in this case, and each of them has a very limited number of values it can possess. Not any noun taking on the value of any two or more other nouns at once. 2) it is almost never in question that only one meaning was meant, and the other meaning was merely a cover, to prevent a faux-pas. -- Rod Adams
Boolean literals
Just a quick question. The prettyprinter of Pugs (the thing that handles the ".perl" method) currently prints out boolean true and false as #t and #f, which is obviously not correct. pugs> (1 > 2, 2 > 1) (#f, #t) What should I do, though? Inventing two primitives, "true" and "false"? Or is there a way to annotate values with types, similar to Haskell's "::" construct? pugs> (1 > 2, 2 > 1) (0 as Bool, 1 as Bool) Thanks, /Autrijus/ pgpBOnIuv0xyM.pgp Description: PGP signature
Re: Containers vs Objects.
On Tue, Feb 15, 2005 at 10:01:52PM -0600, Patrick R. Michaud wrote: : Uh oh, I hadn't caught that particular nuance. Is it indeed over the : entire equi-precedential part of the operation, or just over the : chained operators? Just the chained operators, I think. For more general expression threading you can always force it with $junkout = -> $x { random_expression }.($junkin) or $junkout = do given $junkin -> $x { random_expression } or some such (assuming the $x parameter is taken to be non-junctive). Larry
Re: Boolean literals
On Wed, Feb 16, 2005 at 02:29:36PM +0800, Autrijus Tang wrote: : Just a quick question. The prettyprinter of Pugs (the thing that : handles the ".perl" method) currently prints out boolean true and : false as #t and #f, which is obviously not correct. : : pugs> (1 > 2, 2 > 1) : (#f, #t) : : What should I do, though? Inventing two primitives, "true" and : "false"? Or is there a way to annotate values with types, similar : to Haskell's "::" construct? : : pugs> (1 > 2, 2 > 1) : (0 as Bool, 1 as Bool) The latest S12 has it as bool::true and bool::false. (In general, you can print out any enum as "role::identifier".) When unambiguous, bare "true" and "false" can be used, but in any event the use of symbolic booleans is somewhat discouraged in Perl because it leads people to write stupidities like while foo() == true {...} Instead, we try to make sure all types know how to behave in boolean context directly. Any object that does the "bool" role has an attribute of type "bit", which will return 0 if the object is false, and 1 if the object is true. (The optimizer is free to optimize away the method call if it can, of course. Native integers and floats are always true if non-zero, for instance. But object types can always be derived from, or have "but true" mixed into them.) Larry
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 07:20:53PM -0600, Jonathan Scott Duff wrote: : For the case where a junction is stringified, I would imagine that the : Junction's C or C (ala python) method gets called and it does : something appropriate. The C method is called C<.perl> in Perl, assuming you want a Perl representation. If you want Python's .repr you could perhaps call .python instead. Likewise you could spit out a .lisp, .xml, or .fortran representation if those methods are available. Personally I'm looking forward to seeing what the .mathematica method spits out for a junction, but maybe I'll have to settle for a .apl method instead. I admit that calling the .brainf*ck method is problematic several ways... Larry
Re: Fun with junctions (was Sets vs Junctions)
On Tue, Feb 15, 2005 at 09:34:31PM -0600, Patrick R. Michaud wrote: > On Tue, Feb 15, 2005 at 07:20:53PM -0600, Jonathan Scott Duff wrote: > > > Patrick R. Michaud wrote: > > > >OTOH, what happens with...? > > > > > > > > sub nofun($x is rw) { > > > > $x += 2; > > > > } > > > > > > > > $y = 3 | 4; > > > > nofun($y); > > > > That's either an error ("Can't modify constant") or the same as 5|6. > > The former makes the most sense to me at the moment. > > Hmm. $y is definitely not constant -- that's how I was able to do > the assignment in the first place. And "is rw" certainly doesn't > sound like "constant" to me. :-) No, no, I was thinking that $y is composed of constants 3 and 4. The autothreading happens such that the call to nofun() is the same as if you'd written: 3 += 2; 4 += 2; which are attempts to modify those constants. This is assuming that the Any type is inconsistent with the Junction type; otherwise it's just the same as $y += 2; which should certainly yield 5|6 $y += 2 -> $y = $y + 2 -> $y = (3 + 2)|(4 +2) -> $y = 5|6 -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]