Re: Do slurpy parameters auto-flatten arrays?

2005-07-27 Thread TSa (Thomas Sandlaß)

Ingo Blechschmidt wrote:

Hi,


ReHi,



are the following assumptions correct?


I don't know in general. But see my assumptions below
for comparison. They are derived from my type theoretic
approach and as such might collide with Perl6's referential
semantics. In particular with the auto-ref/deref and how
far it follows links.



  sub foo ([EMAIL PROTECTED]) { @args[0] }

  say ~foo(a, b, c); # a


foo( List of Str )


  my @array = a b c d;
  say ~foo(@array);# a b c d (or a?)


foo( Ref of Array )  # @args[0] derefs the array ref
 # I guess you need @args[0][0] to get a

But I don't like this level of reference preservation.
E.g. one then needs to know how far out the flat array
resides, to use the right number of dereferencers. Here
type theory doesn't constrain the definitional freedom
because both interpretations are compatible with [EMAIL PROTECTED]

Actually that unspecificity could be preserved, see below.



  say ~foo(@array, z);   # a b c d (or a?)


foo( Ref of Array, Str )  # @args[0] as above

Here typing constrains the interpretation to be the
one that needs @args[0][0] to get at a. This is slightly
untrue. The problem is actually shifted to the question:
How does comma handle a Ref of Array?.



  say ~foo([EMAIL PROTECTED]);   # a


foo( List of Str build from Array of Str)



  say ~foo(*(@array, z));# a
 


  sub bar ([EMAIL PROTECTED]) { [EMAIL PROTECTED] }

  say bar(1,2,3);  # 3
  say bar(@array); # 1 (or 4?)


Type theory actually should come up with any(1|4) :)
And yes, any(1|4) is a type literal and any($x,$y)
is a parametric type which is fixed whenever $x and
$y are.

Side node: A nice test for hidden assumptions in
code is to replace functions which return Any to
behave randomly.

A Vogon optimizer OTOH, might blow away a complete
planet and return 42 everywhere :)

For this very reason the default signature of the
ideal sub is of course ::Any -- ::All where All is
pure specificity. And---even thow I should start a
'type theory foundations of Perl6' thread, I mention it
here---the ideal method is

  ::All . ::Any -- ::All

A multi sub/method is in that view a *metric* dispatcher
on the middle ::Any between the selector before the dot
and the return type after the arrow.



  say bar(@array, z);# 2 (or 5?)


I opt for 2.


  say bar([EMAIL PROTECTED]);# 4


Yep.
--
TSa (Thomas Sandlaß)




block owner, topic and the referential environment

2005-07-27 Thread TSa (Thomas Sandlaß)

This is another spin-off from the 'Exposing the Garbage Collector'
thread. Here is an enhanced version.

I wonder how the generic, lexically scoped invocant/owner is called.
I propose to call it $/ (other option is to call it $)and let the
former topicalizer become block owners and $_ the block topic that flows
into blocks from further outside if not explicitly bound with - like:

   $topic := Some.new;
   $_ := $topic;
   for @objects { .action } # call on $/ from @objects with $_ := $topic
# in all loops

   @objects».action;  # same for single action syntax


   # but
   for @objects - { .action } # means $/.action($/) because
   # $_ bound to dynamic block owner;
   # but usefull for methods that don't
   # use the topic, in particular accessors
   # and mutators
   # same as sub call
   for @objects - { action }  # means action($/) because $_ := $/
   # but $/ is there if action is of
   # type Method

   # but the $. @. %. and . are bound through $?SELF
   # in particular
   for @objects - { .action } # subref curried on invocant

This implies that a .action means name lookup of 'action' while
.action is an onboard method of $?SELF. This latter case is
typically implemented with a vtbl lookup.

The only drawback I see is, that the careless method programmer could be
caugth in an endless .action loop if .action invokes .action explicitly
on $_ where $_ := $/ from the outside. The same endless loop could of
course be achieved with a free standing .action but that looks more like
intention.

With the lurking pitfalls an occasional check of $_ =:= $?SELF and
$/ =:= $_ seems advisable and indicates that the invocant wasn't
exchanged midway :)

Same with other block topicalizers/owners

  given $x{...}  # topic untouched, but $/ := $x
  given $x - {...}  # $_ := $x as well

But

  if $x{...}   # $/ and $_ untouched
  if $x - {...}   # $_ := $x (non boolean value)

One more interessting thing is that in exception handlers all three
variables $!, $/ and $_ are in scope. This might allow to resume where
the exception occurred after the cause was fixed e.g. by loading or
generating some code, some revamping or other DEEP_MAGIC. Hmm, debug
exceptions come to mind...
--
TSa (Thomas Sandlaß)




Re: Do slurpy parameters auto-flatten arrays?

2005-07-27 Thread Luke Palmer
On 7/26/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 Hi,
 
 are the following assumptions correct?
 
   sub foo ([EMAIL PROTECTED]) { @args[0] }
 
   say ~foo(a, b, c); # a

Yep.

   my @array = a b c d;
   say ~foo(@array);# a b c d (or a?)
   say ~foo(@array, z);   # a b c d (or a?)

a for both of these.  The *@ area behaves just like Perl 5's calling
conventions.  I could argue for never auto flattening arrays, but then
there'd really be no difference between @ and $.

   say ~foo([EMAIL PROTECTED]);   # a
   say ~foo(*(@array, z));# a

Hmm, *(@array, z)... what does that mean?  Whatever it means, you're
correct in both of these.  In the latter, the @array is in a
flattening context, so it gets, well, flattened.

   sub bar ([EMAIL PROTECTED]) { [EMAIL PROTECTED] }
 
   say bar(1,2,3);  # 3
   say bar(@array); # 1 (or 4?)

4

   say bar(@array, z);# 2 (or 5?)

5

   say bar([EMAIL PROTECTED]);# 4

Yep.

Luke


Re: Exposing the Garbage Collector (Iterating the live set)

2005-07-27 Thread Luke Palmer
On 7/26/05, TSa (Thomas Sandlaß) [EMAIL PROTECTED] wrote:
 Piers Cawley wrote:
  I would like to be able to iterate over all the
  objects in the live set.
 
 My Idea actually is to embedd that into the namespace syntax.
 The idea is that of looking up non-negativ integer literals
 with 0 beeing the namespace owner.
 
for ::Namespace - $instance
{
   if +$instance != 0 { reconfigure $instance }
}

Oh, so a namespace can behave as an array then.  Well, to avoid
auto-flattening problems in other, more common places, we ought to
make that:

for *::Namespace - $instance {...}

