Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-23 Thread Dave Whipp

Darren Duncan wrote:

I don't quite follow you.  Are you saying your version of sqrt is an 
implicit declaration; maybe I don't understand how that differs from an 
explicit definition in this case?  In any event, right at this moment I 
can't think of an answer to your question.  Go ahead with what you think 
works and I'll just speak up later if I have something constructive to 
offer. -- Darren Duncan


I actually agree that your explicit definition (a simple/efficient 
implementation in terms of other operators) is better for prelude than 
my declarative form (which isn't really declarative, because Perl6 
isn't a declarative language). My only disagreement was with your 
earlier statement in this thread, where you said that prelude.pm should 
use a declarative style.


I think we agree that what you really meant was that it should be 
written in an explicit self-referential style; and that it should avoid 
programming implementations as much as possible (e.g. prefer hyper-ops 
over explicit loops)


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-23 Thread Darren Duncan

Dave Whipp wrote:
I actually agree that your explicit definition (a simple/efficient 
implementation in terms of other operators) is better for prelude than 
my declarative form (which isn't really declarative, because Perl6 
isn't a declarative language). My only disagreement was with your 
earlier statement in this thread, where you said that prelude.pm should 
use a declarative style.


I think we agree that what you really meant was that it should be 
written in an explicit self-referential style; and that it should avoid 
programming implementations as much as possible (e.g. prefer hyper-ops 
over explicit loops)


Yes, I agree; what you stated in the second paragraph here is what I considered 
important for a prelude.pm. -- Darren Duncan


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-22 Thread Dave Whipp

Darren Duncan wrote:

Dave Whipp wrote:



sub sqrt(Num where { 0 = $_ = Real::Max } $x) {
  (0..$x/2 :by(Real::Epsilon)).min: { abs $x - $^candidate ** 2 }
}

So do you really mean as declarative a manner as possible? Or would 
you consider this example to go beyond possible?


I would declare sqrt this way instead (the body is the important change):

  sub sqrt(Num where { 0 = $_ = Real::Max } $x) {
$x ** (1/2)
  }


In other words, you prefer explicit definition to implicit declaration 
(in this case, you're basically saying that sqrt is a curried 
exponentiation). Do you have any examples of what you'd propose as 
declarative forms for prelude.pm?


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-22 Thread Darren Duncan

Dave Whipp wrote:

Darren Duncan wrote:

Dave Whipp wrote:



sub sqrt(Num where { 0 = $_ = Real::Max } $x) {
  (0..$x/2 :by(Real::Epsilon)).min: { abs $x - $^candidate ** 2 }
}

So do you really mean as declarative a manner as possible? Or would 
you consider this example to go beyond possible?


I would declare sqrt this way instead (the body is the important change):

  sub sqrt(Num where { 0 = $_ = Real::Max } $x) {
$x ** (1/2)
  }


In other words, you prefer explicit definition to implicit declaration 
(in this case, you're basically saying that sqrt is a curried 
exponentiation). Do you have any examples of what you'd propose as 
declarative forms for prelude.pm?


I don't quite follow you.  Are you saying your version of sqrt is an implicit 
declaration; maybe I don't understand how that differs from an explicit 
definition in this case?  In any event, right at this moment I can't think of an 
answer to your question.  Go ahead with what you think works and I'll just speak 
up later if I have something constructive to offer. -- Darren Duncan


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-20 Thread Dave Whipp

Darren Duncan wrote:
1.  What we *should* be doing with the Prelude, like with STD.pm, is 
write under the assumption that the implementation is also written in 
Perl 6.


We should write the Prelude in as declarative a manner as possible, 
saying *what* we want to happen rather than how, such as you do when 
writing in a functional language.


We should make use of Perl's higher-level tools like hyper-operators and 
reduce-operators etc and write in a fashion that is developer focused, 
same as writing normal Perl 6.


I do agree that a prelude.pm should be written atas higher level as 
possible, but I would not that Perl6 is not a declarative language. 
Using the most powerful operators available (I'd like to see more of 
them) is about the best you can do: as soon at you start using 
codeblocks to define things, you get beyond the realm where compile-time 
analysis is possible in a dynamic language.


Lets imagine I want to define a sqrt($x) function in a declarative 
style in perl6 (and lets image we've defined a Real type with 
Real::Epsilon being the precision of the representation). The 
declarative version of sqrt must say to find a value within the set of 
Real numbers that, when squared, is closest to $x:


sub sqrt(Num where { 0 = $_ = Real::Max } $x) {
  (0..$x/2 :by(Real::Epsilon)).min: { abs $x - $^candidate ** 2 }
}

(This assumes that Array::min will one day accept a code-block, just 
like grep, to define the property of the input list to be minimized).


The code would give a correct answer (the positive sqrt), and is written 
as a fairly direct implementation of the declarative formulation. What 
I'm not so sure of is that it would be a good way to write prelude.pm: 
running the test suite would probably take quite a while.


So do you really mean as declarative a manner as possible? Or would 
you consider this example to go beyond possible?


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-18 Thread ajr

The Prelude could be helpful for training. I've been trying to work out a
logical path into Perl 6 for quite some time, not least because it's been
a moving target. If there's a set of definitions that a computer can
follow, humans should be able to move along that path too.


--

Email and shopping with the feelgood factor!
55% of income to good causes. http://www.ippimail.com



Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-16 Thread Jonathan Scott Duff
On Thu, Jan 15, 2009 at 8:31 PM, Jon Lang datawea...@gmail.com wrote:

 Forgive my ignorance, but what is a Prelude?

 --
 Jonathan Dataweaver Lang


The stuff you load (and execute) to bootstrap the language into utility on
each invocation.  Usually it's written in terms of the language you're
trying to bootstrap as much as possible with just a few primitives to get
things started.

-Scott
-- 
Jonathan Scott Duff
perlpi...@gmail.com


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Geoffrey Broadwell
On Thu, 2009-01-15 at 16:03 -0800, Darren Duncan wrote:
 Patrick R. Michaud wrote (on p6c):
  On Thu, Jan 15, 2009 at 08:53:33AM +0100, Moritz Lenz wrote:
  Another thing to keep in mind is that once we start to have a Perl 6
  prelude, we might decide to be nice neighbors and share it with other
  implementations, as far as that's practical. 
  
  My guess is that there will be a shared prelude that is maintained
  in a central repository like the spectests, but that individual
  implementations are likely to want or need customized versions of
  the prelude for performance or implementation reasons.  In this
  sense the shared prelude acts as a reference standard that
  implementations can use directly or optimize as appropriate.
 
 What I recommend, and forgive me if things already work this way, is to 
 expand 
 the Prelude so that it defines every Perl 6 core type and operator using pure 
 Perl 6, complete enough such that there are as few as possible actual 
 primitives 
 not defined in terms of other things.  This Prelude would then be shared 
 unchanged between all the Perl 6 implementations.
 
 Then, each implementation would also define its own PreludeOverride file 
 (name 
 can be different) in which it lists a subset of the type and operator 
 definitions in the Prelude that the particular implementation has its own 
 implementation-specific version of, and the latter then takes precedence over 
 the former in terms of being compiled and executed by the implementation.

The problem with this method is that there are usually *several* ways to
implement each feature in terms of some number of other features.  The
creators of the shared prelude are then stuck with the problem of
deciding which of these to use.  If their choices do not match the way a
particular implementation is designed, it will then be necessary for the
implementation to replace large swaths of the Prelude to get decent
performance.

For example, implementations in pure C, Common Lisp, and PIR will
probably have VASTLY different concepts of available and optimized
primitive operations.  A prelude written with any one of them in mind
may well be pessimal for one of the others.

That's not to say it's not a useful idea for helping to jumpstart new
implementations -- I just somewhat doubt that a mature implementation
will be able to use more than a fraction of a common prelude.


-'f

P.S.  I did this sort of thing once -- a Forth prelude that attempted to
minimize the primitive set, and it *was* very nice from an abstract
perspective.  Unfortunately, it also made some operations take millions
of cycles that would take no more than one assembly instruction on just
about every CPU known to man.  It's a REALLY easy trap to fall into.




Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Darren Duncan

Geoffrey Broadwell wrote:

The problem with this method is that there are usually *several* ways to
implement each feature in terms of some number of other features.  The
creators of the shared prelude are then stuck with the problem of
deciding which of these to use.  If their choices do not match the way a
particular implementation is designed, it will then be necessary for the
implementation to replace large swaths of the Prelude to get decent
performance.

For example, implementations in pure C, Common Lisp, and PIR will
probably have VASTLY different concepts of available and optimized
primitive operations.  A prelude written with any one of them in mind
may well be pessimal for one of the others.

That's not to say it's not a useful idea for helping to jumpstart new
implementations -- I just somewhat doubt that a mature implementation
will be able to use more than a fraction of a common prelude.


I have a few answers to this:

0.  I agree that, no matter what, the implementation will still want to 
substitute in its own versions.  But so what?  Having a reasonably more complete 
high-level reference implementation of the Prelude in Perl 6 won't lose us 
anything over what we have now and should on average gain something.


1.  What we *should* be doing with the Prelude, like with STD.pm, is write under 
the assumption that the implementation is also written in Perl 6.


We should write the Prelude in as declarative a manner as possible, saying 
*what* we want to happen rather than how, such as you do when writing in a 
functional language.


We should make use of Perl's higher-level tools like hyper-operators and 
reduce-operators etc and write in a fashion that is developer focused, same as 
writing normal Perl 6.


We do not, except where it makes sense, want to be defining things in terms of 
the lowest level things possible, as that would be premature optimization, which 
may help some implementations and harm others.


We should instead be defining all the low level operators in terms of the high 
level operators, where possible.  It is easier for an average implementation to 
translate a high level source operation to low level native operations on 
average, than try to amalgamate a whole bunch of low level source operations to 
fewer high level implementation operations.


(Note for example I suggested using big/unlimited-size Int as a basis of 
definition rather than a machine-int.)


Don't be afraid to be recursive, if it is even possible.  For example, one could 
define Hash in terms of Array *and* define Array in terms of Hash.  Or Int in 
terms of Rat *and* Rat in terms of Int.


2.  We should be able to live with the benefit of at least short term hindsight, 
seeing what likely implementations we will have, and aim for the middle.  For 
example, write as if high-level concepts are supported in the implementation.


3.  Perl 6 does have multi-methods.  Maybe make use of them to define 
alternative sample implementations where it makes sense, though don't go too far 
citing combinational exponents.


Or if multi-methods don't work quite that way, we could add a kind of trait to 
them or something that says use one or the other but not both, and 
implementations can mark in their override file to pick a particular version.


Even if not all implementations are the same, some are similar to each other and 
can share that work.


Call them possible representations or possible implementation versions or 
something.


To some extent I think Perl 6 does have what we need in a different fashion, 
such as where you can declare a class or attribute and indicate an 
implementation type like Opaque vs Hash or what-have-you.



P.S.  I did this sort of thing once -- a Forth prelude that attempted to
minimize the primitive set, and it *was* very nice from an abstract
perspective.  Unfortunately, it also made some operations take millions
of cycles that would take no more than one assembly instruction on just
about every CPU known to man.  It's a REALLY easy trap to fall into.


That may be because you wrote in terms of a few low level operations rather than 
a few high level ones; what if you did the reverse?


As for me, I am in the process of doing this now with my Muldis D language, 
which is fairly high level and should run on everything Perl 6 does, though with 
a stronger implied support for functional-paradigm-supporting languages, and 
also run over SQL; though at the same time each implementation can choose to 
leave out some features as it sees fit, some are more important to include than 
others.  In my implementation of Muldis D over Perl (Muldis Rosetta's default 
engine), most built-in types and operators are defined as users would, in terms 
of other ones, save for its only 4 truly-primitive types, [Int (opaque 
unlim-size scalar), String (dense-array-of-Int), QTuple (heterogenous 
collection), QRelation (homogenous collection)], but the Perl class/object 
representing a 

Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Jon Lang
Forgive my ignorance, but what is a Prelude?

-- 
Jonathan Dataweaver Lang


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Darren Duncan

Jon Lang wrote:

Forgive my ignorance, but what is a Prelude?


The Prelude is a file written in Perl 6 that defines some Perl 6 built-ins.

See http://perlcabal.org/svn/pugs/view/src/perl6/Prelude.pm for what AFAIK is 
the newest version.


-- Darren Duncan


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Jon Lang
On Thu, Jan 15, 2009 at 6:45 PM, Jonathan Scott Duff
perlpi...@gmail.com wrote:
 On Thu, Jan 15, 2009 at 8:31 PM, Jon Lang datawea...@gmail.com wrote:

 Forgive my ignorance, but what is a Prelude?

 --
 Jonathan Dataweaver Lang

 The stuff you load (and execute) to bootstrap the language into utility on
 each invocation.  Usually it's written in terms of the language you're
 trying to bootstrap as much as possible with just a few primitives to get
 things started.

OK, then.  If I'm understanding this correctly, the problem being
raised has to do with deciding which language features to treat as
primitives and which ones to bootstrap from those primitives.  The
difficulty is that different compilers provide different sets of
primitives; and you're looking for a way to avoid having to write a
whole new Prelude for each compiler.  Correct?

Note my use of the term language features in the above.  Presumably,
you're going to have to decide on some primitive functions as well as
some primitive datatypes, etc.  For instance: before you can use
meta-operators in the Prelude, you're going to have to define them in
terms of some choice of primitive functions - and that choice is
likely to be compiler-specific.  So how is that any easier to address
than the matter of defining datatypes?  Or is it?

-- 
Jonathan Dataweaver Lang


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread jason switzer
On Thu, Jan 15, 2009 at 8:59 PM, Jon Lang datawea...@gmail.com wrote:

 OK, then.  If I'm understanding this correctly, the problem being
 raised has to do with deciding which language features to treat as
 primitives and which ones to bootstrap from those primitives.  The
 difficulty is that different compilers provide different sets of
 primitives; and you're looking for a way to avoid having to write a
 whole new Prelude for each compiler.  Correct?

 Note my use of the term language features in the above.  Presumably,
 you're going to have to decide on some primitive functions as well as
 some primitive datatypes, etc.  For instance: before you can use
 meta-operators in the Prelude, you're going to have to define them in
 terms of some choice of primitive functions - and that choice is
 likely to be compiler-specific.  So how is that any easier to address
 than the matter of defining datatypes?  Or is it?


Did I miss something here? I've never heard Prelude. I'm not really
convinced that each implementation should have a large set of shared code;
that seems contrary of the idea of having independent implementations.
Having to support a common set of implemented classes like this may end up
being more of a burden than a benefit. You may find each implementation
replacing parts of the Prelude to serve their needs.

It also seems like that Prelude.pm is dated and also very pugs specific,
which is ironic. What are all the references to Pugs::Internals and
pugs_internals_m:perl5? Is rx:Perl5 and rd:P5 valid perl6?

I'm skeptical of the this idea unless someone can convince me otherwise.

-Jason s1n Switzer


Re: design of the Prelude (was Re: Rakudo leaving the Parrot nest)

2009-01-15 Thread Darren Duncan
Following some responses I've seen, I'll try to clarify my proposal.  Basically 
its like this.


A significant subset of Perl 6 native features, eg types and operators, native 
meaning they are declared and described in the Perl 6 Synopsis documents, have 
been implemented under Pugs by being written in plain Perl 6 in terms of other 
Perl 6 features, rather than being written in Haskell or C or Perl 5.


See for example the modules Math::Basic and Set, which live in the ext/ 
directory of Pugs and are defined like any user-defined module.


Then recall that different languages have varying concepts of what constitutes a 
core language feature and what is an optional or third-party extension feature. 
 For example, some languages have native types and operators for temporal 
artifacts like dates and times and durations, and others don't.  Some languages 
have big numbers as a fundamental and others only have machine-size numbers.


Now I anticipate that for any given native / Synopsis-described types and 
operators of Perl 6, some Perl 6 implementations will define those as plain Perl 
6 code in terms of other Perl 6 features, and other implementations will instead 
have them directly wrap features of the host language.


My main point here is that the demarcation line between what is written in Perl 
6 and what is written in the host language can vary wildly and can pay little to 
no attention to the conceptual boundaries in the Perl 6 Synopsis between what is 
more fundamental and what is more of an extension.


Therefore, it does not hurt to increase as much as possible the fraction of the 
Perl 6 language that has a reference implementation defined just in terms of Perl 6.


Especially if this reference Perl 6 code is written in a more declarative 
fashion, it increases the likelihood that more starter code is available to help 
bootstrap any given Perl 6 implementation, where writing some parts of the 
language are more optional for them to do themselves than otherwise.


Note that I just referred to this body as the Prelude because I was replying to 
a particular p6c comment naming that, and also Pugs had something by that name 
with a similar purpose which is what was referred to in the original post.


So I'm not so much talking about the existing Prelude file as the concept it 
represents, which is making it easier to share code between Perl 6 
implementations, where each implementation wants to use it.  Or just to take 
advantage of the fact that Perl 6 itself should be easier to write some kinds of 
code in than other languages, including itself.  We can go further than the 
minimal bit we have now.


-- Darren Duncan