Re: Time::Local

2005-07-05 Thread Craig DeForest

Quoth Darren Duncan on Tuesday 05 July 2005 04:20 pm,
> I believe that at its core [the time/date] object should simply store a 
count of
> rigorously defined time units relative to a rigorously defined epoch.
> What the epoch is and what the time unit is will need to be
> officially defined (eg, Jan 1, 2000; counting in fractions of
> seconds).  The object should not store anything other than this
> single numerical value internally (smart caching of conversions
> aside).


Agree agree...

Hmmm  Straight seconds-counting has the flavor of international atomic 
time (TAI) to it, which suggests using the TAI (rather than UNIX) epoch.

Using the TAI epoch of 1958-01-01 00:00:00 has several advantages:
- TAI is recognized by international standards-setting bodies (BIPM).
- Perl6 will then shake out the 31-bit time rollover a full 12 years 
before 
the rest of the UNIX-speaking world. :-)
- TAI is sufficiently different from UNIX time to make implementors 
think 
carefully about their time conversion software.  This is important because 
some UNIX implementations handle leap-seconds and others don't, and this is a 
nice chance to get everything Right the first time.
- TAI-to-UT conversion modules can easily ingest leap-second 
announcements 
without further conversion to a different time base (see, e.g., 
ftp://62.161.69.5/pub/tai/publication/leaptab.txt).  This is important 
because, without proper maintenance of the leap-second table, all of our 
perl6 calendar programs will run an hour late a mere 500 years from now.



Re: Time::Local

2005-07-05 Thread Craig DeForest
Quoth Craig DeForest on Tuesday 05 July 2005 04:59 pm,
> ...This is important
> because, without proper maintenance of the leap-second table, all of our
> perl6 calendar programs will run an hour late a mere 500 years from now.
Uh, sorry -- "...an hour fast a mere 500 years from now."


Re: Time::Local

2005-08-16 Thread Craig DeForest
I vote for double-precision floating-point.  Since double precision  
is good to 10^-15, that allows times to be specified to a precision  
of about 3 microseconds for the next century, and to a precision of  
30 microseconds for the next millennium. Anyone who wants more  
precision than that is likely to have implemented his/her own  
library.  Further, the trade between distance from the epoch and time  
resolution goes in the correct direction -- e.g. nobody wants  
microsecond precision when considering times 1,000,000 years in the  
past.  Finally, floating point encapsulates nicely the practical  
nonexistence of simultaneity ( "$t1 == $t2" makes no sense without a  
measure of the allowed slop; integer times force an implied slop  
scale. )



On Aug 16, 2005, at 10:39 AM, Brano Tichý wrote:




A related question:
I think it was stated, that the time will be some floating-point  
number.

Will its precision be predetermined or will it be system-dependent?
(Or maybe the precision is no-issue -- it could be important in  
comparisons, but one can argue one should always specify the  
smallest unit when comparing times. Only issues left are intervals;  
I vaguely remember something about losing precision when  
subtracting two close floating-point numbers.)


I ask because I stumbled across uuu time (http://www.unununium.org/ 
articles/uuutime) when I was looking for explanation of UTC/TAI/ 
*J*D et al. It is counted from 2000-01-01 TAI in microseconds and  
stored in signed 64 bit integer.



brano








Re: crossing lists

2005-10-27 Thread Craig DeForest

If PDL-like threading syntax is adopted, this is trivial.  In PDL:
$a = pdl(1,2);
$b = pdl(3,4);
$c = $a->(*1) * $b;
print $c;
yields the output:
[
 [3 4]
 [6 8]
]
The '(*1)' inserts a dummy dimension into $a, making it a 1x2-array  
rather than a 2-array.  Then

the threading engine makes the appropriate outer product.

I strongly encourage the use of threading syntax (see the very nice  
PDL::NiceSlice module) rather than a specific outer-product operator:  
threading syntax turns out to be the answer to a rather large  
collection of problems.



On Oct 28, 2005, at 12:21 AM, Darren Duncan wrote:

Not sure if this matter was resolved on a previous discussion, but  
here goes ...


I would like to have a simple way to combine 2 array where every  
element of each array is combined with every element of the other  
array; this can also chain or scale to handle any number of arrays.  
For now lets name it 'cross', since it behaves similarly to the set  
operation that SQL calls a cross-join.


What I'm not yet sure about is whether this would be better as  
something resembling the zip() operator or a hyper-operator.


One thing I would like to be able to do is this:

  @baz = cross([1,2],[3,4]); # yields ([1,3],[1,4],[2,3],[2,4])

And alternately, this:

  for cross([1,2],[3,4]) -> $foo,$bar { ... } # loop has 4 iterations

More examples:

  cross() # yields ()
  cross([],[1]) # yields ()
  cross([1,2]) # yields ([1],[2])
  cross([1,2],[3]); # yields ([1,3],[2,3])
  cross([1],[2],[3]) # yields ([1,2,3])
  cross([1],[2],[3,4]) # yields ([1,2,3],[1,2,4])

The order of the output elements is determined by the order of the  
input elements.


If one were to be able to use this as a simple joining mechanism,  
then each combination would have to be returned as an array, so  
that 'map' or 'grep' etc would work properly.  For example:


  @A = ('red shirt', 'white shirt');
  @B = ('blue pants', 'black pants');

  @C = map { "going with $_[0] and $_[1] today" } cross(@A,@B);

On the other hand, perhaps something I actually want is something  
like the hyper-operation but with appropriately different syntax:


  ['a','b'] >>~<< ['c','d']

But that it returns ['ac','ad','bc','bd'] rather than ['ac','bd'].

So is there a similarly terse way to do combinations already, and  
if not then would you consider it commonly used enough to add?


-- Darren Duncan






Re: "Don't tell me what I can't do!"

2006-10-02 Thread Craig DeForest


On Oct 2, 2006, at 10:26 AM, jerry gay wrote:

On 10/2/06, Jonathan Lang <[EMAIL PROTECTED]> wrote:

I'm not used to programming styles where a programmer intentionally
and explicitly forbids the use of otherwise perfectly legal code.  Is
there really a market for this sort of thing?


use strict;




The advantage of "use strict" is that it is purely advisory.  If  
you're about to do something
sleazy and you know it, you can always use the escape hatch of "{no  
strict; ... }".