However, this is very huffmanly incorrect.  First of all, what you're
doing may take a quarter of a second or more for a large program
(which isn't a short amount of time by any means).  Second, the fact
that you're using it means you're doing something evil.  Third, only a
fraction of 1/omega perl programmers will be using this feature. 
Therefore, it should probably look like:

use introspection;
for introspection::ALL_INSTANCES(::Namespace) - $instance {...}

And it might even be platform-specific, given the constraints of some
of our targets.

Luke


Re: Exposing the Garbage Collector (Iterating the live set)

2005-07-27 Thread TSa (Thomas Sandlaß)

Luke Palmer wrote:

On 7/26/05, TSa (Thomas Sandlaß) [EMAIL PROTECTED] wrote:


Piers Cawley wrote:


I would like to be able to iterate over all the
objects in the live set.


My Idea actually is to embedd that into the namespace syntax.
The idea is that of looking up non-negativ integer literals
with 0 beeing the namespace owner.

  for ::Namespace - $instance
  {
 if +$instance != 0 { reconfigure $instance }
  }



Oh, so a namespace can behave as an array then.  Well, to avoid
auto-flattening problems in other, more common places, we ought to
make that:

for *::Namespace - $instance {...}


Well, even more huffmanized would be

  for Namespace - {...; use $_}

might be what you expect after

  my @array = (0,1,2,3);
  ::Namespace ::= @array;



However, this is very huffmanly incorrect.  First of all, what you're
doing may take a quarter of a second or more for a large program
(which isn't a short amount of time by any means).  Second, the fact
that you're using it means you're doing something evil.  Third, only a
fraction of 1/omega perl programmers will be using this feature. 
Therefore, it should probably look like:


use introspection;
for introspection::ALL_INSTANCES(::Namespace) - $instance {...}


This is why I wonder how writeable the namespace is, and when.
On some platforms it might actually not even be readable because
it was compiled away or stripped from the excecutable ;)
All that remains then is the possible behaviour as it is constrained
by the types of souls/daemons the creator happened to *choose*.
I guess you should re-read $Luke::Bible or watch the 
$*::Movies::WarnerBrothers::Matrix again :))

If both refs are undef in your namespace, go and bind them!

If the above is insulting, feel free to invoke my .apologize with
you as topic. You know, I'm the $/ of this $email.



And it might even be platform-specific, given the constraints of some
of our targets.


The platform is yet another restriction on Space::Search::Solution.
Interestingly namespace lookup is big endian...
--
$Language::Perl6::TSa.greeting
(somehow we are all part of it or was that $_?)



Messing with the type heirarchy

2005-07-27 Thread Luke Palmer
http://repetae.net/john/recent/out/supertyping.html

This was a passing proposal to allow supertype declarations in
Haskell.  I'm referencing it here because it's something that I've had
in the back of my mind for a while for Perl 6.  I'm glad somebody else
has thought of it.

Something that is worth looking into is Sather's type system.  I
haven't read anything about it yet, but worry not, I will.

Anyway, on to the proposal.

I've often thought that it would be very powerful to put types
in-between other types in the hierarchy.  This includes making
existing types do your roles (which Damian describes as spooky action
at a distance).  Allow me to provide an example.

Let's say that Perl 6 does not provide a complex number class by
default.  How would you go about writing one?  Well, let's do the
standard Perl practice of making words that your users are supposed to
say in their code roles.

role Complex { 
# implementation details are unimportant (as always :-p)
}

Now, where does it belong in the type heirarcy so it can interact well
with standard types?  It belongs *above* Num (and below whatever is
above Num).  Everything that is a Num is a Complex right?  It just has
a zero imaginary part.  But currently that is impossible.  So we have
to define conversions, which behave quite differently from simple
interface compatibilites.  For one, we have to reference a concrete
complex type.  Basically, we've made Complex feel like an outsider to
the Perl standard hierarchy.

As another example, let's say I'm implementing my own Junction class,
MyJunction.  I want it to be lower precedence than standard Junctions
(for an appropriate definition of precedence; in this case, it means
it will be threaded first).  Put aside for the moment how we define
the multimethods for all existing subs at once.

The safe way to implement a threading object is to give it its own
level in the type hierarchy.  For example, to do Junction, we
structure the type hierarchy like so:

Any
|- Junction
|- JunctionObject   # or some other appropriate name
   |- Object
  |- ...

Then we can safely define MMD variants and be sure that they won't
change their semantics when derivation levels change under manhattan
distance.  Under pure ordering, we prevent against ambiguity errors
(which is in fact how I came up with this pattern).

So, anyway, to define MyJunction, I'd like the hierarchy to look like this:

Any
|- MyJunction
|- MyJunctionObject
   |- Junction
   |- JunctionObject
  |- Object
 |- ...

This is a case where it is absolutely necessary to supertype in order
to achieve certain semantics.

Okay, now that I have the need out of the way, the syntax is obvious:

role Complex
does Object
contains Num
{...}

There is probably a better word than contains.  I was thinking set
theory when I came up with that one.

It might be wise only to allow this for roles if we go with a
derivation metric-based MMD scheme.  Allowing this for classes would
mean that you could add depth to the metric that the author of the
classes in question didn't intend, and I've already shown that you can
screw up manhattan MMD semantics at a distance, spookily, if you do
that.

Luke


Re: The Use and Abuse of Liskov

2005-07-27 Thread Luke Palmer
On 7/19/05, Damian Conway [EMAIL PROTECTED] wrote:
  And now maybe you see why I am so disgusted by this metric.  You see,
  I'm thinking of a class simply as the set of all of its possible
  instances.
 
 There's your problem. Classes are not isomorphic to sets of instances and
 derived classes are not isomorphic to subsets.

Ahh, I understand now.  If you think that way, then there is no way to
convince you, since that is the piece of mathematics that my whole
argument is based on.  Please seriously consider this world model and
its implications (especially regarding my new thread about
superclassing).  I'll give up on the theoretical side now.

~

I've just released Class::Multimethods::Pure for an account of how
pure ordering works in practice.  As the first case study, see
Class::Multimethods::Pure (it bootstraps itself :-).  The ambiguities
that it pointed to me turned out to be very important design-wise, and
I noticed that under manhattan distance it would have silently worked
and then broken (in ambiguity) later.

Readers, do your best to follow along.  This is pretty complex, but
that's exactly what I'm arguing: that a derivation metric like
Manhattan will decieve you when things get complex.

The piece was the junction factoring that I described in my other
thread (I use junctions in MMD to implement type junctions).  At first
I had this model:

Object
|- Junction
   |- Disjunction
   |- Conjunction
   |- Injunction
|- Constrained
   |- Subtype
|- PackageType
|- ...

And the multis defined as:

multi subset (Junction, Object)   {...}
multi subset (Object, Junction)   {...}
multi subset (Junction, Junciton) {...}

Which made recursive calls to subset on their constituent types.  The
various Junction subclasses have a logic method which knows how to
evaluate the junction in boolean context.  I also had:

multi subset (Subtype, Object)  {...}
multi subset (Object, Subtype)  {...}
multi subset (Subtype, Subtype) {...}

Then:

multi subset (Package, Package) {...}

Etc. for all the other non-combinatoric types, and:

multi subset (Object, Object) { 0 }

As the fallback.  Naturally, when I called:

subset(Disjunction.new(...),  Subtype.new(...))

I got an ambiguity.  Did you mean (Junction, Object) or (Object,
Subtype)?  Something was wrong with my design: I needed to structure
my types to tell the MMD system which one I wanted to thread first. 
This is an error that you'd expect, right?  I didn't tell the compiler
something it needed to know.

However, look at the applicable candidates:

subset(Junction, Object)   #  1 + 2  =  3
subset(Object, Subset) #  2 + 0  =  2
subset(Object, Object) #  2 + 2  =  4

The second variant, (Object, Subset) matches.  Oh goody, it worked! 
Now I can go on my merry way documenting and releasing my module.

Now Mr. Joe Schmoe comes along and decides that he wants to write a
new subtype type -- one that accepts his new statically-analyzable
subtyping language or something.  He decides to reuse code and derive
from the existing Subtype type.  The new type hierarchy follows:

Object
|- Junction
   |- Disjunction
   |- Conjunction
   |- Injunction
|- Constrained
   |- Subtype
  |- MagicSubtype# the new type
|- PackageType
|- ...

