unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* function registered with scm_c_define_gsubr: how can i handle an optional parameter?
@ 2017-12-13 21:50 Pierre LINDENBAUM
  2017-12-14 10:19 ` Alex Vong
  0 siblings, 1 reply; 6+ messages in thread
From: Pierre LINDENBAUM @ 2017-12-13 21:50 UTC (permalink / raw
  To: guile-user

Hi all,

(cross posted on SO: https://stackoverflow.com/questions/47797521 )


I've defined a guile C function:

     static SCM myfun(SCM arg1,SCM opt_arg2)
       {
       return SCM_BOOL_T;
       }

registered with

     scm_c_define_gsubr ("myfun", 1, 1, 0, myfun);

there is one optional argument. How can I detect if opt_arg2 has been 
used ?

in

     (myfun 1)

or

     (myfun 1 2)


Thanks !



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: function registered with scm_c_define_gsubr: how can i handle an optional parameter?
  2017-12-13 21:50 function registered with scm_c_define_gsubr: how can i handle an optional parameter? Pierre LINDENBAUM
@ 2017-12-14 10:19 ` Alex Vong
  2017-12-14 12:30   ` Mark H Weaver
  0 siblings, 1 reply; 6+ messages in thread
From: Alex Vong @ 2017-12-14 10:19 UTC (permalink / raw
  To: Pierre LINDENBAUM; +Cc: guile-user


[-- Attachment #1.1: Type: text/plain, Size: 654 bytes --]

Hello,

From the Guile manual ``6.1 Overview of the Guile API'',

>    For some Scheme functions, some last arguments are optional; the
> corresponding C function must always be invoked with all optional
> arguments specified.  To get the effect as if an argument has not been
> specified, pass ‘SCM_UNDEFINED’ as its value.  You can not do this for
> an argument in the middle; when one argument is ‘SCM_UNDEFINED’ all the
> ones following it must be ‘SCM_UNDEFINED’ as well.

Therefore, we can check if opt_arg2 has the value SCM_UNDEFINED, to
decide if we have received an optional argument. The code is in the
attachment:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: myfun.c --]
[-- Type: text/x-csrc, Size: 436 bytes --]

#include <libguile.h>

static SCM myfun(SCM arg1,SCM opt_arg2)
{
  if (opt_arg2 == SCM_UNDEFINED)
    scm_display(scm_from_utf8_string("Optional argument NOT received!\n"),
                scm_current_output_port());
  else
    scm_display(scm_from_utf8_string("Optional argument received!\n"),
                scm_current_output_port());
  return SCM_BOOL_T;
}

void
init_myfun(void)
{
  scm_c_define_gsubr("myfun", 1, 1, 0, myfun);
}

[-- Attachment #1.3: Type: text/plain, Size: 517 bytes --]


Cheers,
Alex

Pierre LINDENBAUM <Pierre.Lindenbaum@univ-nantes.fr> writes:

> Hi all,
>
> (cross posted on SO: https://stackoverflow.com/questions/47797521 )
>
>
> I've defined a guile C function:
>
>     static SCM myfun(SCM arg1,SCM opt_arg2)
>       {
>       return SCM_BOOL_T;
>       }
>
> registered with
>
>     scm_c_define_gsubr ("myfun", 1, 1, 0, myfun);
>
> there is one optional argument. How can I detect if opt_arg2 has been
> used ?
>
> in
>
>     (myfun 1)
>
> or
>
>     (myfun 1 2)
>
>
> Thanks !

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: function registered with scm_c_define_gsubr: how can i handle an optional parameter?
  2017-12-14 10:19 ` Alex Vong
@ 2017-12-14 12:30   ` Mark H Weaver
  2017-12-14 13:50     ` Alex Vong
  0 siblings, 1 reply; 6+ messages in thread
