Safe pattern matching

2013-02-09 Thread Nikita Karetnikov
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

2013-02-09 Thread Daniel Hartwig
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

2013-02-09 Thread Daniel Hartwig
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

2013-02-09 Thread Ian Price
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

2013-02-09 Thread Ian Price

> 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

2013-02-09 Thread Richard Shann
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

2013-02-09 Thread Mark H Weaver
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

2013-02-09 Thread Mark H Weaver
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

2013-02-09 Thread Neal H. Walfield
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

2013-02-09 Thread Richard Shann
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

2013-02-09 Thread Richard Shann
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

2013-02-09 Thread Mark H Weaver
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