Now look at what happens for subtype(Disjunction.new(...),
MagicSubtype.new(...)):

subset(Junction, Object) # 1 + 2 = 3
subset(Object, Subtype)  # 2 + 1 = 3
subset(Object, Object)   # 2 + 2 = 4

Oh no!  An ambiguity!  What the hell, Joe's just trying to extend
Subtype a little, and now he has to write a specialized MMD variant
just for that, which delegates *exactly* to the (Object, Subtype)
variant.

I'll also point out that if you remove the Constrained intermediate
type, which I did (!), you also end up in ambiguity for the call
subtype(Disjunction.new(...), Subtype.new(...)).

And that's it.  Two innocent changes, and a working program breaks
into ambiguity errors.  And the person who sees the ambiguity errors
is not the person who wrote -- or even touched -- the multimethods. 
Keep in mind: these multimethods could be for internal use, so the
extender may not even know they exist.

Using pure ordering, we saw the ambiguity early and were forced to
think about the design and come up with one that passed the tests. 
When I did that, I was able to factor things to avoid duplication and
needless disambiguating variants[1].  It is impossible to break the
new factoring by simply deriving from any class.  You would have to
add a new generic, like Junction, to the top in order to break
existing code.  Manhattan distance suffers from the same problem.  See
the supertyping thread for a solution :-)

I'm seeing after this case study, and something that I suspected all
along, that Manhattan MMD is to pure ordering as mixins are to roles. 
Roles don't provide any extra semantics over 

Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote:
 I dunno.  I'm inclined to say that it should default to Item|Pair, and
 let people say Any explicitly if they really want to suppress autothreading.
 Otherwise conditionals and switches are going to behave oddly in the
 presence of accidental junctions.

Okay.  However, in that view, I suspect many builtins will be defined on
Item|Pair, for example perl, clone, id, as well as various coercion
builtins.  Considering that builtins are Code objects but not Routines,
maybe they, too, should default to Item|Pair -- except the ones that
operates on junctions, of course.

This leads me to think that maybe users don't really need to write down
the two junctive types, under the hierarchy below:

- Object
- Any
- Item
- ...pretty much everything
- Pair
- Junction
- num, int, str...

Since junctions are still boxed objects, having the Object type to
effectively mean Any|Junction seems natural (everything is an object).

Also, since Any unifies Item and Pair, the rule for implicit types of
argument becomes:

sub ($x) { }# Item $x
- $x { }   # Any $x- i.e. Item|Pair but not Junction
{ $^x } # Any $x- i.e. Item|Pair but not Junction

Does this sound sane?

Thanks,
/Autrijus/


pgpbsmHzHG4yc.pgp
Description: PGP signature


Re: The Use and Abuse of Liskov (was: Type::Class::Haskell does Role)

2005-07-27 Thread Luke Palmer
I just realized something that may be very important to my side of the
story.  It appears that I was skimming over your example when I should
have been playing closer attention:

On 7/18/05, Damian Conway [EMAIL PROTECTED] wrote:
 Consider the following classes:
 
class A   {...}   #   AB
class B   {...}   #|
class C is B  {...}   #C   D
class D   {...}   # \ /
class E is C is D {...}   #  E
 
multi sub foo(A $x, B $y) { (1) }
multi sub foo(A $x, C $y) { (2) }
 
foo(A.new, E.new);
 
 Clearly this produces (2) under either Pure Ordering or Manhattan Metric.
 
 Now we change the class hierarchy, adding *zero* extra empty classes
 (which is surely an even stricter LSP/Meyer test-case than adding one
 extra empty class!)
 
 We get this:
 
class A   {...}   #   A  B
class B   {...}   # / \
class C is B  {...}   #C   D
class D is B  {...}   # \ /
class E is C is D {...}   #  E
 
multi sub foo(A $x, B $y) { (1) }
multi sub foo(A $x, C $y) { (2) }
 
foo(A.new, E.new);
 
 Manhattan Metric dispatch continues to produce (2), but Pure Ordering
 now breaks the program.

Um... no it doesn't.  Pure ordering continues to produce (2) as
well.  Here are the precise semantics of the algorithm again:

A variant a is said to be _more specific than_ a variant b if:
* Every type in a's signature is a subset (derived from or
equal) of the corresponding type in b's signature.
* At least one of these is a proper subset (not an equality).
A variant is dispatched if there is a unique most specific method
applicable to the given arguments. That is, there exists an applicable
variant a such that for all other applicable variants x, a is more
specific than x.

A is equal to A, and C is a proper subset of B, therefore the latter
variant is more specific than the former.  Since the latter is the
unique most specific variant, and it is applicable to the argument
types, it is chosen.

How did you think pure ordering worked?  Were we arguing over
different definitions of that algorithm?

Luke


Re: Messing with the type heirarchy

2005-07-27 Thread Aankhen
[sorry Luke, I hit Send too soon]

On 7/27/05, Luke Palmer [EMAIL PROTECTED] wrote:
  There is probably a better word than contains.  I was thinking set
  theory when I came up with that one.

What about derives?

Aankhen


Re: Messing with the type heirarchy

2005-07-27 Thread Ingo Blechschmidt
Hi,

Luke Palmer wrote:
 http://repetae.net/john/recent/out/supertyping.html
 
 This was a passing proposal to allow supertype declarations in
 Haskell.  I'm referencing it here because it's something that I've had
 in the back of my mind for a while for Perl 6.  I'm glad somebody else
 has thought of it.
[...]
 role Complex
 does Object
 contains Num
 {...}

I've probably misunderstood you, but...:

role Complex does Object {...}
Num does Complex;
# That should work and DWYM, right?


--Ingo

-- 
Linux, the choice of a GNU | Wissen ist Wissen, wo man es findet.  
generation on a dual AMD   | 
Athlon!| 



execution platform object? gestalt?

2005-07-27 Thread Randal L. Schwartz

With the recent realization of the beginnings of a PIL-Javascript
emitter, it appears that my Perl6 program can run in a bizarre mix of
execution environments.

Forgive me if I missed this while trying to skim through the unearthly
number of perl6 messages so far, but...

It'd be nice if there was one central object that represented the
execution platform, with various methods based on the capabilities.

For example, this object, call it $*OS, could be queried to see
if we can get a native Javascript class (true only when running on
a JSplatform):

  if $*OS.can(get_javascript_class) { # I'm running on a js platform
my $main_window = $*OS.get_javascript_class(Window).main;
...
  }

The point would be to have one object that would understand the
platform dependent parts, and have a consistent naming for the methods
that are used by that object as the execution platform varies.

This is similar to the OS-9's gestalt tables, which got smarter as
the operating system had more features, but was a consistent way to
ask do we have a color monitor here?.

Is something like this already planned?

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


Re: Messing with the type heirarchy

2005-07-27 Thread Luke Palmer
On 7/27/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 Luke Palmer wrote:
  role Complex
  does Object
  contains Num
  {...}
 
 I've probably misunderstood you, but...:
 
 role Complex does Object {...}
 Num does Complex;
 # That should work and DWYM, right?

Supposing that you can actually do that, and that Num does Complex
gets executed at compile time.  I didn't know you could add does
declarations to classes referring to other classes (rather than making
the class object do a metaclass role... though I admit that that would
only be warranted by a pretty bizarre situation).


Re: Messing with the type heirarchy

2005-07-27 Thread TSa (Thomas Sandlaß)

HaloO,

Ingo Blechschmidt wrote:

I've probably misunderstood you, but...:

