Safe pattern matching
Any Haskellers here? How would you rewrite the following function in Guile? foo :: [Int] -> String -> [Int] foo (x:y:ys) "+" = (x + y):ys foo (x:y:ys) "-" = (x - y):ys foo xs num = read num:xs *Main> foo [] "42" [42] *Main> foo [1,2] "42" [42,1,2] *Main> foo [1,2] "+" [3] *Main> foo [1..10] "42" [42,1,2,3,4,5,6,7,8,9,10] *Main> foo [1..10] "+" [3,3,4,5,6,7,8,9,10] It will fail if you call it like this: *Main> foo [] "+" [*** Exception: Prelude.read: no parse But let's assume that it's OK. I guess that 'match' is the answer, but I don't understand how to use it. pgpbTGjPhPOm8.pgp Description: PGP signature
Re: Safe pattern matching
On 9 February 2013 17:57, Nikita Karetnikov wrote: > Any Haskellers here? > > How would you rewrite the following function in Guile? > > foo :: [Int] -> String -> [Int] > foo (x:y:ys) "+" = (x + y):ys > foo (x:y:ys) "-" = (x - y):ys > foo xs num = read num:xs Indeed, match can do this. The style is very similar. Using symbols and literals, rather than strings: > (use-modules (ice-9 match)) > (define (foo . args) (match args (((x y . ys) '+) (cons (+ x y) ys)) (((x y . ys) '-) (cons (- x y) ys)) ((xs num) (cons num xs > (foo '() 42) $1 = (42) > (foo '(1 2) 42) $2 = (42 1 2) > (foo '(1 2) '+) $3 = (3) > (use-modules (srfi srfi-1)) > (foo (iota 10 1) 42) $4 = (42 1 2 3 4 5 6 7 8 9 10) > (foo (iota 10 1) '+) $5 = (3 3 4 5 6 7 8 9 10)
Re: Safe pattern matching
On 9 February 2013 18:12, Daniel Hartwig wrote: > Using symbols and literals, rather than strings: Though strings work just as well as symbols :-)
Re: Safe pattern matching
Nikita Karetnikov writes: > How would you rewrite the following function in Guile? > > foo :: [Int] -> String -> [Int] > foo (x:y:ys) "+" = (x + y):ys > foo (x:y:ys) "-" = (x - y):ys > foo xs num = read num:xs Daniel covered most of this already, but instead you might consider (define foo (match-lambda* )) rather than (define (foo . args) (match args )) the nearest analogue to read is object->string, but it is not a generic. -- Ian Price -- shift-reset.com "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled"
Re: Safe pattern matching
> the nearest analogue to read is object->string, but it is not a generic. That should be string->object. It's funny how often I mix up a->b and b->a -- Ian Price -- shift-reset.com "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled"
Re: statically linking in srfi modules
Well it seems I may have been premature in saying that srfi-1 was successfully loaded. Although the error message is gone, there is no symbol 'map which srfi-1 should have re-defined. Can someone suggest what this might be a symptom of? Denemo has a command line interpreter for guile, so I can feed it any scheme expression and have it evaluated to debug the problem... Richard On Fri, 2013-02-08 at 17:11 -0500, Mark H Weaver wrote: > I wrote: > > > Richard Shann writes: > > > >> > > > > The problem is the call to 'load-extension' near the top of > > 'srfi-1.scm', which again tries to load that shared library. > > You'll have to remove that call from 'srfi-1.scm'. > > > > You should probably do the same thing for libguile-srfi-srfi-13-14-v-3, > > so that Denemo users who wish to use the string or character set > > libraries can do so. > > Sorry, I was mistaken. It turns out that srfi-13-14 was moved into the > core a while ago, and that shared library is just an empty dummy > library. The same is true of srfi-4. > > However, there's also a shared library for srfi-60, which should be > statically linked as well. Just as for srfi-1, the call to > 'load-extension' should be removed from srfi-60.scm, and you should add > the following to your C initialization code: > > scm_c_register_extension ("libguile-srfi-srfi-60-v-2", "scm_init_srfi_60", > scm_init_srfi_60, NULL); > > Regards, > Mark
Re: statically linking in srfi modules
Richard Shann writes: > Well it seems I may have been premature in saying that srfi-1 was > successfully loaded. Although the error message is gone, there is no > symbol 'map which srfi-1 should have re-defined. > Can someone suggest what this might be a symptom of? I know what's wrong. Please try replacing the calls to 'scm_c_register_extension' with the following: scm_c_define_module ("srfi srfi-1", init_srfi_1, NULL); scm_c_define_module ("srfi srfi-60", init_srfi_60, NULL); Where 'init_srfi_1' and 'init_srfi_60' are defined as follows: static void init_srfi_1 (void *dummy) { scm_init_srfi_1 (); } static void init_srfi_60 (void *dummy) { scm_init_srfi_60 (); } Mark
Re: statically linking in srfi modules
Richard Shann writes: > Well it seems I may have been premature in saying that srfi-1 was > successfully loaded. Although the error message is gone, there is no > symbol 'map which srfi-1 should have re-defined. > Can someone suggest what this might be a symptom of? I wrote: > I know what's wrong. Please try replacing the calls to > 'scm_c_register_extension' with the following: > > scm_c_define_module ("srfi srfi-1", init_srfi_1, NULL); > scm_c_define_module ("srfi srfi-60", init_srfi_60, NULL); [...] Sorry, this isn't quite right either. Instead of the above, please try replacing the calls to 'scm_c_register_extension' with the following: scm_c_call_with_current_module (scm_c_resolve_module ("srfi srfi-1"), init_srfi_1, NULL); scm_c_call_with_current_module (scm_c_resolve_module ("srfi srfi-60"), init_srfi_60, NULL); Where 'init_srfi_1' and 'init_srfi_60' are defined as follows: static SCM init_srfi_1 (void *dummy) { scm_init_srfi_1 (); return SCM_UNSPECIFIED; } static SCM init_srfi_60 (void *dummy) { scm_init_srfi_60 (); return SCM_UNSPECIFIED; } Hopefully this will work. I'm too lazy to try it myself. Mark
Re: Guile not running properly on GNU/Hurd
At Sat, 2 Feb 2013 23:24:38 +0100, Richard Braun wrote: > On Sat, Feb 02, 2013 at 07:51:38PM +0100, Gabriel Schnoering wrote: > > I can't run guile in gdb as there are some error with the garbage > > collector. > > These are probably not errors. Many language interpretors rely on > receiving SIGSEGV to implement memory. Use the gdb "handle" command to > make it automatically pass on SIGSEGV signals so that you only catch the > SIGILL you're interested in. It might be an interesting project to use Mach Memory Objects to back garbage collected memory rather than rely on the SIGSEGV machinery. This would be more efficient and perhaps more accurate. You'd still have to deal with the stack separately. Neal
Re: statically linking in srfi modules
On Sat, 2013-02-09 at 10:32 -0500, Mark H Weaver wrote: > Richard Shann writes: > > Well it seems I may have been premature in saying that srfi-1 was > > successfully loaded. Although the error message is gone, there is no > > symbol 'map which srfi-1 should have re-defined. > > Can someone suggest what this might be a symptom of? > > I wrote: > > I know what's wrong. Please try replacing the calls to > > 'scm_c_register_extension' with the following: > > > > scm_c_define_module ("srfi srfi-1", init_srfi_1, NULL); > > scm_c_define_module ("srfi srfi-60", init_srfi_60, NULL); > [...] This worked in that map was defined, but then make-regexp was undefined - we (use-modules (ice-9 regex)) in our opening preamble, which I guess may re-define that, but grepping through the ice-9 directory I didn't see any sign of the load-extension call that happens in srfi-1 and 60. > > Sorry, this isn't quite right either. Instead of the above, please try > replacing the calls to 'scm_c_register_extension' with the following: > > scm_c_call_with_current_module (scm_c_resolve_module ("srfi srfi-1"), > init_srfi_1, NULL); > scm_c_call_with_current_module (scm_c_resolve_module ("srfi srfi-60"), > init_srfi_60, NULL); > > Where 'init_srfi_1' and 'init_srfi_60' are defined as follows: > > static SCM > init_srfi_1 (void *dummy) > { > scm_init_srfi_1 (); > return SCM_UNSPECIFIED; > } > > static SCM > init_srfi_60 (void *dummy) > { > scm_init_srfi_60 (); > return SCM_UNSPECIFIED; > } > This seemed to have a dramatic effect! The program exits at startup with the message ERROR: Unbound variable: map and return status 1 Until now I felt we were converging on something :) One thing that puzzles me is that other srfi numbers have static libraries generated for them, but on 1 and 60 would seem to be needed? Thanks for the support... Richard
Re: statically linking in srfi modules
More on that call to scm_c_call_with_current_module (scm_c_resolve_module ("srfi srfi-1"), init_srfi_1, NULL); I have had a look using gdb and it is exiting during the call to scm_c_resolve_module() HTH Richard
Re: statically linking in srfi modules
Hi Richard, Don't worry, we'll get it working. Here's another attempt. Replace the calls to 'scm_c_register_extension' with the following: scm_c_call_with_current_module (scm_c_resolve_module ("guile"), bind_srfi_initializers, NULL); With the following additional definitions: static SCM init_srfi_1 (void) { scm_init_srfi_1 (); return SCM_UNSPECIFIED; } static SCM init_srfi_60 (void) { scm_init_srfi_60 (); return SCM_UNSPECIFIED; } static SCM bind_srfi_initializers (void *dummy) { scm_c_define_gsubr ("%init-srfi-1", 0, 0, 0, init_srfi_1); scm_c_define_gsubr ("%init-srfi-60", 0, 0, 0, init_srfi_60); return SCM_UNSPECIFIED; } Then, starting with the original versions of srfi-1.scm and srfi-60.scm from Guile 1.8, replace the (load-extension ...) calls in those two files with (%init-srfi-1) and (%init-srfi-60), respectively. *crosses fingers* Mark