I've been playing with writing a Zork-style engine, to scrape the rust off my C and possibly learn LISP. The basic structure is to define a bunch of locations, objects, and commands. The commands are a mapping between a word (read in from the commandline) and a funcp. So far, so good. Except, the function signature I'm using is getting more and more complex, to account for all the possible cases. Yet, each function is only using 2 or 3 of the currently 7 parameters being passed in. And, it's limiting me in terms of providing location-specific functions.

I started thinking about how I'd go about implementing this in Perl.

$locations{road}{actions}{north} = sub { $_[LOCATION] = $locations{woods}; }; $locations{road}{actions}{woods} = $locations{road}{actions}{north};

It's the lack of anonymous functions in C that's pissing me off. Whoever implemented them in Perl ... THANK YOU!

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

I shouldn't have to say this, but any code, unless otherwise stated, is untested

Replies are listed 'Best First'.
Re: I love anonymous functions!
by BrowserUk (Patriarch) on Jun 29, 2004 at 18:06 UTC

    Why not write a perl script to generate all the little C functions and the associated dispatch table initilisation?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: I love anonymous functions!
by stvn (Monsignor) on Jun 29, 2004 at 16:32 UTC

    I agree with you 100%, I love anonymous functions too. I first used them in Javascript actually. After that I fiddled with them in python, then I played with a number of functional langauges which all had similar concepts, and lastly I found perl and it was love at first type.

    As for your Zork engine, C has function pointers, but I know they are not the same thing. But LISP can do anonymous functions for sure.

    #'(lambda (args) (body))

    -stvn
      C's function pointers are not the same thing, but you can create a struct of a function pointer and a data pointer, and then you can create a function that calls that function with two arguments, the data in the struct and an additional pointer passed in.

      This construct can then be treated similarly to how you'd use an anonymous function in Perl. You'll have to do the equivalent of closures by stuffing information into the data pointer and then binding it inside the function.

      Alternately you can use Inline::Perl in CPR mode and then escape to actual Perl functions written in Perl wherever you want...

Re: I love anonymous functions!
by mpeppler (Vicar) on Jun 29, 2004 at 17:42 UTC
    I'd go with Fletch's solution of using a struct with a type field and a union with the various parameter options. Then pass this as a pointer/array. Maybe something like:
    struct data { int type; union { int i; char *c; } value; }; int the_function(int argc, struct data *argv) { .... }
    which gives you a single signature for all of your calls.

    Not exactly clean, but workable...

    Michael

Re: I love anonymous functions!
by Hanamaki (Chaplain) on Jun 29, 2004 at 16:39 UTC
    Did you have a look at function pointers and vectored execution in C? ... Its not the same, but probably a way which gives a similiar feeling and if well done some major speed gain compared to "if" statements etc.
      I am using funcp's, as I said in the original post. The issue is that I want to define those funcp's at runtime. Otherwise, I'm stuck with a kitchen-sink of small functions that have different signatures, which means I'm stuck with one of a few undesirable options:
      1. I create a catchall signature, which is ugly, but manageable
      2. I use void* pointers in my data structure, forcing me to cast all my funcp's. (Would this even work??)
      3. I don't use the same data structure, instead using void* and casting the templated nodes in my array. (Would this even work??)
      4. Use a signature that has varargs in it. But, that's ugly and bypasses a lot of the benefits of using a stronglystatically-typed language. (Would this even work??)

      Nope. Give me funcp's every time.

      Update:Fixed error as per hardburn's reply.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

        . . . bypasses a lot of the benefits of using a strongly-typed language

        C is not a strongly-typed langauge. Its type system is only useful for hints to the compiler. There are too many ways to subvert it to be anything more. Further, its type errors are just as likely to be annoyances as they are real problems. Rather, C is statically typed, i.e. its types are determined at compile time. Static != strong.

        Perl is more strongly typed than C is. Perl's scalars and lists are very seperate types, and are not so trivial to convert into each other. In fact, it doesn't make sense for there to be a generalized solution for doing list -> scalar.

        Try OcaML. There's a real type system.

        ----
        send money to your kernel via the boot loader.. This and more wisdom available from Markov Hardburn.

        This is where you mix OO and functional constructs. It's staring you in the face. Do it.
Re: I love anonymous functions!
by BUU (Prior) on Jun 29, 2004 at 16:59 UTC
    To address you rC concerns (assuming I understand them correctly), your best bet would probably be to defined a struct containing all of your possible paramters:
    struct Args { int stuff; int stuff2; };
    Then you can just pass this one struct to all of your functions, and they can all have the same function signature/prototype.

      Actually it might be better to make a struct with a type field and a union member that contained all the possible arguments rather than having a potentially huge struct. Then again if you're going to do that just pass the type and a void* and cast appropriately.

Re: I love anonymous functions!
by grey (Novice) on Jul 02, 2004 at 09:29 UTC

    > It's the lack of anonymous functions in C that's pissing me off

    That can be implemented in C++ though, by pushing the language to its limits. Like in the The Boost Lambda Library.

    grey.