role Complex does Object {...}
Num does Complex;
# That should work and DWYM, right?


My 0.02: Complex should provide e.g. a + that, when
called with two Nums, doesn't bother the return
value to carry on a useless imaginary part. And
Complex should consistently return undef when compared
to other Nums or Complexes. And the Compare role
shouldn't treat undef == false but as any(true|false).
Otherwise funny things can happen  (as was observered
correctly in another thread about != applied to any
Juntions). In code:

   if $c  3 { die if $c.does(Complex) }

This is the Perl6 representation of the following
sentence: If Any::$c is less then Int::3 then
die if this $c does behave like a Complex. I hope
$Larry likes it. BTW, is their a plain english output
module planned, that would produce the above automatically?

Don't question (Light ::= Particle|Wave) with a double
slit! At least not if you want a deterministic answer
where it actually passed.

tie rant
Imagine a Casino that hands out ties to players
who don't have one even though the Casino is
a tied area. If a Num playing in the Casino likes
the imaginary standard tie it can keep it. But
among Nums this imaginary tie is no differentiator.
Actually other Num methods will say: A tie? I see
no tie. Must be an imaginary one. In simple
environments the tie might not even be applicable
imaginarily. Thus it's stripped off or entrance is
denied. Under all cicumstances the Num may decide
how to deal with this tieing.

fun: d(en)ie(d) == die in the end :)
/tie rant

The only question is how much effort all this is for
(1) the implementor of Complex
(2) the implementor of Num
(3) the user of either one in isolation
(4) when they come together

In particular the user in (4) should be able to
state his expectations in a form that is checkable
by the VM. Which basically means that (1) and (2)
have to state their assumptions to the VM in the
same form/syntax.
--
$TSa.greeting := HaloO; # mind the echo!


Re: execution platform object? gestalt?

2005-07-27 Thread TSa (Thomas Sandlaß)

Randal L. Schwartz wrote:

This is similar to the OS-9's gestalt tables, which got smarter as
the operating system had more features, but was a consistent way to
ask do we have a color monitor here?.

Is something like this already planned?


From my bubble in the Perl6 Universe this thing is an unbound
symbolic reference $::(to The Type System).

Welche Gestalt es bisher angenommen hat weiss ich nicht.

But it should be capable to appear in any(@form) to help
all(@us) where {any(@us) != ::United::States of America}. :)
--
$TSa.greeting := HaloO; # mind the echo!


Re: execution platform object? gestalt?

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 07:09:41AM -0700, Randal L. Schwartz wrote:
: With the recent realization of the beginnings of a PIL-Javascript
: emitter, it appears that my Perl6 program can run in a bizarre mix of
: execution environments.
: 
: Forgive me if I missed this while trying to skim through the unearthly
: number of perl6 messages so far, but...
: 
: It'd be nice if there was one central object that represented the
: execution platform, with various methods based on the capabilities.

Yes, we'll have something like that, but...

: For example, this object, call it $*OS, could be queried to see
: if we can get a native Javascript class (true only when running on
: a JSplatform):
: 
:   if $*OS.can(get_javascript_class) { # I'm running on a js platform
: my $main_window = $*OS.get_javascript_class(Window).main;
: ...
:   }
: 
: The point would be to have one object that would understand the
: platform dependent parts, and have a consistent naming for the methods
: that are used by that object as the execution platform varies.

It's not entirely clear that get_javascript_class should be considered
a method of the OS and/or platform for which .can would be appropriate.
The method might be supplied by the platform, or it might be supplied
merely because someone somewhere said use JS and imported the behavior.

So in this particular case it might be better to just say

if exists get_javascript_class {...}

or maybe (if it's actually the time to get the class) just try
calling the routine and catch the exception, unless you're trying
to second-guess ahead of time.  Or ask the language loader object
whether it has loaded JS.  I'm just saying that the language loader
doesn't necessarily have to be considered part of the OS.

But that aside, yes, we'll have visiblility into $?OS (the compile-time
OS) and $*OS (the run-time OS).  Or maybe those are just the names,
and hashes like %?OSfeature and %*OSfeature are the appropriate forms
for interrogating particular items.  But $*OS as an object can subsume
both of those behaviors and also provide methods, so that's probably
the right way to go.

On the other hand, it's also not entirely clear that all platformish
feature sets should make themselves visible through one name.  What's
an OS?  Should we distinguish VM from that?  Should we be able
to peer through VM and OS and get at MACHINE?  What if it's running on
multiple machines and they want to give conflicting advice?

Arguably, it's probably good to have a single access point for
everything outside the VM, and OS is as good a name as anything for
that, as the abstraction of the world.  (Hmm, if your program is
the flesh, that leaves the VM to be the devil, I guess.)  However,
if we do that, then it would have to be recognized that the entire
Internet is hiding inside that OS bubble.

So I guess the question is whether we need $?VM and $*VM as well?  Or
should we consider the VM to also be foreign and lump it with OS?

: This is similar to the OS-9's gestalt tables, which got smarter as
: the operating system had more features, but was a consistent way to
: ask do we have a color monitor here?.
: 
: Is something like this already planned?

Yes, but we just need to be careful not to recreate The Registry.
We're looking more for a place for everything and everything in
its place, but we're still trying to understand what that means.
As you say, whatever we end up with does have to be extensible,
since we don't know all the places we'll want ten years from now.
It seems to me that the more places we can come up with now, though,
the less likely we are to have collisions later, unless our categories
are artificial.  That tends to argue for separating out VM from OS,
and maybe COMPUTER, and NET, unless you think that NET =:= COMPUTER.

Larry


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 08:01:25PM +0800, Autrijus Tang wrote:
: On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote:
:  I dunno.  I'm inclined to say that it should default to Item|Pair, and
:  let people say Any explicitly if they really want to suppress autothreading.
:  Otherwise conditionals and switches are going to behave oddly in the
:  presence of accidental junctions.
: 
: Okay.  However, in that view, I suspect many builtins will be defined on
: Item|Pair, for example perl, clone, id, as well as various coercion
: builtins.  Considering that builtins are Code objects but not Routines,
: maybe they, too, should default to Item|Pair -- except the ones that
: operates on junctions, of course.
: 
: This leads me to think that maybe users don't really need to write down
: the two junctive types, under the hierarchy below:
: 
: - Object
:   - Any
:   - Item
:   - ...pretty much everything
:   - Pair
:   - Junction
: - num, int, str...
: 
: Since junctions are still boxed objects, having the Object type to
: effectively mean Any|Junction seems natural (everything is an object).
: 
: Also, since Any unifies Item and Pair, the rule for implicit types of
: argument becomes:
: 
: sub ($x) { }# Item $x
: - $x { } # Any $x- i.e. Item|Pair but not Junction
: { $^x }   # Any $x- i.e. Item|Pair but not Junction
: 
: Does this sound sane?

Yes.  The only thing I don't like about it is that any() isn't an Any.
Maybe we should rename Any to Atom.  Then maybe swap Item with Atom,
since in colloquial English you can say that pair of people are
an item.  That would give us:

- Object
- Item
- Atom
- ...pretty much everything
- Pair
- Junction
- num, int, str...

which nicely distinguishes Item from Junction.  On the other hand,
I actually kinda dislike the word Atom for common use (too much
exposure to Lisp, I guess), so maybe we just want

- Object
- Mumble
- Item
- ...pretty much everything
- Pair
- Junction
- num, int, str...

where Mumble is something like Atom/NonJunction/Unit/Scalar/[your ad here].

