This is the mail archive of the guile@cygnus.com mailing list for the guile project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
I've been using guile-ii for some time now and I am finally looking at making the transition to 1.2. I've been lurking in this group for some time now simply because most of the issues never pertained to me... now they do :-) I have a number of issues and questions regarding my transition: 1) when an error occured during a "load" guile-ii would give the line number at which the error was detected. For example with the following file: > (let ((x 3)) > (foopy) > ) guile-ii gave: > guile> (load "/tmp/y.scm") > "/tmp/y.scm", line 3: ERROR: unbound variable: foopy > ; in expression: (... foopy) > ; in scope: > ; x Guile 1.2 does this: > guile> (load "/tmp/y.scm")y.scm") > ERROR: Unbound variable: foopy > ABORT: (misc-error) 2) To do a sort, I used something like: > (require 'sort) > (sort! '("hello" "there" "testing" "one") string<?) This no longer works and I cannot find *any* sort function in the guile-1.2 distribution. Is there some other place I should be going for "extras" like this? 3) I am using guile as an embedded language for a C++ program that has its own notion of "commands". I have a central dispatch routine for all entry from scheme into my commands. The previous engineer had done a *lot* of tweaking of guile-ii to make this work. My take on this, for each internal command, create a closure in which I reference the one dispatch routine and pass as data the pointer to the C++ command object. Here's my code: > #define DISPATCH_CCLO_CMD(cclo) (SCM_VELTS(cclo)[1]) > > static SCM > dispatch(SCM args) > { > SCM cclo = SCM_CAR(args); > args = SCM_CDR(args); > > Cmd *cmd = (Cmd *)(SCM_INUM(DISPATCH_CCLO_CMD(cclo)) << 2); > > // convert args into internal format > > cmd->exec(...) > } > > // can this be local to RegisterCommand and not mess up GC? > static SCM dispatch_proc = SCM_UNDEFINED; > > void RegisterCommand( Cmd *cmd ) > { > if (dispatch_proc == SCM_UNDEFINED) { > // This seems to have the desired effect of creating the > // "$my-dispatch" procedure object without making the name > // visible to the user so he/she cannot directly access > // this internal procedure. > > dispatch_proc = scm_make_subr_opt( "$my-dispatch", scm_tc7_lsubr, > (SCM (*)())dispatch, 0 ); > > } > > SCM cclo = scm_makcclo( dispatch_proc, 2 ); > > // stuff my command pointer into an integer so that guile garbage > // collection doesn't try to do anything with it. takes advantage > // of fact that Cmd's will always be aligned on word boundary or > // bigger (need to shift right 2 since MAKINUM shifts left 2) > DISPATCH_CCLO_CMD(cclo) = SCM_MAKINUM(((long)cmd) >> 2); > > // register the closure with global symbol table > // ugh, const cast > scm_sysintern( (char *)cmd->getName(), cclo ); > } So, my questions are... a) Does anybody see any problems that might come up with this particularly with garbage collection? In the past, we had some really nasty problems debugging problems with garbage collection so I'm a little gun shy. b) I'd like to ensure that users cannot directly run ($my-dispatch) since it is an internal routine and will likely cause nastiness if directly invoked. The code above seems to do the trick (by using "scm_make_subr_opt") but I felt a little nervous about using this routine not really knowing its real purpose. c) Is there a "better" way to save the pointer to the Cmd object. I don't really like doing casts of pointers to ints and back (it seems sort of a hack). I simply want to save the pointer but *not* have the garbage collector mess with it. I tried just storing the pointer directly in the SCM, but, of course, that caused problems. d) Every once in a while I run into problems with "const-correctness" of the library. Routines that conceptually should use "const char *" declared as "char *" ("scm_sysintern", above, is an example). Is there any fundamental reason going through the library and making these const won't work? 4) I have some C++ code which writes to a scheme port. I used to use "gscm_fwrite" which would return the number of chars written. The only public routine I can find to do the same thing is "scm_gen_write" which does not return the char count. Is there some other routine I should use? 5) When in interactive mode, "(let ((x 3)) (write foopy))" gives: > ERROR: While evaluating arguments to write in expression (write foopy): > ERROR: Unbound variable: foopy > ABORT: (misc-error) in non-interactive mode I just get: > guile: Unbound variable: foopy Obviously the interactive version of the message is much more useful. Is there a way to get the whole message regardless of mode? 6) How do I expand a procedure? In guile-ii I could just type the procedure name and it would give a (somewhat) readable representation of the procedure. In guile-1.2, I just get "#<procedure blah args>". 7) As an example, the procedure "debug-enable" doesn't actually show up in the main symbol table. However, it is defined. Is this an example of the new module system? Can someone point me to some docs on how the module system works? --- A bunch of other things I've noted. Most of these you all probably know but I'll state them in case I'm doing something wrong. 1) "#f" used to mean empty list (in addition to "()"). As such: a. (cons 1 #f) used to return a proper list; now it returns a dotted pair. The fix is to use "()" instead. b. (null? #f) used to return #t; now it returns #f. In some cases (badly written) code was using "null?" instead of "not". The fix is to use "not" 2) "defined?" used to be a macro so that (defined? goober) was legit. Now, one must use (defined? 'goober) 3) "print" routine is gone... have to use (write obj) and (newline) instead Well, that's all for now... I have some other comments about things like "readline" support and giving a prompt which shows how deeply indented one is (two things we did in our guile-ii support), but I'll send that under separate cover. Thanks, Rob -- ------------------------------------------------------------------------ Rob Engle grenoble@spimageworks.com Sony Pictures Imageworks voice: 310-840-8203 9050 West Washington Boulevard fax: 310-840-8567 Culver City, CA 90232 ------------------------------------------------------------------------