Is there a standard argument sequence identity function in Clojure? - function

Is there a function in the Clojure standard library equivalent to the following?
(fn [& args] args)
If not, why?
Example usage:
(take 10 (apply (fn [& args] args) (range)))
;=> (0 1 2 3 4 5 6 7 8 9)
;; ironically, map isn't lazy enough, so let's take it up to 11
(defn lazy-map [f & colls]
(lazy-seq (cons (apply f (map first colls))
(apply lazy-map f (map rest colls)))))
(defn transpose [m]
(apply lazy-map (fn [& args] args) m))
(defn take-2d [rows cols coll]
(take rows (map (partial take cols) coll)))
(take-2d 3 3 (transpose (map (partial iterate inc) (range))))
;=> ((0 1 2) (1 2 3) (2 3 4))
Please note that I am not asking for a transformative, eager function such as vector or list.

There is no such function, you are free to implement and use it as you like:
(defn args [& args] args)
(set (map type (apply map args [[1 2 3][4 5 6][7 8 9]])))
=> #{clojure.lang.ArraySeq}
Why isn't it already available?
This is rarely fruitful question: not only we don't know what happens in the mind of implementors, it is impracticable to ask them to justify or document why they did not do something. Was adding this function ever considered? How can we know? Is there really a reason, or did it just happen?
On the other hand, I agree that args feels simpler because it passes around an already existing immutable sequence.
I also can understand if you think that not converting the arguments as a persistent list in the first place is better, if only for the sake of parcimony.
But this is not how it is implemented, and the overhead of using list is really negligible (and specialized when building from an instance of ArraySeq).
You are supposed to code to an interface and never look behind the curtain, and from this point of view, list and args are equivalent, even though they do not return identical results.
You added a remark about laziness, and you are right: if you ever need to take the arguments from a variadic function and pass it to a function which operates on sequences, The version with list will consume all the given arguments whereas args will not. In some cases, as with (apply list (range)), where you literally pass an infinite number of arguments, this might hang forever.
From that point of view, the little args function is in fact interesting: you can move from arguments to actual sequences without introducing potential problems.
I am however not sure how often this case happens in practice.
In fact, I have a hard time finding a use case where laziness in the argument list really matters as far as args is concerned.
After all, in order to pass an infinite sequence, the only way (?) is to use apply:
(apply f (infinite))
In order to have a use-case for args, that means that we want to convert from an argument list back to a single list so that another function g can use it as a sequence, like so:
(g (apply args (infinite)))
But in that case, we could directly call:
(g (infinite))
In your example, g would stand for cons inside lazy-map, but since f is given in input, we cannot write (cons (map ...) ...) directly. The example thus looks like a genuine use case for args, but you should document the function heavily because the snippet you gave is quite complex. I tend to think that giving an unbounded number of arguments to a function is a code smell: should every function with an [& args] signature avoid consuming all arguments because the given sequence might in fact be infinite, like lazy-map does? I'd rather have a single argument be a lazy sequence for this kind of usage (and pass identity where needed) instead of the whole argument list, to clarify the intent. But in the end, I am not strongly opposed to the use of args either.
So to conclude, unless you manage to convince Rich Hickey to add args as a core function, I am confident that almost nobody will want to depend on an external library which does just this1: it is unfamiliar, but also trivial to implement and mostly useless. The only reward is knowing that you skip a little transformation step which costs nothing in most cases. Likewise, do not worry about having to choose between a vector and a list: it has practically no influence on your code and you can still modify the code later if you can prove it is necessary.
Regarding laziness, while I agree that wrapping arguments in lists or vectors can be problematic with unbounded argument lists, I am not sure the problem actually arises in practice.
1. Of course, if it ever reaches clojure.core, everybody will be quick to say that is is a fundamental operation which is most useful and definitely idiomatic </cynic>

There's identity function. It takes an argument and just returns that argument. Clojure's identity is single arity though.
usage:
(identity 4) ;=> 4
(identity [1 2 3 4]) ;=> [1 2 3 4]
I don't think there's much sense in having the identity function with variable arity since Clojure functions return only one value. If you want to return multiple values from a function, then you can wrap them in a seq which you can later destructure. In that case you can have something like this:
(defn varity-identity [& args]
(map identity args))
(varity-identity 1 2 3 4 5) ;=> (1 2 3 4 5)
Hope this helps.