Larry


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Matt Fowles
Larry~

On 7/27/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Jul 27, 2005 at 08:01:25PM +0800, Autrijus Tang wrote:
 : On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote:
 :  I dunno.  I'm inclined to say that it should default to Item|Pair, and
 :  let people say Any explicitly if they really want to suppress 
 autothreading.
 :  Otherwise conditionals and switches are going to behave oddly in the
 :  presence of accidental junctions.
 :
 : Okay.  However, in that view, I suspect many builtins will be defined on
 : Item|Pair, for example perl, clone, id, as well as various coercion
 : builtins.  Considering that builtins are Code objects but not Routines,
 : maybe they, too, should default to Item|Pair -- except the ones that
 : operates on junctions, of course.
 :
 : This leads me to think that maybe users don't really need to write down
 : the two junctive types, under the hierarchy below:
 :
 : - Object
 :   - Any
 :   - Item
 :   - ...pretty much everything
 :   - Pair
 :   - Junction
 : - num, int, str...
 :
 : Since junctions are still boxed objects, having the Object type to
 : effectively mean Any|Junction seems natural (everything is an object).
 :
 : Also, since Any unifies Item and Pair, the rule for implicit types of
 : argument becomes:
 :
 : sub ($x) { }# Item $x
 : - $x { } # Any $x- i.e. Item|Pair but not Junction
 : { $^x }   # Any $x- i.e. Item|Pair but not Junction
 :
 : Does this sound sane?
 
 Yes.  The only thing I don't like about it is that any() isn't an Any.
 Maybe we should rename Any to Atom.  Then maybe swap Item with Atom,
 since in colloquial English you can say that pair of people are
 an item.  That would give us:
 
 - Object
 - Item
 - Atom
 - ...pretty much everything
 - Pair
 - Junction
 - num, int, str...
 
 which nicely distinguishes Item from Junction.  On the other hand,
 I actually kinda dislike the word Atom for common use (too much
 exposure to Lisp, I guess), so maybe we just want
 
 - Object
 - Mumble
 - Item
 - ...pretty much everything
 - Pair
 - Junction
 - num, int, str...
 
 where Mumble is something like Atom/NonJunction/Unit/Scalar/[your ad here].

While we are talking about words... I dislike having Object encompass
Juction.  I get the feeling that some people will write functions that
take Objects and not expect Junctions to slip in.  I suppose that
could be one of those hurdles that developers just have to jump, but
it doesn't feel like it should be.

Matt
-- 
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Wed, Jul 27, 2005 at 12:19:10PM -0400, Matt Fowles wrote:
 While we are talking about words... I dislike having Object encompass
 Juction.  I get the feeling that some people will write functions that
 take Objects and not expect Junctions to slip in.  I suppose that
 could be one of those hurdles that developers just have to jump, but
 it doesn't feel like it should be.

Er, but Junctions take methods, the same way Objects do, so if there is
an Object in the type hierarchy, Junction probably belongs to it.

However we can tone down the ordinariness of Object so people will be
less inclined to use it. Boxed?

Thanks,
/Autrijus/


pgpO521iJVLcV.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread TSa (Thomas Sandlaß)

HaloO,

Larry Wall wrote:

Yes.  The only thing I don't like about it is that any() isn't an Any.
Maybe we should rename Any to Atom.  Then maybe swap Item with Atom,
since in colloquial English you can say that pair of people are
an item.


Since we are in type hierachies these days, here's my from ::Any
towards ::All version. The bottom part where everything finds
together is missing for this installment.

 ::Any
... | ..
   ___:_|_:static type :
  |   : | :  | | = context :
   Package: | : Void  Bool :
  |   : | :.
Module: |
   ___|___: |
  |   |   : |
Class Grammar : |
  |___|   : |
  |   : |
 Role :   Object
  : |
  : | || |
  :   Code @Array   %Hash $Item
  : | // |
  with: |   TupleRecord  |
  invocant(s) : ||
  :/ \__   __|_
 |:  | |\ /  || |  |   |
  .Method : Sub  Block   |   |   Inf  Undef  Match  Junction
/|:  |\  |   |
   / |:  | \Ref[Code]|
   Rule  |:  |  Macro|
 |:_/|__/|\
 |:  |   | | | |
   Multi  :  | ~Str  +Num  \Ref  :Pair
..:  |   | | |\|
 |   |Int| \   |
 ___/|   | | |  Entry[::T where T.does(Hash)]
| |  |   |/|\|
  *List  Pipe =Iterator Enum ?Bit  Pos[::T where T.does(Str|Array)]
|\___
|  | |
 **Eager  Lazy  Ref[Array|Hash]


any() == lub( all --- any ) == glb( any -- all )   lesser -- greater
all() == glb( all --- any ) == lub( any -- all )

Some operators and prefixes are added in to show their
relation to the corresponding type. I hope it looks familiar.

Here is some pseudo code that describes a bare minimum data layout
required to support the respective types.

type Item[::T]
{
  has $.value of T;
}

type Pair[::T]
{
  has $.key;
  has $.value of T;
}

type Tuple[::T where T does lub( @.values )]  # lub = least upper bound
{
  has @.values of T;
  has $.value ::= @.values; # auto-enreference for Item subtyping
  has T $.head ::= @.values[0];
  has T $.tail ::= @.values[-1];
}

type Record[::T where T does lub( @.values )]
{
  has @.keys;
  has @.values of Pair[T];
  has @.pairs ::= { zip @.keys, @.values };
  has $.value ::= @.pairs;
}

type Code
{
  has %.MY;# lexical scratchpad
  has .block;
  has $.value ::= { use %.MY; .block() }; # coderef literal
}

type Junction[::T where enum any all one none]
{
  has @.values;
  has Junction $.value ::= { @.values as Junction[T] };
  has .evaluate ::= ::JUNCTION_MAGIC; # what's the exact type of this?
}
--
$TSa.greeting := HaloO; # mind the echo!


Re: Messing with the type heirarchy

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 11:00:20AM +, Luke Palmer wrote:
: Let's say that Perl 6 does not provide a complex number class by
: default.  How would you go about writing one?  Well, let's do the
: standard Perl practice of making words that your users are supposed to
: say in their code roles.
: 
: role Complex { 
: # implementation details are unimportant (as always :-p)
: }
: 
: Now, where does it belong in the type heirarcy so it can interact well
: with standard types?  It belongs *above* Num (and below whatever is
: above Num).  Everything that is a Num is a Complex right?

Not according to Liskov.  Num is behaving more like a constrained
subtype of Complex as soon as you admit that isa is about both
implementation and interface.  By the interface definition it's
slightly truer to say that Complex is a Num because it extends Num's
interface.  But this is one of the standard OO paradoxes, and we're
hoping roles are the way out of it.  (Or to be less precise and more
accurate, we're hoping it's the way to sweep the problem under N
carpets where N is greater than 0 most of the time.)

Larry


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 06:28:22PM +0200, TSa (Thomas Sandlaß) wrote:
: Since we are in type hierachies these days, here's my from ::Any
: towards ::All version.

That's pretty, but if you don't move Junction upward, you haven't
really addressed the question Autrijus is asking.  We're looking
for a simple type name that means none(Junction) for use as the
default type of the $x parameter to - $x {...}.  Whatever we call
it, this type/class/role/subtype has to admit Item and Pair objects
but not Junctions.  (And if that's the wrong way to think about it,
please tell us why.)

Larry


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Mark A. Biggar