Any such restrictions that a coder places on future users of his code  
or template should also be
advisory.  One big advantage of Perl 5 is that there is an advisory  
class structure that can
be overridden in cases of extreme need, even when the original coder  
clearly intended that you
never override the interface. (an example is DBI, which wraps its  
objects up inside tied hashes simply to prevent access to the inside  
by less-than-determined coders)


Restrictions are useful for code style control, but mainly as  
markers: "Here be dragons", or whatever.  For the case of someone who  
wants that (Jonathan's words) "any declaration of method 'm' that  
doesn't conform to this signature should be illegal", it should be  
possible for the method coder to override that restriction by taking  
some explicit action in the source.  Otherwise we'll have the  
programming equivalent of evil no-fast-forward previews on DVDs.


Dimension of slices; scalars versus 1-element arrays?

2005-01-08 Thread Craig DeForest
I just re-read Synopsis 9, which covers PDL-related actions and array slicing, 
and came to the conclusion that either (A) there's a hole in the syntax as it 
is lain out,  (B) I lack sufficient understanding of what has been thought 
out so far, or (C) that part of the language definition isn't finished yet.

Is the perl6 expression
@a[4; 0..5];
a 1x6 array (probably correct)?  Or a 6 array (probably not correct)? If the
former, how do you specify that you want the latter?  There's a significant 
difference between the two -- for example, if '4' is some list expression 
that happens to have just one element, you don't want the whole shape of the 
output array to change.

The problem is the near-universal wart that scalars are not merely lists with 
but a single element, so you need to be able to tell the difference between a 
dimension that exists but has size 1, and a dimension that doesn't exist.
(In perl5, all arrays are one-dimensional, so the issue is sidestepped by the 
presence of scalar/list context.)

Perl5/PDL solves the problem with 'extra-parenthesis' syntax in slicing, and 
with zero-size dimensions in operators like range() [no relation to perl6 
range operators] that take a dimension size list.  Examples:
$a(  4,  0:5 );  # This perl5/PDL slice is a 1x6-array
$a( (4), 0:5 );  # This perl5/PDL slice is a 6-array
$a->range($xy,[1,3]);# This perl5/PDL range is a 1x3-array
$a->range($xy,[0,3]);# This perl5/PDL range is a 3-array
The extra parens only remove the dimension if they would otherwise be no-ops.

It is not (yet) clear to me whether the extra parens syntax is a good solution 
for perl 6 slices.



Re: Dimension of slices; scalars versus 1-element arrays?

2005-01-10 Thread Craig DeForest
Sorry, too terse :-)

I meant "...a two dimensional array with 1x6 elements (probably correct)?  Or 
a one dimensional array with 6 elements (probably not correct)?"

Cheers,
Craig


