multiple values in a return from function 
Author Message
 multiple values in a return from function

I'm not sure what I'm doing wrong here.  I wanted to return two values from
a function that computes solar positions--the right ascension and
declination of the sun.  Both are <floats>.  When I tried interactively
testing this function, it would only return 1 value.  I must be missing
something simple, but I don't get it.   If I change the function to return
an object that contains a right ascension slot and a declination slot, it
works fine.  If I return a list of the right ascension and declination, it
works too.

What Dylan concept do I need to bone up on?

I've included the source for illustration:

  **** This one works when tested interactively ****
define method compute-solar-position( epoch-day :: <integer> ) =>
  ( results :: <astro-position>)

   // Now pre-compute the important values based on epoch day
   ecliptic-obliquity := 23.4393 - 3.563e-7 * epoch-day;
   solar-eccentricity := 0.016709 - 1.151E-9 * epoch-day;
   solar-mean-anomaly := 356.0470 + 0.9856002585 * epoch-day;
   solar-arg-perihelion := 282.9404 + 4.70935E-5 * epoch-day;

  // compute eccentric anomaly in radians
  let eccentric-anomaly = solar-mean-anomaly +  (solar-eccentricity  *
                                           sin( solar-mean-anomaly ) *
                                           ( 1.0 + solar-eccentricity *
os( solar-mean-anomaly )));
  // compute x and y component of true anomaly position
  let x-true-anom       = cos( eccentric-anomaly ) - solar-eccentricity;
  let y-true-anom       = sqrt( 1.0 - solar-eccentricity ^ 2 ) *
in( eccentric-anomaly );

  let true-anomaly = atan2( y-true-anom , x-true-anom );

  // assume this is in AU?
  let solar-distance = sqrt( x-true-anom ^ 2  + y-true-anom ^ 2);

  // compute solar true longitude
  let solar-true-long = true-anomaly + solar-arg-perihelion;

   // compute solar ecliptic rectangular coordinates
  let x-sun = solar-distance * cos( solar-true-long );
  let y-sun = solar-distance * sin( solar-true-long );

  // now convert these to equatorial, rectangular coordinates
  let eq-x-sun = x-sun;
  let eq-y-sun = y-sun * cos( ecliptic-obliquity );
  let eq-z-sun = y-sun * sin( ecliptic-obliquity );

  let suns-pos = make( <astro-position> );
  // Finally, compute right ascension and declination
  suns-pos.right-ascension := atan2( eq-y-sun, eq-x-sun );
  suns-pos.declination     := atan2( eq-z-sun, sqrt( eq-x-sun ^ 2  +
eq-y-sun ^ 2));
  suns-pos;

end method;

  **** This one doesn't ****

define method compute-solar-position( epoch-day :: <integer> ) =>
  ( results :: false-or( <astro-position>))

   // Now pre-compute the important values based on epoch day
   ecliptic-obliquity := 23.4393 - 3.563e-7 * epoch-day;
   solar-eccentricity := 0.016709 - 1.151E-9 * epoch-day;
   solar-mean-anomaly := 356.0470 + 0.9856002585 * epoch-day;
   solar-arg-perihelion := 282.9404 + 4.70935E-5 * epoch-day;

  // compute eccentric anomaly in radians
  let eccentric-anomaly = solar-mean-anomaly +  (solar-eccentricity  *
                                           sin( solar-mean-anomaly ) *
                                           ( 1.0 + solar-eccentricity *
os( solar-mean-anomaly )));
  // compute x and y component of true anomaly position
  let x-true-anom       = cos( eccentric-anomaly ) - solar-eccentricity;
  let y-true-anom       = sqrt( 1.0 - solar-eccentricity ^ 2 ) *