Larry Wall wrote:

On Wed, Jul 27, 2005 at 06:28:22PM +0200, TSa (Thomas Sandlaß) wrote:
: Since we are in type hierachies these days, here's my from ::Any
: towards ::All version.

That's pretty, but if you don't move Junction upward, you haven't
really addressed the question Autrijus is asking.  We're looking
for a simple type name that means none(Junction) for use as the
default type of the $x parameter to - $x {...}.  Whatever we call
it, this type/class/role/subtype has to admit Item and Pair objects
but not Junctions.  (And if that's the wrong way to think about it,
please tell us why.)


Suggestions:

Definite
Singelton (but that may mean no pairs, oops)
Solid
Settled
NonJunctive (yuck)
Terminal
NonThreaded (yuck)
Simple (but that could exclude arrays and hashs)]
Basic

Interesting question: are junctions infectious, are class object that 
include a member with ajunction type also junctions?



--
[EMAIL PROTECTED]
[EMAIL PROTECTED]



Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Wed, Jul 27, 2005 at 09:12:00AM -0700, Larry Wall wrote:
 Yes.  The only thing I don't like about it is that any() isn't an Any.

snip

 - Object
   - Mumble
   - Item
   - ...pretty much everything
   - Pair
   - Junction
 - num, int, str...

Hrm.  I thought the original motivation of forcing people to write

Any|Junction

was precisely to discourage people from accidentally write

sub foo (Any $x)

and have $x accept a Junction.  In other words, any() should not be of
type Any.  Hence it still feels natural for me that Any occurs at the
position of Mumble.

Thanks,
/Autrijus/


pgplBqGItv0yM.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Darren Duncan

At 9:12 AM -0700 7/27/05, Larry Wall wrote:

Yes.  The only thing I don't like about it is that any() isn't an Any.
Maybe we should rename Any to Atom.  Then maybe swap Item with Atom,
since in colloquial English you can say that pair of people are
an item.  That would give us:

- Object
- Item
- Atom
- ...pretty much everything
- Pair
- Junction
- num, int, str...

which nicely distinguishes Item from Junction.  On the other hand,
I actually kinda dislike the word Atom for common use (too much
exposure to Lisp, I guess), so maybe we just want

- Object
- Mumble
- Item
- ...pretty much everything
- Pair
- Junction
- num, int, str...

where Mumble is something like Atom/NonJunction/Unit/Scalar/[your ad here].


At 11:35 AM -0700 7/27/05, Larry Wall wrote:

We're looking
for a simple type name that means none(Junction) for use as the
default type of the $x parameter to - $x {...}.  Whatever we call
it, this type/class/role/subtype has to admit Item and Pair objects
but not Junctions.  (And if that's the wrong way to think about it,
please tell us why.)


Between what you've said, I prefer the top diagram myself.  Where 
something and Pair are each Item.  Item seems more generic, and is 
what one often calls a constituent of a list being iterated through. 
So the $x parameter to - $x {...} should be called Item.


So then the question is what to replace Atom with:

- Object
- Item
- Mumble
- ...pretty much everything
- Pair
- Junction
- num, int, str...

In my brainstorming, I found it is a lot easier to come up with words 
that mean single than non-junction.  So working from that perspective 
...


Why don't we just call it a Single?

   - Object
- Item
- Single
- ...pretty much everything
- Pair
- Junction
- num, int, str...

The noun Single is common in speech, unambiguous in meaning, and 
looks visually distinct from all the other types.  It is often used 
side by side in speech, such as she is a single and they are a 
pair.  Also, Single doesn't suggest being indivisible like Atom does.


I also vote against the use of Scalar there, since Scalar seems too 
specific.  Likewise with NonJunction, if we can help it, because it 
looks messy.


-- Darren Duncan


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 12:19:10PM -0400, Matt Fowles wrote:
: While we are talking about words... I dislike having Object encompass
: Juction.  I get the feeling that some people will write functions that
: take Objects and not expect Junctions to slip in.  I suppose that
: could be one of those hurdles that developers just have to jump, but
: it doesn't feel like it should be.

In which case

- Any
- Object
- Item
- ...pretty much everything
- Pair
- Junction
- num, int, str...

would be a little more like Thomas's type lattice.  (Though I expect he'd
treat the value types as constrained subtypes of Num, Int, Str, etc.)

It seems stupid to split Object into just two things.  But maybe
there are other magical beasties like Pair that go alongside Pair,
such as ordinary lazily bound argument lists before they are bound
to a particular signature, or semicolons/pipes before it's determined
if the signature is semicolon-sensitive.  Basically, anything that's
magical to the binder goes on that level, and according to the above
would be an Object but not an Item.

However we do it, we can only aim for Least Surprise, since No Surprise
is not really attainable here.

Larry


Re: execution platform object? gestalt?

2005-07-27 Thread Uri Guttman
 LW == Larry Wall [EMAIL PROTECTED] writes:

  LW Yes, but we just need to be careful not to recreate The Registry.
  LW We're looking more for a place for everything and everything in
  LW its place, but we're still trying to understand what that means.
  LW As you say, whatever we end up with does have to be extensible,
  LW since we don't know all the places we'll want ten years from now.
  LW It seems to me that the more places we can come up with now, though,
  LW the less likely we are to have collisions later, unless our categories
  LW are artificial.  That tends to argue for separating out VM from OS,
  LW and maybe COMPUTER, and NET, unless you think that NET =:= COMPUTER.

then why not name it something like *?ENV (not to be confused with the
shell/exec env which is still %ENV i assume)? then under that there are
methods/hash entries like OS, VM, etc. it is the sum of all the
(reasonably) known external things about this perl. OS seems too
specific as does VM. they should just be subparts of the full env. this
is also more like an intelligent Config.pm it seems.

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


The meaning of returns

2005-07-27 Thread Autrijus Tang
Consider this:

sub id (Any $x) returns Any { return($x) }
sub length (Str $y) returns Int { ... }

length(id(abc));

Under standard static subtyping rules, this call will perform three
different typechecks:

 1) abc.does(Any) # (abc as Str)  === (Any $x) in id
 2) $x.does(Any)# ($x as Any) === (returns Any) in return
 3) Any.does(Str)   # (returns Any)   === (Str $y) in length

The final (returns Int) is unimportant here.

Obviously, typecheck #3 fails, as Any cannot do Str.  Indeed, there is
no type literal in the return position that can satisfy this static
typecheck for id, other than the bottom type which would be a subtype
for every type.  Let's call it All:

sub id (Any $x) returns All { return($x) }

However, had we used that, #2 will fail, as it would now be checking for
$x.does(All), which is guaranteed to fail regardless of whether the
check occurs at runtime (Str.does(All)) or compile time (Any.does(All)).

Hence, it seems to me that there are only four ways out:

  A) Omit the #3 check from compile time; at runtime, use the actual
 type of $x.  The returns type annotation will not propagate
 outward to the caller.
 
At compile time, check for #2: Any.does(Any)
At runtime, check for #2: abc.does(Any)
check for #3: abc.does(Str)

  B) Omit the #2 check from both compile time and runtime; this allows
 us to write the returns All version.
 
At compile time, check for #3: All.does(Str)
At runtime, check for #3: abc.does(Str)

  C) Make the return type observe both #2 and #3 at compile time,
 using junctive types to pass both checks:

sub id ( Any $x ) returns Any|All { return($x) }

  D) Make the return type observe both #2 and #3 at compile time,
 using type variables:

