top | item 46240682

(no title)

sparkie | 2 months ago

So we can't return the closure?

Then it's clearly only half a solution.

The example I gave above should work fine in any language with first-class closures.

discuss

order

groundzeros2015|2 months ago

> The closure problem can be neatly described by as “how do I get extra data to use within this qsort call?”

    _Thread_local struct {
      void *data;
      int (*compare)(const void *a, const void*, void*);
    } _qsort2_closure ; 

    static int _qsort2_helper(const void *a, const void *b) {
        return _qsort2_closure.compare(a, b, _qsort2_closure.data);
    }

    void qsort2(void *base, size_t elements, size_t width, int (*compare)(const void *a, const void*, void*), void *userData) 
    {
        _qsort2_closure.data = userData;
        _qsort2_closure.compare = compare;
        qsort(base, elements, width, _qsort2_helper);
    }

gpderetta|2 months ago

you also need to restore the _qsort2_closure when done. But again you are reinventing dynamic scoping with all its advantages and disadvantages.

gpderetta|2 months ago

This is the classic lexical vs dynamic scoping. Dynamic scoping works great until it doesn't.

groundzeros2015|2 months ago

Don’t use C then? It sounds like you want JavaScript, Python, or Lisp.

Once again, the caller of the API does not declare any variables so there is no dynamic scoping.