[Prev][Next][Index][Thread]
Re: multiple values in a return from function
At 11:30 PM 2/10/00 -0500, John Whittaker wrote:
>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.
>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;
>
>
>
References: