*C extensions@ 2021-02-21 3:56 Tim Meehan2021-02-21 4:10 ` Nala Ginrut 2021-02-21 16:00 ` Olivier Dion via General Guile related discussions 0 siblings, 2 replies; 6+ messages in thread From: Tim Meehan @ 2021-02-21 3:56 UTC (permalink / raw) To: guile-user I'm trying my hand a writing C extensions. I've done this for stuff like Matlab before, and was wondering how you do the usual checking of the arguments that are passed in from Guile. In the manual, 6.13.13.1 "C Support" has a few functions. libguile/numbers.h has a bunch more ... What I have is an extension function, sort of like the bessel function in the tutorial: https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html What I would like to do is verify that the first argument is an inexact number, larger than 0. How would I go about that? Perhaps some of it could be: SCM_REALP scm_misc_error Any tips? ^ permalink raw reply [flat|nested] 6+ messages in thread

*Re: C extensions2021-02-21 3:56 C extensions Tim Meehan@ 2021-02-21 4:10 ` Nala Ginrut2021-02-21 16:00 ` Olivier Dion via General Guile related discussions 1 sibling, 0 replies; 6+ messages in thread From: Nala Ginrut @ 2021-02-21 4:10 UTC (permalink / raw) To: Tim Meehan;+Cc:guile-user Hi Tim! I think you may try these functions: scm_is_true scm_is_real_p scm_geq_p Best regards. On Sun, Feb 21, 2021 at 11:57 AM Tim Meehan <btmeehan@gmail.com> wrote: > I'm trying my hand a writing C extensions. > I've done this for stuff like Matlab before, and was wondering how you do > the usual checking of the arguments that are passed in from Guile. > > In the manual, 6.13.13.1 "C Support" has a few functions. > libguile/numbers.h has a bunch more ... > > What I have is an extension function, sort of like the bessel function in > the tutorial: > > https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html > > What I would like to do is verify that the first argument is an inexact > number, larger than 0. How would I go about that? Perhaps some of it could > be: > SCM_REALP > scm_misc_error > > Any tips? > ^ permalink raw reply [flat|nested] 6+ messages in thread

*Re: C extensions2021-02-21 3:56 C extensions Tim Meehan 2021-02-21 4:10 ` Nala Ginrut@ 2021-02-21 16:00 ` Olivier Dion via General Guile related discussions2021-02-21 21:58 ` Tim Meehan 1 sibling, 1 reply; 6+ messages in thread From: Olivier Dion via General Guile related discussions @ 2021-02-21 16:00 UTC (permalink / raw) To: Tim Meehan, guile-user On Sat, 20 Feb 2021, Tim Meehan <btmeehan@gmail.com> wrote: > I'm trying my hand a writing C extensions. > I've done this for stuff like Matlab before, and was wondering how you do > the usual checking of the arguments that are passed in from Guile. > > In the manual, 6.13.13.1 "C Support" has a few functions. > libguile/numbers.h has a bunch more ... > > What I have is an extension function, sort of like the bessel function in > the tutorial: > https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html Usually I do this in 2 or 3 steps. 1. Define the primitive in C with raw arguments. 2. Make a wrapper of this primitive for Guile to use. Optionnaly do the arguments checking here or go to step 3. 3. Make a second wrapper in Scheme and check the arguments there. This wrapper will call wrapper in made in 2. Here's a full example: ---------------------------------------------------------------------- float c_sin(double x) { return sin(x); } SCM_DEFINE(c_sin_wrapper, "sin", 1, 0, 0, (SCM x), "My sine") { if (scm_is_number(x)) { return c_sin(scm_to_double(x)); } return SCM_BOOL_F; } ---------------------------------------------------------------------- > What I would like to do is verify that the first argument is an inexact > number, larger than 0. How would I go about that? Perhaps some of it > could For your example, use the following predicates: ---------------------------------------------------------------------- scm_is_inexact(x) && scm_is_true(scm_positive_p(x)) ---------------------------------------------------------------------- > be: > SCM_REALP > scm_misc_error > > Any tips? -- Olivier Dion PolyMtl ^ permalink raw reply [flat|nested] 6+ messages in thread

*Re: C extensions2021-02-21 16:00 ` Olivier Dion via General Guile related discussions@ 2021-02-21 21:58 ` Tim Meehan2021-02-21 22:18 ` Tim Meehan 2021-02-21 22:41 ` Olivier Dion via General Guile related discussions 0 siblings, 2 replies; 6+ messages in thread From: Tim Meehan @ 2021-02-21 21:58 UTC (permalink / raw) Cc: guile-user Hello Olivier, thanks! Those functions helped, and now I know where in the source of Guile to look. Is "inexact" the same thing as "floating point number" in Guile-speak? Here is one of the functions in my extension - it returns a lognormal variate. There are a bunch of things like this that could be added to "random.c" - but I'm imagining that the only user of stuff like that might be ... me ... anyhow: Right now, it doesn't give really helpful errors when you give it a negative standard deviation: scheme@(guile-user)> (random:lognormal 0 -1) $1 = #f SCM_DEFINE (scm_random_lognormal, "random:lognormal", 2, 1, 0, (SCM _mu, SCM _sigma, SCM state), "Return an inexact real in a Log Normal distribution.\n" "\n" "@var{mu} - mean of the underlying normal distribution.\n" "@var{sigma} - standard deviation of the same.\n" "Optionally, a random @var{state} can be provided.\n" "See @code{seed->random-state}.") #define FUNC_NAME s_scm_random_lognormal { if (SCM_UNBNDP (state)) state = SCM_VARIABLE_REF (scm_var_random_state); SCM_VALIDATE_RSTATE (1, state); if (scm_is_false (scm_positive_p (_sigma))) return SCM_BOOL_F; // I'd like to return some meaningful error here ... double mu = scm_to_double (_mu); double sigma = scm_to_double (_sigma); return scm_from_double (exp (mu + sigma*scm_c_normal01 (SCM_RSTATE(state)))); } #undef FUNC_NAME On Sun, Feb 21, 2021 at 9:59 AM Olivier Dion <olivier.dion@polymtl.ca> wrote: > On Sat, 20 Feb 2021, Tim Meehan <btmeehan@gmail.com> wrote: > > I'm trying my hand a writing C extensions. > > I've done this for stuff like Matlab before, and was wondering how you do > > the usual checking of the arguments that are passed in from Guile. > > > > In the manual, 6.13.13.1 "C Support" has a few functions. > > libguile/numbers.h has a bunch more ... > > > > What I have is an extension function, sort of like the bessel function in > > the tutorial: > > > https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html > > Usually I do this in 2 or 3 steps. > > 1. Define the primitive in C with raw arguments. > > 2. Make a wrapper of this primitive for Guile to use. Optionnaly do > the arguments checking here or go to step 3. > > 3. Make a second wrapper in Scheme and check the arguments there. > This wrapper will call wrapper in made in 2. > > Here's a full example: > ---------------------------------------------------------------------- > float c_sin(double x) > { > return sin(x); > } > > SCM_DEFINE(c_sin_wrapper, "sin", 1, 0, 0, > (SCM x), > "My sine") > { > if (scm_is_number(x)) { > return c_sin(scm_to_double(x)); > } > > return SCM_BOOL_F; > } > ---------------------------------------------------------------------- > > > What I would like to do is verify that the first argument is an inexact > > number, larger than 0. How would I go about that? Perhaps some of it > > could > > For your example, use the following predicates: > ---------------------------------------------------------------------- > scm_is_inexact(x) && scm_is_true(scm_positive_p(x)) > ---------------------------------------------------------------------- > > > be: > > SCM_REALP > > scm_misc_error > > > > Any tips? > -- > Olivier Dion > PolyMtl > ^ permalink raw reply [flat|nested] 6+ messages in thread

*Re: C extensions2021-02-21 21:58 ` Tim Meehan@ 2021-02-21 22:18 ` Tim Meehan2021-02-21 22:41 ` Olivier Dion via General Guile related discussions 1 sibling, 0 replies; 6+ messages in thread From: Tim Meehan @ 2021-02-21 22:18 UTC (permalink / raw) Cc: guile-user I suppose that I could use something like "scm_wrong_type_arg_msg" ... which gives better looking feedback than "#f": scheme@(guile-user)> (random:lognormal 0 -1) ice-9/boot-9.scm:1669:16: In procedure raise-exception: In procedure random:lognormal: Wrong type argument in position 2 (expecting standard deviation): -1 On Sun, Feb 21, 2021 at 3:58 PM Tim Meehan <btmeehan@gmail.com> wrote: > Hello Olivier, thanks! > Those functions helped, and now I know where in the source of Guile to > look. > > Is "inexact" the same thing as "floating point number" in Guile-speak? > > Here is one of the functions in my extension - it returns a lognormal > variate. There are a bunch of things like this that could be added to > "random.c" - but I'm imagining that the only user of stuff like that might > be ... me ... anyhow: > > Right now, it doesn't give really helpful errors when you give it a > negative standard deviation: > scheme@(guile-user)> (random:lognormal 0 -1) > $1 = #f > > SCM_DEFINE (scm_random_lognormal, "random:lognormal", 2, 1, 0, > (SCM _mu, SCM _sigma, SCM state), > "Return an inexact real in a Log Normal distribution.\n" > "\n" > "@var{mu} - mean of the underlying normal distribution.\n" > "@var{sigma} - standard deviation of the same.\n" > "Optionally, a random @var{state} can be provided.\n" > "See @code{seed->random-state}.") > #define FUNC_NAME s_scm_random_lognormal > { > if (SCM_UNBNDP (state)) > state = SCM_VARIABLE_REF (scm_var_random_state); > SCM_VALIDATE_RSTATE (1, state); > > if (scm_is_false (scm_positive_p (_sigma))) > return SCM_BOOL_F; // I'd like to return some meaningful error here ... > > double mu = scm_to_double (_mu); > double sigma = scm_to_double (_sigma); > return scm_from_double (exp (mu + sigma*scm_c_normal01 > (SCM_RSTATE(state)))); > } > #undef FUNC_NAME > > On Sun, Feb 21, 2021 at 9:59 AM Olivier Dion <olivier.dion@polymtl.ca> > wrote: > >> On Sat, 20 Feb 2021, Tim Meehan <btmeehan@gmail.com> wrote: >> > I'm trying my hand a writing C extensions. >> > I've done this for stuff like Matlab before, and was wondering how you >> do >> > the usual checking of the arguments that are passed in from Guile. >> > >> > In the manual, 6.13.13.1 "C Support" has a few functions. >> > libguile/numbers.h has a bunch more ... >> > >> > What I have is an extension function, sort of like the bessel function >> in >> > the tutorial: >> > >> https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html >> >> Usually I do this in 2 or 3 steps. >> >> 1. Define the primitive in C with raw arguments. >> >> 2. Make a wrapper of this primitive for Guile to use. Optionnaly do >> the arguments checking here or go to step 3. >> >> 3. Make a second wrapper in Scheme and check the arguments there. >> This wrapper will call wrapper in made in 2. >> >> Here's a full example: >> ---------------------------------------------------------------------- >> float c_sin(double x) >> { >> return sin(x); >> } >> >> SCM_DEFINE(c_sin_wrapper, "sin", 1, 0, 0, >> (SCM x), >> "My sine") >> { >> if (scm_is_number(x)) { >> return c_sin(scm_to_double(x)); >> } >> >> return SCM_BOOL_F; >> } >> ---------------------------------------------------------------------- >> >> > What I would like to do is verify that the first argument is an inexact >> > number, larger than 0. How would I go about that? Perhaps some of it >> > could >> >> For your example, use the following predicates: >> ---------------------------------------------------------------------- >> scm_is_inexact(x) && scm_is_true(scm_positive_p(x)) >> ---------------------------------------------------------------------- >> >> > be: >> > SCM_REALP >> > scm_misc_error >> > >> > Any tips? >> -- >> Olivier Dion >> PolyMtl >> > ^ permalink raw reply [flat|nested] 6+ messages in thread