Quoth David Storrs on Monday 10 January 2005 08:33 am,
> On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote:
> > @a[4; 0..5];
> > a 1x6 array (probably correct)?  Or a 6 array (probably not
> > correct)?
>
> For the ignorant among us (such as myself), what is a 6 array?  Google
> and pdl.perl.org did not yield any immediate answers.
>
> --Dks


Re: Dimension of slices; scalars versus 1-element arrays?

2005-01-10 Thread Craig DeForest
H... It would be easy to distinguish the slicing cases if it were easier
to distinguish between a number and a list containing just  [In fact, that is 
more or less how perl5/PDL's arg-list-based slicer ('mslice') does things.]

At the top of Synopsis 9, there's a discussion about exactly that:

>   @array[0..10; 42; @x]
>is really short for
>   @array.postcircumfix:<[ ]>( <== [0..10], [42], [EMAIL PROTECTED] );
>though in the list of lists form, a bare number is interpreted as if it were
>a list of one element, so you can also say:
>   @array.postcircumfix:<[ ]>( <== [0..10], 42, [EMAIL PROTECTED] );

I believe that this is Wrong, because the distinction that is being blurred 
turns out to be important.  Ideally, those two postcircumfix cases should do 
different things (slice versus index).

But you can have your cake and eat it too.  If those postcircumfix cases were
really different, one could take advantage of the still-unused postfix unary 
'!' (for example) to distinguish:
@array[0..10; 42!; @x]   [[ maps to ]]   (<== [0..10],  42 , [EMAIL 
PROTECTED] );
@array[0..10; 42;  @x]   [[ maps to ]]   (<== [0..10], [42], [EMAIL 
PROTECTED] );

Then the default behavior is consistent (semicolons denote lists of lists)
but there is an "escape hatch" that lets you make a list of scalars-and-lists.




Quoth Larry Wall on Monday 10 January 2005 11:04 am,
> On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote:
> : I just re-read Synopsis 9, which covers PDL-related actions and array
> : slicing, and came to the conclusion that either (A) there's a hole in the
> : syntax as it is lain out,  (B) I lack sufficient understanding of what
> : has been thought out so far, or (C) that part of the language definition
> : isn't finished yet.
>
> I expect C is closest to the mark.  :-)
>
> : Is the perl6 expression
> : @a[4; 0..5];
> : a 1x6 array (probably correct)?  Or a 6 array (probably not correct)?
>
> Certainly the former.  I don't think dimensions should ever disappear
> accidentally.
>
> : If the former, how do you specify that you want the latter?
>
> I don't know offhand.  I see both the lure and the danger of the
> extra parens, so we'll probably not go that route.  We could find
> some keyword that destroys the current dimension while supplying a
> scalar argument:
>
> @a[gone(4); 0..5];
>
> Or maybe we want some notation that is explicitly a null slice with
> a scalar value, maybe something like:
>
> @a[() but 4; 0..5];
>
> or
>
> @a[():pick(4); 0..5];
>
> or
>
> @a[4 but dim(); 0..5];
>
> or maybe even something strange like:
>
> @a[()=4; 0..5];
>
> But I'm certainly open to other suggestions.
>
> Larry


Re: Dimension of slices; scalars versus 1-element arrays?

2005-01-10 Thread Craig DeForest
Double hmmm  That would also supplant the lone '*'  wart in indexing 
syntax:  instead of saying
@array[0..10;*;@x]
you could say
@array[0..10; !; @x]

Presumably, the '!;' would expand to the scalar undef value, which could be 
interpreted as "do nothing on this axis", while in the related construct
@a=();
@array[0..10; @a; @x]
the '@a;' would instead expand to a list ref pointing to the empty list, which 
could be interpreted instead as "return the null set" -- minimizing surprise 
if @a is only occasionally empty.

(Of course, substitute your favorite postfix unary character instead of '!';
'*' would work just as well...)


