Page 1 of 1

How to determine if function is defined

PostPosted: Thu Feb 05, 2015 10:28 pm
by neil456
What is the correct way to determine that a function is defined. I am conditionally importing from a C lib and need to determine if the function was actually imported.

This is the import function.
Code: Select all
(define (pg_import_warn fun_name)
  (if (not (catch (import library fun_name "cdecl") 'pg_load_error))
    (println "pg_import WARNING: " pg_load_error)))

Import is done like this
Code: Select all
(pg_import_warn "PQescapeIdentifier")

Then sometime later i want to be able to do something like
Code: Select all
(if (function? PQescapeIdentifier)  (PQescapeIdentifier text) (SomeOtherFuncton text))

to use the function or not as the case may be.

Re: How to determine if function is defined

PostPosted: Thu Feb 05, 2015 11:27 pm
by Lutz
Just use the primitive? predicate, which works on built-in and imported functions:

Code: Select all
> (import "libc.dylib" "printf")
printf@7FFF8BF44910
> (primitive? printf)
true
>


or after loading postgres.lsp

Code: Select all
> (primitive? PgSQL:PQconnectdb)
true
>


for user-defined functions you would use lambda?

Code: Select all
> (define (double x) (+ x x))
(lambda (x) (+ x x))
> (lambda? double)
true

Re: How to determine if function is defined

PostPosted: Thu Feb 05, 2015 11:37 pm
by neil456
Excellent, thanks
Neil

Re: How to determine if function is defined

PostPosted: Sun Feb 08, 2015 8:09 pm
by neil456
Still having a problem with this. Consider the following example:

Code: Select all
(dolist (symb (symbols PgSQL))
   (if (lambda? symb)
      (println "found function: " symb)))


This does not work, so how do I get a list of symbols in a context that have lambda expressions assigned to them?

Re: How to determine if function is defined

PostPosted: Sun Feb 08, 2015 8:43 pm
by Lutz
The lambda? predicate is applied not to the symbol, but what is inside:

Code: Select all
(dolist (symb (symbols PgSQL))
 (if (lambda? (eval symb))
    (println "found function: " symb)))

found function: PgSQL:NULL?
found function: PgSQL:affected-rows
found function: PgSQL:clear-result
...

or shorter:
Code: Select all
> (filter (fn (s) (lambda? (eval s))) (symbols PgSQL))

(PgSQL:NULL? PgSQL:affected-rows PgSQL:clear-result PgSQL:close-db PgSQL:connect
 PgSQL:connectdb PgSQL:data-seek PgSQL:databases PgSQL:error PgSQL:escape PgSQL:fetch-all
 PgSQL:fetch-row PgSQL:fetch-value PgSQL:fields PgSQL:fnumber PgSQL:num-fields PgSQL:num-rows
 PgSQL:query PgSQL:tables)
>