*2021-02-21 21:58 ` Tim Meehan 2021-02-21 22:18 ` Tim MeehanRe: C extensions@ 2021-02-21 22:41 ` Olivier Dion via General Guile related discussions1 sibling, 0 replies; 6+ messages in thread From: Olivier Dion via General Guile related discussions @ 2021-02-21 22:41 UTC (permalink / raw) To: Tim Meehan;+Cc:guile-user On Sun, 21 Feb 2021, Tim Meehan <btmeehan@gmail.com> wrote: > Hello Olivier, thanks! > Those functions helped, and now I know where in the source of Guile to look. > > Is "inexact" the same thing as "floating point number" in Guile-speak? I don't think so. If I remember correctly, exact numbers are numbers that can be represented by a quotient of two integers. In other words, any rational number is an exact number. I might be wrong here. I highly suggest that you read the numerical tower from the Guile's texinfo manual for more informations on that. > > Here is one of the functions in my extension - it returns a lognormal > variate. There are a bunch of things like this that could be added to > "random.c" - but I'm imagining that the only user of stuff like that might > be ... me ... anyhow: > > Right now, it doesn't give really helpful errors when you give it a > negative standard deviation: > scheme@(guile-user)> (random:lognormal 0 -1) > $1 = #f In my example, I returned false because this is how I would approach the problem from a C perspective. i.e., returning an error code. I'm still learning on how to work with Scheme. I guess that if you want something more Pythonic, you would throw an exception. > SCM_DEFINE (scm_random_lognormal, "random:lognormal", 2, 1, 0, > (SCM _mu, SCM _sigma, SCM state), > "Return an inexact real in a Log Normal distribution.\n" > "\n" > "@var{mu} - mean of the underlying normal distribution.\n" > "@var{sigma} - standard deviation of the same.\n" > "Optionally, a random @var{state} can be provided.\n" > "See @code{seed->random-state}.") > #define FUNC_NAME s_scm_random_lognormal > { > if (SCM_UNBNDP (state)) > state = SCM_VARIABLE_REF (scm_var_random_state); > SCM_VALIDATE_RSTATE (1, state); > > if (scm_is_false (scm_positive_p (_sigma))) > return SCM_BOOL_F; // I'd like to return some meaningful error > here ... You can use `scm_throw()` to throw an exception. ---------------------------------------------------------------------- /* * This create a symbol that has static linkage in C. You might want * to declare it globally instead. */ SCM_SYMBOL(lognormal_error_key, "invalid-argument"); if (scm_is_false (scm_positive_p (_sigma))) { scm_throw(lognormal_error_key, scm_list_n(SCM_UNDEFINED)); /* Unreachable path! */ assert(0); } ---------------------------------------------------------------------- Note that throwing an error might be easier to do in Scheme itself: ---------------------------------------------------------------------- (throw 'invalid-argument) ---------------------------------------------------------------------- > > double mu = scm_to_double (_mu); > double sigma = scm_to_double (_sigma); > return scm_from_double (exp (mu + sigma*scm_c_normal01 > (SCM_RSTATE(state)))); > } > #undef FUNC_NAME > > On Sun, Feb 21, 2021 at 9:59 AM Olivier Dion <olivier.dion@polymtl.ca> > wrote: > >> On Sat, 20 Feb 2021, Tim Meehan <btmeehan@gmail.com> wrote: >> > I'm trying my hand a writing C extensions. >> > I've done this for stuff like Matlab before, and was wondering how you do >> > the usual checking of the arguments that are passed in from Guile. >> > >> > In the manual, 6.13.13.1 "C Support" has a few functions. >> > libguile/numbers.h has a bunch more ... >> > >> > What I have is an extension function, sort of like the bessel function in >> > the tutorial: >> > >> https://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Extension.html >> >> Usually I do this in 2 or 3 steps. >> >> 1. Define the primitive in C with raw arguments. >> >> 2. Make a wrapper of this primitive for Guile to use. Optionnaly do >> the arguments checking here or go to step 3. >> >> 3. Make a second wrapper in Scheme and check the arguments there. >> This wrapper will call wrapper in made in 2. >> >> Here's a full example: >> ---------------------------------------------------------------------- >> float c_sin(double x) >> { >> return sin(x); >> } >> >> SCM_DEFINE(c_sin_wrapper, "sin", 1, 0, 0, >> (SCM x), >> "My sine") >> { >> if (scm_is_number(x)) { >> return c_sin(scm_to_double(x)); >> } >> >> return SCM_BOOL_F; >> } >> ---------------------------------------------------------------------- >> >> > What I would like to do is verify that the first argument is an inexact >> > number, larger than 0. How would I go about that? Perhaps some of it >> > could >> >> For your example, use the following predicates: >> ---------------------------------------------------------------------- >> scm_is_inexact(x) && scm_is_true(scm_positive_p(x)) >> ---------------------------------------------------------------------- >> >> > be: >> > SCM_REALP >> > scm_misc_error >> > >> > Any tips? >> -- >> Olivier Dion >> PolyMtl >> -- Olivier Dion PolyMtl ^ permalink raw reply [flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-02-21 22:41 UTC | newest]Thread overview:6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-02-21 3:56 C extensions Tim Meehan 2021-02-21 4:10 ` Nala Ginrut 2021-02-21 16:00 ` Olivier Dion via General Guile related discussions 2021-02-21 21:58 ` Tim Meehan 2021-02-21 22:18 ` Tim Meehan 2021-02-21 22:41 ` Olivier Dion via General Guile related discussions

unofficial mirror of guile-user@gnu.org This inbox may be cloned and mirrored by anyone: git clone --mirror https://yhetil.org/guile-user/0 guile-user/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 guile-user guile-user/ https://yhetil.org/guile-user \ guile-user@gnu.org public-inbox-index guile-user Example config snippet for mirrors. Newsgroups are available over NNTP: nntp://news.yhetil.org/yhetil.lisp.guile.user nntp://news.gmane.io/gmane.lisp.guile.user AGPL code for this site: git clone http://ou63pmih66umazou.onion/public-inbox.git