Quoth Craig DeForest on Monday 10 January 2005 03:56 pm,
> H... It would be easy to distinguish the slicing cases if it were
> easier to distinguish between a number and a list containing just  [In
> fact, that is more or less how perl5/PDL's arg-list-based slicer ('mslice')
> does things.]
>
> At the top of Synopsis 9, there's a discussion about exactly that:
> >   @array[0..10; 42; @x]
> >is really short for
> >   @array.postcircumfix:<[ ]>( <== [0..10], [42], [EMAIL PROTECTED] );
> >though in the list of lists form, a bare number is interpreted as if it
> > were a list of one element, so you can also say:
> >   @array.postcircumfix:<[ ]>( <== [0..10], 42, [EMAIL PROTECTED] );
>
> I believe that this is Wrong, because the distinction that is being blurred
> turns out to be important.  Ideally, those two postcircumfix cases should
> do different things (slice versus index).
>
> But you can have your cake and eat it too.  If those postcircumfix cases
> were really different, one could take advantage of the still-unused postfix
> unary '!' (for example) to distinguish:
>   @array[0..10; 42!; @x]   [[ maps to ]]   (<== [0..10],  42 , [EMAIL 
> PROTECTED] );
>   @array[0..10; 42;  @x]   [[ maps to ]]   (<== [0..10], [42], [EMAIL 
> PROTECTED] );
>
> Then the default behavior is consistent (semicolons denote lists of lists)
> but there is an "escape hatch" that lets you make a list of
> scalars-and-lists.
>
>
>
>
> Quoth Larry Wall on Monday 10 January 2005 11:04 am,
>
> > On Sat, Jan 08, 2005 at 11:37:06AM -0700, Craig DeForest wrote:
> > : I just re-read Synopsis 9, which covers PDL-related actions and array
> > : slicing, and came to the conclusion that either (A) there's a hole in
> > : the syntax as it is lain out,  (B) I lack sufficient understanding of
> > : what has been thought out so far, or (C) that part of the language
> > : definition isn't finished yet.
> >
> > I expect C is closest to the mark.  :-)
> >
> > : Is the perl6 expression
> > :   @a[4; 0..5];
> > : a 1x6 array (probably correct)?  Or a 6 array (probably not correct)?
> >
> > Certainly the former.  I don't think dimensions should ever disappear
> > accidentally.
> >
> > : If the former, how do you specify that you want the latter?
> >
> > I don't know offhand.  I see both the lure and the danger of the
> > extra parens, so we'll probably not go that route.  We could find
> > some keyword that destroys the current dimension while supplying a
> > scalar argument:
> >
> > @a[gone(4); 0..5];
> >
> > Or maybe we want some notation that is explicitly a null slice with
> > a scalar value, maybe something like:
> >
> > @a[() but 4; 0..5];
> >
> > or
> >
> > @a[():pick(4); 0..5];
> >
> > or
> >
> > @a[4 but dim(); 0..5];
> >
> > or maybe even something strange like:
> >
> > @a[()=4; 0..5];
> >
> > But I'm certainly open to other suggestions.
> >
> > Larry


Re: Dimension of slices; scalars versus 1-element arrays?

2005-01-11 Thread Craig DeForest
On Tuesday 11 January 2005 10:06 pm, Dave Whipp wrote:
> We know that
>
> @a = (1, 2, 3);
> $b = @a[1];
>
> Loses the dimension as a DWIM.
>
> So perhaps we could say that assigning to a lower dimension always gets
> rid of a dimension of size 1 -- or error if it can't:
>
> @c = ( 1,2,3 ; 4,5,6 );
> @d[*;*] = @c[ 1 ; * ]; # @d is 2d
> @e[*] = @c[ 1 ; * ];  # @e is 1d
> @f = @c[1;1];  # @f is 2d: no dimensions lost

Hmmm   I'm sorry, but I'm not quite following what you mean by 
the '=' in this case.  I've been thinking of '=' as a full-on, 
dimensional-context-free assignment, and of ':=' as a shaped, elementwise 
assignment, by analogy to the current perl5/PDL setup.  In that paradigm, 
"@e[*] = @c[1;*]" doesn't mean anything, since the LHS isn't really a
full-on lvalue -- it's an array slice with (already) a definite shape (an 
"l2value"?).

But I could just be confused about intent here. I'm used to thinking of 
piddles, which are pretty regimented -- they have a definite size along each 
axis.  Do perl6 multi-dimensional arrays have definite sizes, or are they 
"just" lists of lists of whatevers, under the hood?  Each of those structures 
would be very useful for an almost completely different set of things.

I guess Larry was right when he hinted that there're still dragons here... so,
er, sorry to have opened a can of wyrms...


Re: Dimension of slices; scalars versus 1-element arrays?

2005-01-13 Thread Craig DeForest
Hmmm...  David,  you seem to have covered all the issues with that rather 
lucid screed [attached at bottom].  I have a couple of dragon-nits to pick, 
one involving infrastructure and one involving syntax.  