in( eccentric-anomaly );

  let true-anomaly = atan2( y-true-anom , x-true-anom );

  // assume this is in AU?
  let solar-distance = sqrt( x-true-anom ^ 2  + y-true-anom ^ 2);

  // compute solar true longitude
  let solar-true-long = true-anomaly + solar-arg-perihelion;

   // compute solar ecliptic rectangular coordinates
  let x-sun = solar-distance * cos( solar-true-long );
  let y-sun = solar-distance * sin( solar-true-long );

  // now convert these to equatorial, rectangular coordinates
  let eq-x-sun = x-sun;
  let eq-y-sun = y-sun * cos( ecliptic-obliquity );
  let eq-z-sun = y-sun * sin( ecliptic-obliquity );

  // Finally, compute right ascension and declination
  let right-ascension = atan2( eq-y-sun, eq-x-sun );
  let declination       = atan2( eq-z-sun, sqrt( eq-x-sun ^ 2  + eq-y-sun ^
2));

   values( right-ascension, declination );
end method;



Tue, 30 Jul 2002 03:00:00 GMT  
 multiple values in a return from function

Quote:
>I'm not sure what I'm doing wrong here.  I wanted to return two values from
>a function that computes solar positions--the right ascension and
>declination of the sun.  Both are <floats>.  When I tried interactively
>testing this function, it would only return 1 value.  I must be missing
>something simple, but I don't get it.   If I change the function to return
>an object that contains a right ascension slot and a declination slot, it
>works fine.  If I return a list of the right ascension and declination, it
>works too.
>What Dylan concept do I need to bone up on?

The problem is that you have defined compute-solar-position to return only
one value (i.e., => (results :: <astro-position>) ).  Dylan (unlike CL)
will discard extra values if less values are defined than are actually
returned (and pad values with falses if more are defined than are actually
returned).  You can use #rest in the values specification if you want a
varying number of return values (e.g., => (#rest results ::
<astro-position>) ).

Jonathan Bachrach
President, Functional Objects, Inc.

Quote:
>I've included the source for illustration:

>   **** This one works when tested interactively ****
>define method compute-solar-position( epoch-day :: <integer> ) =>
>   ( results :: <astro-position>)

>    // Now pre-compute the important values based on epoch day
>    ecliptic-obliquity := 23.4393 - 3.563e-7 * epoch-day;
>    solar-eccentricity := 0.016709 - 1.151E-9 * epoch-day;
>    solar-mean-anomaly := 356.0470 + 0.9856002585 * epoch-day;
>    solar-arg-perihelion := 282.9404 + 4.70935E-5 * epoch-day;

>   // compute eccentric anomaly in radians
>   let eccentric-anomaly = solar-mean-anomaly +  (solar-eccentricity  *
>                                            sin( solar-mean-anomaly ) *
>                                            ( 1.0 + solar-eccentricity *
>os( solar-mean-anomaly )));
>   // compute x and y component of true anomaly position
>   let x-true-anom       = cos( eccentric-anomaly ) - solar-eccentricity;
>   let y-true-anom       = sqrt( 1.0 - solar-eccentricity ^ 2 ) *
>in( eccentric-anomaly );

>   let true-anomaly = atan2( y-true-anom , x-true-anom );

>   // assume this is in AU?
>   let solar-distance = sqrt( x-true-anom ^ 2  + y-true-anom ^ 2);

>   // compute solar true longitude
>   let solar-true-long = true-anomaly + solar-arg-perihelion;

>    // compute solar ecliptic rectangular coordinates
>   let x-sun = solar-distance * cos( solar-true-long );
>   let y-sun = solar-distance * sin( solar-true-long );

>   // now convert these to equatorial, rectangular coordinates
>   let eq-x-sun = x-sun;
>   let eq-y-sun = y-sun * cos( ecliptic-obliquity );
>   let eq-z-sun = y-sun * sin( ecliptic-obliquity );

>   let suns-pos = make( <astro-position> );
>   // Finally, compute right ascension and declination
>   suns-pos.right-ascension := atan2( eq-y-sun, eq-x-sun );
>   suns-pos.declination     := atan2( eq-z-sun, sqrt( eq-x-sun ^ 2  +
>eq-y-sun ^ 2));
>   suns-pos;

>end method;

>   **** This one doesn't ****

>define method compute-solar-position( epoch-day :: <integer> ) =>
>   ( results :: false-or( <astro-position>))

