Live data from Hacker News

Lisp in fewer than 200 lines of C

carld.github.io

11–20 of 108 posts

Re: Lisp in fewer than 200 lines of C

#11
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

Dude, if you used Rust, you wouldn’t have that problem.

Re: Lisp in fewer than 200 lines of C

#12
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

"but this is an irresponsible way to write software"

Segfault is a totally safe way to terminate a process on a modern desktop os. Besides - there is no 'correct' way to write software.

Re: Lisp in fewer than 200 lines of C

#14
post #4

Earlier quoted context omitted.

If people always wrote software responsibly we'd have a great deal fewer interesting projects on GitHub

Would it really be so hard to do this exact same thing in a memory safe language? Would that stifle the author's creativity in any way?

People often do what they love with the tools they love. Complaining that someone wrote a hobby project with C is akin to complaining that your neighbor made a decorative baseball bat with her lathe instead of a 3D printer.

Re: Lisp in fewer than 200 lines of C

#16
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

The author isn't responsible if people read it and think it's how they should be writing C, especially when the objective of writing lisp in as little C as possible is communicated.

So why is it fair to label it irresponsible?

Re: Lisp in fewer than 200 lines of C

#18
post #12
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

"but this is an irresponsible way to write software" Segfault is a totally safe way to terminate a process on a modern desktop os. Besides - there is no 'correct' way to write software.

Sorry, this is wrong. A segfault means you got lucky and your bad memory access hit an unmapped or otherwise invalid page. Other times the program will keep running with incorrect results. Many such issues represent exploitable bugs.

In any case it's a bad issue and should not be a normal failure mode for a syntax error.

Re: Lisp in fewer than 200 lines of C

#19
post #16
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

The author isn't responsible if people read it and think it's how they should be writing C, especially when the objective of writing lisp in as little C as possible is communicated. So why is it fair to label it irresponsible?

it's not irresponsible, but copy/paste proliferation does exist, and happens surprisingly often with code posted online like this. When you write code for posting online, you'd want to consider this problem.

Re: Lisp in fewer than 200 lines of C

#20
post #3

No calls to free() to match calloc(), no overflow checking in gettoken() and then I read this: > a program with missing or unmatched parenthesis, unresolved symbols, etc will likely just result in something like a segmentation fault. I understand this is just a fun thing to hack on, but this is an irresponsible way to write software. I hope no one here is reading this and thinking it's how they should be writing C.

It's a lot longer if it's done properly. You should use an array of dotted pairs to store your list elements, out of which you build a free list, from which you allocate by calling cons. To garbage collect, you mark all objects in use (on the stack, or accessible from the symbol table) and then you add the unmarked conses to the free list. You should not be using malloc or calloc at all, certainly not to implement cons.

Below is some of the relevant code in C/C++ from the virtual machine of Emblem (the Lisp dialect I'm using to implement inter alia my visual dataflow language, Full Metal Jacket). To keep things short I haven't included initialization or the garbage collector. cons_op takes the top two stack entries (one on the stack, the other in tos), conses them, and returns it in tos.

-------------------

    typedef struct ListStruct {
        void *head;
        void *tail;
    } *List;

    static struct ListStruct consTable[NUM_CONSES];

    static List freeStore;

    #define hd(X) (((List)(X))->head)
    #define tl(X) (((List)(X))->tail)
    #define NIL (void *)&consTable[0]
    #define null(X) ((X) == NIL)

    static void **stack;
    static void *tos; /* Top of stack register. */
    static long sp;

    static void cons_op()
    {
        List x;

        if (null(freeStore)) { cons_gc(); }
        x = freeStore;
        freeStore = (List)tl(freeStore);
        hd(x) = stack[sp++];
        tl(x) = tos;
        tos = x;
    }
----------------------

Alternatively, instead of C you could use a garbage collected language such as Java, C#, or Go, and then not have to worry about memory management.

Post reply on HN