The Question: # --- This problem was asked by Jane Street.
cons(a, b) constructs a pair, and car(pair) and cdr(pair) returns the first and last element of that pair. For example, car(cons(3, 4)) returns 3, and cdr(cons(3, 4)) returns 4. Given this implementation of cons: def cons(a, b): def pair(f): return f(a, b) return pair Implement car and cdr. # --- Kind Regards, Abdur-Rahmaan Janhangeer https://www.github.com/Abdur-RahmaanJ Mauritius sent from gmail client on Android, that's why the signature is so ugly. On Fri, 18 Dec 2020, 10:02 Cameron Simpson, <c...@cskk.id.au> wrote: > On 17Dec2020 23:52, Abdur-Rahmaan Janhangeer <arj.pyt...@gmail.com> wrote: > >Here is a famous question's solution > > These look like implementations of Lisp operators, which I've never > found easy to remember. So I'll do this from first principles, but > looking at the (uncommented) code. > > This is some gratuitiously tricky code. Maybe that's needed for these > operators. But there's a lot here, so let's unpick it: > > >def cons(a, b): > > def pair(f): > > return f(a, b) > > return pair > > Cons returns "pair", a function which itself accepts a function "f", > calls it with 2 values "a, b" and returns the result. For ultra > trickiness, those 2 values "a, b" are the ones you passed to the initial > call to cons(). > > This last bit is a closure: when you define a function, any nonlocal > variables (those you use but never assign to) have the defining scope > available for finding them. So the "pair" function gets "a" and "b" from > those you passed to "cons". > > Anyway, cons() returns a "pair" function hooked to the "a" and "b" you > called it with. > > >def car(c): > > return c(lambda a, b: a) > > The function accepts a function, and calls that function with "lambda a, > b: a", which is itself a function which returns its first argument. You > could write car like this: > > def car(c): > def first(a, b): > return a > return c(first) > > The lambda is just a way to write a simple single expression function. > > >print(cons(1, 2)(lambda a, b: a)) > > What is "cons(1,2)". That returns a "pair" function hooked up to the a=1 > and b=2 values you supplied. And the pair function accepts a function of > 2 variables. > > What does this do? > > cons(1, 2)(lambda a, b: a) > > This takes the function returns by cons(1,2) and _calls_ that with a > simple function which accepts 2 values and returns the first of them. > > So: > > cons(1,2) => "pair function hooked to a=1 and b=2" > > Then call: > > pair(lambda a, b: a) > > which sets "f" to the lambda function, can calls that with (a,b). So it > calls the lambda function with (1,2). Which returns 1. > > >print(car(cons(1, 2))) > > The "car" function pretty much just embodies the call-with-the-lambda. > > >but i don't understand how lambda achieves this > > If you rewite the lambda like this: > > def a_from_ab(a,b): > return a > > and then rewrite the first call to cons() like this: > > cons(1,2)(a_from_ab) > > does it make any more sense? > > Frankly, I think this is a terrible way to solve this problem, whatever > the problem was supposed to be - that is not clear. > > On the other hand, I presume it does implement the Lisp cons and car > functions. I truly have no idea, I just remember these names from my > brief brush with Lisp in the past. > > Cheers, > Cameron Simpson <c...@cskk.id.au> > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list