First: it seems strange to me to add yet another property ("but 
used_to_be_scalar") to the output of the LoL semicolon, when there's a 
perfectly good distinction still floating around (the one that is 
deliberately blurred between [1] and 1).  Using the scalarness of a LoL 
element has the potential to make some really esoteric but useful things very 
easy to do, since it's a general syntax that could be used for any LoL, not 
just for slicing.  

But then, there may be good reasons (not obvious to me) to use a property.

Second: Regardless of the LoL infrastructure, we seem to be adopting opposing 
viewpoints on whether scalar-ish element in the LoL should be a scalar by 
default, with a syntactic hook to denote it as a list-of-1; or whether it 
should be a list-of-1 by default, with a syntactic hook to denote it as a 
scalar.  There are good reasons why either case will surprise a nontrivial 
subset of people.  Maybe we can sidestep the issue by making use of list 
context as you pointed out. 

Hmmm... What about replacing '*' entirely, with the yadda-yadda-yadda?
Certainly '0...' ought to enumerate (lazily) everything from 0 to infinity,
so it ought to return everything.  But then why not make term-'...' into 
an abbreviation for '0...'?  That sort of keeps the conceptual crud down
while letting everything get written straightforwardly:

How about this scenario?:

Ground rules: list expressions slice; scalar expressions index; 

Basic cases:
  [5;  0..6]# scalar exps are scalar by default (index)
  [(5)  ;  0..6]# 5 is now in list context (slice)
  [1..1 ;  0..6]# '..' returns a list of 1 element (slice)
  [0... ;  0..6]# '0...' is a valid lazy list, if ugly (whole axis)
  [...  ;  0..6]# '...' acts like '0...' (whole axis)
  [*;  0..6]# OK, have it your way - '*' is a synonym for '0...'.

Cases that return nothing: (either an empty list or undef...)
  [ ; 0..6] # An empty list yields nothing 
  [undef; 0..6] # undefined value yields nothing 
  [1..0;  0..6] # '..' gives list of no elements; you get nothing
 
Forcing syntax:
  [+(5) ; 0..6] # unary '+' forces scalar context (index always)
  [(5)  ; 0..6] # List-context parens force list context (slice always)
  [5*   ; 0..6] # postfix-* forces a slice? (no conflicts?)

Not accepted syntax:
  [*5   ; 0..6] # does something strange -- tries to index with a glob.
 
The only reason to gripe about that (for me) is that surrounding parens change
sense compared to perl5/PDL slicing -- but that seems trivial compared to 
hammering out something that's convenient for everyone and still makes some 
sort of coherent sense.

 
Quoth David Green on Wednesday 12 January 2005 05:40 am,
> OK, so at issue is the difference between an element of an array ($p5[1])
> and a slice (that might contain only one element, @p5[1]), only
> generalised to n dimensions.  (A problem which didn't exist in P5 because
> there were no higher dimensions!)
>
> And we don't want @B[4; 0..6] to reduce to a 1-D 6-array because then
> dimensions would just be disappearing into some other...dimension.
> (To lose one dimension is a misfortune, to lose two is plane careless)
> On the other hand, nobody wants to have to write @B[gone(4)] every time
> you need an array element.
>
> Given $a=42 and @a=(42), what if @X[$a] returned a scalar and @[EMAIL 
> PROTECTED]
> returned a slice?  Similarly, @X[$a; 0..6] would return a 6-array, and
> @[EMAIL PROTECTED]; 0..6] a 1x6-array -- scalar subscripts drop a given 
> dimension and
> array subscripts keep it.  (I think this is almost what Craig was
> suggesting, only without giving up ! for factorial. =))
>
> The list-of-lists semicolon can still turn the 42 into [42], so that if
> you have a list-of-listy function that doesn't care whether you started
> with scalars or not, it doesn't have to know.  But really the LoL
> semicolon would turn 42 into C<[42] but used_to_be_scalar>, so that
> something that *does* care (e.g. subscripting an array) can simply check
> for that property.
>
> Using a scalar to get a scalar feels rather appropriate, and not too
> surprising, I think.  Most people would probably expect @X[$a] to return
> a scalar, and use @[EMAIL PROTECTED] to mean a slice (if @a happened to have 
> only a
> single element, you're still probably using an array subscript to get
> possibly many elements -- otherwise why would you be using an array @a
> instead of just a plain scalar in the first place?)
>
> Plus if you do want to force an array subscript instead of a scalar, or
> vice versa, you don't need any new keywords to do it: @[EMAIL PROTECTED]; 
> 0..6] or
> @X[[42]; 0..6] (which is the same as @X[list 42; 0..6], right?  Which
> could also be written @X[*42; 0..6], w

Re: Autothreading generalization

2005-01-31 Thread Craig DeForest
Quoth Luke Palmer on Monday 31 January 2005 03:46 pm,
> C_{ijkl} = A_{ij} * B_{kl}
>
> You write either of:
>
> Â @C[$^i; $^j; $^k; $^l] = @A[$^i; $^j] * @B[$^k; $^l] Â
> @C = Â @A[$^i; $^j] * @B[$^k; $^l] Â

Hmm... This is both insanely great and also greatly insane.  

The issue is that, although the tensor notation is powerful, the readability 
is becoming lost in all the sigils/funny_characters on the thread variables.

Most of the non-perl-geek scientific-computing people I know already balk at 
the '$' and '@' characters because they increase the amount of black noise in 
scientific code too much; constructions like that just might send them all 
screaming back to FORTRAN.  Is there a way to generalize that reduces the 
amount of black noise so that the expression shines through?

   << @C[ ^i; ^j; ^k; ^l ] = @A[ ^i; ^j ] * @B[ ^k; ^l ] >>

is much better from a readability standpoint since the j's and k's are 
actually visible, but may be horrific from a parsing perspective.



Re: Autothreading generalization

2005-02-01 Thread Craig DeForest
On Tuesday 01 February 2005 01:18 am, Markus Laire wrote:
> Luke Palmer writes:
> > Yeah, the sigils do get in the way for small placeholder variables like
> > these:
> > Â @C[ $i; $j; $k; $l ] = @A[ $i; $j ] * @B[ $k; $l ] Â
>...
> Would placeholder variables be used often enough to varrant their own
> sigil?

Can't say for sure.  This style of explicit threading was tried in PDL but 
turned out to not be as important as robust implicit threading, and the 
explicit threading (handled by block-scoped "thread variables" that you would 
declare before using them) never got robust enough to be considered a 
production feature.

The current threading engine in PDL uses positional dimension slots to work 
out what is what:  active dimensions have to be at the start of the dimension 
list, and thread dimensions have to be at the end.   In principle, this is a 
Bad Thing since you sometimes have to transpose arrays just to get the dims 
in the right slots; but it turns out to be a Good Thing: it is  the right 
optimization for nearly all of the expressions that ever get written.

For example, with PDL-style threading, Luke's expression (written by someone 
paranoid) would be:
$c = $a(:,:,*1,*1) * $b(*1,*1,:,:);  # perl5/PDL 4-D outer product
where the names have been replaced by dimensional positions.
That still turns out to be more concise than the named version.