>    // Now pre-compute the important values based on epoch day
>    ecliptic-obliquity := 23.4393 - 3.563e-7 * epoch-day;
>    solar-eccentricity := 0.016709 - 1.151E-9 * epoch-day;
>    solar-mean-anomaly := 356.0470 + 0.9856002585 * epoch-day;
>    solar-arg-perihelion := 282.9404 + 4.70935E-5 * epoch-day;

>   // compute eccentric anomaly in radians
>   let eccentric-anomaly = solar-mean-anomaly +  (solar-eccentricity  *
>                                            sin( solar-mean-anomaly ) *
>                                            ( 1.0 + solar-eccentricity *
>os( solar-mean-anomaly )));
>   // compute x and y component of true anomaly position
>   let x-true-anom       = cos( eccentric-anomaly ) - solar-eccentricity;
>   let y-true-anom       = sqrt( 1.0 - solar-eccentricity ^ 2 ) *
>in( eccentric-anomaly );

>   let true-anomaly = atan2( y-true-anom , x-true-anom );

>   // assume this is in AU?
>   let solar-distance = sqrt( x-true-anom ^ 2  + y-true-anom ^ 2);

>   // compute solar true longitude
>   let solar-true-long = true-anomaly + solar-arg-perihelion;

>    // compute solar ecliptic rectangular coordinates
>   let x-sun = solar-distance * cos( solar-true-long );
>   let y-sun = solar-distance * sin( solar-true-long );

>   // now convert these to equatorial, rectangular coordinates
>   let eq-x-sun = x-sun;
>   let eq-y-sun = y-sun * cos( ecliptic-obliquity );
>   let eq-z-sun = y-sun * sin( ecliptic-obliquity );

>   // Finally, compute right ascension and declination
>   let right-ascension = atan2( eq-y-sun, eq-x-sun );
>   let declination       = atan2( eq-z-sun, sqrt( eq-x-sun ^ 2  + eq-y-sun ^
>2));

>    values( right-ascension, declination );
>end method;



Tue, 30 Jul 2002 03:00:00 GMT  
 multiple values in a return from function

Quote:

> I'm not sure what I'm doing wrong here.  I wanted to return two values from
> a function that computes solar positions--the right ascension and
> declination of the sun.  Both are <floats>.  When I tried interactively
> testing this function, it would only return 1 value.

It should work fine, but you don't show how you're testing it.

[interpreter thread starting.]
Marlais 0.5.11
? define method sincos(a)

Quote:
>  values(sin(a), cos(a))
> end;

==> sincos
? define variable (x, y) = sincos(3.141592654/6);;
? x;
==> 0.500000
? y;
==> 0.866025
?

Note that the *only* ways to make use of multiple return values are to
assign them to variables using either "define variable (foo, bar, baz) = "
or else "let (foo, bar, baz) = ".  Any other method of using the function
return will ignore all but the first value.

-- Bruce



Tue, 30 Jul 2002 03:00:00 GMT  
 multiple values in a return from function

Quote:

> define method compute-solar-position( epoch-day :: <integer> ) =>
>   ( results :: false-or( <astro-position>))
   [...snip...]

>    values( right-ascension, declination );
> end method;

It's possibly because you are declaring the return result as being a
single value (of type false or instance of class <astro-position>),
whereas you are actually returning two values. The compiler will be
ignoring the second value.

Try it with just (ie. no return value declared):

Quote:
> define method compute-solar-position( epoch-day :: <integer> )
   [...snip...]
>    values( right-ascension, declination );
> end method;

Chris.
--
http://www.double.co.nz/dylan


Tue, 30 Jul 2002 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. return multiple values from an awk function?

2. multiple return values for functions

3. ???Eiffel idiom for multiple return values???

4. Tuples, iterators, and multiple return values in Eiffel?

5. Wait ms Timer Multiple returning inaccurate timer value

6. Multiple return values

7. multiple return values

8. Multiple return values

9. Newbie on multiple return values

10. Multiple return values

11. 1st-class method closures (was Re: Multiple return values)

12. C-interface and multiple return values

 

 
Powered by phpBB® Forum Software