Re: statement_controlfoo()
On Wed, 30 Nov 2005, Piers Cawley wrote: $fh = open '', 'quotefile' or fail; $fh.print 'EOQ' Hmmm... 1/sqrt(2) * ( |Perl5 + |Perl6 ) ? ;-) (I thought '' C. were gone...) Michele -- We can only see a short distance ahead, but we can see plenty there that needs to be done. - Alan Turing
Capabilities in Perl6?
I just read the slides about CAPerl (http://caperl.links.org/) and it's an interesting idea. Leaving aside the question of whether this would work in Perl5 or not, I think it would be very interesting to look at building this concept into Perl6. Here's how I'd envision doing so: * Any subroutine is allowed to work with the parameters it was given. (If you didn't want it to work with those, why did you give them to it?) Variables outside its scope are, by default, not allowed. * When looking at a variable you're allowed to see, you are only allowed to use the methods it exposes - no peeking! * A subroutine may be explicitly granted access to a variable in a parent scope through the grant keyword. (More later.) * A subroutine may be disallowed access to a variable in a parent scope through the revoke keyword. (More later.) * Access to resources outside the program (files, etc) must be provided to the subroutine through parameters or explicit grants. * The outermost scope is completely trusted. (Someone has to be ...) Grant/revoke (names may be changed, as needed) take the following (pseudocode) signatures: grant ( Sub, Var, [Var, ... ] ) revoke( Sub, Var, [Var, ... ] ) It is an error to: * attempt to grant/revoke access to a variable you don't have access to * attempt to grant/revoke access to a variable that isn't in scope for the grantee Thanks, Rob
Re: Capabilities in Perl6?
On Thu, Dec 01, 2005 at 10:54:14AM -0500, Rob Kinyon wrote: : I just read the slides about CAPerl (http://caperl.links.org/) and it's an : interesting idea. Leaving aside the question of whether this would work in : Perl5 or not, I think it would be very interesting to look at building this : concept into Perl6. Here's how I'd envision doing so: We should probably think about as a potential variant of the recent env addition to S02. : * Any subroutine is allowed to work with the parameters it was given. : (If you didn't want it to work with those, why did you give them to it?) Um, maybe because you're calling a set of routines, and some of the routines are interested in some of the initializers but not others? Currently we have methods implicitly all having *%_ to soak up unexpected arguments. : Variables outside its scope are, by default, not allowed. Maybe we need to differentiate lexical and dynamic scoping here. The env mechanism is only addressing dynamic scoping of lexicals. And we turn on $_ visibility by default. That would be a considered a security hole under this model. : * When looking at a variable you're allowed to see, you are only allowed : to use the methods it exposes - no peeking! I'm not entirely sure what this means. What counts as a method? Use as an rvalue? Use as an lvalue. Modification? Different scopes see different sets of methods to attributes depending on whether the attribute is private/public, rw or readonly, native or boxed type. I can see a lot of times where you might be allowed to read a native value but not write it, for instance. (Possibly readonly access to any externals should be the default for eval, even if we don't go with a stronger capabilities model.) : * A subroutine may be explicitly granted access to a variable in a : parent scope through the grant keyword. (More later.) More or less what the env declarator does. : * A subroutine may be disallowed access to a variable in a parent scope : through the revoke keyword. (More later.) That would currently have to be done with an inner my scope to hide the env scope. : * Access to resources outside the program (files, etc) must be provided : to the subroutine through parameters or explicit grants. Hmm. What if you want to provide part of %ENV? I suppose one would have to copy in your own env %ENV. : * The outermost scope is completely trusted. (Someone has to be ...) What's an outermost scope? Dynamic or lexical? What about modules that can be executed directly? : Grant/revoke (names may be changed, as needed) take the following : (pseudocode) signatures: : grant ( Sub, Var, [Var, ... ] ) : revoke( Sub, Var, [Var, ... ] ) Seems inside out to me in the use vars vs our sense. I think these things want to associate with the declaration, which is why things like our and env are declarators. Minor magical stuff that is orthogonal to declarators ends up as traits. : It is an error to: : * attempt to grant/revoke access to a variable you don't have access to : * attempt to grant/revoke access to a variable that isn't in scope for : the grantee More good reasons for attaching the grant to the declaration in the first place. If you're going to grant access by delegation then you should *use* delegation, I expect. Larry
Re: Capabilities in Perl6?
On Thu, Dec 01, 2005 at 10:54:14 -0500, Rob Kinyon wrote: I just read the slides about CAPerl (http://caperl.links.org/) and it's an interesting idea. The ideas I tossed around regarding the circular prelude should make perl 6 be roughly on the same level as javascript in terms of this security stuff. This is a very good start towards a model where a crippled runtime is mixed with a fully priviliged one, with grey areas in the middle. -- () Yuval Kogman [EMAIL PROTECTED] 0xEBD27418 perl hacker /\ kung foo master: : neeyah! pgphItl8rypLf.pgp Description: PGP signature
PIR methods and local variables occupy the same 'namespace'
I realize this is a side effect of the fact that method names are actually strings, but it's an unfortunate result. If I have a little bit of code that calls a method without quotes around the name of the method, it calls the method (prints out Boojum), exactly as expected: .sub main :main newclass $P1, 'Thingy' $P2 = new 'Thingy' $P2.snark() end .end .namespace [ Thingy ] .sub snark method print Boojum\n .end But, if I were to foolishly have a local PMC variable of the same name as the method in the same compilation unit as the method call, then it tries to invoke the local variable: .sub main :main newclass $P1, 'Thingy' $P2 = new 'Thingy' .local pmc snark snark = new PerlArray $P2.snark() end .end And I get the error: invoke() not implemented in class 'PerlArray' If the local variable happens to be a string, it treats the string as the name of the method and calls that. So if the string happens to be snark it calls the snark method and prints out Boojum, otherwise it fails (because Thingy doesn't have any other methods, so any other method name is not found). .sub main :main newclass $P1, 'Thingy' $P2 = new 'Thingy' .local string snark snark = snark $P2.snark() end .end There's an easy way to ensure the clash between method names and local variables never happens: always wrap the method name in quotes. This will never try to invoke the local snark variable, because it knows the method name is a literal string. .sub main :main newclass $P1, 'Thingy' $P2 = new 'Thingy' .local pmc snark snark = new PerlArray $P2.snark() end .end So, my question is, should we prevent the obj.method() syntax from ever being interpreted as object.method()? It's nice convenient syntax, but makes for some pretty nasty collisions. Or, maybe there's another solution, like requiring some explicit way of marking when obj.method() is doing anything other than obj.method(). (That at least has the advantage of making the common case the default.) And, yeah, I just spent some time debugging a bit of code that read something like: .local pmc children children = node.children() Allison
Namespaces (At Long Last)
After many months and lots of work, I'm happy to present you with the latest namespace spec draft. Comments are most welcome: to quote Chip, The rest of the discussion would benefit from more eyes. Thanks, -- matt diephouse http://matt.diephouse.com Synopsis - Languages should contain their namespaces - Namespaces should be hierarchical - Add a get_namespace opcode (that takes an array or a multidimensional hash index) - Namespaces follow the semantics of the HLL in which they're defined - Imports follow the semantics of the library's language - Two interfaces: typed and generic Namespace PMC API There are many different ways to implement a namespace and Parrot's target languages display a wide variety of them. By implementing an API, it should be possible to allow interoperability while still allowing each one choose the best internal representation. Definitions HLL A High Level Language, such as Perl, Python, or Tcl. This is in contrast to PIR. Current namespace The current namespace is the namespace associated with the currently executing subroutine. Naming Conventions For interoperability, languages should use hierarchical namespaces. There's no way to outlaw flat namespaces, of course, and that remains an option for language implementors, but a standard must be chosen for easy interoperability, and hierarchical seems to be the better choice. HLL Private Namespaces HLLs should use a namespace with an underscore and the lowercased name of the HLL to store any private items. For instance, Tcl should use the _tcl namespace to store the subroutines that make up the compiler. User Defined Namespaces All HLLs should prefix any namespaces with the lowercased name of the HLL (so there's no question of what to capitalize). So Perl 5's CGI module should be stored under perl5::CGI. This eliminates any accidental collisions between languages. Interfaces: Generic and Typed Most languages leave their symbols plain, which makes lookups quite straightforward. Others use sigils or other mangling techniques, complicating the problem of interoperability. Parrot namespaces assist with interoperability by providing two interface subsets: the *raw interface* and the *typed interface*. Raw Interface Each HLL may, when working with its own namespace objects, use the *raw interface*, which allows direct naming in the native style of the namespace's HLL. This interface consists of the following methods: TODO: Decide whether this is best exposed by does hash. add($S0, $P0) Store the PMC in $P0 under the raw name $S0. del($S0) Delete the entry named $S0. $P0 = find($S0) Find the sub, namespace, or variable named $S0. Return a null PMC on lookup failure. $P0 = names() Get an array of the names contained in the namespace. NOTE: The return value may be a psuedo-array holding a reference to the namespace and some kind of internal iterator. Typed Interface When a given namespace's HLL is either different from the current HLL or unknown, an HLL should generally use only the language-agnostic namespace interface. This interface isolates HLLs from each others' naming quirks. It consists of add_foo(), find_foo(), and del_foo() methods, for values of foo including sub (something executable), namespace (something in which to find more names), and var (anything). NOTE: The job of the typed interface is to bridge *naming* differences, and *only* naming differences. It does not enforce, nor even notice, the interface requirements of sub or namespace. Thus, for example, successful execution of add_sub(foo, $P0) does *not* automatically guarantee that $P0 is an invokable subroutine. Caveat usor. add_sub($S0, $P0) Store $P0 as a subroutine with the name of $S0. add_namespace($S0, $P0) Store $P0 as a sub-namespace with the name of $S0. Note that to add Bar::Baz to the Foo namespace, one must add Bar to Foo and then Baz to Foo::Bar. add_var($S0, $P0) Store $P0 as a variable under the name of $S0. IMPLEMENTATION NOTE: perl6::namespace.add_var may choose to check which parts of the variable interface are implemented by $P0 so it can decide on an appropriate sigil. del_sub($S0) del_namespace($S0) del_var($S0) Delete the sub, namespace, or variable named $S0. $P0 = find_sub($S0) $P0 = find_namespace($S0) $P0 = find_var($S0) Find the sub, namespace, or variable named $S0. IMPLEMENTATION NOTE: perl6::namespace.find_var should check all variable sigils, but the order is not to be counted on by users. If you're planning to let Python code see your module, don't