From: Mark H Weaver @ 2017-12-14 12:30 UTC (permalink / raw
  To: Alex Vong; +Cc: guile-user, Pierre LINDENBAUM

Hi Alex,

Alex Vong <alexvong1995@gmail.com> writes:

> From the Guile manual ``6.1 Overview of the Guile API'',
>
>>    For some Scheme functions, some last arguments are optional; the
>> corresponding C function must always be invoked with all optional
>> arguments specified.  To get the effect as if an argument has not been
>> specified, pass ‘SCM_UNDEFINED’ as its value.  You can not do this for
>> an argument in the middle; when one argument is ‘SCM_UNDEFINED’ all the
>> ones following it must be ‘SCM_UNDEFINED’ as well.
>
> Therefore, we can check if opt_arg2 has the value SCM_UNDEFINED, to
> decide if we have received an optional argument.

Yes indeed, and your attached code is *almost* correct, except for one
serious problem:

> #include <libguile.h>
>
> static SCM myfun(SCM arg1,SCM opt_arg2)
> {
>   if (opt_arg2 == SCM_UNDEFINED)

You must not use '==' to compare values of type SCM.  Instead, use
'scm_is_eq', like this:

  if (scm_is_eq (opt_arg2, SCM_UNDEFINED))

Guile explicitly makes no promises about the SCM type, so there's no
guarantee that '==' will do the right thing.  SCM is to be treated as an
abstract type.  Look up 'SCM' in the Guile manual's index.  Section 6.3
(The SCM Type) of the manual states:

 -- C Type: SCM
     ‘SCM’ is the user level abstract C type that is used to represent
     all of Guile’s Scheme objects, no matter what the Scheme object
     type is.  No C operation except assignment is guaranteed to work
     with variables of type ‘SCM’, so you should only use macros and
     functions to work with ‘SCM’ values.  [...]

Here's the Guile manual entry for 'scm_is_eq', which also mentions that
you must not use '==':

 -- C Function: int scm_is_eq (SCM x, SCM y)
     Return ‘1’ when X and Y are equal in the sense of ‘eq?’, otherwise
     return ‘0’.

     The ‘==’ operator should not be used on ‘SCM’ values, an ‘SCM’ is a
     C type which cannot necessarily be compared using ‘==’ (*note The
     SCM Type::).

Other than that, the attached code looks good to me.

       Mark



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: function registered with scm_c_define_gsubr: how can i handle an optional parameter?
  2017-12-14 12:30   ` Mark H Weaver
@ 2017-12-14 13:50     ` Alex Vong
  2017-12-15  8:06       ` Mark H Weaver
  0 siblings, 1 reply; 6+ messages in thread
From: Alex Vong @ 2017-12-14 13:50 UTC (permalink / raw
  To: Mark H Weaver; +Cc: guile-user, Pierre LINDENBAUM

[-- Attachment #1: Type: text/plain, Size: 2519 bytes --]

Hello Mark,

Oh, I didn't really think too much about this. I always thought immediate
objects like SCM_EOL, SCM_BOOL_T, ..., SCM_UNDEFINED can be compared
using '=='. Is this an implementation detail that I should not depend
on?

Mark H Weaver <mhw@netris.org> writes:

> Hi Alex,
>
> Alex Vong <alexvong1995@gmail.com> writes:
>
>> From the Guile manual ``6.1 Overview of the Guile API'',
>>
>>>    For some Scheme functions, some last arguments are optional; the
>>> corresponding C function must always be invoked with all optional
>>> arguments specified.  To get the effect as if an argument has not been
>>> specified, pass ‘SCM_UNDEFINED’ as its value.  You can not do this for
>>> an argument in the middle; when one argument is ‘SCM_UNDEFINED’ all the
>>> ones following it must be ‘SCM_UNDEFINED’ as well.
>>
>> Therefore, we can check if opt_arg2 has the value SCM_UNDEFINED, to
>> decide if we have received an optional argument.
>
> Yes indeed, and your attached code is *almost* correct, except for one
> serious problem:
>
>> #include <libguile.h>
>>
>> static SCM myfun(SCM arg1,SCM opt_arg2)
>> {
>>   if (opt_arg2 == SCM_UNDEFINED)
>
> You must not use '==' to compare values of type SCM.  Instead, use
> 'scm_is_eq', like this:
>
>   if (scm_is_eq (opt_arg2, SCM_UNDEFINED))
>
> Guile explicitly makes no promises about the SCM type, so there's no
> guarantee that '==' will do the right thing.  SCM is to be treated as an
> abstract type.  Look up 'SCM' in the Guile manual's index.  Section 6.3
> (The SCM Type) of the manual states:
>
>  -- C Type: SCM
>      ‘SCM’ is the user level abstract C type that is used to represent
>      all of Guile’s Scheme objects, no matter what the Scheme object
>      type is.  No C operation except assignment is guaranteed to work
>      with variables of type ‘SCM’, so you should only use macros and
>      functions to work with ‘SCM’ values.  [...]
>
> Here's the Guile manual entry for 'scm_is_eq', which also mentions that
> you must not use '==':
>
>  -- C Function: int scm_is_eq (SCM x, SCM y)
>      Return ‘1’ when X and Y are equal in the sense of ‘eq?’, otherwise
>      return ‘0’.
>
>      The ‘==’ operator should not be used on ‘SCM’ values, an ‘SCM’ is a
>      C type which cannot necessarily be compared using ‘==’ (*note The
>      SCM Type::).
>
> Other than that, the attached code looks good to me.
>
>        Mark

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: function registered with scm_c_define_gsubr: how can i handle an optional parameter?
  2017-12-14 13:50     ` Alex Vong
@ 2017-12-15  8:06       ` Mark H Weaver
  2017-12-15 16:59         ` Alex Vong
  0 siblings, 1 reply; 6+ messages in thread
From: Mark H Weaver @ 2017-12-15  8:06 UTC (permalink / raw
  To: Alex Vong; +Cc: guile-user, Pierre LINDENBAUM

Hi Alex,

Alex Vong <alexvong1995@gmail.com> writes:

> Oh, I didn't really think too much about this. I always thought immediate
> objects like SCM_EOL, SCM_BOOL_T, ..., SCM_UNDEFINED can be compared
> using '=='. Is this an implementation detail that I should not depend
> on?

That's right.  You should not rely on SCM being represented in any
particular way.  In C, '==' works only on pointers and values of
arithmetic type, not on structs or unions.  Therefore, in general, you
cannot use '==' on a value of an abstract type without some knowledge of
the underlying type.

Guile's API is designed to avoid propagating assumptions about the SCM
type.  Please use only the functions and macros in Guile's public API to
inspect, compare, or manipulate values of type SCM.  This will enable
Guile implementors and other hackers to experiment with other SCM data
representations.  We reserve the right to change the SCM type in future
versions of Guile (but not within a stable release series e.g. 2.2.x).

I should also mention that Guile provides a mechanism to check for such
mistakes.  If you test compiling your libguile-using code with
-DSCM_DEBUG_TYPING_STRICTNESS=2, it will change SCM to be a struct type,
and you'll get a compile error if you attempt to use '==' on values of
type SCM.  (Note that this will produce code that is ABI-incompatible
with libguile compiled using the default SCM_DEBUG_TYPING_STRICTNESS=1
setting, so typically you would set SCM_DEBUG_TYPING_STRICTNESS=2 only
as a compile-time check.)

For details, see the description of SCM_DEBUG_TYPING_STRICTNESS in
__scm.h, and also the top few pages of tags.h, which describes the
fundamental concepts of how Guile Scheme objects are represented in C,
including the definitions of the SCM type and the 'scm_is_eq' macro.

     Regards,
       Mark



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: function registered with scm_c_define_gsubr: how can i handle an optional parameter?
  2017-12-15  8:06       ` Mark H Weaver
@ 2017-12-15 16:59         ` Alex Vong
  0 siblings, 0 replies; 6+ messages in thread
From: Alex Vong @ 2017-12-15 16:59 UTC (permalink / raw
  To: Mark H Weaver; +Cc: guile-user, Pierre LINDENBAUM

[-- Attachment #1: Type: text/plain, Size: 1966 bytes --]

Mark H Weaver <mhw@netris.org> writes:

> Hi Alex,
>
> Alex Vong <alexvong1995@gmail.com> writes:
>
>> Oh, I didn't really think too much about this. I always thought immediate
>> objects like SCM_EOL, SCM_BOOL_T, ..., SCM_UNDEFINED can be compared
>> using '=='. Is this an implementation detail that I should not depend
>> on?
>
> That's right.  You should not rely on SCM being represented in any
> particular way.  In C, '==' works only on pointers and values of
> arithmetic type, not on structs or unions.  Therefore, in general, you
> cannot use '==' on a value of an abstract type without some knowledge of
> the underlying type.
>
> Guile's API is designed to avoid propagating assumptions about the SCM
> type.  Please use only the functions and macros in Guile's public API to
> inspect, compare, or manipulate values of type SCM.  This will enable
> Guile implementors and other hackers to experiment with other SCM data
> representations.  We reserve the right to change the SCM type in future
> versions of Guile (but not within a stable release series e.g. 2.2.x).
>
> I should also mention that Guile provides a mechanism to check for such
> mistakes.  If you test compiling your libguile-using code with
> -DSCM_DEBUG_TYPING_STRICTNESS=2, it will change SCM to be a struct type,
> and you'll get a compile error if you attempt to use '==' on values of
> type SCM.  (Note that this will produce code that is ABI-incompatible
> with libguile compiled using the default SCM_DEBUG_TYPING_STRICTNESS=1
> setting, so typically you would set SCM_DEBUG_TYPING_STRICTNESS=2 only
> as a compile-time check.)
>
> For details, see the description of SCM_DEBUG_TYPING_STRICTNESS in
> __scm.h, and also the top few pages of tags.h, which describes the
> fundamental concepts of how Guile Scheme objects are represented in C,
> including the definitions of the SCM type and the 'scm_is_eq' macro.
>
>      Regards,
>        Mark

Thanks for your informative post!

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-12-15 16:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-13 21:50 function registered with scm_c_define_gsubr: how can i handle an optional parameter? Pierre LINDENBAUM
2017-12-14 10:19 ` Alex Vong
2017-12-14 12:30   ` Mark H Weaver
2017-12-14 13:50     ` Alex Vong
2017-12-15  8:06       ` Mark H Weaver
2017-12-15 16:59         ` Alex Vong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).