Re: Question about how to check a symbol is bound

2023-06-23 Thread Kon Lovett



> On Jun 22, 2023, at 9:07 PM, Pan Xie  wrote:
> 
> Hello
> 
> I am new to CHICKEN scheme and here is a (very) quick question of how to 
> check whether a symbol is bound.
> 
> I know it doable but I can't find the way.
> 
> I don't find the methods from the main CHICKEN manual document. Then I import 
> the "symbol-value-utils" module. I believe the "unbound?" or "symbol-value" 
> will do what I want, but to my surprise they does NOT:
> 
> I expect `symbol-value' will give me value of a symbol, but it will throw 
> exception for an
> undefined symbol, even I provide the default value:
> 
> (symbol-value foo #f)
> Error: unbound variable: foo

#;2> (symbol-value 'foo #f)
#f

(symbol-value foo #f) is asking for the symbol-value of the derefed variable 
`foo’

> 
> I expect (symbol-value (string->symbol "list")) will give me the list 
> procedure, but what I get is '#f'
> 
> (symbol-value (string->symbol "list"))
> #f

#;6> (symbol-value (string->symbol (string-append "scheme" "#" "list")))
#

> 
> I expect (unbound? foo) will return True value, but it just throw exception.

#;7> (unbound? ‘foo)
#t

#;9> (unbound? (string->symbol (string-append "scheme" "#" "list")))
#f

> 
> Does CHICKEN scheme provide facilities that make user check whether arbitrary 
> symbol is bound or get its value, just like the `boundp' or `symbol-value' in 
> Common Lisp?
> 
> Thanks
> Pan
> 
> 




Re: Question about how to check a symbol is bound

2023-06-23 Thread Thomas Chust
Hello,

if you are looking for record introspection capabilities, I would recommend
looking into SRFI-99[1], which combines static structure definition and
dynamic reflection APIs. You're example could look like this:

(import
(chicken format)
srfi-42
srfi-99)

(define-record-type egg-info
make-egg-info egg-info?
name author desc)