Most of the threading ops I do in PDL turn out to have zero active dimensions 
(scalar op, being looped over).  A few of them are vector ops (e.g. lookup 
into a table), and a lot are just matrix multiplication.  I have only had a 
few opportunities to use 5-D constructs (e.g. a collection of i x j image 
tiles that are themselves arrayed in an n x m matrix, with 3 colors).  I 
suspect that these sorts of higher dimensional operations will turn out to be 
ignored by virtually everyone -- but that they will turn out to be devilishly 
useful for a handful of brilliant people.





Re: Junction Values

2005-02-18 Thread Craig DeForest
Hmmm... It seems that this way does lie madness -- there's a fundamental 
ambiguity between autothreading happening inside or outside the declared 
loop, and there's no "least surprising" way to implement it.  Certainly 
inside the loop is the easiest and most natural to implement, but that acts 
strange from an API standpoint.  Outside the loop works well from an API 
standpoint but introduces all sorts of weird cases that the implementation 
has to consider.  

P5/PDL has some junction-like aspects, in that it does autothreading. 
We sidestep the issue by not allowing multiple-element PDLs in boolean 
comparisons, but treating single-element PDLs as scalars whenever possible.
This flows down to '..',  so (1..pdl(3)) returns (1,2,3) or does the Right 
Thing in scalar context --  but (1..pdl(3,4)) probably ought to throw an 
exception (it actually returns the empty set or always-false, depending on 
context).

I'm no language designer, but it seems to me that certain operators simply 
won't generalize well to the autothreaded case, and those operators should 
simply try to pick up the pieces -- ie treat single-element junctions like 
ordinary scalars, and treat empty junctions like undef values, but otherwise 
do something exceptional  (whether or not that involves throwing an actual 
exception).  My personal preference is that constructs like 1..($a|$b) should 
be disallowed.  It's certainly easy enough to expand the junction manually 
into a list and loop over that.

Note that other weird constructs in perl5, such as (1..[2,3]), do very 
surprising, architecture-dependent things.