sub id ( (::T) $x ) returns ::T { return($x) }

At this moment, I don't have a strong preference to either; I'm more
curious on whether this topic has been covered before by p6l and @Larry.

Thanks,
/Autrijus/


pgpRRbY7g7rEe.pgp
Description: PGP signature


Re: Elimination of Item|Pair and Any|Junction

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 03:55:55AM +0800, Autrijus Tang wrote:
 Hrm.  I thought the original motivation of forcing people to write
 
 Any|Junction
 
 was precisely to discourage people from accidentally write
 
 sub foo (Any $x)
 
 and have $x accept a Junction.  In other words, any() should not be of
 type Any.  Hence it still feels natural for me that Any occurs at the
 position of Mumble.

FWIW, if Any is to be ruled to be the top type and includes Junction,
then I support Darren's proposal of Single, and maybe the Object type
can be simply eliminated to Any:

Any - Item - Single
   - Pair
- Junction
- int, num, str

This also means that int num str will fit to Any via autoboxing.

Thanks,
/Autrijus/


pgpQPssdL4iZm.pgp
Description: PGP signature


Re: The meaning of returns

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 05:03:05AM +0800, Autrijus Tang wrote:
 Hence, it seems to me that there are only four ways out:

Some annotations copied from discussion in #perl6:

   A) Omit the #3 check from compile time; at runtime, use the actual
  type of $x.  The returns type annotation will not propagate
  outward to the caller.
  
 At compile time, check for #2: Any.does(Any)
 At runtime, check for #2: abc.does(Any)
 check for #3: abc.does(Str)

This is the view that says (returns Foo) amounts to declare a:

my sub return (Foo $x) { *return($x) }

and perform no static checking for return types to match their calling
context.  It's got the dynamic language feel, which means practically
no nontrivial type errors will happen at compile time, because function
calls, regardless of its declared return type, can be used in any type
context.

   B) Omit the #2 check from both compile time and runtime; this allows
  us to write the returns All version.
  
 At compile time, check for #3: All.does(Str)
 At runtime, check for #3: abc.does(Str)

This is quite absurd, and was included only for completeness.

   C) Make the return type observe both #2 and #3 at compile time,
  using junctive types to pass both checks:
 
 sub id ( Any $x ) returns Any|All { return($x) }

This is similar to the approach taken by OO-style local type
inferencers; see the Colored local type inference paper for details.

The idea is that, if one omits the returns declaration from a function
of undecidable type, the inferencer can silently fill in (Any|All) and
make the program compile, effectively defer typechecks to runtime.

On the other hand, if the user does provide a type annotation, then both
#2 and #3 will be observed, and type errors can occur.  It's closer to
the soft typing or incremental typing idea.

   D) Make the return type observe both #2 and #3 at compile time,
  using type variables:
 
 sub id ( (::T) $x ) returns ::T { return($x) }

And this is a natural extension to guide the inferencer so it won't be
totally giving up on polymorphic functions such as id.  C) and D) can
be taken together, resulting to a powerful soft typed language.

However, if we take the view that type annotation are merely storage
allocation hints and runtime coercers, then A) is probably the way to go.

Thanks,
/Autrijus/


pgpcVsbqfgSlq.pgp
Description: PGP signature


Re: execution platform object? gestalt?

2005-07-27 Thread Larry Wall
On Wed, Jul 27, 2005 at 04:27:15PM -0400, Uri Guttman wrote:
: then why not name it something like *?ENV (not to be confused with the
: shell/exec env which is still %ENV i assume)?

Of course, the fact that you have to say not to be confused with
can be taken as indicating that people will in fact confuse them...

Larry


Re: execution platform object? gestalt?

2005-07-27 Thread Uri Guttman
 LW == Larry Wall [EMAIL PROTECTED] writes:

  LW On Wed, Jul 27, 2005 at 04:27:15PM -0400, Uri Guttman wrote:
  LW : then why not name it something like *?ENV (not to be confused with the
  LW : shell/exec env which is still %ENV i assume)?

  LW Of course, the fact that you have to say not to be confused with
  LW can be taken as indicating that people will in fact confuse them...

you could do it even worse by making the shell env be a method/entry of
the perl env (bad syntax ahead):

*?ENV.ENVPATH

but my original point stands in that all this is should be under one
builtin and it shouldn't be OS or VM. those should be parts of it and
maybe shell env should be part of it too. this thingy should encompass
all about this perl and the world it is in and the shell env is part of
that.

so other choices are the common and lame INFO and CONF. too bad ENV was
taken already. i wish we could invent new words. :)

bad idea: call it *?WALL cause everything is hanging on the wall.

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: The meaning of returns

2005-07-27 Thread Autrijus Tang
On Thu, Jul 28, 2005 at 05:57:28AM +0800, Autrijus Tang wrote:
 On Thu, Jul 28, 2005 at 05:03:05AM +0800, Autrijus Tang wrote:
  Hence, it seems to me that there are only four ways out:
 
 Some annotations copied from discussion in #perl6:

Last time I reply to myself on this thread, hopefully. :-)

B) Omit the #2 check from both compile time and runtime; this allows
   us to write the returns All version.
   
  At compile time, check for #3: All.does(Str)
  At runtime, check for #3: abc.does(Str)
 
 This is quite absurd, and was included only for completeness.

On second thought, this is not as absurd as it seems.  This view is that
sub f () returns Foo means f() can be used in any place that a Foo
literal can occur, which means that it can be used in contexts that
demands a supertype of Foo (like Any), but never a subtype of Foo.

The language defined this way would still be dynamic; disabling #2 means
that the type of $x will not be checked against Foo upon return($x), so
anything at all can be used in that position.  Meaningful type errors
can occur, for example when saying close(length(abc)), where length
would have returns Int and close have a IO parameter.

However, this does require the curious device of returns All as the
default return type, unless we eliminate that using type variables
and/or type inferencing, at which time we can get #2 back for free and
implement full static typechecking anyway.

Thanks,
/Autrius/


pgpaH5X3qHeTw.pgp
Description: PGP signature


Re: execution platform object? gestalt?

2005-07-27 Thread David Storrs


On Jul 27, 2005, at 6:18 PM, Uri Guttman wrote:


this thingy should encompass
all about this perl and the world it is in and the shell env is  
part of

that.


How about *?PERL   ?

if ( *?PERL.COMPILED_OS eq 'Unix') {...}

if ( *?PERL.CURRENT_OS eq 'Unix') {...}

*?PERL.Grammars{Regex} = $my_bizarre_new_regex_grammar;

etc.

--Dks


lazy list syntax?

2005-07-27 Thread Flavio S. Glock
How can I create a lazy list from an object?

I have an object representing the sequence 1..Inf.
I tried creating a Coroutine, and then assigning the Coroutine to an
Array, but it only yielded 1:

  my @a = $span.lazy;   # 1

The coroutine worked fine in a while loop, but it didn't work in a for loop.

This is the implementation (in ext/Span):

coro lazy ($self: ) {
my $iter = $self.iterator();
loop { 
my $n = $iter.next;
return unless defined $n;
yield $n;
}
}

I understand that this is not fully specified yet, but I'd like to
start writing some tests for it.

Thanks!
- Flavio S. Glock


An idea for doing pack.

2005-07-27 Thread David Formosa \(aka ? the Platypus\)

Last night I had an idea about a possable pack API.  Most likely when
Pugs gets signifigently powerfull I will attempt to implement it.
However I would like everyones input, below is a draft of its POD.