(define (print-record/fields r)
(define rtd (record-rtd r))
(do-ec (: f (rtd-field-names rtd))
(format #t "~a: ~a~%" f ((rtd-accessor rtd f) r

(print-record/fields
(make-egg-info
"F-operator"
"Kon Lovett"
"Shift/Reset Control Operators"))

Ciao,
Thomas

-- 
[1]: https://srfi.schemers.org/srfi-99/srfi-99.html


Am Fr., 23. Juni 2023 um 10:03 Uhr schrieb Pan Xie :

> #+begin_quote
> Perhaps if you can explain why you need to know if a symbol is bound or
> unbound, we might be able to help you better achieve your goal.
> #+end_quote
>
>
> For example, if I want to do things shown in following codes, it is useful
> to get the
> interned symbols from their names and also get their bound procedures:
>
>   (define-record egg-info
> name author desc)
>
>   (define (show-egg-info egg)
> (define (symbol-value sym)
>   (##sys#slot sym 0))
>
> (define (getter field-name)
>   (symbol-value
>(string->symbol
> (format #f "egg-info-~a"
> field-name
>
> (let ((fields '(name author desc)))
>   (for-each
>(lambda (f)
>  (format #t "~a: ~a~%"
>  f
>  ((getter f) egg)))
>fields)))
>
>   (show-egg-info (make-egg-info
>   "F-operator"
>   "Kon Lovett"
>   "Shift/Reset Control Operators"))
>
> I think it is a very common idiom in languages from Lisp family. So it is
> important to know
> how to check symbol is bound and get its value. Every scheme
> implementation means for
> business seriously should have the ability.
>
> Thanks
> Pan
>
>
> On 6/23/23 15:40, Peter Bex wrote:
> > On Fri, Jun 23, 2023 at 03:32:38PM +0800, Pan wrote:
> >> Ah, that make sense. It seems I can just use the '##sys#slot' procedure
> to
> >> accomplish all that tasks.
> > Please don't use ##sys#slot unless you know what you're doing - the
> > procedure is unsafe and will cause segmentation faults when used on
> > non-block objects.  Anything that starts with ##sys# or ##core# etc
> > is intentionally undocumented because it's not meant for user code.
> >
> >> Would you please elaborate about the "transformed
> >> name"?  I see there are codes reference symbols like "##sys#slot" or
> >> "scheme#list", but I can't find document describe them. Is there any
> >> document I can look into? More specifically, how can I transfer "list"
> to
> >> "scheme#list"? Is there procedure can do that?
> > scheme#list is the fully qualified symbol that means it's the "list"
> > procedure from the "scheme" module.  If you do "(import scheme)" and then
> > just use "list" without prefix, it will get rewritten under the hood.
> >
> > Again, this is an implementation detail and not meant to be used
> > directly.
> >
> > Perhaps if you can explain why you need to know if a symbol is bound or
> > unbound, we might be able to help you better achieve your goal.
> >
> > Cheers,
> > Peter
>
>


Re: Question about how to check a symbol is bound

2023-06-23 Thread Peter Bex
On Fri, Jun 23, 2023 at 04:01:40PM +0800, Pan Xie wrote:
> For example, if I want to do things shown in following codes, it is useful to 
> get the
> interned symbols from their names and also get their bound procedures:

...[code elided]...

> I think it is a very common idiom in languages from Lisp family. So it is 
> important to know
> how to check symbol is bound and get its value. Every scheme implementation 
> means for
> business seriously should have the ability.

That's a bit of a roundabout way of doing things - you're defining a
static record type and then dynamically accessing the fields, which kind
of defeats the point of defining the fields statically.  Your code
*almost* amounts to doing 

 (define (getter f)
   (eval (symbol-append 'egg-info f)))

If the fields are supposed to be dynamic, it'd make more sense to use
a hash table or alist and access the fields that way.

Or, if you insist on using a record type, perhaps a tiny bit of
macrology would help, like so:

 (import (chicken format))

 (define-record egg-info
   name author desc)
 (define (show-egg-info egg)
   (let-syntax ((fields->accessors
 (er-macro-transformer
  (lambda (e r c)
(let ((fields (cdr e))
  (%list (r 'list))
  (%cons (r 'cons)))
  `(,%list ,@(map (lambda (f)
`(,%cons ',f ,(symbol-append 'egg-info- 
f)))
  fields)))
 (for-each (lambda (name)
 (let ((field-name (car name))
   (field-accessor (cdr name)))
  (format #t "~a: ~a~%"
  field-name
  (field-accessor egg
   (fields->accessors name author desc

 (show-egg-info (make-egg-info
 "F-operator"
 "Kon Lovett"
 "Shift/Reset Control Operators"))

This way, you're dynamically generating the code to access the record
type statically and you don't have to do low-level symbol groveling.

In Scheme, identifiers are typically not considered "global" like in
Common Lisp because of the strong module system - they can be imported
under a different name etc.  For instance, I can make a module in which
the "global" variable "list" means something entirely different.

However, CHICKEN does maintain a global symbol table with fully
qualified symbols.  So scheme#list refers to the "global" list procedure
from the "scheme" module.  But again, that's an implementation detail
you don't want to rely on in general.

Cheers,
Peter


signature.asc
Description: PGP signature


Re: Question about how to check a symbol is bound

2023-06-23 Thread Lassi Kortela

  (define-record egg-info
    name author desc)

  (define (show-egg-info egg)
    (define (symbol-value sym)
  (##sys#slot sym 0))
    (define (getter field-name)
  (symbol-value
   (string->symbol
    (format #f "egg-info-~a"
    field-name
    (let ((fields '(name author desc)))
  (for-each
   (lambda (f)
     (format #t "~a: ~a~%"
     f
     ((getter f) egg)))
   fields)))

  (show-egg-info (make-egg-info
  "F-operator"
  "Kon Lovett"
  "Shift/Reset Control Operators"))


What you're looking for is record inspection (aka introspection). That 
has been standardized in R6RS, but Chicken doesn't have it AFAIK.


The right points of comparison in Common Lisp are:

* slot-value
* slot-boundp
* slot-exists-p

Symbol-value is not a good point of comparison, as it has to do with 
packages, not records. Neither Scheme not CL programmers tend to solve 
problems by poking around the symbol table. It's a last resort.


Your best bet in Scheme as it stands, is to use a hash table or 
association list instead of a record type. Or wrap a hash table in a record.


I think it is a very common idiom in languages from Lisp family. So it 
is important to know

how to check symbol is bound and get its value.


It's not idiomatic at all. It's useful mainly for tools that support 
interactive development, e.g. via REPL or Emacs.




Re: Question about how to check a symbol is bound

2023-06-23 Thread Pan Xie

#+begin_quote
Perhaps if you can explain why you need to know if a symbol is bound or
unbound, we might be able to help you better achieve your goal.
#+end_quote


For example, if I want to do things shown in following codes, it is useful to 
get the
interned symbols from their names and also get their bound procedures:

 (define-record egg-info
   name author desc)
 
 (define (show-egg-info egg)

   (define (symbol-value sym)
 (##sys#slot sym 0))
   
   (define (getter field-name)

 (symbol-value
  (string->symbol
   (format #f "egg-info-~a"
   field-name
   
   (let ((fields '(name author desc)))

 (for-each
  (lambda (f)
(format #t "~a: ~a~%"
f
((getter f) egg)))
  fields)))

 (show-egg-info (make-egg-info
 "F-operator"
 "Kon Lovett"
 "Shift/Reset Control Operators"))

I think it is a very common idiom in languages from Lisp family. So it is 
important to know
how to check symbol is bound and get its value. Every scheme implementation 
means for
business seriously should have the ability.

Thanks
Pan


On 6/23/23 15:40, Peter Bex wrote:

On Fri, Jun 23, 2023 at 03:32:38PM +0800, Pan wrote:

Ah, that make sense. It seems I can just use the '##sys#slot' procedure to
accomplish all that tasks.

Please don't use ##sys#slot unless you know what you're doing - the
procedure is unsafe and will cause segmentation faults when used on
non-block objects.  Anything that starts with ##sys# or ##core# etc
is intentionally undocumented because it's not meant for user code.


Would you please elaborate about the "transformed
name"?  I see there are codes reference symbols like "##sys#slot" or
"scheme#list", but I can't find document describe them. Is there any
document I can look into? More specifically, how can I transfer "list" to
"scheme#list"? Is there procedure can do that?

scheme#list is the fully qualified symbol that means it's the "list"
procedure from the "scheme" module.  If you do "(import scheme)" and then
just use "list" without prefix, it will get rewritten under the hood.

Again, this is an implementation detail and not meant to be used
directly.

Perhaps if you can explain why you need to know if a symbol is bound or
unbound, we might be able to help you better achieve your goal.

Cheers,
Peter




Re: Question about how to check a symbol is bound

2023-06-23 Thread Peter Bex
On Fri, Jun 23, 2023 at 03:32:38PM +0800, Pan wrote:
> Ah, that make sense. It seems I can just use the '##sys#slot' procedure to
> accomplish all that tasks.

Please don't use ##sys#slot unless you know what you're doing - the
procedure is unsafe and will cause segmentation faults when used on
non-block objects.  Anything that starts with ##sys# or ##core# etc
is intentionally undocumented because it's not meant for user code.

> Would you please elaborate about the "transformed
> name"?  I see there are codes reference symbols like "##sys#slot" or
> "scheme#list", but I can't find document describe them. Is there any
> document I can look into? More specifically, how can I transfer "list" to
> "scheme#list"? Is there procedure can do that?

scheme#list is the fully qualified symbol that means it's the "list"
procedure from the "scheme" module.  If you do "(import scheme)" and then
just use "list" without prefix, it will get rewritten under the hood.

Again, this is an implementation detail and not meant to be used
directly.

Perhaps if you can explain why you need to know if a symbol is bound or
unbound, we might be able to help you better achieve your goal.

Cheers,
Peter


signature.asc
Description: PGP signature


Re: Question about how to check a symbol is bound

2023-06-23 Thread Pan
Ah, that make sense. It seems I can just use the '##sys#slot' procedure 
to accomplish all that tasks. Would you please elaborate about the 
"transformed name"?  I see there are codes reference symbols like 
"##sys#slot" or "scheme#list", but I can't find document describe them. 
Is there any document I can look into? More specifically, how can I 
transfer "list" to "scheme#list"? Is there procedure can do that?


On 6/23/23 13:28, Shawn Wagner wrote:
Looks like unbound? and symbol-value take quoted symbols if passing them 
directly: And for list you have to use the transformed name scheme#list


#;2> (unbound? 'x)
#t
#;3> (define x 1)
#;4> (unbound? 'x)
#f
#;5> (symbol-value 'x)
1
#;6> (symbol-value 'scheme#list)
#

On Thu, Jun 22, 2023 at 10:15 PM Pan Xie > wrote:


Hello

I am new to CHICKEN scheme and here is a (very) quick question of
how to
check whether a symbol is bound.

I know it doable but I can't find the way.

I don't find the methods from the main CHICKEN manual document. Then I
import the "symbol-value-utils" module. I believe the "unbound?" or
"symbol-value" will do what I want, but to my surprise they does NOT:

I expect `symbol-value' will give me value of a symbol, but it will
throw exception for an
undefined symbol, even I provide the default value:

(symbol-value foo #f)
Error: unbound variable: foo

I expect (symbol-value (string->symbol "list")) will give me the list
procedure, but what I get is '#f'

(symbol-value (string->symbol "list"))
#f

I expect (unbound? foo) will return True value, but it just throw
exception.

Does CHICKEN scheme provide facilities that make user check whether
arbitrary symbol is bound or get its value, just like the `boundp' or
`symbol-value' in Common Lisp?

Thanks
Pan