Quoth Ashley Winters on Friday 18 February 2005 04:09 pm,
> On Fri, 18 Feb 2005 14:35:53 -0800, Ashley Winters
>
> <[EMAIL PROTECTED]> wrote:
> > 1 .. sqrt(10) -> LazyList of (1..3)
> > 1 .. sqrt(10|20) -> Junction of any(1,2,3, 1,2,3,4)
> >
> > LazyList does Iterator, but Junction does not. You'd have to use (1 ..
> > sqrt(3|6)).values to iterate through the possible values
> > semi-randomly.
>
> Okay, changed my mind again.
>
> 1 .. sqrt(10|20) -> Junction of any(1,2,3, 1,2,3,4)
>
> therefore, for(1 .. sqrt(10|20)) iterates ONCE, but $_ is a junction.
> Anything inside the loop which uses $_ would autothread. Anything
> which doesn't use $_ would only get called once. That's insane, right?
>
> for(1 .. sqrt(10|20) {
> if($_ > 2) {}# uses junctive value
> say "Here";  # called once
> bar($_);   # calls bar() lots of times
> }
>
> > More likely, I'm nuts.
>
> I'm definitely crazy. I give up! I'll stop now, since I clearly don't get
> it. :)
>
> Ashley Winters


Re: Units on numbers [was Re: S28ish]

2005-03-28 Thread Craig DeForest
Yow -- units would be extra cool for perl6: I know of no other language that 
has units support built in.  It would go a long way toward making perl6 the 
language of choice for students in the physical sciences...

The perl5 CPAN modules already have a pretty good unit system that could be 
ported to the junctive strategy.  The problem of resolving ambiguous units is 
subject to DWIMming based on context; my own units engines always include a 
context field that lets you choose what context should be used for further 
unit string parsing (e.g. "SI", "currency", etc.).  If not specified, any 
unambiguous units in a compound statement can be used to guess an appropriate 
context for the ambiguous ones.  It's not clear how that would fit into the 
junction scheme, but that might bear some thinking about...

Another point:  one should probably worry more about making the unit parser 
extensible, than about making it complete.  The main symptom of an incomplete 
or confused parser is a bunch of units-junk that is usually parsable by a 
human but not in "simplest form" (e.g. "barn megaparsec tsp^-1" or some such 
[0.63]); that's generally not a fatal problem, especially if the user has 
access to the units database and can add another simplifying resolution.

Yet another point: there are plenty of non-obvious reductions that people 
worry about, such as "N m" -> "J" (energy) but "m N" -> "m N" (torque); but
it's probably not worth worrying about such things: if the coder knows that 
s/he wants a torque, s/he should be able to ask for reduction to a particular
form [e.g. 'units( $val, $template )' should exist and return $val in whatever 
units $template has, if possible.]