=head1 NAME

Pack - (un)pack structures as defined by a Template

=head1 SYNOPSIS

  my Pack $template = Pack::compile {uint8 rat32};

  my $string = pack($template, 244, 3.14);

  my @unpack = unpack($template, $string);

=head1 ABSTRACT

This perl library defines a declarative minilanuage that allows the
conversion of Perl6 variables into (and from) a string of bytes.

=head1 DESCRIPTION

=head2 MACROS and SUBS

macro Pack::compile ($template) is parsed (/\{ Pack.template \}/) {...}

This macro is used to compile a template at compile time.  This may
throw a execution at compile time if there is an error in the template.

sub Pack::eval (Str $template) returns Pack {...}

And this sub will compile a template at runtime.  This may return
undef and set $! if there is an error in the template.

sub Pack::pack (Pack $template,[EMAIL PROTECTED]) returns Str of byte {...}

This function takes a [EMAIL PROTECTED] of ordinary Perl values and converts 
them
into a string of bytes according to the $template.  If you procide
more arguments then $template requires, the extra arguments are
ignored.

sub Pack::pack (Str $template,[EMAIL PROTECTED]) returns Str of byte {...}

A convenience function, $template is compiled into a Pack object and
then run on @list;

sub Pack::unpack (Pack $template,Str of byte $expr) returns List {...}
sub Pack::unpack (Str  $template,Str of byte $expr) returns List {...}

These functions do the reverse of Pack::pack

=head2 THE PACK TEMPLATE DESCRIPTION LANGUAGE (PTDL)

=head3 SYNTAX

The template description language describes the structure of the
string as a sequence of declarations.  Each declaration consists of a
type, an optional argument and zero or more adjectives.  Also each
declaration may be bound to a variable.

grammar {

  rule template :w { [binding? declaration]* };

  rule binding :w { [Perl6.variable | Perl6.literal] :=: }

  rule declaration :w { [\: adjective]* Perl6.name [\( argument \)]? }

  rule adjective :w { Perl6.name [\( argument \)]? }

  rule argument :w { Perl6.variable | Perl6.closure | Perl6.literal }

}

For example the following are valid templates

$^0 :=: byte
@^_  :=: str(8)
@^_  :=: str($^0)
$^1 :=: rat32

=head3 SEMANTICS

When packing if a declaration is bound to a scalar variable then the
contents of that variable are packed into the return value of pack
according to the nature of that declaration.

Simmerly when unpacking each declaration will set the value of the
scalar it is bound to based on its nature and the value of $expr.

$^number has a special meaning in PTDL $^i is the ith (zero indexed)
item of @list when packing and the ith (zero indexed) item of the
return array when unpacking.

If a declaration is bound to an array, when packing items will be
shifted out of the array and then packed according to the declaration.
Simmerly when unpacking the array will have the declaration's return
values pushed into it.

@^_ has a special meaning in PTDL.  It is an alias to @list when
packing and an alias to the return array when unpacking.  By default a
declaration is bound to @^_ .

If a declaration is bound to a literal then when packing the value of
that literal is packed, when unpacking the unpacked value is
discarded.

The following declarations are built in.

 int1
 int2
 int4
 int8
 int16
 int32   (aka int on 32-bit machines)
 int64   (aka int on 64-bit machines)

 uint1   (aka bit) (like vec)
 uint2
 uint4
 uint8   (aka byte)
 uint16
 uint32
 uint64

 rat32
 rat64   (aka rat on most architectures)
 rat128

 str   A string of bytes
 utf8  A number encoded using the utf8 mapping (doesn't check for bad unicode)
 UTF-8 A codepoint endcoded using UTF-8

 noop   Does nothing (though its adjectives may have side effects)

 hex   A hexadecimal string
 uuencode A uuencoded string
 base64 A base64 encoded string
 base32 A base32 encoded string
 base16 A base16 encoded string
 berA ber compressed integer

The following adjectives are built in.

:bigend   Endcode this using bigendian order
:litend   Endcode this using littleendian order
:pad($n)  Pad to $n bytes
:padchar($char)  Pad using $char
:term($char) String is $char terminated
:mvabsMove to absolute position filling with padchar if defined.
:mvrelMove to relative position filling with padchar if defined.

For convenience the following declarations are defined.

a($n) = :pad($n) :padchar(\x00) byte
A($n) = :pad($n) :padchar( ) byte
b($n) = :bigend bit($n)
B($n) = :litend bit($n)
c = int8
C = uint8
d = rat64
f = rat32
h = :bigend hex
H = :litend hex
i = int
I = uint
l = int32
L = uint32
n = :bigend int16
N = :bigend int32
q = int64
Q = uint64
s = int16
S = uint16
u = uuencode
U = UTF-8
v = :litend int16
V = :litend int32
w = ber
x = :pad(1) :padchar(\x00) noop
X = 

Inferring (Foo of Int).does(Foo of Any)

2005-07-27 Thread Autrijus Tang
As Perl 6's aggregate types are generics (Role that takes type
parameters), the problem of type variancy naturally arises.

The basic premise is that:

1.  (Array of Item).does(Array of Int); # false
2.  (Array of Int).does(Array of Item); # also false!

Intuitively, while an (Array of Item) can store anything that an
(Array of Int) can store, it cannot promise to yield a Int as the
latter can.  Conversely, while (Array of Int) can always yield
something that does Item, it cannot promise to store any Item.
Hence neither can be the subtype of the other.

As another example, consider this:

sub f (Foo @x) { ... }
my Bar @y;

One can't expect f(@y) to work, unless both Bar.does(Foo) _and_
Foo.does(Bar).  To see the reason, consider Array's interface:

# invariant generics
role Array[of = ::t] {
method FETCH (Int $idx) returns ::t { ... }
method STORE (Int $idx, ::t $elm) { ... }
}

Note that ::t occurs at both the return position, and at the parameter
position.  This means what when we fetch elements from an array of @foo,
it needs to be used in a context that expects a supertype of Foo.
On the other hand, when we store something into @foo, the expected
context is a subtype of Foo.  For @y to work in both positions, Bar
needs to meet both side of the demands.

I think it makes sense to hold both #1 and #2, instead of favoring
one side or the other.  If so, then the default Array type needs to be
something like (Array of Any|All), and do a coerce:as whenever an
actual fetch happens.

However, this rigid invariancy does not need to apply to all generic
types.  For example, consider this:

# covariant generics
role Input[of = ::t] {
method READ () returns ::t { ... }
}

Clearly, we can have (Input of Int).does(Input of Item), since anything
that can read Int can be used in places that expects Item as inputs.

On the other hand, this:

# contravariant generics
role Output[of = ::t] {
method WRITE (::t) { ... }
}

means that (Output of Item).does(Output of Int), as a output channel for
Items can surely be used anywhere that wishes to writes out Ints.

As a final example:

# nonvariant generics
role Contrived[of = ::t] {
method NOOP () { ... }
}

Not only (Contrived of Int).does(Contrived of Item), the converse is
also true, as the type parameter is not actually used anywhere.

Hence, my proposal is that Perl 6's generics should infer its variancy,
based on the signature of its methods, and derive subtyping relationships
accordingly.

The other alternative is do as Java does, which is assume invariancy by
default, then force users to write variancy annotations, but I think
that is considerably less attractive.  There may be a case for inferring
by default, but overridable by the user; if so there needs to be a
syntax for that.

Thanks,
/Autrijus/


pgpBEYZkstO6X.pgp
Description: PGP signature