Go deep into lisp (clojure)-Variables

Source: Internet
Author: User

This article by larrylgq prepared, reproduced please note the Source: http://blog.csdn.net/larrylgq/article/details/7395261

Author: Lu guiqiang

Email: larry.lv.word@gmail.com

Variables in clojure can be divided into lexical variables and dynamic variables, which are somewhat similar to local variables and global variables in other languages.

A variable is a named location that can save values without declaring the storage type. It can save any type of values with the type information used for runtime checks. In addition, if a type error occurs, it will be detected dynamically.

Eg :( pass a non-numeric object to the + function)

From this perspective, lisp is a strongly typed and Dynamic Language.

Lisp transmits values, but the transmitted values are references of objects. This is similar to Java and python. This means that if a variable modifies a variable object to which it points, this change will be applied to any variable that references this object.

 

One way to introduce new variables is to use the function parameters: the Parameter List defines the variables that save the real parameters when the function is called.

Eg :( defn Foo [x y z] (+ x y z ))

Each time a function is called, clojure creates a new binding and stores the real parameters passed by the caller. the lifecycle of the binding ends at the end of the runtime. (The form parameters of recursive functions are re-bound when each callback function is called)

 

Another way to introduce new variables is to use the let special operator.

Eg :( let [variable *] body-form *)

Variable can assign initial values or not assign values. The following is a let that binds X, Y, and Z to 1, 2, and nil respectively:

(Let [[[x 1] [Y 2] Z]

...)

The let function is a macro that calls an anonymous function. The preceding example can be expanded to (FN [x y z] (...) 1 2 nil)

After the call is completed, if the variable is referenced before the let, it points to the referenced object again.
Function Definition and let are called binding forms. Multiple nested variables are bound to variables of the same name. The variable binding on the inner layer overwrites the outer layer.

Clojure Closure

If an anonymous function references a variable with a closed scope like this:

(Let [count 0] # (FN [] (INC count )))

The reference to count in the lambda expression based on the scope rule is legal, and the anonymous function that references count will be returned as a return value by the let function.

If we assign the closure created by this expression to a global variable, for example:

(DEF * fN * (let [count 0] # (FN [] (INC count ))))

In this way, we can call it externally.

User> (* fN *)

1

User> (* fN *)

2

Of course, multiple closures can also reference the same variable.

For example:

(Let [count 0]

(List

# (FN [] (INC count ))

# (FN [] (deccount ))

# (FN [] Count)

)

)

 

Dynamic Variables

Clojure contains four types of dynamic variables: vars, refs, atoms, and agents.

The following table compares them:

The functions mentioned in this table will be described later.

  VaR Ref Atom Agent
Purpose Synchronize modifications to the variables of a local thread Synchronize modifications to one or more dynamic variables Modify a variable synchronously. Asynchronously modifies a variable.
Creation Method (def name initial-value) (ref initial-value) (atom initial-value) (agent initial-value)
Modification Method (def name new-value)
Assign a new value to the variable.

(alter-var-root
(var name) update-fn args)

Use VaR and FN to dynamically modify a function reference

(Set!Name New-Value) Used inside the binding to modify the local value of a thread.

(ref-set ref new-value)
Assign a new value to the variable, which must be called in dosync

(alter ref
update-fn arguments
)

Modify the ref value, which must be called in dosync. If the value changes after the transaction starts, the current transaction will retry.

(commute ref
update-fn arguments
)

Modify the ref value, which must be called in dosync. The current transaction will not retry even if the value changes after the transaction starts.

(reset! atom new-value)

The new value is saved no matter what the old value looks like.

(Compare-and-set!Atom current-value new-Value) Check the old value before setting the new value. If it is the same as the current-value, true is set. Otherwise, only false is returned.

(Swap!Atom
Update-FN arguments
) For compare-and-set! Will automatically retry when false is returned.

(send agent
update-fn arguments
)

The number of threads used is (Java. util. Concurrent. executors. newfixedthreadpool). The number of threads is the number of CPUs + 2

(Send-offAgent
Update-FN arguments
) The thread pool used is (Java. util. Concurrent. executors. newcachedthreadpool)
The number of threads is allocated as needed

Note:

1: Software transactional memory (STM ):

Modifications made in the STM transaction can only be seen by other threads after the transaction is committed. This achieves a (Atomicity) and I (isolation) in acid)

After the transaction starts, if another thread changes this ref, the transaction will roll back to the starting state, which achieves C (consistency)

2: Send returns immediately after an action is assigned to the agent. After the action is executed, the return value is assigned to the agent.
The number of threads used is (Java. util. Concurrent. executors. newfixedthreadpool). The number of threads is the number of CPUs + 2
Send-off is similar to set. The thread pool used is (Java. util. Concurrent. executors. newcachedthreadpool)
The number of threads is allocated as needed.
When the send and send-off functions are called in transactions. This action is sent to another thread for execution until the thread submits it.

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.