RE: overloading the variable declaration process
Stevan Little wrote: ^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the class (actually it's a prototypical instance of the class which the metaclass ^Dog describes, but you dont really need to know that to use it). ^Dog.can(bark) # false Dog.can(bark) # true Wasn't the ^ sigil dropped in favor of a 0..^n list creation op? So the first line is spelled ::Dog.can(bark) # false instead? Of course you have a conceptual circulatiry issue now because well,.. what is a MetaClass? Well it could be an instance of a MetaMetaClass, but what is that an instance of? This could go on forever (turtles all the way down as it is sometimes called). But in practice you either just stop and say this is as far as it goes, or you bootstrap your class model somehow and tie the knot. I prefer the boostrapping as it is much more elegant and tends to allow for much more flexibility. I agree. Your cicularity is basically an a-priori infinity conceptually one level outside of the meta system. And there will be an orthogonal type/kind system. IIRC, you can always create a new method for a class, even outside of its definition, simply by ensuring that the first parameter to be passed in will be an object of that type: method bark (Dog $_) { ... } I don't think this is true unless it is a multi method, in which case it is not actually a method of the of the class, but instead just DWIMs because of MMD and the fact we allow an invocant calling style freely. Yes, the question of ownership of methods is still somewhat unresolved. I think we need to distinguish something I've called slots in an object from free (multi) methods that are defined outside of the class definition block. BTW, do the outsiders have access to the private data slots with the $! twigil? or maybe method Dog.bark () { ... } Yes that works too. Shouldn't that read Dog::bark? Why the dot? -- $TSa.greeting := HaloO; # mind the echo!
order ops beeing based on a ternary MMD?
HaloO, this sort of follows up on the 'Re: Junctions again (was Re: binding arguments)' thread. The point I tried to make there is that the optimizer needs the permission to change boolean checks in the prime boolean block controller 'if' and its friends like unless, while etc. Of course certain contstraints must hold. These are IMHO the axioms of a group with the six compare ops , ==, , =, !=, = and negation in general. And of course the string equivalents lt, eq, gt, ge, ne, le. These ops are not fundamental, though. I see them more as syntactic sugar for an underlying framework build around = and cmp which return one(-1,0,+1). In the numeric case the minus function might suffice. Well and there is the fourth return type undef that somehow must be digested by if and unless. For if the undef right away prevents the entry to the controlled block, but should unless allow entry? I see an undef boolean more like none(true,false) which might nicely prevent entry in both cases, or so. Here is the lattice defining the join and meet replacement operations that the optimizer might use to cut away branches in a truth check. For junctions this has to be deferred until runtime: ( ) # undef, none(-1,0,+1) / | \ / | \ /\ / | \ meet/|\ (-1) (0) (+1) # one(-1,0,+1) element belt join |\ / \ /| \/| \/ \/ |# no intersection of diagonals | /\ /\ | |/ \ / \| (-1,0) (-1,+1) (0,+1)# one( any(-1,0), any(-1,+1), any(0,+1) ) \|/ \ | / \ | / \ | / (-1,0,+1) # any(-1,0,+1) The underlying idea is that the Int type arises similarly Void / | \ / | \ / | \ /|\ Neg Zero Pos |\ / \ /| | \/ \/ | | /\ /\ | |/ \ / \| NonPos NonZero NonNeg \|/ \ | / \ | / \ | / Int NonPos ::= Neg | Zero # (-1, 0) NonZero ::= Neg | Pos# (-1, +1) NonNeg ::= Zero | Pos# (0,+1) The full glory of Num arises when the void between the int values is filled with remainders. Doubling then gives the Complex type which drops out of Order ;) Not to mention Quaternions and Octonions! The ternary compare MMD method then has the default entries compare:(Str,Str,Str) compare:(Str,Any,Any) compare:(Num,Num,Num) compare:(Num,Any,Any) and perhaps and optimized version for compare:(Int,Int,Int) The first parameter is just used to constrain the choice of MMD. It is usually provided syntactically. The interesting question is how a *heterogenous* list of things is sorted! Because there this first parameter needs to be determined upfront from the other two. In other words the above compare methods might actually look like compare:( ::X, ::Y : ::Z where { Z does meet(X,Y): } -- one(-1,0,+1) ) with the syntactic parameter last for syntactic reasons. Note the two colons to indicate a two step dispatch! BTW, I would welcome the addition of meet and join lattice operations to the set of Perl6's ops. With the nice operator spelling /\ and \/ respectively: \/ join, supremum, least upper bound, |, any(), .kind, max, union /\ meet, infimum, greatest lower bound, , all(), .meta, min, intersection Comments? -- $TSa.greeting := HaloO; # mind the echo!
syntactic, static and dynamic type
HaloO, I'm still trying to understand the concept of context in Perl6 from a typing perspective. My current interpretation let me to coin three levels of typing in Perl6: syntactic, static and dynamic. I guess the latter two are well known but the syntactic type is new---at least do I hope so. Please inform me about prior art! Well, in a certain way I've just replaced context with 'syntactic type' to get two better understood words in there. Here's a little table summarizing the idea: type| syntactical | static | dynamic +-++--- | compiler| runtime handler +-++--- | parser | inferencer | dispatcher The syntactical type is strongly coupled with the sigils which serve as some minimal type information and together with whitespace, comma, semicolon and parens provide the basic tokenization. Again I'll try to express the concept in a little table: meaning | sigil| handler ---+--+---+ arity | type |:: | compile ---+--+---+ | code || . | 1 +--+-+-+ | item | $ | : | runtime ---+--+-+-+ 0..Inf | data | @ | % | ---+--+-+-+ access| pos | key | The Fantastic Four [EMAIL PROTECTED] can be used to declare variables while the dotted three :: : . are syntactic markers only. The rest of the language is operator recognition and special forms for statements and declaration. Comments? -- TSa
RE: multisub.arity?
HaloO, Luke wrote: I just proved that is not transitive. I can do that for every boolean operator that Perl has. They no longer have any general properties, so you can't write code based on assumptions that they do. In particular, testing whether all elements in a list are equal goes from an O(n) operation to an O(n^2) operation, since I can't make the assumption that equality is transitive. I fully second this. I guess the axiom of excluded middle simply doesn't hold for the four junction types, nor are they ordered. (Sidenode as non-native: is the last usage of 'nor' incorrect?) But so will be many other types. Could someone point me to a mathematical paper or general material what axiom system applies to junctions? So my original point was that, as cool as junctions are, they must not be values, lest logical assumptions that code makes be violated. I can tell you one thing: an ordered set class assumes that is transitive. You had better not make an ordered set of junctions! With a certain stricture on defining the meaning of tokens like I think Perl6 shouldn't join poor C++ with its fixed set of operators to overload ops arbitrarily with unrelated meaning. Unicode has enough to offer. But back to the point that Luke made: all comparison ops don't apply to junctions which spoils a big advantage and deminishes junctions to a nice form to avoid chained boolean connectives like || with an any(). To me junctions always felt more code like than value like. They are even some kind of meta ops that consume boolean comparison ops in terms of another boolean connective (any = or, all = and, etc.) Why not reflect that in the syntax and make them like for, map, grep etc? I mean with the junction name in front: if all( @new_coefficients @prev_coefficients ) {...} or Brent's example if any( $active eq ['all', keys %to] ) {...} The desugared forms would be simple ternary calls: if any( infix:{''}, $active, ['all', keys %to] ) {...} The return value would need to be lists of tuples to allow combining junctions: if any($x all(@values 0)) That latter property also gives for all(@values 0) - $x { say sqrt $x } And as all other code types junctions are subject to currying and later usage like other code refs x_in = any.assuming( lhs = $x, op = infix:== ); if x_in( @array ) {...} With (curried) junctions travelling in vars I guess people have less problems with the auto-threading behaviour as well. Hmm, and we win back the three single character infix ops |, and ^. The simple example if $x == 1|2|3 {...} then reads if any($x == [1,2,3]) {...} I admit though, that the any might be optically attached to the $x and not to the implicitly hyperated ==. Thus the idiom needs to be spelled if any([1,2,3] == $x) {...} TSa.
RE: Proposal: split ternary ?? :: into binary ?? and //
HaloO, Luke wrote: ?? !! ain't bad either. It's definitely much better that sabotaging the (highly useful) // operator within (highly useful) ternaries. I guess the thing that I really think is nice is getting :: out of that role and into the type-only domain. Right. To make :: indicate type or meta was my primary concern. So I see the following situation: unwanted ?? :: ASCII replacements ?? //# two binaries ?? \\# I would like it as chaining binary nor ?? !!# wasn't binary ! the none() constructor # and !! the binary nor---at least in Pugs? Latin1 replacements ?? ¦¦ ?? ¡¡ ?? ¿¿ @Larry's choice? -- TSa
RE: Proposal: split ternary ?? :: into binary ?? and //
HaloO, Luke wrote: Okay, now why don't you tell us about this new binary :: you're proposing. Well, not a new one. Just plain old foo::bar::blahh and 'my ::blubb $x' with relaxed whitespace rules. The ternary ?? :: is a splinter in my mind's eye because it is not a compile time or symbol lookup construct. The driving idea is to let tokens always mean the same or at least very similar things in different contexts. And I thought that is your rating as well. For :: that should be 'symbol table management'. E.g. ::= fits that notion perfectly while the alternative separation of the ternary doesn't. There's yet another approach, to make ternary listfix: $val = $cond ?? true ?? false; and perhaps we change it from ternary to (n 2)-ary: $val = $tested_only ?? $val_or_test ?? $other_or_test ?? $final; But in both ways, recursive ternary needs parens. Which can be regarded as a good thing. This listfix ?? behaves more like a rhs returning ||. As the RegularityGuy(TM) I like the chaining triple // || \\ where // returns the first defined, || returns the first true and \\ returns the first false. And of course there are low precedence counterparts err, or, nor. And the binary \ for none() construction. BTW is (\) indicating the relative complement of the set operators? Even the unary ref prefix makes sense as \ because it means 'not the value' or 'not right here but keep for later reference'. -- TSa
Proposal: split ternary ?? :: into binary ?? and //
HaloO, I'm still contemplating how to get rid of the :: in the ternary and make :: unequivocally available for a type sigil and as a binary infix for symbol lookup. Here's a possible solution: 1) ?? becomes a binary operator that behaves as follows: a) it evaluates its lhs in boolean context b) if this is true, ?? evaluates its rhs such that it can't be undef c) if this is false, ?? returns undef 2) the precedence of ?? is above // which naturally catches the undef of a false condition. This gives $x = $y 3 ?? small // large; and possibly even a low precedence version $x = $y 3 then small err large; # hmm thence # old fashioned therefore # long, but clear An implementation could read: *infix:?? (cond, code) is parsed(...) # trait needed to insert {}? { if cond() { return code() but defined } else { return undef } } Comments? TSa
Re: Transparent / Opaque references = Link / Ref
Luke wrote: Both transparent dereferencing (infinite $$foo) and opaque dereferencing (one-level $$foo) have their uses, but they are definitely distinct. Well, they are more like variations on a theme. Instead of adding different syntax for each kind, I'll propose something different: two types of references: Opaque and transparent. Which could be as simple as a boolean property .opaque on the Ref class or with the reverse meaning .transparent or .autoref which I think is better self documenting. OTOH for MMD distinct types are better. Other well known terms for indirection besides reference are pointer and link. Pointer sounds a bit too low level. So we could choose Ref = opaque, one-level (this also maintains the Perl 5 meaning) Link = transparent, chain following Jargon would be that you deref a Ref but you follow a Link. The latter is an intrinsic feature of the language. Links will be hardly visible on language level. Something like my Link $x; sub foo( Link $l ) { ... } would be errors but could also be just superfluous because every variable basically is a link. I haven't worked that out, though. Opaque references always need to be explicitly dereferenced (except for binding an array to an array reference, etc.). Which is easily achievable with overloads of infix:{'='} for Array and Ref of Array. While Link should be more of a subtype of the value it links to. Thus links are more intrinsic to the language infra-structure while Ref is an application level concept. Transparent references always automatically dereference. The decision of what type of dereferencing will go on is left up to the reference taker. What I can't decide is which one \ will create, and how you will create the other kind. Also, I can't decide how to one-level dereference the transparent references so that you can change them. I would make prefix:\ a normal operator available for overloading. Nourishing my idea that none of ::=, := and =:= are overloadable I would like to invent another colon op like :\ or \: which if given term precedence might give access to the Link of a variable such that \:$link.some_link_method() or :\$link.some_link_method() mean (\:$link).some_link_method() or (:\$link).some_link_method() Hmm, I like the :\ better because it goes with its counterpart := the link operator. This nicely mirrors the pair \ and = somewhat. I admit that :\ is not a real beauty but its seldomly used anyway. The only question that remains is how then to single step down the link chain if that isn't contradicting the link concept in the first place. But I think it doesn't need an operator. A method might suffice: :\$link.follow.follow -- TSa (Thomas Sandla)
RE: Transparent / Opaque references
Luke wrote: Both transparent dereferencing (infinite $$foo) and opaque dereferencing (one-level $$foo) have their uses, but they are definitely distinct. Well, they are more like variations on a theme. Instead of adding different syntax for each kind, I'll propose something different: two types of references: Opaque and transparent. Which could be as simple as a boolean property .opaque on the Ref class or with the reverse meaning .transparent or .autoref which I think is better self documenting. OTOH for MMD distinct types are better. Other well known terms for indirection besides reference are pointer and link. Pointer sounds a bit too low level. So we could choose Ref = opaque, one-level (this also maintains the Perl 5 meaning) Link = transparent, chain following Jargon would be that you deref a Ref but you follow a Link. The latter is actually an intrinsic feature of the language. Links will be hardly visible on language level. Something like my Link $x; sub foo( Link $l ) { ... } would be errors but could also be just superfluous because every variable basically is a link. I haven't worked that out. Opaque references always need to be explicitly dereferenced (except for binding an array to an array reference, etc.). Which is easily achievable with overloads of infix:{'='} for Array and Ref of Array. While Link should be more of a subtype of the value it links to. Thus links are more intrinsic to the language infra-structure while Ref is an application level concept. Transparent references always automatically dereference. The decision of what type of dereferencing will go on is left up to the reference taker. What I can't decide is which one \ will create, and how you will create the other kind. Also, I can't decide how to one-level dereference the transparent references so that you can change them. I would make prefix:\ a normal operator available for overloading. Nourishing my idea that none of ::=, := and =:= are overloadable I would like to invent another colon op like :\ or \: which if given term precedence might give access to the Link of a variable such that \:$link.some_link_method() or :\$link.some_link_method() mean (\:$link).some_link_method() or (:\$link).some_link_method() Hmm, I like the :\ better because it goes with its counterpart := the link operator. This nicely mirrors the pair \ and = somewhat. The only question that remains is how then to single step down the link chain if that isn't contradicting the link concept in the first place. But I think it doesn't need an operator. A method might suffice: :\$link.follow.follow -- TSa (Thomas Sandla)
RE: Transparent / Opaque references = Link / Ref
Luke wrote: Both transparent dereferencing (infinite $$foo) and opaque dereferencing (one-level $$foo) have their uses, but they are definitely distinct. Well, they are more like variations on a theme. Instead of adding different syntax for each kind, I'll propose something different: two types of references: Opaque and transparent. Which could be as simple as a boolean property .opaque on the Ref class or with the reverse meaning .transparent or .autoref which I think is better self documenting. OTOH for MMD distinct types are better. Other well known terms for indirection besides reference are pointer and link. Pointer sounds a bit too low level. So we could choose Ref = opaque, one-level (this also maintains the Perl 5 meaning) Link = transparent, chain following Jargon would be that you deref a Ref but you follow a Link. The latter is actually an intrinsic feature of the language. Links will be hardly visible on language level. Something like my Link $x; sub foo( Link $l ) { ... } would be errors but could also be just superfluous because every variable basically is a link. I haven't worked that out. Opaque references always need to be explicitly dereferenced (except for binding an array to an array reference, etc.). Which is easily achievable with overloads of infix:{'='} for Array and Ref of Array. While Link should be more of a subtype of the value it links to. Thus links are more intrinsic to the language infra-structure while Ref is an application level concept. Transparent references always automatically dereference. The decision of what type of dereferencing will go on is left up to the reference taker. What I can't decide is which one \ will create, and how you will create the other kind. Also, I can't decide how to one-level dereference the transparent references so that you can change them. I would make prefix:\ a normal operator available for overloading. Nourishing my idea that none of ::=, := and =:= are overloadable I would like to invent another colon op like :\ or \: which if given term precedence might give access to the Link of a variable such that \:$link.some_link_method() or :\$link.some_link_method() mean (\:$link).some_link_method() or (:\$link).some_link_method() Hmm, I like the :\ better because it goes with its counterpart := the link operator. This nicely mirrors the pair \ and = somewhat. The only question that remains is how then to single step down the link chain if that isn't contradicting the link concept in the first place. But I think it doesn't need an operator. A method might suffice: :\$link.follow.follow -- TSa (Thomas Sandla)
RE: Transparent / Opaque references
Juerd wrote: The only real problem with having only infix := for binding, is that you can't easily use an alias (aka transparent reference) in a list. You can have an array of aliases, but it's harder to have an array or hash in which one element is an alias. Binding can be done explicitly: %hash = { key = undef, foo = 'bar' }; %hashkey := $variable; %hashkey = 5; # $variable is now 5 too Sorry to interrupt, but wasn't {} not derefed when assigned to a % variable? Don't get me wrong, I like this meaning. And it seems to be intuitive once in a while ;) But there is no way to set the transparent reference (aka alias) initially, because we lack a \-like syntax. Why isn't \ good enough there? Because it requires $%hashkey = 5? So I propose that := becomes a prefix operator as well as an infix one, allowing: %hash = { key = := $variable, foo = 'bar' }; %hashkey = 5; # $variable is now 5 too I propose %hash = { key = :\$variable, foo = 'bar' }; Or should we also invent := to make a key/link pair? Question: when a variable contains an opaque Ref and one uses this variable in an assignment as lhs, that still goes to the referee? How is the variable then detached? To wit: $var = 7; $ref = \$var; $$ref = 12; # should $ref suffice? say $var; # prints 12 $ref = 17; # detaches? Or is :\$ref = 17 needed? say $var; # still prints 12 -- TSa (Thomas Sandla)