Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #142711

Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness
Date 2019-04-01 23:55 +0100
Organization A noiseless patient Spider
Message-ID <87ef6l72u5.fsf@bsb.me.uk> (permalink)
References <vriumul9to0v.fsf@gmail.com>

Show all headers | View raw


This is interesting, and I admire your bravery in wading into these
shark-infested waters dressed only in C, so I hope you won't find these
remarks overly negative.

First, I don't see any closures because I don't see any environments.  I
don't think that's a problem -- you may not need them -- but it affects
the description and that affects the readers expectations.

Secondly, a monad is very general.  I see bind and return functions but
they seem to be tied to parsers.  Am I to read bind and return as a
specific instance of a monad?

Some comments on the code...

M Joshua Ryan <luser.droog@gmail.com> writes:
> Norah is my computer's name.
>
>
> #include <ctype.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> typedef union object *object;

I'm not a fan of hiding a pointer like this.  It tripped me up for a
while.  For the price of a space and a * you lose the ability to remind
the reader that it's pointers all the way down.  However, I'm used to
this construct, so I got over my initial stumble pretty quickly.  It's a
small point.

> typedef enum { INT, LIST, SUSP, PARSER, OPER } tag;
> union object { tag t;
>       struct { tag t; int i; } Int;
>       struct { tag t; object a, b; } List;
>       struct { tag t; void *v; object (*f)( void * ); } Susp;
>       struct { tag t; void *v; object (*f)( void *, object ); } Parser;
>       struct { tag t; void *v; object (*f)( void *, object ); } Oper;
> };

I would be tempted to make all of these last three take the same
function pointer type (giving the suspension a dummy object), and to
typedef that function (but not the pointer type!) so as to tidy all this
up a bit.

<cut constructors>

> object at( object a ){ return  a && a->t == SUSP  ? at( a->Susp.f( a->Susp.v ) ) : a; }
> object x( object a ){  return  a && a->t == LIST  ? a->List.a : NULL; }

Why is there no at( a->List.a ) here?  Do you know there is never a
suspension here?  Is that a safe assumption in general?  (I really don't
know -- just asking.)

> object xs( object a ){ return  a && a->t == LIST  ? a->List.b = at( a->List.b ) : NULL; }

You are cleverly doing a sort of pauper's graph reduction with that
assignment.  It's a neat idea (in a sneaky sort of way), but I am used
to the suspension being evaluated when a value is actually used.  I hope
you don't find this is ever one step too soon.  If you did delay until
actual last-minute use, you would not be able to replace the list node,
so I see why you are doing it like this.

> object parse( object p, object input ){
>   return  p->t == PARSER  ? p->Parser.f( p->Parser.v, input ) : NULL;
> }

I am out of time but for one last remark, and I can make it here though
it applies to other functions too.  You might find it more helpful, down
the line, to replace the

  return check_type ? something : NULL;

pattern with

  retutn check_type_or_fail(), something;

In code like this, NULL is a perfectly fine value (it's like Lisp's nil)
and, with all the checks for it, your code will usually just elegantly,
and silently, stop processing when it pops up.  That's been my
experience at least...

<cut more code I don't have time for>
-- 
Ben.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

[PC] Simulating Monads, Lambdas, Closures, and Laziness M Joshua Ryan <luser.droog@gmail.com> - 2019-04-01 16:26 -0500
  Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Chad <cdalten@gmail.com> - 2019-04-01 14:42 -0700
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-01 14:57 -0700
  Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-01 23:55 +0100
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-02 00:31 -0700
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness David Brown <david.brown@hesbynett.no> - 2019-04-02 10:25 +0200
        Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Manfred <noname@add.invalid> - 2019-04-02 14:11 +0200
          Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness David Brown <david.brown@hesbynett.no> - 2019-04-02 15:51 +0200
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-02 12:10 +0100
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-02 12:07 -0700
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-04-03 07:59 -0700
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-03 16:29 +0100
        Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-04-07 00:11 -0700
          Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-12 23:20 -0700
            Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Chad <cdalten@gmail.com> - 2019-04-13 04:42 -0700

csiph-web