Quoth Rod Adams on Monday 28 March 2005 01:07 pm,
> Markus Laire wrote:
> > Larry Wall wrote:
> >> Now, I admit that I've handwaved the tricksy bit, which is, "How do
> >> you know, Larry, that substr() wants 5`Codes rather than 5`Meters?
> >> It's all very well if you have a single predeclared subroutine and
> >> can look at the signature at compile time, but you wrote those as multi
> >> methods up above, so we don't know the signature at compile time."
> >>
> >> Well, that's correct, we don't know it at compile time.  But what
> >> *do* we know?  We know we have a number, and that it was generated
> >> in a context where, if you use it like a string position, it should
> >> turn into a number of code points, and if you use it like a weight,
> >> it should turn into a number of kilograms (or pounds, if you're NASA).
> >>
> >> In other words, the effective type of that literal 5 is not "Int",
> >> but "Int|Codes|Meters|Kilograms|Seconds|Bogomips" or some such.
> >> And if MMD can handle that in an argument type and match up Codes as
> >> a subtype of Ptr, and if we write our method signature only in the
> >> abstract types like Ptr, we're pretty much home free.  That certainly
> >> simplifies how you write S29, though I don't know if the MMD folks
> >> will be terribly happy with the notion of dispatching arguments with
> >> junctional types.  But it does fall out of the design rather naturally.
> >>
> > > ...
> >
> > So do you actually envision perl6 to allow a junction of units on
> > numbers? This would have huge implications, depending on what exactly
> > is possible with these units...
> >
> >
> > Would/could some of these DWIM in perl6?
> >
> > # import proper MMD-subs for + - * etc...
> > use MyUnitConversions;
> >
> > my $length = 1.3`Meters + 4.6`Yards;
> > my $weight = 4`Pounds - 1'Kilograms;
> > my $money = 12`€ + 5.78`£ + 12`US$;
> >
> > Then, how would I specify the unit of the result?
>
> The real "fun" in determining what should happen with units comes to
> when you do operations that _change_ the units.
>
>   my $Current= 5`Amps;
>   my $Resistance = 10`Ohms;
>   my $Power  = $Current * $Resistance; # Do I get 50`Watts here?
>
>
>   my $theta  = 45`Degrees;
>   my $x  = cos($theta);  # no units on $x
>   my $theta2 = acos($x); # in radians? or does $x carry a
>  # "used to be Degrees" property?
>
>
>   my $distance1= 100`Meters;
>   my $distance2= 0.25`Kilometers;
>   my $timeinterval = 5'Seconds;
>   my $velocity1= $distance1 / $timeinterval;
>   my $velocity2= $distance2 / $timeinterval;
>   my $acceleration = ($velocity2-$velocity1)/$timeinterval;
>   # is $acceleration something like 30`Meters/Second/Second ?
>
> Don't forget fun operations like C<$x**2> and others, which should be
> nicely reversible, or used as is. (Think cubic meters for volume). And
> there will likely always be corner cases like C 5`Feet**2> which I would be very surprised about it Perl caught them.
>
> Another fun thing is dealing with ambiguous unit names. "Pound" can
> refer to Force, Mass, or Money. "1`Gallon" can be either "4`Quarts" or
> "5`Quarts" depending on which side of the Atlantic you're on. "Ounce"
> can be either Mass or Liquid Volume, _and_ has US/

Re: Units on numbers [was Re: S28ish]

2005-03-28 Thread Craig DeForest
The problem with using the units(1) database is that it only deals with 
multiplicative relations -- so, e.g., it won't handle temperature.
 
Units resolvers are not so hard to come by -- the strategy is to try to break
each compound unit out into a collection of fundamental quantities that
are interconvertible (e.g. all lengths get converted to "meters"), while 
keeping track of the conversion constant.  I haven't looked at units(1) in
a while, but it used to do this to both the original units and the destination
units, then take the ratio of the accumulated constants.  That's why the 
"conformability" error messages are sometimes a little weird: they always
refer to the fully expanded SI representation of each unit.


Quoth Aaron Sherman on Monday 28 March 2005 03:40 pm,
> On Mon, 2005-03-28 at 16:00, Larry Wall wrote:
> > I've always thought that we should make use of the database of the
> > "units" program for standardized names of units.  The units database
> > has a pretty good list of which units are just differently scaled
> > units of the actual underlying fundamental dimensions, and a lot
> > of encoded experience in distinguishing ambiguous units names.  It'd
> > be a shame to reinvent all that.
>
> That makes fine sense, and I think it would be fairly trivial to
> generate a set of roles from the Units database at run-time,
> pre-compiled with the source or both (selectable in some way).
>
> Of course, there are going to be people who have to re-define chunks of
> that namespace because they have special needs (e.g. money -- this is
> such a huge bear of a problem that it can only be solved for the
> domain-specific cases), but that's fine, and does not preclude your
> suggestion.
>
> here's a start:
>
> perl -nle 'while(<>) {print("# $_"),next if /^\s*($|\#)/;$c="";s/\s+\#.*//
> && ($c=$&);($unit,$def)=split /\s+/, $_, 2;if ($def eq "!")
> {$base{$unit}=1;print "class units::$unit does unit { ... }$c"} elsif
> ($unit =~ /-$/){print "# No handling for prefixes yet
> ($unit=$def)$c"}elsif($base{$def}){print "class units::$unit is
> units::$def;$c"}else{print "# No handling for derived units yet
> ($unit=$def)$c"}}' < /usr/share/units.dat


Re: single element lists

2005-05-11 Thread Craig DeForest
My perspective from PDL is that "(1)[0][0][0]"..."[0]" should evaluate 
to 1.  The artificial distinction between a scalar and an array of 
length 1 (in each dimension) is the source of endless hassles, and it's 
a pretty simple DWIM to allow indexing of element 0 of any unused 
dimension.  That makes it much, much easier to write code that 
generalizes, because you don't have to check for the scalar case -- you 
can always assume that any given dimensional axis will always have one 
value along it (*), and loop/thread/whatever along that dimension.

(*) Of course, that's assuming that there's at least one value in the 
list as a whole -- PDL does, and perl 6 should, support zero-element 
lists; any looping or threading construct on a zero-element list is a no-op.

Jonathan Scott Duff wrote:
We're discussing the proper semantics of (1)[0] on #perl6. Here's
where we're at so far:
1. specialise ()[] to parse as (,)[]
2. scalars are singleton lists, so ()[] naturally
3. make (1)[0] die horribly.
We all seem to agree that #3 is least useful and probably wrong. But
there's a divide between whether #1 or #2 is the "right" behavior.
#2 implies that (1)[0][0][0][0] == 1
#1 means that (1)[0] == 1 and (1)[0][0] is an error
FWIW, I'm in favor of #1
What does p6l think?  (What does @Larry think?)
-Scott