Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement lambda as a function called "lambda" in Clojure?

I'd like to be able to define lambdas using common Lisp syntax, in Clojure. For example:

(lambda (myarg)
  (some-functions-that-refer-to myarg))

This needs to result in the same as:

#(some-functions-that-refer-to %)

In my case, I know I'll always have exactly one arg, so perhaps that simplifies things. (But it can be called anything -- "myarg" or whatever.)

I suspect a workable solution is to "(defmacro lambda ...". If so, I'm not sure of the best way to proceed. How to cleanly translate the arg name to %? And how to end up with the correct function?

Or, is there a simpler solution than writing my own macro that actually re-implements Clojure's... lambda?

like image 465
dirtyvagabond Avatar asked Mar 23 '10 04:03

dirtyvagabond


People also ask

Can Lambda invoke Lambda?

You can invoke Lambda functions directly using the Lambda console, a function URL HTTP(S) endpoint, the Lambda API, an AWS SDK, the AWS Command Line Interface (AWS CLI), and AWS toolkits.

Can we clone lambda function?

There is no provided function to copy/clone Lambda Functions and API Gateway configurations. You will need to create new a new function from scratch. If you envision having to duplicate functions in the future, it may be worthwhile to use AWS CloudFormation to create your Lambda Functions.

What is AWS Lambda used for?

AWS Lambda is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you. These events may include changes in state or an update, such as a user placing an item in a shopping cart on an ecommerce website.


1 Answers

#(foo %) is just reader shorthand for (fn [arg] (foo arg)). There's no reason to write a macro that expands into #(...). All the %'s in a #(...) construct are expanded into gensyms right away anyways.

user> `#(foo % %1 %2)
(fn* [user/p1__1877 user/p2__1878] 
  (user/foo user/p1__1877 user/p1__1877 user/p2__1878))

If you're ever writing a macro that expands to build anonymous functions, you might as well just expand them to fn forms yourself. In your case, you should probably just use fn directly and skip the macros. fn is Clojure's lambda.

The difference between (fn [] ...) and (lambda () ...) in this case is that "fn" is shorter to type than "lambda", and fn takes a vector for its bindings whereas lambda takes a list. If you're using Clojure, you will have to get used to this eventually, because vectors are always used for collections of bindings, in all the do forms and in for and binding etc. The rationale behind this as I understand it is that lists are used for function calls or macro calls, and vectors are used for things that aren't calls (lists of symbols to bind, for example). Arguably, it makes it easier to scan the code visually than lists-all-the-way-down. Clojure is not Common Lisp, and you will experience pain if you try to force it to be.

If you really, really wanted to do this, just to say you did:

user> (defmacro lambda [args & body]
        `(fn ~(vec args) ~@body))
user> ((lambda (x) (println x)) "foo")
foo
nil

This doesn't let you put a docstring or metadata on your function, among other things. I don't think you would want to use this in a real Clojure program.

like image 165
Brian Carper Avatar answered Sep 30 '22 22:09

Brian Carper