Related

I'm stuck trying to implement this function in Racket and ML

I have this assignment:
Consider a list where every element is a nested list of length 2. The first
element of each nested list is either a 0 or a 1. The second element of each nested list
is some integer. An example input in Scheme is written below.
'((0 1) (1 2) (1 3) (0 4) (0 3))
For the purposes of this question, let’s call the first element of each nested list the
key and the second element of the nested lists the value. Now consider a function,
count_by_cat, that takes such a list as input and yields a two-element list where
the first element is the sum of the values of all nested lists with 0 as the key,
and
the second element is the sum of the values of all nested lists with 1 as the key
Implement count_by_cat in
(a) Racket, and
(b) ML.
It might be helpful to create helper functions. Also do not forget about map and filter
(filter is not a built-in in ML).
I'm new to Racket and ML. I'm stuck at using accessing lists and stuff in Racket. Some help with ML would also be great.
Well you're suggested to use higher order functions like map and filter.
And indeed it is easy to manipulate our data as a whole instead of focusing, mentally, on one element at a time. Which approach (i.e. the former one) some might argue, is the essence of functional programming paradigm.
In Racket,
(define (count_by_cat ls)
"return a two-element list"
(list
;; .....
;; ..... ))
where the first element is the sum of
(sum-of
the values of all nested lists
(map value
with 0 as the key
(filter (lambda (x) (= 0 (key x))) ls)))
and the second element is the sum of the values of all nested lists
(sum-of
(map value
with 1 as the key
(filter (lambda (x) (= 1 (key x))) ls))) ))
And so we need to define the helper functions accessing the nested lists,
(define (key n) (car n))
(define (value n) (cadr n))
and also the sum-of function, for summing up the numerical values in a list:
(require math/base)
(define (sum-of ls)
(sum ls))
This was easy to write, and will be easy to maintain.
The more performant code would do everything in one pass over the input, like is shown in the other answer. It has all the logic fused into one loop body. It could be more brittle to write and maintain.
The hint about map and filter is a bit of a red herring (As well as being wrong about them not being in ML languages); a helper function is very useful, but it's a fold you want, which basically calls a function with the current element of a list and an accumulator value, and uses what it returns as the accumulator for the next element and ultimately the return value of the entire fold.
For example, in ocaml, using a fold to sum a list of integers:
let sum = List.fold_left (+) 0 [ 1; 2; 3; 4; 5 ];;
((+) is the function version of the infix operator +).
Or your problem in Racket, using the for/fold comprehension, and returning two values instead of a two-element list, which is more idiomatic in Racket and Scheme (In ocaml and presumably Standard ML, you'd return a two-element tuple instead of a list, and take a list of tuples).
(define (count-by-cat lol)
(for/fold ([zero-sum 0]
[one-sum 0])
([elem (in-list lol)])
(case (first elem)
[(0) (values (+ zero-sum (second elem)) one-sum)]
[(1) (values zero-sum (+ one-sum (second elem)))])))
You could also use foldl, but for/fold is often easier to use, especially when working with multiple values or other non-trivial cases.

Clojure, can macros do something that couldn't be done with a function

I'm learning Clojure macros, and wonder why we can't use just functions for metaprogramming.
As far as I know the difference between macro and function is that arguments of macro are not evaluated but passed as data structures and symbols as they are, whereas the return value is evaluated (in the place where macro is called). Macro works as a proxy between reader and evaluator, transforming the form in an arbitrary way before the evaluation takes place. Internally they may use all the language features, including functions, special forms, literals, recursion, other macros etc.
Functions are the opposite. Arguments are evaluated before the call, return value is not after return. But the mirroring nature of macros and functions makes me wonder, couldn't we as well use functions as macros by quoting their arguments (the form), transforming the form, evaluating it inside the function, finally returning it's value. Wouldn't this logically produce the same outcome? Of course this would be inconvenient, but theoretically, is there equivalent function for every possible macro?
Here is simple infix macro
(defmacro infix
"translate infix notation to clojure form"
[form]
(list (second form) (first form) (last form)))
(infix (6 + 6)) ;-> 12
Here is same logic using a function
(defn infix-fn
"infix using a function"
[form]
((eval (second form)) (eval (first form)) (eval (last form))))
(infix-fn '(6 + 6)) ;-> 12
Now, is this perception generalizable to all situations, or are there some corner cases where macro couldn't be outdone? In the end, are macros just a syntactic sugar over a function call?
It would help if I read the question before answering it.
Your infix function doesn't work except with literals:
(let [m 3, n 22] (infix-fn '(m + n)))
CompilerException java.lang.RuntimeException:
Unable to resolve symbol: m in this context ...
This is the consequence of what #jkinski noted: by the time eval acts, m is gone.
Can macros do what functions cannot?
Yes. But if you can do it with a function, you generally should.
Macros are good for
deferred evaluation;
capturing forms;
re-organizing syntax;
none of which a function can do.
Deferred Evaluation
Consider (from Programming Clojure by Halloway & Bedra)
(defmacro unless [test then]
(list 'if (list 'not test) then)))
... a partial clone of if-not. Let's use it to define
(defn safe-div [num denom]
(unless (zero? denom) (/ num denom)))
... which prevents division by zero, returning nil:
(safe-div 10 0)
=> nil
If we tried to define it as a function:
(defn unless [test then]
(if (not test) then))
... then
(safe-div 10 0)
ArithmeticException Divide by zero ...
The potential result is evaluated as the then argument to unless, before the body of unless ignores it.
Capturing Forms and Re-organizing Syntax
Suppose Clojure had no case form. Here is a rough-and-ready substitute:
(defmacro my-case [expr & stuff]
(let [thunk (fn [form] `(fn [] ~form))
pairs (partition 2 stuff)
default (if (-> stuff count odd?)
(-> stuff last thunk)
'(constantly nil))
[ks vs] (apply map list pairs)
the-map (zipmap ks (map thunk vs))]
(list (list the-map expr default))))
This
picks apart the keys (ks) and corresponding expressions (vs),
wraps the latter as parameterless fn forms,
constructs a map from the former to the latter,
returns a form that calls the function returned by looking up the
map.
The details are unimportant. The point is it can be done.
When Guido van Rossum proposed adding a case statement to Python, the committee turned him down. So Python has no case statement. If Rich didn't want a case statement, but I did, I can have one.
Just for fun, let's use macros to contrive a passable clone of the if form. This is no doubt a cliche in functional programming circles, but took me by surprise. I had thought of if as an irreducible primitive of lazy evaluation.
An easy way is to piggy-back on the the my-case macro:
(defmacro if-like
([test then] `(if-like ~test ~then nil))
([test then else]
`(my-case ~test
false ~else
nil ~else
~then)))
This is prolix and slow, and it uses stack and loses recur, which gets buried in the closures. However ...
(defn fact [n]
(if-like (pos? n)
(* (fact (dec n)) n)
1))
(map fact (range 10))
=> (1 1 2 6 24 120 720 5040 40320 362880)
... it works, more or less.
Please, dear reader, point out any errors in my code.

Idiomatic way to pass a method name for evaluation in Clojure?

I'm passing the name of a function for use in another method.
(defn mapper [m function]
(cond
(= '() m) '()
true (cons (function (first m))
(mapper (rest m) function))))
(println (mapper '((blue red)(green red)(white red)) #'first))
Is there a more idiomatic way to do this in clojure?
Prefer vectors to lists. You don't have to quote a vector most of the time, and it has better performance for a lot of things, like random access. Lists are used much more rarely in Clojure than in other Lisps.
Prefer keywords to quoted symbols. Keywords stand out as "constant strings" or enumerated values. Keywords in Clojure can belong to a namespace, so they have all the advantages of symbols. And again, there's no need to quote keywords, which is nice. Quoted symbols are used pretty rarely in Clojure, unless you're writing macros.
#'first is the var called "first"; first is the value of the var called "first", i.e. the fn. In this case (#'first foo) and (first foo) give the same answer, but #'first does an extra dereference every time you call it. So don't do this unless you want that dereference to happen over and over. There's usually no need to use #'.
The built-in map is lazy, whereas yours isn't. The built-in map takes advantage of chunked seqs for better performance, whereas yours doesn't. Idiomatic code doesn't have to be lazy or use chunked seqs, but keep in mind that the builtins have some of this magic going on. So it's good to take advantage.
Rather than (= '() x), the idiomatic test for an empty seq is (seq x), which returns nil if x is empty. Note that in Clojure, (= '() nil) is false.
If you do ever need to use the empty list (which you should rarely need to do), you don't have to quote it. Just use ().
Built-in map takes the function argument first because it accepts multiple collection arguments. When a function takes multiple arguments, those arguments have to go last in the argument list. I think it reads better the other way too: "(map f coll): map this function across this collection".
There's no need to use cond if you only have two options. You can use if instead. And if one of the branches in your if returns nil, you can use when. It's nice to use when and if when appropriate, because they signal your intentions to the reader immediately, whereas cond could do anything and forces the reader to read more.
Rafał Dowgird's version is idiomatic, except I'd flip the order of arguments around. And I'd call it like this:
user> (mapper first [[:blue :red] [:green :red] [:white :red]])
(:blue :green :white)
I believe you got it mostly idiomatic. Clojure's own map uses:
(defn mapper [coll f]
(when-let [s (seq coll)]
(cons (f (first s)) (mapper (rest s) f))))
I have shortened it severely - the original produces a lazy sequence, deals with multiple collections, chunked-seqs, etc. By the way - I assume you want to pass the actual function, not it's name.
The coll and f are idiomatic arg names to represent collections and functions, respectively.
Your version looks good to me. The usual names you will see in the clojure code base is 'coll' for collections. I have also seen 'xs' which is the Haskell style, I think. You may also refer to the Clojure library coding standards on various conventions.
Coming back to the example: Two observations.
Use :else for 'cond' as the escape condition, instead of the Common Lisp style 'T'.
Instead of assuming lists, think sequences.
With these two in mind, if I rewrite your code:
user> (defn mapper [coll f]
(cond
(not (seq coll)) nil
:else (conj (mapper (next coll) f)
(f (first coll)))))
#'user/mapper
user> (mapper '(1 2 3) #(* % %))
(1 4 9)
user> (mapper [1 2 3] #(* % %))
(1 4 9)
Note that conj does the "right thing" as far as collections are concerned. It adds the new element to the head of a list, to the tail of a vector and so on. Also note the use of 'next' instead of the first/rest idioms in traditional lisp. 'next' returns a sequence of elements after the first element. So, empty-ness can be checked by seq'ing on the collection which will return nil for an empty list or an empty vector. This way it works for all collections.

Mechanism of a function in Scheme

Here it is a strange function in Scheme:
(define f
(call/cc
(lambda (x) x) ) )
(((f 'f) f) 1 )
When f is called in the command line, the result displayed is f .
What is the explanation of this mechanism ?..
Thanks!
You've just stumbled upon 'continuations', possibly the hardest thing of Scheme to understand.
call/cc is an abbreviation for call-with-current-continuation, what the procedure does is it takes a single argument function as its own argument, and calls it with the current 'continuation'.
So what's a continuation? That's infamously hard to explain and you should probably google it to get a better explanation than mine. But a continuation is simply a function of one argument, whose body represents a certain 'continuation' of a value.
Like, when we have (+ 2 (* 2 exp)) with exp being a random expression, if we evaluate that expression there is a 'continuation' waiting for that result, a place where evaluation continues, if it evaluates to 3 for instance, it inserts that value into the expression (* 2 3) and goes on from there with the next 'continuation', or the place where evaluation continues, which is (+ 2 ...).
In almost all contexts of programming languages, the place where computation continues with the value is the same place as it started, though the return statement in many languages is a key counterexample, the continuation is at a totally different place than the return statement itself.
In Scheme, you have direct control over your continuations, you can 'capture' them like done there. What f does is nothing more than evaluate to the current continuation, after all, when (lambda (x) x) is called with the current continuation, it just evaluates to it, so the entire function body does. As I said, continuations are functions themselves whose body can just be seen as the continuation they are to capture, which was famously shown by the designers of Scheme, that continuations are simply just lambda abstractions.
So in the code f first evaluates to the continuation it was called in. Then this continuation as a function is applied to 'f (a symbol). This means that that symbol is brought back to that continuation, where it is evaluated again as a symbol, to reveal the function it is bound to, which again is called with a symbol as its argument, which is finally displayed.
Kind of mind boggling, if you've seen the film 'primer', maybe this explains it:
http://thisdomainisirrelevant.net/1047

In common-lisp, how do I modify part of a list parameter from within a function without changing the original list?

I'm trying to pass a list to a function in Lisp, and change the contents of that list within the function without affecting the original list. I've read that Lisp is pass-by-value, and it's true, but there is something else going on that I don't quite understand. For example, this code works as expected:
(defun test ()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf n '(x y z))
n)
If you call (test), it prints (a b c) even though (modify) returns (x y z).
However, it doesn't work that way if you try to change just part of the list. I assume this has something to do with lists that have the same content being the same in memory everywhere or something like that? Here is an example:
(defun test ()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf (first n) 'x)
n)
Then (test) prints (x b c). So how do I change some elements of a list parameter in a function, as if that list was local to that function?
Lisp lists are based on cons cells. Variables are like pointers to cons cells (or other Lisp objects). Changing a variable will not change other variables. Changing cons cells will be visible in all places where there are references to those cons cells.
A good book is Touretzky, Common Lisp: A Gentle Introduction to Symbolic Computation.
There is also software that draws trees of lists and cons cells.
If you pass a list to a function like this:
(modify (list 1 2 3))
Then you have three different ways to use the list:
destructive modification of cons cells
(defun modify (list)
(setf (first list) 'foo)) ; This sets the CAR of the first cons cell to 'foo .
structure sharing
(defun modify (list)
(cons 'bar (rest list)))
Above returns a list that shares structure with the passed in list: the rest elements are the same in both lists.
copying
(defun modify (list)
(cons 'baz (copy-list (rest list))))
Above function BAZ is similar to BAR, but no list cells are shared, since the list is copied.
Needless to say that destructive modification often should be avoided, unless there is a real reason to do it (like saving memory when it is worth it).
Notes:
never destructively modify literal constant lists
Dont' do: (let ((l '(a b c))) (setf (first l) 'bar))
Reason: the list may be write protected, or may be shared with other lists (arranged by the compiler), etc.
Also:
Introduce variables
like this
(let ((original (list 'a 'b 'c)))
(setf (first original) 'bar))
or like this
(defun foo (original-list)
(setf (first original-list) 'bar))
never SETF an undefined variable.
SETF modifies a place. n can be a place. The first element of the list n points to can also be a place.
In both cases, the list held by original is passed to modify as its parameter n. This means that both original in the function test and n in the function modify now hold the same list, which means that both original and n now point to its first element.
After SETF modifies n in the first case, it no longer points to that list but to a new list. The list pointed to by original is unaffected. The new list is then returned by modify, but since this value is not assigned to anything, it fades out of existence and will soon be garbage collected.
In the second case, SETF modifies not n, but the first element of the list n points to. This is the same list original points to, so, afterwards, you can see the modified list also through this variable.
In order to copy a list, use COPY-LIST.
it's nearly the same as this example in C:
void modify1(char *p) {
p = "hi";
}
void modify2(char *p) {
p[0] = 'h';
}
in both cases a pointer is passed, if you change the pointer, you're changing the parameter copy of the pointer value (that it's on the stack), if you change the contents, you're changing the value of whatever object was pointed.
You probably have problems because even though Lisp is pass-by-value references to objects are passed, like in Java or Python. Your cons cells contain references which you modify, so you modify both original and local one.
IMO, you should try to write functions in a more functional style to avoid such problems. Even though Common Lisp is multi-paradigm a functional style is a more appropriate way.
(defun modify (n)
(cons 'x (cdr n))