A lisp oriented question - interning symbols for use in Maxima



On Oct 18, 2009, at 10:13 PM, Dieter Kaiser wrote:

> Am Sonntag, den 18.10.2009, 19:12 +0200 schrieb ?iga Lenar?i?:
>> Hi!
>>
>> I'm writing a Maxima interface to CFFI (for using C libraries from
>> Maxima).
>>
>> I have the following problem - I want to convert a lisp string into a
>> symbol representing a Maxima function which would be invoked by the
>> same 'string' from Maxima console.
>>
>> Right now I use
>>
>> (intern (concatenate 'string "$" string))
>>
>> to get the symbol which should represent the maxima function.
>>
>> I get the correct results for cases such as "HelloWorld" -> |
>> $HelloWorld| (then the function can be called from maxima with
>> 'HelloWorld()').
>>
>> However if I try non-mixed case strings I get an inverted result. So
>> a string like "mul2" gives me a symbol |$MUL2|, which from Maxima is
>> seen as 'MUL2' and not 'mul2' as I would want it to be.
>>
>> What should I do to get the correct lisp symbol, so calling from
>> Maxima will look like the string I use?
>>
>> Are there already any functions in Maxima I should use or how should
>> I roll my own?
>>
>>
>> On a side note, is there any interest for a foreign library interface
>> in Maxima? Of course it works only in CFFI supported lisps, so no GCL
>> support, sorry. I quickly compared the calling overhead by importing
>> the C function 'rand()' from 'libc' and compared it to Maxima's
>> function 'random' - calling C function from Maxima was faster, so I
>> guess the overhead is quite small (on SBCL at least).
>
> The functions which handle Maxima's convention of inverting strings  
> are:
>
>   maybe-invert-string-case
>   intern-invert-case
>   print-invert-case
>
> maybe-invert-string-case accepts a string and returns a string,  
> which is
> inverted, if all characters are upper case or lower case.
>
> Examples:
>
>  (maybe-invert-string-case "example") --> "EXAMPLE"
>  (maybe-invert-string-case "EXAMPLE") --> "example"
>  (maybe-invert-string-case "Example") --> "Example"
>
> intern-invert-case accepts strings too, but interns the converted  
> string
> in the package :maxima. This function is equivalent to
>   (intern (maybe-invert-string-case str))
>
> Examples:
>
>   (intern-invert-case "text") --> TEXT :INTERNAL
>   (intern-invert-case "TEXT") --> |text| NIL
>   (intern-invert-case "Text") --> |Text| NIL
>
> print-invert-case accepts symbols as input and returns an inverted
> string. The routines accepts strings and any other printable values  
> too,
> but returns strings unchanged.
>
> Examples:
>
>   (print-invert-case 'text)  --> "text"
>   (print-invert-case '|text| --> "TEXT"
>
>   (print-invert-case "TEXT"  --> "TEXT"
>   (print-invert-case 10.0)   --> "10.0"
>
> Dieter Kaiser
>

Thanks for the exhaustive explanation, (intern-invert-case  
(concatenate 'string "$" str)) does the trick!

On a side note, perhaps an interesting experiment with GSL:

(%i85) load_library("libgsl");
(%o85) #<FOREIGN-LIBRARY {13C85C69}>

(%i86) import_c_function(double, "gsl_sf_bessel_J0", double);
(%o86) gsl_sf_bessel_J0

(%i87) gsl_sf_bessel_J0(1.0);
(%o87) .7651976865579666

(%i88) bessel_j(0,1.0);
(%o88) .7651976865579666

(%i89) showtime:true;
Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.
(%o89) true

(%i90) makelist(gsl_sf_bessel_J0(1.0),i,1,10000)$
Evaluation took 0.1230 seconds (0.1250 elapsed) using 3.051 MB.

(%i91) makelist(bessel_j(0,1.0),i,1,10000)$
Evaluation took 0.1670 seconds (0.1680 elapsed) using 5.875 MB.


Regards,
Ziga